Rev 72880 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
*> \brief \b DBBCSD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DBBCSD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dbbcsd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dbbcsd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dbbcsd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q,* THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T,* V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,* B22D, B22E, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS* INTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q* ..* .. Array Arguments ..* DOUBLE PRECISION B11D( * ), B11E( * ), B12D( * ), B12E( * ),* $ B21D( * ), B21E( * ), B22D( * ), B22E( * ),* $ PHI( * ), THETA( * ), WORK( * )* DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),* $ V2T( LDV2T, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DBBCSD computes the CS decomposition of an orthogonal matrix in*> bidiagonal-block form,*>*>*> [ B11 | B12 0 0 ]*> [ 0 | 0 -I 0 ]*> X = [----------------]*> [ B21 | B22 0 0 ]*> [ 0 | 0 0 I ]*>*> [ C | -S 0 0 ]*> [ U1 | ] [ 0 | 0 -I 0 ] [ V1 | ]**T*> = [---------] [---------------] [---------] .*> [ | U2 ] [ S | C 0 0 ] [ | V2 ]*> [ 0 | 0 0 I ]*>*> X is M-by-M, its top-left block is P-by-Q, and Q must be no larger*> than P, M-P, or M-Q. (If Q is not the smallest index, then X must be*> transposed and/or permuted. This can be done in constant time using*> the TRANS and SIGNS options. See DORCSD for details.)*>*> The bidiagonal matrices B11, B12, B21, and B22 are represented*> implicitly by angles THETA(1:Q) and PHI(1:Q-1).*>*> The orthogonal matrices U1, U2, V1T, and V2T are input/output.*> The input matrices are pre- or post-multiplied by the appropriate*> singular vector matrices.*> \endverbatim** Arguments:* ==========**> \param[in] JOBU1*> \verbatim*> JOBU1 is CHARACTER*> = 'Y': U1 is updated;*> otherwise: U1 is not updated.*> \endverbatim*>*> \param[in] JOBU2*> \verbatim*> JOBU2 is CHARACTER*> = 'Y': U2 is updated;*> otherwise: U2 is not updated.*> \endverbatim*>*> \param[in] JOBV1T*> \verbatim*> JOBV1T is CHARACTER*> = 'Y': V1T is updated;*> otherwise: V1T is not updated.*> \endverbatim*>*> \param[in] JOBV2T*> \verbatim*> JOBV2T is CHARACTER*> = 'Y': V2T is updated;*> otherwise: V2T is not updated.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*> = 'T': X, U1, U2, V1T, and V2T are stored in row-major*> order;*> otherwise: X, U1, U2, V1T, and V2T are stored in column-*> major order.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows and columns in X, the orthogonal matrix in*> bidiagonal-block form.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows in the top-left block of X. 0 <= P <= M.*> \endverbatim*>*> \param[in] Q*> \verbatim*> Q is INTEGER*> The number of columns in the top-left block of X.*> 0 <= Q <= MIN(P,M-P,M-Q).*> \endverbatim*>*> \param[in,out] THETA*> \verbatim*> THETA is DOUBLE PRECISION array, dimension (Q)*> On entry, the angles THETA(1),...,THETA(Q) that, along with*> PHI(1), ...,PHI(Q-1), define the matrix in bidiagonal-block*> form. On exit, the angles whose cosines and sines define the*> diagonal blocks in the CS decomposition.*> \endverbatim*>*> \param[in,out] PHI*> \verbatim*> PHI is DOUBLE PRECISION array, dimension (Q-1)*> The angles PHI(1),...,PHI(Q-1) that, along with THETA(1),...,*> THETA(Q), define the matrix in bidiagonal-block form.*> \endverbatim*>*> \param[in,out] U1*> \verbatim*> U1 is DOUBLE PRECISION array, dimension (LDU1,P)*> On entry, a P-by-P matrix. On exit, U1 is postmultiplied*> by the left singular vector matrix common to [ B11 ; 0 ] and*> [ B12 0 0 ; 0 -I 0 0 ].*> \endverbatim*>*> \param[in] LDU1*> \verbatim*> LDU1 is INTEGER*> The leading dimension of the array U1, LDU1 >= MAX(1,P).*> \endverbatim*>*> \param[in,out] U2*> \verbatim*> U2 is DOUBLE PRECISION array, dimension (LDU2,M-P)*> On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is*> postmultiplied by the left singular vector matrix common to*> [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].*> \endverbatim*>*> \param[in] LDU2*> \verbatim*> LDU2 is INTEGER*> The leading dimension of the array U2, LDU2 >= MAX(1,M-P).*> \endverbatim*>*> \param[in,out] V1T*> \verbatim*> V1T is DOUBLE PRECISION array, dimension (LDV1T,Q)*> On entry, a Q-by-Q matrix. On exit, V1T is premultiplied*> by the transpose of the right singular vector*> matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].*> \endverbatim*>*> \param[in] LDV1T*> \verbatim*> LDV1T is INTEGER*> The leading dimension of the array V1T, LDV1T >= MAX(1,Q).*> \endverbatim*>*> \param[in,out] V2T*> \verbatim*> V2T is DOUBLE PRECISION array, dimension (LDV2T,M-Q)*> On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is*> premultiplied by the transpose of the right*> singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and*> [ B22 0 0 ; 0 0 I ].*> \endverbatim*>*> \param[in] LDV2T*> \verbatim*> LDV2T is INTEGER*> The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).*> \endverbatim*>*> \param[out] B11D*> \verbatim*> B11D is DOUBLE PRECISION array, dimension (Q)*> When DBBCSD converges, B11D contains the cosines of THETA(1),*> ..., THETA(Q). If DBBCSD fails to converge, then B11D*> contains the diagonal of the partially reduced top-left*> block.*> \endverbatim*>*> \param[out] B11E*> \verbatim*> B11E is DOUBLE PRECISION array, dimension (Q-1)*> When DBBCSD converges, B11E contains zeros. If DBBCSD fails*> to converge, then B11E contains the superdiagonal of the*> partially reduced top-left block.*> \endverbatim*>*> \param[out] B12D*> \verbatim*> B12D is DOUBLE PRECISION array, dimension (Q)*> When DBBCSD converges, B12D contains the negative sines of*> THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then*> B12D contains the diagonal of the partially reduced top-right*> block.*> \endverbatim*>*> \param[out] B12E*> \verbatim*> B12E is DOUBLE PRECISION array, dimension (Q-1)*> When DBBCSD converges, B12E contains zeros. If DBBCSD fails*> to converge, then B12E contains the subdiagonal of the*> partially reduced top-right block.*> \endverbatim*>*> \param[out] B21D*> \verbatim*> B21D is DOUBLE PRECISION array, dimension (Q)*> When DBBCSD converges, B21D contains the negative sines of*> THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then*> B21D contains the diagonal of the partially reduced bottom-left*> block.*> \endverbatim*>*> \param[out] B21E*> \verbatim*> B21E is DOUBLE PRECISION array, dimension (Q-1)*> When DBBCSD converges, B21E contains zeros. If DBBCSD fails*> to converge, then B21E contains the subdiagonal of the*> partially reduced bottom-left block.*> \endverbatim*>*> \param[out] B22D*> \verbatim*> B22D is DOUBLE PRECISION array, dimension (Q)*> When DBBCSD converges, B22D contains the negative sines of*> THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then*> B22D contains the diagonal of the partially reduced bottom-right*> block.*> \endverbatim*>*> \param[out] B22E*> \verbatim*> B22E is DOUBLE PRECISION array, dimension (Q-1)*> When DBBCSD converges, B22E contains zeros. If DBBCSD fails*> to converge, then B22E contains the subdiagonal of the*> partially reduced bottom-right block.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= MAX(1,8*Q).*>*> If LWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the WORK array,*> returns this value as the first entry of the work array, and*> no error message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if DBBCSD did not converge, INFO specifies the number*> of nonzero entries in PHI, and B11D, B11E, etc.,*> contain the partially reduced matrix.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> TOLMUL DOUBLE PRECISION, default = MAX(10,MIN(100,EPS**(-1/8)))*> TOLMUL controls the convergence criterion of the QR loop.*> Angles THETA(i), PHI(i) are rounded to 0 or PI/2 when they*> are within TOLMUL*EPS of either bound.*> \endverbatim**> \par References:* ================*>*> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.*> Algorithms, 50(1):33-65, 2009.** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q,$ THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T,$ V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,$ B22D, B22E, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANSINTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q* ..* .. Array Arguments ..DOUBLE PRECISION B11D( * ), B11E( * ), B12D( * ), B12E( * ),$ B21D( * ), B21E( * ), B22D( * ), B22E( * ),$ PHI( * ), THETA( * ), WORK( * )DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),$ V2T( LDV2T, * )* ..** ===================================================================** .. Parameters ..INTEGER MAXITRPARAMETER ( MAXITR = 6 )DOUBLE PRECISION HUNDRED, MEIGHTH, ONE, PIOVER2, TEN, ZEROPARAMETER ( HUNDRED = 100.0D0, MEIGHTH = -0.125D0,$ ONE = 1.0D0, PIOVER2 = 1.57079632679489662D0,$ TEN = 10.0D0, ZERO = 0.0D0 )DOUBLE PRECISION NEGONEPARAMETER ( NEGONE = -1.0D0 )* ..* .. Local Scalars ..LOGICAL COLMAJOR, LQUERY, RESTART11, RESTART12,$ RESTART21, RESTART22, WANTU1, WANTU2, WANTV1T,$ WANTV2TINTEGER I, IMIN, IMAX, ITER, IU1CS, IU1SN, IU2CS,$ IU2SN, IV1TCS, IV1TSN, IV2TCS, IV2TSN, J,$ LWORKMIN, LWORKOPT, MAXIT, MINIDOUBLE PRECISION B11BULGE, B12BULGE, B21BULGE, B22BULGE, DUMMY,$ EPS, MU, NU, R, SIGMA11, SIGMA21,$ TEMP, THETAMAX, THETAMIN, THRESH, TOL, TOLMUL,$ UNFL, X1, X2, Y1, Y2** .. External Subroutines ..EXTERNAL DLASR, DSCAL, DSWAP, DLARTGP, DLARTGS, DLAS2,$ XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMCHLOGICAL LSAMEEXTERNAL LSAME, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, ATAN2, COS, MAX, MIN, SIN, SQRT* ..* .. Executable Statements ..** Test input arguments*INFO = 0LQUERY = LWORK .EQ. -1WANTU1 = LSAME( JOBU1, 'Y' )WANTU2 = LSAME( JOBU2, 'Y' )WANTV1T = LSAME( JOBV1T, 'Y' )WANTV2T = LSAME( JOBV2T, 'Y' )COLMAJOR = .NOT. LSAME( TRANS, 'T' )*IF( M .LT. 0 ) THENINFO = -6ELSE IF( P .LT. 0 .OR. P .GT. M ) THENINFO = -7ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THENINFO = -8ELSE IF( Q .GT. P .OR. Q .GT. M-P .OR. Q .GT. M-Q ) THENINFO = -8ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THENINFO = -12ELSE IF( WANTU2 .AND. LDU2 .LT. M-P ) THENINFO = -14ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THENINFO = -16ELSE IF( WANTV2T .AND. LDV2T .LT. M-Q ) THENINFO = -18END IF** Quick return if Q = 0*IF( INFO .EQ. 0 .AND. Q .EQ. 0 ) THENLWORKMIN = 1WORK(1) = LWORKMINRETURNEND IF** Compute workspace*IF( INFO .EQ. 0 ) THENIU1CS = 1IU1SN = IU1CS + QIU2CS = IU1SN + QIU2SN = IU2CS + QIV1TCS = IU2SN + QIV1TSN = IV1TCS + QIV2TCS = IV1TSN + QIV2TSN = IV2TCS + QLWORKOPT = IV2TSN + Q - 1LWORKMIN = LWORKOPTWORK(1) = LWORKOPTIF( LWORK .LT. LWORKMIN .AND. .NOT. LQUERY ) THENINFO = -28END IFEND IF*IF( INFO .NE. 0 ) THENCALL XERBLA( 'DBBCSD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Get machine constants*EPS = DLAMCH( 'Epsilon' )UNFL = DLAMCH( 'Safe minimum' )TOLMUL = MAX( TEN, MIN( HUNDRED, EPS**MEIGHTH ) )TOL = TOLMUL*EPSTHRESH = MAX( TOL, MAXITR*Q*Q*UNFL )** Test for negligible sines or cosines*DO I = 1, QIF( THETA(I) .LT. THRESH ) THENTHETA(I) = ZEROELSE IF( THETA(I) .GT. PIOVER2-THRESH ) THENTHETA(I) = PIOVER2END IFEND DODO I = 1, Q-1IF( PHI(I) .LT. THRESH ) THENPHI(I) = ZEROELSE IF( PHI(I) .GT. PIOVER2-THRESH ) THENPHI(I) = PIOVER2END IFEND DO** Initial deflation*IMAX = QDO WHILE( IMAX .GT. 1 )IF( PHI(IMAX-1) .NE. ZERO ) THENEXITEND IFIMAX = IMAX - 1END DOIMIN = IMAX - 1IF ( IMIN .GT. 1 ) THENDO WHILE( PHI(IMIN-1) .NE. ZERO )IMIN = IMIN - 1IF ( IMIN .LE. 1 ) EXITEND DOEND IF** Initialize iteration counter*MAXIT = MAXITR*Q*QITER = 0** Begin main iteration loop*DO WHILE( IMAX .GT. 1 )** Compute the matrix entries*B11D(IMIN) = COS( THETA(IMIN) )B21D(IMIN) = -SIN( THETA(IMIN) )DO I = IMIN, IMAX - 1B11E(I) = -SIN( THETA(I) ) * SIN( PHI(I) )B11D(I+1) = COS( THETA(I+1) ) * COS( PHI(I) )B12D(I) = SIN( THETA(I) ) * COS( PHI(I) )B12E(I) = COS( THETA(I+1) ) * SIN( PHI(I) )B21E(I) = -COS( THETA(I) ) * SIN( PHI(I) )B21D(I+1) = -SIN( THETA(I+1) ) * COS( PHI(I) )B22D(I) = COS( THETA(I) ) * COS( PHI(I) )B22E(I) = -SIN( THETA(I+1) ) * SIN( PHI(I) )END DOB12D(IMAX) = SIN( THETA(IMAX) )B22D(IMAX) = COS( THETA(IMAX) )** Abort if not converging; otherwise, increment ITER*IF( ITER .GT. MAXIT ) THENINFO = 0DO I = 1, QIF( PHI(I) .NE. ZERO )$ INFO = INFO + 1END DORETURNEND IF*ITER = ITER + IMAX - IMIN** Compute shifts*THETAMAX = THETA(IMIN)THETAMIN = THETA(IMIN)DO I = IMIN+1, IMAXIF( THETA(I) > THETAMAX )$ THETAMAX = THETA(I)IF( THETA(I) < THETAMIN )$ THETAMIN = THETA(I)END DO*IF( THETAMAX .GT. PIOVER2 - THRESH ) THEN** Zero on diagonals of B11 and B22; induce deflation with a* zero shift*MU = ZERONU = ONE*ELSE IF( THETAMIN .LT. THRESH ) THEN** Zero on diagonals of B12 and B22; induce deflation with a* zero shift*MU = ONENU = ZERO*ELSE** Compute shifts for B11 and B21 and use the lesser*CALL DLAS2( B11D(IMAX-1), B11E(IMAX-1), B11D(IMAX), SIGMA11,$ DUMMY )CALL DLAS2( B21D(IMAX-1), B21E(IMAX-1), B21D(IMAX), SIGMA21,$ DUMMY )*IF( SIGMA11 .LE. SIGMA21 ) THENMU = SIGMA11NU = SQRT( ONE - MU**2 )IF( MU .LT. THRESH ) THENMU = ZERONU = ONEEND IFELSENU = SIGMA21MU = SQRT( 1.0 - NU**2 )IF( NU .LT. THRESH ) THENMU = ONENU = ZEROEND IFEND IFEND IF** Rotate to produce bulges in B11 and B21*IF( MU .LE. NU ) THENCALL DLARTGS( B11D(IMIN), B11E(IMIN), MU,$ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1) )ELSECALL DLARTGS( B21D(IMIN), B21E(IMIN), NU,$ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1) )END IF*TEMP = WORK(IV1TCS+IMIN-1)*B11D(IMIN) +$ WORK(IV1TSN+IMIN-1)*B11E(IMIN)B11E(IMIN) = WORK(IV1TCS+IMIN-1)*B11E(IMIN) -$ WORK(IV1TSN+IMIN-1)*B11D(IMIN)B11D(IMIN) = TEMPB11BULGE = WORK(IV1TSN+IMIN-1)*B11D(IMIN+1)B11D(IMIN+1) = WORK(IV1TCS+IMIN-1)*B11D(IMIN+1)TEMP = WORK(IV1TCS+IMIN-1)*B21D(IMIN) +$ WORK(IV1TSN+IMIN-1)*B21E(IMIN)B21E(IMIN) = WORK(IV1TCS+IMIN-1)*B21E(IMIN) -$ WORK(IV1TSN+IMIN-1)*B21D(IMIN)B21D(IMIN) = TEMPB21BULGE = WORK(IV1TSN+IMIN-1)*B21D(IMIN+1)B21D(IMIN+1) = WORK(IV1TCS+IMIN-1)*B21D(IMIN+1)** Compute THETA(IMIN)*THETA( IMIN ) = ATAN2( SQRT( B21D(IMIN)**2+B21BULGE**2 ),$ SQRT( B11D(IMIN)**2+B11BULGE**2 ) )** Chase the bulges in B11(IMIN+1,IMIN) and B21(IMIN+1,IMIN)*IF( B11D(IMIN)**2+B11BULGE**2 .GT. THRESH**2 ) THENCALL DLARTGP( B11BULGE, B11D(IMIN), WORK(IU1SN+IMIN-1),$ WORK(IU1CS+IMIN-1), R )ELSE IF( MU .LE. NU ) THENCALL DLARTGS( B11E( IMIN ), B11D( IMIN + 1 ), MU,$ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1) )ELSECALL DLARTGS( B12D( IMIN ), B12E( IMIN ), NU,$ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1) )END IFIF( B21D(IMIN)**2+B21BULGE**2 .GT. THRESH**2 ) THENCALL DLARTGP( B21BULGE, B21D(IMIN), WORK(IU2SN+IMIN-1),$ WORK(IU2CS+IMIN-1), R )ELSE IF( NU .LT. MU ) THENCALL DLARTGS( B21E( IMIN ), B21D( IMIN + 1 ), NU,$ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1) )ELSECALL DLARTGS( B22D(IMIN), B22E(IMIN), MU,$ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1) )END IFWORK(IU2CS+IMIN-1) = -WORK(IU2CS+IMIN-1)WORK(IU2SN+IMIN-1) = -WORK(IU2SN+IMIN-1)*TEMP = WORK(IU1CS+IMIN-1)*B11E(IMIN) +$ WORK(IU1SN+IMIN-1)*B11D(IMIN+1)B11D(IMIN+1) = WORK(IU1CS+IMIN-1)*B11D(IMIN+1) -$ WORK(IU1SN+IMIN-1)*B11E(IMIN)B11E(IMIN) = TEMPIF( IMAX .GT. IMIN+1 ) THENB11BULGE = WORK(IU1SN+IMIN-1)*B11E(IMIN+1)B11E(IMIN+1) = WORK(IU1CS+IMIN-1)*B11E(IMIN+1)END IFTEMP = WORK(IU1CS+IMIN-1)*B12D(IMIN) +$ WORK(IU1SN+IMIN-1)*B12E(IMIN)B12E(IMIN) = WORK(IU1CS+IMIN-1)*B12E(IMIN) -$ WORK(IU1SN+IMIN-1)*B12D(IMIN)B12D(IMIN) = TEMPB12BULGE = WORK(IU1SN+IMIN-1)*B12D(IMIN+1)B12D(IMIN+1) = WORK(IU1CS+IMIN-1)*B12D(IMIN+1)TEMP = WORK(IU2CS+IMIN-1)*B21E(IMIN) +$ WORK(IU2SN+IMIN-1)*B21D(IMIN+1)B21D(IMIN+1) = WORK(IU2CS+IMIN-1)*B21D(IMIN+1) -$ WORK(IU2SN+IMIN-1)*B21E(IMIN)B21E(IMIN) = TEMPIF( IMAX .GT. IMIN+1 ) THENB21BULGE = WORK(IU2SN+IMIN-1)*B21E(IMIN+1)B21E(IMIN+1) = WORK(IU2CS+IMIN-1)*B21E(IMIN+1)END IFTEMP = WORK(IU2CS+IMIN-1)*B22D(IMIN) +$ WORK(IU2SN+IMIN-1)*B22E(IMIN)B22E(IMIN) = WORK(IU2CS+IMIN-1)*B22E(IMIN) -$ WORK(IU2SN+IMIN-1)*B22D(IMIN)B22D(IMIN) = TEMPB22BULGE = WORK(IU2SN+IMIN-1)*B22D(IMIN+1)B22D(IMIN+1) = WORK(IU2CS+IMIN-1)*B22D(IMIN+1)** Inner loop: chase bulges from B11(IMIN,IMIN+2),* B12(IMIN,IMIN+1), B21(IMIN,IMIN+2), and B22(IMIN,IMIN+1) to* bottom-right*DO I = IMIN+1, IMAX-1** Compute PHI(I-1)*X1 = SIN(THETA(I-1))*B11E(I-1) + COS(THETA(I-1))*B21E(I-1)X2 = SIN(THETA(I-1))*B11BULGE + COS(THETA(I-1))*B21BULGEY1 = SIN(THETA(I-1))*B12D(I-1) + COS(THETA(I-1))*B22D(I-1)Y2 = SIN(THETA(I-1))*B12BULGE + COS(THETA(I-1))*B22BULGE*PHI(I-1) = ATAN2( SQRT(X1**2+X2**2), SQRT(Y1**2+Y2**2) )** Determine if there are bulges to chase or if a new direct* summand has been reached*RESTART11 = B11E(I-1)**2 + B11BULGE**2 .LE. THRESH**2RESTART21 = B21E(I-1)**2 + B21BULGE**2 .LE. THRESH**2RESTART12 = B12D(I-1)**2 + B12BULGE**2 .LE. THRESH**2RESTART22 = B22D(I-1)**2 + B22BULGE**2 .LE. THRESH**2** If possible, chase bulges from B11(I-1,I+1), B12(I-1,I),* B21(I-1,I+1), and B22(I-1,I). If necessary, restart bulge-* chasing by applying the original shift again.*IF( .NOT. RESTART11 .AND. .NOT. RESTART21 ) THENCALL DLARTGP( X2, X1, WORK(IV1TSN+I-1), WORK(IV1TCS+I-1),$ R )ELSE IF( .NOT. RESTART11 .AND. RESTART21 ) THENCALL DLARTGP( B11BULGE, B11E(I-1), WORK(IV1TSN+I-1),$ WORK(IV1TCS+I-1), R )ELSE IF( RESTART11 .AND. .NOT. RESTART21 ) THENCALL DLARTGP( B21BULGE, B21E(I-1), WORK(IV1TSN+I-1),$ WORK(IV1TCS+I-1), R )ELSE IF( MU .LE. NU ) THENCALL DLARTGS( B11D(I), B11E(I), MU, WORK(IV1TCS+I-1),$ WORK(IV1TSN+I-1) )ELSECALL DLARTGS( B21D(I), B21E(I), NU, WORK(IV1TCS+I-1),$ WORK(IV1TSN+I-1) )END IFWORK(IV1TCS+I-1) = -WORK(IV1TCS+I-1)WORK(IV1TSN+I-1) = -WORK(IV1TSN+I-1)IF( .NOT. RESTART12 .AND. .NOT. RESTART22 ) THENCALL DLARTGP( Y2, Y1, WORK(IV2TSN+I-1-1),$ WORK(IV2TCS+I-1-1), R )ELSE IF( .NOT. RESTART12 .AND. RESTART22 ) THENCALL DLARTGP( B12BULGE, B12D(I-1), WORK(IV2TSN+I-1-1),$ WORK(IV2TCS+I-1-1), R )ELSE IF( RESTART12 .AND. .NOT. RESTART22 ) THENCALL DLARTGP( B22BULGE, B22D(I-1), WORK(IV2TSN+I-1-1),$ WORK(IV2TCS+I-1-1), R )ELSE IF( NU .LT. MU ) THENCALL DLARTGS( B12E(I-1), B12D(I), NU, WORK(IV2TCS+I-1-1),$ WORK(IV2TSN+I-1-1) )ELSECALL DLARTGS( B22E(I-1), B22D(I), MU, WORK(IV2TCS+I-1-1),$ WORK(IV2TSN+I-1-1) )END IF*TEMP = WORK(IV1TCS+I-1)*B11D(I) + WORK(IV1TSN+I-1)*B11E(I)B11E(I) = WORK(IV1TCS+I-1)*B11E(I) -$ WORK(IV1TSN+I-1)*B11D(I)B11D(I) = TEMPB11BULGE = WORK(IV1TSN+I-1)*B11D(I+1)B11D(I+1) = WORK(IV1TCS+I-1)*B11D(I+1)TEMP = WORK(IV1TCS+I-1)*B21D(I) + WORK(IV1TSN+I-1)*B21E(I)B21E(I) = WORK(IV1TCS+I-1)*B21E(I) -$ WORK(IV1TSN+I-1)*B21D(I)B21D(I) = TEMPB21BULGE = WORK(IV1TSN+I-1)*B21D(I+1)B21D(I+1) = WORK(IV1TCS+I-1)*B21D(I+1)TEMP = WORK(IV2TCS+I-1-1)*B12E(I-1) +$ WORK(IV2TSN+I-1-1)*B12D(I)B12D(I) = WORK(IV2TCS+I-1-1)*B12D(I) -$ WORK(IV2TSN+I-1-1)*B12E(I-1)B12E(I-1) = TEMPB12BULGE = WORK(IV2TSN+I-1-1)*B12E(I)B12E(I) = WORK(IV2TCS+I-1-1)*B12E(I)TEMP = WORK(IV2TCS+I-1-1)*B22E(I-1) +$ WORK(IV2TSN+I-1-1)*B22D(I)B22D(I) = WORK(IV2TCS+I-1-1)*B22D(I) -$ WORK(IV2TSN+I-1-1)*B22E(I-1)B22E(I-1) = TEMPB22BULGE = WORK(IV2TSN+I-1-1)*B22E(I)B22E(I) = WORK(IV2TCS+I-1-1)*B22E(I)** Compute THETA(I)*X1 = COS(PHI(I-1))*B11D(I) + SIN(PHI(I-1))*B12E(I-1)X2 = COS(PHI(I-1))*B11BULGE + SIN(PHI(I-1))*B12BULGEY1 = COS(PHI(I-1))*B21D(I) + SIN(PHI(I-1))*B22E(I-1)Y2 = COS(PHI(I-1))*B21BULGE + SIN(PHI(I-1))*B22BULGE*THETA(I) = ATAN2( SQRT(Y1**2+Y2**2), SQRT(X1**2+X2**2) )** Determine if there are bulges to chase or if a new direct* summand has been reached*RESTART11 = B11D(I)**2 + B11BULGE**2 .LE. THRESH**2RESTART12 = B12E(I-1)**2 + B12BULGE**2 .LE. THRESH**2RESTART21 = B21D(I)**2 + B21BULGE**2 .LE. THRESH**2RESTART22 = B22E(I-1)**2 + B22BULGE**2 .LE. THRESH**2** If possible, chase bulges from B11(I+1,I), B12(I+1,I-1),* B21(I+1,I), and B22(I+1,I-1). If necessary, restart bulge-* chasing by applying the original shift again.*IF( .NOT. RESTART11 .AND. .NOT. RESTART12 ) THENCALL DLARTGP( X2, X1, WORK(IU1SN+I-1), WORK(IU1CS+I-1),$ R )ELSE IF( .NOT. RESTART11 .AND. RESTART12 ) THENCALL DLARTGP( B11BULGE, B11D(I), WORK(IU1SN+I-1),$ WORK(IU1CS+I-1), R )ELSE IF( RESTART11 .AND. .NOT. RESTART12 ) THENCALL DLARTGP( B12BULGE, B12E(I-1), WORK(IU1SN+I-1),$ WORK(IU1CS+I-1), R )ELSE IF( MU .LE. NU ) THENCALL DLARTGS( B11E(I), B11D(I+1), MU, WORK(IU1CS+I-1),$ WORK(IU1SN+I-1) )ELSECALL DLARTGS( B12D(I), B12E(I), NU, WORK(IU1CS+I-1),$ WORK(IU1SN+I-1) )END IFIF( .NOT. RESTART21 .AND. .NOT. RESTART22 ) THENCALL DLARTGP( Y2, Y1, WORK(IU2SN+I-1), WORK(IU2CS+I-1),$ R )ELSE IF( .NOT. RESTART21 .AND. RESTART22 ) THENCALL DLARTGP( B21BULGE, B21D(I), WORK(IU2SN+I-1),$ WORK(IU2CS+I-1), R )ELSE IF( RESTART21 .AND. .NOT. RESTART22 ) THENCALL DLARTGP( B22BULGE, B22E(I-1), WORK(IU2SN+I-1),$ WORK(IU2CS+I-1), R )ELSE IF( NU .LT. MU ) THENCALL DLARTGS( B21E(I), B21E(I+1), NU, WORK(IU2CS+I-1),$ WORK(IU2SN+I-1) )ELSECALL DLARTGS( B22D(I), B22E(I), MU, WORK(IU2CS+I-1),$ WORK(IU2SN+I-1) )END IFWORK(IU2CS+I-1) = -WORK(IU2CS+I-1)WORK(IU2SN+I-1) = -WORK(IU2SN+I-1)*TEMP = WORK(IU1CS+I-1)*B11E(I) + WORK(IU1SN+I-1)*B11D(I+1)B11D(I+1) = WORK(IU1CS+I-1)*B11D(I+1) -$ WORK(IU1SN+I-1)*B11E(I)B11E(I) = TEMPIF( I .LT. IMAX - 1 ) THENB11BULGE = WORK(IU1SN+I-1)*B11E(I+1)B11E(I+1) = WORK(IU1CS+I-1)*B11E(I+1)END IFTEMP = WORK(IU2CS+I-1)*B21E(I) + WORK(IU2SN+I-1)*B21D(I+1)B21D(I+1) = WORK(IU2CS+I-1)*B21D(I+1) -$ WORK(IU2SN+I-1)*B21E(I)B21E(I) = TEMPIF( I .LT. IMAX - 1 ) THENB21BULGE = WORK(IU2SN+I-1)*B21E(I+1)B21E(I+1) = WORK(IU2CS+I-1)*B21E(I+1)END IFTEMP = WORK(IU1CS+I-1)*B12D(I) + WORK(IU1SN+I-1)*B12E(I)B12E(I) = WORK(IU1CS+I-1)*B12E(I) - WORK(IU1SN+I-1)*B12D(I)B12D(I) = TEMPB12BULGE = WORK(IU1SN+I-1)*B12D(I+1)B12D(I+1) = WORK(IU1CS+I-1)*B12D(I+1)TEMP = WORK(IU2CS+I-1)*B22D(I) + WORK(IU2SN+I-1)*B22E(I)B22E(I) = WORK(IU2CS+I-1)*B22E(I) - WORK(IU2SN+I-1)*B22D(I)B22D(I) = TEMPB22BULGE = WORK(IU2SN+I-1)*B22D(I+1)B22D(I+1) = WORK(IU2CS+I-1)*B22D(I+1)*END DO** Compute PHI(IMAX-1)*X1 = SIN(THETA(IMAX-1))*B11E(IMAX-1) +$ COS(THETA(IMAX-1))*B21E(IMAX-1)Y1 = SIN(THETA(IMAX-1))*B12D(IMAX-1) +$ COS(THETA(IMAX-1))*B22D(IMAX-1)Y2 = SIN(THETA(IMAX-1))*B12BULGE + COS(THETA(IMAX-1))*B22BULGE*PHI(IMAX-1) = ATAN2( ABS(X1), SQRT(Y1**2+Y2**2) )** Chase bulges from B12(IMAX-1,IMAX) and B22(IMAX-1,IMAX)*RESTART12 = B12D(IMAX-1)**2 + B12BULGE**2 .LE. THRESH**2RESTART22 = B22D(IMAX-1)**2 + B22BULGE**2 .LE. THRESH**2*IF( .NOT. RESTART12 .AND. .NOT. RESTART22 ) THENCALL DLARTGP( Y2, Y1, WORK(IV2TSN+IMAX-1-1),$ WORK(IV2TCS+IMAX-1-1), R )ELSE IF( .NOT. RESTART12 .AND. RESTART22 ) THENCALL DLARTGP( B12BULGE, B12D(IMAX-1), WORK(IV2TSN+IMAX-1-1),$ WORK(IV2TCS+IMAX-1-1), R )ELSE IF( RESTART12 .AND. .NOT. RESTART22 ) THENCALL DLARTGP( B22BULGE, B22D(IMAX-1), WORK(IV2TSN+IMAX-1-1),$ WORK(IV2TCS+IMAX-1-1), R )ELSE IF( NU .LT. MU ) THENCALL DLARTGS( B12E(IMAX-1), B12D(IMAX), NU,$ WORK(IV2TCS+IMAX-1-1), WORK(IV2TSN+IMAX-1-1) )ELSECALL DLARTGS( B22E(IMAX-1), B22D(IMAX), MU,$ WORK(IV2TCS+IMAX-1-1), WORK(IV2TSN+IMAX-1-1) )END IF*TEMP = WORK(IV2TCS+IMAX-1-1)*B12E(IMAX-1) +$ WORK(IV2TSN+IMAX-1-1)*B12D(IMAX)B12D(IMAX) = WORK(IV2TCS+IMAX-1-1)*B12D(IMAX) -$ WORK(IV2TSN+IMAX-1-1)*B12E(IMAX-1)B12E(IMAX-1) = TEMPTEMP = WORK(IV2TCS+IMAX-1-1)*B22E(IMAX-1) +$ WORK(IV2TSN+IMAX-1-1)*B22D(IMAX)B22D(IMAX) = WORK(IV2TCS+IMAX-1-1)*B22D(IMAX) -$ WORK(IV2TSN+IMAX-1-1)*B22E(IMAX-1)B22E(IMAX-1) = TEMP** Update singular vectors*IF( WANTU1 ) THENIF( COLMAJOR ) THENCALL DLASR( 'R', 'V', 'F', P, IMAX-IMIN+1,$ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1),$ U1(1,IMIN), LDU1 )ELSECALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, P,$ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1),$ U1(IMIN,1), LDU1 )END IFEND IFIF( WANTU2 ) THENIF( COLMAJOR ) THENCALL DLASR( 'R', 'V', 'F', M-P, IMAX-IMIN+1,$ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1),$ U2(1,IMIN), LDU2 )ELSECALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, M-P,$ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1),$ U2(IMIN,1), LDU2 )END IFEND IFIF( WANTV1T ) THENIF( COLMAJOR ) THENCALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, Q,$ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1),$ V1T(IMIN,1), LDV1T )ELSECALL DLASR( 'R', 'V', 'F', Q, IMAX-IMIN+1,$ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1),$ V1T(1,IMIN), LDV1T )END IFEND IFIF( WANTV2T ) THENIF( COLMAJOR ) THENCALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, M-Q,$ WORK(IV2TCS+IMIN-1), WORK(IV2TSN+IMIN-1),$ V2T(IMIN,1), LDV2T )ELSECALL DLASR( 'R', 'V', 'F', M-Q, IMAX-IMIN+1,$ WORK(IV2TCS+IMIN-1), WORK(IV2TSN+IMIN-1),$ V2T(1,IMIN), LDV2T )END IFEND IF** Fix signs on B11(IMAX-1,IMAX) and B21(IMAX-1,IMAX)*IF( B11E(IMAX-1)+B21E(IMAX-1) .GT. 0 ) THENB11D(IMAX) = -B11D(IMAX)B21D(IMAX) = -B21D(IMAX)IF( WANTV1T ) THENIF( COLMAJOR ) THENCALL DSCAL( Q, NEGONE, V1T(IMAX,1), LDV1T )ELSECALL DSCAL( Q, NEGONE, V1T(1,IMAX), 1 )END IFEND IFEND IF** Compute THETA(IMAX)*X1 = COS(PHI(IMAX-1))*B11D(IMAX) +$ SIN(PHI(IMAX-1))*B12E(IMAX-1)Y1 = COS(PHI(IMAX-1))*B21D(IMAX) +$ SIN(PHI(IMAX-1))*B22E(IMAX-1)*THETA(IMAX) = ATAN2( ABS(Y1), ABS(X1) )** Fix signs on B11(IMAX,IMAX), B12(IMAX,IMAX-1), B21(IMAX,IMAX),* and B22(IMAX,IMAX-1)*IF( B11D(IMAX)+B12E(IMAX-1) .LT. 0 ) THENB12D(IMAX) = -B12D(IMAX)IF( WANTU1 ) THENIF( COLMAJOR ) THENCALL DSCAL( P, NEGONE, U1(1,IMAX), 1 )ELSECALL DSCAL( P, NEGONE, U1(IMAX,1), LDU1 )END IFEND IFEND IFIF( B21D(IMAX)+B22E(IMAX-1) .GT. 0 ) THENB22D(IMAX) = -B22D(IMAX)IF( WANTU2 ) THENIF( COLMAJOR ) THENCALL DSCAL( M-P, NEGONE, U2(1,IMAX), 1 )ELSECALL DSCAL( M-P, NEGONE, U2(IMAX,1), LDU2 )END IFEND IFEND IF** Fix signs on B12(IMAX,IMAX) and B22(IMAX,IMAX)*IF( B12D(IMAX)+B22D(IMAX) .LT. 0 ) THENIF( WANTV2T ) THENIF( COLMAJOR ) THENCALL DSCAL( M-Q, NEGONE, V2T(IMAX,1), LDV2T )ELSECALL DSCAL( M-Q, NEGONE, V2T(1,IMAX), 1 )END IFEND IFEND IF** Test for negligible sines or cosines*DO I = IMIN, IMAXIF( THETA(I) .LT. THRESH ) THENTHETA(I) = ZEROELSE IF( THETA(I) .GT. PIOVER2-THRESH ) THENTHETA(I) = PIOVER2END IFEND DODO I = IMIN, IMAX-1IF( PHI(I) .LT. THRESH ) THENPHI(I) = ZEROELSE IF( PHI(I) .GT. PIOVER2-THRESH ) THENPHI(I) = PIOVER2END IFEND DO** Deflate*IF (IMAX .GT. 1) THENDO WHILE( PHI(IMAX-1) .EQ. ZERO )IMAX = IMAX - 1IF (IMAX .LE. 1) EXITEND DOEND IFIF( IMIN .GT. IMAX - 1 )$ IMIN = IMAX - 1IF (IMIN .GT. 1) THENDO WHILE (PHI(IMIN-1) .NE. ZERO)IMIN = IMIN - 1IF (IMIN .LE. 1) EXITEND DOEND IF** Repeat main iteration loop*END DO** Postprocessing: order THETA from least to greatest*DO I = 1, Q*MINI = ITHETAMIN = THETA(I)DO J = I+1, QIF( THETA(J) .LT. THETAMIN ) THENMINI = JTHETAMIN = THETA(J)END IFEND DO*IF( MINI .NE. I ) THENTHETA(MINI) = THETA(I)THETA(I) = THETAMINIF( COLMAJOR ) THENIF( WANTU1 )$ CALL DSWAP( P, U1(1,I), 1, U1(1,MINI), 1 )IF( WANTU2 )$ CALL DSWAP( M-P, U2(1,I), 1, U2(1,MINI), 1 )IF( WANTV1T )$ CALL DSWAP( Q, V1T(I,1), LDV1T, V1T(MINI,1), LDV1T )IF( WANTV2T )$ CALL DSWAP( M-Q, V2T(I,1), LDV2T, V2T(MINI,1),$ LDV2T )ELSEIF( WANTU1 )$ CALL DSWAP( P, U1(I,1), LDU1, U1(MINI,1), LDU1 )IF( WANTU2 )$ CALL DSWAP( M-P, U2(I,1), LDU2, U2(MINI,1), LDU2 )IF( WANTV1T )$ CALL DSWAP( Q, V1T(1,I), 1, V1T(1,MINI), 1 )IF( WANTV2T )$ CALL DSWAP( M-Q, V2T(1,I), 1, V2T(1,MINI), 1 )END IFEND IF*END DO*RETURN** End of DBBCSD*END*> \brief \b DBDSDC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DBDSDC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dbdsdc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dbdsdc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dbdsdc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DBDSDC( UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER COMPQ, UPLO* INTEGER INFO, LDU, LDVT, N* ..* .. Array Arguments ..* INTEGER IQ( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), Q( * ), U( LDU, * ),* $ VT( LDVT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DBDSDC computes the singular value decomposition (SVD) of a real*> N-by-N (upper or lower) bidiagonal matrix B: B = U * S * VT,*> using a divide and conquer method, where S is a diagonal matrix*> with non-negative diagonal elements (the singular values of B), and*> U and VT are orthogonal matrices of left and right singular vectors,*> respectively. DBDSDC can be used to compute all singular values,*> and optionally, singular vectors or singular vectors in compact form.*>*> This code makes very mild assumptions about floating point*> arithmetic. It will work on machines with a guard digit in*> add/subtract, or on those binary machines without guard digits*> which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.*> It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none. See DLASD3 for details.*>*> The code currently calls DLASDQ if singular values only are desired.*> However, it can be slightly modified to compute singular values*> using the divide and conquer method.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': B is upper bidiagonal.*> = 'L': B is lower bidiagonal.*> \endverbatim*>*> \param[in] COMPQ*> \verbatim*> COMPQ is CHARACTER*1*> Specifies whether singular vectors are to be computed*> as follows:*> = 'N': Compute singular values only;*> = 'P': Compute singular values and compute singular*> vectors in compact form;*> = 'I': Compute singular values and singular vectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix B. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the bidiagonal matrix B.*> On exit, if INFO=0, the singular values of B.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the elements of E contain the offdiagonal*> elements of the bidiagonal matrix whose SVD is desired.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,N)*> If COMPQ = 'I', then:*> On exit, if INFO = 0, U contains the left singular vectors*> of the bidiagonal matrix.*> For other values of COMPQ, U is not referenced.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= 1.*> If singular vectors are desired, then LDU >= max( 1, N ).*> \endverbatim*>*> \param[out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT,N)*> If COMPQ = 'I', then:*> On exit, if INFO = 0, VT**T contains the right singular*> vectors of the bidiagonal matrix.*> For other values of COMPQ, VT is not referenced.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT. LDVT >= 1.*> If singular vectors are desired, then LDVT >= max( 1, N ).*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ)*> If COMPQ = 'P', then:*> On exit, if INFO = 0, Q and IQ contain the left*> and right singular vectors in a compact form,*> requiring O(N log N) space instead of 2*N**2.*> In particular, Q contains all the DOUBLE PRECISION data in*> LDQ >= N*(11 + 2*SMLSIZ + 8*INT(LOG_2(N/(SMLSIZ+1))))*> words of memory, where SMLSIZ is returned by ILAENV and*> is equal to the maximum size of the subproblems at the*> bottom of the computation tree (usually about 25).*> For other values of COMPQ, Q is not referenced.*> \endverbatim*>*> \param[out] IQ*> \verbatim*> IQ is INTEGER array, dimension (LDIQ)*> If COMPQ = 'P', then:*> On exit, if INFO = 0, Q and IQ contain the left*> and right singular vectors in a compact form,*> requiring O(N log N) space instead of 2*N**2.*> In particular, IQ contains all INTEGER data in*> LDIQ >= N*(3 + 3*INT(LOG_2(N/(SMLSIZ+1))))*> words of memory, where SMLSIZ is returned by ILAENV and*> is equal to the maximum size of the subproblems at the*> bottom of the computation tree (usually about 25).*> For other values of COMPQ, IQ is not referenced.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> If COMPQ = 'N' then LWORK >= (4 * N).*> If COMPQ = 'P' then LWORK >= (6 * N).*> If COMPQ = 'I' then LWORK >= (3 * N**2 + 4 * N).*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (8*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: The algorithm failed to compute a singular value.*> The update process of divide and conquer failed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DBDSDC( UPLO, COMPQ, N, D, E, U, LDU, VT, LDVT, Q, IQ,$ WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER COMPQ, UPLOINTEGER INFO, LDU, LDVT, N* ..* .. Array Arguments ..INTEGER IQ( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), Q( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** =====================================================================* Changed dimension statement in comment describing E from (N) to* (N-1). Sven, 17 Feb 05.* =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER DIFL, DIFR, GIVCOL, GIVNUM, GIVPTR, I, IC,$ ICOMPQ, IERR, II, IS, IU, IUPLO, IVT, J, K, KK,$ MLVL, NM1, NSIZE, PERM, POLES, QSTART, SMLSIZ,$ SMLSZP, SQRE, START, WSTART, ZDOUBLE PRECISION CS, EPS, ORGNRM, P, R, SN* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, ILAENV, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DLARTG, DLASCL, DLASD0, DLASDA, DLASDQ,$ DLASET, DLASR, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, SIGN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IUPLO = 0IF( LSAME( UPLO, 'U' ) )$ IUPLO = 1IF( LSAME( UPLO, 'L' ) )$ IUPLO = 2IF( LSAME( COMPQ, 'N' ) ) THENICOMPQ = 0ELSE IF( LSAME( COMPQ, 'P' ) ) THENICOMPQ = 1ELSE IF( LSAME( COMPQ, 'I' ) ) THENICOMPQ = 2ELSEICOMPQ = -1END IFIF( IUPLO.EQ.0 ) THENINFO = -1ELSE IF( ICOMPQ.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ( LDU.LT.1 ) .OR. ( ( ICOMPQ.EQ.2 ) .AND. ( LDU.LT.$ N ) ) ) THENINFO = -7ELSE IF( ( LDVT.LT.1 ) .OR. ( ( ICOMPQ.EQ.2 ) .AND. ( LDVT.LT.$ N ) ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DBDSDC', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNSMLSIZ = ILAENV( 9, 'DBDSDC', ' ', 0, 0, 0, 0 )IF( N.EQ.1 ) THENIF( ICOMPQ.EQ.1 ) THENQ( 1 ) = SIGN( ONE, D( 1 ) )Q( 1+SMLSIZ*N ) = ONEELSE IF( ICOMPQ.EQ.2 ) THENU( 1, 1 ) = SIGN( ONE, D( 1 ) )VT( 1, 1 ) = ONEEND IFD( 1 ) = ABS( D( 1 ) )RETURNEND IFNM1 = N - 1** If matrix lower bidiagonal, rotate to be upper bidiagonal* by applying Givens rotations on the left*WSTART = 1QSTART = 3IF( ICOMPQ.EQ.1 ) THENCALL DCOPY( N, D, 1, Q( 1 ), 1 )CALL DCOPY( N-1, E, 1, Q( N+1 ), 1 )END IFIF( IUPLO.EQ.2 ) THENQSTART = 5IF( ICOMPQ .EQ. 2 ) WSTART = 2*N - 1DO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )IF( ICOMPQ.EQ.1 ) THENQ( I+2*N ) = CSQ( I+3*N ) = SNELSE IF( ICOMPQ.EQ.2 ) THENWORK( I ) = CSWORK( NM1+I ) = -SNEND IF10 CONTINUEEND IF** If ICOMPQ = 0, use DLASDQ to compute the singular values.*IF( ICOMPQ.EQ.0 ) THEN* Ignore WSTART, instead using WORK( 1 ), since the two vectors* for CS and -SN above are added only if ICOMPQ == 2,* and adding them exceeds documented WORK size of 4*n.CALL DLASDQ( 'U', 0, N, 0, 0, 0, D, E, VT, LDVT, U, LDU, U,$ LDU, WORK( 1 ), INFO )GO TO 40END IF** If N is smaller than the minimum divide size SMLSIZ, then solve* the problem with another solver.*IF( N.LE.SMLSIZ ) THENIF( ICOMPQ.EQ.2 ) THENCALL DLASET( 'A', N, N, ZERO, ONE, U, LDU )CALL DLASET( 'A', N, N, ZERO, ONE, VT, LDVT )CALL DLASDQ( 'U', 0, N, N, N, 0, D, E, VT, LDVT, U, LDU, U,$ LDU, WORK( WSTART ), INFO )ELSE IF( ICOMPQ.EQ.1 ) THENIU = 1IVT = IU + NCALL DLASET( 'A', N, N, ZERO, ONE, Q( IU+( QSTART-1 )*N ),$ N )CALL DLASET( 'A', N, N, ZERO, ONE, Q( IVT+( QSTART-1 )*N ),$ N )CALL DLASDQ( 'U', 0, N, N, N, 0, D, E,$ Q( IVT+( QSTART-1 )*N ), N,$ Q( IU+( QSTART-1 )*N ), N,$ Q( IU+( QSTART-1 )*N ), N, WORK( WSTART ),$ INFO )END IFGO TO 40END IF*IF( ICOMPQ.EQ.2 ) THENCALL DLASET( 'A', N, N, ZERO, ONE, U, LDU )CALL DLASET( 'A', N, N, ZERO, ONE, VT, LDVT )END IF** Scale.*ORGNRM = DLANST( 'M', N, D, E )IF( ORGNRM.EQ.ZERO )$ RETURNCALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, IERR )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, IERR )*EPS = (0.9D+0)*DLAMCH( 'Epsilon' )*MLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1SMLSZP = SMLSIZ + 1*IF( ICOMPQ.EQ.1 ) THENIU = 1IVT = 1 + SMLSIZDIFL = IVT + SMLSZPDIFR = DIFL + MLVLZ = DIFR + MLVL*2IC = Z + MLVLIS = IC + 1POLES = IS + 1GIVNUM = POLES + 2*MLVL*K = 1GIVPTR = 2PERM = 3GIVCOL = PERM + MLVLEND IF*DO 20 I = 1, NIF( ABS( D( I ) ).LT.EPS ) THEND( I ) = SIGN( EPS, D( I ) )END IF20 CONTINUE*START = 1SQRE = 0*DO 30 I = 1, NM1IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THEN** Subproblem found. First determine its size and then* apply divide and conquer on it.*IF( I.LT.NM1 ) THEN** A subproblem with E(I) small for I < NM1.*NSIZE = I - START + 1ELSE IF( ABS( E( I ) ).GE.EPS ) THEN** A subproblem with E(NM1) not too small but I = NM1.*NSIZE = N - START + 1ELSE** A subproblem with E(NM1) small. This implies an* 1-by-1 subproblem at D(N). Solve this 1-by-1 problem* first.*NSIZE = I - START + 1IF( ICOMPQ.EQ.2 ) THENU( N, N ) = SIGN( ONE, D( N ) )VT( N, N ) = ONEELSE IF( ICOMPQ.EQ.1 ) THENQ( N+( QSTART-1 )*N ) = SIGN( ONE, D( N ) )Q( N+( SMLSIZ+QSTART-1 )*N ) = ONEEND IFD( N ) = ABS( D( N ) )END IFIF( ICOMPQ.EQ.2 ) THENCALL DLASD0( NSIZE, SQRE, D( START ), E( START ),$ U( START, START ), LDU, VT( START, START ),$ LDVT, SMLSIZ, IWORK, WORK( WSTART ), INFO )ELSECALL DLASDA( ICOMPQ, SMLSIZ, NSIZE, SQRE, D( START ),$ E( START ), Q( START+( IU+QSTART-2 )*N ), N,$ Q( START+( IVT+QSTART-2 )*N ),$ IQ( START+K*N ), Q( START+( DIFL+QSTART-2 )*$ N ), Q( START+( DIFR+QSTART-2 )*N ),$ Q( START+( Z+QSTART-2 )*N ),$ Q( START+( POLES+QSTART-2 )*N ),$ IQ( START+GIVPTR*N ), IQ( START+GIVCOL*N ),$ N, IQ( START+PERM*N ),$ Q( START+( GIVNUM+QSTART-2 )*N ),$ Q( START+( IC+QSTART-2 )*N ),$ Q( START+( IS+QSTART-2 )*N ),$ WORK( WSTART ), IWORK, INFO )END IFIF( INFO.NE.0 ) THENRETURNEND IFSTART = I + 1END IF30 CONTINUE** Unscale*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, IERR )40 CONTINUE** Use Selection Sort to minimize swaps of singular vectors*DO 60 II = 2, NI = II - 1KK = IP = D( I )DO 50 J = II, NIF( D( J ).GT.P ) THENKK = JP = D( J )END IF50 CONTINUEIF( KK.NE.I ) THEND( KK ) = D( I )D( I ) = PIF( ICOMPQ.EQ.1 ) THENIQ( I ) = KKELSE IF( ICOMPQ.EQ.2 ) THENCALL DSWAP( N, U( 1, I ), 1, U( 1, KK ), 1 )CALL DSWAP( N, VT( I, 1 ), LDVT, VT( KK, 1 ), LDVT )END IFELSE IF( ICOMPQ.EQ.1 ) THENIQ( I ) = IEND IF60 CONTINUE** If ICOMPQ = 1, use IQ(N,1) as the indicator for UPLO*IF( ICOMPQ.EQ.1 ) THENIF( IUPLO.EQ.1 ) THENIQ( N ) = 1ELSEIQ( N ) = 0END IFEND IF** If B is lower bidiagonal, update U by those Givens rotations* which rotated B to be upper bidiagonal*IF( ( IUPLO.EQ.2 ) .AND. ( ICOMPQ.EQ.2 ) )$ CALL DLASR( 'L', 'V', 'B', N, N, WORK( 1 ), WORK( N ), U, LDU )*RETURN** End of DBDSDC*END*> \brief \b DBDSQR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DBDSQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dbdsqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dbdsqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dbdsqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,* LDU, C, LDC, WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),* $ VT( LDVT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DBDSQR computes the singular values and, optionally, the right and/or*> left singular vectors from the singular value decomposition (SVD) of*> a real N-by-N (upper or lower) bidiagonal matrix B using the implicit*> zero-shift QR algorithm. The SVD of B has the form*>*> B = Q * S * P**T*>*> where S is the diagonal matrix of singular values, Q is an orthogonal*> matrix of left singular vectors, and P is an orthogonal matrix of*> right singular vectors. If left singular vectors are requested, this*> subroutine actually returns U*Q instead of Q, and, if right singular*> vectors are requested, this subroutine returns P**T*VT instead of*> P**T, for given real input matrices U and VT. When U and VT are the*> orthogonal matrices that reduce a general matrix A to bidiagonal*> form: A = U*B*VT, as computed by DGEBRD, then*>*> A = (U*Q) * S * (P**T*VT)*>*> is the SVD of A. Optionally, the subroutine may also compute Q**T*C*> for a given real input matrix C.*>*> See "Computing Small Singular Values of Bidiagonal Matrices With*> Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,*> LAPACK Working Note #3 (or SIAM J. Sci. Statist. Comput. vol. 11,*> no. 5, pp. 873-912, Sept 1990) and*> "Accurate singular values and differential qd algorithms," by*> B. Parlett and V. Fernando, Technical Report CPAM-554, Mathematics*> Department, University of California at Berkeley, July 1992*> for a detailed description of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': B is upper bidiagonal;*> = 'L': B is lower bidiagonal.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix B. N >= 0.*> \endverbatim*>*> \param[in] NCVT*> \verbatim*> NCVT is INTEGER*> The number of columns of the matrix VT. NCVT >= 0.*> \endverbatim*>*> \param[in] NRU*> \verbatim*> NRU is INTEGER*> The number of rows of the matrix U. NRU >= 0.*> \endverbatim*>*> \param[in] NCC*> \verbatim*> NCC is INTEGER*> The number of columns of the matrix C. NCC >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the bidiagonal matrix B.*> On exit, if INFO=0, the singular values of B in decreasing*> order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the N-1 offdiagonal elements of the bidiagonal*> matrix B.*> On exit, if INFO = 0, E is destroyed; if INFO > 0, D and E*> will contain the diagonal and superdiagonal elements of a*> bidiagonal matrix orthogonally equivalent to the one given*> as input.*> \endverbatim*>*> \param[in,out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT, NCVT)*> On entry, an N-by-NCVT matrix VT.*> On exit, VT is overwritten by P**T * VT.*> Not referenced if NCVT = 0.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT.*> LDVT >= max(1,N) if NCVT > 0; LDVT >= 1 if NCVT = 0.*> \endverbatim*>*> \param[in,out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU, N)*> On entry, an NRU-by-N matrix U.*> On exit, U is overwritten by U * Q.*> Not referenced if NRU = 0.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= max(1,NRU).*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC, NCC)*> On entry, an N-by-NCC matrix C.*> On exit, C is overwritten by Q**T * C.*> Not referenced if NCC = 0.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C.*> LDC >= max(1,N) if NCC > 0; LDC >=1 if NCC = 0.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: If INFO = -i, the i-th argument had an illegal value*> > 0:*> if NCVT = NRU = NCC = 0,*> = 1, a split was marked by a positive value in E*> = 2, current block of Z not diagonalized after 30*N*> iterations (in inner while loop)*> = 3, termination criterion of outer while loop not met*> (program created more than N unreduced blocks)*> else NCVT = NRU = NCC = 0,*> the algorithm did not converge; D and E contain the*> elements of a bidiagonal matrix which is orthogonally*> similar to the input matrix B; if INFO = i, i*> elements of E have not converged to zero.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> TOLMUL DOUBLE PRECISION, default = max(10,min(100,EPS**(-1/8)))*> TOLMUL controls the convergence criterion of the QR loop.*> If it is positive, TOLMUL*EPS is the desired relative*> precision in the computed singular values.*> If it is negative, abs(TOLMUL*EPS*sigma_max) is the*> desired absolute accuracy in the computed singular*> values (corresponds to relative accuracy*> abs(TOLMUL*EPS) in the largest singular value.*> abs(TOLMUL) should be between 1 and 1/EPS, and preferably*> between 10 (for fast convergence) and .1/EPS*> (for there to be some accuracy in the results).*> Default is to lose at either one eighth or 2 of the*> available decimal digits in each computed singular value*> (whichever is smaller).*>*> MAXITR INTEGER, default = 6*> MAXITR controls the maximum number of passes of the*> algorithm through its inner loop. The algorithms stops*> (and so fails to converge) if the number of passes*> through the inner loop exceeds MAXITR*N**2.*>*> \endverbatim**> \par Note:* ===========*>*> \verbatim*> Bug report from Cezary Dendek.*> On March 23rd 2017, the INTEGER variable MAXIT = MAXITR*N**2 is*> removed since it can overflow pretty easily (for N larger or equal*> than 18,919). We instead use MAXITDIVN = MAXITR*N.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,$ LDU, C, LDC, WORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION NEGONEPARAMETER ( NEGONE = -1.0D0 )DOUBLE PRECISION HNDRTHPARAMETER ( HNDRTH = 0.01D0 )DOUBLE PRECISION TENPARAMETER ( TEN = 10.0D0 )DOUBLE PRECISION HNDRDPARAMETER ( HNDRD = 100.0D0 )DOUBLE PRECISION MEIGTHPARAMETER ( MEIGTH = -0.125D0 )INTEGER MAXITRPARAMETER ( MAXITR = 6 )* ..* .. Local Scalars ..LOGICAL LOWER, ROTATEINTEGER I, IDIR, ISUB, ITER, ITERDIVN, J, LL, LLL, M,$ MAXITDIVN, NM1, NM12, NM13, OLDLL, OLDMDOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,$ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,$ SINR, SLL, SMAX, SMIN, SMINL, SMINOA,$ SN, THRESH, TOL, TOLMUL, UNFL* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLARTG, DLAS2, DLASQ1, DLASR, DLASV2, DROT,$ DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0LOWER = LSAME( UPLO, 'L' )IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NCVT.LT.0 ) THENINFO = -3ELSE IF( NRU.LT.0 ) THENINFO = -4ELSE IF( NCC.LT.0 ) THENINFO = -5ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.$ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THENINFO = -9ELSE IF( LDU.LT.MAX( 1, NRU ) ) THENINFO = -11ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.$ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DBDSQR', -INFO )RETURNEND IFIF( N.EQ.0 )$ RETURNIF( N.EQ.1 )$ GO TO 160** ROTATE is true if any singular vectors desired, false otherwise*ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )** If no singular vectors desired, use qd algorithm*IF( .NOT.ROTATE ) THENCALL DLASQ1( N, D, E, WORK, INFO )** If INFO equals 2, dqds didn't finish, try to finish*IF( INFO .NE. 2 ) RETURNINFO = 0END IF*NM1 = N - 1NM12 = NM1 + NM1NM13 = NM12 + NM1IDIR = 0** Get machine constants*EPS = DLAMCH( 'Epsilon' )UNFL = DLAMCH( 'Safe minimum' )** If matrix lower bidiagonal, rotate to be upper bidiagonal* by applying Givens rotations on the left*IF( LOWER ) THENDO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )WORK( I ) = CSWORK( NM1+I ) = SN10 CONTINUE** Update singular vectors if desired*IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ), WORK( N ), U,$ LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ), WORK( N ), C,$ LDC )END IF** Compute singular values to relative accuracy TOL* (By setting TOL to be negative, algorithm will compute* singular values to absolute accuracy ABS(TOL)*norm(input matrix))*TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )TOL = TOLMUL*EPS** Compute approximate maximum, minimum singular values*SMAX = ZERODO 20 I = 1, NSMAX = MAX( SMAX, ABS( D( I ) ) )20 CONTINUEDO 30 I = 1, N - 1SMAX = MAX( SMAX, ABS( E( I ) ) )30 CONTINUESMINL = ZEROIF( TOL.GE.ZERO ) THEN** Relative accuracy desired*SMINOA = ABS( D( 1 ) )IF( SMINOA.EQ.ZERO )$ GO TO 50MU = SMINOADO 40 I = 2, NMU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )SMINOA = MIN( SMINOA, MU )IF( SMINOA.EQ.ZERO )$ GO TO 5040 CONTINUE50 CONTINUESMINOA = SMINOA / SQRT( DBLE( N ) )THRESH = MAX( TOL*SMINOA, MAXITR*(N*(N*UNFL)) )ELSE** Absolute accuracy desired*THRESH = MAX( ABS( TOL )*SMAX, MAXITR*(N*(N*UNFL)) )END IF** Prepare for main iteration loop for the singular values* (MAXIT is the maximum number of passes through the inner* loop permitted before nonconvergence signalled.)*MAXITDIVN = MAXITR*NITERDIVN = 0ITER = -1OLDLL = -1OLDM = -1** M points to last element of unconverged part of matrix*M = N** Begin main iteration loop*60 CONTINUE** Check for convergence or exceeding iteration count*IF( M.LE.1 )$ GO TO 160*IF( ITER.GE.N ) THENITER = ITER - NITERDIVN = ITERDIVN + 1IF( ITERDIVN.GE.MAXITDIVN )$ GO TO 200END IF** Find diagonal block of matrix to work on*IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )$ D( M ) = ZEROSMAX = ABS( D( M ) )SMIN = SMAXDO 70 LLL = 1, M - 1LL = M - LLLABSS = ABS( D( LL ) )ABSE = ABS( E( LL ) )IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )$ D( LL ) = ZEROIF( ABSE.LE.THRESH )$ GO TO 80SMIN = MIN( SMIN, ABSS )SMAX = MAX( SMAX, ABSS, ABSE )70 CONTINUELL = 0GO TO 9080 CONTINUEE( LL ) = ZERO** Matrix splits since E(LL) = 0*IF( LL.EQ.M-1 ) THEN** Convergence of bottom singular value, return to top of loop*M = M - 1GO TO 60END IF90 CONTINUELL = LL + 1** E(LL) through E(M-1) are nonzero, E(LL-1) is zero*IF( LL.EQ.M-1 ) THEN** 2 by 2 block, handle separately*CALL DLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,$ COSR, SINL, COSL )D( M-1 ) = SIGMXE( M-1 ) = ZEROD( M ) = SIGMN** Compute singular vectors, if desired*IF( NCVT.GT.0 )$ CALL DROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT, COSR,$ SINR )IF( NRU.GT.0 )$ CALL DROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )IF( NCC.GT.0 )$ CALL DROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,$ SINL )M = M - 2GO TO 60END IF** If working on new submatrix, choose shift direction* (from larger end diagonal element towards smaller)*IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THENIF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN** Chase bulge from top (big end) to bottom (small end)*IDIR = 1ELSE** Chase bulge from bottom (big end) to top (small end)*IDIR = 2END IFEND IF** Apply convergence tests*IF( IDIR.EQ.1 ) THEN** Run convergence test in forward direction* First apply standard test to bottom of matrix*IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.$ ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THENE( M-1 ) = ZEROGO TO 60END IF*IF( TOL.GE.ZERO ) THEN** If relative accuracy desired,* apply convergence criterion forward*MU = ABS( D( LL ) )SMINL = MUDO 100 LLL = LL, M - 1IF( ABS( E( LLL ) ).LE.TOL*MU ) THENE( LLL ) = ZEROGO TO 60END IFMU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )SMINL = MIN( SMINL, MU )100 CONTINUEEND IF*ELSE** Run convergence test in backward direction* First apply standard test to top of matrix*IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.$ ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THENE( LL ) = ZEROGO TO 60END IF*IF( TOL.GE.ZERO ) THEN** If relative accuracy desired,* apply convergence criterion backward*MU = ABS( D( M ) )SMINL = MUDO 110 LLL = M - 1, LL, -1IF( ABS( E( LLL ) ).LE.TOL*MU ) THENE( LLL ) = ZEROGO TO 60END IFMU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )SMINL = MIN( SMINL, MU )110 CONTINUEEND IFEND IFOLDLL = LLOLDM = M** Compute shift. First, test if shifting would ruin relative* accuracy, and if so set the shift to zero.*IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.$ MAX( EPS, HNDRTH*TOL ) ) THEN** Use a zero shift to avoid loss of relative accuracy*SHIFT = ZEROELSE** Compute the shift from 2-by-2 block at end of matrix*IF( IDIR.EQ.1 ) THENSLL = ABS( D( LL ) )CALL DLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )ELSESLL = ABS( D( M ) )CALL DLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )END IF** Test if shift negligible, and if so set to zero*IF( SLL.GT.ZERO ) THENIF( ( SHIFT / SLL )**2.LT.EPS )$ SHIFT = ZEROEND IFEND IF** Increment iteration count*ITER = ITER + M - LL** If SHIFT = 0, do simplified QR iteration*IF( SHIFT.EQ.ZERO ) THENIF( IDIR.EQ.1 ) THEN** Chase bulge from top to bottom* Save cosines and sines for later singular vector updates*CS = ONEOLDCS = ONEDO 120 I = LL, M - 1CALL DLARTG( D( I )*CS, E( I ), CS, SN, R )IF( I.GT.LL )$ E( I-1 ) = OLDSN*RCALL DLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )WORK( I-LL+1 ) = CSWORK( I-LL+1+NM1 ) = SNWORK( I-LL+1+NM12 ) = OLDCSWORK( I-LL+1+NM13 ) = OLDSN120 CONTINUEH = D( M )*CSD( M ) = H*OLDCSE( M-1 ) = H*OLDSN** Update singular vectors*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),$ WORK( N ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),$ WORK( NM13+1 ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),$ WORK( NM13+1 ), C( LL, 1 ), LDC )** Test convergence*IF( ABS( E( M-1 ) ).LE.THRESH )$ E( M-1 ) = ZERO*ELSE** Chase bulge from bottom to top* Save cosines and sines for later singular vector updates*CS = ONEOLDCS = ONEDO 130 I = M, LL + 1, -1CALL DLARTG( D( I )*CS, E( I-1 ), CS, SN, R )IF( I.LT.M )$ E( I ) = OLDSN*RCALL DLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )WORK( I-LL ) = CSWORK( I-LL+NM1 ) = -SNWORK( I-LL+NM12 ) = OLDCSWORK( I-LL+NM13 ) = -OLDSN130 CONTINUEH = D( LL )*CSD( LL ) = H*OLDCSE( LL ) = H*OLDSN** Update singular vectors*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),$ WORK( NM13+1 ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),$ WORK( N ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),$ WORK( N ), C( LL, 1 ), LDC )** Test convergence*IF( ABS( E( LL ) ).LE.THRESH )$ E( LL ) = ZEROEND IFELSE** Use nonzero shift*IF( IDIR.EQ.1 ) THEN** Chase bulge from top to bottom* Save cosines and sines for later singular vector updates*F = ( ABS( D( LL ) )-SHIFT )*$ ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )G = E( LL )DO 140 I = LL, M - 1CALL DLARTG( F, G, COSR, SINR, R )IF( I.GT.LL )$ E( I-1 ) = RF = COSR*D( I ) + SINR*E( I )E( I ) = COSR*E( I ) - SINR*D( I )G = SINR*D( I+1 )D( I+1 ) = COSR*D( I+1 )CALL DLARTG( F, G, COSL, SINL, R )D( I ) = RF = COSL*E( I ) + SINL*D( I+1 )D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )IF( I.LT.M-1 ) THENG = SINL*E( I+1 )E( I+1 ) = COSL*E( I+1 )END IFWORK( I-LL+1 ) = COSRWORK( I-LL+1+NM1 ) = SINRWORK( I-LL+1+NM12 ) = COSLWORK( I-LL+1+NM13 ) = SINL140 CONTINUEE( M-1 ) = F** Update singular vectors*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCVT, WORK( 1 ),$ WORK( N ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'F', NRU, M-LL+1, WORK( NM12+1 ),$ WORK( NM13+1 ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'F', M-LL+1, NCC, WORK( NM12+1 ),$ WORK( NM13+1 ), C( LL, 1 ), LDC )** Test convergence*IF( ABS( E( M-1 ) ).LE.THRESH )$ E( M-1 ) = ZERO*ELSE** Chase bulge from bottom to top* Save cosines and sines for later singular vector updates*F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /$ D( M ) )G = E( M-1 )DO 150 I = M, LL + 1, -1CALL DLARTG( F, G, COSR, SINR, R )IF( I.LT.M )$ E( I ) = RF = COSR*D( I ) + SINR*E( I-1 )E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )G = SINR*D( I-1 )D( I-1 ) = COSR*D( I-1 )CALL DLARTG( F, G, COSL, SINL, R )D( I ) = RF = COSL*E( I-1 ) + SINL*D( I-1 )D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )IF( I.GT.LL+1 ) THENG = SINL*E( I-2 )E( I-2 ) = COSL*E( I-2 )END IFWORK( I-LL ) = COSRWORK( I-LL+NM1 ) = -SINRWORK( I-LL+NM12 ) = COSLWORK( I-LL+NM13 ) = -SINL150 CONTINUEE( LL ) = F** Test convergence*IF( ABS( E( LL ) ).LE.THRESH )$ E( LL ) = ZERO** Update singular vectors if desired*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCVT, WORK( NM12+1 ),$ WORK( NM13+1 ), VT( LL, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DLASR( 'R', 'V', 'B', NRU, M-LL+1, WORK( 1 ),$ WORK( N ), U( 1, LL ), LDU )IF( NCC.GT.0 )$ CALL DLASR( 'L', 'V', 'B', M-LL+1, NCC, WORK( 1 ),$ WORK( N ), C( LL, 1 ), LDC )END IFEND IF** QR iteration finished, go back and check convergence*GO TO 60** All singular values converged, so make them positive*160 CONTINUEDO 170 I = 1, NIF( D( I ).LT.ZERO ) THEND( I ) = -D( I )** Change sign of singular vectors, if desired*IF( NCVT.GT.0 )$ CALL DSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )END IF170 CONTINUE** Sort the singular values into decreasing order (insertion sort on* singular values, but only one transposition per singular vector)*DO 190 I = 1, N - 1** Scan for smallest D(I)*ISUB = 1SMIN = D( 1 )DO 180 J = 2, N + 1 - IIF( D( J ).LE.SMIN ) THENISUB = JSMIN = D( J )END IF180 CONTINUEIF( ISUB.NE.N+1-I ) THEN** Swap singular values and vectors*D( ISUB ) = D( N+1-I )D( N+1-I ) = SMINIF( NCVT.GT.0 )$ CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),$ LDVT )IF( NRU.GT.0 )$ CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )IF( NCC.GT.0 )$ CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )END IF190 CONTINUEGO TO 220** Maximum number of iterations exceeded, failure to converge*200 CONTINUEINFO = 0DO 210 I = 1, N - 1IF( E( I ).NE.ZERO )$ INFO = INFO + 1210 CONTINUE220 CONTINUERETURN** End of DBDSQR*END*> \brief \b DDISNA** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DDISNA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ddisna.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ddisna.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ddisna.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DDISNA( JOB, M, N, D, SEP, INFO )** .. Scalar Arguments ..* CHARACTER JOB* INTEGER INFO, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), SEP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DDISNA computes the reciprocal condition numbers for the eigenvectors*> of a real symmetric or complex Hermitian matrix or for the left or*> right singular vectors of a general m-by-n matrix. The reciprocal*> condition number is the 'gap' between the corresponding eigenvalue or*> singular value and the nearest other one.*>*> The bound on the error, measured by angle in radians, in the I-th*> computed vector is given by*>*> DLAMCH( 'E' ) * ( ANORM / SEP( I ) )*>*> where ANORM = 2-norm(A) = max( abs( D(j) ) ). SEP(I) is not allowed*> to be smaller than DLAMCH( 'E' )*ANORM in order to limit the size of*> the error bound.*>*> DDISNA may also be used to compute error bounds for eigenvectors of*> the generalized symmetric definite eigenproblem.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies for which problem the reciprocal condition numbers*> should be computed:*> = 'E': the eigenvectors of a symmetric/Hermitian matrix;*> = 'L': the left singular vectors of a general matrix;*> = 'R': the right singular vectors of a general matrix.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> If JOB = 'L' or 'R', the number of columns of the matrix,*> in which case N >= 0. Ignored if JOB = 'E'.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (M) if JOB = 'E'*> dimension (min(M,N)) if JOB = 'L' or 'R'*> The eigenvalues (if JOB = 'E') or singular values (if JOB =*> 'L' or 'R') of the matrix, in either increasing or decreasing*> order. If singular values, they must be non-negative.*> \endverbatim*>*> \param[out] SEP*> \verbatim*> SEP is DOUBLE PRECISION array, dimension (M) if JOB = 'E'*> dimension (min(M,N)) if JOB = 'L' or 'R'*> The reciprocal condition numbers of the vectors.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DDISNA( JOB, M, N, D, SEP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBINTEGER INFO, M, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), SEP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL DECR, EIGEN, INCR, LEFT, RIGHT, SINGINTEGER I, KDOUBLE PRECISION ANORM, EPS, NEWGAP, OLDGAP, SAFMIN, THRESH* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input arguments*INFO = 0EIGEN = LSAME( JOB, 'E' )LEFT = LSAME( JOB, 'L' )RIGHT = LSAME( JOB, 'R' )SING = LEFT .OR. RIGHTIF( EIGEN ) THENK = MELSE IF( SING ) THENK = MIN( M, N )END IFIF( .NOT.EIGEN .AND. .NOT.SING ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( K.LT.0 ) THENINFO = -3ELSEINCR = .TRUE.DECR = .TRUE.DO 10 I = 1, K - 1IF( INCR )$ INCR = INCR .AND. D( I ).LE.D( I+1 )IF( DECR )$ DECR = DECR .AND. D( I ).GE.D( I+1 )10 CONTINUEIF( SING .AND. K.GT.0 ) THENIF( INCR )$ INCR = INCR .AND. ZERO.LE.D( 1 )IF( DECR )$ DECR = DECR .AND. D( K ).GE.ZEROEND IFIF( .NOT.( INCR .OR. DECR ) )$ INFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DDISNA', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.0 )$ RETURN** Compute reciprocal condition numbers*IF( K.EQ.1 ) THENSEP( 1 ) = DLAMCH( 'O' )ELSEOLDGAP = ABS( D( 2 )-D( 1 ) )SEP( 1 ) = OLDGAPDO 20 I = 2, K - 1NEWGAP = ABS( D( I+1 )-D( I ) )SEP( I ) = MIN( OLDGAP, NEWGAP )OLDGAP = NEWGAP20 CONTINUESEP( K ) = OLDGAPEND IFIF( SING ) THENIF( ( LEFT .AND. M.GT.N ) .OR. ( RIGHT .AND. M.LT.N ) ) THENIF( INCR )$ SEP( 1 ) = MIN( SEP( 1 ), D( 1 ) )IF( DECR )$ SEP( K ) = MIN( SEP( K ), D( K ) )END IFEND IF** Ensure that reciprocal condition numbers are not less than* threshold, in order to limit the size of the error bound*EPS = DLAMCH( 'E' )SAFMIN = DLAMCH( 'S' )ANORM = MAX( ABS( D( 1 ) ), ABS( D( K ) ) )IF( ANORM.EQ.ZERO ) THENTHRESH = EPSELSETHRESH = MAX( EPS*ANORM, SAFMIN )END IFDO 30 I = 1, KSEP( I ) = MAX( SEP( I ), THRESH )30 CONTINUE*RETURN** End of DDISNA*END*> \brief \b DGBBRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBBRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbbrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbbrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbbrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBBRD( VECT, M, N, NCC, KL, KU, AB, LDAB, D, E, Q,* LDQ, PT, LDPT, C, LDC, WORK, INFO )** .. Scalar Arguments ..* CHARACTER VECT* INTEGER INFO, KL, KU, LDAB, LDC, LDPT, LDQ, M, N, NCC* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), C( LDC, * ), D( * ), E( * ),* $ PT( LDPT, * ), Q( LDQ, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBBRD reduces a real general m-by-n band matrix A to upper*> bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.*>*> The routine computes B, and optionally forms Q or P**T, or computes*> Q**T*C for a given matrix C.*> \endverbatim** Arguments:* ==========**> \param[in] VECT*> \verbatim*> VECT is CHARACTER*1*> Specifies whether or not the matrices Q and P**T are to be*> formed.*> = 'N': do not form Q or P**T;*> = 'Q': form Q only;*> = 'P': form P**T only;*> = 'B': form both.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NCC*> \verbatim*> NCC is INTEGER*> The number of columns of the matrix C. NCC >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals of the matrix A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals of the matrix A. KU >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the m-by-n band matrix A, stored in rows 1 to*> KL+KU+1. The j-th column of A is stored in the j-th column of*> the array AB as follows:*> AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl).*> On exit, A is overwritten by values generated during the*> reduction.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array A. LDAB >= KL+KU+1.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (min(M,N))*> The diagonal elements of the bidiagonal matrix B.*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (min(M,N)-1)*> The superdiagonal elements of the bidiagonal matrix B.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,M)*> If VECT = 'Q' or 'B', the m-by-m orthogonal matrix Q.*> If VECT = 'N' or 'P', the array Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q.*> LDQ >= max(1,M) if VECT = 'Q' or 'B'; LDQ >= 1 otherwise.*> \endverbatim*>*> \param[out] PT*> \verbatim*> PT is DOUBLE PRECISION array, dimension (LDPT,N)*> If VECT = 'P' or 'B', the n-by-n orthogonal matrix P'.*> If VECT = 'N' or 'Q', the array PT is not referenced.*> \endverbatim*>*> \param[in] LDPT*> \verbatim*> LDPT is INTEGER*> The leading dimension of the array PT.*> LDPT >= max(1,N) if VECT = 'P' or 'B'; LDPT >= 1 otherwise.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,NCC)*> On entry, an m-by-ncc matrix C.*> On exit, C is overwritten by Q**T*C.*> C is not referenced if NCC = 0.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C.*> LDC >= max(1,M) if NCC > 0; LDC >= 1 if NCC = 0.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*max(M,N))*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DGBBRD( VECT, M, N, NCC, KL, KU, AB, LDAB, D, E, Q,$ LDQ, PT, LDPT, C, LDC, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER VECTINTEGER INFO, KL, KU, LDAB, LDC, LDPT, LDQ, M, N, NCC* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), C( LDC, * ), D( * ), E( * ),$ PT( LDPT, * ), Q( LDQ, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL WANTB, WANTC, WANTPT, WANTQINTEGER I, INCA, J, J1, J2, KB, KB1, KK, KLM, KLU1,$ KUN, L, MINMN, ML, ML0, MN, MU, MU0, NR, NRTDOUBLE PRECISION RA, RB, RC, RS* ..* .. External Subroutines ..EXTERNAL DLARGV, DLARTG, DLARTV, DLASET, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Test the input parameters*WANTB = LSAME( VECT, 'B' )WANTQ = LSAME( VECT, 'Q' ) .OR. WANTBWANTPT = LSAME( VECT, 'P' ) .OR. WANTBWANTC = NCC.GT.0KLU1 = KL + KU + 1INFO = 0IF( .NOT.WANTQ .AND. .NOT.WANTPT .AND. .NOT.LSAME( VECT, 'N' ) )$ THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NCC.LT.0 ) THENINFO = -4ELSE IF( KL.LT.0 ) THENINFO = -5ELSE IF( KU.LT.0 ) THENINFO = -6ELSE IF( LDAB.LT.KLU1 ) THENINFO = -8ELSE IF( LDQ.LT.1 .OR. WANTQ .AND. LDQ.LT.MAX( 1, M ) ) THENINFO = -12ELSE IF( LDPT.LT.1 .OR. WANTPT .AND. LDPT.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDC.LT.1 .OR. WANTC .AND. LDC.LT.MAX( 1, M ) ) THENINFO = -16END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBBRD', -INFO )RETURNEND IF** Initialize Q and P**T to the unit matrix, if needed*IF( WANTQ )$ CALL DLASET( 'Full', M, M, ZERO, ONE, Q, LDQ )IF( WANTPT )$ CALL DLASET( 'Full', N, N, ZERO, ONE, PT, LDPT )** Quick return if possible.*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN*MINMN = MIN( M, N )*IF( KL+KU.GT.1 ) THEN** Reduce to upper bidiagonal form if KU > 0; if KU = 0, reduce* first to lower bidiagonal form and then transform to upper* bidiagonal*IF( KU.GT.0 ) THENML0 = 1MU0 = 2ELSEML0 = 2MU0 = 1END IF** Wherever possible, plane rotations are generated and applied in* vector operations of length NR over the index set J1:J2:KLU1.** The sines of the plane rotations are stored in WORK(1:max(m,n))* and the cosines in WORK(max(m,n)+1:2*max(m,n)).*MN = MAX( M, N )KLM = MIN( M-1, KL )KUN = MIN( N-1, KU )KB = KLM + KUNKB1 = KB + 1INCA = KB1*LDABNR = 0J1 = KLM + 2J2 = 1 - KUN*DO 90 I = 1, MINMN** Reduce i-th column and i-th row of matrix to bidiagonal form*ML = KLM + 1MU = KUN + 1DO 80 KK = 1, KBJ1 = J1 + KBJ2 = J2 + KB** generate plane rotations to annihilate nonzero elements* which have been created below the band*IF( NR.GT.0 )$ CALL DLARGV( NR, AB( KLU1, J1-KLM-1 ), INCA,$ WORK( J1 ), KB1, WORK( MN+J1 ), KB1 )** apply plane rotations from the left*DO 10 L = 1, KBIF( J2-KLM+L-1.GT.N ) THENNRT = NR - 1ELSENRT = NREND IFIF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KLU1-L, J1-KLM+L-1 ), INCA,$ AB( KLU1-L+1, J1-KLM+L-1 ), INCA,$ WORK( MN+J1 ), WORK( J1 ), KB1 )10 CONTINUE*IF( ML.GT.ML0 ) THENIF( ML.LE.M-I+1 ) THEN** generate plane rotation to annihilate a(i+ml-1,i)* within the band, and apply rotation from the left*CALL DLARTG( AB( KU+ML-1, I ), AB( KU+ML, I ),$ WORK( MN+I+ML-1 ), WORK( I+ML-1 ),$ RA )AB( KU+ML-1, I ) = RAIF( I.LT.N )$ CALL DROT( MIN( KU+ML-2, N-I ),$ AB( KU+ML-2, I+1 ), LDAB-1,$ AB( KU+ML-1, I+1 ), LDAB-1,$ WORK( MN+I+ML-1 ), WORK( I+ML-1 ) )END IFNR = NR + 1J1 = J1 - KB1END IF*IF( WANTQ ) THEN** accumulate product of plane rotations in Q*DO 20 J = J1, J2, KB1CALL DROT( M, Q( 1, J-1 ), 1, Q( 1, J ), 1,$ WORK( MN+J ), WORK( J ) )20 CONTINUEEND IF*IF( WANTC ) THEN** apply plane rotations to C*DO 30 J = J1, J2, KB1CALL DROT( NCC, C( J-1, 1 ), LDC, C( J, 1 ), LDC,$ WORK( MN+J ), WORK( J ) )30 CONTINUEEND IF*IF( J2+KUN.GT.N ) THEN** adjust J2 to keep within the bounds of the matrix*NR = NR - 1J2 = J2 - KB1END IF*DO 40 J = J1, J2, KB1** create nonzero element a(j-1,j+ku) above the band* and store it in WORK(n+1:2*n)*WORK( J+KUN ) = WORK( J )*AB( 1, J+KUN )AB( 1, J+KUN ) = WORK( MN+J )*AB( 1, J+KUN )40 CONTINUE** generate plane rotations to annihilate nonzero elements* which have been generated above the band*IF( NR.GT.0 )$ CALL DLARGV( NR, AB( 1, J1+KUN-1 ), INCA,$ WORK( J1+KUN ), KB1, WORK( MN+J1+KUN ),$ KB1 )** apply plane rotations from the right*DO 50 L = 1, KBIF( J2+L-1.GT.M ) THENNRT = NR - 1ELSENRT = NREND IFIF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L+1, J1+KUN-1 ), INCA,$ AB( L, J1+KUN ), INCA,$ WORK( MN+J1+KUN ), WORK( J1+KUN ),$ KB1 )50 CONTINUE*IF( ML.EQ.ML0 .AND. MU.GT.MU0 ) THENIF( MU.LE.N-I+1 ) THEN** generate plane rotation to annihilate a(i,i+mu-1)* within the band, and apply rotation from the right*CALL DLARTG( AB( KU-MU+3, I+MU-2 ),$ AB( KU-MU+2, I+MU-1 ),$ WORK( MN+I+MU-1 ), WORK( I+MU-1 ),$ RA )AB( KU-MU+3, I+MU-2 ) = RACALL DROT( MIN( KL+MU-2, M-I ),$ AB( KU-MU+4, I+MU-2 ), 1,$ AB( KU-MU+3, I+MU-1 ), 1,$ WORK( MN+I+MU-1 ), WORK( I+MU-1 ) )END IFNR = NR + 1J1 = J1 - KB1END IF*IF( WANTPT ) THEN** accumulate product of plane rotations in P**T*DO 60 J = J1, J2, KB1CALL DROT( N, PT( J+KUN-1, 1 ), LDPT,$ PT( J+KUN, 1 ), LDPT, WORK( MN+J+KUN ),$ WORK( J+KUN ) )60 CONTINUEEND IF*IF( J2+KB.GT.M ) THEN** adjust J2 to keep within the bounds of the matrix*NR = NR - 1J2 = J2 - KB1END IF*DO 70 J = J1, J2, KB1** create nonzero element a(j+kl+ku,j+ku-1) below the* band and store it in WORK(1:n)*WORK( J+KB ) = WORK( J+KUN )*AB( KLU1, J+KUN )AB( KLU1, J+KUN ) = WORK( MN+J+KUN )*AB( KLU1, J+KUN )70 CONTINUE*IF( ML.GT.ML0 ) THENML = ML - 1ELSEMU = MU - 1END IF80 CONTINUE90 CONTINUEEND IF*IF( KU.EQ.0 .AND. KL.GT.0 ) THEN** A has been reduced to lower bidiagonal form** Transform lower bidiagonal form to upper bidiagonal by applying* plane rotations from the left, storing diagonal elements in D* and off-diagonal elements in E*DO 100 I = 1, MIN( M-1, N )CALL DLARTG( AB( 1, I ), AB( 2, I ), RC, RS, RA )D( I ) = RAIF( I.LT.N ) THENE( I ) = RS*AB( 1, I+1 )AB( 1, I+1 ) = RC*AB( 1, I+1 )END IFIF( WANTQ )$ CALL DROT( M, Q( 1, I ), 1, Q( 1, I+1 ), 1, RC, RS )IF( WANTC )$ CALL DROT( NCC, C( I, 1 ), LDC, C( I+1, 1 ), LDC, RC,$ RS )100 CONTINUEIF( M.LE.N )$ D( M ) = AB( 1, M )ELSE IF( KU.GT.0 ) THEN** A has been reduced to upper bidiagonal form*IF( M.LT.N ) THEN** Annihilate a(m,m+1) by applying plane rotations from the* right, storing diagonal elements in D and off-diagonal* elements in E*RB = AB( KU, M+1 )DO 110 I = M, 1, -1CALL DLARTG( AB( KU+1, I ), RB, RC, RS, RA )D( I ) = RAIF( I.GT.1 ) THENRB = -RS*AB( KU, I )E( I-1 ) = RC*AB( KU, I )END IFIF( WANTPT )$ CALL DROT( N, PT( I, 1 ), LDPT, PT( M+1, 1 ), LDPT,$ RC, RS )110 CONTINUEELSE** Copy off-diagonal elements to E and diagonal elements to D*DO 120 I = 1, MINMN - 1E( I ) = AB( KU, I+1 )120 CONTINUEDO 130 I = 1, MINMND( I ) = AB( KU+1, I )130 CONTINUEEND IFELSE** A is diagonal. Set elements of E to zero and copy diagonal* elements to D.*DO 140 I = 1, MINMN - 1E( I ) = ZERO140 CONTINUEDO 150 I = 1, MINMND( I ) = AB( 1, I )150 CONTINUEEND IFRETURN** End of DGBBRD*END*> \brief \b DGBCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER INFO, KL, KU, LDAB, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBCON estimates the reciprocal of the condition number of a real*> general band matrix A, in either the 1-norm or the infinity-norm,*> using the LU factorization computed by DGBTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as*> RCOND = 1 / ( norm(A) * norm(inv(A)) ).*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies whether the 1-norm condition number or the*> infinity-norm condition number is required:*> = '1' or 'O': 1-norm;*> = 'I': Infinity-norm.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> Details of the LU factorization of the band matrix A, as*> computed by DGBTRF. U is stored as an upper triangular band*> matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and*> the multipliers used during the factorization are stored in*> rows KL+KU+2 to 2*KL+KU+1.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= 2*KL+KU+1.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= N, row i of the matrix was*> interchanged with row IPIV(i).*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> If NORM = '1' or 'O', the 1-norm of the original matrix A.*> If NORM = 'I', the infinity-norm of the original matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(norm(A) * norm(inv(A))).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DGBCON( NORM, N, KL, KU, AB, LDAB, IPIV, ANORM, RCOND,$ WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER INFO, KL, KU, LDAB, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LNOTI, ONENRMCHARACTER NORMININTEGER IX, J, JP, KASE, KASE1, KD, LMDOUBLE PRECISION AINVNM, SCALE, SMLNUM, T* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DLACN2, DLATBS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.2*KL+KU+1 ) THENINFO = -6ELSE IF( ANORM.LT.ZERO ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the norm of inv(A).*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKD = KL + KU + 1LNOTI = KL.GT.0KASE = 010 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(L).*IF( LNOTI ) THENDO 20 J = 1, N - 1LM = MIN( KL, N-J )JP = IPIV( J )T = WORK( JP )IF( JP.NE.J ) THENWORK( JP ) = WORK( J )WORK( J ) = TEND IFCALL DAXPY( LM, -T, AB( KD+1, J ), 1, WORK( J+1 ), 1 )20 CONTINUEEND IF** Multiply by inv(U).*CALL DLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),$ INFO )ELSE** Multiply by inv(U**T).*CALL DLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,$ KL+KU, AB, LDAB, WORK, SCALE, WORK( 2*N+1 ),$ INFO )** Multiply by inv(L**T).*IF( LNOTI ) THENDO 30 J = N - 1, 1, -1LM = MIN( KL, N-J )WORK( J ) = WORK( J ) - DDOT( LM, AB( KD+1, J ), 1,$ WORK( J+1 ), 1 )JP = IPIV( J )IF( JP.NE.J ) THENT = WORK( JP )WORK( JP ) = WORK( J )WORK( J ) = TEND IF30 CONTINUEEND IFEND IF** Divide X by 1/SCALE if doing so will not cause overflow.*NORMIN = 'Y'IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 40CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*40 CONTINUERETURN** End of DGBCON*END*> \brief \b DGBEQU** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBEQU + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbequ.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbequ.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbequ.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBEQU( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,* AMAX, INFO )** .. Scalar Arguments ..* INTEGER INFO, KL, KU, LDAB, M, N* DOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBEQU computes row and column scalings intended to equilibrate an*> M-by-N band matrix A and reduce its condition number. R returns the*> row scale factors and C the column scale factors, chosen to try to*> make the largest element in each row and column of the matrix B with*> elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.*>*> R(i) and C(j) are restricted to be between SMLNUM = smallest safe*> number and BIGNUM = largest safe number. Use of these scaling*> factors is not guaranteed to reduce the condition number of A but*> works well in practice.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The band matrix A, stored in rows 1 to KL+KU+1. The j-th*> column of A is stored in the j-th column of the array AB as*> follows:*> AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KL+KU+1.*> \endverbatim*>*> \param[out] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (M)*> If INFO = 0, or INFO > M, R contains the row scale factors*> for A.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, C contains the column scale factors for A.*> \endverbatim*>*> \param[out] ROWCND*> \verbatim*> ROWCND is DOUBLE PRECISION*> If INFO = 0 or INFO > M, ROWCND contains the ratio of the*> smallest R(i) to the largest R(i). If ROWCND >= 0.1 and*> AMAX is neither too large nor too small, it is not worth*> scaling by R.*> \endverbatim*>*> \param[out] COLCND*> \verbatim*> COLCND is DOUBLE PRECISION*> If INFO = 0, COLCND contains the ratio of the smallest*> C(i) to the largest C(i). If COLCND >= 0.1, it is not*> worth scaling by C.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= M: the i-th row of A is exactly zero*> > M: the (i-M)-th column of A is exactly zero*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DGBEQU( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,$ AMAX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, KDDOUBLE PRECISION BIGNUM, RCMAX, RCMIN, SMLNUM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KU+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBEQU', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENROWCND = ONECOLCND = ONEAMAX = ZERORETURNEND IF** Get machine constants.*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUM** Compute row scale factors.*DO 10 I = 1, MR( I ) = ZERO10 CONTINUE** Find the maximum element in each row.*KD = KU + 1DO 30 J = 1, NDO 20 I = MAX( J-KU, 1 ), MIN( J+KL, M )R( I ) = MAX( R( I ), ABS( AB( KD+I-J, J ) ) )20 CONTINUE30 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 40 I = 1, MRCMAX = MAX( RCMAX, R( I ) )RCMIN = MIN( RCMIN, R( I ) )40 CONTINUEAMAX = RCMAX*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 50 I = 1, MIF( R( I ).EQ.ZERO ) THENINFO = IRETURNEND IF50 CONTINUEELSE** Invert the scale factors.*DO 60 I = 1, MR( I ) = ONE / MIN( MAX( R( I ), SMLNUM ), BIGNUM )60 CONTINUE** Compute ROWCND = min(R(I)) / max(R(I))*ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF** Compute column scale factors*DO 70 J = 1, NC( J ) = ZERO70 CONTINUE** Find the maximum element in each column,* assuming the row scaling computed above.*KD = KU + 1DO 90 J = 1, NDO 80 I = MAX( J-KU, 1 ), MIN( J+KL, M )C( J ) = MAX( C( J ), ABS( AB( KD+I-J, J ) )*R( I ) )80 CONTINUE90 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 100 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )100 CONTINUE*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 110 J = 1, NIF( C( J ).EQ.ZERO ) THENINFO = M + JRETURNEND IF110 CONTINUEELSE** Invert the scale factors.*DO 120 J = 1, NC( J ) = ONE / MIN( MAX( C( J ), SMLNUM ), BIGNUM )120 CONTINUE** Compute COLCND = min(C(J)) / max(C(J))*COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF*RETURN** End of DGBEQU*END*> \brief \b DGBEQUB** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBEQUB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbequb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbequb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbequb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBEQUB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,* AMAX, INFO )** .. Scalar Arguments ..* INTEGER INFO, KL, KU, LDAB, M, N* DOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBEQUB computes row and column scalings intended to equilibrate an*> M-by-N matrix A and reduce its condition number. R returns the row*> scale factors and C the column scale factors, chosen to try to make*> the largest element in each row and column of the matrix B with*> elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most*> the radix.*>*> R(i) and C(j) are restricted to be a power of the radix between*> SMLNUM = smallest safe number and BIGNUM = largest safe number. Use*> of these scaling factors is not guaranteed to reduce the condition*> number of A but works well in practice.*>*> This routine differs from DGEEQU by restricting the scaling factors*> to a power of the radix. Barring over- and underflow, scaling by*> these factors introduces no additional rounding errors. However, the*> scaled entries' magnitudes are no longer approximately 1 but lie*> between sqrt(radix) and 1/sqrt(radix).*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the matrix A in band storage, in rows 1 to KL+KU+1.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(KU+1+i-j,j) = A(i,j) for max(1,j-KU)<=i<=min(N,j+kl)*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array A. LDAB >= max(1,M).*> \endverbatim*>*> \param[out] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (M)*> If INFO = 0 or INFO > M, R contains the row scale factors*> for A.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, C contains the column scale factors for A.*> \endverbatim*>*> \param[out] ROWCND*> \verbatim*> ROWCND is DOUBLE PRECISION*> If INFO = 0 or INFO > M, ROWCND contains the ratio of the*> smallest R(i) to the largest R(i). If ROWCND >= 0.1 and*> AMAX is neither too large nor too small, it is not worth*> scaling by R.*> \endverbatim*>*> \param[out] COLCND*> \verbatim*> COLCND is DOUBLE PRECISION*> If INFO = 0, COLCND contains the ratio of the smallest*> C(i) to the largest C(i). If COLCND >= 0.1, it is not*> worth scaling by C.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= M: the i-th row of A is exactly zero*> > M: the (i-M)-th column of A is exactly zero*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DGBEQUB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,$ AMAX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, KDDOUBLE PRECISION BIGNUM, RCMAX, RCMIN, SMLNUM, RADIX, LOGRDX* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, LOG* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KU+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBEQUB', -INFO )RETURNEND IF** Quick return if possible.*IF( M.EQ.0 .OR. N.EQ.0 ) THENROWCND = ONECOLCND = ONEAMAX = ZERORETURNEND IF** Get machine constants. Assume SMLNUM is a power of the radix.*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMRADIX = DLAMCH( 'B' )LOGRDX = LOG(RADIX)** Compute row scale factors.*DO 10 I = 1, MR( I ) = ZERO10 CONTINUE** Find the maximum element in each row.*KD = KU + 1DO 30 J = 1, NDO 20 I = MAX( J-KU, 1 ), MIN( J+KL, M )R( I ) = MAX( R( I ), ABS( AB( KD+I-J, J ) ) )20 CONTINUE30 CONTINUEDO I = 1, MIF( R( I ).GT.ZERO ) THENR( I ) = RADIX**INT( LOG( R( I ) ) / LOGRDX )END IFEND DO** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 40 I = 1, MRCMAX = MAX( RCMAX, R( I ) )RCMIN = MIN( RCMIN, R( I ) )40 CONTINUEAMAX = RCMAX*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 50 I = 1, MIF( R( I ).EQ.ZERO ) THENINFO = IRETURNEND IF50 CONTINUEELSE** Invert the scale factors.*DO 60 I = 1, MR( I ) = ONE / MIN( MAX( R( I ), SMLNUM ), BIGNUM )60 CONTINUE** Compute ROWCND = min(R(I)) / max(R(I)).*ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF** Compute column scale factors.*DO 70 J = 1, NC( J ) = ZERO70 CONTINUE** Find the maximum element in each column,* assuming the row scaling computed above.*DO 90 J = 1, NDO 80 I = MAX( J-KU, 1 ), MIN( J+KL, M )C( J ) = MAX( C( J ), ABS( AB( KD+I-J, J ) )*R( I ) )80 CONTINUEIF( C( J ).GT.ZERO ) THENC( J ) = RADIX**INT( LOG( C( J ) ) / LOGRDX )END IF90 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 100 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )100 CONTINUE*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 110 J = 1, NIF( C( J ).EQ.ZERO ) THENINFO = M + JRETURNEND IF110 CONTINUEELSE** Invert the scale factors.*DO 120 J = 1, NC( J ) = ONE / MIN( MAX( C( J ), SMLNUM ), BIGNUM )120 CONTINUE** Compute COLCND = min(C(J)) / max(C(J)).*COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF*RETURN** End of DGBEQUB*END*> \brief \b DGBRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBRFS( TRANS, N, KL, KU, NRHS, AB, LDAB, AFB, LDAFB,* IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, KL, KU, LDAB, LDAFB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is banded, and provides*> error bounds and backward error estimates for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The original band matrix A, stored in rows 1 to KL+KU+1.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(n,j+kl).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KL+KU+1.*> \endverbatim*>*> \param[in] AFB*> \verbatim*> AFB is DOUBLE PRECISION array, dimension (LDAFB,N)*> Details of the LU factorization of the band matrix A, as*> computed by DGBTRF. U is stored as an upper triangular band*> matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and*> the multipliers used during the factorization are stored in*> rows KL+KU+2 to 2*KL+KU+1.*> \endverbatim*>*> \param[in] LDAFB*> \verbatim*> LDAFB is INTEGER*> The leading dimension of the array AFB. LDAFB >= 2*KL*KU+1.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices from DGBTRF; for 1<=i<=N, row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DGBTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DGBRFS( TRANS, N, KL, KU, NRHS, AB, LDAB, AFB, LDAFB,$ IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, KL, KU, LDAB, LDAFB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANCHARACTER TRANSTINTEGER COUNT, I, J, K, KASE, KK, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGBMV, DGBTRS, DLACN2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.KL+KU+1 ) THENINFO = -7ELSE IF( LDAFB.LT.2*KL+KU+1 ) THENINFO = -9ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -12ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = MIN( KL+KU+2, N+1 )EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - op(A) * X,* where op(A) = A, A**T, or A**H, depending on TRANS.*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DGBMV( TRANS, N, N, KL, KU, -ONE, AB, LDAB, X( 1, J ), 1,$ ONE, WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(op(A))*abs(X) + abs(B).*IF( NOTRAN ) THENDO 50 K = 1, NKK = KU + 1 - KXK = ABS( X( K, J ) )DO 40 I = MAX( 1, K-KU ), MIN( N, K+KL )WORK( I ) = WORK( I ) + ABS( AB( KK+I, K ) )*XK40 CONTINUE50 CONTINUEELSEDO 70 K = 1, NS = ZEROKK = KU + 1 - KDO 60 I = MAX( 1, K-KU ), MIN( N, K+KL )S = S + ABS( AB( KK+I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DGBTRS( TRANS, N, KL, KU, 1, AFB, LDAFB, IPIV,$ WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DGBTRS( TRANST, N, KL, KU, 1, AFB, LDAFB, IPIV,$ WORK( N+1 ), N, INFO )DO 110 I = 1, NWORK( N+I ) = WORK( N+I )*WORK( I )110 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( N+I )*WORK( I )120 CONTINUECALL DGBTRS( TRANS, N, KL, KU, 1, AFB, LDAFB, IPIV,$ WORK( N+1 ), N, INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DGBRFS*END*> \brief <b> DGBSV computes the solution to system of linear equations A * X = B for GB matrices</b> (simple driver)** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBSV( N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB, INFO )** .. Scalar Arguments ..* INTEGER INFO, KL, KU, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBSV computes the solution to a real system of linear equations*> A * X = B, where A is a band matrix of order N with KL subdiagonals*> and KU superdiagonals, and X and B are N-by-NRHS matrices.*>*> The LU decomposition with partial pivoting and row interchanges is*> used to factor A as A = L * U, where L is a product of permutation*> and unit lower triangular matrices with KL subdiagonals, and U is*> upper triangular with KL+KU superdiagonals. The factored form of A*> is then used to solve the system of equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the matrix A in band storage, in rows KL+1 to*> 2*KL+KU+1; rows 1 to KL of the array need not be set.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(KL+KU+1+i-j,j) = A(i,j) for max(1,j-KU)<=i<=min(N,j+KL)*> On exit, details of the factorization: U is stored as an*> upper triangular band matrix with KL+KU superdiagonals in*> rows 1 to KL+KU+1, and the multipliers used during the*> factorization are stored in rows KL+KU+2 to 2*KL+KU+1.*> See below for further details.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= 2*KL+KU+1.*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices that define the permutation matrix P;*> row i of the matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and the solution has not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> M = N = 6, KL = 2, KU = 1:*>*> On entry: On exit:*>*> * * * + + + * * * u14 u25 u36*> * * + + + + * * u13 u24 u35 u46*> * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56*> a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66*> a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 **> a31 a42 a53 a64 * * m31 m42 m53 m64 * **>*> Array elements marked * are not used by the routine; elements marked*> + need not be set on entry, but are required by the routine to store*> elements of U because of fill-in resulting from the row interchanges.*> \endverbatim*>* =====================================================================SUBROUTINE DGBSV( N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..** =====================================================================** .. External Subroutines ..EXTERNAL DGBTRF, DGBTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( KL.LT.0 ) THENINFO = -2ELSE IF( KU.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.2*KL+KU+1 ) THENINFO = -6ELSE IF( LDB.LT.MAX( N, 1 ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBSV ', -INFO )RETURNEND IF** Compute the LU factorization of the band matrix A.*CALL DGBTRF( N, N, KL, KU, AB, LDAB, IPIV, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DGBTRS( 'No transpose', N, KL, KU, NRHS, AB, LDAB, IPIV,$ B, LDB, INFO )END IFRETURN** End of DGBSV*END*> \brief <b> DGBSVX computes the solution to system of linear equations A * X = B for GB matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbsvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbsvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbsvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBSVX( FACT, TRANS, N, KL, KU, NRHS, AB, LDAB, AFB,* LDAFB, IPIV, EQUED, R, C, B, LDB, X, LDX,* RCOND, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER EQUED, FACT, TRANS* INTEGER INFO, KL, KU, LDAB, LDAFB, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),* $ BERR( * ), C( * ), FERR( * ), R( * ),* $ WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBSVX uses the LU factorization to compute the solution to a real*> system of linear equations A * X = B, A**T * X = B, or A**H * X = B,*> where A is a band matrix of order N with KL subdiagonals and KU*> superdiagonals, and X and B are N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed by this subroutine:*>*> 1. If FACT = 'E', real scaling factors are computed to equilibrate*> the system:*> TRANS = 'N': diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B*> TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B*> TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B*> Whether or not the system will be equilibrated depends on the*> scaling of the matrix A, but if equilibration is used, A is*> overwritten by diag(R)*A*diag(C) and B by diag(R)*B (if TRANS='N')*> or diag(C)*B (if TRANS = 'T' or 'C').*>*> 2. If FACT = 'N' or 'E', the LU decomposition is used to factor the*> matrix A (after equilibration if FACT = 'E') as*> A = L * U,*> where L is a product of permutation and unit lower triangular*> matrices with KL subdiagonals, and U is upper triangular with*> KL+KU superdiagonals.*>*> 3. If some U(i,i)=0, so that U is exactly singular, then the routine*> returns with INFO = i. Otherwise, the factored form of A is used*> to estimate the condition number of the matrix A. If the*> reciprocal of the condition number is less than machine precision,*> INFO = N+1 is returned as a warning, but the routine still goes on*> to solve for X and compute error bounds as described below.*>*> 4. The system of equations is solved for X using the factored form*> of A.*>*> 5. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*>*> 6. If equilibration was used, the matrix X is premultiplied by*> diag(C) (if TRANS = 'N') or diag(R) (if TRANS = 'T' or 'C') so*> that it solves the original system before equilibration.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of the matrix A is*> supplied on entry, and if not, whether the matrix A should be*> equilibrated before it is factored.*> = 'F': On entry, AFB and IPIV contain the factored form of*> A. If EQUED is not 'N', the matrix A has been*> equilibrated with scaling factors given by R and C.*> AB, AFB, and IPIV are not modified.*> = 'N': The matrix A will be copied to AFB and factored.*> = 'E': The matrix A will be equilibrated if necessary, then*> copied to AFB and factored.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations.*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the matrix A in band storage, in rows 1 to KL+KU+1.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(KU+1+i-j,j) = A(i,j) for max(1,j-KU)<=i<=min(N,j+kl)*>*> If FACT = 'F' and EQUED is not 'N', then A must have been*> equilibrated by the scaling factors in R and/or C. AB is not*> modified if FACT = 'F' or 'N', or if FACT = 'E' and*> EQUED = 'N' on exit.*>*> On exit, if EQUED .ne. 'N', A is scaled as follows:*> EQUED = 'R': A := diag(R) * A*> EQUED = 'C': A := A * diag(C)*> EQUED = 'B': A := diag(R) * A * diag(C).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KL+KU+1.*> \endverbatim*>*> \param[in,out] AFB*> \verbatim*> AFB is DOUBLE PRECISION array, dimension (LDAFB,N)*> If FACT = 'F', then AFB is an input argument and on entry*> contains details of the LU factorization of the band matrix*> A, as computed by DGBTRF. U is stored as an upper triangular*> band matrix with KL+KU superdiagonals in rows 1 to KL+KU+1,*> and the multipliers used during the factorization are stored*> in rows KL+KU+2 to 2*KL+KU+1. If EQUED .ne. 'N', then AFB is*> the factored form of the equilibrated matrix A.*>*> If FACT = 'N', then AFB is an output argument and on exit*> returns details of the LU factorization of A.*>*> If FACT = 'E', then AFB is an output argument and on exit*> returns details of the LU factorization of the equilibrated*> matrix A (see the description of AB for the form of the*> equilibrated matrix).*> \endverbatim*>*> \param[in] LDAFB*> \verbatim*> LDAFB is INTEGER*> The leading dimension of the array AFB. LDAFB >= 2*KL+KU+1.*> \endverbatim*>*> \param[in,out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> If FACT = 'F', then IPIV is an input argument and on entry*> contains the pivot indices from the factorization A = L*U*> as computed by DGBTRF; row i of the matrix was interchanged*> with row IPIV(i).*>*> If FACT = 'N', then IPIV is an output argument and on exit*> contains the pivot indices from the factorization A = L*U*> of the original matrix A.*>*> If FACT = 'E', then IPIV is an output argument and on exit*> contains the pivot indices from the factorization A = L*U*> of the equilibrated matrix A.*> \endverbatim*>*> \param[in,out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration (always true if FACT = 'N').*> = 'R': Row equilibration, i.e., A has been premultiplied by*> diag(R).*> = 'C': Column equilibration, i.e., A has been postmultiplied*> by diag(C).*> = 'B': Both row and column equilibration, i.e., A has been*> replaced by diag(R) * A * diag(C).*> EQUED is an input argument if FACT = 'F'; otherwise, it is an*> output argument.*> \endverbatim*>*> \param[in,out] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (N)*> The row scale factors for A. If EQUED = 'R' or 'B', A is*> multiplied on the left by diag(R); if EQUED = 'N' or 'C', R*> is not accessed. R is an input argument if FACT = 'F';*> otherwise, R is an output argument. If FACT = 'F' and*> EQUED = 'R' or 'B', each element of R must be positive.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> The column scale factors for A. If EQUED = 'C' or 'B', A is*> multiplied on the right by diag(C); if EQUED = 'N' or 'R', C*> is not accessed. C is an input argument if FACT = 'F';*> otherwise, C is an output argument. If FACT = 'F' and*> EQUED = 'C' or 'B', each element of C must be positive.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit,*> if EQUED = 'N', B is not modified;*> if TRANS = 'N' and EQUED = 'R' or 'B', B is overwritten by*> diag(R)*B;*> if TRANS = 'T' or 'C' and EQUED = 'C' or 'B', B is*> overwritten by diag(C)*B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X*> to the original system of equations. Note that A and B are*> modified on exit if EQUED .ne. 'N', and the solution to the*> equilibrated system is inv(diag(C))*X if TRANS = 'N' and*> EQUED = 'C' or 'B', or inv(diag(R))*X if TRANS = 'T' or 'C'*> and EQUED = 'R' or 'B'.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A after equilibration (if done). If RCOND is less than the*> machine precision (in particular, if RCOND = 0), the matrix*> is singular to working precision. This condition is*> indicated by a return code of INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> On exit, WORK(1) contains the reciprocal pivot growth*> factor norm(A)/norm(U). The "max absolute element" norm is*> used. If WORK(1) is much less than 1, then the stability*> of the LU factorization of the (equilibrated) matrix A*> could be poor. This also means that the solution X, condition*> estimator RCOND, and forward error bound FERR could be*> unreliable. If factorization fails with 0<INFO<=N, then*> WORK(1) contains the reciprocal pivot growth factor for the*> leading INFO columns of A.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, so the solution and error bounds*> could not be computed. RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleGBsolve** =====================================================================SUBROUTINE DGBSVX( FACT, TRANS, N, KL, KU, NRHS, AB, LDAB, AFB,$ LDAFB, IPIV, EQUED, R, C, B, LDB, X, LDX,$ RCOND, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER EQUED, FACT, TRANSINTEGER INFO, KL, KU, LDAB, LDAFB, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),$ BERR( * ), C( * ), FERR( * ), R( * ),$ WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL COLEQU, EQUIL, NOFACT, NOTRAN, ROWEQUCHARACTER NORMINTEGER I, INFEQU, J, J1, J2DOUBLE PRECISION AMAX, ANORM, BIGNUM, COLCND, RCMAX, RCMIN,$ ROWCND, RPVGRW, SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANGB, DLANTBEXTERNAL LSAME, DLAMCH, DLANGB, DLANTB* ..* .. External Subroutines ..EXTERNAL DCOPY, DGBCON, DGBEQU, DGBRFS, DGBTRF, DGBTRS,$ DLACPY, DLAQGB, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )EQUIL = LSAME( FACT, 'E' )NOTRAN = LSAME( TRANS, 'N' )IF( NOFACT .OR. EQUIL ) THENEQUED = 'N'ROWEQU = .FALSE.COLEQU = .FALSE.ELSEROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )SMLNUM = DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMEND IF** Test the input parameters.*IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )$ THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KL.LT.0 ) THENINFO = -4ELSE IF( KU.LT.0 ) THENINFO = -5ELSE IF( NRHS.LT.0 ) THENINFO = -6ELSE IF( LDAB.LT.KL+KU+1 ) THENINFO = -8ELSE IF( LDAFB.LT.2*KL+KU+1 ) THENINFO = -10ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.$ ( ROWEQU .OR. COLEQU .OR. LSAME( EQUED, 'N' ) ) ) THENINFO = -12ELSEIF( ROWEQU ) THENRCMIN = BIGNUMRCMAX = ZERODO 10 J = 1, NRCMIN = MIN( RCMIN, R( J ) )RCMAX = MAX( RCMAX, R( J ) )10 CONTINUEIF( RCMIN.LE.ZERO ) THENINFO = -13ELSE IF( N.GT.0 ) THENROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )ELSEROWCND = ONEEND IFEND IFIF( COLEQU .AND. INFO.EQ.0 ) THENRCMIN = BIGNUMRCMAX = ZERODO 20 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )20 CONTINUEIF( RCMIN.LE.ZERO ) THENINFO = -14ELSE IF( N.GT.0 ) THENCOLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )ELSECOLCND = ONEEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDB.LT.MAX( 1, N ) ) THENINFO = -16ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -18END IFEND IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGBSVX', -INFO )RETURNEND IF*IF( EQUIL ) THEN** Compute row and column scalings to equilibrate the matrix A.*CALL DGBEQU( N, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,$ AMAX, INFEQU )IF( INFEQU.EQ.0 ) THEN** Equilibrate the matrix.*CALL DLAQGB( N, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,$ AMAX, EQUED )ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )END IFEND IF** Scale the right hand side.*IF( NOTRAN ) THENIF( ROWEQU ) THENDO 40 J = 1, NRHSDO 30 I = 1, NB( I, J ) = R( I )*B( I, J )30 CONTINUE40 CONTINUEEND IFELSE IF( COLEQU ) THENDO 60 J = 1, NRHSDO 50 I = 1, NB( I, J ) = C( I )*B( I, J )50 CONTINUE60 CONTINUEEND IF*IF( NOFACT .OR. EQUIL ) THEN** Compute the LU factorization of the band matrix A.*DO 70 J = 1, NJ1 = MAX( J-KU, 1 )J2 = MIN( J+KL, N )CALL DCOPY( J2-J1+1, AB( KU+1-J+J1, J ), 1,$ AFB( KL+KU+1-J+J1, J ), 1 )70 CONTINUE*CALL DGBTRF( N, N, KL, KU, AFB, LDAFB, IPIV, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 ) THEN** Compute the reciprocal pivot growth factor of the* leading rank-deficient INFO columns of A.*ANORM = ZERODO 90 J = 1, INFODO 80 I = MAX( KU+2-J, 1 ), MIN( N+KU+1-J, KL+KU+1 )ANORM = MAX( ANORM, ABS( AB( I, J ) ) )80 CONTINUE90 CONTINUERPVGRW = DLANTB( 'M', 'U', 'N', INFO, MIN( INFO-1, KL+KU ),$ AFB( MAX( 1, KL+KU+2-INFO ), 1 ), LDAFB,$ WORK )IF( RPVGRW.EQ.ZERO ) THENRPVGRW = ONEELSERPVGRW = ANORM / RPVGRWEND IFWORK( 1 ) = RPVGRWRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A and the* reciprocal pivot growth factor RPVGRW.*IF( NOTRAN ) THENNORM = '1'ELSENORM = 'I'END IFANORM = DLANGB( NORM, N, KL, KU, AB, LDAB, WORK )RPVGRW = DLANTB( 'M', 'U', 'N', N, KL+KU, AFB, LDAFB, WORK )IF( RPVGRW.EQ.ZERO ) THENRPVGRW = ONEELSERPVGRW = DLANGB( 'M', N, KL, KU, AB, LDAB, WORK ) / RPVGRWEND IF** Compute the reciprocal of the condition number of A.*CALL DGBCON( NORM, N, KL, KU, AFB, LDAFB, IPIV, ANORM, RCOND,$ WORK, IWORK, INFO )** Compute the solution matrix X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DGBTRS( TRANS, N, KL, KU, NRHS, AFB, LDAFB, IPIV, X, LDX,$ INFO )** Use iterative refinement to improve the computed solution and* compute error bounds and backward error estimates for it.*CALL DGBRFS( TRANS, N, KL, KU, NRHS, AB, LDAB, AFB, LDAFB, IPIV,$ B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )** Transform the solution matrix X to a solution of the original* system.*IF( NOTRAN ) THENIF( COLEQU ) THENDO 110 J = 1, NRHSDO 100 I = 1, NX( I, J ) = C( I )*X( I, J )100 CONTINUE110 CONTINUEDO 120 J = 1, NRHSFERR( J ) = FERR( J ) / COLCND120 CONTINUEEND IFELSE IF( ROWEQU ) THENDO 140 J = 1, NRHSDO 130 I = 1, NX( I, J ) = R( I )*X( I, J )130 CONTINUE140 CONTINUEDO 150 J = 1, NRHSFERR( J ) = FERR( J ) / ROWCND150 CONTINUEEND IF** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*WORK( 1 ) = RPVGRWRETURN** End of DGBSVX*END*> \brief \b DGBTF2 computes the LU factorization of a general band matrix using the unblocked version of the algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBTF2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbtf2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbtf2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbtf2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, KL, KU, LDAB, M, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AB( LDAB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBTF2 computes an LU factorization of a real m-by-n band matrix A*> using partial pivoting with row interchanges.*>*> This is the unblocked version of the algorithm, calling Level 2 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the matrix A in band storage, in rows KL+1 to*> 2*KL+KU+1; rows 1 to KL of the array need not be set.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)*>*> On exit, details of the factorization: U is stored as an*> upper triangular band matrix with KL+KU superdiagonals in*> rows 1 to KL+KU+1, and the multipliers used during the*> factorization are stored in rows KL+KU+2 to 2*KL+KU+1.*> See below for further details.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= 2*KL+KU+1.*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (min(M,N))*> The pivot indices; for 1 <= i <= min(M,N), row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = +i, U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and division by zero will occur if it is used*> to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> M = N = 6, KL = 2, KU = 1:*>*> On entry: On exit:*>*> * * * + + + * * * u14 u25 u36*> * * + + + + * * u13 u24 u35 u46*> * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56*> a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66*> a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 **> a31 a42 a53 a64 * * m31 m42 m53 m64 * **>*> Array elements marked * are not used by the routine; elements marked*> + need not be set on entry, but are required by the routine to store*> elements of U, because of fill-in resulting from the row*> interchanges.*> \endverbatim*>* =====================================================================SUBROUTINE DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, JP, JU, KM, KV* ..* .. External Functions ..INTEGER IDAMAXEXTERNAL IDAMAX* ..* .. External Subroutines ..EXTERNAL DGER, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** KV is the number of superdiagonals in the factor U, allowing for* fill-in.*KV = KU + KL** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KV+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBTF2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Gaussian elimination with partial pivoting** Set fill-in elements in columns KU+2 to KV to zero.*DO 20 J = KU + 2, MIN( KV, N )DO 10 I = KV - J + 2, KLAB( I, J ) = ZERO10 CONTINUE20 CONTINUE** JU is the index of the last column affected by the current stage* of the factorization.*JU = 1*DO 40 J = 1, MIN( M, N )** Set fill-in elements in column J+KV to zero.*IF( J+KV.LE.N ) THENDO 30 I = 1, KLAB( I, J+KV ) = ZERO30 CONTINUEEND IF** Find pivot and test for singularity. KM is the number of* subdiagonal elements in the current column.*KM = MIN( KL, M-J )JP = IDAMAX( KM+1, AB( KV+1, J ), 1 )IPIV( J ) = JP + J - 1IF( AB( KV+JP, J ).NE.ZERO ) THENJU = MAX( JU, MIN( J+KU+JP-1, N ) )** Apply interchange to columns J to JU.*IF( JP.NE.1 )$ CALL DSWAP( JU-J+1, AB( KV+JP, J ), LDAB-1,$ AB( KV+1, J ), LDAB-1 )*IF( KM.GT.0 ) THEN** Compute multipliers.*CALL DSCAL( KM, ONE / AB( KV+1, J ), AB( KV+2, J ), 1 )** Update trailing submatrix within the band.*IF( JU.GT.J )$ CALL DGER( KM, JU-J, -ONE, AB( KV+2, J ), 1,$ AB( KV, J+1 ), LDAB-1, AB( KV+1, J+1 ),$ LDAB-1 )END IFELSE** If pivot is zero, set INFO to the index of the pivot* unless a zero pivot has already been found.*IF( INFO.EQ.0 )$ INFO = JEND IF40 CONTINUERETURN** End of DGBTF2*END*> \brief \b DGBTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbtrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbtrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbtrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, KL, KU, LDAB, M, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AB( LDAB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBTRF computes an LU factorization of a real m-by-n band matrix A*> using partial pivoting with row interchanges.*>*> This is the blocked version of the algorithm, calling Level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the matrix A in band storage, in rows KL+1 to*> 2*KL+KU+1; rows 1 to KL of the array need not be set.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(kl+ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)*>*> On exit, details of the factorization: U is stored as an*> upper triangular band matrix with KL+KU superdiagonals in*> rows 1 to KL+KU+1, and the multipliers used during the*> factorization are stored in rows KL+KU+2 to 2*KL+KU+1.*> See below for further details.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= 2*KL+KU+1.*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (min(M,N))*> The pivot indices; for 1 <= i <= min(M,N), row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = +i, U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and division by zero will occur if it is used*> to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> M = N = 6, KL = 2, KU = 1:*>*> On entry: On exit:*>*> * * * + + + * * * u14 u25 u36*> * * + + + + * * u13 u24 u35 u46*> * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56*> a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66*> a21 a32 a43 a54 a65 * m21 m32 m43 m54 m65 **> a31 a42 a53 a64 * * m31 m42 m53 m64 * **>*> Array elements marked * are not used by the routine; elements marked*> + need not be set on entry, but are required by the routine to store*> elements of U because of fill-in resulting from the row interchanges.*> \endverbatim*>* =====================================================================SUBROUTINE DGBTRF( M, N, KL, KU, AB, LDAB, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, KL, KU, LDAB, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )INTEGER NBMAX, LDWORKPARAMETER ( NBMAX = 64, LDWORK = NBMAX+1 )* ..* .. Local Scalars ..INTEGER I, I2, I3, II, IP, J, J2, J3, JB, JJ, JM, JP,$ JU, K2, KM, KV, NB, NWDOUBLE PRECISION TEMP* ..* .. Local Arrays ..DOUBLE PRECISION WORK13( LDWORK, NBMAX ),$ WORK31( LDWORK, NBMAX )* ..* .. External Functions ..INTEGER IDAMAX, ILAENVEXTERNAL IDAMAX, ILAENV* ..* .. External Subroutines ..EXTERNAL DCOPY, DGBTF2, DGEMM, DGER, DLASWP, DSCAL,$ DSWAP, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** KV is the number of superdiagonals in the factor U, allowing for* fill-in*KV = KU + KL** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KL+KV+1 ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBTRF', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Determine the block size for this environment*NB = ILAENV( 1, 'DGBTRF', ' ', M, N, KL, KU )** The block size must not exceed the limit set by the size of the* local arrays WORK13 and WORK31.*NB = MIN( NB, NBMAX )*IF( NB.LE.1 .OR. NB.GT.KL ) THEN** Use unblocked code*CALL DGBTF2( M, N, KL, KU, AB, LDAB, IPIV, INFO )ELSE** Use blocked code** Zero the superdiagonal elements of the work array WORK13*DO 20 J = 1, NBDO 10 I = 1, J - 1WORK13( I, J ) = ZERO10 CONTINUE20 CONTINUE** Zero the subdiagonal elements of the work array WORK31*DO 40 J = 1, NBDO 30 I = J + 1, NBWORK31( I, J ) = ZERO30 CONTINUE40 CONTINUE** Gaussian elimination with partial pivoting** Set fill-in elements in columns KU+2 to KV to zero*DO 60 J = KU + 2, MIN( KV, N )DO 50 I = KV - J + 2, KLAB( I, J ) = ZERO50 CONTINUE60 CONTINUE** JU is the index of the last column affected by the current* stage of the factorization*JU = 1*DO 180 J = 1, MIN( M, N ), NBJB = MIN( NB, MIN( M, N )-J+1 )** The active part of the matrix is partitioned** A11 A12 A13* A21 A22 A23* A31 A32 A33** Here A11, A21 and A31 denote the current block of JB columns* which is about to be factorized. The number of rows in the* partitioning are JB, I2, I3 respectively, and the numbers* of columns are JB, J2, J3. The superdiagonal elements of A13* and the subdiagonal elements of A31 lie outside the band.*I2 = MIN( KL-JB, M-J-JB+1 )I3 = MIN( JB, M-J-KL+1 )** J2 and J3 are computed after JU has been updated.** Factorize the current block of JB columns*DO 80 JJ = J, J + JB - 1** Set fill-in elements in column JJ+KV to zero*IF( JJ+KV.LE.N ) THENDO 70 I = 1, KLAB( I, JJ+KV ) = ZERO70 CONTINUEEND IF** Find pivot and test for singularity. KM is the number of* subdiagonal elements in the current column.*KM = MIN( KL, M-JJ )JP = IDAMAX( KM+1, AB( KV+1, JJ ), 1 )IPIV( JJ ) = JP + JJ - JIF( AB( KV+JP, JJ ).NE.ZERO ) THENJU = MAX( JU, MIN( JJ+KU+JP-1, N ) )IF( JP.NE.1 ) THEN** Apply interchange to columns J to J+JB-1*IF( JP+JJ-1.LT.J+KL ) THEN*CALL DSWAP( JB, AB( KV+1+JJ-J, J ), LDAB-1,$ AB( KV+JP+JJ-J, J ), LDAB-1 )ELSE** The interchange affects columns J to JJ-1 of A31* which are stored in the work array WORK31*CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,$ WORK31( JP+JJ-J-KL, 1 ), LDWORK )CALL DSWAP( J+JB-JJ, AB( KV+1, JJ ), LDAB-1,$ AB( KV+JP, JJ ), LDAB-1 )END IFEND IF** Compute multipliers*CALL DSCAL( KM, ONE / AB( KV+1, JJ ), AB( KV+2, JJ ),$ 1 )** Update trailing submatrix within the band and within* the current block. JM is the index of the last column* which needs to be updated.*JM = MIN( JU, J+JB-1 )IF( JM.GT.JJ )$ CALL DGER( KM, JM-JJ, -ONE, AB( KV+2, JJ ), 1,$ AB( KV, JJ+1 ), LDAB-1,$ AB( KV+1, JJ+1 ), LDAB-1 )ELSE** If pivot is zero, set INFO to the index of the pivot* unless a zero pivot has already been found.*IF( INFO.EQ.0 )$ INFO = JJEND IF** Copy current column of A31 into the work array WORK31*NW = MIN( JJ-J+1, I3 )IF( NW.GT.0 )$ CALL DCOPY( NW, AB( KV+KL+1-JJ+J, JJ ), 1,$ WORK31( 1, JJ-J+1 ), 1 )80 CONTINUEIF( J+JB.LE.N ) THEN** Apply the row interchanges to the other blocks.*J2 = MIN( JU-J+1, KV ) - JBJ3 = MAX( 0, JU-J-KV+1 )** Use DLASWP to apply the row interchanges to A12, A22, and* A32.*CALL DLASWP( J2, AB( KV+1-JB, J+JB ), LDAB-1, 1, JB,$ IPIV( J ), 1 )** Adjust the pivot indices.*DO 90 I = J, J + JB - 1IPIV( I ) = IPIV( I ) + J - 190 CONTINUE** Apply the row interchanges to A13, A23, and A33* columnwise.*K2 = J - 1 + JB + J2DO 110 I = 1, J3JJ = K2 + IDO 100 II = J + I - 1, J + JB - 1IP = IPIV( II )IF( IP.NE.II ) THENTEMP = AB( KV+1+II-JJ, JJ )AB( KV+1+II-JJ, JJ ) = AB( KV+1+IP-JJ, JJ )AB( KV+1+IP-JJ, JJ ) = TEMPEND IF100 CONTINUE110 CONTINUE** Update the relevant part of the trailing submatrix*IF( J2.GT.0 ) THEN** Update A12*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit',$ JB, J2, ONE, AB( KV+1, J ), LDAB-1,$ AB( KV+1-JB, J+JB ), LDAB-1 )*IF( I2.GT.0 ) THEN** Update A22*CALL DGEMM( 'No transpose', 'No transpose', I2, J2,$ JB, -ONE, AB( KV+1+JB, J ), LDAB-1,$ AB( KV+1-JB, J+JB ), LDAB-1, ONE,$ AB( KV+1, J+JB ), LDAB-1 )END IF*IF( I3.GT.0 ) THEN** Update A32*CALL DGEMM( 'No transpose', 'No transpose', I3, J2,$ JB, -ONE, WORK31, LDWORK,$ AB( KV+1-JB, J+JB ), LDAB-1, ONE,$ AB( KV+KL+1-JB, J+JB ), LDAB-1 )END IFEND IF*IF( J3.GT.0 ) THEN** Copy the lower triangle of A13 into the work array* WORK13*DO 130 JJ = 1, J3DO 120 II = JJ, JBWORK13( II, JJ ) = AB( II-JJ+1, JJ+J+KV-1 )120 CONTINUE130 CONTINUE** Update A13 in the work array*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit',$ JB, J3, ONE, AB( KV+1, J ), LDAB-1,$ WORK13, LDWORK )*IF( I2.GT.0 ) THEN** Update A23*CALL DGEMM( 'No transpose', 'No transpose', I2, J3,$ JB, -ONE, AB( KV+1+JB, J ), LDAB-1,$ WORK13, LDWORK, ONE, AB( 1+JB, J+KV ),$ LDAB-1 )END IF*IF( I3.GT.0 ) THEN** Update A33*CALL DGEMM( 'No transpose', 'No transpose', I3, J3,$ JB, -ONE, WORK31, LDWORK, WORK13,$ LDWORK, ONE, AB( 1+KL, J+KV ), LDAB-1 )END IF** Copy the lower triangle of A13 back into place*DO 150 JJ = 1, J3DO 140 II = JJ, JBAB( II-JJ+1, JJ+J+KV-1 ) = WORK13( II, JJ )140 CONTINUE150 CONTINUEEND IFELSE** Adjust the pivot indices.*DO 160 I = J, J + JB - 1IPIV( I ) = IPIV( I ) + J - 1160 CONTINUEEND IF** Partially undo the interchanges in the current block to* restore the upper triangular form of A31 and copy the upper* triangle of A31 back into place*DO 170 JJ = J + JB - 1, J, -1JP = IPIV( JJ ) - JJ + 1IF( JP.NE.1 ) THEN** Apply interchange to columns J to JJ-1*IF( JP+JJ-1.LT.J+KL ) THEN** The interchange does not affect A31*CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,$ AB( KV+JP+JJ-J, J ), LDAB-1 )ELSE** The interchange does affect A31*CALL DSWAP( JJ-J, AB( KV+1+JJ-J, J ), LDAB-1,$ WORK31( JP+JJ-J-KL, 1 ), LDWORK )END IFEND IF** Copy the current column of A31 back into place*NW = MIN( I3, JJ-J+1 )IF( NW.GT.0 )$ CALL DCOPY( NW, WORK31( 1, JJ-J+1 ), 1,$ AB( KV+KL+1-JJ+J, JJ ), 1 )170 CONTINUE180 CONTINUEEND IF*RETURN** End of DGBTRF*END*> \brief \b DGBTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGBTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgbtrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgbtrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgbtrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,* INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, KL, KU, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGBTRS solves a system of linear equations*> A * X = B or A**T * X = B*> with a general band matrix A using the LU factorization computed*> by DGBTRF.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations.*> = 'N': A * X = B (No transpose)*> = 'T': A**T* X = B (Transpose)*> = 'C': A**T* X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> Details of the LU factorization of the band matrix A, as*> computed by DGBTRF. U is stored as an upper triangular band*> matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and*> the multipliers used during the factorization are stored in*> rows KL+KU+2 to 2*KL+KU+1.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= 2*KL+KU+1.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= N, row i of the matrix was*> interchanged with row IPIV(i).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DGBTRS( TRANS, N, KL, KU, NRHS, AB, LDAB, IPIV, B, LDB,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, KL, KU, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LNOTI, NOTRANINTEGER I, J, KD, L, LM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER, DSWAP, DTBSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KL.LT.0 ) THENINFO = -3ELSE IF( KU.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.( 2*KL+KU+1 ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGBTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*KD = KU + KL + 1LNOTI = KL.GT.0*IF( NOTRAN ) THEN** Solve A*X = B.** Solve L*X = B, overwriting B with X.** L is represented as a product of permutations and unit lower* triangular matrices L = P(1) * L(1) * ... * P(n-1) * L(n-1),* where each transformation L(i) is a rank-one modification of* the identity matrix.*IF( LNOTI ) THENDO 10 J = 1, N - 1LM = MIN( KL, N-J )L = IPIV( J )IF( L.NE.J )$ CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )CALL DGER( LM, NRHS, -ONE, AB( KD+1, J ), 1, B( J, 1 ),$ LDB, B( J+1, 1 ), LDB )10 CONTINUEEND IF*DO 20 I = 1, NRHS** Solve U*X = B, overwriting B with X.*CALL DTBSV( 'Upper', 'No transpose', 'Non-unit', N, KL+KU,$ AB, LDAB, B( 1, I ), 1 )20 CONTINUE*ELSE** Solve A**T*X = B.*DO 30 I = 1, NRHS** Solve U**T*X = B, overwriting B with X.*CALL DTBSV( 'Upper', 'Transpose', 'Non-unit', N, KL+KU, AB,$ LDAB, B( 1, I ), 1 )30 CONTINUE** Solve L**T*X = B, overwriting B with X.*IF( LNOTI ) THENDO 40 J = N - 1, 1, -1LM = MIN( KL, N-J )CALL DGEMV( 'Transpose', LM, NRHS, -ONE, B( J+1, 1 ),$ LDB, AB( KD+1, J ), 1, ONE, B( J, 1 ), LDB )L = IPIV( J )IF( L.NE.J )$ CALL DSWAP( NRHS, B( L, 1 ), LDB, B( J, 1 ), LDB )40 CONTINUEEND IFEND IFRETURN** End of DGBTRS*END*> \brief \b DGEBAK** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEBAK + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgebak.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgebak.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgebak.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,* INFO )** .. Scalar Arguments ..* CHARACTER JOB, SIDE* INTEGER IHI, ILO, INFO, LDV, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION SCALE( * ), V( LDV, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEBAK forms the right or left eigenvectors of a real general matrix*> by backward transformation on the computed eigenvectors of the*> balanced matrix output by DGEBAL.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies the type of backward transformation required:*> = 'N', do nothing, return immediately;*> = 'P', do backward transformation for permutation only;*> = 'S', do backward transformation for scaling only;*> = 'B', do backward transformations for both permutation and*> scaling.*> JOB must be the same as the argument JOB supplied to DGEBAL.*> \endverbatim*>*> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'R': V contains right eigenvectors;*> = 'L': V contains left eigenvectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows of the matrix V. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> The integers ILO and IHI determined by DGEBAL.*> 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.*> \endverbatim*>*> \param[in] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutation and scaling factors, as returned*> by DGEBAL.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of columns of the matrix V. M >= 0.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,M)*> On entry, the matrix of right or left eigenvectors to be*> transformed, as returned by DHSEIN or DTREVC.*> On exit, V is overwritten by the transformed eigenvectors.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V. LDV >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGEBAK( JOB, SIDE, N, ILO, IHI, SCALE, M, V, LDV,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOB, SIDEINTEGER IHI, ILO, INFO, LDV, M, N* ..* .. Array Arguments ..DOUBLE PRECISION SCALE( * ), V( LDV, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LEFTV, RIGHTVINTEGER I, II, KDOUBLE PRECISION S* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Decode and Test the input parameters*RIGHTV = LSAME( SIDE, 'R' )LEFTV = LSAME( SIDE, 'L' )*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -4ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -5ELSE IF( M.LT.0 ) THENINFO = -7ELSE IF( LDV.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEBAK', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( M.EQ.0 )$ RETURNIF( LSAME( JOB, 'N' ) )$ RETURN*IF( ILO.EQ.IHI )$ GO TO 30** Backward balance*IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN*IF( RIGHTV ) THENDO 10 I = ILO, IHIS = SCALE( I )CALL DSCAL( M, S, V( I, 1 ), LDV )10 CONTINUEEND IF*IF( LEFTV ) THENDO 20 I = ILO, IHIS = ONE / SCALE( I )CALL DSCAL( M, S, V( I, 1 ), LDV )20 CONTINUEEND IF*END IF** Backward permutation** For I = ILO-1 step -1 until 1,* IHI+1 step 1 until N do --*30 CONTINUEIF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THENIF( RIGHTV ) THENDO 40 II = 1, NI = IIIF( I.GE.ILO .AND. I.LE.IHI )$ GO TO 40IF( I.LT.ILO )$ I = ILO - IIK = SCALE( I )IF( K.EQ.I )$ GO TO 40CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )40 CONTINUEEND IF*IF( LEFTV ) THENDO 50 II = 1, NI = IIIF( I.GE.ILO .AND. I.LE.IHI )$ GO TO 50IF( I.LT.ILO )$ I = ILO - IIK = SCALE( I )IF( K.EQ.I )$ GO TO 50CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )50 CONTINUEEND IFEND IF*RETURN** End of DGEBAK*END*> \brief \b DGEBAL** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEBAL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgebal.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgebal.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgebal.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )** .. Scalar Arguments ..* CHARACTER JOB* INTEGER IHI, ILO, INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), SCALE( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEBAL balances a general real matrix A. This involves, first,*> permuting A by a similarity transformation to isolate eigenvalues*> in the first 1 to ILO-1 and last IHI+1 to N elements on the*> diagonal; and second, applying a diagonal similarity transformation*> to rows and columns ILO to IHI to make the rows and columns as*> close in norm as possible. Both steps are optional.*>*> Balancing may reduce the 1-norm of the matrix, and improve the*> accuracy of the computed eigenvalues and/or eigenvectors.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies the operations to be performed on A:*> = 'N': none: simply set ILO = 1, IHI = N, SCALE(I) = 1.0*> for i = 1,...,N;*> = 'P': permute only;*> = 'S': scale only;*> = 'B': both permute and scale.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the input matrix A.*> On exit, A is overwritten by the balanced matrix.*> If JOB = 'N', A is not referenced.*> See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*> \param[out] IHI*> \verbatim*> IHI is INTEGER*> ILO and IHI are set to integers such that on exit*> A(i,j) = 0 if i > j and j = 1,...,ILO-1 or I = IHI+1,...,N.*> If JOB = 'N' or 'S', ILO = 1 and IHI = N.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and scaling factors applied to*> A. If P(j) is the index of the row and column interchanged*> with row and column j and D(j) is the scaling factor*> applied to row and column j, then*> SCALE(j) = P(j) for j = 1,...,ILO-1*> = D(j) for j = ILO,...,IHI*> = P(j) for j = IHI+1,...,N.*> The order in which the interchanges are made is N to IHI+1,*> then 1 to ILO-1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The permutations consist of row and column interchanges which put*> the matrix in the form*>*> ( T1 X Y )*> P A P = ( 0 B Z )*> ( 0 0 T2 )*>*> where T1 and T2 are upper triangular matrices whose eigenvalues lie*> along the diagonal. The column indices ILO and IHI mark the starting*> and ending columns of the submatrix B. Balancing consists of applying*> a diagonal similarity transformation inv(D) * B * D to make the*> 1-norms of each row of B and its corresponding column nearly equal.*> The output matrix is*>*> ( T1 X*D Y )*> ( 0 inv(D)*B*D inv(D)*Z ).*> ( 0 0 T2 )*>*> Information about the permutations P and the diagonal matrix D is*> returned in the vector SCALE.*>*> This subroutine is based on the EISPACK routine BALANC.*>*> Modified by Tzu-Yi Chen, Computer Science Division, University of*> California at Berkeley, USA*> \endverbatim*>* =====================================================================SUBROUTINE DGEBAL( JOB, N, A, LDA, ILO, IHI, SCALE, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER JOBINTEGER IHI, ILO, INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), SCALE( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION SCLFACPARAMETER ( SCLFAC = 2.0D+0 )DOUBLE PRECISION FACTORPARAMETER ( FACTOR = 0.95D+0 )* ..* .. Local Scalars ..LOGICAL NOCONVINTEGER I, ICA, IEXC, IRA, J, K, L, MDOUBLE PRECISION C, CA, F, G, R, RA, S, SFMAX1, SFMAX2, SFMIN1,$ SFMIN2* ..* .. External Functions ..LOGICAL DISNAN, LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCH, DNRM2EXTERNAL DISNAN, LSAME, IDAMAX, DLAMCH, DNRM2* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* Test the input parameters*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEBAL', -INFO )RETURNEND IF*K = 1L = N*IF( N.EQ.0 )$ GO TO 210*IF( LSAME( JOB, 'N' ) ) THENDO 10 I = 1, NSCALE( I ) = ONE10 CONTINUEGO TO 210END IF*IF( LSAME( JOB, 'S' ) )$ GO TO 120** Permutation to isolate eigenvalues if possible*GO TO 50** Row and column exchange.*20 CONTINUESCALE( M ) = JIF( J.EQ.M )$ GO TO 30*CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )CALL DSWAP( N-K+1, A( J, K ), LDA, A( M, K ), LDA )*30 CONTINUEGO TO ( 40, 80 )IEXC** Search for rows isolating an eigenvalue and push them down.*40 CONTINUEIF( L.EQ.1 )$ GO TO 210L = L - 1*50 CONTINUEDO 70 J = L, 1, -1*DO 60 I = 1, LIF( I.EQ.J )$ GO TO 60IF( A( J, I ).NE.ZERO )$ GO TO 7060 CONTINUE*M = LIEXC = 1GO TO 2070 CONTINUE*GO TO 90** Search for columns isolating an eigenvalue and push them left.*80 CONTINUEK = K + 1*90 CONTINUEDO 110 J = K, L*DO 100 I = K, LIF( I.EQ.J )$ GO TO 100IF( A( I, J ).NE.ZERO )$ GO TO 110100 CONTINUE*M = KIEXC = 2GO TO 20110 CONTINUE*120 CONTINUEDO 130 I = K, LSCALE( I ) = ONE130 CONTINUE*IF( LSAME( JOB, 'P' ) )$ GO TO 210** Balance the submatrix in rows K to L.** Iterative loop for norm reduction*SFMIN1 = DLAMCH( 'S' ) / DLAMCH( 'P' )SFMAX1 = ONE / SFMIN1SFMIN2 = SFMIN1*SCLFACSFMAX2 = ONE / SFMIN2*140 CONTINUENOCONV = .FALSE.*DO 200 I = K, L*C = DNRM2( L-K+1, A( K, I ), 1 )R = DNRM2( L-K+1, A( I, K ), LDA )ICA = IDAMAX( L, A( 1, I ), 1 )CA = ABS( A( ICA, I ) )IRA = IDAMAX( N-K+1, A( I, K ), LDA )RA = ABS( A( I, IRA+K-1 ) )** Guard against zero C or R due to underflow.*IF( C.EQ.ZERO .OR. R.EQ.ZERO )$ GO TO 200G = R / SCLFACF = ONES = C + R160 CONTINUEIF( C.GE.G .OR. MAX( F, C, CA ).GE.SFMAX2 .OR.$ MIN( R, G, RA ).LE.SFMIN2 )GO TO 170IF( DISNAN( C+F+CA+R+G+RA ) ) THEN** Exit if NaN to avoid infinite loop*INFO = -3CALL XERBLA( 'DGEBAL', -INFO )RETURNEND IFF = F*SCLFACC = C*SCLFACCA = CA*SCLFACR = R / SCLFACG = G / SCLFACRA = RA / SCLFACGO TO 160*170 CONTINUEG = C / SCLFAC180 CONTINUEIF( G.LT.R .OR. MAX( R, RA ).GE.SFMAX2 .OR.$ MIN( F, C, G, CA ).LE.SFMIN2 )GO TO 190F = F / SCLFACC = C / SCLFACG = G / SCLFACCA = CA / SCLFACR = R*SCLFACRA = RA*SCLFACGO TO 180** Now balance.*190 CONTINUEIF( ( C+R ).GE.FACTOR*S )$ GO TO 200IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THENIF( F*SCALE( I ).LE.SFMIN1 )$ GO TO 200END IFIF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THENIF( SCALE( I ).GE.SFMAX1 / F )$ GO TO 200END IFG = ONE / FSCALE( I ) = SCALE( I )*FNOCONV = .TRUE.*CALL DSCAL( N-K+1, G, A( I, K ), LDA )CALL DSCAL( L, F, A( 1, I ), 1 )*200 CONTINUE*IF( NOCONV )$ GO TO 140*210 CONTINUEILO = KIHI = L*RETURN** End of DGEBAL*END*> \brief \b DGEBD2 reduces a general matrix to bidiagonal form using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEBD2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgebd2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgebd2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgebd2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),* $ TAUQ( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEBD2 reduces a real general m by n matrix A to upper or lower*> bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.*>*> If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows in the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns in the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n general matrix to be reduced.*> On exit,*> if m >= n, the diagonal and the first superdiagonal are*> overwritten with the upper bidiagonal matrix B; the*> elements below the diagonal, with the array TAUQ, represent*> the orthogonal matrix Q as a product of elementary*> reflectors, and the elements above the first superdiagonal,*> with the array TAUP, represent the orthogonal matrix P as*> a product of elementary reflectors;*> if m < n, the diagonal and the first subdiagonal are*> overwritten with the lower bidiagonal matrix B; the*> elements below the first subdiagonal, with the array TAUQ,*> represent the orthogonal matrix Q as a product of*> elementary reflectors, and the elements above the diagonal,*> with the array TAUP, represent the orthogonal matrix P as*> a product of elementary reflectors.*> See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (min(M,N))*> The diagonal elements of the bidiagonal matrix B:*> D(i) = A(i,i).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (min(M,N)-1)*> The off-diagonal elements of the bidiagonal matrix B:*> if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;*> if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.*> \endverbatim*>*> \param[out] TAUQ*> \verbatim*> TAUQ is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Q. See Further Details.*> \endverbatim*>*> \param[out] TAUP*> \verbatim*> TAUP is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix P. See Further Details.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (max(M,N))*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrices Q and P are represented as products of elementary*> reflectors:*>*> If m >= n,*>*> Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1)*>*> Each H(i) and G(i) has the form:*>*> H(i) = I - tauq * v * v**T and G(i) = I - taup * u * u**T*>*> where tauq and taup are real scalars, and v and u are real vectors;*> v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);*> u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);*> tauq is stored in TAUQ(i) and taup in TAUP(i).*>*> If m < n,*>*> Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m)*>*> Each H(i) and G(i) has the form:*>*> H(i) = I - tauq * v * v**T and G(i) = I - taup * u * u**T*>*> where tauq and taup are real scalars, and v and u are real vectors;*> v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);*> u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);*> tauq is stored in TAUQ(i) and taup in TAUP(i).*>*> The contents of A on exit are illustrated by the following examples:*>*> m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n):*>*> ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 )*> ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 )*> ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 )*> ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 )*> ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 )*> ( v1 v2 v3 v4 v5 )*>*> where d and e denote diagonal and off-diagonal elements of B, vi*> denotes an element of the vector defining H(i), and ui an element of*> the vector defining G(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEBD2( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),$ TAUQ( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.LT.0 ) THENCALL XERBLA( 'DGEBD2', -INFO )RETURNEND IF*IF( M.GE.N ) THEN** Reduce to upper bidiagonal form*DO 10 I = 1, N** Generate elementary reflector H(i) to annihilate A(i+1:m,i)*CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ TAUQ( I ) )D( I ) = A( I, I )A( I, I ) = ONE** Apply H(i) to A(i:m,i+1:n) from the left*IF( I.LT.N )$ CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAUQ( I ),$ A( I, I+1 ), LDA, WORK )A( I, I ) = D( I )*IF( I.LT.N ) THEN** Generate elementary reflector G(i) to annihilate* A(i,i+2:n)*CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),$ LDA, TAUP( I ) )E( I ) = A( I, I+1 )A( I, I+1 ) = ONE** Apply G(i) to A(i+1:m,i+1:n) from the right*CALL DLARF( 'Right', M-I, N-I, A( I, I+1 ), LDA,$ TAUP( I ), A( I+1, I+1 ), LDA, WORK )A( I, I+1 ) = E( I )ELSETAUP( I ) = ZEROEND IF10 CONTINUEELSE** Reduce to lower bidiagonal form*DO 20 I = 1, M** Generate elementary reflector G(i) to annihilate A(i,i+1:n)*CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,$ TAUP( I ) )D( I ) = A( I, I )A( I, I ) = ONE** Apply G(i) to A(i+1:m,i:n) from the right*IF( I.LT.M )$ CALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,$ TAUP( I ), A( I+1, I ), LDA, WORK )A( I, I ) = D( I )*IF( I.LT.M ) THEN** Generate elementary reflector H(i) to annihilate* A(i+2:m,i)*CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,$ TAUQ( I ) )E( I ) = A( I+1, I )A( I+1, I ) = ONE** Apply H(i) to A(i+1:m,i+1:n) from the left*CALL DLARF( 'Left', M-I, N-I, A( I+1, I ), 1, TAUQ( I ),$ A( I+1, I+1 ), LDA, WORK )A( I+1, I ) = E( I )ELSETAUQ( I ) = ZEROEND IF20 CONTINUEEND IFRETURN** End of DGEBD2*END*> \brief \b DGEBRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEBRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgebrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgebrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgebrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,* INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),* $ TAUQ( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEBRD reduces a general real M-by-N matrix A to upper or lower*> bidiagonal form B by an orthogonal transformation: Q**T * A * P = B.*>*> If m >= n, B is upper bidiagonal; if m < n, B is lower bidiagonal.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows in the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns in the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N general matrix to be reduced.*> On exit,*> if m >= n, the diagonal and the first superdiagonal are*> overwritten with the upper bidiagonal matrix B; the*> elements below the diagonal, with the array TAUQ, represent*> the orthogonal matrix Q as a product of elementary*> reflectors, and the elements above the first superdiagonal,*> with the array TAUP, represent the orthogonal matrix P as*> a product of elementary reflectors;*> if m < n, the diagonal and the first subdiagonal are*> overwritten with the lower bidiagonal matrix B; the*> elements below the first subdiagonal, with the array TAUQ,*> represent the orthogonal matrix Q as a product of*> elementary reflectors, and the elements above the diagonal,*> with the array TAUP, represent the orthogonal matrix P as*> a product of elementary reflectors.*> See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (min(M,N))*> The diagonal elements of the bidiagonal matrix B:*> D(i) = A(i,i).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (min(M,N)-1)*> The off-diagonal elements of the bidiagonal matrix B:*> if m >= n, E(i) = A(i,i+1) for i = 1,2,...,n-1;*> if m < n, E(i) = A(i+1,i) for i = 1,2,...,m-1.*> \endverbatim*>*> \param[out] TAUQ*> \verbatim*> TAUQ is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Q. See Further Details.*> \endverbatim*>*> \param[out] TAUP*> \verbatim*> TAUP is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix P. See Further Details.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of the array WORK. LWORK >= max(1,M,N).*> For optimum performance LWORK >= (M+N)*NB, where NB*> is the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrices Q and P are represented as products of elementary*> reflectors:*>*> If m >= n,*>*> Q = H(1) H(2) . . . H(n) and P = G(1) G(2) . . . G(n-1)*>*> Each H(i) and G(i) has the form:*>*> H(i) = I - tauq * v * v**T and G(i) = I - taup * u * u**T*>*> where tauq and taup are real scalars, and v and u are real vectors;*> v(1:i-1) = 0, v(i) = 1, and v(i+1:m) is stored on exit in A(i+1:m,i);*> u(1:i) = 0, u(i+1) = 1, and u(i+2:n) is stored on exit in A(i,i+2:n);*> tauq is stored in TAUQ(i) and taup in TAUP(i).*>*> If m < n,*>*> Q = H(1) H(2) . . . H(m-1) and P = G(1) G(2) . . . G(m)*>*> Each H(i) and G(i) has the form:*>*> H(i) = I - tauq * v * v**T and G(i) = I - taup * u * u**T*>*> where tauq and taup are real scalars, and v and u are real vectors;*> v(1:i) = 0, v(i+1) = 1, and v(i+2:m) is stored on exit in A(i+2:m,i);*> u(1:i-1) = 0, u(i) = 1, and u(i+1:n) is stored on exit in A(i,i+1:n);*> tauq is stored in TAUQ(i) and taup in TAUP(i).*>*> The contents of A on exit are illustrated by the following examples:*>*> m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n):*>*> ( d e u1 u1 u1 ) ( d u1 u1 u1 u1 u1 )*> ( v1 d e u2 u2 ) ( e d u2 u2 u2 u2 )*> ( v1 v2 d e u3 ) ( v1 e d u3 u3 u3 )*> ( v1 v2 v3 d e ) ( v1 v2 e d u4 u4 )*> ( v1 v2 v3 v4 d ) ( v1 v2 v3 e d u5 )*> ( v1 v2 v3 v4 v5 )*>*> where d and e denote diagonal and off-diagonal elements of B, vi*> denotes an element of the vector defining H(i), and ui an element of*> the vector defining G(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEBRD( M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK,$ INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),$ TAUQ( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IINFO, J, LDWRKX, LDWRKY, LWKOPT, MINMN, NB,$ NBMIN, NX, WS* ..* .. External Subroutines ..EXTERNAL DGEBD2, DGEMM, DLABRD, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB = MAX( 1, ILAENV( 1, 'DGEBRD', ' ', M, N, -1, -1 ) )LWKOPT = ( M+N )*NBWORK( 1 ) = DBLE( LWKOPT )LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, M, N ) .AND. .NOT.LQUERY ) THENINFO = -10END IFIF( INFO.LT.0 ) THENCALL XERBLA( 'DGEBRD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*MINMN = MIN( M, N )IF( MINMN.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*WS = MAX( M, N )LDWRKX = MLDWRKY = N*IF( NB.GT.1 .AND. NB.LT.MINMN ) THEN** Set the crossover point NX.*NX = MAX( NB, ILAENV( 3, 'DGEBRD', ' ', M, N, -1, -1 ) )** Determine when to switch from blocked to unblocked code.*IF( NX.LT.MINMN ) THENWS = ( M+N )*NBIF( LWORK.LT.WS ) THEN** Not enough work space for the optimal NB, consider using* a smaller block size.*NBMIN = ILAENV( 2, 'DGEBRD', ' ', M, N, -1, -1 )IF( LWORK.GE.( M+N )*NBMIN ) THENNB = LWORK / ( M+N )ELSENB = 1NX = MINMNEND IFEND IFEND IFELSENX = MINMNEND IF*DO 30 I = 1, MINMN - NX, NB** Reduce rows and columns i:i+nb-1 to bidiagonal form and return* the matrices X and Y which are needed to update the unreduced* part of the matrix*CALL DLABRD( M-I+1, N-I+1, NB, A( I, I ), LDA, D( I ), E( I ),$ TAUQ( I ), TAUP( I ), WORK, LDWRKX,$ WORK( LDWRKX*NB+1 ), LDWRKY )** Update the trailing submatrix A(i+nb:m,i+nb:n), using an update* of the form A := A - V*Y**T - X*U**T*CALL DGEMM( 'No transpose', 'Transpose', M-I-NB+1, N-I-NB+1,$ NB, -ONE, A( I+NB, I ), LDA,$ WORK( LDWRKX*NB+NB+1 ), LDWRKY, ONE,$ A( I+NB, I+NB ), LDA )CALL DGEMM( 'No transpose', 'No transpose', M-I-NB+1, N-I-NB+1,$ NB, -ONE, WORK( NB+1 ), LDWRKX, A( I, I+NB ), LDA,$ ONE, A( I+NB, I+NB ), LDA )** Copy diagonal and off-diagonal elements of B back into A*IF( M.GE.N ) THENDO 10 J = I, I + NB - 1A( J, J ) = D( J )A( J, J+1 ) = E( J )10 CONTINUEELSEDO 20 J = I, I + NB - 1A( J, J ) = D( J )A( J+1, J ) = E( J )20 CONTINUEEND IF30 CONTINUE** Use unblocked code to reduce the remainder of the matrix*CALL DGEBD2( M-I+1, N-I+1, A( I, I ), LDA, D( I ), E( I ),$ TAUQ( I ), TAUP( I ), WORK, IINFO )WORK( 1 ) = WSRETURN** End of DGEBRD*END*> \brief \b DGECON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGECON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgecon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgecon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgecon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER INFO, LDA, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGECON estimates the reciprocal of the condition number of a general*> real matrix A, in either the 1-norm or the infinity-norm, using*> the LU factorization computed by DGETRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as*> RCOND = 1 / ( norm(A) * norm(inv(A)) ).*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies whether the 1-norm condition number or the*> infinity-norm condition number is required:*> = '1' or 'O': 1-norm;*> = 'I': Infinity-norm.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The factors L and U from the factorization A = P*L*U*> as computed by DGETRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> If NORM = '1' or 'O', the 1-norm of the original matrix A.*> If NORM = 'I', the infinity-norm of the original matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(norm(A) * norm(inv(A))).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGECON( NORM, N, A, LDA, ANORM, RCOND, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER INFO, LDA, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ONENRMCHARACTER NORMININTEGER IX, KASE, KASE1DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL LSAME, IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATRS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( ANORM.LT.ZERO ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGECON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the norm of inv(A).*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 010 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(L).*CALL DLATRS( 'Lower', 'No transpose', 'Unit', NORMIN, N, A,$ LDA, WORK, SL, WORK( 2*N+1 ), INFO )** Multiply by inv(U).*CALL DLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ A, LDA, WORK, SU, WORK( 3*N+1 ), INFO )ELSE** Multiply by inv(U**T).*CALL DLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,$ LDA, WORK, SU, WORK( 3*N+1 ), INFO )** Multiply by inv(L**T).*CALL DLATRS( 'Lower', 'Transpose', 'Unit', NORMIN, N, A,$ LDA, WORK, SL, WORK( 2*N+1 ), INFO )END IF** Divide X by 1/(SL*SU) if doing so will not cause overflow.*SCALE = SL*SUNORMIN = 'Y'IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*20 CONTINUERETURN** End of DGECON*END*> \brief \b DGEEQU** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEEQU + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeequ.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeequ.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeequ.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEEQU( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,* INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* DOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEEQU computes row and column scalings intended to equilibrate an*> M-by-N matrix A and reduce its condition number. R returns the row*> scale factors and C the column scale factors, chosen to try to make*> the largest element in each row and column of the matrix B with*> elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1.*>*> R(i) and C(j) are restricted to be between SMLNUM = smallest safe*> number and BIGNUM = largest safe number. Use of these scaling*> factors is not guaranteed to reduce the condition number of A but*> works well in practice.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The M-by-N matrix whose equilibration factors are*> to be computed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (M)*> If INFO = 0 or INFO > M, R contains the row scale factors*> for A.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, C contains the column scale factors for A.*> \endverbatim*>*> \param[out] ROWCND*> \verbatim*> ROWCND is DOUBLE PRECISION*> If INFO = 0 or INFO > M, ROWCND contains the ratio of the*> smallest R(i) to the largest R(i). If ROWCND >= 0.1 and*> AMAX is neither too large nor too small, it is not worth*> scaling by R.*> \endverbatim*>*> \param[out] COLCND*> \verbatim*> COLCND is DOUBLE PRECISION*> If INFO = 0, COLCND contains the ratio of the smallest*> C(i) to the largest C(i). If COLCND >= 0.1, it is not*> worth scaling by C.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= M: the i-th row of A is exactly zero*> > M: the (i-M)-th column of A is exactly zero*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGEEQU( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION BIGNUM, RCMAX, RCMIN, SMLNUM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEQU', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENROWCND = ONECOLCND = ONEAMAX = ZERORETURNEND IF** Get machine constants.*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUM** Compute row scale factors.*DO 10 I = 1, MR( I ) = ZERO10 CONTINUE** Find the maximum element in each row.*DO 30 J = 1, NDO 20 I = 1, MR( I ) = MAX( R( I ), ABS( A( I, J ) ) )20 CONTINUE30 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 40 I = 1, MRCMAX = MAX( RCMAX, R( I ) )RCMIN = MIN( RCMIN, R( I ) )40 CONTINUEAMAX = RCMAX*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 50 I = 1, MIF( R( I ).EQ.ZERO ) THENINFO = IRETURNEND IF50 CONTINUEELSE** Invert the scale factors.*DO 60 I = 1, MR( I ) = ONE / MIN( MAX( R( I ), SMLNUM ), BIGNUM )60 CONTINUE** Compute ROWCND = min(R(I)) / max(R(I))*ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF** Compute column scale factors*DO 70 J = 1, NC( J ) = ZERO70 CONTINUE** Find the maximum element in each column,* assuming the row scaling computed above.*DO 90 J = 1, NDO 80 I = 1, MC( J ) = MAX( C( J ), ABS( A( I, J ) )*R( I ) )80 CONTINUE90 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 100 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )100 CONTINUE*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 110 J = 1, NIF( C( J ).EQ.ZERO ) THENINFO = M + JRETURNEND IF110 CONTINUEELSE** Invert the scale factors.*DO 120 J = 1, NC( J ) = ONE / MIN( MAX( C( J ), SMLNUM ), BIGNUM )120 CONTINUE** Compute COLCND = min(C(J)) / max(C(J))*COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF*RETURN** End of DGEEQU*END*> \brief \b DGEEQUB** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEEQUB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeequb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeequb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeequb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEEQUB( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,* INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* DOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEEQUB computes row and column scalings intended to equilibrate an*> M-by-N matrix A and reduce its condition number. R returns the row*> scale factors and C the column scale factors, chosen to try to make*> the largest element in each row and column of the matrix B with*> elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most*> the radix.*>*> R(i) and C(j) are restricted to be a power of the radix between*> SMLNUM = smallest safe number and BIGNUM = largest safe number. Use*> of these scaling factors is not guaranteed to reduce the condition*> number of A but works well in practice.*>*> This routine differs from DGEEQU by restricting the scaling factors*> to a power of the radix. Barring over- and underflow, scaling by*> these factors introduces no additional rounding errors. However, the*> scaled entries' magnitudes are no longer approximately 1 but lie*> between sqrt(radix) and 1/sqrt(radix).*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The M-by-N matrix whose equilibration factors are*> to be computed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (M)*> If INFO = 0 or INFO > M, R contains the row scale factors*> for A.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, C contains the column scale factors for A.*> \endverbatim*>*> \param[out] ROWCND*> \verbatim*> ROWCND is DOUBLE PRECISION*> If INFO = 0 or INFO > M, ROWCND contains the ratio of the*> smallest R(i) to the largest R(i). If ROWCND >= 0.1 and*> AMAX is neither too large nor too small, it is not worth*> scaling by R.*> \endverbatim*>*> \param[out] COLCND*> \verbatim*> COLCND is DOUBLE PRECISION*> If INFO = 0, COLCND contains the ratio of the smallest*> C(i) to the largest C(i). If COLCND >= 0.1, it is not*> worth scaling by C.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= M: the i-th row of A is exactly zero*> > M: the (i-M)-th column of A is exactly zero*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGEEQUB( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION BIGNUM, RCMAX, RCMIN, SMLNUM, RADIX, LOGRDX* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, LOG* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEQUB', -INFO )RETURNEND IF** Quick return if possible.*IF( M.EQ.0 .OR. N.EQ.0 ) THENROWCND = ONECOLCND = ONEAMAX = ZERORETURNEND IF** Get machine constants. Assume SMLNUM is a power of the radix.*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMRADIX = DLAMCH( 'B' )LOGRDX = LOG( RADIX )** Compute row scale factors.*DO 10 I = 1, MR( I ) = ZERO10 CONTINUE** Find the maximum element in each row.*DO 30 J = 1, NDO 20 I = 1, MR( I ) = MAX( R( I ), ABS( A( I, J ) ) )20 CONTINUE30 CONTINUEDO I = 1, MIF( R( I ).GT.ZERO ) THENR( I ) = RADIX**INT( LOG( R( I ) ) / LOGRDX )END IFEND DO** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 40 I = 1, MRCMAX = MAX( RCMAX, R( I ) )RCMIN = MIN( RCMIN, R( I ) )40 CONTINUEAMAX = RCMAX*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 50 I = 1, MIF( R( I ).EQ.ZERO ) THENINFO = IRETURNEND IF50 CONTINUEELSE** Invert the scale factors.*DO 60 I = 1, MR( I ) = ONE / MIN( MAX( R( I ), SMLNUM ), BIGNUM )60 CONTINUE** Compute ROWCND = min(R(I)) / max(R(I)).*ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF** Compute column scale factors*DO 70 J = 1, NC( J ) = ZERO70 CONTINUE** Find the maximum element in each column,* assuming the row scaling computed above.*DO 90 J = 1, NDO 80 I = 1, MC( J ) = MAX( C( J ), ABS( A( I, J ) )*R( I ) )80 CONTINUEIF( C( J ).GT.ZERO ) THENC( J ) = RADIX**INT( LOG( C( J ) ) / LOGRDX )END IF90 CONTINUE** Find the maximum and minimum scale factors.*RCMIN = BIGNUMRCMAX = ZERODO 100 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )100 CONTINUE*IF( RCMIN.EQ.ZERO ) THEN** Find the first zero scale factor and return an error code.*DO 110 J = 1, NIF( C( J ).EQ.ZERO ) THENINFO = M + JRETURNEND IF110 CONTINUEELSE** Invert the scale factors.*DO 120 J = 1, NC( J ) = ONE / MIN( MAX( C( J ), SMLNUM ), BIGNUM )120 CONTINUE** Compute COLCND = min(C(J)) / max(C(J)).*COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )END IF*RETURN** End of DGEEQUB*END*> \brief <b> DGEES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEES + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgees.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgees.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgees.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,* VS, LDVS, WORK, LWORK, BWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVS, SORT* INTEGER INFO, LDA, LDVS, LWORK, N, SDIM* ..* .. Array Arguments ..* LOGICAL BWORK( * )* DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),* $ WR( * )* ..* .. Function Arguments ..* LOGICAL SELECT* EXTERNAL SELECT* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEES computes for an N-by-N real nonsymmetric matrix A, the*> eigenvalues, the real Schur form T, and, optionally, the matrix of*> Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).*>*> Optionally, it also orders the eigenvalues on the diagonal of the*> real Schur form so that selected eigenvalues are at the top left.*> The leading columns of Z then form an orthonormal basis for the*> invariant subspace corresponding to the selected eigenvalues.*>*> A matrix is in real Schur form if it is upper quasi-triangular with*> 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in the*> form*> [ a b ]*> [ c a ]*>*> where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).*> \endverbatim** Arguments:* ==========**> \param[in] JOBVS*> \verbatim*> JOBVS is CHARACTER*1*> = 'N': Schur vectors are not computed;*> = 'V': Schur vectors are computed.*> \endverbatim*>*> \param[in] SORT*> \verbatim*> SORT is CHARACTER*1*> Specifies whether or not to order the eigenvalues on the*> diagonal of the Schur form.*> = 'N': Eigenvalues are not ordered;*> = 'S': Eigenvalues are ordered (see SELECT).*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is a LOGICAL FUNCTION of two DOUBLE PRECISION arguments*> SELECT must be declared EXTERNAL in the calling subroutine.*> If SORT = 'S', SELECT is used to select eigenvalues to sort*> to the top left of the Schur form.*> If SORT = 'N', SELECT is not referenced.*> An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if*> SELECT(WR(j),WI(j)) is true; i.e., if either one of a complex*> conjugate pair of eigenvalues is selected, then both complex*> eigenvalues are selected.*> Note that a selected complex eigenvalue may no longer*> satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since*> ordering may change the value of complex eigenvalues*> (especially if the eigenvalue is ill-conditioned); in this*> case INFO is set to N+2 (see INFO below).*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the N-by-N matrix A.*> On exit, A has been overwritten by its real Schur form T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] SDIM*> \verbatim*> SDIM is INTEGER*> If SORT = 'N', SDIM = 0.*> If SORT = 'S', SDIM = number of eigenvalues (after sorting)*> for which SELECT is true. (Complex conjugate*> pairs for which SELECT is true for either*> eigenvalue count as 2.)*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*> WR and WI contain the real and imaginary parts,*> respectively, of the computed eigenvalues in the same order*> that they appear on the diagonal of the output Schur form T.*> Complex conjugate pairs of eigenvalues will appear*> consecutively with the eigenvalue having the positive*> imaginary part first.*> \endverbatim*>*> \param[out] VS*> \verbatim*> VS is DOUBLE PRECISION array, dimension (LDVS,N)*> If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur*> vectors.*> If JOBVS = 'N', VS is not referenced.*> \endverbatim*>*> \param[in] LDVS*> \verbatim*> LDVS is INTEGER*> The leading dimension of the array VS. LDVS >= 1; if*> JOBVS = 'V', LDVS >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) contains the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,3*N).*> For good performance, LWORK must generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] BWORK*> \verbatim*> BWORK is LOGICAL array, dimension (N)*> Not referenced if SORT = 'N'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, and i is*> <= N: the QR algorithm failed to compute all the*> eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI*> contain those eigenvalues which have converged; if*> JOBVS = 'V', VS contains the matrix which reduces A*> to its partially converged Schur form.*> = N+1: the eigenvalues could not be reordered because some*> eigenvalues were too close to separate (the problem*> is very ill-conditioned);*> = N+2: after reordering, roundoff changed values of some*> complex eigenvalues so that leading eigenvalues in*> the Schur form no longer satisfy SELECT=.TRUE. This*> could also be caused by underflow due to scaling.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,$ VS, LDVS, WORK, LWORK, BWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBVS, SORTINTEGER INFO, LDA, LDVS, LWORK, N, SDIM* ..* .. Array Arguments ..LOGICAL BWORK( * )DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),$ WR( * )* ..* .. Function Arguments ..LOGICAL SELECTEXTERNAL SELECT* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTST,$ WANTVSINTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,$ IHI, ILO, INXT, IP, ITAU, IWRK, MAXWRK, MINWRKDOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM* ..* .. Local Arrays ..INTEGER IDUM( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,$ DLABAD, DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )WANTVS = LSAME( JOBVS, 'V' )WANTST = LSAME( SORT, 'S' )IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THENINFO = -1ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THENINFO = -11END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.)*IF( INFO.EQ.0 ) THENIF( N.EQ.0 ) THENMINWRK = 1MAXWRK = 1ELSEMAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )MINWRK = 3*N*CALL DHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,$ WORK, -1, IEVAL )HSWORK = WORK( 1 )*IF( .NOT.WANTVS ) THENMAXWRK = MAX( MAXWRK, N + HSWORK )ELSEMAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,$ 'DORGHR', ' ', N, 1, N, -1 ) )MAXWRK = MAX( MAXWRK, N + HSWORK )END IFEND IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -13END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEES ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSDIM = 0RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Permute the matrix to make it more nearly triangular* (Workspace: need N)*IBAL = 1CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )** Reduce to upper Hessenberg form* (Workspace: need 3*N, prefer 2*N+N*NB)*ITAU = N + IBALIWRK = N + ITAUCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVS ) THEN** Copy Householder vectors to VS*CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )** Generate orthogonal matrix in VS* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )END IF*SDIM = 0** Perform QR iteration, accumulating Schur vectors in VS if desired* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,$ WORK( IWRK ), LWORK-IWRK+1, IEVAL )IF( IEVAL.GT.0 )$ INFO = IEVAL** Sort eigenvalues if desired*IF( WANTST .AND. INFO.EQ.0 ) THENIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )END IFDO 10 I = 1, NBWORK( I ) = SELECT( WR( I ), WI( I ) )10 CONTINUE** Reorder eigenvalues and transform Schur vectors* (Workspace: none needed)*CALL DTRSEN( 'N', JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,$ SDIM, S, SEP, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,$ ICOND )IF( ICOND.GT.0 )$ INFO = N + ICONDEND IF*IF( WANTVS ) THEN** Undo balancing* (Workspace: need N)*CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,$ IERR )END IF*IF( SCALEA ) THEN** Undo scaling for the Schur form of A*CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )CALL DCOPY( N, A, LDA+1, WR, 1 )IF( CSCALE.EQ.SMLNUM ) THEN** If scaling back towards underflow, adjust WI if an* offdiagonal element of a 2-by-2 block in the Schur form* underflows.*IF( IEVAL.GT.0 ) THENI1 = IEVAL + 1I2 = IHI - 1CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI,$ MAX( ILO-1, 1 ), IERR )ELSE IF( WANTST ) THENI1 = 1I2 = N - 1ELSEI1 = ILOI2 = IHI - 1END IFINXT = I1 - 1DO 20 I = I1, I2IF( I.LT.INXT )$ GO TO 20IF( WI( I ).EQ.ZERO ) THENINXT = I + 1ELSEIF( A( I+1, I ).EQ.ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.$ ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROIF( I.GT.1 )$ CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )IF( N.GT.I+1 )$ CALL DSWAP( N-I-1, A( I, I+2 ), LDA,$ A( I+1, I+2 ), LDA )IF( WANTVS ) THENCALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )END IFA( I, I+1 ) = A( I+1, I )A( I+1, I ) = ZEROEND IFINXT = I + 2END IF20 CONTINUEEND IF** Undo scaling for the imaginary part of the eigenvalues*CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,$ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )END IF*IF( WANTST .AND. INFO.EQ.0 ) THEN** Check if reordering successful*LASTSL = .TRUE.LST2SL = .TRUE.SDIM = 0IP = 0DO 30 I = 1, NCURSL = SELECT( WR( I ), WI( I ) )IF( WI( I ).EQ.ZERO ) THENIF( CURSL )$ SDIM = SDIM + 1IP = 0IF( CURSL .AND. .NOT.LASTSL )$ INFO = N + 2ELSEIF( IP.EQ.1 ) THEN** Last eigenvalue of conjugate pair*CURSL = CURSL .OR. LASTSLLASTSL = CURSLIF( CURSL )$ SDIM = SDIM + 2IP = -1IF( CURSL .AND. .NOT.LST2SL )$ INFO = N + 2ELSE** First eigenvalue of conjugate pair*IP = 1END IFEND IFLST2SL = LASTSLLASTSL = CURSL30 CONTINUEEND IF*WORK( 1 ) = MAXWRKRETURN** End of DGEES*END*> \brief <b> DGEESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEESX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeesx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeesx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeesx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,* WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,* IWORK, LIWORK, BWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVS, SENSE, SORT* INTEGER INFO, LDA, LDVS, LIWORK, LWORK, N, SDIM* DOUBLE PRECISION RCONDE, RCONDV* ..* .. Array Arguments ..* LOGICAL BWORK( * )* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),* $ WR( * )* ..* .. Function Arguments ..* LOGICAL SELECT* EXTERNAL SELECT* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEESX computes for an N-by-N real nonsymmetric matrix A, the*> eigenvalues, the real Schur form T, and, optionally, the matrix of*> Schur vectors Z. This gives the Schur factorization A = Z*T*(Z**T).*>*> Optionally, it also orders the eigenvalues on the diagonal of the*> real Schur form so that selected eigenvalues are at the top left;*> computes a reciprocal condition number for the average of the*> selected eigenvalues (RCONDE); and computes a reciprocal condition*> number for the right invariant subspace corresponding to the*> selected eigenvalues (RCONDV). The leading columns of Z form an*> orthonormal basis for this invariant subspace.*>*> For further explanation of the reciprocal condition numbers RCONDE*> and RCONDV, see Section 4.10 of the LAPACK Users' Guide (where*> these quantities are called s and sep respectively).*>*> A real matrix is in real Schur form if it is upper quasi-triangular*> with 1-by-1 and 2-by-2 blocks. 2-by-2 blocks will be standardized in*> the form*> [ a b ]*> [ c a ]*>*> where b*c < 0. The eigenvalues of such a block are a +- sqrt(bc).*> \endverbatim** Arguments:* ==========**> \param[in] JOBVS*> \verbatim*> JOBVS is CHARACTER*1*> = 'N': Schur vectors are not computed;*> = 'V': Schur vectors are computed.*> \endverbatim*>*> \param[in] SORT*> \verbatim*> SORT is CHARACTER*1*> Specifies whether or not to order the eigenvalues on the*> diagonal of the Schur form.*> = 'N': Eigenvalues are not ordered;*> = 'S': Eigenvalues are ordered (see SELECT).*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is a LOGICAL FUNCTION of two DOUBLE PRECISION arguments*> SELECT must be declared EXTERNAL in the calling subroutine.*> If SORT = 'S', SELECT is used to select eigenvalues to sort*> to the top left of the Schur form.*> If SORT = 'N', SELECT is not referenced.*> An eigenvalue WR(j)+sqrt(-1)*WI(j) is selected if*> SELECT(WR(j),WI(j)) is true; i.e., if either one of a*> complex conjugate pair of eigenvalues is selected, then both*> are. Note that a selected complex eigenvalue may no longer*> satisfy SELECT(WR(j),WI(j)) = .TRUE. after ordering, since*> ordering may change the value of complex eigenvalues*> (especially if the eigenvalue is ill-conditioned); in this*> case INFO may be set to N+3 (see INFO below).*> \endverbatim*>*> \param[in] SENSE*> \verbatim*> SENSE is CHARACTER*1*> Determines which reciprocal condition numbers are computed.*> = 'N': None are computed;*> = 'E': Computed for average of selected eigenvalues only;*> = 'V': Computed for selected right invariant subspace only;*> = 'B': Computed for both.*> If SENSE = 'E', 'V' or 'B', SORT must equal 'S'.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the N-by-N matrix A.*> On exit, A is overwritten by its real Schur form T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] SDIM*> \verbatim*> SDIM is INTEGER*> If SORT = 'N', SDIM = 0.*> If SORT = 'S', SDIM = number of eigenvalues (after sorting)*> for which SELECT is true. (Complex conjugate*> pairs for which SELECT is true for either*> eigenvalue count as 2.)*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*> WR and WI contain the real and imaginary parts, respectively,*> of the computed eigenvalues, in the same order that they*> appear on the diagonal of the output Schur form T. Complex*> conjugate pairs of eigenvalues appear consecutively with the*> eigenvalue having the positive imaginary part first.*> \endverbatim*>*> \param[out] VS*> \verbatim*> VS is DOUBLE PRECISION array, dimension (LDVS,N)*> If JOBVS = 'V', VS contains the orthogonal matrix Z of Schur*> vectors.*> If JOBVS = 'N', VS is not referenced.*> \endverbatim*>*> \param[in] LDVS*> \verbatim*> LDVS is INTEGER*> The leading dimension of the array VS. LDVS >= 1, and if*> JOBVS = 'V', LDVS >= N.*> \endverbatim*>*> \param[out] RCONDE*> \verbatim*> RCONDE is DOUBLE PRECISION*> If SENSE = 'E' or 'B', RCONDE contains the reciprocal*> condition number for the average of the selected eigenvalues.*> Not referenced if SENSE = 'N' or 'V'.*> \endverbatim*>*> \param[out] RCONDV*> \verbatim*> RCONDV is DOUBLE PRECISION*> If SENSE = 'V' or 'B', RCONDV contains the reciprocal*> condition number for the selected right invariant subspace.*> Not referenced if SENSE = 'N' or 'E'.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,3*N).*> Also, if SENSE = 'E' or 'V' or 'B',*> LWORK >= N+2*SDIM*(N-SDIM), where SDIM is the number of*> selected eigenvalues computed by this routine. Note that*> N+2*SDIM*(N-SDIM) <= N+N*N/2. Note also that an error is only*> returned if LWORK < max(1,3*N), but if SENSE = 'E' or 'V' or*> 'B' this may not be large enough.*> For good performance, LWORK must generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates upper bounds on the optimal sizes of the*> arrays WORK and IWORK, returns these values as the first*> entries of the WORK and IWORK arrays, and no error messages*> related to LWORK or LIWORK are issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> LIWORK >= 1; if SENSE = 'V' or 'B', LIWORK >= SDIM*(N-SDIM).*> Note that SDIM*(N-SDIM) <= N*N/4. Note also that an error is*> only returned if LIWORK < 1, but if SENSE = 'V' or 'B' this*> may not be large enough.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates upper bounds on the optimal sizes of*> the arrays WORK and IWORK, returns these values as the first*> entries of the WORK and IWORK arrays, and no error messages*> related to LWORK or LIWORK are issued by XERBLA.*> \endverbatim*>*> \param[out] BWORK*> \verbatim*> BWORK is LOGICAL array, dimension (N)*> Not referenced if SORT = 'N'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, and i is*> <= N: the QR algorithm failed to compute all the*> eigenvalues; elements 1:ILO-1 and i+1:N of WR and WI*> contain those eigenvalues which have converged; if*> JOBVS = 'V', VS contains the transformation which*> reduces A to its partially converged Schur form.*> = N+1: the eigenvalues could not be reordered because some*> eigenvalues were too close to separate (the problem*> is very ill-conditioned);*> = N+2: after reordering, roundoff changed values of some*> complex eigenvalues so that leading eigenvalues in*> the Schur form no longer satisfy SELECT=.TRUE. This*> could also be caused by underflow due to scaling.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGEESX( JOBVS, SORT, SELECT, SENSE, N, A, LDA, SDIM,$ WR, WI, VS, LDVS, RCONDE, RCONDV, WORK, LWORK,$ IWORK, LIWORK, BWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBVS, SENSE, SORTINTEGER INFO, LDA, LDVS, LIWORK, LWORK, N, SDIMDOUBLE PRECISION RCONDE, RCONDV* ..* .. Array Arguments ..LOGICAL BWORK( * )INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),$ WR( * )* ..* .. Function Arguments ..LOGICAL SELECTEXTERNAL SELECT* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTSB,$ WANTSE, WANTSN, WANTST, WANTSV, WANTVSINTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,$ IHI, ILO, INXT, IP, ITAU, IWRK, LIWRK, LWRK,$ MAXWRK, MINWRKDOUBLE PRECISION ANRM, BIGNUM, CSCALE, EPS, SMLNUM* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLACPY,$ DLASCL, DORGHR, DSWAP, DTRSEN, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLABAD, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0WANTVS = LSAME( JOBVS, 'V' )WANTST = LSAME( SORT, 'S' )WANTSN = LSAME( SENSE, 'N' )WANTSE = LSAME( SENSE, 'E' )WANTSV = LSAME( SENSE, 'V' )WANTSB = LSAME( SENSE, 'B' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THENINFO = -1ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.$ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THENINFO = -12END IF** Compute workspace* (Note: Comments in the code beginning "RWorkspace:" describe the* minimal amount of real workspace needed at that point in the* code, as well as the preferred amount for good performance.* IWorkspace refers to integer workspace.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.* If SENSE = 'E', 'V' or 'B', then the amount of workspace needed* depends on SDIM, which is computed by the routine DTRSEN later* in the code.)*IF( INFO.EQ.0 ) THENLIWRK = 1IF( N.EQ.0 ) THENMINWRK = 1LWRK = 1ELSEMAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )MINWRK = 3*N*CALL DHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,$ WORK, -1, IEVAL )HSWORK = WORK( 1 )*IF( .NOT.WANTVS ) THENMAXWRK = MAX( MAXWRK, N + HSWORK )ELSEMAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,$ 'DORGHR', ' ', N, 1, N, -1 ) )MAXWRK = MAX( MAXWRK, N + HSWORK )END IFLWRK = MAXWRKIF( .NOT.WANTSN )$ LWRK = MAX( LWRK, N + ( N*N )/2 )IF( WANTSV .OR. WANTSB )$ LIWRK = ( N*N )/4END IFIWORK( 1 ) = LIWRKWORK( 1 ) = LWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -16ELSE IF( LIWORK.LT.1 .AND. .NOT.LQUERY ) THENINFO = -18END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEESX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSDIM = 0RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Permute the matrix to make it more nearly triangular* (RWorkspace: need N)*IBAL = 1CALL DGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )** Reduce to upper Hessenberg form* (RWorkspace: need 3*N, prefer 2*N+N*NB)*ITAU = N + IBALIWRK = N + ITAUCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVS ) THEN** Copy Householder vectors to VS*CALL DLACPY( 'L', N, N, A, LDA, VS, LDVS )** Generate orthogonal matrix in VS* (RWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )END IF*SDIM = 0** Perform QR iteration, accumulating Schur vectors in VS if desired* (RWorkspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,$ WORK( IWRK ), LWORK-IWRK+1, IEVAL )IF( IEVAL.GT.0 )$ INFO = IEVAL** Sort eigenvalues if desired*IF( WANTST .AND. INFO.EQ.0 ) THENIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )END IFDO 10 I = 1, NBWORK( I ) = SELECT( WR( I ), WI( I ) )10 CONTINUE** Reorder eigenvalues, transform Schur vectors, and compute* reciprocal condition numbers* (RWorkspace: if SENSE is not 'N', need N+2*SDIM*(N-SDIM)* otherwise, need N )* (IWorkspace: if SENSE is 'V' or 'B', need SDIM*(N-SDIM)* otherwise, need 0 )*CALL DTRSEN( SENSE, JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,$ SDIM, RCONDE, RCONDV, WORK( IWRK ), LWORK-IWRK+1,$ IWORK, LIWORK, ICOND )IF( .NOT.WANTSN )$ MAXWRK = MAX( MAXWRK, N+2*SDIM*( N-SDIM ) )IF( ICOND.EQ.-15 ) THEN** Not enough real workspace*INFO = -16ELSE IF( ICOND.EQ.-17 ) THEN** Not enough integer workspace*INFO = -18ELSE IF( ICOND.GT.0 ) THEN** DTRSEN failed to reorder or to restore standard Schur form*INFO = ICOND + NEND IFEND IF*IF( WANTVS ) THEN** Undo balancing* (RWorkspace: need N)*CALL DGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,$ IERR )END IF*IF( SCALEA ) THEN** Undo scaling for the Schur form of A*CALL DLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )CALL DCOPY( N, A, LDA+1, WR, 1 )IF( ( WANTSV .OR. WANTSB ) .AND. INFO.EQ.0 ) THENDUM( 1 ) = RCONDVCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )RCONDV = DUM( 1 )END IFIF( CSCALE.EQ.SMLNUM ) THEN** If scaling back towards underflow, adjust WI if an* offdiagonal element of a 2-by-2 block in the Schur form* underflows.*IF( IEVAL.GT.0 ) THENI1 = IEVAL + 1I2 = IHI - 1CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,$ IERR )ELSE IF( WANTST ) THENI1 = 1I2 = N - 1ELSEI1 = ILOI2 = IHI - 1END IFINXT = I1 - 1DO 20 I = I1, I2IF( I.LT.INXT )$ GO TO 20IF( WI( I ).EQ.ZERO ) THENINXT = I + 1ELSEIF( A( I+1, I ).EQ.ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.$ ZERO ) THENWI( I ) = ZEROWI( I+1 ) = ZEROIF( I.GT.1 )$ CALL DSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )IF( N.GT.I+1 )$ CALL DSWAP( N-I-1, A( I, I+2 ), LDA,$ A( I+1, I+2 ), LDA )CALL DSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )A( I, I+1 ) = A( I+1, I )A( I+1, I ) = ZEROEND IFINXT = I + 2END IF20 CONTINUEEND IFCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,$ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )END IF*IF( WANTST .AND. INFO.EQ.0 ) THEN** Check if reordering successful*LASTSL = .TRUE.LST2SL = .TRUE.SDIM = 0IP = 0DO 30 I = 1, NCURSL = SELECT( WR( I ), WI( I ) )IF( WI( I ).EQ.ZERO ) THENIF( CURSL )$ SDIM = SDIM + 1IP = 0IF( CURSL .AND. .NOT.LASTSL )$ INFO = N + 2ELSEIF( IP.EQ.1 ) THEN** Last eigenvalue of conjugate pair*CURSL = CURSL .OR. LASTSLLASTSL = CURSLIF( CURSL )$ SDIM = SDIM + 2IP = -1IF( CURSL .AND. .NOT.LST2SL )$ INFO = N + 2ELSE** First eigenvalue of conjugate pair*IP = 1END IFEND IFLST2SL = LASTSLLASTSL = CURSL30 CONTINUEEND IF*WORK( 1 ) = MAXWRKIF( WANTSV .OR. WANTSB ) THENIWORK( 1 ) = MAX( 1, SDIM*( N-SDIM ) )ELSEIWORK( 1 ) = 1END IF*RETURN** End of DGEESX*END*> \brief <b> DGEEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEEV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeev.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeev.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeev.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,* LDVR, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVL, JOBVR* INTEGER INFO, LDA, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),* $ WI( * ), WORK( * ), WR( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEEV computes for an N-by-N real nonsymmetric matrix A, the*> eigenvalues and, optionally, the left and/or right eigenvectors.*>*> The right eigenvector v(j) of A satisfies*> A * v(j) = lambda(j) * v(j)*> where lambda(j) is its eigenvalue.*> The left eigenvector u(j) of A satisfies*> u(j)**H * A = lambda(j) * u(j)**H*> where u(j)**H denotes the conjugate-transpose of u(j).*>*> The computed eigenvectors are normalized to have Euclidean norm*> equal to 1 and largest component real.*> \endverbatim** Arguments:* ==========**> \param[in] JOBVL*> \verbatim*> JOBVL is CHARACTER*1*> = 'N': left eigenvectors of A are not computed;*> = 'V': left eigenvectors of A are computed.*> \endverbatim*>*> \param[in] JOBVR*> \verbatim*> JOBVR is CHARACTER*1*> = 'N': right eigenvectors of A are not computed;*> = 'V': right eigenvectors of A are computed.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the N-by-N matrix A.*> On exit, A has been overwritten.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*> WR and WI contain the real and imaginary parts,*> respectively, of the computed eigenvalues. Complex*> conjugate pairs of eigenvalues appear consecutively*> with the eigenvalue having the positive imaginary part*> first.*> \endverbatim*>*> \param[out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,N)*> If JOBVL = 'V', the left eigenvectors u(j) are stored one*> after another in the columns of VL, in the same order*> as their eigenvalues.*> If JOBVL = 'N', VL is not referenced.*> If the j-th eigenvalue is real, then u(j) = VL(:,j),*> the j-th column of VL.*> If the j-th and (j+1)-st eigenvalues form a complex*> conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and*> u(j+1) = VL(:,j) - i*VL(:,j+1).*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL. LDVL >= 1; if*> JOBVL = 'V', LDVL >= N.*> \endverbatim*>*> \param[out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,N)*> If JOBVR = 'V', the right eigenvectors v(j) are stored one*> after another in the columns of VR, in the same order*> as their eigenvalues.*> If JOBVR = 'N', VR is not referenced.*> If the j-th eigenvalue is real, then v(j) = VR(:,j),*> the j-th column of VR.*> If the j-th and (j+1)-st eigenvalues form a complex*> conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and*> v(j+1) = VR(:,j) - i*VR(:,j+1).*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR. LDVR >= 1; if*> JOBVR = 'V', LDVR >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,3*N), and*> if JOBVL = 'V' or JOBVR = 'V', LWORK >= 4*N. For good*> performance, LWORK must generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, the QR algorithm failed to compute all the*> eigenvalues, and no eigenvectors have been computed;*> elements i+1:N of WR and WI contain eigenvalues which*> have converged.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016** @precisions fortran d -> s**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGEEV( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,$ LDVR, WORK, LWORK, INFO )implicit none** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBVL, JOBVRINTEGER INFO, LDA, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),$ WI( * ), WORK( * ), WR( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, SCALEA, WANTVL, WANTVRCHARACTER SIDEINTEGER HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,$ LWORK_TREVC, MAXWRK, MINWRK, NOUTDOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,$ SN* ..* .. Local Arrays ..LOGICAL SELECT( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,$ DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC3,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAX, ILAENVDOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,$ DNRM2* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )WANTVL = LSAME( JOBVL, 'V' )WANTVR = LSAME( JOBVR, 'V' )IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THENINFO = -1ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THENINFO = -9ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THENINFO = -11END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.)*IF( INFO.EQ.0 ) THENIF( N.EQ.0 ) THENMINWRK = 1MAXWRK = 1ELSEMAXWRK = 2*N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )IF( WANTVL ) THENMINWRK = 4*NMAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,$ 'DORGHR', ' ', N, 1, N, -1 ) )CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,$ WORK, -1, INFO )HSWORK = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )CALL DTREVC3( 'L', 'B', SELECT, N, A, LDA,$ VL, LDVL, VR, LDVR, N, NOUT,$ WORK, -1, IERR )LWORK_TREVC = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )MAXWRK = MAX( MAXWRK, 4*N )ELSE IF( WANTVR ) THENMINWRK = 4*NMAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,$ 'DORGHR', ' ', N, 1, N, -1 ) )CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,$ WORK, -1, INFO )HSWORK = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )CALL DTREVC3( 'R', 'B', SELECT, N, A, LDA,$ VL, LDVL, VR, LDVR, N, NOUT,$ WORK, -1, IERR )LWORK_TREVC = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )MAXWRK = MAX( MAXWRK, 4*N )ELSEMINWRK = 3*NCALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR, LDVR,$ WORK, -1, INFO )HSWORK = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + 1, N + HSWORK )END IFMAXWRK = MAX( MAXWRK, MINWRK )END IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -13END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Balance the matrix* (Workspace: need N)*IBAL = 1CALL DGEBAL( 'B', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )** Reduce to upper Hessenberg form* (Workspace: need 3*N, prefer 2*N+N*NB)*ITAU = IBAL + NIWRK = ITAU + NCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVL ) THEN** Want left eigenvectors* Copy Householder vectors to VL*SIDE = 'L'CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )** Generate orthogonal matrix in VL* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VL* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*IF( WANTVR ) THEN** Want left and right eigenvectors* Copy Schur vectors to VR*SIDE = 'B'CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )END IF*ELSE IF( WANTVR ) THEN** Want right eigenvectors* Copy Householder vectors to VR*SIDE = 'R'CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )** Generate orthogonal matrix in VR* (Workspace: need 3*N-1, prefer 2*N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VR* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*ELSE** Compute eigenvalues only* (Workspace: need N+1, prefer N+HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'E', 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )END IF** If INFO .NE. 0 from DHSEQR, then quit*IF( INFO.NE.0 )$ GO TO 50*IF( WANTVL .OR. WANTVR ) THEN** Compute left and/or right eigenvectors* (Workspace: need 4*N, prefer N + N + 2*N*NB)*CALL DTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,$ N, NOUT, WORK( IWRK ), LWORK-IWRK+1, IERR )END IF*IF( WANTVL ) THEN** Undo balancing of left eigenvectors* (Workspace: need N)*CALL DGEBAK( 'B', 'L', N, ILO, IHI, WORK( IBAL ), N, VL, LDVL,$ IERR )** Normalize left eigenvectors and make largest component real*DO 20 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),$ DNRM2( N, VL( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )DO 10 K = 1, NWORK( IWRK+K-1 ) = VL( K, I )**2 + VL( K, I+1 )**210 CONTINUEK = IDAMAX( N, WORK( IWRK ), 1 )CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )VL( K, I+1 ) = ZEROEND IF20 CONTINUEEND IF*IF( WANTVR ) THEN** Undo balancing of right eigenvectors* (Workspace: need N)*CALL DGEBAK( 'B', 'R', N, ILO, IHI, WORK( IBAL ), N, VR, LDVR,$ IERR )** Normalize right eigenvectors and make largest component real*DO 40 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),$ DNRM2( N, VR( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )DO 30 K = 1, NWORK( IWRK+K-1 ) = VR( K, I )**2 + VR( K, I+1 )**230 CONTINUEK = IDAMAX( N, WORK( IWRK ), 1 )CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )VR( K, I+1 ) = ZEROEND IF40 CONTINUEEND IF** Undo scaling if necessary*50 CONTINUEIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )IF( INFO.GT.0 ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,$ IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,$ IERR )END IFEND IF*WORK( 1 ) = MAXWRKRETURN** End of DGEEV*END*> \brief <b> DGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEEVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeevx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeevx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeevx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,* VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,* RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER BALANC, JOBVL, JOBVR, SENSE* INTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, N* DOUBLE PRECISION ABNRM* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), RCONDE( * ), RCONDV( * ),* $ SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),* $ WI( * ), WORK( * ), WR( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEEVX computes for an N-by-N real nonsymmetric matrix A, the*> eigenvalues and, optionally, the left and/or right eigenvectors.*>*> Optionally also, it computes a balancing transformation to improve*> the conditioning of the eigenvalues and eigenvectors (ILO, IHI,*> SCALE, and ABNRM), reciprocal condition numbers for the eigenvalues*> (RCONDE), and reciprocal condition numbers for the right*> eigenvectors (RCONDV).*>*> The right eigenvector v(j) of A satisfies*> A * v(j) = lambda(j) * v(j)*> where lambda(j) is its eigenvalue.*> The left eigenvector u(j) of A satisfies*> u(j)**H * A = lambda(j) * u(j)**H*> where u(j)**H denotes the conjugate-transpose of u(j).*>*> The computed eigenvectors are normalized to have Euclidean norm*> equal to 1 and largest component real.*>*> Balancing a matrix means permuting the rows and columns to make it*> more nearly upper triangular, and applying a diagonal similarity*> transformation D * A * D**(-1), where D is a diagonal matrix, to*> make its rows and columns closer in norm and the condition numbers*> of its eigenvalues and eigenvectors smaller. The computed*> reciprocal condition numbers correspond to the balanced matrix.*> Permuting rows and columns will not change the condition numbers*> (in exact arithmetic) but diagonal scaling will. For further*> explanation of balancing, see section 4.10.2 of the LAPACK*> Users' Guide.*> \endverbatim** Arguments:* ==========**> \param[in] BALANC*> \verbatim*> BALANC is CHARACTER*1*> Indicates how the input matrix should be diagonally scaled*> and/or permuted to improve the conditioning of its*> eigenvalues.*> = 'N': Do not diagonally scale or permute;*> = 'P': Perform permutations to make the matrix more nearly*> upper triangular. Do not diagonally scale;*> = 'S': Diagonally scale the matrix, i.e. replace A by*> D*A*D**(-1), where D is a diagonal matrix chosen*> to make the rows and columns of A more equal in*> norm. Do not permute;*> = 'B': Both diagonally scale and permute A.*>*> Computed reciprocal condition numbers will be for the matrix*> after balancing and/or permuting. Permuting does not change*> condition numbers (in exact arithmetic), but balancing does.*> \endverbatim*>*> \param[in] JOBVL*> \verbatim*> JOBVL is CHARACTER*1*> = 'N': left eigenvectors of A are not computed;*> = 'V': left eigenvectors of A are computed.*> If SENSE = 'E' or 'B', JOBVL must = 'V'.*> \endverbatim*>*> \param[in] JOBVR*> \verbatim*> JOBVR is CHARACTER*1*> = 'N': right eigenvectors of A are not computed;*> = 'V': right eigenvectors of A are computed.*> If SENSE = 'E' or 'B', JOBVR must = 'V'.*> \endverbatim*>*> \param[in] SENSE*> \verbatim*> SENSE is CHARACTER*1*> Determines which reciprocal condition numbers are computed.*> = 'N': None are computed;*> = 'E': Computed for eigenvalues only;*> = 'V': Computed for right eigenvectors only;*> = 'B': Computed for eigenvalues and right eigenvectors.*>*> If SENSE = 'E' or 'B', both left and right eigenvectors*> must also be computed (JOBVL = 'V' and JOBVR = 'V').*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the N-by-N matrix A.*> On exit, A has been overwritten. If JOBVL = 'V' or*> JOBVR = 'V', A contains the real Schur form of the balanced*> version of the input matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*> WR and WI contain the real and imaginary parts,*> respectively, of the computed eigenvalues. Complex*> conjugate pairs of eigenvalues will appear consecutively*> with the eigenvalue having the positive imaginary part*> first.*> \endverbatim*>*> \param[out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,N)*> If JOBVL = 'V', the left eigenvectors u(j) are stored one*> after another in the columns of VL, in the same order*> as their eigenvalues.*> If JOBVL = 'N', VL is not referenced.*> If the j-th eigenvalue is real, then u(j) = VL(:,j),*> the j-th column of VL.*> If the j-th and (j+1)-st eigenvalues form a complex*> conjugate pair, then u(j) = VL(:,j) + i*VL(:,j+1) and*> u(j+1) = VL(:,j) - i*VL(:,j+1).*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL. LDVL >= 1; if*> JOBVL = 'V', LDVL >= N.*> \endverbatim*>*> \param[out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,N)*> If JOBVR = 'V', the right eigenvectors v(j) are stored one*> after another in the columns of VR, in the same order*> as their eigenvalues.*> If JOBVR = 'N', VR is not referenced.*> If the j-th eigenvalue is real, then v(j) = VR(:,j),*> the j-th column of VR.*> If the j-th and (j+1)-st eigenvalues form a complex*> conjugate pair, then v(j) = VR(:,j) + i*VR(:,j+1) and*> v(j+1) = VR(:,j) - i*VR(:,j+1).*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR. LDVR >= 1, and if*> JOBVR = 'V', LDVR >= N.*> \endverbatim*>*> \param[out] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[out] IHI*> \verbatim*> IHI is INTEGER*> ILO and IHI are integer values determined when A was*> balanced. The balanced A(i,j) = 0 if I > J and*> J = 1,...,ILO-1 or I = IHI+1,...,N.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and scaling factors applied*> when balancing A. If P(j) is the index of the row and column*> interchanged with row and column j, and D(j) is the scaling*> factor applied to row and column j, then*> SCALE(J) = P(J), for J = 1,...,ILO-1*> = D(J), for J = ILO,...,IHI*> = P(J) for J = IHI+1,...,N.*> The order in which the interchanges are made is N to IHI+1,*> then 1 to ILO-1.*> \endverbatim*>*> \param[out] ABNRM*> \verbatim*> ABNRM is DOUBLE PRECISION*> The one-norm of the balanced matrix (the maximum*> of the sum of absolute values of elements of any column).*> \endverbatim*>*> \param[out] RCONDE*> \verbatim*> RCONDE is DOUBLE PRECISION array, dimension (N)*> RCONDE(j) is the reciprocal condition number of the j-th*> eigenvalue.*> \endverbatim*>*> \param[out] RCONDV*> \verbatim*> RCONDV is DOUBLE PRECISION array, dimension (N)*> RCONDV(j) is the reciprocal condition number of the j-th*> right eigenvector.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. If SENSE = 'N' or 'E',*> LWORK >= max(1,2*N), and if JOBVL = 'V' or JOBVR = 'V',*> LWORK >= 3*N. If SENSE = 'V' or 'B', LWORK >= N*(N+6).*> For good performance, LWORK must generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (2*N-2)*> If SENSE = 'N' or 'E', not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, the QR algorithm failed to compute all the*> eigenvalues, and no eigenvectors or condition numbers*> have been computed; elements 1:ILO-1 and i+1:N of WR*> and WI contain eigenvalues which have converged.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016** @precisions fortran d -> s**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGEEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, WR, WI,$ VL, LDVL, VR, LDVR, ILO, IHI, SCALE, ABNRM,$ RCONDE, RCONDV, WORK, LWORK, IWORK, INFO )implicit none** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER BALANC, JOBVL, JOBVR, SENSEINTEGER IHI, ILO, INFO, LDA, LDVL, LDVR, LWORK, NDOUBLE PRECISION ABNRM* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), RCONDE( * ), RCONDV( * ),$ SCALE( * ), VL( LDVL, * ), VR( LDVR, * ),$ WI( * ), WORK( * ), WR( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, SCALEA, WANTVL, WANTVR, WNTSNB, WNTSNE,$ WNTSNN, WNTSNVCHARACTER JOB, SIDEINTEGER HSWORK, I, ICOND, IERR, ITAU, IWRK, K,$ LWORK_TREVC, MAXWRK, MINWRK, NOUTDOUBLE PRECISION ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,$ SN* ..* .. Local Arrays ..LOGICAL SELECT( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DGEBAK, DGEBAL, DGEHRD, DHSEQR, DLABAD, DLACPY,$ DLARTG, DLASCL, DORGHR, DROT, DSCAL, DTREVC3,$ DTRSNA, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAX, ILAENVDOUBLE PRECISION DLAMCH, DLANGE, DLAPY2, DNRM2EXTERNAL LSAME, IDAMAX, ILAENV, DLAMCH, DLANGE, DLAPY2,$ DNRM2* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )WANTVL = LSAME( JOBVL, 'V' )WANTVR = LSAME( JOBVR, 'V' )WNTSNN = LSAME( SENSE, 'N' )WNTSNE = LSAME( SENSE, 'E' )WNTSNV = LSAME( SENSE, 'V' )WNTSNB = LSAME( SENSE, 'B' )IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'S' )$ .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )$ THENINFO = -1ELSE IF( ( .NOT.WANTVL ) .AND. ( .NOT.LSAME( JOBVL, 'N' ) ) ) THENINFO = -2ELSE IF( ( .NOT.WANTVR ) .AND. ( .NOT.LSAME( JOBVR, 'N' ) ) ) THENINFO = -3ELSE IF( .NOT.( WNTSNN .OR. WNTSNE .OR. WNTSNB .OR. WNTSNV ) .OR.$ ( ( WNTSNE .OR. WNTSNB ) .AND. .NOT.( WANTVL .AND.$ WANTVR ) ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVL.LT.1 .OR. ( WANTVL .AND. LDVL.LT.N ) ) THENINFO = -11ELSE IF( LDVR.LT.1 .OR. ( WANTVR .AND. LDVR.LT.N ) ) THENINFO = -13END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.* HSWORK refers to the workspace preferred by DHSEQR, as* calculated below. HSWORK is computed assuming ILO=1 and IHI=N,* the worst case.)*IF( INFO.EQ.0 ) THENIF( N.EQ.0 ) THENMINWRK = 1MAXWRK = 1ELSEMAXWRK = N + N*ILAENV( 1, 'DGEHRD', ' ', N, 1, N, 0 )*IF( WANTVL ) THENCALL DTREVC3( 'L', 'B', SELECT, N, A, LDA,$ VL, LDVL, VR, LDVR,$ N, NOUT, WORK, -1, IERR )LWORK_TREVC = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VL, LDVL,$ WORK, -1, INFO )ELSE IF( WANTVR ) THENCALL DTREVC3( 'R', 'B', SELECT, N, A, LDA,$ VL, LDVL, VR, LDVR,$ N, NOUT, WORK, -1, IERR )LWORK_TREVC = INT( WORK(1) )MAXWRK = MAX( MAXWRK, N + LWORK_TREVC )CALL DHSEQR( 'S', 'V', N, 1, N, A, LDA, WR, WI, VR, LDVR,$ WORK, -1, INFO )ELSEIF( WNTSNN ) THENCALL DHSEQR( 'E', 'N', N, 1, N, A, LDA, WR, WI, VR,$ LDVR, WORK, -1, INFO )ELSECALL DHSEQR( 'S', 'N', N, 1, N, A, LDA, WR, WI, VR,$ LDVR, WORK, -1, INFO )END IFEND IFHSWORK = INT( WORK(1) )*IF( ( .NOT.WANTVL ) .AND. ( .NOT.WANTVR ) ) THENMINWRK = 2*NIF( .NOT.WNTSNN )$ MINWRK = MAX( MINWRK, N*N+6*N )MAXWRK = MAX( MAXWRK, HSWORK )IF( .NOT.WNTSNN )$ MAXWRK = MAX( MAXWRK, N*N + 6*N )ELSEMINWRK = 3*NIF( ( .NOT.WNTSNN ) .AND. ( .NOT.WNTSNE ) )$ MINWRK = MAX( MINWRK, N*N + 6*N )MAXWRK = MAX( MAXWRK, HSWORK )MAXWRK = MAX( MAXWRK, N + ( N - 1 )*ILAENV( 1, 'DORGHR',$ ' ', N, 1, N, -1 ) )IF( ( .NOT.WNTSNN ) .AND. ( .NOT.WNTSNE ) )$ MAXWRK = MAX( MAXWRK, N*N + 6*N )MAXWRK = MAX( MAXWRK, 3*N )END IFMAXWRK = MAX( MAXWRK, MINWRK )END IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -21END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEEVX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ICOND = 0ANRM = DLANGE( 'M', N, N, A, LDA, DUM )SCALEA = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENSCALEA = .TRUE.CSCALE = SMLNUMELSE IF( ANRM.GT.BIGNUM ) THENSCALEA = .TRUE.CSCALE = BIGNUMEND IFIF( SCALEA )$ CALL DLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )** Balance the matrix and compute ABNRM*CALL DGEBAL( BALANC, N, A, LDA, ILO, IHI, SCALE, IERR )ABNRM = DLANGE( '1', N, N, A, LDA, DUM )IF( SCALEA ) THENDUM( 1 ) = ABNRMCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, 1, 1, DUM, 1, IERR )ABNRM = DUM( 1 )END IF** Reduce to upper Hessenberg form* (Workspace: need 2*N, prefer N+N*NB)*ITAU = 1IWRK = ITAU + NCALL DGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )*IF( WANTVL ) THEN** Want left eigenvectors* Copy Householder vectors to VL*SIDE = 'L'CALL DLACPY( 'L', N, N, A, LDA, VL, LDVL )** Generate orthogonal matrix in VL* (Workspace: need 2*N-1, prefer N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VL, LDVL, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VL* (Workspace: need 1, prefer HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VL, LDVL,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*IF( WANTVR ) THEN** Want left and right eigenvectors* Copy Schur vectors to VR*SIDE = 'B'CALL DLACPY( 'F', N, N, VL, LDVL, VR, LDVR )END IF*ELSE IF( WANTVR ) THEN** Want right eigenvectors* Copy Householder vectors to VR*SIDE = 'R'CALL DLACPY( 'L', N, N, A, LDA, VR, LDVR )** Generate orthogonal matrix in VR* (Workspace: need 2*N-1, prefer N+(N-1)*NB)*CALL DORGHR( N, ILO, IHI, VR, LDVR, WORK( ITAU ), WORK( IWRK ),$ LWORK-IWRK+1, IERR )** Perform QR iteration, accumulating Schur vectors in VR* (Workspace: need 1, prefer HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( 'S', 'V', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )*ELSE** Compute eigenvalues only* If condition numbers desired, compute Schur form*IF( WNTSNN ) THENJOB = 'E'ELSEJOB = 'S'END IF** (Workspace: need 1, prefer HSWORK (see comments) )*IWRK = ITAUCALL DHSEQR( JOB, 'N', N, ILO, IHI, A, LDA, WR, WI, VR, LDVR,$ WORK( IWRK ), LWORK-IWRK+1, INFO )END IF** If INFO .NE. 0 from DHSEQR, then quit*IF( INFO.NE.0 )$ GO TO 50*IF( WANTVL .OR. WANTVR ) THEN** Compute left and/or right eigenvectors* (Workspace: need 3*N, prefer N + 2*N*NB)*CALL DTREVC3( SIDE, 'B', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,$ N, NOUT, WORK( IWRK ), LWORK-IWRK+1, IERR )END IF** Compute condition numbers if desired* (Workspace: need N*N+6*N unless SENSE = 'E')*IF( .NOT.WNTSNN ) THENCALL DTRSNA( SENSE, 'A', SELECT, N, A, LDA, VL, LDVL, VR, LDVR,$ RCONDE, RCONDV, N, NOUT, WORK( IWRK ), N, IWORK,$ ICOND )END IF*IF( WANTVL ) THEN** Undo balancing of left eigenvectors*CALL DGEBAK( BALANC, 'L', N, ILO, IHI, SCALE, N, VL, LDVL,$ IERR )** Normalize left eigenvectors and make largest component real*DO 20 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VL( 1, I ), 1 ),$ DNRM2( N, VL( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VL( 1, I ), 1 )CALL DSCAL( N, SCL, VL( 1, I+1 ), 1 )DO 10 K = 1, NWORK( K ) = VL( K, I )**2 + VL( K, I+1 )**210 CONTINUEK = IDAMAX( N, WORK, 1 )CALL DLARTG( VL( K, I ), VL( K, I+1 ), CS, SN, R )CALL DROT( N, VL( 1, I ), 1, VL( 1, I+1 ), 1, CS, SN )VL( K, I+1 ) = ZEROEND IF20 CONTINUEEND IF*IF( WANTVR ) THEN** Undo balancing of right eigenvectors*CALL DGEBAK( BALANC, 'R', N, ILO, IHI, SCALE, N, VR, LDVR,$ IERR )** Normalize right eigenvectors and make largest component real*DO 40 I = 1, NIF( WI( I ).EQ.ZERO ) THENSCL = ONE / DNRM2( N, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I ), 1 )ELSE IF( WI( I ).GT.ZERO ) THENSCL = ONE / DLAPY2( DNRM2( N, VR( 1, I ), 1 ),$ DNRM2( N, VR( 1, I+1 ), 1 ) )CALL DSCAL( N, SCL, VR( 1, I ), 1 )CALL DSCAL( N, SCL, VR( 1, I+1 ), 1 )DO 30 K = 1, NWORK( K ) = VR( K, I )**2 + VR( K, I+1 )**230 CONTINUEK = IDAMAX( N, WORK, 1 )CALL DLARTG( VR( K, I ), VR( K, I+1 ), CS, SN, R )CALL DROT( N, VR( 1, I ), 1, VR( 1, I+1 ), 1, CS, SN )VR( K, I+1 ) = ZEROEND IF40 CONTINUEEND IF** Undo scaling if necessary*50 CONTINUEIF( SCALEA ) THENCALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WR( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N-INFO, 1, WI( INFO+1 ),$ MAX( N-INFO, 1 ), IERR )IF( INFO.EQ.0 ) THENIF( ( WNTSNV .OR. WNTSNB ) .AND. ICOND.EQ.0 )$ CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, RCONDV, N,$ IERR )ELSECALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WR, N,$ IERR )CALL DLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI, N,$ IERR )END IFEND IF*WORK( 1 ) = MAXWRKRETURN** End of DGEEVX*END*> \brief <b> DGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEGS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgegs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgegs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgegs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEGS( JOBVSL, JOBVSR, N, A, LDA, B, LDB, ALPHAR,* ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, WORK,* LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVSL, JOBVSR* INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),* $ VSR( LDVSR, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DGGES.*>*> DGEGS computes the eigenvalues, real Schur form, and, optionally,*> left and or/right Schur vectors of a real matrix pair (A,B).*> Given two square matrices A and B, the generalized real Schur*> factorization has the form*>*> A = Q*S*Z**T, B = Q*T*Z**T*>*> where Q and Z are orthogonal matrices, T is upper triangular, and S*> is an upper quasi-triangular matrix with 1-by-1 and 2-by-2 diagonal*> blocks, the 2-by-2 blocks corresponding to complex conjugate pairs*> of eigenvalues of (A,B). The columns of Q are the left Schur vectors*> and the columns of Z are the right Schur vectors.*>*> If only the eigenvalues of (A,B) are needed, the driver routine*> DGEGV should be used instead. See DGEGV for a description of the*> eigenvalues of the generalized nonsymmetric eigenvalue problem*> (GNEP).*> \endverbatim** Arguments:* ==========**> \param[in] JOBVSL*> \verbatim*> JOBVSL is CHARACTER*1*> = 'N': do not compute the left Schur vectors;*> = 'V': compute the left Schur vectors (returned in VSL).*> \endverbatim*>*> \param[in] JOBVSR*> \verbatim*> JOBVSR is CHARACTER*1*> = 'N': do not compute the right Schur vectors;*> = 'V': compute the right Schur vectors (returned in VSR).*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A, B, VSL, and VSR. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the matrix A.*> On exit, the upper quasi-triangular matrix S from the*> generalized real Schur factorization.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the matrix B.*> On exit, the upper triangular matrix T from the generalized*> real Schur factorization.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> The real parts of each scalar alpha defining an eigenvalue*> of GNEP.*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> The imaginary parts of each scalar alpha defining an*> eigenvalue of GNEP. If ALPHAI(j) is zero, then the j-th*> eigenvalue is real; if positive, then the j-th and (j+1)-st*> eigenvalues are a complex conjugate pair, with*> ALPHAI(j+1) = -ALPHAI(j).*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> The scalars beta that define the eigenvalues of GNEP.*> Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and*> beta = BETA(j) represent the j-th eigenvalue of the matrix*> pair (A,B), in one of the forms lambda = alpha/beta or*> mu = beta/alpha. Since either lambda or mu may overflow,*> they should not, in general, be computed.*> \endverbatim*>*> \param[out] VSL*> \verbatim*> VSL is DOUBLE PRECISION array, dimension (LDVSL,N)*> If JOBVSL = 'V', the matrix of left Schur vectors Q.*> Not referenced if JOBVSL = 'N'.*> \endverbatim*>*> \param[in] LDVSL*> \verbatim*> LDVSL is INTEGER*> The leading dimension of the matrix VSL. LDVSL >=1, and*> if JOBVSL = 'V', LDVSL >= N.*> \endverbatim*>*> \param[out] VSR*> \verbatim*> VSR is DOUBLE PRECISION array, dimension (LDVSR,N)*> If JOBVSR = 'V', the matrix of right Schur vectors Z.*> Not referenced if JOBVSR = 'N'.*> \endverbatim*>*> \param[in] LDVSR*> \verbatim*> LDVSR is INTEGER*> The leading dimension of the matrix VSR. LDVSR >= 1, and*> if JOBVSR = 'V', LDVSR >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,4*N).*> For good performance, LWORK must generally be larger.*> To compute the optimal value of LWORK, call ILAENV to get*> blocksizes (for DGEQRF, DORMQR, and DORGQR.) Then compute:*> NB -- MAX of the blocksizes for DGEQRF, DORMQR, and DORGQR*> The optimal LWORK is 2*N + N*(NB+1).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1,...,N:*> The QZ iteration failed. (A,B) are not in Schur*> form, but ALPHAR(j), ALPHAI(j), and BETA(j) should*> be correct for j=INFO+1,...,N.*> > N: errors that usually indicate LAPACK problems:*> =N+1: error return from DGGBAL*> =N+2: error return from DGEQRF*> =N+3: error return from DORMQR*> =N+4: error return from DORGQR*> =N+5: error return from DGGHRD*> =N+6: error return from DHGEQZ (other than failed*> iteration)*> =N+7: error return from DGGBAK (computing VSL)*> =N+8: error return from DGGBAK (computing VSR)*> =N+9: error return from DLASCL (various places)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGEGS( JOBVSL, JOBVSR, N, A, LDA, B, LDB, ALPHAR,$ ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, WORK,$ LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBVSL, JOBVSRINTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),$ VSR( LDVSR, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL ILASCL, ILBSCL, ILVSL, ILVSR, LQUERYINTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,$ IRIGHT, IROWS, ITAU, IWORK, LOPT, LWKMIN,$ LWKOPT, NB, NB1, NB2, NB3DOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,$ SAFMIN, SMLNUM* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLACPY,$ DLASCL, DLASET, DORGQR, DORMQR, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX* ..* .. Executable Statements ..** Decode the input arguments*IF( LSAME( JOBVSL, 'N' ) ) THENIJOBVL = 1ILVSL = .FALSE.ELSE IF( LSAME( JOBVSL, 'V' ) ) THENIJOBVL = 2ILVSL = .TRUE.ELSEIJOBVL = -1ILVSL = .FALSE.END IF*IF( LSAME( JOBVSR, 'N' ) ) THENIJOBVR = 1ILVSR = .FALSE.ELSE IF( LSAME( JOBVSR, 'V' ) ) THENIJOBVR = 2ILVSR = .TRUE.ELSEIJOBVR = -1ILVSR = .FALSE.END IF** Test the input arguments*LWKMIN = MAX( 4*N, 1 )LWKOPT = LWKMINWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )INFO = 0IF( IJOBVL.LE.0 ) THENINFO = -1ELSE IF( IJOBVR.LE.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THENINFO = -12ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THENINFO = -14ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -16END IF*IF( INFO.EQ.0 ) THENNB1 = ILAENV( 1, 'DGEQRF', ' ', N, N, -1, -1 )NB2 = ILAENV( 1, 'DORMQR', ' ', N, N, N, -1 )NB3 = ILAENV( 1, 'DORGQR', ' ', N, N, N, -1 )NB = MAX( NB1, NB2, NB3 )LOPT = 2*N + N*( NB+1 )WORK( 1 ) = LOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEGS ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'E' )*DLAMCH( 'B' )SAFMIN = DLAMCH( 'S' )SMLNUM = N*SAFMIN / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, WORK )ILASCL = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENANRMTO = SMLNUMILASCL = .TRUE.ELSE IF( ANRM.GT.BIGNUM ) THENANRMTO = BIGNUMILASCL = .TRUE.END IF*IF( ILASCL ) THENCALL DLASCL( 'G', -1, -1, ANRM, ANRMTO, N, N, A, LDA, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFEND IF** Scale B if max element outside range [SMLNUM,BIGNUM]*BNRM = DLANGE( 'M', N, N, B, LDB, WORK )ILBSCL = .FALSE.IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THENBNRMTO = SMLNUMILBSCL = .TRUE.ELSE IF( BNRM.GT.BIGNUM ) THENBNRMTO = BIGNUMILBSCL = .TRUE.END IF*IF( ILBSCL ) THENCALL DLASCL( 'G', -1, -1, BNRM, BNRMTO, N, N, B, LDB, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFEND IF** Permute the matrix to make it more nearly triangular* Workspace layout: (2*N words -- "work..." not actually used)* left_permutation, right_permutation, work...*ILEFT = 1IRIGHT = N + 1IWORK = IRIGHT + NCALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), WORK( IWORK ), IINFO )IF( IINFO.NE.0 ) THENINFO = N + 1GO TO 10END IF** Reduce B to triangular form, and initialize VSL and/or VSR* Workspace layout: ("work..." must have at least N words)* left_permutation, right_permutation, tau, work...*IROWS = IHI + 1 - ILOICOLS = N + 1 - ILOITAU = IWORKIWORK = ITAU + IROWSCALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),$ WORK( IWORK ), LWORK+1-IWORK, IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENINFO = N + 2GO TO 10END IF*CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),$ LWORK+1-IWORK, IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENINFO = N + 3GO TO 10END IF*IF( ILVSL ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,$ VSL( ILO+1, ILO ), LDVSL )CALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,$ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,$ IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENINFO = N + 4GO TO 10END IFEND IF*IF( ILVSR )$ CALL DLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )** Reduce to generalized Hessenberg form*CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,$ LDVSL, VSR, LDVSR, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 5GO TO 10END IF** Perform QZ algorithm, computing Schur vectors if desired* Workspace layout: ("work..." must have at least 1 word)* left_permutation, right_permutation, work...*IWORK = ITAUCALL DHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,$ WORK( IWORK ), LWORK+1-IWORK, IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENIF( IINFO.GT.0 .AND. IINFO.LE.N ) THENINFO = IINFOELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THENINFO = IINFO - NELSEINFO = N + 6END IFGO TO 10END IF** Apply permutation to VSL and VSR*IF( ILVSL ) THENCALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VSL, LDVSL, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 7GO TO 10END IFEND IFIF( ILVSR ) THENCALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VSR, LDVSR, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 8GO TO 10END IFEND IF** Undo scaling*IF( ILASCL ) THENCALL DLASCL( 'H', -1, -1, ANRMTO, ANRM, N, N, A, LDA, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFCALL DLASCL( 'G', -1, -1, ANRMTO, ANRM, N, 1, ALPHAR, N,$ IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFCALL DLASCL( 'G', -1, -1, ANRMTO, ANRM, N, 1, ALPHAI, N,$ IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFEND IF*IF( ILBSCL ) THENCALL DLASCL( 'U', -1, -1, BNRMTO, BNRM, N, N, B, LDB, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFCALL DLASCL( 'G', -1, -1, BNRMTO, BNRM, N, 1, BETA, N, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9RETURNEND IFEND IF*10 CONTINUEWORK( 1 ) = LWKOPT*RETURN** End of DGEGS*END*> \brief <b> DGEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEGV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgegv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgegv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgegv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,* BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVL, JOBVR* INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), VL( LDVL, * ),* $ VR( LDVR, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DGGEV.*>*> DGEGV computes the eigenvalues and, optionally, the left and/or right*> eigenvectors of a real matrix pair (A,B).*> Given two square matrices A and B,*> the generalized nonsymmetric eigenvalue problem (GNEP) is to find the*> eigenvalues lambda and corresponding (non-zero) eigenvectors x such*> that*>*> A*x = lambda*B*x.*>*> An alternate form is to find the eigenvalues mu and corresponding*> eigenvectors y such that*>*> mu*A*y = B*y.*>*> These two forms are equivalent with mu = 1/lambda and x = y if*> neither lambda nor mu is zero. In order to deal with the case that*> lambda or mu is zero or small, two values alpha and beta are returned*> for each eigenvalue, such that lambda = alpha/beta and*> mu = beta/alpha.*>*> The vectors x and y in the above equations are right eigenvectors of*> the matrix pair (A,B). Vectors u and v satisfying*>*> u**H*A = lambda*u**H*B or mu*v**H*A = v**H*B*>*> are left eigenvectors of (A,B).*>*> Note: this routine performs "full balancing" on A and B*> \endverbatim** Arguments:* ==========**> \param[in] JOBVL*> \verbatim*> JOBVL is CHARACTER*1*> = 'N': do not compute the left generalized eigenvectors;*> = 'V': compute the left generalized eigenvectors (returned*> in VL).*> \endverbatim*>*> \param[in] JOBVR*> \verbatim*> JOBVR is CHARACTER*1*> = 'N': do not compute the right generalized eigenvectors;*> = 'V': compute the right generalized eigenvectors (returned*> in VR).*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A, B, VL, and VR. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the matrix A.*> If JOBVL = 'V' or JOBVR = 'V', then on exit A*> contains the real Schur form of A from the generalized Schur*> factorization of the pair (A,B) after balancing.*> If no eigenvectors were computed, then only the diagonal*> blocks from the Schur form will be correct. See DGGHRD and*> DHGEQZ for details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the matrix B.*> If JOBVL = 'V' or JOBVR = 'V', then on exit B contains the*> upper triangular matrix obtained from B in the generalized*> Schur factorization of the pair (A,B) after balancing.*> If no eigenvectors were computed, then only those elements of*> B corresponding to the diagonal blocks from the Schur form of*> A will be correct. See DGGHRD and DHGEQZ for details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> The real parts of each scalar alpha defining an eigenvalue of*> GNEP.*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> The imaginary parts of each scalar alpha defining an*> eigenvalue of GNEP. If ALPHAI(j) is zero, then the j-th*> eigenvalue is real; if positive, then the j-th and*> (j+1)-st eigenvalues are a complex conjugate pair, with*> ALPHAI(j+1) = -ALPHAI(j).*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> The scalars beta that define the eigenvalues of GNEP.*>*> Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and*> beta = BETA(j) represent the j-th eigenvalue of the matrix*> pair (A,B), in one of the forms lambda = alpha/beta or*> mu = beta/alpha. Since either lambda or mu may overflow,*> they should not, in general, be computed.*> \endverbatim*>*> \param[out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,N)*> If JOBVL = 'V', the left eigenvectors u(j) are stored*> in the columns of VL, in the same order as their eigenvalues.*> If the j-th eigenvalue is real, then u(j) = VL(:,j).*> If the j-th and (j+1)-st eigenvalues form a complex conjugate*> pair, then*> u(j) = VL(:,j) + i*VL(:,j+1)*> and*> u(j+1) = VL(:,j) - i*VL(:,j+1).*>*> Each eigenvector is scaled so that its largest component has*> abs(real part) + abs(imag. part) = 1, except for eigenvectors*> corresponding to an eigenvalue with alpha = beta = 0, which*> are set to zero.*> Not referenced if JOBVL = 'N'.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the matrix VL. LDVL >= 1, and*> if JOBVL = 'V', LDVL >= N.*> \endverbatim*>*> \param[out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,N)*> If JOBVR = 'V', the right eigenvectors x(j) are stored*> in the columns of VR, in the same order as their eigenvalues.*> If the j-th eigenvalue is real, then x(j) = VR(:,j).*> If the j-th and (j+1)-st eigenvalues form a complex conjugate*> pair, then*> x(j) = VR(:,j) + i*VR(:,j+1)*> and*> x(j+1) = VR(:,j) - i*VR(:,j+1).*>*> Each eigenvector is scaled so that its largest component has*> abs(real part) + abs(imag. part) = 1, except for eigenvalues*> corresponding to an eigenvalue with alpha = beta = 0, which*> are set to zero.*> Not referenced if JOBVR = 'N'.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the matrix VR. LDVR >= 1, and*> if JOBVR = 'V', LDVR >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,8*N).*> For good performance, LWORK must generally be larger.*> To compute the optimal value of LWORK, call ILAENV to get*> blocksizes (for DGEQRF, DORMQR, and DORGQR.) Then compute:*> NB -- MAX of the blocksizes for DGEQRF, DORMQR, and DORGQR;*> The optimal LWORK is:*> 2*N + MAX( 6*N, N*(NB+1) ).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1,...,N:*> The QZ iteration failed. No eigenvectors have been*> calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)*> should be correct for j=INFO+1,...,N.*> > N: errors that usually indicate LAPACK problems:*> =N+1: error return from DGGBAL*> =N+2: error return from DGEQRF*> =N+3: error return from DORMQR*> =N+4: error return from DORGQR*> =N+5: error return from DGGHRD*> =N+6: error return from DHGEQZ (other than failed*> iteration)*> =N+7: error return from DTGEVC*> =N+8: error return from DGGBAK (computing VL)*> =N+9: error return from DGGBAK (computing VR)*> =N+10: error return from DLASCL (various calls)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEeigen**> \par Further Details:* =====================*>*> \verbatim*>*> Balancing*> ---------*>*> This driver calls DGGBAL to both permute and scale rows and columns*> of A and B. The permutations PL and PR are chosen so that PL*A*PR*> and PL*B*R will be upper triangular except for the diagonal blocks*> A(i:j,i:j) and B(i:j,i:j), with i and j as close together as*> possible. The diagonal scaling matrices DL and DR are chosen so*> that the pair DL*PL*A*PR*DR, DL*PL*B*PR*DR have elements close to*> one (except for the elements that start out zero.)*>*> After the eigenvalues and eigenvectors of the balanced matrices*> have been computed, DGGBAK transforms the eigenvectors back to what*> they would have been (in perfect arithmetic) if they had not been*> balanced.*>*> Contents of A and B on Exit*> -------- -- - --- - -- ----*>*> If any eigenvectors are computed (either JOBVL='V' or JOBVR='V' or*> both), then on exit the arrays A and B will contain the real Schur*> form[*] of the "balanced" versions of A and B. If no eigenvectors*> are computed, then only the diagonal blocks will be correct.*>*> [*] See DHGEQZ, DGEGS, or read the book "Matrix Computations",*> by Golub & van Loan, pub. by Johns Hopkins U. Press.*> \endverbatim*>* =====================================================================SUBROUTINE DGEGV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,$ BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBVL, JOBVRINTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), VL( LDVL, * ),$ VR( LDVR, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL ILIMIT, ILV, ILVL, ILVR, LQUERYCHARACTER CHTEMPINTEGER ICOLS, IHI, IINFO, IJOBVL, IJOBVR, ILEFT, ILO,$ IN, IRIGHT, IROWS, ITAU, IWORK, JC, JR, LOPT,$ LWKMIN, LWKOPT, NB, NB1, NB2, NB3DOUBLE PRECISION ABSAI, ABSAR, ABSB, ANRM, ANRM1, ANRM2, BNRM,$ BNRM1, BNRM2, EPS, ONEPLS, SAFMAX, SAFMIN,$ SALFAI, SALFAR, SBETA, SCALE, TEMP* ..* .. Local Arrays ..LOGICAL LDUMMA( 1 )* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLACPY,$ DLASCL, DLASET, DORGQR, DORMQR, DTGEVC, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, MAX* ..* .. Executable Statements ..** Decode the input arguments*IF( LSAME( JOBVL, 'N' ) ) THENIJOBVL = 1ILVL = .FALSE.ELSE IF( LSAME( JOBVL, 'V' ) ) THENIJOBVL = 2ILVL = .TRUE.ELSEIJOBVL = -1ILVL = .FALSE.END IF*IF( LSAME( JOBVR, 'N' ) ) THENIJOBVR = 1ILVR = .FALSE.ELSE IF( LSAME( JOBVR, 'V' ) ) THENIJOBVR = 2ILVR = .TRUE.ELSEIJOBVR = -1ILVR = .FALSE.END IFILV = ILVL .OR. ILVR** Test the input arguments*LWKMIN = MAX( 8*N, 1 )LWKOPT = LWKMINWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )INFO = 0IF( IJOBVL.LE.0 ) THENINFO = -1ELSE IF( IJOBVR.LE.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THENINFO = -12ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THENINFO = -14ELSE IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -16END IF*IF( INFO.EQ.0 ) THENNB1 = ILAENV( 1, 'DGEQRF', ' ', N, N, -1, -1 )NB2 = ILAENV( 1, 'DORMQR', ' ', N, N, N, -1 )NB3 = ILAENV( 1, 'DORGQR', ' ', N, N, N, -1 )NB = MAX( NB1, NB2, NB3 )LOPT = 2*N + MAX( 6*N, N*( NB+1 ) )WORK( 1 ) = LOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEGV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'E' )*DLAMCH( 'B' )SAFMIN = DLAMCH( 'S' )SAFMIN = SAFMIN + SAFMINSAFMAX = ONE / SAFMINONEPLS = ONE + ( 4*EPS )** Scale A*ANRM = DLANGE( 'M', N, N, A, LDA, WORK )ANRM1 = ANRMANRM2 = ONEIF( ANRM.LT.ONE ) THENIF( SAFMAX*ANRM.LT.ONE ) THENANRM1 = SAFMINANRM2 = SAFMAX*ANRMEND IFEND IF*IF( ANRM.GT.ZERO ) THENCALL DLASCL( 'G', -1, -1, ANRM, ONE, N, N, A, LDA, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 10RETURNEND IFEND IF** Scale B*BNRM = DLANGE( 'M', N, N, B, LDB, WORK )BNRM1 = BNRMBNRM2 = ONEIF( BNRM.LT.ONE ) THENIF( SAFMAX*BNRM.LT.ONE ) THENBNRM1 = SAFMINBNRM2 = SAFMAX*BNRMEND IFEND IF*IF( BNRM.GT.ZERO ) THENCALL DLASCL( 'G', -1, -1, BNRM, ONE, N, N, B, LDB, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 10RETURNEND IFEND IF** Permute the matrix to make it more nearly triangular* Workspace layout: (8*N words -- "work" requires 6*N words)* left_permutation, right_permutation, work...*ILEFT = 1IRIGHT = N + 1IWORK = IRIGHT + NCALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), WORK( IWORK ), IINFO )IF( IINFO.NE.0 ) THENINFO = N + 1GO TO 120END IF** Reduce B to triangular form, and initialize VL and/or VR* Workspace layout: ("work..." must have at least N words)* left_permutation, right_permutation, tau, work...*IROWS = IHI + 1 - ILOIF( ILV ) THENICOLS = N + 1 - ILOELSEICOLS = IROWSEND IFITAU = IWORKIWORK = ITAU + IROWSCALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),$ WORK( IWORK ), LWORK+1-IWORK, IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENINFO = N + 2GO TO 120END IF*CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWORK ),$ LWORK+1-IWORK, IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENINFO = N + 3GO TO 120END IF*IF( ILVL ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )CALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,$ VL( ILO+1, ILO ), LDVL )CALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,$ WORK( ITAU ), WORK( IWORK ), LWORK+1-IWORK,$ IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENINFO = N + 4GO TO 120END IFEND IF*IF( ILVR )$ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )** Reduce to generalized Hessenberg form*IF( ILV ) THEN** Eigenvectors requested -- work on whole matrix.*CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,$ LDVL, VR, LDVR, IINFO )ELSECALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,$ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IINFO )END IFIF( IINFO.NE.0 ) THENINFO = N + 5GO TO 120END IF** Perform QZ algorithm* Workspace layout: ("work..." must have at least 1 word)* left_permutation, right_permutation, work...*IWORK = ITAUIF( ILV ) THENCHTEMP = 'S'ELSECHTEMP = 'E'END IFCALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,$ WORK( IWORK ), LWORK+1-IWORK, IINFO )IF( IINFO.GE.0 )$ LWKOPT = MAX( LWKOPT, INT( WORK( IWORK ) )+IWORK-1 )IF( IINFO.NE.0 ) THENIF( IINFO.GT.0 .AND. IINFO.LE.N ) THENINFO = IINFOELSE IF( IINFO.GT.N .AND. IINFO.LE.2*N ) THENINFO = IINFO - NELSEINFO = N + 6END IFGO TO 120END IF*IF( ILV ) THEN** Compute Eigenvectors (DTGEVC requires 6*N words of workspace)*IF( ILVL ) THENIF( ILVR ) THENCHTEMP = 'B'ELSECHTEMP = 'L'END IFELSECHTEMP = 'R'END IF*CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,$ VR, LDVR, N, IN, WORK( IWORK ), IINFO )IF( IINFO.NE.0 ) THENINFO = N + 7GO TO 120END IF** Undo balancing on VL and VR, rescale*IF( ILVL ) THENCALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VL, LDVL, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 8GO TO 120END IFDO 50 JC = 1, NIF( ALPHAI( JC ).LT.ZERO )$ GO TO 50TEMP = ZEROIF( ALPHAI( JC ).EQ.ZERO ) THENDO 10 JR = 1, NTEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )10 CONTINUEELSEDO 20 JR = 1, NTEMP = MAX( TEMP, ABS( VL( JR, JC ) )+$ ABS( VL( JR, JC+1 ) ) )20 CONTINUEEND IFIF( TEMP.LT.SAFMIN )$ GO TO 50TEMP = ONE / TEMPIF( ALPHAI( JC ).EQ.ZERO ) THENDO 30 JR = 1, NVL( JR, JC ) = VL( JR, JC )*TEMP30 CONTINUEELSEDO 40 JR = 1, NVL( JR, JC ) = VL( JR, JC )*TEMPVL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP40 CONTINUEEND IF50 CONTINUEEND IFIF( ILVR ) THENCALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VR, LDVR, IINFO )IF( IINFO.NE.0 ) THENINFO = N + 9GO TO 120END IFDO 100 JC = 1, NIF( ALPHAI( JC ).LT.ZERO )$ GO TO 100TEMP = ZEROIF( ALPHAI( JC ).EQ.ZERO ) THENDO 60 JR = 1, NTEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )60 CONTINUEELSEDO 70 JR = 1, NTEMP = MAX( TEMP, ABS( VR( JR, JC ) )+$ ABS( VR( JR, JC+1 ) ) )70 CONTINUEEND IFIF( TEMP.LT.SAFMIN )$ GO TO 100TEMP = ONE / TEMPIF( ALPHAI( JC ).EQ.ZERO ) THENDO 80 JR = 1, NVR( JR, JC ) = VR( JR, JC )*TEMP80 CONTINUEELSEDO 90 JR = 1, NVR( JR, JC ) = VR( JR, JC )*TEMPVR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP90 CONTINUEEND IF100 CONTINUEEND IF** End of eigenvector calculation*END IF** Undo scaling in alpha, beta** Note: this does not give the alpha and beta for the unscaled* problem.** Un-scaling is limited to avoid underflow in alpha and beta* if they are significant.*DO 110 JC = 1, NABSAR = ABS( ALPHAR( JC ) )ABSAI = ABS( ALPHAI( JC ) )ABSB = ABS( BETA( JC ) )SALFAR = ANRM*ALPHAR( JC )SALFAI = ANRM*ALPHAI( JC )SBETA = BNRM*BETA( JC )ILIMIT = .FALSE.SCALE = ONE** Check for significant underflow in ALPHAI*IF( ABS( SALFAI ).LT.SAFMIN .AND. ABSAI.GE.$ MAX( SAFMIN, EPS*ABSAR, EPS*ABSB ) ) THENILIMIT = .TRUE.SCALE = ( ONEPLS*SAFMIN / ANRM1 ) /$ MAX( ONEPLS*SAFMIN, ANRM2*ABSAI )*ELSE IF( SALFAI.EQ.ZERO ) THEN** If insignificant underflow in ALPHAI, then make the* conjugate eigenvalue real.*IF( ALPHAI( JC ).LT.ZERO .AND. JC.GT.1 ) THENALPHAI( JC-1 ) = ZEROELSE IF( ALPHAI( JC ).GT.ZERO .AND. JC.LT.N ) THENALPHAI( JC+1 ) = ZEROEND IFEND IF** Check for significant underflow in ALPHAR*IF( ABS( SALFAR ).LT.SAFMIN .AND. ABSAR.GE.$ MAX( SAFMIN, EPS*ABSAI, EPS*ABSB ) ) THENILIMIT = .TRUE.SCALE = MAX( SCALE, ( ONEPLS*SAFMIN / ANRM1 ) /$ MAX( ONEPLS*SAFMIN, ANRM2*ABSAR ) )END IF** Check for significant underflow in BETA*IF( ABS( SBETA ).LT.SAFMIN .AND. ABSB.GE.$ MAX( SAFMIN, EPS*ABSAR, EPS*ABSAI ) ) THENILIMIT = .TRUE.SCALE = MAX( SCALE, ( ONEPLS*SAFMIN / BNRM1 ) /$ MAX( ONEPLS*SAFMIN, BNRM2*ABSB ) )END IF** Check for possible overflow when limiting scaling*IF( ILIMIT ) THENTEMP = ( SCALE*SAFMIN )*MAX( ABS( SALFAR ), ABS( SALFAI ),$ ABS( SBETA ) )IF( TEMP.GT.ONE )$ SCALE = SCALE / TEMPIF( SCALE.LT.ONE )$ ILIMIT = .FALSE.END IF** Recompute un-scaled ALPHAR, ALPHAI, BETA if necessary.*IF( ILIMIT ) THENSALFAR = ( SCALE*ALPHAR( JC ) )*ANRMSALFAI = ( SCALE*ALPHAI( JC ) )*ANRMSBETA = ( SCALE*BETA( JC ) )*BNRMEND IFALPHAR( JC ) = SALFARALPHAI( JC ) = SALFAIBETA( JC ) = SBETA110 CONTINUE*120 CONTINUEWORK( 1 ) = LWKOPT*RETURN** End of DGEGV*END*> \brief \b DGEHD2 reduces a general square matrix to upper Hessenberg form using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEHD2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgehd2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgehd2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgehd2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER IHI, ILO, INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEHD2 reduces a real general matrix A to upper Hessenberg form H by*> an orthogonal similarity transformation: Q**T * A * Q = H .*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*>*> It is assumed that A is already upper triangular in rows*> and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally*> set by a previous call to DGEBAL; otherwise they should be*> set to 1 and N respectively. See Further Details.*> 1 <= ILO <= IHI <= max(1,N).*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the n by n general matrix to be reduced.*> On exit, the upper triangle and the first subdiagonal of A*> are overwritten with the upper Hessenberg matrix H, and the*> elements below the first subdiagonal, with the array TAU,*> represent the orthogonal matrix Q as a product of elementary*> reflectors. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of (ihi-ilo) elementary*> reflectors*>*> Q = H(ilo) H(ilo+1) . . . H(ihi-1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on*> exit in A(i+2:ihi,i), and tau in TAU(i).*>*> The contents of A are illustrated by the following example, with*> n = 7, ilo = 2 and ihi = 6:*>*> on entry, on exit,*>*> ( a a a a a a a ) ( a a h h h h a )*> ( a a a a a a ) ( a h h h h a )*> ( a a a a a a ) ( h h h h h h )*> ( a a a a a a ) ( v2 h h h h h )*> ( a a a a a a ) ( v2 v3 h h h h )*> ( a a a a a a ) ( v2 v3 v4 h h h )*> ( a ) ( a )*>*> where a denotes an element of the original matrix A, h denotes a*> modified element of the upper Hessenberg matrix H, and vi denotes an*> element of the vector defining H(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEHD2( N, ILO, IHI, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, ILO, INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -2ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEHD2', -INFO )RETURNEND IF*DO 10 I = ILO, IHI - 1** Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)*CALL DLARFG( IHI-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,$ TAU( I ) )AII = A( I+1, I )A( I+1, I ) = ONE** Apply H(i) to A(1:ihi,i+1:ihi) from the right*CALL DLARF( 'Right', IHI, IHI-I, A( I+1, I ), 1, TAU( I ),$ A( 1, I+1 ), LDA, WORK )** Apply H(i) to A(i+1:ihi,i+1:n) from the left*CALL DLARF( 'Left', IHI-I, N-I, A( I+1, I ), 1, TAU( I ),$ A( I+1, I+1 ), LDA, WORK )*A( I+1, I ) = AII10 CONTINUE*RETURN** End of DGEHD2*END*> \brief \b DGEHRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEHRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgehrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgehrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgehrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER IHI, ILO, INFO, LDA, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEHRD reduces a real general matrix A to upper Hessenberg form H by*> an orthogonal similarity transformation: Q**T * A * Q = H .*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*>*> It is assumed that A is already upper triangular in rows*> and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally*> set by a previous call to DGEBAL; otherwise they should be*> set to 1 and N respectively. See Further Details.*> 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the N-by-N general matrix to be reduced.*> On exit, the upper triangle and the first subdiagonal of A*> are overwritten with the upper Hessenberg matrix H, and the*> elements below the first subdiagonal, with the array TAU,*> represent the orthogonal matrix Q as a product of elementary*> reflectors. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> The scalar factors of the elementary reflectors (see Further*> Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to*> zero.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of the array WORK. LWORK >= max(1,N).*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of (ihi-ilo) elementary*> reflectors*>*> Q = H(ilo) H(ilo+1) . . . H(ihi-1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on*> exit in A(i+2:ihi,i), and tau in TAU(i).*>*> The contents of A are illustrated by the following example, with*> n = 7, ilo = 2 and ihi = 6:*>*> on entry, on exit,*>*> ( a a a a a a a ) ( a a h h h h a )*> ( a a a a a a ) ( a h h h h a )*> ( a a a a a a ) ( h h h h h h )*> ( a a a a a a ) ( v2 h h h h h )*> ( a a a a a a ) ( v2 v3 h h h h )*> ( a a a a a a ) ( v2 v3 v4 h h h )*> ( a ) ( a )*>*> where a denotes an element of the original matrix A, h denotes a*> modified element of the upper Hessenberg matrix H, and vi denotes an*> element of the vector defining H(i).*>*> This file is a slight modification of LAPACK-3.0's DGEHRD*> subroutine incorporating improvements proposed by Quintana-Orti and*> Van de Geijn (2006). (See DLAHR2.)*> \endverbatim*>* =====================================================================SUBROUTINE DGEHRD( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, ILO, INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER NBMAX, LDT, TSIZEPARAMETER ( NBMAX = 64, LDT = NBMAX+1,$ TSIZE = LDT*NBMAX )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0,$ ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWT, J, LDWORK, LWKOPT, NB,$ NBMIN, NH, NXDOUBLE PRECISION EI* ..* .. External Subroutines ..EXTERNAL DAXPY, DGEHD2, DGEMM, DLAHR2, DLARFB, DTRMM,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input parameters*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -2ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -8END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*NB = MIN( NBMAX, ILAENV( 1, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )LWKOPT = N*NB + TSIZEWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEHRD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Set elements 1:ILO-1 and IHI:N-1 of TAU to zero*DO 10 I = 1, ILO - 1TAU( I ) = ZERO10 CONTINUEDO 20 I = MAX( 1, IHI ), N - 1TAU( I ) = ZERO20 CONTINUE** Quick return if possible*NH = IHI - ILO + 1IF( NH.LE.1 ) THENWORK( 1 ) = 1RETURNEND IF** Determine the block size*NB = MIN( NBMAX, ILAENV( 1, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )NBMIN = 2IF( NB.GT.1 .AND. NB.LT.NH ) THEN** Determine when to cross over from blocked to unblocked code* (last block is always handled by unblocked code)*NX = MAX( NB, ILAENV( 3, 'DGEHRD', ' ', N, ILO, IHI, -1 ) )IF( NX.LT.NH ) THEN** Determine if workspace is large enough for blocked code*IF( LWORK.LT.N*NB+TSIZE ) THEN** Not enough workspace to use optimal NB: determine the* minimum value of NB, and reduce NB or force use of* unblocked code*NBMIN = MAX( 2, ILAENV( 2, 'DGEHRD', ' ', N, ILO, IHI,$ -1 ) )IF( LWORK.GE.(N*NBMIN + TSIZE) ) THENNB = (LWORK-TSIZE) / NELSENB = 1END IFEND IFEND IFEND IFLDWORK = N*IF( NB.LT.NBMIN .OR. NB.GE.NH ) THEN** Use unblocked code below*I = ILO*ELSE** Use blocked code*IWT = 1 + N*NBDO 40 I = ILO, IHI - 1 - NX, NBIB = MIN( NB, IHI-I )** Reduce columns i:i+ib-1 to Hessenberg form, returning the* matrices V and T of the block reflector H = I - V*T*V**T* which performs the reduction, and also the matrix Y = A*V*T*CALL DLAHR2( IHI, I, IB, A( 1, I ), LDA, TAU( I ),$ WORK( IWT ), LDT, WORK, LDWORK )** Apply the block reflector H to A(1:ihi,i+ib:ihi) from the* right, computing A := A - Y * V**T. V(i+ib,ib-1) must be set* to 1*EI = A( I+IB, I+IB-1 )A( I+IB, I+IB-1 ) = ONECALL DGEMM( 'No transpose', 'Transpose',$ IHI, IHI-I-IB+1,$ IB, -ONE, WORK, LDWORK, A( I+IB, I ), LDA, ONE,$ A( 1, I+IB ), LDA )A( I+IB, I+IB-1 ) = EI** Apply the block reflector H to A(1:i,i+1:i+ib-1) from the* right*CALL DTRMM( 'Right', 'Lower', 'Transpose',$ 'Unit', I, IB-1,$ ONE, A( I+1, I ), LDA, WORK, LDWORK )DO 30 J = 0, IB-2CALL DAXPY( I, -ONE, WORK( LDWORK*J+1 ), 1,$ A( 1, I+J+1 ), 1 )30 CONTINUE** Apply the block reflector H to A(i+1:ihi,i+ib:n) from the* left*CALL DLARFB( 'Left', 'Transpose', 'Forward',$ 'Columnwise',$ IHI-I, N-I-IB+1, IB, A( I+1, I ), LDA,$ WORK( IWT ), LDT, A( I+1, I+IB ), LDA,$ WORK, LDWORK )40 CONTINUEEND IF** Use unblocked code to reduce the rest of the matrix*CALL DGEHD2( N, I, IHI, A, LDA, TAU, WORK, IINFO )WORK( 1 ) = LWKOPT*RETURN** End of DGEHRD*END*> \brief \b DGEJSV** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEJSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgejsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgejsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgejsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEJSV( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,* M, N, A, LDA, SVA, U, LDU, V, LDV,* WORK, LWORK, IWORK, INFO )** .. Scalar Arguments ..* IMPLICIT NONE* INTEGER INFO, LDA, LDU, LDV, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), SVA( N ), U( LDU, * ), V( LDV, * ),* $ WORK( LWORK )* INTEGER IWORK( * )* CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEJSV computes the singular value decomposition (SVD) of a real M-by-N*> matrix [A], where M >= N. The SVD of [A] is written as*>*> [A] = [U] * [SIGMA] * [V]^t,*>*> where [SIGMA] is an N-by-N (M-by-N) matrix which is zero except for its N*> diagonal elements, [U] is an M-by-N (or M-by-M) orthonormal matrix, and*> [V] is an N-by-N orthogonal matrix. The diagonal elements of [SIGMA] are*> the singular values of [A]. The columns of [U] and [V] are the left and*> the right singular vectors of [A], respectively. The matrices [U] and [V]*> are computed and stored in the arrays U and V, respectively. The diagonal*> of [SIGMA] is computed and stored in the array SVA.*> DGEJSV can sometimes compute tiny singular values and their singular vectors much*> more accurately than other SVD routines, see below under Further Details.*> \endverbatim** Arguments:* ==========**> \param[in] JOBA*> \verbatim*> JOBA is CHARACTER*1*> Specifies the level of accuracy:*> = 'C': This option works well (high relative accuracy) if A = B * D,*> with well-conditioned B and arbitrary diagonal matrix D.*> The accuracy cannot be spoiled by COLUMN scaling. The*> accuracy of the computed output depends on the condition of*> B, and the procedure aims at the best theoretical accuracy.*> The relative error max_{i=1:N}|d sigma_i| / sigma_i is*> bounded by f(M,N)*epsilon* cond(B), independent of D.*> The input matrix is preprocessed with the QRF with column*> pivoting. This initial preprocessing and preconditioning by*> a rank revealing QR factorization is common for all values of*> JOBA. Additional actions are specified as follows:*> = 'E': Computation as with 'C' with an additional estimate of the*> condition number of B. It provides a realistic error bound.*> = 'F': If A = D1 * C * D2 with ill-conditioned diagonal scalings*> D1, D2, and well-conditioned matrix C, this option gives*> higher accuracy than the 'C' option. If the structure of the*> input matrix is not known, and relative accuracy is*> desirable, then this option is advisable. The input matrix A*> is preprocessed with QR factorization with FULL (row and*> column) pivoting.*> = 'G' Computation as with 'F' with an additional estimate of the*> condition number of B, where A=D*B. If A has heavily weighted*> rows, then using this condition number gives too pessimistic*> error bound.*> = 'A': Small singular values are the noise and the matrix is treated*> as numerically rank deficient. The error in the computed*> singular values is bounded by f(m,n)*epsilon*||A||.*> The computed SVD A = U * S * V^t restores A up to*> f(m,n)*epsilon*||A||.*> This gives the procedure the licence to discard (set to zero)*> all singular values below N*epsilon*||A||.*> = 'R': Similar as in 'A'. Rank revealing property of the initial*> QR factorization is used do reveal (using triangular factor)*> a gap sigma_{r+1} < epsilon * sigma_r in which case the*> numerical RANK is declared to be r. The SVD is computed with*> absolute error bounds, but more accurately than with 'A'.*> \endverbatim*>*> \param[in] JOBU*> \verbatim*> JOBU is CHARACTER*1*> Specifies whether to compute the columns of U:*> = 'U': N columns of U are returned in the array U.*> = 'F': full set of M left sing. vectors is returned in the array U.*> = 'W': U may be used as workspace of length M*N. See the description*> of U.*> = 'N': U is not computed.*> \endverbatim*>*> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> Specifies whether to compute the matrix V:*> = 'V': N columns of V are returned in the array V; Jacobi rotations*> are not explicitly accumulated.*> = 'J': N columns of V are returned in the array V, but they are*> computed as the product of Jacobi rotations. This option is*> allowed only if JOBU .NE. 'N', i.e. in computing the full SVD.*> = 'W': V may be used as workspace of length N*N. See the description*> of V.*> = 'N': V is not computed.*> \endverbatim*>*> \param[in] JOBR*> \verbatim*> JOBR is CHARACTER*1*> Specifies the RANGE for the singular values. Issues the licence to*> set to zero small positive singular values if they are outside*> specified range. If A .NE. 0 is scaled so that the largest singular*> value of c*A is around DSQRT(BIG), BIG=SLAMCH('O'), then JOBR issues*> the licence to kill columns of A whose norm in c*A is less than*> DSQRT(SFMIN) (for JOBR.EQ.'R'), or less than SMALL=SFMIN/EPSLN,*> where SFMIN=SLAMCH('S'), EPSLN=SLAMCH('E').*> = 'N': Do not kill small columns of c*A. This option assumes that*> BLAS and QR factorizations and triangular solvers are*> implemented to work in that range. If the condition of A*> is greater than BIG, use DGESVJ.*> = 'R': RESTRICTED range for sigma(c*A) is [DSQRT(SFMIN), DSQRT(BIG)]*> (roughly, as described above). This option is recommended.*> ~~~~~~~~~~~~~~~~~~~~~~~~~~~*> For computing the singular values in the FULL range [SFMIN,BIG]*> use DGESVJ.*> \endverbatim*>*> \param[in] JOBT*> \verbatim*> JOBT is CHARACTER*1*> If the matrix is square then the procedure may determine to use*> transposed A if A^t seems to be better with respect to convergence.*> If the matrix is not square, JOBT is ignored. This is subject to*> changes in the future.*> The decision is based on two values of entropy over the adjoint*> orbit of A^t * A. See the descriptions of WORK(6) and WORK(7).*> = 'T': transpose if entropy test indicates possibly faster*> convergence of Jacobi process if A^t is taken as input. If A is*> replaced with A^t, then the row pivoting is included automatically.*> = 'N': do not speculate.*> This option can be used to compute only the singular values, or the*> full SVD (U, SIGMA and V). For only one set of singular vectors*> (U or V), the caller should provide both U and V, as one of the*> matrices is used as workspace if the matrix A is transposed.*> The implementer can easily remove this constraint and make the*> code more complicated. See the descriptions of U and V.*> \endverbatim*>*> \param[in] JOBP*> \verbatim*> JOBP is CHARACTER*1*> Issues the licence to introduce structured perturbations to drown*> denormalized numbers. This licence should be active if the*> denormals are poorly implemented, causing slow computation,*> especially in cases of fast convergence (!). For details see [1,2].*> For the sake of simplicity, this perturbations are included only*> when the full SVD or only the singular values are requested. The*> implementer/user can easily add the perturbation for the cases of*> computing one set of singular vectors.*> = 'P': introduce perturbation*> = 'N': do not perturb*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the input matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the input matrix A. M >= N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] SVA*> \verbatim*> SVA is DOUBLE PRECISION array, dimension (N)*> On exit,*> - For WORK(1)/WORK(2) = ONE: The singular values of A. During the*> computation SVA contains Euclidean column norms of the*> iterated matrices in the array A.*> - For WORK(1) .NE. WORK(2): The singular values of A are*> (WORK(1)/WORK(2)) * SVA(1:N). This factored form is used if*> sigma_max(A) overflows or if small singular values have been*> saved from underflow by scaling the input matrix A.*> - If JOBR='R' then some of the singular values may be returned*> as exact zeros obtained by "set to zero" because they are*> below the numerical rank threshold or are denormalized numbers.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension ( LDU, N )*> If JOBU = 'U', then U contains on exit the M-by-N matrix of*> the left singular vectors.*> If JOBU = 'F', then U contains on exit the M-by-M matrix of*> the left singular vectors, including an ONB*> of the orthogonal complement of the Range(A).*> If JOBU = 'W' .AND. (JOBV.EQ.'V' .AND. JOBT.EQ.'T' .AND. M.EQ.N),*> then U is used as workspace if the procedure*> replaces A with A^t. In that case, [V] is computed*> in U as left singular vectors of A^t and then*> copied back to the V array. This 'W' option is just*> a reminder to the caller that in this case U is*> reserved as workspace of length N*N.*> If JOBU = 'N' U is not referenced, unless JOBT='T'.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U, LDU >= 1.*> IF JOBU = 'U' or 'F' or 'W', then LDU >= M.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension ( LDV, N )*> If JOBV = 'V', 'J' then V contains on exit the N-by-N matrix of*> the right singular vectors;*> If JOBV = 'W', AND (JOBU.EQ.'U' AND JOBT.EQ.'T' AND M.EQ.N),*> then V is used as workspace if the pprocedure*> replaces A with A^t. In that case, [U] is computed*> in V as right singular vectors of A^t and then*> copied back to the U array. This 'W' option is just*> a reminder to the caller that in this case V is*> reserved as workspace of length N*N.*> If JOBV = 'N' V is not referenced, unless JOBT='T'.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V, LDV >= 1.*> If JOBV = 'V' or 'J' or 'W', then LDV >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, if N.GT.0 .AND. M.GT.0 (else not referenced),*> WORK(1) = SCALE = WORK(2) / WORK(1) is the scaling factor such*> that SCALE*SVA(1:N) are the computed singular values*> of A. (See the description of SVA().)*> WORK(2) = See the description of WORK(1).*> WORK(3) = SCONDA is an estimate for the condition number of*> column equilibrated A. (If JOBA .EQ. 'E' or 'G')*> SCONDA is an estimate of DSQRT(||(R^t * R)^(-1)||_1).*> It is computed using DPOCON. It holds*> N^(-1/4) * SCONDA <= ||R^(-1)||_2 <= N^(1/4) * SCONDA*> where R is the triangular factor from the QRF of A.*> However, if R is truncated and the numerical rank is*> determined to be strictly smaller than N, SCONDA is*> returned as -1, thus indicating that the smallest*> singular values might be lost.*>*> If full SVD is needed, the following two condition numbers are*> useful for the analysis of the algorithm. They are provied for*> a developer/implementer who is familiar with the details of*> the method.*>*> WORK(4) = an estimate of the scaled condition number of the*> triangular factor in the first QR factorization.*> WORK(5) = an estimate of the scaled condition number of the*> triangular factor in the second QR factorization.*> The following two parameters are computed if JOBT .EQ. 'T'.*> They are provided for a developer/implementer who is familiar*> with the details of the method.*>*> WORK(6) = the entropy of A^t*A :: this is the Shannon entropy*> of diag(A^t*A) / Trace(A^t*A) taken as point in the*> probability simplex.*> WORK(7) = the entropy of A*A^t.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> Length of WORK to confirm proper allocation of work space.*> LWORK depends on the job:*>*> If only SIGMA is needed ( JOBU.EQ.'N', JOBV.EQ.'N' ) and*> -> .. no scaled condition estimate required (JOBE.EQ.'N'):*> LWORK >= max(2*M+N,4*N+1,7). This is the minimal requirement.*> ->> For optimal performance (blocked code) the optimal value*> is LWORK >= max(2*M+N,3*N+(N+1)*NB,7). Here NB is the optimal*> block size for DGEQP3 and DGEQRF.*> In general, optimal LWORK is computed as*> LWORK >= max(2*M+N,N+LWORK(DGEQP3),N+LWORK(DGEQRF), 7).*> -> .. an estimate of the scaled condition number of A is*> required (JOBA='E', 'G'). In this case, LWORK is the maximum*> of the above and N*N+4*N, i.e. LWORK >= max(2*M+N,N*N+4*N,7).*> ->> For optimal performance (blocked code) the optimal value*> is LWORK >= max(2*M+N,3*N+(N+1)*NB, N*N+4*N, 7).*> In general, the optimal length LWORK is computed as*> LWORK >= max(2*M+N,N+LWORK(DGEQP3),N+LWORK(DGEQRF),*> N+N*N+LWORK(DPOCON),7).*>*> If SIGMA and the right singular vectors are needed (JOBV.EQ.'V'),*> -> the minimal requirement is LWORK >= max(2*M+N,4*N+1,7).*> -> For optimal performance, LWORK >= max(2*M+N,3*N+(N+1)*NB,7),*> where NB is the optimal block size for DGEQP3, DGEQRF, DGELQF,*> DORMLQ. In general, the optimal length LWORK is computed as*> LWORK >= max(2*M+N,N+LWORK(DGEQP3), N+LWORK(DPOCON),*> N+LWORK(DGELQF), 2*N+LWORK(DGEQRF), N+LWORK(DORMLQ)).*>*> If SIGMA and the left singular vectors are needed*> -> the minimal requirement is LWORK >= max(2*M+N,4*N+1,7).*> -> For optimal performance:*> if JOBU.EQ.'U' :: LWORK >= max(2*M+N,3*N+(N+1)*NB,7),*> if JOBU.EQ.'F' :: LWORK >= max(2*M+N,3*N+(N+1)*NB,N+M*NB,7),*> where NB is the optimal block size for DGEQP3, DGEQRF, DORMQR.*> In general, the optimal length LWORK is computed as*> LWORK >= max(2*M+N,N+LWORK(DGEQP3),N+LWORK(DPOCON),*> 2*N+LWORK(DGEQRF), N+LWORK(DORMQR)).*> Here LWORK(DORMQR) equals N*NB (for JOBU.EQ.'U') or*> M*NB (for JOBU.EQ.'F').*>*> If the full SVD is needed: (JOBU.EQ.'U' or JOBU.EQ.'F') and*> -> if JOBV.EQ.'V'*> the minimal requirement is LWORK >= max(2*M+N,6*N+2*N*N).*> -> if JOBV.EQ.'J' the minimal requirement is*> LWORK >= max(2*M+N, 4*N+N*N,2*N+N*N+6).*> -> For optimal performance, LWORK should be additionally*> larger than N+M*NB, where NB is the optimal block size*> for DORMQR.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (M+3*N).*> On exit,*> IWORK(1) = the numerical rank determined after the initial*> QR factorization with pivoting. See the descriptions*> of JOBA and JOBR.*> IWORK(2) = the number of the computed nonzero singular values*> IWORK(3) = if nonzero, a warning message:*> If IWORK(3).EQ.1 then some of the column norms of A*> were denormalized floats. The requested high accuracy*> is not warranted by the data.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> < 0 : if INFO = -i, then the i-th argument had an illegal value.*> = 0 : successful exit;*> > 0 : DGEJSV did not converge in the maximal allowed number*> of sweeps. The computed values may be inaccurate.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEsing**> \par Further Details:* =====================*>*> \verbatim*>*> DGEJSV implements a preconditioned Jacobi SVD algorithm. It uses DGEQP3,*> DGEQRF, and DGELQF as preprocessors and preconditioners. Optionally, an*> additional row pivoting can be used as a preprocessor, which in some*> cases results in much higher accuracy. An example is matrix A with the*> structure A = D1 * C * D2, where D1, D2 are arbitrarily ill-conditioned*> diagonal matrices and C is well-conditioned matrix. In that case, complete*> pivoting in the first QR factorizations provides accuracy dependent on the*> condition number of C, and independent of D1, D2. Such higher accuracy is*> not completely understood theoretically, but it works well in practice.*> Further, if A can be written as A = B*D, with well-conditioned B and some*> diagonal D, then the high accuracy is guaranteed, both theoretically and*> in software, independent of D. For more details see [1], [2].*> The computational range for the singular values can be the full range*> ( UNDERFLOW,OVERFLOW ), provided that the machine arithmetic and the BLAS*> & LAPACK routines called by DGEJSV are implemented to work in that range.*> If that is not the case, then the restriction for safe computation with*> the singular values in the range of normalized IEEE numbers is that the*> spectral condition number kappa(A)=sigma_max(A)/sigma_min(A) does not*> overflow. This code (DGEJSV) is best used in this restricted range,*> meaning that singular values of magnitude below ||A||_2 / DLAMCH('O') are*> returned as zeros. See JOBR for details on this.*> Further, this implementation is somewhat slower than the one described*> in [1,2] due to replacement of some non-LAPACK components, and because*> the choice of some tuning parameters in the iterative part (DGESVJ) is*> left to the implementer on a particular machine.*> The rank revealing QR factorization (in this code: DGEQP3) should be*> implemented as in [3]. We have a new version of DGEQP3 under development*> that is more robust than the current one in LAPACK, with a cleaner cut in*> rank deficient cases. It will be available in the SIGMA library [4].*> If M is much larger than N, it is obvious that the initial QRF with*> column pivoting can be preprocessed by the QRF without pivoting. That*> well known trick is not used in DGEJSV because in some cases heavy row*> weighting can be treated with complete pivoting. The overhead in cases*> M much larger than N is then only due to pivoting, but the benefits in*> terms of accuracy have prevailed. The implementer/user can incorporate*> this extra QRF step easily. The implementer can also improve data movement*> (matrix transpose, matrix copy, matrix transposed copy) - this*> implementation of DGEJSV uses only the simplest, naive data movement.*> \endverbatim**> \par Contributors:* ==================*>*> Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)**> \par References:* ================*>*> \verbatim*>*> [1] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm I.*> SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1322-1342.*> LAPACK Working note 169.*> [2] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm II.*> SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1343-1362.*> LAPACK Working note 170.*> [3] Z. Drmac and Z. Bujanovic: On the failure of rank-revealing QR*> factorization software - a case study.*> ACM Trans. Math. Softw. Vol. 35, No 2 (2008), pp. 1-28.*> LAPACK Working note 176.*> [4] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV,*> QSVD, (H,K)-SVD computations.*> Department of Mathematics, University of Zagreb, 2008.*> \endverbatim**> \par Bugs, examples and comments:* =================================*>*> Please report all bugs and send interesting examples and/or comments to*> drmac@math.hr. Thank you.*>* =====================================================================SUBROUTINE DGEJSV( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,$ M, N, A, LDA, SVA, U, LDU, V, LDV,$ WORK, LWORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..IMPLICIT NONEINTEGER INFO, LDA, LDU, LDV, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), SVA( N ), U( LDU, * ), V( LDV, * ),$ WORK( LWORK )INTEGER IWORK( * )CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV* ..** ===========================================================================** .. Local Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, COND_OK,$ CONDR1, CONDR2, ENTRA, ENTRAT, EPSLN, MAXPRJ, SCALEM,$ SCONDA, SFMIN, SMALL, TEMP1, USCAL1, USCAL2, XSCINTEGER IERR, N1, NR, NUMRANK, p, q, WARNINGLOGICAL ALMORT, DEFR, ERREST, GOSCAL, JRACC, KILL, LSVEC,$ L2ABER, L2KILL, L2PERT, L2RANK, L2TRAN,$ NOSCAL, ROWPIV, RSVEC, TRANSP* ..* .. Intrinsic Functions ..INTRINSIC DABS, DLOG, MAX, MIN, DBLE, IDNINT, DSIGN, DSQRT* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DNRM2INTEGER IDAMAXLOGICAL LSAMEEXTERNAL IDAMAX, LSAME, DLAMCH, DNRM2* ..* .. External Subroutines ..EXTERNAL DCOPY, DGELQF, DGEQP3, DGEQRF, DLACPY, DLASCL,$ DLASET, DLASSQ, DLASWP, DORGQR, DORMLQ,$ DORMQR, DPOCON, DSCAL, DSWAP, DTRSM, XERBLA*EXTERNAL DGESVJ* ..** Test the input arguments*LSVEC = LSAME( JOBU, 'U' ) .OR. LSAME( JOBU, 'F' )JRACC = LSAME( JOBV, 'J' )RSVEC = LSAME( JOBV, 'V' ) .OR. JRACCROWPIV = LSAME( JOBA, 'F' ) .OR. LSAME( JOBA, 'G' )L2RANK = LSAME( JOBA, 'R' )L2ABER = LSAME( JOBA, 'A' )ERREST = LSAME( JOBA, 'E' ) .OR. LSAME( JOBA, 'G' )L2TRAN = LSAME( JOBT, 'T' )L2KILL = LSAME( JOBR, 'R' )DEFR = LSAME( JOBR, 'N' )L2PERT = LSAME( JOBP, 'P' )*IF ( .NOT.(ROWPIV .OR. L2RANK .OR. L2ABER .OR.$ ERREST .OR. LSAME( JOBA, 'C' ) )) THENINFO = - 1ELSE IF ( .NOT.( LSVEC .OR. LSAME( JOBU, 'N' ) .OR.$ LSAME( JOBU, 'W' )) ) THENINFO = - 2ELSE IF ( .NOT.( RSVEC .OR. LSAME( JOBV, 'N' ) .OR.$ LSAME( JOBV, 'W' )) .OR. ( JRACC .AND. (.NOT.LSVEC) ) ) THENINFO = - 3ELSE IF ( .NOT. ( L2KILL .OR. DEFR ) ) THENINFO = - 4ELSE IF ( .NOT. ( L2TRAN .OR. LSAME( JOBT, 'N' ) ) ) THENINFO = - 5ELSE IF ( .NOT. ( L2PERT .OR. LSAME( JOBP, 'N' ) ) ) THENINFO = - 6ELSE IF ( M .LT. 0 ) THENINFO = - 7ELSE IF ( ( N .LT. 0 ) .OR. ( N .GT. M ) ) THENINFO = - 8ELSE IF ( LDA .LT. M ) THENINFO = - 10ELSE IF ( LSVEC .AND. ( LDU .LT. M ) ) THENINFO = - 13ELSE IF ( RSVEC .AND. ( LDV .LT. N ) ) THENINFO = - 15ELSE IF ( (.NOT.(LSVEC .OR. RSVEC .OR. ERREST).AND.& (LWORK .LT. MAX(7,4*N+1,2*M+N))) .OR.& (.NOT.(LSVEC .OR. RSVEC) .AND. ERREST .AND.& (LWORK .LT. MAX(7,4*N+N*N,2*M+N))) .OR.& (LSVEC .AND. (.NOT.RSVEC) .AND. (LWORK .LT. MAX(7,2*M+N,4*N+1)))& .OR.& (RSVEC .AND. (.NOT.LSVEC) .AND. (LWORK .LT. MAX(7,2*M+N,4*N+1)))& .OR.& (LSVEC .AND. RSVEC .AND. (.NOT.JRACC) .AND.& (LWORK.LT.MAX(2*M+N,6*N+2*N*N)))& .OR. (LSVEC .AND. RSVEC .AND. JRACC .AND.& LWORK.LT.MAX(2*M+N,4*N+N*N,2*N+N*N+6)))& THENINFO = - 17ELSE* #:)INFO = 0END IF*IF ( INFO .NE. 0 ) THEN* #:(CALL XERBLA( 'DGEJSV', - INFO )RETURNEND IF** Quick return for void matrix (Y3K safe)* #:)IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) THENIWORK(1:3) = 0WORK(1:7) = 0RETURNENDIF** Determine whether the matrix U should be M x N or M x M*IF ( LSVEC ) THENN1 = NIF ( LSAME( JOBU, 'F' ) ) N1 = MEND IF** Set numerical parameters**! NOTE: Make sure DLAMCH() does not fail on the target architecture.*EPSLN = DLAMCH('Epsilon')SFMIN = DLAMCH('SafeMinimum')SMALL = SFMIN / EPSLNBIG = DLAMCH('O')* BIG = ONE / SFMIN** Initialize SVA(1:N) = diag( ||A e_i||_2 )_1^N**(!) If necessary, scale SVA() to protect the largest norm from* overflow. It is possible that this scaling pushes the smallest* column norm left from the underflow threshold (extreme case).*SCALEM = ONE / DSQRT(DBLE(M)*DBLE(N))NOSCAL = .TRUE.GOSCAL = .TRUE.DO 1874 p = 1, NAAPP = ZEROAAQQ = ONECALL DLASSQ( M, A(1,p), 1, AAPP, AAQQ )IF ( AAPP .GT. BIG ) THENINFO = - 9CALL XERBLA( 'DGEJSV', -INFO )RETURNEND IFAAQQ = DSQRT(AAQQ)IF ( ( AAPP .LT. (BIG / AAQQ) ) .AND. NOSCAL ) THENSVA(p) = AAPP * AAQQELSENOSCAL = .FALSE.SVA(p) = AAPP * ( AAQQ * SCALEM )IF ( GOSCAL ) THENGOSCAL = .FALSE.CALL DSCAL( p-1, SCALEM, SVA, 1 )END IFEND IF1874 CONTINUE*IF ( NOSCAL ) SCALEM = ONE*AAPP = ZEROAAQQ = BIGDO 4781 p = 1, NAAPP = MAX( AAPP, SVA(p) )IF ( SVA(p) .NE. ZERO ) AAQQ = MIN( AAQQ, SVA(p) )4781 CONTINUE** Quick return for zero M x N matrix* #:)IF ( AAPP .EQ. ZERO ) THENIF ( LSVEC ) CALL DLASET( 'G', M, N1, ZERO, ONE, U, LDU )IF ( RSVEC ) CALL DLASET( 'G', N, N, ZERO, ONE, V, LDV )WORK(1) = ONEWORK(2) = ONEIF ( ERREST ) WORK(3) = ONEIF ( LSVEC .AND. RSVEC ) THENWORK(4) = ONEWORK(5) = ONEEND IFIF ( L2TRAN ) THENWORK(6) = ZEROWORK(7) = ZEROEND IFIWORK(1) = 0IWORK(2) = 0IWORK(3) = 0RETURNEND IF** Issue warning if denormalized column norms detected. Override the* high relative accuracy request. Issue licence to kill columns* (set them to zero) whose norm is less than sigma_max / BIG (roughly).* #:(WARNING = 0IF ( AAQQ .LE. SFMIN ) THENL2RANK = .TRUE.L2KILL = .TRUE.WARNING = 1END IF** Quick return for one-column matrix* #:)IF ( N .EQ. 1 ) THEN*IF ( LSVEC ) THENCALL DLASCL( 'G',0,0,SVA(1),SCALEM, M,1,A(1,1),LDA,IERR )CALL DLACPY( 'A', M, 1, A, LDA, U, LDU )* computing all M left singular vectors of the M x 1 matrixIF ( N1 .NE. N ) THENCALL DGEQRF( M, N, U,LDU, WORK, WORK(N+1),LWORK-N,IERR )CALL DORGQR( M,N1,1, U,LDU,WORK,WORK(N+1),LWORK-N,IERR )CALL DCOPY( M, A(1,1), 1, U(1,1), 1 )END IFEND IFIF ( RSVEC ) THENV(1,1) = ONEEND IFIF ( SVA(1) .LT. (BIG*SCALEM) ) THENSVA(1) = SVA(1) / SCALEMSCALEM = ONEEND IFWORK(1) = ONE / SCALEMWORK(2) = ONEIF ( SVA(1) .NE. ZERO ) THENIWORK(1) = 1IF ( ( SVA(1) / SCALEM) .GE. SFMIN ) THENIWORK(2) = 1ELSEIWORK(2) = 0END IFELSEIWORK(1) = 0IWORK(2) = 0END IFIWORK(3) = 0IF ( ERREST ) WORK(3) = ONEIF ( LSVEC .AND. RSVEC ) THENWORK(4) = ONEWORK(5) = ONEEND IFIF ( L2TRAN ) THENWORK(6) = ZEROWORK(7) = ZEROEND IFRETURN*END IF*TRANSP = .FALSE.L2TRAN = L2TRAN .AND. ( M .EQ. N )*AATMAX = -ONEAATMIN = BIGIF ( ROWPIV .OR. L2TRAN ) THEN** Compute the row norms, needed to determine row pivoting sequence* (in the case of heavily row weighted A, row pivoting is strongly* advised) and to collect information needed to compare the* structures of A * A^t and A^t * A (in the case L2TRAN.EQ..TRUE.).*IF ( L2TRAN ) THENDO 1950 p = 1, MXSC = ZEROTEMP1 = ONECALL DLASSQ( N, A(p,1), LDA, XSC, TEMP1 )* DLASSQ gets both the ell_2 and the ell_infinity norm* in one pass through the vectorWORK(M+N+p) = XSC * SCALEMWORK(N+p) = XSC * (SCALEM*DSQRT(TEMP1))AATMAX = MAX( AATMAX, WORK(N+p) )IF (WORK(N+p) .NE. ZERO) AATMIN = MIN(AATMIN,WORK(N+p))1950 CONTINUEELSEDO 1904 p = 1, MWORK(M+N+p) = SCALEM*DABS( A(p,IDAMAX(N,A(p,1),LDA)) )AATMAX = MAX( AATMAX, WORK(M+N+p) )AATMIN = MIN( AATMIN, WORK(M+N+p) )1904 CONTINUEEND IF*END IF** For square matrix A try to determine whether A^t would be better* input for the preconditioned Jacobi SVD, with faster convergence.* The decision is based on an O(N) function of the vector of column* and row norms of A, based on the Shannon entropy. This should give* the right choice in most cases when the difference actually matters.* It may fail and pick the slower converging side.*ENTRA = ZEROENTRAT = ZEROIF ( L2TRAN ) THEN*XSC = ZEROTEMP1 = ONECALL DLASSQ( N, SVA, 1, XSC, TEMP1 )TEMP1 = ONE / TEMP1*ENTRA = ZERODO 1113 p = 1, NBIG1 = ( ( SVA(p) / XSC )**2 ) * TEMP1IF ( BIG1 .NE. ZERO ) ENTRA = ENTRA + BIG1 * DLOG(BIG1)1113 CONTINUEENTRA = - ENTRA / DLOG(DBLE(N))** Now, SVA().^2/Trace(A^t * A) is a point in the probability simplex.* It is derived from the diagonal of A^t * A. Do the same with the* diagonal of A * A^t, compute the entropy of the corresponding* probability distribution. Note that A * A^t and A^t * A have the* same trace.*ENTRAT = ZERODO 1114 p = N+1, N+MBIG1 = ( ( WORK(p) / XSC )**2 ) * TEMP1IF ( BIG1 .NE. ZERO ) ENTRAT = ENTRAT + BIG1 * DLOG(BIG1)1114 CONTINUEENTRAT = - ENTRAT / DLOG(DBLE(M))** Analyze the entropies and decide A or A^t. Smaller entropy* usually means better input for the algorithm.*TRANSP = ( ENTRAT .LT. ENTRA )** If A^t is better than A, transpose A.*IF ( TRANSP ) THEN* In an optimal implementation, this trivial transpose* should be replaced with faster transpose.DO 1115 p = 1, N - 1DO 1116 q = p + 1, NTEMP1 = A(q,p)A(q,p) = A(p,q)A(p,q) = TEMP11116 CONTINUE1115 CONTINUEDO 1117 p = 1, NWORK(M+N+p) = SVA(p)SVA(p) = WORK(N+p)1117 CONTINUETEMP1 = AAPPAAPP = AATMAXAATMAX = TEMP1TEMP1 = AAQQAAQQ = AATMINAATMIN = TEMP1KILL = LSVECLSVEC = RSVECRSVEC = KILLIF ( LSVEC ) N1 = N*ROWPIV = .TRUE.END IF*END IF* END IF L2TRAN** Scale the matrix so that its maximal singular value remains less* than DSQRT(BIG) -- the matrix is scaled so that its maximal column* has Euclidean norm equal to DSQRT(BIG/N). The only reason to keep* DSQRT(BIG) instead of BIG is the fact that DGEJSV uses LAPACK and* BLAS routines that, in some implementations, are not capable of* working in the full interval [SFMIN,BIG] and that they may provoke* overflows in the intermediate results. If the singular values spread* from SFMIN to BIG, then DGESVJ will compute them. So, in that case,* one should use DGESVJ instead of DGEJSV.*BIG1 = DSQRT( BIG )TEMP1 = DSQRT( BIG / DBLE(N) )*CALL DLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )IF ( AAQQ .GT. (AAPP * SFMIN) ) THENAAQQ = ( AAQQ / AAPP ) * TEMP1ELSEAAQQ = ( AAQQ * TEMP1 ) / AAPPEND IFTEMP1 = TEMP1 * SCALEMCALL DLASCL( 'G', 0, 0, AAPP, TEMP1, M, N, A, LDA, IERR )** To undo scaling at the end of this procedure, multiply the* computed singular values with USCAL2 / USCAL1.*USCAL1 = TEMP1USCAL2 = AAPP*IF ( L2KILL ) THEN* L2KILL enforces computation of nonzero singular values in* the restricted range of condition number of the initial A,* sigma_max(A) / sigma_min(A) approx. DSQRT(BIG)/DSQRT(SFMIN).XSC = DSQRT( SFMIN )ELSEXSC = SMALL** Now, if the condition number of A is too big,* sigma_max(A) / sigma_min(A) .GT. DSQRT(BIG/N) * EPSLN / SFMIN,* as a precaution measure, the full SVD is computed using DGESVJ* with accumulated Jacobi rotations. This provides numerically* more robust computation, at the cost of slightly increased run* time. Depending on the concrete implementation of BLAS and LAPACK* (i.e. how they behave in presence of extreme ill-conditioning) the* implementor may decide to remove this switch.IF ( ( AAQQ.LT.DSQRT(SFMIN) ) .AND. LSVEC .AND. RSVEC ) THENJRACC = .TRUE.END IF*END IFIF ( AAQQ .LT. XSC ) THENDO 700 p = 1, NIF ( SVA(p) .LT. XSC ) THENCALL DLASET( 'A', M, 1, ZERO, ZERO, A(1,p), LDA )SVA(p) = ZEROEND IF700 CONTINUEEND IF** Preconditioning using QR factorization with pivoting*IF ( ROWPIV ) THEN* Optional row permutation (Bjoerck row pivoting):* A result by Cox and Higham shows that the Bjoerck's* row pivoting combined with standard column pivoting* has similar effect as Powell-Reid complete pivoting.* The ell-infinity norms of A are made nonincreasing.DO 1952 p = 1, M - 1q = IDAMAX( M-p+1, WORK(M+N+p), 1 ) + p - 1IWORK(2*N+p) = qIF ( p .NE. q ) THENTEMP1 = WORK(M+N+p)WORK(M+N+p) = WORK(M+N+q)WORK(M+N+q) = TEMP1END IF1952 CONTINUECALL DLASWP( N, A, LDA, 1, M-1, IWORK(2*N+1), 1 )END IF** End of the preparation phase (scaling, optional sorting and* transposing, optional flushing of small columns).** Preconditioning** If the full SVD is needed, the right singular vectors are computed* from a matrix equation, and for that we need theoretical analysis* of the Businger-Golub pivoting. So we use DGEQP3 as the first RR QRF.* In all other cases the first RR QRF can be chosen by other criteria* (eg speed by replacing global with restricted window pivoting, such* as in SGEQPX from TOMS # 782). Good results will be obtained using* SGEQPX with properly (!) chosen numerical parameters.* Any improvement of DGEQP3 improves overal performance of DGEJSV.** A * P1 = Q1 * [ R1^t 0]^t:DO 1963 p = 1, N* .. all columns are free columnsIWORK(p) = 01963 CONTINUECALL DGEQP3( M,N,A,LDA, IWORK,WORK, WORK(N+1),LWORK-N, IERR )** The upper triangular matrix R1 from the first QRF is inspected for* rank deficiency and possibilities for deflation, or possible* ill-conditioning. Depending on the user specified flag L2RANK,* the procedure explores possibilities to reduce the numerical* rank by inspecting the computed upper triangular factor. If* L2RANK or L2ABER are up, then DGEJSV will compute the SVD of* A + dA, where ||dA|| <= f(M,N)*EPSLN.*NR = 1IF ( L2ABER ) THEN* Standard absolute error bound suffices. All sigma_i with* sigma_i < N*EPSLN*||A|| are flushed to zero. This is an* agressive enforcement of lower numerical rank by introducing a* backward error of the order of N*EPSLN*||A||.TEMP1 = DSQRT(DBLE(N))*EPSLNDO 3001 p = 2, NIF ( DABS(A(p,p)) .GE. (TEMP1*DABS(A(1,1))) ) THENNR = NR + 1ELSEGO TO 3002END IF3001 CONTINUE3002 CONTINUEELSE IF ( L2RANK ) THEN* .. similarly as above, only slightly more gentle (less agressive).* Sudden drop on the diagonal of R1 is used as the criterion for* close-to-rank-deficient.TEMP1 = DSQRT(SFMIN)DO 3401 p = 2, NIF ( ( DABS(A(p,p)) .LT. (EPSLN*DABS(A(p-1,p-1))) ) .OR.$ ( DABS(A(p,p)) .LT. SMALL ) .OR.$ ( L2KILL .AND. (DABS(A(p,p)) .LT. TEMP1) ) ) GO TO 3402NR = NR + 13401 CONTINUE3402 CONTINUE*ELSE* The goal is high relative accuracy. However, if the matrix* has high scaled condition number the relative accuracy is in* general not feasible. Later on, a condition number estimator* will be deployed to estimate the scaled condition number.* Here we just remove the underflowed part of the triangular* factor. This prevents the situation in which the code is* working hard to get the accuracy not warranted by the data.TEMP1 = DSQRT(SFMIN)DO 3301 p = 2, NIF ( ( DABS(A(p,p)) .LT. SMALL ) .OR.$ ( L2KILL .AND. (DABS(A(p,p)) .LT. TEMP1) ) ) GO TO 3302NR = NR + 13301 CONTINUE3302 CONTINUE*END IF*ALMORT = .FALSE.IF ( NR .EQ. N ) THENMAXPRJ = ONEDO 3051 p = 2, NTEMP1 = DABS(A(p,p)) / SVA(IWORK(p))MAXPRJ = MIN( MAXPRJ, TEMP1 )3051 CONTINUEIF ( MAXPRJ**2 .GE. ONE - DBLE(N)*EPSLN ) ALMORT = .TRUE.END IF**SCONDA = - ONECONDR1 = - ONECONDR2 = - ONE*IF ( ERREST ) THENIF ( N .EQ. NR ) THENIF ( RSVEC ) THEN* .. V is available as workspaceCALL DLACPY( 'U', N, N, A, LDA, V, LDV )DO 3053 p = 1, NTEMP1 = SVA(IWORK(p))CALL DSCAL( p, ONE/TEMP1, V(1,p), 1 )3053 CONTINUECALL DPOCON( 'U', N, V, LDV, ONE, TEMP1,$ WORK(N+1), IWORK(2*N+M+1), IERR )ELSE IF ( LSVEC ) THEN* .. U is available as workspaceCALL DLACPY( 'U', N, N, A, LDA, U, LDU )DO 3054 p = 1, NTEMP1 = SVA(IWORK(p))CALL DSCAL( p, ONE/TEMP1, U(1,p), 1 )3054 CONTINUECALL DPOCON( 'U', N, U, LDU, ONE, TEMP1,$ WORK(N+1), IWORK(2*N+M+1), IERR )ELSECALL DLACPY( 'U', N, N, A, LDA, WORK(N+1), N )DO 3052 p = 1, NTEMP1 = SVA(IWORK(p))CALL DSCAL( p, ONE/TEMP1, WORK(N+(p-1)*N+1), 1 )3052 CONTINUE* .. the columns of R are scaled to have unit Euclidean lengths.CALL DPOCON( 'U', N, WORK(N+1), N, ONE, TEMP1,$ WORK(N+N*N+1), IWORK(2*N+M+1), IERR )END IFSCONDA = ONE / DSQRT(TEMP1)* SCONDA is an estimate of DSQRT(||(R^t * R)^(-1)||_1).* N^(-1/4) * SCONDA <= ||R^(-1)||_2 <= N^(1/4) * SCONDAELSESCONDA = - ONEEND IFEND IF*L2PERT = L2PERT .AND. ( DABS( A(1,1)/A(NR,NR) ) .GT. DSQRT(BIG1) )* If there is no violent scaling, artificial perturbation is not needed.** Phase 3:*IF ( .NOT. ( RSVEC .OR. LSVEC ) ) THEN** Singular Values only** .. transpose A(1:NR,1:N)DO 1946 p = 1, MIN( N-1, NR )CALL DCOPY( N-p, A(p,p+1), LDA, A(p+1,p), 1 )1946 CONTINUE** The following two DO-loops introduce small relative perturbation* into the strict upper triangle of the lower triangular matrix.* Small entries below the main diagonal are also changed.* This modification is useful if the computing environment does not* provide/allow FLUSH TO ZERO underflow, for it prevents many* annoying denormalized numbers in case of strongly scaled matrices.* The perturbation is structured so that it does not introduce any* new perturbation of the singular values, and it does not destroy* the job done by the preconditioner.* The licence for this perturbation is in the variable L2PERT, which* should be .FALSE. if FLUSH TO ZERO underflow is active.*IF ( .NOT. ALMORT ) THEN*IF ( L2PERT ) THEN* XSC = DSQRT(SMALL)XSC = EPSLN / DBLE(N)DO 4947 q = 1, NRTEMP1 = XSC*DABS(A(q,q))DO 4949 p = 1, NIF ( ( (p.GT.q) .AND. (DABS(A(p,q)).LE.TEMP1) )$ .OR. ( p .LT. q ) )$ A(p,q) = DSIGN( TEMP1, A(p,q) )4949 CONTINUE4947 CONTINUEELSECALL DLASET( 'U', NR-1,NR-1, ZERO,ZERO, A(1,2),LDA )END IF** .. second preconditioning using the QR factorization*CALL DGEQRF( N,NR, A,LDA, WORK, WORK(N+1),LWORK-N, IERR )** .. and transpose upper to lower triangularDO 1948 p = 1, NR - 1CALL DCOPY( NR-p, A(p,p+1), LDA, A(p+1,p), 1 )1948 CONTINUE*END IF** Row-cyclic Jacobi SVD algorithm with column pivoting** .. again some perturbation (a "background noise") is added* to drown denormalsIF ( L2PERT ) THEN* XSC = DSQRT(SMALL)XSC = EPSLN / DBLE(N)DO 1947 q = 1, NRTEMP1 = XSC*DABS(A(q,q))DO 1949 p = 1, NRIF ( ( (p.GT.q) .AND. (DABS(A(p,q)).LE.TEMP1) )$ .OR. ( p .LT. q ) )$ A(p,q) = DSIGN( TEMP1, A(p,q) )1949 CONTINUE1947 CONTINUEELSECALL DLASET( 'U', NR-1, NR-1, ZERO, ZERO, A(1,2), LDA )END IF** .. and one-sided Jacobi rotations are started on a lower* triangular matrix (plus perturbation which is ignored in* the part which destroys triangular form (confusing?!))*CALL DGESVJ( 'L', 'NoU', 'NoV', NR, NR, A, LDA, SVA,$ N, V, LDV, WORK, LWORK, INFO )*SCALEM = WORK(1)NUMRANK = IDNINT(WORK(2))**ELSE IF ( RSVEC .AND. ( .NOT. LSVEC ) ) THEN** -> Singular Values and Right Singular Vectors <-*IF ( ALMORT ) THEN** .. in this case NR equals NDO 1998 p = 1, NRCALL DCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )1998 CONTINUECALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )*CALL DGESVJ( 'L','U','N', N, NR, V,LDV, SVA, NR, A,LDA,$ WORK, LWORK, INFO )SCALEM = WORK(1)NUMRANK = IDNINT(WORK(2))ELSE** .. two more QR factorizations ( one QRF is not enough, two require* accumulated product of Jacobi rotations, three are perfect )*CALL DLASET( 'Lower', NR-1, NR-1, ZERO, ZERO, A(2,1), LDA )CALL DGELQF( NR, N, A, LDA, WORK, WORK(N+1), LWORK-N, IERR)CALL DLACPY( 'Lower', NR, NR, A, LDA, V, LDV )CALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )CALL DGEQRF( NR, NR, V, LDV, WORK(N+1), WORK(2*N+1),$ LWORK-2*N, IERR )DO 8998 p = 1, NRCALL DCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 )8998 CONTINUECALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )*CALL DGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U,$ LDU, WORK(N+1), LWORK, INFO )SCALEM = WORK(N+1)NUMRANK = IDNINT(WORK(N+2))IF ( NR .LT. N ) THENCALL DLASET( 'A',N-NR, NR, ZERO,ZERO, V(NR+1,1), LDV )CALL DLASET( 'A',NR, N-NR, ZERO,ZERO, V(1,NR+1), LDV )CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE, V(NR+1,NR+1), LDV )END IF*CALL DORMLQ( 'Left', 'Transpose', N, N, NR, A, LDA, WORK,$ V, LDV, WORK(N+1), LWORK-N, IERR )*END IF*DO 8991 p = 1, NCALL DCOPY( N, V(p,1), LDV, A(IWORK(p),1), LDA )8991 CONTINUECALL DLACPY( 'All', N, N, A, LDA, V, LDV )*IF ( TRANSP ) THENCALL DLACPY( 'All', N, N, V, LDV, U, LDU )END IF*ELSE IF ( LSVEC .AND. ( .NOT. RSVEC ) ) THEN** .. Singular Values and Left Singular Vectors ..** .. second preconditioning step to avoid need to accumulate* Jacobi rotations in the Jacobi iterations.DO 1965 p = 1, NRCALL DCOPY( N-p+1, A(p,p), LDA, U(p,p), 1 )1965 CONTINUECALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )*CALL DGEQRF( N, NR, U, LDU, WORK(N+1), WORK(2*N+1),$ LWORK-2*N, IERR )*DO 1967 p = 1, NR - 1CALL DCOPY( NR-p, U(p,p+1), LDU, U(p+1,p), 1 )1967 CONTINUECALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )*CALL DGESVJ( 'Lower', 'U', 'N', NR,NR, U, LDU, SVA, NR, A,$ LDA, WORK(N+1), LWORK-N, INFO )SCALEM = WORK(N+1)NUMRANK = IDNINT(WORK(N+2))*IF ( NR .LT. M ) THENCALL DLASET( 'A', M-NR, NR,ZERO, ZERO, U(NR+1,1), LDU )IF ( NR .LT. N1 ) THENCALL DLASET( 'A',NR, N1-NR, ZERO, ZERO, U(1,NR+1), LDU )CALL DLASET( 'A',M-NR,N1-NR,ZERO,ONE,U(NR+1,NR+1), LDU )END IFEND IF*CALL DORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,$ LDU, WORK(N+1), LWORK-N, IERR )*IF ( ROWPIV )$ CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )*DO 1974 p = 1, N1XSC = ONE / DNRM2( M, U(1,p), 1 )CALL DSCAL( M, XSC, U(1,p), 1 )1974 CONTINUE*IF ( TRANSP ) THENCALL DLACPY( 'All', N, N, U, LDU, V, LDV )END IF*ELSE** .. Full SVD ..*IF ( .NOT. JRACC ) THEN*IF ( .NOT. ALMORT ) THEN** Second Preconditioning Step (QRF [with pivoting])* Note that the composition of TRANSPOSE, QRF and TRANSPOSE is* equivalent to an LQF CALL. Since in many libraries the QRF* seems to be better optimized than the LQF, we do explicit* transpose and use the QRF. This is subject to changes in an* optimized implementation of DGEJSV.*DO 1968 p = 1, NRCALL DCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )1968 CONTINUE** .. the following two loops perturb small entries to avoid* denormals in the second QR factorization, where they are* as good as zeros. This is done to avoid painfully slow* computation with denormals. The relative size of the perturbation* is a parameter that can be changed by the implementer.* This perturbation device will be obsolete on machines with* properly implemented arithmetic.* To switch it off, set L2PERT=.FALSE. To remove it from the* code, remove the action under L2PERT=.TRUE., leave the ELSE part.* The following two loops should be blocked and fused with the* transposed copy above.*IF ( L2PERT ) THENXSC = DSQRT(SMALL)DO 2969 q = 1, NRTEMP1 = XSC*DABS( V(q,q) )DO 2968 p = 1, NIF ( ( p .GT. q ) .AND. ( DABS(V(p,q)) .LE. TEMP1 )$ .OR. ( p .LT. q ) )$ V(p,q) = DSIGN( TEMP1, V(p,q) )IF ( p .LT. q ) V(p,q) = - V(p,q)2968 CONTINUE2969 CONTINUEELSECALL DLASET( 'U', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )END IF** Estimate the row scaled condition number of R1* (If R1 is rectangular, N > NR, then the condition number* of the leading NR x NR submatrix is estimated.)*CALL DLACPY( 'L', NR, NR, V, LDV, WORK(2*N+1), NR )DO 3950 p = 1, NRTEMP1 = DNRM2(NR-p+1,WORK(2*N+(p-1)*NR+p),1)CALL DSCAL(NR-p+1,ONE/TEMP1,WORK(2*N+(p-1)*NR+p),1)3950 CONTINUECALL DPOCON('Lower',NR,WORK(2*N+1),NR,ONE,TEMP1,$ WORK(2*N+NR*NR+1),IWORK(M+2*N+1),IERR)CONDR1 = ONE / DSQRT(TEMP1)* .. here need a second oppinion on the condition number* .. then assume worst case scenario* R1 is OK for inverse <=> CONDR1 .LT. DBLE(N)* more conservative <=> CONDR1 .LT. DSQRT(DBLE(N))*COND_OK = DSQRT(DBLE(NR))*[TP] COND_OK is a tuning parameter.IF ( CONDR1 .LT. COND_OK ) THEN* .. the second QRF without pivoting. Note: in an optimized* implementation, this QRF should be implemented as the QRF* of a lower triangular matrix.* R1^t = Q2 * R2CALL DGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),$ LWORK-2*N, IERR )*IF ( L2PERT ) THENXSC = DSQRT(SMALL)/EPSLNDO 3959 p = 2, NRDO 3958 q = 1, p - 1TEMP1 = XSC * MIN(DABS(V(p,p)),DABS(V(q,q)))IF ( DABS(V(q,p)) .LE. TEMP1 )$ V(q,p) = DSIGN( TEMP1, V(q,p) )3958 CONTINUE3959 CONTINUEEND IF*IF ( NR .NE. N )$ CALL DLACPY( 'A', N, NR, V, LDV, WORK(2*N+1), N )* .. save ...** .. this transposed copy should be better than naiveDO 1969 p = 1, NR - 1CALL DCOPY( NR-p, V(p,p+1), LDV, V(p+1,p), 1 )1969 CONTINUE*CONDR2 = CONDR1*ELSE** .. ill-conditioned case: second QRF with pivoting* Note that windowed pivoting would be equaly good* numerically, and more run-time efficient. So, in* an optimal implementation, the next call to DGEQP3* should be replaced with eg. CALL SGEQPX (ACM TOMS #782)* with properly (carefully) chosen parameters.** R1^t * P2 = Q2 * R2DO 3003 p = 1, NRIWORK(N+p) = 03003 CONTINUECALL DGEQP3( N, NR, V, LDV, IWORK(N+1), WORK(N+1),$ WORK(2*N+1), LWORK-2*N, IERR )** CALL DGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),** $ LWORK-2*N, IERR )IF ( L2PERT ) THENXSC = DSQRT(SMALL)DO 3969 p = 2, NRDO 3968 q = 1, p - 1TEMP1 = XSC * MIN(DABS(V(p,p)),DABS(V(q,q)))IF ( DABS(V(q,p)) .LE. TEMP1 )$ V(q,p) = DSIGN( TEMP1, V(q,p) )3968 CONTINUE3969 CONTINUEEND IF*CALL DLACPY( 'A', N, NR, V, LDV, WORK(2*N+1), N )*IF ( L2PERT ) THENXSC = DSQRT(SMALL)DO 8970 p = 2, NRDO 8971 q = 1, p - 1TEMP1 = XSC * MIN(DABS(V(p,p)),DABS(V(q,q)))V(p,q) = - DSIGN( TEMP1, V(q,p) )8971 CONTINUE8970 CONTINUEELSECALL DLASET( 'L',NR-1,NR-1,ZERO,ZERO,V(2,1),LDV )END IF* Now, compute R2 = L3 * Q3, the LQ factorization.CALL DGELQF( NR, NR, V, LDV, WORK(2*N+N*NR+1),$ WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, IERR )* .. and estimate the condition numberCALL DLACPY( 'L',NR,NR,V,LDV,WORK(2*N+N*NR+NR+1),NR )DO 4950 p = 1, NRTEMP1 = DNRM2( p, WORK(2*N+N*NR+NR+p), NR )CALL DSCAL( p, ONE/TEMP1, WORK(2*N+N*NR+NR+p), NR )4950 CONTINUECALL DPOCON( 'L',NR,WORK(2*N+N*NR+NR+1),NR,ONE,TEMP1,$ WORK(2*N+N*NR+NR+NR*NR+1),IWORK(M+2*N+1),IERR )CONDR2 = ONE / DSQRT(TEMP1)*IF ( CONDR2 .GE. COND_OK ) THEN* .. save the Householder vectors used for Q3* (this overwrittes the copy of R2, as it will not be* needed in this branch, but it does not overwritte the* Huseholder vectors of Q2.).CALL DLACPY( 'U', NR, NR, V, LDV, WORK(2*N+1), N )* .. and the rest of the information on Q3 is in* WORK(2*N+N*NR+1:2*N+N*NR+N)END IF*END IF*IF ( L2PERT ) THENXSC = DSQRT(SMALL)DO 4968 q = 2, NRTEMP1 = XSC * V(q,q)DO 4969 p = 1, q - 1* V(p,q) = - DSIGN( TEMP1, V(q,p) )V(p,q) = - DSIGN( TEMP1, V(p,q) )4969 CONTINUE4968 CONTINUEELSECALL DLASET( 'U', NR-1,NR-1, ZERO,ZERO, V(1,2), LDV )END IF** Second preconditioning finished; continue with Jacobi SVD* The input matrix is lower trinagular.** Recover the right singular vectors as solution of a well* conditioned triangular matrix equation.*IF ( CONDR1 .LT. COND_OK ) THEN*CALL DGESVJ( 'L','U','N',NR,NR,V,LDV,SVA,NR,U,$ LDU,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,INFO )SCALEM = WORK(2*N+N*NR+NR+1)NUMRANK = IDNINT(WORK(2*N+N*NR+NR+2))DO 3970 p = 1, NRCALL DCOPY( NR, V(1,p), 1, U(1,p), 1 )CALL DSCAL( NR, SVA(p), V(1,p), 1 )3970 CONTINUE* .. pick the right matrix equation and solve it*IF ( NR .EQ. N ) THEN* :)) .. best case, R1 is inverted. The solution of this matrix* equation is Q2*V2 = the product of the Jacobi rotations* used in DGESVJ, premultiplied with the orthogonal matrix* from the second QR factorization.CALL DTRSM( 'L','U','N','N', NR,NR,ONE, A,LDA, V,LDV )ELSE* .. R1 is well conditioned, but non-square. Transpose(R2)* is inverted to get the product of the Jacobi rotations* used in DGESVJ. The Q-factor from the second QR* factorization is then built in explicitly.CALL DTRSM('L','U','T','N',NR,NR,ONE,WORK(2*N+1),$ N,V,LDV)IF ( NR .LT. N ) THENCALL DLASET('A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV)CALL DLASET('A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV)CALL DLASET('A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV)END IFCALL DORMQR('L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),$ V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR)END IF*ELSE IF ( CONDR2 .LT. COND_OK ) THEN** :) .. the input matrix A is very likely a relative of* the Kahan matrix :)* The matrix R2 is inverted. The solution of the matrix equation* is Q3^T*V3 = the product of the Jacobi rotations (appplied to* the lower triangular L3 from the LQ factorization of* R2=L3*Q3), pre-multiplied with the transposed Q3.CALL DGESVJ( 'L', 'U', 'N', NR, NR, V, LDV, SVA, NR, U,$ LDU, WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, INFO )SCALEM = WORK(2*N+N*NR+NR+1)NUMRANK = IDNINT(WORK(2*N+N*NR+NR+2))DO 3870 p = 1, NRCALL DCOPY( NR, V(1,p), 1, U(1,p), 1 )CALL DSCAL( NR, SVA(p), U(1,p), 1 )3870 CONTINUECALL DTRSM('L','U','N','N',NR,NR,ONE,WORK(2*N+1),N,U,LDU)* .. apply the permutation from the second QR factorizationDO 873 q = 1, NRDO 872 p = 1, NRWORK(2*N+N*NR+NR+IWORK(N+p)) = U(p,q)872 CONTINUEDO 874 p = 1, NRU(p,q) = WORK(2*N+N*NR+NR+p)874 CONTINUE873 CONTINUEIF ( NR .LT. N ) THENCALL DLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )CALL DLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )END IFCALL DORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),$ V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )ELSE* Last line of defense.* #:( This is a rather pathological case: no scaled condition* improvement after two pivoted QR factorizations. Other* possibility is that the rank revealing QR factorization* or the condition estimator has failed, or the COND_OK* is set very close to ONE (which is unnecessary). Normally,* this branch should never be executed, but in rare cases of* failure of the RRQR or condition estimator, the last line of* defense ensures that DGEJSV completes the task.* Compute the full SVD of L3 using DGESVJ with explicit* accumulation of Jacobi rotations.CALL DGESVJ( 'L', 'U', 'V', NR, NR, V, LDV, SVA, NR, U,$ LDU, WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, INFO )SCALEM = WORK(2*N+N*NR+NR+1)NUMRANK = IDNINT(WORK(2*N+N*NR+NR+2))IF ( NR .LT. N ) THENCALL DLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )CALL DLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )END IFCALL DORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),$ V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )*CALL DORMLQ( 'L', 'T', NR, NR, NR, WORK(2*N+1), N,$ WORK(2*N+N*NR+1), U, LDU, WORK(2*N+N*NR+NR+1),$ LWORK-2*N-N*NR-NR, IERR )DO 773 q = 1, NRDO 772 p = 1, NRWORK(2*N+N*NR+NR+IWORK(N+p)) = U(p,q)772 CONTINUEDO 774 p = 1, NRU(p,q) = WORK(2*N+N*NR+NR+p)774 CONTINUE773 CONTINUE*END IF** Permute the rows of V using the (column) permutation from the* first QRF. Also, scale the columns to make them unit in* Euclidean norm. This applies to all cases.*TEMP1 = DSQRT(DBLE(N)) * EPSLNDO 1972 q = 1, NDO 972 p = 1, NWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)972 CONTINUEDO 973 p = 1, NV(p,q) = WORK(2*N+N*NR+NR+p)973 CONTINUEXSC = ONE / DNRM2( N, V(1,q), 1 )IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )$ CALL DSCAL( N, XSC, V(1,q), 1 )1972 CONTINUE* At this moment, V contains the right singular vectors of A.* Next, assemble the left singular vector matrix U (M x N).IF ( NR .LT. M ) THENCALL DLASET( 'A', M-NR, NR, ZERO, ZERO, U(NR+1,1), LDU )IF ( NR .LT. N1 ) THENCALL DLASET('A',NR,N1-NR,ZERO,ZERO,U(1,NR+1),LDU)CALL DLASET('A',M-NR,N1-NR,ZERO,ONE,U(NR+1,NR+1),LDU)END IFEND IF** The Q matrix from the first QRF is built into the left singular* matrix U. This applies to all cases.*CALL DORMQR( 'Left', 'No_Tr', M, N1, N, A, LDA, WORK, U,$ LDU, WORK(N+1), LWORK-N, IERR )* The columns of U are normalized. The cost is O(M*N) flops.TEMP1 = DSQRT(DBLE(M)) * EPSLNDO 1973 p = 1, NRXSC = ONE / DNRM2( M, U(1,p), 1 )IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )$ CALL DSCAL( M, XSC, U(1,p), 1 )1973 CONTINUE** If the initial QRF is computed with row pivoting, the left* singular vectors must be adjusted.*IF ( ROWPIV )$ CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )*ELSE** .. the initial matrix A has almost orthogonal columns and* the second QRF is not needed*CALL DLACPY( 'Upper', N, N, A, LDA, WORK(N+1), N )IF ( L2PERT ) THENXSC = DSQRT(SMALL)DO 5970 p = 2, NTEMP1 = XSC * WORK( N + (p-1)*N + p )DO 5971 q = 1, p - 1WORK(N+(q-1)*N+p)=-DSIGN(TEMP1,WORK(N+(p-1)*N+q))5971 CONTINUE5970 CONTINUEELSECALL DLASET( 'Lower',N-1,N-1,ZERO,ZERO,WORK(N+2),N )END IF*CALL DGESVJ( 'Upper', 'U', 'N', N, N, WORK(N+1), N, SVA,$ N, U, LDU, WORK(N+N*N+1), LWORK-N-N*N, INFO )*SCALEM = WORK(N+N*N+1)NUMRANK = IDNINT(WORK(N+N*N+2))DO 6970 p = 1, NCALL DCOPY( N, WORK(N+(p-1)*N+1), 1, U(1,p), 1 )CALL DSCAL( N, SVA(p), WORK(N+(p-1)*N+1), 1 )6970 CONTINUE*CALL DTRSM( 'Left', 'Upper', 'NoTrans', 'No UD', N, N,$ ONE, A, LDA, WORK(N+1), N )DO 6972 p = 1, NCALL DCOPY( N, WORK(N+p), N, V(IWORK(p),1), LDV )6972 CONTINUETEMP1 = DSQRT(DBLE(N))*EPSLNDO 6971 p = 1, NXSC = ONE / DNRM2( N, V(1,p), 1 )IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )$ CALL DSCAL( N, XSC, V(1,p), 1 )6971 CONTINUE** Assemble the left singular vector matrix U (M x N).*IF ( N .LT. M ) THENCALL DLASET( 'A', M-N, N, ZERO, ZERO, U(N+1,1), LDU )IF ( N .LT. N1 ) THENCALL DLASET( 'A',N, N1-N, ZERO, ZERO, U(1,N+1),LDU )CALL DLASET( 'A',M-N,N1-N, ZERO, ONE,U(N+1,N+1),LDU )END IFEND IFCALL DORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,$ LDU, WORK(N+1), LWORK-N, IERR )TEMP1 = DSQRT(DBLE(M))*EPSLNDO 6973 p = 1, N1XSC = ONE / DNRM2( M, U(1,p), 1 )IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )$ CALL DSCAL( M, XSC, U(1,p), 1 )6973 CONTINUE*IF ( ROWPIV )$ CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )*END IF** end of the >> almost orthogonal case << in the full SVD*ELSE** This branch deploys a preconditioned Jacobi SVD with explicitly* accumulated rotations. It is included as optional, mainly for* experimental purposes. It does perfom well, and can also be used.* In this implementation, this branch will be automatically activated* if the condition number sigma_max(A) / sigma_min(A) is predicted* to be greater than the overflow threshold. This is because the* a posteriori computation of the singular vectors assumes robust* implementation of BLAS and some LAPACK procedures, capable of working* in presence of extreme values. Since that is not always the case, ...*DO 7968 p = 1, NRCALL DCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )7968 CONTINUE*IF ( L2PERT ) THENXSC = DSQRT(SMALL/EPSLN)DO 5969 q = 1, NRTEMP1 = XSC*DABS( V(q,q) )DO 5968 p = 1, NIF ( ( p .GT. q ) .AND. ( DABS(V(p,q)) .LE. TEMP1 )$ .OR. ( p .LT. q ) )$ V(p,q) = DSIGN( TEMP1, V(p,q) )IF ( p .LT. q ) V(p,q) = - V(p,q)5968 CONTINUE5969 CONTINUEELSECALL DLASET( 'U', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )END IFCALL DGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),$ LWORK-2*N, IERR )CALL DLACPY( 'L', N, NR, V, LDV, WORK(2*N+1), N )*DO 7969 p = 1, NRCALL DCOPY( NR-p+1, V(p,p), LDV, U(p,p), 1 )7969 CONTINUEIF ( L2PERT ) THENXSC = DSQRT(SMALL/EPSLN)DO 9970 q = 2, NRDO 9971 p = 1, q - 1TEMP1 = XSC * MIN(DABS(U(p,p)),DABS(U(q,q)))U(p,q) = - DSIGN( TEMP1, U(q,p) )9971 CONTINUE9970 CONTINUEELSECALL DLASET('U', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )END IFCALL DGESVJ( 'G', 'U', 'V', NR, NR, U, LDU, SVA,$ N, V, LDV, WORK(2*N+N*NR+1), LWORK-2*N-N*NR, INFO )SCALEM = WORK(2*N+N*NR+1)NUMRANK = IDNINT(WORK(2*N+N*NR+2))IF ( NR .LT. N ) THENCALL DLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )CALL DLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )END IFCALL DORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),$ V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )** Permute the rows of V using the (column) permutation from the* first QRF. Also, scale the columns to make them unit in* Euclidean norm. This applies to all cases.*TEMP1 = DSQRT(DBLE(N)) * EPSLNDO 7972 q = 1, NDO 8972 p = 1, NWORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)8972 CONTINUEDO 8973 p = 1, NV(p,q) = WORK(2*N+N*NR+NR+p)8973 CONTINUEXSC = ONE / DNRM2( N, V(1,q), 1 )IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )$ CALL DSCAL( N, XSC, V(1,q), 1 )7972 CONTINUE** At this moment, V contains the right singular vectors of A.* Next, assemble the left singular vector matrix U (M x N).*IF ( NR .LT. M ) THENCALL DLASET( 'A', M-NR, NR, ZERO, ZERO, U(NR+1,1), LDU )IF ( NR .LT. N1 ) THENCALL DLASET( 'A',NR, N1-NR, ZERO, ZERO, U(1,NR+1),LDU )CALL DLASET( 'A',M-NR,N1-NR, ZERO, ONE,U(NR+1,NR+1),LDU )END IFEND IF*CALL DORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,$ LDU, WORK(N+1), LWORK-N, IERR )*IF ( ROWPIV )$ CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )**END IFIF ( TRANSP ) THEN* .. swap U and V because the procedure worked on A^tDO 6974 p = 1, NCALL DSWAP( N, U(1,p), 1, V(1,p), 1 )6974 CONTINUEEND IF*END IF* end of the full SVD** Undo scaling, if necessary (and possible)*IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THENCALL DLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )USCAL1 = ONEUSCAL2 = ONEEND IF*IF ( NR .LT. N ) THENDO 3004 p = NR+1, NSVA(p) = ZERO3004 CONTINUEEND IF*WORK(1) = USCAL2 * SCALEMWORK(2) = USCAL1IF ( ERREST ) WORK(3) = SCONDAIF ( LSVEC .AND. RSVEC ) THENWORK(4) = CONDR1WORK(5) = CONDR2END IFIF ( L2TRAN ) THENWORK(6) = ENTRAWORK(7) = ENTRATEND IF*IWORK(1) = NRIWORK(2) = NUMRANKIWORK(3) = WARNING*RETURN* ..* .. END OF DGEJSV* ..END**> \brief \b DGELQ2 computes the LQ factorization of a general rectangular matrix using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELQ2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelq2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgelq2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelq2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELQ2( M, N, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGELQ2 computes an LQ factorization of a real m by n matrix A:*> A = L * Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n matrix A.*> On exit, the elements on and below the diagonal of the array*> contain the m by min(m,n) lower trapezoidal matrix L (L is*> lower triangular if m <= n); the elements above the diagonal,*> with the array TAU, represent the orthogonal matrix Q as a*> product of elementary reflectors (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (M)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(k) . . . H(2) H(1), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),*> and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGELQ2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGELQ2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = 1, K** Generate elementary reflector H(i) to annihilate A(i,i+1:n)*CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,$ TAU( I ) )IF( I.LT.M ) THEN** Apply H(i) to A(i+1:m,i:n) from the right*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA, TAU( I ),$ A( I+1, I ), LDA, WORK )A( I, I ) = AIIEND IF10 CONTINUERETURN** End of DGELQ2*END*> \brief \b DGELQF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELQF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelqf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgelqf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelqf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGELQF computes an LQ factorization of a real M-by-N matrix A:*> A = L * Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the elements on and below the diagonal of the array*> contain the m-by-min(m,n) lower trapezoidal matrix L (L is*> lower triangular if m <= n); the elements above the diagonal,*> with the array TAU, represent the orthogonal matrix Q as a*> product of elementary reflectors (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,M).*> For optimum performance LWORK >= M*NB, where NB is the*> optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(k) . . . H(2) H(1), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i,i+1:n),*> and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGELQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DGELQ2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )LWKOPT = M*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGELQF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = MIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGELQF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGELQF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially*DO 10 I = 1, K - NX, NBIB = MIN( K-I+1, NB )** Compute the LQ factorization of the current block* A(i:i+ib-1,i:n)*CALL DGELQ2( IB, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )IF( I+IB.LE.M ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),$ LDA, TAU( I ), WORK, LDWORK )** Apply H to A(i+ib:m,i:n) from the right*CALL DLARFB( 'Right', 'No transpose', 'Forward',$ 'Rowwise', M-I-IB+1, N-I+1, IB, A( I, I ),$ LDA, WORK, LDWORK, A( I+IB, I ), LDA,$ WORK( IB+1 ), LDWORK )END IF10 CONTINUEELSEI = 1END IF** Use unblocked code to factor the last or only block.*IF( I.LE.K )$ CALL DGELQ2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )*WORK( 1 ) = IWSRETURN** End of DGELQF*END*> \brief <b> DGELS solves overdetermined or underdetermined systems for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgels.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgels.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgels.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,* INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGELS solves overdetermined or underdetermined real linear systems*> involving an M-by-N matrix A, or its transpose, using a QR or LQ*> factorization of A. It is assumed that A has full rank.*>*> The following options are provided:*>*> 1. If TRANS = 'N' and m >= n: find the least squares solution of*> an overdetermined system, i.e., solve the least squares problem*> minimize || B - A*X ||.*>*> 2. If TRANS = 'N' and m < n: find the minimum norm solution of*> an underdetermined system A * X = B.*>*> 3. If TRANS = 'T' and m >= n: find the minimum norm solution of*> an underdetermined system A**T * X = B.*>*> 4. If TRANS = 'T' and m < n: find the least squares solution of*> an overdetermined system, i.e., solve the least squares problem*> minimize || B - A**T * X ||.*>*> Several right hand side vectors b and solution vectors x can be*> handled in a single call; they are stored as the columns of the*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution*> matrix X.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': the linear system involves A;*> = 'T': the linear system involves A**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of*> columns of the matrices B and X. NRHS >=0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit,*> if M >= N, A is overwritten by details of its QR*> factorization as returned by DGEQRF;*> if M < N, A is overwritten by details of its LQ*> factorization as returned by DGELQF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the matrix B of right hand side vectors, stored*> columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS*> if TRANS = 'T'.*> On exit, if INFO = 0, B is overwritten by the solution*> vectors, stored columnwise:*> if TRANS = 'N' and m >= n, rows 1 to n of B contain the least*> squares solution vectors; the residual sum of squares for the*> solution in each column is given by the sum of squares of*> elements N+1 to M in that column;*> if TRANS = 'N' and m < n, rows 1 to N of B contain the*> minimum norm solution vectors;*> if TRANS = 'T' and m >= n, rows 1 to M of B contain the*> minimum norm solution vectors;*> if TRANS = 'T' and m < n, rows 1 to M of B contain the*> least squares solution vectors; the residual sum of squares*> for the solution in each column is given by the sum of*> squares of elements M+1 to N in that column.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= MAX(1,M,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> LWORK >= max( 1, MN + max( MN, NRHS ) ).*> For optimal performance,*> LWORK >= max( 1, MN + max( MN, NRHS )*NB ).*> where MN = min(M,N) and NB is the optimum block size.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element of the*> triangular factor of A is zero, so that A does not have*> full rank; the least squares solution could not be*> computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEsolve** =====================================================================SUBROUTINE DGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,$ INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDA, LDB, LWORK, M, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, TPSDINTEGER BROW, I, IASCL, IBSCL, J, MN, NB, SCLLEN, WSIZEDOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM* ..* .. Local Arrays ..DOUBLE PRECISION RWORK( 1 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLABAD, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DGELQF, DGEQRF, DLASCL, DLASET, DORMLQ, DORMQR,$ DTRTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX, MIN* ..* .. Executable Statements ..** Test the input arguments.*INFO = 0MN = MIN( M, N )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.( LSAME( TRANS, 'N' ) .OR. LSAME( TRANS, 'T' ) ) ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, M, N ) ) THENINFO = -8ELSE IF( LWORK.LT.MAX( 1, MN+MAX( MN, NRHS ) ) .AND. .NOT.LQUERY )$ THENINFO = -10END IF** Figure out optimal block size*IF( INFO.EQ.0 .OR. INFO.EQ.-10 ) THEN*TPSD = .TRUE.IF( LSAME( TRANS, 'N' ) )$ TPSD = .FALSE.*IF( M.GE.N ) THENNB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )IF( TPSD ) THENNB = MAX( NB, ILAENV( 1, 'DORMQR', 'LN', M, NRHS, N,$ -1 ) )ELSENB = MAX( NB, ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N,$ -1 ) )END IFELSENB = ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )IF( TPSD ) THENNB = MAX( NB, ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M,$ -1 ) )ELSENB = MAX( NB, ILAENV( 1, 'DORMLQ', 'LN', N, NRHS, M,$ -1 ) )END IFEND IF*WSIZE = MAX( 1, MN+MAX( MN, NRHS )*NB )WORK( 1 ) = DBLE( WSIZE )*END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGELS ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( MIN( M, N, NRHS ).EQ.0 ) THENCALL DLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )RETURNEND IF** Get machine parameters*SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Scale A, B if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, RWORK )IASCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )IASCL = 1ELSE IF( ANRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )IASCL = 2ELSE IF( ANRM.EQ.ZERO ) THEN** Matrix all zero. Return zero solution.*CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )GO TO 50END IF*BROW = MIF( TPSD )$ BROW = NBNRM = DLANGE( 'M', BROW, NRHS, B, LDB, RWORK )IBSCL = 0IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, BROW, NRHS, B, LDB,$ INFO )IBSCL = 1ELSE IF( BNRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, BROW, NRHS, B, LDB,$ INFO )IBSCL = 2END IF*IF( M.GE.N ) THEN** compute QR factorization of A*CALL DGEQRF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,$ INFO )** workspace at least N, optimally N*NB*IF( .NOT.TPSD ) THEN** Least-Squares Problem min || A * X - B ||** B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)*CALL DORMQR( 'Left', 'Transpose', M, NRHS, N, A, LDA,$ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,$ INFO )** workspace at least NRHS, optimally NRHS*NB** B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)*CALL DTRTRS( 'Upper', 'No transpose', 'Non-unit', N, NRHS,$ A, LDA, B, LDB, INFO )*IF( INFO.GT.0 ) THENRETURNEND IF*SCLLEN = N*ELSE** Underdetermined system of equations A**T * X = B** B(1:N,1:NRHS) := inv(R**T) * B(1:N,1:NRHS)*CALL DTRTRS( 'Upper', 'Transpose', 'Non-unit', N, NRHS,$ A, LDA, B, LDB, INFO )*IF( INFO.GT.0 ) THENRETURNEND IF** B(N+1:M,1:NRHS) = ZERO*DO 20 J = 1, NRHSDO 10 I = N + 1, MB( I, J ) = ZERO10 CONTINUE20 CONTINUE** B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)*CALL DORMQR( 'Left', 'No transpose', M, NRHS, N, A, LDA,$ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,$ INFO )** workspace at least NRHS, optimally NRHS*NB*SCLLEN = M*END IF*ELSE** Compute LQ factorization of A*CALL DGELQF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,$ INFO )** workspace at least M, optimally M*NB.*IF( .NOT.TPSD ) THEN** underdetermined system of equations A * X = B** B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)*CALL DTRTRS( 'Lower', 'No transpose', 'Non-unit', M, NRHS,$ A, LDA, B, LDB, INFO )*IF( INFO.GT.0 ) THENRETURNEND IF** B(M+1:N,1:NRHS) = 0*DO 40 J = 1, NRHSDO 30 I = M + 1, NB( I, J ) = ZERO30 CONTINUE40 CONTINUE** B(1:N,1:NRHS) := Q(1:N,:)**T * B(1:M,1:NRHS)*CALL DORMLQ( 'Left', 'Transpose', N, NRHS, M, A, LDA,$ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,$ INFO )** workspace at least NRHS, optimally NRHS*NB*SCLLEN = N*ELSE** overdetermined system min || A**T * X - B ||** B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)*CALL DORMLQ( 'Left', 'No transpose', N, NRHS, M, A, LDA,$ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,$ INFO )** workspace at least NRHS, optimally NRHS*NB** B(1:M,1:NRHS) := inv(L**T) * B(1:M,1:NRHS)*CALL DTRTRS( 'Lower', 'Transpose', 'Non-unit', M, NRHS,$ A, LDA, B, LDB, INFO )*IF( INFO.GT.0 ) THENRETURNEND IF*SCLLEN = M*END IF*END IF** Undo scaling*IF( IASCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,$ INFO )ELSE IF( IASCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,$ INFO )END IFIF( IBSCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,$ INFO )ELSE IF( IBSCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,$ INFO )END IF*50 CONTINUEWORK( 1 ) = DBLE( WSIZE )*RETURN** End of DGELS*END*> \brief <b> DGELSD computes the minimum-norm solution to a linear least squares problem for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELSD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelsd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgelsd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelsd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,* WORK, LWORK, IWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGELSD computes the minimum-norm solution to a real linear least*> squares problem:*> minimize 2-norm(| b - A*x |)*> using the singular value decomposition (SVD) of A. A is an M-by-N*> matrix which may be rank-deficient.*>*> Several right hand side vectors b and solution vectors x can be*> handled in a single call; they are stored as the columns of the*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution*> matrix X.*>*> The problem is solved in three steps:*> (1) Reduce the coefficient matrix A to bidiagonal form with*> Householder transformations, reducing the original problem*> into a "bidiagonal least squares problem" (BLS)*> (2) Solve the BLS using a divide and conquer approach.*> (3) Apply back all the Householder transformations to solve*> the original least squares problem.*>*> The effective rank of A is determined by treating as zero those*> singular values which are less than RCOND times the largest singular*> value.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, A has been destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the M-by-NRHS right hand side matrix B.*> On exit, B is overwritten by the N-by-NRHS solution*> matrix X. If m >= n and RANK = n, the residual*> sum-of-squares for the solution in the i-th column is given*> by the sum of squares of elements n+1:m in that column.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,max(M,N)).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (min(M,N))*> The singular values of A in decreasing order.*> The condition number of A in the 2-norm = S(1)/S(min(m,n)).*> \endverbatim*>*> \param[in] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> RCOND is used to determine the effective rank of A.*> Singular values S(i) <= RCOND*S(1) are treated as zero.*> If RCOND < 0, machine precision is used instead.*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The effective rank of A, i.e., the number of singular values*> which are greater than RCOND*S(1).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK must be at least 1.*> The exact minimum amount of workspace needed depends on M,*> N and NRHS. As long as LWORK is at least*> 12*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2,*> if M is greater than or equal to N or*> 12*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS + (SMLSIZ+1)**2,*> if M is less than N, the code will execute correctly.*> SMLSIZ is returned by ILAENV and is equal to the maximum*> size of the subproblems at the bottom of the computation*> tree (usually about 25), and*> NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> LIWORK >= max(1, 3 * MINMN * NLVL + 11 * MINMN),*> where MINMN = MIN( M,N ).*> On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: the algorithm for computing the SVD failed to converge;*> if INFO = i, i off-diagonal elements of an intermediate*> bidiagonal form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleGEsolve**> \par Contributors:* ==================*>*> Ming Gu and Ren-Cang Li, Computer Science Division, University of*> California at Berkeley, USA \n*> Osni Marques, LBNL/NERSC, USA \n** =====================================================================SUBROUTINE DGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,$ WORK, LWORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANKDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,$ LDWORK, LIWORK, MAXMN, MAXWRK, MINMN, MINWRK,$ MM, MNTHR, NLVL, NWORK, SMLSIZ, WLALSDDOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM* ..* .. External Subroutines ..EXTERNAL DGEBRD, DGELQF, DGEQRF, DLABAD, DLACPY, DLALSD,$ DLASCL, DLASET, DORMBR, DORMLQ, DORMQR, XERBLA* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC DBLE, INT, LOG, MAX, MIN* ..* .. Executable Statements ..** Test the input arguments.*INFO = 0MINMN = MIN( M, N )MAXMN = MAX( M, N )MNTHR = ILAENV( 6, 'DGELSD', ' ', M, N, NRHS, -1 )LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THENINFO = -7END IF*SMLSIZ = ILAENV( 9, 'DGELSD', ' ', 0, 0, 0, 0 )** Compute workspace.* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)*MINWRK = 1LIWORK = 1MINMN = MAX( 1, MINMN )NLVL = MAX( INT( LOG( DBLE( MINMN ) / DBLE( SMLSIZ+1 ) ) /$ LOG( TWO ) ) + 1, 0 )*IF( INFO.EQ.0 ) THENMAXWRK = 0LIWORK = 3*MINMN*NLVL + 11*MINMNMM = MIF( M.GE.N .AND. M.GE.MNTHR ) THEN** Path 1a - overdetermined, with many more rows than columns.*MM = NMAXWRK = MAX( MAXWRK, N+N*ILAENV( 1, 'DGEQRF', ' ', M, N,$ -1, -1 ) )MAXWRK = MAX( MAXWRK, N+NRHS*$ ILAENV( 1, 'DORMQR', 'LT', M, NRHS, N, -1 ) )END IFIF( M.GE.N ) THEN** Path 1 - overdetermined or exactly determined.*MAXWRK = MAX( MAXWRK, 3*N+( MM+N )*$ ILAENV( 1, 'DGEBRD', ' ', MM, N, -1, -1 ) )MAXWRK = MAX( MAXWRK, 3*N+NRHS*$ ILAENV( 1, 'DORMBR', 'QLT', MM, NRHS, N, -1 ) )MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*$ ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, N, -1 ) )WLALSD = 9*N+2*N*SMLSIZ+8*N*NLVL+N*NRHS+(SMLSIZ+1)**2MAXWRK = MAX( MAXWRK, 3*N+WLALSD )MINWRK = MAX( 3*N+MM, 3*N+NRHS, 3*N+WLALSD )END IFIF( N.GT.M ) THENWLALSD = 9*M+2*M*SMLSIZ+8*M*NLVL+M*NRHS+(SMLSIZ+1)**2IF( N.GE.MNTHR ) THEN** Path 2a - underdetermined, with many more columns* than rows.*MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )MAXWRK = MAX( MAXWRK, M*M+4*M+2*M*$ ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )MAXWRK = MAX( MAXWRK, M*M+4*M+NRHS*$ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, M, -1 ) )MAXWRK = MAX( MAXWRK, M*M+4*M+( M-1 )*$ ILAENV( 1, 'DORMBR', 'PLN', M, NRHS, M, -1 ) )IF( NRHS.GT.1 ) THENMAXWRK = MAX( MAXWRK, M*M+M+M*NRHS )ELSEMAXWRK = MAX( MAXWRK, M*M+2*M )END IFMAXWRK = MAX( MAXWRK, M+NRHS*$ ILAENV( 1, 'DORMLQ', 'LT', N, NRHS, M, -1 ) )MAXWRK = MAX( MAXWRK, M*M+4*M+WLALSD )! XXX: Ensure the Path 2a case below is triggered. The workspace! calculation should use queries for all routines eventually.MAXWRK = MAX( MAXWRK,$ 4*M+M*M+MAX( M, 2*M-4, NRHS, N-3*M ) )ELSE** Path 2 - remaining underdetermined cases.*MAXWRK = 3*M + ( N+M )*ILAENV( 1, 'DGEBRD', ' ', M, N,$ -1, -1 )MAXWRK = MAX( MAXWRK, 3*M+NRHS*$ ILAENV( 1, 'DORMBR', 'QLT', M, NRHS, N, -1 ) )MAXWRK = MAX( MAXWRK, 3*M+M*$ ILAENV( 1, 'DORMBR', 'PLN', N, NRHS, M, -1 ) )MAXWRK = MAX( MAXWRK, 3*M+WLALSD )END IFMINWRK = MAX( 3*M+NRHS, 3*M+M, 3*M+WLALSD )END IFMINWRK = MIN( MINWRK, MAXWRK )WORK( 1 ) = MAXWRKIWORK( 1 ) = LIWORKIF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -12END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGELSD', -INFO )RETURNELSE IF( LQUERY ) THENGO TO 10END IF** Quick return if possible.*IF( M.EQ.0 .OR. N.EQ.0 ) THENRANK = 0RETURNEND IF** Get machine parameters.*EPS = DLAMCH( 'P' )SFMIN = DLAMCH( 'S' )SMLNUM = SFMIN / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Scale A if max entry outside range [SMLNUM,BIGNUM].*ANRM = DLANGE( 'M', M, N, A, LDA, WORK )IASCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM.*CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )IASCL = 1ELSE IF( ANRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM.*CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )IASCL = 2ELSE IF( ANRM.EQ.ZERO ) THEN** Matrix all zero. Return zero solution.*CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, 1 )RANK = 0GO TO 10END IF** Scale B if max entry outside range [SMLNUM,BIGNUM].*BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )IBSCL = 0IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM.*CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )IBSCL = 1ELSE IF( BNRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM.*CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )IBSCL = 2END IF** If M < N make sure certain entries of B are zero.*IF( M.LT.N )$ CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )** Overdetermined case.*IF( M.GE.N ) THEN** Path 1 - overdetermined or exactly determined.*MM = MIF( M.GE.MNTHR ) THEN** Path 1a - overdetermined, with many more rows than columns.*MM = NITAU = 1NWORK = ITAU + N** Compute A=Q*R.* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK-NWORK+1, INFO )** Multiply B by transpose(Q).* (Workspace: need N+NRHS, prefer N+NRHS*NB)*CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,$ LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )** Zero out below R.*IF( N.GT.1 ) THENCALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )END IFEND IF*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NNWORK = ITAUP + N** Bidiagonalize R in A.* (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)*CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ INFO )** Multiply B by transpose of left bidiagonalizing vectors of R.* (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)*CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),$ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )** Solve the bidiagonal least squares problem.*CALL DLALSD( 'U', SMLSIZ, N, NRHS, S, WORK( IE ), B, LDB,$ RCOND, RANK, WORK( NWORK ), IWORK, INFO )IF( INFO.NE.0 ) THENGO TO 10END IF** Multiply B by right bidiagonalizing vectors of R.*CALL DORMBR( 'P', 'L', 'N', N, NRHS, N, A, LDA, WORK( ITAUP ),$ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )*ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+$ MAX( M, 2*M-4, NRHS, N-3*M, WLALSD ) ) THEN** Path 2a - underdetermined, with many more columns than rows* and sufficient workspace for an efficient algorithm.*LDWORK = MIF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),$ M*LDA+M+M*NRHS, 4*M+M*LDA+WLALSD ) )LDWORK = LDAITAU = 1NWORK = M + 1** Compute A=L*Q.* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK-NWORK+1, INFO )IL = NWORK** Copy L to WORK(IL), zeroing out above its diagonal.*CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),$ LDWORK )IE = IL + LDWORK*MITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize L in WORK(IL).* (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),$ LWORK-NWORK+1, INFO )** Multiply B by transpose of left bidiagonalizing vectors of L.* (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)*CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,$ WORK( ITAUQ ), B, LDB, WORK( NWORK ),$ LWORK-NWORK+1, INFO )** Solve the bidiagonal least squares problem.*CALL DLALSD( 'U', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,$ RCOND, RANK, WORK( NWORK ), IWORK, INFO )IF( INFO.NE.0 ) THENGO TO 10END IF** Multiply B by right bidiagonalizing vectors of L.*CALL DORMBR( 'P', 'L', 'N', M, NRHS, M, WORK( IL ), LDWORK,$ WORK( ITAUP ), B, LDB, WORK( NWORK ),$ LWORK-NWORK+1, INFO )** Zero out below first M rows of B.*CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )NWORK = ITAU + M** Multiply transpose(Q) by B.* (Workspace: need M+NRHS, prefer M+NRHS*NB)*CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,$ LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )*ELSE** Path 2 - remaining underdetermined cases.*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize A.* (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ INFO )** Multiply B by transpose of left bidiagonalizing vectors.* (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)*CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),$ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )** Solve the bidiagonal least squares problem.*CALL DLALSD( 'L', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,$ RCOND, RANK, WORK( NWORK ), IWORK, INFO )IF( INFO.NE.0 ) THENGO TO 10END IF** Multiply B by right bidiagonalizing vectors of A.*CALL DORMBR( 'P', 'L', 'N', N, NRHS, M, A, LDA, WORK( ITAUP ),$ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )*END IF** Undo scaling.*IF( IASCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,$ INFO )ELSE IF( IASCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,$ INFO )END IFIF( IBSCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )ELSE IF( IBSCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )END IF*10 CONTINUEWORK( 1 ) = MAXWRKIWORK( 1 ) = LIWORKRETURN** End of DGELSD*END*> \brief <b> DGELSS solves overdetermined or underdetermined systems for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELSS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelss.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgelss.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelss.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,* WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGELSS computes the minimum norm solution to a real linear least*> squares problem:*>*> Minimize 2-norm(| b - A*x |).*>*> using the singular value decomposition (SVD) of A. A is an M-by-N*> matrix which may be rank-deficient.*>*> Several right hand side vectors b and solution vectors x can be*> handled in a single call; they are stored as the columns of the*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix*> X.*>*> The effective rank of A is determined by treating as zero those*> singular values which are less than RCOND times the largest singular*> value.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the first min(m,n) rows of A are overwritten with*> its right singular vectors, stored rowwise.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the M-by-NRHS right hand side matrix B.*> On exit, B is overwritten by the N-by-NRHS solution*> matrix X. If m >= n and RANK = n, the residual*> sum-of-squares for the solution in the i-th column is given*> by the sum of squares of elements n+1:m in that column.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,max(M,N)).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (min(M,N))*> The singular values of A in decreasing order.*> The condition number of A in the 2-norm = S(1)/S(min(m,n)).*> \endverbatim*>*> \param[in] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> RCOND is used to determine the effective rank of A.*> Singular values S(i) <= RCOND*S(1) are treated as zero.*> If RCOND < 0, machine precision is used instead.*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The effective rank of A, i.e., the number of singular values*> which are greater than RCOND*S(1).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= 1, and also:*> LWORK >= 3*min(M,N) + max( 2*min(M,N), max(M,N), NRHS )*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: the algorithm for computing the SVD failed to converge;*> if INFO = i, i off-diagonal elements of an intermediate*> bidiagonal form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEsolve** =====================================================================SUBROUTINE DGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,$ WORK, LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANKDOUBLE PRECISION RCOND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,$ ITAU, ITAUP, ITAUQ, IWORK, LDWORK, MAXMN,$ MAXWRK, MINMN, MINWRK, MM, MNTHRINTEGER LWORK_DGEQRF, LWORK_DORMQR, LWORK_DGEBRD,$ LWORK_DORMBR, LWORK_DORGBR, LWORK_DORMLQ,$ LWORK_DGELQFDOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DBDSQR, DCOPY, DGEBRD, DGELQF, DGEMM, DGEMV,$ DGEQRF, DLABAD, DLACPY, DLASCL, DLASET, DORGBR,$ DORMBR, DORMLQ, DORMQR, DRSCL, XERBLA* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0MINMN = MIN( M, N )MAXMN = MAX( M, N )LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, MAXMN ) ) THENINFO = -7END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)*IF( INFO.EQ.0 ) THENMINWRK = 1MAXWRK = 1IF( MINMN.GT.0 ) THENMM = MMNTHR = ILAENV( 6, 'DGELSS', ' ', M, N, NRHS, -1 )IF( M.GE.N .AND. M.GE.MNTHR ) THEN** Path 1a - overdetermined, with many more rows than* columns** Compute space needed for DGEQRFCALL DGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, INFO )LWORK_DGEQRF=DUM(1)* Compute space needed for DORMQRCALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, DUM(1), B,$ LDB, DUM(1), -1, INFO )LWORK_DORMQR=DUM(1)MM = NMAXWRK = MAX( MAXWRK, N + LWORK_DGEQRF )MAXWRK = MAX( MAXWRK, N + LWORK_DORMQR )END IFIF( M.GE.N ) THEN** Path 1 - overdetermined or exactly determined** Compute workspace needed for DBDSQR*BDSPAC = MAX( 1, 5*N )* Compute space needed for DGEBRDCALL DGEBRD( MM, N, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, INFO )LWORK_DGEBRD=DUM(1)* Compute space needed for DORMBRCALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, DUM(1),$ B, LDB, DUM(1), -1, INFO )LWORK_DORMBR=DUM(1)* Compute space needed for DORGBRCALL DORGBR( 'P', N, N, N, A, LDA, DUM(1),$ DUM(1), -1, INFO )LWORK_DORGBR=DUM(1)* Compute total workspace neededMAXWRK = MAX( MAXWRK, 3*N + LWORK_DGEBRD )MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORMBR )MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR )MAXWRK = MAX( MAXWRK, BDSPAC )MAXWRK = MAX( MAXWRK, N*NRHS )MINWRK = MAX( 3*N + MM, 3*N + NRHS, BDSPAC )MAXWRK = MAX( MINWRK, MAXWRK )END IFIF( N.GT.M ) THEN** Compute workspace needed for DBDSQR*BDSPAC = MAX( 1, 5*M )MINWRK = MAX( 3*M+NRHS, 3*M+N, BDSPAC )IF( N.GE.MNTHR ) THEN** Path 2a - underdetermined, with many more columns* than rows** Compute space needed for DGELQFCALL DGELQF( M, N, A, LDA, DUM(1), DUM(1),$ -1, INFO )LWORK_DGELQF=DUM(1)* Compute space needed for DGEBRDCALL DGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, INFO )LWORK_DGEBRD=DUM(1)* Compute space needed for DORMBRCALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA,$ DUM(1), B, LDB, DUM(1), -1, INFO )LWORK_DORMBR=DUM(1)* Compute space needed for DORGBRCALL DORGBR( 'P', M, M, M, A, LDA, DUM(1),$ DUM(1), -1, INFO )LWORK_DORGBR=DUM(1)* Compute space needed for DORMLQCALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, DUM(1),$ B, LDB, DUM(1), -1, INFO )LWORK_DORMLQ=DUM(1)* Compute total workspace neededMAXWRK = M + LWORK_DGELQFMAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DGEBRD )MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DORMBR )MAXWRK = MAX( MAXWRK, M*M + 4*M + LWORK_DORGBR )MAXWRK = MAX( MAXWRK, M*M + M + BDSPAC )IF( NRHS.GT.1 ) THENMAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )ELSEMAXWRK = MAX( MAXWRK, M*M + 2*M )END IFMAXWRK = MAX( MAXWRK, M + LWORK_DORMLQ )ELSE** Path 2 - underdetermined** Compute space needed for DGEBRDCALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, INFO )LWORK_DGEBRD=DUM(1)* Compute space needed for DORMBRCALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, A, LDA,$ DUM(1), B, LDB, DUM(1), -1, INFO )LWORK_DORMBR=DUM(1)* Compute space needed for DORGBRCALL DORGBR( 'P', M, N, M, A, LDA, DUM(1),$ DUM(1), -1, INFO )LWORK_DORGBR=DUM(1)MAXWRK = 3*M + LWORK_DGEBRDMAXWRK = MAX( MAXWRK, 3*M + LWORK_DORMBR )MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR )MAXWRK = MAX( MAXWRK, BDSPAC )MAXWRK = MAX( MAXWRK, N*NRHS )END IFEND IFMAXWRK = MAX( MINWRK, MAXWRK )END IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )$ INFO = -12END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGELSS', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENRANK = 0RETURNEND IF** Get machine parameters*EPS = DLAMCH( 'P' )SFMIN = DLAMCH( 'S' )SMLNUM = SFMIN / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, WORK )IASCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )IASCL = 1ELSE IF( ANRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )IASCL = 2ELSE IF( ANRM.EQ.ZERO ) THEN** Matrix all zero. Return zero solution.*CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )CALL DLASET( 'F', MINMN, 1, ZERO, ZERO, S, MINMN )RANK = 0GO TO 70END IF** Scale B if max element outside range [SMLNUM,BIGNUM]*BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )IBSCL = 0IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )IBSCL = 1ELSE IF( BNRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )IBSCL = 2END IF** Overdetermined case*IF( M.GE.N ) THEN** Path 1 - overdetermined or exactly determined*MM = MIF( M.GE.MNTHR ) THEN** Path 1a - overdetermined, with many more rows than columns*MM = NITAU = 1IWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N, prefer N+N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),$ LWORK-IWORK+1, INFO )** Multiply B by transpose(Q)* (Workspace: need N+NRHS, prefer N+NRHS*NB)*CALL DORMQR( 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAU ), B,$ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )** Zero out below R*IF( N.GT.1 )$ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )END IF*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in A* (Workspace: need 3*N+MM, prefer 3*N+(MM+N)*NB)*CALL DGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ INFO )** Multiply B by transpose of left bidiagonalizing vectors of R* (Workspace: need 3*N+NRHS, prefer 3*N+NRHS*NB)*CALL DORMBR( 'Q', 'L', 'T', MM, NRHS, N, A, LDA, WORK( ITAUQ ),$ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )** Generate right bidiagonalizing vectors of R in A* (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, INFO )IWORK = IE + N** Perform bidiagonal QR iteration* multiply B by transpose of left singular vectors* compute right singular vectors in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, 0, NRHS, S, WORK( IE ), A, LDA, DUM,$ 1, B, LDB, WORK( IWORK ), INFO )IF( INFO.NE.0 )$ GO TO 70** Multiply B by reciprocals of singular values*THR = MAX( RCOND*S( 1 ), SFMIN )IF( RCOND.LT.ZERO )$ THR = MAX( EPS*S( 1 ), SFMIN )RANK = 0DO 10 I = 1, NIF( S( I ).GT.THR ) THENCALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )RANK = RANK + 1ELSECALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )END IF10 CONTINUE** Multiply B by right singular vectors* (Workspace: need N, prefer N*NRHS)*IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THENCALL DGEMM( 'T', 'N', N, NRHS, N, ONE, A, LDA, B, LDB, ZERO,$ WORK, LDB )CALL DLACPY( 'G', N, NRHS, WORK, LDB, B, LDB )ELSE IF( NRHS.GT.1 ) THENCHUNK = LWORK / NDO 20 I = 1, NRHS, CHUNKBL = MIN( NRHS-I+1, CHUNK )CALL DGEMM( 'T', 'N', N, BL, N, ONE, A, LDA, B( 1, I ),$ LDB, ZERO, WORK, N )CALL DLACPY( 'G', N, BL, WORK, N, B( 1, I ), LDB )20 CONTINUEELSECALL DGEMV( 'T', N, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )CALL DCOPY( N, WORK, 1, B, 1 )END IF*ELSE IF( N.GE.MNTHR .AND. LWORK.GE.4*M+M*M+$ MAX( M, 2*M-4, NRHS, N-3*M ) ) THEN** Path 2a - underdetermined, with many more columns than rows* and sufficient workspace for an efficient algorithm*LDWORK = MIF( LWORK.GE.MAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),$ M*LDA+M+M*NRHS ) )LDWORK = LDAITAU = 1IWORK = M + 1** Compute A=L*Q* (Workspace: need 2*M, prefer M+M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),$ LWORK-IWORK+1, INFO )IL = IWORK** Copy L to WORK(IL), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWORK )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),$ LDWORK )IE = IL + LDWORK*MITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IL)* (Workspace: need M*M+5*M, prefer M*M+4*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, INFO )** Multiply B by transpose of left bidiagonalizing vectors of L* (Workspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)*CALL DORMBR( 'Q', 'L', 'T', M, NRHS, M, WORK( IL ), LDWORK,$ WORK( ITAUQ ), B, LDB, WORK( IWORK ),$ LWORK-IWORK+1, INFO )** Generate right bidiagonalizing vectors of R in WORK(IL)* (Workspace: need M*M+5*M-1, prefer M*M+4*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IL ), LDWORK, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, INFO )IWORK = IE + M** Perform bidiagonal QR iteration,* computing right singular vectors of L in WORK(IL) and* multiplying B by transpose of left singular vectors* (Workspace: need M*M+M+BDSPAC)*CALL DBDSQR( 'U', M, M, 0, NRHS, S, WORK( IE ), WORK( IL ),$ LDWORK, A, LDA, B, LDB, WORK( IWORK ), INFO )IF( INFO.NE.0 )$ GO TO 70** Multiply B by reciprocals of singular values*THR = MAX( RCOND*S( 1 ), SFMIN )IF( RCOND.LT.ZERO )$ THR = MAX( EPS*S( 1 ), SFMIN )RANK = 0DO 30 I = 1, MIF( S( I ).GT.THR ) THENCALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )RANK = RANK + 1ELSECALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )END IF30 CONTINUEIWORK = IE** Multiply B by right singular vectors of L in WORK(IL)* (Workspace: need M*M+2*M, prefer M*M+M+M*NRHS)*IF( LWORK.GE.LDB*NRHS+IWORK-1 .AND. NRHS.GT.1 ) THENCALL DGEMM( 'T', 'N', M, NRHS, M, ONE, WORK( IL ), LDWORK,$ B, LDB, ZERO, WORK( IWORK ), LDB )CALL DLACPY( 'G', M, NRHS, WORK( IWORK ), LDB, B, LDB )ELSE IF( NRHS.GT.1 ) THENCHUNK = ( LWORK-IWORK+1 ) / MDO 40 I = 1, NRHS, CHUNKBL = MIN( NRHS-I+1, CHUNK )CALL DGEMM( 'T', 'N', M, BL, M, ONE, WORK( IL ), LDWORK,$ B( 1, I ), LDB, ZERO, WORK( IWORK ), M )CALL DLACPY( 'G', M, BL, WORK( IWORK ), M, B( 1, I ),$ LDB )40 CONTINUEELSECALL DGEMV( 'T', M, M, ONE, WORK( IL ), LDWORK, B( 1, 1 ),$ 1, ZERO, WORK( IWORK ), 1 )CALL DCOPY( M, WORK( IWORK ), 1, B( 1, 1 ), 1 )END IF** Zero out below first M rows of B*CALL DLASET( 'F', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )IWORK = ITAU + M** Multiply transpose(Q) by B* (Workspace: need M+NRHS, prefer M+NRHS*NB)*CALL DORMLQ( 'L', 'T', N, NRHS, M, A, LDA, WORK( ITAU ), B,$ LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )*ELSE** Path 2 - remaining underdetermined cases*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize A* (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ INFO )** Multiply B by transpose of left bidiagonalizing vectors* (Workspace: need 3*M+NRHS, prefer 3*M+NRHS*NB)*CALL DORMBR( 'Q', 'L', 'T', M, NRHS, N, A, LDA, WORK( ITAUQ ),$ B, LDB, WORK( IWORK ), LWORK-IWORK+1, INFO )** Generate right bidiagonalizing vectors in A* (Workspace: need 4*M, prefer 3*M+M*NB)*CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, INFO )IWORK = IE + M** Perform bidiagonal QR iteration,* computing right singular vectors of A in A and* multiplying B by transpose of left singular vectors* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, N, 0, NRHS, S, WORK( IE ), A, LDA, DUM,$ 1, B, LDB, WORK( IWORK ), INFO )IF( INFO.NE.0 )$ GO TO 70** Multiply B by reciprocals of singular values*THR = MAX( RCOND*S( 1 ), SFMIN )IF( RCOND.LT.ZERO )$ THR = MAX( EPS*S( 1 ), SFMIN )RANK = 0DO 50 I = 1, MIF( S( I ).GT.THR ) THENCALL DRSCL( NRHS, S( I ), B( I, 1 ), LDB )RANK = RANK + 1ELSECALL DLASET( 'F', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )END IF50 CONTINUE** Multiply B by right singular vectors of A* (Workspace: need N, prefer N*NRHS)*IF( LWORK.GE.LDB*NRHS .AND. NRHS.GT.1 ) THENCALL DGEMM( 'T', 'N', N, NRHS, M, ONE, A, LDA, B, LDB, ZERO,$ WORK, LDB )CALL DLACPY( 'F', N, NRHS, WORK, LDB, B, LDB )ELSE IF( NRHS.GT.1 ) THENCHUNK = LWORK / NDO 60 I = 1, NRHS, CHUNKBL = MIN( NRHS-I+1, CHUNK )CALL DGEMM( 'T', 'N', N, BL, M, ONE, A, LDA, B( 1, I ),$ LDB, ZERO, WORK, N )CALL DLACPY( 'F', N, BL, WORK, N, B( 1, I ), LDB )60 CONTINUEELSECALL DGEMV( 'T', M, N, ONE, A, LDA, B, 1, ZERO, WORK, 1 )CALL DCOPY( N, WORK, 1, B, 1 )END IFEND IF** Undo scaling*IF( IASCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,$ INFO )ELSE IF( IASCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,$ INFO )END IFIF( IBSCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )ELSE IF( IBSCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )END IF*70 CONTINUEWORK( 1 ) = MAXWRKRETURN** End of DGELSS*END*> \brief <b> DGELSX solves overdetermined or underdetermined systems for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELSX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelsx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgelsx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelsx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,* WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, M, N, NRHS, RANK* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER JPVT( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DGELSY.*>*> DGELSX computes the minimum-norm solution to a real linear least*> squares problem:*> minimize || A * X - B ||*> using a complete orthogonal factorization of A. A is an M-by-N*> matrix which may be rank-deficient.*>*> Several right hand side vectors b and solution vectors x can be*> handled in a single call; they are stored as the columns of the*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution*> matrix X.*>*> The routine first computes a QR factorization with column pivoting:*> A * P = Q * [ R11 R12 ]*> [ 0 R22 ]*> with R11 defined as the largest leading submatrix whose estimated*> condition number is less than 1/RCOND. The order of R11, RANK,*> is the effective rank of A.*>*> Then, R22 is considered to be negligible, and R12 is annihilated*> by orthogonal transformations from the right, arriving at the*> complete orthogonal factorization:*> A * P = Q * [ T11 0 ] * Z*> [ 0 0 ]*> The minimum-norm solution is then*> X = P * Z**T [ inv(T11)*Q1**T*B ]*> [ 0 ]*> where Q1 consists of the first RANK columns of Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of*> columns of matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, A has been overwritten by details of its*> complete orthogonal factorization.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the M-by-NRHS right hand side matrix B.*> On exit, the N-by-NRHS solution matrix X.*> If m >= n and RANK = n, the residual sum-of-squares for*> the solution in the i-th column is given by the sum of*> squares of elements N+1:M in that column.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,M,N).*> \endverbatim*>*> \param[in,out] JPVT*> \verbatim*> JPVT is INTEGER array, dimension (N)*> On entry, if JPVT(i) .ne. 0, the i-th column of A is an*> initial column, otherwise it is a free column. Before*> the QR factorization of A, all initial columns are*> permuted to the leading positions; only the remaining*> free columns are moved as a result of column pivoting*> during the factorization.*> On exit, if JPVT(i) = k, then the i-th column of A*P*> was the k-th column of A.*> \endverbatim*>*> \param[in] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> RCOND is used to determine the effective rank of A, which*> is defined as the order of the largest leading triangular*> submatrix R11 in the QR factorization with pivoting of A,*> whose estimated condition number < 1/RCOND.*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The effective rank of A, i.e., the order of the submatrix*> R11. This is the same as the order of the submatrix T11*> in the complete orthogonal factorization of A.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (max( min(M,N)+3*N, 2*min(M,N)+NRHS )),*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEsolve** =====================================================================SUBROUTINE DGELSX( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,$ WORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, M, N, NRHS, RANKDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER IMAX, IMINPARAMETER ( IMAX = 1, IMIN = 2 )DOUBLE PRECISION ZERO, ONE, DONE, NTDONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, DONE = ZERO,$ NTDONE = ONE )* ..* .. Local Scalars ..INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, K, MNDOUBLE PRECISION ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,$ SMAXPR, SMIN, SMINPR, SMLNUM, T1, T2* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLANGEEXTERNAL DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DGEQPF, DLAIC1, DLASCL, DLASET, DLATZM, DORM2R,$ DTRSM, DTZRQF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*MN = MIN( M, N )ISMIN = MN + 1ISMAX = 2*MN + 1** Test the input arguments.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, M, N ) ) THENINFO = -7END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGELSX', -INFO )RETURNEND IF** Quick return if possible*IF( MIN( M, N, NRHS ).EQ.0 ) THENRANK = 0RETURNEND IF** Get machine parameters*SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Scale A, B if max elements outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, WORK )IASCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )IASCL = 1ELSE IF( ANRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )IASCL = 2ELSE IF( ANRM.EQ.ZERO ) THEN** Matrix all zero. Return zero solution.*CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )RANK = 0GO TO 100END IF*BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )IBSCL = 0IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )IBSCL = 1ELSE IF( BNRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )IBSCL = 2END IF** Compute QR factorization with column pivoting of A:* A * P = Q * R*CALL DGEQPF( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ), INFO )** workspace 3*N. Details of Householder rotations stored* in WORK(1:MN).** Determine RANK using incremental condition estimation*WORK( ISMIN ) = ONEWORK( ISMAX ) = ONESMAX = ABS( A( 1, 1 ) )SMIN = SMAXIF( ABS( A( 1, 1 ) ).EQ.ZERO ) THENRANK = 0CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )GO TO 100ELSERANK = 1END IF*10 CONTINUEIF( RANK.LT.MN ) THENI = RANK + 1CALL DLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),$ A( I, I ), SMINPR, S1, C1 )CALL DLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),$ A( I, I ), SMAXPR, S2, C2 )*IF( SMAXPR*RCOND.LE.SMINPR ) THENDO 20 I = 1, RANKWORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )20 CONTINUEWORK( ISMIN+RANK ) = C1WORK( ISMAX+RANK ) = C2SMIN = SMINPRSMAX = SMAXPRRANK = RANK + 1GO TO 10END IFEND IF** Logically partition R = [ R11 R12 ]* [ 0 R22 ]* where R11 = R(1:RANK,1:RANK)** [R11,R12] = [ T11, 0 ] * Y*IF( RANK.LT.N )$ CALL DTZRQF( RANK, N, A, LDA, WORK( MN+1 ), INFO )** Details of Householder rotations stored in WORK(MN+1:2*MN)** B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)*CALL DORM2R( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),$ B, LDB, WORK( 2*MN+1 ), INFO )** workspace NRHS** B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)*CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,$ NRHS, ONE, A, LDA, B, LDB )*DO 40 I = RANK + 1, NDO 30 J = 1, NRHSB( I, J ) = ZERO30 CONTINUE40 CONTINUE** B(1:N,1:NRHS) := Y**T * B(1:N,1:NRHS)*IF( RANK.LT.N ) THENDO 50 I = 1, RANKCALL DLATZM( 'Left', N-RANK+1, NRHS, A( I, RANK+1 ), LDA,$ WORK( MN+I ), B( I, 1 ), B( RANK+1, 1 ), LDB,$ WORK( 2*MN+1 ) )50 CONTINUEEND IF** workspace NRHS** B(1:N,1:NRHS) := P * B(1:N,1:NRHS)*DO 90 J = 1, NRHSDO 60 I = 1, NWORK( 2*MN+I ) = NTDONE60 CONTINUEDO 80 I = 1, NIF( WORK( 2*MN+I ).EQ.NTDONE ) THENIF( JPVT( I ).NE.I ) THENK = IT1 = B( K, J )T2 = B( JPVT( K ), J )70 CONTINUEB( JPVT( K ), J ) = T1WORK( 2*MN+K ) = DONET1 = T2K = JPVT( K )T2 = B( JPVT( K ), J )IF( JPVT( K ).NE.I )$ GO TO 70B( I, J ) = T1WORK( 2*MN+K ) = DONEEND IFEND IF80 CONTINUE90 CONTINUE** Undo scaling*IF( IASCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,$ INFO )ELSE IF( IASCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,$ INFO )END IFIF( IBSCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )ELSE IF( IBSCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )END IF*100 CONTINUE*RETURN** End of DGELSX*END*> \brief <b> DGELSY solves overdetermined or underdetermined systems for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGELSY + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelsy.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgelsy.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelsy.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,* WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER JPVT( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGELSY computes the minimum-norm solution to a real linear least*> squares problem:*> minimize || A * X - B ||*> using a complete orthogonal factorization of A. A is an M-by-N*> matrix which may be rank-deficient.*>*> Several right hand side vectors b and solution vectors x can be*> handled in a single call; they are stored as the columns of the*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution*> matrix X.*>*> The routine first computes a QR factorization with column pivoting:*> A * P = Q * [ R11 R12 ]*> [ 0 R22 ]*> with R11 defined as the largest leading submatrix whose estimated*> condition number is less than 1/RCOND. The order of R11, RANK,*> is the effective rank of A.*>*> Then, R22 is considered to be negligible, and R12 is annihilated*> by orthogonal transformations from the right, arriving at the*> complete orthogonal factorization:*> A * P = Q * [ T11 0 ] * Z*> [ 0 0 ]*> The minimum-norm solution is then*> X = P * Z**T [ inv(T11)*Q1**T*B ]*> [ 0 ]*> where Q1 consists of the first RANK columns of Q.*>*> This routine is basically identical to the original xGELSX except*> three differences:*> o The call to the subroutine xGEQPF has been substituted by the*> the call to the subroutine xGEQP3. This subroutine is a Blas-3*> version of the QR factorization with column pivoting.*> o Matrix B (the right hand side) is updated with Blas-3.*> o The permutation of matrix B (the right hand side) is faster and*> more simple.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of*> columns of matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, A has been overwritten by details of its*> complete orthogonal factorization.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the M-by-NRHS right hand side matrix B.*> On exit, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,M,N).*> \endverbatim*>*> \param[in,out] JPVT*> \verbatim*> JPVT is INTEGER array, dimension (N)*> On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted*> to the front of AP, otherwise column i is a free column.*> On exit, if JPVT(i) = k, then the i-th column of AP*> was the k-th column of A.*> \endverbatim*>*> \param[in] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> RCOND is used to determine the effective rank of A, which*> is defined as the order of the largest leading triangular*> submatrix R11 in the QR factorization with pivoting of A,*> whose estimated condition number < 1/RCOND.*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The effective rank of A, i.e., the order of the submatrix*> R11. This is the same as the order of the submatrix T11*> in the complete orthogonal factorization of A.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> The unblocked strategy requires that:*> LWORK >= MAX( MN+3*N+1, 2*MN+NRHS ),*> where MN = min( M, N ).*> The block algorithm requires that:*> LWORK >= MAX( MN+2*N+NB*(N+1), 2*MN+NB*NRHS ),*> where NB is an upper bound on the blocksize returned*> by ILAENV for the routines DGEQP3, DTZRZF, STZRQF, DORMQR,*> and DORMRZ.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: If INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEsolve**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA \n*> E. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain \n*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain \n*>* =====================================================================SUBROUTINE DGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,$ WORK, LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANKDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER IMAX, IMINPARAMETER ( IMAX = 1, IMIN = 2 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,$ LWKOPT, MN, NB, NB1, NB2, NB3, NB4DOUBLE PRECISION ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,$ SMAXPR, SMIN, SMINPR, SMLNUM, WSIZE* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL ILAENV, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEQP3, DLABAD, DLAIC1, DLASCL, DLASET,$ DORMQR, DORMRZ, DTRSM, DTZRZF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*MN = MIN( M, N )ISMIN = MN + 1ISMAX = 2*MN + 1** Test the input arguments.*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, M, N ) ) THENINFO = -7END IF** Figure out optimal block size*IF( INFO.EQ.0 ) THENIF( MN.EQ.0 .OR. NRHS.EQ.0 ) THENLWKMIN = 1LWKOPT = 1ELSENB1 = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )NB2 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )NB3 = ILAENV( 1, 'DORMQR', ' ', M, N, NRHS, -1 )NB4 = ILAENV( 1, 'DORMRQ', ' ', M, N, NRHS, -1 )NB = MAX( NB1, NB2, NB3, NB4 )LWKMIN = MN + MAX( 2*MN, N + 1, MN + NRHS )LWKOPT = MAX( LWKMIN,$ MN + 2*N + NB*( N + 1 ), 2*MN + NB*NRHS )END IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -12END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGELSY', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( MN.EQ.0 .OR. NRHS.EQ.0 ) THENRANK = 0RETURNEND IF** Get machine parameters*SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Scale A, B if max entries outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, WORK )IASCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )IASCL = 1ELSE IF( ANRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )IASCL = 2ELSE IF( ANRM.EQ.ZERO ) THEN** Matrix all zero. Return zero solution.*CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )RANK = 0GO TO 70END IF*BNRM = DLANGE( 'M', M, NRHS, B, LDB, WORK )IBSCL = 0IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN** Scale matrix norm up to SMLNUM*CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )IBSCL = 1ELSE IF( BNRM.GT.BIGNUM ) THEN** Scale matrix norm down to BIGNUM*CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )IBSCL = 2END IF** Compute QR factorization with column pivoting of A:* A * P = Q * R*CALL DGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),$ LWORK-MN, INFO )WSIZE = MN + WORK( MN+1 )** workspace: MN+2*N+NB*(N+1).* Details of Householder rotations stored in WORK(1:MN).** Determine RANK using incremental condition estimation*WORK( ISMIN ) = ONEWORK( ISMAX ) = ONESMAX = ABS( A( 1, 1 ) )SMIN = SMAXIF( ABS( A( 1, 1 ) ).EQ.ZERO ) THENRANK = 0CALL DLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )GO TO 70ELSERANK = 1END IF*10 CONTINUEIF( RANK.LT.MN ) THENI = RANK + 1CALL DLAIC1( IMIN, RANK, WORK( ISMIN ), SMIN, A( 1, I ),$ A( I, I ), SMINPR, S1, C1 )CALL DLAIC1( IMAX, RANK, WORK( ISMAX ), SMAX, A( 1, I ),$ A( I, I ), SMAXPR, S2, C2 )*IF( SMAXPR*RCOND.LE.SMINPR ) THENDO 20 I = 1, RANKWORK( ISMIN+I-1 ) = S1*WORK( ISMIN+I-1 )WORK( ISMAX+I-1 ) = S2*WORK( ISMAX+I-1 )20 CONTINUEWORK( ISMIN+RANK ) = C1WORK( ISMAX+RANK ) = C2SMIN = SMINPRSMAX = SMAXPRRANK = RANK + 1GO TO 10END IFEND IF** workspace: 3*MN.** Logically partition R = [ R11 R12 ]* [ 0 R22 ]* where R11 = R(1:RANK,1:RANK)** [R11,R12] = [ T11, 0 ] * Y*IF( RANK.LT.N )$ CALL DTZRZF( RANK, N, A, LDA, WORK( MN+1 ), WORK( 2*MN+1 ),$ LWORK-2*MN, INFO )** workspace: 2*MN.* Details of Householder rotations stored in WORK(MN+1:2*MN)** B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)*CALL DORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),$ B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )WSIZE = MAX( WSIZE, 2*MN+WORK( 2*MN+1 ) )** workspace: 2*MN+NB*NRHS.** B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS)*CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,$ NRHS, ONE, A, LDA, B, LDB )*DO 40 J = 1, NRHSDO 30 I = RANK + 1, NB( I, J ) = ZERO30 CONTINUE40 CONTINUE** B(1:N,1:NRHS) := Y**T * B(1:N,1:NRHS)*IF( RANK.LT.N ) THENCALL DORMRZ( 'Left', 'Transpose', N, NRHS, RANK, N-RANK, A,$ LDA, WORK( MN+1 ), B, LDB, WORK( 2*MN+1 ),$ LWORK-2*MN, INFO )END IF** workspace: 2*MN+NRHS.** B(1:N,1:NRHS) := P * B(1:N,1:NRHS)*DO 60 J = 1, NRHSDO 50 I = 1, NWORK( JPVT( I ) ) = B( I, J )50 CONTINUECALL DCOPY( N, WORK( 1 ), 1, B( 1, J ), 1 )60 CONTINUE** workspace: N.** Undo scaling*IF( IASCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,$ INFO )ELSE IF( IASCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )CALL DLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,$ INFO )END IFIF( IBSCL.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )ELSE IF( IBSCL.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )END IF*70 CONTINUEWORK( 1 ) = LWKOPT*RETURN** End of DGELSY*END*> \brief \b DGEMQRT** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEMQRT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgemqrt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgemqrt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgemqrt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEMQRT( SIDE, TRANS, M, N, K, NB, V, LDV, T, LDT,* C, LDC, WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDV, LDC, M, N, NB, LDT* ..* .. Array Arguments ..* DOUBLE PRECISION V( LDV, * ), C( LDC, * ), T( LDT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEMQRT overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q C C Q*> TRANS = 'T': Q**T C C Q**T*>*> where Q is a real orthogonal matrix defined as the product of K*> elementary reflectors:*>*> Q = H(1) H(2) . . . H(K) = I - V T V**T*>*> generated using the compact WY representation as returned by DGEQRT.*>*> Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'C': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The block size used for the storage of T. K >= NB >= 1.*> This must be the same value of NB used to generate T*> in CGEQRT.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,K)*> The i-th column must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> CGEQRT in the first K columns of its array argument A.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If SIDE = 'L', LDA >= max(1,M);*> if SIDE = 'R', LDA >= max(1,N).*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The upper triangular factors of the block reflectors*> as returned by CGEQRT, stored as a NB-by-N matrix.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= NB.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q C, Q**T C, C Q**T or C Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array. The dimension of*> WORK is N*NB if SIDE = 'L', or M*NB if SIDE = 'R'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGEMQRT( SIDE, TRANS, M, N, K, NB, V, LDV, T, LDT,$ C, LDC, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDV, LDC, M, N, NB, LDT* ..* .. Array Arguments ..DOUBLE PRECISION V( LDV, * ), C( LDC, * ), T( LDT, * ), WORK( * )* ..** =====================================================================** ..* .. Local Scalars ..LOGICAL LEFT, RIGHT, TRAN, NOTRANINTEGER I, IB, LDWORK, KF, Q* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DLARFB* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** .. Test the input arguments ..*INFO = 0LEFT = LSAME( SIDE, 'L' )RIGHT = LSAME( SIDE, 'R' )TRAN = LSAME( TRANS, 'T' )NOTRAN = LSAME( TRANS, 'N' )*IF( LEFT ) THENLDWORK = MAX( 1, N )Q = MELSE IF ( RIGHT ) THENLDWORK = MAX( 1, M )Q = NEND IFIF( .NOT.LEFT .AND. .NOT.RIGHT ) THENINFO = -1ELSE IF( .NOT.TRAN .AND. .NOT.NOTRAN ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.Q ) THENINFO = -5ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0)) THENINFO = -6ELSE IF( LDV.LT.MAX( 1, Q ) ) THENINFO = -8ELSE IF( LDT.LT.NB ) THENINFO = -10ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -12END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEMQRT', -INFO )RETURNEND IF** .. Quick return if possible ..*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) RETURN*IF( LEFT .AND. TRAN ) THEN*DO I = 1, K, NBIB = MIN( NB, K-I+1 )CALL DLARFB( 'L', 'T', 'F', 'C', M-I+1, N, IB,$ V( I, I ), LDV, T( 1, I ), LDT,$ C( I, 1 ), LDC, WORK, LDWORK )END DO*ELSE IF( RIGHT .AND. NOTRAN ) THEN*DO I = 1, K, NBIB = MIN( NB, K-I+1 )CALL DLARFB( 'R', 'N', 'F', 'C', M, N-I+1, IB,$ V( I, I ), LDV, T( 1, I ), LDT,$ C( 1, I ), LDC, WORK, LDWORK )END DO*ELSE IF( LEFT .AND. NOTRAN ) THEN*KF = ((K-1)/NB)*NB+1DO I = KF, 1, -NBIB = MIN( NB, K-I+1 )CALL DLARFB( 'L', 'N', 'F', 'C', M-I+1, N, IB,$ V( I, I ), LDV, T( 1, I ), LDT,$ C( I, 1 ), LDC, WORK, LDWORK )END DO*ELSE IF( RIGHT .AND. TRAN ) THEN*KF = ((K-1)/NB)*NB+1DO I = KF, 1, -NBIB = MIN( NB, K-I+1 )CALL DLARFB( 'R', 'T', 'F', 'C', M, N-I+1, IB,$ V( I, I ), LDV, T( 1, I ), LDT,$ C( 1, I ), LDC, WORK, LDWORK )END DO*END IF*RETURN** End of DGEMQRT*END*> \brief \b DGEQL2 computes the QL factorization of a general rectangular matrix using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQL2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeql2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeql2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeql2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQL2( M, N, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQL2 computes a QL factorization of a real m by n matrix A:*> A = Q * L.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n matrix A.*> On exit, if m >= n, the lower triangle of the subarray*> A(m-n+1:m,1:n) contains the n by n lower triangular matrix L;*> if m <= n, the elements on and below the (n-m)-th*> superdiagonal contain the m by n lower trapezoidal matrix L;*> the remaining elements, with the array TAU, represent the*> orthogonal matrix Q as a product of elementary reflectors*> (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(k) . . . H(2) H(1), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in*> A(1:m-k+i-1,n-k+i), and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEQL2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQL2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = K, 1, -1** Generate elementary reflector H(i) to annihilate* A(1:m-k+i-1,n-k+i)*CALL DLARFG( M-K+I, A( M-K+I, N-K+I ), A( 1, N-K+I ), 1,$ TAU( I ) )** Apply H(i) to A(1:m-k+i,1:n-k+i-1) from the left*AII = A( M-K+I, N-K+I )A( M-K+I, N-K+I ) = ONECALL DLARF( 'Left', M-K+I, N-K+I-1, A( 1, N-K+I ), 1, TAU( I ),$ A, LDA, WORK )A( M-K+I, N-K+I ) = AII10 CONTINUERETURN** End of DGEQL2*END*> \brief \b DGEQLF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQLF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqlf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqlf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqlf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQLF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQLF computes a QL factorization of a real M-by-N matrix A:*> A = Q * L.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit,*> if m >= n, the lower triangle of the subarray*> A(m-n+1:m,1:n) contains the N-by-N lower triangular matrix L;*> if m <= n, the elements on and below the (n-m)-th*> superdiagonal contain the M-by-N lower trapezoidal matrix L;*> the remaining elements, with the array TAU, represent the*> orthogonal matrix Q as a product of elementary reflectors*> (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> For optimum performance LWORK >= N*NB, where NB is the*> optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(k) . . . H(2) H(1), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(m-k+i+1:m) = 0 and v(m-k+i) = 1; v(1:m-k+i-1) is stored on exit in*> A(1:m-k+i-1,n-k+i), and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEQLF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, KI, KK, LDWORK, LWKOPT,$ MU, NB, NBMIN, NU, NX* ..* .. External Subroutines ..EXTERNAL DGEQL2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IF*IF( INFO.EQ.0 ) THENK = MIN( M, N )IF( K.EQ.0 ) THENLWKOPT = 1ELSENB = ILAENV( 1, 'DGEQLF', ' ', M, N, -1, -1 )LWKOPT = N*NBEND IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -7END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQLF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( K.EQ.0 ) THENRETURNEND IF*NBMIN = 2NX = 1IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGEQLF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGEQLF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially.* The last kk columns are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )*DO 10 I = K - KK + KI + 1, K - KK + 1, -NBIB = MIN( K-I+1, NB )** Compute the QL factorization of the current block* A(1:m-k+i+ib-1,n-k+i:n-k+i+ib-1)*CALL DGEQL2( M-K+I+IB-1, IB, A( 1, N-K+I ), LDA, TAU( I ),$ WORK, IINFO )IF( N-K+I.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,$ A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )** Apply H**T to A(1:m-k+i+ib-1,1:n-k+i-1) from the left*CALL DLARFB( 'Left', 'Transpose', 'Backward',$ 'Columnwise', M-K+I+IB-1, N-K+I-1, IB,$ A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,$ WORK( IB+1 ), LDWORK )END IF10 CONTINUEMU = M - K + I + NB - 1NU = N - K + I + NB - 1ELSEMU = MNU = NEND IF** Use unblocked code to factor the last or only block*IF( MU.GT.0 .AND. NU.GT.0 )$ CALL DGEQL2( MU, NU, A, LDA, TAU, WORK, IINFO )*WORK( 1 ) = IWSRETURN** End of DGEQLF*END*> \brief \b DGEQP3** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQP3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqp3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqp3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqp3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* INTEGER JPVT( * )* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQP3 computes a QR factorization with column pivoting of a*> matrix A: A*P = Q*R using Level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the upper triangle of the array contains the*> min(M,N)-by-N upper trapezoidal matrix R; the elements below*> the diagonal, together with the array TAU, represent the*> orthogonal matrix Q as a product of min(M,N) elementary*> reflectors.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] JPVT*> \verbatim*> JPVT is INTEGER array, dimension (N)*> On entry, if JPVT(J).ne.0, the J-th column of A is permuted*> to the front of A*P (a leading column); if JPVT(J)=0,*> the J-th column of A is a free column.*> On exit, if JPVT(J)=K, then the J-th column of A*P was the*> the K-th column of A.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO=0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= 3*N+1.*> For optimal performance LWORK >= 2*N+( N+1 )*NB, where NB*> is the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real/complex vector*> with v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in*> A(i+1:m,i), and tau in TAU(i).*> \endverbatim**> \par Contributors:* ==================*>*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain*> X. Sun, Computer Science Dept., Duke University, USA*>* =====================================================================SUBROUTINE DGEQP3( M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER INB, INBMIN, IXOVERPARAMETER ( INB = 1, INBMIN = 2, IXOVER = 3 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER FJB, IWS, J, JB, LWKOPT, MINMN, MINWS, NA, NB,$ NBMIN, NFXD, NX, SM, SMINMN, SN, TOPBMN* ..* .. External Subroutines ..EXTERNAL DGEQRF, DLAQP2, DLAQPS, DORMQR, DSWAP, XERBLA* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DNRM2EXTERNAL ILAENV, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test input arguments* ====================*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IF*IF( INFO.EQ.0 ) THENMINMN = MIN( M, N )IF( MINMN.EQ.0 ) THENIWS = 1LWKOPT = 1ELSEIWS = 3*N + 1NB = ILAENV( INB, 'DGEQRF', ' ', M, N, -1, -1 )LWKOPT = 2*N + ( N + 1 )*NBEND IFWORK( 1 ) = LWKOPT*IF( ( LWORK.LT.IWS ) .AND. .NOT.LQUERY ) THENINFO = -8END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQP3', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Move initial columns up front.*NFXD = 1DO 10 J = 1, NIF( JPVT( J ).NE.0 ) THENIF( J.NE.NFXD ) THENCALL DSWAP( M, A( 1, J ), 1, A( 1, NFXD ), 1 )JPVT( J ) = JPVT( NFXD )JPVT( NFXD ) = JELSEJPVT( J ) = JEND IFNFXD = NFXD + 1ELSEJPVT( J ) = JEND IF10 CONTINUENFXD = NFXD - 1** Factorize fixed columns* =======================** Compute the QR factorization of fixed columns and update* remaining columns.*IF( NFXD.GT.0 ) THENNA = MIN( M, NFXD )*CC CALL DGEQR2( M, NA, A, LDA, TAU, WORK, INFO )CALL DGEQRF( M, NA, A, LDA, TAU, WORK, LWORK, INFO )IWS = MAX( IWS, INT( WORK( 1 ) ) )IF( NA.LT.N ) THEN*CC CALL DORM2R( 'Left', 'Transpose', M, N-NA, NA, A, LDA,*CC $ TAU, A( 1, NA+1 ), LDA, WORK, INFO )CALL DORMQR( 'Left', 'Transpose', M, N-NA, NA, A, LDA, TAU,$ A( 1, NA+1 ), LDA, WORK, LWORK, INFO )IWS = MAX( IWS, INT( WORK( 1 ) ) )END IFEND IF** Factorize free columns* ======================*IF( NFXD.LT.MINMN ) THEN*SM = M - NFXDSN = N - NFXDSMINMN = MINMN - NFXD** Determine the block size.*NB = ILAENV( INB, 'DGEQRF', ' ', SM, SN, -1, -1 )NBMIN = 2NX = 0*IF( ( NB.GT.1 ) .AND. ( NB.LT.SMINMN ) ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( IXOVER, 'DGEQRF', ' ', SM, SN, -1,$ -1 ) )**IF( NX.LT.SMINMN ) THEN** Determine if workspace is large enough for blocked code.*MINWS = 2*SN + ( SN+1 )*NBIWS = MAX( IWS, MINWS )IF( LWORK.LT.MINWS ) THEN** Not enough workspace to use optimal NB: Reduce NB and* determine the minimum value of NB.*NB = ( LWORK-2*SN ) / ( SN+1 )NBMIN = MAX( 2, ILAENV( INBMIN, 'DGEQRF', ' ', SM, SN,$ -1, -1 ) )**END IFEND IFEND IF** Initialize partial column norms. The first N elements of work* store the exact column norms.*DO 20 J = NFXD + 1, NWORK( J ) = DNRM2( SM, A( NFXD+1, J ), 1 )WORK( N+J ) = WORK( J )20 CONTINUE*IF( ( NB.GE.NBMIN ) .AND. ( NB.LT.SMINMN ) .AND.$ ( NX.LT.SMINMN ) ) THEN** Use blocked code initially.*J = NFXD + 1** Compute factorization: while loop.**TOPBMN = MINMN - NX30 CONTINUEIF( J.LE.TOPBMN ) THENJB = MIN( NB, TOPBMN-J+1 )** Factorize JB columns among columns J:N.*CALL DLAQPS( M, N-J+1, J-1, JB, FJB, A( 1, J ), LDA,$ JPVT( J ), TAU( J ), WORK( J ), WORK( N+J ),$ WORK( 2*N+1 ), WORK( 2*N+JB+1 ), N-J+1 )*J = J + FJBGO TO 30END IFELSEJ = NFXD + 1END IF** Use unblocked code to factor the last or only block.**IF( J.LE.MINMN )$ CALL DLAQP2( M, N-J+1, J-1, A( 1, J ), LDA, JPVT( J ),$ TAU( J ), WORK( J ), WORK( N+J ),$ WORK( 2*N+1 ) )*END IF*WORK( 1 ) = IWSRETURN** End of DGEQP3*END*> \brief \b DGEQPF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQPF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqpf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqpf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqpf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQPF( M, N, A, LDA, JPVT, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* INTEGER JPVT( * )* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DGEQP3.*>*> DGEQPF computes a QR factorization with column pivoting of a*> real M-by-N matrix A: A*P = Q*R.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the upper triangle of the array contains the*> min(M,N)-by-N upper triangular matrix R; the elements*> below the diagonal, together with the array TAU,*> represent the orthogonal matrix Q as a product of*> min(m,n) elementary reflectors.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] JPVT*> \verbatim*> JPVT is INTEGER array, dimension (N)*> On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted*> to the front of A*P (a leading column); if JPVT(i) = 0,*> the i-th column of A is a free column.*> On exit, if JPVT(i) = k, then the i-th column of A*P*> was the k-th column of A.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(n)*>*> Each H(i) has the form*>*> H = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i).*>*> The matrix P is represented in jpvt as follows: If*> jpvt(j) = i*> then the jth column of P is the ith canonical unit vector.*>*> Partial column norm updating strategy modified by*> Z. Drmac and Z. Bujanovic, Dept. of Mathematics,*> University of Zagreb, Croatia.*> -- April 2011 --*> For more details see LAPACK Working Note 176.*> \endverbatim*>* =====================================================================SUBROUTINE DGEQPF( M, N, A, LDA, JPVT, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, ITEMP, J, MA, MN, PVTDOUBLE PRECISION AII, TEMP, TEMP2, TOL3Z* ..* .. External Subroutines ..EXTERNAL DGEQR2, DLARF, DLARFG, DORM2R, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DNRM2EXTERNAL IDAMAX, DLAMCH, DNRM2* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQPF', -INFO )RETURNEND IF*MN = MIN( M, N )TOL3Z = SQRT(DLAMCH('Epsilon'))** Move initial columns up front*ITEMP = 1DO 10 I = 1, NIF( JPVT( I ).NE.0 ) THENIF( I.NE.ITEMP ) THENCALL DSWAP( M, A( 1, I ), 1, A( 1, ITEMP ), 1 )JPVT( I ) = JPVT( ITEMP )JPVT( ITEMP ) = IELSEJPVT( I ) = IEND IFITEMP = ITEMP + 1ELSEJPVT( I ) = IEND IF10 CONTINUEITEMP = ITEMP - 1** Compute the QR factorization and update remaining columns*IF( ITEMP.GT.0 ) THENMA = MIN( ITEMP, M )CALL DGEQR2( M, MA, A, LDA, TAU, WORK, INFO )IF( MA.LT.N ) THENCALL DORM2R( 'Left', 'Transpose', M, N-MA, MA, A, LDA, TAU,$ A( 1, MA+1 ), LDA, WORK, INFO )END IFEND IF*IF( ITEMP.LT.MN ) THEN** Initialize partial column norms. The first n elements of* work store the exact column norms.*DO 20 I = ITEMP + 1, NWORK( I ) = DNRM2( M-ITEMP, A( ITEMP+1, I ), 1 )WORK( N+I ) = WORK( I )20 CONTINUE** Compute factorization*DO 40 I = ITEMP + 1, MN** Determine ith pivot column and swap if necessary*PVT = ( I-1 ) + IDAMAX( N-I+1, WORK( I ), 1 )*IF( PVT.NE.I ) THENCALL DSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )ITEMP = JPVT( PVT )JPVT( PVT ) = JPVT( I )JPVT( I ) = ITEMPWORK( PVT ) = WORK( I )WORK( N+PVT ) = WORK( N+I )END IF** Generate elementary reflector H(i)*IF( I.LT.M ) THENCALL DLARFG( M-I+1, A( I, I ), A( I+1, I ), 1, TAU( I ) )ELSECALL DLARFG( 1, A( M, M ), A( M, M ), 1, TAU( M ) )END IF*IF( I.LT.N ) THEN** Apply H(i) to A(i:m,i+1:n) from the left*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'LEFT', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK( 2*N+1 ) )A( I, I ) = AIIEND IF** Update partial column norms*DO 30 J = I + 1, NIF( WORK( J ).NE.ZERO ) THEN** NOTE: The following 4 lines follow from the analysis in* Lapack Working Note 176.*TEMP = ABS( A( I, J ) ) / WORK( J )TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )TEMP2 = TEMP*( WORK( J ) / WORK( N+J ) )**2IF( TEMP2 .LE. TOL3Z ) THENIF( M-I.GT.0 ) THENWORK( J ) = DNRM2( M-I, A( I+1, J ), 1 )WORK( N+J ) = WORK( J )ELSEWORK( J ) = ZEROWORK( N+J ) = ZEROEND IFELSEWORK( J ) = WORK( J )*SQRT( TEMP )END IFEND IF30 CONTINUE*40 CONTINUEEND IFRETURN** End of DGEQPF*END*> \brief \b DGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQR2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqr2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqr2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqr2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQR2( M, N, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQR2 computes a QR factorization of a real m by n matrix A:*> A = Q * R.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(m,n) by n upper trapezoidal matrix R (R is*> upper triangular if m >= n); the elements below the diagonal,*> with the array TAU, represent the orthogonal matrix Q as a*> product of elementary reflectors (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),*> and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEQR2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQR2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = 1, K** Generate elementary reflector H(i) to annihilate A(i+1:m,i)*CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ TAU( I ) )IF( I.LT.N ) THEN** Apply H(i) to A(i:m,i+1:n) from the left*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK )A( I, I ) = AIIEND IF10 CONTINUERETURN** End of DGEQR2*END*> \brief \b DGEQR2P computes the QR factorization of a general rectangular matrix with non-negative diagonal elements using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQR2P + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqr2p.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqr2p.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqr2p.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQR2P( M, N, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQR2P computes a QR factorization of a real m by n matrix A:*> A = Q * R. The diagonal entries of R are nonnegative.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(m,n) by n upper trapezoidal matrix R (R is*> upper triangular if m >= n). The diagonal entries of R are*> nonnegative; the elements below the diagonal,*> with the array TAU, represent the orthogonal matrix Q as a*> product of elementary reflectors (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),*> and tau in TAU(i).*>*> See Lapack Working Note 203 for details*> \endverbatim*>* =====================================================================SUBROUTINE DGEQR2P( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFGP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQR2P', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = 1, K** Generate elementary reflector H(i) to annihilate A(i+1:m,i)*CALL DLARFGP( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ TAU( I ) )IF( I.LT.N ) THEN** Apply H(i) to A(i:m,i+1:n) from the left*AII = A( I, I )A( I, I ) = ONECALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK )A( I, I ) = AIIEND IF10 CONTINUERETURN** End of DGEQR2P*END*> \brief \b DGEQRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQRF computes a QR factorization of a real M-by-N matrix A:*> A = Q * R.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(M,N)-by-N upper trapezoidal matrix R (R is*> upper triangular if m >= n); the elements below the diagonal,*> with the array TAU, represent the orthogonal matrix Q as a*> product of min(m,n) elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> For optimum performance LWORK >= N*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),*> and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGEQRF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DGEQR2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQRF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGEQRF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGEQRF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially*DO 10 I = 1, K - NX, NBIB = MIN( K-I+1, NB )** Compute the QR factorization of the current block* A(i:m,i:i+ib-1)*CALL DGEQR2( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )IF( I+IB.LE.N ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB,$ A( I, I ), LDA, TAU( I ), WORK, LDWORK )** Apply H**T to A(i:m,i+ib:n) from the left*CALL DLARFB( 'Left', 'Transpose', 'Forward',$ 'Columnwise', M-I+1, N-I-IB+1, IB,$ A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),$ LDA, WORK( IB+1 ), LDWORK )END IF10 CONTINUEELSEI = 1END IF** Use unblocked code to factor the last or only block.*IF( I.LE.K )$ CALL DGEQR2( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )*WORK( 1 ) = IWSRETURN** End of DGEQRF*END*> \brief \b DGEQRFP** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQRFP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqrfp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqrfp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqrfp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQRFP( M, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQRFP computes a QR factorization of a real M-by-N matrix A:*> A = Q * R. The diagonal entries of R are nonnegative.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(M,N)-by-N upper trapezoidal matrix R (R is*> upper triangular if m >= n). The diagonal entries of R*> are nonnegative; the elements below the diagonal,*> with the array TAU, represent the orthogonal matrix Q as a*> product of min(m,n) elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> For optimum performance LWORK >= N*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i),*> and tau in TAU(i).*>*> See Lapack Working Note 203 for details*> \endverbatim*>* =====================================================================SUBROUTINE DGEQRFP( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DGEQR2P, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQRFP', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGEQRF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGEQRF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially*DO 10 I = 1, K - NX, NBIB = MIN( K-I+1, NB )** Compute the QR factorization of the current block* A(i:m,i:i+ib-1)*CALL DGEQR2P( M-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )IF( I+IB.LE.N ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB,$ A( I, I ), LDA, TAU( I ), WORK, LDWORK )** Apply H**T to A(i:m,i+ib:n) from the left*CALL DLARFB( 'Left', 'Transpose', 'Forward',$ 'Columnwise', M-I+1, N-I-IB+1, IB,$ A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),$ LDA, WORK( IB+1 ), LDWORK )END IF10 CONTINUEELSEI = 1END IF** Use unblocked code to factor the last or only block.*IF( I.LE.K )$ CALL DGEQR2P( M-I+1, N-I+1, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )*WORK( 1 ) = IWSRETURN** End of DGEQRFP*END*> \brief \b DGEQRT** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQRT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqrt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqrt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqrt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQRT( M, N, NB, A, LDA, T, LDT, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDT, M, N, NB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), T( LDT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQRT computes a blocked QR factorization of a real M-by-N matrix A*> using the compact WY representation of Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The block size to be used in the blocked QR. MIN(M,N) >= NB >= 1.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(M,N)-by-N upper trapezoidal matrix R (R is*> upper triangular if M >= N); the elements below the diagonal*> are the columns of V.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,MIN(M,N))*> The upper triangular block reflectors stored in compact form*> as a sequence of upper triangular blocks. See below*> for further details.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= NB.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (NB*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix V stores the elementary reflectors H(i) in the i-th column*> below the diagonal. For example, if M=5 and N=3, the matrix V is*>*> V = ( 1 )*> ( v1 1 )*> ( v1 v2 1 )*> ( v1 v2 v3 )*> ( v1 v2 v3 )*>*> where the vi's represent the vectors which define H(i), which are returned*> in the matrix A. The 1's along the diagonal of V are not stored in A.*>*> Let K=MIN(M,N). The number of blocks is B = ceiling(K/NB), where each*> block is of order NB except for the last block, which is of order*> IB = K - (B-1)*NB. For each of the B blocks, a upper triangular block*> reflector factor is computed: T1, T2, ..., TB. The NB-by-NB (and IB-by-IB*> for the last block) T's are stored in the NB-by-K matrix T as*>*> T = (T1 T2 ... TB).*> \endverbatim*>* =====================================================================SUBROUTINE DGEQRT( M, N, NB, A, LDA, T, LDT, WORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, LDA, LDT, M, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), T( LDT, * ), WORK( * )* ..** =====================================================================** ..* .. Local Scalars ..INTEGER I, IB, IINFO, KLOGICAL USE_RECURSIVE_QRPARAMETER( USE_RECURSIVE_QR=.TRUE. )* ..* .. External Subroutines ..EXTERNAL DGEQRT2, DGEQRT3, DLARFB, XERBLA* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NB.LT.1 .OR. ( NB.GT.MIN(M,N) .AND. MIN(M,N).GT.0 ) )THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDT.LT.NB ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQRT', -INFO )RETURNEND IF** Quick return if possible*K = MIN( M, N )IF( K.EQ.0 ) RETURN** Blocked loop of length K*DO I = 1, K, NBIB = MIN( K-I+1, NB )** Compute the QR factorization of the current block A(I:M,I:I+IB-1)*IF( USE_RECURSIVE_QR ) THENCALL DGEQRT3( M-I+1, IB, A(I,I), LDA, T(1,I), LDT, IINFO )ELSECALL DGEQRT2( M-I+1, IB, A(I,I), LDA, T(1,I), LDT, IINFO )END IFIF( I+IB.LE.N ) THEN** Update by applying H**T to A(I:M,I+IB:N) from the left*CALL DLARFB( 'L', 'T', 'F', 'C', M-I+1, N-I-IB+1, IB,$ A( I, I ), LDA, T( 1, I ), LDT,$ A( I, I+IB ), LDA, WORK , N-I-IB+1 )END IFEND DORETURN** End of DGEQRT*END*> \brief \b DGEQRT2 computes a QR factorization of a general real or complex matrix using the compact WY representation of Q.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQRT2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqrt2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqrt2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqrt2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGEQRT2( M, N, A, LDA, T, LDT, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDT, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), T( LDT, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQRT2 computes a QR factorization of a real M-by-N matrix A,*> using the compact WY representation of Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= N.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the real M-by-N matrix A. On exit, the elements on and*> above the diagonal contain the N-by-N upper triangular matrix R; the*> elements below the diagonal are the columns of V. See below for*> further details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The N-by-N upper triangular factor of the block reflector.*> The elements on and above the diagonal contain the block*> reflector T; the elements below the diagonal are not used.*> See below for further details.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix V stores the elementary reflectors H(i) in the i-th column*> below the diagonal. For example, if M=5 and N=3, the matrix V is*>*> V = ( 1 )*> ( v1 1 )*> ( v1 v2 1 )*> ( v1 v2 v3 )*> ( v1 v2 v3 )*>*> where the vi's represent the vectors which define H(i), which are returned*> in the matrix A. The 1's along the diagonal of V are not stored in A. The*> block reflector H is then given by*>*> H = I - V * T * V**T*>*> where V**T is the transpose of V.*> \endverbatim*>* =====================================================================SUBROUTINE DGEQRT2( M, N, A, LDA, T, LDT, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDT, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), T( LDT, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER( ONE = 1.0D+00, ZERO = 0.0D+00 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII, ALPHA* ..* .. External Subroutines ..EXTERNAL DLARFG, DGEMV, DGER, DTRMV, XERBLA* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQRT2', -INFO )RETURNEND IF*K = MIN( M, N )*DO I = 1, K** Generate elem. refl. H(i) to annihilate A(i+1:m,i), tau(I) -> T(I,1)*CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ T( I, 1 ) )IF( I.LT.N ) THEN** Apply H(i) to A(I:M,I+1:N) from the left*AII = A( I, I )A( I, I ) = ONE** W(1:N-I) := A(I:M,I+1:N)^H * A(I:M,I) [W = T(:,N)]*CALL DGEMV( 'T',M-I+1, N-I, ONE, A( I, I+1 ), LDA,$ A( I, I ), 1, ZERO, T( 1, N ), 1 )** A(I:M,I+1:N) = A(I:m,I+1:N) + alpha*A(I:M,I)*W(1:N-1)^H*ALPHA = -(T( I, 1 ))CALL DGER( M-I+1, N-I, ALPHA, A( I, I ), 1,$ T( 1, N ), 1, A( I, I+1 ), LDA )A( I, I ) = AIIEND IFEND DO*DO I = 2, NAII = A( I, I )A( I, I ) = ONE** T(1:I-1,I) := alpha * A(I:M,1:I-1)**T * A(I:M,I)*ALPHA = -T( I, 1 )CALL DGEMV( 'T', M-I+1, I-1, ALPHA, A( I, 1 ), LDA,$ A( I, I ), 1, ZERO, T( 1, I ), 1 )A( I, I ) = AII** T(1:I-1,I) := T(1:I-1,1:I-1) * T(1:I-1,I)*CALL DTRMV( 'U', 'N', 'N', I-1, T, LDT, T( 1, I ), 1 )** T(I,I) = tau(I)*T( I, I ) = T( I, 1 )T( I, 1) = ZEROEND DO** End of DGEQRT2*END*> \brief \b DGEQRT3 recursively computes a QR factorization of a general real or complex matrix using the compact WY representation of Q.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGEQRT3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgeqrt3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgeqrt3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgeqrt3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** RECURSIVE SUBROUTINE DGEQRT3( M, N, A, LDA, T, LDT, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N, LDT* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), T( LDT, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGEQRT3 recursively computes a QR factorization of a real M-by-N*> matrix A, using the compact WY representation of Q.*>*> Based on the algorithm of Elmroth and Gustavson,*> IBM J. Res. Develop. Vol 44 No. 4 July 2000.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= N.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the real M-by-N matrix A. On exit, the elements on and*> above the diagonal contain the N-by-N upper triangular matrix R; the*> elements below the diagonal are the columns of V. See below for*> further details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The N-by-N upper triangular factor of the block reflector.*> The elements on and above the diagonal contain the block*> reflector T; the elements below the diagonal are not used.*> See below for further details.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix V stores the elementary reflectors H(i) in the i-th column*> below the diagonal. For example, if M=5 and N=3, the matrix V is*>*> V = ( 1 )*> ( v1 1 )*> ( v1 v2 1 )*> ( v1 v2 v3 )*> ( v1 v2 v3 )*>*> where the vi's represent the vectors which define H(i), which are returned*> in the matrix A. The 1's along the diagonal of V are not stored in A. The*> block reflector H is then given by*>*> H = I - V * T * V**T*>*> where V**T is the transpose of V.*>*> For details of the algorithm, see Elmroth and Gustavson (cited above).*> \endverbatim*>* =====================================================================RECURSIVE SUBROUTINE DGEQRT3( M, N, A, LDA, T, LDT, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N, LDT* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), T( LDT, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+00 )* ..* .. Local Scalars ..INTEGER I, I1, J, J1, N1, N2, IINFO* ..* .. External Subroutines ..EXTERNAL DLARFG, DTRMM, DGEMM, XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N .LT. 0 ) THENINFO = -2ELSE IF( M .LT. N ) THENINFO = -1ELSE IF( LDA .LT. MAX( 1, M ) ) THENINFO = -4ELSE IF( LDT .LT. MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGEQRT3', -INFO )RETURNEND IF*IF( N.EQ.1 ) THEN** Compute Householder transform when N=1*CALL DLARFG( M, A(1,1), A( MIN( 2, M ), 1 ), 1, T(1,1) )*ELSE** Otherwise, split A into blocks...*N1 = N/2N2 = N-N1J1 = MIN( N1+1, N )I1 = MIN( N+1, M )** Compute A(1:M,1:N1) <- (Y1,R1,T1), where Q1 = I - Y1 T1 Y1^H*CALL DGEQRT3( M, N1, A, LDA, T, LDT, IINFO )** Compute A(1:M,J1:N) = Q1^H A(1:M,J1:N) [workspace: T(1:N1,J1:N)]*DO J=1,N2DO I=1,N1T( I, J+N1 ) = A( I, J+N1 )END DOEND DOCALL DTRMM( 'L', 'L', 'T', 'U', N1, N2, ONE,& A, LDA, T( 1, J1 ), LDT )*CALL DGEMM( 'T', 'N', N1, N2, M-N1, ONE, A( J1, 1 ), LDA,& A( J1, J1 ), LDA, ONE, T( 1, J1 ), LDT)*CALL DTRMM( 'L', 'U', 'T', 'N', N1, N2, ONE,& T, LDT, T( 1, J1 ), LDT )*CALL DGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( J1, 1 ), LDA,& T( 1, J1 ), LDT, ONE, A( J1, J1 ), LDA )*CALL DTRMM( 'L', 'L', 'N', 'U', N1, N2, ONE,& A, LDA, T( 1, J1 ), LDT )*DO J=1,N2DO I=1,N1A( I, J+N1 ) = A( I, J+N1 ) - T( I, J+N1 )END DOEND DO** Compute A(J1:M,J1:N) <- (Y2,R2,T2) where Q2 = I - Y2 T2 Y2^H*CALL DGEQRT3( M-N1, N2, A( J1, J1 ), LDA,& T( J1, J1 ), LDT, IINFO )** Compute T3 = T(1:N1,J1:N) = -T1 Y1^H Y2 T2*DO I=1,N1DO J=1,N2T( I, J+N1 ) = (A( J+N1, I ))END DOEND DO*CALL DTRMM( 'R', 'L', 'N', 'U', N1, N2, ONE,& A( J1, J1 ), LDA, T( 1, J1 ), LDT )*CALL DGEMM( 'T', 'N', N1, N2, M-N, ONE, A( I1, 1 ), LDA,& A( I1, J1 ), LDA, ONE, T( 1, J1 ), LDT )*CALL DTRMM( 'L', 'U', 'N', 'N', N1, N2, -ONE, T, LDT,& T( 1, J1 ), LDT )*CALL DTRMM( 'R', 'U', 'N', 'N', N1, N2, ONE,& T( J1, J1 ), LDT, T( 1, J1 ), LDT )** Y = (Y1,Y2); R = [ R1 A(1:N1,J1:N) ]; T = [T1 T3]* [ 0 R2 ] [ 0 T2]*END IF*RETURN** End of DGEQRT3*END*> \brief \b DGERFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGERFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgerfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgerfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgerfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,* X, LDX, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGERFS improves the computed solution to a system of linear*> equations and provides error bounds and backward error estimates for*> the solution.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The original N-by-N matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] AF*> \verbatim*> AF is DOUBLE PRECISION array, dimension (LDAF,N)*> The factors L and U from the factorization A = P*L*U*> as computed by DGETRF.*> \endverbatim*>*> \param[in] LDAF*> \verbatim*> LDAF is INTEGER*> The leading dimension of the array AF. LDAF >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices from DGETRF; for 1<=i<=N, row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DGETRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,$ X, LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANCHARACTER TRANSTINTEGER COUNT, I, J, K, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGETRS, DLACN2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGERFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - op(A) * X,* where op(A) = A, A**T, or A**H, depending on TRANS.*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DGEMV( TRANS, N, N, -ONE, A, LDA, X( 1, J ), 1, ONE,$ WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(op(A))*abs(X) + abs(B).*IF( NOTRAN ) THENDO 50 K = 1, NXK = ABS( X( K, J ) )DO 40 I = 1, NWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XK40 CONTINUE50 CONTINUEELSEDO 70 K = 1, NS = ZERODO 60 I = 1, NS = S + ABS( A( I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DGETRS( TRANS, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DGETRS( TRANST, N, 1, AF, LDAF, IPIV, WORK( N+1 ),$ N, INFO )DO 110 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )110 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )120 CONTINUECALL DGETRS( TRANS, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DGERFS*END*> \brief \b DGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGERQ2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgerq2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgerq2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgerq2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGERQ2( M, N, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGERQ2 computes an RQ factorization of a real m by n matrix A:*> A = R * Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n matrix A.*> On exit, if m <= n, the upper triangle of the subarray*> A(1:m,n-m+1:n) contains the m by m upper triangular matrix R;*> if m >= n, the elements on and above the (m-n)-th subdiagonal*> contain the m by n upper trapezoidal matrix R; the remaining*> elements, with the array TAU, represent the orthogonal matrix*> Q as a product of elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (M)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in*> A(m-k+i,1:n-k+i-1), and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGERQ2( M, N, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, KDOUBLE PRECISION AII* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGERQ2', -INFO )RETURNEND IF*K = MIN( M, N )*DO 10 I = K, 1, -1** Generate elementary reflector H(i) to annihilate* A(m-k+i,1:n-k+i-1)*CALL DLARFG( N-K+I, A( M-K+I, N-K+I ), A( M-K+I, 1 ), LDA,$ TAU( I ) )** Apply H(i) to A(1:m-k+i-1,1:n-k+i) from the right*AII = A( M-K+I, N-K+I )A( M-K+I, N-K+I ) = ONECALL DLARF( 'Right', M-K+I-1, N-K+I, A( M-K+I, 1 ), LDA,$ TAU( I ), A, LDA, WORK )A( M-K+I, N-K+I ) = AII10 CONTINUERETURN** End of DGERQ2*END*> \brief \b DGERQF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGERQF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgerqf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgerqf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgerqf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGERQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGERQF computes an RQ factorization of a real M-by-N matrix A:*> A = R * Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit,*> if m <= n, the upper triangle of the subarray*> A(1:m,n-m+1:n) contains the M-by-M upper triangular matrix R;*> if m >= n, the elements on and above the (m-n)-th subdiagonal*> contain the M-by-N upper trapezoidal matrix R;*> the remaining elements, with the array TAU, represent the*> orthogonal matrix Q as a product of min(m,n) elementary*> reflectors (see Further Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,M).*> For optimum performance LWORK >= M*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in*> A(m-k+i,1:n-k+i-1), and tau in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DGERQF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, K, KI, KK, LDWORK, LWKOPT,$ MU, NB, NBMIN, NU, NX* ..* .. External Subroutines ..EXTERNAL DGERQ2, DLARFB, DLARFT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IF*IF( INFO.EQ.0 ) THENK = MIN( M, N )IF( K.EQ.0 ) THENLWKOPT = 1ELSENB = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )LWKOPT = M*NBEND IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -7END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGERQF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( K.EQ.0 ) THENRETURNEND IF*NBMIN = 2NX = 1IWS = MIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGERQF', ' ', M, N, -1, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGERQF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code initially.* The last kk rows are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )*DO 10 I = K - KK + KI + 1, K - KK + 1, -NBIB = MIN( K-I+1, NB )** Compute the RQ factorization of the current block* A(m-k+i:m-k+i+ib-1,1:n-k+i+ib-1)*CALL DGERQ2( IB, N-K+I+IB-1, A( M-K+I, 1 ), LDA, TAU( I ),$ WORK, IINFO )IF( M-K+I.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Rowwise', N-K+I+IB-1, IB,$ A( M-K+I, 1 ), LDA, TAU( I ), WORK, LDWORK )** Apply H to A(1:m-k+i-1,1:n-k+i+ib-1) from the right*CALL DLARFB( 'Right', 'No transpose', 'Backward',$ 'Rowwise', M-K+I-1, N-K+I+IB-1, IB,$ A( M-K+I, 1 ), LDA, WORK, LDWORK, A, LDA,$ WORK( IB+1 ), LDWORK )END IF10 CONTINUEMU = M - K + I + NB - 1NU = N - K + I + NB - 1ELSEMU = MNU = NEND IF** Use unblocked code to factor the last or only block*IF( MU.GT.0 .AND. NU.GT.0 )$ CALL DGERQ2( MU, NU, A, LDA, TAU, WORK, IINFO )*WORK( 1 ) = IWSRETURN** End of DGERQF*END*> \brief \b DGESC2 solves a system of linear equations using the LU factorization with complete pivoting computed by sgetc2.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGESC2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesc2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesc2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesc2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGESC2( N, A, LDA, RHS, IPIV, JPIV, SCALE )** .. Scalar Arguments ..* INTEGER LDA, N* DOUBLE PRECISION SCALE* ..* .. Array Arguments ..* INTEGER IPIV( * ), JPIV( * )* DOUBLE PRECISION A( LDA, * ), RHS( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGESC2 solves a system of linear equations*>*> A * X = scale* RHS*>*> with a general N-by-N matrix A using the LU factorization with*> complete pivoting computed by DGETC2.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the LU part of the factorization of the n-by-n*> matrix A computed by DGETC2: A = P * L * U * Q*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1, N).*> \endverbatim*>*> \param[in,out] RHS*> \verbatim*> RHS is DOUBLE PRECISION array, dimension (N).*> On entry, the right hand side vector b.*> On exit, the solution vector X.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N).*> The pivot indices; for 1 <= i <= N, row i of the*> matrix has been interchanged with row IPIV(i).*> \endverbatim*>*> \param[in] JPIV*> \verbatim*> JPIV is INTEGER array, dimension (N).*> The pivot indices; for 1 <= j <= N, column j of the*> matrix has been interchanged with column JPIV(j).*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> On exit, SCALE contains the scale factor. SCALE is chosen*> 0 <= SCALE <= 1 to prevent owerflow in the solution.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleGEauxiliary**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.** =====================================================================SUBROUTINE DGESC2( N, A, LDA, RHS, IPIV, JPIV, SCALE )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER LDA, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..INTEGER IPIV( * ), JPIV( * )DOUBLE PRECISION A( LDA, * ), RHS( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, TWOPARAMETER ( ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION BIGNUM, EPS, SMLNUM, TEMP* ..* .. External Subroutines ..EXTERNAL DLASWP, DSCAL, DLABAD* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL IDAMAX, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Set constant to control owerflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Apply permutations IPIV to RHS*CALL DLASWP( 1, RHS, LDA, 1, N-1, IPIV, 1 )** Solve for L part*DO 20 I = 1, N - 1DO 10 J = I + 1, NRHS( J ) = RHS( J ) - A( J, I )*RHS( I )10 CONTINUE20 CONTINUE** Solve for U part*SCALE = ONE** Check for scaling*I = IDAMAX( N, RHS, 1 )IF( TWO*SMLNUM*ABS( RHS( I ) ).GT.ABS( A( N, N ) ) ) THENTEMP = ( ONE / TWO ) / ABS( RHS( I ) )CALL DSCAL( N, TEMP, RHS( 1 ), 1 )SCALE = SCALE*TEMPEND IF*DO 40 I = N, 1, -1TEMP = ONE / A( I, I )RHS( I ) = RHS( I )*TEMPDO 30 J = I + 1, NRHS( I ) = RHS( I ) - RHS( J )*( A( I, J )*TEMP )30 CONTINUE40 CONTINUE** Apply permutations JPIV to the solution (RHS)*CALL DLASWP( 1, RHS, LDA, 1, N-1, JPIV, -1 )RETURN** End of DGESC2*END*> \brief \b DGESDD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGESDD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesdd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesdd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesdd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,* WORK, LWORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ* INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),* $ VT( LDVT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGESDD computes the singular value decomposition (SVD) of a real*> M-by-N matrix A, optionally computing the left and right singular*> vectors. If singular vectors are desired, it uses a*> divide-and-conquer algorithm.*>*> The SVD is written*>*> A = U * SIGMA * transpose(V)*>*> where SIGMA is an M-by-N matrix which is zero except for its*> min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and*> V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA*> are the singular values of A; they are real and non-negative, and*> are returned in descending order. The first min(m,n) columns of*> U and V are the left and right singular vectors of A.*>*> Note that the routine returns VT = V**T, not V.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> Specifies options for computing all or part of the matrix U:*> = 'A': all M columns of U and all N rows of V**T are*> returned in the arrays U and VT;*> = 'S': the first min(M,N) columns of U and the first*> min(M,N) rows of V**T are returned in the arrays U*> and VT;*> = 'O': If M >= N, the first N columns of U are overwritten*> on the array A and all rows of V**T are returned in*> the array VT;*> otherwise, all columns of U are returned in the*> array U and the first M rows of V**T are overwritten*> in the array A;*> = 'N': no columns of U or rows of V**T are computed.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the input matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the input matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit,*> if JOBZ = 'O', A is overwritten with the first N columns*> of U (the left singular vectors, stored*> columnwise) if M >= N;*> A is overwritten with the first M rows*> of V**T (the right singular vectors, stored*> rowwise) otherwise.*> if JOBZ .ne. 'O', the contents of A are destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (min(M,N))*> The singular values of A, sorted so that S(i) >= S(i+1).*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,UCOL)*> UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N;*> UCOL = min(M,N) if JOBZ = 'S'.*> If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M*> orthogonal matrix U;*> if JOBZ = 'S', U contains the first min(M,N) columns of U*> (the left singular vectors, stored columnwise);*> if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= 1; if*> JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.*> \endverbatim*>*> \param[out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT,N)*> If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the*> N-by-N orthogonal matrix V**T;*> if JOBZ = 'S', VT contains the first min(M,N) rows of*> V**T (the right singular vectors, stored rowwise);*> if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT. LDVT >= 1;*> if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;*> if JOBZ = 'S', LDVT >= min(M,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK;*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= 1.*> If LWORK = -1, a workspace query is assumed. The optimal*> size for the WORK array is calculated and stored in WORK(1),*> and no other work except argument checking is performed.*>*> Let mx = max(M,N) and mn = min(M,N).*> If JOBZ = 'N', LWORK >= 3*mn + max( mx, 7*mn ).*> If JOBZ = 'O', LWORK >= 3*mn + max( mx, 5*mn*mn + 4*mn ).*> If JOBZ = 'S', LWORK >= 4*mn*mn + 7*mn.*> If JOBZ = 'A', LWORK >= 4*mn*mn + 6*mn + mx.*> These are not tight minimums in all cases; see comments inside code.*> For good performance, LWORK should generally be larger;*> a query is recommended.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (8*min(M,N))*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: DBDSDC did not converge, updating process failed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEsing**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,$ WORK, LWORK, IWORK, INFO )implicit none** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZINTEGER INFO, LDA, LDU, LDVT, LWORK, M, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQSINTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IL,$ IR, ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,$ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,$ MNTHR, NWORK, WRKBLINTEGER LWORK_DGEBRD_MN, LWORK_DGEBRD_MM,$ LWORK_DGEBRD_NN, LWORK_DGELQF_MN,$ LWORK_DGEQRF_MN,$ LWORK_DORGBR_P_MM, LWORK_DORGBR_Q_NN,$ LWORK_DORGLQ_MN, LWORK_DORGLQ_NN,$ LWORK_DORGQR_MM, LWORK_DORGQR_MN,$ LWORK_DORMBR_PRT_MM, LWORK_DORMBR_QLN_MM,$ LWORK_DORMBR_PRT_MN, LWORK_DORMBR_QLN_MN,$ LWORK_DORMBR_PRT_NN, LWORK_DORMBR_QLN_NNDOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM* ..* .. Local Arrays ..INTEGER IDUM( 1 )DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DBDSDC, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,$ DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL DLAMCH, DLANGE, LSAME* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0MINMN = MIN( M, N )WNTQA = LSAME( JOBZ, 'A' )WNTQS = LSAME( JOBZ, 'S' )WNTQAS = WNTQA .OR. WNTQSWNTQO = LSAME( JOBZ, 'O' )WNTQN = LSAME( JOBZ, 'N' )LQUERY = ( LWORK.EQ.-1 )*IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDU.LT.1 .OR. ( WNTQAS .AND. LDU.LT.M ) .OR.$ ( WNTQO .AND. M.LT.N .AND. LDU.LT.M ) ) THENINFO = -8ELSE IF( LDVT.LT.1 .OR. ( WNTQA .AND. LDVT.LT.N ) .OR.$ ( WNTQS .AND. LDVT.LT.MINMN ) .OR.$ ( WNTQO .AND. M.GE.N .AND. LDVT.LT.N ) ) THENINFO = -10END IF** Compute workspace* Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace allocated at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.*IF( INFO.EQ.0 ) THENMINWRK = 1MAXWRK = 1BDSPAC = 0MNTHR = INT( MINMN*11.0D0 / 6.0D0 )IF( M.GE.N .AND. MINMN.GT.0 ) THEN** Compute space needed for DBDSDC*IF( WNTQN ) THEN* dbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6)* keep 7*N for backwards compatability.BDSPAC = 7*NELSEBDSPAC = 3*N*N + 4*NEND IF** Compute space preferred for each routineCALL DGEBRD( M, N, DUM(1), M, DUM(1), DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD_MN = INT( DUM(1) )*CALL DGEBRD( N, N, DUM(1), N, DUM(1), DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD_NN = INT( DUM(1) )*CALL DGEQRF( M, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )LWORK_DGEQRF_MN = INT( DUM(1) )*CALL DORGBR( 'Q', N, N, N, DUM(1), N, DUM(1), DUM(1), -1,$ IERR )LWORK_DORGBR_Q_NN = INT( DUM(1) )*CALL DORGQR( M, M, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )LWORK_DORGQR_MM = INT( DUM(1) )*CALL DORGQR( M, N, N, DUM(1), M, DUM(1), DUM(1), -1, IERR )LWORK_DORGQR_MN = INT( DUM(1) )*CALL DORMBR( 'P', 'R', 'T', N, N, N, DUM(1), N,$ DUM(1), DUM(1), N, DUM(1), -1, IERR )LWORK_DORMBR_PRT_NN = INT( DUM(1) )*CALL DORMBR( 'Q', 'L', 'N', N, N, N, DUM(1), N,$ DUM(1), DUM(1), N, DUM(1), -1, IERR )LWORK_DORMBR_QLN_NN = INT( DUM(1) )*CALL DORMBR( 'Q', 'L', 'N', M, N, N, DUM(1), M,$ DUM(1), DUM(1), M, DUM(1), -1, IERR )LWORK_DORMBR_QLN_MN = INT( DUM(1) )*CALL DORMBR( 'Q', 'L', 'N', M, M, N, DUM(1), M,$ DUM(1), DUM(1), M, DUM(1), -1, IERR )LWORK_DORMBR_QLN_MM = INT( DUM(1) )*IF( M.GE.MNTHR ) THENIF( WNTQN ) THEN** Path 1 (M >> N, JOBZ='N')*WRKBL = N + LWORK_DGEQRF_MNWRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )MAXWRK = MAX( WRKBL, BDSPAC + N )MINWRK = BDSPAC + NELSE IF( WNTQO ) THEN** Path 2 (M >> N, JOBZ='O')*WRKBL = N + LWORK_DGEQRF_MNWRKBL = MAX( WRKBL, N + LWORK_DORGQR_MN )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )WRKBL = MAX( WRKBL, 3*N + BDSPAC )MAXWRK = WRKBL + 2*N*NMINWRK = BDSPAC + 2*N*N + 3*NELSE IF( WNTQS ) THEN** Path 3 (M >> N, JOBZ='S')*WRKBL = N + LWORK_DGEQRF_MNWRKBL = MAX( WRKBL, N + LWORK_DORGQR_MN )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )WRKBL = MAX( WRKBL, 3*N + BDSPAC )MAXWRK = WRKBL + N*NMINWRK = BDSPAC + N*N + 3*NELSE IF( WNTQA ) THEN** Path 4 (M >> N, JOBZ='A')*WRKBL = N + LWORK_DGEQRF_MNWRKBL = MAX( WRKBL, N + LWORK_DORGQR_MM )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )WRKBL = MAX( WRKBL, 3*N + BDSPAC )MAXWRK = WRKBL + N*NMINWRK = N*N + MAX( 3*N + BDSPAC, N + M )END IFELSE** Path 5 (M >= N, but not much larger)*WRKBL = 3*N + LWORK_DGEBRD_MNIF( WNTQN ) THEN* Path 5n (M >= N, jobz='N')MAXWRK = MAX( WRKBL, 3*N + BDSPAC )MINWRK = 3*N + MAX( M, BDSPAC )ELSE IF( WNTQO ) THEN* Path 5o (M >= N, jobz='O')WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_MN )WRKBL = MAX( WRKBL, 3*N + BDSPAC )MAXWRK = WRKBL + M*NMINWRK = 3*N + MAX( M, N*N + BDSPAC )ELSE IF( WNTQS ) THEN* Path 5s (M >= N, jobz='S')WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_MN )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )MAXWRK = MAX( WRKBL, 3*N + BDSPAC )MINWRK = 3*N + MAX( M, BDSPAC )ELSE IF( WNTQA ) THEN* Path 5a (M >= N, jobz='A')WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*N + LWORK_DORMBR_PRT_NN )MAXWRK = MAX( WRKBL, 3*N + BDSPAC )MINWRK = 3*N + MAX( M, BDSPAC )END IFEND IFELSE IF( MINMN.GT.0 ) THEN** Compute space needed for DBDSDC*IF( WNTQN ) THEN* dbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6)* keep 7*N for backwards compatability.BDSPAC = 7*MELSEBDSPAC = 3*M*M + 4*MEND IF** Compute space preferred for each routineCALL DGEBRD( M, N, DUM(1), M, DUM(1), DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD_MN = INT( DUM(1) )*CALL DGEBRD( M, M, A, M, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD_MM = INT( DUM(1) )*CALL DGELQF( M, N, A, M, DUM(1), DUM(1), -1, IERR )LWORK_DGELQF_MN = INT( DUM(1) )*CALL DORGLQ( N, N, M, DUM(1), N, DUM(1), DUM(1), -1, IERR )LWORK_DORGLQ_NN = INT( DUM(1) )*CALL DORGLQ( M, N, M, A, M, DUM(1), DUM(1), -1, IERR )LWORK_DORGLQ_MN = INT( DUM(1) )*CALL DORGBR( 'P', M, M, M, A, N, DUM(1), DUM(1), -1, IERR )LWORK_DORGBR_P_MM = INT( DUM(1) )*CALL DORMBR( 'P', 'R', 'T', M, M, M, DUM(1), M,$ DUM(1), DUM(1), M, DUM(1), -1, IERR )LWORK_DORMBR_PRT_MM = INT( DUM(1) )*CALL DORMBR( 'P', 'R', 'T', M, N, M, DUM(1), M,$ DUM(1), DUM(1), M, DUM(1), -1, IERR )LWORK_DORMBR_PRT_MN = INT( DUM(1) )*CALL DORMBR( 'P', 'R', 'T', N, N, M, DUM(1), N,$ DUM(1), DUM(1), N, DUM(1), -1, IERR )LWORK_DORMBR_PRT_NN = INT( DUM(1) )*CALL DORMBR( 'Q', 'L', 'N', M, M, M, DUM(1), M,$ DUM(1), DUM(1), M, DUM(1), -1, IERR )LWORK_DORMBR_QLN_MM = INT( DUM(1) )*IF( N.GE.MNTHR ) THENIF( WNTQN ) THEN** Path 1t (N >> M, JOBZ='N')*WRKBL = M + LWORK_DGELQF_MNWRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )MAXWRK = MAX( WRKBL, BDSPAC + M )MINWRK = BDSPAC + MELSE IF( WNTQO ) THEN** Path 2t (N >> M, JOBZ='O')*WRKBL = M + LWORK_DGELQF_MNWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_MN )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MM )WRKBL = MAX( WRKBL, 3*M + BDSPAC )MAXWRK = WRKBL + 2*M*MMINWRK = BDSPAC + 2*M*M + 3*MELSE IF( WNTQS ) THEN** Path 3t (N >> M, JOBZ='S')*WRKBL = M + LWORK_DGELQF_MNWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_MN )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MM )WRKBL = MAX( WRKBL, 3*M + BDSPAC )MAXWRK = WRKBL + M*MMINWRK = BDSPAC + M*M + 3*MELSE IF( WNTQA ) THEN** Path 4t (N >> M, JOBZ='A')*WRKBL = M + LWORK_DGELQF_MNWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_NN )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MM )WRKBL = MAX( WRKBL, 3*M + BDSPAC )MAXWRK = WRKBL + M*MMINWRK = M*M + MAX( 3*M + BDSPAC, M + N )END IFELSE** Path 5t (N > M, but not much larger)*WRKBL = 3*M + LWORK_DGEBRD_MNIF( WNTQN ) THEN* Path 5tn (N > M, jobz='N')MAXWRK = MAX( WRKBL, 3*M + BDSPAC )MINWRK = 3*M + MAX( N, BDSPAC )ELSE IF( WNTQO ) THEN* Path 5to (N > M, jobz='O')WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MN )WRKBL = MAX( WRKBL, 3*M + BDSPAC )MAXWRK = WRKBL + M*NMINWRK = 3*M + MAX( N, M*M + BDSPAC )ELSE IF( WNTQS ) THEN* Path 5ts (N > M, jobz='S')WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_MN )MAXWRK = MAX( WRKBL, 3*M + BDSPAC )MINWRK = 3*M + MAX( N, BDSPAC )ELSE IF( WNTQA ) THEN* Path 5ta (N > M, jobz='A')WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_QLN_MM )WRKBL = MAX( WRKBL, 3*M + LWORK_DORMBR_PRT_NN )MAXWRK = MAX( WRKBL, 3*M + BDSPAC )MINWRK = 3*M + MAX( N, BDSPAC )END IFEND IFEND IFMAXWRK = MAX( MAXWRK, MINWRK )WORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -12END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGESDD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENRETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, DUM )ISCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENISCL = 1CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )ELSE IF( ANRM.GT.BIGNUM ) THENISCL = 1CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )END IF*IF( M.GE.N ) THEN** A has at least as many rows as columns. If A has sufficiently* more rows than columns, first reduce using the QR* decomposition (if sufficient workspace available)*IF( M.GE.MNTHR ) THEN*IF( WNTQN ) THEN** Path 1 (M >> N, JOBZ='N')* No singular vectors to be computed*ITAU = 1NWORK = ITAU + N** Compute A=Q*R* Workspace: need N [tau] + N [work]* Workspace: prefer N [tau] + N*NB [work]*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Zero out below R*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )IE = 1ITAUQ = IE + NITAUP = ITAUQ + NNWORK = ITAUP + N** Bidiagonalize R in A* Workspace: need 3*N [e, tauq, taup] + N [work]* Workspace: prefer 3*N [e, tauq, taup] + 2*N*NB [work]*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ IERR )NWORK = IE + N** Perform bidiagonal SVD, computing singular values only* Workspace: need N [e] + BDSPAC*CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,$ DUM, IDUM, WORK( NWORK ), IWORK, INFO )*ELSE IF( WNTQO ) THEN** Path 2 (M >> N, JOBZ = 'O')* N left singular vectors to be overwritten on A and* N right singular vectors to be computed in VT*IR = 1** WORK(IR) is LDWRKR by N*IF( LWORK .GE. LDA*N + N*N + 3*N + BDSPAC ) THENLDWRKR = LDAELSELDWRKR = ( LWORK - N*N - 3*N - BDSPAC ) / NEND IFITAU = IR + LDWRKR*NNWORK = ITAU + N** Compute A=Q*R* Workspace: need N*N [R] + N [tau] + N [work]* Workspace: prefer N*N [R] + N [tau] + N*NB [work]*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Copy R to WORK(IR), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )CALL DLASET( 'L', N - 1, N - 1, ZERO, ZERO, WORK(IR+1),$ LDWRKR )** Generate Q in A* Workspace: need N*N [R] + N [tau] + N [work]* Workspace: prefer N*N [R] + N [tau] + N*NB [work]*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NNWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* Workspace: need N*N [R] + 3*N [e, tauq, taup] + N [work]* Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work]*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** WORK(IU) is N by N*IU = NWORKNWORK = IU + N*N** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in WORK(IU) and computing right* singular vectors of bidiagonal matrix in VT* Workspace: need N*N [R] + 3*N [e, tauq, taup] + N*N [U] + BDSPAC*CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,$ VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Overwrite WORK(IU) by left singular vectors of R* and VT by right singular vectors of R* Workspace: need N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N [work]* Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N*NB [work]*CALL DORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IU ), N, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Multiply Q in A by left singular vectors of R in* WORK(IU), storing result in WORK(IR) and copying to A* Workspace: need N*N [R] + 3*N [e, tauq, taup] + N*N [U]* Workspace: prefer M*N [R] + 3*N [e, tauq, taup] + N*N [U]*DO 10 I = 1, M, LDWRKRCHUNK = MIN( M - I + 1, LDWRKR )CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),$ LDA, WORK( IU ), N, ZERO, WORK( IR ),$ LDWRKR )CALL DLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,$ A( I, 1 ), LDA )10 CONTINUE*ELSE IF( WNTQS ) THEN** Path 3 (M >> N, JOBZ='S')* N left singular vectors to be computed in U and* N right singular vectors to be computed in VT*IR = 1** WORK(IR) is N by N*LDWRKR = NITAU = IR + LDWRKR*NNWORK = ITAU + N** Compute A=Q*R* Workspace: need N*N [R] + N [tau] + N [work]* Workspace: prefer N*N [R] + N [tau] + N*NB [work]*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Copy R to WORK(IR), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )CALL DLASET( 'L', N - 1, N - 1, ZERO, ZERO, WORK(IR+1),$ LDWRKR )** Generate Q in A* Workspace: need N*N [R] + N [tau] + N [work]* Workspace: prefer N*N [R] + N [tau] + N*NB [work]*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NNWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* Workspace: need N*N [R] + 3*N [e, tauq, taup] + N [work]* Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work]*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Perform bidiagonal SVD, computing left singular vectors* of bidiagoal matrix in U and computing right singular* vectors of bidiagonal matrix in VT* Workspace: need N*N [R] + 3*N [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,$ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Overwrite U by left singular vectors of R and VT* by right singular vectors of R* Workspace: need N*N [R] + 3*N [e, tauq, taup] + N [work]* Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*NB [work]*CALL DORMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )*CALL DORMBR( 'P', 'R', 'T', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in U* Workspace: need N*N [R]*CALL DLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA, WORK( IR ),$ LDWRKR, ZERO, U, LDU )*ELSE IF( WNTQA ) THEN** Path 4 (M >> N, JOBZ='A')* M left singular vectors to be computed in U and* N right singular vectors to be computed in VT*IU = 1** WORK(IU) is N by N*LDWRKU = NITAU = IU + LDWRKU*NNWORK = ITAU + N** Compute A=Q*R, copying result to U* Workspace: need N*N [U] + N [tau] + N [work]* Workspace: prefer N*N [U] + N [tau] + N*NB [work]*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* Workspace: need N*N [U] + N [tau] + M [work]* Workspace: prefer N*N [U] + N [tau] + M*NB [work]CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Produce R in A, zeroing out other entries*CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NNWORK = ITAUP + N** Bidiagonalize R in A* Workspace: need N*N [U] + 3*N [e, tauq, taup] + N [work]* Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + 2*N*NB [work]*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ IERR )** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in WORK(IU) and computing right* singular vectors of bidiagonal matrix in VT* Workspace: need N*N [U] + 3*N [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ), N,$ VT, LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Overwrite WORK(IU) by left singular vectors of R and VT* by right singular vectors of R* Workspace: need N*N [U] + 3*N [e, tauq, taup] + N [work]* Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + N*NB [work]*CALL DORMBR( 'Q', 'L', 'N', N, N, N, A, LDA,$ WORK( ITAUQ ), WORK( IU ), LDWRKU,$ WORK( NWORK ), LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Multiply Q in U by left singular vectors of R in* WORK(IU), storing result in A* Workspace: need N*N [U]*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU, WORK( IU ),$ LDWRKU, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )*END IF*ELSE** M .LT. MNTHR** Path 5 (M >= N, but not much larger)* Reduce to bidiagonal form without QR decomposition*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NNWORK = ITAUP + N** Bidiagonalize A* Workspace: need 3*N [e, tauq, taup] + M [work]* Workspace: prefer 3*N [e, tauq, taup] + (M+N)*NB [work]*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ IERR )IF( WNTQN ) THEN** Path 5n (M >= N, JOBZ='N')* Perform bidiagonal SVD, only computing singular values* Workspace: need 3*N [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'U', 'N', N, S, WORK( IE ), DUM, 1, DUM, 1,$ DUM, IDUM, WORK( NWORK ), IWORK, INFO )ELSE IF( WNTQO ) THEN* Path 5o (M >= N, JOBZ='O')IU = NWORKIF( LWORK .GE. M*N + 3*N + BDSPAC ) THEN** WORK( IU ) is M by N*LDWRKU = MNWORK = IU + LDWRKU*NCALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IU ),$ LDWRKU )* IR is unused; silence compile warningsIR = -1ELSE** WORK( IU ) is N by N*LDWRKU = NNWORK = IU + LDWRKU*N** WORK(IR) is LDWRKR by N*IR = NWORKLDWRKR = ( LWORK - N*N - 3*N ) / NEND IFNWORK = IU + LDWRKU*N** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in WORK(IU) and computing right* singular vectors of bidiagonal matrix in VT* Workspace: need 3*N [e, tauq, taup] + N*N [U] + BDSPAC*CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), WORK( IU ),$ LDWRKU, VT, LDVT, DUM, IDUM, WORK( NWORK ),$ IWORK, INFO )** Overwrite VT by right singular vectors of A* Workspace: need 3*N [e, tauq, taup] + N*N [U] + N [work]* Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work]*CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )*IF( LWORK .GE. M*N + 3*N + BDSPAC ) THEN** Path 5o-fast* Overwrite WORK(IU) by left singular vectors of A* Workspace: need 3*N [e, tauq, taup] + M*N [U] + N [work]* Workspace: prefer 3*N [e, tauq, taup] + M*N [U] + N*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), WORK( IU ), LDWRKU,$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Copy left singular vectors of A from WORK(IU) to A*CALL DLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )ELSE** Path 5o-slow* Generate Q in A* Workspace: need 3*N [e, tauq, taup] + N*N [U] + N [work]* Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work]*CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Multiply Q in A by left singular vectors of* bidiagonal matrix in WORK(IU), storing result in* WORK(IR) and copying to A* Workspace: need 3*N [e, tauq, taup] + N*N [U] + NB*N [R]* Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + M*N [R]*DO 20 I = 1, M, LDWRKRCHUNK = MIN( M - I + 1, LDWRKR )CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),$ LDA, WORK( IU ), LDWRKU, ZERO,$ WORK( IR ), LDWRKR )CALL DLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,$ A( I, 1 ), LDA )20 CONTINUEEND IF*ELSE IF( WNTQS ) THEN** Path 5s (M >= N, JOBZ='S')* Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in VT* Workspace: need 3*N [e, tauq, taup] + BDSPAC*CALL DLASET( 'F', M, N, ZERO, ZERO, U, LDU )CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,$ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Overwrite U by left singular vectors of A and VT* by right singular vectors of A* Workspace: need 3*N [e, tauq, taup] + N [work]* Workspace: prefer 3*N [e, tauq, taup] + N*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', N, N, N, A, LDA,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )ELSE IF( WNTQA ) THEN** Path 5a (M >= N, JOBZ='A')* Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in VT* Workspace: need 3*N [e, tauq, taup] + BDSPAC*CALL DLASET( 'F', M, M, ZERO, ZERO, U, LDU )CALL DBDSDC( 'U', 'I', N, S, WORK( IE ), U, LDU, VT,$ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Set the right corner of U to identity matrix*IF( M.GT.N ) THENCALL DLASET( 'F', M - N, M - N, ZERO, ONE, U(N+1,N+1),$ LDU )END IF** Overwrite U by left singular vectors of A and VT* by right singular vectors of A* Workspace: need 3*N [e, tauq, taup] + M [work]* Workspace: prefer 3*N [e, tauq, taup] + M*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )END IF*END IF*ELSE** A has more columns than rows. If A has sufficiently more* columns than rows, first reduce using the LQ decomposition (if* sufficient workspace available)*IF( N.GE.MNTHR ) THEN*IF( WNTQN ) THEN** Path 1t (N >> M, JOBZ='N')* No singular vectors to be computed*ITAU = 1NWORK = ITAU + M** Compute A=L*Q* Workspace: need M [tau] + M [work]* Workspace: prefer M [tau] + M*NB [work]*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Zero out above L*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )IE = 1ITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize L in A* Workspace: need 3*M [e, tauq, taup] + M [work]* Workspace: prefer 3*M [e, tauq, taup] + 2*M*NB [work]*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ IERR )NWORK = IE + M** Perform bidiagonal SVD, computing singular values only* Workspace: need M [e] + BDSPAC*CALL DBDSDC( 'U', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,$ DUM, IDUM, WORK( NWORK ), IWORK, INFO )*ELSE IF( WNTQO ) THEN** Path 2t (N >> M, JOBZ='O')* M right singular vectors to be overwritten on A and* M left singular vectors to be computed in U*IVT = 1** WORK(IVT) is M by M* WORK(IL) is M by M; it is later resized to M by chunk for gemm*IL = IVT + M*MIF( LWORK .GE. M*N + M*M + 3*M + BDSPAC ) THENLDWRKL = MCHUNK = NELSELDWRKL = MCHUNK = ( LWORK - M*M ) / MEND IFITAU = IL + LDWRKL*MNWORK = ITAU + M** Compute A=L*Q* Workspace: need M*M [VT] + M*M [L] + M [tau] + M [work]* Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Copy L to WORK(IL), zeroing about above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )CALL DLASET( 'U', M - 1, M - 1, ZERO, ZERO,$ WORK( IL + LDWRKL ), LDWRKL )** Generate Q in A* Workspace: need M*M [VT] + M*M [L] + M [tau] + M [work]* Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize L in WORK(IL)* Workspace: need M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M [work]* Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work]*CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U, and computing right singular* vectors of bidiagonal matrix in WORK(IVT)* Workspace: need M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,$ WORK( IVT ), M, DUM, IDUM, WORK( NWORK ),$ IWORK, INFO )** Overwrite U by left singular vectors of L and WORK(IVT)* by right singular vectors of L* Workspace: need M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M [work]* Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,$ WORK( ITAUP ), WORK( IVT ), M,$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Multiply right singular vectors of L in WORK(IVT) by Q* in A, storing result in WORK(IL) and copying to A* Workspace: need M*M [VT] + M*M [L]* Workspace: prefer M*M [VT] + M*N [L]* At this point, L is resized as M by chunk.*DO 30 I = 1, N, CHUNKBLK = MIN( N - I + 1, CHUNK )CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ), M,$ A( 1, I ), LDA, ZERO, WORK( IL ), LDWRKL )CALL DLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,$ A( 1, I ), LDA )30 CONTINUE*ELSE IF( WNTQS ) THEN** Path 3t (N >> M, JOBZ='S')* M right singular vectors to be computed in VT and* M left singular vectors to be computed in U*IL = 1** WORK(IL) is M by M*LDWRKL = MITAU = IL + LDWRKL*MNWORK = ITAU + M** Compute A=L*Q* Workspace: need M*M [L] + M [tau] + M [work]* Workspace: prefer M*M [L] + M [tau] + M*NB [work]*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Copy L to WORK(IL), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )CALL DLASET( 'U', M - 1, M - 1, ZERO, ZERO,$ WORK( IL + LDWRKL ), LDWRKL )** Generate Q in A* Workspace: need M*M [L] + M [tau] + M [work]* Workspace: prefer M*M [L] + M [tau] + M*NB [work]*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize L in WORK(IU).* Workspace: need M*M [L] + 3*M [e, tauq, taup] + M [work]* Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work]*CALL DGEBRD( M, M, WORK( IL ), LDWRKL, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in VT* Workspace: need M*M [L] + 3*M [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU, VT,$ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Overwrite U by left singular vectors of L and VT* by right singular vectors of L* Workspace: need M*M [L] + 3*M [e, tauq, taup] + M [work]* Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + M*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', M, M, M, WORK( IL ), LDWRKL,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )** Multiply right singular vectors of L in WORK(IL) by* Q in A, storing result in VT* Workspace: need M*M [L]*CALL DLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IL ), LDWRKL,$ A, LDA, ZERO, VT, LDVT )*ELSE IF( WNTQA ) THEN** Path 4t (N >> M, JOBZ='A')* N right singular vectors to be computed in VT and* M left singular vectors to be computed in U*IVT = 1** WORK(IVT) is M by M*LDWKVT = MITAU = IVT + LDWKVT*MNWORK = ITAU + M** Compute A=L*Q, copying result to VT* Workspace: need M*M [VT] + M [tau] + M [work]* Workspace: prefer M*M [VT] + M [tau] + M*NB [work]*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* Workspace: need M*M [VT] + M [tau] + N [work]* Workspace: prefer M*M [VT] + M [tau] + N*NB [work]*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Produce L in A, zeroing out other entries*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize L in A* Workspace: need M*M [VT] + 3*M [e, tauq, taup] + M [work]* Workspace: prefer M*M [VT] + 3*M [e, tauq, taup] + 2*M*NB [work]*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ IERR )** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in WORK(IVT)* Workspace: need M*M [VT] + 3*M [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'U', 'I', M, S, WORK( IE ), U, LDU,$ WORK( IVT ), LDWKVT, DUM, IDUM,$ WORK( NWORK ), IWORK, INFO )** Overwrite U by left singular vectors of L and WORK(IVT)* by right singular vectors of L* Workspace: need M*M [VT] + 3*M [e, tauq, taup]+ M [work]* Workspace: prefer M*M [VT] + 3*M [e, tauq, taup]+ M*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, M, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', M, M, M, A, LDA,$ WORK( ITAUP ), WORK( IVT ), LDWKVT,$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Multiply right singular vectors of L in WORK(IVT) by* Q in VT, storing result in A* Workspace: need M*M [VT]*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IVT ), LDWKVT,$ VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )*END IF*ELSE** N .LT. MNTHR** Path 5t (N > M, but not much larger)* Reduce to bidiagonal form without LQ decomposition*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MNWORK = ITAUP + M** Bidiagonalize A* Workspace: need 3*M [e, tauq, taup] + N [work]* Workspace: prefer 3*M [e, tauq, taup] + (M+N)*NB [work]*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,$ IERR )IF( WNTQN ) THEN** Path 5tn (N > M, JOBZ='N')* Perform bidiagonal SVD, only computing singular values* Workspace: need 3*M [e, tauq, taup] + BDSPAC*CALL DBDSDC( 'L', 'N', M, S, WORK( IE ), DUM, 1, DUM, 1,$ DUM, IDUM, WORK( NWORK ), IWORK, INFO )ELSE IF( WNTQO ) THEN* Path 5to (N > M, JOBZ='O')LDWKVT = MIVT = NWORKIF( LWORK .GE. M*N + 3*M + BDSPAC ) THEN** WORK( IVT ) is M by N*CALL DLASET( 'F', M, N, ZERO, ZERO, WORK( IVT ),$ LDWKVT )NWORK = IVT + LDWKVT*N* IL is unused; silence compile warningsIL = -1ELSE** WORK( IVT ) is M by M*NWORK = IVT + LDWKVT*MIL = NWORK** WORK(IL) is M by CHUNK*CHUNK = ( LWORK - M*M - 3*M ) / MEND IF** Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in WORK(IVT)* Workspace: need 3*M [e, tauq, taup] + M*M [VT] + BDSPAC*CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU,$ WORK( IVT ), LDWKVT, DUM, IDUM,$ WORK( NWORK ), IWORK, INFO )** Overwrite U by left singular vectors of A* Workspace: need 3*M [e, tauq, taup] + M*M [VT] + M [work]* Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )*IF( LWORK .GE. M*N + 3*M + BDSPAC ) THEN** Path 5to-fast* Overwrite WORK(IVT) by left singular vectors of A* Workspace: need 3*M [e, tauq, taup] + M*N [VT] + M [work]* Workspace: prefer 3*M [e, tauq, taup] + M*N [VT] + M*NB [work]*CALL DORMBR( 'P', 'R', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), WORK( IVT ), LDWKVT,$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Copy right singular vectors of A from WORK(IVT) to A*CALL DLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )ELSE** Path 5to-slow* Generate P**T in A* Workspace: need 3*M [e, tauq, taup] + M*M [VT] + M [work]* Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work]*CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),$ WORK( NWORK ), LWORK - NWORK + 1, IERR )** Multiply Q in A by right singular vectors of* bidiagonal matrix in WORK(IVT), storing result in* WORK(IL) and copying to A* Workspace: need 3*M [e, tauq, taup] + M*M [VT] + M*NB [L]* Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*N [L]*DO 40 I = 1, N, CHUNKBLK = MIN( N - I + 1, CHUNK )CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IVT ),$ LDWKVT, A( 1, I ), LDA, ZERO,$ WORK( IL ), M )CALL DLACPY( 'F', M, BLK, WORK( IL ), M, A( 1, I ),$ LDA )40 CONTINUEEND IFELSE IF( WNTQS ) THEN** Path 5ts (N > M, JOBZ='S')* Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in VT* Workspace: need 3*M [e, tauq, taup] + BDSPAC*CALL DLASET( 'F', M, N, ZERO, ZERO, VT, LDVT )CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,$ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Overwrite U by left singular vectors of A and VT* by right singular vectors of A* Workspace: need 3*M [e, tauq, taup] + M [work]* Workspace: prefer 3*M [e, tauq, taup] + M*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )ELSE IF( WNTQA ) THEN** Path 5ta (N > M, JOBZ='A')* Perform bidiagonal SVD, computing left singular vectors* of bidiagonal matrix in U and computing right singular* vectors of bidiagonal matrix in VT* Workspace: need 3*M [e, tauq, taup] + BDSPAC*CALL DLASET( 'F', N, N, ZERO, ZERO, VT, LDVT )CALL DBDSDC( 'L', 'I', M, S, WORK( IE ), U, LDU, VT,$ LDVT, DUM, IDUM, WORK( NWORK ), IWORK,$ INFO )** Set the right corner of VT to identity matrix*IF( N.GT.M ) THENCALL DLASET( 'F', N-M, N-M, ZERO, ONE, VT(M+1,M+1),$ LDVT )END IF** Overwrite U by left singular vectors of A and VT* by right singular vectors of A* Workspace: need 3*M [e, tauq, taup] + N [work]* Workspace: prefer 3*M [e, tauq, taup] + N*NB [work]*CALL DORMBR( 'Q', 'L', 'N', M, M, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )CALL DORMBR( 'P', 'R', 'T', N, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),$ LWORK - NWORK + 1, IERR )END IF*END IF*END IF** Undo scaling if necessary*IF( ISCL.EQ.1 ) THENIF( ANRM.GT.BIGNUM )$ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,$ IERR )IF( ANRM.LT.SMLNUM )$ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,$ IERR )END IF** Return optimal workspace in WORK(1)*WORK( 1 ) = MAXWRK*RETURN** End of DGESDD*END*> \brief <b> DGESV computes the solution to system of linear equations A * X = B for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGESV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGESV computes the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N matrix and X and B are N-by-NRHS matrices.*>*> The LU decomposition with partial pivoting and row interchanges is*> used to factor A as*> A = P * L * U,*> where P is a permutation matrix, L is unit lower triangular, and U is*> upper triangular. The factored form of A is then used to solve the*> system of equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the N-by-N coefficient matrix A.*> On exit, the factors L and U from the factorization*> A = P*L*U; the unit diagonal elements of L are not stored.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices that define the permutation matrix P;*> row i of the matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS matrix of right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, so the solution could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEsolve** =====================================================================SUBROUTINE DGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. External Subroutines ..EXTERNAL DGETRF, DGETRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( NRHS.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGESV ', -INFO )RETURNEND IF** Compute the LU factorization of A.*CALL DGETRF( N, N, A, LDA, IPIV, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DGETRS( 'No transpose', N, NRHS, A, LDA, IPIV, B, LDB,$ INFO )END IFRETURN** End of DGESV*END*> \brief <b> DGESVD computes the singular value decomposition (SVD) for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGESVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesvd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesvd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesvd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBU, JOBVT* INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),* $ VT( LDVT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGESVD computes the singular value decomposition (SVD) of a real*> M-by-N matrix A, optionally computing the left and/or right singular*> vectors. The SVD is written*>*> A = U * SIGMA * transpose(V)*>*> where SIGMA is an M-by-N matrix which is zero except for its*> min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and*> V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA*> are the singular values of A; they are real and non-negative, and*> are returned in descending order. The first min(m,n) columns of*> U and V are the left and right singular vectors of A.*>*> Note that the routine returns V**T, not V.*> \endverbatim** Arguments:* ==========**> \param[in] JOBU*> \verbatim*> JOBU is CHARACTER*1*> Specifies options for computing all or part of the matrix U:*> = 'A': all M columns of U are returned in array U:*> = 'S': the first min(m,n) columns of U (the left singular*> vectors) are returned in the array U;*> = 'O': the first min(m,n) columns of U (the left singular*> vectors) are overwritten on the array A;*> = 'N': no columns of U (no left singular vectors) are*> computed.*> \endverbatim*>*> \param[in] JOBVT*> \verbatim*> JOBVT is CHARACTER*1*> Specifies options for computing all or part of the matrix*> V**T:*> = 'A': all N rows of V**T are returned in the array VT;*> = 'S': the first min(m,n) rows of V**T (the right singular*> vectors) are returned in the array VT;*> = 'O': the first min(m,n) rows of V**T (the right singular*> vectors) are overwritten on the array A;*> = 'N': no rows of V**T (no right singular vectors) are*> computed.*>*> JOBVT and JOBU cannot both be 'O'.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the input matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the input matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit,*> if JOBU = 'O', A is overwritten with the first min(m,n)*> columns of U (the left singular vectors,*> stored columnwise);*> if JOBVT = 'O', A is overwritten with the first min(m,n)*> rows of V**T (the right singular vectors,*> stored rowwise);*> if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A*> are destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (min(M,N))*> The singular values of A, sorted so that S(i) >= S(i+1).*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,UCOL)*> (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.*> If JOBU = 'A', U contains the M-by-M orthogonal matrix U;*> if JOBU = 'S', U contains the first min(m,n) columns of U*> (the left singular vectors, stored columnwise);*> if JOBU = 'N' or 'O', U is not referenced.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= 1; if*> JOBU = 'S' or 'A', LDU >= M.*> \endverbatim*>*> \param[out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT,N)*> If JOBVT = 'A', VT contains the N-by-N orthogonal matrix*> V**T;*> if JOBVT = 'S', VT contains the first min(m,n) rows of*> V**T (the right singular vectors, stored rowwise);*> if JOBVT = 'N' or 'O', VT is not referenced.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT. LDVT >= 1; if*> JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK;*> if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged*> superdiagonal elements of an upper bidiagonal matrix B*> whose diagonal is in S (not necessarily sorted). B*> satisfies A = U * B * VT, so it has the same singular values*> as A, and singular vectors related by U and VT.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> LWORK >= MAX(1,5*MIN(M,N)) for the paths (see comments inside code):*> - PATH 1 (M much larger than N, JOBU='N')*> - PATH 1t (N much larger than M, JOBVT='N')*> LWORK >= MAX(1,3*MIN(M,N) + MAX(M,N),5*MIN(M,N)) for the other paths*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if DBDSQR did not converge, INFO specifies how many*> superdiagonals of an intermediate bidiagonal form B*> did not converge to zero. See the description of WORK*> above for details.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleGEsing** =====================================================================SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU,$ VT, LDVT, WORK, LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER JOBU, JOBVTINTEGER INFO, LDA, LDU, LDVT, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), S( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,$ WNTVA, WNTVAS, WNTVN, WNTVO, WNTVSINTEGER BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,$ ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,$ MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,$ NRVT, WRKBLINTEGER LWORK_DGEQRF, LWORK_DORGQR_N, LWORK_DORGQR_M,$ LWORK_DGEBRD, LWORK_DORGBR_P, LWORK_DORGBR_Q,$ LWORK_DGELQF, LWORK_DORGLQ_N, LWORK_DORGLQ_MDOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 )* ..* .. External Subroutines ..EXTERNAL DBDSQR, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,$ DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments*INFO = 0MINMN = MIN( M, N )WNTUA = LSAME( JOBU, 'A' )WNTUS = LSAME( JOBU, 'S' )WNTUAS = WNTUA .OR. WNTUSWNTUO = LSAME( JOBU, 'O' )WNTUN = LSAME( JOBU, 'N' )WNTVA = LSAME( JOBVT, 'A' )WNTVS = LSAME( JOBVT, 'S' )WNTVAS = WNTVA .OR. WNTVSWNTVO = LSAME( JOBVT, 'O' )WNTVN = LSAME( JOBVT, 'N' )LQUERY = ( LWORK.EQ.-1 )*IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THENINFO = -1ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.$ ( WNTVO .AND. WNTUO ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THENINFO = -9ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.$ ( WNTVS .AND. LDVT.LT.MINMN ) ) THENINFO = -11END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)*IF( INFO.EQ.0 ) THENMINWRK = 1MAXWRK = 1IF( M.GE.N .AND. MINMN.GT.0 ) THEN** Compute space needed for DBDSQR*MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )BDSPAC = 5*N* Compute space needed for DGEQRFCALL DGEQRF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )LWORK_DGEQRF = INT( DUM(1) )* Compute space needed for DORGQRCALL DORGQR( M, N, N, A, LDA, DUM(1), DUM(1), -1, IERR )LWORK_DORGQR_N = INT( DUM(1) )CALL DORGQR( M, M, N, A, LDA, DUM(1), DUM(1), -1, IERR )LWORK_DORGQR_M = INT( DUM(1) )* Compute space needed for DGEBRDCALL DGEBRD( N, N, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD = INT( DUM(1) )* Compute space needed for DORGBR PCALL DORGBR( 'P', N, N, N, A, LDA, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_P = INT( DUM(1) )* Compute space needed for DORGBR QCALL DORGBR( 'Q', N, N, N, A, LDA, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_Q = INT( DUM(1) )*IF( M.GE.MNTHR ) THENIF( WNTUN ) THEN** Path 1 (M much larger than N, JOBU='N')*MAXWRK = N + LWORK_DGEQRFMAXWRK = MAX( MAXWRK, 3*N + LWORK_DGEBRD )IF( WNTVO .OR. WNTVAS )$ MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_P )MAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 4*N, BDSPAC )ELSE IF( WNTUO .AND. WNTVN ) THEN** Path 2 (M much larger than N, JOBU='O', JOBVT='N')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( N*N + WRKBL, N*N + M*N + N )MINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUO .AND. WNTVAS ) THEN** Path 3 (M much larger than N, JOBU='O', JOBVT='S' or* 'A')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( N*N + WRKBL, N*N + M*N + N )MINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUS .AND. WNTVN ) THEN** Path 4 (M much larger than N, JOBU='S', JOBVT='N')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUS .AND. WNTVO ) THEN** Path 5 (M much larger than N, JOBU='S', JOBVT='O')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*N*N + WRKBLMINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUS .AND. WNTVAS ) THEN** Path 6 (M much larger than N, JOBU='S', JOBVT='S' or* 'A')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_N )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUA .AND. WNTVN ) THEN** Path 7 (M much larger than N, JOBU='A', JOBVT='N')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_M )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUA .AND. WNTVO ) THEN** Path 8 (M much larger than N, JOBU='A', JOBVT='O')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_M )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*N*N + WRKBLMINWRK = MAX( 3*N + M, BDSPAC )ELSE IF( WNTUA .AND. WNTVAS ) THEN** Path 9 (M much larger than N, JOBU='A', JOBVT='S' or* 'A')*WRKBL = N + LWORK_DGEQRFWRKBL = MAX( WRKBL, N + LWORK_DORGQR_M )WRKBL = MAX( WRKBL, 3*N + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, 3*N + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = N*N + WRKBLMINWRK = MAX( 3*N + M, BDSPAC )END IFELSE** Path 10 (M at least N, but not much larger)*CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD = INT( DUM(1) )MAXWRK = 3*N + LWORK_DGEBRDIF( WNTUS .OR. WNTUO ) THENCALL DORGBR( 'Q', M, N, N, A, LDA, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_Q = INT( DUM(1) )MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_Q )END IFIF( WNTUA ) THENCALL DORGBR( 'Q', M, M, N, A, LDA, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_Q = INT( DUM(1) )MAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_Q )END IFIF( .NOT.WNTVN ) THENMAXWRK = MAX( MAXWRK, 3*N + LWORK_DORGBR_P )END IFMAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 3*N + M, BDSPAC )END IFELSE IF( MINMN.GT.0 ) THEN** Compute space needed for DBDSQR*MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )BDSPAC = 5*M* Compute space needed for DGELQFCALL DGELQF( M, N, A, LDA, DUM(1), DUM(1), -1, IERR )LWORK_DGELQF = INT( DUM(1) )* Compute space needed for DORGLQCALL DORGLQ( N, N, M, DUM(1), N, DUM(1), DUM(1), -1, IERR )LWORK_DORGLQ_N = INT( DUM(1) )CALL DORGLQ( M, N, M, A, LDA, DUM(1), DUM(1), -1, IERR )LWORK_DORGLQ_M = INT( DUM(1) )* Compute space needed for DGEBRDCALL DGEBRD( M, M, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD = INT( DUM(1) )* Compute space needed for DORGBR PCALL DORGBR( 'P', M, M, M, A, N, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_P = INT( DUM(1) )* Compute space needed for DORGBR QCALL DORGBR( 'Q', M, M, M, A, N, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_Q = INT( DUM(1) )IF( N.GE.MNTHR ) THENIF( WNTVN ) THEN** Path 1t(N much larger than M, JOBVT='N')*MAXWRK = M + LWORK_DGELQFMAXWRK = MAX( MAXWRK, 3*M + LWORK_DGEBRD )IF( WNTUO .OR. WNTUAS )$ MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_Q )MAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 4*M, BDSPAC )ELSE IF( WNTVO .AND. WNTUN ) THEN** Path 2t(N much larger than M, JOBU='N', JOBVT='O')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( M*M + WRKBL, M*M + M*N + M )MINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVO .AND. WNTUAS ) THEN** Path 3t(N much larger than M, JOBU='S' or 'A',* JOBVT='O')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = MAX( M*M + WRKBL, M*M + M*N + M )MINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVS .AND. WNTUN ) THEN** Path 4t(N much larger than M, JOBU='N', JOBVT='S')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVS .AND. WNTUO ) THEN** Path 5t(N much larger than M, JOBU='O', JOBVT='S')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*M*M + WRKBLMINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVS .AND. WNTUAS ) THEN** Path 6t(N much larger than M, JOBU='S' or 'A',* JOBVT='S')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_M )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVA .AND. WNTUN ) THEN** Path 7t(N much larger than M, JOBU='N', JOBVT='A')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_N )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVA .AND. WNTUO ) THEN** Path 8t(N much larger than M, JOBU='O', JOBVT='A')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_N )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = 2*M*M + WRKBLMINWRK = MAX( 3*M + N, BDSPAC )ELSE IF( WNTVA .AND. WNTUAS ) THEN** Path 9t(N much larger than M, JOBU='S' or 'A',* JOBVT='A')*WRKBL = M + LWORK_DGELQFWRKBL = MAX( WRKBL, M + LWORK_DORGLQ_N )WRKBL = MAX( WRKBL, 3*M + LWORK_DGEBRD )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_P )WRKBL = MAX( WRKBL, 3*M + LWORK_DORGBR_Q )WRKBL = MAX( WRKBL, BDSPAC )MAXWRK = M*M + WRKBLMINWRK = MAX( 3*M + N, BDSPAC )END IFELSE** Path 10t(N greater than M, but not much larger)*CALL DGEBRD( M, N, A, LDA, S, DUM(1), DUM(1),$ DUM(1), DUM(1), -1, IERR )LWORK_DGEBRD = INT( DUM(1) )MAXWRK = 3*M + LWORK_DGEBRDIF( WNTVS .OR. WNTVO ) THEN* Compute space needed for DORGBR PCALL DORGBR( 'P', M, N, M, A, N, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_P = INT( DUM(1) )MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_P )END IFIF( WNTVA ) THENCALL DORGBR( 'P', N, N, M, A, N, DUM(1),$ DUM(1), -1, IERR )LWORK_DORGBR_P = INT( DUM(1) )MAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_P )END IFIF( .NOT.WNTUN ) THENMAXWRK = MAX( MAXWRK, 3*M + LWORK_DORGBR_Q )END IFMAXWRK = MAX( MAXWRK, BDSPAC )MINWRK = MAX( 3*M + N, BDSPAC )END IFEND IFMAXWRK = MAX( MAXWRK, MINWRK )WORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -13END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGESVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENRETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', M, N, A, LDA, DUM )ISCL = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENISCL = 1CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )ELSE IF( ANRM.GT.BIGNUM ) THENISCL = 1CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )END IF*IF( M.GE.N ) THEN** A has at least as many rows as columns. If A has sufficiently* more rows than columns, first reduce using the QR* decomposition (if sufficient workspace available)*IF( M.GE.MNTHR ) THEN*IF( WNTUN ) THEN** Path 1 (M much larger than N, JOBU='N')* No left singular vectors to be computed*ITAU = 1IWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Zero out below R*IF( N .GT. 1 ) THENCALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),$ LDA )END IFIE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )NCVT = 0IF( WNTVO .OR. WNTVAS ) THEN** If right singular vectors desired, generate P'.* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )NCVT = NEND IFIWORK = IE + N** Perform bidiagonal QR iteration, computing right* singular vectors of A in A if desired* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,$ DUM, 1, DUM, 1, WORK( IWORK ), INFO )** If right singular vectors desired in VT, copy them there*IF( WNTVAS )$ CALL DLACPY( 'F', N, N, A, LDA, VT, LDVT )*ELSE IF( WNTUO .AND. WNTVN ) THEN** Path 2 (M much larger than N, JOBU='O', JOBVT='N')* N left singular vectors to be overwritten on A and* no right singular vectors to be computed*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + LDA*N ) THEN** WORK(IU) is LDA by N, WORK(IR) is LDA by N*LDWRKU = LDALDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + N*N ) THEN** WORK(IU) is LDA by N, WORK(IR) is N by N*LDWRKU = LDALDWRKR = NELSE** WORK(IU) is LDWRKU by N, WORK(IR) is N by N*LDWRKU = ( LWORK-N*N-N ) / NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IR) and zero out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),$ LDWRKR )** Generate Q in A* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing R* (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR)* (Workspace: need N*N + BDSPAC)*CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,$ WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + N** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in WORK(IU) and copying to A* (Workspace: need N*N + 2*N, prefer N*N + M*N + N)*DO 10 I = 1, M, LDWRKUCHUNK = MIN( M-I+1, LDWRKU )CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),$ LDA, WORK( IR ), LDWRKR, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,$ A( I, 1 ), LDA )10 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize A* (Workspace: need 3*N + M, prefer 3*N + (M + N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing A* (Workspace: need 4*N, prefer 3*N + N*NB)*CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,$ A, LDA, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTUO .AND. WNTVAS ) THEN** Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')* N left singular vectors to be overwritten on A and* N right singular vectors to be computed in VT*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + LDA*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by N*LDWRKU = LDALDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + N ) + N*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is N by N*LDWRKU = LDALDWRKR = NELSE** WORK(IU) is LDWRKU by N and WORK(IR) is N by N*LDWRKU = ( LWORK-N*N-N ) / NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )IF( N.GT.1 )$ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ VT( 2, 1 ), LDVT )** Generate Q in A* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT, copying result to WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )** Generate left vectors bidiagonalizing R in WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing R in VT* (Workspace: need N*N + 4*N-1, prefer N*N + 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR) and computing right* singular vectors of R in VT* (Workspace: need N*N + BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,$ WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + N** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in WORK(IU) and copying to A* (Workspace: need N*N + 2*N, prefer N*N + M*N + N)*DO 20 I = 1, M, LDWRKUCHUNK = MIN( M-I+1, LDWRKU )CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),$ LDA, WORK( IR ), LDWRKR, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,$ A( I, 1 ), LDA )20 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )IF( N.GT.1 )$ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ VT( 2, 1 ), LDVT )** Generate Q in A* (Workspace: need 2*N, prefer N + N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in A by left vectors bidiagonalizing R* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,$ WORK( ITAUQ ), A, LDA, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing R in VT* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in A and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,$ A, LDA, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTUS ) THEN*IF( WNTVN ) THEN** Path 4 (M much larger than N, JOBU='S', JOBVT='N')* N left singular vectors to be computed in U and* no right singular vectors to be computed*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IR) is LDA by N*LDWRKR = LDAELSE** WORK(IR) is N by N*LDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IR), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IR+1 ), LDWRKR )** Generate Q in A* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing R in WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR)* (Workspace: need N*N + BDSPAC)*CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,$ 1, WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in A by left singular vectors of R in* WORK(IR), storing result in U* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,$ WORK( IR ), LDWRKR, ZERO, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N, prefer N + N*NB)*CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*IF( N .GT. 1 ) THENCALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ A( 2, 1 ), LDA )END IF** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left vectors bidiagonalizing R* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,$ 1, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVO ) THEN** Path 5 (M much larger than N, JOBU='S', JOBVT='O')* N left singular vectors to be computed in U and* N right singular vectors to be overwritten on A*IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA + N )*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is N by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = NELSE** WORK(IU) is N by N and WORK(IR) is N by N*LDWRKU = NIR = IU + LDWRKU*NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need 2*N*N + 2*N, prefer 2*N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )** Generate Q in A* (Workspace: need 2*N*N + 2*N, prefer 2*N*N + N + N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*N*N + 4*N,* prefer 2*N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*N*N + 4*N, prefer 2*N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*N*N + 4*N-1,* prefer 2*N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in WORK(IR)* (Workspace: need 2*N*N + BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, WORK( IU ),$ LDWRKU, DUM, 1, WORK( IWORK ), INFO )** Multiply Q in A by left singular vectors of R in* WORK(IU), storing result in U* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,$ WORK( IU ), LDWRKU, ZERO, U, LDU )** Copy right singular vectors of R to A* (Workspace: need N*N)*CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N, prefer N + N*NB)*CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*IF( N .GT. 1 ) THENCALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ A( 2, 1 ), LDA )END IF** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left vectors bidiagonalizing R* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing R in A* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,$ LDA, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVAS ) THEN** Path 6 (M much larger than N, JOBU='S', JOBVT='S'* or 'A')* N left singular vectors to be computed in U and* N right singular vectors to be computed in VT*IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IU) is LDA by N*LDWRKU = LDAELSE** WORK(IU) is N by N*LDWRKU = NEND IFITAU = IU + LDWRKU*NIWORK = ITAU + N** Compute A=Q*R* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )** Generate Q in A* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to VT* (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,$ LDVT )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need N*N + 4*N-1,* prefer N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in VT* (Workspace: need N*N + BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,$ LDVT, WORK( IU ), LDWRKU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in A by left singular vectors of R in* WORK(IU), storing result in U* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,$ WORK( IU ), LDWRKU, ZERO, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N, prefer N + N*NB)*CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )IF( N.GT.1 )$ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ VT( 2, 1 ), LDVT )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in VT* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*ELSE IF( WNTUA ) THEN*IF( WNTVN ) THEN** Path 7 (M much larger than N, JOBU='A', JOBVT='N')* M left singular vectors to be computed in U and* no right singular vectors to be computed*IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IR) is LDA by N*LDWRKR = LDAELSE** WORK(IR) is N by N*LDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Copy R to WORK(IR), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IR+1 ), LDWRKR )** Generate Q in U* (Workspace: need N*N + N + M, prefer N*N + N + M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)*CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in WORK(IR)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IR)* (Workspace: need N*N + BDSPAC)*CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,$ 1, WORK( IR ), LDWRKR, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in U by left singular vectors of R in* WORK(IR), storing result in A* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,$ WORK( IR ), LDWRKR, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N + M, prefer N + M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*IF( N .GT. 1 ) THENCALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ A( 2, 1 ), LDA )END IF** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in A* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,$ 1, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVO ) THEN** Path 8 (M much larger than N, JOBU='A', JOBVT='O')* M left singular vectors to be computed in U and* N right singular vectors to be overwritten on A*IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA + N )*N ) THEN** WORK(IU) is LDA by N and WORK(IR) is N by N*LDWRKU = LDAIR = IU + LDWRKU*NLDWRKR = NELSE** WORK(IU) is N by N and WORK(IR) is N by N*LDWRKU = NIR = IU + LDWRKU*NLDWRKR = NEND IFITAU = IR + LDWRKR*NIWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N*N + 2*N, prefer 2*N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need 2*N*N + N + M, prefer 2*N*N + N + M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*N*N + 4*N,* prefer 2*N*N+3*N+2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*N*N + 4*N, prefer 2*N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*N*N + 4*N-1,* prefer 2*N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in WORK(IR)* (Workspace: need 2*N*N + BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, WORK( IU ),$ LDWRKU, DUM, 1, WORK( IWORK ), INFO )** Multiply Q in U by left singular vectors of R in* WORK(IU), storing result in A* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,$ WORK( IU ), LDWRKU, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )** Copy right singular vectors of R from WORK(IR) to A*CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N + M, prefer N + M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Zero out below R in A*IF( N .GT. 1 ) THENCALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ A( 2, 1 ), LDA )END IF** Bidiagonalize R in A* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in A* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in A* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,$ LDA, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTVAS ) THEN** Path 9 (M much larger than N, JOBU='A', JOBVT='S'* or 'A')* M left singular vectors to be computed in U and* N right singular vectors to be computed in VT*IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*N ) THEN** WORK(IU) is LDA by N*LDWRKU = LDAELSE** WORK(IU) is N by N*LDWRKU = NEND IFITAU = IU + LDWRKU*NIWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need N*N + 2*N, prefer N*N + N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N*N + N + M, prefer N*N + N + M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R to WORK(IU), zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ WORK( IU+1 ), LDWRKU )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in WORK(IU), copying result to VT* (Workspace: need N*N + 4*N, prefer N*N + 3*N + 2*N*NB)*CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,$ LDVT )** Generate left bidiagonalizing vectors in WORK(IU)* (Workspace: need N*N + 4*N, prefer N*N + 3*N + N*NB)*CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need N*N + 4*N-1,* prefer N*N+3*N+(N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of R in WORK(IU) and computing* right singular vectors of R in VT* (Workspace: need N*N + BDSPAC)*CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,$ LDVT, WORK( IU ), LDWRKU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply Q in U by left singular vectors of R in* WORK(IU), storing result in A* (Workspace: need N*N)*CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,$ WORK( IU ), LDWRKU, ZERO, A, LDA )** Copy left singular vectors of A from A to U*CALL DLACPY( 'F', M, N, A, LDA, U, LDU )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + N** Compute A=Q*R, copying result to U* (Workspace: need 2*N, prefer N + N*NB)*CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, N, A, LDA, U, LDU )** Generate Q in U* (Workspace: need N + M, prefer N + M*NB)*CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy R from A to VT, zeroing out below it*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )IF( N.GT.1 )$ CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,$ VT( 2, 1 ), LDVT )IE = ITAUITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize R in VT* (Workspace: need 4*N, prefer 3*N + 2*N*NB)*CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply Q in U by left bidiagonalizing vectors* in VT* (Workspace: need 3*N + M, prefer 3*N + M*NB)*CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,$ WORK( ITAUQ ), U, LDU, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in VT* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + N** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*END IF*ELSE** M .LT. MNTHR** Path 10 (M at least N, but not much larger)* Reduce to bidiagonal form without QR decomposition*IE = 1ITAUQ = IE + NITAUP = ITAUQ + NIWORK = ITAUP + N** Bidiagonalize A* (Workspace: need 3*N + M, prefer 3*N + (M + N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )IF( WNTUAS ) THEN** If left singular vectors desired in U, copy result to U* and generate left bidiagonalizing vectors in U* (Workspace: need 3*N + NCU, prefer 3*N + NCU*NB)*CALL DLACPY( 'L', M, N, A, LDA, U, LDU )IF( WNTUS )$ NCU = NIF( WNTUA )$ NCU = MCALL DORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVAS ) THEN** If right singular vectors desired in VT, copy result to* VT and generate right bidiagonalizing vectors in VT* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTUO ) THEN** If left singular vectors desired in A, generate left* bidiagonalizing vectors in A* (Workspace: need 4*N, prefer 3*N + N*NB)*CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVO ) THEN** If right singular vectors desired in A, generate right* bidiagonalizing vectors in A* (Workspace: need 4*N-1, prefer 3*N + (N-1)*NB)*CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIWORK = IE + NIF( WNTUAS .OR. WNTUO )$ NRU = MIF( WNTUN )$ NRU = 0IF( WNTVAS .OR. WNTVO )$ NCVT = NIF( WNTVN )$ NCVT = 0IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,$ U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in A and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )END IF*END IF*ELSE** A has more columns than rows. If A has sufficiently more* columns than rows, first reduce using the LQ decomposition (if* sufficient workspace available)*IF( N.GE.MNTHR ) THEN*IF( WNTVN ) THEN** Path 1t(N much larger than M, JOBVT='N')* No right singular vectors to be computed*ITAU = 1IWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Zero out above L*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )IF( WNTUO .OR. WNTUAS ) THEN** If left singular vectors desired, generate Q* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIWORK = IE + MNRU = 0IF( WNTUO .OR. WNTUAS )$ NRU = M** Perform bidiagonal QR iteration, computing left singular* vectors of A in A if desired* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,$ LDA, DUM, 1, WORK( IWORK ), INFO )** If left singular vectors desired in U, copy them there*IF( WNTUAS )$ CALL DLACPY( 'F', M, M, A, LDA, U, LDU )*ELSE IF( WNTVO .AND. WNTUN ) THEN** Path 2t(N much larger than M, JOBU='N', JOBVT='O')* M right singular vectors to be overwritten on A and* no left singular vectors to be computed*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + LDA*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by M*LDWRKU = LDACHUNK = NLDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + M*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is M by M*LDWRKU = LDACHUNK = NLDWRKR = MELSE** WORK(IU) is M by CHUNK and WORK(IR) is M by M*LDWRKU = MCHUNK = ( LWORK-M*M-M ) / MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IR) and zero out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IR+LDWRKR ), LDWRKR )** Generate Q in A* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IR)* (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)*CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing L* (Workspace: need M*M + 4*M-1, prefer M*M + 3*M + (M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + M** Multiply right singular vectors of L in WORK(IR) by Q* in A, storing result in WORK(IU) and copying to A* (Workspace: need M*M + 2*M, prefer M*M + M*N + M)*DO 30 I = 1, N, CHUNKBLK = MIN( N-I+1, CHUNK )CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),$ LDWRKR, A( 1, I ), LDA, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,$ A( 1, I ), LDA )30 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize A* (Workspace: need 3*M + N, prefer 3*M + (M + N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing A* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,$ DUM, 1, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTVO .AND. WNTUAS ) THEN** Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')* M right singular vectors to be overwritten on A and* M left singular vectors to be computed in U*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + LDA*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is LDA by M*LDWRKU = LDACHUNK = NLDWRKR = LDAELSE IF( LWORK.GE.MAX( WRKBL, LDA*N + M ) + M*M ) THEN** WORK(IU) is LDA by N and WORK(IR) is M by M*LDWRKU = LDACHUNK = NLDWRKR = MELSE** WORK(IU) is M by CHUNK and WORK(IR) is M by M*LDWRKU = MCHUNK = ( LWORK-M*M-M ) / MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing about above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )** Generate Q in A* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U, copying result to WORK(IR)* (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )** Generate right vectors bidiagonalizing L in WORK(IR)* (Workspace: need M*M + 4*M-1, prefer M*M + 3*M + (M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing L in U* (Workspace: need M*M + 4*M, prefer M*M + 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in U, and computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, U, LDU, DUM, 1,$ WORK( IWORK ), INFO )IU = IE + M** Multiply right singular vectors of L in WORK(IR) by Q* in A, storing result in WORK(IU) and copying to A* (Workspace: need M*M + 2*M, prefer M*M + M*N + M))*DO 40 I = 1, N, CHUNKBLK = MIN( N-I+1, CHUNK )CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),$ LDWRKR, A( 1, I ), LDA, ZERO,$ WORK( IU ), LDWRKU )CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,$ A( 1, I ), LDA )40 CONTINUE*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )** Generate Q in A* (Workspace: need 2*M, prefer M + M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right vectors bidiagonalizing L by Q in A* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,$ WORK( ITAUP ), A, LDA, WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left vectors bidiagonalizing L in U* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,$ U, LDU, DUM, 1, WORK( IWORK ), INFO )*END IF*ELSE IF( WNTVS ) THEN*IF( WNTUN ) THEN** Path 4t(N much larger than M, JOBU='N', JOBVT='S')* M right singular vectors to be computed in VT and* no left singular vectors to be computed*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IR) is LDA by M*LDWRKR = LDAELSE** WORK(IR) is M by M*LDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IR), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IR+LDWRKR ), LDWRKR )** Generate Q in A* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IR)* (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)*CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right vectors bidiagonalizing L in* WORK(IR)* (Workspace: need M*M + 4*M, prefer M*M + 3*M + (M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IR) by* Q in A, storing result in VT* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),$ LDWRKR, A, LDA, ZERO, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy result to VT*CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right vectors bidiagonalizing L by Q in VT* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,$ LDVT, DUM, 1, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUO ) THEN** Path 5t(N much larger than M, JOBU='O', JOBVT='S')* M right singular vectors to be computed in VT and* M left singular vectors to be overwritten on A*IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is LDA by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA + M )*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is M by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = MELSE** WORK(IU) is M by M and WORK(IR) is M by M*LDWRKU = MIR = IU + LDWRKU*MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need 2*M*M + 2*M, prefer 2*M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out below it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )** Generate Q in A* (Workspace: need 2*M*M + 2*M, prefer 2*M*M + M + M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*M*M + 4*M,* prefer 2*M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*M*M + 4*M-1,* prefer 2*M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*M*M + 4*M, prefer 2*M*M + 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in WORK(IR) and computing* right singular vectors of L in WORK(IU)* (Workspace: need 2*M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, WORK( IR ),$ LDWRKR, DUM, 1, WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in A, storing result in VT* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, A, LDA, ZERO, VT, LDVT )** Copy left singular vectors of L to A* (Workspace: need M*M)*CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right vectors bidiagonalizing L by Q in VT* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors of L in A* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, compute left* singular vectors of A in A and compute right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUAS ) THEN** Path 6t(N much larger than M, JOBU='S' or 'A',* JOBVT='S')* M right singular vectors to be computed in VT and* M left singular vectors to be computed in U*IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IU) is LDA by N*LDWRKU = LDAELSE** WORK(IU) is LDA by M*LDWRKU = MEND IFITAU = IU + LDWRKU*MIWORK = ITAU + M** Compute A=L*Q* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )** Generate Q in A* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to U* (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,$ LDU )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need M*M + 4*M-1,* prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need M*M + 4*M, prefer M*M + 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in U and computing right* singular vectors of L in WORK(IU)* (Workspace: need M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, U, LDU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in A, storing result in VT* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, A, LDA, ZERO, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in U by Q* in VT* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*ELSE IF( WNTVA ) THEN*IF( WNTUN ) THEN** Path 7t(N much larger than M, JOBU='N', JOBVT='A')* N right singular vectors to be computed in VT and* no left singular vectors to be computed*IF( LWORK.GE.M*M+MAX( N + M, 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IR = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IR) is LDA by M*LDWRKR = LDAELSE** WORK(IR) is M by M*LDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Copy L to WORK(IR), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),$ LDWRKR )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IR+LDWRKR ), LDWRKR )** Generate Q in VT* (Workspace: need M*M + M + N, prefer M*M + M + N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IR)* (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)*CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate right bidiagonalizing vectors in WORK(IR)* (Workspace: need M*M + 4*M-1,* prefer M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of L in WORK(IR)* (Workspace: need M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),$ WORK( IR ), LDWRKR, DUM, 1, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IR) by* Q in VT, storing result in A* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),$ LDWRKR, VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M + N, prefer M + N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in A by Q* in VT* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,$ LDVT, DUM, 1, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUO ) THEN** Path 8t(N much larger than M, JOBU='O', JOBVT='A')* N right singular vectors to be computed in VT and* M left singular vectors to be overwritten on A*IF( LWORK.GE.2*M*M+MAX( N + M, 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+2*LDA*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is LDA by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = LDAELSE IF( LWORK.GE.WRKBL+( LDA + M )*M ) THEN** WORK(IU) is LDA by M and WORK(IR) is M by M*LDWRKU = LDAIR = IU + LDWRKU*MLDWRKR = MELSE** WORK(IU) is M by M and WORK(IR) is M by M*LDWRKU = MIR = IU + LDWRKU*MLDWRKR = MEND IFITAU = IR + LDWRKR*MIWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M*M + 2*M, prefer 2*M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need 2*M*M + M + N, prefer 2*M*M + M + N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to* WORK(IR)* (Workspace: need 2*M*M + 4*M,* prefer 2*M*M+3*M+2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,$ WORK( IR ), LDWRKR )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need 2*M*M + 4*M-1,* prefer 2*M*M+3*M+(M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in WORK(IR)* (Workspace: need 2*M*M + 4*M, prefer 2*M*M + 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,$ WORK( ITAUQ ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in WORK(IR) and computing* right singular vectors of L in WORK(IU)* (Workspace: need 2*M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, WORK( IR ),$ LDWRKR, DUM, 1, WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in VT, storing result in A* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )** Copy left singular vectors of A from WORK(IR) to A*CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,$ LDA )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M + N, prefer M + N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Zero out above L in A*CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),$ LDA )** Bidiagonalize L in A* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in A by Q* in VT* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in A* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in A and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ),$ INFO )*END IF*ELSE IF( WNTUAS ) THEN** Path 9t(N much larger than M, JOBU='S' or 'A',* JOBVT='A')* N right singular vectors to be computed in VT and* M left singular vectors to be computed in U*IF( LWORK.GE.M*M+MAX( N + M, 4*M, BDSPAC ) ) THEN** Sufficient workspace for a fast algorithm*IU = 1IF( LWORK.GE.WRKBL+LDA*M ) THEN** WORK(IU) is LDA by M*LDWRKU = LDAELSE** WORK(IU) is M by M*LDWRKU = MEND IFITAU = IU + LDWRKU*MIWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need M*M + 2*M, prefer M*M + M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M*M + M + N, prefer M*M + M + N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to WORK(IU), zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),$ LDWRKU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,$ WORK( IU+LDWRKU ), LDWRKU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in WORK(IU), copying result to U* (Workspace: need M*M + 4*M, prefer M*M + 3*M + 2*M*NB)*CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,$ WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,$ LDU )** Generate right bidiagonalizing vectors in WORK(IU)* (Workspace: need M*M + 4*M, prefer M*M + 3*M + (M-1)*NB)*CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,$ WORK( ITAUP ), WORK( IWORK ),$ LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need M*M + 4*M, prefer M*M + 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of L in U and computing right* singular vectors of L in WORK(IU)* (Workspace: need M*M + BDSPAC)*CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),$ WORK( IU ), LDWRKU, U, LDU, DUM, 1,$ WORK( IWORK ), INFO )** Multiply right singular vectors of L in WORK(IU) by* Q in VT, storing result in A* (Workspace: need M*M)*CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),$ LDWRKU, VT, LDVT, ZERO, A, LDA )** Copy right singular vectors of A from A to VT*CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )*ELSE** Insufficient workspace for a fast algorithm*ITAU = 1IWORK = ITAU + M** Compute A=L*Q, copying result to VT* (Workspace: need 2*M, prefer M + M*NB)*CALL DGELQF( M, N, A, LDA, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )** Generate Q in VT* (Workspace: need M + N, prefer M + N*NB)*CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Copy L to U, zeroing out above it*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),$ LDU )IE = ITAUITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize L in U* (Workspace: need 4*M, prefer 3*M + 2*M*NB)*CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),$ WORK( ITAUQ ), WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Multiply right bidiagonalizing vectors in U by Q* in VT* (Workspace: need 3*M + N, prefer 3*M + N*NB)*CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,$ WORK( ITAUP ), VT, LDVT,$ WORK( IWORK ), LWORK-IWORK+1, IERR )** Generate left bidiagonalizing vectors in U* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )IWORK = IE + M** Perform bidiagonal QR iteration, computing left* singular vectors of A in U and computing right* singular vectors of A in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ),$ INFO )*END IF*END IF*END IF*ELSE** N .LT. MNTHR** Path 10t(N greater than M, but not much larger)* Reduce to bidiagonal form without LQ decomposition*IE = 1ITAUQ = IE + MITAUP = ITAUQ + MIWORK = ITAUP + M** Bidiagonalize A* (Workspace: need 3*M + N, prefer 3*M + (M + N)*NB)*CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),$ WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,$ IERR )IF( WNTUAS ) THEN** If left singular vectors desired in U, copy result to U* and generate left bidiagonalizing vectors in U* (Workspace: need 4*M-1, prefer 3*M + (M-1)*NB)*CALL DLACPY( 'L', M, M, A, LDA, U, LDU )CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVAS ) THEN** If right singular vectors desired in VT, copy result to* VT and generate right bidiagonalizing vectors in VT* (Workspace: need 3*M + NRVT, prefer 3*M + NRVT*NB)*CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )IF( WNTVA )$ NRVT = NIF( WNTVS )$ NRVT = MCALL DORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTUO ) THEN** If left singular vectors desired in A, generate left* bidiagonalizing vectors in A* (Workspace: need 4*M-1, prefer 3*M + (M-1)*NB)*CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIF( WNTVO ) THEN** If right singular vectors desired in A, generate right* bidiagonalizing vectors in A* (Workspace: need 4*M, prefer 3*M + M*NB)*CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),$ WORK( IWORK ), LWORK-IWORK+1, IERR )END IFIWORK = IE + MIF( WNTUAS .OR. WNTUO )$ NRU = MIF( WNTUN )$ NRU = 0IF( WNTVAS .OR. WNTVO )$ NCVT = NIF( WNTVN )$ NCVT = 0IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in U and computing right singular* vectors in A* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,$ U, LDU, DUM, 1, WORK( IWORK ), INFO )ELSE** Perform bidiagonal QR iteration, if desired, computing* left singular vectors in A and computing right singular* vectors in VT* (Workspace: need BDSPAC)*CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,$ LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )END IF*END IF*END IF** If DBDSQR failed to converge, copy unconverged superdiagonals* to WORK( 2:MINMN )*IF( INFO.NE.0 ) THENIF( IE.GT.2 ) THENDO 50 I = 1, MINMN - 1WORK( I+1 ) = WORK( I+IE-1 )50 CONTINUEEND IFIF( IE.LT.2 ) THENDO 60 I = MINMN - 1, 1, -1WORK( I+1 ) = WORK( I+IE-1 )60 CONTINUEEND IFEND IF** Undo scaling if necessary*IF( ISCL.EQ.1 ) THENIF( ANRM.GT.BIGNUM )$ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,$ IERR )IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )$ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),$ MINMN, IERR )IF( ANRM.LT.SMLNUM )$ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,$ IERR )IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )$ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),$ MINMN, IERR )END IF** Return optimal workspace in WORK(1)*WORK( 1 ) = MAXWRK*RETURN** End of DGESVD*END*> \brief \b DGESVJ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGESVJ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesvj.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesvj.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesvj.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGESVJ( JOBA, JOBU, JOBV, M, N, A, LDA, SVA, MV, V,* LDV, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDV, LWORK, M, MV, N* CHARACTER*1 JOBA, JOBU, JOBV* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), SVA( N ), V( LDV, * ),* $ WORK( LWORK )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGESVJ computes the singular value decomposition (SVD) of a real*> M-by-N matrix A, where M >= N. The SVD of A is written as*> [++] [xx] [x0] [xx]*> A = U * SIGMA * V^t, [++] = [xx] * [ox] * [xx]*> [++] [xx]*> where SIGMA is an N-by-N diagonal matrix, U is an M-by-N orthonormal*> matrix, and V is an N-by-N orthogonal matrix. The diagonal elements*> of SIGMA are the singular values of A. The columns of U and V are the*> left and the right singular vectors of A, respectively.*> DGESVJ can sometimes compute tiny singular values and their singular vectors much*> more accurately than other SVD routines, see below under Further Details.*> \endverbatim** Arguments:* ==========**> \param[in] JOBA*> \verbatim*> JOBA is CHARACTER*1*> Specifies the structure of A.*> = 'L': The input matrix A is lower triangular;*> = 'U': The input matrix A is upper triangular;*> = 'G': The input matrix A is general M-by-N matrix, M >= N.*> \endverbatim*>*> \param[in] JOBU*> \verbatim*> JOBU is CHARACTER*1*> Specifies whether to compute the left singular vectors*> (columns of U):*> = 'U': The left singular vectors corresponding to the nonzero*> singular values are computed and returned in the leading*> columns of A. See more details in the description of A.*> The default numerical orthogonality threshold is set to*> approximately TOL=CTOL*EPS, CTOL=DSQRT(M), EPS=DLAMCH('E').*> = 'C': Analogous to JOBU='U', except that user can control the*> level of numerical orthogonality of the computed left*> singular vectors. TOL can be set to TOL = CTOL*EPS, where*> CTOL is given on input in the array WORK.*> No CTOL smaller than ONE is allowed. CTOL greater*> than 1 / EPS is meaningless. The option 'C'*> can be used if M*EPS is satisfactory orthogonality*> of the computed left singular vectors, so CTOL=M could*> save few sweeps of Jacobi rotations.*> See the descriptions of A and WORK(1).*> = 'N': The matrix U is not computed. However, see the*> description of A.*> \endverbatim*>*> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> Specifies whether to compute the right singular vectors, that*> is, the matrix V:*> = 'V' : the matrix V is computed and returned in the array V*> = 'A' : the Jacobi rotations are applied to the MV-by-N*> array V. In other words, the right singular vector*> matrix V is not computed explicitly, instead it is*> applied to an MV-by-N matrix initially stored in the*> first MV rows of V.*> = 'N' : the matrix V is not computed and the array V is not*> referenced*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the input matrix A. 1/DLAMCH('E') > M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the input matrix A.*> M >= N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit :*> If JOBU .EQ. 'U' .OR. JOBU .EQ. 'C' :*> If INFO .EQ. 0 :*> RANKA orthonormal columns of U are returned in the*> leading RANKA columns of the array A. Here RANKA <= N*> is the number of computed singular values of A that are*> above the underflow threshold DLAMCH('S'). The singular*> vectors corresponding to underflowed or zero singular*> values are not computed. The value of RANKA is returned*> in the array WORK as RANKA=NINT(WORK(2)). Also see the*> descriptions of SVA and WORK. The computed columns of U*> are mutually numerically orthogonal up to approximately*> TOL=DSQRT(M)*EPS (default); or TOL=CTOL*EPS (JOBU.EQ.'C'),*> see the description of JOBU.*> If INFO .GT. 0 :*> the procedure DGESVJ did not converge in the given number*> of iterations (sweeps). In that case, the computed*> columns of U may not be orthogonal up to TOL. The output*> U (stored in A), SIGMA (given by the computed singular*> values in SVA(1:N)) and V is still a decomposition of the*> input matrix A in the sense that the residual*> ||A-SCALE*U*SIGMA*V^T||_2 / ||A||_2 is small.*>*> If JOBU .EQ. 'N' :*> If INFO .EQ. 0 :*> Note that the left singular vectors are 'for free' in the*> one-sided Jacobi SVD algorithm. However, if only the*> singular values are needed, the level of numerical*> orthogonality of U is not an issue and iterations are*> stopped when the columns of the iterated matrix are*> numerically orthogonal up to approximately M*EPS. Thus,*> on exit, A contains the columns of U scaled with the*> corresponding singular values.*> If INFO .GT. 0 :*> the procedure DGESVJ did not converge in the given number*> of iterations (sweeps).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] SVA*> \verbatim*> SVA is DOUBLE PRECISION array, dimension (N)*> On exit :*> If INFO .EQ. 0 :*> depending on the value SCALE = WORK(1), we have:*> If SCALE .EQ. ONE :*> SVA(1:N) contains the computed singular values of A.*> During the computation SVA contains the Euclidean column*> norms of the iterated matrices in the array A.*> If SCALE .NE. ONE :*> The singular values of A are SCALE*SVA(1:N), and this*> factored representation is due to the fact that some of the*> singular values of A might underflow or overflow.*> If INFO .GT. 0 :*> the procedure DGESVJ did not converge in the given number of*> iterations (sweeps) and SCALE*SVA(1:N) may not be accurate.*> \endverbatim*>*> \param[in] MV*> \verbatim*> MV is INTEGER*> If JOBV .EQ. 'A', then the product of Jacobi rotations in DGESVJ*> is applied to the first MV rows of V. See the description of JOBV.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,N)*> If JOBV = 'V', then V contains on exit the N-by-N matrix of*> the right singular vectors;*> If JOBV = 'A', then V contains the product of the computed right*> singular vector matrix and the initial matrix in*> the array V.*> If JOBV = 'N', then V is not referenced.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V, LDV .GE. 1.*> If JOBV .EQ. 'V', then LDV .GE. max(1,N).*> If JOBV .EQ. 'A', then LDV .GE. max(1,MV) .*> \endverbatim*>*> \param[in,out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On entry :*> If JOBU .EQ. 'C' :*> WORK(1) = CTOL, where CTOL defines the threshold for convergence.*> The process stops if all columns of A are mutually*> orthogonal up to CTOL*EPS, EPS=DLAMCH('E').*> It is required that CTOL >= ONE, i.e. it is not*> allowed to force the routine to obtain orthogonality*> below EPS.*> On exit :*> WORK(1) = SCALE is the scaling factor such that SCALE*SVA(1:N)*> are the computed singular values of A.*> (See description of SVA().)*> WORK(2) = NINT(WORK(2)) is the number of the computed nonzero*> singular values.*> WORK(3) = NINT(WORK(3)) is the number of the computed singular*> values that are larger than the underflow threshold.*> WORK(4) = NINT(WORK(4)) is the number of sweeps of Jacobi*> rotations needed for numerical convergence.*> WORK(5) = max_{i.NE.j} |COS(A(:,i),A(:,j))| in the last sweep.*> This is useful information in cases when DGESVJ did*> not converge, as it can be used to estimate whether*> the output is stil useful and for post festum analysis.*> WORK(6) = the largest absolute value over all sines of the*> Jacobi rotation angles in the last sweep. It can be*> useful for a post festum analysis.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> length of WORK, WORK >= MAX(6,M+N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0 : successful exit.*> < 0 : if INFO = -i, then the i-th argument had an illegal value*> > 0 : DGESVJ did not converge in the maximal allowed number (30)*> of sweeps. The output may still be useful. See the*> description of WORK.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The orthogonal N-by-N matrix V is obtained as a product of Jacobi plane*> rotations. The rotations are implemented as fast scaled rotations of*> Anda and Park [1]. In the case of underflow of the Jacobi angle, a*> modified Jacobi transformation of Drmac [4] is used. Pivot strategy uses*> column interchanges of de Rijk [2]. The relative accuracy of the computed*> singular values and the accuracy of the computed singular vectors (in*> angle metric) is as guaranteed by the theory of Demmel and Veselic [3].*> The condition number that determines the accuracy in the full rank case*> is essentially min_{D=diag} kappa(A*D), where kappa(.) is the*> spectral condition number. The best performance of this Jacobi SVD*> procedure is achieved if used in an accelerated version of Drmac and*> Veselic [5,6], and it is the kernel routine in the SIGMA library [7].*> Some tunning parameters (marked with [TP]) are available for the*> implementer.*> The computational range for the nonzero singular values is the machine*> number interval ( UNDERFLOW , OVERFLOW ). In extreme cases, even*> denormalized singular values can be computed with the corresponding*> gradual loss of accurate digits.*> \endverbatim**> \par Contributors:* ==================*>*> \verbatim*>*> ============*>*> Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)*> \endverbatim**> \par References:* ================*>*> \verbatim*>*> [1] A. A. Anda and H. Park: Fast plane rotations with dynamic scaling.*> SIAM J. matrix Anal. Appl., Vol. 15 (1994), pp. 162-174.*> [2] P. P. M. De Rijk: A one-sided Jacobi algorithm for computing the*> singular value decomposition on a vector computer.*> SIAM J. Sci. Stat. Comp., Vol. 10 (1998), pp. 359-371.*> [3] J. Demmel and K. Veselic: Jacobi method is more accurate than QR.*> [4] Z. Drmac: Implementation of Jacobi rotations for accurate singular*> value computation in floating point arithmetic.*> SIAM J. Sci. Comp., Vol. 18 (1997), pp. 1200-1222.*> [5] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm I.*> SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1322-1342.*> LAPACK Working note 169.*> [6] Z. Drmac and K. Veselic: New fast and accurate Jacobi SVD algorithm II.*> SIAM J. Matrix Anal. Appl. Vol. 35, No. 2 (2008), pp. 1343-1362.*> LAPACK Working note 170.*> [7] Z. Drmac: SIGMA - mathematical software library for accurate SVD, PSV,*> QSVD, (H,K)-SVD computations.*> Department of Mathematics, University of Zagreb, 2008.*> \endverbatim**> \par Bugs, examples and comments:* =================================*>*> \verbatim*> ===========================*> Please report all bugs and send interesting test examples and comments to*> drmac@math.hr. Thank you.*> \endverbatim*>* =====================================================================SUBROUTINE DGESVJ( JOBA, JOBU, JOBV, M, N, A, LDA, SVA, MV, V,$ LDV, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, LDA, LDV, LWORK, M, MV, NCHARACTER*1 JOBA, JOBU, JOBV* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), SVA( N ), V( LDV, * ),$ WORK( LWORK )* ..** =====================================================================** .. Local Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0)INTEGER NSWEEPPARAMETER ( NSWEEP = 30 )* ..* .. Local Scalars ..DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,$ BIGTHETA, CS, CTOL, EPSLN, LARGE, MXAAPQ,$ MXSINJ, ROOTBIG, ROOTEPS, ROOTSFMIN, ROOTTOL,$ SKL, SFMIN, SMALL, SN, T, TEMP1, THETA,$ THSIGN, TOLINTEGER BLSKIP, EMPTSW, i, ibr, IERR, igl, IJBLSK, ir1,$ ISWROT, jbc, jgl, KBL, LKAHEAD, MVL, N2, N34,$ N4, NBL, NOTROT, p, PSKIPPED, q, ROWSKIP,$ SWBANDLOGICAL APPLV, GOSCALE, LOWER, LSVEC, NOSCALE, ROTOK,$ RSVEC, UCTOL, UPPER* ..* .. Local Arrays ..DOUBLE PRECISION FASTR( 5 )* ..* .. Intrinsic Functions ..INTRINSIC DABS, MAX, MIN, DBLE, DSIGN, DSQRT* ..* .. External Functions ..* ..* from BLASDOUBLE PRECISION DDOT, DNRM2EXTERNAL DDOT, DNRM2INTEGER IDAMAXEXTERNAL IDAMAX* from LAPACKDOUBLE PRECISION DLAMCHEXTERNAL DLAMCHLOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..* ..* from BLASEXTERNAL DAXPY, DCOPY, DROTM, DSCAL, DSWAP* from LAPACKEXTERNAL DLASCL, DLASET, DLASSQ, XERBLA*EXTERNAL DGSVJ0, DGSVJ1* ..* .. Executable Statements ..** Test the input arguments*LSVEC = LSAME( JOBU, 'U' )UCTOL = LSAME( JOBU, 'C' )RSVEC = LSAME( JOBV, 'V' )APPLV = LSAME( JOBV, 'A' )UPPER = LSAME( JOBA, 'U' )LOWER = LSAME( JOBA, 'L' )*IF( .NOT.( UPPER .OR. LOWER .OR. LSAME( JOBA, 'G' ) ) ) THENINFO = -1ELSE IF( .NOT.( LSVEC .OR. UCTOL .OR. LSAME( JOBU, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( ( N.LT.0 ) .OR. ( N.GT.M ) ) THENINFO = -5ELSE IF( LDA.LT.M ) THENINFO = -7ELSE IF( MV.LT.0 ) THENINFO = -9ELSE IF( ( RSVEC .AND. ( LDV.LT.N ) ) .OR.$ ( APPLV .AND. ( LDV.LT.MV ) ) ) THENINFO = -11ELSE IF( UCTOL .AND. ( WORK( 1 ).LE.ONE ) ) THENINFO = -12ELSE IF( LWORK.LT.MAX( M+N, 6 ) ) THENINFO = -13ELSEINFO = 0END IF** #:(IF( INFO.NE.0 ) THENCALL XERBLA( 'DGESVJ', -INFO )RETURNEND IF** #:) Quick return for void matrix*IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )RETURN** Set numerical parameters* The stopping criterion for Jacobi rotations is** max_{i<>j}|A(:,i)^T * A(:,j)|/(||A(:,i)||*||A(:,j)||) < CTOL*EPS** where EPS is the round-off and CTOL is defined as follows:*IF( UCTOL ) THEN* ... user controlledCTOL = WORK( 1 )ELSE* ... defaultIF( LSVEC .OR. RSVEC .OR. APPLV ) THENCTOL = DSQRT( DBLE( M ) )ELSECTOL = DBLE( M )END IFEND IF* ... and the machine dependent parameters are*[!] (Make sure that DLAMCH() works properly on the target machine.)*EPSLN = DLAMCH( 'Epsilon' )ROOTEPS = DSQRT( EPSLN )SFMIN = DLAMCH( 'SafeMinimum' )ROOTSFMIN = DSQRT( SFMIN )SMALL = SFMIN / EPSLNBIG = DLAMCH( 'Overflow' )* BIG = ONE / SFMINROOTBIG = ONE / ROOTSFMINLARGE = BIG / DSQRT( DBLE( M*N ) )BIGTHETA = ONE / ROOTEPS*TOL = CTOL*EPSLNROOTTOL = DSQRT( TOL )*IF( DBLE( M )*EPSLN.GE.ONE ) THENINFO = -4CALL XERBLA( 'DGESVJ', -INFO )RETURNEND IF** Initialize the right singular vector matrix.*IF( RSVEC ) THENMVL = NCALL DLASET( 'A', MVL, N, ZERO, ONE, V, LDV )ELSE IF( APPLV ) THENMVL = MVEND IFRSVEC = RSVEC .OR. APPLV** Initialize SVA( 1:N ) = ( ||A e_i||_2, i = 1:N )*(!) If necessary, scale A to protect the largest singular value* from overflow. It is possible that saving the largest singular* value destroys the information about the small ones.* This initial scaling is almost minimal in the sense that the* goal is to make sure that no column norm overflows, and that* DSQRT(N)*max_i SVA(i) does not overflow. If INFinite entries* in A are detected, the procedure returns with INFO=-6.*SKL= ONE / DSQRT( DBLE( M )*DBLE( N ) )NOSCALE = .TRUE.GOSCALE = .TRUE.*IF( LOWER ) THEN* the input matrix is M-by-N lower triangular (trapezoidal)DO 1874 p = 1, NAAPP = ZEROAAQQ = ONECALL DLASSQ( M-p+1, A( p, p ), 1, AAPP, AAQQ )IF( AAPP.GT.BIG ) THENINFO = -6CALL XERBLA( 'DGESVJ', -INFO )RETURNEND IFAAQQ = DSQRT( AAQQ )IF( ( AAPP.LT.( BIG / AAQQ ) ) .AND. NOSCALE ) THENSVA( p ) = AAPP*AAQQELSENOSCALE = .FALSE.SVA( p ) = AAPP*( AAQQ*SKL)IF( GOSCALE ) THENGOSCALE = .FALSE.DO 1873 q = 1, p - 1SVA( q ) = SVA( q )*SKL1873 CONTINUEEND IFEND IF1874 CONTINUEELSE IF( UPPER ) THEN* the input matrix is M-by-N upper triangular (trapezoidal)DO 2874 p = 1, NAAPP = ZEROAAQQ = ONECALL DLASSQ( p, A( 1, p ), 1, AAPP, AAQQ )IF( AAPP.GT.BIG ) THENINFO = -6CALL XERBLA( 'DGESVJ', -INFO )RETURNEND IFAAQQ = DSQRT( AAQQ )IF( ( AAPP.LT.( BIG / AAQQ ) ) .AND. NOSCALE ) THENSVA( p ) = AAPP*AAQQELSENOSCALE = .FALSE.SVA( p ) = AAPP*( AAQQ*SKL)IF( GOSCALE ) THENGOSCALE = .FALSE.DO 2873 q = 1, p - 1SVA( q ) = SVA( q )*SKL2873 CONTINUEEND IFEND IF2874 CONTINUEELSE* the input matrix is M-by-N general denseDO 3874 p = 1, NAAPP = ZEROAAQQ = ONECALL DLASSQ( M, A( 1, p ), 1, AAPP, AAQQ )IF( AAPP.GT.BIG ) THENINFO = -6CALL XERBLA( 'DGESVJ', -INFO )RETURNEND IFAAQQ = DSQRT( AAQQ )IF( ( AAPP.LT.( BIG / AAQQ ) ) .AND. NOSCALE ) THENSVA( p ) = AAPP*AAQQELSENOSCALE = .FALSE.SVA( p ) = AAPP*( AAQQ*SKL)IF( GOSCALE ) THENGOSCALE = .FALSE.DO 3873 q = 1, p - 1SVA( q ) = SVA( q )*SKL3873 CONTINUEEND IFEND IF3874 CONTINUEEND IF*IF( NOSCALE )SKL= ONE** Move the smaller part of the spectrum from the underflow threshold*(!) Start by determining the position of the nonzero entries of the* array SVA() relative to ( SFMIN, BIG ).*AAPP = ZEROAAQQ = BIGDO 4781 p = 1, NIF( SVA( p ).NE.ZERO )AAQQ = MIN( AAQQ, SVA( p ) )AAPP = MAX( AAPP, SVA( p ) )4781 CONTINUE** #:) Quick return for zero matrix*IF( AAPP.EQ.ZERO ) THENIF( LSVEC )CALL DLASET( 'G', M, N, ZERO, ONE, A, LDA )WORK( 1 ) = ONEWORK( 2 ) = ZEROWORK( 3 ) = ZEROWORK( 4 ) = ZEROWORK( 5 ) = ZEROWORK( 6 ) = ZERORETURNEND IF** #:) Quick return for one-column matrix*IF( N.EQ.1 ) THENIF( LSVEC )CALL DLASCL( 'G', 0, 0, SVA( 1 ), SKL, M, 1,$ A( 1, 1 ), LDA, IERR )WORK( 1 ) = ONE / SKLIF( SVA( 1 ).GE.SFMIN ) THENWORK( 2 ) = ONEELSEWORK( 2 ) = ZEROEND IFWORK( 3 ) = ZEROWORK( 4 ) = ZEROWORK( 5 ) = ZEROWORK( 6 ) = ZERORETURNEND IF** Protect small singular values from underflow, and try to* avoid underflows/overflows in computing Jacobi rotations.*SN = DSQRT( SFMIN / EPSLN )TEMP1 = DSQRT( BIG / DBLE( N ) )IF( ( AAPP.LE.SN ) .OR. ( AAQQ.GE.TEMP1 ) .OR.$ ( ( SN.LE.AAQQ ) .AND. ( AAPP.LE.TEMP1 ) ) ) THENTEMP1 = MIN( BIG, TEMP1 / AAPP )* AAQQ = AAQQ*TEMP1* AAPP = AAPP*TEMP1ELSE IF( ( AAQQ.LE.SN ) .AND. ( AAPP.LE.TEMP1 ) ) THENTEMP1 = MIN( SN / AAQQ, BIG / ( AAPP*DSQRT( DBLE( N ) ) ) )* AAQQ = AAQQ*TEMP1* AAPP = AAPP*TEMP1ELSE IF( ( AAQQ.GE.SN ) .AND. ( AAPP.GE.TEMP1 ) ) THENTEMP1 = MAX( SN / AAQQ, TEMP1 / AAPP )* AAQQ = AAQQ*TEMP1* AAPP = AAPP*TEMP1ELSE IF( ( AAQQ.LE.SN ) .AND. ( AAPP.GE.TEMP1 ) ) THENTEMP1 = MIN( SN / AAQQ, BIG / ( DSQRT( DBLE( N ) )*AAPP ) )* AAQQ = AAQQ*TEMP1* AAPP = AAPP*TEMP1ELSETEMP1 = ONEEND IF** Scale, if necessary*IF( TEMP1.NE.ONE ) THENCALL DLASCL( 'G', 0, 0, ONE, TEMP1, N, 1, SVA, N, IERR )END IFSKL= TEMP1*SKLIF( SKL.NE.ONE ) THENCALL DLASCL( JOBA, 0, 0, ONE, SKL, M, N, A, LDA, IERR )SKL= ONE / SKLEND IF** Row-cyclic Jacobi SVD algorithm with column pivoting*EMPTSW = ( N*( N-1 ) ) / 2NOTROT = 0FASTR( 1 ) = ZERO** A is represented in factored form A = A * diag(WORK), where diag(WORK)* is initialized to identity. WORK is updated during fast scaled* rotations.*DO 1868 q = 1, NWORK( q ) = ONE1868 CONTINUE**SWBAND = 3*[TP] SWBAND is a tuning parameter [TP]. It is meaningful and effective* if DGESVJ is used as a computational routine in the preconditioned* Jacobi SVD algorithm DGESVJ. For sweeps i=1:SWBAND the procedure* works on pivots inside a band-like region around the diagonal.* The boundaries are determined dynamically, based on the number of* pivots above a threshold.*KBL = MIN( 8, N )*[TP] KBL is a tuning parameter that defines the tile size in the* tiling of the p-q loops of pivot pairs. In general, an optimal* value of KBL depends on the matrix dimensions and on the* parameters of the computer's memory.*NBL = N / KBLIF( ( NBL*KBL ).NE.N )NBL = NBL + 1*BLSKIP = KBL**2*[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL.*ROWSKIP = MIN( 5, KBL )*[TP] ROWSKIP is a tuning parameter.*LKAHEAD = 1*[TP] LKAHEAD is a tuning parameter.** Quasi block transformations, using the lower (upper) triangular* structure of the input matrix. The quasi-block-cycling usually* invokes cubic convergence. Big part of this cycle is done inside* canonical subspaces of dimensions less than M.*IF( ( LOWER .OR. UPPER ) .AND. ( N.GT.MAX( 64, 4*KBL ) ) ) THEN*[TP] The number of partition levels and the actual partition are* tuning parameters.N4 = N / 4N2 = N / 2N34 = 3*N4IF( APPLV ) THENq = 0ELSEq = 1END IF*IF( LOWER ) THEN** This works very well on lower triangular matrices, in particular* in the framework of the preconditioned Jacobi SVD (xGEJSV).* The idea is simple:* [+ 0 0 0] Note that Jacobi transformations of [0 0]* [+ + 0 0] [0 0]* [+ + x 0] actually work on [x 0] [x 0]* [+ + x x] [x x]. [x x]*CALL DGSVJ0( JOBV, M-N34, N-N34, A( N34+1, N34+1 ), LDA,$ WORK( N34+1 ), SVA( N34+1 ), MVL,$ V( N34*q+1, N34+1 ), LDV, EPSLN, SFMIN, TOL,$ 2, WORK( N+1 ), LWORK-N, IERR )*CALL DGSVJ0( JOBV, M-N2, N34-N2, A( N2+1, N2+1 ), LDA,$ WORK( N2+1 ), SVA( N2+1 ), MVL,$ V( N2*q+1, N2+1 ), LDV, EPSLN, SFMIN, TOL, 2,$ WORK( N+1 ), LWORK-N, IERR )*CALL DGSVJ1( JOBV, M-N2, N-N2, N4, A( N2+1, N2+1 ), LDA,$ WORK( N2+1 ), SVA( N2+1 ), MVL,$ V( N2*q+1, N2+1 ), LDV, EPSLN, SFMIN, TOL, 1,$ WORK( N+1 ), LWORK-N, IERR )*CALL DGSVJ0( JOBV, M-N4, N2-N4, A( N4+1, N4+1 ), LDA,$ WORK( N4+1 ), SVA( N4+1 ), MVL,$ V( N4*q+1, N4+1 ), LDV, EPSLN, SFMIN, TOL, 1,$ WORK( N+1 ), LWORK-N, IERR )*CALL DGSVJ0( JOBV, M, N4, A, LDA, WORK, SVA, MVL, V, LDV,$ EPSLN, SFMIN, TOL, 1, WORK( N+1 ), LWORK-N,$ IERR )*CALL DGSVJ1( JOBV, M, N2, N4, A, LDA, WORK, SVA, MVL, V,$ LDV, EPSLN, SFMIN, TOL, 1, WORK( N+1 ),$ LWORK-N, IERR )**ELSE IF( UPPER ) THEN**CALL DGSVJ0( JOBV, N4, N4, A, LDA, WORK, SVA, MVL, V, LDV,$ EPSLN, SFMIN, TOL, 2, WORK( N+1 ), LWORK-N,$ IERR )*CALL DGSVJ0( JOBV, N2, N4, A( 1, N4+1 ), LDA, WORK( N4+1 ),$ SVA( N4+1 ), MVL, V( N4*q+1, N4+1 ), LDV,$ EPSLN, SFMIN, TOL, 1, WORK( N+1 ), LWORK-N,$ IERR )*CALL DGSVJ1( JOBV, N2, N2, N4, A, LDA, WORK, SVA, MVL, V,$ LDV, EPSLN, SFMIN, TOL, 1, WORK( N+1 ),$ LWORK-N, IERR )*CALL DGSVJ0( JOBV, N2+N4, N4, A( 1, N2+1 ), LDA,$ WORK( N2+1 ), SVA( N2+1 ), MVL,$ V( N2*q+1, N2+1 ), LDV, EPSLN, SFMIN, TOL, 1,$ WORK( N+1 ), LWORK-N, IERR )END IF*END IF** .. Row-cyclic pivot strategy with de Rijk's pivoting ..*DO 1993 i = 1, NSWEEP** .. go go go ...*MXAAPQ = ZEROMXSINJ = ZEROISWROT = 0*NOTROT = 0PSKIPPED = 0** Each sweep is unrolled using KBL-by-KBL tiles over the pivot pairs* 1 <= p < q <= N. This is the first step toward a blocked implementation* of the rotations. New implementation, based on block transformations,* is under development.*DO 2000 ibr = 1, NBL*igl = ( ibr-1 )*KBL + 1*DO 1002 ir1 = 0, MIN( LKAHEAD, NBL-ibr )*igl = igl + ir1*KBL*DO 2001 p = igl, MIN( igl+KBL-1, N-1 )** .. de Rijk's pivoting*q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1IF( p.NE.q ) THENCALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1,$ V( 1, q ), 1 )TEMP1 = SVA( p )SVA( p ) = SVA( q )SVA( q ) = TEMP1TEMP1 = WORK( p )WORK( p ) = WORK( q )WORK( q ) = TEMP1END IF*IF( ir1.EQ.0 ) THEN** Column norms are periodically updated by explicit* norm computation.* Caveat:* Unfortunately, some BLAS implementations compute DNRM2(M,A(1,p),1)* as DSQRT(DDOT(M,A(1,p),1,A(1,p),1)), which may cause the result to* overflow for ||A(:,p)||_2 > DSQRT(overflow_threshold), and to* underflow for ||A(:,p)||_2 < DSQRT(underflow_threshold).* Hence, DNRM2 cannot be trusted, not even in the case when* the true norm is far from the under(over)flow boundaries.* If properly implemented DNRM2 is available, the IF-THEN-ELSE* below should read "AAPP = DNRM2( M, A(1,p), 1 ) * WORK(p)".*IF( ( SVA( p ).LT.ROOTBIG ) .AND.$ ( SVA( p ).GT.ROOTSFMIN ) ) THENSVA( p ) = DNRM2( M, A( 1, p ), 1 )*WORK( p )ELSETEMP1 = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, TEMP1, AAPP )SVA( p ) = TEMP1*DSQRT( AAPP )*WORK( p )END IFAAPP = SVA( p )ELSEAAPP = SVA( p )END IF*IF( AAPP.GT.ZERO ) THEN*PSKIPPED = 0*DO 2002 q = p + 1, MIN( igl+KBL-1, N )*AAQQ = SVA( q )*IF( AAQQ.GT.ZERO ) THEN*AAPP0 = AAPPIF( AAQQ.GE.ONE ) THENROTOK = ( SMALL*AAPP ).LE.AAQQIF( AAPP.LT.( BIG / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*WORK( p )*WORK( q ) /$ AAQQ ) / AAPPELSECALL DCOPY( M, A( 1, p ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAPP,$ WORK( p ), M, 1,$ WORK( N+1 ), LDA, IERR )AAPQ = DDOT( M, WORK( N+1 ), 1,$ A( 1, q ), 1 )*WORK( q ) / AAQQEND IFELSEROTOK = AAPP.LE.( AAQQ / SMALL )IF( AAPP.GT.( SMALL / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*WORK( p )*WORK( q ) /$ AAQQ ) / AAPPELSECALL DCOPY( M, A( 1, q ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAQQ,$ WORK( q ), M, 1,$ WORK( N+1 ), LDA, IERR )AAPQ = DDOT( M, WORK( N+1 ), 1,$ A( 1, p ), 1 )*WORK( p ) / AAPPEND IFEND IF*MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )** TO rotate or NOT to rotate, THAT is the question ...*IF( DABS( AAPQ ).GT.TOL ) THEN** .. rotate*[RTD] ROTATED = ROTATED + ONE*IF( ir1.EQ.0 ) THENNOTROT = 0PSKIPPED = 0ISWROT = ISWROT + 1END IF*IF( ROTOK ) THEN*AQOAP = AAQQ / AAPPAPOAQ = AAPP / AAQQTHETA = -HALF*DABS(AQOAP-APOAQ)/AAPQ*IF( DABS( THETA ).GT.BIGTHETA ) THEN*T = HALF / THETAFASTR( 3 ) = T*WORK( p ) / WORK( q )FASTR( 4 ) = -T*WORK( q ) /$ WORK( p )CALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1, FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1,$ V( 1, q ), 1,$ FASTR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )MXSINJ = MAX( MXSINJ, DABS( T ) )*ELSE** .. choose correct signum for THETA and rotate*THSIGN = -DSIGN( ONE, AAPQ )T = ONE / ( THETA+THSIGN*$ DSQRT( ONE+THETA*THETA ) )CS = DSQRT( ONE / ( ONE+T*T ) )SN = T*CS*MXSINJ = MAX( MXSINJ, DABS( SN ) )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )*APOAQ = WORK( p ) / WORK( q )AQOAP = WORK( q ) / WORK( p )IF( WORK( p ).GE.ONE ) THENIF( WORK( q ).GE.ONE ) THENFASTR( 3 ) = T*APOAQFASTR( 4 ) = -T*AQOAPWORK( p ) = WORK( p )*CSWORK( q ) = WORK( q )*CSCALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1,$ FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1, V( 1, q ),$ 1, FASTR )ELSECALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )WORK( p ) = WORK( p )*CSWORK( q ) = WORK( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL, -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFEND IFELSEIF( WORK( q ).GE.ONE ) THENCALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M, -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )WORK( p ) = WORK( p ) / CSWORK( q ) = WORK( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL, T*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFELSEIF( WORK( p ).GE.WORK( q ) )$ THENCALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )WORK( p ) = WORK( p )*CSWORK( q ) = WORK( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL,$ -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFELSECALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M,$ -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )WORK( p ) = WORK( p ) / CSWORK( q ) = WORK( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL,$ T*APOAQ, V( 1, p ),$ 1, V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFEND IFEND IFEND IFEND IF*ELSE* .. have to use modified Gram-Schmidt like transformationCALL DCOPY( M, A( 1, p ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAPP, ONE, M,$ 1, WORK( N+1 ), LDA,$ IERR )CALL DLASCL( 'G', 0, 0, AAQQ, ONE, M,$ 1, A( 1, q ), LDA, IERR )TEMP1 = -AAPQ*WORK( p ) / WORK( q )CALL DAXPY( M, TEMP1, WORK( N+1 ), 1,$ A( 1, q ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAQQ, M,$ 1, A( 1, q ), LDA, IERR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )END IF* END IF ROTOK THEN ... ELSE** In the case of cancellation in updating SVA(q), SVA(p)* recompute SVA(q), SVA(p).*IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )$ THENIF( ( AAQQ.LT.ROOTBIG ) .AND.$ ( AAQQ.GT.ROOTSFMIN ) ) THENSVA( q ) = DNRM2( M, A( 1, q ), 1 )*$ WORK( q )ELSET = ZEROAAQQ = ONECALL DLASSQ( M, A( 1, q ), 1, T,$ AAQQ )SVA( q ) = T*DSQRT( AAQQ )*WORK( q )END IFEND IFIF( ( AAPP / AAPP0 ).LE.ROOTEPS ) THENIF( ( AAPP.LT.ROOTBIG ) .AND.$ ( AAPP.GT.ROOTSFMIN ) ) THENAAPP = DNRM2( M, A( 1, p ), 1 )*$ WORK( p )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, T,$ AAPP )AAPP = T*DSQRT( AAPP )*WORK( p )END IFSVA( p ) = AAPPEND IF*ELSE* A(:,p) and A(:,q) already numerically orthogonalIF( ir1.EQ.0 )NOTROT = NOTROT + 1*[RTD] SKIPPED = SKIPPED + 1PSKIPPED = PSKIPPED + 1END IFELSE* A(:,q) is zero columnIF( ir1.EQ.0 )NOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1END IF*IF( ( i.LE.SWBAND ) .AND.$ ( PSKIPPED.GT.ROWSKIP ) ) THENIF( ir1.EQ.0 )AAPP = -AAPPNOTROT = 0GO TO 2103END IF*2002 CONTINUE* END q-LOOP*2103 CONTINUE* bailed out of q-loop*SVA( p ) = AAPP*ELSESVA( p ) = AAPPIF( ( ir1.EQ.0 ) .AND. ( AAPP.EQ.ZERO ) )$ NOTROT = NOTROT + MIN( igl+KBL-1, N ) - pEND IF*2001 CONTINUE* end of the p-loop* end of doing the block ( ibr, ibr )1002 CONTINUE* end of ir1-loop** ... go to the off diagonal blocks*igl = ( ibr-1 )*KBL + 1*DO 2010 jbc = ibr + 1, NBL*jgl = ( jbc-1 )*KBL + 1** doing the block at ( ibr, jbc )*IJBLSK = 0DO 2100 p = igl, MIN( igl+KBL-1, N )*AAPP = SVA( p )IF( AAPP.GT.ZERO ) THEN*PSKIPPED = 0*DO 2200 q = jgl, MIN( jgl+KBL-1, N )*AAQQ = SVA( q )IF( AAQQ.GT.ZERO ) THENAAPP0 = AAPP** .. M x 2 Jacobi SVD ..** Safe Gram matrix computation*IF( AAQQ.GE.ONE ) THENIF( AAPP.GE.AAQQ ) THENROTOK = ( SMALL*AAPP ).LE.AAQQELSEROTOK = ( SMALL*AAQQ ).LE.AAPPEND IFIF( AAPP.LT.( BIG / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*WORK( p )*WORK( q ) /$ AAQQ ) / AAPPELSECALL DCOPY( M, A( 1, p ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAPP,$ WORK( p ), M, 1,$ WORK( N+1 ), LDA, IERR )AAPQ = DDOT( M, WORK( N+1 ), 1,$ A( 1, q ), 1 )*WORK( q ) / AAQQEND IFELSEIF( AAPP.GE.AAQQ ) THENROTOK = AAPP.LE.( AAQQ / SMALL )ELSEROTOK = AAQQ.LE.( AAPP / SMALL )END IFIF( AAPP.GT.( SMALL / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*WORK( p )*WORK( q ) /$ AAQQ ) / AAPPELSECALL DCOPY( M, A( 1, q ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAQQ,$ WORK( q ), M, 1,$ WORK( N+1 ), LDA, IERR )AAPQ = DDOT( M, WORK( N+1 ), 1,$ A( 1, p ), 1 )*WORK( p ) / AAPPEND IFEND IF*MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )** TO rotate or NOT to rotate, THAT is the question ...*IF( DABS( AAPQ ).GT.TOL ) THENNOTROT = 0*[RTD] ROTATED = ROTATED + 1PSKIPPED = 0ISWROT = ISWROT + 1*IF( ROTOK ) THEN*AQOAP = AAQQ / AAPPAPOAQ = AAPP / AAQQTHETA = -HALF*DABS(AQOAP-APOAQ)/AAPQIF( AAQQ.GT.AAPP0 )THETA = -THETA*IF( DABS( THETA ).GT.BIGTHETA ) THENT = HALF / THETAFASTR( 3 ) = T*WORK( p ) / WORK( q )FASTR( 4 ) = -T*WORK( q ) /$ WORK( p )CALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1, FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1,$ V( 1, q ), 1,$ FASTR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )MXSINJ = MAX( MXSINJ, DABS( T ) )ELSE** .. choose correct signum for THETA and rotate*THSIGN = -DSIGN( ONE, AAPQ )IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGNT = ONE / ( THETA+THSIGN*$ DSQRT( ONE+THETA*THETA ) )CS = DSQRT( ONE / ( ONE+T*T ) )SN = T*CSMXSINJ = MAX( MXSINJ, DABS( SN ) )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )*APOAQ = WORK( p ) / WORK( q )AQOAP = WORK( q ) / WORK( p )IF( WORK( p ).GE.ONE ) THEN*IF( WORK( q ).GE.ONE ) THENFASTR( 3 ) = T*APOAQFASTR( 4 ) = -T*AQOAPWORK( p ) = WORK( p )*CSWORK( q ) = WORK( q )*CSCALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1,$ FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1, V( 1, q ),$ 1, FASTR )ELSECALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )IF( RSVEC ) THENCALL DAXPY( MVL, -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFWORK( p ) = WORK( p )*CSWORK( q ) = WORK( q ) / CSEND IFELSEIF( WORK( q ).GE.ONE ) THENCALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M, -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )IF( RSVEC ) THENCALL DAXPY( MVL, T*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFWORK( p ) = WORK( p ) / CSWORK( q ) = WORK( q )*CSELSEIF( WORK( p ).GE.WORK( q ) )$ THENCALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )WORK( p ) = WORK( p )*CSWORK( q ) = WORK( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL,$ -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFELSECALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M,$ -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )WORK( p ) = WORK( p ) / CSWORK( q ) = WORK( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL,$ T*APOAQ, V( 1, p ),$ 1, V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFEND IFEND IFEND IFEND IF*ELSEIF( AAPP.GT.AAQQ ) THENCALL DCOPY( M, A( 1, p ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAPP, ONE,$ M, 1, WORK( N+1 ), LDA,$ IERR )CALL DLASCL( 'G', 0, 0, AAQQ, ONE,$ M, 1, A( 1, q ), LDA,$ IERR )TEMP1 = -AAPQ*WORK( p ) / WORK( q )CALL DAXPY( M, TEMP1, WORK( N+1 ),$ 1, A( 1, q ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAQQ,$ M, 1, A( 1, q ), LDA,$ IERR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )ELSECALL DCOPY( M, A( 1, q ), 1,$ WORK( N+1 ), 1 )CALL DLASCL( 'G', 0, 0, AAQQ, ONE,$ M, 1, WORK( N+1 ), LDA,$ IERR )CALL DLASCL( 'G', 0, 0, AAPP, ONE,$ M, 1, A( 1, p ), LDA,$ IERR )TEMP1 = -AAPQ*WORK( q ) / WORK( p )CALL DAXPY( M, TEMP1, WORK( N+1 ),$ 1, A( 1, p ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAPP,$ M, 1, A( 1, p ), LDA,$ IERR )SVA( p ) = AAPP*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )END IFEND IF* END IF ROTOK THEN ... ELSE** In the case of cancellation in updating SVA(q)* .. recompute SVA(q)IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )$ THENIF( ( AAQQ.LT.ROOTBIG ) .AND.$ ( AAQQ.GT.ROOTSFMIN ) ) THENSVA( q ) = DNRM2( M, A( 1, q ), 1 )*$ WORK( q )ELSET = ZEROAAQQ = ONECALL DLASSQ( M, A( 1, q ), 1, T,$ AAQQ )SVA( q ) = T*DSQRT( AAQQ )*WORK( q )END IFEND IFIF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THENIF( ( AAPP.LT.ROOTBIG ) .AND.$ ( AAPP.GT.ROOTSFMIN ) ) THENAAPP = DNRM2( M, A( 1, p ), 1 )*$ WORK( p )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, T,$ AAPP )AAPP = T*DSQRT( AAPP )*WORK( p )END IFSVA( p ) = AAPPEND IF* end of OK rotationELSENOTROT = NOTROT + 1*[RTD] SKIPPED = SKIPPED + 1PSKIPPED = PSKIPPED + 1IJBLSK = IJBLSK + 1END IFELSENOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1IJBLSK = IJBLSK + 1END IF*IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) )$ THENSVA( p ) = AAPPNOTROT = 0GO TO 2011END IFIF( ( i.LE.SWBAND ) .AND.$ ( PSKIPPED.GT.ROWSKIP ) ) THENAAPP = -AAPPNOTROT = 0GO TO 2203END IF*2200 CONTINUE* end of the q-loop2203 CONTINUE*SVA( p ) = AAPP*ELSE*IF( AAPP.EQ.ZERO )NOTROT = NOTROT +$ MIN( jgl+KBL-1, N ) - jgl + 1IF( AAPP.LT.ZERO )NOTROT = 0*END IF*2100 CONTINUE* end of the p-loop2010 CONTINUE* end of the jbc-loop2011 CONTINUE*2011 bailed out of the jbc-loopDO 2012 p = igl, MIN( igl+KBL-1, N )SVA( p ) = DABS( SVA( p ) )2012 CONTINUE***2000 CONTINUE*2000 :: end of the ibr-loop** .. update SVA(N)IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) )$ THENSVA( N ) = DNRM2( M, A( 1, N ), 1 )*WORK( N )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, N ), 1, T, AAPP )SVA( N ) = T*DSQRT( AAPP )*WORK( N )END IF** Additional steering devices*IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.$ ( ISWROT.LE.N ) ) )SWBAND = i*IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DSQRT( DBLE( N ) )*$ TOL ) .AND. ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THENGO TO 1994END IF*IF( NOTROT.GE.EMPTSW )GO TO 1994*1993 CONTINUE* end i=1:NSWEEP loop** #:( Reaching this point means that the procedure has not converged.INFO = NSWEEP - 1GO TO 1995*1994 CONTINUE* #:) Reaching this point means numerical convergence after the i-th* sweep.*INFO = 0* #:) INFO = 0 confirms successful iterations.1995 CONTINUE** Sort the singular values and find how many are above* the underflow threshold.*N2 = 0N4 = 0DO 5991 p = 1, N - 1q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1IF( p.NE.q ) THENTEMP1 = SVA( p )SVA( p ) = SVA( q )SVA( q ) = TEMP1TEMP1 = WORK( p )WORK( p ) = WORK( q )WORK( q ) = TEMP1CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )END IFIF( SVA( p ).NE.ZERO ) THENN4 = N4 + 1IF( SVA( p )*SKL.GT.SFMIN )N2 = N2 + 1END IF5991 CONTINUEIF( SVA( N ).NE.ZERO ) THENN4 = N4 + 1IF( SVA( N )*SKL.GT.SFMIN )N2 = N2 + 1END IF** Normalize the left singular vectors.*IF( LSVEC .OR. UCTOL ) THENDO 1998 p = 1, N2CALL DSCAL( M, WORK( p ) / SVA( p ), A( 1, p ), 1 )1998 CONTINUEEND IF** Scale the product of Jacobi rotations (assemble the fast rotations).*IF( RSVEC ) THENIF( APPLV ) THENDO 2398 p = 1, NCALL DSCAL( MVL, WORK( p ), V( 1, p ), 1 )2398 CONTINUEELSEDO 2399 p = 1, NTEMP1 = ONE / DNRM2( MVL, V( 1, p ), 1 )CALL DSCAL( MVL, TEMP1, V( 1, p ), 1 )2399 CONTINUEEND IFEND IF** Undo scaling, if necessary (and possible).IF( ( ( SKL.GT.ONE ) .AND. ( SVA( 1 ).LT.( BIG / SKL) ) )$ .OR. ( ( SKL.LT.ONE ) .AND. ( SVA( MAX( N2, 1 ) ) .GT.$ ( SFMIN / SKL) ) ) ) THENDO 2400 p = 1, NSVA( P ) = SKL*SVA( P )2400 CONTINUESKL= ONEEND IF*WORK( 1 ) = SKL* The singular values of A are SKL*SVA(1:N). If SKL.NE.ONE* then some of the singular values may overflow or underflow and* the spectrum is given in this factored representation.*WORK( 2 ) = DBLE( N4 )* N4 is the number of computed nonzero singular values of A.*WORK( 3 ) = DBLE( N2 )* N2 is the number of singular values of A greater than SFMIN.* If N2<N, SVA(N2:N) contains ZEROS and/or denormalized numbers* that may carry some information.*WORK( 4 ) = DBLE( i )* i is the index of the last sweep before declaring convergence.*WORK( 5 ) = MXAAPQ* MXAAPQ is the largest absolute value of scaled pivots in the* last sweep*WORK( 6 ) = MXSINJ* MXSINJ is the largest absolute value of the sines of Jacobi angles* in the last sweep*RETURN* ..* .. END OF DGESVJ* ..END*> \brief <b> DGESVX computes the solution to system of linear equations A * X = B for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGESVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGESVX( FACT, TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV,* EQUED, R, C, B, LDB, X, LDX, RCOND, FERR, BERR,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER EQUED, FACT, TRANS* INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),* $ BERR( * ), C( * ), FERR( * ), R( * ),* $ WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGESVX uses the LU factorization to compute the solution to a real*> system of linear equations*> A * X = B,*> where A is an N-by-N matrix and X and B are N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'E', real scaling factors are computed to equilibrate*> the system:*> TRANS = 'N': diag(R)*A*diag(C) *inv(diag(C))*X = diag(R)*B*> TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B*> TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B*> Whether or not the system will be equilibrated depends on the*> scaling of the matrix A, but if equilibration is used, A is*> overwritten by diag(R)*A*diag(C) and B by diag(R)*B (if TRANS='N')*> or diag(C)*B (if TRANS = 'T' or 'C').*>*> 2. If FACT = 'N' or 'E', the LU decomposition is used to factor the*> matrix A (after equilibration if FACT = 'E') as*> A = P * L * U,*> where P is a permutation matrix, L is a unit lower triangular*> matrix, and U is upper triangular.*>*> 3. If some U(i,i)=0, so that U is exactly singular, then the routine*> returns with INFO = i. Otherwise, the factored form of A is used*> to estimate the condition number of the matrix A. If the*> reciprocal of the condition number is less than machine precision,*> INFO = N+1 is returned as a warning, but the routine still goes on*> to solve for X and compute error bounds as described below.*>*> 4. The system of equations is solved for X using the factored form*> of A.*>*> 5. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*>*> 6. If equilibration was used, the matrix X is premultiplied by*> diag(C) (if TRANS = 'N') or diag(R) (if TRANS = 'T' or 'C') so*> that it solves the original system before equilibration.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of the matrix A is*> supplied on entry, and if not, whether the matrix A should be*> equilibrated before it is factored.*> = 'F': On entry, AF and IPIV contain the factored form of A.*> If EQUED is not 'N', the matrix A has been*> equilibrated with scaling factors given by R and C.*> A, AF, and IPIV are not modified.*> = 'N': The matrix A will be copied to AF and factored.*> = 'E': The matrix A will be equilibrated if necessary, then*> copied to AF and factored.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the N-by-N matrix A. If FACT = 'F' and EQUED is*> not 'N', then A must have been equilibrated by the scaling*> factors in R and/or C. A is not modified if FACT = 'F' or*> 'N', or if FACT = 'E' and EQUED = 'N' on exit.*>*> On exit, if EQUED .ne. 'N', A is scaled as follows:*> EQUED = 'R': A := diag(R) * A*> EQUED = 'C': A := A * diag(C)*> EQUED = 'B': A := diag(R) * A * diag(C).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] AF*> \verbatim*> AF is DOUBLE PRECISION array, dimension (LDAF,N)*> If FACT = 'F', then AF is an input argument and on entry*> contains the factors L and U from the factorization*> A = P*L*U as computed by DGETRF. If EQUED .ne. 'N', then*> AF is the factored form of the equilibrated matrix A.*>*> If FACT = 'N', then AF is an output argument and on exit*> returns the factors L and U from the factorization A = P*L*U*> of the original matrix A.*>*> If FACT = 'E', then AF is an output argument and on exit*> returns the factors L and U from the factorization A = P*L*U*> of the equilibrated matrix A (see the description of A for*> the form of the equilibrated matrix).*> \endverbatim*>*> \param[in] LDAF*> \verbatim*> LDAF is INTEGER*> The leading dimension of the array AF. LDAF >= max(1,N).*> \endverbatim*>*> \param[in,out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> If FACT = 'F', then IPIV is an input argument and on entry*> contains the pivot indices from the factorization A = P*L*U*> as computed by DGETRF; row i of the matrix was interchanged*> with row IPIV(i).*>*> If FACT = 'N', then IPIV is an output argument and on exit*> contains the pivot indices from the factorization A = P*L*U*> of the original matrix A.*>*> If FACT = 'E', then IPIV is an output argument and on exit*> contains the pivot indices from the factorization A = P*L*U*> of the equilibrated matrix A.*> \endverbatim*>*> \param[in,out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration (always true if FACT = 'N').*> = 'R': Row equilibration, i.e., A has been premultiplied by*> diag(R).*> = 'C': Column equilibration, i.e., A has been postmultiplied*> by diag(C).*> = 'B': Both row and column equilibration, i.e., A has been*> replaced by diag(R) * A * diag(C).*> EQUED is an input argument if FACT = 'F'; otherwise, it is an*> output argument.*> \endverbatim*>*> \param[in,out] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (N)*> The row scale factors for A. If EQUED = 'R' or 'B', A is*> multiplied on the left by diag(R); if EQUED = 'N' or 'C', R*> is not accessed. R is an input argument if FACT = 'F';*> otherwise, R is an output argument. If FACT = 'F' and*> EQUED = 'R' or 'B', each element of R must be positive.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> The column scale factors for A. If EQUED = 'C' or 'B', A is*> multiplied on the right by diag(C); if EQUED = 'N' or 'R', C*> is not accessed. C is an input argument if FACT = 'F';*> otherwise, C is an output argument. If FACT = 'F' and*> EQUED = 'C' or 'B', each element of C must be positive.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit,*> if EQUED = 'N', B is not modified;*> if TRANS = 'N' and EQUED = 'R' or 'B', B is overwritten by*> diag(R)*B;*> if TRANS = 'T' or 'C' and EQUED = 'C' or 'B', B is*> overwritten by diag(C)*B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X*> to the original system of equations. Note that A and B are*> modified on exit if EQUED .ne. 'N', and the solution to the*> equilibrated system is inv(diag(C))*X if TRANS = 'N' and*> EQUED = 'C' or 'B', or inv(diag(R))*X if TRANS = 'T' or 'C'*> and EQUED = 'R' or 'B'.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A after equilibration (if done). If RCOND is less than the*> machine precision (in particular, if RCOND = 0), the matrix*> is singular to working precision. This condition is*> indicated by a return code of INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> On exit, WORK(1) contains the reciprocal pivot growth*> factor norm(A)/norm(U). The "max absolute element" norm is*> used. If WORK(1) is much less than 1, then the stability*> of the LU factorization of the (equilibrated) matrix A*> could be poor. This also means that the solution X, condition*> estimator RCOND, and forward error bound FERR could be*> unreliable. If factorization fails with 0<INFO<=N, then*> WORK(1) contains the reciprocal pivot growth factor for the*> leading INFO columns of A.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: U(i,i) is exactly zero. The factorization has*> been completed, but the factor U is exactly*> singular, so the solution and error bounds*> could not be computed. RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleGEsolve** =====================================================================SUBROUTINE DGESVX( FACT, TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV,$ EQUED, R, C, B, LDB, X, LDX, RCOND, FERR, BERR,$ WORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER EQUED, FACT, TRANSINTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), C( * ), FERR( * ), R( * ),$ WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL COLEQU, EQUIL, NOFACT, NOTRAN, ROWEQUCHARACTER NORMINTEGER I, INFEQU, JDOUBLE PRECISION AMAX, ANORM, BIGNUM, COLCND, RCMAX, RCMIN,$ ROWCND, RPVGRW, SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANGE, DLANTREXTERNAL LSAME, DLAMCH, DLANGE, DLANTR* ..* .. External Subroutines ..EXTERNAL DGECON, DGEEQU, DGERFS, DGETRF, DGETRS, DLACPY,$ DLAQGE, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )EQUIL = LSAME( FACT, 'E' )NOTRAN = LSAME( TRANS, 'N' )IF( NOFACT .OR. EQUIL ) THENEQUED = 'N'ROWEQU = .FALSE.COLEQU = .FALSE.ELSEROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )SMLNUM = DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMEND IF** Test the input parameters.*IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )$ THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.$ ( ROWEQU .OR. COLEQU .OR. LSAME( EQUED, 'N' ) ) ) THENINFO = -10ELSEIF( ROWEQU ) THENRCMIN = BIGNUMRCMAX = ZERODO 10 J = 1, NRCMIN = MIN( RCMIN, R( J ) )RCMAX = MAX( RCMAX, R( J ) )10 CONTINUEIF( RCMIN.LE.ZERO ) THENINFO = -11ELSE IF( N.GT.0 ) THENROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )ELSEROWCND = ONEEND IFEND IFIF( COLEQU .AND. INFO.EQ.0 ) THENRCMIN = BIGNUMRCMAX = ZERODO 20 J = 1, NRCMIN = MIN( RCMIN, C( J ) )RCMAX = MAX( RCMAX, C( J ) )20 CONTINUEIF( RCMIN.LE.ZERO ) THENINFO = -12ELSE IF( N.GT.0 ) THENCOLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )ELSECOLCND = ONEEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDB.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -16END IFEND IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGESVX', -INFO )RETURNEND IF*IF( EQUIL ) THEN** Compute row and column scalings to equilibrate the matrix A.*CALL DGEEQU( N, N, A, LDA, R, C, ROWCND, COLCND, AMAX, INFEQU )IF( INFEQU.EQ.0 ) THEN** Equilibrate the matrix.*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 IFEND IF** Scale the right hand side.*IF( NOTRAN ) THENIF( ROWEQU ) THENDO 40 J = 1, NRHSDO 30 I = 1, NB( I, J ) = R( I )*B( I, J )30 CONTINUE40 CONTINUEEND IFELSE IF( COLEQU ) THENDO 60 J = 1, NRHSDO 50 I = 1, NB( I, J ) = C( I )*B( I, J )50 CONTINUE60 CONTINUEEND IF*IF( NOFACT .OR. EQUIL ) THEN** Compute the LU factorization of A.*CALL DLACPY( 'Full', N, N, A, LDA, AF, LDAF )CALL DGETRF( N, N, AF, LDAF, IPIV, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 ) THEN** Compute the reciprocal pivot growth factor of the* leading rank-deficient INFO columns of A.*RPVGRW = DLANTR( 'M', 'U', 'N', INFO, INFO, AF, LDAF,$ WORK )IF( RPVGRW.EQ.ZERO ) THENRPVGRW = ONEELSERPVGRW = DLANGE( 'M', N, INFO, A, LDA, WORK ) / RPVGRWEND IFWORK( 1 ) = RPVGRWRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A and the* reciprocal pivot growth factor RPVGRW.*IF( NOTRAN ) THENNORM = '1'ELSENORM = 'I'END IFANORM = DLANGE( NORM, N, N, A, LDA, WORK )RPVGRW = DLANTR( 'M', 'U', 'N', N, N, AF, LDAF, WORK )IF( RPVGRW.EQ.ZERO ) THENRPVGRW = ONEELSERPVGRW = DLANGE( 'M', N, N, A, LDA, WORK ) / RPVGRWEND IF** Compute the reciprocal of the condition number of A.*CALL DGECON( NORM, N, AF, LDAF, ANORM, RCOND, WORK, IWORK, INFO )** Compute the solution matrix X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DGETRS( TRANS, N, NRHS, AF, LDAF, IPIV, X, LDX, INFO )** Use iterative refinement to improve the computed solution and* compute error bounds and backward error estimates for it.*CALL DGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB, X,$ LDX, FERR, BERR, WORK, IWORK, INFO )** Transform the solution matrix X to a solution of the original* system.*IF( NOTRAN ) THENIF( COLEQU ) THENDO 80 J = 1, NRHSDO 70 I = 1, NX( I, J ) = C( I )*X( I, J )70 CONTINUE80 CONTINUEDO 90 J = 1, NRHSFERR( J ) = FERR( J ) / COLCND90 CONTINUEEND IFELSE IF( ROWEQU ) THENDO 110 J = 1, NRHSDO 100 I = 1, NX( I, J ) = R( I )*X( I, J )100 CONTINUE110 CONTINUEDO 120 J = 1, NRHSFERR( J ) = FERR( J ) / ROWCND120 CONTINUEEND IF*WORK( 1 ) = RPVGRW** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1RETURN** End of DGESVX*END*> \brief \b DGETC2 computes the LU factorization with complete pivoting of the general n-by-n matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGETC2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgetc2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgetc2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgetc2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGETC2( N, A, LDA, IPIV, JPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* INTEGER IPIV( * ), JPIV( * )* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGETC2 computes an LU factorization with complete pivoting of the*> n-by-n matrix A. The factorization has the form A = P * L * U * Q,*> where P and Q are permutation matrices, L is lower triangular with*> unit diagonal elements and U is upper triangular.*>*> This is the Level 2 BLAS algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the n-by-n matrix A to be factored.*> On exit, the factors L and U from the factorization*> A = P*L*U*Q; the unit diagonal elements of L are not stored.*> If U(k, k) appears to be less than SMIN, U(k, k) is given the*> value of SMIN, i.e., giving a nonsingular perturbed system.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension(N).*> The pivot indices; for 1 <= i <= N, row i of the*> matrix has been interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] JPIV*> \verbatim*> JPIV is INTEGER array, dimension(N).*> The pivot indices; for 1 <= j <= N, column j of the*> matrix has been interchanged with column JPIV(j).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> > 0: if INFO = k, U(k, k) is likely to produce owerflow if*> we try to solve for x in Ax = b. So U is perturbed to*> avoid the overflow.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEauxiliary**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.** =====================================================================SUBROUTINE DGETC2( N, A, LDA, IPIV, JPIV, INFO )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER INFO, LDA, N* ..* .. Array Arguments ..INTEGER IPIV( * ), JPIV( * )DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, IP, IPV, J, JP, JPVDOUBLE PRECISION BIGNUM, EPS, SMIN, SMLNUM, XMAX* ..* .. External Subroutines ..EXTERNAL DGER, DSWAP, DLABAD* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Handle the case N=1 by itself*IF( N.EQ.1 ) THENIPIV( 1 ) = 1JPIV( 1 ) = 1IF( ABS( A( 1, 1 ) ).LT.SMLNUM ) THENINFO = 1A( 1, 1 ) = SMLNUMEND IFRETURNEND IF** Factorize A using complete pivoting.* Set pivots less than SMIN to SMIN.*DO 40 I = 1, N - 1** Find max element in matrix A*XMAX = ZERODO 20 IP = I, NDO 10 JP = I, NIF( ABS( A( IP, JP ) ).GE.XMAX ) THENXMAX = ABS( A( IP, JP ) )IPV = IPJPV = JPEND IF10 CONTINUE20 CONTINUEIF( I.EQ.1 )$ SMIN = MAX( EPS*XMAX, SMLNUM )** Swap rows*IF( IPV.NE.I )$ CALL DSWAP( N, A( IPV, 1 ), LDA, A( I, 1 ), LDA )IPIV( I ) = IPV** Swap columns*IF( JPV.NE.I )$ CALL DSWAP( N, A( 1, JPV ), 1, A( 1, I ), 1 )JPIV( I ) = JPV** Check for singularity*IF( ABS( A( I, I ) ).LT.SMIN ) THENINFO = IA( I, I ) = SMINEND IFDO 30 J = I + 1, NA( J, I ) = A( J, I ) / A( I, I )30 CONTINUECALL DGER( N-I, N-I, -ONE, A( I+1, I ), 1, A( I, I+1 ), LDA,$ A( I+1, I+1 ), LDA )40 CONTINUE*IF( ABS( A( N, N ) ).LT.SMIN ) THENINFO = NA( N, N ) = SMINEND IF** Set last pivots to N*IPIV( N ) = NJPIV( N ) = N*RETURN** End of DGETC2*END*> \brief \b DGETF2 computes the LU factorization of a general m-by-n matrix using partial pivoting with row interchanges (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGETF2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgetf2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgetf2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgetf2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGETF2( M, N, A, LDA, IPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGETF2 computes an LU factorization of a general m-by-n matrix A*> using partial pivoting with row interchanges.*>*> The factorization has the form*> A = P * L * U*> where P is a permutation matrix, L is lower triangular with unit*> diagonal elements (lower trapezoidal if m > n), and U is upper*> triangular (upper trapezoidal if m < n).*>*> This is the right-looking Level 2 BLAS version of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n matrix to be factored.*> On exit, the factors L and U from the factorization*> A = P*L*U; the unit diagonal elements of L are not stored.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (min(M,N))*> The pivot indices; for 1 <= i <= min(M,N), row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> > 0: if INFO = k, U(k,k) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and division by zero will occur if it is used*> to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGETF2( M, N, A, LDA, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION SFMININTEGER I, J, JP* ..* .. External Functions ..DOUBLE PRECISION DLAMCHINTEGER IDAMAXEXTERNAL DLAMCH, IDAMAX* ..* .. External Subroutines ..EXTERNAL DGER, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETF2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Compute machine safe minimum*SFMIN = DLAMCH('S')*DO 10 J = 1, MIN( M, N )** Find pivot and test for singularity.*JP = J - 1 + IDAMAX( M-J+1, A( J, J ), 1 )IPIV( J ) = JPIF( A( JP, J ).NE.ZERO ) THEN** Apply the interchange to columns 1:N.*IF( JP.NE.J )$ CALL DSWAP( N, A( J, 1 ), LDA, A( JP, 1 ), LDA )** Compute elements J+1:M of J-th column.*IF( J.LT.M ) THENIF( ABS(A( J, J )) .GE. SFMIN ) THENCALL DSCAL( M-J, ONE / A( J, J ), A( J+1, J ), 1 )ELSEDO 20 I = 1, M-JA( J+I, J ) = A( J+I, J ) / A( J, J )20 CONTINUEEND IFEND IF*ELSE IF( INFO.EQ.0 ) THEN*INFO = JEND IF*IF( J.LT.MIN( M, N ) ) THEN** Update trailing submatrix.*CALL DGER( M-J, N-J, -ONE, A( J+1, J ), 1, A( J, J+1 ), LDA,$ A( J+1, J+1 ), LDA )END IF10 CONTINUERETURN** End of DGETF2*END*> \brief \b DGETRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGETRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgetrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgetrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgetrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGETRF( M, N, A, LDA, IPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGETRF computes an LU factorization of a general M-by-N matrix A*> using partial pivoting with row interchanges.*>*> The factorization has the form*> A = P * L * U*> where P is a permutation matrix, L is lower triangular with unit*> diagonal elements (lower trapezoidal if m > n), and U is upper*> triangular (upper trapezoidal if m < n).*>*> This is the right-looking Level 3 BLAS version of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix to be factored.*> On exit, the factors L and U from the factorization*> A = P*L*U; the unit diagonal elements of L are not stored.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (min(M,N))*> The pivot indices; for 1 <= i <= min(M,N), row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and division by zero will occur if it is used*> to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGETRF( M, N, A, LDA, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, IINFO, J, JB, NB* ..* .. External Subroutines ..EXTERNAL DGEMM, DGETRF2, DLASWP, DTRSM, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRF', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Determine the block size for this environment.*NB = ILAENV( 1, 'DGETRF', ' ', M, N, -1, -1 )IF( NB.LE.1 .OR. NB.GE.MIN( M, N ) ) THEN** Use unblocked code.*CALL DGETRF2( M, N, A, LDA, IPIV, INFO )ELSE** Use blocked code.*DO 20 J = 1, MIN( M, N ), NBJB = MIN( MIN( M, N )-J+1, NB )** Factor diagonal and subdiagonal blocks and test for exact* singularity.*CALL DGETRF2( M-J+1, JB, A( J, J ), LDA, IPIV( J ), IINFO )** Adjust INFO and the pivot indices.*IF( INFO.EQ.0 .AND. IINFO.GT.0 )$ INFO = IINFO + J - 1DO 10 I = J, MIN( M, J+JB-1 )IPIV( I ) = J - 1 + IPIV( I )10 CONTINUE** Apply interchanges to columns 1:J-1.*CALL DLASWP( J-1, A, LDA, J, J+JB-1, IPIV, 1 )*IF( J+JB.LE.N ) THEN** Apply interchanges to columns J+JB:N.*CALL DLASWP( N-J-JB+1, A( 1, J+JB ), LDA, J, J+JB-1,$ IPIV, 1 )** Compute block row of U.*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', JB,$ N-J-JB+1, ONE, A( J, J ), LDA, A( J, J+JB ),$ LDA )IF( J+JB.LE.M ) THEN** Update trailing submatrix.*CALL DGEMM( 'No transpose', 'No transpose', M-J-JB+1,$ N-J-JB+1, JB, -ONE, A( J+JB, J ), LDA,$ A( J, J+JB ), LDA, ONE, A( J+JB, J+JB ),$ LDA )END IFEND IF20 CONTINUEEND IFRETURN** End of DGETRF*END*> \brief \b DGETRF2** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/** Definition:* ===========** RECURSIVE SUBROUTINE DGETRF2( M, N, A, LDA, IPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGETRF2 computes an LU factorization of a general M-by-N matrix A*> using partial pivoting with row interchanges.*>*> The factorization has the form*> A = P * L * U*> where P is a permutation matrix, L is lower triangular with unit*> diagonal elements (lower trapezoidal if m > n), and U is upper*> triangular (upper trapezoidal if m < n).*>*> This is the recursive version of the algorithm. It divides*> the matrix into four submatrices:*>*> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2*> A = [ -----|----- ] with n1 = min(m,n)/2*> [ A21 | A22 ] n2 = n-n1*>*> [ A11 ]*> The subroutine calls itself to factor [ --- ],*> [ A12 ]*> [ A12 ]*> do the swaps on [ --- ], solve A12, update A22,*> [ A22 ]*>*> then calls itself to factor A22 and do the swaps on A21.*>*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix to be factored.*> On exit, the factors L and U from the factorization*> A = P*L*U; the unit diagonal elements of L are not stored.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (min(M,N))*> The pivot indices; for 1 <= i <= min(M,N), row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, U(i,i) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and division by zero will occur if it is used*> to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEcomputational** =====================================================================RECURSIVE SUBROUTINE DGETRF2( M, N, A, LDA, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION SFMIN, TEMPINTEGER I, IINFO, N1, N2* ..* .. External Functions ..DOUBLE PRECISION DLAMCHINTEGER IDAMAXEXTERNAL DLAMCH, IDAMAX* ..* .. External Subroutines ..EXTERNAL DGEMM, DSCAL, DLASWP, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRF2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURNIF ( M.EQ.1 ) THEN** Use unblocked code for one row case* Just need to handle IPIV and INFO*IPIV( 1 ) = 1IF ( A(1,1).EQ.ZERO )$ INFO = 1*ELSE IF( N.EQ.1 ) THEN** Use unblocked code for one column case*** Compute machine safe minimum*SFMIN = DLAMCH('S')** Find pivot and test for singularity*I = IDAMAX( M, A( 1, 1 ), 1 )IPIV( 1 ) = IIF( A( I, 1 ).NE.ZERO ) THEN** Apply the interchange*IF( I.NE.1 ) THENTEMP = A( 1, 1 )A( 1, 1 ) = A( I, 1 )A( I, 1 ) = TEMPEND IF** Compute elements 2:M of the column*IF( ABS(A( 1, 1 )) .GE. SFMIN ) THENCALL DSCAL( M-1, ONE / A( 1, 1 ), A( 2, 1 ), 1 )ELSEDO 10 I = 1, M-1A( 1+I, 1 ) = A( 1+I, 1 ) / A( 1, 1 )10 CONTINUEEND IF*ELSEINFO = 1END IF*ELSE** Use recursive code*N1 = MIN( M, N ) / 2N2 = N-N1** [ A11 ]* Factor [ --- ]* [ A21 ]*CALL DGETRF2( M, N1, A, LDA, IPIV, IINFO )IF ( INFO.EQ.0 .AND. IINFO.GT.0 )$ INFO = IINFO** [ A12 ]* Apply interchanges to [ --- ]* [ A22 ]*CALL DLASWP( N2, A( 1, N1+1 ), LDA, 1, N1, IPIV, 1 )** Solve A12*CALL DTRSM( 'L', 'L', 'N', 'U', N1, N2, ONE, A, LDA,$ A( 1, N1+1 ), LDA )** Update A22*CALL DGEMM( 'N', 'N', M-N1, N2, N1, -ONE, A( N1+1, 1 ), LDA,$ A( 1, N1+1 ), LDA, ONE, A( N1+1, N1+1 ), LDA )** Factor A22*CALL DGETRF2( M-N1, N2, A( N1+1, N1+1 ), LDA, IPIV( N1+1 ),$ IINFO )** Adjust INFO and the pivot indices*IF ( INFO.EQ.0 .AND. IINFO.GT.0 )$ INFO = IINFO + N1DO 20 I = N1+1, MIN( M, N )IPIV( I ) = IPIV( I ) + N120 CONTINUE** Apply interchanges to A21*CALL DLASWP( N1, A( 1, 1 ), LDA, N1+1, MIN( M, N), IPIV, 1 )*END IFRETURN** End of DGETRF2*END*> \brief \b DGETRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGETRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgetri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgetri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgetri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGETRI computes the inverse of a matrix using the LU factorization*> computed by DGETRF.*>*> This method inverts U and then computes inv(A) by solving the system*> inv(A)*L = inv(U) for inv(A).*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the factors L and U from the factorization*> A = P*L*U as computed by DGETRF.*> On exit, if INFO = 0, the inverse of the original matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices from DGETRF; for 1<=i<=N, row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO=0, then WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> For optimal performance LWORK >= N*NB, where NB is*> the optimal blocksize returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, U(i,i) is exactly zero; the matrix is*> singular and its inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,$ NBMIN, NN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. External Subroutines ..EXTERNAL DGEMM, DGEMV, DSWAP, DTRSM, DTRTRI, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NB = ILAENV( 1, 'DGETRI', ' ', N, -1, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -3ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRI', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form inv(U). If INFO > 0 from DTRTRI, then U is singular,* and the inverse is not computed.*CALL DTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )IF( INFO.GT.0 )$ RETURN*NBMIN = 2LDWORK = NIF( NB.GT.1 .AND. NB.LT.N ) THENIWS = MAX( LDWORK*NB, 1 )IF( LWORK.LT.IWS ) THENNB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGETRI', ' ', N, -1, -1, -1 ) )END IFELSEIWS = NEND IF** Solve the equation inv(A)*L = inv(U) for inv(A).*IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN** Use unblocked code.*DO 20 J = N, 1, -1** Copy current column of L to WORK and replace with zeros.*DO 10 I = J + 1, NWORK( I ) = A( I, J )A( I, J ) = ZERO10 CONTINUE** Compute current column of inv(A).*IF( J.LT.N )$ CALL DGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),$ LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )20 CONTINUEELSE** Use blocked code.*NN = ( ( N-1 ) / NB )*NB + 1DO 50 J = NN, 1, -NBJB = MIN( NB, N-J+1 )** Copy current block column of L to WORK and replace with* zeros.*DO 40 JJ = J, J + JB - 1DO 30 I = JJ + 1, NWORK( I+( JJ-J )*LDWORK ) = A( I, JJ )A( I, JJ ) = ZERO30 CONTINUE40 CONTINUE** Compute current block column of inv(A).*IF( J+JB.LE.N )$ CALL DGEMM( 'No transpose', 'No transpose', N, JB,$ N-J-JB+1, -ONE, A( 1, J+JB ), LDA,$ WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )CALL DTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,$ ONE, WORK( J ), LDWORK, A( 1, J ), LDA )50 CONTINUEEND IF** Apply column interchanges.*DO 60 J = N - 1, 1, -1JP = IPIV( J )IF( JP.NE.J )$ CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )60 CONTINUE*WORK( 1 ) = IWSRETURN** End of DGETRI*END*> \brief \b DGETRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGETRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgetrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgetrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgetrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGETRS solves a system of linear equations*> A * X = B or A**T * X = B*> with a general N-by-N matrix A using the LU factorization computed*> by DGETRF.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T* X = B (Transpose)*> = 'C': A**T* X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The factors L and U from the factorization A = P*L*U*> as computed by DGETRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices from DGETRF; for 1<=i<=N, row i of the*> matrix was interchanged with row IPIV(i).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational** =====================================================================SUBROUTINE DGETRS( TRANS, N, NRHS, A, LDA, IPIV, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLASWP, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGETRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( NOTRAN ) THEN** Solve A * X = B.** Apply row interchanges to the right hand sides.*CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, 1 )** Solve L*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Unit', N, NRHS,$ ONE, A, LDA, B, LDB )** Solve U*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,$ NRHS, ONE, A, LDA, B, LDB )ELSE** Solve A**T * X = B.** Solve U**T *X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,$ ONE, A, LDA, B, LDB )** Solve L**T *X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Unit', N, NRHS, ONE,$ A, LDA, B, LDB )** Apply row interchanges to the solution vectors.*CALL DLASWP( NRHS, B, LDB, 1, N, IPIV, -1 )END IF*RETURN** End of DGETRS*END*> \brief \b DGGBAK** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGBAK + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggbak.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggbak.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggbak.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,* LDV, INFO )** .. Scalar Arguments ..* CHARACTER JOB, SIDE* INTEGER IHI, ILO, INFO, LDV, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION LSCALE( * ), RSCALE( * ), V( LDV, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGBAK forms the right or left eigenvectors of a real generalized*> eigenvalue problem A*x = lambda*B*x, by backward transformation on*> the computed eigenvectors of the balanced pair of matrices output by*> DGGBAL.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies the type of backward transformation required:*> = 'N': do nothing, return immediately;*> = 'P': do backward transformation for permutation only;*> = 'S': do backward transformation for scaling only;*> = 'B': do backward transformations for both permutation and*> scaling.*> JOB must be the same as the argument JOB supplied to DGGBAL.*> \endverbatim*>*> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'R': V contains right eigenvectors;*> = 'L': V contains left eigenvectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows of the matrix V. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> The integers ILO and IHI determined by DGGBAL.*> 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.*> \endverbatim*>*> \param[in] LSCALE*> \verbatim*> LSCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and/or scaling factors applied*> to the left side of A and B, as returned by DGGBAL.*> \endverbatim*>*> \param[in] RSCALE*> \verbatim*> RSCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and/or scaling factors applied*> to the right side of A and B, as returned by DGGBAL.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of columns of the matrix V. M >= 0.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,M)*> On entry, the matrix of right or left eigenvectors to be*> transformed, as returned by DTGEVC.*> On exit, V is overwritten by the transformed eigenvectors.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the matrix V. LDV >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> See R.C. Ward, Balancing the generalized eigenvalue problem,*> SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.*> \endverbatim*>* =====================================================================SUBROUTINE DGGBAK( JOB, SIDE, N, ILO, IHI, LSCALE, RSCALE, M, V,$ LDV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOB, SIDEINTEGER IHI, ILO, INFO, LDV, M, N* ..* .. Array Arguments ..DOUBLE PRECISION LSCALE( * ), RSCALE( * ), V( LDV, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LEFTV, RIGHTVINTEGER I, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, INT* ..* .. Executable Statements ..** Test the input parameters*RIGHTV = LSAME( SIDE, 'R' )LEFTV = LSAME( SIDE, 'L' )*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 ) THENINFO = -4ELSE IF( N.EQ.0 .AND. IHI.EQ.0 .AND. ILO.NE.1 ) THENINFO = -4ELSE IF( N.GT.0 .AND. ( IHI.LT.ILO .OR. IHI.GT.MAX( 1, N ) ) )$ THENINFO = -5ELSE IF( N.EQ.0 .AND. ILO.EQ.1 .AND. IHI.NE.0 ) THENINFO = -5ELSE IF( M.LT.0 ) THENINFO = -8ELSE IF( LDV.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGBAK', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( M.EQ.0 )$ RETURNIF( LSAME( JOB, 'N' ) )$ RETURN*IF( ILO.EQ.IHI )$ GO TO 30** Backward balance*IF( LSAME( JOB, 'S' ) .OR. LSAME( JOB, 'B' ) ) THEN** Backward transformation on right eigenvectors*IF( RIGHTV ) THENDO 10 I = ILO, IHICALL DSCAL( M, RSCALE( I ), V( I, 1 ), LDV )10 CONTINUEEND IF** Backward transformation on left eigenvectors*IF( LEFTV ) THENDO 20 I = ILO, IHICALL DSCAL( M, LSCALE( I ), V( I, 1 ), LDV )20 CONTINUEEND IFEND IF** Backward permutation*30 CONTINUEIF( LSAME( JOB, 'P' ) .OR. LSAME( JOB, 'B' ) ) THEN** Backward permutation on right eigenvectors*IF( RIGHTV ) THENIF( ILO.EQ.1 )$ GO TO 50*DO 40 I = ILO - 1, 1, -1K = INT(RSCALE( I ))IF( K.EQ.I )$ GO TO 40CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )40 CONTINUE*50 CONTINUEIF( IHI.EQ.N )$ GO TO 70DO 60 I = IHI + 1, NK = INT(RSCALE( I ))IF( K.EQ.I )$ GO TO 60CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )60 CONTINUEEND IF** Backward permutation on left eigenvectors*70 CONTINUEIF( LEFTV ) THENIF( ILO.EQ.1 )$ GO TO 90DO 80 I = ILO - 1, 1, -1K = INT(LSCALE( I ))IF( K.EQ.I )$ GO TO 80CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )80 CONTINUE*90 CONTINUEIF( IHI.EQ.N )$ GO TO 110DO 100 I = IHI + 1, NK = INT(LSCALE( I ))IF( K.EQ.I )$ GO TO 100CALL DSWAP( M, V( I, 1 ), LDV, V( K, 1 ), LDV )100 CONTINUEEND IFEND IF*110 CONTINUE*RETURN** End of DGGBAK*END*> \brief \b DGGBAL** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGBAL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggbal.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggbal.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggbal.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,* RSCALE, WORK, INFO )** .. Scalar Arguments ..* CHARACTER JOB* INTEGER IHI, ILO, INFO, LDA, LDB, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), LSCALE( * ),* $ RSCALE( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGBAL balances a pair of general real matrices (A,B). This*> involves, first, permuting A and B by similarity transformations to*> isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N*> elements on the diagonal; and second, applying a diagonal similarity*> transformation to rows and columns ILO to IHI to make the rows*> and columns as close in norm as possible. Both steps are optional.*>*> Balancing may reduce the 1-norm of the matrices, and improve the*> accuracy of the computed eigenvalues and/or eigenvectors in the*> generalized eigenvalue problem A*x = lambda*B*x.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies the operations to be performed on A and B:*> = 'N': none: simply set ILO = 1, IHI = N, LSCALE(I) = 1.0*> and RSCALE(I) = 1.0 for i = 1,...,N.*> = 'P': permute only;*> = 'S': scale only;*> = 'B': both permute and scale.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the input matrix A.*> On exit, A is overwritten by the balanced matrix.*> If JOB = 'N', A is not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the input matrix B.*> On exit, B is overwritten by the balanced matrix.*> If JOB = 'N', B is not referenced.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[out] IHI*> \verbatim*> IHI is INTEGER*> ILO and IHI are set to integers such that on exit*> A(i,j) = 0 and B(i,j) = 0 if i > j and*> j = 1,...,ILO-1 or i = IHI+1,...,N.*> If JOB = 'N' or 'S', ILO = 1 and IHI = N.*> \endverbatim*>*> \param[out] LSCALE*> \verbatim*> LSCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and scaling factors applied*> to the left side of A and B. If P(j) is the index of the*> row interchanged with row j, and D(j)*> is the scaling factor applied to row j, then*> LSCALE(j) = P(j) for J = 1,...,ILO-1*> = D(j) for J = ILO,...,IHI*> = P(j) for J = IHI+1,...,N.*> The order in which the interchanges are made is N to IHI+1,*> then 1 to ILO-1.*> \endverbatim*>*> \param[out] RSCALE*> \verbatim*> RSCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and scaling factors applied*> to the right side of A and B. If P(j) is the index of the*> column interchanged with column j, and D(j)*> is the scaling factor applied to column j, then*> LSCALE(j) = P(j) for J = 1,...,ILO-1*> = D(j) for J = ILO,...,IHI*> = P(j) for J = IHI+1,...,N.*> The order in which the interchanges are made is N to IHI+1,*> then 1 to ILO-1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (lwork)*> lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and*> at least 1 when JOB = 'N' or 'P'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> See R.C. WARD, Balancing the generalized eigenvalue problem,*> SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.*> \endverbatim*>* =====================================================================SUBROUTINE DGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,$ RSCALE, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBINTEGER IHI, ILO, INFO, LDA, LDB, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), LSCALE( * ),$ RSCALE( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )DOUBLE PRECISION THREE, SCLFACPARAMETER ( THREE = 3.0D+0, SCLFAC = 1.0D+1 )* ..* .. Local Scalars ..INTEGER I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,$ K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,$ M, NR, NRP2DOUBLE PRECISION ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,$ COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,$ SFMIN, SUM, T, TA, TB, TC* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG10, MAX, MIN, SIGN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.$ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGBAL', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENILO = 1IHI = NRETURNEND IF*IF( N.EQ.1 ) THENILO = 1IHI = NLSCALE( 1 ) = ONERSCALE( 1 ) = ONERETURNEND IF*IF( LSAME( JOB, 'N' ) ) THENILO = 1IHI = NDO 10 I = 1, NLSCALE( I ) = ONERSCALE( I ) = ONE10 CONTINUERETURNEND IF*K = 1L = NIF( LSAME( JOB, 'S' ) )$ GO TO 190*GO TO 30** Permute the matrices A and B to isolate the eigenvalues.** Find row with one nonzero in columns 1 through L*20 CONTINUEL = LM1IF( L.NE.1 )$ GO TO 30*RSCALE( 1 ) = ONELSCALE( 1 ) = ONEGO TO 190*30 CONTINUELM1 = L - 1DO 80 I = L, 1, -1DO 40 J = 1, LM1JP1 = J + 1IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 5040 CONTINUEJ = LGO TO 70*50 CONTINUEDO 60 J = JP1, LIF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 8060 CONTINUEJ = JP1 - 1*70 CONTINUEM = LIFLOW = 1GO TO 16080 CONTINUEGO TO 100** Find column with one nonzero in rows K through N*90 CONTINUEK = K + 1*100 CONTINUEDO 150 J = K, LDO 110 I = K, LM1IP1 = I + 1IF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 120110 CONTINUEI = LGO TO 140120 CONTINUEDO 130 I = IP1, LIF( A( I, J ).NE.ZERO .OR. B( I, J ).NE.ZERO )$ GO TO 150130 CONTINUEI = IP1 - 1140 CONTINUEM = KIFLOW = 2GO TO 160150 CONTINUEGO TO 190** Permute rows M and I*160 CONTINUELSCALE( M ) = IIF( I.EQ.M )$ GO TO 170CALL DSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )CALL DSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )** Permute columns M and J*170 CONTINUERSCALE( M ) = JIF( J.EQ.M )$ GO TO 180CALL DSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )CALL DSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )*180 CONTINUEGO TO ( 20, 90 )IFLOW*190 CONTINUEILO = KIHI = L*IF( LSAME( JOB, 'P' ) ) THENDO 195 I = ILO, IHILSCALE( I ) = ONERSCALE( I ) = ONE195 CONTINUERETURNEND IF*IF( ILO.EQ.IHI )$ RETURN** Balance the submatrix in rows ILO to IHI.*NR = IHI - ILO + 1DO 200 I = ILO, IHIRSCALE( I ) = ZEROLSCALE( I ) = ZERO*WORK( I ) = ZEROWORK( I+N ) = ZEROWORK( I+2*N ) = ZEROWORK( I+3*N ) = ZEROWORK( I+4*N ) = ZEROWORK( I+5*N ) = ZERO200 CONTINUE** Compute right side vector in resulting linear equations*BASL = LOG10( SCLFAC )DO 240 I = ILO, IHIDO 230 J = ILO, IHITB = B( I, J )TA = A( I, J )IF( TA.EQ.ZERO )$ GO TO 210TA = LOG10( ABS( TA ) ) / BASL210 CONTINUEIF( TB.EQ.ZERO )$ GO TO 220TB = LOG10( ABS( TB ) ) / BASL220 CONTINUEWORK( I+4*N ) = WORK( I+4*N ) - TA - TBWORK( J+5*N ) = WORK( J+5*N ) - TA - TB230 CONTINUE240 CONTINUE*COEF = ONE / DBLE( 2*NR )COEF2 = COEF*COEFCOEF5 = HALF*COEF2NRP2 = NR + 2BETA = ZEROIT = 1** Start generalized conjugate gradient iteration*250 CONTINUE*GAMMA = DDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +$ DDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )*EW = ZEROEWC = ZERODO 260 I = ILO, IHIEW = EW + WORK( I+4*N )EWC = EWC + WORK( I+5*N )260 CONTINUE*GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2IF( GAMMA.EQ.ZERO )$ GO TO 350IF( IT.NE.1 )$ BETA = GAMMA / PGAMMAT = COEF5*( EWC-THREE*EW )TC = COEF5*( EW-THREE*EWC )*CALL DSCAL( NR, BETA, WORK( ILO ), 1 )CALL DSCAL( NR, BETA, WORK( ILO+N ), 1 )*CALL DAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )CALL DAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )*DO 270 I = ILO, IHIWORK( I ) = WORK( I ) + TCWORK( I+N ) = WORK( I+N ) + T270 CONTINUE** Apply matrix to vector*DO 300 I = ILO, IHIKOUNT = 0SUM = ZERODO 290 J = ILO, IHIIF( A( I, J ).EQ.ZERO )$ GO TO 280KOUNT = KOUNT + 1SUM = SUM + WORK( J )280 CONTINUEIF( B( I, J ).EQ.ZERO )$ GO TO 290KOUNT = KOUNT + 1SUM = SUM + WORK( J )290 CONTINUEWORK( I+2*N ) = DBLE( KOUNT )*WORK( I+N ) + SUM300 CONTINUE*DO 330 J = ILO, IHIKOUNT = 0SUM = ZERODO 320 I = ILO, IHIIF( A( I, J ).EQ.ZERO )$ GO TO 310KOUNT = KOUNT + 1SUM = SUM + WORK( I+N )310 CONTINUEIF( B( I, J ).EQ.ZERO )$ GO TO 320KOUNT = KOUNT + 1SUM = SUM + WORK( I+N )320 CONTINUEWORK( J+3*N ) = DBLE( KOUNT )*WORK( J ) + SUM330 CONTINUE*SUM = DDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +$ DDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )ALPHA = GAMMA / SUM** Determine correction to current iteration*CMAX = ZERODO 340 I = ILO, IHICOR = ALPHA*WORK( I+N )IF( ABS( COR ).GT.CMAX )$ CMAX = ABS( COR )LSCALE( I ) = LSCALE( I ) + CORCOR = ALPHA*WORK( I )IF( ABS( COR ).GT.CMAX )$ CMAX = ABS( COR )RSCALE( I ) = RSCALE( I ) + COR340 CONTINUEIF( CMAX.LT.HALF )$ GO TO 350*CALL DAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )CALL DAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )*PGAMMA = GAMMAIT = IT + 1IF( IT.LE.NRP2 )$ GO TO 250** End generalized conjugate gradient iteration*350 CONTINUESFMIN = DLAMCH( 'S' )SFMAX = ONE / SFMINLSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )LSFMAX = INT( LOG10( SFMAX ) / BASL )DO 360 I = ILO, IHIIRAB = IDAMAX( N-ILO+1, A( I, ILO ), LDA )RAB = ABS( A( I, IRAB+ILO-1 ) )IRAB = IDAMAX( N-ILO+1, B( I, ILO ), LDB )RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )IR = INT(LSCALE( I ) + SIGN( HALF, LSCALE( I ) ))IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )LSCALE( I ) = SCLFAC**IRICAB = IDAMAX( IHI, A( 1, I ), 1 )CAB = ABS( A( ICAB, I ) )ICAB = IDAMAX( IHI, B( 1, I ), 1 )CAB = MAX( CAB, ABS( B( ICAB, I ) ) )LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )JC = INT(RSCALE( I ) + SIGN( HALF, RSCALE( I ) ))JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )RSCALE( I ) = SCLFAC**JC360 CONTINUE** Row scaling of matrices A and B*DO 370 I = ILO, IHICALL DSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )CALL DSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )370 CONTINUE** Column scaling of matrices A and B*DO 380 J = ILO, IHICALL DSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )CALL DSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )380 CONTINUE*RETURN** End of DGGBAL*END*> \brief <b> DGGES computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGES + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgges.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgges.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgges.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGES( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB,* SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR,* LDVSR, WORK, LWORK, BWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVSL, JOBVSR, SORT* INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM* ..* .. Array Arguments ..* LOGICAL BWORK( * )* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),* $ VSR( LDVSR, * ), WORK( * )* ..* .. Function Arguments ..* LOGICAL SELCTG* EXTERNAL SELCTG* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGES computes for a pair of N-by-N real nonsymmetric matrices (A,B),*> the generalized eigenvalues, the generalized real Schur form (S,T),*> optionally, the left and/or right matrices of Schur vectors (VSL and*> VSR). This gives the generalized Schur factorization*>*> (A,B) = ( (VSL)*S*(VSR)**T, (VSL)*T*(VSR)**T )*>*> Optionally, it also orders the eigenvalues so that a selected cluster*> of eigenvalues appears in the leading diagonal blocks of the upper*> quasi-triangular matrix S and the upper triangular matrix T.The*> leading columns of VSL and VSR then form an orthonormal basis for the*> corresponding left and right eigenspaces (deflating subspaces).*>*> (If only the generalized eigenvalues are needed, use the driver*> DGGEV instead, which is faster.)*>*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w*> or a ratio alpha/beta = w, such that A - w*B is singular. It is*> usually represented as the pair (alpha,beta), as there is a*> reasonable interpretation for beta=0 or both being zero.*>*> A pair of matrices (S,T) is in generalized real Schur form if T is*> upper triangular with non-negative diagonal and S is block upper*> triangular with 1-by-1 and 2-by-2 blocks. 1-by-1 blocks correspond*> to real generalized eigenvalues, while 2-by-2 blocks of S will be*> "standardized" by making the corresponding elements of T have the*> form:*> [ a 0 ]*> [ 0 b ]*>*> and the pair of corresponding 2-by-2 blocks in S and T will have a*> complex conjugate pair of generalized eigenvalues.*>*> \endverbatim** Arguments:* ==========**> \param[in] JOBVSL*> \verbatim*> JOBVSL is CHARACTER*1*> = 'N': do not compute the left Schur vectors;*> = 'V': compute the left Schur vectors.*> \endverbatim*>*> \param[in] JOBVSR*> \verbatim*> JOBVSR is CHARACTER*1*> = 'N': do not compute the right Schur vectors;*> = 'V': compute the right Schur vectors.*> \endverbatim*>*> \param[in] SORT*> \verbatim*> SORT is CHARACTER*1*> Specifies whether or not to order the eigenvalues on the*> diagonal of the generalized Schur form.*> = 'N': Eigenvalues are not ordered;*> = 'S': Eigenvalues are ordered (see SELCTG);*> \endverbatim*>*> \param[in] SELCTG*> \verbatim*> SELCTG is a LOGICAL FUNCTION of three DOUBLE PRECISION arguments*> SELCTG must be declared EXTERNAL in the calling subroutine.*> If SORT = 'N', SELCTG is not referenced.*> If SORT = 'S', SELCTG is used to select eigenvalues to sort*> to the top left of the Schur form.*> An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if*> SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either*> one of a complex conjugate pair of eigenvalues is selected,*> then both complex eigenvalues are selected.*>*> Note that in the ill-conditioned case, a selected complex*> eigenvalue may no longer satisfy SELCTG(ALPHAR(j),ALPHAI(j),*> BETA(j)) = .TRUE. after ordering. INFO is to be set to N+2*> in this case.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A, B, VSL, and VSR. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the first of the pair of matrices.*> On exit, A has been overwritten by its generalized Schur*> form S.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the second of the pair of matrices.*> On exit, B has been overwritten by its generalized Schur*> form T.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] SDIM*> \verbatim*> SDIM is INTEGER*> If SORT = 'N', SDIM = 0.*> If SORT = 'S', SDIM = number of eigenvalues (after sorting)*> for which SELCTG is true. (Complex conjugate pairs for which*> SELCTG is true for either eigenvalue count as 2.)*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will*> be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i,*> and BETA(j),j=1,...,N are the diagonals of the complex Schur*> form (S,T) that would result if the 2-by-2 diagonal blocks of*> the real Schur form of (A,B) were further reduced to*> triangular form using 2-by-2 complex unitary transformations.*> If ALPHAI(j) is zero, then the j-th eigenvalue is real; if*> positive, then the j-th and (j+1)-st eigenvalues are a*> complex conjugate pair, with ALPHAI(j+1) negative.*>*> Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)*> may easily over- or underflow, and BETA(j) may even be zero.*> Thus, the user should avoid naively computing the ratio.*> However, ALPHAR and ALPHAI will be always less than and*> usually comparable with norm(A) in magnitude, and BETA always*> less than and usually comparable with norm(B).*> \endverbatim*>*> \param[out] VSL*> \verbatim*> VSL is DOUBLE PRECISION array, dimension (LDVSL,N)*> If JOBVSL = 'V', VSL will contain the left Schur vectors.*> Not referenced if JOBVSL = 'N'.*> \endverbatim*>*> \param[in] LDVSL*> \verbatim*> LDVSL is INTEGER*> The leading dimension of the matrix VSL. LDVSL >=1, and*> if JOBVSL = 'V', LDVSL >= N.*> \endverbatim*>*> \param[out] VSR*> \verbatim*> VSR is DOUBLE PRECISION array, dimension (LDVSR,N)*> If JOBVSR = 'V', VSR will contain the right Schur vectors.*> Not referenced if JOBVSR = 'N'.*> \endverbatim*>*> \param[in] LDVSR*> \verbatim*> LDVSR is INTEGER*> The leading dimension of the matrix VSR. LDVSR >= 1, and*> if JOBVSR = 'V', LDVSR >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N = 0, LWORK >= 1, else LWORK >= 8*N+16.*> For good performance , LWORK must generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] BWORK*> \verbatim*> BWORK is LOGICAL array, dimension (N)*> Not referenced if SORT = 'N'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1,...,N:*> The QZ iteration failed. (A,B) are not in Schur*> form, but ALPHAR(j), ALPHAI(j), and BETA(j) should*> be correct for j=INFO+1,...,N.*> > N: =N+1: other than QZ iteration failed in DHGEQZ.*> =N+2: after reordering, roundoff changed values of*> some complex eigenvalues so that leading*> eigenvalues in the Generalized Schur form no*> longer satisfy SELCTG=.TRUE. This could also*> be caused due to scaling.*> =N+3: reordering failed in DTGSEN.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGGES( JOBVSL, JOBVSR, SORT, SELCTG, N, A, LDA, B, LDB,$ SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR,$ LDVSR, WORK, LWORK, BWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBVSL, JOBVSR, SORTINTEGER INFO, LDA, LDB, LDVSL, LDVSR, LWORK, N, SDIM* ..* .. Array Arguments ..LOGICAL BWORK( * )DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), VSL( LDVSL, * ),$ VSR( LDVSR, * ), WORK( * )* ..* .. Function Arguments ..LOGICAL SELCTGEXTERNAL SELCTG* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,$ LQUERY, LST2SL, WANTSTINTEGER I, ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT,$ ILO, IP, IRIGHT, IROWS, ITAU, IWRK, MAXWRK,$ MINWRKDOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PVSL,$ PVSR, SAFMAX, SAFMIN, SMLNUM* ..* .. Local Arrays ..INTEGER IDUM( 1 )DOUBLE PRECISION DIF( 2 )* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,$ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGSEN,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode the input arguments*IF( LSAME( JOBVSL, 'N' ) ) THENIJOBVL = 1ILVSL = .FALSE.ELSE IF( LSAME( JOBVSL, 'V' ) ) THENIJOBVL = 2ILVSL = .TRUE.ELSEIJOBVL = -1ILVSL = .FALSE.END IF*IF( LSAME( JOBVSR, 'N' ) ) THENIJOBVR = 1ILVSR = .FALSE.ELSE IF( LSAME( JOBVSR, 'V' ) ) THENIJOBVR = 2ILVSR = .TRUE.ELSEIJOBVR = -1ILVSR = .FALSE.END IF*WANTST = LSAME( SORT, 'S' )** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( IJOBVL.LE.0 ) THENINFO = -1ELSE IF( IJOBVR.LE.0 ) THENINFO = -2ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THENINFO = -15ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THENINFO = -17END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)*IF( INFO.EQ.0 ) THENIF( N.GT.0 )THENMINWRK = MAX( 8*N, 6*N + 16 )MAXWRK = MINWRK - N +$ N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 )MAXWRK = MAX( MAXWRK, MINWRK - N +$ N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, -1 ) )IF( ILVSL ) THENMAXWRK = MAX( MAXWRK, MINWRK - N +$ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) )END IFELSEMINWRK = 1MAXWRK = 1END IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )$ INFO = -19END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGGES ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSDIM = 0RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINCALL DLABAD( SAFMIN, SAFMAX )SMLNUM = SQRT( SAFMIN ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, WORK )ILASCL = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENANRMTO = SMLNUMILASCL = .TRUE.ELSE IF( ANRM.GT.BIGNUM ) THENANRMTO = BIGNUMILASCL = .TRUE.END IFIF( ILASCL )$ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )** Scale B if max element outside range [SMLNUM,BIGNUM]*BNRM = DLANGE( 'M', N, N, B, LDB, WORK )ILBSCL = .FALSE.IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THENBNRMTO = SMLNUMILBSCL = .TRUE.ELSE IF( BNRM.GT.BIGNUM ) THENBNRMTO = BIGNUMILBSCL = .TRUE.END IFIF( ILBSCL )$ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )** Permute the matrix to make it more nearly triangular* (Workspace: need 6*N + 2*N space for storing balancing factors)*ILEFT = 1IRIGHT = N + 1IWRK = IRIGHT + NCALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), WORK( IWRK ), IERR )** Reduce B to triangular form (QR decomposition of B)* (Workspace: need N, prefer N*NB)*IROWS = IHI + 1 - ILOICOLS = N + 1 - ILOITAU = IWRKIWRK = ITAU + IROWSCALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),$ WORK( IWRK ), LWORK+1-IWRK, IERR )** Apply the orthogonal transformation to matrix A* (Workspace: need N, prefer N*NB)*CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),$ LWORK+1-IWRK, IERR )** Initialize VSL* (Workspace: need N, prefer N*NB)*IF( ILVSL ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )IF( IROWS.GT.1 ) THENCALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,$ VSL( ILO+1, ILO ), LDVSL )END IFCALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,$ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )END IF** Initialize VSR*IF( ILVSR )$ CALL DLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )** Reduce to generalized Hessenberg form* (Workspace: none needed)*CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,$ LDVSL, VSR, LDVSR, IERR )** Perform QZ algorithm, computing Schur vectors if desired* (Workspace: need N)*IWRK = ITAUCALL DHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,$ WORK( IWRK ), LWORK+1-IWRK, IERR )IF( IERR.NE.0 ) THENIF( IERR.GT.0 .AND. IERR.LE.N ) THENINFO = IERRELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THENINFO = IERR - NELSEINFO = N + 1END IFGO TO 50END IF** Sort eigenvalues ALPHA/BETA if desired* (Workspace: need 4*N+16 )*SDIM = 0IF( WANTST ) THEN** Undo scaling on eigenvalues before SELCTGing*IF( ILASCL ) THENCALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,$ IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,$ IERR )END IFIF( ILBSCL )$ CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )** Select eigenvalues*DO 10 I = 1, NBWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )10 CONTINUE*CALL DTGSEN( 0, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB, ALPHAR,$ ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR, SDIM, PVSL,$ PVSR, DIF, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,$ IERR )IF( IERR.EQ.1 )$ INFO = N + 3*END IF** Apply back-permutation to VSL and VSR* (Workspace: none needed)*IF( ILVSL )$ CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VSL, LDVSL, IERR )*IF( ILVSR )$ CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VSR, LDVSR, IERR )** Check if unscaling would cause over/underflow, if so, rescale* (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of* B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I)*IF( ILASCL ) THENDO 20 I = 1, NIF( ALPHAI( I ).NE.ZERO ) THENIF( ( ALPHAR( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) .OR.$ ( SAFMIN / ALPHAR( I ) ).GT.( ANRM / ANRMTO ) ) THENWORK( 1 ) = ABS( A( I, I ) / ALPHAR( I ) )BETA( I ) = BETA( I )*WORK( 1 )ALPHAR( I ) = ALPHAR( I )*WORK( 1 )ALPHAI( I ) = ALPHAI( I )*WORK( 1 )ELSE IF( ( ALPHAI( I ) / SAFMAX ).GT.$ ( ANRMTO / ANRM ) .OR.$ ( SAFMIN / ALPHAI( I ) ).GT.( ANRM / ANRMTO ) )$ THENWORK( 1 ) = ABS( A( I, I+1 ) / ALPHAI( I ) )BETA( I ) = BETA( I )*WORK( 1 )ALPHAR( I ) = ALPHAR( I )*WORK( 1 )ALPHAI( I ) = ALPHAI( I )*WORK( 1 )END IFEND IF20 CONTINUEEND IF*IF( ILBSCL ) THENDO 30 I = 1, NIF( ALPHAI( I ).NE.ZERO ) THENIF( ( BETA( I ) / SAFMAX ).GT.( BNRMTO / BNRM ) .OR.$ ( SAFMIN / BETA( I ) ).GT.( BNRM / BNRMTO ) ) THENWORK( 1 ) = ABS( B( I, I ) / BETA( I ) )BETA( I ) = BETA( I )*WORK( 1 )ALPHAR( I ) = ALPHAR( I )*WORK( 1 )ALPHAI( I ) = ALPHAI( I )*WORK( 1 )END IFEND IF30 CONTINUEEND IF** Undo scaling*IF( ILASCL ) THENCALL DLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )END IF*IF( ILBSCL ) THENCALL DLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )END IF*IF( WANTST ) THEN** Check if reordering is correct*LASTSL = .TRUE.LST2SL = .TRUE.SDIM = 0IP = 0DO 40 I = 1, NCURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )IF( ALPHAI( I ).EQ.ZERO ) THENIF( CURSL )$ SDIM = SDIM + 1IP = 0IF( CURSL .AND. .NOT.LASTSL )$ INFO = N + 2ELSEIF( IP.EQ.1 ) THEN** Last eigenvalue of conjugate pair*CURSL = CURSL .OR. LASTSLLASTSL = CURSLIF( CURSL )$ SDIM = SDIM + 2IP = -1IF( CURSL .AND. .NOT.LST2SL )$ INFO = N + 2ELSE** First eigenvalue of conjugate pair*IP = 1END IFEND IFLST2SL = LASTSLLASTSL = CURSL40 CONTINUE*END IF*50 CONTINUE*WORK( 1 ) = MAXWRK*RETURN** End of DGGES*END*> \brief <b> DGGESX computes the eigenvalues, the Schur form, and, optionally, the matrix of Schur vectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGESX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggesx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggesx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggesx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,* B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,* VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,* LIWORK, BWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVSL, JOBVSR, SENSE, SORT* INTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,* $ SDIM* ..* .. Array Arguments ..* LOGICAL BWORK( * )* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), RCONDE( 2 ),* $ RCONDV( 2 ), VSL( LDVSL, * ), VSR( LDVSR, * ),* $ WORK( * )* ..* .. Function Arguments ..* LOGICAL SELCTG* EXTERNAL SELCTG* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGESX computes for a pair of N-by-N real nonsymmetric matrices*> (A,B), the generalized eigenvalues, the real Schur form (S,T), and,*> optionally, the left and/or right matrices of Schur vectors (VSL and*> VSR). This gives the generalized Schur factorization*>*> (A,B) = ( (VSL) S (VSR)**T, (VSL) T (VSR)**T )*>*> Optionally, it also orders the eigenvalues so that a selected cluster*> of eigenvalues appears in the leading diagonal blocks of the upper*> quasi-triangular matrix S and the upper triangular matrix T; computes*> a reciprocal condition number for the average of the selected*> eigenvalues (RCONDE); and computes a reciprocal condition number for*> the right and left deflating subspaces corresponding to the selected*> eigenvalues (RCONDV). The leading columns of VSL and VSR then form*> an orthonormal basis for the corresponding left and right eigenspaces*> (deflating subspaces).*>*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar w*> or a ratio alpha/beta = w, such that A - w*B is singular. It is*> usually represented as the pair (alpha,beta), as there is a*> reasonable interpretation for beta=0 or for both being zero.*>*> A pair of matrices (S,T) is in generalized real Schur form if T is*> upper triangular with non-negative diagonal and S is block upper*> triangular with 1-by-1 and 2-by-2 blocks. 1-by-1 blocks correspond*> to real generalized eigenvalues, while 2-by-2 blocks of S will be*> "standardized" by making the corresponding elements of T have the*> form:*> [ a 0 ]*> [ 0 b ]*>*> and the pair of corresponding 2-by-2 blocks in S and T will have a*> complex conjugate pair of generalized eigenvalues.*>*> \endverbatim** Arguments:* ==========**> \param[in] JOBVSL*> \verbatim*> JOBVSL is CHARACTER*1*> = 'N': do not compute the left Schur vectors;*> = 'V': compute the left Schur vectors.*> \endverbatim*>*> \param[in] JOBVSR*> \verbatim*> JOBVSR is CHARACTER*1*> = 'N': do not compute the right Schur vectors;*> = 'V': compute the right Schur vectors.*> \endverbatim*>*> \param[in] SORT*> \verbatim*> SORT is CHARACTER*1*> Specifies whether or not to order the eigenvalues on the*> diagonal of the generalized Schur form.*> = 'N': Eigenvalues are not ordered;*> = 'S': Eigenvalues are ordered (see SELCTG).*> \endverbatim*>*> \param[in] SELCTG*> \verbatim*> SELCTG is a LOGICAL FUNCTION of three DOUBLE PRECISION arguments*> SELCTG must be declared EXTERNAL in the calling subroutine.*> If SORT = 'N', SELCTG is not referenced.*> If SORT = 'S', SELCTG is used to select eigenvalues to sort*> to the top left of the Schur form.*> An eigenvalue (ALPHAR(j)+ALPHAI(j))/BETA(j) is selected if*> SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) is true; i.e. if either*> one of a complex conjugate pair of eigenvalues is selected,*> then both complex eigenvalues are selected.*> Note that a selected complex eigenvalue may no longer satisfy*> SELCTG(ALPHAR(j),ALPHAI(j),BETA(j)) = .TRUE. after ordering,*> since ordering may change the value of complex eigenvalues*> (especially if the eigenvalue is ill-conditioned), in this*> case INFO is set to N+3.*> \endverbatim*>*> \param[in] SENSE*> \verbatim*> SENSE is CHARACTER*1*> Determines which reciprocal condition numbers are computed.*> = 'N' : None are computed;*> = 'E' : Computed for average of selected eigenvalues only;*> = 'V' : Computed for selected deflating subspaces only;*> = 'B' : Computed for both.*> If SENSE = 'E', 'V', or 'B', SORT must equal 'S'.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A, B, VSL, and VSR. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the first of the pair of matrices.*> On exit, A has been overwritten by its generalized Schur*> form S.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the second of the pair of matrices.*> On exit, B has been overwritten by its generalized Schur*> form T.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] SDIM*> \verbatim*> SDIM is INTEGER*> If SORT = 'N', SDIM = 0.*> If SORT = 'S', SDIM = number of eigenvalues (after sorting)*> for which SELCTG is true. (Complex conjugate pairs for which*> SELCTG is true for either eigenvalue count as 2.)*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will*> be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i*> and BETA(j),j=1,...,N are the diagonals of the complex Schur*> form (S,T) that would result if the 2-by-2 diagonal blocks of*> the real Schur form of (A,B) were further reduced to*> triangular form using 2-by-2 complex unitary transformations.*> If ALPHAI(j) is zero, then the j-th eigenvalue is real; if*> positive, then the j-th and (j+1)-st eigenvalues are a*> complex conjugate pair, with ALPHAI(j+1) negative.*>*> Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)*> may easily over- or underflow, and BETA(j) may even be zero.*> Thus, the user should avoid naively computing the ratio.*> However, ALPHAR and ALPHAI will be always less than and*> usually comparable with norm(A) in magnitude, and BETA always*> less than and usually comparable with norm(B).*> \endverbatim*>*> \param[out] VSL*> \verbatim*> VSL is DOUBLE PRECISION array, dimension (LDVSL,N)*> If JOBVSL = 'V', VSL will contain the left Schur vectors.*> Not referenced if JOBVSL = 'N'.*> \endverbatim*>*> \param[in] LDVSL*> \verbatim*> LDVSL is INTEGER*> The leading dimension of the matrix VSL. LDVSL >=1, and*> if JOBVSL = 'V', LDVSL >= N.*> \endverbatim*>*> \param[out] VSR*> \verbatim*> VSR is DOUBLE PRECISION array, dimension (LDVSR,N)*> If JOBVSR = 'V', VSR will contain the right Schur vectors.*> Not referenced if JOBVSR = 'N'.*> \endverbatim*>*> \param[in] LDVSR*> \verbatim*> LDVSR is INTEGER*> The leading dimension of the matrix VSR. LDVSR >= 1, and*> if JOBVSR = 'V', LDVSR >= N.*> \endverbatim*>*> \param[out] RCONDE*> \verbatim*> RCONDE is DOUBLE PRECISION array, dimension ( 2 )*> If SENSE = 'E' or 'B', RCONDE(1) and RCONDE(2) contain the*> reciprocal condition numbers for the average of the selected*> eigenvalues.*> Not referenced if SENSE = 'N' or 'V'.*> \endverbatim*>*> \param[out] RCONDV*> \verbatim*> RCONDV is DOUBLE PRECISION array, dimension ( 2 )*> If SENSE = 'V' or 'B', RCONDV(1) and RCONDV(2) contain the*> reciprocal condition numbers for the selected deflating*> subspaces.*> Not referenced if SENSE = 'N' or 'E'.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N = 0, LWORK >= 1, else if SENSE = 'E', 'V', or 'B',*> LWORK >= max( 8*N, 6*N+16, 2*SDIM*(N-SDIM) ), else*> LWORK >= max( 8*N, 6*N+16 ).*> Note that 2*SDIM*(N-SDIM) <= N*N/2.*> Note also that an error is only returned if*> LWORK < max( 8*N, 6*N+16), but if SENSE = 'E' or 'V' or 'B'*> this may not be large enough.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the bound on the optimal size of the WORK*> array and the minimum size of the IWORK array, returns these*> values as the first entries of the WORK and IWORK arrays, and*> no error message related to LWORK or LIWORK is issued by*> XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If SENSE = 'N' or N = 0, LIWORK >= 1, otherwise*> LIWORK >= N+6.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the bound on the optimal size of the*> WORK array and the minimum size of the IWORK array, returns*> these values as the first entries of the WORK and IWORK*> arrays, and no error message related to LWORK or LIWORK is*> issued by XERBLA.*> \endverbatim*>*> \param[out] BWORK*> \verbatim*> BWORK is LOGICAL array, dimension (N)*> Not referenced if SORT = 'N'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1,...,N:*> The QZ iteration failed. (A,B) are not in Schur*> form, but ALPHAR(j), ALPHAI(j), and BETA(j) should*> be correct for j=INFO+1,...,N.*> > N: =N+1: other than QZ iteration failed in DHGEQZ*> =N+2: after reordering, roundoff changed values of*> some complex eigenvalues so that leading*> eigenvalues in the Generalized Schur form no*> longer satisfy SELCTG=.TRUE. This could also*> be caused due to scaling.*> =N+3: reordering failed in DTGSEN.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleGEeigen**> \par Further Details:* =====================*>*> \verbatim*>*> An approximate (asymptotic) bound on the average absolute error of*> the selected eigenvalues is*>*> EPS * norm((A, B)) / RCONDE( 1 ).*>*> An approximate (asymptotic) bound on the maximum angular error in*> the computed deflating subspaces is*>*> EPS * norm((A, B)) / RCONDV( 2 ).*>*> See LAPACK User's Guide, section 4.11 for more information.*> \endverbatim*>* =====================================================================SUBROUTINE DGGESX( JOBVSL, JOBVSR, SORT, SELCTG, SENSE, N, A, LDA,$ B, LDB, SDIM, ALPHAR, ALPHAI, BETA, VSL, LDVSL,$ VSR, LDVSR, RCONDE, RCONDV, WORK, LWORK, IWORK,$ LIWORK, BWORK, INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER JOBVSL, JOBVSR, SENSE, SORTINTEGER INFO, LDA, LDB, LDVSL, LDVSR, LIWORK, LWORK, N,$ SDIM* ..* .. Array Arguments ..LOGICAL BWORK( * )INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), RCONDE( 2 ),$ RCONDV( 2 ), VSL( LDVSL, * ), VSR( LDVSR, * ),$ WORK( * )* ..* .. Function Arguments ..LOGICAL SELCTGEXTERNAL SELCTG* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL CURSL, ILASCL, ILBSCL, ILVSL, ILVSR, LASTSL,$ LQUERY, LST2SL, WANTSB, WANTSE, WANTSN, WANTST,$ WANTSVINTEGER I, ICOLS, IERR, IHI, IJOB, IJOBVL, IJOBVR,$ ILEFT, ILO, IP, IRIGHT, IROWS, ITAU, IWRK,$ LIWMIN, LWRK, MAXWRK, MINWRKDOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS, PL,$ PR, SAFMAX, SAFMIN, SMLNUM* ..* .. Local Arrays ..DOUBLE PRECISION DIF( 2 )* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,$ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGSEN,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode the input arguments*IF( LSAME( JOBVSL, 'N' ) ) THENIJOBVL = 1ILVSL = .FALSE.ELSE IF( LSAME( JOBVSL, 'V' ) ) THENIJOBVL = 2ILVSL = .TRUE.ELSEIJOBVL = -1ILVSL = .FALSE.END IF*IF( LSAME( JOBVSR, 'N' ) ) THENIJOBVR = 1ILVSR = .FALSE.ELSE IF( LSAME( JOBVSR, 'V' ) ) THENIJOBVR = 2ILVSR = .TRUE.ELSEIJOBVR = -1ILVSR = .FALSE.END IF*WANTST = LSAME( SORT, 'S' )WANTSN = LSAME( SENSE, 'N' )WANTSE = LSAME( SENSE, 'E' )WANTSV = LSAME( SENSE, 'V' )WANTSB = LSAME( SENSE, 'B' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )IF( WANTSN ) THENIJOB = 0ELSE IF( WANTSE ) THENIJOB = 1ELSE IF( WANTSV ) THENIJOB = 2ELSE IF( WANTSB ) THENIJOB = 4END IF** Test the input arguments*INFO = 0IF( IJOBVL.LE.0 ) THENINFO = -1ELSE IF( IJOBVR.LE.0 ) THENINFO = -2ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THENINFO = -3ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSV .OR. WANTSB ) .OR.$ ( .NOT.WANTST .AND. .NOT.WANTSN ) ) THENINFO = -5ELSE IF( N.LT.0 ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDVSL.LT.1 .OR. ( ILVSL .AND. LDVSL.LT.N ) ) THENINFO = -16ELSE IF( LDVSR.LT.1 .OR. ( ILVSR .AND. LDVSR.LT.N ) ) THENINFO = -18END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV.)*IF( INFO.EQ.0 ) THENIF( N.GT.0) THENMINWRK = MAX( 8*N, 6*N + 16 )MAXWRK = MINWRK - N +$ N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 )MAXWRK = MAX( MAXWRK, MINWRK - N +$ N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, -1 ) )IF( ILVSL ) THENMAXWRK = MAX( MAXWRK, MINWRK - N +$ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) )END IFLWRK = MAXWRKIF( IJOB.GE.1 )$ LWRK = MAX( LWRK, N*N/2 )ELSEMINWRK = 1MAXWRK = 1LWRK = 1END IFWORK( 1 ) = LWRKIF( WANTSN .OR. N.EQ.0 ) THENLIWMIN = 1ELSELIWMIN = N + 6END IFIWORK( 1 ) = LIWMIN*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -22ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -24END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGGESX', -INFO )RETURNELSE IF (LQUERY) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSDIM = 0RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINCALL DLABAD( SAFMIN, SAFMAX )SMLNUM = SQRT( SAFMIN ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, WORK )ILASCL = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENANRMTO = SMLNUMILASCL = .TRUE.ELSE IF( ANRM.GT.BIGNUM ) THENANRMTO = BIGNUMILASCL = .TRUE.END IFIF( ILASCL )$ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )** Scale B if max element outside range [SMLNUM,BIGNUM]*BNRM = DLANGE( 'M', N, N, B, LDB, WORK )ILBSCL = .FALSE.IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THENBNRMTO = SMLNUMILBSCL = .TRUE.ELSE IF( BNRM.GT.BIGNUM ) THENBNRMTO = BIGNUMILBSCL = .TRUE.END IFIF( ILBSCL )$ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )** Permute the matrix to make it more nearly triangular* (Workspace: need 6*N + 2*N for permutation parameters)*ILEFT = 1IRIGHT = N + 1IWRK = IRIGHT + NCALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), WORK( IWRK ), IERR )** Reduce B to triangular form (QR decomposition of B)* (Workspace: need N, prefer N*NB)*IROWS = IHI + 1 - ILOICOLS = N + 1 - ILOITAU = IWRKIWRK = ITAU + IROWSCALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),$ WORK( IWRK ), LWORK+1-IWRK, IERR )** Apply the orthogonal transformation to matrix A* (Workspace: need N, prefer N*NB)*CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),$ LWORK+1-IWRK, IERR )** Initialize VSL* (Workspace: need N, prefer N*NB)*IF( ILVSL ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, VSL, LDVSL )IF( IROWS.GT.1 ) THENCALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,$ VSL( ILO+1, ILO ), LDVSL )END IFCALL DORGQR( IROWS, IROWS, IROWS, VSL( ILO, ILO ), LDVSL,$ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )END IF** Initialize VSR*IF( ILVSR )$ CALL DLASET( 'Full', N, N, ZERO, ONE, VSR, LDVSR )** Reduce to generalized Hessenberg form* (Workspace: none needed)*CALL DGGHRD( JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB, VSL,$ LDVSL, VSR, LDVSR, IERR )*SDIM = 0** Perform QZ algorithm, computing Schur vectors if desired* (Workspace: need N)*IWRK = ITAUCALL DHGEQZ( 'S', JOBVSL, JOBVSR, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,$ WORK( IWRK ), LWORK+1-IWRK, IERR )IF( IERR.NE.0 ) THENIF( IERR.GT.0 .AND. IERR.LE.N ) THENINFO = IERRELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THENINFO = IERR - NELSEINFO = N + 1END IFGO TO 60END IF** Sort eigenvalues ALPHA/BETA and compute the reciprocal of* condition number(s)* (Workspace: If IJOB >= 1, need MAX( 8*(N+1), 2*SDIM*(N-SDIM) )* otherwise, need 8*(N+1) )*IF( WANTST ) THEN** Undo scaling on eigenvalues before SELCTGing*IF( ILASCL ) THENCALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N,$ IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N,$ IERR )END IFIF( ILBSCL )$ CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )** Select eigenvalues*DO 10 I = 1, NBWORK( I ) = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )10 CONTINUE** Reorder eigenvalues, transform Generalized Schur vectors, and* compute reciprocal condition numbers*CALL DTGSEN( IJOB, ILVSL, ILVSR, BWORK, N, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VSL, LDVSL, VSR, LDVSR,$ SDIM, PL, PR, DIF, WORK( IWRK ), LWORK-IWRK+1,$ IWORK, LIWORK, IERR )*IF( IJOB.GE.1 )$ MAXWRK = MAX( MAXWRK, 2*SDIM*( N-SDIM ) )IF( IERR.EQ.-22 ) THEN** not enough real workspace*INFO = -22ELSEIF( IJOB.EQ.1 .OR. IJOB.EQ.4 ) THENRCONDE( 1 ) = PLRCONDE( 2 ) = PREND IFIF( IJOB.EQ.2 .OR. IJOB.EQ.4 ) THENRCONDV( 1 ) = DIF( 1 )RCONDV( 2 ) = DIF( 2 )END IFIF( IERR.EQ.1 )$ INFO = N + 3END IF*END IF** Apply permutation to VSL and VSR* (Workspace: none needed)*IF( ILVSL )$ CALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VSL, LDVSL, IERR )*IF( ILVSR )$ CALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VSR, LDVSR, IERR )** Check if unscaling would cause over/underflow, if so, rescale* (ALPHAR(I),ALPHAI(I),BETA(I)) so BETA(I) is on the order of* B(I,I) and ALPHAR(I) and ALPHAI(I) are on the order of A(I,I)*IF( ILASCL ) THENDO 20 I = 1, NIF( ALPHAI( I ).NE.ZERO ) THENIF( ( ALPHAR( I ) / SAFMAX ).GT.( ANRMTO / ANRM ) .OR.$ ( SAFMIN / ALPHAR( I ) ).GT.( ANRM / ANRMTO ) ) THENWORK( 1 ) = ABS( A( I, I ) / ALPHAR( I ) )BETA( I ) = BETA( I )*WORK( 1 )ALPHAR( I ) = ALPHAR( I )*WORK( 1 )ALPHAI( I ) = ALPHAI( I )*WORK( 1 )ELSE IF( ( ALPHAI( I ) / SAFMAX ).GT.$ ( ANRMTO / ANRM ) .OR.$ ( SAFMIN / ALPHAI( I ) ).GT.( ANRM / ANRMTO ) )$ THENWORK( 1 ) = ABS( A( I, I+1 ) / ALPHAI( I ) )BETA( I ) = BETA( I )*WORK( 1 )ALPHAR( I ) = ALPHAR( I )*WORK( 1 )ALPHAI( I ) = ALPHAI( I )*WORK( 1 )END IFEND IF20 CONTINUEEND IF*IF( ILBSCL ) THENDO 30 I = 1, NIF( ALPHAI( I ).NE.ZERO ) THENIF( ( BETA( I ) / SAFMAX ).GT.( BNRMTO / BNRM ) .OR.$ ( SAFMIN / BETA( I ) ).GT.( BNRM / BNRMTO ) ) THENWORK( 1 ) = ABS( B( I, I ) / BETA( I ) )BETA( I ) = BETA( I )*WORK( 1 )ALPHAR( I ) = ALPHAR( I )*WORK( 1 )ALPHAI( I ) = ALPHAI( I )*WORK( 1 )END IFEND IF30 CONTINUEEND IF** Undo scaling*IF( ILASCL ) THENCALL DLASCL( 'H', 0, 0, ANRMTO, ANRM, N, N, A, LDA, IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )END IF*IF( ILBSCL ) THENCALL DLASCL( 'U', 0, 0, BNRMTO, BNRM, N, N, B, LDB, IERR )CALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )END IF*IF( WANTST ) THEN** Check if reordering is correct*LASTSL = .TRUE.LST2SL = .TRUE.SDIM = 0IP = 0DO 50 I = 1, NCURSL = SELCTG( ALPHAR( I ), ALPHAI( I ), BETA( I ) )IF( ALPHAI( I ).EQ.ZERO ) THENIF( CURSL )$ SDIM = SDIM + 1IP = 0IF( CURSL .AND. .NOT.LASTSL )$ INFO = N + 2ELSEIF( IP.EQ.1 ) THEN** Last eigenvalue of conjugate pair*CURSL = CURSL .OR. LASTSLLASTSL = CURSLIF( CURSL )$ SDIM = SDIM + 2IP = -1IF( CURSL .AND. .NOT.LST2SL )$ INFO = N + 2ELSE** First eigenvalue of conjugate pair*IP = 1END IFEND IFLST2SL = LASTSLLASTSL = CURSL50 CONTINUE*END IF*60 CONTINUE*WORK( 1 ) = MAXWRKIWORK( 1 ) = LIWMIN*RETURN** End of DGGESX*END*> \brief <b> DGGEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGEV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggev.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggev.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggev.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,* BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBVL, JOBVR* INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), VL( LDVL, * ),* $ VR( LDVR, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGEV computes for a pair of N-by-N real nonsymmetric matrices (A,B)*> the generalized eigenvalues, and optionally, the left and/or right*> generalized eigenvectors.*>*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar*> lambda or a ratio alpha/beta = lambda, such that A - lambda*B is*> singular. It is usually represented as the pair (alpha,beta), as*> there is a reasonable interpretation for beta=0, and even for both*> being zero.*>*> The right eigenvector v(j) corresponding to the eigenvalue lambda(j)*> of (A,B) satisfies*>*> A * v(j) = lambda(j) * B * v(j).*>*> The left eigenvector u(j) corresponding to the eigenvalue lambda(j)*> of (A,B) satisfies*>*> u(j)**H * A = lambda(j) * u(j)**H * B .*>*> where u(j)**H is the conjugate-transpose of u(j).*>*> \endverbatim** Arguments:* ==========**> \param[in] JOBVL*> \verbatim*> JOBVL is CHARACTER*1*> = 'N': do not compute the left generalized eigenvectors;*> = 'V': compute the left generalized eigenvectors.*> \endverbatim*>*> \param[in] JOBVR*> \verbatim*> JOBVR is CHARACTER*1*> = 'N': do not compute the right generalized eigenvectors;*> = 'V': compute the right generalized eigenvectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A, B, VL, and VR. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the matrix A in the pair (A,B).*> On exit, A has been overwritten.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the matrix B in the pair (A,B).*> On exit, B has been overwritten.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will*> be the generalized eigenvalues. If ALPHAI(j) is zero, then*> the j-th eigenvalue is real; if positive, then the j-th and*> (j+1)-st eigenvalues are a complex conjugate pair, with*> ALPHAI(j+1) negative.*>*> Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)*> may easily over- or underflow, and BETA(j) may even be zero.*> Thus, the user should avoid naively computing the ratio*> alpha/beta. However, ALPHAR and ALPHAI will be always less*> than and usually comparable with norm(A) in magnitude, and*> BETA always less than and usually comparable with norm(B).*> \endverbatim*>*> \param[out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,N)*> If JOBVL = 'V', the left eigenvectors u(j) are stored one*> after another in the columns of VL, in the same order as*> their eigenvalues. If the j-th eigenvalue is real, then*> u(j) = VL(:,j), the j-th column of VL. If the j-th and*> (j+1)-th eigenvalues form a complex conjugate pair, then*> u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).*> Each eigenvector is scaled so the largest component has*> abs(real part)+abs(imag. part)=1.*> Not referenced if JOBVL = 'N'.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the matrix VL. LDVL >= 1, and*> if JOBVL = 'V', LDVL >= N.*> \endverbatim*>*> \param[out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,N)*> If JOBVR = 'V', the right eigenvectors v(j) are stored one*> after another in the columns of VR, in the same order as*> their eigenvalues. If the j-th eigenvalue is real, then*> v(j) = VR(:,j), the j-th column of VR. If the j-th and*> (j+1)-th eigenvalues form a complex conjugate pair, then*> v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).*> Each eigenvector is scaled so the largest component has*> abs(real part)+abs(imag. part)=1.*> Not referenced if JOBVR = 'N'.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the matrix VR. LDVR >= 1, and*> if JOBVR = 'V', LDVR >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,8*N).*> For good performance, LWORK must generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1,...,N:*> The QZ iteration failed. No eigenvectors have been*> calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)*> should be correct for j=INFO+1,...,N.*> > N: =N+1: other than QZ iteration failed in DHGEQZ.*> =N+2: error return from DTGEVC.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleGEeigen** =====================================================================SUBROUTINE DGGEV( JOBVL, JOBVR, N, A, LDA, B, LDB, ALPHAR, ALPHAI,$ BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER JOBVL, JOBVRINTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), VL( LDVL, * ),$ VR( LDVR, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERYCHARACTER CHTEMPINTEGER ICOLS, IERR, IHI, IJOBVL, IJOBVR, ILEFT, ILO,$ IN, IRIGHT, IROWS, ITAU, IWRK, JC, JR, MAXWRK,$ MINWRKDOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,$ SMLNUM, TEMP* ..* .. Local Arrays ..LOGICAL LDUMMA( 1 )* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,$ DLACPY,DLASCL, DLASET, DORGQR, DORMQR, DTGEVC,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode the input arguments*IF( LSAME( JOBVL, 'N' ) ) THENIJOBVL = 1ILVL = .FALSE.ELSE IF( LSAME( JOBVL, 'V' ) ) THENIJOBVL = 2ILVL = .TRUE.ELSEIJOBVL = -1ILVL = .FALSE.END IF*IF( LSAME( JOBVR, 'N' ) ) THENIJOBVR = 1ILVR = .FALSE.ELSE IF( LSAME( JOBVR, 'V' ) ) THENIJOBVR = 2ILVR = .TRUE.ELSEIJOBVR = -1ILVR = .FALSE.END IFILV = ILVL .OR. ILVR** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( IJOBVL.LE.0 ) THENINFO = -1ELSE IF( IJOBVR.LE.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THENINFO = -12ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THENINFO = -14END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV. The workspace is* computed assuming ILO = 1 and IHI = N, the worst case.)*IF( INFO.EQ.0 ) THENMINWRK = MAX( 1, 8*N )MAXWRK = MAX( 1, N*( 7 +$ ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 ) ) )MAXWRK = MAX( MAXWRK, N*( 7 +$ ILAENV( 1, 'DORMQR', ' ', N, 1, N, 0 ) ) )IF( ILVL ) THENMAXWRK = MAX( MAXWRK, N*( 7 +$ ILAENV( 1, 'DORGQR', ' ', N, 1, N, -1 ) ) )END IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY )$ INFO = -16END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGGEV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, WORK )ILASCL = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENANRMTO = SMLNUMILASCL = .TRUE.ELSE IF( ANRM.GT.BIGNUM ) THENANRMTO = BIGNUMILASCL = .TRUE.END IFIF( ILASCL )$ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )** Scale B if max element outside range [SMLNUM,BIGNUM]*BNRM = DLANGE( 'M', N, N, B, LDB, WORK )ILBSCL = .FALSE.IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THENBNRMTO = SMLNUMILBSCL = .TRUE.ELSE IF( BNRM.GT.BIGNUM ) THENBNRMTO = BIGNUMILBSCL = .TRUE.END IFIF( ILBSCL )$ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )** Permute the matrices A, B to isolate eigenvalues if possible* (Workspace: need 6*N)*ILEFT = 1IRIGHT = N + 1IWRK = IRIGHT + NCALL DGGBAL( 'P', N, A, LDA, B, LDB, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), WORK( IWRK ), IERR )** Reduce B to triangular form (QR decomposition of B)* (Workspace: need N, prefer N*NB)*IROWS = IHI + 1 - ILOIF( ILV ) THENICOLS = N + 1 - ILOELSEICOLS = IROWSEND IFITAU = IWRKIWRK = ITAU + IROWSCALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),$ WORK( IWRK ), LWORK+1-IWRK, IERR )** Apply the orthogonal transformation to matrix A* (Workspace: need N, prefer N*NB)*CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),$ LWORK+1-IWRK, IERR )** Initialize VL* (Workspace: need N, prefer N*NB)*IF( ILVL ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )IF( IROWS.GT.1 ) THENCALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,$ VL( ILO+1, ILO ), LDVL )END IFCALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,$ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )END IF** Initialize VR*IF( ILVR )$ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )** Reduce to generalized Hessenberg form* (Workspace: none needed)*IF( ILV ) THEN** Eigenvectors requested -- work on whole matrix.*CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,$ LDVL, VR, LDVR, IERR )ELSECALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,$ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )END IF** Perform QZ algorithm (Compute eigenvalues, and optionally, the* Schur forms and Schur vectors)* (Workspace: need N)*IWRK = ITAUIF( ILV ) THENCHTEMP = 'S'ELSECHTEMP = 'E'END IFCALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR,$ WORK( IWRK ), LWORK+1-IWRK, IERR )IF( IERR.NE.0 ) THENIF( IERR.GT.0 .AND. IERR.LE.N ) THENINFO = IERRELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THENINFO = IERR - NELSEINFO = N + 1END IFGO TO 110END IF** Compute Eigenvectors* (Workspace: need 6*N)*IF( ILV ) THENIF( ILVL ) THENIF( ILVR ) THENCHTEMP = 'B'ELSECHTEMP = 'L'END IFELSECHTEMP = 'R'END IFCALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL, LDVL,$ VR, LDVR, N, IN, WORK( IWRK ), IERR )IF( IERR.NE.0 ) THENINFO = N + 2GO TO 110END IF** Undo balancing on VL and VR and normalization* (Workspace: none needed)*IF( ILVL ) THENCALL DGGBAK( 'P', 'L', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VL, LDVL, IERR )DO 50 JC = 1, NIF( ALPHAI( JC ).LT.ZERO )$ GO TO 50TEMP = ZEROIF( ALPHAI( JC ).EQ.ZERO ) THENDO 10 JR = 1, NTEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )10 CONTINUEELSEDO 20 JR = 1, NTEMP = MAX( TEMP, ABS( VL( JR, JC ) )+$ ABS( VL( JR, JC+1 ) ) )20 CONTINUEEND IFIF( TEMP.LT.SMLNUM )$ GO TO 50TEMP = ONE / TEMPIF( ALPHAI( JC ).EQ.ZERO ) THENDO 30 JR = 1, NVL( JR, JC ) = VL( JR, JC )*TEMP30 CONTINUEELSEDO 40 JR = 1, NVL( JR, JC ) = VL( JR, JC )*TEMPVL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP40 CONTINUEEND IF50 CONTINUEEND IFIF( ILVR ) THENCALL DGGBAK( 'P', 'R', N, ILO, IHI, WORK( ILEFT ),$ WORK( IRIGHT ), N, VR, LDVR, IERR )DO 100 JC = 1, NIF( ALPHAI( JC ).LT.ZERO )$ GO TO 100TEMP = ZEROIF( ALPHAI( JC ).EQ.ZERO ) THENDO 60 JR = 1, NTEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )60 CONTINUEELSEDO 70 JR = 1, NTEMP = MAX( TEMP, ABS( VR( JR, JC ) )+$ ABS( VR( JR, JC+1 ) ) )70 CONTINUEEND IFIF( TEMP.LT.SMLNUM )$ GO TO 100TEMP = ONE / TEMPIF( ALPHAI( JC ).EQ.ZERO ) THENDO 80 JR = 1, NVR( JR, JC ) = VR( JR, JC )*TEMP80 CONTINUEELSEDO 90 JR = 1, NVR( JR, JC ) = VR( JR, JC )*TEMPVR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP90 CONTINUEEND IF100 CONTINUEEND IF** End of eigenvector calculation*END IF** Undo scaling if necessary*110 CONTINUE*IF( ILASCL ) THENCALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )END IF*IF( ILBSCL ) THENCALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )END IF*WORK( 1 ) = MAXWRKRETURN** End of DGGEV*END*> \brief <b> DGGEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGEVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggevx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggevx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggevx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,* ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,* IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,* RCONDV, WORK, LWORK, IWORK, BWORK, INFO )** .. Scalar Arguments ..* CHARACTER BALANC, JOBVL, JOBVR, SENSE* INTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, N* DOUBLE PRECISION ABNRM, BBNRM* ..* .. Array Arguments ..* LOGICAL BWORK( * )* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), LSCALE( * ),* $ RCONDE( * ), RCONDV( * ), RSCALE( * ),* $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGEVX computes for a pair of N-by-N real nonsymmetric matrices (A,B)*> the generalized eigenvalues, and optionally, the left and/or right*> generalized eigenvectors.*>*> Optionally also, it computes a balancing transformation to improve*> the conditioning of the eigenvalues and eigenvectors (ILO, IHI,*> LSCALE, RSCALE, ABNRM, and BBNRM), reciprocal condition numbers for*> the eigenvalues (RCONDE), and reciprocal condition numbers for the*> right eigenvectors (RCONDV).*>*> A generalized eigenvalue for a pair of matrices (A,B) is a scalar*> lambda or a ratio alpha/beta = lambda, such that A - lambda*B is*> singular. It is usually represented as the pair (alpha,beta), as*> there is a reasonable interpretation for beta=0, and even for both*> being zero.*>*> The right eigenvector v(j) corresponding to the eigenvalue lambda(j)*> of (A,B) satisfies*>*> A * v(j) = lambda(j) * B * v(j) .*>*> The left eigenvector u(j) corresponding to the eigenvalue lambda(j)*> of (A,B) satisfies*>*> u(j)**H * A = lambda(j) * u(j)**H * B.*>*> where u(j)**H is the conjugate-transpose of u(j).*>*> \endverbatim** Arguments:* ==========**> \param[in] BALANC*> \verbatim*> BALANC is CHARACTER*1*> Specifies the balance option to be performed.*> = 'N': do not diagonally scale or permute;*> = 'P': permute only;*> = 'S': scale only;*> = 'B': both permute and scale.*> Computed reciprocal condition numbers will be for the*> matrices after permuting and/or balancing. Permuting does*> not change condition numbers (in exact arithmetic), but*> balancing does.*> \endverbatim*>*> \param[in] JOBVL*> \verbatim*> JOBVL is CHARACTER*1*> = 'N': do not compute the left generalized eigenvectors;*> = 'V': compute the left generalized eigenvectors.*> \endverbatim*>*> \param[in] JOBVR*> \verbatim*> JOBVR is CHARACTER*1*> = 'N': do not compute the right generalized eigenvectors;*> = 'V': compute the right generalized eigenvectors.*> \endverbatim*>*> \param[in] SENSE*> \verbatim*> SENSE is CHARACTER*1*> Determines which reciprocal condition numbers are computed.*> = 'N': none are computed;*> = 'E': computed for eigenvalues only;*> = 'V': computed for eigenvectors only;*> = 'B': computed for eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A, B, VL, and VR. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the matrix A in the pair (A,B).*> On exit, A has been overwritten. If JOBVL='V' or JOBVR='V'*> or both, then A contains the first part of the real Schur*> form of the "balanced" versions of the input A and B.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the matrix B in the pair (A,B).*> On exit, B has been overwritten. If JOBVL='V' or JOBVR='V'*> or both, then B contains the second part of the real Schur*> form of the "balanced" versions of the input A and B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will*> be the generalized eigenvalues. If ALPHAI(j) is zero, then*> the j-th eigenvalue is real; if positive, then the j-th and*> (j+1)-st eigenvalues are a complex conjugate pair, with*> ALPHAI(j+1) negative.*>*> Note: the quotients ALPHAR(j)/BETA(j) and ALPHAI(j)/BETA(j)*> may easily over- or underflow, and BETA(j) may even be zero.*> Thus, the user should avoid naively computing the ratio*> ALPHA/BETA. However, ALPHAR and ALPHAI will be always less*> than and usually comparable with norm(A) in magnitude, and*> BETA always less than and usually comparable with norm(B).*> \endverbatim*>*> \param[out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,N)*> If JOBVL = 'V', the left eigenvectors u(j) are stored one*> after another in the columns of VL, in the same order as*> their eigenvalues. If the j-th eigenvalue is real, then*> u(j) = VL(:,j), the j-th column of VL. If the j-th and*> (j+1)-th eigenvalues form a complex conjugate pair, then*> u(j) = VL(:,j)+i*VL(:,j+1) and u(j+1) = VL(:,j)-i*VL(:,j+1).*> Each eigenvector will be scaled so the largest component have*> abs(real part) + abs(imag. part) = 1.*> Not referenced if JOBVL = 'N'.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the matrix VL. LDVL >= 1, and*> if JOBVL = 'V', LDVL >= N.*> \endverbatim*>*> \param[out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,N)*> If JOBVR = 'V', the right eigenvectors v(j) are stored one*> after another in the columns of VR, in the same order as*> their eigenvalues. If the j-th eigenvalue is real, then*> v(j) = VR(:,j), the j-th column of VR. If the j-th and*> (j+1)-th eigenvalues form a complex conjugate pair, then*> v(j) = VR(:,j)+i*VR(:,j+1) and v(j+1) = VR(:,j)-i*VR(:,j+1).*> Each eigenvector will be scaled so the largest component have*> abs(real part) + abs(imag. part) = 1.*> Not referenced if JOBVR = 'N'.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the matrix VR. LDVR >= 1, and*> if JOBVR = 'V', LDVR >= N.*> \endverbatim*>*> \param[out] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[out] IHI*> \verbatim*> IHI is INTEGER*> ILO and IHI are integer values such that on exit*> A(i,j) = 0 and B(i,j) = 0 if i > j and*> j = 1,...,ILO-1 or i = IHI+1,...,N.*> If BALANC = 'N' or 'S', ILO = 1 and IHI = N.*> \endverbatim*>*> \param[out] LSCALE*> \verbatim*> LSCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and scaling factors applied*> to the left side of A and B. If PL(j) is the index of the*> row interchanged with row j, and DL(j) is the scaling*> factor applied to row j, then*> LSCALE(j) = PL(j) for j = 1,...,ILO-1*> = DL(j) for j = ILO,...,IHI*> = PL(j) for j = IHI+1,...,N.*> The order in which the interchanges are made is N to IHI+1,*> then 1 to ILO-1.*> \endverbatim*>*> \param[out] RSCALE*> \verbatim*> RSCALE is DOUBLE PRECISION array, dimension (N)*> Details of the permutations and scaling factors applied*> to the right side of A and B. If PR(j) is the index of the*> column interchanged with column j, and DR(j) is the scaling*> factor applied to column j, then*> RSCALE(j) = PR(j) for j = 1,...,ILO-1*> = DR(j) for j = ILO,...,IHI*> = PR(j) for j = IHI+1,...,N*> The order in which the interchanges are made is N to IHI+1,*> then 1 to ILO-1.*> \endverbatim*>*> \param[out] ABNRM*> \verbatim*> ABNRM is DOUBLE PRECISION*> The one-norm of the balanced matrix A.*> \endverbatim*>*> \param[out] BBNRM*> \verbatim*> BBNRM is DOUBLE PRECISION*> The one-norm of the balanced matrix B.*> \endverbatim*>*> \param[out] RCONDE*> \verbatim*> RCONDE is DOUBLE PRECISION array, dimension (N)*> If SENSE = 'E' or 'B', the reciprocal condition numbers of*> the eigenvalues, stored in consecutive elements of the array.*> For a complex conjugate pair of eigenvalues two consecutive*> elements of RCONDE are set to the same value. Thus RCONDE(j),*> RCONDV(j), and the j-th columns of VL and VR all correspond*> to the j-th eigenpair.*> If SENSE = 'N or 'V', RCONDE is not referenced.*> \endverbatim*>*> \param[out] RCONDV*> \verbatim*> RCONDV is DOUBLE PRECISION array, dimension (N)*> If SENSE = 'V' or 'B', the estimated reciprocal condition*> numbers of the eigenvectors, stored in consecutive elements*> of the array. For a complex eigenvector two consecutive*> elements of RCONDV are set to the same value. If the*> eigenvalues cannot be reordered to compute RCONDV(j),*> RCONDV(j) is set to 0; this can only occur when the true*> value would be very small anyway.*> If SENSE = 'N' or 'E', RCONDV is not referenced.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,2*N).*> If BALANC = 'S' or 'B', or JOBVL = 'V', or JOBVR = 'V',*> LWORK >= max(1,6*N).*> If SENSE = 'E' or 'B', LWORK >= max(1,10*N).*> If SENSE = 'V' or 'B', LWORK >= 2*N*N+8*N+16.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N+6)*> If SENSE = 'E', IWORK is not referenced.*> \endverbatim*>*> \param[out] BWORK*> \verbatim*> BWORK is LOGICAL array, dimension (N)*> If SENSE = 'N', BWORK is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1,...,N:*> The QZ iteration failed. No eigenvectors have been*> calculated, but ALPHAR(j), ALPHAI(j), and BETA(j)*> should be correct for j=INFO+1,...,N.*> > N: =N+1: other than QZ iteration failed in DHGEQZ.*> =N+2: error return from DTGEVC.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleGEeigen**> \par Further Details:* =====================*>*> \verbatim*>*> Balancing a matrix pair (A,B) includes, first, permuting rows and*> columns to isolate eigenvalues, second, applying diagonal similarity*> transformation to the rows and columns to make the rows and columns*> as close in norm as possible. The computed reciprocal condition*> numbers correspond to the balanced matrix. Permuting rows and columns*> will not change the condition numbers (in exact arithmetic) but*> diagonal scaling will. For further explanation of balancing, see*> section 4.11.1.2 of LAPACK Users' Guide.*>*> An approximate error bound on the chordal distance between the i-th*> computed generalized eigenvalue w and the corresponding exact*> eigenvalue lambda is*>*> chord(w, lambda) <= EPS * norm(ABNRM, BBNRM) / RCONDE(I)*>*> An approximate error bound for the angle between the i-th computed*> eigenvector VL(i) or VR(i) is given by*>*> EPS * norm(ABNRM, BBNRM) / DIF(i).*>*> For further explanation of the reciprocal condition numbers RCONDE*> and RCONDV, see section 4.11 of LAPACK User's Guide.*> \endverbatim*>* =====================================================================SUBROUTINE DGGEVX( BALANC, JOBVL, JOBVR, SENSE, N, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, ILO,$ IHI, LSCALE, RSCALE, ABNRM, BBNRM, RCONDE,$ RCONDV, WORK, LWORK, IWORK, BWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER BALANC, JOBVL, JOBVR, SENSEINTEGER IHI, ILO, INFO, LDA, LDB, LDVL, LDVR, LWORK, NDOUBLE PRECISION ABNRM, BBNRM* ..* .. Array Arguments ..LOGICAL BWORK( * )INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), LSCALE( * ),$ RCONDE( * ), RCONDV( * ), RSCALE( * ),$ VL( LDVL, * ), VR( LDVR, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL ILASCL, ILBSCL, ILV, ILVL, ILVR, LQUERY, NOSCL,$ PAIR, WANTSB, WANTSE, WANTSN, WANTSVCHARACTER CHTEMPINTEGER I, ICOLS, IERR, IJOBVL, IJOBVR, IN, IROWS,$ ITAU, IWRK, IWRK1, J, JC, JR, M, MAXWRK,$ MINWRK, MMDOUBLE PRECISION ANRM, ANRMTO, BIGNUM, BNRM, BNRMTO, EPS,$ SMLNUM, TEMP* ..* .. Local Arrays ..LOGICAL LDUMMA( 1 )* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGGBAK, DGGBAL, DGGHRD, DHGEQZ, DLABAD,$ DLACPY, DLASCL, DLASET, DORGQR, DORMQR, DTGEVC,$ DTGSNA, XERBLA* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, ILAENV, DLAMCH, DLANGE* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode the input arguments*IF( LSAME( JOBVL, 'N' ) ) THENIJOBVL = 1ILVL = .FALSE.ELSE IF( LSAME( JOBVL, 'V' ) ) THENIJOBVL = 2ILVL = .TRUE.ELSEIJOBVL = -1ILVL = .FALSE.END IF*IF( LSAME( JOBVR, 'N' ) ) THENIJOBVR = 1ILVR = .FALSE.ELSE IF( LSAME( JOBVR, 'V' ) ) THENIJOBVR = 2ILVR = .TRUE.ELSEIJOBVR = -1ILVR = .FALSE.END IFILV = ILVL .OR. ILVR*NOSCL = LSAME( BALANC, 'N' ) .OR. LSAME( BALANC, 'P' )WANTSN = LSAME( SENSE, 'N' )WANTSE = LSAME( SENSE, 'E' )WANTSV = LSAME( SENSE, 'V' )WANTSB = LSAME( SENSE, 'B' )** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( .NOT.( LSAME( BALANC, 'N' ) .OR. LSAME( BALANC,$ 'S' ) .OR. LSAME( BALANC, 'P' ) .OR. LSAME( BALANC, 'B' ) ) )$ THENINFO = -1ELSE IF( IJOBVL.LE.0 ) THENINFO = -2ELSE IF( IJOBVR.LE.0 ) THENINFO = -3ELSE IF( .NOT.( WANTSN .OR. WANTSE .OR. WANTSB .OR. WANTSV ) )$ THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDVL.LT.1 .OR. ( ILVL .AND. LDVL.LT.N ) ) THENINFO = -14ELSE IF( LDVR.LT.1 .OR. ( ILVR .AND. LDVR.LT.N ) ) THENINFO = -16END IF** Compute workspace* (Note: Comments in the code beginning "Workspace:" describe the* minimal amount of workspace needed at that point in the code,* as well as the preferred amount for good performance.* NB refers to the optimal block size for the immediately* following subroutine, as returned by ILAENV. The workspace is* computed assuming ILO = 1 and IHI = N, the worst case.)*IF( INFO.EQ.0 ) THENIF( N.EQ.0 ) THENMINWRK = 1MAXWRK = 1ELSEIF( NOSCL .AND. .NOT.ILV ) THENMINWRK = 2*NELSEMINWRK = 6*NEND IFIF( WANTSE .OR. WANTSB ) THENMINWRK = 10*NEND IFIF( WANTSV .OR. WANTSB ) THENMINWRK = MAX( MINWRK, 2*N*( N + 4 ) + 16 )END IFMAXWRK = MINWRKMAXWRK = MAX( MAXWRK,$ N + N*ILAENV( 1, 'DGEQRF', ' ', N, 1, N, 0 ) )MAXWRK = MAX( MAXWRK,$ N + N*ILAENV( 1, 'DORMQR', ' ', N, 1, N, 0 ) )IF( ILVL ) THENMAXWRK = MAX( MAXWRK, N +$ N*ILAENV( 1, 'DORGQR', ' ', N, 1, N, 0 ) )END IFEND IFWORK( 1 ) = MAXWRK*IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THENINFO = -26END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGGEVX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SQRT( SMLNUM ) / EPSBIGNUM = ONE / SMLNUM** Scale A if max element outside range [SMLNUM,BIGNUM]*ANRM = DLANGE( 'M', N, N, A, LDA, WORK )ILASCL = .FALSE.IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THENANRMTO = SMLNUMILASCL = .TRUE.ELSE IF( ANRM.GT.BIGNUM ) THENANRMTO = BIGNUMILASCL = .TRUE.END IFIF( ILASCL )$ CALL DLASCL( 'G', 0, 0, ANRM, ANRMTO, N, N, A, LDA, IERR )** Scale B if max element outside range [SMLNUM,BIGNUM]*BNRM = DLANGE( 'M', N, N, B, LDB, WORK )ILBSCL = .FALSE.IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THENBNRMTO = SMLNUMILBSCL = .TRUE.ELSE IF( BNRM.GT.BIGNUM ) THENBNRMTO = BIGNUMILBSCL = .TRUE.END IFIF( ILBSCL )$ CALL DLASCL( 'G', 0, 0, BNRM, BNRMTO, N, N, B, LDB, IERR )** Permute and/or balance the matrix pair (A,B)* (Workspace: need 6*N if BALANC = 'S' or 'B', 1 otherwise)*CALL DGGBAL( BALANC, N, A, LDA, B, LDB, ILO, IHI, LSCALE, RSCALE,$ WORK, IERR )** Compute ABNRM and BBNRM*ABNRM = DLANGE( '1', N, N, A, LDA, WORK( 1 ) )IF( ILASCL ) THENWORK( 1 ) = ABNRMCALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, 1, 1, WORK( 1 ), 1,$ IERR )ABNRM = WORK( 1 )END IF*BBNRM = DLANGE( '1', N, N, B, LDB, WORK( 1 ) )IF( ILBSCL ) THENWORK( 1 ) = BBNRMCALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, 1, 1, WORK( 1 ), 1,$ IERR )BBNRM = WORK( 1 )END IF** Reduce B to triangular form (QR decomposition of B)* (Workspace: need N, prefer N*NB )*IROWS = IHI + 1 - ILOIF( ILV .OR. .NOT.WANTSN ) THENICOLS = N + 1 - ILOELSEICOLS = IROWSEND IFITAU = 1IWRK = ITAU + IROWSCALL DGEQRF( IROWS, ICOLS, B( ILO, ILO ), LDB, WORK( ITAU ),$ WORK( IWRK ), LWORK+1-IWRK, IERR )** Apply the orthogonal transformation to A* (Workspace: need N, prefer N*NB)*CALL DORMQR( 'L', 'T', IROWS, ICOLS, IROWS, B( ILO, ILO ), LDB,$ WORK( ITAU ), A( ILO, ILO ), LDA, WORK( IWRK ),$ LWORK+1-IWRK, IERR )** Initialize VL and/or VR* (Workspace: need N, prefer N*NB)*IF( ILVL ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, VL, LDVL )IF( IROWS.GT.1 ) THENCALL DLACPY( 'L', IROWS-1, IROWS-1, B( ILO+1, ILO ), LDB,$ VL( ILO+1, ILO ), LDVL )END IFCALL DORGQR( IROWS, IROWS, IROWS, VL( ILO, ILO ), LDVL,$ WORK( ITAU ), WORK( IWRK ), LWORK+1-IWRK, IERR )END IF*IF( ILVR )$ CALL DLASET( 'Full', N, N, ZERO, ONE, VR, LDVR )** Reduce to generalized Hessenberg form* (Workspace: none needed)*IF( ILV .OR. .NOT.WANTSN ) THEN** Eigenvectors requested -- work on whole matrix.*CALL DGGHRD( JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB, VL,$ LDVL, VR, LDVR, IERR )ELSECALL DGGHRD( 'N', 'N', IROWS, 1, IROWS, A( ILO, ILO ), LDA,$ B( ILO, ILO ), LDB, VL, LDVL, VR, LDVR, IERR )END IF** Perform QZ algorithm (Compute eigenvalues, and optionally, the* Schur forms and Schur vectors)* (Workspace: need N)*IF( ILV .OR. .NOT.WANTSN ) THENCHTEMP = 'S'ELSECHTEMP = 'E'END IF*CALL DHGEQZ( CHTEMP, JOBVL, JOBVR, N, ILO, IHI, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK,$ LWORK, IERR )IF( IERR.NE.0 ) THENIF( IERR.GT.0 .AND. IERR.LE.N ) THENINFO = IERRELSE IF( IERR.GT.N .AND. IERR.LE.2*N ) THENINFO = IERR - NELSEINFO = N + 1END IFGO TO 130END IF** Compute Eigenvectors and estimate condition numbers if desired* (Workspace: DTGEVC: need 6*N* DTGSNA: need 2*N*(N+2)+16 if SENSE = 'V' or 'B',* need N otherwise )*IF( ILV .OR. .NOT.WANTSN ) THENIF( ILV ) THENIF( ILVL ) THENIF( ILVR ) THENCHTEMP = 'B'ELSECHTEMP = 'L'END IFELSECHTEMP = 'R'END IF*CALL DTGEVC( CHTEMP, 'B', LDUMMA, N, A, LDA, B, LDB, VL,$ LDVL, VR, LDVR, N, IN, WORK, IERR )IF( IERR.NE.0 ) THENINFO = N + 2GO TO 130END IFEND IF*IF( .NOT.WANTSN ) THEN** compute eigenvectors (DTGEVC) and estimate condition* numbers (DTGSNA). Note that the definition of the condition* number is not invariant under transformation (u,v) to* (Q*u, Z*v), where (u,v) are eigenvectors of the generalized* Schur form (S,T), Q and Z are orthogonal matrices. In order* to avoid using extra 2*N*N workspace, we have to recalculate* eigenvectors and estimate one condition numbers at a time.*PAIR = .FALSE.DO 20 I = 1, N*IF( PAIR ) THENPAIR = .FALSE.GO TO 20END IFMM = 1IF( I.LT.N ) THENIF( A( I+1, I ).NE.ZERO ) THENPAIR = .TRUE.MM = 2END IFEND IF*DO 10 J = 1, NBWORK( J ) = .FALSE.10 CONTINUEIF( MM.EQ.1 ) THENBWORK( I ) = .TRUE.ELSE IF( MM.EQ.2 ) THENBWORK( I ) = .TRUE.BWORK( I+1 ) = .TRUE.END IF*IWRK = MM*N + 1IWRK1 = IWRK + MM*N** Compute a pair of left and right eigenvectors.* (compute workspace: need up to 4*N + 6*N)*IF( WANTSE .OR. WANTSB ) THENCALL DTGEVC( 'B', 'S', BWORK, N, A, LDA, B, LDB,$ WORK( 1 ), N, WORK( IWRK ), N, MM, M,$ WORK( IWRK1 ), IERR )IF( IERR.NE.0 ) THENINFO = N + 2GO TO 130END IFEND IF*CALL DTGSNA( SENSE, 'S', BWORK, N, A, LDA, B, LDB,$ WORK( 1 ), N, WORK( IWRK ), N, RCONDE( I ),$ RCONDV( I ), MM, M, WORK( IWRK1 ),$ LWORK-IWRK1+1, IWORK, IERR )*20 CONTINUEEND IFEND IF** Undo balancing on VL and VR and normalization* (Workspace: none needed)*IF( ILVL ) THENCALL DGGBAK( BALANC, 'L', N, ILO, IHI, LSCALE, RSCALE, N, VL,$ LDVL, IERR )*DO 70 JC = 1, NIF( ALPHAI( JC ).LT.ZERO )$ GO TO 70TEMP = ZEROIF( ALPHAI( JC ).EQ.ZERO ) THENDO 30 JR = 1, NTEMP = MAX( TEMP, ABS( VL( JR, JC ) ) )30 CONTINUEELSEDO 40 JR = 1, NTEMP = MAX( TEMP, ABS( VL( JR, JC ) )+$ ABS( VL( JR, JC+1 ) ) )40 CONTINUEEND IFIF( TEMP.LT.SMLNUM )$ GO TO 70TEMP = ONE / TEMPIF( ALPHAI( JC ).EQ.ZERO ) THENDO 50 JR = 1, NVL( JR, JC ) = VL( JR, JC )*TEMP50 CONTINUEELSEDO 60 JR = 1, NVL( JR, JC ) = VL( JR, JC )*TEMPVL( JR, JC+1 ) = VL( JR, JC+1 )*TEMP60 CONTINUEEND IF70 CONTINUEEND IFIF( ILVR ) THENCALL DGGBAK( BALANC, 'R', N, ILO, IHI, LSCALE, RSCALE, N, VR,$ LDVR, IERR )DO 120 JC = 1, NIF( ALPHAI( JC ).LT.ZERO )$ GO TO 120TEMP = ZEROIF( ALPHAI( JC ).EQ.ZERO ) THENDO 80 JR = 1, NTEMP = MAX( TEMP, ABS( VR( JR, JC ) ) )80 CONTINUEELSEDO 90 JR = 1, NTEMP = MAX( TEMP, ABS( VR( JR, JC ) )+$ ABS( VR( JR, JC+1 ) ) )90 CONTINUEEND IFIF( TEMP.LT.SMLNUM )$ GO TO 120TEMP = ONE / TEMPIF( ALPHAI( JC ).EQ.ZERO ) THENDO 100 JR = 1, NVR( JR, JC ) = VR( JR, JC )*TEMP100 CONTINUEELSEDO 110 JR = 1, NVR( JR, JC ) = VR( JR, JC )*TEMPVR( JR, JC+1 ) = VR( JR, JC+1 )*TEMP110 CONTINUEEND IF120 CONTINUEEND IF** Undo scaling if necessary*130 CONTINUE*IF( ILASCL ) THENCALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAR, N, IERR )CALL DLASCL( 'G', 0, 0, ANRMTO, ANRM, N, 1, ALPHAI, N, IERR )END IF*IF( ILBSCL ) THENCALL DLASCL( 'G', 0, 0, BNRMTO, BNRM, N, 1, BETA, N, IERR )END IF*WORK( 1 ) = MAXWRKRETURN** End of DGGEVX*END*> \brief \b DGGGLM** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGGLM + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggglm.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggglm.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggglm.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGGLM( N, M, P, A, LDA, B, LDB, D, X, Y, WORK, LWORK,* INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), D( * ), WORK( * ),* $ X( * ), Y( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGGLM solves a general Gauss-Markov linear model (GLM) problem:*>*> minimize || y ||_2 subject to d = A*x + B*y*> x*>*> where A is an N-by-M matrix, B is an N-by-P matrix, and d is a*> given N-vector. It is assumed that M <= N <= M+P, and*>*> rank(A) = M and rank( A B ) = N.*>*> Under these assumptions, the constrained equation is always*> consistent, and there is a unique solution x and a minimal 2-norm*> solution y, which is obtained using a generalized QR factorization*> of the matrices (A, B) given by*>*> A = Q*(R), B = Q*T*Z.*> (0)*>*> In particular, if matrix B is square nonsingular, then the problem*> GLM is equivalent to the following weighted linear least squares*> problem*>*> minimize || inv(B)*(d-A*x) ||_2*> x*>*> where inv(B) denotes the inverse of B.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of columns of the matrix A. 0 <= M <= N.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of columns of the matrix B. P >= N-M.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,M)*> On entry, the N-by-M matrix A.*> On exit, the upper triangular part of the array A contains*> the M-by-M upper triangular matrix R.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,P)*> On entry, the N-by-P matrix B.*> On exit, if N <= P, the upper triangle of the subarray*> B(1:N,P-N+1:P) contains the N-by-N upper triangular matrix T;*> if N > P, the elements on and above the (N-P)th subdiagonal*> contain the N-by-P upper trapezoidal matrix T.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, D is the left hand side of the GLM equation.*> On exit, D is destroyed.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (M)*> \endverbatim*>*> \param[out] Y*> \verbatim*> Y is DOUBLE PRECISION array, dimension (P)*>*> On exit, X and Y are the solutions of the GLM problem.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N+M+P).*> For optimum performance, LWORK >= M+min(N,P)+max(N,P)*NB,*> where NB is an upper bound for the optimal blocksizes for*> DGEQRF, SGERQF, DORMQR and SORMRQ.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1: the upper triangular factor R associated with A in the*> generalized QR factorization of the pair (A, B) is*> singular, so that rank(A) < M; the least squares*> solution could not be computed.*> = 2: the bottom (N-M) by (N-M) part of the upper trapezoidal*> factor T associated with B in the generalized QR*> factorization of the pair (A, B) is singular, so that*> rank( A B ) < N; the least squares solution could not*> be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DGGGLM( N, M, P, A, LDA, B, LDB, D, X, Y, WORK, LWORK,$ INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), D( * ), WORK( * ),$ X( * ), Y( * )* ..** ===================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, LOPT, LWKMIN, LWKOPT, NB, NB1, NB2, NB3,$ NB4, NP* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DGGQRF, DORMQR, DORMRQ, DTRTRS,$ XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NP = MIN( N, P )LQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( M.LT.0 .OR. M.GT.N ) THENINFO = -2ELSE IF( P.LT.0 .OR. P.LT.N-M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IF** Calculate workspace*IF( INFO.EQ.0) THENIF( N.EQ.0 ) THENLWKMIN = 1LWKOPT = 1ELSENB1 = ILAENV( 1, 'DGEQRF', ' ', N, M, -1, -1 )NB2 = ILAENV( 1, 'DGERQF', ' ', N, M, -1, -1 )NB3 = ILAENV( 1, 'DORMQR', ' ', N, M, P, -1 )NB4 = ILAENV( 1, 'DORMRQ', ' ', N, M, P, -1 )NB = MAX( NB1, NB2, NB3, NB4 )LWKMIN = M + N + PLWKOPT = M + NP + MAX( N, P )*NBEND IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -12END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGGGLM', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Compute the GQR factorization of matrices A and B:** Q**T*A = ( R11 ) M, Q**T*B*Z**T = ( T11 T12 ) M* ( 0 ) N-M ( 0 T22 ) N-M* M M+P-N N-M** where R11 and T22 are upper triangular, and Q and Z are* orthogonal.*CALL DGGQRF( N, M, P, A, LDA, WORK, B, LDB, WORK( M+1 ),$ WORK( M+NP+1 ), LWORK-M-NP, INFO )LOPT = WORK( M+NP+1 )** Update left-hand-side vector d = Q**T*d = ( d1 ) M* ( d2 ) N-M*CALL DORMQR( 'Left', 'Transpose', N, 1, M, A, LDA, WORK, D,$ MAX( 1, N ), WORK( M+NP+1 ), LWORK-M-NP, INFO )LOPT = MAX( LOPT, INT( WORK( M+NP+1 ) ) )** Solve T22*y2 = d2 for y2*IF( N.GT.M ) THENCALL DTRTRS( 'Upper', 'No transpose', 'Non unit', N-M, 1,$ B( M+1, M+P-N+1 ), LDB, D( M+1 ), N-M, INFO )*IF( INFO.GT.0 ) THENINFO = 1RETURNEND IF*CALL DCOPY( N-M, D( M+1 ), 1, Y( M+P-N+1 ), 1 )END IF** Set y1 = 0*DO 10 I = 1, M + P - NY( I ) = ZERO10 CONTINUE** Update d1 = d1 - T12*y2*CALL DGEMV( 'No transpose', M, N-M, -ONE, B( 1, M+P-N+1 ), LDB,$ Y( M+P-N+1 ), 1, ONE, D, 1 )** Solve triangular system: R11*x = d1*IF( M.GT.0 ) THENCALL DTRTRS( 'Upper', 'No Transpose', 'Non unit', M, 1, A, LDA,$ D, M, INFO )*IF( INFO.GT.0 ) THENINFO = 2RETURNEND IF** Copy D to X*CALL DCOPY( M, D, 1, X, 1 )END IF** Backward transformation y = Z**T *y*CALL DORMRQ( 'Left', 'Transpose', P, 1, NP,$ B( MAX( 1, N-P+1 ), 1 ), LDB, WORK( M+1 ), Y,$ MAX( 1, P ), WORK( M+NP+1 ), LWORK-M-NP, INFO )WORK( 1 ) = M + NP + MAX( LOPT, INT( WORK( M+NP+1 ) ) )*RETURN** End of DGGGLM*END*> \brief \b DGGHRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGHRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgghrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgghrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgghrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,* LDQ, Z, LDZ, INFO )** .. Scalar Arguments ..* CHARACTER COMPQ, COMPZ* INTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGHRD reduces a pair of real matrices (A,B) to generalized upper*> Hessenberg form using orthogonal transformations, where A is a*> general matrix and B is upper triangular. The form of the*> generalized eigenvalue problem is*> A*x = lambda*B*x,*> and B is typically made upper triangular by computing its QR*> factorization and moving the orthogonal matrix Q to the left side*> of the equation.*>*> This subroutine simultaneously reduces A to a Hessenberg matrix H:*> Q**T*A*Z = H*> and transforms B to another upper triangular matrix T:*> Q**T*B*Z = T*> in order to reduce the problem to its standard form*> H*y = lambda*T*y*> where y = Z**T*x.*>*> The orthogonal matrices Q and Z are determined as products of Givens*> rotations. They may either be formed explicitly, or they may be*> postmultiplied into input matrices Q1 and Z1, so that*>*> Q1 * A * Z1**T = (Q1*Q) * H * (Z1*Z)**T*>*> Q1 * B * Z1**T = (Q1*Q) * T * (Z1*Z)**T*>*> If Q1 is the orthogonal matrix from the QR factorization of B in the*> original equation A*x = lambda*B*x, then DGGHRD reduces the original*> problem to generalized Hessenberg form.*> \endverbatim** Arguments:* ==========**> \param[in] COMPQ*> \verbatim*> COMPQ is CHARACTER*1*> = 'N': do not compute Q;*> = 'I': Q is initialized to the unit matrix, and the*> orthogonal matrix Q is returned;*> = 'V': Q must contain an orthogonal matrix Q1 on entry,*> and the product Q1*Q is returned.*> \endverbatim*>*> \param[in] COMPZ*> \verbatim*> COMPZ is CHARACTER*1*> = 'N': do not compute Z;*> = 'I': Z is initialized to the unit matrix, and the*> orthogonal matrix Z is returned;*> = 'V': Z must contain an orthogonal matrix Z1 on entry,*> and the product Z1*Z is returned.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*>*> ILO and IHI mark the rows and columns of A which are to be*> reduced. It is assumed that A is already upper triangular*> in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are*> normally set by a previous call to DGGBAL; otherwise they*> should be set to 1 and N respectively.*> 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the N-by-N general matrix to be reduced.*> On exit, the upper triangle and the first subdiagonal of A*> are overwritten with the upper Hessenberg matrix H, and the*> rest is set to zero.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the N-by-N upper triangular matrix B.*> On exit, the upper triangular matrix T = Q**T B Z. The*> elements below the diagonal are set to zero.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> On entry, if COMPQ = 'V', the orthogonal matrix Q1,*> typically from the QR factorization of B.*> On exit, if COMPQ='I', the orthogonal matrix Q, and if*> COMPQ = 'V', the product Q1*Q.*> Not referenced if COMPQ='N'.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q.*> LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> On entry, if COMPZ = 'V', the orthogonal matrix Z1.*> On exit, if COMPZ='I', the orthogonal matrix Z, and if*> COMPZ = 'V', the product Z1*Z.*> Not referenced if COMPZ='N'.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z.*> LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> This routine reduces A to Hessenberg and B to triangular form by*> an unblocked reduction, as described in _Matrix_Computations_,*> by Golub and Van Loan (Johns Hopkins Press.)*> \endverbatim*>* =====================================================================SUBROUTINE DGGHRD( COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q,$ LDQ, Z, LDZ, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER COMPQ, COMPZINTEGER IHI, ILO, INFO, LDA, LDB, LDQ, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),$ Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ILQ, ILZINTEGER ICOMPQ, ICOMPZ, JCOL, JROWDOUBLE PRECISION C, S, TEMP* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARTG, DLASET, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Decode COMPQ*IF( LSAME( COMPQ, 'N' ) ) THENILQ = .FALSE.ICOMPQ = 1ELSE IF( LSAME( COMPQ, 'V' ) ) THENILQ = .TRUE.ICOMPQ = 2ELSE IF( LSAME( COMPQ, 'I' ) ) THENILQ = .TRUE.ICOMPQ = 3ELSEICOMPQ = 0END IF** Decode COMPZ*IF( LSAME( COMPZ, 'N' ) ) THENILZ = .FALSE.ICOMPZ = 1ELSE IF( LSAME( COMPZ, 'V' ) ) THENILZ = .TRUE.ICOMPZ = 2ELSE IF( LSAME( COMPZ, 'I' ) ) THENILZ = .TRUE.ICOMPZ = 3ELSEICOMPZ = 0END IF** Test the input parameters.*INFO = 0IF( ICOMPQ.LE.0 ) THENINFO = -1ELSE IF( ICOMPZ.LE.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 ) THENINFO = -4ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( ( ILQ .AND. LDQ.LT.N ) .OR. LDQ.LT.1 ) THENINFO = -11ELSE IF( ( ILZ .AND. LDZ.LT.N ) .OR. LDZ.LT.1 ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGHRD', -INFO )RETURNEND IF** Initialize Q and Z if desired.*IF( ICOMPQ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )IF( ICOMPZ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Quick return if possible*IF( N.LE.1 )$ RETURN** Zero out lower triangle of B*DO 20 JCOL = 1, N - 1DO 10 JROW = JCOL + 1, NB( JROW, JCOL ) = ZERO10 CONTINUE20 CONTINUE** Reduce A and B*DO 40 JCOL = ILO, IHI - 2*DO 30 JROW = IHI, JCOL + 2, -1** Step 1: rotate rows JROW-1, JROW to kill A(JROW,JCOL)*TEMP = A( JROW-1, JCOL )CALL DLARTG( TEMP, A( JROW, JCOL ), C, S,$ A( JROW-1, JCOL ) )A( JROW, JCOL ) = ZEROCALL DROT( N-JCOL, A( JROW-1, JCOL+1 ), LDA,$ A( JROW, JCOL+1 ), LDA, C, S )CALL DROT( N+2-JROW, B( JROW-1, JROW-1 ), LDB,$ B( JROW, JROW-1 ), LDB, C, S )IF( ILQ )$ CALL DROT( N, Q( 1, JROW-1 ), 1, Q( 1, JROW ), 1, C, S )** Step 2: rotate columns JROW, JROW-1 to kill B(JROW,JROW-1)*TEMP = B( JROW, JROW )CALL DLARTG( TEMP, B( JROW, JROW-1 ), C, S,$ B( JROW, JROW ) )B( JROW, JROW-1 ) = ZEROCALL DROT( IHI, A( 1, JROW ), 1, A( 1, JROW-1 ), 1, C, S )CALL DROT( JROW-1, B( 1, JROW ), 1, B( 1, JROW-1 ), 1, C,$ S )IF( ILZ )$ CALL DROT( N, Z( 1, JROW ), 1, Z( 1, JROW-1 ), 1, C, S )30 CONTINUE40 CONTINUE*RETURN** End of DGGHRD*END*> \brief <b> DGGLSE solves overdetermined or underdetermined systems for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGLSE + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgglse.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgglse.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgglse.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGLSE( M, N, P, A, LDA, B, LDB, C, D, X, WORK, LWORK,* INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( * ), D( * ),* $ WORK( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGLSE solves the linear equality-constrained least squares (LSE)*> problem:*>*> minimize || c - A*x ||_2 subject to B*x = d*>*> where A is an M-by-N matrix, B is a P-by-N matrix, c is a given*> M-vector, and d is a given P-vector. It is assumed that*> P <= N <= M+P, and*>*> rank(B) = P and rank( (A) ) = N.*> ( (B) )*>*> These conditions ensure that the LSE problem has a unique solution,*> which is obtained using a generalized RQ factorization of the*> matrices (B, A) given by*>*> B = (0 R)*Q, A = Z*T*Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows of the matrix B. 0 <= P <= N <= M+P.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(M,N)-by-N upper trapezoidal matrix T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the P-by-N matrix B.*> On exit, the upper triangle of the subarray B(1:P,N-P+1:N)*> contains the P-by-P upper triangular matrix R.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,P).*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (M)*> On entry, C contains the right hand side vector for the*> least squares part of the LSE problem.*> On exit, the residual sum of squares for the solution*> is given by the sum of squares of elements N-P+1 to M of*> vector C.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (P)*> On entry, D contains the right hand side vector for the*> constrained equation.*> On exit, D is destroyed.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> On exit, X is the solution of the LSE problem.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,M+N+P).*> For optimum performance LWORK >= P+min(M,N)+max(M,N)*NB,*> where NB is an upper bound for the optimal blocksizes for*> DGEQRF, SGERQF, DORMQR and SORMRQ.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1: the upper triangular factor R associated with B in the*> generalized RQ factorization of the pair (B, A) is*> singular, so that rank(B) < P; the least squares*> solution could not be computed.*> = 2: the (N-P) by (N-P) part of the upper trapezoidal factor*> T associated with A in the generalized RQ factorization*> of the pair (B, A) is singular, so that*> rank( (A) ) < N; the least squares solution could not*> ( (B) )*> be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERsolve** =====================================================================SUBROUTINE DGGLSE( M, N, P, A, LDA, B, LDB, C, D, X, WORK, LWORK,$ INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( * ), D( * ),$ WORK( * ), X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER LOPT, LWKMIN, LWKOPT, MN, NB, NB1, NB2, NB3,$ NB4, NR* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGGRQF, DORMQR, DORMRQ,$ DTRMV, DTRTRS, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0MN = MIN( M, N )LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( P.LT.0 .OR. P.GT.N .OR. P.LT.N-M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -7END IF** Calculate workspace*IF( INFO.EQ.0) THENIF( N.EQ.0 ) THENLWKMIN = 1LWKOPT = 1ELSENB1 = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )NB2 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )NB3 = ILAENV( 1, 'DORMQR', ' ', M, N, P, -1 )NB4 = ILAENV( 1, 'DORMRQ', ' ', M, N, P, -1 )NB = MAX( NB1, NB2, NB3, NB4 )LWKMIN = M + N + PLWKOPT = P + MN + MAX( M, N )*NBEND IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -12END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DGGLSE', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Compute the GRQ factorization of matrices B and A:** B*Q**T = ( 0 T12 ) P Z**T*A*Q**T = ( R11 R12 ) N-P* N-P P ( 0 R22 ) M+P-N* N-P P** where T12 and R11 are upper triangular, and Q and Z are* orthogonal.*CALL DGGRQF( P, M, N, B, LDB, WORK, A, LDA, WORK( P+1 ),$ WORK( P+MN+1 ), LWORK-P-MN, INFO )LOPT = WORK( P+MN+1 )** Update c = Z**T *c = ( c1 ) N-P* ( c2 ) M+P-N*CALL DORMQR( 'Left', 'Transpose', M, 1, MN, A, LDA, WORK( P+1 ),$ C, MAX( 1, M ), WORK( P+MN+1 ), LWORK-P-MN, INFO )LOPT = MAX( LOPT, INT( WORK( P+MN+1 ) ) )** Solve T12*x2 = d for x2*IF( P.GT.0 ) THENCALL DTRTRS( 'Upper', 'No transpose', 'Non-unit', P, 1,$ B( 1, N-P+1 ), LDB, D, P, INFO )*IF( INFO.GT.0 ) THENINFO = 1RETURNEND IF** Put the solution in X*CALL DCOPY( P, D, 1, X( N-P+1 ), 1 )** Update c1*CALL DGEMV( 'No transpose', N-P, P, -ONE, A( 1, N-P+1 ), LDA,$ D, 1, ONE, C, 1 )END IF** Solve R11*x1 = c1 for x1*IF( N.GT.P ) THENCALL DTRTRS( 'Upper', 'No transpose', 'Non-unit', N-P, 1,$ A, LDA, C, N-P, INFO )*IF( INFO.GT.0 ) THENINFO = 2RETURNEND IF** Put the solutions in X*CALL DCOPY( N-P, C, 1, X, 1 )END IF** Compute the residual vector:*IF( M.LT.N ) THENNR = M + P - NIF( NR.GT.0 )$ CALL DGEMV( 'No transpose', NR, N-M, -ONE, A( N-P+1, M+1 ),$ LDA, D( NR+1 ), 1, ONE, C( N-P+1 ), 1 )ELSENR = PEND IFIF( NR.GT.0 ) THENCALL DTRMV( 'Upper', 'No transpose', 'Non unit', NR,$ A( N-P+1, N-P+1 ), LDA, D, 1 )CALL DAXPY( NR, -ONE, D, 1, C( N-P+1 ), 1 )END IF** Backward transformation x = Q**T*x*CALL DORMRQ( 'Left', 'Transpose', N, 1, P, B, LDB, WORK( 1 ), X,$ N, WORK( P+MN+1 ), LWORK-P-MN, INFO )WORK( 1 ) = P + MN + MAX( LOPT, INT( WORK( P+MN+1 ) ) )*RETURN** End of DGGLSE*END*> \brief \b DGGQRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGQRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggqrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggqrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggqrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGQRF( N, M, P, A, LDA, TAUA, B, LDB, TAUB, WORK,* LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), TAUA( * ), TAUB( * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGQRF computes a generalized QR factorization of an N-by-M matrix A*> and an N-by-P matrix B:*>*> A = Q*R, B = Q*T*Z,*>*> where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal*> matrix, and R and T assume one of the forms:*>*> if N >= M, R = ( R11 ) M , or if N < M, R = ( R11 R12 ) N,*> ( 0 ) N-M N M-N*> M*>*> where R11 is upper triangular, and*>*> if N <= P, T = ( 0 T12 ) N, or if N > P, T = ( T11 ) N-P,*> P-N N ( T21 ) P*> P*>*> where T12 or T21 is upper triangular.*>*> In particular, if B is square and nonsingular, the GQR factorization*> of A and B implicitly gives the QR factorization of inv(B)*A:*>*> inv(B)*A = Z**T*(inv(T)*R)*>*> where inv(B) denotes the inverse of the matrix B, and Z**T denotes the*> transpose of the matrix Z.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of columns of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of columns of the matrix B. P >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,M)*> On entry, the N-by-M matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the min(N,M)-by-M upper trapezoidal matrix R (R is*> upper triangular if N >= M); the elements below the diagonal,*> with the array TAUA, represent the orthogonal matrix Q as a*> product of min(N,M) elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] TAUA*> \verbatim*> TAUA is DOUBLE PRECISION array, dimension (min(N,M))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Q (see Further Details).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,P)*> On entry, the N-by-P matrix B.*> On exit, if N <= P, the upper triangle of the subarray*> B(1:N,P-N+1:P) contains the N-by-N upper triangular matrix T;*> if N > P, the elements on and above the (N-P)-th subdiagonal*> contain the N-by-P upper trapezoidal matrix T; the remaining*> elements, with the array TAUB, represent the orthogonal*> matrix Z as a product of elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] TAUB*> \verbatim*> TAUB is DOUBLE PRECISION array, dimension (min(N,P))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Z (see Further Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N,M,P).*> For optimum performance LWORK >= max(N,M,P)*max(NB1,NB2,NB3),*> where NB1 is the optimal blocksize for the QR factorization*> of an N-by-M matrix, NB2 is the optimal blocksize for the*> RQ factorization of an N-by-P matrix, and NB3 is the optimal*> blocksize for a call of DORMQR.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(n,m).*>*> Each H(i) has the form*>*> H(i) = I - taua * v * v**T*>*> where taua is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),*> and taua in TAUA(i).*> To form Q explicitly, use LAPACK subroutine DORGQR.*> To use Q to update another matrix, use LAPACK subroutine DORMQR.*>*> The matrix Z is represented as a product of elementary reflectors*>*> Z = H(1) H(2) . . . H(k), where k = min(n,p).*>*> Each H(i) has the form*>*> H(i) = I - taub * v * v**T*>*> where taub is a real scalar, and v is a real vector with*> v(p-k+i+1:p) = 0 and v(p-k+i) = 1; v(1:p-k+i-1) is stored on exit in*> B(n-k+i,1:p-k+i-1), and taub in TAUB(i).*> To form Z explicitly, use LAPACK subroutine DORGRQ.*> To use Z to update another matrix, use LAPACK subroutine DORMRQ.*> \endverbatim*>* =====================================================================SUBROUTINE DGGQRF( N, M, P, A, LDA, TAUA, B, LDB, TAUB, WORK,$ LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), TAUA( * ), TAUB( * ),$ WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER LOPT, LWKOPT, NB, NB1, NB2, NB3* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGERQF, DORMQR, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB1 = ILAENV( 1, 'DGEQRF', ' ', N, M, -1, -1 )NB2 = ILAENV( 1, 'DGERQF', ' ', N, P, -1, -1 )NB3 = ILAENV( 1, 'DORMQR', ' ', N, M, P, -1 )NB = MAX( NB1, NB2, NB3 )LWKOPT = MAX( N, M, P )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( P.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LWORK.LT.MAX( 1, N, M, P ) .AND. .NOT.LQUERY ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGQRF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** QR factorization of N-by-M matrix A: A = Q*R*CALL DGEQRF( N, M, A, LDA, TAUA, WORK, LWORK, INFO )LOPT = WORK( 1 )** Update B := Q**T*B.*CALL DORMQR( 'Left', 'Transpose', N, P, MIN( N, M ), A, LDA, TAUA,$ B, LDB, WORK, LWORK, INFO )LOPT = MAX( LOPT, INT( WORK( 1 ) ) )** RQ factorization of N-by-P matrix B: B = T*Z.*CALL DGERQF( N, P, B, LDB, TAUB, WORK, LWORK, INFO )WORK( 1 ) = MAX( LOPT, INT( WORK( 1 ) ) )*RETURN** End of DGGQRF*END*> \brief \b DGGRQF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGRQF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggrqf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggrqf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggrqf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGRQF( M, P, N, A, LDA, TAUA, B, LDB, TAUB, WORK,* LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), TAUA( * ), TAUB( * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGGRQF computes a generalized RQ factorization of an M-by-N matrix A*> and a P-by-N matrix B:*>*> A = R*Q, B = Z*T*Q,*>*> where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal*> matrix, and R and T assume one of the forms:*>*> if M <= N, R = ( 0 R12 ) M, or if M > N, R = ( R11 ) M-N,*> N-M M ( R21 ) N*> N*>*> where R12 or R21 is upper triangular, and*>*> if P >= N, T = ( T11 ) N , or if P < N, T = ( T11 T12 ) P,*> ( 0 ) P-N P N-P*> N*>*> where T11 is upper triangular.*>*> In particular, if B is square and nonsingular, the GRQ factorization*> of A and B implicitly gives the RQ factorization of A*inv(B):*>*> A*inv(B) = (R*inv(T))*Z**T*>*> where inv(B) denotes the inverse of the matrix B, and Z**T denotes the*> transpose of the matrix Z.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows of the matrix B. P >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, if M <= N, the upper triangle of the subarray*> A(1:M,N-M+1:N) contains the M-by-M upper triangular matrix R;*> if M > N, the elements on and above the (M-N)-th subdiagonal*> contain the M-by-N upper trapezoidal matrix R; the remaining*> elements, with the array TAUA, represent the orthogonal*> matrix Q as a product of elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAUA*> \verbatim*> TAUA is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Q (see Further Details).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the P-by-N matrix B.*> On exit, the elements on and above the diagonal of the array*> contain the min(P,N)-by-N upper trapezoidal matrix T (T is*> upper triangular if P >= N); the elements below the diagonal,*> with the array TAUB, represent the orthogonal matrix Z as a*> product of elementary reflectors (see Further Details).*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,P).*> \endverbatim*>*> \param[out] TAUB*> \verbatim*> TAUB is DOUBLE PRECISION array, dimension (min(P,N))*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Z (see Further Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N,M,P).*> For optimum performance LWORK >= max(N,M,P)*max(NB1,NB2,NB3),*> where NB1 is the optimal blocksize for the RQ factorization*> of an M-by-N matrix, NB2 is the optimal blocksize for the*> QR factorization of a P-by-N matrix, and NB3 is the optimal*> blocksize for a call of DORMRQ.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INF0= -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of elementary reflectors*>*> Q = H(1) H(2) . . . H(k), where k = min(m,n).*>*> Each H(i) has the form*>*> H(i) = I - taua * v * v**T*>*> where taua is a real scalar, and v is a real vector with*> v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in*> A(m-k+i,1:n-k+i-1), and taua in TAUA(i).*> To form Q explicitly, use LAPACK subroutine DORGRQ.*> To use Q to update another matrix, use LAPACK subroutine DORMRQ.*>*> The matrix Z is represented as a product of elementary reflectors*>*> Z = H(1) H(2) . . . H(k), where k = min(p,n).*>*> Each H(i) has the form*>*> H(i) = I - taub * v * v**T*>*> where taub is a real scalar, and v is a real vector with*> v(1:i-1) = 0 and v(i) = 1; v(i+1:p) is stored on exit in B(i+1:p,i),*> and taub in TAUB(i).*> To form Z explicitly, use LAPACK subroutine DORGQR.*> To use Z to update another matrix, use LAPACK subroutine DORMQR.*> \endverbatim*>* =====================================================================SUBROUTINE DGGRQF( M, P, N, A, LDA, TAUA, B, LDB, TAUB, WORK,$ LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LWORK, M, N, P* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), TAUA( * ), TAUB( * ),$ WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER LOPT, LWKOPT, NB, NB1, NB2, NB3* ..* .. External Subroutines ..EXTERNAL DGEQRF, DGERQF, DORMRQ, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0NB1 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )NB2 = ILAENV( 1, 'DGEQRF', ' ', P, N, -1, -1 )NB3 = ILAENV( 1, 'DORMRQ', ' ', M, N, P, -1 )NB = MAX( NB1, NB2, NB3 )LWKOPT = MAX( N, M, P )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( P.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -8ELSE IF( LWORK.LT.MAX( 1, M, P, N ) .AND. .NOT.LQUERY ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGRQF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** RQ factorization of M-by-N matrix A: A = R*Q*CALL DGERQF( M, N, A, LDA, TAUA, WORK, LWORK, INFO )LOPT = WORK( 1 )** Update B := B*Q**T*CALL DORMRQ( 'Right', 'Transpose', P, N, MIN( M, N ),$ A( MAX( 1, M-N+1 ), 1 ), LDA, TAUA, B, LDB, WORK,$ LWORK, INFO )LOPT = MAX( LOPT, INT( WORK( 1 ) ) )** QR factorization of P-by-N matrix B: B = Z*T*CALL DGEQRF( P, N, B, LDB, TAUB, WORK, LWORK, INFO )WORK( 1 ) = MAX( LOPT, INT( WORK( 1 ) ) )*RETURN** End of DGGRQF*END*> \brief <b> DGGSVD computes the singular value decomposition (SVD) for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGSVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggsvd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggsvd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggsvd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGSVD( JOBU, JOBV, JOBQ, M, N, P, K, L, A, LDA, B,* LDB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ, WORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBQ, JOBU, JOBV* INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), ALPHA( * ), B( LDB, * ),* $ BETA( * ), Q( LDQ, * ), U( LDU, * ),* $ V( LDV, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DGGSVD3.*>*> DGGSVD computes the generalized singular value decomposition (GSVD)*> of an M-by-N real matrix A and P-by-N real matrix B:*>*> U**T*A*Q = D1*( 0 R ), V**T*B*Q = D2*( 0 R )*>*> where U, V and Q are orthogonal matrices.*> Let K+L = the effective numerical rank of the matrix (A**T,B**T)**T,*> then R is a K+L-by-K+L nonsingular upper triangular matrix, D1 and*> D2 are M-by-(K+L) and P-by-(K+L) "diagonal" matrices and of the*> following structures, respectively:*>*> If M-K-L >= 0,*>*> K L*> D1 = K ( I 0 )*> L ( 0 C )*> M-K-L ( 0 0 )*>*> K L*> D2 = L ( 0 S )*> P-L ( 0 0 )*>*> N-K-L K L*> ( 0 R ) = K ( 0 R11 R12 )*> L ( 0 0 R22 )*>*> where*>*> C = diag( ALPHA(K+1), ... , ALPHA(K+L) ),*> S = diag( BETA(K+1), ... , BETA(K+L) ),*> C**2 + S**2 = I.*>*> R is stored in A(1:K+L,N-K-L+1:N) on exit.*>*> If M-K-L < 0,*>*> K M-K K+L-M*> D1 = K ( I 0 0 )*> M-K ( 0 C 0 )*>*> K M-K K+L-M*> D2 = M-K ( 0 S 0 )*> K+L-M ( 0 0 I )*> P-L ( 0 0 0 )*>*> N-K-L K M-K K+L-M*> ( 0 R ) = K ( 0 R11 R12 R13 )*> M-K ( 0 0 R22 R23 )*> K+L-M ( 0 0 0 R33 )*>*> where*>*> C = diag( ALPHA(K+1), ... , ALPHA(M) ),*> S = diag( BETA(K+1), ... , BETA(M) ),*> C**2 + S**2 = I.*>*> (R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N), and R33 is stored*> ( 0 R22 R23 )*> in B(M-K+1:L,N+M-K-L+1:N) on exit.*>*> The routine computes C, S, R, and optionally the orthogonal*> transformation matrices U, V and Q.*>*> In particular, if B is an N-by-N nonsingular matrix, then the GSVD of*> A and B implicitly gives the SVD of A*inv(B):*> A*inv(B) = U*(D1*inv(D2))*V**T.*> If ( A**T,B**T)**T has orthonormal columns, then the GSVD of A and B is*> also equal to the CS decomposition of A and B. Furthermore, the GSVD*> can be used to derive the solution of the eigenvalue problem:*> A**T*A x = lambda* B**T*B x.*> In some literature, the GSVD of A and B is presented in the form*> U**T*A*X = ( 0 D1 ), V**T*B*X = ( 0 D2 )*> where U and V are orthogonal and X is nonsingular, D1 and D2 are*> ``diagonal''. The former GSVD form can be converted to the latter*> form by taking the nonsingular matrix X as*>*> X = Q*( I 0 )*> ( 0 inv(R) ).*> \endverbatim** Arguments:* ==========**> \param[in] JOBU*> \verbatim*> JOBU is CHARACTER*1*> = 'U': Orthogonal matrix U is computed;*> = 'N': U is not computed.*> \endverbatim*>*> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> = 'V': Orthogonal matrix V is computed;*> = 'N': V is not computed.*> \endverbatim*>*> \param[in] JOBQ*> \verbatim*> JOBQ is CHARACTER*1*> = 'Q': Orthogonal matrix Q is computed;*> = 'N': Q is not computed.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows of the matrix B. P >= 0.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER*> \endverbatim*>*> \param[out] L*> \verbatim*> L is INTEGER*>*> On exit, K and L specify the dimension of the subblocks*> described in Purpose.*> K + L = effective numerical rank of (A**T,B**T)**T.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, A contains the triangular matrix R, or part of R.*> See Purpose for details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the P-by-N matrix B.*> On exit, B contains the triangular matrix R if M-K-L < 0.*> See Purpose for details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,P).*> \endverbatim*>*> \param[out] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*>*> On exit, ALPHA and BETA contain the generalized singular*> value pairs of A and B;*> ALPHA(1:K) = 1,*> BETA(1:K) = 0,*> and if M-K-L >= 0,*> ALPHA(K+1:K+L) = C,*> BETA(K+1:K+L) = S,*> or if M-K-L < 0,*> ALPHA(K+1:M)=C, ALPHA(M+1:K+L)=0*> BETA(K+1:M) =S, BETA(M+1:K+L) =1*> and*> ALPHA(K+L+1:N) = 0*> BETA(K+L+1:N) = 0*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,M)*> If JOBU = 'U', U contains the M-by-M orthogonal matrix U.*> If JOBU = 'N', U is not referenced.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= max(1,M) if*> JOBU = 'U'; LDU >= 1 otherwise.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,P)*> If JOBV = 'V', V contains the P-by-P orthogonal matrix V.*> If JOBV = 'N', V is not referenced.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V. LDV >= max(1,P) if*> JOBV = 'V'; LDV >= 1 otherwise.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> If JOBQ = 'Q', Q contains the N-by-N orthogonal matrix Q.*> If JOBQ = 'N', Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N) if*> JOBQ = 'Q'; LDQ >= 1 otherwise.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array,*> dimension (max(3*N,M,P)+N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> On exit, IWORK stores the sorting information. More*> precisely, the following loop will sort ALPHA*> for I = K+1, min(M,K+L)*> swap ALPHA(I) and ALPHA(IWORK(I))*> endfor*> such that ALPHA(1) >= ALPHA(2) >= ... >= ALPHA(N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, the Jacobi-type procedure failed to*> converge. For further details, see subroutine DTGSJA.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> TOLA DOUBLE PRECISION*> TOLB DOUBLE PRECISION*> TOLA and TOLB are the thresholds to determine the effective*> rank of (A',B')**T. Generally, they are set to*> TOLA = MAX(M,N)*norm(A)*MAZHEPS,*> TOLB = MAX(P,N)*norm(B)*MAZHEPS.*> The size of TOLA and TOLB may affect the size of backward*> errors of the decomposition.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERsing**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DGGSVD( JOBU, JOBV, JOBQ, M, N, P, K, L, A, LDA, B,$ LDB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ, WORK,$ IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBQ, JOBU, JOBVINTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), ALPHA( * ), B( LDB, * ),$ BETA( * ), Q( LDQ, * ), U( LDU, * ),$ V( LDV, * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL WANTQ, WANTU, WANTVINTEGER I, IBND, ISUB, J, NCYCLEDOUBLE PRECISION ANORM, BNORM, SMAX, TEMP, TOLA, TOLB, ULP, UNFL* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANGEEXTERNAL LSAME, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DCOPY, DGGSVP, DTGSJA, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*WANTU = LSAME( JOBU, 'U' )WANTV = LSAME( JOBV, 'V' )WANTQ = LSAME( JOBQ, 'Q' )*INFO = 0IF( .NOT.( WANTU .OR. LSAME( JOBU, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( WANTV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( P.LT.0 ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -12ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THENINFO = -16ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THENINFO = -18ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -20END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGSVD', -INFO )RETURNEND IF** Compute the Frobenius norm of matrices A and B*ANORM = DLANGE( '1', M, N, A, LDA, WORK )BNORM = DLANGE( '1', P, N, B, LDB, WORK )** Get machine precision and set up threshold for determining* the effective numerical rank of the matrices A and B.*ULP = DLAMCH( 'Precision' )UNFL = DLAMCH( 'Safe Minimum' )TOLA = MAX( M, N )*MAX( ANORM, UNFL )*ULPTOLB = MAX( P, N )*MAX( BNORM, UNFL )*ULP** Preprocessing*CALL DGGSVP( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB, TOLA,$ TOLB, K, L, U, LDU, V, LDV, Q, LDQ, IWORK, WORK,$ WORK( N+1 ), INFO )** Compute the GSVD of two upper "triangular" matrices*CALL DTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B, LDB,$ TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ,$ WORK, NCYCLE, INFO )** Sort the singular values and store the pivot indices in IWORK* Copy ALPHA to WORK, then sort ALPHA in WORK*CALL DCOPY( N, ALPHA, 1, WORK, 1 )IBND = MIN( L, M-K )DO 20 I = 1, IBND** Scan for largest ALPHA(K+I)*ISUB = ISMAX = WORK( K+I )DO 10 J = I + 1, IBNDTEMP = WORK( K+J )IF( TEMP.GT.SMAX ) THENISUB = JSMAX = TEMPEND IF10 CONTINUEIF( ISUB.NE.I ) THENWORK( K+ISUB ) = WORK( K+I )WORK( K+I ) = SMAXIWORK( K+I ) = K + ISUBELSEIWORK( K+I ) = K + IEND IF20 CONTINUE*RETURN** End of DGGSVD*END*> \brief \b DGGSVP** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGGSVP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dggsvp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dggsvp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dggsvp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGGSVP( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,* TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,* IWORK, TAU, WORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBQ, JOBU, JOBV* INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P* DOUBLE PRECISION TOLA, TOLB* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),* $ TAU( * ), U( LDU, * ), V( LDV, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DGGSVP3.*>*> DGGSVP computes orthogonal matrices U, V and Q such that*>*> N-K-L K L*> U**T*A*Q = K ( 0 A12 A13 ) if M-K-L >= 0;*> L ( 0 0 A23 )*> M-K-L ( 0 0 0 )*>*> N-K-L K L*> = K ( 0 A12 A13 ) if M-K-L < 0;*> M-K ( 0 0 A23 )*>*> N-K-L K L*> V**T*B*Q = L ( 0 0 B13 )*> P-L ( 0 0 0 )*>*> where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular*> upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0,*> otherwise A23 is (M-K)-by-L upper trapezoidal. K+L = the effective*> numerical rank of the (M+P)-by-N matrix (A**T,B**T)**T.*>*> This decomposition is the preprocessing step for computing the*> Generalized Singular Value Decomposition (GSVD), see subroutine*> DGGSVD.*> \endverbatim** Arguments:* ==========**> \param[in] JOBU*> \verbatim*> JOBU is CHARACTER*1*> = 'U': Orthogonal matrix U is computed;*> = 'N': U is not computed.*> \endverbatim*>*> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> = 'V': Orthogonal matrix V is computed;*> = 'N': V is not computed.*> \endverbatim*>*> \param[in] JOBQ*> \verbatim*> JOBQ is CHARACTER*1*> = 'Q': Orthogonal matrix Q is computed;*> = 'N': Q is not computed.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows of the matrix B. P >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, A contains the triangular (or trapezoidal) matrix*> described in the Purpose section.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the P-by-N matrix B.*> On exit, B contains the triangular matrix described in*> the Purpose section.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,P).*> \endverbatim*>*> \param[in] TOLA*> \verbatim*> TOLA is DOUBLE PRECISION*> \endverbatim*>*> \param[in] TOLB*> \verbatim*> TOLB is DOUBLE PRECISION*>*> TOLA and TOLB are the thresholds to determine the effective*> numerical rank of matrix B and a subblock of A. Generally,*> they are set to*> TOLA = MAX(M,N)*norm(A)*MACHEPS,*> TOLB = MAX(P,N)*norm(B)*MACHEPS.*> The size of TOLA and TOLB may affect the size of backward*> errors of the decomposition.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER*> \endverbatim*>*> \param[out] L*> \verbatim*> L is INTEGER*>*> On exit, K and L specify the dimension of the subblocks*> described in Purpose section.*> K + L = effective numerical rank of (A**T,B**T)**T.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,M)*> If JOBU = 'U', U contains the orthogonal matrix U.*> If JOBU = 'N', U is not referenced.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= max(1,M) if*> JOBU = 'U'; LDU >= 1 otherwise.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,P)*> If JOBV = 'V', V contains the orthogonal matrix V.*> If JOBV = 'N', V is not referenced.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V. LDV >= max(1,P) if*> JOBV = 'V'; LDV >= 1 otherwise.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> If JOBQ = 'Q', Q contains the orthogonal matrix Q.*> If JOBQ = 'N', Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N) if*> JOBQ = 'Q'; LDQ >= 1 otherwise.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (max(3*N,M,P))*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> The subroutine uses LAPACK subroutine DGEQPF for the QR factorization*> with column pivoting to detect the effective numerical rank of the*> a matrix. It may be replaced by a better rank determination strategy.*>* =====================================================================SUBROUTINE DGGSVP( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,$ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,$ IWORK, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBQ, JOBU, JOBVINTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, PDOUBLE PRECISION TOLA, TOLB* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),$ TAU( * ), U( LDU, * ), V( LDV, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL FORWRD, WANTQ, WANTU, WANTVINTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEQPF, DGEQR2, DGERQ2, DLACPY, DLAPMT, DLASET,$ DORG2R, DORM2R, DORMR2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*WANTU = LSAME( JOBU, 'U' )WANTV = LSAME( JOBV, 'V' )WANTQ = LSAME( JOBQ, 'Q' )FORWRD = .TRUE.*INFO = 0IF( .NOT.( WANTU .OR. LSAME( JOBU, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( WANTV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( P.LT.0 ) THENINFO = -5ELSE IF( N.LT.0 ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -10ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THENINFO = -16ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THENINFO = -18ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -20END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGGSVP', -INFO )RETURNEND IF** QR with column pivoting of B: B*P = V*( S11 S12 )* ( 0 0 )*DO 10 I = 1, NIWORK( I ) = 010 CONTINUECALL DGEQPF( P, N, B, LDB, IWORK, TAU, WORK, INFO )** Update A := A*P*CALL DLAPMT( FORWRD, M, N, A, LDA, IWORK )** Determine the effective rank of matrix B.*L = 0DO 20 I = 1, MIN( P, N )IF( ABS( B( I, I ) ).GT.TOLB )$ L = L + 120 CONTINUE*IF( WANTV ) THEN** Copy the details of V, and form V.*CALL DLASET( 'Full', P, P, ZERO, ZERO, V, LDV )IF( P.GT.1 )$ CALL DLACPY( 'Lower', P-1, N, B( 2, 1 ), LDB, V( 2, 1 ),$ LDV )CALL DORG2R( P, P, MIN( P, N ), V, LDV, TAU, WORK, INFO )END IF** Clean up B*DO 40 J = 1, L - 1DO 30 I = J + 1, LB( I, J ) = ZERO30 CONTINUE40 CONTINUEIF( P.GT.L )$ CALL DLASET( 'Full', P-L, N, ZERO, ZERO, B( L+1, 1 ), LDB )*IF( WANTQ ) THEN** Set Q = I and Update Q := Q*P*CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )CALL DLAPMT( FORWRD, N, N, Q, LDQ, IWORK )END IF*IF( P.GE.L .AND. N.NE.L ) THEN** RQ factorization of (S11 S12): ( S11 S12 ) = ( 0 S12 )*Z*CALL DGERQ2( L, N, B, LDB, TAU, WORK, INFO )** Update A := A*Z**T*CALL DORMR2( 'Right', 'Transpose', M, N, L, B, LDB, TAU, A,$ LDA, WORK, INFO )*IF( WANTQ ) THEN** Update Q := Q*Z**T*CALL DORMR2( 'Right', 'Transpose', N, N, L, B, LDB, TAU, Q,$ LDQ, WORK, INFO )END IF** Clean up B*CALL DLASET( 'Full', L, N-L, ZERO, ZERO, B, LDB )DO 60 J = N - L + 1, NDO 50 I = J - N + L + 1, LB( I, J ) = ZERO50 CONTINUE60 CONTINUE*END IF** Let N-L L* A = ( A11 A12 ) M,** then the following does the complete QR decomposition of A11:** A11 = U*( 0 T12 )*P1**T* ( 0 0 )*DO 70 I = 1, N - LIWORK( I ) = 070 CONTINUECALL DGEQPF( M, N-L, A, LDA, IWORK, TAU, WORK, INFO )** Determine the effective rank of A11*K = 0DO 80 I = 1, MIN( M, N-L )IF( ABS( A( I, I ) ).GT.TOLA )$ K = K + 180 CONTINUE** Update A12 := U**T*A12, where A12 = A( 1:M, N-L+1:N )*CALL DORM2R( 'Left', 'Transpose', M, L, MIN( M, N-L ), A, LDA,$ TAU, A( 1, N-L+1 ), LDA, WORK, INFO )*IF( WANTU ) THEN** Copy the details of U, and form U*CALL DLASET( 'Full', M, M, ZERO, ZERO, U, LDU )IF( M.GT.1 )$ CALL DLACPY( 'Lower', M-1, N-L, A( 2, 1 ), LDA, U( 2, 1 ),$ LDU )CALL DORG2R( M, M, MIN( M, N-L ), U, LDU, TAU, WORK, INFO )END IF*IF( WANTQ ) THEN** Update Q( 1:N, 1:N-L ) = Q( 1:N, 1:N-L )*P1*CALL DLAPMT( FORWRD, N, N-L, Q, LDQ, IWORK )END IF** Clean up A: set the strictly lower triangular part of* A(1:K, 1:K) = 0, and A( K+1:M, 1:N-L ) = 0.*DO 100 J = 1, K - 1DO 90 I = J + 1, KA( I, J ) = ZERO90 CONTINUE100 CONTINUEIF( M.GT.K )$ CALL DLASET( 'Full', M-K, N-L, ZERO, ZERO, A( K+1, 1 ), LDA )*IF( N-L.GT.K ) THEN** RQ factorization of ( T11 T12 ) = ( 0 T12 )*Z1*CALL DGERQ2( K, N-L, A, LDA, TAU, WORK, INFO )*IF( WANTQ ) THEN** Update Q( 1:N,1:N-L ) = Q( 1:N,1:N-L )*Z1**T*CALL DORMR2( 'Right', 'Transpose', N, N-L, K, A, LDA, TAU,$ Q, LDQ, WORK, INFO )END IF** Clean up A*CALL DLASET( 'Full', K, N-L-K, ZERO, ZERO, A, LDA )DO 120 J = N - L - K + 1, N - LDO 110 I = J - N + L + K + 1, KA( I, J ) = ZERO110 CONTINUE120 CONTINUE*END IF*IF( M.GT.K ) THEN** QR factorization of A( K+1:M,N-L+1:N )*CALL DGEQR2( M-K, L, A( K+1, N-L+1 ), LDA, TAU, WORK, INFO )*IF( WANTU ) THEN** Update U(:,K+1:M) := U(:,K+1:M)*U1*CALL DORM2R( 'Right', 'No transpose', M, M-K, MIN( M-K, L ),$ A( K+1, N-L+1 ), LDA, TAU, U( 1, K+1 ), LDU,$ WORK, INFO )END IF** Clean up*DO 140 J = N - L + 1, NDO 130 I = J - N + K + L + 1, MA( I, J ) = ZERO130 CONTINUE140 CONTINUE*END IF*RETURN** End of DGGSVP*END*> \brief \b DGSVJ0 pre-processor for the routine dgesvj.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGSVJ0 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgsvj0.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgsvj0.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgsvj0.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,* SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEP* DOUBLE PRECISION EPS, SFMIN, TOL* CHARACTER*1 JOBV* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ),* $ WORK( LWORK )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGSVJ0 is called from DGESVJ as a pre-processor and that is its main*> purpose. It applies Jacobi rotations in the same way as DGESVJ does, but*> it does not check convergence (stopping criterion). Few tuning*> parameters (marked by [TP]) are available for the implementer.*> \endverbatim** Arguments:* ==========**> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> Specifies whether the output from this procedure is used*> to compute the matrix V:*> = 'V': the product of the Jacobi rotations is accumulated*> by postmulyiplying the N-by-N array V.*> (See the description of V.)*> = 'A': the product of the Jacobi rotations is accumulated*> by postmulyiplying the MV-by-N array V.*> (See the descriptions of MV and V.)*> = 'N': the Jacobi rotations are not accumulated.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the input matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the input matrix A.*> M >= N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, M-by-N matrix A, such that A*diag(D) represents*> the input matrix.*> On exit,*> A_onexit * D_onexit represents the input matrix A*diag(D)*> post-multiplied by a sequence of Jacobi rotations, where the*> rotation threshold and the total number of sweeps are given in*> TOL and NSWEEP, respectively.*> (See the descriptions of D, TOL and NSWEEP.)*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The array D accumulates the scaling factors from the fast scaled*> Jacobi rotations.*> On entry, A*diag(D) represents the input matrix.*> On exit, A_onexit*diag(D_onexit) represents the input matrix*> post-multiplied by a sequence of Jacobi rotations, where the*> rotation threshold and the total number of sweeps are given in*> TOL and NSWEEP, respectively.*> (See the descriptions of A, TOL and NSWEEP.)*> \endverbatim*>*> \param[in,out] SVA*> \verbatim*> SVA is DOUBLE PRECISION array, dimension (N)*> On entry, SVA contains the Euclidean norms of the columns of*> the matrix A*diag(D).*> On exit, SVA contains the Euclidean norms of the columns of*> the matrix onexit*diag(D_onexit).*> \endverbatim*>*> \param[in] MV*> \verbatim*> MV is INTEGER*> If JOBV .EQ. 'A', then MV rows of V are post-multipled by a*> sequence of Jacobi rotations.*> If JOBV = 'N', then MV is not referenced.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,N)*> If JOBV .EQ. 'V' then N rows of V are post-multipled by a*> sequence of Jacobi rotations.*> If JOBV .EQ. 'A' then MV rows of V are post-multipled by a*> sequence of Jacobi rotations.*> If JOBV = 'N', then V is not referenced.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V, LDV >= 1.*> If JOBV = 'V', LDV .GE. N.*> If JOBV = 'A', LDV .GE. MV.*> \endverbatim*>*> \param[in] EPS*> \verbatim*> EPS is DOUBLE PRECISION*> EPS = DLAMCH('Epsilon')*> \endverbatim*>*> \param[in] SFMIN*> \verbatim*> SFMIN is DOUBLE PRECISION*> SFMIN = DLAMCH('Safe Minimum')*> \endverbatim*>*> \param[in] TOL*> \verbatim*> TOL is DOUBLE PRECISION*> TOL is the threshold for Jacobi rotations. For a pair*> A(:,p), A(:,q) of pivot columns, the Jacobi rotation is*> applied only if DABS(COS(angle(A(:,p),A(:,q)))) .GT. TOL.*> \endverbatim*>*> \param[in] NSWEEP*> \verbatim*> NSWEEP is INTEGER*> NSWEEP is the number of sweeps of Jacobi rotations to be*> performed.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> LWORK is the dimension of WORK. LWORK .GE. M.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0 : successful exit.*> < 0 : if INFO = -i, then the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> DGSVJ0 is used just to enable DGESVJ to call a simplified version of*> itself to work on a submatrix of the original matrix.*>*> \par Contributors:* ==================*>*> Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)*>*> \par Bugs, Examples and Comments:* =================================*>*> Please report all bugs and send interesting test examples and comments to*> drmac@math.hr. Thank you.** =====================================================================SUBROUTINE DGSVJ0( JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS,$ SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER INFO, LDA, LDV, LWORK, M, MV, N, NSWEEPDOUBLE PRECISION EPS, SFMIN, TOLCHARACTER*1 JOBV* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), SVA( N ), D( N ), V( LDV, * ),$ WORK( LWORK )* ..** =====================================================================** .. Local Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0)* ..* .. Local Scalars ..DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,$ BIGTHETA, CS, MXAAPQ, MXSINJ, ROOTBIG, ROOTEPS,$ ROOTSFMIN, ROOTTOL, SMALL, SN, T, TEMP1, THETA,$ THSIGNINTEGER BLSKIP, EMPTSW, i, ibr, IERR, igl, IJBLSK, ir1,$ ISWROT, jbc, jgl, KBL, LKAHEAD, MVL, NBL,$ NOTROT, p, PSKIPPED, q, ROWSKIP, SWBANDLOGICAL APPLV, ROTOK, RSVEC* ..* .. Local Arrays ..DOUBLE PRECISION FASTR( 5 )* ..* .. Intrinsic Functions ..INTRINSIC DABS, MAX, DBLE, MIN, DSIGN, DSQRT* ..* .. External Functions ..DOUBLE PRECISION DDOT, DNRM2INTEGER IDAMAXLOGICAL LSAMEEXTERNAL IDAMAX, LSAME, DDOT, DNRM2* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP,$ XERBLA* ..* .. Executable Statements ..** Test the input parameters.*APPLV = LSAME( JOBV, 'A' )RSVEC = LSAME( JOBV, 'V' )IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( ( N.LT.0 ) .OR. ( N.GT.M ) ) THENINFO = -3ELSE IF( LDA.LT.M ) THENINFO = -5ELSE IF( ( RSVEC.OR.APPLV ) .AND. ( MV.LT.0 ) ) THENINFO = -8ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR.$ ( APPLV.AND.( LDV.LT.MV ) ) ) THENINFO = -10ELSE IF( TOL.LE.EPS ) THENINFO = -13ELSE IF( NSWEEP.LT.0 ) THENINFO = -14ELSE IF( LWORK.LT.M ) THENINFO = -16ELSEINFO = 0END IF** #:(IF( INFO.NE.0 ) THENCALL XERBLA( 'DGSVJ0', -INFO )RETURNEND IF*IF( RSVEC ) THENMVL = NELSE IF( APPLV ) THENMVL = MVEND IFRSVEC = RSVEC .OR. APPLVROOTEPS = DSQRT( EPS )ROOTSFMIN = DSQRT( SFMIN )SMALL = SFMIN / EPSBIG = ONE / SFMINROOTBIG = ONE / ROOTSFMINBIGTHETA = ONE / ROOTEPSROOTTOL = DSQRT( TOL )** -#- Row-cyclic Jacobi SVD algorithm with column pivoting -#-*EMPTSW = ( N*( N-1 ) ) / 2NOTROT = 0FASTR( 1 ) = ZERO** -#- Row-cyclic pivot strategy with de Rijk's pivoting -#-*SWBAND = 0*[TP] SWBAND is a tuning parameter. It is meaningful and effective* if SGESVJ is used as a computational routine in the preconditioned* Jacobi SVD algorithm SGESVJ. For sweeps i=1:SWBAND the procedure* ......KBL = MIN( 8, N )*[TP] KBL is a tuning parameter that defines the tile size in the* tiling of the p-q loops of pivot pairs. In general, an optimal* value of KBL depends on the matrix dimensions and on the* parameters of the computer's memory.*NBL = N / KBLIF( ( NBL*KBL ).NE.N )NBL = NBL + 1BLSKIP = ( KBL**2 ) + 1*[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL.ROWSKIP = MIN( 5, KBL )*[TP] ROWSKIP is a tuning parameter.LKAHEAD = 1*[TP] LKAHEAD is a tuning parameter.SWBAND = 0PSKIPPED = 0*DO 1993 i = 1, NSWEEP* .. go go go ...*MXAAPQ = ZEROMXSINJ = ZEROISWROT = 0*NOTROT = 0PSKIPPED = 0*DO 2000 ibr = 1, NBLigl = ( ibr-1 )*KBL + 1*DO 1002 ir1 = 0, MIN( LKAHEAD, NBL-ibr )*igl = igl + ir1*KBL*DO 2001 p = igl, MIN( igl+KBL-1, N-1 )* .. de Rijk's pivotingq = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1IF( p.NE.q ) THENCALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1,$ V( 1, q ), 1 )TEMP1 = SVA( p )SVA( p ) = SVA( q )SVA( q ) = TEMP1TEMP1 = D( p )D( p ) = D( q )D( q ) = TEMP1END IF*IF( ir1.EQ.0 ) THEN** Column norms are periodically updated by explicit* norm computation.* Caveat:* Some BLAS implementations compute DNRM2(M,A(1,p),1)* as DSQRT(DDOT(M,A(1,p),1,A(1,p),1)), which may result in* overflow for ||A(:,p)||_2 > DSQRT(overflow_threshold), and* undeflow for ||A(:,p)||_2 < DSQRT(underflow_threshold).* Hence, DNRM2 cannot be trusted, not even in the case when* the true norm is far from the under(over)flow boundaries.* If properly implemented DNRM2 is available, the IF-THEN-ELSE* below should read "AAPP = DNRM2( M, A(1,p), 1 ) * D(p)".*IF( ( SVA( p ).LT.ROOTBIG ) .AND.$ ( SVA( p ).GT.ROOTSFMIN ) ) THENSVA( p ) = DNRM2( M, A( 1, p ), 1 )*D( p )ELSETEMP1 = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, TEMP1, AAPP )SVA( p ) = TEMP1*DSQRT( AAPP )*D( p )END IFAAPP = SVA( p )ELSEAAPP = SVA( p )END IF*IF( AAPP.GT.ZERO ) THEN*PSKIPPED = 0*DO 2002 q = p + 1, MIN( igl+KBL-1, N )*AAQQ = SVA( q )IF( AAQQ.GT.ZERO ) THEN*AAPP0 = AAPPIF( AAQQ.GE.ONE ) THENROTOK = ( SMALL*AAPP ).LE.AAQQIF( AAPP.LT.( BIG / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*D( p )*D( q ) / AAQQ )$ / AAPPELSECALL DCOPY( M, A( 1, p ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAPP, D( p ),$ M, 1, WORK, LDA, IERR )AAPQ = DDOT( M, WORK, 1, A( 1, q ),$ 1 )*D( q ) / AAQQEND IFELSEROTOK = AAPP.LE.( AAQQ / SMALL )IF( AAPP.GT.( SMALL / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*D( p )*D( q ) / AAQQ )$ / AAPPELSECALL DCOPY( M, A( 1, q ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAQQ, D( q ),$ M, 1, WORK, LDA, IERR )AAPQ = DDOT( M, WORK, 1, A( 1, p ),$ 1 )*D( p ) / AAPPEND IFEND IF*MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )** TO rotate or NOT to rotate, THAT is the question ...*IF( DABS( AAPQ ).GT.TOL ) THEN** .. rotate* ROTATED = ROTATED + ONE*IF( ir1.EQ.0 ) THENNOTROT = 0PSKIPPED = 0ISWROT = ISWROT + 1END IF*IF( ROTOK ) THEN*AQOAP = AAQQ / AAPPAPOAQ = AAPP / AAQQTHETA = -HALF*DABS( AQOAP-APOAQ )/AAPQ*IF( DABS( THETA ).GT.BIGTHETA ) THEN*T = HALF / THETAFASTR( 3 ) = T*D( p ) / D( q )FASTR( 4 ) = -T*D( q ) / D( p )CALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1, FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1,$ V( 1, q ), 1,$ FASTR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )MXSINJ = MAX( MXSINJ, DABS( T ) )*ELSE** .. choose correct signum for THETA and rotate*THSIGN = -DSIGN( ONE, AAPQ )T = ONE / ( THETA+THSIGN*$ DSQRT( ONE+THETA*THETA ) )CS = DSQRT( ONE / ( ONE+T*T ) )SN = T*CS*MXSINJ = MAX( MXSINJ, DABS( SN ) )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )*APOAQ = D( p ) / D( q )AQOAP = D( q ) / D( p )IF( D( p ).GE.ONE ) THENIF( D( q ).GE.ONE ) THENFASTR( 3 ) = T*APOAQFASTR( 4 ) = -T*AQOAPD( p ) = D( p )*CSD( q ) = D( q )*CSCALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1,$ FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1, V( 1, q ),$ 1, FASTR )ELSECALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )D( p ) = D( p )*CSD( q ) = D( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL, -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFEND IFELSEIF( D( q ).GE.ONE ) THENCALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M, -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )D( p ) = D( p ) / CSD( q ) = D( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL, T*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFELSEIF( D( p ).GE.D( q ) ) THENCALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )D( p ) = D( p )*CSD( q ) = D( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL,$ -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFELSECALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M,$ -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )D( p ) = D( p ) / CSD( q ) = D( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL,$ T*APOAQ, V( 1, p ),$ 1, V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFEND IFEND IFEND IFEND IF*ELSE* .. have to use modified Gram-Schmidt like transformationCALL DCOPY( M, A( 1, p ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAPP, ONE, M,$ 1, WORK, LDA, IERR )CALL DLASCL( 'G', 0, 0, AAQQ, ONE, M,$ 1, A( 1, q ), LDA, IERR )TEMP1 = -AAPQ*D( p ) / D( q )CALL DAXPY( M, TEMP1, WORK, 1,$ A( 1, q ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAQQ, M,$ 1, A( 1, q ), LDA, IERR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )END IF* END IF ROTOK THEN ... ELSE** In the case of cancellation in updating SVA(q), SVA(p)* recompute SVA(q), SVA(p).IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )$ THENIF( ( AAQQ.LT.ROOTBIG ) .AND.$ ( AAQQ.GT.ROOTSFMIN ) ) THENSVA( q ) = DNRM2( M, A( 1, q ), 1 )*$ D( q )ELSET = ZEROAAQQ = ONECALL DLASSQ( M, A( 1, q ), 1, T,$ AAQQ )SVA( q ) = T*DSQRT( AAQQ )*D( q )END IFEND IFIF( ( AAPP / AAPP0 ).LE.ROOTEPS ) THENIF( ( AAPP.LT.ROOTBIG ) .AND.$ ( AAPP.GT.ROOTSFMIN ) ) THENAAPP = DNRM2( M, A( 1, p ), 1 )*$ D( p )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, T,$ AAPP )AAPP = T*DSQRT( AAPP )*D( p )END IFSVA( p ) = AAPPEND IF*ELSE* A(:,p) and A(:,q) already numerically orthogonalIF( ir1.EQ.0 )NOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1END IFELSE* A(:,q) is zero columnIF( ir1.EQ.0 )NOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1END IF*IF( ( i.LE.SWBAND ) .AND.$ ( PSKIPPED.GT.ROWSKIP ) ) THENIF( ir1.EQ.0 )AAPP = -AAPPNOTROT = 0GO TO 2103END IF*2002 CONTINUE* END q-LOOP*2103 CONTINUE* bailed out of q-loopSVA( p ) = AAPPELSESVA( p ) = AAPPIF( ( ir1.EQ.0 ) .AND. ( AAPP.EQ.ZERO ) )$ NOTROT = NOTROT + MIN( igl+KBL-1, N ) - pEND IF*2001 CONTINUE* end of the p-loop* end of doing the block ( ibr, ibr )1002 CONTINUE* end of ir1-loop**........................................................* ... go to the off diagonal blocks*igl = ( ibr-1 )*KBL + 1*DO 2010 jbc = ibr + 1, NBL*jgl = ( jbc-1 )*KBL + 1** doing the block at ( ibr, jbc )*IJBLSK = 0DO 2100 p = igl, MIN( igl+KBL-1, N )*AAPP = SVA( p )*IF( AAPP.GT.ZERO ) THEN*PSKIPPED = 0*DO 2200 q = jgl, MIN( jgl+KBL-1, N )*AAQQ = SVA( q )*IF( AAQQ.GT.ZERO ) THENAAPP0 = AAPP** -#- M x 2 Jacobi SVD -#-** -#- Safe Gram matrix computation -#-*IF( AAQQ.GE.ONE ) THENIF( AAPP.GE.AAQQ ) THENROTOK = ( SMALL*AAPP ).LE.AAQQELSEROTOK = ( SMALL*AAQQ ).LE.AAPPEND IFIF( AAPP.LT.( BIG / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*D( p )*D( q ) / AAQQ )$ / AAPPELSECALL DCOPY( M, A( 1, p ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAPP, D( p ),$ M, 1, WORK, LDA, IERR )AAPQ = DDOT( M, WORK, 1, A( 1, q ),$ 1 )*D( q ) / AAQQEND IFELSEIF( AAPP.GE.AAQQ ) THENROTOK = AAPP.LE.( AAQQ / SMALL )ELSEROTOK = AAQQ.LE.( AAPP / SMALL )END IFIF( AAPP.GT.( SMALL / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*D( p )*D( q ) / AAQQ )$ / AAPPELSECALL DCOPY( M, A( 1, q ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAQQ, D( q ),$ M, 1, WORK, LDA, IERR )AAPQ = DDOT( M, WORK, 1, A( 1, p ),$ 1 )*D( p ) / AAPPEND IFEND IF*MXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )** TO rotate or NOT to rotate, THAT is the question ...*IF( DABS( AAPQ ).GT.TOL ) THENNOTROT = 0* ROTATED = ROTATED + 1PSKIPPED = 0ISWROT = ISWROT + 1*IF( ROTOK ) THEN*AQOAP = AAQQ / AAPPAPOAQ = AAPP / AAQQTHETA = -HALF*DABS( AQOAP-APOAQ )/AAPQIF( AAQQ.GT.AAPP0 )THETA = -THETA*IF( DABS( THETA ).GT.BIGTHETA ) THENT = HALF / THETAFASTR( 3 ) = T*D( p ) / D( q )FASTR( 4 ) = -T*D( q ) / D( p )CALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1, FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1,$ V( 1, q ), 1,$ FASTR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )MXSINJ = MAX( MXSINJ, DABS( T ) )ELSE** .. choose correct signum for THETA and rotate*THSIGN = -DSIGN( ONE, AAPQ )IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGNT = ONE / ( THETA+THSIGN*$ DSQRT( ONE+THETA*THETA ) )CS = DSQRT( ONE / ( ONE+T*T ) )SN = T*CSMXSINJ = MAX( MXSINJ, DABS( SN ) )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )*APOAQ = D( p ) / D( q )AQOAP = D( q ) / D( p )IF( D( p ).GE.ONE ) THEN*IF( D( q ).GE.ONE ) THENFASTR( 3 ) = T*APOAQFASTR( 4 ) = -T*AQOAPD( p ) = D( p )*CSD( q ) = D( q )*CSCALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1,$ FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1, V( 1, q ),$ 1, FASTR )ELSECALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )IF( RSVEC ) THENCALL DAXPY( MVL, -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFD( p ) = D( p )*CSD( q ) = D( q ) / CSEND IFELSEIF( D( q ).GE.ONE ) THENCALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M, -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )IF( RSVEC ) THENCALL DAXPY( MVL, T*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFD( p ) = D( p ) / CSD( q ) = D( q )*CSELSEIF( D( p ).GE.D( q ) ) THENCALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )D( p ) = D( p )*CSD( q ) = D( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL,$ -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFELSECALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M,$ -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )D( p ) = D( p ) / CSD( q ) = D( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL,$ T*APOAQ, V( 1, p ),$ 1, V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFEND IFEND IFEND IFEND IF*ELSEIF( AAPP.GT.AAQQ ) THENCALL DCOPY( M, A( 1, p ), 1, WORK,$ 1 )CALL DLASCL( 'G', 0, 0, AAPP, ONE,$ M, 1, WORK, LDA, IERR )CALL DLASCL( 'G', 0, 0, AAQQ, ONE,$ M, 1, A( 1, q ), LDA,$ IERR )TEMP1 = -AAPQ*D( p ) / D( q )CALL DAXPY( M, TEMP1, WORK, 1,$ A( 1, q ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAQQ,$ M, 1, A( 1, q ), LDA,$ IERR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )ELSECALL DCOPY( M, A( 1, q ), 1, WORK,$ 1 )CALL DLASCL( 'G', 0, 0, AAQQ, ONE,$ M, 1, WORK, LDA, IERR )CALL DLASCL( 'G', 0, 0, AAPP, ONE,$ M, 1, A( 1, p ), LDA,$ IERR )TEMP1 = -AAPQ*D( q ) / D( p )CALL DAXPY( M, TEMP1, WORK, 1,$ A( 1, p ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAPP,$ M, 1, A( 1, p ), LDA,$ IERR )SVA( p ) = AAPP*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )END IFEND IF* END IF ROTOK THEN ... ELSE** In the case of cancellation in updating SVA(q)* .. recompute SVA(q)IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )$ THENIF( ( AAQQ.LT.ROOTBIG ) .AND.$ ( AAQQ.GT.ROOTSFMIN ) ) THENSVA( q ) = DNRM2( M, A( 1, q ), 1 )*$ D( q )ELSET = ZEROAAQQ = ONECALL DLASSQ( M, A( 1, q ), 1, T,$ AAQQ )SVA( q ) = T*DSQRT( AAQQ )*D( q )END IFEND IFIF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THENIF( ( AAPP.LT.ROOTBIG ) .AND.$ ( AAPP.GT.ROOTSFMIN ) ) THENAAPP = DNRM2( M, A( 1, p ), 1 )*$ D( p )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, T,$ AAPP )AAPP = T*DSQRT( AAPP )*D( p )END IFSVA( p ) = AAPPEND IF* end of OK rotationELSENOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1IJBLSK = IJBLSK + 1END IFELSENOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1IJBLSK = IJBLSK + 1END IF*IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) )$ THENSVA( p ) = AAPPNOTROT = 0GO TO 2011END IFIF( ( i.LE.SWBAND ) .AND.$ ( PSKIPPED.GT.ROWSKIP ) ) THENAAPP = -AAPPNOTROT = 0GO TO 2203END IF*2200 CONTINUE* end of the q-loop2203 CONTINUE*SVA( p ) = AAPP*ELSEIF( AAPP.EQ.ZERO )NOTROT = NOTROT +$ MIN( jgl+KBL-1, N ) - jgl + 1IF( AAPP.LT.ZERO )NOTROT = 0END IF2100 CONTINUE* end of the p-loop2010 CONTINUE* end of the jbc-loop2011 CONTINUE*2011 bailed out of the jbc-loopDO 2012 p = igl, MIN( igl+KBL-1, N )SVA( p ) = DABS( SVA( p ) )2012 CONTINUE*2000 CONTINUE*2000 :: end of the ibr-loop** .. update SVA(N)IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) )$ THENSVA( N ) = DNRM2( M, A( 1, N ), 1 )*D( N )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, N ), 1, T, AAPP )SVA( N ) = T*DSQRT( AAPP )*D( N )END IF** Additional steering devices*IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.$ ( ISWROT.LE.N ) ) )SWBAND = i*IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DBLE( N )*TOL ) .AND.$ ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THENGO TO 1994END IF*IF( NOTROT.GE.EMPTSW )GO TO 19941993 CONTINUE* end i=1:NSWEEP loop* #:) Reaching this point means that the procedure has comleted the given* number of iterations.INFO = NSWEEP - 1GO TO 19951994 CONTINUE* #:) Reaching this point means that during the i-th sweep all pivots were* below the given tolerance, causing early exit.*INFO = 0* #:) INFO = 0 confirms successful iterations.1995 CONTINUE** Sort the vector D.DO 5991 p = 1, N - 1q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1IF( p.NE.q ) THENTEMP1 = SVA( p )SVA( p ) = SVA( q )SVA( q ) = TEMP1TEMP1 = D( p )D( p ) = D( q )D( q ) = TEMP1CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )END IF5991 CONTINUE*RETURN* ..* .. END OF DGSVJ0* ..END*> \brief \b DGSVJ1 pre-processor for the routine dgesvj, applies Jacobi rotations targeting only particular pivots.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGSVJ1 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgsvj1.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgsvj1.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgsvj1.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGSVJ1( JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV,* EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )** .. Scalar Arguments ..* DOUBLE PRECISION EPS, SFMIN, TOL* INTEGER INFO, LDA, LDV, LWORK, M, MV, N, N1, NSWEEP* CHARACTER*1 JOBV* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), D( N ), SVA( N ), V( LDV, * ),* $ WORK( LWORK )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGSVJ1 is called from DGESVJ as a pre-processor and that is its main*> purpose. It applies Jacobi rotations in the same way as DGESVJ does, but*> it targets only particular pivots and it does not check convergence*> (stopping criterion). Few tunning parameters (marked by [TP]) are*> available for the implementer.*>*> Further Details*> ~~~~~~~~~~~~~~~*> DGSVJ1 applies few sweeps of Jacobi rotations in the column space of*> the input M-by-N matrix A. The pivot pairs are taken from the (1,2)*> off-diagonal block in the corresponding N-by-N Gram matrix A^T * A. The*> block-entries (tiles) of the (1,2) off-diagonal block are marked by the*> [x]'s in the following scheme:*>*> | * * * [x] [x] [x]|*> | * * * [x] [x] [x]| Row-cycling in the nblr-by-nblc [x] blocks.*> | * * * [x] [x] [x]| Row-cyclic pivoting inside each [x] block.*> |[x] [x] [x] * * * |*> |[x] [x] [x] * * * |*> |[x] [x] [x] * * * |*>*> In terms of the columns of A, the first N1 columns are rotated 'against'*> the remaining N-N1 columns, trying to increase the angle between the*> corresponding subspaces. The off-diagonal block is N1-by(N-N1) and it is*> tiled using quadratic tiles of side KBL. Here, KBL is a tunning parmeter.*> The number of sweeps is given in NSWEEP and the orthogonality threshold*> is given in TOL.*> \endverbatim** Arguments:* ==========**> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> Specifies whether the output from this procedure is used*> to compute the matrix V:*> = 'V': the product of the Jacobi rotations is accumulated*> by postmulyiplying the N-by-N array V.*> (See the description of V.)*> = 'A': the product of the Jacobi rotations is accumulated*> by postmulyiplying the MV-by-N array V.*> (See the descriptions of MV and V.)*> = 'N': the Jacobi rotations are not accumulated.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the input matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the input matrix A.*> M >= N >= 0.*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> N1 specifies the 2 x 2 block partition, the first N1 columns are*> rotated 'against' the remaining N-N1 columns of A.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, M-by-N matrix A, such that A*diag(D) represents*> the input matrix.*> On exit,*> A_onexit * D_onexit represents the input matrix A*diag(D)*> post-multiplied by a sequence of Jacobi rotations, where the*> rotation threshold and the total number of sweeps are given in*> TOL and NSWEEP, respectively.*> (See the descriptions of N1, D, TOL and NSWEEP.)*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The array D accumulates the scaling factors from the fast scaled*> Jacobi rotations.*> On entry, A*diag(D) represents the input matrix.*> On exit, A_onexit*diag(D_onexit) represents the input matrix*> post-multiplied by a sequence of Jacobi rotations, where the*> rotation threshold and the total number of sweeps are given in*> TOL and NSWEEP, respectively.*> (See the descriptions of N1, A, TOL and NSWEEP.)*> \endverbatim*>*> \param[in,out] SVA*> \verbatim*> SVA is DOUBLE PRECISION array, dimension (N)*> On entry, SVA contains the Euclidean norms of the columns of*> the matrix A*diag(D).*> On exit, SVA contains the Euclidean norms of the columns of*> the matrix onexit*diag(D_onexit).*> \endverbatim*>*> \param[in] MV*> \verbatim*> MV is INTEGER*> If JOBV .EQ. 'A', then MV rows of V are post-multipled by a*> sequence of Jacobi rotations.*> If JOBV = 'N', then MV is not referenced.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,N)*> If JOBV .EQ. 'V' then N rows of V are post-multipled by a*> sequence of Jacobi rotations.*> If JOBV .EQ. 'A' then MV rows of V are post-multipled by a*> sequence of Jacobi rotations.*> If JOBV = 'N', then V is not referenced.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V, LDV >= 1.*> If JOBV = 'V', LDV .GE. N.*> If JOBV = 'A', LDV .GE. MV.*> \endverbatim*>*> \param[in] EPS*> \verbatim*> EPS is DOUBLE PRECISION*> EPS = DLAMCH('Epsilon')*> \endverbatim*>*> \param[in] SFMIN*> \verbatim*> SFMIN is DOUBLE PRECISION*> SFMIN = DLAMCH('Safe Minimum')*> \endverbatim*>*> \param[in] TOL*> \verbatim*> TOL is DOUBLE PRECISION*> TOL is the threshold for Jacobi rotations. For a pair*> A(:,p), A(:,q) of pivot columns, the Jacobi rotation is*> applied only if DABS(COS(angle(A(:,p),A(:,q)))) .GT. TOL.*> \endverbatim*>*> \param[in] NSWEEP*> \verbatim*> NSWEEP is INTEGER*> NSWEEP is the number of sweeps of Jacobi rotations to be*> performed.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> LWORK is the dimension of WORK. LWORK .GE. M.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0 : successful exit.*> < 0 : if INFO = -i, then the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)** =====================================================================SUBROUTINE DGSVJ1( JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV,$ EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..DOUBLE PRECISION EPS, SFMIN, TOLINTEGER INFO, LDA, LDV, LWORK, M, MV, N, N1, NSWEEPCHARACTER*1 JOBV* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( N ), SVA( N ), V( LDV, * ),$ WORK( LWORK )* ..** =====================================================================** .. Local Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,$ BIGTHETA, CS, LARGE, MXAAPQ, MXSINJ, ROOTBIG,$ ROOTEPS, ROOTSFMIN, ROOTTOL, SMALL, SN, T,$ TEMP1, THETA, THSIGNINTEGER BLSKIP, EMPTSW, i, ibr, igl, IERR, IJBLSK,$ ISWROT, jbc, jgl, KBL, MVL, NOTROT, nblc, nblr,$ p, PSKIPPED, q, ROWSKIP, SWBANDLOGICAL APPLV, ROTOK, RSVEC* ..* .. Local Arrays ..DOUBLE PRECISION FASTR( 5 )* ..* .. Intrinsic Functions ..INTRINSIC DABS, MAX, DBLE, MIN, DSIGN, DSQRT* ..* .. External Functions ..DOUBLE PRECISION DDOT, DNRM2INTEGER IDAMAXLOGICAL LSAMEEXTERNAL IDAMAX, LSAME, DDOT, DNRM2* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP,$ XERBLA* ..* .. Executable Statements ..** Test the input parameters.*APPLV = LSAME( JOBV, 'A' )RSVEC = LSAME( JOBV, 'V' )IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( ( N.LT.0 ) .OR. ( N.GT.M ) ) THENINFO = -3ELSE IF( N1.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.M ) THENINFO = -6ELSE IF( ( RSVEC.OR.APPLV ) .AND. ( MV.LT.0 ) ) THENINFO = -9ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR.$ ( APPLV.AND.( LDV.LT.MV ) ) ) THENINFO = -11ELSE IF( TOL.LE.EPS ) THENINFO = -14ELSE IF( NSWEEP.LT.0 ) THENINFO = -15ELSE IF( LWORK.LT.M ) THENINFO = -17ELSEINFO = 0END IF** #:(IF( INFO.NE.0 ) THENCALL XERBLA( 'DGSVJ1', -INFO )RETURNEND IF*IF( RSVEC ) THENMVL = NELSE IF( APPLV ) THENMVL = MVEND IFRSVEC = RSVEC .OR. APPLVROOTEPS = DSQRT( EPS )ROOTSFMIN = DSQRT( SFMIN )SMALL = SFMIN / EPSBIG = ONE / SFMINROOTBIG = ONE / ROOTSFMINLARGE = BIG / DSQRT( DBLE( M*N ) )BIGTHETA = ONE / ROOTEPSROOTTOL = DSQRT( TOL )** .. Initialize the right singular vector matrix ..** RSVEC = LSAME( JOBV, 'Y' )*EMPTSW = N1*( N-N1 )NOTROT = 0FASTR( 1 ) = ZERO** .. Row-cyclic pivot strategy with de Rijk's pivoting ..*KBL = MIN( 8, N )NBLR = N1 / KBLIF( ( NBLR*KBL ).NE.N1 )NBLR = NBLR + 1* .. the tiling is nblr-by-nblc [tiles]NBLC = ( N-N1 ) / KBLIF( ( NBLC*KBL ).NE.( N-N1 ) )NBLC = NBLC + 1BLSKIP = ( KBL**2 ) + 1*[TP] BLKSKIP is a tuning parameter that depends on SWBAND and KBL.ROWSKIP = MIN( 5, KBL )*[TP] ROWSKIP is a tuning parameter.SWBAND = 0*[TP] SWBAND is a tuning parameter. It is meaningful and effective* if SGESVJ is used as a computational routine in the preconditioned* Jacobi SVD algorithm SGESVJ.*** | * * * [x] [x] [x]|* | * * * [x] [x] [x]| Row-cycling in the nblr-by-nblc [x] blocks.* | * * * [x] [x] [x]| Row-cyclic pivoting inside each [x] block.* |[x] [x] [x] * * * |* |[x] [x] [x] * * * |* |[x] [x] [x] * * * |**DO 1993 i = 1, NSWEEP* .. go go go ...*MXAAPQ = ZEROMXSINJ = ZEROISWROT = 0*NOTROT = 0PSKIPPED = 0*DO 2000 ibr = 1, NBLRigl = ( ibr-1 )*KBL + 1***........................................................* ... go to the off diagonal blocksigl = ( ibr-1 )*KBL + 1DO 2010 jbc = 1, NBLCjgl = N1 + ( jbc-1 )*KBL + 1* doing the block at ( ibr, jbc )IJBLSK = 0DO 2100 p = igl, MIN( igl+KBL-1, N1 )AAPP = SVA( p )IF( AAPP.GT.ZERO ) THENPSKIPPED = 0DO 2200 q = jgl, MIN( jgl+KBL-1, N )*AAQQ = SVA( q )IF( AAQQ.GT.ZERO ) THENAAPP0 = AAPP** .. M x 2 Jacobi SVD ..** .. Safe Gram matrix computation ..*IF( AAQQ.GE.ONE ) THENIF( AAPP.GE.AAQQ ) THENROTOK = ( SMALL*AAPP ).LE.AAQQELSEROTOK = ( SMALL*AAQQ ).LE.AAPPEND IFIF( AAPP.LT.( BIG / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*D( p )*D( q ) / AAQQ )$ / AAPPELSECALL DCOPY( M, A( 1, p ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAPP, D( p ),$ M, 1, WORK, LDA, IERR )AAPQ = DDOT( M, WORK, 1, A( 1, q ),$ 1 )*D( q ) / AAQQEND IFELSEIF( AAPP.GE.AAQQ ) THENROTOK = AAPP.LE.( AAQQ / SMALL )ELSEROTOK = AAQQ.LE.( AAPP / SMALL )END IFIF( AAPP.GT.( SMALL / AAQQ ) ) THENAAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,$ q ), 1 )*D( p )*D( q ) / AAQQ )$ / AAPPELSECALL DCOPY( M, A( 1, q ), 1, WORK, 1 )CALL DLASCL( 'G', 0, 0, AAQQ, D( q ),$ M, 1, WORK, LDA, IERR )AAPQ = DDOT( M, WORK, 1, A( 1, p ),$ 1 )*D( p ) / AAPPEND IFEND IFMXAAPQ = MAX( MXAAPQ, DABS( AAPQ ) )* TO rotate or NOT to rotate, THAT is the question ...*IF( DABS( AAPQ ).GT.TOL ) THENNOTROT = 0* ROTATED = ROTATED + 1PSKIPPED = 0ISWROT = ISWROT + 1*IF( ROTOK ) THEN*AQOAP = AAQQ / AAPPAPOAQ = AAPP / AAQQTHETA = -HALF*DABS(AQOAP-APOAQ) / AAPQIF( AAQQ.GT.AAPP0 )THETA = -THETAIF( DABS( THETA ).GT.BIGTHETA ) THENT = HALF / THETAFASTR( 3 ) = T*D( p ) / D( q )FASTR( 4 ) = -T*D( q ) / D( p )CALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1, FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1,$ V( 1, q ), 1,$ FASTR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )MXSINJ = MAX( MXSINJ, DABS( T ) )ELSE** .. choose correct signum for THETA and rotate*THSIGN = -DSIGN( ONE, AAPQ )IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGNT = ONE / ( THETA+THSIGN*$ DSQRT( ONE+THETA*THETA ) )CS = DSQRT( ONE / ( ONE+T*T ) )SN = T*CSMXSINJ = MAX( MXSINJ, DABS( SN ) )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE+T*APOAQ*AAPQ ) )AAPP = AAPP*DSQRT( MAX( ZERO,$ ONE-T*AQOAP*AAPQ ) )APOAQ = D( p ) / D( q )AQOAP = D( q ) / D( p )IF( D( p ).GE.ONE ) THEN*IF( D( q ).GE.ONE ) THENFASTR( 3 ) = T*APOAQFASTR( 4 ) = -T*AQOAPD( p ) = D( p )*CSD( q ) = D( q )*CSCALL DROTM( M, A( 1, p ), 1,$ A( 1, q ), 1,$ FASTR )IF( RSVEC )CALL DROTM( MVL,$ V( 1, p ), 1, V( 1, q ),$ 1, FASTR )ELSECALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )IF( RSVEC ) THENCALL DAXPY( MVL, -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFD( p ) = D( p )*CSD( q ) = D( q ) / CSEND IFELSEIF( D( q ).GE.ONE ) THENCALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M, -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )IF( RSVEC ) THENCALL DAXPY( MVL, T*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFD( p ) = D( p ) / CSD( q ) = D( q )*CSELSEIF( D( p ).GE.D( q ) ) THENCALL DAXPY( M, -T*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )CALL DAXPY( M, CS*SN*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )D( p ) = D( p )*CSD( q ) = D( q ) / CSIF( RSVEC ) THENCALL DAXPY( MVL,$ -T*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )CALL DAXPY( MVL,$ CS*SN*APOAQ,$ V( 1, p ), 1,$ V( 1, q ), 1 )END IFELSECALL DAXPY( M, T*APOAQ,$ A( 1, p ), 1,$ A( 1, q ), 1 )CALL DAXPY( M,$ -CS*SN*AQOAP,$ A( 1, q ), 1,$ A( 1, p ), 1 )D( p ) = D( p ) / CSD( q ) = D( q )*CSIF( RSVEC ) THENCALL DAXPY( MVL,$ T*APOAQ, V( 1, p ),$ 1, V( 1, q ), 1 )CALL DAXPY( MVL,$ -CS*SN*AQOAP,$ V( 1, q ), 1,$ V( 1, p ), 1 )END IFEND IFEND IFEND IFEND IFELSEIF( AAPP.GT.AAQQ ) THENCALL DCOPY( M, A( 1, p ), 1, WORK,$ 1 )CALL DLASCL( 'G', 0, 0, AAPP, ONE,$ M, 1, WORK, LDA, IERR )CALL DLASCL( 'G', 0, 0, AAQQ, ONE,$ M, 1, A( 1, q ), LDA,$ IERR )TEMP1 = -AAPQ*D( p ) / D( q )CALL DAXPY( M, TEMP1, WORK, 1,$ A( 1, q ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAQQ,$ M, 1, A( 1, q ), LDA,$ IERR )SVA( q ) = AAQQ*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )ELSECALL DCOPY( M, A( 1, q ), 1, WORK,$ 1 )CALL DLASCL( 'G', 0, 0, AAQQ, ONE,$ M, 1, WORK, LDA, IERR )CALL DLASCL( 'G', 0, 0, AAPP, ONE,$ M, 1, A( 1, p ), LDA,$ IERR )TEMP1 = -AAPQ*D( q ) / D( p )CALL DAXPY( M, TEMP1, WORK, 1,$ A( 1, p ), 1 )CALL DLASCL( 'G', 0, 0, ONE, AAPP,$ M, 1, A( 1, p ), LDA,$ IERR )SVA( p ) = AAPP*DSQRT( MAX( ZERO,$ ONE-AAPQ*AAPQ ) )MXSINJ = MAX( MXSINJ, SFMIN )END IFEND IF* END IF ROTOK THEN ... ELSE** In the case of cancellation in updating SVA(q)* .. recompute SVA(q)IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )$ THENIF( ( AAQQ.LT.ROOTBIG ) .AND.$ ( AAQQ.GT.ROOTSFMIN ) ) THENSVA( q ) = DNRM2( M, A( 1, q ), 1 )*$ D( q )ELSET = ZEROAAQQ = ONECALL DLASSQ( M, A( 1, q ), 1, T,$ AAQQ )SVA( q ) = T*DSQRT( AAQQ )*D( q )END IFEND IFIF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THENIF( ( AAPP.LT.ROOTBIG ) .AND.$ ( AAPP.GT.ROOTSFMIN ) ) THENAAPP = DNRM2( M, A( 1, p ), 1 )*$ D( p )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, p ), 1, T,$ AAPP )AAPP = T*DSQRT( AAPP )*D( p )END IFSVA( p ) = AAPPEND IF* end of OK rotationELSENOTROT = NOTROT + 1* SKIPPED = SKIPPED + 1PSKIPPED = PSKIPPED + 1IJBLSK = IJBLSK + 1END IFELSENOTROT = NOTROT + 1PSKIPPED = PSKIPPED + 1IJBLSK = IJBLSK + 1END IF* IF ( NOTROT .GE. EMPTSW ) GO TO 2011IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) )$ THENSVA( p ) = AAPPNOTROT = 0GO TO 2011END IFIF( ( i.LE.SWBAND ) .AND.$ ( PSKIPPED.GT.ROWSKIP ) ) THENAAPP = -AAPPNOTROT = 0GO TO 2203END IF*2200 CONTINUE* end of the q-loop2203 CONTINUESVA( p ) = AAPP*ELSEIF( AAPP.EQ.ZERO )NOTROT = NOTROT +$ MIN( jgl+KBL-1, N ) - jgl + 1IF( AAPP.LT.ZERO )NOTROT = 0*** IF ( NOTROT .GE. EMPTSW ) GO TO 2011END IF2100 CONTINUE* end of the p-loop2010 CONTINUE* end of the jbc-loop2011 CONTINUE*2011 bailed out of the jbc-loopDO 2012 p = igl, MIN( igl+KBL-1, N )SVA( p ) = DABS( SVA( p ) )2012 CONTINUE*** IF ( NOTROT .GE. EMPTSW ) GO TO 19942000 CONTINUE*2000 :: end of the ibr-loop** .. update SVA(N)IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) )$ THENSVA( N ) = DNRM2( M, A( 1, N ), 1 )*D( N )ELSET = ZEROAAPP = ONECALL DLASSQ( M, A( 1, N ), 1, T, AAPP )SVA( N ) = T*DSQRT( AAPP )*D( N )END IF** Additional steering devices*IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.$ ( ISWROT.LE.N ) ) )SWBAND = iIF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DBLE( N )*TOL ) .AND.$ ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THENGO TO 1994END IF*IF( NOTROT.GE.EMPTSW )GO TO 19941993 CONTINUE* end i=1:NSWEEP loop* #:) Reaching this point means that the procedure has completed the given* number of sweeps.INFO = NSWEEP - 1GO TO 19951994 CONTINUE* #:) Reaching this point means that during the i-th sweep all pivots were* below the given threshold, causing early exit.INFO = 0* #:) INFO = 0 confirms successful iterations.1995 CONTINUE** Sort the vector D*DO 5991 p = 1, N - 1q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1IF( p.NE.q ) THENTEMP1 = SVA( p )SVA( p ) = SVA( q )SVA( q ) = TEMP1TEMP1 = D( p )D( p ) = D( q )D( q ) = TEMP1CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )END IF5991 CONTINUE*RETURN* ..* .. END OF DGSVJ1* ..END*> \brief \b DGTCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgtcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgtcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgtcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTCON( NORM, N, DL, D, DU, DU2, IPIV, ANORM, RCOND,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER INFO, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION D( * ), DL( * ), DU( * ), DU2( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTCON estimates the reciprocal of the condition number of a real*> tridiagonal matrix A using the LU factorization as computed by*> DGTTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies whether the 1-norm condition number or the*> infinity-norm condition number is required:*> = '1' or 'O': 1-norm;*> = 'I': Infinity-norm.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) multipliers that define the matrix L from the*> LU factorization of A as computed by DGTTRF.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the upper triangular matrix U from*> the LU factorization of A.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) elements of the first superdiagonal of U.*> \endverbatim*>*> \param[in] DU2*> \verbatim*> DU2 is DOUBLE PRECISION array, dimension (N-2)*> The (n-2) elements of the second superdiagonal of U.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= n, row i of the matrix was*> interchanged with row IPIV(i). IPIV(i) will always be either*> i or i+1; IPIV(i) = i indicates a row interchange was not*> required.*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> If NORM = '1' or 'O', the 1-norm of the original matrix A.*> If NORM = 'I', the infinity-norm of the original matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an*> estimate of the 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTcomputational** =====================================================================SUBROUTINE DGTCON( NORM, N, DL, D, DU, DU2, IPIV, ANORM, RCOND,$ WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER INFO, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION D( * ), DL( * ), DU( * ), DU2( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ONENRMINTEGER I, KASE, KASE1DOUBLE PRECISION AINVNM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGTTRS, DLACN2, XERBLA* ..* .. Executable Statements ..** Test the input arguments.*INFO = 0ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ANORM.LT.ZERO ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF** Check that D(1:N) is non-zero.*DO 10 I = 1, NIF( D( I ).EQ.ZERO )$ RETURN10 CONTINUE*AINVNM = ZEROIF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 020 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(U)*inv(L).*CALL DGTTRS( 'No transpose', N, 1, DL, D, DU, DU2, IPIV,$ WORK, N, INFO )ELSE** Multiply by inv(L**T)*inv(U**T).*CALL DGTTRS( 'Transpose', N, 1, DL, D, DU, DU2, IPIV, WORK,$ N, INFO )END IFGO TO 20END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*RETURN** End of DGTCON*END*> \brief \b DGTRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgtrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgtrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgtrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTRFS( TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF, DU2,* IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),* $ DL( * ), DLF( * ), DU( * ), DU2( * ), DUF( * ),* $ FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is tridiagonal, and provides*> error bounds and backward error estimates for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of A.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of A.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) superdiagonal elements of A.*> \endverbatim*>*> \param[in] DLF*> \verbatim*> DLF is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) multipliers that define the matrix L from the*> LU factorization of A as computed by DGTTRF.*> \endverbatim*>*> \param[in] DF*> \verbatim*> DF is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the upper triangular matrix U from*> the LU factorization of A.*> \endverbatim*>*> \param[in] DUF*> \verbatim*> DUF is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) elements of the first superdiagonal of U.*> \endverbatim*>*> \param[in] DU2*> \verbatim*> DU2 is DOUBLE PRECISION array, dimension (N-2)*> The (n-2) elements of the second superdiagonal of U.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= n, row i of the matrix was*> interchanged with row IPIV(i). IPIV(i) will always be either*> i or i+1; IPIV(i) = i indicates a row interchange was not*> required.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DGTTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTcomputational** =====================================================================SUBROUTINE DGTRFS( TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF, DU2,$ IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),$ DL( * ), DLF( * ), DU( * ), DU2( * ), DUF( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANCHARACTER TRANSN, TRANSTINTEGER COUNT, I, J, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGTTRS, DLACN2, DLAGTM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -13ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -15END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANSN = 'N'TRANST = 'T'ELSETRANSN = 'T'TRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = 4EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 110 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - op(A) * X,* where op(A) = A, A**T, or A**H, depending on TRANS.*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DLAGTM( TRANS, N, 1, -ONE, DL, D, DU, X( 1, J ), LDX, ONE,$ WORK( N+1 ), N )** Compute abs(op(A))*abs(x) + abs(b) for use in the backward* error bound.*IF( NOTRAN ) THENIF( N.EQ.1 ) THENWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) )ELSEWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) ) +$ ABS( DU( 1 )*X( 2, J ) )DO 30 I = 2, N - 1WORK( I ) = ABS( B( I, J ) ) +$ ABS( DL( I-1 )*X( I-1, J ) ) +$ ABS( D( I )*X( I, J ) ) +$ ABS( DU( I )*X( I+1, J ) )30 CONTINUEWORK( N ) = ABS( B( N, J ) ) +$ ABS( DL( N-1 )*X( N-1, J ) ) +$ ABS( D( N )*X( N, J ) )END IFELSEIF( N.EQ.1 ) THENWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) )ELSEWORK( 1 ) = ABS( B( 1, J ) ) + ABS( D( 1 )*X( 1, J ) ) +$ ABS( DL( 1 )*X( 2, J ) )DO 40 I = 2, N - 1WORK( I ) = ABS( B( I, J ) ) +$ ABS( DU( I-1 )*X( I-1, J ) ) +$ ABS( D( I )*X( I, J ) ) +$ ABS( DL( I )*X( I+1, J ) )40 CONTINUEWORK( N ) = ABS( B( N, J ) ) +$ ABS( DU( N-1 )*X( N-1, J ) ) +$ ABS( D( N )*X( N, J ) )END IFEND IF** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*S = ZERODO 50 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF50 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DGTTRS( TRANS, N, 1, DLF, DF, DUF, DU2, IPIV,$ WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 60 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF60 CONTINUE*KASE = 070 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DGTTRS( TRANST, N, 1, DLF, DF, DUF, DU2, IPIV,$ WORK( N+1 ), N, INFO )DO 80 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )80 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 90 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )90 CONTINUECALL DGTTRS( TRANSN, N, 1, DLF, DF, DUF, DU2, IPIV,$ WORK( N+1 ), N, INFO )END IFGO TO 70END IF** Normalize error.*LSTRES = ZERODO 100 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )100 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*110 CONTINUE*RETURN** End of DGTRFS*END*> \brief <b> DGTSV computes the solution to system of linear equations A * X = B for GT matrices </b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgtsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgtsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgtsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTSV solves the equation*>*> A*X = B,*>*> where A is an n by n tridiagonal matrix, by Gaussian elimination with*> partial pivoting.*>*> Note that the equation A**T*X = B may be solved by interchanging the*> order of the arguments DU and DL.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> On entry, DL must contain the (n-1) sub-diagonal elements of*> A.*>*> On exit, DL is overwritten by the (n-2) elements of the*> second super-diagonal of the upper triangular matrix U from*> the LU factorization of A, in DL(1), ..., DL(n-2).*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, D must contain the diagonal elements of A.*>*> On exit, D is overwritten by the n diagonal elements of U.*> \endverbatim*>*> \param[in,out] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> On entry, DU must contain the (n-1) super-diagonal elements*> of A.*>*> On exit, DU is overwritten by the (n-1) elements of the first*> super-diagonal of U.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N by NRHS matrix of right hand side matrix B.*> On exit, if INFO = 0, the N by NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, U(i,i) is exactly zero, and the solution*> has not been computed. The factorization has not been*> completed unless i = N.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTsolve** =====================================================================SUBROUTINE DGTSV( N, NRHS, DL, D, DU, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION FACT, TEMP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( NRHS.LT.0 ) THENINFO = -2ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTSV ', -INFO )RETURNEND IF*IF( N.EQ.0 )$ RETURN*IF( NRHS.EQ.1 ) THENDO 10 I = 1, N - 2IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN** No row interchange required*IF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )ELSEINFO = IRETURNEND IFDL( I ) = ZEROELSE** Interchange rows I and I+1*FACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDL( I ) = DU( I+1 )DU( I+1 ) = -FACT*DL( I )DU( I ) = TEMPTEMP = B( I, 1 )B( I, 1 ) = B( I+1, 1 )B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )END IF10 CONTINUEIF( N.GT.1 ) THENI = N - 1IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THENIF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )B( I+1, 1 ) = B( I+1, 1 ) - FACT*B( I, 1 )ELSEINFO = IRETURNEND IFELSEFACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDU( I ) = TEMPTEMP = B( I, 1 )B( I, 1 ) = B( I+1, 1 )B( I+1, 1 ) = TEMP - FACT*B( I+1, 1 )END IFEND IFIF( D( N ).EQ.ZERO ) THENINFO = NRETURNEND IFELSEDO 40 I = 1, N - 2IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN** No row interchange required*IF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )DO 20 J = 1, NRHSB( I+1, J ) = B( I+1, J ) - FACT*B( I, J )20 CONTINUEELSEINFO = IRETURNEND IFDL( I ) = ZEROELSE** Interchange rows I and I+1*FACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDL( I ) = DU( I+1 )DU( I+1 ) = -FACT*DL( I )DU( I ) = TEMPDO 30 J = 1, NRHSTEMP = B( I, J )B( I, J ) = B( I+1, J )B( I+1, J ) = TEMP - FACT*B( I+1, J )30 CONTINUEEND IF40 CONTINUEIF( N.GT.1 ) THENI = N - 1IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THENIF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )D( I+1 ) = D( I+1 ) - FACT*DU( I )DO 50 J = 1, NRHSB( I+1, J ) = B( I+1, J ) - FACT*B( I, J )50 CONTINUEELSEINFO = IRETURNEND IFELSEFACT = D( I ) / DL( I )D( I ) = DL( I )TEMP = D( I+1 )D( I+1 ) = DU( I ) - FACT*TEMPDU( I ) = TEMPDO 60 J = 1, NRHSTEMP = B( I, J )B( I, J ) = B( I+1, J )B( I+1, J ) = TEMP - FACT*B( I+1, J )60 CONTINUEEND IFEND IFIF( D( N ).EQ.ZERO ) THENINFO = NRETURNEND IFEND IF** Back solve with the matrix U from the factorization.*IF( NRHS.LE.2 ) THENJ = 170 CONTINUEB( N, J ) = B( N, J ) / D( N )IF( N.GT.1 )$ B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) / D( N-1 )DO 80 I = N - 2, 1, -1B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*$ B( I+2, J ) ) / D( I )80 CONTINUEIF( J.LT.NRHS ) THENJ = J + 1GO TO 70END IFELSEDO 100 J = 1, NRHSB( N, J ) = B( N, J ) / D( N )IF( N.GT.1 )$ B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /$ D( N-1 )DO 90 I = N - 2, 1, -1B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DL( I )*$ B( I+2, J ) ) / D( I )90 CONTINUE100 CONTINUEEND IF*RETURN** End of DGTSV*END*> \brief <b> DGTSVX computes the solution to system of linear equations A * X = B for GT matrices </b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgtsvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgtsvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgtsvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTSVX( FACT, TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF,* DU2, IPIV, B, LDB, X, LDX, RCOND, FERR, BERR,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER FACT, TRANS* INTEGER INFO, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),* $ DL( * ), DLF( * ), DU( * ), DU2( * ), DUF( * ),* $ FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTSVX uses the LU factorization to compute the solution to a real*> system of linear equations A * X = B or A**T * X = B,*> where A is a tridiagonal matrix of order N and X and B are N-by-NRHS*> matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'N', the LU decomposition is used to factor the matrix A*> as A = L * U, where L is a product of permutation and unit lower*> bidiagonal matrices and U is upper triangular with nonzeros in*> only the main diagonal and first two superdiagonals.*>*> 2. If some U(i,i)=0, so that U is exactly singular, then the routine*> returns with INFO = i. Otherwise, the factored form of A is used*> to estimate the condition number of the matrix A. If the*> reciprocal of the condition number is less than machine precision,*> INFO = N+1 is returned as a warning, but the routine still goes on*> to solve for X and compute error bounds as described below.*>*> 3. The system of equations is solved for X using the factored form*> of A.*>*> 4. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of A has been*> supplied on entry.*> = 'F': DLF, DF, DUF, DU2, and IPIV contain the factored*> form of A; DL, D, DU, DLF, DF, DUF, DU2 and IPIV*> will not be modified.*> = 'N': The matrix will be copied to DLF, DF, and DUF*> and factored.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of A.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of A.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) superdiagonal elements of A.*> \endverbatim*>*> \param[in,out] DLF*> \verbatim*> DLF is DOUBLE PRECISION array, dimension (N-1)*> If FACT = 'F', then DLF is an input argument and on entry*> contains the (n-1) multipliers that define the matrix L from*> the LU factorization of A as computed by DGTTRF.*>*> If FACT = 'N', then DLF is an output argument and on exit*> contains the (n-1) multipliers that define the matrix L from*> the LU factorization of A.*> \endverbatim*>*> \param[in,out] DF*> \verbatim*> DF is DOUBLE PRECISION array, dimension (N)*> If FACT = 'F', then DF is an input argument and on entry*> contains the n diagonal elements of the upper triangular*> matrix U from the LU factorization of A.*>*> If FACT = 'N', then DF is an output argument and on exit*> contains the n diagonal elements of the upper triangular*> matrix U from the LU factorization of A.*> \endverbatim*>*> \param[in,out] DUF*> \verbatim*> DUF is DOUBLE PRECISION array, dimension (N-1)*> If FACT = 'F', then DUF is an input argument and on entry*> contains the (n-1) elements of the first superdiagonal of U.*>*> If FACT = 'N', then DUF is an output argument and on exit*> contains the (n-1) elements of the first superdiagonal of U.*> \endverbatim*>*> \param[in,out] DU2*> \verbatim*> DU2 is DOUBLE PRECISION array, dimension (N-2)*> If FACT = 'F', then DU2 is an input argument and on entry*> contains the (n-2) elements of the second superdiagonal of*> U.*>*> If FACT = 'N', then DU2 is an output argument and on exit*> contains the (n-2) elements of the second superdiagonal of*> U.*> \endverbatim*>*> \param[in,out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> If FACT = 'F', then IPIV is an input argument and on entry*> contains the pivot indices from the LU factorization of A as*> computed by DGTTRF.*>*> If FACT = 'N', then IPIV is an output argument and on exit*> contains the pivot indices from the LU factorization of A;*> row i of the matrix was interchanged with row IPIV(i).*> IPIV(i) will always be either i or i+1; IPIV(i) = i indicates*> a row interchange was not required.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The N-by-NRHS right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A. If RCOND is less than the machine precision (in*> particular, if RCOND = 0), the matrix is singular to working*> precision. This condition is indicated by a return code of*> INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: U(i,i) is exactly zero. The factorization*> has not been completed unless i = N, but the*> factor U is exactly singular, so the solution*> and error bounds could not be computed.*> RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTsolve** =====================================================================SUBROUTINE DGTSVX( FACT, TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF,$ DU2, IPIV, B, LDB, X, LDX, RCOND, FERR, BERR,$ WORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER FACT, TRANSINTEGER INFO, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),$ DL( * ), DLF( * ), DU( * ), DU2( * ), DUF( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOFACT, NOTRANCHARACTER NORMDOUBLE PRECISION ANORM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANGTEXTERNAL LSAME, DLAMCH, DLANGT* ..* .. External Subroutines ..EXTERNAL DCOPY, DGTCON, DGTRFS, DGTTRF, DGTTRS, DLACPY,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -16END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTSVX', -INFO )RETURNEND IF*IF( NOFACT ) THEN** Compute the LU factorization of A.*CALL DCOPY( N, D, 1, DF, 1 )IF( N.GT.1 ) THENCALL DCOPY( N-1, DL, 1, DLF, 1 )CALL DCOPY( N-1, DU, 1, DUF, 1 )END IFCALL DGTTRF( N, DLF, DF, DUF, DU2, IPIV, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*IF( NOTRAN ) THENNORM = '1'ELSENORM = 'I'END IFANORM = DLANGT( NORM, N, DL, D, DU )** Compute the reciprocal of the condition number of A.*CALL DGTCON( NORM, N, DLF, DF, DUF, DU2, IPIV, ANORM, RCOND, WORK,$ IWORK, INFO )** Compute the solution vectors X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DGTTRS( TRANS, N, NRHS, DLF, DF, DUF, DU2, IPIV, X, LDX,$ INFO )** Use iterative refinement to improve the computed solutions and* compute error bounds and backward error estimates for them.*CALL DGTRFS( TRANS, N, NRHS, DL, D, DU, DLF, DF, DUF, DU2, IPIV,$ B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*RETURN** End of DGTSVX*END*> \brief \b DGTTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgttrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgttrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgttrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTTRF( N, DL, D, DU, DU2, IPIV, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION D( * ), DL( * ), DU( * ), DU2( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTTRF computes an LU factorization of a real tridiagonal matrix A*> using elimination with partial pivoting and row interchanges.*>*> The factorization has the form*> A = L * U*> where L is a product of permutation and unit lower bidiagonal*> matrices and U is upper triangular with nonzeros in only the main*> diagonal and first two superdiagonals.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in,out] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> On entry, DL must contain the (n-1) sub-diagonal elements of*> A.*>*> On exit, DL is overwritten by the (n-1) multipliers that*> define the matrix L from the LU factorization of A.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, D must contain the diagonal elements of A.*>*> On exit, D is overwritten by the n diagonal elements of the*> upper triangular matrix U from the LU factorization of A.*> \endverbatim*>*> \param[in,out] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> On entry, DU must contain the (n-1) super-diagonal elements*> of A.*>*> On exit, DU is overwritten by the (n-1) elements of the first*> super-diagonal of U.*> \endverbatim*>*> \param[out] DU2*> \verbatim*> DU2 is DOUBLE PRECISION array, dimension (N-2)*> On exit, DU2 is overwritten by the (n-2) elements of the*> second super-diagonal of U.*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= n, row i of the matrix was*> interchanged with row IPIV(i). IPIV(i) will always be either*> i or i+1; IPIV(i) = i indicates a row interchange was not*> required.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> > 0: if INFO = k, U(k,k) is exactly zero. The factorization*> has been completed, but the factor U is exactly*> singular, and division by zero will occur if it is used*> to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTcomputational** =====================================================================SUBROUTINE DGTTRF( N, DL, D, DU, DU2, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION D( * ), DL( * ), DU( * ), DU2( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION FACT, TEMP* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DGTTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Initialize IPIV(i) = i and DU2(I) = 0*DO 10 I = 1, NIPIV( I ) = I10 CONTINUEDO 20 I = 1, N - 2DU2( I ) = ZERO20 CONTINUE*DO 30 I = 1, N - 2IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THEN** No row interchange required, eliminate DL(I)*IF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )DL( I ) = FACTD( I+1 ) = D( I+1 ) - FACT*DU( I )END IFELSE** Interchange rows I and I+1, eliminate DL(I)*FACT = D( I ) / DL( I )D( I ) = DL( I )DL( I ) = FACTTEMP = DU( I )DU( I ) = D( I+1 )D( I+1 ) = TEMP - FACT*D( I+1 )DU2( I ) = DU( I+1 )DU( I+1 ) = -FACT*DU( I+1 )IPIV( I ) = I + 1END IF30 CONTINUEIF( N.GT.1 ) THENI = N - 1IF( ABS( D( I ) ).GE.ABS( DL( I ) ) ) THENIF( D( I ).NE.ZERO ) THENFACT = DL( I ) / D( I )DL( I ) = FACTD( I+1 ) = D( I+1 ) - FACT*DU( I )END IFELSEFACT = D( I ) / DL( I )D( I ) = DL( I )DL( I ) = FACTTEMP = DU( I )DU( I ) = D( I+1 )D( I+1 ) = TEMP - FACT*D( I+1 )IPIV( I ) = I + 1END IFEND IF** Check for a zero on the diagonal of U.*DO 40 I = 1, NIF( D( I ).EQ.ZERO ) THENINFO = IGO TO 50END IF40 CONTINUE50 CONTINUE*RETURN** End of DGTTRF*END*> \brief \b DGTTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgttrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgttrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgttrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,* INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTTRS solves one of the systems of equations*> A*X = B or A**T*X = B,*> with a tridiagonal matrix A using the LU factorization computed*> by DGTTRF.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations.*> = 'N': A * X = B (No transpose)*> = 'T': A**T* X = B (Transpose)*> = 'C': A**T* X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) multipliers that define the matrix L from the*> LU factorization of A.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the upper triangular matrix U from*> the LU factorization of A.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) elements of the first super-diagonal of U.*> \endverbatim*>*> \param[in] DU2*> \verbatim*> DU2 is DOUBLE PRECISION array, dimension (N-2)*> The (n-2) elements of the second super-diagonal of U.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= n, row i of the matrix was*> interchanged with row IPIV(i). IPIV(i) will always be either*> i or i+1; IPIV(i) = i indicates a row interchange was not*> required.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the matrix of right hand side vectors B.*> On exit, B is overwritten by the solution vectors X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTcomputational** =====================================================================SUBROUTINE DGTTRS( TRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL NOTRANINTEGER ITRANS, J, JB, NB* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. External Subroutines ..EXTERNAL DGTTS2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOTRAN = ( TRANS.EQ.'N' .OR. TRANS.EQ.'n' )IF( .NOT.NOTRAN .AND. .NOT.( TRANS.EQ.'T' .OR. TRANS.EQ.$ 't' ) .AND. .NOT.( TRANS.EQ.'C' .OR. TRANS.EQ.'c' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( N, 1 ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DGTTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN** Decode TRANS*IF( NOTRAN ) THENITRANS = 0ELSEITRANS = 1END IF** Determine the number of right-hand sides to solve at a time.*IF( NRHS.EQ.1 ) THENNB = 1ELSENB = MAX( 1, ILAENV( 1, 'DGTTRS', TRANS, N, NRHS, -1, -1 ) )END IF*IF( NB.GE.NRHS ) THENCALL DGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )ELSEDO 10 J = 1, NRHS, NBJB = MIN( NRHS-J+1, NB )CALL DGTTS2( ITRANS, N, JB, DL, D, DU, DU2, IPIV, B( 1, J ),$ LDB )10 CONTINUEEND IF** End of DGTTRS*END*> \brief \b DGTTS2 solves a system of linear equations with a tridiagonal matrix using the LU factorization computed by sgttrf.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DGTTS2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgtts2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgtts2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgtts2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )** .. Scalar Arguments ..* INTEGER ITRANS, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DGTTS2 solves one of the systems of equations*> A*X = B or A**T*X = B,*> with a tridiagonal matrix A using the LU factorization computed*> by DGTTRF.*> \endverbatim** Arguments:* ==========**> \param[in] ITRANS*> \verbatim*> ITRANS is INTEGER*> Specifies the form of the system of equations.*> = 0: A * X = B (No transpose)*> = 1: A**T* X = B (Transpose)*> = 2: A**T* X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) multipliers that define the matrix L from the*> LU factorization of A.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the upper triangular matrix U from*> the LU factorization of A.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) elements of the first super-diagonal of U.*> \endverbatim*>*> \param[in] DU2*> \verbatim*> DU2 is DOUBLE PRECISION array, dimension (N-2)*> The (n-2) elements of the second super-diagonal of U.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> The pivot indices; for 1 <= i <= n, row i of the matrix was*> interchanged with row IPIV(i). IPIV(i) will always be either*> i or i+1; IPIV(i) = i indicates a row interchange was not*> required.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the matrix of right hand side vectors B.*> On exit, B is overwritten by the solution vectors X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGTcomputational** =====================================================================SUBROUTINE DGTTS2( ITRANS, N, NRHS, DL, D, DU, DU2, IPIV, B, LDB )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER ITRANS, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ), DU2( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, IP, JDOUBLE PRECISION TEMP* ..* .. Executable Statements ..** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( ITRANS.EQ.0 ) THEN** Solve A*X = B using the LU factorization of A,* overwriting each right hand side vector with its solution.*IF( NRHS.LE.1 ) THENJ = 110 CONTINUE** Solve L*x = b.*DO 20 I = 1, N - 1IP = IPIV( I )TEMP = B( I+1-IP+I, J ) - DL( I )*B( IP, J )B( I, J ) = B( IP, J )B( I+1, J ) = TEMP20 CONTINUE** Solve U*x = b.*B( N, J ) = B( N, J ) / D( N )IF( N.GT.1 )$ B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /$ D( N-1 )DO 30 I = N - 2, 1, -1B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*$ B( I+2, J ) ) / D( I )30 CONTINUEIF( J.LT.NRHS ) THENJ = J + 1GO TO 10END IFELSEDO 60 J = 1, NRHS** Solve L*x = b.*DO 40 I = 1, N - 1IF( IPIV( I ).EQ.I ) THENB( I+1, J ) = B( I+1, J ) - DL( I )*B( I, J )ELSETEMP = B( I, J )B( I, J ) = B( I+1, J )B( I+1, J ) = TEMP - DL( I )*B( I, J )END IF40 CONTINUE** Solve U*x = b.*B( N, J ) = B( N, J ) / D( N )IF( N.GT.1 )$ B( N-1, J ) = ( B( N-1, J )-DU( N-1 )*B( N, J ) ) /$ D( N-1 )DO 50 I = N - 2, 1, -1B( I, J ) = ( B( I, J )-DU( I )*B( I+1, J )-DU2( I )*$ B( I+2, J ) ) / D( I )50 CONTINUE60 CONTINUEEND IFELSE** Solve A**T * X = B.*IF( NRHS.LE.1 ) THEN** Solve U**T*x = b.*J = 170 CONTINUEB( 1, J ) = B( 1, J ) / D( 1 )IF( N.GT.1 )$ B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )DO 80 I = 3, NB( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-DU2( I-2 )*$ B( I-2, J ) ) / D( I )80 CONTINUE** Solve L**T*x = b.*DO 90 I = N - 1, 1, -1IP = IPIV( I )TEMP = B( I, J ) - DL( I )*B( I+1, J )B( I, J ) = B( IP, J )B( IP, J ) = TEMP90 CONTINUEIF( J.LT.NRHS ) THENJ = J + 1GO TO 70END IF*ELSEDO 120 J = 1, NRHS** Solve U**T*x = b.*B( 1, J ) = B( 1, J ) / D( 1 )IF( N.GT.1 )$ B( 2, J ) = ( B( 2, J )-DU( 1 )*B( 1, J ) ) / D( 2 )DO 100 I = 3, NB( I, J ) = ( B( I, J )-DU( I-1 )*B( I-1, J )-$ DU2( I-2 )*B( I-2, J ) ) / D( I )100 CONTINUEDO 110 I = N - 1, 1, -1IF( IPIV( I ).EQ.I ) THENB( I, J ) = B( I, J ) - DL( I )*B( I+1, J )ELSETEMP = B( I+1, J )B( I+1, J ) = B( I, J ) - DL( I )*TEMPB( I, J ) = TEMPEND IF110 CONTINUE120 CONTINUEEND IFEND IF** End of DGTTS2*END*> \brief \b DHGEQZ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DHGEQZ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dhgeqz.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dhgeqz.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dhgeqz.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,* ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,* LWORK, INFO )** .. Scalar Arguments ..* CHARACTER COMPQ, COMPZ, JOB* INTEGER IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION ALPHAI( * ), ALPHAR( * ), BETA( * ),* $ H( LDH, * ), Q( LDQ, * ), T( LDT, * ),* $ WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DHGEQZ computes the eigenvalues of a real matrix pair (H,T),*> where H is an upper Hessenberg matrix and T is upper triangular,*> using the double-shift QZ method.*> Matrix pairs of this type are produced by the reduction to*> generalized upper Hessenberg form of a real matrix pair (A,B):*>*> A = Q1*H*Z1**T, B = Q1*T*Z1**T,*>*> as computed by DGGHRD.*>*> If JOB='S', then the Hessenberg-triangular pair (H,T) is*> also reduced to generalized Schur form,*>*> H = Q*S*Z**T, T = Q*P*Z**T,*>*> where Q and Z are orthogonal matrices, P is an upper triangular*> matrix, and S is a quasi-triangular matrix with 1-by-1 and 2-by-2*> diagonal blocks.*>*> The 1-by-1 blocks correspond to real eigenvalues of the matrix pair*> (H,T) and the 2-by-2 blocks correspond to complex conjugate pairs of*> eigenvalues.*>*> Additionally, the 2-by-2 upper triangular diagonal blocks of P*> corresponding to 2-by-2 blocks of S are reduced to positive diagonal*> form, i.e., if S(j+1,j) is non-zero, then P(j+1,j) = P(j,j+1) = 0,*> P(j,j) > 0, and P(j+1,j+1) > 0.*>*> Optionally, the orthogonal matrix Q from the generalized Schur*> factorization may be postmultiplied into an input matrix Q1, and the*> orthogonal matrix Z may be postmultiplied into an input matrix Z1.*> If Q1 and Z1 are the orthogonal matrices from DGGHRD that reduced*> the matrix pair (A,B) to generalized upper Hessenberg form, then the*> output matrices Q1*Q and Z1*Z are the orthogonal factors from the*> generalized Schur factorization of (A,B):*>*> A = (Q1*Q)*S*(Z1*Z)**T, B = (Q1*Q)*P*(Z1*Z)**T.*>*> To avoid overflow, eigenvalues of the matrix pair (H,T) (equivalently,*> of (A,B)) are computed as a pair of values (alpha,beta), where alpha is*> complex and beta real.*> If beta is nonzero, lambda = alpha / beta is an eigenvalue of the*> generalized nonsymmetric eigenvalue problem (GNEP)*> A*x = lambda*B*x*> and if alpha is nonzero, mu = beta / alpha is an eigenvalue of the*> alternate form of the GNEP*> mu*A*y = B*y.*> Real eigenvalues can be read directly from the generalized Schur*> form:*> alpha = S(i,i), beta = P(i,i).*>*> Ref: C.B. Moler & G.W. Stewart, "An Algorithm for Generalized Matrix*> Eigenvalue Problems", SIAM J. Numer. Anal., 10(1973),*> pp. 241--256.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> = 'E': Compute eigenvalues only;*> = 'S': Compute eigenvalues and the Schur form.*> \endverbatim*>*> \param[in] COMPQ*> \verbatim*> COMPQ is CHARACTER*1*> = 'N': Left Schur vectors (Q) are not computed;*> = 'I': Q is initialized to the unit matrix and the matrix Q*> of left Schur vectors of (H,T) is returned;*> = 'V': Q must contain an orthogonal matrix Q1 on entry and*> the product Q1*Q is returned.*> \endverbatim*>*> \param[in] COMPZ*> \verbatim*> COMPZ is CHARACTER*1*> = 'N': Right Schur vectors (Z) are not computed;*> = 'I': Z is initialized to the unit matrix and the matrix Z*> of right Schur vectors of (H,T) is returned;*> = 'V': Z must contain an orthogonal matrix Z1 on entry and*> the product Z1*Z is returned.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices H, T, Q, and Z. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> ILO and IHI mark the rows and columns of H which are in*> Hessenberg form. It is assumed that A is already upper*> triangular in rows and columns 1:ILO-1 and IHI+1:N.*> If N > 0, 1 <= ILO <= IHI <= N; if N = 0, ILO=1 and IHI=0.*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH, N)*> On entry, the N-by-N upper Hessenberg matrix H.*> On exit, if JOB = 'S', H contains the upper quasi-triangular*> matrix S from the generalized Schur factorization.*> If JOB = 'E', the diagonal blocks of H match those of S, but*> the rest of H is unspecified.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH >= max( 1, N ).*> \endverbatim*>*> \param[in,out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT, N)*> On entry, the N-by-N upper triangular matrix T.*> On exit, if JOB = 'S', T contains the upper triangular*> matrix P from the generalized Schur factorization;*> 2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks of S*> are reduced to positive diagonal form, i.e., if H(j+1,j) is*> non-zero, then T(j+1,j) = T(j,j+1) = 0, T(j,j) > 0, and*> T(j+1,j+1) > 0.*> If JOB = 'E', the diagonal blocks of T match those of P, but*> the rest of T is unspecified.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max( 1, N ).*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> The real parts of each scalar alpha defining an eigenvalue*> of GNEP.*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> The imaginary parts of each scalar alpha defining an*> eigenvalue of GNEP.*> If ALPHAI(j) is zero, then the j-th eigenvalue is real; if*> positive, then the j-th and (j+1)-st eigenvalues are a*> complex conjugate pair, with ALPHAI(j+1) = -ALPHAI(j).*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*> The scalars beta that define the eigenvalues of GNEP.*> Together, the quantities alpha = (ALPHAR(j),ALPHAI(j)) and*> beta = BETA(j) represent the j-th eigenvalue of the matrix*> pair (A,B), in one of the forms lambda = alpha/beta or*> mu = beta/alpha. Since either lambda or mu may overflow,*> they should not, in general, be computed.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> On entry, if COMPQ = 'V', the orthogonal matrix Q1 used in*> the reduction of (A,B) to generalized Hessenberg form.*> On exit, if COMPQ = 'I', the orthogonal matrix of left Schur*> vectors of (H,T), and if COMPQ = 'V', the orthogonal matrix*> of left Schur vectors of (A,B).*> Not referenced if COMPQ = 'N'.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= 1.*> If COMPQ='V' or 'I', then LDQ >= N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> On entry, if COMPZ = 'V', the orthogonal matrix Z1 used in*> the reduction of (A,B) to generalized Hessenberg form.*> On exit, if COMPZ = 'I', the orthogonal matrix of*> right Schur vectors of (H,T), and if COMPZ = 'V', the*> orthogonal matrix of right Schur vectors of (A,B).*> Not referenced if COMPZ = 'N'.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1.*> If COMPZ='V' or 'I', then LDZ >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO >= 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> = 1,...,N: the QZ iteration did not converge. (H,T) is not*> in Schur form, but ALPHAR(i), ALPHAI(i), and*> BETA(i), i=INFO+1,...,N should be correct.*> = N+1,...,2*N: the shift calculation failed. (H,T) is not*> in Schur form, but ALPHAR(i), ALPHAI(i), and*> BETA(i), i=INFO-N+1,...,N should be correct.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> Iteration counters:*>*> JITER -- counts iterations.*> IITER -- counts iterations run since ILAST was last*> changed. This is therefore reset only when a 1-by-1 or*> 2-by-2 block deflates off the bottom.*> \endverbatim*>* =====================================================================SUBROUTINE DHGEQZ( JOB, COMPQ, COMPZ, N, ILO, IHI, H, LDH, T, LDT,$ ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, WORK,$ LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER COMPQ, COMPZ, JOBINTEGER IHI, ILO, INFO, LDH, LDQ, LDT, LDZ, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION ALPHAI( * ), ALPHAR( * ), BETA( * ),$ H( LDH, * ), Q( LDQ, * ), T( LDT, * ),$ WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..* $ SAFETY = 1.0E+0 )DOUBLE PRECISION HALF, ZERO, ONE, SAFETYPARAMETER ( HALF = 0.5D+0, ZERO = 0.0D+0, ONE = 1.0D+0,$ SAFETY = 1.0D+2 )* ..* .. Local Scalars ..LOGICAL ILAZR2, ILAZRO, ILPIVT, ILQ, ILSCHR, ILZ,$ LQUERYINTEGER ICOMPQ, ICOMPZ, IFIRST, IFRSTM, IITER, ILAST,$ ILASTM, IN, ISCHUR, ISTART, J, JC, JCH, JITER,$ JR, MAXITDOUBLE PRECISION A11, A12, A1I, A1R, A21, A22, A2I, A2R, AD11,$ AD11L, AD12, AD12L, AD21, AD21L, AD22, AD22L,$ AD32L, AN, ANORM, ASCALE, ATOL, B11, B1A, B1I,$ B1R, B22, B2A, B2I, B2R, BN, BNORM, BSCALE,$ BTOL, C, C11I, C11R, C12, C21, C22I, C22R, CL,$ CQ, CR, CZ, ESHIFT, S, S1, S1INV, S2, SAFMAX,$ SAFMIN, SCALE, SL, SQI, SQR, SR, SZI, SZR, T1,$ TAU, TEMP, TEMP2, TEMPI, TEMPR, U1, U12, U12L,$ U2, ULP, VS, W11, W12, W21, W22, WABS, WI, WR,$ WR2* ..* .. Local Arrays ..DOUBLE PRECISION V( 3 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANHS, DLAPY2, DLAPY3EXTERNAL LSAME, DLAMCH, DLANHS, DLAPY2, DLAPY3* ..* .. External Subroutines ..EXTERNAL DLAG2, DLARFG, DLARTG, DLASET, DLASV2, DROT,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SQRT* ..* .. Executable Statements ..** Decode JOB, COMPQ, COMPZ*IF( LSAME( JOB, 'E' ) ) THENILSCHR = .FALSE.ISCHUR = 1ELSE IF( LSAME( JOB, 'S' ) ) THENILSCHR = .TRUE.ISCHUR = 2ELSEISCHUR = 0END IF*IF( LSAME( COMPQ, 'N' ) ) THENILQ = .FALSE.ICOMPQ = 1ELSE IF( LSAME( COMPQ, 'V' ) ) THENILQ = .TRUE.ICOMPQ = 2ELSE IF( LSAME( COMPQ, 'I' ) ) THENILQ = .TRUE.ICOMPQ = 3ELSEICOMPQ = 0END IF*IF( LSAME( COMPZ, 'N' ) ) THENILZ = .FALSE.ICOMPZ = 1ELSE IF( LSAME( COMPZ, 'V' ) ) THENILZ = .TRUE.ICOMPZ = 2ELSE IF( LSAME( COMPZ, 'I' ) ) THENILZ = .TRUE.ICOMPZ = 3ELSEICOMPZ = 0END IF** Check Argument Values*INFO = 0WORK( 1 ) = MAX( 1, N )LQUERY = ( LWORK.EQ.-1 )IF( ISCHUR.EQ.0 ) THENINFO = -1ELSE IF( ICOMPQ.EQ.0 ) THENINFO = -2ELSE IF( ICOMPZ.EQ.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( ILO.LT.1 ) THENINFO = -5ELSE IF( IHI.GT.N .OR. IHI.LT.ILO-1 ) THENINFO = -6ELSE IF( LDH.LT.N ) THENINFO = -8ELSE IF( LDT.LT.N ) THENINFO = -10ELSE IF( LDQ.LT.1 .OR. ( ILQ .AND. LDQ.LT.N ) ) THENINFO = -15ELSE IF( LDZ.LT.1 .OR. ( ILZ .AND. LDZ.LT.N ) ) THENINFO = -17ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -19END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DHGEQZ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.0 ) THENWORK( 1 ) = DBLE( 1 )RETURNEND IF** Initialize Q and Z*IF( ICOMPQ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )IF( ICOMPZ.EQ.3 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Machine Constants*IN = IHI + 1 - ILOSAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINULP = DLAMCH( 'E' )*DLAMCH( 'B' )ANORM = DLANHS( 'F', IN, H( ILO, ILO ), LDH, WORK )BNORM = DLANHS( 'F', IN, T( ILO, ILO ), LDT, WORK )ATOL = MAX( SAFMIN, ULP*ANORM )BTOL = MAX( SAFMIN, ULP*BNORM )ASCALE = ONE / MAX( SAFMIN, ANORM )BSCALE = ONE / MAX( SAFMIN, BNORM )** Set Eigenvalues IHI+1:N*DO 30 J = IHI + 1, NIF( T( J, J ).LT.ZERO ) THENIF( ILSCHR ) THENDO 10 JR = 1, JH( JR, J ) = -H( JR, J )T( JR, J ) = -T( JR, J )10 CONTINUEELSEH( J, J ) = -H( J, J )T( J, J ) = -T( J, J )END IFIF( ILZ ) THENDO 20 JR = 1, NZ( JR, J ) = -Z( JR, J )20 CONTINUEEND IFEND IFALPHAR( J ) = H( J, J )ALPHAI( J ) = ZEROBETA( J ) = T( J, J )30 CONTINUE** If IHI < ILO, skip QZ steps*IF( IHI.LT.ILO )$ GO TO 380** MAIN QZ ITERATION LOOP** Initialize dynamic indices** Eigenvalues ILAST+1:N have been found.* Column operations modify rows IFRSTM:whatever.* Row operations modify columns whatever:ILASTM.** If only eigenvalues are being computed, then* IFRSTM is the row of the last splitting row above row ILAST;* this is always at least ILO.* IITER counts iterations since the last eigenvalue was found,* to tell when to use an extraordinary shift.* MAXIT is the maximum number of QZ sweeps allowed.*ILAST = IHIIF( ILSCHR ) THENIFRSTM = 1ILASTM = NELSEIFRSTM = ILOILASTM = IHIEND IFIITER = 0ESHIFT = ZEROMAXIT = 30*( IHI-ILO+1 )*DO 360 JITER = 1, MAXIT** Split the matrix if possible.** Two tests:* 1: H(j,j-1)=0 or j=ILO* 2: T(j,j)=0*IF( ILAST.EQ.ILO ) THEN** Special case: j=ILAST*GO TO 80ELSEIF( ABS( H( ILAST, ILAST-1 ) ).LE.ATOL ) THENH( ILAST, ILAST-1 ) = ZEROGO TO 80END IFEND IF*IF( ABS( T( ILAST, ILAST ) ).LE.BTOL ) THENT( ILAST, ILAST ) = ZEROGO TO 70END IF** General case: j<ILAST*DO 60 J = ILAST - 1, ILO, -1** Test 1: for H(j,j-1)=0 or j=ILO*IF( J.EQ.ILO ) THENILAZRO = .TRUE.ELSEIF( ABS( H( J, J-1 ) ).LE.ATOL ) THENH( J, J-1 ) = ZEROILAZRO = .TRUE.ELSEILAZRO = .FALSE.END IFEND IF** Test 2: for T(j,j)=0*IF( ABS( T( J, J ) ).LT.BTOL ) THENT( J, J ) = ZERO** Test 1a: Check for 2 consecutive small subdiagonals in A*ILAZR2 = .FALSE.IF( .NOT.ILAZRO ) THENTEMP = ABS( H( J, J-1 ) )TEMP2 = ABS( H( J, J ) )TEMPR = MAX( TEMP, TEMP2 )IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THENTEMP = TEMP / TEMPRTEMP2 = TEMP2 / TEMPREND IFIF( TEMP*( ASCALE*ABS( H( J+1, J ) ) ).LE.TEMP2*$ ( ASCALE*ATOL ) )ILAZR2 = .TRUE.END IF** If both tests pass (1 & 2), i.e., the leading diagonal* element of B in the block is zero, split a 1x1 block off* at the top. (I.e., at the J-th row/column) The leading* diagonal element of the remainder can also be zero, so* this may have to be done repeatedly.*IF( ILAZRO .OR. ILAZR2 ) THENDO 40 JCH = J, ILAST - 1TEMP = H( JCH, JCH )CALL DLARTG( TEMP, H( JCH+1, JCH ), C, S,$ H( JCH, JCH ) )H( JCH+1, JCH ) = ZEROCALL DROT( ILASTM-JCH, H( JCH, JCH+1 ), LDH,$ H( JCH+1, JCH+1 ), LDH, C, S )CALL DROT( ILASTM-JCH, T( JCH, JCH+1 ), LDT,$ T( JCH+1, JCH+1 ), LDT, C, S )IF( ILQ )$ CALL DROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,$ C, S )IF( ILAZR2 )$ H( JCH, JCH-1 ) = H( JCH, JCH-1 )*CILAZR2 = .FALSE.IF( ABS( T( JCH+1, JCH+1 ) ).GE.BTOL ) THENIF( JCH+1.GE.ILAST ) THENGO TO 80ELSEIFIRST = JCH + 1GO TO 110END IFEND IFT( JCH+1, JCH+1 ) = ZERO40 CONTINUEGO TO 70ELSE** Only test 2 passed -- chase the zero to T(ILAST,ILAST)* Then process as in the case T(ILAST,ILAST)=0*DO 50 JCH = J, ILAST - 1TEMP = T( JCH, JCH+1 )CALL DLARTG( TEMP, T( JCH+1, JCH+1 ), C, S,$ T( JCH, JCH+1 ) )T( JCH+1, JCH+1 ) = ZEROIF( JCH.LT.ILASTM-1 )$ CALL DROT( ILASTM-JCH-1, T( JCH, JCH+2 ), LDT,$ T( JCH+1, JCH+2 ), LDT, C, S )CALL DROT( ILASTM-JCH+2, H( JCH, JCH-1 ), LDH,$ H( JCH+1, JCH-1 ), LDH, C, S )IF( ILQ )$ CALL DROT( N, Q( 1, JCH ), 1, Q( 1, JCH+1 ), 1,$ C, S )TEMP = H( JCH+1, JCH )CALL DLARTG( TEMP, H( JCH+1, JCH-1 ), C, S,$ H( JCH+1, JCH ) )H( JCH+1, JCH-1 ) = ZEROCALL DROT( JCH+1-IFRSTM, H( IFRSTM, JCH ), 1,$ H( IFRSTM, JCH-1 ), 1, C, S )CALL DROT( JCH-IFRSTM, T( IFRSTM, JCH ), 1,$ T( IFRSTM, JCH-1 ), 1, C, S )IF( ILZ )$ CALL DROT( N, Z( 1, JCH ), 1, Z( 1, JCH-1 ), 1,$ C, S )50 CONTINUEGO TO 70END IFELSE IF( ILAZRO ) THEN** Only test 1 passed -- work on J:ILAST*IFIRST = JGO TO 110END IF** Neither test passed -- try next J*60 CONTINUE** (Drop-through is "impossible")*INFO = N + 1GO TO 420** T(ILAST,ILAST)=0 -- clear H(ILAST,ILAST-1) to split off a* 1x1 block.*70 CONTINUETEMP = H( ILAST, ILAST )CALL DLARTG( TEMP, H( ILAST, ILAST-1 ), C, S,$ H( ILAST, ILAST ) )H( ILAST, ILAST-1 ) = ZEROCALL DROT( ILAST-IFRSTM, H( IFRSTM, ILAST ), 1,$ H( IFRSTM, ILAST-1 ), 1, C, S )CALL DROT( ILAST-IFRSTM, T( IFRSTM, ILAST ), 1,$ T( IFRSTM, ILAST-1 ), 1, C, S )IF( ILZ )$ CALL DROT( N, Z( 1, ILAST ), 1, Z( 1, ILAST-1 ), 1, C, S )** H(ILAST,ILAST-1)=0 -- Standardize B, set ALPHAR, ALPHAI,* and BETA*80 CONTINUEIF( T( ILAST, ILAST ).LT.ZERO ) THENIF( ILSCHR ) THENDO 90 J = IFRSTM, ILASTH( J, ILAST ) = -H( J, ILAST )T( J, ILAST ) = -T( J, ILAST )90 CONTINUEELSEH( ILAST, ILAST ) = -H( ILAST, ILAST )T( ILAST, ILAST ) = -T( ILAST, ILAST )END IFIF( ILZ ) THENDO 100 J = 1, NZ( J, ILAST ) = -Z( J, ILAST )100 CONTINUEEND IFEND IFALPHAR( ILAST ) = H( ILAST, ILAST )ALPHAI( ILAST ) = ZEROBETA( ILAST ) = T( ILAST, ILAST )** Go to next block -- exit if finished.*ILAST = ILAST - 1IF( ILAST.LT.ILO )$ GO TO 380** Reset counters*IITER = 0ESHIFT = ZEROIF( .NOT.ILSCHR ) THENILASTM = ILASTIF( IFRSTM.GT.ILAST )$ IFRSTM = ILOEND IFGO TO 350** QZ step** This iteration only involves rows/columns IFIRST:ILAST. We* assume IFIRST < ILAST, and that the diagonal of B is non-zero.*110 CONTINUEIITER = IITER + 1IF( .NOT.ILSCHR ) THENIFRSTM = IFIRSTEND IF** Compute single shifts.** At this point, IFIRST < ILAST, and the diagonal elements of* T(IFIRST:ILAST,IFIRST,ILAST) are larger than BTOL (in* magnitude)*IF( ( IITER / 10 )*10.EQ.IITER ) THEN** Exceptional shift. Chosen for no particularly good reason.* (Single shift only.)*IF( ( DBLE( MAXIT )*SAFMIN )*ABS( H( ILAST, ILAST-1 ) ).LT.$ ABS( T( ILAST-1, ILAST-1 ) ) ) THENESHIFT = H( ILAST, ILAST-1 ) /$ T( ILAST-1, ILAST-1 )ELSEESHIFT = ESHIFT + ONE / ( SAFMIN*DBLE( MAXIT ) )END IFS1 = ONEWR = ESHIFT*ELSE** Shifts based on the generalized eigenvalues of the* bottom-right 2x2 block of A and B. The first eigenvalue* returned by DLAG2 is the Wilkinson shift (AEP p.512),*CALL DLAG2( H( ILAST-1, ILAST-1 ), LDH,$ T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1,$ S2, WR, WR2, WI )*IF ( ABS( (WR/S1)*T( ILAST, ILAST ) - H( ILAST, ILAST ) )$ .GT. ABS( (WR2/S2)*T( ILAST, ILAST )$ - H( ILAST, ILAST ) ) ) THENTEMP = WRWR = WR2WR2 = TEMPTEMP = S1S1 = S2S2 = TEMPEND IFTEMP = MAX( S1, SAFMIN*MAX( ONE, ABS( WR ), ABS( WI ) ) )IF( WI.NE.ZERO )$ GO TO 200END IF** Fiddle with shift to avoid overflow*TEMP = MIN( ASCALE, ONE )*( HALF*SAFMAX )IF( S1.GT.TEMP ) THENSCALE = TEMP / S1ELSESCALE = ONEEND IF*TEMP = MIN( BSCALE, ONE )*( HALF*SAFMAX )IF( ABS( WR ).GT.TEMP )$ SCALE = MIN( SCALE, TEMP / ABS( WR ) )S1 = SCALE*S1WR = SCALE*WR** Now check for two consecutive small subdiagonals.*DO 120 J = ILAST - 1, IFIRST + 1, -1ISTART = JTEMP = ABS( S1*H( J, J-1 ) )TEMP2 = ABS( S1*H( J, J )-WR*T( J, J ) )TEMPR = MAX( TEMP, TEMP2 )IF( TEMPR.LT.ONE .AND. TEMPR.NE.ZERO ) THENTEMP = TEMP / TEMPRTEMP2 = TEMP2 / TEMPREND IFIF( ABS( ( ASCALE*H( J+1, J ) )*TEMP ).LE.( ASCALE*ATOL )*$ TEMP2 )GO TO 130120 CONTINUE*ISTART = IFIRST130 CONTINUE** Do an implicit single-shift QZ sweep.** Initial Q*TEMP = S1*H( ISTART, ISTART ) - WR*T( ISTART, ISTART )TEMP2 = S1*H( ISTART+1, ISTART )CALL DLARTG( TEMP, TEMP2, C, S, TEMPR )** Sweep*DO 190 J = ISTART, ILAST - 1IF( J.GT.ISTART ) THENTEMP = H( J, J-1 )CALL DLARTG( TEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )H( J+1, J-1 ) = ZEROEND IF*DO 140 JC = J, ILASTMTEMP = C*H( J, JC ) + S*H( J+1, JC )H( J+1, JC ) = -S*H( J, JC ) + C*H( J+1, JC )H( J, JC ) = TEMPTEMP2 = C*T( J, JC ) + S*T( J+1, JC )T( J+1, JC ) = -S*T( J, JC ) + C*T( J+1, JC )T( J, JC ) = TEMP2140 CONTINUEIF( ILQ ) THENDO 150 JR = 1, NTEMP = C*Q( JR, J ) + S*Q( JR, J+1 )Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )Q( JR, J ) = TEMP150 CONTINUEEND IF*TEMP = T( J+1, J+1 )CALL DLARTG( TEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )T( J+1, J ) = ZERO*DO 160 JR = IFRSTM, MIN( J+2, ILAST )TEMP = C*H( JR, J+1 ) + S*H( JR, J )H( JR, J ) = -S*H( JR, J+1 ) + C*H( JR, J )H( JR, J+1 ) = TEMP160 CONTINUEDO 170 JR = IFRSTM, JTEMP = C*T( JR, J+1 ) + S*T( JR, J )T( JR, J ) = -S*T( JR, J+1 ) + C*T( JR, J )T( JR, J+1 ) = TEMP170 CONTINUEIF( ILZ ) THENDO 180 JR = 1, NTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )Z( JR, J+1 ) = TEMP180 CONTINUEEND IF190 CONTINUE*GO TO 350** Use Francis double-shift** Note: the Francis double-shift should work with real shifts,* but only if the block is at least 3x3.* This code may break if this point is reached with* a 2x2 block with real eigenvalues.*200 CONTINUEIF( IFIRST+1.EQ.ILAST ) THEN** Special case -- 2x2 block with complex eigenvectors** Step 1: Standardize, that is, rotate so that** ( B11 0 )* B = ( ) with B11 non-negative.* ( 0 B22 )*CALL DLASV2( T( ILAST-1, ILAST-1 ), T( ILAST-1, ILAST ),$ T( ILAST, ILAST ), B22, B11, SR, CR, SL, CL )*IF( B11.LT.ZERO ) THENCR = -CRSR = -SRB11 = -B11B22 = -B22END IF*CALL DROT( ILASTM+1-IFIRST, H( ILAST-1, ILAST-1 ), LDH,$ H( ILAST, ILAST-1 ), LDH, CL, SL )CALL DROT( ILAST+1-IFRSTM, H( IFRSTM, ILAST-1 ), 1,$ H( IFRSTM, ILAST ), 1, CR, SR )*IF( ILAST.LT.ILASTM )$ CALL DROT( ILASTM-ILAST, T( ILAST-1, ILAST+1 ), LDT,$ T( ILAST, ILAST+1 ), LDT, CL, SL )IF( IFRSTM.LT.ILAST-1 )$ CALL DROT( IFIRST-IFRSTM, T( IFRSTM, ILAST-1 ), 1,$ T( IFRSTM, ILAST ), 1, CR, SR )*IF( ILQ )$ CALL DROT( N, Q( 1, ILAST-1 ), 1, Q( 1, ILAST ), 1, CL,$ SL )IF( ILZ )$ CALL DROT( N, Z( 1, ILAST-1 ), 1, Z( 1, ILAST ), 1, CR,$ SR )*T( ILAST-1, ILAST-1 ) = B11T( ILAST-1, ILAST ) = ZEROT( ILAST, ILAST-1 ) = ZEROT( ILAST, ILAST ) = B22** If B22 is negative, negate column ILAST*IF( B22.LT.ZERO ) THENDO 210 J = IFRSTM, ILASTH( J, ILAST ) = -H( J, ILAST )T( J, ILAST ) = -T( J, ILAST )210 CONTINUE*IF( ILZ ) THENDO 220 J = 1, NZ( J, ILAST ) = -Z( J, ILAST )220 CONTINUEEND IFB22 = -B22END IF** Step 2: Compute ALPHAR, ALPHAI, and BETA (see refs.)** Recompute shift*CALL DLAG2( H( ILAST-1, ILAST-1 ), LDH,$ T( ILAST-1, ILAST-1 ), LDT, SAFMIN*SAFETY, S1,$ TEMP, WR, TEMP2, WI )** If standardization has perturbed the shift onto real line,* do another (real single-shift) QR step.*IF( WI.EQ.ZERO )$ GO TO 350S1INV = ONE / S1** Do EISPACK (QZVAL) computation of alpha and beta*A11 = H( ILAST-1, ILAST-1 )A21 = H( ILAST, ILAST-1 )A12 = H( ILAST-1, ILAST )A22 = H( ILAST, ILAST )** Compute complex Givens rotation on right* (Assume some element of C = (sA - wB) > unfl )* __* (sA - wB) ( CZ -SZ )* ( SZ CZ )*C11R = S1*A11 - WR*B11C11I = -WI*B11C12 = S1*A12C21 = S1*A21C22R = S1*A22 - WR*B22C22I = -WI*B22*IF( ABS( C11R )+ABS( C11I )+ABS( C12 ).GT.ABS( C21 )+$ ABS( C22R )+ABS( C22I ) ) THENT1 = DLAPY3( C12, C11R, C11I )CZ = C12 / T1SZR = -C11R / T1SZI = -C11I / T1ELSECZ = DLAPY2( C22R, C22I )IF( CZ.LE.SAFMIN ) THENCZ = ZEROSZR = ONESZI = ZEROELSETEMPR = C22R / CZTEMPI = C22I / CZT1 = DLAPY2( CZ, C21 )CZ = CZ / T1SZR = -C21*TEMPR / T1SZI = C21*TEMPI / T1END IFEND IF** Compute Givens rotation on left** ( CQ SQ )* ( __ ) A or B* ( -SQ CQ )*AN = ABS( A11 ) + ABS( A12 ) + ABS( A21 ) + ABS( A22 )BN = ABS( B11 ) + ABS( B22 )WABS = ABS( WR ) + ABS( WI )IF( S1*AN.GT.WABS*BN ) THENCQ = CZ*B11SQR = SZR*B22SQI = -SZI*B22ELSEA1R = CZ*A11 + SZR*A12A1I = SZI*A12A2R = CZ*A21 + SZR*A22A2I = SZI*A22CQ = DLAPY2( A1R, A1I )IF( CQ.LE.SAFMIN ) THENCQ = ZEROSQR = ONESQI = ZEROELSETEMPR = A1R / CQTEMPI = A1I / CQSQR = TEMPR*A2R + TEMPI*A2ISQI = TEMPI*A2R - TEMPR*A2IEND IFEND IFT1 = DLAPY3( CQ, SQR, SQI )CQ = CQ / T1SQR = SQR / T1SQI = SQI / T1** Compute diagonal elements of QBZ*TEMPR = SQR*SZR - SQI*SZITEMPI = SQR*SZI + SQI*SZRB1R = CQ*CZ*B11 + TEMPR*B22B1I = TEMPI*B22B1A = DLAPY2( B1R, B1I )B2R = CQ*CZ*B22 + TEMPR*B11B2I = -TEMPI*B11B2A = DLAPY2( B2R, B2I )** Normalize so beta > 0, and Im( alpha1 ) > 0*BETA( ILAST-1 ) = B1ABETA( ILAST ) = B2AALPHAR( ILAST-1 ) = ( WR*B1A )*S1INVALPHAI( ILAST-1 ) = ( WI*B1A )*S1INVALPHAR( ILAST ) = ( WR*B2A )*S1INVALPHAI( ILAST ) = -( WI*B2A )*S1INV** Step 3: Go to next block -- exit if finished.*ILAST = IFIRST - 1IF( ILAST.LT.ILO )$ GO TO 380** Reset counters*IITER = 0ESHIFT = ZEROIF( .NOT.ILSCHR ) THENILASTM = ILASTIF( IFRSTM.GT.ILAST )$ IFRSTM = ILOEND IFGO TO 350ELSE** Usual case: 3x3 or larger block, using Francis implicit* double-shift** 2* Eigenvalue equation is w - c w + d = 0,** -1 2 -1* so compute 1st column of (A B ) - c A B + d* using the formula in QZIT (from EISPACK)** We assume that the block is at least 3x3*AD11 = ( ASCALE*H( ILAST-1, ILAST-1 ) ) /$ ( BSCALE*T( ILAST-1, ILAST-1 ) )AD21 = ( ASCALE*H( ILAST, ILAST-1 ) ) /$ ( BSCALE*T( ILAST-1, ILAST-1 ) )AD12 = ( ASCALE*H( ILAST-1, ILAST ) ) /$ ( BSCALE*T( ILAST, ILAST ) )AD22 = ( ASCALE*H( ILAST, ILAST ) ) /$ ( BSCALE*T( ILAST, ILAST ) )U12 = T( ILAST-1, ILAST ) / T( ILAST, ILAST )AD11L = ( ASCALE*H( IFIRST, IFIRST ) ) /$ ( BSCALE*T( IFIRST, IFIRST ) )AD21L = ( ASCALE*H( IFIRST+1, IFIRST ) ) /$ ( BSCALE*T( IFIRST, IFIRST ) )AD12L = ( ASCALE*H( IFIRST, IFIRST+1 ) ) /$ ( BSCALE*T( IFIRST+1, IFIRST+1 ) )AD22L = ( ASCALE*H( IFIRST+1, IFIRST+1 ) ) /$ ( BSCALE*T( IFIRST+1, IFIRST+1 ) )AD32L = ( ASCALE*H( IFIRST+2, IFIRST+1 ) ) /$ ( BSCALE*T( IFIRST+1, IFIRST+1 ) )U12L = T( IFIRST, IFIRST+1 ) / T( IFIRST+1, IFIRST+1 )*V( 1 ) = ( AD11-AD11L )*( AD22-AD11L ) - AD12*AD21 +$ AD21*U12*AD11L + ( AD12L-AD11L*U12L )*AD21LV( 2 ) = ( ( AD22L-AD11L )-AD21L*U12L-( AD11-AD11L )-$ ( AD22-AD11L )+AD21*U12 )*AD21LV( 3 ) = AD32L*AD21L*ISTART = IFIRST*CALL DLARFG( 3, V( 1 ), V( 2 ), 1, TAU )V( 1 ) = ONE** Sweep*DO 290 J = ISTART, ILAST - 2** All but last elements: use 3x3 Householder transforms.** Zero (j-1)st column of A*IF( J.GT.ISTART ) THENV( 1 ) = H( J, J-1 )V( 2 ) = H( J+1, J-1 )V( 3 ) = H( J+2, J-1 )*CALL DLARFG( 3, H( J, J-1 ), V( 2 ), 1, TAU )V( 1 ) = ONEH( J+1, J-1 ) = ZEROH( J+2, J-1 ) = ZEROEND IF*DO 230 JC = J, ILASTMTEMP = TAU*( H( J, JC )+V( 2 )*H( J+1, JC )+V( 3 )*$ H( J+2, JC ) )H( J, JC ) = H( J, JC ) - TEMPH( J+1, JC ) = H( J+1, JC ) - TEMP*V( 2 )H( J+2, JC ) = H( J+2, JC ) - TEMP*V( 3 )TEMP2 = TAU*( T( J, JC )+V( 2 )*T( J+1, JC )+V( 3 )*$ T( J+2, JC ) )T( J, JC ) = T( J, JC ) - TEMP2T( J+1, JC ) = T( J+1, JC ) - TEMP2*V( 2 )T( J+2, JC ) = T( J+2, JC ) - TEMP2*V( 3 )230 CONTINUEIF( ILQ ) THENDO 240 JR = 1, NTEMP = TAU*( Q( JR, J )+V( 2 )*Q( JR, J+1 )+V( 3 )*$ Q( JR, J+2 ) )Q( JR, J ) = Q( JR, J ) - TEMPQ( JR, J+1 ) = Q( JR, J+1 ) - TEMP*V( 2 )Q( JR, J+2 ) = Q( JR, J+2 ) - TEMP*V( 3 )240 CONTINUEEND IF** Zero j-th column of B (see DLAGBC for details)** Swap rows to pivot*ILPIVT = .FALSE.TEMP = MAX( ABS( T( J+1, J+1 ) ), ABS( T( J+1, J+2 ) ) )TEMP2 = MAX( ABS( T( J+2, J+1 ) ), ABS( T( J+2, J+2 ) ) )IF( MAX( TEMP, TEMP2 ).LT.SAFMIN ) THENSCALE = ZEROU1 = ONEU2 = ZEROGO TO 250ELSE IF( TEMP.GE.TEMP2 ) THENW11 = T( J+1, J+1 )W21 = T( J+2, J+1 )W12 = T( J+1, J+2 )W22 = T( J+2, J+2 )U1 = T( J+1, J )U2 = T( J+2, J )ELSEW21 = T( J+1, J+1 )W11 = T( J+2, J+1 )W22 = T( J+1, J+2 )W12 = T( J+2, J+2 )U2 = T( J+1, J )U1 = T( J+2, J )END IF** Swap columns if nec.*IF( ABS( W12 ).GT.ABS( W11 ) ) THENILPIVT = .TRUE.TEMP = W12TEMP2 = W22W12 = W11W22 = W21W11 = TEMPW21 = TEMP2END IF** LU-factor*TEMP = W21 / W11U2 = U2 - TEMP*U1W22 = W22 - TEMP*W12W21 = ZERO** Compute SCALE*SCALE = ONEIF( ABS( W22 ).LT.SAFMIN ) THENSCALE = ZEROU2 = ONEU1 = -W12 / W11GO TO 250END IFIF( ABS( W22 ).LT.ABS( U2 ) )$ SCALE = ABS( W22 / U2 )IF( ABS( W11 ).LT.ABS( U1 ) )$ SCALE = MIN( SCALE, ABS( W11 / U1 ) )** Solve*U2 = ( SCALE*U2 ) / W22U1 = ( SCALE*U1-W12*U2 ) / W11*250 CONTINUEIF( ILPIVT ) THENTEMP = U2U2 = U1U1 = TEMPEND IF** Compute Householder Vector*T1 = SQRT( SCALE**2+U1**2+U2**2 )TAU = ONE + SCALE / T1VS = -ONE / ( SCALE+T1 )V( 1 ) = ONEV( 2 ) = VS*U1V( 3 ) = VS*U2** Apply transformations from the right.*DO 260 JR = IFRSTM, MIN( J+3, ILAST )TEMP = TAU*( H( JR, J )+V( 2 )*H( JR, J+1 )+V( 3 )*$ H( JR, J+2 ) )H( JR, J ) = H( JR, J ) - TEMPH( JR, J+1 ) = H( JR, J+1 ) - TEMP*V( 2 )H( JR, J+2 ) = H( JR, J+2 ) - TEMP*V( 3 )260 CONTINUEDO 270 JR = IFRSTM, J + 2TEMP = TAU*( T( JR, J )+V( 2 )*T( JR, J+1 )+V( 3 )*$ T( JR, J+2 ) )T( JR, J ) = T( JR, J ) - TEMPT( JR, J+1 ) = T( JR, J+1 ) - TEMP*V( 2 )T( JR, J+2 ) = T( JR, J+2 ) - TEMP*V( 3 )270 CONTINUEIF( ILZ ) THENDO 280 JR = 1, NTEMP = TAU*( Z( JR, J )+V( 2 )*Z( JR, J+1 )+V( 3 )*$ Z( JR, J+2 ) )Z( JR, J ) = Z( JR, J ) - TEMPZ( JR, J+1 ) = Z( JR, J+1 ) - TEMP*V( 2 )Z( JR, J+2 ) = Z( JR, J+2 ) - TEMP*V( 3 )280 CONTINUEEND IFT( J+1, J ) = ZEROT( J+2, J ) = ZERO290 CONTINUE** Last elements: Use Givens rotations** Rotations from the left*J = ILAST - 1TEMP = H( J, J-1 )CALL DLARTG( TEMP, H( J+1, J-1 ), C, S, H( J, J-1 ) )H( J+1, J-1 ) = ZERO*DO 300 JC = J, ILASTMTEMP = C*H( J, JC ) + S*H( J+1, JC )H( J+1, JC ) = -S*H( J, JC ) + C*H( J+1, JC )H( J, JC ) = TEMPTEMP2 = C*T( J, JC ) + S*T( J+1, JC )T( J+1, JC ) = -S*T( J, JC ) + C*T( J+1, JC )T( J, JC ) = TEMP2300 CONTINUEIF( ILQ ) THENDO 310 JR = 1, NTEMP = C*Q( JR, J ) + S*Q( JR, J+1 )Q( JR, J+1 ) = -S*Q( JR, J ) + C*Q( JR, J+1 )Q( JR, J ) = TEMP310 CONTINUEEND IF** Rotations from the right.*TEMP = T( J+1, J+1 )CALL DLARTG( TEMP, T( J+1, J ), C, S, T( J+1, J+1 ) )T( J+1, J ) = ZERO*DO 320 JR = IFRSTM, ILASTTEMP = C*H( JR, J+1 ) + S*H( JR, J )H( JR, J ) = -S*H( JR, J+1 ) + C*H( JR, J )H( JR, J+1 ) = TEMP320 CONTINUEDO 330 JR = IFRSTM, ILAST - 1TEMP = C*T( JR, J+1 ) + S*T( JR, J )T( JR, J ) = -S*T( JR, J+1 ) + C*T( JR, J )T( JR, J+1 ) = TEMP330 CONTINUEIF( ILZ ) THENDO 340 JR = 1, NTEMP = C*Z( JR, J+1 ) + S*Z( JR, J )Z( JR, J ) = -S*Z( JR, J+1 ) + C*Z( JR, J )Z( JR, J+1 ) = TEMP340 CONTINUEEND IF** End of Double-Shift code*END IF*GO TO 350** End of iteration loop*350 CONTINUE360 CONTINUE** Drop-through = non-convergence*INFO = ILASTGO TO 420** Successful completion of all QZ steps*380 CONTINUE** Set Eigenvalues 1:ILO-1*DO 410 J = 1, ILO - 1IF( T( J, J ).LT.ZERO ) THENIF( ILSCHR ) THENDO 390 JR = 1, JH( JR, J ) = -H( JR, J )T( JR, J ) = -T( JR, J )390 CONTINUEELSEH( J, J ) = -H( J, J )T( J, J ) = -T( J, J )END IFIF( ILZ ) THENDO 400 JR = 1, NZ( JR, J ) = -Z( JR, J )400 CONTINUEEND IFEND IFALPHAR( J ) = H( J, J )ALPHAI( J ) = ZEROBETA( J ) = T( J, J )410 CONTINUE** Normal Termination*INFO = 0** Exit (other than argument error) -- return optimal workspace size*420 CONTINUEWORK( 1 ) = DBLE( N )RETURN** End of DHGEQZ*END*> \brief \b DHSEIN** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DHSEIN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dhsein.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dhsein.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dhsein.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI,* VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL,* IFAILR, INFO )** .. Scalar Arguments ..* CHARACTER EIGSRC, INITV, SIDE* INTEGER INFO, LDH, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..* LOGICAL SELECT( * )* INTEGER IFAILL( * ), IFAILR( * )* DOUBLE PRECISION H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ),* $ WI( * ), WORK( * ), WR( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DHSEIN uses inverse iteration to find specified right and/or left*> eigenvectors of a real upper Hessenberg matrix H.*>*> The right eigenvector x and the left eigenvector y of the matrix H*> corresponding to an eigenvalue w are defined by:*>*> H * x = w * x, y**h * H = w * y**h*>*> where y**h denotes the conjugate transpose of the vector y.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'R': compute right eigenvectors only;*> = 'L': compute left eigenvectors only;*> = 'B': compute both right and left eigenvectors.*> \endverbatim*>*> \param[in] EIGSRC*> \verbatim*> EIGSRC is CHARACTER*1*> Specifies the source of eigenvalues supplied in (WR,WI):*> = 'Q': the eigenvalues were found using DHSEQR; thus, if*> H has zero subdiagonal elements, and so is*> block-triangular, then the j-th eigenvalue can be*> assumed to be an eigenvalue of the block containing*> the j-th row/column. This property allows DHSEIN to*> perform inverse iteration on just one diagonal block.*> = 'N': no assumptions are made on the correspondence*> between eigenvalues and diagonal blocks. In this*> case, DHSEIN must always perform inverse iteration*> using the whole matrix H.*> \endverbatim*>*> \param[in] INITV*> \verbatim*> INITV is CHARACTER*1*> = 'N': no initial vectors are supplied;*> = 'U': user-supplied initial vectors are stored in the arrays*> VL and/or VR.*> \endverbatim*>*> \param[in,out] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> Specifies the eigenvectors to be computed. To select the*> real eigenvector corresponding to a real eigenvalue WR(j),*> SELECT(j) must be set to .TRUE.. To select the complex*> eigenvector corresponding to a complex eigenvalue*> (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)),*> either SELECT(j) or SELECT(j+1) or both must be set to*> .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is*> .FALSE..*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H. N >= 0.*> \endverbatim*>*> \param[in] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> The upper Hessenberg matrix H.*> If a NaN is detected in H, the routine will return with INFO=-6.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH >= max(1,N).*> \endverbatim*>*> \param[in,out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[in] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*>*> On entry, the real and imaginary parts of the eigenvalues of*> H; a complex conjugate pair of eigenvalues must be stored in*> consecutive elements of WR and WI.*> On exit, WR may have been altered since close eigenvalues*> are perturbed slightly in searching for independent*> eigenvectors.*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,MM)*> On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must*> contain starting vectors for the inverse iteration for the*> left eigenvectors; the starting vector for each eigenvector*> must be in the same column(s) in which the eigenvector will*> be stored.*> On exit, if SIDE = 'L' or 'B', the left eigenvectors*> specified by SELECT will be stored consecutively in the*> columns of VL, in the same order as their eigenvalues. A*> complex eigenvector corresponding to a complex eigenvalue is*> stored in two consecutive columns, the first holding the real*> part and the second the imaginary part.*> If SIDE = 'R', VL is not referenced.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL.*> LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.*> \endverbatim*>*> \param[in,out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,MM)*> On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must*> contain starting vectors for the inverse iteration for the*> right eigenvectors; the starting vector for each eigenvector*> must be in the same column(s) in which the eigenvector will*> be stored.*> On exit, if SIDE = 'R' or 'B', the right eigenvectors*> specified by SELECT will be stored consecutively in the*> columns of VR, in the same order as their eigenvalues. A*> complex eigenvector corresponding to a complex eigenvalue is*> stored in two consecutive columns, the first holding the real*> part and the second the imaginary part.*> If SIDE = 'L', VR is not referenced.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR.*> LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.*> \endverbatim*>*> \param[in] MM*> \verbatim*> MM is INTEGER*> The number of columns in the arrays VL and/or VR. MM >= M.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The number of columns in the arrays VL and/or VR required to*> store the eigenvectors; each selected real eigenvector*> occupies one column and each selected complex eigenvector*> occupies two columns.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension ((N+2)*N)*> \endverbatim*>*> \param[out] IFAILL*> \verbatim*> IFAILL is INTEGER array, dimension (MM)*> If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left*> eigenvector in the i-th column of VL (corresponding to the*> eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the*> eigenvector converged satisfactorily. If the i-th and (i+1)th*> columns of VL hold a complex eigenvector, then IFAILL(i) and*> IFAILL(i+1) are set to the same value.*> If SIDE = 'R', IFAILL is not referenced.*> \endverbatim*>*> \param[out] IFAILR*> \verbatim*> IFAILR is INTEGER array, dimension (MM)*> If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right*> eigenvector in the i-th column of VR (corresponding to the*> eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the*> eigenvector converged satisfactorily. If the i-th and (i+1)th*> columns of VR hold a complex eigenvector, then IFAILR(i) and*> IFAILR(i+1) are set to the same value.*> If SIDE = 'L', IFAILR is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, i is the number of eigenvectors which*> failed to converge; see IFAILL and IFAILR for further*> details.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> Each eigenvector is normalized so that the element of largest*> magnitude has magnitude 1; here the magnitude of a complex number*> (x,y) is taken to be |x|+|y|.*> \endverbatim*>* =====================================================================SUBROUTINE DHSEIN( SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI,$ VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL,$ IFAILR, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER EIGSRC, INITV, SIDEINTEGER INFO, LDH, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IFAILL( * ), IFAILR( * )DOUBLE PRECISION H( LDH, * ), VL( LDVL, * ), VR( LDVR, * ),$ WI( * ), WORK( * ), WR( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL BOTHV, FROMQR, LEFTV, NOINIT, PAIR, RIGHTVINTEGER I, IINFO, K, KL, KLN, KR, KSI, KSR, LDWORKDOUBLE PRECISION BIGNUM, EPS3, HNORM, SMLNUM, ULP, UNFL, WKI,$ WKR* ..* .. External Functions ..LOGICAL LSAME, DISNANDOUBLE PRECISION DLAMCH, DLANHSEXTERNAL LSAME, DLAMCH, DLANHS, DISNAN* ..* .. External Subroutines ..EXTERNAL DLAEIN, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Decode and test the input parameters.*BOTHV = LSAME( SIDE, 'B' )RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHVLEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV*FROMQR = LSAME( EIGSRC, 'Q' )*NOINIT = LSAME( INITV, 'N' )** Set M to the number of columns required to store the selected* eigenvectors, and standardize the array SELECT.*M = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.SELECT( K ) = .FALSE.ELSEIF( WI( K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) ) THENSELECT( K ) = .TRUE.M = M + 2END IFEND IFEND IF10 CONTINUE*INFO = 0IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -1ELSE IF( .NOT.FROMQR .AND. .NOT.LSAME( EIGSRC, 'N' ) ) THENINFO = -2ELSE IF( .NOT.NOINIT .AND. .NOT.LSAME( INITV, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDH.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THENINFO = -11ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THENINFO = -13ELSE IF( MM.LT.M ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DHSEIN', -INFO )RETURNEND IF** Quick return if possible.*IF( N.EQ.0 )$ RETURN** Set machine-dependent constants.*UNFL = DLAMCH( 'Safe minimum' )ULP = DLAMCH( 'Precision' )SMLNUM = UNFL*( N / ULP )BIGNUM = ( ONE-ULP ) / SMLNUM*LDWORK = N + 1*KL = 1KLN = 0IF( FROMQR ) THENKR = 0ELSEKR = NEND IFKSR = 1*DO 120 K = 1, NIF( SELECT( K ) ) THEN** Compute eigenvector(s) corresponding to W(K).*IF( FROMQR ) THEN** If affiliation of eigenvalues is known, check whether* the matrix splits.** Determine KL and KR such that 1 <= KL <= K <= KR <= N* and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or* KR = N).** Then inverse iteration can be performed with the* submatrix H(KL:N,KL:N) for a left eigenvector, and with* the submatrix H(1:KR,1:KR) for a right eigenvector.*DO 20 I = K, KL + 1, -1IF( H( I, I-1 ).EQ.ZERO )$ GO TO 3020 CONTINUE30 CONTINUEKL = IIF( K.GT.KR ) THENDO 40 I = K, N - 1IF( H( I+1, I ).EQ.ZERO )$ GO TO 5040 CONTINUE50 CONTINUEKR = IEND IFEND IF*IF( KL.NE.KLN ) THENKLN = KL** Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it* has not ben computed before.*HNORM = DLANHS( 'I', KR-KL+1, H( KL, KL ), LDH, WORK )IF( DISNAN( HNORM ) ) THENINFO = -6RETURNELSE IF( HNORM.GT.ZERO ) THENEPS3 = HNORM*ULPELSEEPS3 = SMLNUMEND IFEND IF** Perturb eigenvalue if it is close to any previous* selected eigenvalues affiliated to the submatrix* H(KL:KR,KL:KR). Close roots are modified by EPS3.*WKR = WR( K )WKI = WI( K )60 CONTINUEDO 70 I = K - 1, KL, -1IF( SELECT( I ) .AND. ABS( WR( I )-WKR )+$ ABS( WI( I )-WKI ).LT.EPS3 ) THENWKR = WKR + EPS3GO TO 60END IF70 CONTINUEWR( K ) = WKR*PAIR = WKI.NE.ZEROIF( PAIR ) THENKSI = KSR + 1ELSEKSI = KSREND IFIF( LEFTV ) THEN** Compute left eigenvector.*CALL DLAEIN( .FALSE., NOINIT, N-KL+1, H( KL, KL ), LDH,$ WKR, WKI, VL( KL, KSR ), VL( KL, KSI ),$ WORK, LDWORK, WORK( N*N+N+1 ), EPS3, SMLNUM,$ BIGNUM, IINFO )IF( IINFO.GT.0 ) THENIF( PAIR ) THENINFO = INFO + 2ELSEINFO = INFO + 1END IFIFAILL( KSR ) = KIFAILL( KSI ) = KELSEIFAILL( KSR ) = 0IFAILL( KSI ) = 0END IFDO 80 I = 1, KL - 1VL( I, KSR ) = ZERO80 CONTINUEIF( PAIR ) THENDO 90 I = 1, KL - 1VL( I, KSI ) = ZERO90 CONTINUEEND IFEND IFIF( RIGHTV ) THEN** Compute right eigenvector.*CALL DLAEIN( .TRUE., NOINIT, KR, H, LDH, WKR, WKI,$ VR( 1, KSR ), VR( 1, KSI ), WORK, LDWORK,$ WORK( N*N+N+1 ), EPS3, SMLNUM, BIGNUM,$ IINFO )IF( IINFO.GT.0 ) THENIF( PAIR ) THENINFO = INFO + 2ELSEINFO = INFO + 1END IFIFAILR( KSR ) = KIFAILR( KSI ) = KELSEIFAILR( KSR ) = 0IFAILR( KSI ) = 0END IFDO 100 I = KR + 1, NVR( I, KSR ) = ZERO100 CONTINUEIF( PAIR ) THENDO 110 I = KR + 1, NVR( I, KSI ) = ZERO110 CONTINUEEND IFEND IF*IF( PAIR ) THENKSR = KSR + 2ELSEKSR = KSR + 1END IFEND IF120 CONTINUE*RETURN** End of DHSEIN*END*> \brief \b DHSEQR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DHSEQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dhseqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dhseqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dhseqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,* LDZ, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, N* CHARACTER COMPZ, JOB* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DHSEQR computes the eigenvalues of a Hessenberg matrix H*> and, optionally, the matrices T and Z from the Schur decomposition*> H = Z T Z**T, where T is an upper quasi-triangular matrix (the*> Schur form), and Z is the orthogonal matrix of Schur vectors.*>*> Optionally Z may be postmultiplied into an input orthogonal*> matrix Q so that this routine can give the Schur factorization*> of a matrix A which has been reduced to the Hessenberg form H*> by the orthogonal matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> = 'E': compute eigenvalues only;*> = 'S': compute eigenvalues and the Schur form T.*> \endverbatim*>*> \param[in] COMPZ*> \verbatim*> COMPZ is CHARACTER*1*> = 'N': no Schur vectors are computed;*> = 'I': Z is initialized to the unit matrix and the matrix Z*> of Schur vectors of H is returned;*> = 'V': Z must contain an orthogonal matrix Q on entry, and*> the product Q*Z is returned.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H. N .GE. 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*>*> It is assumed that H is already upper triangular in rows*> and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally*> set by a previous call to DGEBAL, and then passed to ZGEHRD*> when the matrix output by DGEBAL is reduced to Hessenberg*> form. Otherwise ILO and IHI should be set to 1 and N*> respectively. If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.*> If N = 0, then ILO = 1 and IHI = 0.*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On entry, the upper Hessenberg matrix H.*> On exit, if INFO = 0 and JOB = 'S', then H contains the*> upper quasi-triangular matrix T from the Schur decomposition*> (the Schur form); 2-by-2 diagonal blocks (corresponding to*> complex conjugate pairs of eigenvalues) are returned in*> standard form, with H(i,i) = H(i+1,i+1) and*> H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and JOB = 'E', the*> contents of H are unspecified on exit. (The output value of*> H when INFO.GT.0 is given under the description of INFO*> below.)*>*> Unlike earlier versions of DHSEQR, this subroutine may*> explicitly H(i,j) = 0 for i.GT.j and j = 1, 2, ... ILO-1*> or j = IHI+1, IHI+2, ... N.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH .GE. max(1,N).*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*>*> The real and imaginary parts, respectively, of the computed*> eigenvalues. If two eigenvalues are computed as a complex*> conjugate pair, they are stored in consecutive elements of*> WR and WI, say the i-th and (i+1)th, with WI(i) .GT. 0 and*> WI(i+1) .LT. 0. If JOB = 'S', the eigenvalues are stored in*> the same order as on the diagonal of the Schur form returned*> in H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2*> diagonal block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and*> WI(i+1) = -WI(i).*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> If COMPZ = 'N', Z is not referenced.*> If COMPZ = 'I', on entry Z need not be set and on exit,*> if INFO = 0, Z contains the orthogonal matrix Z of the Schur*> vectors of H. If COMPZ = 'V', on entry Z must contain an*> N-by-N matrix Q, which is assumed to be equal to the unit*> matrix except for the submatrix Z(ILO:IHI,ILO:IHI). On exit,*> if INFO = 0, Z contains Q*Z.*> Normally Q is the orthogonal matrix generated by DORGHR*> after the call to DGEHRD which formed the Hessenberg matrix*> H. (The output value of Z when INFO.GT.0 is given under*> the description of INFO below.)*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. if COMPZ = 'I' or*> COMPZ = 'V', then LDZ.GE.MAX(1,N). Otherwize, LDZ.GE.1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns an estimate of*> the optimal value for LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK .GE. max(1,N)*> is sufficient and delivers very good and sometimes*> optimal performance. However, LWORK as large as 11*N*> may be required for optimal performance. A workspace*> query is recommended to determine the optimal workspace*> size.*>*> If LWORK = -1, then DHSEQR does a workspace query.*> In this case, DHSEQR checks the input parameters and*> estimates the optimal workspace size for the given*> values of N, ILO and IHI. The estimate is returned*> in WORK(1). No error message related to LWORK is*> issued by XERBLA. Neither H nor Z are accessed.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> .LT. 0: if INFO = -i, the i-th argument had an illegal*> value*> .GT. 0: if INFO = i, DHSEQR failed to compute all of*> the eigenvalues. Elements 1:ilo-1 and i+1:n of WR*> and WI contain those eigenvalues which have been*> successfully computed. (Failures are rare.)*>*> If INFO .GT. 0 and JOB = 'E', then on exit, the*> remaining unconverged eigenvalues are the eigen-*> values of the upper Hessenberg matrix rows and*> columns ILO through INFO of the final, output*> value of H.*>*> If INFO .GT. 0 and JOB = 'S', then on exit*>*> (*) (initial value of H)*U = U*(final value of H)*>*> where U is an orthogonal matrix. The final*> value of H is upper Hessenberg and quasi-triangular*> in rows and columns INFO+1 through IHI.*>*> If INFO .GT. 0 and COMPZ = 'V', then on exit*>*> (final value of Z) = (initial value of Z)*U*>*> where U is the orthogonal matrix in (*) (regard-*> less of the value of JOB.)*>*> If INFO .GT. 0 and COMPZ = 'I', then on exit*> (final value of Z) = U*> where U is the orthogonal matrix in (*) (regard-*> less of the value of JOB.)*>*> If INFO .GT. 0 and COMPZ = 'N', then Z is not*> accessed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA**> \par Further Details:* =====================*>*> \verbatim*>*> Default values supplied by*> ILAENV(ISPEC,'DHSEQR',JOB(:1)//COMPZ(:1),N,ILO,IHI,LWORK).*> It is suggested that these defaults be adjusted in order*> to attain best performance in each particular*> computational environment.*>*> ISPEC=12: The DLAHQR vs DLAQR0 crossover point.*> Default: 75. (Must be at least 11.)*>*> ISPEC=13: Recommended deflation window size.*> This depends on ILO, IHI and NS. NS is the*> number of simultaneous shifts returned*> by ILAENV(ISPEC=15). (See ISPEC=15 below.)*> The default for (IHI-ILO+1).LE.500 is NS.*> The default for (IHI-ILO+1).GT.500 is 3*NS/2.*>*> ISPEC=14: Nibble crossover point. (See IPARMQ for*> details.) Default: 14% of deflation window*> size.*>*> ISPEC=15: Number of simultaneous shifts in a multishift*> QR iteration.*>*> If IHI-ILO+1 is ...*>*> greater than ...but less ... the*> or equal to ... than default is*>*> 1 30 NS = 2(+)*> 30 60 NS = 4(+)*> 60 150 NS = 10(+)*> 150 590 NS = ***> 590 3000 NS = 64*> 3000 6000 NS = 128*> 6000 infinity NS = 256*>*> (+) By default some or all matrices of this order*> are passed to the implicit double shift routine*> DLAHQR and this parameter is ignored. See*> ISPEC=12 above and comments in IPARMQ for*> details.*>*> (**) The asterisks (**) indicate an ad-hoc*> function of N increasing from 10 to 64.*>*> ISPEC=16: Select structured matrix multiply.*> If the number of simultaneous shifts (specified*> by ISPEC=15) is less than 14, then the default*> for ISPEC=16 is 0. Otherwise the default for*> ISPEC=16 is 2.*> \endverbatim**> \par References:* ================*>*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part I: Maintaining Well Focused Shifts, and Level 3*> Performance, SIAM Journal of Matrix Analysis, volume 23, pages*> 929--947, 2002.*> \n*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part II: Aggressive Early Deflation, SIAM Journal*> of Matrix Analysis, volume 23, pages 948--973, 2002.** =====================================================================SUBROUTINE DHSEQR( JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z,$ LDZ, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, ILO, INFO, LDH, LDZ, LWORK, NCHARACTER COMPZ, JOB* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),$ Z( LDZ, * )* ..** =====================================================================** .. Parameters ..** ==== Matrices of order NTINY or smaller must be processed by* . DLAHQR because of insufficient subdiagonal scratch space.* . (This is a hard limit.) ====INTEGER NTINYPARAMETER ( NTINY = 11 )** ==== NL allocates some local workspace to help small matrices* . through a rare DLAHQR failure. NL .GT. NTINY = 11 is* . required and NL .LE. NMIN = ILAENV(ISPEC=12,...) is recom-* . mended. (The default value of NMIN is 75.) Using NL = 49* . allows up to six simultaneous shifts and a 16-by-16* . deflation window. ====INTEGER NLPARAMETER ( NL = 49 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 )* ..* .. Local Arrays ..DOUBLE PRECISION HL( NL, NL ), WORKL( NL )* ..* .. Local Scalars ..INTEGER I, KBOT, NMINLOGICAL INITZ, LQUERY, WANTT, WANTZ* ..* .. External Functions ..INTEGER ILAENVLOGICAL LSAMEEXTERNAL ILAENV, LSAME* ..* .. External Subroutines ..EXTERNAL DLACPY, DLAHQR, DLAQR0, DLASET, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX, MIN* ..* .. Executable Statements ..** ==== Decode and check the input parameters. ====*WANTT = LSAME( JOB, 'S' )INITZ = LSAME( COMPZ, 'I' )WANTZ = INITZ .OR. LSAME( COMPZ, 'V' )WORK( 1 ) = DBLE( MAX( 1, N ) )LQUERY = LWORK.EQ.-1*INFO = 0IF( .NOT.LSAME( JOB, 'E' ) .AND. .NOT.WANTT ) THENINFO = -1ELSE IF( .NOT.LSAME( COMPZ, 'N' ) .AND. .NOT.WANTZ ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -4ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -5ELSE IF( LDH.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.MAX( 1, N ) ) ) THENINFO = -11ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -13END IF*IF( INFO.NE.0 ) THEN** ==== Quick return in case of invalid argument. ====*CALL XERBLA( 'DHSEQR', -INFO )RETURN*ELSE IF( N.EQ.0 ) THEN** ==== Quick return in case N = 0; nothing to do. ====*RETURN*ELSE IF( LQUERY ) THEN** ==== Quick return in case of a workspace query ====*CALL DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,$ IHI, Z, LDZ, WORK, LWORK, INFO )* ==== Ensure reported workspace size is backward-compatible with* . previous LAPACK versions. ====WORK( 1 ) = MAX( DBLE( MAX( 1, N ) ), WORK( 1 ) )RETURN*ELSE** ==== copy eigenvalues isolated by DGEBAL ====*DO 10 I = 1, ILO - 1WR( I ) = H( I, I )WI( I ) = ZERO10 CONTINUEDO 20 I = IHI + 1, NWR( I ) = H( I, I )WI( I ) = ZERO20 CONTINUE** ==== Initialize Z, if requested ====*IF( INITZ )$ CALL DLASET( 'A', N, N, ZERO, ONE, Z, LDZ )** ==== Quick return if possible ====*IF( ILO.EQ.IHI ) THENWR( ILO ) = H( ILO, ILO )WI( ILO ) = ZERORETURNEND IF** ==== DLAHQR/DLAQR0 crossover point ====*NMIN = ILAENV( 12, 'DHSEQR', JOB( : 1 ) // COMPZ( : 1 ), N,$ ILO, IHI, LWORK )NMIN = MAX( NTINY, NMIN )** ==== DLAQR0 for big matrices; DLAHQR for small ones ====*IF( N.GT.NMIN ) THENCALL DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,$ IHI, Z, LDZ, WORK, LWORK, INFO )ELSE** ==== Small matrix ====*CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI, ILO,$ IHI, Z, LDZ, INFO )*IF( INFO.GT.0 ) THEN** ==== A rare DLAHQR failure! DLAQR0 sometimes succeeds* . when DLAHQR fails. ====*KBOT = INFO*IF( N.GE.NL ) THEN** ==== Larger matrices have enough subdiagonal scratch* . space to call DLAQR0 directly. ====*CALL DLAQR0( WANTT, WANTZ, N, ILO, KBOT, H, LDH, WR,$ WI, ILO, IHI, Z, LDZ, WORK, LWORK, INFO )*ELSE** ==== Tiny matrices don't have enough subdiagonal* . scratch space to benefit from DLAQR0. Hence,* . tiny matrices must be copied into a larger* . array before calling DLAQR0. ====*CALL DLACPY( 'A', N, N, H, LDH, HL, NL )HL( N+1, N ) = ZEROCALL DLASET( 'A', NL, NL-N, ZERO, ZERO, HL( 1, N+1 ),$ NL )CALL DLAQR0( WANTT, WANTZ, NL, ILO, KBOT, HL, NL, WR,$ WI, ILO, IHI, Z, LDZ, WORKL, NL, INFO )IF( WANTT .OR. INFO.NE.0 )$ CALL DLACPY( 'A', N, N, HL, NL, H, LDH )END IFEND IFEND IF** ==== Clear out the trash, if necessary. ====*IF( ( WANTT .OR. INFO.NE.0 ) .AND. N.GT.2 )$ CALL DLASET( 'L', N-2, N-2, ZERO, ZERO, H( 3, 1 ), LDH )** ==== Ensure reported workspace size is backward-compatible with* . previous LAPACK versions. ====*WORK( 1 ) = MAX( DBLE( MAX( 1, N ) ), WORK( 1 ) )END IF** ==== End of DHSEQR ====*END*> \brief \b DISNAN tests input for NaN.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DISNAN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/disnan.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/disnan.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/disnan.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** LOGICAL FUNCTION DISNAN( DIN )** .. Scalar Arguments ..* DOUBLE PRECISION, INTENT(IN) :: DIN* ..***> \par Purpose:* =============*>*> \verbatim*>*> DISNAN returns .TRUE. if its argument is NaN, and .FALSE.*> otherwise. To be replaced by the Fortran 2003 intrinsic in the*> future.*> \endverbatim** Arguments:* ==========**> \param[in] DIN*> \verbatim*> DIN is DOUBLE PRECISION*> Input to test for NaN.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary** =====================================================================LOGICAL FUNCTION DISNAN( DIN )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..DOUBLE PRECISION, INTENT(IN) :: DIN* ..** =====================================================================** .. External Functions ..LOGICAL DLAISNANEXTERNAL DLAISNAN* ..* .. Executable Statements ..DISNAN = DLAISNAN(DIN,DIN)RETURNEND*> \brief \b DLABAD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLABAD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlabad.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlabad.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlabad.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLABAD( SMALL, LARGE )** .. Scalar Arguments ..* DOUBLE PRECISION LARGE, SMALL* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLABAD takes as input the values computed by DLAMCH for underflow and*> overflow, and returns the square root of each of these values if the*> log of LARGE is sufficiently large. This subroutine is intended to*> identify machines with a large exponent range, such as the Crays, and*> redefine the underflow and overflow limits to be the square roots of*> the values computed by DLAMCH. This subroutine is needed because*> DLAMCH does not compensate for poor arithmetic in the upper half of*> the exponent range, as is found on a Cray.*> \endverbatim** Arguments:* ==========**> \param[in,out] SMALL*> \verbatim*> SMALL is DOUBLE PRECISION*> On entry, the underflow threshold as computed by DLAMCH.*> On exit, if LOG10(LARGE) is sufficiently large, the square*> root of SMALL, otherwise unchanged.*> \endverbatim*>*> \param[in,out] LARGE*> \verbatim*> LARGE is DOUBLE PRECISION*> On entry, the overflow threshold as computed by DLAMCH.*> On exit, if LOG10(LARGE) is sufficiently large, the square*> root of LARGE, otherwise unchanged.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLABAD( SMALL, LARGE )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION LARGE, SMALL* ..** =====================================================================** .. Intrinsic Functions ..INTRINSIC LOG10, SQRT* ..* .. Executable Statements ..** If it looks like we're on a Cray, take the square root of* SMALL and LARGE to avoid overflow and underflow problems.*IF( LOG10( LARGE ).GT.2000.D0 ) THENSMALL = SQRT( SMALL )LARGE = SQRT( LARGE )END IF*RETURN** End of DLABAD*END*> \brief \b DLABRD reduces the first nb rows and columns of a general matrix to a bidiagonal form.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLABRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlabrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlabrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlabrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,* LDY )** .. Scalar Arguments ..* INTEGER LDA, LDX, LDY, M, N, NB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),* $ TAUQ( * ), X( LDX, * ), Y( LDY, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLABRD reduces the first NB rows and columns of a real general*> m by n matrix A to upper or lower bidiagonal form by an orthogonal*> transformation Q**T * A * P, and returns the matrices X and Y which*> are needed to apply the transformation to the unreduced part of A.*>*> If m >= n, A is reduced to upper bidiagonal form; if m < n, to lower*> bidiagonal form.*>*> This is an auxiliary routine called by DGEBRD*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows in the matrix A.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns in the matrix A.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The number of leading rows and columns of A to be reduced.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the m by n general matrix to be reduced.*> On exit, the first NB rows and columns of the matrix are*> overwritten; the rest of the array is unchanged.*> If m >= n, elements on and below the diagonal in the first NB*> columns, with the array TAUQ, represent the orthogonal*> matrix Q as a product of elementary reflectors; and*> elements above the diagonal in the first NB rows, with the*> array TAUP, represent the orthogonal matrix P as a product*> of elementary reflectors.*> If m < n, elements below the diagonal in the first NB*> columns, with the array TAUQ, represent the orthogonal*> matrix Q as a product of elementary reflectors, and*> elements on and above the diagonal in the first NB rows,*> with the array TAUP, represent the orthogonal matrix P as*> a product of elementary reflectors.*> See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (NB)*> The diagonal elements of the first NB rows and columns of*> the reduced matrix. D(i) = A(i,i).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (NB)*> The off-diagonal elements of the first NB rows and columns of*> the reduced matrix.*> \endverbatim*>*> \param[out] TAUQ*> \verbatim*> TAUQ is DOUBLE PRECISION array, dimension (NB)*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix Q. See Further Details.*> \endverbatim*>*> \param[out] TAUP*> \verbatim*> TAUP is DOUBLE PRECISION array, dimension (NB)*> The scalar factors of the elementary reflectors which*> represent the orthogonal matrix P. See Further Details.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NB)*> The m-by-nb matrix X required to update the unreduced part*> of A.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,M).*> \endverbatim*>*> \param[out] Y*> \verbatim*> Y is DOUBLE PRECISION array, dimension (LDY,NB)*> The n-by-nb matrix Y required to update the unreduced part*> of A.*> \endverbatim*>*> \param[in] LDY*> \verbatim*> LDY is INTEGER*> The leading dimension of the array Y. LDY >= max(1,N).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The matrices Q and P are represented as products of elementary*> reflectors:*>*> Q = H(1) H(2) . . . H(nb) and P = G(1) G(2) . . . G(nb)*>*> Each H(i) and G(i) has the form:*>*> H(i) = I - tauq * v * v**T and G(i) = I - taup * u * u**T*>*> where tauq and taup are real scalars, and v and u are real vectors.*>*> If m >= n, v(1:i-1) = 0, v(i) = 1, and v(i:m) is stored on exit in*> A(i:m,i); u(1:i) = 0, u(i+1) = 1, and u(i+1:n) is stored on exit in*> A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).*>*> If m < n, v(1:i) = 0, v(i+1) = 1, and v(i+1:m) is stored on exit in*> A(i+2:m,i); u(1:i-1) = 0, u(i) = 1, and u(i:n) is stored on exit in*> A(i,i+1:n); tauq is stored in TAUQ(i) and taup in TAUP(i).*>*> The elements of the vectors v and u together form the m-by-nb matrix*> V and the nb-by-n matrix U**T which are needed, with X and Y, to apply*> the transformation to the unreduced part of the matrix, using a block*> update of the form: A := A - V*Y**T - X*U**T.*>*> The contents of A on exit are illustrated by the following examples*> with nb = 2:*>*> m = 6 and n = 5 (m > n): m = 5 and n = 6 (m < n):*>*> ( 1 1 u1 u1 u1 ) ( 1 u1 u1 u1 u1 u1 )*> ( v1 1 1 u2 u2 ) ( 1 1 u2 u2 u2 u2 )*> ( v1 v2 a a a ) ( v1 1 a a a a )*> ( v1 v2 a a a ) ( v1 v2 a a a a )*> ( v1 v2 a a a ) ( v1 v2 a a a a )*> ( v1 v2 a a a )*>*> where a denotes an element of the original matrix which is unchanged,*> vi denotes an element of the vector defining H(i), and ui an element*> of the vector defining G(i).*> \endverbatim*>* =====================================================================SUBROUTINE DLABRD( M, N, NB, A, LDA, D, E, TAUQ, TAUP, X, LDX, Y,$ LDY )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER LDA, LDX, LDY, M, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAUP( * ),$ TAUQ( * ), X( LDX, * ), Y( LDY, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER I* ..* .. External Subroutines ..EXTERNAL DGEMV, DLARFG, DSCAL* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 )$ RETURN*IF( M.GE.N ) THEN** Reduce to upper bidiagonal form*DO 10 I = 1, NB** Update A(i:m,i)*CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, A( I, 1 ),$ LDA, Y( I, 1 ), LDY, ONE, A( I, I ), 1 )CALL DGEMV( 'No transpose', M-I+1, I-1, -ONE, X( I, 1 ),$ LDX, A( 1, I ), 1, ONE, A( I, I ), 1 )** Generate reflection Q(i) to annihilate A(i+1:m,i)*CALL DLARFG( M-I+1, A( I, I ), A( MIN( I+1, M ), I ), 1,$ TAUQ( I ) )D( I ) = A( I, I )IF( I.LT.N ) THENA( I, I ) = ONE** Compute Y(i+1:n,i)*CALL DGEMV( 'Transpose', M-I+1, N-I, ONE, A( I, I+1 ),$ LDA, A( I, I ), 1, ZERO, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, A( I, 1 ), LDA,$ A( I, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),$ LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I+1, I-1, ONE, X( I, 1 ), LDX,$ A( I, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),$ LDA, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )** Update A(i,i+1:n)*CALL DGEMV( 'No transpose', N-I, I, -ONE, Y( I+1, 1 ),$ LDY, A( I, 1 ), LDA, ONE, A( I, I+1 ), LDA )CALL DGEMV( 'Transpose', I-1, N-I, -ONE, A( 1, I+1 ),$ LDA, X( I, 1 ), LDX, ONE, A( I, I+1 ), LDA )** Generate reflection P(i) to annihilate A(i,i+2:n)*CALL DLARFG( N-I, A( I, I+1 ), A( I, MIN( I+2, N ) ),$ LDA, TAUP( I ) )E( I ) = A( I, I+1 )A( I, I+1 ) = ONE** Compute X(i+1:m,i)*CALL DGEMV( 'No transpose', M-I, N-I, ONE, A( I+1, I+1 ),$ LDA, A( I, I+1 ), LDA, ZERO, X( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I, I, ONE, Y( I+1, 1 ), LDY,$ A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I, -ONE, A( I+1, 1 ),$ LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),$ LDA, A( I, I+1 ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),$ LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )END IF10 CONTINUEELSE** Reduce to lower bidiagonal form*DO 20 I = 1, NB** Update A(i,i:n)*CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, Y( I, 1 ),$ LDY, A( I, 1 ), LDA, ONE, A( I, I ), LDA )CALL DGEMV( 'Transpose', I-1, N-I+1, -ONE, A( 1, I ), LDA,$ X( I, 1 ), LDX, ONE, A( I, I ), LDA )** Generate reflection P(i) to annihilate A(i,i+1:n)*CALL DLARFG( N-I+1, A( I, I ), A( I, MIN( I+1, N ) ), LDA,$ TAUP( I ) )D( I ) = A( I, I )IF( I.LT.M ) THENA( I, I ) = ONE** Compute X(i+1:m,i)*CALL DGEMV( 'No transpose', M-I, N-I+1, ONE, A( I+1, I ),$ LDA, A( I, I ), LDA, ZERO, X( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I+1, I-1, ONE, Y( I, 1 ), LDY,$ A( I, I ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),$ LDA, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DGEMV( 'No transpose', I-1, N-I+1, ONE, A( 1, I ),$ LDA, A( I, I ), LDA, ZERO, X( 1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I-1, -ONE, X( I+1, 1 ),$ LDX, X( 1, I ), 1, ONE, X( I+1, I ), 1 )CALL DSCAL( M-I, TAUP( I ), X( I+1, I ), 1 )** Update A(i+1:m,i)*CALL DGEMV( 'No transpose', M-I, I-1, -ONE, A( I+1, 1 ),$ LDA, Y( I, 1 ), LDY, ONE, A( I+1, I ), 1 )CALL DGEMV( 'No transpose', M-I, I, -ONE, X( I+1, 1 ),$ LDX, A( 1, I ), 1, ONE, A( I+1, I ), 1 )** Generate reflection Q(i) to annihilate A(i+2:m,i)*CALL DLARFG( M-I, A( I+1, I ), A( MIN( I+2, M ), I ), 1,$ TAUQ( I ) )E( I ) = A( I+1, I )A( I+1, I ) = ONE** Compute Y(i+1:n,i)*CALL DGEMV( 'Transpose', M-I, N-I, ONE, A( I+1, I+1 ),$ LDA, A( I+1, I ), 1, ZERO, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I, I-1, ONE, A( I+1, 1 ), LDA,$ A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, Y( I+1, 1 ),$ LDY, Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DGEMV( 'Transpose', M-I, I, ONE, X( I+1, 1 ), LDX,$ A( I+1, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'Transpose', I, N-I, -ONE, A( 1, I+1 ), LDA,$ Y( 1, I ), 1, ONE, Y( I+1, I ), 1 )CALL DSCAL( N-I, TAUQ( I ), Y( I+1, I ), 1 )END IF20 CONTINUEEND IFRETURN** End of DLABRD*END*> \brief \b DLACN2 estimates the 1-norm of a square matrix, using reverse communication for evaluating matrix-vector products.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLACN2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlacn2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlacn2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlacn2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLACN2( N, V, X, ISGN, EST, KASE, ISAVE )** .. Scalar Arguments ..* INTEGER KASE, N* DOUBLE PRECISION EST* ..* .. Array Arguments ..* INTEGER ISGN( * ), ISAVE( 3 )* DOUBLE PRECISION V( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLACN2 estimates the 1-norm of a square, real matrix A.*> Reverse communication is used for evaluating matrix-vector products.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 1.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (N)*> On the final return, V = A*W, where EST = norm(V)/norm(W)*> (W is not returned).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> On an intermediate return, X should be overwritten by*> A * X, if KASE=1,*> A**T * X, if KASE=2,*> and DLACN2 must be re-called with all the other parameters*> unchanged.*> \endverbatim*>*> \param[out] ISGN*> \verbatim*> ISGN is INTEGER array, dimension (N)*> \endverbatim*>*> \param[in,out] EST*> \verbatim*> EST is DOUBLE PRECISION*> On entry with KASE = 1 or 2 and ISAVE(1) = 3, EST should be*> unchanged from the previous call to DLACN2.*> On exit, EST is an estimate (a lower bound) for norm(A).*> \endverbatim*>*> \param[in,out] KASE*> \verbatim*> KASE is INTEGER*> On the initial call to DLACN2, KASE should be 0.*> On an intermediate return, KASE will be 1 or 2, indicating*> whether X should be overwritten by A * X or A**T * X.*> On the final return from DLACN2, KASE will again be 0.*> \endverbatim*>*> \param[in,out] ISAVE*> \verbatim*> ISAVE is INTEGER array, dimension (3)*> ISAVE is used to save variables between calls to DLACN2*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Originally named SONEST, dated March 16, 1988.*>*> This is a thread safe version of DLACON, which uses the array ISAVE*> in place of a SAVE statement, as follows:*>*> DLACON DLACN2*> JUMP ISAVE(1)*> J ISAVE(2)*> ITER ISAVE(3)*> \endverbatim**> \par Contributors:* ==================*>*> Nick Higham, University of Manchester**> \par References:* ================*>*> N.J. Higham, "FORTRAN codes for estimating the one-norm of*> a real or complex matrix, with applications to condition estimation",*> ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.*>* =====================================================================SUBROUTINE DLACN2( N, V, X, ISGN, EST, KASE, ISAVE )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER KASE, NDOUBLE PRECISION EST* ..* .. Array Arguments ..INTEGER ISGN( * ), ISAVE( 3 )DOUBLE PRECISION V( * ), X( * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER I, JLASTDOUBLE PRECISION ALTSGN, ESTOLD, TEMP* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DASUMEXTERNAL IDAMAX, DASUM* ..* .. External Subroutines ..EXTERNAL DCOPY* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, NINT, SIGN* ..* .. Executable Statements ..*IF( KASE.EQ.0 ) THENDO 10 I = 1, NX( I ) = ONE / DBLE( N )10 CONTINUEKASE = 1ISAVE( 1 ) = 1RETURNEND IF*GO TO ( 20, 40, 70, 110, 140 )ISAVE( 1 )** ................ ENTRY (ISAVE( 1 ) = 1)* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X.*20 CONTINUEIF( N.EQ.1 ) THENV( 1 ) = X( 1 )EST = ABS( V( 1 ) )* ... QUITGO TO 150END IFEST = DASUM( N, X, 1 )*DO 30 I = 1, NX( I ) = SIGN( ONE, X( I ) )ISGN( I ) = NINT( X( I ) )30 CONTINUEKASE = 2ISAVE( 1 ) = 2RETURN** ................ ENTRY (ISAVE( 1 ) = 2)* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.*40 CONTINUEISAVE( 2 ) = IDAMAX( N, X, 1 )ISAVE( 3 ) = 2** MAIN LOOP - ITERATIONS 2,3,...,ITMAX.*50 CONTINUEDO 60 I = 1, NX( I ) = ZERO60 CONTINUEX( ISAVE( 2 ) ) = ONEKASE = 1ISAVE( 1 ) = 3RETURN** ................ ENTRY (ISAVE( 1 ) = 3)* X HAS BEEN OVERWRITTEN BY A*X.*70 CONTINUECALL DCOPY( N, X, 1, V, 1 )ESTOLD = ESTEST = DASUM( N, V, 1 )DO 80 I = 1, NIF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )$ GO TO 9080 CONTINUE* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.GO TO 120*90 CONTINUE* TEST FOR CYCLING.IF( EST.LE.ESTOLD )$ GO TO 120*DO 100 I = 1, NX( I ) = SIGN( ONE, X( I ) )ISGN( I ) = NINT( X( I ) )100 CONTINUEKASE = 2ISAVE( 1 ) = 4RETURN** ................ ENTRY (ISAVE( 1 ) = 4)* X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.*110 CONTINUEJLAST = ISAVE( 2 )ISAVE( 2 ) = IDAMAX( N, X, 1 )IF( ( X( JLAST ).NE.ABS( X( ISAVE( 2 ) ) ) ) .AND.$ ( ISAVE( 3 ).LT.ITMAX ) ) THENISAVE( 3 ) = ISAVE( 3 ) + 1GO TO 50END IF** ITERATION COMPLETE. FINAL STAGE.*120 CONTINUEALTSGN = ONEDO 130 I = 1, NX( I ) = ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) )ALTSGN = -ALTSGN130 CONTINUEKASE = 1ISAVE( 1 ) = 5RETURN** ................ ENTRY (ISAVE( 1 ) = 5)* X HAS BEEN OVERWRITTEN BY A*X.*140 CONTINUETEMP = TWO*( DASUM( N, X, 1 ) / DBLE( 3*N ) )IF( TEMP.GT.EST ) THENCALL DCOPY( N, X, 1, V, 1 )EST = TEMPEND IF*150 CONTINUEKASE = 0RETURN** End of DLACN2*END*> \brief \b DLACON estimates the 1-norm of a square matrix, using reverse communication for evaluating matrix-vector products.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLACON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlacon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlacon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlacon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLACON( N, V, X, ISGN, EST, KASE )** .. Scalar Arguments ..* INTEGER KASE, N* DOUBLE PRECISION EST* ..* .. Array Arguments ..* INTEGER ISGN( * )* DOUBLE PRECISION V( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLACON estimates the 1-norm of a square, real matrix A.*> Reverse communication is used for evaluating matrix-vector products.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 1.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (N)*> On the final return, V = A*W, where EST = norm(V)/norm(W)*> (W is not returned).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> On an intermediate return, X should be overwritten by*> A * X, if KASE=1,*> A**T * X, if KASE=2,*> and DLACON must be re-called with all the other parameters*> unchanged.*> \endverbatim*>*> \param[out] ISGN*> \verbatim*> ISGN is INTEGER array, dimension (N)*> \endverbatim*>*> \param[in,out] EST*> \verbatim*> EST is DOUBLE PRECISION*> On entry with KASE = 1 or 2 and JUMP = 3, EST should be*> unchanged from the previous call to DLACON.*> On exit, EST is an estimate (a lower bound) for norm(A).*> \endverbatim*>*> \param[in,out] KASE*> \verbatim*> KASE is INTEGER*> On the initial call to DLACON, KASE should be 0.*> On an intermediate return, KASE will be 1 or 2, indicating*> whether X should be overwritten by A * X or A**T * X.*> On the final return from DLACON, KASE will again be 0.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Nick Higham, University of Manchester. \n*> Originally named SONEST, dated March 16, 1988.**> \par References:* ================*>*> N.J. Higham, "FORTRAN codes for estimating the one-norm of*> a real or complex matrix, with applications to condition estimation",*> ACM Trans. Math. Soft., vol. 14, no. 4, pp. 381-396, December 1988.*>* =====================================================================SUBROUTINE DLACON( N, V, X, ISGN, EST, KASE )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER KASE, NDOUBLE PRECISION EST* ..* .. Array Arguments ..INTEGER ISGN( * )DOUBLE PRECISION V( * ), X( * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER I, ITER, J, JLAST, JUMPDOUBLE PRECISION ALTSGN, ESTOLD, TEMP* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DASUMEXTERNAL IDAMAX, DASUM* ..* .. External Subroutines ..EXTERNAL DCOPY* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, NINT, SIGN* ..* .. Save statement ..SAVE* ..* .. Executable Statements ..*IF( KASE.EQ.0 ) THENDO 10 I = 1, NX( I ) = ONE / DBLE( N )10 CONTINUEKASE = 1JUMP = 1RETURNEND IF*GO TO ( 20, 40, 70, 110, 140 )JUMP** ................ ENTRY (JUMP = 1)* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY A*X.*20 CONTINUEIF( N.EQ.1 ) THENV( 1 ) = X( 1 )EST = ABS( V( 1 ) )* ... QUITGO TO 150END IFEST = DASUM( N, X, 1 )*DO 30 I = 1, NX( I ) = SIGN( ONE, X( I ) )ISGN( I ) = NINT( X( I ) )30 CONTINUEKASE = 2JUMP = 2RETURN** ................ ENTRY (JUMP = 2)* FIRST ITERATION. X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.*40 CONTINUEJ = IDAMAX( N, X, 1 )ITER = 2** MAIN LOOP - ITERATIONS 2,3,...,ITMAX.*50 CONTINUEDO 60 I = 1, NX( I ) = ZERO60 CONTINUEX( J ) = ONEKASE = 1JUMP = 3RETURN** ................ ENTRY (JUMP = 3)* X HAS BEEN OVERWRITTEN BY A*X.*70 CONTINUECALL DCOPY( N, X, 1, V, 1 )ESTOLD = ESTEST = DASUM( N, V, 1 )DO 80 I = 1, NIF( NINT( SIGN( ONE, X( I ) ) ).NE.ISGN( I ) )$ GO TO 9080 CONTINUE* REPEATED SIGN VECTOR DETECTED, HENCE ALGORITHM HAS CONVERGED.GO TO 120*90 CONTINUE* TEST FOR CYCLING.IF( EST.LE.ESTOLD )$ GO TO 120*DO 100 I = 1, NX( I ) = SIGN( ONE, X( I ) )ISGN( I ) = NINT( X( I ) )100 CONTINUEKASE = 2JUMP = 4RETURN** ................ ENTRY (JUMP = 4)* X HAS BEEN OVERWRITTEN BY TRANSPOSE(A)*X.*110 CONTINUEJLAST = JJ = IDAMAX( N, X, 1 )IF( ( X( JLAST ).NE.ABS( X( J ) ) ) .AND. ( ITER.LT.ITMAX ) ) THENITER = ITER + 1GO TO 50END IF** ITERATION COMPLETE. FINAL STAGE.*120 CONTINUEALTSGN = ONEDO 130 I = 1, NX( I ) = ALTSGN*( ONE+DBLE( I-1 ) / DBLE( N-1 ) )ALTSGN = -ALTSGN130 CONTINUEKASE = 1JUMP = 5RETURN** ................ ENTRY (JUMP = 5)* X HAS BEEN OVERWRITTEN BY A*X.*140 CONTINUETEMP = TWO*( DASUM( N, X, 1 ) / DBLE( 3*N ) )IF( TEMP.GT.EST ) THENCALL DCOPY( N, X, 1, V, 1 )EST = TEMPEND IF*150 CONTINUEKASE = 0RETURN** End of DLACON*END*> \brief \b DLACPY copies all or part of one two-dimensional array to another.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLACPY + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlacpy.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlacpy.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlacpy.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER LDA, LDB, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLACPY copies all or part of a two-dimensional matrix A to another*> matrix B.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies the part of the matrix A to be copied to B.*> = 'U': Upper triangular part*> = 'L': Lower triangular part*> Otherwise: All of the matrix A*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The m by n matrix A. If UPLO = 'U', only the upper triangle*> or trapezoid is accessed; if UPLO = 'L', only the lower*> triangle or trapezoid is accessed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On exit, B = A in the locations specified by UPLO.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER LDA, LDB, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = 1, MIN( J, M )B( I, J ) = A( I, J )10 CONTINUE20 CONTINUEELSE IF( LSAME( UPLO, 'L' ) ) THENDO 40 J = 1, NDO 30 I = J, MB( I, J ) = A( I, J )30 CONTINUE40 CONTINUEELSEDO 60 J = 1, NDO 50 I = 1, MB( I, J ) = A( I, J )50 CONTINUE60 CONTINUEEND IFRETURN** End of DLACPY*END*> \brief \b DLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLADIV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dladiv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dladiv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dladiv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLADIV( A, B, C, D, P, Q )** .. Scalar Arguments ..* DOUBLE PRECISION A, B, C, D, P, Q* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLADIV performs complex division in real arithmetic*>*> a + i*b*> p + i*q = ---------*> c + i*d*>*> The algorithm is due to Michael Baudin and Robert L. Smith*> and can be found in the paper*> "A Robust Complex Division in Scilab"*> \endverbatim** Arguments:* ==========**> \param[in] A*> \verbatim*> A is DOUBLE PRECISION*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION*> The scalars a, b, c, and d in the above expression.*> \endverbatim*>*> \param[out] P*> \verbatim*> P is DOUBLE PRECISION*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION*> The scalars p and q in the above expression.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date January 2013**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLADIV( A, B, C, D, P, Q )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* January 2013** .. Scalar Arguments ..DOUBLE PRECISION A, B, C, D, P, Q* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION BSPARAMETER ( BS = 2.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )** .. Local Scalars ..DOUBLE PRECISION AA, BB, CC, DD, AB, CD, S, OV, UN, BE, EPS* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DLADIV1* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..*AA = ABB = BCC = CDD = DAB = MAX( ABS(A), ABS(B) )CD = MAX( ABS(C), ABS(D) )S = 1.0D0OV = DLAMCH( 'Overflow threshold' )UN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Epsilon' )BE = BS / (EPS*EPS)IF( AB >= HALF*OV ) THENAA = HALF * AABB = HALF * BBS = TWO * SEND IFIF( CD >= HALF*OV ) THENCC = HALF * CCDD = HALF * DDS = HALF * SEND IFIF( AB <= UN*BS/EPS ) THENAA = AA * BEBB = BB * BES = S / BEEND IFIF( CD <= UN*BS/EPS ) THENCC = CC * BEDD = DD * BES = S * BEEND IFIF( ABS( D ).LE.ABS( C ) ) THENCALL DLADIV1(AA, BB, CC, DD, P, Q)ELSECALL DLADIV1(BB, AA, DD, CC, P, Q)Q = -QEND IFP = P * SQ = Q * S*RETURN** End of DLADIV*END*> \ingroup doubleOTHERauxiliarySUBROUTINE DLADIV1( A, B, C, D, P, Q )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* January 2013** .. Scalar Arguments ..DOUBLE PRECISION A, B, C, D, P, Q* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )** .. Local Scalars ..DOUBLE PRECISION R, T* ..* .. External Functions ..DOUBLE PRECISION DLADIV2EXTERNAL DLADIV2* ..* .. Executable Statements ..*R = D / CT = ONE / (C + D * R)P = DLADIV2(A, B, C, D, R, T)A = -AQ = DLADIV2(B, A, C, D, R, T)*RETURN** End of DLADIV1*END*> \ingroup doubleOTHERauxiliaryDOUBLE PRECISION FUNCTION DLADIV2( A, B, C, D, R, T )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* January 2013** .. Scalar Arguments ..DOUBLE PRECISION A, B, C, D, R, T* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )** .. Local Scalars ..DOUBLE PRECISION BR* ..* .. Executable Statements ..*IF( R.NE.ZERO ) THENBR = B * RIF( BR.NE.ZERO ) THENDLADIV2 = (A + BR) * TELSEDLADIV2 = A * T + (B * T) * REND IFELSEDLADIV2 = (A + D * (B / C)) * TEND IF*RETURN** End of DLADIV12*END*> \brief \b DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAE2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlae2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlae2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlae2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAE2( A, B, C, RT1, RT2 )** .. Scalar Arguments ..* DOUBLE PRECISION A, B, C, RT1, RT2* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix*> [ A B ]*> [ B C ].*> On return, RT1 is the eigenvalue of larger absolute value, and RT2*> is the eigenvalue of smaller absolute value.*> \endverbatim** Arguments:* ==========**> \param[in] A*> \verbatim*> A is DOUBLE PRECISION*> The (1,1) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION*> The (1,2) and (2,1) elements of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION*> The (2,2) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[out] RT1*> \verbatim*> RT1 is DOUBLE PRECISION*> The eigenvalue of larger absolute value.*> \endverbatim*>*> \param[out] RT2*> \verbatim*> RT2 is DOUBLE PRECISION*> The eigenvalue of smaller absolute value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> RT1 is accurate to a few ulps barring over/underflow.*>*> RT2 may be inaccurate if there is massive cancellation in the*> determinant A*C-B*B; higher precision or correctly rounded or*> correctly truncated arithmetic would be needed to compute RT2*> accurately in all cases.*>*> Overflow is possible only if RT1 is within a factor of 5 of overflow.*> Underflow is harmless if the input data is 0 or exceeds*> underflow_threshold / macheps.*> \endverbatim*>* =====================================================================SUBROUTINE DLAE2( A, B, C, RT1, RT2 )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION A, B, C, RT1, RT2* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )* ..* .. Local Scalars ..DOUBLE PRECISION AB, ACMN, ACMX, ADF, DF, RT, SM, TB* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..** Compute the eigenvalues*SM = A + CDF = A - CADF = ABS( DF )TB = B + BAB = ABS( TB )IF( ABS( A ).GT.ABS( C ) ) THENACMX = AACMN = CELSEACMX = CACMN = AEND IFIF( ADF.GT.AB ) THENRT = ADF*SQRT( ONE+( AB / ADF )**2 )ELSE IF( ADF.LT.AB ) THENRT = AB*SQRT( ONE+( ADF / AB )**2 )ELSE** Includes case AB=ADF=0*RT = AB*SQRT( TWO )END IFIF( SM.LT.ZERO ) THENRT1 = HALF*( SM-RT )** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE IF( SM.GT.ZERO ) THENRT1 = HALF*( SM+RT )** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE** Includes case RT1 = RT2 = 0*RT1 = HALF*RTRT2 = -HALF*RTEND IFRETURN** End of DLAE2*END*> \brief \b DLAEBZ computes the number of eigenvalues of a real symmetric tridiagonal matrix which are less than or equal to a given value, and performs other tasks required by the routine sstebz.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAEBZ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaebz.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaebz.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaebz.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAEBZ( IJOB, NITMAX, N, MMAX, MINP, NBMIN, ABSTOL,* RELTOL, PIVMIN, D, E, E2, NVAL, AB, C, MOUT,* NAB, WORK, IWORK, INFO )** .. Scalar Arguments ..* INTEGER IJOB, INFO, MINP, MMAX, MOUT, N, NBMIN, NITMAX* DOUBLE PRECISION ABSTOL, PIVMIN, RELTOL* ..* .. Array Arguments ..* INTEGER IWORK( * ), NAB( MMAX, * ), NVAL( * )* DOUBLE PRECISION AB( MMAX, * ), C( * ), D( * ), E( * ), E2( * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAEBZ contains the iteration loops which compute and use the*> function N(w), which is the count of eigenvalues of a symmetric*> tridiagonal matrix T less than or equal to its argument w. It*> performs a choice of two types of loops:*>*> IJOB=1, followed by*> IJOB=2: It takes as input a list of intervals and returns a list of*> sufficiently small intervals whose union contains the same*> eigenvalues as the union of the original intervals.*> The input intervals are (AB(j,1),AB(j,2)], j=1,...,MINP.*> The output interval (AB(j,1),AB(j,2)] will contain*> eigenvalues NAB(j,1)+1,...,NAB(j,2), where 1 <= j <= MOUT.*>*> IJOB=3: It performs a binary search in each input interval*> (AB(j,1),AB(j,2)] for a point w(j) such that*> N(w(j))=NVAL(j), and uses C(j) as the starting point of*> the search. If such a w(j) is found, then on output*> AB(j,1)=AB(j,2)=w. If no such w(j) is found, then on output*> (AB(j,1),AB(j,2)] will be a small interval containing the*> point where N(w) jumps through NVAL(j), unless that point*> lies outside the initial interval.*>*> Note that the intervals are in all cases half-open intervals,*> i.e., of the form (a,b] , which includes b but not a .*>*> To avoid underflow, the matrix should be scaled so that its largest*> element is no greater than overflow**(1/2) * underflow**(1/4)*> in absolute value. To assure the most accurate computation*> of small eigenvalues, the matrix should be scaled to be*> not much smaller than that, either.*>*> See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal*> Matrix", Report CS41, Computer Science Dept., Stanford*> University, July 21, 1966*>*> Note: the arguments are, in general, *not* checked for unreasonable*> values.*> \endverbatim** Arguments:* ==========**> \param[in] IJOB*> \verbatim*> IJOB is INTEGER*> Specifies what is to be done:*> = 1: Compute NAB for the initial intervals.*> = 2: Perform bisection iteration to find eigenvalues of T.*> = 3: Perform bisection iteration to invert N(w), i.e.,*> to find a point which has a specified number of*> eigenvalues of T to its left.*> Other values will cause DLAEBZ to return with INFO=-1.*> \endverbatim*>*> \param[in] NITMAX*> \verbatim*> NITMAX is INTEGER*> The maximum number of "levels" of bisection to be*> performed, i.e., an interval of width W will not be made*> smaller than 2^(-NITMAX) * W. If not all intervals*> have converged after NITMAX iterations, then INFO is set*> to the number of non-converged intervals.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension n of the tridiagonal matrix T. It must be at*> least 1.*> \endverbatim*>*> \param[in] MMAX*> \verbatim*> MMAX is INTEGER*> The maximum number of intervals. If more than MMAX intervals*> are generated, then DLAEBZ will quit with INFO=MMAX+1.*> \endverbatim*>*> \param[in] MINP*> \verbatim*> MINP is INTEGER*> The initial number of intervals. It may not be greater than*> MMAX.*> \endverbatim*>*> \param[in] NBMIN*> \verbatim*> NBMIN is INTEGER*> The smallest number of intervals that should be processed*> using a vector loop. If zero, then only the scalar loop*> will be used.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The minimum (absolute) width of an interval. When an*> interval is narrower than ABSTOL, or than RELTOL times the*> larger (in magnitude) endpoint, then it is considered to be*> sufficiently small, i.e., converged. This must be at least*> zero.*> \endverbatim*>*> \param[in] RELTOL*> \verbatim*> RELTOL is DOUBLE PRECISION*> The minimum relative width of an interval. When an interval*> is narrower than ABSTOL, or than RELTOL times the larger (in*> magnitude) endpoint, then it is considered to be*> sufficiently small, i.e., converged. Note: this should*> always be at least radix*machine epsilon.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum absolute value of a "pivot" in the Sturm*> sequence loop.*> This must be at least max |e(j)**2|*safe_min and at*> least safe_min, where safe_min is at least*> the smallest number that can divide one without overflow.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> The offdiagonal elements of the tridiagonal matrix T in*> positions 1 through N-1. E(N) is arbitrary.*> \endverbatim*>*> \param[in] E2*> \verbatim*> E2 is DOUBLE PRECISION array, dimension (N)*> The squares of the offdiagonal elements of the tridiagonal*> matrix T. E2(N) is ignored.*> \endverbatim*>*> \param[in,out] NVAL*> \verbatim*> NVAL is INTEGER array, dimension (MINP)*> If IJOB=1 or 2, not referenced.*> If IJOB=3, the desired values of N(w). The elements of NVAL*> will be reordered to correspond with the intervals in AB.*> Thus, NVAL(j) on output will not, in general be the same as*> NVAL(j) on input, but it will correspond with the interval*> (AB(j,1),AB(j,2)] on output.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (MMAX,2)*> The endpoints of the intervals. AB(j,1) is a(j), the left*> endpoint of the j-th interval, and AB(j,2) is b(j), the*> right endpoint of the j-th interval. The input intervals*> will, in general, be modified, split, and reordered by the*> calculation.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (MMAX)*> If IJOB=1, ignored.*> If IJOB=2, workspace.*> If IJOB=3, then on input C(j) should be initialized to the*> first search point in the binary search.*> \endverbatim*>*> \param[out] MOUT*> \verbatim*> MOUT is INTEGER*> If IJOB=1, the number of eigenvalues in the intervals.*> If IJOB=2 or 3, the number of intervals output.*> If IJOB=3, MOUT will equal MINP.*> \endverbatim*>*> \param[in,out] NAB*> \verbatim*> NAB is INTEGER array, dimension (MMAX,2)*> If IJOB=1, then on output NAB(i,j) will be set to N(AB(i,j)).*> If IJOB=2, then on input, NAB(i,j) should be set. It must*> satisfy the condition:*> N(AB(i,1)) <= NAB(i,1) <= NAB(i,2) <= N(AB(i,2)),*> which means that in interval i only eigenvalues*> NAB(i,1)+1,...,NAB(i,2) will be considered. Usually,*> NAB(i,j)=N(AB(i,j)), from a previous call to DLAEBZ with*> IJOB=1.*> On output, NAB(i,j) will contain*> max(na(k),min(nb(k),N(AB(i,j)))), where k is the index of*> the input interval that the output interval*> (AB(j,1),AB(j,2)] came from, and na(k) and nb(k) are the*> the input values of NAB(k,1) and NAB(k,2).*> If IJOB=3, then on output, NAB(i,j) contains N(AB(i,j)),*> unless N(w) > NVAL(i) for all search points w , in which*> case NAB(i,1) will not be modified, i.e., the output*> value will be the same as the input value (modulo*> reorderings -- see NVAL and AB), or unless N(w) < NVAL(i)*> for all search points w , in which case NAB(i,2) will*> not be modified. Normally, NAB should be set to some*> distinctive value(s) before DLAEBZ is called.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MMAX)*> Workspace.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MMAX)*> Workspace.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: All intervals converged.*> = 1--MMAX: The last INFO intervals did not converge.*> = MMAX+1: More than MMAX intervals were generated.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> This routine is intended to be called only by other LAPACK*> routines, thus the interface is less user-friendly. It is intended*> for two purposes:*>*> (a) finding eigenvalues. In this case, DLAEBZ should have one or*> more initial intervals set up in AB, and DLAEBZ should be called*> with IJOB=1. This sets up NAB, and also counts the eigenvalues.*> Intervals with no eigenvalues would usually be thrown out at*> this point. Also, if not all the eigenvalues in an interval i*> are desired, NAB(i,1) can be increased or NAB(i,2) decreased.*> For example, set NAB(i,1)=NAB(i,2)-1 to get the largest*> eigenvalue. DLAEBZ is then called with IJOB=2 and MMAX*> no smaller than the value of MOUT returned by the call with*> IJOB=1. After this (IJOB=2) call, eigenvalues NAB(i,1)+1*> through NAB(i,2) are approximately AB(i,1) (or AB(i,2)) to the*> tolerance specified by ABSTOL and RELTOL.*>*> (b) finding an interval (a',b'] containing eigenvalues w(f),...,w(l).*> In this case, start with a Gershgorin interval (a,b). Set up*> AB to contain 2 search intervals, both initially (a,b). One*> NVAL element should contain f-1 and the other should contain l*> , while C should contain a and b, resp. NAB(i,1) should be -1*> and NAB(i,2) should be N+1, to flag an error if the desired*> interval does not lie in (a,b). DLAEBZ is then called with*> IJOB=3. On exit, if w(f-1) < w(f), then one of the intervals --*> j -- will have AB(j,1)=AB(j,2) and NAB(j,1)=NAB(j,2)=f-1, while*> if, to the specified tolerance, w(f-k)=...=w(f+r), k > 0 and r*> >= 0, then the interval will have N(AB(j,1))=NAB(j,1)=f-k and*> N(AB(j,2))=NAB(j,2)=f+r. The cases w(l) < w(l+1) and*> w(l-r)=...=w(l+k) are handled similarly.*> \endverbatim*>* =====================================================================SUBROUTINE DLAEBZ( IJOB, NITMAX, N, MMAX, MINP, NBMIN, ABSTOL,$ RELTOL, PIVMIN, D, E, E2, NVAL, AB, C, MOUT,$ NAB, WORK, IWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IJOB, INFO, MINP, MMAX, MOUT, N, NBMIN, NITMAXDOUBLE PRECISION ABSTOL, PIVMIN, RELTOL* ..* .. Array Arguments ..INTEGER IWORK( * ), NAB( MMAX, * ), NVAL( * )DOUBLE PRECISION AB( MMAX, * ), C( * ), D( * ), E( * ), E2( * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, TWO, HALFPARAMETER ( ZERO = 0.0D0, TWO = 2.0D0,$ HALF = 1.0D0 / TWO )* ..* .. Local Scalars ..INTEGER ITMP1, ITMP2, J, JI, JIT, JP, KF, KFNEW, KL,$ KLNEWDOUBLE PRECISION TMP1, TMP2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Check for Errors*INFO = 0IF( IJOB.LT.1 .OR. IJOB.GT.3 ) THENINFO = -1RETURNEND IF** Initialize NAB*IF( IJOB.EQ.1 ) THEN** Compute the number of eigenvalues in the initial intervals.*MOUT = 0DO 30 JI = 1, MINPDO 20 JP = 1, 2TMP1 = D( 1 ) - AB( JI, JP )IF( ABS( TMP1 ).LT.PIVMIN )$ TMP1 = -PIVMINNAB( JI, JP ) = 0IF( TMP1.LE.ZERO )$ NAB( JI, JP ) = 1*DO 10 J = 2, NTMP1 = D( J ) - E2( J-1 ) / TMP1 - AB( JI, JP )IF( ABS( TMP1 ).LT.PIVMIN )$ TMP1 = -PIVMINIF( TMP1.LE.ZERO )$ NAB( JI, JP ) = NAB( JI, JP ) + 110 CONTINUE20 CONTINUEMOUT = MOUT + NAB( JI, 2 ) - NAB( JI, 1 )30 CONTINUERETURNEND IF** Initialize for loop** KF and KL have the following meaning:* Intervals 1,...,KF-1 have converged.* Intervals KF,...,KL still need to be refined.*KF = 1KL = MINP** If IJOB=2, initialize C.* If IJOB=3, use the user-supplied starting point.*IF( IJOB.EQ.2 ) THENDO 40 JI = 1, MINPC( JI ) = HALF*( AB( JI, 1 )+AB( JI, 2 ) )40 CONTINUEEND IF** Iteration loop*DO 130 JIT = 1, NITMAX** Loop over intervals*IF( KL-KF+1.GE.NBMIN .AND. NBMIN.GT.0 ) THEN** Begin of Parallel Version of the loop*DO 60 JI = KF, KL** Compute N(c), the number of eigenvalues less than c*WORK( JI ) = D( 1 ) - C( JI )IWORK( JI ) = 0IF( WORK( JI ).LE.PIVMIN ) THENIWORK( JI ) = 1WORK( JI ) = MIN( WORK( JI ), -PIVMIN )END IF*DO 50 J = 2, NWORK( JI ) = D( J ) - E2( J-1 ) / WORK( JI ) - C( JI )IF( WORK( JI ).LE.PIVMIN ) THENIWORK( JI ) = IWORK( JI ) + 1WORK( JI ) = MIN( WORK( JI ), -PIVMIN )END IF50 CONTINUE60 CONTINUE*IF( IJOB.LE.2 ) THEN** IJOB=2: Choose all intervals containing eigenvalues.*KLNEW = KLDO 70 JI = KF, KL** Insure that N(w) is monotone*IWORK( JI ) = MIN( NAB( JI, 2 ),$ MAX( NAB( JI, 1 ), IWORK( JI ) ) )** Update the Queue -- add intervals if both halves* contain eigenvalues.*IF( IWORK( JI ).EQ.NAB( JI, 2 ) ) THEN** No eigenvalue in the upper interval:* just use the lower interval.*AB( JI, 2 ) = C( JI )*ELSE IF( IWORK( JI ).EQ.NAB( JI, 1 ) ) THEN** No eigenvalue in the lower interval:* just use the upper interval.*AB( JI, 1 ) = C( JI )ELSEKLNEW = KLNEW + 1IF( KLNEW.LE.MMAX ) THEN** Eigenvalue in both intervals -- add upper to* queue.*AB( KLNEW, 2 ) = AB( JI, 2 )NAB( KLNEW, 2 ) = NAB( JI, 2 )AB( KLNEW, 1 ) = C( JI )NAB( KLNEW, 1 ) = IWORK( JI )AB( JI, 2 ) = C( JI )NAB( JI, 2 ) = IWORK( JI )ELSEINFO = MMAX + 1END IFEND IF70 CONTINUEIF( INFO.NE.0 )$ RETURNKL = KLNEWELSE** IJOB=3: Binary search. Keep only the interval containing* w s.t. N(w) = NVAL*DO 80 JI = KF, KLIF( IWORK( JI ).LE.NVAL( JI ) ) THENAB( JI, 1 ) = C( JI )NAB( JI, 1 ) = IWORK( JI )END IFIF( IWORK( JI ).GE.NVAL( JI ) ) THENAB( JI, 2 ) = C( JI )NAB( JI, 2 ) = IWORK( JI )END IF80 CONTINUEEND IF*ELSE** End of Parallel Version of the loop** Begin of Serial Version of the loop*KLNEW = KLDO 100 JI = KF, KL** Compute N(w), the number of eigenvalues less than w*TMP1 = C( JI )TMP2 = D( 1 ) - TMP1ITMP1 = 0IF( TMP2.LE.PIVMIN ) THENITMP1 = 1TMP2 = MIN( TMP2, -PIVMIN )END IF*DO 90 J = 2, NTMP2 = D( J ) - E2( J-1 ) / TMP2 - TMP1IF( TMP2.LE.PIVMIN ) THENITMP1 = ITMP1 + 1TMP2 = MIN( TMP2, -PIVMIN )END IF90 CONTINUE*IF( IJOB.LE.2 ) THEN** IJOB=2: Choose all intervals containing eigenvalues.** Insure that N(w) is monotone*ITMP1 = MIN( NAB( JI, 2 ),$ MAX( NAB( JI, 1 ), ITMP1 ) )** Update the Queue -- add intervals if both halves* contain eigenvalues.*IF( ITMP1.EQ.NAB( JI, 2 ) ) THEN** No eigenvalue in the upper interval:* just use the lower interval.*AB( JI, 2 ) = TMP1*ELSE IF( ITMP1.EQ.NAB( JI, 1 ) ) THEN** No eigenvalue in the lower interval:* just use the upper interval.*AB( JI, 1 ) = TMP1ELSE IF( KLNEW.LT.MMAX ) THEN** Eigenvalue in both intervals -- add upper to queue.*KLNEW = KLNEW + 1AB( KLNEW, 2 ) = AB( JI, 2 )NAB( KLNEW, 2 ) = NAB( JI, 2 )AB( KLNEW, 1 ) = TMP1NAB( KLNEW, 1 ) = ITMP1AB( JI, 2 ) = TMP1NAB( JI, 2 ) = ITMP1ELSEINFO = MMAX + 1RETURNEND IFELSE** IJOB=3: Binary search. Keep only the interval* containing w s.t. N(w) = NVAL*IF( ITMP1.LE.NVAL( JI ) ) THENAB( JI, 1 ) = TMP1NAB( JI, 1 ) = ITMP1END IFIF( ITMP1.GE.NVAL( JI ) ) THENAB( JI, 2 ) = TMP1NAB( JI, 2 ) = ITMP1END IFEND IF100 CONTINUEKL = KLNEW*END IF** Check for convergence*KFNEW = KFDO 110 JI = KF, KLTMP1 = ABS( AB( JI, 2 )-AB( JI, 1 ) )TMP2 = MAX( ABS( AB( JI, 2 ) ), ABS( AB( JI, 1 ) ) )IF( TMP1.LT.MAX( ABSTOL, PIVMIN, RELTOL*TMP2 ) .OR.$ NAB( JI, 1 ).GE.NAB( JI, 2 ) ) THEN** Converged -- Swap with position KFNEW,* then increment KFNEW*IF( JI.GT.KFNEW ) THENTMP1 = AB( JI, 1 )TMP2 = AB( JI, 2 )ITMP1 = NAB( JI, 1 )ITMP2 = NAB( JI, 2 )AB( JI, 1 ) = AB( KFNEW, 1 )AB( JI, 2 ) = AB( KFNEW, 2 )NAB( JI, 1 ) = NAB( KFNEW, 1 )NAB( JI, 2 ) = NAB( KFNEW, 2 )AB( KFNEW, 1 ) = TMP1AB( KFNEW, 2 ) = TMP2NAB( KFNEW, 1 ) = ITMP1NAB( KFNEW, 2 ) = ITMP2IF( IJOB.EQ.3 ) THENITMP1 = NVAL( JI )NVAL( JI ) = NVAL( KFNEW )NVAL( KFNEW ) = ITMP1END IFEND IFKFNEW = KFNEW + 1END IF110 CONTINUEKF = KFNEW** Choose Midpoints*DO 120 JI = KF, KLC( JI ) = HALF*( AB( JI, 1 )+AB( JI, 2 ) )120 CONTINUE** If no more intervals to refine, quit.*IF( KF.GT.KL )$ GO TO 140130 CONTINUE** Converged*140 CONTINUEINFO = MAX( KL+1-KF, 0 )MOUT = KL*RETURN** End of DLAEBZ*END*> \brief \b DLAED0 used by sstedc. Computes all eigenvalues and corresponding eigenvectors of an unreduced symmetric tridiagonal matrix using the divide and conquer method.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED0 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed0.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed0.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed0.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED0( ICOMPQ, QSIZ, N, D, E, Q, LDQ, QSTORE, LDQS,* WORK, IWORK, INFO )** .. Scalar Arguments ..* INTEGER ICOMPQ, INFO, LDQ, LDQS, N, QSIZ* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION D( * ), E( * ), Q( LDQ, * ), QSTORE( LDQS, * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED0 computes all eigenvalues and corresponding eigenvectors of a*> symmetric tridiagonal matrix using the divide and conquer method.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> = 0: Compute eigenvalues only.*> = 1: Compute eigenvectors of original dense symmetric matrix*> also. On entry, Q contains the orthogonal matrix used*> to reduce the original matrix to tridiagonal form.*> = 2: Compute eigenvalues and eigenvectors of tridiagonal*> matrix.*> \endverbatim*>*> \param[in] QSIZ*> \verbatim*> QSIZ is INTEGER*> The dimension of the orthogonal matrix used to reduce*> the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the main diagonal of the tridiagonal matrix.*> On exit, its eigenvalues.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The off-diagonal elements of the tridiagonal matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> On entry, Q must contain an N-by-N orthogonal matrix.*> If ICOMPQ = 0 Q is not referenced.*> If ICOMPQ = 1 On entry, Q is a subset of the columns of the*> orthogonal matrix used to reduce the full*> matrix to tridiagonal form corresponding to*> the subset of the full matrix which is being*> decomposed at this time.*> If ICOMPQ = 2 On entry, Q will be the identity matrix.*> On exit, Q contains the eigenvectors of the*> tridiagonal matrix.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. If eigenvectors are*> desired, then LDQ >= max(1,N). In any case, LDQ >= 1.*> \endverbatim*>*> \param[out] QSTORE*> \verbatim*> QSTORE is DOUBLE PRECISION array, dimension (LDQS, N)*> Referenced only when ICOMPQ = 1. Used to store parts of*> the eigenvector matrix when the updating matrix multiplies*> take place.*> \endverbatim*>*> \param[in] LDQS*> \verbatim*> LDQS is INTEGER*> The leading dimension of the array QSTORE. If ICOMPQ = 1,*> then LDQS >= max(1,N). In any case, LDQS >= 1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array,*> If ICOMPQ = 0 or 1, the dimension of WORK must be at least*> 1 + 3*N + 2*N*lg N + 3*N**2*> ( lg( N ) = smallest integer k*> such that 2^k >= N )*> If ICOMPQ = 2, the dimension of WORK must be at least*> 4*N + N**2.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array,*> If ICOMPQ = 0 or 1, the dimension of IWORK must be at least*> 6 + 6*N + 5*N*lg N.*> ( lg( N ) = smallest integer k*> such that 2^k >= N )*> If ICOMPQ = 2, the dimension of IWORK must be at least*> 3 + 5*N.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: The algorithm failed to compute an eigenvalue while*> working on the submatrix lying in rows and columns*> INFO/(N+1) through mod(INFO,N+1).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA** =====================================================================SUBROUTINE DLAED0( ICOMPQ, QSIZ, N, D, E, Q, LDQ, QSTORE, LDQS,$ WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER ICOMPQ, INFO, LDQ, LDQS, N, QSIZ* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), E( * ), Q( LDQ, * ), QSTORE( LDQS, * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.D0, ONE = 1.D0, TWO = 2.D0 )* ..* .. Local Scalars ..INTEGER CURLVL, CURPRB, CURR, I, IGIVCL, IGIVNM,$ IGIVPT, INDXQ, IPERM, IPRMPT, IQ, IQPTR, IWREM,$ J, K, LGN, MATSIZ, MSD2, SMLSIZ, SMM1, SPM1,$ SPM2, SUBMAT, SUBPBS, TLVLSDOUBLE PRECISION TEMP* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLAED1, DLAED7, DSTEQR,$ XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ICOMPQ.LT.0 .OR. ICOMPQ.GT.2 ) THENINFO = -1ELSE IF( ( ICOMPQ.EQ.1 ) .AND. ( QSIZ.LT.MAX( 0, N ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDQS.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED0', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*SMLSIZ = ILAENV( 9, 'DLAED0', ' ', 0, 0, 0, 0 )** Determine the size and placement of the submatrices, and save in* the leading elements of IWORK.*IWORK( 1 ) = NSUBPBS = 1TLVLS = 010 CONTINUEIF( IWORK( SUBPBS ).GT.SMLSIZ ) THENDO 20 J = SUBPBS, 1, -1IWORK( 2*J ) = ( IWORK( J )+1 ) / 2IWORK( 2*J-1 ) = IWORK( J ) / 220 CONTINUETLVLS = TLVLS + 1SUBPBS = 2*SUBPBSGO TO 10END IFDO 30 J = 2, SUBPBSIWORK( J ) = IWORK( J ) + IWORK( J-1 )30 CONTINUE** Divide the matrix into SUBPBS submatrices of size at most SMLSIZ+1* using rank-1 modifications (cuts).*SPM1 = SUBPBS - 1DO 40 I = 1, SPM1SUBMAT = IWORK( I ) + 1SMM1 = SUBMAT - 1D( SMM1 ) = D( SMM1 ) - ABS( E( SMM1 ) )D( SUBMAT ) = D( SUBMAT ) - ABS( E( SMM1 ) )40 CONTINUE*INDXQ = 4*N + 3IF( ICOMPQ.NE.2 ) THEN** Set up workspaces for eigenvalues only/accumulate new vectors* routine*TEMP = LOG( DBLE( N ) ) / LOG( TWO )LGN = INT( TEMP )IF( 2**LGN.LT.N )$ LGN = LGN + 1IF( 2**LGN.LT.N )$ LGN = LGN + 1IPRMPT = INDXQ + N + 1IPERM = IPRMPT + N*LGNIQPTR = IPERM + N*LGNIGIVPT = IQPTR + N + 2IGIVCL = IGIVPT + N*LGN*IGIVNM = 1IQ = IGIVNM + 2*N*LGNIWREM = IQ + N**2 + 1** Initialize pointers*DO 50 I = 0, SUBPBSIWORK( IPRMPT+I ) = 1IWORK( IGIVPT+I ) = 150 CONTINUEIWORK( IQPTR ) = 1END IF** Solve each submatrix eigenproblem at the bottom of the divide and* conquer tree.*CURR = 0DO 70 I = 0, SPM1IF( I.EQ.0 ) THENSUBMAT = 1MATSIZ = IWORK( 1 )ELSESUBMAT = IWORK( I ) + 1MATSIZ = IWORK( I+1 ) - IWORK( I )END IFIF( ICOMPQ.EQ.2 ) THENCALL DSTEQR( 'I', MATSIZ, D( SUBMAT ), E( SUBMAT ),$ Q( SUBMAT, SUBMAT ), LDQ, WORK, INFO )IF( INFO.NE.0 )$ GO TO 130ELSECALL DSTEQR( 'I', MATSIZ, D( SUBMAT ), E( SUBMAT ),$ WORK( IQ-1+IWORK( IQPTR+CURR ) ), MATSIZ, WORK,$ INFO )IF( INFO.NE.0 )$ GO TO 130IF( ICOMPQ.EQ.1 ) THENCALL DGEMM( 'N', 'N', QSIZ, MATSIZ, MATSIZ, ONE,$ Q( 1, SUBMAT ), LDQ, WORK( IQ-1+IWORK( IQPTR+$ CURR ) ), MATSIZ, ZERO, QSTORE( 1, SUBMAT ),$ LDQS )END IFIWORK( IQPTR+CURR+1 ) = IWORK( IQPTR+CURR ) + MATSIZ**2CURR = CURR + 1END IFK = 1DO 60 J = SUBMAT, IWORK( I+1 )IWORK( INDXQ+J ) = KK = K + 160 CONTINUE70 CONTINUE** Successively merge eigensystems of adjacent submatrices* into eigensystem for the corresponding larger matrix.** while ( SUBPBS > 1 )*CURLVL = 180 CONTINUEIF( SUBPBS.GT.1 ) THENSPM2 = SUBPBS - 2DO 90 I = 0, SPM2, 2IF( I.EQ.0 ) THENSUBMAT = 1MATSIZ = IWORK( 2 )MSD2 = IWORK( 1 )CURPRB = 0ELSESUBMAT = IWORK( I ) + 1MATSIZ = IWORK( I+2 ) - IWORK( I )MSD2 = MATSIZ / 2CURPRB = CURPRB + 1END IF** Merge lower order eigensystems (of size MSD2 and MATSIZ - MSD2)* into an eigensystem of size MATSIZ.* DLAED1 is used only for the full eigensystem of a tridiagonal* matrix.* DLAED7 handles the cases in which eigenvalues only or eigenvalues* and eigenvectors of a full symmetric matrix (which was reduced to* tridiagonal form) are desired.*IF( ICOMPQ.EQ.2 ) THENCALL DLAED1( MATSIZ, D( SUBMAT ), Q( SUBMAT, SUBMAT ),$ LDQ, IWORK( INDXQ+SUBMAT ),$ E( SUBMAT+MSD2-1 ), MSD2, WORK,$ IWORK( SUBPBS+1 ), INFO )ELSECALL DLAED7( ICOMPQ, MATSIZ, QSIZ, TLVLS, CURLVL, CURPRB,$ D( SUBMAT ), QSTORE( 1, SUBMAT ), LDQS,$ IWORK( INDXQ+SUBMAT ), E( SUBMAT+MSD2-1 ),$ MSD2, WORK( IQ ), IWORK( IQPTR ),$ IWORK( IPRMPT ), IWORK( IPERM ),$ IWORK( IGIVPT ), IWORK( IGIVCL ),$ WORK( IGIVNM ), WORK( IWREM ),$ IWORK( SUBPBS+1 ), INFO )END IFIF( INFO.NE.0 )$ GO TO 130IWORK( I / 2+1 ) = IWORK( I+2 )90 CONTINUESUBPBS = SUBPBS / 2CURLVL = CURLVL + 1GO TO 80END IF** end while** Re-merge the eigenvalues/vectors which were deflated at the final* merge step.*IF( ICOMPQ.EQ.1 ) THENDO 100 I = 1, NJ = IWORK( INDXQ+I )WORK( I ) = D( J )CALL DCOPY( QSIZ, QSTORE( 1, J ), 1, Q( 1, I ), 1 )100 CONTINUECALL DCOPY( N, WORK, 1, D, 1 )ELSE IF( ICOMPQ.EQ.2 ) THENDO 110 I = 1, NJ = IWORK( INDXQ+I )WORK( I ) = D( J )CALL DCOPY( N, Q( 1, J ), 1, WORK( N*I+1 ), 1 )110 CONTINUECALL DCOPY( N, WORK, 1, D, 1 )CALL DLACPY( 'A', N, N, WORK( N+1 ), N, Q, LDQ )ELSEDO 120 I = 1, NJ = IWORK( INDXQ+I )WORK( I ) = D( J )120 CONTINUECALL DCOPY( N, WORK, 1, D, 1 )END IFGO TO 140*130 CONTINUEINFO = SUBMAT*( N+1 ) + SUBMAT + MATSIZ - 1*140 CONTINUERETURN** End of DLAED0*END*> \brief \b DLAED1 used by sstedc. Computes the updated eigensystem of a diagonal matrix after modification by a rank-one symmetric matrix. Used when the original matrix is tridiagonal.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED1 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed1.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed1.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed1.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED1( N, D, Q, LDQ, INDXQ, RHO, CUTPNT, WORK, IWORK,* INFO )** .. Scalar Arguments ..* INTEGER CUTPNT, INFO, LDQ, N* DOUBLE PRECISION RHO* ..* .. Array Arguments ..* INTEGER INDXQ( * ), IWORK( * )* DOUBLE PRECISION D( * ), Q( LDQ, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED1 computes the updated eigensystem of a diagonal*> matrix after modification by a rank-one symmetric matrix. This*> routine is used only for the eigenproblem which requires all*> eigenvalues and eigenvectors of a tridiagonal matrix. DLAED7 handles*> the case in which eigenvalues only or eigenvalues and eigenvectors*> of a full symmetric matrix (which was reduced to tridiagonal form)*> are desired.*>*> T = Q(in) ( D(in) + RHO * Z*Z**T ) Q**T(in) = Q(out) * D(out) * Q**T(out)*>*> where Z = Q**T*u, u is a vector of length N with ones in the*> CUTPNT and CUTPNT + 1 th elements and zeros elsewhere.*>*> The eigenvectors of the original matrix are stored in Q, and the*> eigenvalues are in D. The algorithm consists of three stages:*>*> The first stage consists of deflating the size of the problem*> when there are multiple eigenvalues or if there is a zero in*> the Z vector. For each such occurrence the dimension of the*> secular equation problem is reduced by one. This stage is*> performed by the routine DLAED2.*>*> The second stage consists of calculating the updated*> eigenvalues. This is done by finding the roots of the secular*> equation via the routine DLAED4 (as called by DLAED3).*> This routine also calculates the eigenvectors of the current*> problem.*>*> The final stage consists of computing the updated eigenvectors*> directly using the updated eigenvalues. The eigenvectors for*> the current problem are multiplied with the eigenvectors from*> the overall problem.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the eigenvalues of the rank-1-perturbed matrix.*> On exit, the eigenvalues of the repaired matrix.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, the eigenvectors of the rank-1-perturbed matrix.*> On exit, the eigenvectors of the repaired tridiagonal matrix.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N).*> \endverbatim*>*> \param[in,out] INDXQ*> \verbatim*> INDXQ is INTEGER array, dimension (N)*> On entry, the permutation which separately sorts the two*> subproblems in D into ascending order.*> On exit, the permutation which will reintegrate the*> subproblems back into sorted order,*> i.e. D( INDXQ( I = 1, N ) ) will be in ascending order.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The subdiagonal entry used to create the rank-1 modification.*> \endverbatim*>*> \param[in] CUTPNT*> \verbatim*> CUTPNT is INTEGER*> The location of the last eigenvalue in the leading sub-matrix.*> min(1,N) <= CUTPNT <= N/2.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N + N**2)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (4*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, an eigenvalue did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA \n*> Modified by Francoise Tisseur, University of Tennessee*>* =====================================================================SUBROUTINE DLAED1( N, D, Q, LDQ, INDXQ, RHO, CUTPNT, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER CUTPNT, INFO, LDQ, NDOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER INDXQ( * ), IWORK( * )DOUBLE PRECISION D( * ), Q( LDQ, * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..INTEGER COLTYP, I, IDLMDA, INDX, INDXC, INDXP, IQ2, IS,$ IW, IZ, K, N1, N2, ZPP1* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAED2, DLAED3, DLAMRG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -1ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( MIN( 1, N / 2 ).GT.CUTPNT .OR. ( N / 2 ).LT.CUTPNT ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED1', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** The following values are integer pointers which indicate* the portion of the workspace* used by a particular array in DLAED2 and DLAED3.*IZ = 1IDLMDA = IZ + NIW = IDLMDA + NIQ2 = IW + N*INDX = 1INDXC = INDX + NCOLTYP = INDXC + NINDXP = COLTYP + N*** Form the z-vector which consists of the last row of Q_1 and the* first row of Q_2.*CALL DCOPY( CUTPNT, Q( CUTPNT, 1 ), LDQ, WORK( IZ ), 1 )ZPP1 = CUTPNT + 1CALL DCOPY( N-CUTPNT, Q( ZPP1, ZPP1 ), LDQ, WORK( IZ+CUTPNT ), 1 )** Deflate eigenvalues.*CALL DLAED2( K, N, CUTPNT, D, Q, LDQ, INDXQ, RHO, WORK( IZ ),$ WORK( IDLMDA ), WORK( IW ), WORK( IQ2 ),$ IWORK( INDX ), IWORK( INDXC ), IWORK( INDXP ),$ IWORK( COLTYP ), INFO )*IF( INFO.NE.0 )$ GO TO 20** Solve Secular Equation.*IF( K.NE.0 ) THENIS = ( IWORK( COLTYP )+IWORK( COLTYP+1 ) )*CUTPNT +$ ( IWORK( COLTYP+1 )+IWORK( COLTYP+2 ) )*( N-CUTPNT ) + IQ2CALL DLAED3( K, N, CUTPNT, D, Q, LDQ, RHO, WORK( IDLMDA ),$ WORK( IQ2 ), IWORK( INDXC ), IWORK( COLTYP ),$ WORK( IW ), WORK( IS ), INFO )IF( INFO.NE.0 )$ GO TO 20** Prepare the INDXQ sorting permutation.*N1 = KN2 = N - KCALL DLAMRG( N1, N2, D, 1, -1, INDXQ )ELSEDO 10 I = 1, NINDXQ( I ) = I10 CONTINUEEND IF*20 CONTINUERETURN** End of DLAED1*END*> \brief \b DLAED2 used by sstedc. Merges eigenvalues and deflates secular equation. Used when the original matrix is tridiagonal.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED2( K, N, N1, D, Q, LDQ, INDXQ, RHO, Z, DLAMDA, W,* Q2, INDX, INDXC, INDXP, COLTYP, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDQ, N, N1* DOUBLE PRECISION RHO* ..* .. Array Arguments ..* INTEGER COLTYP( * ), INDX( * ), INDXC( * ), INDXP( * ),* $ INDXQ( * )* DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), Q2( * ),* $ W( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED2 merges the two sets of eigenvalues together into a single*> sorted set. Then it tries to deflate the size of the problem.*> There are two ways in which deflation can occur: when two or more*> eigenvalues are close together or if there is a tiny entry in the*> Z vector. For each such occurrence the order of the related secular*> equation problem is reduced by one.*> \endverbatim** Arguments:* ==========**> \param[out] K*> \verbatim*> K is INTEGER*> The number of non-deflated eigenvalues, and the order of the*> related secular equation. 0 <= K <=N.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> The location of the last eigenvalue in the leading sub-matrix.*> min(1,N) <= N1 <= N/2.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, D contains the eigenvalues of the two submatrices to*> be combined.*> On exit, D contains the trailing (N-K) updated eigenvalues*> (those which were deflated) sorted into increasing order.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> On entry, Q contains the eigenvectors of two submatrices in*> the two square blocks with corners at (1,1), (N1,N1)*> and (N1+1, N1+1), (N,N).*> On exit, Q contains the trailing (N-K) updated eigenvectors*> (those which were deflated) in its last N-K columns.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N).*> \endverbatim*>*> \param[in,out] INDXQ*> \verbatim*> INDXQ is INTEGER array, dimension (N)*> The permutation which separately sorts the two sub-problems*> in D into ascending order. Note that elements in the second*> half of this permutation must first have N1 added to their*> values. Destroyed on exit.*> \endverbatim*>*> \param[in,out] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> On entry, the off-diagonal element associated with the rank-1*> cut which originally split the two submatrices which are now*> being recombined.*> On exit, RHO has been modified to the value required by*> DLAED3.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (N)*> On entry, Z contains the updating vector (the last*> row of the first sub-eigenvector matrix and the first row of*> the second sub-eigenvector matrix).*> On exit, the contents of Z have been destroyed by the updating*> process.*> \endverbatim*>*> \param[out] DLAMDA*> \verbatim*> DLAMDA is DOUBLE PRECISION array, dimension (N)*> A copy of the first K eigenvalues which will be used by*> DLAED3 to form the secular equation.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first k values of the final deflation-altered z-vector*> which will be passed to DLAED3.*> \endverbatim*>*> \param[out] Q2*> \verbatim*> Q2 is DOUBLE PRECISION array, dimension (N1**2+(N-N1)**2)*> A copy of the first K eigenvectors which will be used by*> DLAED3 in a matrix multiply (DGEMM) to solve for the new*> eigenvectors.*> \endverbatim*>*> \param[out] INDX*> \verbatim*> INDX is INTEGER array, dimension (N)*> The permutation used to sort the contents of DLAMDA into*> ascending order.*> \endverbatim*>*> \param[out] INDXC*> \verbatim*> INDXC is INTEGER array, dimension (N)*> The permutation used to arrange the columns of the deflated*> Q matrix into three groups: the first group contains non-zero*> elements only at and above N1, the second contains*> non-zero elements only below N1, and the third is dense.*> \endverbatim*>*> \param[out] INDXP*> \verbatim*> INDXP is INTEGER array, dimension (N)*> The permutation used to place deflated values of D at the end*> of the array. INDXP(1:K) points to the nondeflated D-values*> and INDXP(K+1:N) points to the deflated eigenvalues.*> \endverbatim*>*> \param[out] COLTYP*> \verbatim*> COLTYP is INTEGER array, dimension (N)*> During execution, a label which will indicate which of the*> following types a column in the Q2 matrix is:*> 1 : non-zero in the upper half only;*> 2 : dense;*> 3 : non-zero in the lower half only;*> 4 : deflated.*> On exit, COLTYP(i) is the number of columns of type i,*> for i=1 to 4 only.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA \n*> Modified by Francoise Tisseur, University of Tennessee*>* =====================================================================SUBROUTINE DLAED2( K, N, N1, D, Q, LDQ, INDXQ, RHO, Z, DLAMDA, W,$ Q2, INDX, INDXC, INDXP, COLTYP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDQ, N, N1DOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER COLTYP( * ), INDX( * ), INDXC( * ), INDXP( * ),$ INDXQ( * )DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), Q2( * ),$ W( * ), Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION MONE, ZERO, ONE, TWO, EIGHTPARAMETER ( MONE = -1.0D0, ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, EIGHT = 8.0D0 )* ..* .. Local Arrays ..INTEGER CTOT( 4 ), PSM( 4 )* ..* .. Local Scalars ..INTEGER CT, I, IMAX, IQ1, IQ2, J, JMAX, JS, K2, N1P1,$ N2, NJ, PJDOUBLE PRECISION C, EPS, S, T, TAU, TOL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL IDAMAX, DLAMCH, DLAPY2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAMRG, DROT, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -2ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( MIN( 1, ( N / 2 ) ).GT.N1 .OR. ( N / 2 ).LT.N1 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*N2 = N - N1N1P1 = N1 + 1*IF( RHO.LT.ZERO ) THENCALL DSCAL( N2, MONE, Z( N1P1 ), 1 )END IF** Normalize z so that norm(z) = 1. Since z is the concatenation of* two normalized vectors, norm2(z) = sqrt(2).*T = ONE / SQRT( TWO )CALL DSCAL( N, T, Z, 1 )** RHO = ABS( norm(z)**2 * RHO )*RHO = ABS( TWO*RHO )** Sort the eigenvalues into increasing order*DO 10 I = N1P1, NINDXQ( I ) = INDXQ( I ) + N110 CONTINUE** re-integrate the deflated parts from the last pass*DO 20 I = 1, NDLAMDA( I ) = D( INDXQ( I ) )20 CONTINUECALL DLAMRG( N1, N2, DLAMDA, 1, 1, INDXC )DO 30 I = 1, NINDX( I ) = INDXQ( INDXC( I ) )30 CONTINUE** Calculate the allowable deflation tolerance*IMAX = IDAMAX( N, Z, 1 )JMAX = IDAMAX( N, D, 1 )EPS = DLAMCH( 'Epsilon' )TOL = EIGHT*EPS*MAX( ABS( D( JMAX ) ), ABS( Z( IMAX ) ) )** If the rank-1 modifier is small enough, no more needs to be done* except to reorganize Q so that its columns correspond with the* elements in D.*IF( RHO*ABS( Z( IMAX ) ).LE.TOL ) THENK = 0IQ2 = 1DO 40 J = 1, NI = INDX( J )CALL DCOPY( N, Q( 1, I ), 1, Q2( IQ2 ), 1 )DLAMDA( J ) = D( I )IQ2 = IQ2 + N40 CONTINUECALL DLACPY( 'A', N, N, Q2, N, Q, LDQ )CALL DCOPY( N, DLAMDA, 1, D, 1 )GO TO 190END IF** If there are multiple eigenvalues then the problem deflates. Here* the number of equal eigenvalues are found. As each equal* eigenvalue is found, an elementary reflector is computed to rotate* the corresponding eigensubspace so that the corresponding* components of Z are zero in this new basis.*DO 50 I = 1, N1COLTYP( I ) = 150 CONTINUEDO 60 I = N1P1, NCOLTYP( I ) = 360 CONTINUE**K = 0K2 = N + 1DO 70 J = 1, NNJ = INDX( J )IF( RHO*ABS( Z( NJ ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1COLTYP( NJ ) = 4INDXP( K2 ) = NJIF( J.EQ.N )$ GO TO 100ELSEPJ = NJGO TO 80END IF70 CONTINUE80 CONTINUEJ = J + 1NJ = INDX( J )IF( J.GT.N )$ GO TO 100IF( RHO*ABS( Z( NJ ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1COLTYP( NJ ) = 4INDXP( K2 ) = NJELSE** Check if eigenvalues are close enough to allow deflation.*S = Z( PJ )C = Z( NJ )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.*TAU = DLAPY2( C, S )T = D( NJ ) - D( PJ )C = C / TAUS = -S / TAUIF( ABS( T*C*S ).LE.TOL ) THEN** Deflation is possible.*Z( NJ ) = TAUZ( PJ ) = ZEROIF( COLTYP( NJ ).NE.COLTYP( PJ ) )$ COLTYP( NJ ) = 2COLTYP( PJ ) = 4CALL DROT( N, Q( 1, PJ ), 1, Q( 1, NJ ), 1, C, S )T = D( PJ )*C**2 + D( NJ )*S**2D( NJ ) = D( PJ )*S**2 + D( NJ )*C**2D( PJ ) = TK2 = K2 - 1I = 190 CONTINUEIF( K2+I.LE.N ) THENIF( D( PJ ).LT.D( INDXP( K2+I ) ) ) THENINDXP( K2+I-1 ) = INDXP( K2+I )INDXP( K2+I ) = PJI = I + 1GO TO 90ELSEINDXP( K2+I-1 ) = PJEND IFELSEINDXP( K2+I-1 ) = PJEND IFPJ = NJELSEK = K + 1DLAMDA( K ) = D( PJ )W( K ) = Z( PJ )INDXP( K ) = PJPJ = NJEND IFEND IFGO TO 80100 CONTINUE** Record the last eigenvalue.*K = K + 1DLAMDA( K ) = D( PJ )W( K ) = Z( PJ )INDXP( K ) = PJ** Count up the total number of the various types of columns, then* form a permutation which positions the four column types into* four uniform groups (although one or more of these groups may be* empty).*DO 110 J = 1, 4CTOT( J ) = 0110 CONTINUEDO 120 J = 1, NCT = COLTYP( J )CTOT( CT ) = CTOT( CT ) + 1120 CONTINUE** PSM(*) = Position in SubMatrix (of types 1 through 4)*PSM( 1 ) = 1PSM( 2 ) = 1 + CTOT( 1 )PSM( 3 ) = PSM( 2 ) + CTOT( 2 )PSM( 4 ) = PSM( 3 ) + CTOT( 3 )K = N - CTOT( 4 )** Fill out the INDXC array so that the permutation which it induces* will place all type-1 columns first, all type-2 columns next,* then all type-3's, and finally all type-4's.*DO 130 J = 1, NJS = INDXP( J )CT = COLTYP( JS )INDX( PSM( CT ) ) = JSINDXC( PSM( CT ) ) = JPSM( CT ) = PSM( CT ) + 1130 CONTINUE** Sort the eigenvalues and corresponding eigenvectors into DLAMDA* and Q2 respectively. The eigenvalues/vectors which were not* deflated go into the first K slots of DLAMDA and Q2 respectively,* while those which were deflated go into the last N - K slots.*I = 1IQ1 = 1IQ2 = 1 + ( CTOT( 1 )+CTOT( 2 ) )*N1DO 140 J = 1, CTOT( 1 )JS = INDX( I )CALL DCOPY( N1, Q( 1, JS ), 1, Q2( IQ1 ), 1 )Z( I ) = D( JS )I = I + 1IQ1 = IQ1 + N1140 CONTINUE*DO 150 J = 1, CTOT( 2 )JS = INDX( I )CALL DCOPY( N1, Q( 1, JS ), 1, Q2( IQ1 ), 1 )CALL DCOPY( N2, Q( N1+1, JS ), 1, Q2( IQ2 ), 1 )Z( I ) = D( JS )I = I + 1IQ1 = IQ1 + N1IQ2 = IQ2 + N2150 CONTINUE*DO 160 J = 1, CTOT( 3 )JS = INDX( I )CALL DCOPY( N2, Q( N1+1, JS ), 1, Q2( IQ2 ), 1 )Z( I ) = D( JS )I = I + 1IQ2 = IQ2 + N2160 CONTINUE*IQ1 = IQ2DO 170 J = 1, CTOT( 4 )JS = INDX( I )CALL DCOPY( N, Q( 1, JS ), 1, Q2( IQ2 ), 1 )IQ2 = IQ2 + NZ( I ) = D( JS )I = I + 1170 CONTINUE** The deflated eigenvalues and their corresponding vectors go back* into the last N - K slots of D and Q respectively.*IF( K.LT.N ) THENCALL DLACPY( 'A', N, CTOT( 4 ), Q2( IQ1 ), N,$ Q( 1, K+1 ), LDQ )CALL DCOPY( N-K, Z( K+1 ), 1, D( K+1 ), 1 )END IF** Copy CTOT into COLTYP for referencing in DLAED3.*DO 180 J = 1, 4COLTYP( J ) = CTOT( J )180 CONTINUE*190 CONTINUERETURN** End of DLAED2*END*> \brief \b DLAED3 used by sstedc. Finds the roots of the secular equation and updates the eigenvectors. Used when the original matrix is tridiagonal.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED3( K, N, N1, D, Q, LDQ, RHO, DLAMDA, Q2, INDX,* CTOT, W, S, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDQ, N, N1* DOUBLE PRECISION RHO* ..* .. Array Arguments ..* INTEGER CTOT( * ), INDX( * )* DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), Q2( * ),* $ S( * ), W( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED3 finds the roots of the secular equation, as defined by the*> values in D, W, and RHO, between 1 and K. It makes the*> appropriate calls to DLAED4 and then updates the eigenvectors by*> multiplying the matrix of eigenvectors of the pair of eigensystems*> being combined by the matrix of eigenvectors of the K-by-K system*> which is solved here.*>*> This code makes very mild assumptions about floating point*> arithmetic. It will work on machines with a guard digit in*> add/subtract, or on those binary machines without guard digits*> which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.*> It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] K*> \verbatim*> K is INTEGER*> The number of terms in the rational function to be solved by*> DLAED4. K >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows and columns in the Q matrix.*> N >= K (deflation may result in N>K).*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> The location of the last eigenvalue in the leading submatrix.*> min(1,N) <= N1 <= N/2.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> D(I) contains the updated eigenvalues for*> 1 <= I <= K.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> Initially the first K columns are used as workspace.*> On output the columns 1 to K contain*> the updated eigenvectors.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N).*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The value of the parameter in the rank one update equation.*> RHO >= 0 required.*> \endverbatim*>*> \param[in,out] DLAMDA*> \verbatim*> DLAMDA is DOUBLE PRECISION array, dimension (K)*> The first K elements of this array contain the old roots*> of the deflated updating problem. These are the poles*> of the secular equation. May be changed on output by*> having lowest order bit set to zero on Cray X-MP, Cray Y-MP,*> Cray-2, or Cray C-90, as described above.*> \endverbatim*>*> \param[in] Q2*> \verbatim*> Q2 is DOUBLE PRECISION array, dimension (LDQ2*N)*> The first K columns of this matrix contain the non-deflated*> eigenvectors for the split problem.*> \endverbatim*>*> \param[in] INDX*> \verbatim*> INDX is INTEGER array, dimension (N)*> The permutation used to arrange the columns of the deflated*> Q matrix into three groups (see DLAED2).*> The rows of the eigenvectors found by DLAED4 must be likewise*> permuted before the matrix multiply can take place.*> \endverbatim*>*> \param[in] CTOT*> \verbatim*> CTOT is INTEGER array, dimension (4)*> A count of the total number of the various types of columns*> in Q, as described in INDX. The fourth column type is any*> column which has been deflated.*> \endverbatim*>*> \param[in,out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (K)*> The first K elements of this array contain the components*> of the deflation-adjusted updating vector. Destroyed on*> output.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N1 + 1)*K*> Will contain the eigenvectors of the repaired matrix which*> will be multiplied by the previously accumulated eigenvectors*> to update the system.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, an eigenvalue did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA \n*> Modified by Francoise Tisseur, University of Tennessee*>* =====================================================================SUBROUTINE DLAED3( K, N, N1, D, Q, LDQ, RHO, DLAMDA, Q2, INDX,$ CTOT, W, S, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, K, LDQ, N, N1DOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER CTOT( * ), INDX( * )DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), Q2( * ),$ S( * ), W( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER I, II, IQ2, J, N12, N2, N23DOUBLE PRECISION TEMP* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLAED4, DLASET, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( K.LT.0 ) THENINFO = -1ELSE IF( N.LT.K ) THENINFO = -2ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED3', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.0 )$ RETURN** Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can* be computed with high relative accuracy (barring over/underflow).* This is a problem on machines without a guard digit in* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).* The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I),* which on any of these machines zeros out the bottommost* bit of DLAMDA(I) if it is 1; this makes the subsequent* subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation* occurs. On binary machines with a guard digit (almost all* machines) it does not change DLAMDA(I) at all. On hexadecimal* and decimal machines with a guard digit, it slightly* changes the bottommost bits of DLAMDA(I). It does not account* for hexadecimal or decimal machines without guard digits* (we know of none). We use a subroutine call to compute* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating* this code.*DO 10 I = 1, KDLAMDA( I ) = DLAMC3( DLAMDA( I ), DLAMDA( I ) ) - DLAMDA( I )10 CONTINUE*DO 20 J = 1, KCALL DLAED4( K, J, DLAMDA, W, Q( 1, J ), RHO, D( J ), INFO )** If the zero finder fails, the computation is terminated.*IF( INFO.NE.0 )$ GO TO 12020 CONTINUE*IF( K.EQ.1 )$ GO TO 110IF( K.EQ.2 ) THENDO 30 J = 1, KW( 1 ) = Q( 1, J )W( 2 ) = Q( 2, J )II = INDX( 1 )Q( 1, J ) = W( II )II = INDX( 2 )Q( 2, J ) = W( II )30 CONTINUEGO TO 110END IF** Compute updated W.*CALL DCOPY( K, W, 1, S, 1 )** Initialize W(I) = Q(I,I)*CALL DCOPY( K, Q, LDQ+1, W, 1 )DO 60 J = 1, KDO 40 I = 1, J - 1W( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )40 CONTINUEDO 50 I = J + 1, KW( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )50 CONTINUE60 CONTINUEDO 70 I = 1, KW( I ) = SIGN( SQRT( -W( I ) ), S( I ) )70 CONTINUE** Compute eigenvectors of the modified rank-1 modification.*DO 100 J = 1, KDO 80 I = 1, KS( I ) = W( I ) / Q( I, J )80 CONTINUETEMP = DNRM2( K, S, 1 )DO 90 I = 1, KII = INDX( I )Q( I, J ) = S( II ) / TEMP90 CONTINUE100 CONTINUE** Compute the updated eigenvectors.*110 CONTINUE*N2 = N - N1N12 = CTOT( 1 ) + CTOT( 2 )N23 = CTOT( 2 ) + CTOT( 3 )*CALL DLACPY( 'A', N23, K, Q( CTOT( 1 )+1, 1 ), LDQ, S, N23 )IQ2 = N1*N12 + 1IF( N23.NE.0 ) THENCALL DGEMM( 'N', 'N', N2, K, N23, ONE, Q2( IQ2 ), N2, S, N23,$ ZERO, Q( N1+1, 1 ), LDQ )ELSECALL DLASET( 'A', N2, K, ZERO, ZERO, Q( N1+1, 1 ), LDQ )END IF*CALL DLACPY( 'A', N12, K, Q, LDQ, S, N12 )IF( N12.NE.0 ) THENCALL DGEMM( 'N', 'N', N1, K, N12, ONE, Q2, N1, S, N12, ZERO, Q,$ LDQ )ELSECALL DLASET( 'A', N1, K, ZERO, ZERO, Q( 1, 1 ), LDQ )END IF**120 CONTINUERETURN** End of DLAED3*END*> \brief \b DLAED4 used by sstedc. Finds a single root of the secular equation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED4 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed4.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed4.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed4.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED4( N, I, D, Z, DELTA, RHO, DLAM, INFO )** .. Scalar Arguments ..* INTEGER I, INFO, N* DOUBLE PRECISION DLAM, RHO* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), DELTA( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine computes the I-th updated eigenvalue of a symmetric*> rank-one modification to a diagonal matrix whose elements are*> given in the array d, and that*>*> D(i) < D(j) for i < j*>*> and that RHO > 0. This is arranged by the calling routine, and is*> no loss in generality. The rank-one modified system is thus*>*> diag( D ) + RHO * Z * Z_transpose.*>*> where we assume the Euclidean norm of Z is 1.*>*> The method consists of approximating the rational functions in the*> secular equation by simpler interpolating rational functions.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The length of all arrays.*> \endverbatim*>*> \param[in] I*> \verbatim*> I is INTEGER*> The index of the eigenvalue to be computed. 1 <= I <= N.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The original eigenvalues. It is assumed that they are in*> order, D(I) < D(J) for I < J.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (N)*> The components of the updating vector.*> \endverbatim*>*> \param[out] DELTA*> \verbatim*> DELTA is DOUBLE PRECISION array, dimension (N)*> If N .GT. 2, DELTA contains (D(j) - lambda_I) in its j-th*> component. If N = 1, then DELTA(1) = 1. If N = 2, see DLAED5*> for detail. The vector DELTA contains the information necessary*> to construct the eigenvectors by DLAED3 and DLAED9.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The scalar in the symmetric updating formula.*> \endverbatim*>*> \param[out] DLAM*> \verbatim*> DLAM is DOUBLE PRECISION*> The computed lambda_I, the I-th updated eigenvalue.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> > 0: if INFO = 1, the updating process failed.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> Logical variable ORGATI (origin-at-i?) is used for distinguishing*> whether D(i) or D(i+1) is treated as the origin.*>*> ORGATI = .true. origin at i*> ORGATI = .false. origin at i+1*>*> Logical variable SWTCH3 (switch-for-3-poles?) is for noting*> if we are working with THREE poles!*>*> MAXIT is the maximum number of iterations allowed for each*> eigenvalue.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Ren-Cang Li, Computer Science Division, University of California*> at Berkeley, USA*>* =====================================================================SUBROUTINE DLAED4( N, I, D, Z, DELTA, RHO, DLAM, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER I, INFO, NDOUBLE PRECISION DLAM, RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DELTA( * ), Z( * )* ..** =====================================================================** .. Parameters ..INTEGER MAXITPARAMETER ( MAXIT = 30 )DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHT, TENPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0,$ TEN = 10.0D0 )* ..* .. Local Scalars ..LOGICAL ORGATI, SWTCH, SWTCH3INTEGER II, IIM1, IIP1, IP1, ITER, J, NITERDOUBLE PRECISION A, B, C, DEL, DLTLB, DLTUB, DPHI, DPSI, DW,$ EPS, ERRETM, ETA, MIDPT, PHI, PREW, PSI,$ RHOINV, TAU, TEMP, TEMP1, W* ..* .. Local Arrays ..DOUBLE PRECISION ZZ( 3 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DLAED5, DLAED6* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Since this routine is called in an inner loop, we do no argument* checking.** Quick return for N=1 and 2.*INFO = 0IF( N.EQ.1 ) THEN** Presumably, I=1 upon entry*DLAM = D( 1 ) + RHO*Z( 1 )*Z( 1 )DELTA( 1 ) = ONERETURNEND IFIF( N.EQ.2 ) THENCALL DLAED5( I, D, Z, DELTA, RHO, DLAM )RETURNEND IF** Compute machine epsilon*EPS = DLAMCH( 'Epsilon' )RHOINV = ONE / RHO** The case I = N*IF( I.EQ.N ) THEN** Initialize some basic variables*II = N - 1NITER = 1** Calculate initial guess*MIDPT = RHO / TWO** If ||Z||_2 is not one, then TEMP should be set to* RHO * ||Z||_2^2 / TWO*DO 10 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - MIDPT10 CONTINUE*PSI = ZERODO 20 J = 1, N - 2PSI = PSI + Z( J )*Z( J ) / DELTA( J )20 CONTINUE*C = RHOINV + PSIW = C + Z( II )*Z( II ) / DELTA( II ) +$ Z( N )*Z( N ) / DELTA( N )*IF( W.LE.ZERO ) THENTEMP = Z( N-1 )*Z( N-1 ) / ( D( N )-D( N-1 )+RHO ) +$ Z( N )*Z( N ) / RHOIF( C.LE.TEMP ) THENTAU = RHOELSEDEL = D( N ) - D( N-1 )A = -C*DEL + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )B = Z( N )*Z( N )*DELIF( A.LT.ZERO ) THENTAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )ELSETAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )END IFEND IF** It can be proved that* D(N)+RHO/2 <= LAMBDA(N) < D(N)+TAU <= D(N)+RHO*DLTLB = MIDPTDLTUB = RHOELSEDEL = D( N ) - D( N-1 )A = -C*DEL + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )B = Z( N )*Z( N )*DELIF( A.LT.ZERO ) THENTAU = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )ELSETAU = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )END IF** It can be proved that* D(N) < D(N)+TAU < LAMBDA(N) < D(N)+RHO/2*DLTLB = ZERODLTUB = MIDPTEND IF*DO 30 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - TAU30 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 40 J = 1, IITEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI40 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / DELTA( N )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +$ ABS( TAU )*( DPSI+DPHI )*W = RHOINV + PHI + PSI** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENDLAM = D( I ) + TAUGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*NITER = NITER + 1C = W - DELTA( N-1 )*DPSI - DELTA( N )*DPHIA = ( DELTA( N-1 )+DELTA( N ) )*W -$ DELTA( N-1 )*DELTA( N )*( DPSI+DPHI )B = DELTA( N-1 )*DELTA( N )*WIF( C.LT.ZERO )$ C = ABS( C )IF( C.EQ.ZERO ) THEN* ETA = B/A* ETA = RHO - TAUETA = DLTUB - TAUELSE IF( A.GE.ZERO ) THENETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GT.ZERO )$ ETA = -W / ( DPSI+DPHI )TEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IFDO 50 J = 1, NDELTA( J ) = DELTA( J ) - ETA50 CONTINUE*TAU = TAU + ETA** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 60 J = 1, IITEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI60 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / DELTA( N )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +$ ABS( TAU )*( DPSI+DPHI )*W = RHOINV + PHI + PSI** Main loop to update the values of the array DELTA*ITER = NITER + 1*DO 90 NITER = ITER, MAXIT** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENDLAM = D( I ) + TAUGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*C = W - DELTA( N-1 )*DPSI - DELTA( N )*DPHIA = ( DELTA( N-1 )+DELTA( N ) )*W -$ DELTA( N-1 )*DELTA( N )*( DPSI+DPHI )B = DELTA( N-1 )*DELTA( N )*WIF( A.GE.ZERO ) THENETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GT.ZERO )$ ETA = -W / ( DPSI+DPHI )TEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IFDO 70 J = 1, NDELTA( J ) = DELTA( J ) - ETA70 CONTINUE*TAU = TAU + ETA** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 80 J = 1, IITEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI80 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / DELTA( N )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV +$ ABS( TAU )*( DPSI+DPHI )*W = RHOINV + PHI + PSI90 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged*INFO = 1DLAM = D( I ) + TAUGO TO 250** End for the case I = N*ELSE** The case for I < N*NITER = 1IP1 = I + 1** Calculate initial guess*DEL = D( IP1 ) - D( I )MIDPT = DEL / TWODO 100 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - MIDPT100 CONTINUE*PSI = ZERODO 110 J = 1, I - 1PSI = PSI + Z( J )*Z( J ) / DELTA( J )110 CONTINUE*PHI = ZERODO 120 J = N, I + 2, -1PHI = PHI + Z( J )*Z( J ) / DELTA( J )120 CONTINUEC = RHOINV + PSI + PHIW = C + Z( I )*Z( I ) / DELTA( I ) +$ Z( IP1 )*Z( IP1 ) / DELTA( IP1 )*IF( W.GT.ZERO ) THEN** d(i)< the ith eigenvalue < (d(i)+d(i+1))/2** We choose d(i) as origin.*ORGATI = .TRUE.A = C*DEL + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )B = Z( I )*Z( I )*DELIF( A.GT.ZERO ) THENTAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )ELSETAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )END IFDLTLB = ZERODLTUB = MIDPTELSE** (d(i)+d(i+1))/2 <= the ith eigenvalue < d(i+1)** We choose d(i+1) as origin.*ORGATI = .FALSE.A = C*DEL - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )B = Z( IP1 )*Z( IP1 )*DELIF( A.LT.ZERO ) THENTAU = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )ELSETAU = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )END IFDLTLB = -MIDPTDLTUB = ZEROEND IF*IF( ORGATI ) THENDO 130 J = 1, NDELTA( J ) = ( D( J )-D( I ) ) - TAU130 CONTINUEELSEDO 140 J = 1, NDELTA( J ) = ( D( J )-D( IP1 ) ) - TAU140 CONTINUEEND IFIF( ORGATI ) THENII = IELSEII = I + 1END IFIIM1 = II - 1IIP1 = II + 1** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 150 J = 1, IIM1TEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI150 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 160 J = N, IIP1, -1TEMP = Z( J ) / DELTA( J )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI160 CONTINUE*W = RHOINV + PHI + PSI** W is the value of the secular function with* its ii-th element removed.*SWTCH3 = .FALSE.IF( ORGATI ) THENIF( W.LT.ZERO )$ SWTCH3 = .TRUE.ELSEIF( W.GT.ZERO )$ SWTCH3 = .TRUE.END IFIF( II.EQ.1 .OR. II.EQ.N )$ SWTCH3 = .FALSE.*TEMP = Z( II ) / DELTA( II )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = W + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +$ THREE*ABS( TEMP ) + ABS( TAU )*DW** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENIF( ORGATI ) THENDLAM = D( I ) + TAUELSEDLAM = D( IP1 ) + TAUEND IFGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*NITER = NITER + 1IF( .NOT.SWTCH3 ) THENIF( ORGATI ) THENC = W - DELTA( IP1 )*DW - ( D( I )-D( IP1 ) )*$ ( Z( I ) / DELTA( I ) )**2ELSEC = W - DELTA( I )*DW - ( D( IP1 )-D( I ) )*$ ( Z( IP1 ) / DELTA( IP1 ) )**2END IFA = ( DELTA( I )+DELTA( IP1 ) )*W -$ DELTA( I )*DELTA( IP1 )*DWB = DELTA( I )*DELTA( IP1 )*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DELTA( IP1 )*DELTA( IP1 )*$ ( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) + DELTA( I )*DELTA( I )*$ ( DPSI+DPHI )END IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFELSE** Interpolation using THREE most relevant poles*TEMP = RHOINV + PSI + PHIIF( ORGATI ) THENTEMP1 = Z( IIM1 ) / DELTA( IIM1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIP1 )*( DPSI+DPHI ) -$ ( D( IIM1 )-D( IIP1 ) )*TEMP1ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )ZZ( 3 ) = DELTA( IIP1 )*DELTA( IIP1 )*$ ( ( DPSI-TEMP1 )+DPHI )ELSETEMP1 = Z( IIP1 ) / DELTA( IIP1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIM1 )*( DPSI+DPHI ) -$ ( D( IIP1 )-D( IIM1 ) )*TEMP1ZZ( 1 ) = DELTA( IIM1 )*DELTA( IIM1 )*$ ( DPSI+( DPHI-TEMP1 ) )ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )END IFZZ( 2 ) = Z( II )*Z( II )CALL DLAED6( NITER, ORGATI, C, DELTA( IIM1 ), ZZ, W, ETA,$ INFO )IF( INFO.NE.0 )$ GO TO 250END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GE.ZERO )$ ETA = -W / DWTEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IF*PREW = W*DO 180 J = 1, NDELTA( J ) = DELTA( J ) - ETA180 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 190 J = 1, IIM1TEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI190 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 200 J = N, IIP1, -1TEMP = Z( J ) / DELTA( J )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI200 CONTINUE*TEMP = Z( II ) / DELTA( II )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = RHOINV + PHI + PSI + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +$ THREE*ABS( TEMP ) + ABS( TAU+ETA )*DW*SWTCH = .FALSE.IF( ORGATI ) THENIF( -W.GT.ABS( PREW ) / TEN )$ SWTCH = .TRUE.ELSEIF( W.GT.ABS( PREW ) / TEN )$ SWTCH = .TRUE.END IF*TAU = TAU + ETA** Main loop to update the values of the array DELTA*ITER = NITER + 1*DO 240 NITER = ITER, MAXIT** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENIF( ORGATI ) THENDLAM = D( I ) + TAUELSEDLAM = D( IP1 ) + TAUEND IFGO TO 250END IF*IF( W.LE.ZERO ) THENDLTLB = MAX( DLTLB, TAU )ELSEDLTUB = MIN( DLTUB, TAU )END IF** Calculate the new step*IF( .NOT.SWTCH3 ) THENIF( .NOT.SWTCH ) THENIF( ORGATI ) THENC = W - DELTA( IP1 )*DW -$ ( D( I )-D( IP1 ) )*( Z( I ) / DELTA( I ) )**2ELSEC = W - DELTA( I )*DW - ( D( IP1 )-D( I ) )*$ ( Z( IP1 ) / DELTA( IP1 ) )**2END IFELSETEMP = Z( II ) / DELTA( II )IF( ORGATI ) THENDPSI = DPSI + TEMP*TEMPELSEDPHI = DPHI + TEMP*TEMPEND IFC = W - DELTA( I )*DPSI - DELTA( IP1 )*DPHIEND IFA = ( DELTA( I )+DELTA( IP1 ) )*W -$ DELTA( I )*DELTA( IP1 )*DWB = DELTA( I )*DELTA( IP1 )*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( .NOT.SWTCH ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DELTA( IP1 )*$ DELTA( IP1 )*( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) +$ DELTA( I )*DELTA( I )*( DPSI+DPHI )END IFELSEA = DELTA( I )*DELTA( I )*DPSI +$ DELTA( IP1 )*DELTA( IP1 )*DPHIEND IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFELSE** Interpolation using THREE most relevant poles*TEMP = RHOINV + PSI + PHIIF( SWTCH ) THENC = TEMP - DELTA( IIM1 )*DPSI - DELTA( IIP1 )*DPHIZZ( 1 ) = DELTA( IIM1 )*DELTA( IIM1 )*DPSIZZ( 3 ) = DELTA( IIP1 )*DELTA( IIP1 )*DPHIELSEIF( ORGATI ) THENTEMP1 = Z( IIM1 ) / DELTA( IIM1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIP1 )*( DPSI+DPHI ) -$ ( D( IIM1 )-D( IIP1 ) )*TEMP1ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )ZZ( 3 ) = DELTA( IIP1 )*DELTA( IIP1 )*$ ( ( DPSI-TEMP1 )+DPHI )ELSETEMP1 = Z( IIP1 ) / DELTA( IIP1 )TEMP1 = TEMP1*TEMP1C = TEMP - DELTA( IIM1 )*( DPSI+DPHI ) -$ ( D( IIP1 )-D( IIM1 ) )*TEMP1ZZ( 1 ) = DELTA( IIM1 )*DELTA( IIM1 )*$ ( DPSI+( DPHI-TEMP1 ) )ZZ( 3 ) = Z( IIP1 )*Z( IIP1 )END IFEND IFCALL DLAED6( NITER, ORGATI, C, DELTA( IIM1 ), ZZ, W, ETA,$ INFO )IF( INFO.NE.0 )$ GO TO 250END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GE.ZERO )$ ETA = -W / DWTEMP = TAU + ETAIF( TEMP.GT.DLTUB .OR. TEMP.LT.DLTLB ) THENIF( W.LT.ZERO ) THENETA = ( DLTUB-TAU ) / TWOELSEETA = ( DLTLB-TAU ) / TWOEND IFEND IF*DO 210 J = 1, NDELTA( J ) = DELTA( J ) - ETA210 CONTINUE*TAU = TAU + ETAPREW = W** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 220 J = 1, IIM1TEMP = Z( J ) / DELTA( J )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI220 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 230 J = N, IIP1, -1TEMP = Z( J ) / DELTA( J )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI230 CONTINUE*TEMP = Z( II ) / DELTA( II )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = RHOINV + PHI + PSI + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV +$ THREE*ABS( TEMP ) + ABS( TAU )*DWIF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )$ SWTCH = .NOT.SWTCH*240 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged*INFO = 1IF( ORGATI ) THENDLAM = D( I ) + TAUELSEDLAM = D( IP1 ) + TAUEND IF*END IF*250 CONTINUE*RETURN** End of DLAED4*END*> \brief \b DLAED5 used by sstedc. Solves the 2-by-2 secular equation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED5 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed5.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed5.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed5.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED5( I, D, Z, DELTA, RHO, DLAM )** .. Scalar Arguments ..* INTEGER I* DOUBLE PRECISION DLAM, RHO* ..* .. Array Arguments ..* DOUBLE PRECISION D( 2 ), DELTA( 2 ), Z( 2 )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine computes the I-th eigenvalue of a symmetric rank-one*> modification of a 2-by-2 diagonal matrix*>*> diag( D ) + RHO * Z * transpose(Z) .*>*> The diagonal elements in the array D are assumed to satisfy*>*> D(i) < D(j) for i < j .*>*> We also assume RHO > 0 and that the Euclidean norm of the vector*> Z is one.*> \endverbatim** Arguments:* ==========**> \param[in] I*> \verbatim*> I is INTEGER*> The index of the eigenvalue to be computed. I = 1 or I = 2.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (2)*> The original eigenvalues. We assume D(1) < D(2).*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (2)*> The components of the updating vector.*> \endverbatim*>*> \param[out] DELTA*> \verbatim*> DELTA is DOUBLE PRECISION array, dimension (2)*> The vector DELTA contains the information necessary*> to construct the eigenvectors.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The scalar in the symmetric updating formula.*> \endverbatim*>*> \param[out] DLAM*> \verbatim*> DLAM is DOUBLE PRECISION*> The computed lambda_I, the I-th updated eigenvalue.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Ren-Cang Li, Computer Science Division, University of California*> at Berkeley, USA*>* =====================================================================SUBROUTINE DLAED5( I, D, Z, DELTA, RHO, DLAM )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IDOUBLE PRECISION DLAM, RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( 2 ), DELTA( 2 ), Z( 2 )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, FOURPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ FOUR = 4.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION B, C, DEL, TAU, TEMP, W* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*DEL = D( 2 ) - D( 1 )IF( I.EQ.1 ) THENW = ONE + TWO*RHO*( Z( 2 )*Z( 2 )-Z( 1 )*Z( 1 ) ) / DELIF( W.GT.ZERO ) THENB = DEL + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 1 )*Z( 1 )*DEL** B > ZERO, always*TAU = TWO*C / ( B+SQRT( ABS( B*B-FOUR*C ) ) )DLAM = D( 1 ) + TAUDELTA( 1 ) = -Z( 1 ) / TAUDELTA( 2 ) = Z( 2 ) / ( DEL-TAU )ELSEB = -DEL + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 2 )*Z( 2 )*DELIF( B.GT.ZERO ) THENTAU = -TWO*C / ( B+SQRT( B*B+FOUR*C ) )ELSETAU = ( B-SQRT( B*B+FOUR*C ) ) / TWOEND IFDLAM = D( 2 ) + TAUDELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )DELTA( 2 ) = -Z( 2 ) / TAUEND IFTEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )DELTA( 1 ) = DELTA( 1 ) / TEMPDELTA( 2 ) = DELTA( 2 ) / TEMPELSE** Now I=2*B = -DEL + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 2 )*Z( 2 )*DELIF( B.GT.ZERO ) THENTAU = ( B+SQRT( B*B+FOUR*C ) ) / TWOELSETAU = TWO*C / ( -B+SQRT( B*B+FOUR*C ) )END IFDLAM = D( 2 ) + TAUDELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )DELTA( 2 ) = -Z( 2 ) / TAUTEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )DELTA( 1 ) = DELTA( 1 ) / TEMPDELTA( 2 ) = DELTA( 2 ) / TEMPEND IFRETURN** End OF DLAED5*END*> \brief \b DLAED6 used by sstedc. Computes one Newton step in solution of the secular equation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED6 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed6.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed6.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed6.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )** .. Scalar Arguments ..* LOGICAL ORGATI* INTEGER INFO, KNITER* DOUBLE PRECISION FINIT, RHO, TAU* ..* .. Array Arguments ..* DOUBLE PRECISION D( 3 ), Z( 3 )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED6 computes the positive or negative root (closest to the origin)*> of*> z(1) z(2) z(3)*> f(x) = rho + --------- + ---------- + ---------*> d(1)-x d(2)-x d(3)-x*>*> It is assumed that*>*> if ORGATI = .true. the root is between d(2) and d(3);*> otherwise it is between d(1) and d(2)*>*> This routine will be called by DLAED4 when necessary. In most cases,*> the root sought is the smallest in magnitude, though it might not be*> in some extremely rare situations.*> \endverbatim** Arguments:* ==========**> \param[in] KNITER*> \verbatim*> KNITER is INTEGER*> Refer to DLAED4 for its significance.*> \endverbatim*>*> \param[in] ORGATI*> \verbatim*> ORGATI is LOGICAL*> If ORGATI is true, the needed root is between d(2) and*> d(3); otherwise it is between d(1) and d(2). See*> DLAED4 for further details.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> Refer to the equation f(x) above.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (3)*> D satisfies d(1) < d(2) < d(3).*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (3)*> Each of the elements in z must be positive.*> \endverbatim*>*> \param[in] FINIT*> \verbatim*> FINIT is DOUBLE PRECISION*> The value of f at 0. It is more accurate than the one*> evaluated inside this routine (if someone wants to do*> so).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The root of the equation f(x).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> > 0: if INFO = 1, failure to converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> 10/02/03: This version has a few statements commented out for thread*> safety (machine parameters are computed on each entry). SJH.*>*> 05/10/06: Modified from a new version of Ren-Cang Li, use*> Gragg-Thornton-Warner cubic convergent scheme for better stability.*> \endverbatim**> \par Contributors:* ==================*>*> Ren-Cang Li, Computer Science Division, University of California*> at Berkeley, USA*>* =====================================================================SUBROUTINE DLAED6( KNITER, ORGATI, RHO, D, Z, FINIT, TAU, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL ORGATIINTEGER INFO, KNITERDOUBLE PRECISION FINIT, RHO, TAU* ..* .. Array Arguments ..DOUBLE PRECISION D( 3 ), Z( 3 )* ..** =====================================================================** .. Parameters ..INTEGER MAXITPARAMETER ( MAXIT = 40 )DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHTPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0, FOUR = 4.0D0, EIGHT = 8.0D0 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Local Arrays ..DOUBLE PRECISION DSCALE( 3 ), ZSCALE( 3 )* ..* .. Local Scalars ..LOGICAL SCALEINTEGER I, ITER, NITERDOUBLE PRECISION A, B, BASE, C, DDF, DF, EPS, ERRETM, ETA, F,$ FC, SCLFAC, SCLINV, SMALL1, SMALL2, SMINV1,$ SMINV2, TEMP, TEMP1, TEMP2, TEMP3, TEMP4,$ LBD, UBD* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT* ..* .. Executable Statements ..*INFO = 0*IF( ORGATI ) THENLBD = D(2)UBD = D(3)ELSELBD = D(1)UBD = D(2)END IFIF( FINIT .LT. ZERO )THENLBD = ZEROELSEUBD = ZEROEND IF*NITER = 1TAU = ZEROIF( KNITER.EQ.2 ) THENIF( ORGATI ) THENTEMP = ( D( 3 )-D( 2 ) ) / TWOC = RHO + Z( 1 ) / ( ( D( 1 )-D( 2 ) )-TEMP )A = C*( D( 2 )+D( 3 ) ) + Z( 2 ) + Z( 3 )B = C*D( 2 )*D( 3 ) + Z( 2 )*D( 3 ) + Z( 3 )*D( 2 )ELSETEMP = ( D( 1 )-D( 2 ) ) / TWOC = RHO + Z( 3 ) / ( ( D( 3 )-D( 2 ) )-TEMP )A = C*( D( 1 )+D( 2 ) ) + Z( 1 ) + Z( 2 )B = C*D( 1 )*D( 2 ) + Z( 1 )*D( 2 ) + Z( 2 )*D( 1 )END IFTEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )A = A / TEMPB = B / TEMPC = C / TEMPIF( C.EQ.ZERO ) THENTAU = B / AELSE IF( A.LE.ZERO ) THENTAU = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSETAU = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFIF( TAU .LT. LBD .OR. TAU .GT. UBD )$ TAU = ( LBD+UBD )/TWOIF( D(1).EQ.TAU .OR. D(2).EQ.TAU .OR. D(3).EQ.TAU ) THENTAU = ZEROELSETEMP = FINIT + TAU*Z(1)/( D(1)*( D( 1 )-TAU ) ) +$ TAU*Z(2)/( D(2)*( D( 2 )-TAU ) ) +$ TAU*Z(3)/( D(3)*( D( 3 )-TAU ) )IF( TEMP .LE. ZERO )THENLBD = TAUELSEUBD = TAUEND IFIF( ABS( FINIT ).LE.ABS( TEMP ) )$ TAU = ZEROEND IFEND IF** get machine parameters for possible scaling to avoid overflow** modified by Sven: parameters SMALL1, SMINV1, SMALL2,* SMINV2, EPS are not SAVEd anymore between one call to the* others but recomputed at each call*EPS = DLAMCH( 'Epsilon' )BASE = DLAMCH( 'Base' )SMALL1 = BASE**( INT( LOG( DLAMCH( 'SafMin' ) ) / LOG( BASE ) /$ THREE ) )SMINV1 = ONE / SMALL1SMALL2 = SMALL1*SMALL1SMINV2 = SMINV1*SMINV1** Determine if scaling of inputs necessary to avoid overflow* when computing 1/TEMP**3*IF( ORGATI ) THENTEMP = MIN( ABS( D( 2 )-TAU ), ABS( D( 3 )-TAU ) )ELSETEMP = MIN( ABS( D( 1 )-TAU ), ABS( D( 2 )-TAU ) )END IFSCALE = .FALSE.IF( TEMP.LE.SMALL1 ) THENSCALE = .TRUE.IF( TEMP.LE.SMALL2 ) THEN** Scale up by power of radix nearest 1/SAFMIN**(2/3)*SCLFAC = SMINV2SCLINV = SMALL2ELSE** Scale up by power of radix nearest 1/SAFMIN**(1/3)*SCLFAC = SMINV1SCLINV = SMALL1END IF** Scaling up safe because D, Z, TAU scaled elsewhere to be O(1)*DO 10 I = 1, 3DSCALE( I ) = D( I )*SCLFACZSCALE( I ) = Z( I )*SCLFAC10 CONTINUETAU = TAU*SCLFACLBD = LBD*SCLFACUBD = UBD*SCLFACELSE** Copy D and Z to DSCALE and ZSCALE*DO 20 I = 1, 3DSCALE( I ) = D( I )ZSCALE( I ) = Z( I )20 CONTINUEEND IF*FC = ZERODF = ZERODDF = ZERODO 30 I = 1, 3TEMP = ONE / ( DSCALE( I )-TAU )TEMP1 = ZSCALE( I )*TEMPTEMP2 = TEMP1*TEMPTEMP3 = TEMP2*TEMPFC = FC + TEMP1 / DSCALE( I )DF = DF + TEMP2DDF = DDF + TEMP330 CONTINUEF = FINIT + TAU*FC*IF( ABS( F ).LE.ZERO )$ GO TO 60IF( F .LE. ZERO )THENLBD = TAUELSEUBD = TAUEND IF** Iteration begins -- Use Gragg-Thornton-Warner cubic convergent* scheme** It is not hard to see that** 1) Iterations will go up monotonically* if FINIT < 0;** 2) Iterations will go down monotonically* if FINIT > 0.*ITER = NITER + 1*DO 50 NITER = ITER, MAXIT*IF( ORGATI ) THENTEMP1 = DSCALE( 2 ) - TAUTEMP2 = DSCALE( 3 ) - TAUELSETEMP1 = DSCALE( 1 ) - TAUTEMP2 = DSCALE( 2 ) - TAUEND IFA = ( TEMP1+TEMP2 )*F - TEMP1*TEMP2*DFB = TEMP1*TEMP2*FC = F - ( TEMP1+TEMP2 )*DF + TEMP1*TEMP2*DDFTEMP = MAX( ABS( A ), ABS( B ), ABS( C ) )A = A / TEMPB = B / TEMPC = C / TEMPIF( C.EQ.ZERO ) THENETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFIF( F*ETA.GE.ZERO ) THENETA = -F / DFEND IF*TAU = TAU + ETAIF( TAU .LT. LBD .OR. TAU .GT. UBD )$ TAU = ( LBD + UBD )/TWO*FC = ZEROERRETM = ZERODF = ZERODDF = ZERODO 40 I = 1, 3IF ( ( DSCALE( I )-TAU ).NE.ZERO ) THENTEMP = ONE / ( DSCALE( I )-TAU )TEMP1 = ZSCALE( I )*TEMPTEMP2 = TEMP1*TEMPTEMP3 = TEMP2*TEMPTEMP4 = TEMP1 / DSCALE( I )FC = FC + TEMP4ERRETM = ERRETM + ABS( TEMP4 )DF = DF + TEMP2DDF = DDF + TEMP3ELSEGO TO 60END IF40 CONTINUEF = FINIT + TAU*FCERRETM = EIGHT*( ABS( FINIT )+ABS( TAU )*ERRETM ) +$ ABS( TAU )*DFIF( ( ABS( F ).LE.FOUR*EPS*ERRETM ) .OR.$ ( (UBD-LBD).LE.FOUR*EPS*ABS(TAU) ) )$ GO TO 60IF( F .LE. ZERO )THENLBD = TAUELSEUBD = TAUEND IF50 CONTINUEINFO = 160 CONTINUE** Undo scaling*IF( SCALE )$ TAU = TAU*SCLINVRETURN** End of DLAED6*END*> \brief \b DLAED7 used by sstedc. Computes the updated eigensystem of a diagonal matrix after modification by a rank-one symmetric matrix. Used when the original matrix is dense.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED7 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed7.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed7.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed7.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED7( ICOMPQ, N, QSIZ, TLVLS, CURLVL, CURPBM, D, Q,* LDQ, INDXQ, RHO, CUTPNT, QSTORE, QPTR, PRMPTR,* PERM, GIVPTR, GIVCOL, GIVNUM, WORK, IWORK,* INFO )** .. Scalar Arguments ..* INTEGER CURLVL, CURPBM, CUTPNT, ICOMPQ, INFO, LDQ, N,* $ QSIZ, TLVLS* DOUBLE PRECISION RHO* ..* .. Array Arguments ..* INTEGER GIVCOL( 2, * ), GIVPTR( * ), INDXQ( * ),* $ IWORK( * ), PERM( * ), PRMPTR( * ), QPTR( * )* DOUBLE PRECISION D( * ), GIVNUM( 2, * ), Q( LDQ, * ),* $ QSTORE( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED7 computes the updated eigensystem of a diagonal*> matrix after modification by a rank-one symmetric matrix. This*> routine is used only for the eigenproblem which requires all*> eigenvalues and optionally eigenvectors of a dense symmetric matrix*> that has been reduced to tridiagonal form. DLAED1 handles*> the case in which all eigenvalues and eigenvectors of a symmetric*> tridiagonal matrix are desired.*>*> T = Q(in) ( D(in) + RHO * Z*Z**T ) Q**T(in) = Q(out) * D(out) * Q**T(out)*>*> where Z = Q**Tu, u is a vector of length N with ones in the*> CUTPNT and CUTPNT + 1 th elements and zeros elsewhere.*>*> The eigenvectors of the original matrix are stored in Q, and the*> eigenvalues are in D. The algorithm consists of three stages:*>*> The first stage consists of deflating the size of the problem*> when there are multiple eigenvalues or if there is a zero in*> the Z vector. For each such occurrence the dimension of the*> secular equation problem is reduced by one. This stage is*> performed by the routine DLAED8.*>*> The second stage consists of calculating the updated*> eigenvalues. This is done by finding the roots of the secular*> equation via the routine DLAED4 (as called by DLAED9).*> This routine also calculates the eigenvectors of the current*> problem.*>*> The final stage consists of computing the updated eigenvectors*> directly using the updated eigenvalues. The eigenvectors for*> the current problem are multiplied with the eigenvectors from*> the overall problem.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> = 0: Compute eigenvalues only.*> = 1: Compute eigenvectors of original dense symmetric matrix*> also. On entry, Q contains the orthogonal matrix used*> to reduce the original matrix to tridiagonal form.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in] QSIZ*> \verbatim*> QSIZ is INTEGER*> The dimension of the orthogonal matrix used to reduce*> the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1.*> \endverbatim*>*> \param[in] TLVLS*> \verbatim*> TLVLS is INTEGER*> The total number of merging levels in the overall divide and*> conquer tree.*> \endverbatim*>*> \param[in] CURLVL*> \verbatim*> CURLVL is INTEGER*> The current level in the overall merge routine,*> 0 <= CURLVL <= TLVLS.*> \endverbatim*>*> \param[in] CURPBM*> \verbatim*> CURPBM is INTEGER*> The current problem in the current level in the overall*> merge routine (counting from upper left to lower right).*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the eigenvalues of the rank-1-perturbed matrix.*> On exit, the eigenvalues of the repaired matrix.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> On entry, the eigenvectors of the rank-1-perturbed matrix.*> On exit, the eigenvectors of the repaired tridiagonal matrix.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N).*> \endverbatim*>*> \param[out] INDXQ*> \verbatim*> INDXQ is INTEGER array, dimension (N)*> The permutation which will reintegrate the subproblem just*> solved back into sorted order, i.e., D( INDXQ( I = 1, N ) )*> will be in ascending order.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The subdiagonal element used to create the rank-1*> modification.*> \endverbatim*>*> \param[in] CUTPNT*> \verbatim*> CUTPNT is INTEGER*> Contains the location of the last eigenvalue in the leading*> sub-matrix. min(1,N) <= CUTPNT <= N.*> \endverbatim*>*> \param[in,out] QSTORE*> \verbatim*> QSTORE is DOUBLE PRECISION array, dimension (N**2+1)*> Stores eigenvectors of submatrices encountered during*> divide and conquer, packed together. QPTR points to*> beginning of the submatrices.*> \endverbatim*>*> \param[in,out] QPTR*> \verbatim*> QPTR is INTEGER array, dimension (N+2)*> List of indices pointing to beginning of submatrices stored*> in QSTORE. The submatrices are numbered starting at the*> bottom left of the divide and conquer tree, from left to*> right and bottom to top.*> \endverbatim*>*> \param[in] PRMPTR*> \verbatim*> PRMPTR is INTEGER array, dimension (N lg N)*> Contains a list of pointers which indicate where in PERM a*> level's permutation is stored. PRMPTR(i+1) - PRMPTR(i)*> indicates the size of the permutation and also the size of*> the full, non-deflated problem.*> \endverbatim*>*> \param[in] PERM*> \verbatim*> PERM is INTEGER array, dimension (N lg N)*> Contains the permutations (from deflation and sorting) to be*> applied to each eigenblock.*> \endverbatim*>*> \param[in] GIVPTR*> \verbatim*> GIVPTR is INTEGER array, dimension (N lg N)*> Contains a list of pointers which indicate where in GIVCOL a*> level's Givens rotations are stored. GIVPTR(i+1) - GIVPTR(i)*> indicates the number of Givens rotations.*> \endverbatim*>*> \param[in] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension (2, N lg N)*> Each pair of numbers indicates a pair of columns to take place*> in a Givens rotation.*> \endverbatim*>*> \param[in] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension (2, N lg N)*> Each number indicates the S value to be used in the*> corresponding Givens rotation.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N+2*QSIZ*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (4*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, an eigenvalue did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA** =====================================================================SUBROUTINE DLAED7( ICOMPQ, N, QSIZ, TLVLS, CURLVL, CURPBM, D, Q,$ LDQ, INDXQ, RHO, CUTPNT, QSTORE, QPTR, PRMPTR,$ PERM, GIVPTR, GIVCOL, GIVNUM, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER CURLVL, CURPBM, CUTPNT, ICOMPQ, INFO, LDQ, N,$ QSIZ, TLVLSDOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER GIVCOL( 2, * ), GIVPTR( * ), INDXQ( * ),$ IWORK( * ), PERM( * ), PRMPTR( * ), QPTR( * )DOUBLE PRECISION D( * ), GIVNUM( 2, * ), Q( LDQ, * ),$ QSTORE( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER COLTYP, CURR, I, IDLMDA, INDX, INDXC, INDXP,$ IQ2, IS, IW, IZ, K, LDQ2, N1, N2, PTR* ..* .. External Subroutines ..EXTERNAL DGEMM, DLAED8, DLAED9, DLAEDA, DLAMRG, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ICOMPQ.LT.0 .OR. ICOMPQ.GT.1 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ICOMPQ.EQ.1 .AND. QSIZ.LT.N ) THENINFO = -3ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( MIN( 1, N ).GT.CUTPNT .OR. N.LT.CUTPNT ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED7', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** The following values are for bookkeeping purposes only. They are* integer pointers which indicate the portion of the workspace* used by a particular array in DLAED8 and DLAED9.*IF( ICOMPQ.EQ.1 ) THENLDQ2 = QSIZELSELDQ2 = NEND IF*IZ = 1IDLMDA = IZ + NIW = IDLMDA + NIQ2 = IW + NIS = IQ2 + N*LDQ2*INDX = 1INDXC = INDX + NCOLTYP = INDXC + NINDXP = COLTYP + N** Form the z-vector which consists of the last row of Q_1 and the* first row of Q_2.*PTR = 1 + 2**TLVLSDO 10 I = 1, CURLVL - 1PTR = PTR + 2**( TLVLS-I )10 CONTINUECURR = PTR + CURPBMCALL DLAEDA( N, TLVLS, CURLVL, CURPBM, PRMPTR, PERM, GIVPTR,$ GIVCOL, GIVNUM, QSTORE, QPTR, WORK( IZ ),$ WORK( IZ+N ), INFO )** When solving the final problem, we no longer need the stored data,* so we will overwrite the data from this level onto the previously* used storage space.*IF( CURLVL.EQ.TLVLS ) THENQPTR( CURR ) = 1PRMPTR( CURR ) = 1GIVPTR( CURR ) = 1END IF** Sort and Deflate eigenvalues.*CALL DLAED8( ICOMPQ, K, N, QSIZ, D, Q, LDQ, INDXQ, RHO, CUTPNT,$ WORK( IZ ), WORK( IDLMDA ), WORK( IQ2 ), LDQ2,$ WORK( IW ), PERM( PRMPTR( CURR ) ), GIVPTR( CURR+1 ),$ GIVCOL( 1, GIVPTR( CURR ) ),$ GIVNUM( 1, GIVPTR( CURR ) ), IWORK( INDXP ),$ IWORK( INDX ), INFO )PRMPTR( CURR+1 ) = PRMPTR( CURR ) + NGIVPTR( CURR+1 ) = GIVPTR( CURR+1 ) + GIVPTR( CURR )** Solve Secular Equation.*IF( K.NE.0 ) THENCALL DLAED9( K, 1, K, N, D, WORK( IS ), K, RHO, WORK( IDLMDA ),$ WORK( IW ), QSTORE( QPTR( CURR ) ), K, INFO )IF( INFO.NE.0 )$ GO TO 30IF( ICOMPQ.EQ.1 ) THENCALL DGEMM( 'N', 'N', QSIZ, K, K, ONE, WORK( IQ2 ), LDQ2,$ QSTORE( QPTR( CURR ) ), K, ZERO, Q, LDQ )END IFQPTR( CURR+1 ) = QPTR( CURR ) + K**2** Prepare the INDXQ sorting permutation.*N1 = KN2 = N - KCALL DLAMRG( N1, N2, D, 1, -1, INDXQ )ELSEQPTR( CURR+1 ) = QPTR( CURR )DO 20 I = 1, NINDXQ( I ) = I20 CONTINUEEND IF*30 CONTINUERETURN** End of DLAED7*END*> \brief \b DLAED8 used by sstedc. Merges eigenvalues and deflates secular equation. Used when the original matrix is dense.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED8 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed8.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed8.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed8.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED8( ICOMPQ, K, N, QSIZ, D, Q, LDQ, INDXQ, RHO,* CUTPNT, Z, DLAMDA, Q2, LDQ2, W, PERM, GIVPTR,* GIVCOL, GIVNUM, INDXP, INDX, INFO )** .. Scalar Arguments ..* INTEGER CUTPNT, GIVPTR, ICOMPQ, INFO, K, LDQ, LDQ2, N,* $ QSIZ* DOUBLE PRECISION RHO* ..* .. Array Arguments ..* INTEGER GIVCOL( 2, * ), INDX( * ), INDXP( * ),* $ INDXQ( * ), PERM( * )* DOUBLE PRECISION D( * ), DLAMDA( * ), GIVNUM( 2, * ),* $ Q( LDQ, * ), Q2( LDQ2, * ), W( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED8 merges the two sets of eigenvalues together into a single*> sorted set. Then it tries to deflate the size of the problem.*> There are two ways in which deflation can occur: when two or more*> eigenvalues are close together or if there is a tiny element in the*> Z vector. For each such occurrence the order of the related secular*> equation problem is reduced by one.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> = 0: Compute eigenvalues only.*> = 1: Compute eigenvectors of original dense symmetric matrix*> also. On entry, Q contains the orthogonal matrix used*> to reduce the original matrix to tridiagonal form.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER*> The number of non-deflated eigenvalues, and the order of the*> related secular equation.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in] QSIZ*> \verbatim*> QSIZ is INTEGER*> The dimension of the orthogonal matrix used to reduce*> the full matrix to tridiagonal form. QSIZ >= N if ICOMPQ = 1.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the eigenvalues of the two submatrices to be*> combined. On exit, the trailing (N-K) updated eigenvalues*> (those which were deflated) sorted into increasing order.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> If ICOMPQ = 0, Q is not referenced. Otherwise,*> on entry, Q contains the eigenvectors of the partially solved*> system which has been previously updated in matrix*> multiplies with other partially solved eigensystems.*> On exit, Q contains the trailing (N-K) updated eigenvectors*> (those which were deflated) in its last N-K columns.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N).*> \endverbatim*>*> \param[in] INDXQ*> \verbatim*> INDXQ is INTEGER array, dimension (N)*> The permutation which separately sorts the two sub-problems*> in D into ascending order. Note that elements in the second*> half of this permutation must first have CUTPNT added to*> their values in order to be accurate.*> \endverbatim*>*> \param[in,out] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> On entry, the off-diagonal element associated with the rank-1*> cut which originally split the two submatrices which are now*> being recombined.*> On exit, RHO has been modified to the value required by*> DLAED3.*> \endverbatim*>*> \param[in] CUTPNT*> \verbatim*> CUTPNT is INTEGER*> The location of the last eigenvalue in the leading*> sub-matrix. min(1,N) <= CUTPNT <= N.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (N)*> On entry, Z contains the updating vector (the last row of*> the first sub-eigenvector matrix and the first row of the*> second sub-eigenvector matrix).*> On exit, the contents of Z are destroyed by the updating*> process.*> \endverbatim*>*> \param[out] DLAMDA*> \verbatim*> DLAMDA is DOUBLE PRECISION array, dimension (N)*> A copy of the first K eigenvalues which will be used by*> DLAED3 to form the secular equation.*> \endverbatim*>*> \param[out] Q2*> \verbatim*> Q2 is DOUBLE PRECISION array, dimension (LDQ2,N)*> If ICOMPQ = 0, Q2 is not referenced. Otherwise,*> a copy of the first K eigenvectors which will be used by*> DLAED7 in a matrix multiply (DGEMM) to update the new*> eigenvectors.*> \endverbatim*>*> \param[in] LDQ2*> \verbatim*> LDQ2 is INTEGER*> The leading dimension of the array Q2. LDQ2 >= max(1,N).*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first k values of the final deflation-altered z-vector and*> will be passed to DLAED3.*> \endverbatim*>*> \param[out] PERM*> \verbatim*> PERM is INTEGER array, dimension (N)*> The permutations (from deflation and sorting) to be applied*> to each eigenblock.*> \endverbatim*>*> \param[out] GIVPTR*> \verbatim*> GIVPTR is INTEGER*> The number of Givens rotations which took place in this*> subproblem.*> \endverbatim*>*> \param[out] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension (2, N)*> Each pair of numbers indicates a pair of columns to take place*> in a Givens rotation.*> \endverbatim*>*> \param[out] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension (2, N)*> Each number indicates the S value to be used in the*> corresponding Givens rotation.*> \endverbatim*>*> \param[out] INDXP*> \verbatim*> INDXP is INTEGER array, dimension (N)*> The permutation used to place deflated values of D at the end*> of the array. INDXP(1:K) points to the nondeflated D-values*> and INDXP(K+1:N) points to the deflated eigenvalues.*> \endverbatim*>*> \param[out] INDX*> \verbatim*> INDX is INTEGER array, dimension (N)*> The permutation used to sort the contents of D into ascending*> order.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA** =====================================================================SUBROUTINE DLAED8( ICOMPQ, K, N, QSIZ, D, Q, LDQ, INDXQ, RHO,$ CUTPNT, Z, DLAMDA, Q2, LDQ2, W, PERM, GIVPTR,$ GIVCOL, GIVNUM, INDXP, INDX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER CUTPNT, GIVPTR, ICOMPQ, INFO, K, LDQ, LDQ2, N,$ QSIZDOUBLE PRECISION RHO* ..* .. Array Arguments ..INTEGER GIVCOL( 2, * ), INDX( * ), INDXP( * ),$ INDXQ( * ), PERM( * )DOUBLE PRECISION D( * ), DLAMDA( * ), GIVNUM( 2, * ),$ Q( LDQ, * ), Q2( LDQ2, * ), W( * ), Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION MONE, ZERO, ONE, TWO, EIGHTPARAMETER ( MONE = -1.0D0, ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, EIGHT = 8.0D0 )* ..* .. Local Scalars ..*INTEGER I, IMAX, J, JLAM, JMAX, JP, K2, N1, N1P1, N2DOUBLE PRECISION C, EPS, S, T, TAU, TOL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL IDAMAX, DLAMCH, DLAPY2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAMRG, DROT, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ICOMPQ.LT.0 .OR. ICOMPQ.GT.1 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ICOMPQ.EQ.1 .AND. QSIZ.LT.N ) THENINFO = -4ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( CUTPNT.LT.MIN( 1, N ) .OR. CUTPNT.GT.N ) THENINFO = -10ELSE IF( LDQ2.LT.MAX( 1, N ) ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED8', -INFO )RETURNEND IF** Need to initialize GIVPTR to O here in case of quick exit* to prevent an unspecified code behavior (usually sigfault)* when IWORK array on entry to *stedc is not zeroed* (or at least some IWORK entries which used in *laed7 for GIVPTR).*GIVPTR = 0** Quick return if possible*IF( N.EQ.0 )$ RETURN*N1 = CUTPNTN2 = N - N1N1P1 = N1 + 1*IF( RHO.LT.ZERO ) THENCALL DSCAL( N2, MONE, Z( N1P1 ), 1 )END IF** Normalize z so that norm(z) = 1*T = ONE / SQRT( TWO )DO 10 J = 1, NINDX( J ) = J10 CONTINUECALL DSCAL( N, T, Z, 1 )RHO = ABS( TWO*RHO )** Sort the eigenvalues into increasing order*DO 20 I = CUTPNT + 1, NINDXQ( I ) = INDXQ( I ) + CUTPNT20 CONTINUEDO 30 I = 1, NDLAMDA( I ) = D( INDXQ( I ) )W( I ) = Z( INDXQ( I ) )30 CONTINUEI = 1J = CUTPNT + 1CALL DLAMRG( N1, N2, DLAMDA, 1, 1, INDX )DO 40 I = 1, ND( I ) = DLAMDA( INDX( I ) )Z( I ) = W( INDX( I ) )40 CONTINUE** Calculate the allowable deflation tolerence*IMAX = IDAMAX( N, Z, 1 )JMAX = IDAMAX( N, D, 1 )EPS = DLAMCH( 'Epsilon' )TOL = EIGHT*EPS*ABS( D( JMAX ) )** If the rank-1 modifier is small enough, no more needs to be done* except to reorganize Q so that its columns correspond with the* elements in D.*IF( RHO*ABS( Z( IMAX ) ).LE.TOL ) THENK = 0IF( ICOMPQ.EQ.0 ) THENDO 50 J = 1, NPERM( J ) = INDXQ( INDX( J ) )50 CONTINUEELSEDO 60 J = 1, NPERM( J ) = INDXQ( INDX( J ) )CALL DCOPY( QSIZ, Q( 1, PERM( J ) ), 1, Q2( 1, J ), 1 )60 CONTINUECALL DLACPY( 'A', QSIZ, N, Q2( 1, 1 ), LDQ2, Q( 1, 1 ),$ LDQ )END IFRETURNEND IF** If there are multiple eigenvalues then the problem deflates. Here* the number of equal eigenvalues are found. As each equal* eigenvalue is found, an elementary reflector is computed to rotate* the corresponding eigensubspace so that the corresponding* components of Z are zero in this new basis.*K = 0K2 = N + 1DO 70 J = 1, NIF( RHO*ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1INDXP( K2 ) = JIF( J.EQ.N )$ GO TO 110ELSEJLAM = JGO TO 80END IF70 CONTINUE80 CONTINUEJ = J + 1IF( J.GT.N )$ GO TO 100IF( RHO*ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1INDXP( K2 ) = JELSE** Check if eigenvalues are close enough to allow deflation.*S = Z( JLAM )C = Z( J )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.*TAU = DLAPY2( C, S )T = D( J ) - D( JLAM )C = C / TAUS = -S / TAUIF( ABS( T*C*S ).LE.TOL ) THEN** Deflation is possible.*Z( J ) = TAUZ( JLAM ) = ZERO** Record the appropriate Givens rotation*GIVPTR = GIVPTR + 1GIVCOL( 1, GIVPTR ) = INDXQ( INDX( JLAM ) )GIVCOL( 2, GIVPTR ) = INDXQ( INDX( J ) )GIVNUM( 1, GIVPTR ) = CGIVNUM( 2, GIVPTR ) = SIF( ICOMPQ.EQ.1 ) THENCALL DROT( QSIZ, Q( 1, INDXQ( INDX( JLAM ) ) ), 1,$ Q( 1, INDXQ( INDX( J ) ) ), 1, C, S )END IFT = D( JLAM )*C*C + D( J )*S*SD( J ) = D( JLAM )*S*S + D( J )*C*CD( JLAM ) = TK2 = K2 - 1I = 190 CONTINUEIF( K2+I.LE.N ) THENIF( D( JLAM ).LT.D( INDXP( K2+I ) ) ) THENINDXP( K2+I-1 ) = INDXP( K2+I )INDXP( K2+I ) = JLAMI = I + 1GO TO 90ELSEINDXP( K2+I-1 ) = JLAMEND IFELSEINDXP( K2+I-1 ) = JLAMEND IFJLAM = JELSEK = K + 1W( K ) = Z( JLAM )DLAMDA( K ) = D( JLAM )INDXP( K ) = JLAMJLAM = JEND IFEND IFGO TO 80100 CONTINUE** Record the last eigenvalue.*K = K + 1W( K ) = Z( JLAM )DLAMDA( K ) = D( JLAM )INDXP( K ) = JLAM*110 CONTINUE** Sort the eigenvalues and corresponding eigenvectors into DLAMDA* and Q2 respectively. The eigenvalues/vectors which were not* deflated go into the first K slots of DLAMDA and Q2 respectively,* while those which were deflated go into the last N - K slots.*IF( ICOMPQ.EQ.0 ) THENDO 120 J = 1, NJP = INDXP( J )DLAMDA( J ) = D( JP )PERM( J ) = INDXQ( INDX( JP ) )120 CONTINUEELSEDO 130 J = 1, NJP = INDXP( J )DLAMDA( J ) = D( JP )PERM( J ) = INDXQ( INDX( JP ) )CALL DCOPY( QSIZ, Q( 1, PERM( J ) ), 1, Q2( 1, J ), 1 )130 CONTINUEEND IF** The deflated eigenvalues and their corresponding vectors go back* into the last N - K slots of D and Q respectively.*IF( K.LT.N ) THENIF( ICOMPQ.EQ.0 ) THENCALL DCOPY( N-K, DLAMDA( K+1 ), 1, D( K+1 ), 1 )ELSECALL DCOPY( N-K, DLAMDA( K+1 ), 1, D( K+1 ), 1 )CALL DLACPY( 'A', QSIZ, N-K, Q2( 1, K+1 ), LDQ2,$ Q( 1, K+1 ), LDQ )END IFEND IF*RETURN** End of DLAED8*END*> \brief \b DLAED9 used by sstedc. Finds the roots of the secular equation and updates the eigenvectors. Used when the original matrix is dense.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAED9 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaed9.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaed9.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaed9.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAED9( K, KSTART, KSTOP, N, D, Q, LDQ, RHO, DLAMDA, W,* S, LDS, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, KSTART, KSTOP, LDQ, LDS, N* DOUBLE PRECISION RHO* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), S( LDS, * ),* $ W( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAED9 finds the roots of the secular equation, as defined by the*> values in D, Z, and RHO, between KSTART and KSTOP. It makes the*> appropriate calls to DLAED4 and then stores the new matrix of*> eigenvectors for use in calculating the next level of Z vectors.*> \endverbatim** Arguments:* ==========**> \param[in] K*> \verbatim*> K is INTEGER*> The number of terms in the rational function to be solved by*> DLAED4. K >= 0.*> \endverbatim*>*> \param[in] KSTART*> \verbatim*> KSTART is INTEGER*> \endverbatim*>*> \param[in] KSTOP*> \verbatim*> KSTOP is INTEGER*> The updated eigenvalues Lambda(I), KSTART <= I <= KSTOP*> are to be computed. 1 <= KSTART <= KSTOP <= K.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows and columns in the Q matrix.*> N >= K (delation may result in N > K).*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> D(I) contains the updated eigenvalues*> for KSTART <= I <= KSTOP.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max( 1, N ).*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The value of the parameter in the rank one update equation.*> RHO >= 0 required.*> \endverbatim*>*> \param[in] DLAMDA*> \verbatim*> DLAMDA is DOUBLE PRECISION array, dimension (K)*> The first K elements of this array contain the old roots*> of the deflated updating problem. These are the poles*> of the secular equation.*> \endverbatim*>*> \param[in] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (K)*> The first K elements of this array contain the components*> of the deflation-adjusted updating vector.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (LDS, K)*> Will contain the eigenvectors of the repaired matrix which*> will be stored for subsequent Z vector calculation and*> multiplied by the previously accumulated eigenvectors*> to update the system.*> \endverbatim*>*> \param[in] LDS*> \verbatim*> LDS is INTEGER*> The leading dimension of S. LDS >= max( 1, K ).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, an eigenvalue did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA** =====================================================================SUBROUTINE DLAED9( K, KSTART, KSTOP, N, D, Q, LDQ, RHO, DLAMDA, W,$ S, LDS, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, KSTART, KSTOP, LDQ, LDS, NDOUBLE PRECISION RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DLAMDA( * ), Q( LDQ, * ), S( LDS, * ),$ W( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, JDOUBLE PRECISION TEMP* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAED4, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( K.LT.0 ) THENINFO = -1ELSE IF( KSTART.LT.1 .OR. KSTART.GT.MAX( 1, K ) ) THENINFO = -2ELSE IF( MAX( 1, KSTOP ).LT.KSTART .OR. KSTOP.GT.MAX( 1, K ) )$ THENINFO = -3ELSE IF( N.LT.K ) THENINFO = -4ELSE IF( LDQ.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDS.LT.MAX( 1, K ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAED9', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.0 )$ RETURN** Modify values DLAMDA(i) to make sure all DLAMDA(i)-DLAMDA(j) can* be computed with high relative accuracy (barring over/underflow).* This is a problem on machines without a guard digit in* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).* The following code replaces DLAMDA(I) by 2*DLAMDA(I)-DLAMDA(I),* which on any of these machines zeros out the bottommost* bit of DLAMDA(I) if it is 1; this makes the subsequent* subtractions DLAMDA(I)-DLAMDA(J) unproblematic when cancellation* occurs. On binary machines with a guard digit (almost all* machines) it does not change DLAMDA(I) at all. On hexadecimal* and decimal machines with a guard digit, it slightly* changes the bottommost bits of DLAMDA(I). It does not account* for hexadecimal or decimal machines without guard digits* (we know of none). We use a subroutine call to compute* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating* this code.*DO 10 I = 1, NDLAMDA( I ) = DLAMC3( DLAMDA( I ), DLAMDA( I ) ) - DLAMDA( I )10 CONTINUE*DO 20 J = KSTART, KSTOPCALL DLAED4( K, J, DLAMDA, W, Q( 1, J ), RHO, D( J ), INFO )** If the zero finder fails, the computation is terminated.*IF( INFO.NE.0 )$ GO TO 12020 CONTINUE*IF( K.EQ.1 .OR. K.EQ.2 ) THENDO 40 I = 1, KDO 30 J = 1, KS( J, I ) = Q( J, I )30 CONTINUE40 CONTINUEGO TO 120END IF** Compute updated W.*CALL DCOPY( K, W, 1, S, 1 )** Initialize W(I) = Q(I,I)*CALL DCOPY( K, Q, LDQ+1, W, 1 )DO 70 J = 1, KDO 50 I = 1, J - 1W( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )50 CONTINUEDO 60 I = J + 1, KW( I ) = W( I )*( Q( I, J ) / ( DLAMDA( I )-DLAMDA( J ) ) )60 CONTINUE70 CONTINUEDO 80 I = 1, KW( I ) = SIGN( SQRT( -W( I ) ), S( I, 1 ) )80 CONTINUE** Compute eigenvectors of the modified rank-1 modification.*DO 110 J = 1, KDO 90 I = 1, KQ( I, J ) = W( I ) / Q( I, J )90 CONTINUETEMP = DNRM2( K, Q( 1, J ), 1 )DO 100 I = 1, KS( I, J ) = Q( I, J ) / TEMP100 CONTINUE110 CONTINUE*120 CONTINUERETURN** End of DLAED9*END*> \brief \b DLAEDA used by sstedc. Computes the Z vector determining the rank-one modification of the diagonal matrix. Used when the original matrix is dense.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAEDA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaeda.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaeda.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaeda.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAEDA( N, TLVLS, CURLVL, CURPBM, PRMPTR, PERM, GIVPTR,* GIVCOL, GIVNUM, Q, QPTR, Z, ZTEMP, INFO )** .. Scalar Arguments ..* INTEGER CURLVL, CURPBM, INFO, N, TLVLS* ..* .. Array Arguments ..* INTEGER GIVCOL( 2, * ), GIVPTR( * ), PERM( * ),* $ PRMPTR( * ), QPTR( * )* DOUBLE PRECISION GIVNUM( 2, * ), Q( * ), Z( * ), ZTEMP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAEDA computes the Z vector corresponding to the merge step in the*> CURLVLth step of the merge process with TLVLS steps for the CURPBMth*> problem.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in] TLVLS*> \verbatim*> TLVLS is INTEGER*> The total number of merging levels in the overall divide and*> conquer tree.*> \endverbatim*>*> \param[in] CURLVL*> \verbatim*> CURLVL is INTEGER*> The current level in the overall merge routine,*> 0 <= curlvl <= tlvls.*> \endverbatim*>*> \param[in] CURPBM*> \verbatim*> CURPBM is INTEGER*> The current problem in the current level in the overall*> merge routine (counting from upper left to lower right).*> \endverbatim*>*> \param[in] PRMPTR*> \verbatim*> PRMPTR is INTEGER array, dimension (N lg N)*> Contains a list of pointers which indicate where in PERM a*> level's permutation is stored. PRMPTR(i+1) - PRMPTR(i)*> indicates the size of the permutation and incidentally the*> size of the full, non-deflated problem.*> \endverbatim*>*> \param[in] PERM*> \verbatim*> PERM is INTEGER array, dimension (N lg N)*> Contains the permutations (from deflation and sorting) to be*> applied to each eigenblock.*> \endverbatim*>*> \param[in] GIVPTR*> \verbatim*> GIVPTR is INTEGER array, dimension (N lg N)*> Contains a list of pointers which indicate where in GIVCOL a*> level's Givens rotations are stored. GIVPTR(i+1) - GIVPTR(i)*> indicates the number of Givens rotations.*> \endverbatim*>*> \param[in] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension (2, N lg N)*> Each pair of numbers indicates a pair of columns to take place*> in a Givens rotation.*> \endverbatim*>*> \param[in] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension (2, N lg N)*> Each number indicates the S value to be used in the*> corresponding Givens rotation.*> \endverbatim*>*> \param[in] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (N**2)*> Contains the square eigenblocks from previous levels, the*> starting positions for blocks are given by QPTR.*> \endverbatim*>*> \param[in] QPTR*> \verbatim*> QPTR is INTEGER array, dimension (N+2)*> Contains a list of pointers which indicate where in Q an*> eigenblock is stored. SQRT( QPTR(i+1) - QPTR(i) ) indicates*> the size of the block.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (N)*> On output this vector contains the updating vector (the last*> row of the first sub-eigenvector matrix and the first row of*> the second sub-eigenvector matrix).*> \endverbatim*>*> \param[out] ZTEMP*> \verbatim*> ZTEMP is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA** =====================================================================SUBROUTINE DLAEDA( N, TLVLS, CURLVL, CURPBM, PRMPTR, PERM, GIVPTR,$ GIVCOL, GIVNUM, Q, QPTR, Z, ZTEMP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER CURLVL, CURPBM, INFO, N, TLVLS* ..* .. Array Arguments ..INTEGER GIVCOL( 2, * ), GIVPTR( * ), PERM( * ),$ PRMPTR( * ), QPTR( * )DOUBLE PRECISION GIVNUM( 2, * ), Q( * ), Z( * ), ZTEMP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER BSIZ1, BSIZ2, CURR, I, K, MID, PSIZ1, PSIZ2,$ PTR, ZPTR1* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, INT, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -1END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAEDA', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine location of first number in second half.*MID = N / 2 + 1** Gather last/first rows of appropriate eigenblocks into center of Z*PTR = 1** Determine location of lowest level subproblem in the full storage* scheme*CURR = PTR + CURPBM*2**CURLVL + 2**( CURLVL-1 ) - 1** Determine size of these matrices. We add HALF to the value of* the SQRT in case the machine underestimates one of these square* roots.*BSIZ1 = INT( HALF+SQRT( DBLE( QPTR( CURR+1 )-QPTR( CURR ) ) ) )BSIZ2 = INT( HALF+SQRT( DBLE( QPTR( CURR+2 )-QPTR( CURR+1 ) ) ) )DO 10 K = 1, MID - BSIZ1 - 1Z( K ) = ZERO10 CONTINUECALL DCOPY( BSIZ1, Q( QPTR( CURR )+BSIZ1-1 ), BSIZ1,$ Z( MID-BSIZ1 ), 1 )CALL DCOPY( BSIZ2, Q( QPTR( CURR+1 ) ), BSIZ2, Z( MID ), 1 )DO 20 K = MID + BSIZ2, NZ( K ) = ZERO20 CONTINUE** Loop through remaining levels 1 -> CURLVL applying the Givens* rotations and permutation and then multiplying the center matrices* against the current Z.*PTR = 2**TLVLS + 1DO 70 K = 1, CURLVL - 1CURR = PTR + CURPBM*2**( CURLVL-K ) + 2**( CURLVL-K-1 ) - 1PSIZ1 = PRMPTR( CURR+1 ) - PRMPTR( CURR )PSIZ2 = PRMPTR( CURR+2 ) - PRMPTR( CURR+1 )ZPTR1 = MID - PSIZ1** Apply Givens at CURR and CURR+1*DO 30 I = GIVPTR( CURR ), GIVPTR( CURR+1 ) - 1CALL DROT( 1, Z( ZPTR1+GIVCOL( 1, I )-1 ), 1,$ Z( ZPTR1+GIVCOL( 2, I )-1 ), 1, GIVNUM( 1, I ),$ GIVNUM( 2, I ) )30 CONTINUEDO 40 I = GIVPTR( CURR+1 ), GIVPTR( CURR+2 ) - 1CALL DROT( 1, Z( MID-1+GIVCOL( 1, I ) ), 1,$ Z( MID-1+GIVCOL( 2, I ) ), 1, GIVNUM( 1, I ),$ GIVNUM( 2, I ) )40 CONTINUEPSIZ1 = PRMPTR( CURR+1 ) - PRMPTR( CURR )PSIZ2 = PRMPTR( CURR+2 ) - PRMPTR( CURR+1 )DO 50 I = 0, PSIZ1 - 1ZTEMP( I+1 ) = Z( ZPTR1+PERM( PRMPTR( CURR )+I )-1 )50 CONTINUEDO 60 I = 0, PSIZ2 - 1ZTEMP( PSIZ1+I+1 ) = Z( MID+PERM( PRMPTR( CURR+1 )+I )-1 )60 CONTINUE** Multiply Blocks at CURR and CURR+1** Determine size of these matrices. We add HALF to the value of* the SQRT in case the machine underestimates one of these* square roots.*BSIZ1 = INT( HALF+SQRT( DBLE( QPTR( CURR+1 )-QPTR( CURR ) ) ) )BSIZ2 = INT( HALF+SQRT( DBLE( QPTR( CURR+2 )-QPTR( CURR+$ 1 ) ) ) )IF( BSIZ1.GT.0 ) THENCALL DGEMV( 'T', BSIZ1, BSIZ1, ONE, Q( QPTR( CURR ) ),$ BSIZ1, ZTEMP( 1 ), 1, ZERO, Z( ZPTR1 ), 1 )END IFCALL DCOPY( PSIZ1-BSIZ1, ZTEMP( BSIZ1+1 ), 1, Z( ZPTR1+BSIZ1 ),$ 1 )IF( BSIZ2.GT.0 ) THENCALL DGEMV( 'T', BSIZ2, BSIZ2, ONE, Q( QPTR( CURR+1 ) ),$ BSIZ2, ZTEMP( PSIZ1+1 ), 1, ZERO, Z( MID ), 1 )END IFCALL DCOPY( PSIZ2-BSIZ2, ZTEMP( PSIZ1+BSIZ2+1 ), 1,$ Z( MID+BSIZ2 ), 1 )*PTR = PTR + 2**( TLVLS-K )70 CONTINUE*RETURN** End of DLAEDA*END*> \brief \b DLAEIN computes a specified right or left eigenvector of an upper Hessenberg matrix by inverse iteration.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAEIN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaein.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaein.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaein.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAEIN( RIGHTV, NOINIT, N, H, LDH, WR, WI, VR, VI, B,* LDB, WORK, EPS3, SMLNUM, BIGNUM, INFO )** .. Scalar Arguments ..* LOGICAL NOINIT, RIGHTV* INTEGER INFO, LDB, LDH, N* DOUBLE PRECISION BIGNUM, EPS3, SMLNUM, WI, WR* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), H( LDH, * ), VI( * ), VR( * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAEIN uses inverse iteration to find a right or left eigenvector*> corresponding to the eigenvalue (WR,WI) of a real upper Hessenberg*> matrix H.*> \endverbatim** Arguments:* ==========**> \param[in] RIGHTV*> \verbatim*> RIGHTV is LOGICAL*> = .TRUE. : compute right eigenvector;*> = .FALSE.: compute left eigenvector.*> \endverbatim*>*> \param[in] NOINIT*> \verbatim*> NOINIT is LOGICAL*> = .TRUE. : no initial vector supplied in (VR,VI).*> = .FALSE.: initial vector supplied in (VR,VI).*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H. N >= 0.*> \endverbatim*>*> \param[in] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> The upper Hessenberg matrix H.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH >= max(1,N).*> \endverbatim*>*> \param[in] WR*> \verbatim*> WR is DOUBLE PRECISION*> \endverbatim*>*> \param[in] WI*> \verbatim*> WI is DOUBLE PRECISION*> The real and imaginary parts of the eigenvalue of H whose*> corresponding right or left eigenvector is to be computed.*> \endverbatim*>*> \param[in,out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[in,out] VI*> \verbatim*> VI is DOUBLE PRECISION array, dimension (N)*> On entry, if NOINIT = .FALSE. and WI = 0.0, VR must contain*> a real starting vector for inverse iteration using the real*> eigenvalue WR; if NOINIT = .FALSE. and WI.ne.0.0, VR and VI*> must contain the real and imaginary parts of a complex*> starting vector for inverse iteration using the complex*> eigenvalue (WR,WI); otherwise VR and VI need not be set.*> On exit, if WI = 0.0 (real eigenvalue), VR contains the*> computed real eigenvector; if WI.ne.0.0 (complex eigenvalue),*> VR and VI contain the real and imaginary parts of the*> computed complex eigenvector. The eigenvector is normalized*> so that the component of largest magnitude has magnitude 1;*> here the magnitude of a complex number (x,y) is taken to be*> |x| + |y|.*> VI is not referenced if WI = 0.0.*> \endverbatim*>*> \param[out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= N+1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[in] EPS3*> \verbatim*> EPS3 is DOUBLE PRECISION*> A small machine-dependent value which is used to perturb*> close eigenvalues, and to replace zero pivots.*> \endverbatim*>*> \param[in] SMLNUM*> \verbatim*> SMLNUM is DOUBLE PRECISION*> A machine-dependent value close to the underflow threshold.*> \endverbatim*>*> \param[in] BIGNUM*> \verbatim*> BIGNUM is DOUBLE PRECISION*> A machine-dependent value close to the overflow threshold.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> = 1: inverse iteration did not converge; VR is set to the*> last iterate, and so is VI if WI.ne.0.0.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAEIN( RIGHTV, NOINIT, N, H, LDH, WR, WI, VR, VI, B,$ LDB, WORK, EPS3, SMLNUM, BIGNUM, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL NOINIT, RIGHTVINTEGER INFO, LDB, LDH, NDOUBLE PRECISION BIGNUM, EPS3, SMLNUM, WI, WR* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), H( LDH, * ), VI( * ), VR( * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TENTHPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TENTH = 1.0D-1 )* ..* .. Local Scalars ..CHARACTER NORMIN, TRANSINTEGER I, I1, I2, I3, IERR, ITS, JDOUBLE PRECISION ABSBII, ABSBJJ, EI, EJ, GROWTO, NORM, NRMSML,$ REC, ROOTN, SCALE, TEMP, VCRIT, VMAX, VNORM, W,$ W1, X, XI, XR, Y* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DASUM, DLAPY2, DNRM2EXTERNAL IDAMAX, DASUM, DLAPY2, DNRM2* ..* .. External Subroutines ..EXTERNAL DLADIV, DLATRS, DSCAL* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, SQRT* ..* .. Executable Statements ..*INFO = 0** GROWTO is the threshold used in the acceptance test for an* eigenvector.*ROOTN = SQRT( DBLE( N ) )GROWTO = TENTH / ROOTNNRMSML = MAX( ONE, EPS3*ROOTN )*SMLNUM** Form B = H - (WR,WI)*I (except that the subdiagonal elements and* the imaginary parts of the diagonal elements are not stored).*DO 20 J = 1, NDO 10 I = 1, J - 1B( I, J ) = H( I, J )10 CONTINUEB( J, J ) = H( J, J ) - WR20 CONTINUE*IF( WI.EQ.ZERO ) THEN** Real eigenvalue.*IF( NOINIT ) THEN** Set initial vector.*DO 30 I = 1, NVR( I ) = EPS330 CONTINUEELSE** Scale supplied initial vector.*VNORM = DNRM2( N, VR, 1 )CALL DSCAL( N, ( EPS3*ROOTN ) / MAX( VNORM, NRMSML ), VR,$ 1 )END IF*IF( RIGHTV ) THEN** LU decomposition with partial pivoting of B, replacing zero* pivots by EPS3.*DO 60 I = 1, N - 1EI = H( I+1, I )IF( ABS( B( I, I ) ).LT.ABS( EI ) ) THEN** Interchange rows and eliminate.*X = B( I, I ) / EIB( I, I ) = EIDO 40 J = I + 1, NTEMP = B( I+1, J )B( I+1, J ) = B( I, J ) - X*TEMPB( I, J ) = TEMP40 CONTINUEELSE** Eliminate without interchange.*IF( B( I, I ).EQ.ZERO )$ B( I, I ) = EPS3X = EI / B( I, I )IF( X.NE.ZERO ) THENDO 50 J = I + 1, NB( I+1, J ) = B( I+1, J ) - X*B( I, J )50 CONTINUEEND IFEND IF60 CONTINUEIF( B( N, N ).EQ.ZERO )$ B( N, N ) = EPS3*TRANS = 'N'*ELSE** UL decomposition with partial pivoting of B, replacing zero* pivots by EPS3.*DO 90 J = N, 2, -1EJ = H( J, J-1 )IF( ABS( B( J, J ) ).LT.ABS( EJ ) ) THEN** Interchange columns and eliminate.*X = B( J, J ) / EJB( J, J ) = EJDO 70 I = 1, J - 1TEMP = B( I, J-1 )B( I, J-1 ) = B( I, J ) - X*TEMPB( I, J ) = TEMP70 CONTINUEELSE** Eliminate without interchange.*IF( B( J, J ).EQ.ZERO )$ B( J, J ) = EPS3X = EJ / B( J, J )IF( X.NE.ZERO ) THENDO 80 I = 1, J - 1B( I, J-1 ) = B( I, J-1 ) - X*B( I, J )80 CONTINUEEND IFEND IF90 CONTINUEIF( B( 1, 1 ).EQ.ZERO )$ B( 1, 1 ) = EPS3*TRANS = 'T'*END IF*NORMIN = 'N'DO 110 ITS = 1, N** Solve U*x = scale*v for a right eigenvector* or U**T*x = scale*v for a left eigenvector,* overwriting x on v.*CALL DLATRS( 'Upper', TRANS, 'Nonunit', NORMIN, N, B, LDB,$ VR, SCALE, WORK, IERR )NORMIN = 'Y'** Test for sufficient growth in the norm of v.*VNORM = DASUM( N, VR, 1 )IF( VNORM.GE.GROWTO*SCALE )$ GO TO 120** Choose new orthogonal starting vector and try again.*TEMP = EPS3 / ( ROOTN+ONE )VR( 1 ) = EPS3DO 100 I = 2, NVR( I ) = TEMP100 CONTINUEVR( N-ITS+1 ) = VR( N-ITS+1 ) - EPS3*ROOTN110 CONTINUE** Failure to find eigenvector in N iterations.*INFO = 1*120 CONTINUE** Normalize eigenvector.*I = IDAMAX( N, VR, 1 )CALL DSCAL( N, ONE / ABS( VR( I ) ), VR, 1 )ELSE** Complex eigenvalue.*IF( NOINIT ) THEN** Set initial vector.*DO 130 I = 1, NVR( I ) = EPS3VI( I ) = ZERO130 CONTINUEELSE** Scale supplied initial vector.*NORM = DLAPY2( DNRM2( N, VR, 1 ), DNRM2( N, VI, 1 ) )REC = ( EPS3*ROOTN ) / MAX( NORM, NRMSML )CALL DSCAL( N, REC, VR, 1 )CALL DSCAL( N, REC, VI, 1 )END IF*IF( RIGHTV ) THEN** LU decomposition with partial pivoting of B, replacing zero* pivots by EPS3.** The imaginary part of the (i,j)-th element of U is stored in* B(j+1,i).*B( 2, 1 ) = -WIDO 140 I = 2, NB( I+1, 1 ) = ZERO140 CONTINUE*DO 170 I = 1, N - 1ABSBII = DLAPY2( B( I, I ), B( I+1, I ) )EI = H( I+1, I )IF( ABSBII.LT.ABS( EI ) ) THEN** Interchange rows and eliminate.*XR = B( I, I ) / EIXI = B( I+1, I ) / EIB( I, I ) = EIB( I+1, I ) = ZERODO 150 J = I + 1, NTEMP = B( I+1, J )B( I+1, J ) = B( I, J ) - XR*TEMPB( J+1, I+1 ) = B( J+1, I ) - XI*TEMPB( I, J ) = TEMPB( J+1, I ) = ZERO150 CONTINUEB( I+2, I ) = -WIB( I+1, I+1 ) = B( I+1, I+1 ) - XI*WIB( I+2, I+1 ) = B( I+2, I+1 ) + XR*WIELSE** Eliminate without interchanging rows.*IF( ABSBII.EQ.ZERO ) THENB( I, I ) = EPS3B( I+1, I ) = ZEROABSBII = EPS3END IFEI = ( EI / ABSBII ) / ABSBIIXR = B( I, I )*EIXI = -B( I+1, I )*EIDO 160 J = I + 1, NB( I+1, J ) = B( I+1, J ) - XR*B( I, J ) +$ XI*B( J+1, I )B( J+1, I+1 ) = -XR*B( J+1, I ) - XI*B( I, J )160 CONTINUEB( I+2, I+1 ) = B( I+2, I+1 ) - WIEND IF** Compute 1-norm of offdiagonal elements of i-th row.*WORK( I ) = DASUM( N-I, B( I, I+1 ), LDB ) +$ DASUM( N-I, B( I+2, I ), 1 )170 CONTINUEIF( B( N, N ).EQ.ZERO .AND. B( N+1, N ).EQ.ZERO )$ B( N, N ) = EPS3WORK( N ) = ZERO*I1 = NI2 = 1I3 = -1ELSE** UL decomposition with partial pivoting of conjg(B),* replacing zero pivots by EPS3.** The imaginary part of the (i,j)-th element of U is stored in* B(j+1,i).*B( N+1, N ) = WIDO 180 J = 1, N - 1B( N+1, J ) = ZERO180 CONTINUE*DO 210 J = N, 2, -1EJ = H( J, J-1 )ABSBJJ = DLAPY2( B( J, J ), B( J+1, J ) )IF( ABSBJJ.LT.ABS( EJ ) ) THEN** Interchange columns and eliminate*XR = B( J, J ) / EJXI = B( J+1, J ) / EJB( J, J ) = EJB( J+1, J ) = ZERODO 190 I = 1, J - 1TEMP = B( I, J-1 )B( I, J-1 ) = B( I, J ) - XR*TEMPB( J, I ) = B( J+1, I ) - XI*TEMPB( I, J ) = TEMPB( J+1, I ) = ZERO190 CONTINUEB( J+1, J-1 ) = WIB( J-1, J-1 ) = B( J-1, J-1 ) + XI*WIB( J, J-1 ) = B( J, J-1 ) - XR*WIELSE** Eliminate without interchange.*IF( ABSBJJ.EQ.ZERO ) THENB( J, J ) = EPS3B( J+1, J ) = ZEROABSBJJ = EPS3END IFEJ = ( EJ / ABSBJJ ) / ABSBJJXR = B( J, J )*EJXI = -B( J+1, J )*EJDO 200 I = 1, J - 1B( I, J-1 ) = B( I, J-1 ) - XR*B( I, J ) +$ XI*B( J+1, I )B( J, I ) = -XR*B( J+1, I ) - XI*B( I, J )200 CONTINUEB( J, J-1 ) = B( J, J-1 ) + WIEND IF** Compute 1-norm of offdiagonal elements of j-th column.*WORK( J ) = DASUM( J-1, B( 1, J ), 1 ) +$ DASUM( J-1, B( J+1, 1 ), LDB )210 CONTINUEIF( B( 1, 1 ).EQ.ZERO .AND. B( 2, 1 ).EQ.ZERO )$ B( 1, 1 ) = EPS3WORK( 1 ) = ZERO*I1 = 1I2 = NI3 = 1END IF*DO 270 ITS = 1, NSCALE = ONEVMAX = ONEVCRIT = BIGNUM** Solve U*(xr,xi) = scale*(vr,vi) for a right eigenvector,* or U**T*(xr,xi) = scale*(vr,vi) for a left eigenvector,* overwriting (xr,xi) on (vr,vi).*DO 250 I = I1, I2, I3*IF( WORK( I ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N, REC, VR, 1 )CALL DSCAL( N, REC, VI, 1 )SCALE = SCALE*RECVMAX = ONEVCRIT = BIGNUMEND IF*XR = VR( I )XI = VI( I )IF( RIGHTV ) THENDO 220 J = I + 1, NXR = XR - B( I, J )*VR( J ) + B( J+1, I )*VI( J )XI = XI - B( I, J )*VI( J ) - B( J+1, I )*VR( J )220 CONTINUEELSEDO 230 J = 1, I - 1XR = XR - B( J, I )*VR( J ) + B( I+1, J )*VI( J )XI = XI - B( J, I )*VI( J ) - B( I+1, J )*VR( J )230 CONTINUEEND IF*W = ABS( B( I, I ) ) + ABS( B( I+1, I ) )IF( W.GT.SMLNUM ) THENIF( W.LT.ONE ) THENW1 = ABS( XR ) + ABS( XI )IF( W1.GT.W*BIGNUM ) THENREC = ONE / W1CALL DSCAL( N, REC, VR, 1 )CALL DSCAL( N, REC, VI, 1 )XR = VR( I )XI = VI( I )SCALE = SCALE*RECVMAX = VMAX*RECEND IFEND IF** Divide by diagonal element of B.*CALL DLADIV( XR, XI, B( I, I ), B( I+1, I ), VR( I ),$ VI( I ) )VMAX = MAX( ABS( VR( I ) )+ABS( VI( I ) ), VMAX )VCRIT = BIGNUM / VMAXELSEDO 240 J = 1, NVR( J ) = ZEROVI( J ) = ZERO240 CONTINUEVR( I ) = ONEVI( I ) = ONESCALE = ZEROVMAX = ONEVCRIT = BIGNUMEND IF250 CONTINUE** Test for sufficient growth in the norm of (VR,VI).*VNORM = DASUM( N, VR, 1 ) + DASUM( N, VI, 1 )IF( VNORM.GE.GROWTO*SCALE )$ GO TO 280** Choose a new orthogonal starting vector and try again.*Y = EPS3 / ( ROOTN+ONE )VR( 1 ) = EPS3VI( 1 ) = ZERO*DO 260 I = 2, NVR( I ) = YVI( I ) = ZERO260 CONTINUEVR( N-ITS+1 ) = VR( N-ITS+1 ) - EPS3*ROOTN270 CONTINUE** Failure to find eigenvector in N iterations*INFO = 1*280 CONTINUE** Normalize eigenvector.*VNORM = ZERODO 290 I = 1, NVNORM = MAX( VNORM, ABS( VR( I ) )+ABS( VI( I ) ) )290 CONTINUECALL DSCAL( N, ONE / VNORM, VR, 1 )CALL DSCAL( N, ONE / VNORM, VI, 1 )*END IF*RETURN** End of DLAEIN*END*> \brief \b DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAEV2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaev2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaev2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaev2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAEV2( A, B, C, RT1, RT2, CS1, SN1 )** .. Scalar Arguments ..* DOUBLE PRECISION A, B, C, CS1, RT1, RT2, SN1* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAEV2 computes the eigendecomposition of a 2-by-2 symmetric matrix*> [ A B ]*> [ B C ].*> On return, RT1 is the eigenvalue of larger absolute value, RT2 is the*> eigenvalue of smaller absolute value, and (CS1,SN1) is the unit right*> eigenvector for RT1, giving the decomposition*>*> [ CS1 SN1 ] [ A B ] [ CS1 -SN1 ] = [ RT1 0 ]*> [-SN1 CS1 ] [ B C ] [ SN1 CS1 ] [ 0 RT2 ].*> \endverbatim** Arguments:* ==========**> \param[in] A*> \verbatim*> A is DOUBLE PRECISION*> The (1,1) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION*> The (1,2) element and the conjugate of the (2,1) element of*> the 2-by-2 matrix.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION*> The (2,2) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[out] RT1*> \verbatim*> RT1 is DOUBLE PRECISION*> The eigenvalue of larger absolute value.*> \endverbatim*>*> \param[out] RT2*> \verbatim*> RT2 is DOUBLE PRECISION*> The eigenvalue of smaller absolute value.*> \endverbatim*>*> \param[out] CS1*> \verbatim*> CS1 is DOUBLE PRECISION*> \endverbatim*>*> \param[out] SN1*> \verbatim*> SN1 is DOUBLE PRECISION*> The vector (CS1, SN1) is a unit right eigenvector for RT1.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> RT1 is accurate to a few ulps barring over/underflow.*>*> RT2 may be inaccurate if there is massive cancellation in the*> determinant A*C-B*B; higher precision or correctly rounded or*> correctly truncated arithmetic would be needed to compute RT2*> accurately in all cases.*>*> CS1 and SN1 are accurate to a few ulps barring over/underflow.*>*> Overflow is possible only if RT1 is within a factor of 5 of overflow.*> Underflow is harmless if the input data is 0 or exceeds*> underflow_threshold / macheps.*> \endverbatim*>* =====================================================================SUBROUTINE DLAEV2( A, B, C, RT1, RT2, CS1, SN1 )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION A, B, C, CS1, RT1, RT2, SN1* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )* ..* .. Local Scalars ..INTEGER SGN1, SGN2DOUBLE PRECISION AB, ACMN, ACMX, ACS, ADF, CS, CT, DF, RT, SM,$ TB, TN* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..** Compute the eigenvalues*SM = A + CDF = A - CADF = ABS( DF )TB = B + BAB = ABS( TB )IF( ABS( A ).GT.ABS( C ) ) THENACMX = AACMN = CELSEACMX = CACMN = AEND IFIF( ADF.GT.AB ) THENRT = ADF*SQRT( ONE+( AB / ADF )**2 )ELSE IF( ADF.LT.AB ) THENRT = AB*SQRT( ONE+( ADF / AB )**2 )ELSE** Includes case AB=ADF=0*RT = AB*SQRT( TWO )END IFIF( SM.LT.ZERO ) THENRT1 = HALF*( SM-RT )SGN1 = -1** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE IF( SM.GT.ZERO ) THENRT1 = HALF*( SM+RT )SGN1 = 1** Order of execution important.* To get fully accurate smaller eigenvalue,* next line needs to be executed in higher precision.*RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*BELSE** Includes case RT1 = RT2 = 0*RT1 = HALF*RTRT2 = -HALF*RTSGN1 = 1END IF** Compute the eigenvector*IF( DF.GE.ZERO ) THENCS = DF + RTSGN2 = 1ELSECS = DF - RTSGN2 = -1END IFACS = ABS( CS )IF( ACS.GT.AB ) THENCT = -TB / CSSN1 = ONE / SQRT( ONE+CT*CT )CS1 = CT*SN1ELSEIF( AB.EQ.ZERO ) THENCS1 = ONESN1 = ZEROELSETN = -CS / TBCS1 = ONE / SQRT( ONE+TN*TN )SN1 = TN*CS1END IFEND IFIF( SGN1.EQ.SGN2 ) THENTN = CS1CS1 = -SN1SN1 = TNEND IFRETURN** End of DLAEV2*END*> \brief \b DLAEXC swaps adjacent diagonal blocks of a real upper quasi-triangular matrix in Schur canonical form, by an orthogonal similarity transformation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAEXC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaexc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaexc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaexc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,* INFO )** .. Scalar Arguments ..* LOGICAL WANTQ* INTEGER INFO, J1, LDQ, LDT, N, N1, N2* ..* .. Array Arguments ..* DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in*> an upper quasi-triangular matrix T by an orthogonal similarity*> transformation.*>*> T must be in Schur canonical form, that is, block upper triangular*> with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block*> has its diagonal elemnts equal and its off-diagonal elements of*> opposite sign.*> \endverbatim** Arguments:* ==========**> \param[in] WANTQ*> \verbatim*> WANTQ is LOGICAL*> = .TRUE. : accumulate the transformation in the matrix Q;*> = .FALSE.: do not accumulate the transformation.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T. N >= 0.*> \endverbatim*>*> \param[in,out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> On entry, the upper quasi-triangular matrix T, in Schur*> canonical form.*> On exit, the updated matrix T, again in Schur canonical form.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if WANTQ is .TRUE., the orthogonal matrix Q.*> On exit, if WANTQ is .TRUE., the updated matrix Q.*> If WANTQ is .FALSE., Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q.*> LDQ >= 1; and if WANTQ is .TRUE., LDQ >= N.*> \endverbatim*>*> \param[in] J1*> \verbatim*> J1 is INTEGER*> The index of the first row of the first block T11.*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> The order of the first block T11. N1 = 0, 1 or 2.*> \endverbatim*>*> \param[in] N2*> \verbatim*> N2 is INTEGER*> The order of the second block T22. N2 = 0, 1 or 2.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> = 1: the transformed matrix T would be too far from Schur*> form; the blocks are not swapped and T and Q are*> unchanged.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAEXC( WANTQ, N, T, LDT, Q, LDQ, J1, N1, N2, WORK,$ INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL WANTQINTEGER INFO, J1, LDQ, LDT, N, N1, N2* ..* .. Array Arguments ..DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TENPARAMETER ( TEN = 1.0D+1 )INTEGER LDD, LDXPARAMETER ( LDD = 4, LDX = 2 )* ..* .. Local Scalars ..INTEGER IERR, J2, J3, J4, K, NDDOUBLE PRECISION CS, DNORM, EPS, SCALE, SMLNUM, SN, T11, T22,$ T33, TAU, TAU1, TAU2, TEMP, THRESH, WI1, WI2,$ WR1, WR2, XNORM* ..* .. Local Arrays ..DOUBLE PRECISION D( LDD, 4 ), U( 3 ), U1( 3 ), U2( 3 ),$ X( LDX, 2 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLANGEEXTERNAL DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DLACPY, DLANV2, DLARFG, DLARFX, DLARTG, DLASY2,$ DROT* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.EQ.0 .OR. N1.EQ.0 .OR. N2.EQ.0 )$ RETURNIF( J1+N1.GT.N )$ RETURN*J2 = J1 + 1J3 = J1 + 2J4 = J1 + 3*IF( N1.EQ.1 .AND. N2.EQ.1 ) THEN** Swap two 1-by-1 blocks.*T11 = T( J1, J1 )T22 = T( J2, J2 )** Determine the transformation to perform the interchange.*CALL DLARTG( T( J1, J2 ), T22-T11, CS, SN, TEMP )** Apply transformation to the matrix T.*IF( J3.LE.N )$ CALL DROT( N-J1-1, T( J1, J3 ), LDT, T( J2, J3 ), LDT, CS,$ SN )CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )*T( J1, J1 ) = T22T( J2, J2 ) = T11*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )END IF*ELSE** Swapping involves at least one 2-by-2 block.** Copy the diagonal block of order N1+N2 to the local array D* and compute its norm.*ND = N1 + N2CALL DLACPY( 'Full', ND, ND, T( J1, J1 ), LDT, D, LDD )DNORM = DLANGE( 'Max', ND, ND, D, LDD, WORK )** Compute machine-dependent threshold for test for accepting* swap.*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSTHRESH = MAX( TEN*EPS*DNORM, SMLNUM )** Solve T11*X - X*T22 = scale*T12 for X.*CALL DLASY2( .FALSE., .FALSE., -1, N1, N2, D, LDD,$ D( N1+1, N1+1 ), LDD, D( 1, N1+1 ), LDD, SCALE, X,$ LDX, XNORM, IERR )** Swap the adjacent diagonal blocks.*K = N1 + N1 + N2 - 3GO TO ( 10, 20, 30 )K*10 CONTINUE** N1 = 1, N2 = 2: generate elementary reflector H so that:** ( scale, X11, X12 ) H = ( 0, 0, * )*U( 1 ) = SCALEU( 2 ) = X( 1, 1 )U( 3 ) = X( 1, 2 )CALL DLARFG( 3, U( 3 ), U, 1, TAU )U( 3 ) = ONET11 = T( J1, J1 )** Perform swap provisionally on diagonal block in D.*CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )** Test whether to reject swap.*IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 3,$ 3 )-T11 ) ).GT.THRESH )GO TO 50** Accept swap: apply transformation to the entire matrix T.*CALL DLARFX( 'L', 3, N-J1+1, U, TAU, T( J1, J1 ), LDT, WORK )CALL DLARFX( 'R', J2, 3, U, TAU, T( 1, J1 ), LDT, WORK )*T( J3, J1 ) = ZEROT( J3, J2 ) = ZEROT( J3, J3 ) = T11*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )END IFGO TO 40*20 CONTINUE** N1 = 2, N2 = 1: generate elementary reflector H so that:** H ( -X11 ) = ( * )* ( -X21 ) = ( 0 )* ( scale ) = ( 0 )*U( 1 ) = -X( 1, 1 )U( 2 ) = -X( 2, 1 )U( 3 ) = SCALECALL DLARFG( 3, U( 1 ), U( 2 ), 1, TAU )U( 1 ) = ONET33 = T( J3, J3 )** Perform swap provisionally on diagonal block in D.*CALL DLARFX( 'L', 3, 3, U, TAU, D, LDD, WORK )CALL DLARFX( 'R', 3, 3, U, TAU, D, LDD, WORK )** Test whether to reject swap.*IF( MAX( ABS( D( 2, 1 ) ), ABS( D( 3, 1 ) ), ABS( D( 1,$ 1 )-T33 ) ).GT.THRESH )GO TO 50** Accept swap: apply transformation to the entire matrix T.*CALL DLARFX( 'R', J3, 3, U, TAU, T( 1, J1 ), LDT, WORK )CALL DLARFX( 'L', 3, N-J1, U, TAU, T( J1, J2 ), LDT, WORK )*T( J1, J1 ) = T33T( J2, J1 ) = ZEROT( J3, J1 ) = ZERO*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DLARFX( 'R', N, 3, U, TAU, Q( 1, J1 ), LDQ, WORK )END IFGO TO 40*30 CONTINUE** N1 = 2, N2 = 2: generate elementary reflectors H(1) and H(2) so* that:** H(2) H(1) ( -X11 -X12 ) = ( * * )* ( -X21 -X22 ) ( 0 * )* ( scale 0 ) ( 0 0 )* ( 0 scale ) ( 0 0 )*U1( 1 ) = -X( 1, 1 )U1( 2 ) = -X( 2, 1 )U1( 3 ) = SCALECALL DLARFG( 3, U1( 1 ), U1( 2 ), 1, TAU1 )U1( 1 ) = ONE*TEMP = -TAU1*( X( 1, 2 )+U1( 2 )*X( 2, 2 ) )U2( 1 ) = -TEMP*U1( 2 ) - X( 2, 2 )U2( 2 ) = -TEMP*U1( 3 )U2( 3 ) = SCALECALL DLARFG( 3, U2( 1 ), U2( 2 ), 1, TAU2 )U2( 1 ) = ONE** Perform swap provisionally on diagonal block in D.*CALL DLARFX( 'L', 3, 4, U1, TAU1, D, LDD, WORK )CALL DLARFX( 'R', 4, 3, U1, TAU1, D, LDD, WORK )CALL DLARFX( 'L', 3, 4, U2, TAU2, D( 2, 1 ), LDD, WORK )CALL DLARFX( 'R', 4, 3, U2, TAU2, D( 1, 2 ), LDD, WORK )** Test whether to reject swap.*IF( MAX( ABS( D( 3, 1 ) ), ABS( D( 3, 2 ) ), ABS( D( 4, 1 ) ),$ ABS( D( 4, 2 ) ) ).GT.THRESH )GO TO 50** Accept swap: apply transformation to the entire matrix T.*CALL DLARFX( 'L', 3, N-J1+1, U1, TAU1, T( J1, J1 ), LDT, WORK )CALL DLARFX( 'R', J4, 3, U1, TAU1, T( 1, J1 ), LDT, WORK )CALL DLARFX( 'L', 3, N-J1+1, U2, TAU2, T( J2, J1 ), LDT, WORK )CALL DLARFX( 'R', J4, 3, U2, TAU2, T( 1, J2 ), LDT, WORK )*T( J3, J1 ) = ZEROT( J3, J2 ) = ZEROT( J4, J1 ) = ZEROT( J4, J2 ) = ZERO*IF( WANTQ ) THEN** Accumulate transformation in the matrix Q.*CALL DLARFX( 'R', N, 3, U1, TAU1, Q( 1, J1 ), LDQ, WORK )CALL DLARFX( 'R', N, 3, U2, TAU2, Q( 1, J2 ), LDQ, WORK )END IF*40 CONTINUE*IF( N2.EQ.2 ) THEN** Standardize new 2-by-2 block T11*CALL DLANV2( T( J1, J1 ), T( J1, J2 ), T( J2, J1 ),$ T( J2, J2 ), WR1, WI1, WR2, WI2, CS, SN )CALL DROT( N-J1-1, T( J1, J1+2 ), LDT, T( J2, J1+2 ), LDT,$ CS, SN )CALL DROT( J1-1, T( 1, J1 ), 1, T( 1, J2 ), 1, CS, SN )IF( WANTQ )$ CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J2 ), 1, CS, SN )END IF*IF( N1.EQ.2 ) THEN** Standardize new 2-by-2 block T22*J3 = J1 + N2J4 = J3 + 1CALL DLANV2( T( J3, J3 ), T( J3, J4 ), T( J4, J3 ),$ T( J4, J4 ), WR1, WI1, WR2, WI2, CS, SN )IF( J3+2.LE.N )$ CALL DROT( N-J3-1, T( J3, J3+2 ), LDT, T( J4, J3+2 ),$ LDT, CS, SN )CALL DROT( J3-1, T( 1, J3 ), 1, T( 1, J4 ), 1, CS, SN )IF( WANTQ )$ CALL DROT( N, Q( 1, J3 ), 1, Q( 1, J4 ), 1, CS, SN )END IF*END IFRETURN** Exit with INFO = 1 if swap was rejected.*50 CONTINUEINFO = 1RETURN** End of DLAEXC*END*> \brief \b DLAG2 computes the eigenvalues of a 2-by-2 generalized eigenvalue problem, with scaling as necessary to avoid over-/underflow.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAG2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlag2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlag2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlag2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,* WR2, WI )** .. Scalar Arguments ..* INTEGER LDA, LDB* DOUBLE PRECISION SAFMIN, SCALE1, SCALE2, WI, WR1, WR2* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAG2 computes the eigenvalues of a 2 x 2 generalized eigenvalue*> problem A - w B, with scaling as necessary to avoid over-/underflow.*>*> The scaling factor "s" results in a modified eigenvalue equation*>*> s A - w B*>*> where s is a non-negative scaling factor chosen so that w, w B,*> and s A do not overflow and, if possible, do not underflow, either.*> \endverbatim** Arguments:* ==========**> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, 2)*> On entry, the 2 x 2 matrix A. It is assumed that its 1-norm*> is less than 1/SAFMIN. Entries less than*> sqrt(SAFMIN)*norm(A) are subject to being treated as zero.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= 2.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, 2)*> On entry, the 2 x 2 upper triangular matrix B. It is*> assumed that the one-norm of B is less than 1/SAFMIN. The*> diagonals should be at least sqrt(SAFMIN) times the largest*> element of B (in absolute value); if a diagonal is smaller*> than that, then +/- sqrt(SAFMIN) will be used instead of*> that diagonal.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= 2.*> \endverbatim*>*> \param[in] SAFMIN*> \verbatim*> SAFMIN is DOUBLE PRECISION*> The smallest positive number s.t. 1/SAFMIN does not*> overflow. (This should always be DLAMCH('S') -- it is an*> argument in order to avoid having to call DLAMCH frequently.)*> \endverbatim*>*> \param[out] SCALE1*> \verbatim*> SCALE1 is DOUBLE PRECISION*> A scaling factor used to avoid over-/underflow in the*> eigenvalue equation which defines the first eigenvalue. If*> the eigenvalues are complex, then the eigenvalues are*> ( WR1 +/- WI i ) / SCALE1 (which may lie outside the*> exponent range of the machine), SCALE1=SCALE2, and SCALE1*> will always be positive. If the eigenvalues are real, then*> the first (real) eigenvalue is WR1 / SCALE1 , but this may*> overflow or underflow, and in fact, SCALE1 may be zero or*> less than the underflow threshold if the exact eigenvalue*> is sufficiently large.*> \endverbatim*>*> \param[out] SCALE2*> \verbatim*> SCALE2 is DOUBLE PRECISION*> A scaling factor used to avoid over-/underflow in the*> eigenvalue equation which defines the second eigenvalue. If*> the eigenvalues are complex, then SCALE2=SCALE1. If the*> eigenvalues are real, then the second (real) eigenvalue is*> WR2 / SCALE2 , but this may overflow or underflow, and in*> fact, SCALE2 may be zero or less than the underflow*> threshold if the exact eigenvalue is sufficiently large.*> \endverbatim*>*> \param[out] WR1*> \verbatim*> WR1 is DOUBLE PRECISION*> If the eigenvalue is real, then WR1 is SCALE1 times the*> eigenvalue closest to the (2,2) element of A B**(-1). If the*> eigenvalue is complex, then WR1=WR2 is SCALE1 times the real*> part of the eigenvalues.*> \endverbatim*>*> \param[out] WR2*> \verbatim*> WR2 is DOUBLE PRECISION*> If the eigenvalue is real, then WR2 is SCALE2 times the*> other eigenvalue. If the eigenvalue is complex, then*> WR1=WR2 is SCALE1 times the real part of the eigenvalues.*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION*> If the eigenvalue is real, then WI is zero. If the*> eigenvalue is complex, then WI is SCALE1 times the imaginary*> part of the eigenvalues. WI will always be non-negative.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,$ WR2, WI )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER LDA, LDBDOUBLE PRECISION SAFMIN, SCALE1, SCALE2, WI, WR1, WR2* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )DOUBLE PRECISION HALFPARAMETER ( HALF = ONE / TWO )DOUBLE PRECISION FUZZY1PARAMETER ( FUZZY1 = ONE+1.0D-5 )* ..* .. Local Scalars ..DOUBLE PRECISION A11, A12, A21, A22, ABI22, ANORM, AS11, AS12,$ AS22, ASCALE, B11, B12, B22, BINV11, BINV22,$ BMIN, BNORM, BSCALE, BSIZE, C1, C2, C3, C4, C5,$ DIFF, DISCR, PP, QQ, R, RTMAX, RTMIN, S1, S2,$ SAFMAX, SHIFT, SS, SUM, WABS, WBIG, WDET,$ WSCALE, WSIZE, WSMALL* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..*RTMIN = SQRT( SAFMIN )RTMAX = ONE / RTMINSAFMAX = ONE / SAFMIN** Scale A*ANORM = MAX( ABS( A( 1, 1 ) )+ABS( A( 2, 1 ) ),$ ABS( A( 1, 2 ) )+ABS( A( 2, 2 ) ), SAFMIN )ASCALE = ONE / ANORMA11 = ASCALE*A( 1, 1 )A21 = ASCALE*A( 2, 1 )A12 = ASCALE*A( 1, 2 )A22 = ASCALE*A( 2, 2 )** Perturb B if necessary to insure non-singularity*B11 = B( 1, 1 )B12 = B( 1, 2 )B22 = B( 2, 2 )BMIN = RTMIN*MAX( ABS( B11 ), ABS( B12 ), ABS( B22 ), RTMIN )IF( ABS( B11 ).LT.BMIN )$ B11 = SIGN( BMIN, B11 )IF( ABS( B22 ).LT.BMIN )$ B22 = SIGN( BMIN, B22 )** Scale B*BNORM = MAX( ABS( B11 ), ABS( B12 )+ABS( B22 ), SAFMIN )BSIZE = MAX( ABS( B11 ), ABS( B22 ) )BSCALE = ONE / BSIZEB11 = B11*BSCALEB12 = B12*BSCALEB22 = B22*BSCALE** Compute larger eigenvalue by method described by C. van Loan** ( AS is A shifted by -SHIFT*B )*BINV11 = ONE / B11BINV22 = ONE / B22S1 = A11*BINV11S2 = A22*BINV22IF( ABS( S1 ).LE.ABS( S2 ) ) THENAS12 = A12 - S1*B12AS22 = A22 - S1*B22SS = A21*( BINV11*BINV22 )ABI22 = AS22*BINV22 - SS*B12PP = HALF*ABI22SHIFT = S1ELSEAS12 = A12 - S2*B12AS11 = A11 - S2*B11SS = A21*( BINV11*BINV22 )ABI22 = -SS*B12PP = HALF*( AS11*BINV11+ABI22 )SHIFT = S2END IFQQ = SS*AS12IF( ABS( PP*RTMIN ).GE.ONE ) THENDISCR = ( RTMIN*PP )**2 + QQ*SAFMINR = SQRT( ABS( DISCR ) )*RTMAXELSEIF( PP**2+ABS( QQ ).LE.SAFMIN ) THENDISCR = ( RTMAX*PP )**2 + QQ*SAFMAXR = SQRT( ABS( DISCR ) )*RTMINELSEDISCR = PP**2 + QQR = SQRT( ABS( DISCR ) )END IFEND IF** Note: the test of R in the following IF is to cover the case when* DISCR is small and negative and is flushed to zero during* the calculation of R. On machines which have a consistent* flush-to-zero threshold and handle numbers above that* threshold correctly, it would not be necessary.*IF( DISCR.GE.ZERO .OR. R.EQ.ZERO ) THENSUM = PP + SIGN( R, PP )DIFF = PP - SIGN( R, PP )WBIG = SHIFT + SUM** Compute smaller eigenvalue*WSMALL = SHIFT + DIFFIF( HALF*ABS( WBIG ).GT.MAX( ABS( WSMALL ), SAFMIN ) ) THENWDET = ( A11*A22-A12*A21 )*( BINV11*BINV22 )WSMALL = WDET / WBIGEND IF** Choose (real) eigenvalue closest to 2,2 element of A*B**(-1)* for WR1.*IF( PP.GT.ABI22 ) THENWR1 = MIN( WBIG, WSMALL )WR2 = MAX( WBIG, WSMALL )ELSEWR1 = MAX( WBIG, WSMALL )WR2 = MIN( WBIG, WSMALL )END IFWI = ZEROELSE** Complex eigenvalues*WR1 = SHIFT + PPWR2 = WR1WI = REND IF** Further scaling to avoid underflow and overflow in computing* SCALE1 and overflow in computing w*B.** This scale factor (WSCALE) is bounded from above using C1 and C2,* and from below using C3 and C4.* C1 implements the condition s A must never overflow.* C2 implements the condition w B must never overflow.* C3, with C2,* implement the condition that s A - w B must never overflow.* C4 implements the condition s should not underflow.* C5 implements the condition max(s,|w|) should be at least 2.*C1 = BSIZE*( SAFMIN*MAX( ONE, ASCALE ) )C2 = SAFMIN*MAX( ONE, BNORM )C3 = BSIZE*SAFMINIF( ASCALE.LE.ONE .AND. BSIZE.LE.ONE ) THENC4 = MIN( ONE, ( ASCALE / SAFMIN )*BSIZE )ELSEC4 = ONEEND IFIF( ASCALE.LE.ONE .OR. BSIZE.LE.ONE ) THENC5 = MIN( ONE, ASCALE*BSIZE )ELSEC5 = ONEEND IF** Scale first eigenvalue*WABS = ABS( WR1 ) + ABS( WI )WSIZE = MAX( SAFMIN, C1, FUZZY1*( WABS*C2+C3 ),$ MIN( C4, HALF*MAX( WABS, C5 ) ) )IF( WSIZE.NE.ONE ) THENWSCALE = ONE / WSIZEIF( WSIZE.GT.ONE ) THENSCALE1 = ( MAX( ASCALE, BSIZE )*WSCALE )*$ MIN( ASCALE, BSIZE )ELSESCALE1 = ( MIN( ASCALE, BSIZE )*WSCALE )*$ MAX( ASCALE, BSIZE )END IFWR1 = WR1*WSCALEIF( WI.NE.ZERO ) THENWI = WI*WSCALEWR2 = WR1SCALE2 = SCALE1END IFELSESCALE1 = ASCALE*BSIZESCALE2 = SCALE1END IF** Scale second eigenvalue (if real)*IF( WI.EQ.ZERO ) THENWSIZE = MAX( SAFMIN, C1, FUZZY1*( ABS( WR2 )*C2+C3 ),$ MIN( C4, HALF*MAX( ABS( WR2 ), C5 ) ) )IF( WSIZE.NE.ONE ) THENWSCALE = ONE / WSIZEIF( WSIZE.GT.ONE ) THENSCALE2 = ( MAX( ASCALE, BSIZE )*WSCALE )*$ MIN( ASCALE, BSIZE )ELSESCALE2 = ( MIN( ASCALE, BSIZE )*WSCALE )*$ MAX( ASCALE, BSIZE )END IFWR2 = WR2*WSCALEELSESCALE2 = ASCALE*BSIZEEND IFEND IF** End of DLAG2*RETURNEND*> \brief \b DLAGS2 computes 2-by-2 orthogonal matrices U, V, and Q, and applies them to matrices A and B such that the rows of the transformed A and B are parallel.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAGS2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlags2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlags2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlags2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,* SNV, CSQ, SNQ )** .. Scalar Arguments ..* LOGICAL UPPER* DOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,* $ SNU, SNV* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAGS2 computes 2-by-2 orthogonal matrices U, V and Q, such*> that if ( UPPER ) then*>*> U**T *A*Q = U**T *( A1 A2 )*Q = ( x 0 )*> ( 0 A3 ) ( x x )*> and*> V**T*B*Q = V**T *( B1 B2 )*Q = ( x 0 )*> ( 0 B3 ) ( x x )*>*> or if ( .NOT.UPPER ) then*>*> U**T *A*Q = U**T *( A1 0 )*Q = ( x x )*> ( A2 A3 ) ( 0 x )*> and*> V**T*B*Q = V**T*( B1 0 )*Q = ( x x )*> ( B2 B3 ) ( 0 x )*>*> The rows of the transformed A and B are parallel, where*>*> U = ( CSU SNU ), V = ( CSV SNV ), Q = ( CSQ SNQ )*> ( -SNU CSU ) ( -SNV CSV ) ( -SNQ CSQ )*>*> Z**T denotes the transpose of Z.*>*> \endverbatim** Arguments:* ==========**> \param[in] UPPER*> \verbatim*> UPPER is LOGICAL*> = .TRUE.: the input matrices A and B are upper triangular.*> = .FALSE.: the input matrices A and B are lower triangular.*> \endverbatim*>*> \param[in] A1*> \verbatim*> A1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] A2*> \verbatim*> A2 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] A3*> \verbatim*> A3 is DOUBLE PRECISION*> On entry, A1, A2 and A3 are elements of the input 2-by-2*> upper (lower) triangular matrix A.*> \endverbatim*>*> \param[in] B1*> \verbatim*> B1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] B2*> \verbatim*> B2 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] B3*> \verbatim*> B3 is DOUBLE PRECISION*> On entry, B1, B2 and B3 are elements of the input 2-by-2*> upper (lower) triangular matrix B.*> \endverbatim*>*> \param[out] CSU*> \verbatim*> CSU is DOUBLE PRECISION*> \endverbatim*>*> \param[out] SNU*> \verbatim*> SNU is DOUBLE PRECISION*> The desired orthogonal matrix U.*> \endverbatim*>*> \param[out] CSV*> \verbatim*> CSV is DOUBLE PRECISION*> \endverbatim*>*> \param[out] SNV*> \verbatim*> SNV is DOUBLE PRECISION*> The desired orthogonal matrix V.*> \endverbatim*>*> \param[out] CSQ*> \verbatim*> CSQ is DOUBLE PRECISION*> \endverbatim*>*> \param[out] SNQ*> \verbatim*> SNQ is DOUBLE PRECISION*> The desired orthogonal matrix Q.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,$ SNV, CSQ, SNQ )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL UPPERDOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,$ SNU, SNV* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION A, AUA11, AUA12, AUA21, AUA22, AVB11, AVB12,$ AVB21, AVB22, B, C, CSL, CSR, D, R, S1, S2,$ SNL, SNR, UA11, UA11R, UA12, UA21, UA22, UA22R,$ VB11, VB11R, VB12, VB21, VB22, VB22R* ..* .. External Subroutines ..EXTERNAL DLARTG, DLASV2* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*IF( UPPER ) THEN** Input matrices A and B are upper triangular matrices** Form matrix C = A*adj(B) = ( a b )* ( 0 d )*A = A1*B3D = A3*B1B = A2*B1 - A1*B2** The SVD of real 2-by-2 triangular C** ( CSL -SNL )*( A B )*( CSR SNR ) = ( R 0 )* ( SNL CSL ) ( 0 D ) ( -SNR CSR ) ( 0 T )*CALL DLASV2( A, B, D, S1, S2, SNR, CSR, SNL, CSL )*IF( ABS( CSL ).GE.ABS( SNL ) .OR. ABS( CSR ).GE.ABS( SNR ) )$ THEN** Compute the (1,1) and (1,2) elements of U**T *A and V**T *B,* and (1,2) element of |U|**T *|A| and |V|**T *|B|.*UA11R = CSL*A1UA12 = CSL*A2 + SNL*A3*VB11R = CSR*B1VB12 = CSR*B2 + SNR*B3*AUA12 = ABS( CSL )*ABS( A2 ) + ABS( SNL )*ABS( A3 )AVB12 = ABS( CSR )*ABS( B2 ) + ABS( SNR )*ABS( B3 )** zero (1,2) elements of U**T *A and V**T *B*IF( ( ABS( UA11R )+ABS( UA12 ) ).NE.ZERO ) THENIF( AUA12 / ( ABS( UA11R )+ABS( UA12 ) ).LE.AVB12 /$ ( ABS( VB11R )+ABS( VB12 ) ) ) THENCALL DLARTG( -UA11R, UA12, CSQ, SNQ, R )ELSECALL DLARTG( -VB11R, VB12, CSQ, SNQ, R )END IFELSECALL DLARTG( -VB11R, VB12, CSQ, SNQ, R )END IF*CSU = CSLSNU = -SNLCSV = CSRSNV = -SNR*ELSE** Compute the (2,1) and (2,2) elements of U**T *A and V**T *B,* and (2,2) element of |U|**T *|A| and |V|**T *|B|.*UA21 = -SNL*A1UA22 = -SNL*A2 + CSL*A3*VB21 = -SNR*B1VB22 = -SNR*B2 + CSR*B3*AUA22 = ABS( SNL )*ABS( A2 ) + ABS( CSL )*ABS( A3 )AVB22 = ABS( SNR )*ABS( B2 ) + ABS( CSR )*ABS( B3 )** zero (2,2) elements of U**T*A and V**T*B, and then swap.*IF( ( ABS( UA21 )+ABS( UA22 ) ).NE.ZERO ) THENIF( AUA22 / ( ABS( UA21 )+ABS( UA22 ) ).LE.AVB22 /$ ( ABS( VB21 )+ABS( VB22 ) ) ) THENCALL DLARTG( -UA21, UA22, CSQ, SNQ, R )ELSECALL DLARTG( -VB21, VB22, CSQ, SNQ, R )END IFELSECALL DLARTG( -VB21, VB22, CSQ, SNQ, R )END IF*CSU = SNLSNU = CSLCSV = SNRSNV = CSR*END IF*ELSE** Input matrices A and B are lower triangular matrices** Form matrix C = A*adj(B) = ( a 0 )* ( c d )*A = A1*B3D = A3*B1C = A2*B3 - A3*B2** The SVD of real 2-by-2 triangular C** ( CSL -SNL )*( A 0 )*( CSR SNR ) = ( R 0 )* ( SNL CSL ) ( C D ) ( -SNR CSR ) ( 0 T )*CALL DLASV2( A, C, D, S1, S2, SNR, CSR, SNL, CSL )*IF( ABS( CSR ).GE.ABS( SNR ) .OR. ABS( CSL ).GE.ABS( SNL ) )$ THEN** Compute the (2,1) and (2,2) elements of U**T *A and V**T *B,* and (2,1) element of |U|**T *|A| and |V|**T *|B|.*UA21 = -SNR*A1 + CSR*A2UA22R = CSR*A3*VB21 = -SNL*B1 + CSL*B2VB22R = CSL*B3*AUA21 = ABS( SNR )*ABS( A1 ) + ABS( CSR )*ABS( A2 )AVB21 = ABS( SNL )*ABS( B1 ) + ABS( CSL )*ABS( B2 )** zero (2,1) elements of U**T *A and V**T *B.*IF( ( ABS( UA21 )+ABS( UA22R ) ).NE.ZERO ) THENIF( AUA21 / ( ABS( UA21 )+ABS( UA22R ) ).LE.AVB21 /$ ( ABS( VB21 )+ABS( VB22R ) ) ) THENCALL DLARTG( UA22R, UA21, CSQ, SNQ, R )ELSECALL DLARTG( VB22R, VB21, CSQ, SNQ, R )END IFELSECALL DLARTG( VB22R, VB21, CSQ, SNQ, R )END IF*CSU = CSRSNU = -SNRCSV = CSLSNV = -SNL*ELSE** Compute the (1,1) and (1,2) elements of U**T *A and V**T *B,* and (1,1) element of |U|**T *|A| and |V|**T *|B|.*UA11 = CSR*A1 + SNR*A2UA12 = SNR*A3*VB11 = CSL*B1 + SNL*B2VB12 = SNL*B3*AUA11 = ABS( CSR )*ABS( A1 ) + ABS( SNR )*ABS( A2 )AVB11 = ABS( CSL )*ABS( B1 ) + ABS( SNL )*ABS( B2 )** zero (1,1) elements of U**T*A and V**T*B, and then swap.*IF( ( ABS( UA11 )+ABS( UA12 ) ).NE.ZERO ) THENIF( AUA11 / ( ABS( UA11 )+ABS( UA12 ) ).LE.AVB11 /$ ( ABS( VB11 )+ABS( VB12 ) ) ) THENCALL DLARTG( UA12, UA11, CSQ, SNQ, R )ELSECALL DLARTG( VB12, VB11, CSQ, SNQ, R )END IFELSECALL DLARTG( VB12, VB11, CSQ, SNQ, R )END IF*CSU = SNRSNU = CSRCSV = SNLSNV = CSL*END IF*END IF*RETURN** End of DLAGS2*END*> \brief \b DLAGTF computes an LU factorization of a matrix T-λI, where T is a general tridiagonal matrix, and λ a scalar, using partial pivoting with row interchanges.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAGTF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlagtf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlagtf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlagtf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAGTF( N, A, LAMBDA, B, C, TOL, D, IN, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* DOUBLE PRECISION LAMBDA, TOL* ..* .. Array Arguments ..* INTEGER IN( * )* DOUBLE PRECISION A( * ), B( * ), C( * ), D( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAGTF factorizes the matrix (T - lambda*I), where T is an n by n*> tridiagonal matrix and lambda is a scalar, as*>*> T - lambda*I = PLU,*>*> where P is a permutation matrix, L is a unit lower tridiagonal matrix*> with at most one non-zero sub-diagonal elements per column and U is*> an upper triangular matrix with at most two non-zero super-diagonal*> elements per column.*>*> The factorization is obtained by Gaussian elimination with partial*> pivoting and implicit row scaling.*>*> The parameter LAMBDA is included in the routine so that DLAGTF may*> be used, in conjunction with DLAGTS, to obtain eigenvectors of T by*> inverse iteration.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (N)*> On entry, A must contain the diagonal elements of T.*>*> On exit, A is overwritten by the n diagonal elements of the*> upper triangular matrix U of the factorization of T.*> \endverbatim*>*> \param[in] LAMBDA*> \verbatim*> LAMBDA is DOUBLE PRECISION*> On entry, the scalar lambda.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (N-1)*> On entry, B must contain the (n-1) super-diagonal elements of*> T.*>*> On exit, B is overwritten by the (n-1) super-diagonal*> elements of the matrix U of the factorization of T.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N-1)*> On entry, C must contain the (n-1) sub-diagonal elements of*> T.*>*> On exit, C is overwritten by the (n-1) sub-diagonal elements*> of the matrix L of the factorization of T.*> \endverbatim*>*> \param[in] TOL*> \verbatim*> TOL is DOUBLE PRECISION*> On entry, a relative tolerance used to indicate whether or*> not the matrix (T - lambda*I) is nearly singular. TOL should*> normally be chose as approximately the largest relative error*> in the elements of T. For example, if the elements of T are*> correct to about 4 significant figures, then TOL should be*> set to about 5*10**(-4). If TOL is supplied as less than eps,*> where eps is the relative machine precision, then the value*> eps is used in place of TOL.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N-2)*> On exit, D is overwritten by the (n-2) second super-diagonal*> elements of the matrix U of the factorization of T.*> \endverbatim*>*> \param[out] IN*> \verbatim*> IN is INTEGER array, dimension (N)*> On exit, IN contains details of the permutation matrix P. If*> an interchange occurred at the kth step of the elimination,*> then IN(k) = 1, otherwise IN(k) = 0. The element IN(n)*> returns the smallest positive integer j such that*>*> abs( u(j,j) ).le. norm( (T - lambda*I)(j) )*TOL,*>*> where norm( A(j) ) denotes the sum of the absolute values of*> the jth row of the matrix A. If no such j exists then IN(n)*> is returned as zero. If IN(n) is returned as positive, then a*> diagonal element of U is small, indicating that*> (T - lambda*I) is singular or nearly singular,*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0 : successful exit*> .lt. 0: if INFO = -k, the kth argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLAGTF( N, A, LAMBDA, B, C, TOL, D, IN, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, NDOUBLE PRECISION LAMBDA, TOL* ..* .. Array Arguments ..INTEGER IN( * )DOUBLE PRECISION A( * ), B( * ), C( * ), D( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER KDOUBLE PRECISION EPS, MULT, PIV1, PIV2, SCALE1, SCALE2, TEMP, TL* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DLAGTF', -INFO )RETURNEND IF*IF( N.EQ.0 )$ RETURN*A( 1 ) = A( 1 ) - LAMBDAIN( N ) = 0IF( N.EQ.1 ) THENIF( A( 1 ).EQ.ZERO )$ IN( 1 ) = 1RETURNEND IF*EPS = DLAMCH( 'Epsilon' )*TL = MAX( TOL, EPS )SCALE1 = ABS( A( 1 ) ) + ABS( B( 1 ) )DO 10 K = 1, N - 1A( K+1 ) = A( K+1 ) - LAMBDASCALE2 = ABS( C( K ) ) + ABS( A( K+1 ) )IF( K.LT.( N-1 ) )$ SCALE2 = SCALE2 + ABS( B( K+1 ) )IF( A( K ).EQ.ZERO ) THENPIV1 = ZEROELSEPIV1 = ABS( A( K ) ) / SCALE1END IFIF( C( K ).EQ.ZERO ) THENIN( K ) = 0PIV2 = ZEROSCALE1 = SCALE2IF( K.LT.( N-1 ) )$ D( K ) = ZEROELSEPIV2 = ABS( C( K ) ) / SCALE2IF( PIV2.LE.PIV1 ) THENIN( K ) = 0SCALE1 = SCALE2C( K ) = C( K ) / A( K )A( K+1 ) = A( K+1 ) - C( K )*B( K )IF( K.LT.( N-1 ) )$ D( K ) = ZEROELSEIN( K ) = 1MULT = A( K ) / C( K )A( K ) = C( K )TEMP = A( K+1 )A( K+1 ) = B( K ) - MULT*TEMPIF( K.LT.( N-1 ) ) THEND( K ) = B( K+1 )B( K+1 ) = -MULT*D( K )END IFB( K ) = TEMPC( K ) = MULTEND IFEND IFIF( ( MAX( PIV1, PIV2 ).LE.TL ) .AND. ( IN( N ).EQ.0 ) )$ IN( N ) = K10 CONTINUEIF( ( ABS( A( N ) ).LE.SCALE1*TL ) .AND. ( IN( N ).EQ.0 ) )$ IN( N ) = N*RETURN** End of DLAGTF*END*> \brief \b DLAGTM performs a matrix-matrix product of the form C = αAB+βC, where A is a tridiagonal matrix, B and C are rectangular matrices, and α and β are scalars, which may be 0, 1, or -1.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAGTM + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlagtm.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlagtm.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlagtm.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAGTM( TRANS, N, NRHS, ALPHA, DL, D, DU, X, LDX, BETA,* B, LDB )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER LDB, LDX, N, NRHS* DOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAGTM performs a matrix-vector product of the form*>*> B := alpha * A * X + beta * B*>*> where A is a tridiagonal matrix of order N, B and X are N by NRHS*> matrices, and alpha and beta are real scalars, each of which may be*> 0., 1., or -1.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the operation applied to A.*> = 'N': No transpose, B := alpha * A * X + beta * B*> = 'T': Transpose, B := alpha * A'* X + beta * B*> = 'C': Conjugate transpose = Transpose*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices X and B.*> \endverbatim*>*> \param[in] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> The scalar alpha. ALPHA must be 0., 1., or -1.; otherwise,*> it is assumed to be 0.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) sub-diagonal elements of T.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of T.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) super-diagonal elements of T.*> \endverbatim*>*> \param[in] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> The N by NRHS matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(N,1).*> \endverbatim*>*> \param[in] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> The scalar beta. BETA must be 0., 1., or -1.; otherwise,*> it is assumed to be 1.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N by NRHS matrix B.*> On exit, B is overwritten by the matrix expression*> B := alpha * A * X + beta * B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(N,1).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAGTM( TRANS, N, NRHS, ALPHA, DL, D, DU, X, LDX, BETA,$ B, LDB )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER LDB, LDX, N, NRHSDOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), D( * ), DL( * ), DU( * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..*IF( N.EQ.0 )$ RETURN** Multiply B by BETA if BETA.NE.1.*IF( BETA.EQ.ZERO ) THENDO 20 J = 1, NRHSDO 10 I = 1, NB( I, J ) = ZERO10 CONTINUE20 CONTINUEELSE IF( BETA.EQ.-ONE ) THENDO 40 J = 1, NRHSDO 30 I = 1, NB( I, J ) = -B( I, J )30 CONTINUE40 CONTINUEEND IF*IF( ALPHA.EQ.ONE ) THENIF( LSAME( TRANS, 'N' ) ) THEN** Compute B := B + A*X*DO 60 J = 1, NRHSIF( N.EQ.1 ) THENB( 1, J ) = B( 1, J ) + D( 1 )*X( 1, J )ELSEB( 1, J ) = B( 1, J ) + D( 1 )*X( 1, J ) +$ DU( 1 )*X( 2, J )B( N, J ) = B( N, J ) + DL( N-1 )*X( N-1, J ) +$ D( N )*X( N, J )DO 50 I = 2, N - 1B( I, J ) = B( I, J ) + DL( I-1 )*X( I-1, J ) +$ D( I )*X( I, J ) + DU( I )*X( I+1, J )50 CONTINUEEND IF60 CONTINUEELSE** Compute B := B + A**T*X*DO 80 J = 1, NRHSIF( N.EQ.1 ) THENB( 1, J ) = B( 1, J ) + D( 1 )*X( 1, J )ELSEB( 1, J ) = B( 1, J ) + D( 1 )*X( 1, J ) +$ DL( 1 )*X( 2, J )B( N, J ) = B( N, J ) + DU( N-1 )*X( N-1, J ) +$ D( N )*X( N, J )DO 70 I = 2, N - 1B( I, J ) = B( I, J ) + DU( I-1 )*X( I-1, J ) +$ D( I )*X( I, J ) + DL( I )*X( I+1, J )70 CONTINUEEND IF80 CONTINUEEND IFELSE IF( ALPHA.EQ.-ONE ) THENIF( LSAME( TRANS, 'N' ) ) THEN** Compute B := B - A*X*DO 100 J = 1, NRHSIF( N.EQ.1 ) THENB( 1, J ) = B( 1, J ) - D( 1 )*X( 1, J )ELSEB( 1, J ) = B( 1, J ) - D( 1 )*X( 1, J ) -$ DU( 1 )*X( 2, J )B( N, J ) = B( N, J ) - DL( N-1 )*X( N-1, J ) -$ D( N )*X( N, J )DO 90 I = 2, N - 1B( I, J ) = B( I, J ) - DL( I-1 )*X( I-1, J ) -$ D( I )*X( I, J ) - DU( I )*X( I+1, J )90 CONTINUEEND IF100 CONTINUEELSE** Compute B := B - A**T*X*DO 120 J = 1, NRHSIF( N.EQ.1 ) THENB( 1, J ) = B( 1, J ) - D( 1 )*X( 1, J )ELSEB( 1, J ) = B( 1, J ) - D( 1 )*X( 1, J ) -$ DL( 1 )*X( 2, J )B( N, J ) = B( N, J ) - DU( N-1 )*X( N-1, J ) -$ D( N )*X( N, J )DO 110 I = 2, N - 1B( I, J ) = B( I, J ) - DU( I-1 )*X( I-1, J ) -$ D( I )*X( I, J ) - DL( I )*X( I+1, J )110 CONTINUEEND IF120 CONTINUEEND IFEND IFRETURN** End of DLAGTM*END*> \brief \b DLAGTS solves the system of equations (T-λI)x = y or (T-λI)Tx = y,where T is a general tridiagonal matrix and λ a scalar, using the LU factorization computed by slagtf.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAGTS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlagts.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlagts.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlagts.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAGTS( JOB, N, A, B, C, D, IN, Y, TOL, INFO )** .. Scalar Arguments ..* INTEGER INFO, JOB, N* DOUBLE PRECISION TOL* ..* .. Array Arguments ..* INTEGER IN( * )* DOUBLE PRECISION A( * ), B( * ), C( * ), D( * ), Y( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAGTS may be used to solve one of the systems of equations*>*> (T - lambda*I)*x = y or (T - lambda*I)**T*x = y,*>*> where T is an n by n tridiagonal matrix, for x, following the*> factorization of (T - lambda*I) as*>*> (T - lambda*I) = P*L*U ,*>*> by routine DLAGTF. The choice of equation to be solved is*> controlled by the argument JOB, and in each case there is an option*> to perturb zero or very small diagonal elements of U, this option*> being intended for use in applications such as inverse iteration.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is INTEGER*> Specifies the job to be performed by DLAGTS as follows:*> = 1: The equations (T - lambda*I)x = y are to be solved,*> but diagonal elements of U are not to be perturbed.*> = -1: The equations (T - lambda*I)x = y are to be solved*> and, if overflow would otherwise occur, the diagonal*> elements of U are to be perturbed. See argument TOL*> below.*> = 2: The equations (T - lambda*I)**Tx = y are to be solved,*> but diagonal elements of U are not to be perturbed.*> = -2: The equations (T - lambda*I)**Tx = y are to be solved*> and, if overflow would otherwise occur, the diagonal*> elements of U are to be perturbed. See argument TOL*> below.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (N)*> On entry, A must contain the diagonal elements of U as*> returned from DLAGTF.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (N-1)*> On entry, B must contain the first super-diagonal elements of*> U as returned from DLAGTF.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N-1)*> On entry, C must contain the sub-diagonal elements of L as*> returned from DLAGTF.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N-2)*> On entry, D must contain the second super-diagonal elements*> of U as returned from DLAGTF.*> \endverbatim*>*> \param[in] IN*> \verbatim*> IN is INTEGER array, dimension (N)*> On entry, IN must contain details of the matrix P as returned*> from DLAGTF.*> \endverbatim*>*> \param[in,out] Y*> \verbatim*> Y is DOUBLE PRECISION array, dimension (N)*> On entry, the right hand side vector y.*> On exit, Y is overwritten by the solution vector x.*> \endverbatim*>*> \param[in,out] TOL*> \verbatim*> TOL is DOUBLE PRECISION*> On entry, with JOB .lt. 0, TOL should be the minimum*> perturbation to be made to very small diagonal elements of U.*> TOL should normally be chosen as about eps*norm(U), where eps*> is the relative machine precision, but if TOL is supplied as*> non-positive, then it is reset to eps*max( abs( u(i,j) ) ).*> If JOB .gt. 0 then TOL is not referenced.*>*> On exit, TOL is changed as described above, only if TOL is*> non-positive on entry. Otherwise TOL is unchanged.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0 : successful exit*> .lt. 0: if INFO = -i, the i-th argument had an illegal value*> .gt. 0: overflow would occur when computing the INFO(th)*> element of the solution vector x. This can only occur*> when JOB is supplied as positive and either means*> that a diagonal element of U is very small, or that*> the elements of the right-hand side vector y are very*> large.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLAGTS( JOB, N, A, B, C, D, IN, Y, TOL, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, JOB, NDOUBLE PRECISION TOL* ..* .. Array Arguments ..INTEGER IN( * )DOUBLE PRECISION A( * ), B( * ), C( * ), D( * ), Y( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER KDOUBLE PRECISION ABSAK, AK, BIGNUM, EPS, PERT, SFMIN, TEMP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SIGN* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..*INFO = 0IF( ( ABS( JOB ).GT.2 ) .OR. ( JOB.EQ.0 ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAGTS', -INFO )RETURNEND IF*IF( N.EQ.0 )$ RETURN*EPS = DLAMCH( 'Epsilon' )SFMIN = DLAMCH( 'Safe minimum' )BIGNUM = ONE / SFMIN*IF( JOB.LT.0 ) THENIF( TOL.LE.ZERO ) THENTOL = ABS( A( 1 ) )IF( N.GT.1 )$ TOL = MAX( TOL, ABS( A( 2 ) ), ABS( B( 1 ) ) )DO 10 K = 3, NTOL = MAX( TOL, ABS( A( K ) ), ABS( B( K-1 ) ),$ ABS( D( K-2 ) ) )10 CONTINUETOL = TOL*EPSIF( TOL.EQ.ZERO )$ TOL = EPSEND IFEND IF*IF( ABS( JOB ).EQ.1 ) THENDO 20 K = 2, NIF( IN( K-1 ).EQ.0 ) THENY( K ) = Y( K ) - C( K-1 )*Y( K-1 )ELSETEMP = Y( K-1 )Y( K-1 ) = Y( K )Y( K ) = TEMP - C( K-1 )*Y( K )END IF20 CONTINUEIF( JOB.EQ.1 ) THENDO 30 K = N, 1, -1IF( K.LE.N-2 ) THENTEMP = Y( K ) - B( K )*Y( K+1 ) - D( K )*Y( K+2 )ELSE IF( K.EQ.N-1 ) THENTEMP = Y( K ) - B( K )*Y( K+1 )ELSETEMP = Y( K )END IFAK = A( K )ABSAK = ABS( AK )IF( ABSAK.LT.ONE ) THENIF( ABSAK.LT.SFMIN ) THENIF( ABSAK.EQ.ZERO .OR. ABS( TEMP )*SFMIN.GT.ABSAK )$ THENINFO = KRETURNELSETEMP = TEMP*BIGNUMAK = AK*BIGNUMEND IFELSE IF( ABS( TEMP ).GT.ABSAK*BIGNUM ) THENINFO = KRETURNEND IFEND IFY( K ) = TEMP / AK30 CONTINUEELSEDO 50 K = N, 1, -1IF( K.LE.N-2 ) THENTEMP = Y( K ) - B( K )*Y( K+1 ) - D( K )*Y( K+2 )ELSE IF( K.EQ.N-1 ) THENTEMP = Y( K ) - B( K )*Y( K+1 )ELSETEMP = Y( K )END IFAK = A( K )PERT = SIGN( TOL, AK )40 CONTINUEABSAK = ABS( AK )IF( ABSAK.LT.ONE ) THENIF( ABSAK.LT.SFMIN ) THENIF( ABSAK.EQ.ZERO .OR. ABS( TEMP )*SFMIN.GT.ABSAK )$ THENAK = AK + PERTPERT = 2*PERTGO TO 40ELSETEMP = TEMP*BIGNUMAK = AK*BIGNUMEND IFELSE IF( ABS( TEMP ).GT.ABSAK*BIGNUM ) THENAK = AK + PERTPERT = 2*PERTGO TO 40END IFEND IFY( K ) = TEMP / AK50 CONTINUEEND IFELSE** Come to here if JOB = 2 or -2*IF( JOB.EQ.2 ) THENDO 60 K = 1, NIF( K.GE.3 ) THENTEMP = Y( K ) - B( K-1 )*Y( K-1 ) - D( K-2 )*Y( K-2 )ELSE IF( K.EQ.2 ) THENTEMP = Y( K ) - B( K-1 )*Y( K-1 )ELSETEMP = Y( K )END IFAK = A( K )ABSAK = ABS( AK )IF( ABSAK.LT.ONE ) THENIF( ABSAK.LT.SFMIN ) THENIF( ABSAK.EQ.ZERO .OR. ABS( TEMP )*SFMIN.GT.ABSAK )$ THENINFO = KRETURNELSETEMP = TEMP*BIGNUMAK = AK*BIGNUMEND IFELSE IF( ABS( TEMP ).GT.ABSAK*BIGNUM ) THENINFO = KRETURNEND IFEND IFY( K ) = TEMP / AK60 CONTINUEELSEDO 80 K = 1, NIF( K.GE.3 ) THENTEMP = Y( K ) - B( K-1 )*Y( K-1 ) - D( K-2 )*Y( K-2 )ELSE IF( K.EQ.2 ) THENTEMP = Y( K ) - B( K-1 )*Y( K-1 )ELSETEMP = Y( K )END IFAK = A( K )PERT = SIGN( TOL, AK )70 CONTINUEABSAK = ABS( AK )IF( ABSAK.LT.ONE ) THENIF( ABSAK.LT.SFMIN ) THENIF( ABSAK.EQ.ZERO .OR. ABS( TEMP )*SFMIN.GT.ABSAK )$ THENAK = AK + PERTPERT = 2*PERTGO TO 70ELSETEMP = TEMP*BIGNUMAK = AK*BIGNUMEND IFELSE IF( ABS( TEMP ).GT.ABSAK*BIGNUM ) THENAK = AK + PERTPERT = 2*PERTGO TO 70END IFEND IFY( K ) = TEMP / AK80 CONTINUEEND IF*DO 90 K = N, 2, -1IF( IN( K-1 ).EQ.0 ) THENY( K-1 ) = Y( K-1 ) - C( K-1 )*Y( K )ELSETEMP = Y( K-1 )Y( K-1 ) = Y( K )Y( K ) = TEMP - C( K-1 )*Y( K )END IF90 CONTINUEEND IF** End of DLAGTS*END*> \brief \b DLAGV2 computes the Generalized Schur factorization of a real 2-by-2 matrix pencil (A,B) where B is upper triangular.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAGV2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlagv2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlagv2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlagv2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAGV2( A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, CSL, SNL,* CSR, SNR )** .. Scalar Arguments ..* INTEGER LDA, LDB* DOUBLE PRECISION CSL, CSR, SNL, SNR* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), ALPHAI( 2 ), ALPHAR( 2 ),* $ B( LDB, * ), BETA( 2 )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAGV2 computes the Generalized Schur factorization of a real 2-by-2*> matrix pencil (A,B) where B is upper triangular. This routine*> computes orthogonal (rotation) matrices given by CSL, SNL and CSR,*> SNR such that*>*> 1) if the pencil (A,B) has two real eigenvalues (include 0/0 or 1/0*> types), then*>*> [ a11 a12 ] := [ CSL SNL ] [ a11 a12 ] [ CSR -SNR ]*> [ 0 a22 ] [ -SNL CSL ] [ a21 a22 ] [ SNR CSR ]*>*> [ b11 b12 ] := [ CSL SNL ] [ b11 b12 ] [ CSR -SNR ]*> [ 0 b22 ] [ -SNL CSL ] [ 0 b22 ] [ SNR CSR ],*>*> 2) if the pencil (A,B) has a pair of complex conjugate eigenvalues,*> then*>*> [ a11 a12 ] := [ CSL SNL ] [ a11 a12 ] [ CSR -SNR ]*> [ a21 a22 ] [ -SNL CSL ] [ a21 a22 ] [ SNR CSR ]*>*> [ b11 0 ] := [ CSL SNL ] [ b11 b12 ] [ CSR -SNR ]*> [ 0 b22 ] [ -SNL CSL ] [ 0 b22 ] [ SNR CSR ]*>*> where b11 >= b22 > 0.*>*> \endverbatim** Arguments:* ==========**> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, 2)*> On entry, the 2 x 2 matrix A.*> On exit, A is overwritten by the ``A-part'' of the*> generalized Schur form.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> THe leading dimension of the array A. LDA >= 2.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, 2)*> On entry, the upper triangular 2 x 2 matrix B.*> On exit, B is overwritten by the ``B-part'' of the*> generalized Schur form.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> THe leading dimension of the array B. LDB >= 2.*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (2)*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (2)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (2)*> (ALPHAR(k)+i*ALPHAI(k))/BETA(k) are the eigenvalues of the*> pencil (A,B), k=1,2, i = sqrt(-1). Note that BETA(k) may*> be zero.*> \endverbatim*>*> \param[out] CSL*> \verbatim*> CSL is DOUBLE PRECISION*> The cosine of the left rotation matrix.*> \endverbatim*>*> \param[out] SNL*> \verbatim*> SNL is DOUBLE PRECISION*> The sine of the left rotation matrix.*> \endverbatim*>*> \param[out] CSR*> \verbatim*> CSR is DOUBLE PRECISION*> The cosine of the right rotation matrix.*> \endverbatim*>*> \param[out] SNR*> \verbatim*> SNR is DOUBLE PRECISION*> The sine of the right rotation matrix.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA** =====================================================================SUBROUTINE DLAGV2( A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, CSL, SNL,$ CSR, SNR )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER LDA, LDBDOUBLE PRECISION CSL, CSR, SNL, SNR* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), ALPHAI( 2 ), ALPHAR( 2 ),$ B( LDB, * ), BETA( 2 )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION ANORM, ASCALE, BNORM, BSCALE, H1, H2, H3, QQ,$ R, RR, SAFMIN, SCALE1, SCALE2, T, ULP, WI, WR1,$ WR2* ..* .. External Subroutines ..EXTERNAL DLAG2, DLARTG, DLASV2, DROT* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL DLAMCH, DLAPY2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..*SAFMIN = DLAMCH( 'S' )ULP = DLAMCH( 'P' )** Scale A*ANORM = MAX( ABS( A( 1, 1 ) )+ABS( A( 2, 1 ) ),$ ABS( A( 1, 2 ) )+ABS( A( 2, 2 ) ), SAFMIN )ASCALE = ONE / ANORMA( 1, 1 ) = ASCALE*A( 1, 1 )A( 1, 2 ) = ASCALE*A( 1, 2 )A( 2, 1 ) = ASCALE*A( 2, 1 )A( 2, 2 ) = ASCALE*A( 2, 2 )** Scale B*BNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 1, 2 ) )+ABS( B( 2, 2 ) ),$ SAFMIN )BSCALE = ONE / BNORMB( 1, 1 ) = BSCALE*B( 1, 1 )B( 1, 2 ) = BSCALE*B( 1, 2 )B( 2, 2 ) = BSCALE*B( 2, 2 )** Check if A can be deflated*IF( ABS( A( 2, 1 ) ).LE.ULP ) THENCSL = ONESNL = ZEROCSR = ONESNR = ZEROA( 2, 1 ) = ZEROB( 2, 1 ) = ZEROWI = ZERO** Check if B is singular*ELSE IF( ABS( B( 1, 1 ) ).LE.ULP ) THENCALL DLARTG( A( 1, 1 ), A( 2, 1 ), CSL, SNL, R )CSR = ONESNR = ZEROCALL DROT( 2, A( 1, 1 ), LDA, A( 2, 1 ), LDA, CSL, SNL )CALL DROT( 2, B( 1, 1 ), LDB, B( 2, 1 ), LDB, CSL, SNL )A( 2, 1 ) = ZEROB( 1, 1 ) = ZEROB( 2, 1 ) = ZEROWI = ZERO*ELSE IF( ABS( B( 2, 2 ) ).LE.ULP ) THENCALL DLARTG( A( 2, 2 ), A( 2, 1 ), CSR, SNR, T )SNR = -SNRCALL DROT( 2, A( 1, 1 ), 1, A( 1, 2 ), 1, CSR, SNR )CALL DROT( 2, B( 1, 1 ), 1, B( 1, 2 ), 1, CSR, SNR )CSL = ONESNL = ZEROA( 2, 1 ) = ZEROB( 2, 1 ) = ZEROB( 2, 2 ) = ZEROWI = ZERO*ELSE** B is nonsingular, first compute the eigenvalues of (A,B)*CALL DLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1, WR2,$ WI )*IF( WI.EQ.ZERO ) THEN** two real eigenvalues, compute s*A-w*B*H1 = SCALE1*A( 1, 1 ) - WR1*B( 1, 1 )H2 = SCALE1*A( 1, 2 ) - WR1*B( 1, 2 )H3 = SCALE1*A( 2, 2 ) - WR1*B( 2, 2 )*RR = DLAPY2( H1, H2 )QQ = DLAPY2( SCALE1*A( 2, 1 ), H3 )*IF( RR.GT.QQ ) THEN** find right rotation matrix to zero 1,1 element of* (sA - wB)*CALL DLARTG( H2, H1, CSR, SNR, T )*ELSE** find right rotation matrix to zero 2,1 element of* (sA - wB)*CALL DLARTG( H3, SCALE1*A( 2, 1 ), CSR, SNR, T )*END IF*SNR = -SNRCALL DROT( 2, A( 1, 1 ), 1, A( 1, 2 ), 1, CSR, SNR )CALL DROT( 2, B( 1, 1 ), 1, B( 1, 2 ), 1, CSR, SNR )** compute inf norms of A and B*H1 = MAX( ABS( A( 1, 1 ) )+ABS( A( 1, 2 ) ),$ ABS( A( 2, 1 ) )+ABS( A( 2, 2 ) ) )H2 = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),$ ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )*IF( ( SCALE1*H1 ).GE.ABS( WR1 )*H2 ) THEN** find left rotation matrix Q to zero out B(2,1)*CALL DLARTG( B( 1, 1 ), B( 2, 1 ), CSL, SNL, R )*ELSE** find left rotation matrix Q to zero out A(2,1)*CALL DLARTG( A( 1, 1 ), A( 2, 1 ), CSL, SNL, R )*END IF*CALL DROT( 2, A( 1, 1 ), LDA, A( 2, 1 ), LDA, CSL, SNL )CALL DROT( 2, B( 1, 1 ), LDB, B( 2, 1 ), LDB, CSL, SNL )*A( 2, 1 ) = ZEROB( 2, 1 ) = ZERO*ELSE** a pair of complex conjugate eigenvalues* first compute the SVD of the matrix B*CALL DLASV2( B( 1, 1 ), B( 1, 2 ), B( 2, 2 ), R, T, SNR,$ CSR, SNL, CSL )** Form (A,B) := Q(A,B)Z**T where Q is left rotation matrix and* Z is right rotation matrix computed from DLASV2*CALL DROT( 2, A( 1, 1 ), LDA, A( 2, 1 ), LDA, CSL, SNL )CALL DROT( 2, B( 1, 1 ), LDB, B( 2, 1 ), LDB, CSL, SNL )CALL DROT( 2, A( 1, 1 ), 1, A( 1, 2 ), 1, CSR, SNR )CALL DROT( 2, B( 1, 1 ), 1, B( 1, 2 ), 1, CSR, SNR )*B( 2, 1 ) = ZEROB( 1, 2 ) = ZERO*END IF*END IF** Unscaling*A( 1, 1 ) = ANORM*A( 1, 1 )A( 2, 1 ) = ANORM*A( 2, 1 )A( 1, 2 ) = ANORM*A( 1, 2 )A( 2, 2 ) = ANORM*A( 2, 2 )B( 1, 1 ) = BNORM*B( 1, 1 )B( 2, 1 ) = BNORM*B( 2, 1 )B( 1, 2 ) = BNORM*B( 1, 2 )B( 2, 2 ) = BNORM*B( 2, 2 )*IF( WI.EQ.ZERO ) THENALPHAR( 1 ) = A( 1, 1 )ALPHAR( 2 ) = A( 2, 2 )ALPHAI( 1 ) = ZEROALPHAI( 2 ) = ZEROBETA( 1 ) = B( 1, 1 )BETA( 2 ) = B( 2, 2 )ELSEALPHAR( 1 ) = ANORM*WR1 / SCALE1 / BNORMALPHAI( 1 ) = ANORM*WI / SCALE1 / BNORMALPHAR( 2 ) = ALPHAR( 1 )ALPHAI( 2 ) = -ALPHAI( 1 )BETA( 1 ) = ONEBETA( 2 ) = ONEEND IF*RETURN** End of DLAGV2*END*> \brief \b DLAHQR computes the eigenvalues and Schur factorization of an upper Hessenberg matrix, using the double-shift/single-shift QR algorithm.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAHQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlahqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlahqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlahqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,* ILOZ, IHIZ, Z, LDZ, INFO )** .. Scalar Arguments ..* INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, N* LOGICAL WANTT, WANTZ* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAHQR is an auxiliary routine called by DHSEQR to update the*> eigenvalues and Schur decomposition already computed by DHSEQR, by*> dealing with the Hessenberg submatrix in rows and columns ILO to*> IHI.*> \endverbatim** Arguments:* ==========**> \param[in] WANTT*> \verbatim*> WANTT is LOGICAL*> = .TRUE. : the full Schur form T is required;*> = .FALSE.: only eigenvalues are required.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> = .TRUE. : the matrix of Schur vectors Z is required;*> = .FALSE.: Schur vectors are not required.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> It is assumed that H is already upper quasi-triangular in*> rows and columns IHI+1:N, and that H(ILO,ILO-1) = 0 (unless*> ILO = 1). DLAHQR works primarily with the Hessenberg*> submatrix in rows and columns ILO to IHI, but applies*> transformations to all of H if WANTT is .TRUE..*> 1 <= ILO <= max(1,IHI); IHI <= N.*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On entry, the upper Hessenberg matrix H.*> On exit, if INFO is zero and if WANTT is .TRUE., H is upper*> quasi-triangular in rows and columns ILO:IHI, with any*> 2-by-2 diagonal blocks in standard form. If INFO is zero*> and WANTT is .FALSE., the contents of H are unspecified on*> exit. The output state of H if INFO is nonzero is given*> below under the description of INFO.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH >= max(1,N).*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*> The real and imaginary parts, respectively, of the computed*> eigenvalues ILO to IHI are stored in the corresponding*> elements of WR and WI. If two eigenvalues are computed as a*> complex conjugate pair, they are stored in consecutive*> elements of WR and WI, say the i-th and (i+1)th, with*> WI(i) > 0 and WI(i+1) < 0. If WANTT is .TRUE., the*> eigenvalues are stored in the same order as on the diagonal*> of the Schur form returned in H, with WR(i) = H(i,i), and, if*> H(i:i+1,i:i+1) is a 2-by-2 diagonal block,*> WI(i) = sqrt(H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i).*> \endverbatim*>*> \param[in] ILOZ*> \verbatim*> ILOZ is INTEGER*> \endverbatim*>*> \param[in] IHIZ*> \verbatim*> IHIZ is INTEGER*> Specify the rows of Z to which transformations must be*> applied if WANTZ is .TRUE..*> 1 <= ILOZ <= ILO; IHI <= IHIZ <= N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> If WANTZ is .TRUE., on entry Z must contain the current*> matrix Z of transformations accumulated by DHSEQR, and on*> exit Z has been updated; transformations are applied only to*> the submatrix Z(ILOZ:IHIZ,ILO:IHI).*> If WANTZ is .FALSE., Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> .GT. 0: If INFO = i, DLAHQR failed to compute all the*> eigenvalues ILO to IHI in a total of 30 iterations*> per eigenvalue; elements i+1:ihi of WR and WI*> contain those eigenvalues which have been*> successfully computed.*>*> If INFO .GT. 0 and WANTT is .FALSE., then on exit,*> the remaining unconverged eigenvalues are the*> eigenvalues of the upper Hessenberg matrix rows*> and columns ILO thorugh INFO of the final, output*> value of H.*>*> If INFO .GT. 0 and WANTT is .TRUE., then on exit*> (*) (initial value of H)*U = U*(final value of H)*> where U is an orthognal matrix. The final*> value of H is upper Hessenberg and triangular in*> rows and columns INFO+1 through IHI.*>*> If INFO .GT. 0 and WANTZ is .TRUE., then on exit*> (final value of Z) = (initial value of Z)*U*> where U is the orthogonal matrix in (*)*> (regardless of the value of WANTT.)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> 02-96 Based on modifications by*> David Day, Sandia National Laboratory, USA*>*> 12-04 Further modifications by*> Ralph Byers, University of Kansas, USA*> This is a modified version of DLAHQR from LAPACK version 3.0.*> It is (1) more robust against overflow and underflow and*> (2) adopts the more conservative Ahues & Tisseur stopping*> criterion (LAWN 122, 1997).*> \endverbatim*>* =====================================================================SUBROUTINE DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,$ ILOZ, IHIZ, Z, LDZ, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, NLOGICAL WANTT, WANTZ* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), WI( * ), WR( * ), Z( LDZ, * )* ..** =========================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0, TWO = 2.0d0 )DOUBLE PRECISION DAT1, DAT2PARAMETER ( DAT1 = 3.0d0 / 4.0d0, DAT2 = -0.4375d0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, AB, BA, BB, CS, DET, H11, H12, H21, H21S,$ H22, RT1I, RT1R, RT2I, RT2R, RTDISC, S, SAFMAX,$ SAFMIN, SMLNUM, SN, SUM, T1, T2, T3, TR, TST,$ ULP, V2, V3INTEGER I, I1, I2, ITS, ITMAX, J, K, L, M, NH, NR, NZ* ..* .. Local Arrays ..DOUBLE PRECISION V( 3 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DCOPY, DLABAD, DLANV2, DLARFG, DROT* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SQRT* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( ILO.EQ.IHI ) THENWR( ILO ) = H( ILO, ILO )WI( ILO ) = ZERORETURNEND IF** ==== clear out the trash ====DO 10 J = ILO, IHI - 3H( J+2, J ) = ZEROH( J+3, J ) = ZERO10 CONTINUEIF( ILO.LE.IHI-2 )$ H( IHI, IHI-2 ) = ZERO*NH = IHI - ILO + 1NZ = IHIZ - ILOZ + 1** Set machine-dependent constants for the stopping criterion.*SAFMIN = DLAMCH( 'SAFE MINIMUM' )SAFMAX = ONE / SAFMINCALL DLABAD( SAFMIN, SAFMAX )ULP = DLAMCH( 'PRECISION' )SMLNUM = SAFMIN*( DBLE( NH ) / ULP )** I1 and I2 are the indices of the first row and last column of H* to which transformations must be applied. If eigenvalues only are* being computed, I1 and I2 are set inside the main loop.*IF( WANTT ) THENI1 = 1I2 = NEND IF** ITMAX is the total number of QR iterations allowed.*ITMAX = 30 * MAX( 10, NH )** The main loop begins here. I is the loop index and decreases from* IHI to ILO in steps of 1 or 2. Each iteration of the loop works* with the active submatrix in rows and columns L to I.* Eigenvalues I+1 to IHI have already converged. Either L = ILO or* H(L,L-1) is negligible so that the matrix splits.*I = IHI20 CONTINUEL = ILOIF( I.LT.ILO )$ GO TO 160** Perform QR iterations on rows and columns ILO to I until a* submatrix of order 1 or 2 splits off at the bottom because a* subdiagonal element has become negligible.*DO 140 ITS = 0, ITMAX** Look for a single small subdiagonal element.*DO 30 K = I, L + 1, -1IF( ABS( H( K, K-1 ) ).LE.SMLNUM )$ GO TO 40TST = ABS( H( K-1, K-1 ) ) + ABS( H( K, K ) )IF( TST.EQ.ZERO ) THENIF( K-2.GE.ILO )$ TST = TST + ABS( H( K-1, K-2 ) )IF( K+1.LE.IHI )$ TST = TST + ABS( H( K+1, K ) )END IF* ==== The following is a conservative small subdiagonal* . deflation criterion due to Ahues & Tisseur (LAWN 122,* . 1997). It has better mathematical foundation and* . improves accuracy in some cases. ====IF( ABS( H( K, K-1 ) ).LE.ULP*TST ) THENAB = MAX( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )BA = MIN( ABS( H( K, K-1 ) ), ABS( H( K-1, K ) ) )AA = MAX( ABS( H( K, K ) ),$ ABS( H( K-1, K-1 )-H( K, K ) ) )BB = MIN( ABS( H( K, K ) ),$ ABS( H( K-1, K-1 )-H( K, K ) ) )S = AA + ABIF( BA*( AB / S ).LE.MAX( SMLNUM,$ ULP*( BB*( AA / S ) ) ) )GO TO 40END IF30 CONTINUE40 CONTINUEL = KIF( L.GT.ILO ) THEN** H(L,L-1) is negligible*H( L, L-1 ) = ZEROEND IF** Exit from loop if a submatrix of order 1 or 2 has split off.*IF( L.GE.I-1 )$ GO TO 150** Now the active submatrix is in rows and columns L to I. If* eigenvalues only are being computed, only the active submatrix* need be transformed.*IF( .NOT.WANTT ) THENI1 = LI2 = IEND IF*IF( ITS.EQ.10 ) THEN** Exceptional shift.*S = ABS( H( L+1, L ) ) + ABS( H( L+2, L+1 ) )H11 = DAT1*S + H( L, L )H12 = DAT2*SH21 = SH22 = H11ELSE IF( ITS.EQ.20 ) THEN** Exceptional shift.*S = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )H11 = DAT1*S + H( I, I )H12 = DAT2*SH21 = SH22 = H11ELSE** Prepare to use Francis' double shift* (i.e. 2nd degree generalized Rayleigh quotient)*H11 = H( I-1, I-1 )H21 = H( I, I-1 )H12 = H( I-1, I )H22 = H( I, I )END IFS = ABS( H11 ) + ABS( H12 ) + ABS( H21 ) + ABS( H22 )IF( S.EQ.ZERO ) THENRT1R = ZERORT1I = ZERORT2R = ZERORT2I = ZEROELSEH11 = H11 / SH21 = H21 / SH12 = H12 / SH22 = H22 / STR = ( H11+H22 ) / TWODET = ( H11-TR )*( H22-TR ) - H12*H21RTDISC = SQRT( ABS( DET ) )IF( DET.GE.ZERO ) THEN** ==== complex conjugate shifts ====*RT1R = TR*SRT2R = RT1RRT1I = RTDISC*SRT2I = -RT1IELSE** ==== real shifts (use only one of them) ====*RT1R = TR + RTDISCRT2R = TR - RTDISCIF( ABS( RT1R-H22 ).LE.ABS( RT2R-H22 ) ) THENRT1R = RT1R*SRT2R = RT1RELSERT2R = RT2R*SRT1R = RT2REND IFRT1I = ZERORT2I = ZEROEND IFEND IF** Look for two consecutive small subdiagonal elements.*DO 50 M = I - 2, L, -1* Determine the effect of starting the double-shift QR* iteration at row M, and see if this would make H(M,M-1)* negligible. (The following uses scaling to avoid* overflows and most underflows.)*H21S = H( M+1, M )S = ABS( H( M, M )-RT2R ) + ABS( RT2I ) + ABS( H21S )H21S = H( M+1, M ) / SV( 1 ) = H21S*H( M, M+1 ) + ( H( M, M )-RT1R )*$ ( ( H( M, M )-RT2R ) / S ) - RT1I*( RT2I / S )V( 2 ) = H21S*( H( M, M )+H( M+1, M+1 )-RT1R-RT2R )V( 3 ) = H21S*H( M+2, M+1 )S = ABS( V( 1 ) ) + ABS( V( 2 ) ) + ABS( V( 3 ) )V( 1 ) = V( 1 ) / SV( 2 ) = V( 2 ) / SV( 3 ) = V( 3 ) / SIF( M.EQ.L )$ GO TO 60IF( ABS( H( M, M-1 ) )*( ABS( V( 2 ) )+ABS( V( 3 ) ) ).LE.$ ULP*ABS( V( 1 ) )*( ABS( H( M-1, M-1 ) )+ABS( H( M,$ M ) )+ABS( H( M+1, M+1 ) ) ) )GO TO 6050 CONTINUE60 CONTINUE** Double-shift QR step*DO 130 K = M, I - 1** The first iteration of this loop determines a reflection G* from the vector V and applies it from left and right to H,* thus creating a nonzero bulge below the subdiagonal.** Each subsequent iteration determines a reflection G to* restore the Hessenberg form in the (K-1)th column, and thus* chases the bulge one step toward the bottom of the active* submatrix. NR is the order of G.*NR = MIN( 3, I-K+1 )IF( K.GT.M )$ CALL DCOPY( NR, H( K, K-1 ), 1, V, 1 )CALL DLARFG( NR, V( 1 ), V( 2 ), 1, T1 )IF( K.GT.M ) THENH( K, K-1 ) = V( 1 )H( K+1, K-1 ) = ZEROIF( K.LT.I-1 )$ H( K+2, K-1 ) = ZEROELSE IF( M.GT.L ) THEN* ==== Use the following instead of* . H( K, K-1 ) = -H( K, K-1 ) to* . avoid a bug when v(2) and v(3)* . underflow. ====H( K, K-1 ) = H( K, K-1 )*( ONE-T1 )END IFV2 = V( 2 )T2 = T1*V2IF( NR.EQ.3 ) THENV3 = V( 3 )T3 = T1*V3** Apply G from the left to transform the rows of the matrix* in columns K to I2.*DO 70 J = K, I2SUM = H( K, J ) + V2*H( K+1, J ) + V3*H( K+2, J )H( K, J ) = H( K, J ) - SUM*T1H( K+1, J ) = H( K+1, J ) - SUM*T2H( K+2, J ) = H( K+2, J ) - SUM*T370 CONTINUE** Apply G from the right to transform the columns of the* matrix in rows I1 to min(K+3,I).*DO 80 J = I1, MIN( K+3, I )SUM = H( J, K ) + V2*H( J, K+1 ) + V3*H( J, K+2 )H( J, K ) = H( J, K ) - SUM*T1H( J, K+1 ) = H( J, K+1 ) - SUM*T2H( J, K+2 ) = H( J, K+2 ) - SUM*T380 CONTINUE*IF( WANTZ ) THEN** Accumulate transformations in the matrix Z*DO 90 J = ILOZ, IHIZSUM = Z( J, K ) + V2*Z( J, K+1 ) + V3*Z( J, K+2 )Z( J, K ) = Z( J, K ) - SUM*T1Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2Z( J, K+2 ) = Z( J, K+2 ) - SUM*T390 CONTINUEEND IFELSE IF( NR.EQ.2 ) THEN** Apply G from the left to transform the rows of the matrix* in columns K to I2.*DO 100 J = K, I2SUM = H( K, J ) + V2*H( K+1, J )H( K, J ) = H( K, J ) - SUM*T1H( K+1, J ) = H( K+1, J ) - SUM*T2100 CONTINUE** Apply G from the right to transform the columns of the* matrix in rows I1 to min(K+3,I).*DO 110 J = I1, ISUM = H( J, K ) + V2*H( J, K+1 )H( J, K ) = H( J, K ) - SUM*T1H( J, K+1 ) = H( J, K+1 ) - SUM*T2110 CONTINUE*IF( WANTZ ) THEN** Accumulate transformations in the matrix Z*DO 120 J = ILOZ, IHIZSUM = Z( J, K ) + V2*Z( J, K+1 )Z( J, K ) = Z( J, K ) - SUM*T1Z( J, K+1 ) = Z( J, K+1 ) - SUM*T2120 CONTINUEEND IFEND IF130 CONTINUE*140 CONTINUE** Failure to converge in remaining number of iterations*INFO = IRETURN*150 CONTINUE*IF( L.EQ.I ) THEN** H(I,I-1) is negligible: one eigenvalue has converged.*WR( I ) = H( I, I )WI( I ) = ZEROELSE IF( L.EQ.I-1 ) THEN** H(I-1,I-2) is negligible: a pair of eigenvalues have converged.** Transform the 2-by-2 submatrix to standard Schur form,* and compute and store the eigenvalues.*CALL DLANV2( H( I-1, I-1 ), H( I-1, I ), H( I, I-1 ),$ H( I, I ), WR( I-1 ), WI( I-1 ), WR( I ), WI( I ),$ CS, SN )*IF( WANTT ) THEN** Apply the transformation to the rest of H.*IF( I2.GT.I )$ CALL DROT( I2-I, H( I-1, I+1 ), LDH, H( I, I+1 ), LDH,$ CS, SN )CALL DROT( I-I1-1, H( I1, I-1 ), 1, H( I1, I ), 1, CS, SN )END IFIF( WANTZ ) THEN** Apply the transformation to Z.*CALL DROT( NZ, Z( ILOZ, I-1 ), 1, Z( ILOZ, I ), 1, CS, SN )END IFEND IF** return to start of the main loop with new value of I.*I = L - 1GO TO 20*160 CONTINUERETURN** End of DLAHQR*END*> \brief \b DLAHR2 reduces the specified number of first columns of a general rectangular matrix A so that elements below the specified subdiagonal are zero, and returns auxiliary matrices which are needed to apply the transformation to the unreduced part of A.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAHR2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlahr2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlahr2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlahr2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )** .. Scalar Arguments ..* INTEGER K, LDA, LDT, LDY, N, NB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ),* $ Y( LDY, NB )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAHR2 reduces the first NB columns of A real general n-BY-(n-k+1)*> matrix A so that elements below the k-th subdiagonal are zero. The*> reduction is performed by an orthogonal similarity transformation*> Q**T * A * Q. The routine returns the matrices V and T which determine*> Q as a block reflector I - V*T*V**T, and also the matrix Y = A * V * T.*>*> This is an auxiliary routine called by DGEHRD.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The offset for the reduction. Elements below the k-th*> subdiagonal in the first NB columns are reduced to zero.*> K < N.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The number of columns to be reduced.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N-K+1)*> On entry, the n-by-(n-k+1) general matrix A.*> On exit, the elements on and above the k-th subdiagonal in*> the first NB columns are overwritten with the corresponding*> elements of the reduced matrix; the elements below the k-th*> subdiagonal, with the array TAU, represent the matrix Q as a*> product of elementary reflectors. The other columns of A are*> unchanged. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (NB)*> The scalar factors of the elementary reflectors. See Further*> Details.*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,NB)*> The upper triangular matrix T.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= NB.*> \endverbatim*>*> \param[out] Y*> \verbatim*> Y is DOUBLE PRECISION array, dimension (LDY,NB)*> The n-by-nb matrix Y.*> \endverbatim*>*> \param[in] LDY*> \verbatim*> LDY is INTEGER*> The leading dimension of the array Y. LDY >= N.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of nb elementary reflectors*>*> Q = H(1) H(2) . . . H(nb).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in*> A(i+k+1:n,i), and tau in TAU(i).*>*> The elements of the vectors v together form the (n-k+1)-by-nb matrix*> V which is needed, with T and Y, to apply the transformation to the*> unreduced part of the matrix, using an update of the form:*> A := (I - V*T*V**T) * (A - Y*V**T).*>*> The contents of A on exit are illustrated by the following example*> with n = 7, k = 3 and nb = 2:*>*> ( a a a a a )*> ( a a a a a )*> ( a a a a a )*> ( h h a a a )*> ( v1 h a a a )*> ( v1 v2 a a a )*> ( v1 v2 a a a )*>*> where a denotes an element of the original matrix A, h denotes a*> modified element of the upper Hessenberg matrix H, and vi denotes an*> element of the vector defining H(i).*>*> This subroutine is a slight modification of LAPACK-3.0's DLAHRD*> incorporating improvements proposed by Quintana-Orti and Van de*> Gejin. Note that the entries of A(1:K,2:NB) differ from those*> returned by the original LAPACK-3.0's DLAHRD routine. (This*> subroutine is not backward compatible with LAPACK-3.0's DLAHRD.)*> \endverbatim**> \par References:* ================*>*> Gregorio Quintana-Orti and Robert van de Geijn, "Improving the*> performance of reduction to Hessenberg form," ACM Transactions on*> Mathematical Software, 32(2):180-194, June 2006.*>* =====================================================================SUBROUTINE DLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER K, LDA, LDT, LDY, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ),$ Y( LDY, NB )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0,$ ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION EI* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMM, DGEMV, DLACPY,$ DLARFG, DSCAL, DTRMM, DTRMV* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.1 )$ RETURN*DO 10 I = 1, NBIF( I.GT.1 ) THEN** Update A(K+1:N,I)** Update I-th column of A - Y * V**T*CALL DGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, Y(K+1,1), LDY,$ A( K+I-1, 1 ), LDA, ONE, A( K+1, I ), 1 )** Apply I - V * T**T * V**T to this column (call it b) from the* left, using the last column of T as workspace** Let V = ( V1 ) and b = ( b1 ) (first I-1 rows)* ( V2 ) ( b2 )** where V1 is unit lower triangular** w := V1**T * b1*CALL DCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )CALL DTRMV( 'Lower', 'Transpose', 'UNIT',$ I-1, A( K+1, 1 ),$ LDA, T( 1, NB ), 1 )** w := w + V2**T * b2*CALL DGEMV( 'Transpose', N-K-I+1, I-1,$ ONE, A( K+I, 1 ),$ LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )** w := T**T * w*CALL DTRMV( 'Upper', 'Transpose', 'NON-UNIT',$ I-1, T, LDT,$ T( 1, NB ), 1 )** b2 := b2 - V2*w*CALL DGEMV( 'NO TRANSPOSE', N-K-I+1, I-1, -ONE,$ A( K+I, 1 ),$ LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )** b1 := b1 - V1*w*CALL DTRMV( 'Lower', 'NO TRANSPOSE',$ 'UNIT', I-1,$ A( K+1, 1 ), LDA, T( 1, NB ), 1 )CALL DAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )*A( K+I-1, I-1 ) = EIEND IF** Generate the elementary reflector H(I) to annihilate* A(K+I+1:N,I)*CALL DLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,$ TAU( I ) )EI = A( K+I, I )A( K+I, I ) = ONE** Compute Y(K+1:N,I)*CALL DGEMV( 'NO TRANSPOSE', N-K, N-K-I+1,$ ONE, A( K+1, I+1 ),$ LDA, A( K+I, I ), 1, ZERO, Y( K+1, I ), 1 )CALL DGEMV( 'Transpose', N-K-I+1, I-1,$ ONE, A( K+I, 1 ), LDA,$ A( K+I, I ), 1, ZERO, T( 1, I ), 1 )CALL DGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE,$ Y( K+1, 1 ), LDY,$ T( 1, I ), 1, ONE, Y( K+1, I ), 1 )CALL DSCAL( N-K, TAU( I ), Y( K+1, I ), 1 )** Compute T(1:I,I)*CALL DSCAL( I-1, -TAU( I ), T( 1, I ), 1 )CALL DTRMV( 'Upper', 'No Transpose', 'NON-UNIT',$ I-1, T, LDT,$ T( 1, I ), 1 )T( I, I ) = TAU( I )*10 CONTINUEA( K+NB, NB ) = EI** Compute Y(1:K,1:NB)*CALL DLACPY( 'ALL', K, NB, A( 1, 2 ), LDA, Y, LDY )CALL DTRMM( 'RIGHT', 'Lower', 'NO TRANSPOSE',$ 'UNIT', K, NB,$ ONE, A( K+1, 1 ), LDA, Y, LDY )IF( N.GT.K+NB )$ CALL DGEMM( 'NO TRANSPOSE', 'NO TRANSPOSE', K,$ NB, N-K-NB, ONE,$ A( 1, 2+NB ), LDA, A( K+1+NB, 1 ), LDA, ONE, Y,$ LDY )CALL DTRMM( 'RIGHT', 'Upper', 'NO TRANSPOSE',$ 'NON-UNIT', K, NB,$ ONE, T, LDT, Y, LDY )*RETURN** End of DLAHR2*END*> \brief \b DLAHRD reduces the first nb columns of a general rectangular matrix A so that elements below the k-th subdiagonal are zero, and returns auxiliary matrices which are needed to apply the transformation to the unreduced part of A.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAHRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlahrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlahrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlahrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )** .. Scalar Arguments ..* INTEGER K, LDA, LDT, LDY, N, NB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ),* $ Y( LDY, NB )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DLAHR2.*>*> DLAHRD reduces the first NB columns of a real general n-by-(n-k+1)*> matrix A so that elements below the k-th subdiagonal are zero. The*> reduction is performed by an orthogonal similarity transformation*> Q**T * A * Q. The routine returns the matrices V and T which determine*> Q as a block reflector I - V*T*V**T, and also the matrix Y = A * V * T.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The offset for the reduction. Elements below the k-th*> subdiagonal in the first NB columns are reduced to zero.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The number of columns to be reduced.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N-K+1)*> On entry, the n-by-(n-k+1) general matrix A.*> On exit, the elements on and above the k-th subdiagonal in*> the first NB columns are overwritten with the corresponding*> elements of the reduced matrix; the elements below the k-th*> subdiagonal, with the array TAU, represent the matrix Q as a*> product of elementary reflectors. The other columns of A are*> unchanged. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (NB)*> The scalar factors of the elementary reflectors. See Further*> Details.*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,NB)*> The upper triangular matrix T.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= NB.*> \endverbatim*>*> \param[out] Y*> \verbatim*> Y is DOUBLE PRECISION array, dimension (LDY,NB)*> The n-by-nb matrix Y.*> \endverbatim*>*> \param[in] LDY*> \verbatim*> LDY is INTEGER*> The leading dimension of the array Y. LDY >= N.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix Q is represented as a product of nb elementary reflectors*>*> Q = H(1) H(2) . . . H(nb).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in*> A(i+k+1:n,i), and tau in TAU(i).*>*> The elements of the vectors v together form the (n-k+1)-by-nb matrix*> V which is needed, with T and Y, to apply the transformation to the*> unreduced part of the matrix, using an update of the form:*> A := (I - V*T*V**T) * (A - Y*V**T).*>*> The contents of A on exit are illustrated by the following example*> with n = 7, k = 3 and nb = 2:*>*> ( a h a a a )*> ( a h a a a )*> ( a h a a a )*> ( h h a a a )*> ( v1 h a a a )*> ( v1 v2 a a a )*> ( v1 v2 a a a )*>*> where a denotes an element of the original matrix A, h denotes a*> modified element of the upper Hessenberg matrix H, and vi denotes an*> element of the vector defining H(i).*> \endverbatim*>* =====================================================================SUBROUTINE DLAHRD( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER K, LDA, LDT, LDY, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ),$ Y( LDY, NB )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION EI* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DLARFG, DSCAL, DTRMV* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.1 )$ RETURN*DO 10 I = 1, NBIF( I.GT.1 ) THEN** Update A(1:n,i)** Compute i-th column of A - Y * V**T*CALL DGEMV( 'No transpose', N, I-1, -ONE, Y, LDY,$ A( K+I-1, 1 ), LDA, ONE, A( 1, I ), 1 )** Apply I - V * T**T * V**T to this column (call it b) from the* left, using the last column of T as workspace** Let V = ( V1 ) and b = ( b1 ) (first I-1 rows)* ( V2 ) ( b2 )** where V1 is unit lower triangular** w := V1**T * b1*CALL DCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 )CALL DTRMV( 'Lower', 'Transpose', 'Unit', I-1, A( K+1, 1 ),$ LDA, T( 1, NB ), 1 )** w := w + V2**T *b2*CALL DGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ),$ LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 )** w := T**T *w*CALL DTRMV( 'Upper', 'Transpose', 'Non-unit', I-1, T, LDT,$ T( 1, NB ), 1 )** b2 := b2 - V2*w*CALL DGEMV( 'No transpose', N-K-I+1, I-1, -ONE, A( K+I, 1 ),$ LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 )** b1 := b1 - V1*w*CALL DTRMV( 'Lower', 'No transpose', 'Unit', I-1,$ A( K+1, 1 ), LDA, T( 1, NB ), 1 )CALL DAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 )*A( K+I-1, I-1 ) = EIEND IF** Generate the elementary reflector H(i) to annihilate* A(k+i+1:n,i)*CALL DLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1,$ TAU( I ) )EI = A( K+I, I )A( K+I, I ) = ONE** Compute Y(1:n,i)*CALL DGEMV( 'No transpose', N, N-K-I+1, ONE, A( 1, I+1 ), LDA,$ A( K+I, I ), 1, ZERO, Y( 1, I ), 1 )CALL DGEMV( 'Transpose', N-K-I+1, I-1, ONE, A( K+I, 1 ), LDA,$ A( K+I, I ), 1, ZERO, T( 1, I ), 1 )CALL DGEMV( 'No transpose', N, I-1, -ONE, Y, LDY, T( 1, I ), 1,$ ONE, Y( 1, I ), 1 )CALL DSCAL( N, TAU( I ), Y( 1, I ), 1 )** Compute T(1:i,i)*CALL DSCAL( I-1, -TAU( I ), T( 1, I ), 1 )CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T, LDT,$ T( 1, I ), 1 )T( I, I ) = TAU( I )*10 CONTINUEA( K+NB, NB ) = EI*RETURN** End of DLAHRD*END*> \brief \b DLAIC1 applies one step of incremental condition estimation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAIC1 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaic1.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaic1.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaic1.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )** .. Scalar Arguments ..* INTEGER J, JOB* DOUBLE PRECISION C, GAMMA, S, SEST, SESTPR* ..* .. Array Arguments ..* DOUBLE PRECISION W( J ), X( J )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAIC1 applies one step of incremental condition estimation in*> its simplest version:*>*> Let x, twonorm(x) = 1, be an approximate singular vector of an j-by-j*> lower triangular matrix L, such that*> twonorm(L*x) = sest*> Then DLAIC1 computes sestpr, s, c such that*> the vector*> [ s*x ]*> xhat = [ c ]*> is an approximate singular vector of*> [ L 0 ]*> Lhat = [ w**T gamma ]*> in the sense that*> twonorm(Lhat*xhat) = sestpr.*>*> Depending on JOB, an estimate for the largest or smallest singular*> value is computed.*>*> Note that [s c]**T and sestpr**2 is an eigenpair of the system*>*> diag(sest*sest, 0) + [alpha gamma] * [ alpha ]*> [ gamma ]*>*> where alpha = x**T*w.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is INTEGER*> = 1: an estimate for the largest singular value is computed.*> = 2: an estimate for the smallest singular value is computed.*> \endverbatim*>*> \param[in] J*> \verbatim*> J is INTEGER*> Length of X and W*> \endverbatim*>*> \param[in] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (J)*> The j-vector x.*> \endverbatim*>*> \param[in] SEST*> \verbatim*> SEST is DOUBLE PRECISION*> Estimated singular value of j by j matrix L*> \endverbatim*>*> \param[in] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (J)*> The j-vector w.*> \endverbatim*>*> \param[in] GAMMA*> \verbatim*> GAMMA is DOUBLE PRECISION*> The diagonal element gamma.*> \endverbatim*>*> \param[out] SESTPR*> \verbatim*> SESTPR is DOUBLE PRECISION*> Estimated singular value of (j+1) by (j+1) matrix Lhat.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION*> Sine needed in forming xhat.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION*> Cosine needed in forming xhat.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAIC1( JOB, J, X, SEST, W, GAMMA, SESTPR, S, C )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER J, JOBDOUBLE PRECISION C, GAMMA, S, SEST, SESTPR* ..* .. Array Arguments ..DOUBLE PRECISION W( J ), X( J )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )DOUBLE PRECISION HALF, FOURPARAMETER ( HALF = 0.5D0, FOUR = 4.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION ABSALP, ABSEST, ABSGAM, ALPHA, B, COSINE, EPS,$ NORMA, S1, S2, SINE, T, TEST, TMP, ZETA1, ZETA2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SIGN, SQRT* ..* .. External Functions ..DOUBLE PRECISION DDOT, DLAMCHEXTERNAL DDOT, DLAMCH* ..* .. Executable Statements ..*EPS = DLAMCH( 'Epsilon' )ALPHA = DDOT( J, X, 1, W, 1 )*ABSALP = ABS( ALPHA )ABSGAM = ABS( GAMMA )ABSEST = ABS( SEST )*IF( JOB.EQ.1 ) THEN** Estimating largest singular value** special cases*IF( SEST.EQ.ZERO ) THENS1 = MAX( ABSGAM, ABSALP )IF( S1.EQ.ZERO ) THENS = ZEROC = ONESESTPR = ZEROELSES = ALPHA / S1C = GAMMA / S1TMP = SQRT( S*S+C*C )S = S / TMPC = C / TMPSESTPR = S1*TMPEND IFRETURNELSE IF( ABSGAM.LE.EPS*ABSEST ) THENS = ONEC = ZEROTMP = MAX( ABSEST, ABSALP )S1 = ABSEST / TMPS2 = ABSALP / TMPSESTPR = TMP*SQRT( S1*S1+S2*S2 )RETURNELSE IF( ABSALP.LE.EPS*ABSEST ) THENS1 = ABSGAMS2 = ABSESTIF( S1.LE.S2 ) THENS = ONEC = ZEROSESTPR = S2ELSES = ZEROC = ONESESTPR = S1END IFRETURNELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THENS1 = ABSGAMS2 = ABSALPIF( S1.LE.S2 ) THENTMP = S1 / S2S = SQRT( ONE+TMP*TMP )SESTPR = S2*SC = ( GAMMA / S2 ) / SS = SIGN( ONE, ALPHA ) / SELSETMP = S2 / S1C = SQRT( ONE+TMP*TMP )SESTPR = S1*CS = ( ALPHA / S1 ) / CC = SIGN( ONE, GAMMA ) / CEND IFRETURNELSE** normal case*ZETA1 = ALPHA / ABSESTZETA2 = GAMMA / ABSEST*B = ( ONE-ZETA1*ZETA1-ZETA2*ZETA2 )*HALFC = ZETA1*ZETA1IF( B.GT.ZERO ) THENT = C / ( B+SQRT( B*B+C ) )ELSET = SQRT( B*B+C ) - BEND IF*SINE = -ZETA1 / TCOSINE = -ZETA2 / ( ONE+T )TMP = SQRT( SINE*SINE+COSINE*COSINE )S = SINE / TMPC = COSINE / TMPSESTPR = SQRT( T+ONE )*ABSESTRETURNEND IF*ELSE IF( JOB.EQ.2 ) THEN** Estimating smallest singular value** special cases*IF( SEST.EQ.ZERO ) THENSESTPR = ZEROIF( MAX( ABSGAM, ABSALP ).EQ.ZERO ) THENSINE = ONECOSINE = ZEROELSESINE = -GAMMACOSINE = ALPHAEND IFS1 = MAX( ABS( SINE ), ABS( COSINE ) )S = SINE / S1C = COSINE / S1TMP = SQRT( S*S+C*C )S = S / TMPC = C / TMPRETURNELSE IF( ABSGAM.LE.EPS*ABSEST ) THENS = ZEROC = ONESESTPR = ABSGAMRETURNELSE IF( ABSALP.LE.EPS*ABSEST ) THENS1 = ABSGAMS2 = ABSESTIF( S1.LE.S2 ) THENS = ZEROC = ONESESTPR = S1ELSES = ONEC = ZEROSESTPR = S2END IFRETURNELSE IF( ABSEST.LE.EPS*ABSALP .OR. ABSEST.LE.EPS*ABSGAM ) THENS1 = ABSGAMS2 = ABSALPIF( S1.LE.S2 ) THENTMP = S1 / S2C = SQRT( ONE+TMP*TMP )SESTPR = ABSEST*( TMP / C )S = -( GAMMA / S2 ) / CC = SIGN( ONE, ALPHA ) / CELSETMP = S2 / S1S = SQRT( ONE+TMP*TMP )SESTPR = ABSEST / SC = ( ALPHA / S1 ) / SS = -SIGN( ONE, GAMMA ) / SEND IFRETURNELSE** normal case*ZETA1 = ALPHA / ABSESTZETA2 = GAMMA / ABSEST*NORMA = MAX( ONE+ZETA1*ZETA1+ABS( ZETA1*ZETA2 ),$ ABS( ZETA1*ZETA2 )+ZETA2*ZETA2 )** See if root is closer to zero or to ONE*TEST = ONE + TWO*( ZETA1-ZETA2 )*( ZETA1+ZETA2 )IF( TEST.GE.ZERO ) THEN** root is close to zero, compute directly*B = ( ZETA1*ZETA1+ZETA2*ZETA2+ONE )*HALFC = ZETA2*ZETA2T = C / ( B+SQRT( ABS( B*B-C ) ) )SINE = ZETA1 / ( ONE-T )COSINE = -ZETA2 / TSESTPR = SQRT( T+FOUR*EPS*EPS*NORMA )*ABSESTELSE** root is closer to ONE, shift by that amount*B = ( ZETA2*ZETA2+ZETA1*ZETA1-ONE )*HALFC = ZETA1*ZETA1IF( B.GE.ZERO ) THENT = -C / ( B+SQRT( B*B+C ) )ELSET = B - SQRT( B*B+C )END IFSINE = -ZETA1 / TCOSINE = -ZETA2 / ( ONE+T )SESTPR = SQRT( ONE+T+FOUR*EPS*EPS*NORMA )*ABSESTEND IFTMP = SQRT( SINE*SINE+COSINE*COSINE )S = SINE / TMPC = COSINE / TMPRETURN*END IFEND IFRETURN** End of DLAIC1*END*> \brief \b DLAISNAN tests input for NaN by comparing two arguments for inequality.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAISNAN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaisnan.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaisnan.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaisnan.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 )** .. Scalar Arguments ..* DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is not for general use. It exists solely to avoid*> over-optimization in DISNAN.*>*> DLAISNAN checks for NaNs by comparing its two arguments for*> inequality. NaN is the only floating-point value where NaN != NaN*> returns .TRUE. To check for NaNs, pass the same variable as both*> arguments.*>*> A compiler must assume that the two arguments are*> not the same variable, and the test will not be optimized away.*> Interprocedural or whole-program optimization may delete this*> test. The ISNAN functions will be replaced by the correct*> Fortran 03 intrinsic once the intrinsic is widely available.*> \endverbatim** Arguments:* ==========**> \param[in] DIN1*> \verbatim*> DIN1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] DIN2*> \verbatim*> DIN2 is DOUBLE PRECISION*> Two numbers to compare for inequality.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary** =====================================================================LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..DOUBLE PRECISION, INTENT(IN) :: DIN1, DIN2* ..** =====================================================================** .. Executable Statements ..DLAISNAN = (DIN1.NE.DIN2)RETURNEND*> \brief \b DLALN2 solves a 1-by-1 or 2-by-2 linear system of equations of the specified form.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLALN2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaln2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaln2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaln2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,* LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )** .. Scalar Arguments ..* LOGICAL LTRANS* INTEGER INFO, LDA, LDB, LDX, NA, NW* DOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLALN2 solves a system of the form (ca A - w D ) X = s B*> or (ca A**T - w D) X = s B with possible scaling ("s") and*> perturbation of A. (A**T means A-transpose.)*>*> A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA*> real diagonal matrix, w is a real or complex value, and X and B are*> NA x 1 matrices -- real if w is real, complex if w is complex. NA*> may be 1 or 2.*>*> If w is complex, X and B are represented as NA x 2 matrices,*> the first column of each being the real part and the second*> being the imaginary part.*>*> "s" is a scaling factor (.LE. 1), computed by DLALN2, which is*> so chosen that X can be computed without overflow. X is further*> scaled if necessary to assure that norm(ca A - w D)*norm(X) is less*> than overflow.*>*> If both singular values of (ca A - w D) are less than SMIN,*> SMIN*identity will be used instead of (ca A - w D). If only one*> singular value is less than SMIN, one element of (ca A - w D) will be*> perturbed enough to make the smallest singular value roughly SMIN.*> If both singular values are at least SMIN, (ca A - w D) will not be*> perturbed. In any case, the perturbation will be at most some small*> multiple of max( SMIN, ulp*norm(ca A - w D) ). The singular values*> are computed by infinity-norm approximations, and thus will only be*> correct to a factor of 2 or so.*>*> Note: all input quantities are assumed to be smaller than overflow*> by a reasonable factor. (See BIGNUM.)*> \endverbatim** Arguments:* ==========**> \param[in] LTRANS*> \verbatim*> LTRANS is LOGICAL*> =.TRUE.: A-transpose will be used.*> =.FALSE.: A will be used (not transposed.)*> \endverbatim*>*> \param[in] NA*> \verbatim*> NA is INTEGER*> The size of the matrix A. It may (only) be 1 or 2.*> \endverbatim*>*> \param[in] NW*> \verbatim*> NW is INTEGER*> 1 if "w" is real, 2 if "w" is complex. It may only be 1*> or 2.*> \endverbatim*>*> \param[in] SMIN*> \verbatim*> SMIN is DOUBLE PRECISION*> The desired lower bound on the singular values of A. This*> should be a safe distance away from underflow or overflow,*> say, between (underflow/machine precision) and (machine*> precision * overflow ). (See BIGNUM and ULP.)*> \endverbatim*>*> \param[in] CA*> \verbatim*> CA is DOUBLE PRECISION*> The coefficient c, which A is multiplied by.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,NA)*> The NA x NA matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of A. It must be at least NA.*> \endverbatim*>*> \param[in] D1*> \verbatim*> D1 is DOUBLE PRECISION*> The 1,1 element in the diagonal matrix D.*> \endverbatim*>*> \param[in] D2*> \verbatim*> D2 is DOUBLE PRECISION*> The 2,2 element in the diagonal matrix D. Not used if NA=1.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NW)*> The NA x NW matrix B (right-hand side). If NW=2 ("w" is*> complex), column 1 contains the real part of B and column 2*> contains the imaginary part.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. It must be at least NA.*> \endverbatim*>*> \param[in] WR*> \verbatim*> WR is DOUBLE PRECISION*> The real part of the scalar "w".*> \endverbatim*>*> \param[in] WI*> \verbatim*> WI is DOUBLE PRECISION*> The imaginary part of the scalar "w". Not used if NW=1.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NW)*> The NA x NW matrix X (unknowns), as computed by DLALN2.*> If NW=2 ("w" is complex), on exit, column 1 will contain*> the real part of X and column 2 will contain the imaginary*> part.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of X. It must be at least NA.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> The scale factor that B must be multiplied by to insure*> that overflow does not occur when computing X. Thus,*> (ca A - w D) X will be SCALE*B, not B (ignoring*> perturbations of A.) It will be at most 1.*> \endverbatim*>*> \param[out] XNORM*> \verbatim*> XNORM is DOUBLE PRECISION*> The infinity-norm of X, when X is regarded as an NA x NW*> real matrix.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> An error flag. It will be set to zero if no error occurs,*> a negative number if an argument is in error, or a positive*> number if ca A - w D had to be perturbed.*> The possible values are:*> = 0: No error occurred, and (ca A - w D) did not have to be*> perturbed.*> = 1: (ca A - w D) had to be perturbed to make its smallest*> (or only) singular value greater than SMIN.*> NOTE: In the interests of speed, this routine does not*> check the inputs for errors.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,$ LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL LTRANSINTEGER INFO, LDA, LDB, LDX, NA, NWDOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..INTEGER ICMAX, JDOUBLE PRECISION BBND, BI1, BI2, BIGNUM, BNORM, BR1, BR2, CI21,$ CI22, CMAX, CNORM, CR21, CR22, CSI, CSR, LI21,$ LR21, SMINI, SMLNUM, TEMP, U22ABS, UI11, UI11R,$ UI12, UI12S, UI22, UR11, UR11R, UR12, UR12S,$ UR22, XI1, XI2, XR1, XR2* ..* .. Local Arrays ..LOGICAL RSWAP( 4 ), ZSWAP( 4 )INTEGER IPIVOT( 4, 4 )DOUBLE PRECISION CI( 2, 2 ), CIV( 4 ), CR( 2, 2 ), CRV( 4 )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DLADIV* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Equivalences ..EQUIVALENCE ( CI( 1, 1 ), CIV( 1 ) ),$ ( CR( 1, 1 ), CRV( 1 ) )* ..* .. Data statements ..DATA ZSWAP / .FALSE., .FALSE., .TRUE., .TRUE. /DATA RSWAP / .FALSE., .TRUE., .FALSE., .TRUE. /DATA IPIVOT / 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4,$ 3, 2, 1 /* ..* .. Executable Statements ..** Compute BIGNUM*SMLNUM = TWO*DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMSMINI = MAX( SMIN, SMLNUM )** Don't check for input errors*INFO = 0** Standard Initializations*SCALE = ONE*IF( NA.EQ.1 ) THEN** 1 x 1 (i.e., scalar) system C X = B*IF( NW.EQ.1 ) THEN** Real 1x1 system.** C = ca A - w D*CSR = CA*A( 1, 1 ) - WR*D1CNORM = ABS( CSR )** If | C | < SMINI, use C = SMINI*IF( CNORM.LT.SMINI ) THENCSR = SMINICNORM = SMINIINFO = 1END IF** Check scaling for X = B / C*BNORM = ABS( B( 1, 1 ) )IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*CNORM )$ SCALE = ONE / BNORMEND IF** Compute X*X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / CSRXNORM = ABS( X( 1, 1 ) )ELSE** Complex 1x1 system (w is complex)** C = ca A - w D*CSR = CA*A( 1, 1 ) - WR*D1CSI = -WI*D1CNORM = ABS( CSR ) + ABS( CSI )** If | C | < SMINI, use C = SMINI*IF( CNORM.LT.SMINI ) THENCSR = SMINICSI = ZEROCNORM = SMINIINFO = 1END IF** Check scaling for X = B / C*BNORM = ABS( B( 1, 1 ) ) + ABS( B( 1, 2 ) )IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*CNORM )$ SCALE = ONE / BNORMEND IF** Compute X*CALL DLADIV( SCALE*B( 1, 1 ), SCALE*B( 1, 2 ), CSR, CSI,$ X( 1, 1 ), X( 1, 2 ) )XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )END IF*ELSE** 2x2 System** Compute the real part of C = ca A - w D (or ca A**T - w D )*CR( 1, 1 ) = CA*A( 1, 1 ) - WR*D1CR( 2, 2 ) = CA*A( 2, 2 ) - WR*D2IF( LTRANS ) THENCR( 1, 2 ) = CA*A( 2, 1 )CR( 2, 1 ) = CA*A( 1, 2 )ELSECR( 2, 1 ) = CA*A( 2, 1 )CR( 1, 2 ) = CA*A( 1, 2 )END IF*IF( NW.EQ.1 ) THEN** Real 2x2 system (w is real)** Find the largest element in C*CMAX = ZEROICMAX = 0*DO 10 J = 1, 4IF( ABS( CRV( J ) ).GT.CMAX ) THENCMAX = ABS( CRV( J ) )ICMAX = JEND IF10 CONTINUE** If norm(C) < SMINI, use SMINI*identity.*IF( CMAX.LT.SMINI ) THENBNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 2, 1 ) ) )IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*SMINI )$ SCALE = ONE / BNORMEND IFTEMP = SCALE / SMINIX( 1, 1 ) = TEMP*B( 1, 1 )X( 2, 1 ) = TEMP*B( 2, 1 )XNORM = TEMP*BNORMINFO = 1RETURNEND IF** Gaussian elimination with complete pivoting.*UR11 = CRV( ICMAX )CR21 = CRV( IPIVOT( 2, ICMAX ) )UR12 = CRV( IPIVOT( 3, ICMAX ) )CR22 = CRV( IPIVOT( 4, ICMAX ) )UR11R = ONE / UR11LR21 = UR11R*CR21UR22 = CR22 - UR12*LR21** If smaller pivot < SMINI, use SMINI*IF( ABS( UR22 ).LT.SMINI ) THENUR22 = SMINIINFO = 1END IFIF( RSWAP( ICMAX ) ) THENBR1 = B( 2, 1 )BR2 = B( 1, 1 )ELSEBR1 = B( 1, 1 )BR2 = B( 2, 1 )END IFBR2 = BR2 - LR21*BR1BBND = MAX( ABS( BR1*( UR22*UR11R ) ), ABS( BR2 ) )IF( BBND.GT.ONE .AND. ABS( UR22 ).LT.ONE ) THENIF( BBND.GE.BIGNUM*ABS( UR22 ) )$ SCALE = ONE / BBNDEND IF*XR2 = ( BR2*SCALE ) / UR22XR1 = ( SCALE*BR1 )*UR11R - XR2*( UR11R*UR12 )IF( ZSWAP( ICMAX ) ) THENX( 1, 1 ) = XR2X( 2, 1 ) = XR1ELSEX( 1, 1 ) = XR1X( 2, 1 ) = XR2END IFXNORM = MAX( ABS( XR1 ), ABS( XR2 ) )** Further scaling if norm(A) norm(X) > overflow*IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THENIF( XNORM.GT.BIGNUM / CMAX ) THENTEMP = CMAX / BIGNUMX( 1, 1 ) = TEMP*X( 1, 1 )X( 2, 1 ) = TEMP*X( 2, 1 )XNORM = TEMP*XNORMSCALE = TEMP*SCALEEND IFEND IFELSE** Complex 2x2 system (w is complex)** Find the largest element in C*CI( 1, 1 ) = -WI*D1CI( 2, 1 ) = ZEROCI( 1, 2 ) = ZEROCI( 2, 2 ) = -WI*D2CMAX = ZEROICMAX = 0*DO 20 J = 1, 4IF( ABS( CRV( J ) )+ABS( CIV( J ) ).GT.CMAX ) THENCMAX = ABS( CRV( J ) ) + ABS( CIV( J ) )ICMAX = JEND IF20 CONTINUE** If norm(C) < SMINI, use SMINI*identity.*IF( CMAX.LT.SMINI ) THENBNORM = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),$ ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THENIF( BNORM.GT.BIGNUM*SMINI )$ SCALE = ONE / BNORMEND IFTEMP = SCALE / SMINIX( 1, 1 ) = TEMP*B( 1, 1 )X( 2, 1 ) = TEMP*B( 2, 1 )X( 1, 2 ) = TEMP*B( 1, 2 )X( 2, 2 ) = TEMP*B( 2, 2 )XNORM = TEMP*BNORMINFO = 1RETURNEND IF** Gaussian elimination with complete pivoting.*UR11 = CRV( ICMAX )UI11 = CIV( ICMAX )CR21 = CRV( IPIVOT( 2, ICMAX ) )CI21 = CIV( IPIVOT( 2, ICMAX ) )UR12 = CRV( IPIVOT( 3, ICMAX ) )UI12 = CIV( IPIVOT( 3, ICMAX ) )CR22 = CRV( IPIVOT( 4, ICMAX ) )CI22 = CIV( IPIVOT( 4, ICMAX ) )IF( ICMAX.EQ.1 .OR. ICMAX.EQ.4 ) THEN** Code when off-diagonals of pivoted C are real*IF( ABS( UR11 ).GT.ABS( UI11 ) ) THENTEMP = UI11 / UR11UR11R = ONE / ( UR11*( ONE+TEMP**2 ) )UI11R = -TEMP*UR11RELSETEMP = UR11 / UI11UI11R = -ONE / ( UI11*( ONE+TEMP**2 ) )UR11R = -TEMP*UI11REND IFLR21 = CR21*UR11RLI21 = CR21*UI11RUR12S = UR12*UR11RUI12S = UR12*UI11RUR22 = CR22 - UR12*LR21UI22 = CI22 - UR12*LI21ELSE** Code when diagonals of pivoted C are real*UR11R = ONE / UR11UI11R = ZEROLR21 = CR21*UR11RLI21 = CI21*UR11RUR12S = UR12*UR11RUI12S = UI12*UR11RUR22 = CR22 - UR12*LR21 + UI12*LI21UI22 = -UR12*LI21 - UI12*LR21END IFU22ABS = ABS( UR22 ) + ABS( UI22 )** If smaller pivot < SMINI, use SMINI*IF( U22ABS.LT.SMINI ) THENUR22 = SMINIUI22 = ZEROINFO = 1END IFIF( RSWAP( ICMAX ) ) THENBR2 = B( 1, 1 )BR1 = B( 2, 1 )BI2 = B( 1, 2 )BI1 = B( 2, 2 )ELSEBR1 = B( 1, 1 )BR2 = B( 2, 1 )BI1 = B( 1, 2 )BI2 = B( 2, 2 )END IFBR2 = BR2 - LR21*BR1 + LI21*BI1BI2 = BI2 - LI21*BR1 - LR21*BI1BBND = MAX( ( ABS( BR1 )+ABS( BI1 ) )*$ ( U22ABS*( ABS( UR11R )+ABS( UI11R ) ) ),$ ABS( BR2 )+ABS( BI2 ) )IF( BBND.GT.ONE .AND. U22ABS.LT.ONE ) THENIF( BBND.GE.BIGNUM*U22ABS ) THENSCALE = ONE / BBNDBR1 = SCALE*BR1BI1 = SCALE*BI1BR2 = SCALE*BR2BI2 = SCALE*BI2END IFEND IF*CALL DLADIV( BR2, BI2, UR22, UI22, XR2, XI2 )XR1 = UR11R*BR1 - UI11R*BI1 - UR12S*XR2 + UI12S*XI2XI1 = UI11R*BR1 + UR11R*BI1 - UI12S*XR2 - UR12S*XI2IF( ZSWAP( ICMAX ) ) THENX( 1, 1 ) = XR2X( 2, 1 ) = XR1X( 1, 2 ) = XI2X( 2, 2 ) = XI1ELSEX( 1, 1 ) = XR1X( 2, 1 ) = XR2X( 1, 2 ) = XI1X( 2, 2 ) = XI2END IFXNORM = MAX( ABS( XR1 )+ABS( XI1 ), ABS( XR2 )+ABS( XI2 ) )** Further scaling if norm(A) norm(X) > overflow*IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THENIF( XNORM.GT.BIGNUM / CMAX ) THENTEMP = CMAX / BIGNUMX( 1, 1 ) = TEMP*X( 1, 1 )X( 2, 1 ) = TEMP*X( 2, 1 )X( 1, 2 ) = TEMP*X( 1, 2 )X( 2, 2 ) = TEMP*X( 2, 2 )XNORM = TEMP*XNORMSCALE = TEMP*SCALEEND IFEND IFEND IFEND IF*RETURN** End of DLALN2*END*> \brief \b DLALS0 applies back multiplying factors in solving the least squares problem using divide and conquer SVD approach. Used by sgelsd.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLALS0 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlals0.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlals0.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlals0.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,* PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,* POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )** .. Scalar Arguments ..* INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,* $ LDGNUM, NL, NR, NRHS, SQRE* DOUBLE PRECISION C, S* ..* .. Array Arguments ..* INTEGER GIVCOL( LDGCOL, * ), PERM( * )* DOUBLE PRECISION B( LDB, * ), BX( LDBX, * ), DIFL( * ),* $ DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),* $ POLES( LDGNUM, * ), WORK( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLALS0 applies back the multiplying factors of either the left or the*> right singular vector matrix of a diagonal matrix appended by a row*> to the right hand side matrix B in solving the least squares problem*> using the divide-and-conquer SVD approach.*>*> For the left singular vector matrix, three types of orthogonal*> matrices are involved:*>*> (1L) Givens rotations: the number of such rotations is GIVPTR; the*> pairs of columns/rows they were applied to are stored in GIVCOL;*> and the C- and S-values of these rotations are stored in GIVNUM.*>*> (2L) Permutation. The (NL+1)-st row of B is to be moved to the first*> row, and for J=2:N, PERM(J)-th row of B is to be moved to the*> J-th row.*>*> (3L) The left singular vector matrix of the remaining matrix.*>*> For the right singular vector matrix, four types of orthogonal*> matrices are involved:*>*> (1R) The right singular vector matrix of the remaining matrix.*>*> (2R) If SQRE = 1, one extra Givens rotation to generate the right*> null space.*>*> (3R) The inverse transformation of (2L).*>*> (4R) The inverse transformation of (1L).*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> Specifies whether singular vectors are to be computed in*> factored form:*> = 0: Left singular vector matrix.*> = 1: Right singular vector matrix.*> \endverbatim*>*> \param[in] NL*> \verbatim*> NL is INTEGER*> The row dimension of the upper block. NL >= 1.*> \endverbatim*>*> \param[in] NR*> \verbatim*> NR is INTEGER*> The row dimension of the lower block. NR >= 1.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: the lower block is an NR-by-NR square matrix.*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.*>*> The bidiagonal matrix has row dimension N = NL + NR + 1,*> and column dimension M = N + SQRE.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of columns of B and BX. NRHS must be at least 1.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension ( LDB, NRHS )*> On input, B contains the right hand sides of the least*> squares problem in rows 1 through M. On output, B contains*> the solution X in rows 1 through N.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B. LDB must be at least*> max(1,MAX( M, N ) ).*> \endverbatim*>*> \param[out] BX*> \verbatim*> BX is DOUBLE PRECISION array, dimension ( LDBX, NRHS )*> \endverbatim*>*> \param[in] LDBX*> \verbatim*> LDBX is INTEGER*> The leading dimension of BX.*> \endverbatim*>*> \param[in] PERM*> \verbatim*> PERM is INTEGER array, dimension ( N )*> The permutations (from deflation and sorting) applied*> to the two blocks.*> \endverbatim*>*> \param[in] GIVPTR*> \verbatim*> GIVPTR is INTEGER*> The number of Givens rotations which took place in this*> subproblem.*> \endverbatim*>*> \param[in] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )*> Each pair of numbers indicates a pair of rows/columns*> involved in a Givens rotation.*> \endverbatim*>*> \param[in] LDGCOL*> \verbatim*> LDGCOL is INTEGER*> The leading dimension of GIVCOL, must be at least N.*> \endverbatim*>*> \param[in] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )*> Each number indicates the C or S value used in the*> corresponding Givens rotation.*> \endverbatim*>*> \param[in] LDGNUM*> \verbatim*> LDGNUM is INTEGER*> The leading dimension of arrays DIFR, POLES and*> GIVNUM, must be at least K.*> \endverbatim*>*> \param[in] POLES*> \verbatim*> POLES is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )*> On entry, POLES(1:K, 1) contains the new singular*> values obtained from solving the secular equation, and*> POLES(1:K, 2) is an array containing the poles in the secular*> equation.*> \endverbatim*>*> \param[in] DIFL*> \verbatim*> DIFL is DOUBLE PRECISION array, dimension ( K ).*> On entry, DIFL(I) is the distance between I-th updated*> (undeflated) singular value and the I-th (undeflated) old*> singular value.*> \endverbatim*>*> \param[in] DIFR*> \verbatim*> DIFR is DOUBLE PRECISION array, dimension ( LDGNUM, 2 ).*> On entry, DIFR(I, 1) contains the distances between I-th*> updated (undeflated) singular value and the I+1-th*> (undeflated) old singular value. And DIFR(I, 2) is the*> normalizing factor for the I-th right singular vector.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( K )*> Contain the components of the deflation-adjusted updating row*> vector.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> Contains the dimension of the non-deflated matrix,*> This is the order of the related secular equation. 1 <= K <=N.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION*> C contains garbage if SQRE =0 and the C-value of a Givens*> rotation related to the right null space if SQRE = 1.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION*> S contains garbage if SQRE =0 and the S-value of a Givens*> rotation related to the right null space if SQRE = 1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension ( K )*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Ming Gu and Ren-Cang Li, Computer Science Division, University of*> California at Berkeley, USA \n*> Osni Marques, LBNL/NERSC, USA \n** =====================================================================SUBROUTINE DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX,$ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,$ POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER GIVPTR, ICOMPQ, INFO, K, LDB, LDBX, LDGCOL,$ LDGNUM, NL, NR, NRHS, SQREDOUBLE PRECISION C, S* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), PERM( * )DOUBLE PRECISION B( LDB, * ), BX( LDBX, * ), DIFL( * ),$ DIFR( LDGNUM, * ), GIVNUM( LDGNUM, * ),$ POLES( LDGNUM, * ), WORK( * ), Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZERO, NEGONEPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0, NEGONE = -1.0D0 )* ..* .. Local Scalars ..INTEGER I, J, M, N, NLP1DOUBLE PRECISION DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, TEMP* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DLACPY, DLASCL, DROT, DSCAL,$ XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0N = NL + NR + 1*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( NL.LT.1 ) THENINFO = -2ELSE IF( NR.LT.1 ) THENINFO = -3ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -4ELSE IF( NRHS.LT.1 ) THENINFO = -5ELSE IF( LDB.LT.N ) THENINFO = -7ELSE IF( LDBX.LT.N ) THENINFO = -9ELSE IF( GIVPTR.LT.0 ) THENINFO = -11ELSE IF( LDGCOL.LT.N ) THENINFO = -13ELSE IF( LDGNUM.LT.N ) THENINFO = -15ELSE IF( K.LT.1 ) THENINFO = -20END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLALS0', -INFO )RETURNEND IF*M = N + SQRENLP1 = NL + 1*IF( ICOMPQ.EQ.0 ) THEN** Apply back orthogonal transformations from the left.** Step (1L): apply back the Givens rotations performed.*DO 10 I = 1, GIVPTRCALL DROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,$ B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),$ GIVNUM( I, 1 ) )10 CONTINUE** Step (2L): permute rows of B.*CALL DCOPY( NRHS, B( NLP1, 1 ), LDB, BX( 1, 1 ), LDBX )DO 20 I = 2, NCALL DCOPY( NRHS, B( PERM( I ), 1 ), LDB, BX( I, 1 ), LDBX )20 CONTINUE** Step (3L): apply the inverse of the left singular vector* matrix to BX.*IF( K.EQ.1 ) THENCALL DCOPY( NRHS, BX, LDBX, B, LDB )IF( Z( 1 ).LT.ZERO ) THENCALL DSCAL( NRHS, NEGONE, B, LDB )END IFELSEDO 50 J = 1, KDIFLJ = DIFL( J )DJ = POLES( J, 1 )DSIGJ = -POLES( J, 2 )IF( J.LT.K ) THENDIFRJ = -DIFR( J, 1 )DSIGJP = -POLES( J+1, 2 )END IFIF( ( Z( J ).EQ.ZERO ) .OR. ( POLES( J, 2 ).EQ.ZERO ) )$ THENWORK( J ) = ZEROELSEWORK( J ) = -POLES( J, 2 )*Z( J ) / DIFLJ /$ ( POLES( J, 2 )+DJ )END IFDO 30 I = 1, J - 1IF( ( Z( I ).EQ.ZERO ) .OR.$ ( POLES( I, 2 ).EQ.ZERO ) ) THENWORK( I ) = ZEROELSEWORK( I ) = POLES( I, 2 )*Z( I ) /$ ( DLAMC3( POLES( I, 2 ), DSIGJ )-$ DIFLJ ) / ( POLES( I, 2 )+DJ )END IF30 CONTINUEDO 40 I = J + 1, KIF( ( Z( I ).EQ.ZERO ) .OR.$ ( POLES( I, 2 ).EQ.ZERO ) ) THENWORK( I ) = ZEROELSEWORK( I ) = POLES( I, 2 )*Z( I ) /$ ( DLAMC3( POLES( I, 2 ), DSIGJP )+$ DIFRJ ) / ( POLES( I, 2 )+DJ )END IF40 CONTINUEWORK( 1 ) = NEGONETEMP = DNRM2( K, WORK, 1 )CALL DGEMV( 'T', K, NRHS, ONE, BX, LDBX, WORK, 1, ZERO,$ B( J, 1 ), LDB )CALL DLASCL( 'G', 0, 0, TEMP, ONE, 1, NRHS, B( J, 1 ),$ LDB, INFO )50 CONTINUEEND IF** Move the deflated rows of BX to B also.*IF( K.LT.MAX( M, N ) )$ CALL DLACPY( 'A', N-K, NRHS, BX( K+1, 1 ), LDBX,$ B( K+1, 1 ), LDB )ELSE** Apply back the right orthogonal transformations.** Step (1R): apply back the new right singular vector matrix* to B.*IF( K.EQ.1 ) THENCALL DCOPY( NRHS, B, LDB, BX, LDBX )ELSEDO 80 J = 1, KDSIGJ = POLES( J, 2 )IF( Z( J ).EQ.ZERO ) THENWORK( J ) = ZEROELSEWORK( J ) = -Z( J ) / DIFL( J ) /$ ( DSIGJ+POLES( J, 1 ) ) / DIFR( J, 2 )END IFDO 60 I = 1, J - 1IF( Z( J ).EQ.ZERO ) THENWORK( I ) = ZEROELSEWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I+1,$ 2 ) )-DIFR( I, 1 ) ) /$ ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )END IF60 CONTINUEDO 70 I = J + 1, KIF( Z( J ).EQ.ZERO ) THENWORK( I ) = ZEROELSEWORK( I ) = Z( J ) / ( DLAMC3( DSIGJ, -POLES( I,$ 2 ) )-DIFL( I ) ) /$ ( DSIGJ+POLES( I, 1 ) ) / DIFR( I, 2 )END IF70 CONTINUECALL DGEMV( 'T', K, NRHS, ONE, B, LDB, WORK, 1, ZERO,$ BX( J, 1 ), LDBX )80 CONTINUEEND IF** Step (2R): if SQRE = 1, apply back the rotation that is* related to the right null space of the subproblem.*IF( SQRE.EQ.1 ) THENCALL DCOPY( NRHS, B( M, 1 ), LDB, BX( M, 1 ), LDBX )CALL DROT( NRHS, BX( 1, 1 ), LDBX, BX( M, 1 ), LDBX, C, S )END IFIF( K.LT.MAX( M, N ) )$ CALL DLACPY( 'A', N-K, NRHS, B( K+1, 1 ), LDB, BX( K+1, 1 ),$ LDBX )** Step (3R): permute rows of B.*CALL DCOPY( NRHS, BX( 1, 1 ), LDBX, B( NLP1, 1 ), LDB )IF( SQRE.EQ.1 ) THENCALL DCOPY( NRHS, BX( M, 1 ), LDBX, B( M, 1 ), LDB )END IFDO 90 I = 2, NCALL DCOPY( NRHS, BX( I, 1 ), LDBX, B( PERM( I ), 1 ), LDB )90 CONTINUE** Step (4R): apply back the Givens rotations performed.*DO 100 I = GIVPTR, 1, -1CALL DROT( NRHS, B( GIVCOL( I, 2 ), 1 ), LDB,$ B( GIVCOL( I, 1 ), 1 ), LDB, GIVNUM( I, 2 ),$ -GIVNUM( I, 1 ) )100 CONTINUEEND IF*RETURN** End of DLALS0*END*> \brief \b DLALSA computes the SVD of the coefficient matrix in compact form. Used by sgelsd.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLALSA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlalsa.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlalsa.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlalsa.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,* LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,* GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK,* IWORK, INFO )** .. Scalar Arguments ..* INTEGER ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,* $ SMLSIZ* ..* .. Array Arguments ..* INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),* $ K( * ), PERM( LDGCOL, * )* DOUBLE PRECISION B( LDB, * ), BX( LDBX, * ), C( * ),* $ DIFL( LDU, * ), DIFR( LDU, * ),* $ GIVNUM( LDU, * ), POLES( LDU, * ), S( * ),* $ U( LDU, * ), VT( LDU, * ), WORK( * ),* $ Z( LDU, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLALSA is an itermediate step in solving the least squares problem*> by computing the SVD of the coefficient matrix in compact form (The*> singular vectors are computed as products of simple orthorgonal*> matrices.).*>*> If ICOMPQ = 0, DLALSA applies the inverse of the left singular vector*> matrix of an upper bidiagonal matrix to the right hand side; and if*> ICOMPQ = 1, DLALSA applies the right singular vector matrix to the*> right hand side. The singular vector matrices were generated in*> compact form by DLALSA.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> Specifies whether the left or the right singular vector*> matrix is involved.*> = 0: Left singular vector matrix*> = 1: Right singular vector matrix*> \endverbatim*>*> \param[in] SMLSIZ*> \verbatim*> SMLSIZ is INTEGER*> The maximum size of the subproblems at the bottom of the*> computation tree.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The row and column dimensions of the upper bidiagonal matrix.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of columns of B and BX. NRHS must be at least 1.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension ( LDB, NRHS )*> On input, B contains the right hand sides of the least*> squares problem in rows 1 through M.*> On output, B contains the solution X in rows 1 through N.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B in the calling subprogram.*> LDB must be at least max(1,MAX( M, N ) ).*> \endverbatim*>*> \param[out] BX*> \verbatim*> BX is DOUBLE PRECISION array, dimension ( LDBX, NRHS )*> On exit, the result of applying the left or right singular*> vector matrix to B.*> \endverbatim*>*> \param[in] LDBX*> \verbatim*> LDBX is INTEGER*> The leading dimension of BX.*> \endverbatim*>*> \param[in] U*> \verbatim*> U is DOUBLE PRECISION array, dimension ( LDU, SMLSIZ ).*> On entry, U contains the left singular vector matrices of all*> subproblems at the bottom level.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER, LDU = > N.*> The leading dimension of arrays U, VT, DIFL, DIFR,*> POLES, GIVNUM, and Z.*> \endverbatim*>*> \param[in] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension ( LDU, SMLSIZ+1 ).*> On entry, VT**T contains the right singular vector matrices of*> all subproblems at the bottom level.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER array, dimension ( N ).*> \endverbatim*>*> \param[in] DIFL*> \verbatim*> DIFL is DOUBLE PRECISION array, dimension ( LDU, NLVL ).*> where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1.*> \endverbatim*>*> \param[in] DIFR*> \verbatim*> DIFR is DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).*> On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record*> distances between singular values on the I-th level and*> singular values on the (I -1)-th level, and DIFR(*, 2 * I)*> record the normalizing factors of the right singular vectors*> matrices of subproblems on I-th level.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( LDU, NLVL ).*> On entry, Z(1, I) contains the components of the deflation-*> adjusted updating row vector for subproblems on the I-th*> level.*> \endverbatim*>*> \param[in] POLES*> \verbatim*> POLES is DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).*> On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old*> singular values involved in the secular equations on the I-th*> level.*> \endverbatim*>*> \param[in] GIVPTR*> \verbatim*> GIVPTR is INTEGER array, dimension ( N ).*> On entry, GIVPTR( I ) records the number of Givens*> rotations performed on the I-th problem on the computation*> tree.*> \endverbatim*>*> \param[in] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension ( LDGCOL, 2 * NLVL ).*> On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the*> locations of Givens rotations performed on the I-th level on*> the computation tree.*> \endverbatim*>*> \param[in] LDGCOL*> \verbatim*> LDGCOL is INTEGER, LDGCOL = > N.*> The leading dimension of arrays GIVCOL and PERM.*> \endverbatim*>*> \param[in] PERM*> \verbatim*> PERM is INTEGER array, dimension ( LDGCOL, NLVL ).*> On entry, PERM(*, I) records permutations done on the I-th*> level of the computation tree.*> \endverbatim*>*> \param[in] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ).*> On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-*> values of Givens rotations performed on the I-th level on the*> computation tree.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension ( N ).*> On entry, if the I-th subproblem is not square,*> C( I ) contains the C-value of a Givens rotation related to*> the right null space of the I-th subproblem.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension ( N ).*> On entry, if the I-th subproblem is not square,*> S( I ) contains the S-value of a Givens rotation related to*> the right null space of the I-th subproblem.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Ming Gu and Ren-Cang Li, Computer Science Division, University of*> California at Berkeley, USA \n*> Osni Marques, LBNL/NERSC, USA \n** =====================================================================SUBROUTINE DLALSA( ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U,$ LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR,$ GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER ICOMPQ, INFO, LDB, LDBX, LDGCOL, LDU, N, NRHS,$ SMLSIZ* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),$ K( * ), PERM( LDGCOL, * )DOUBLE PRECISION B( LDB, * ), BX( LDBX, * ), C( * ),$ DIFL( LDU, * ), DIFR( LDU, * ),$ GIVNUM( LDU, * ), POLES( LDU, * ), S( * ),$ U( LDU, * ), VT( LDU, * ), WORK( * ),$ Z( LDU, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..INTEGER I, I1, IC, IM1, INODE, J, LF, LL, LVL, LVL2,$ ND, NDB1, NDIML, NDIMR, NL, NLF, NLP1, NLVL,$ NR, NRF, NRP1, SQRE* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLALS0, DLASDT, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( SMLSIZ.LT.3 ) THENINFO = -2ELSE IF( N.LT.SMLSIZ ) THENINFO = -3ELSE IF( NRHS.LT.1 ) THENINFO = -4ELSE IF( LDB.LT.N ) THENINFO = -6ELSE IF( LDBX.LT.N ) THENINFO = -8ELSE IF( LDU.LT.N ) THENINFO = -10ELSE IF( LDGCOL.LT.N ) THENINFO = -19END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLALSA', -INFO )RETURNEND IF** Book-keeping and setting up the computation tree.*INODE = 1NDIML = INODE + NNDIMR = NDIML + N*CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),$ IWORK( NDIMR ), SMLSIZ )** The following code applies back the left singular vector factors.* For applying back the right singular vector factors, go to 50.*IF( ICOMPQ.EQ.1 ) THENGO TO 50END IF** The nodes on the bottom level of the tree were solved* by DLASDQ. The corresponding left and right singular vector* matrices are in explicit form. First apply back the left* singular vector matrices.*NDB1 = ( ND+1 ) / 2DO 10 I = NDB1, ND** IC : center row of each node* NL : number of rows of left subproblem* NR : number of rows of right subproblem* NLF: starting row of the left subproblem* NRF: starting row of the right subproblem*I1 = I - 1IC = IWORK( INODE+I1 )NL = IWORK( NDIML+I1 )NR = IWORK( NDIMR+I1 )NLF = IC - NLNRF = IC + 1CALL DGEMM( 'T', 'N', NL, NRHS, NL, ONE, U( NLF, 1 ), LDU,$ B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )CALL DGEMM( 'T', 'N', NR, NRHS, NR, ONE, U( NRF, 1 ), LDU,$ B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )10 CONTINUE** Next copy the rows of B that correspond to unchanged rows* in the bidiagonal matrix to BX.*DO 20 I = 1, NDIC = IWORK( INODE+I-1 )CALL DCOPY( NRHS, B( IC, 1 ), LDB, BX( IC, 1 ), LDBX )20 CONTINUE** Finally go through the left singular vector matrices of all* the other subproblems bottom-up on the tree.*J = 2**NLVLSQRE = 0*DO 40 LVL = NLVL, 1, -1LVL2 = 2*LVL - 1** find the first node LF and last node LL on* the current level LVL*IF( LVL.EQ.1 ) THENLF = 1LL = 1ELSELF = 2**( LVL-1 )LL = 2*LF - 1END IFDO 30 I = LF, LLIM1 = I - 1IC = IWORK( INODE+IM1 )NL = IWORK( NDIML+IM1 )NR = IWORK( NDIMR+IM1 )NLF = IC - NLNRF = IC + 1J = J - 1CALL DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, BX( NLF, 1 ), LDBX,$ B( NLF, 1 ), LDB, PERM( NLF, LVL ),$ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,$ GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),$ DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),$ Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,$ INFO )30 CONTINUE40 CONTINUEGO TO 90** ICOMPQ = 1: applying back the right singular vector factors.*50 CONTINUE** First now go through the right singular vector matrices of all* the tree nodes top-down.*J = 0DO 70 LVL = 1, NLVLLVL2 = 2*LVL - 1** Find the first node LF and last node LL on* the current level LVL.*IF( LVL.EQ.1 ) THENLF = 1LL = 1ELSELF = 2**( LVL-1 )LL = 2*LF - 1END IFDO 60 I = LL, LF, -1IM1 = I - 1IC = IWORK( INODE+IM1 )NL = IWORK( NDIML+IM1 )NR = IWORK( NDIMR+IM1 )NLF = IC - NLNRF = IC + 1IF( I.EQ.LL ) THENSQRE = 0ELSESQRE = 1END IFJ = J + 1CALL DLALS0( ICOMPQ, NL, NR, SQRE, NRHS, B( NLF, 1 ), LDB,$ BX( NLF, 1 ), LDBX, PERM( NLF, LVL ),$ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,$ GIVNUM( NLF, LVL2 ), LDU, POLES( NLF, LVL2 ),$ DIFL( NLF, LVL ), DIFR( NLF, LVL2 ),$ Z( NLF, LVL ), K( J ), C( J ), S( J ), WORK,$ INFO )60 CONTINUE70 CONTINUE** The nodes on the bottom level of the tree were solved* by DLASDQ. The corresponding right singular vector* matrices are in explicit form. Apply them back.*NDB1 = ( ND+1 ) / 2DO 80 I = NDB1, NDI1 = I - 1IC = IWORK( INODE+I1 )NL = IWORK( NDIML+I1 )NR = IWORK( NDIMR+I1 )NLP1 = NL + 1IF( I.EQ.ND ) THENNRP1 = NRELSENRP1 = NR + 1END IFNLF = IC - NLNRF = IC + 1CALL DGEMM( 'T', 'N', NLP1, NRHS, NLP1, ONE, VT( NLF, 1 ), LDU,$ B( NLF, 1 ), LDB, ZERO, BX( NLF, 1 ), LDBX )CALL DGEMM( 'T', 'N', NRP1, NRHS, NRP1, ONE, VT( NRF, 1 ), LDU,$ B( NRF, 1 ), LDB, ZERO, BX( NRF, 1 ), LDBX )80 CONTINUE*90 CONTINUE*RETURN** End of DLALSA*END*> \brief \b DLALSD uses the singular value decomposition of A to solve the least squares problem.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLALSD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlalsd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlalsd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlalsd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,* RANK, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION B( LDB, * ), D( * ), E( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLALSD uses the singular value decomposition of A to solve the least*> squares problem of finding X to minimize the Euclidean norm of each*> column of A*X-B, where A is N-by-N upper bidiagonal, and X and B*> are N-by-NRHS. The solution X overwrites B.*>*> The singular values of A smaller than RCOND times the largest*> singular value are treated as zero in solving the least squares*> problem; in this case a minimum norm solution is returned.*> The actual singular values are returned in D in ascending order.*>*> This code makes very mild assumptions about floating point*> arithmetic. It will work on machines with a guard digit in*> add/subtract, or on those binary machines without guard digits*> which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.*> It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': D and E define an upper bidiagonal matrix.*> = 'L': D and E define a lower bidiagonal matrix.*> \endverbatim*>*> \param[in] SMLSIZ*> \verbatim*> SMLSIZ is INTEGER*> The maximum size of the subproblems at the bottom of the*> computation tree.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the bidiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of columns of B. NRHS must be at least 1.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry D contains the main diagonal of the bidiagonal*> matrix. On exit, if INFO = 0, D contains its singular values.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> Contains the super-diagonal entries of the bidiagonal matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On input, B contains the right hand sides of the least*> squares problem. On output, B contains the solution X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of B in the calling subprogram.*> LDB must be at least max(1,N).*> \endverbatim*>*> \param[in] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The singular values of A less than or equal to RCOND times*> the largest singular value are treated as zero in solving*> the least squares problem. If RCOND is negative,*> machine precision is used instead.*> For example, if diag(S)*X=B were the least squares problem,*> where diag(S) is a diagonal matrix of singular values, the*> solution would be X(i) = B(i) / S(i) if S(i) is greater than*> RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to*> RCOND*max(S).*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The number of singular values of A greater than RCOND times*> the largest singular value.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension at least*> (9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2),*> where NLVL = max(0, INT(log_2 (N/(SMLSIZ+1))) + 1).*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension at least*> (3*N*NLVL + 11*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: The algorithm failed to compute a singular value while*> working on the submatrix lying in rows and columns*> INFO/(N+1) through MOD(INFO,N+1).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Ming Gu and Ren-Cang Li, Computer Science Division, University of*> California at Berkeley, USA \n*> Osni Marques, LBNL/NERSC, USA \n** =====================================================================SUBROUTINE DLALSD( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,$ RANK, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, N, NRHS, RANK, SMLSIZDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION B( LDB, * ), D( * ), E( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )* ..* .. Local Scalars ..INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,$ GIVPTR, I, ICMPQ1, ICMPQ2, IWK, J, K, NLVL,$ NM1, NSIZE, NSUB, NWORK, PERM, POLES, S, SIZEI,$ SMLSZP, SQRE, ST, ST1, U, VT, ZDOUBLE PRECISION CS, EPS, ORGNRM, R, RCND, SN, TOL* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL IDAMAX, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLALSA, DLARTG, DLASCL,$ DLASDA, DLASDQ, DLASET, DLASRT, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, SIGN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.1 ) THENINFO = -4ELSE IF( ( LDB.LT.1 ) .OR. ( LDB.LT.N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLALSD', -INFO )RETURNEND IF*EPS = DLAMCH( 'Epsilon' )** Set up the tolerance.*IF( ( RCOND.LE.ZERO ) .OR. ( RCOND.GE.ONE ) ) THENRCND = EPSELSERCND = RCONDEND IF*RANK = 0** Quick return if possible.*IF( N.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THENIF( D( 1 ).EQ.ZERO ) THENCALL DLASET( 'A', 1, NRHS, ZERO, ZERO, B, LDB )ELSERANK = 1CALL DLASCL( 'G', 0, 0, D( 1 ), ONE, 1, NRHS, B, LDB, INFO )D( 1 ) = ABS( D( 1 ) )END IFRETURNEND IF** Rotate the matrix if it is lower bidiagonal.*IF( UPLO.EQ.'L' ) THENDO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )IF( NRHS.EQ.1 ) THENCALL DROT( 1, B( I, 1 ), 1, B( I+1, 1 ), 1, CS, SN )ELSEWORK( I*2-1 ) = CSWORK( I*2 ) = SNEND IF10 CONTINUEIF( NRHS.GT.1 ) THENDO 30 I = 1, NRHSDO 20 J = 1, N - 1CS = WORK( J*2-1 )SN = WORK( J*2 )CALL DROT( 1, B( J, I ), 1, B( J+1, I ), 1, CS, SN )20 CONTINUE30 CONTINUEEND IFEND IF** Scale.*NM1 = N - 1ORGNRM = DLANST( 'M', N, D, E )IF( ORGNRM.EQ.ZERO ) THENCALL DLASET( 'A', N, NRHS, ZERO, ZERO, B, LDB )RETURNEND IF*CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, NM1, 1, E, NM1, INFO )** If N is smaller than the minimum divide size SMLSIZ, then solve* the problem with another solver.*IF( N.LE.SMLSIZ ) THENNWORK = 1 + N*NCALL DLASET( 'A', N, N, ZERO, ONE, WORK, N )CALL DLASDQ( 'U', 0, N, N, 0, NRHS, D, E, WORK, N, WORK, N, B,$ LDB, WORK( NWORK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFTOL = RCND*ABS( D( IDAMAX( N, D, 1 ) ) )DO 40 I = 1, NIF( D( I ).LE.TOL ) THENCALL DLASET( 'A', 1, NRHS, ZERO, ZERO, B( I, 1 ), LDB )ELSECALL DLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS, B( I, 1 ),$ LDB, INFO )RANK = RANK + 1END IF40 CONTINUECALL DGEMM( 'T', 'N', N, NRHS, N, ONE, WORK, N, B, LDB, ZERO,$ WORK( NWORK ), N )CALL DLACPY( 'A', N, NRHS, WORK( NWORK ), N, B, LDB )** Unscale.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )CALL DLASRT( 'D', N, D, INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )*RETURNEND IF** Book-keeping and setting up some constants.*NLVL = INT( LOG( DBLE( N ) / DBLE( SMLSIZ+1 ) ) / LOG( TWO ) ) + 1*SMLSZP = SMLSIZ + 1*U = 1VT = 1 + SMLSIZ*NDIFL = VT + SMLSZP*NDIFR = DIFL + NLVL*NZ = DIFR + NLVL*N*2C = Z + NLVL*NS = C + NPOLES = S + NGIVNUM = POLES + 2*NLVL*NBX = GIVNUM + 2*NLVL*NNWORK = BX + N*NRHS*SIZEI = 1 + NK = SIZEI + NGIVPTR = K + NPERM = GIVPTR + NGIVCOL = PERM + NLVL*NIWK = GIVCOL + NLVL*N*2*ST = 1SQRE = 0ICMPQ1 = 1ICMPQ2 = 0NSUB = 0*DO 50 I = 1, NIF( ABS( D( I ) ).LT.EPS ) THEND( I ) = SIGN( EPS, D( I ) )END IF50 CONTINUE*DO 60 I = 1, NM1IF( ( ABS( E( I ) ).LT.EPS ) .OR. ( I.EQ.NM1 ) ) THENNSUB = NSUB + 1IWORK( NSUB ) = ST** Subproblem found. First determine its size and then* apply divide and conquer on it.*IF( I.LT.NM1 ) THEN** A subproblem with E(I) small for I < NM1.*NSIZE = I - ST + 1IWORK( SIZEI+NSUB-1 ) = NSIZEELSE IF( ABS( E( I ) ).GE.EPS ) THEN** A subproblem with E(NM1) not too small but I = NM1.*NSIZE = N - ST + 1IWORK( SIZEI+NSUB-1 ) = NSIZEELSE** A subproblem with E(NM1) small. This implies an* 1-by-1 subproblem at D(N), which is not solved* explicitly.*NSIZE = I - ST + 1IWORK( SIZEI+NSUB-1 ) = NSIZENSUB = NSUB + 1IWORK( NSUB ) = NIWORK( SIZEI+NSUB-1 ) = 1CALL DCOPY( NRHS, B( N, 1 ), LDB, WORK( BX+NM1 ), N )END IFST1 = ST - 1IF( NSIZE.EQ.1 ) THEN** This is a 1-by-1 subproblem and is not solved* explicitly.*CALL DCOPY( NRHS, B( ST, 1 ), LDB, WORK( BX+ST1 ), N )ELSE IF( NSIZE.LE.SMLSIZ ) THEN** This is a small subproblem and is solved by DLASDQ.*CALL DLASET( 'A', NSIZE, NSIZE, ZERO, ONE,$ WORK( VT+ST1 ), N )CALL DLASDQ( 'U', 0, NSIZE, NSIZE, 0, NRHS, D( ST ),$ E( ST ), WORK( VT+ST1 ), N, WORK( NWORK ),$ N, B( ST, 1 ), LDB, WORK( NWORK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFCALL DLACPY( 'A', NSIZE, NRHS, B( ST, 1 ), LDB,$ WORK( BX+ST1 ), N )ELSE** A large problem. Solve it using divide and conquer.*CALL DLASDA( ICMPQ1, SMLSIZ, NSIZE, SQRE, D( ST ),$ E( ST ), WORK( U+ST1 ), N, WORK( VT+ST1 ),$ IWORK( K+ST1 ), WORK( DIFL+ST1 ),$ WORK( DIFR+ST1 ), WORK( Z+ST1 ),$ WORK( POLES+ST1 ), IWORK( GIVPTR+ST1 ),$ IWORK( GIVCOL+ST1 ), N, IWORK( PERM+ST1 ),$ WORK( GIVNUM+ST1 ), WORK( C+ST1 ),$ WORK( S+ST1 ), WORK( NWORK ), IWORK( IWK ),$ INFO )IF( INFO.NE.0 ) THENRETURNEND IFBXST = BX + ST1CALL DLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, B( ST, 1 ),$ LDB, WORK( BXST ), N, WORK( U+ST1 ), N,$ WORK( VT+ST1 ), IWORK( K+ST1 ),$ WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),$ WORK( Z+ST1 ), WORK( POLES+ST1 ),$ IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,$ IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),$ WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),$ IWORK( IWK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFEND IFST = I + 1END IF60 CONTINUE** Apply the singular values and treat the tiny ones as zero.*TOL = RCND*ABS( D( IDAMAX( N, D, 1 ) ) )*DO 70 I = 1, N** Some of the elements in D can be negative because 1-by-1* subproblems were not solved explicitly.*IF( ABS( D( I ) ).LE.TOL ) THENCALL DLASET( 'A', 1, NRHS, ZERO, ZERO, WORK( BX+I-1 ), N )ELSERANK = RANK + 1CALL DLASCL( 'G', 0, 0, D( I ), ONE, 1, NRHS,$ WORK( BX+I-1 ), N, INFO )END IFD( I ) = ABS( D( I ) )70 CONTINUE** Now apply back the right singular vectors.*ICMPQ2 = 1DO 80 I = 1, NSUBST = IWORK( I )ST1 = ST - 1NSIZE = IWORK( SIZEI+I-1 )BXST = BX + ST1IF( NSIZE.EQ.1 ) THENCALL DCOPY( NRHS, WORK( BXST ), N, B( ST, 1 ), LDB )ELSE IF( NSIZE.LE.SMLSIZ ) THENCALL DGEMM( 'T', 'N', NSIZE, NRHS, NSIZE, ONE,$ WORK( VT+ST1 ), N, WORK( BXST ), N, ZERO,$ B( ST, 1 ), LDB )ELSECALL DLALSA( ICMPQ2, SMLSIZ, NSIZE, NRHS, WORK( BXST ), N,$ B( ST, 1 ), LDB, WORK( U+ST1 ), N,$ WORK( VT+ST1 ), IWORK( K+ST1 ),$ WORK( DIFL+ST1 ), WORK( DIFR+ST1 ),$ WORK( Z+ST1 ), WORK( POLES+ST1 ),$ IWORK( GIVPTR+ST1 ), IWORK( GIVCOL+ST1 ), N,$ IWORK( PERM+ST1 ), WORK( GIVNUM+ST1 ),$ WORK( C+ST1 ), WORK( S+ST1 ), WORK( NWORK ),$ IWORK( IWK ), INFO )IF( INFO.NE.0 ) THENRETURNEND IFEND IF80 CONTINUE** Unscale and sort the singular values.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )CALL DLASRT( 'D', N, D, INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, NRHS, B, LDB, INFO )*RETURN** End of DLALSD*END*> \brief \b DLAMRG creates a permutation list to merge the entries of two independently sorted sets into a single set sorted in ascending order.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAMRG + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlamrg.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlamrg.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlamrg.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAMRG( N1, N2, A, DTRD1, DTRD2, INDEX )** .. Scalar Arguments ..* INTEGER DTRD1, DTRD2, N1, N2* ..* .. Array Arguments ..* INTEGER INDEX( * )* DOUBLE PRECISION A( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAMRG will create a permutation list which will merge the elements*> of A (which is composed of two independently sorted sets) into a*> single set which is sorted in ascending order.*> \endverbatim** Arguments:* ==========**> \param[in] N1*> \verbatim*> N1 is INTEGER*> \endverbatim*>*> \param[in] N2*> \verbatim*> N2 is INTEGER*> These arguments contain the respective lengths of the two*> sorted lists to be merged.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (N1+N2)*> The first N1 elements of A contain a list of numbers which*> are sorted in either ascending or descending order. Likewise*> for the final N2 elements.*> \endverbatim*>*> \param[in] DTRD1*> \verbatim*> DTRD1 is INTEGER*> \endverbatim*>*> \param[in] DTRD2*> \verbatim*> DTRD2 is INTEGER*> These are the strides to be taken through the array A.*> Allowable strides are 1 and -1. They indicate whether a*> subset of A is sorted in ascending (DTRDx = 1) or descending*> (DTRDx = -1) order.*> \endverbatim*>*> \param[out] INDEX*> \verbatim*> INDEX is INTEGER array, dimension (N1+N2)*> On exit this array will contain a permutation such that*> if B( I ) = A( INDEX( I ) ) for I=1,N1+N2, then B will be*> sorted in ascending order.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLAMRG( N1, N2, A, DTRD1, DTRD2, INDEX )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER DTRD1, DTRD2, N1, N2* ..* .. Array Arguments ..INTEGER INDEX( * )DOUBLE PRECISION A( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, IND1, IND2, N1SV, N2SV* ..* .. Executable Statements ..*N1SV = N1N2SV = N2IF( DTRD1.GT.0 ) THENIND1 = 1ELSEIND1 = N1END IFIF( DTRD2.GT.0 ) THENIND2 = 1 + N1ELSEIND2 = N1 + N2END IFI = 1* while ( (N1SV > 0) & (N2SV > 0) )10 CONTINUEIF( N1SV.GT.0 .AND. N2SV.GT.0 ) THENIF( A( IND1 ).LE.A( IND2 ) ) THENINDEX( I ) = IND1I = I + 1IND1 = IND1 + DTRD1N1SV = N1SV - 1ELSEINDEX( I ) = IND2I = I + 1IND2 = IND2 + DTRD2N2SV = N2SV - 1END IFGO TO 10END IF* end whileIF( N1SV.EQ.0 ) THENDO 20 N1SV = 1, N2SVINDEX( I ) = IND2I = I + 1IND2 = IND2 + DTRD220 CONTINUEELSE* N2SV .EQ. 0DO 30 N2SV = 1, N1SVINDEX( I ) = IND1I = I + 1IND1 = IND1 + DTRD130 CONTINUEEND IF*RETURN** End of DLAMRG*END*> \brief \b DLANEG computes the Sturm count.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANEG + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaneg.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaneg.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaneg.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION DLANEG( N, D, LLD, SIGMA, PIVMIN, R )** .. Scalar Arguments ..* INTEGER N, R* DOUBLE PRECISION PIVMIN, SIGMA* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), LLD( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANEG computes the Sturm count, the number of negative pivots*> encountered while factoring tridiagonal T - sigma I = L D L^T.*> This implementation works directly on the factors without forming*> the tridiagonal matrix T. The Sturm count is also the number of*> eigenvalues of T less than sigma.*>*> This routine is called from DLARRB.*>*> The current routine does not use the PIVMIN parameter but rather*> requires IEEE-754 propagation of Infinities and NaNs. This*> routine also has no input range restrictions but does require*> default exception handling such that x/0 produces Inf when x is*> non-zero, and Inf/Inf produces NaN. For more information, see:*>*> Marques, Riedy, and Voemel, "Benefits of IEEE-754 Features in*> Modern Symmetric Tridiagonal Eigensolvers," SIAM Journal on*> Scientific Computing, v28, n5, 2006. DOI 10.1137/050641624*> (Tech report version in LAWN 172 with the same title.)*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The N diagonal elements of the diagonal matrix D.*> \endverbatim*>*> \param[in] LLD*> \verbatim*> LLD is DOUBLE PRECISION array, dimension (N-1)*> The (N-1) elements L(i)*L(i)*D(i).*> \endverbatim*>*> \param[in] SIGMA*> \verbatim*> SIGMA is DOUBLE PRECISION*> Shift amount in T - sigma I = L D L^T.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot in the Sturm sequence. May be used*> when zero pivots are encountered on non-IEEE-754*> architectures.*> \endverbatim*>*> \param[in] R*> \verbatim*> R is INTEGER*> The twist index for the twisted factorization that is used*> for the negcount.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA \n*> Jason Riedy, University of California, Berkeley, USA \n*>* =====================================================================INTEGER FUNCTION DLANEG( N, D, LLD, SIGMA, PIVMIN, R )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER N, RDOUBLE PRECISION PIVMIN, SIGMA* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), LLD( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* Some architectures propagate Infinities and NaNs very slowly, so* the code computes counts in BLKLEN chunks. Then a NaN can* propagate at most BLKLEN columns before being detected. This is* not a general tuning parameter; it needs only to be just large* enough that the overhead is tiny in common cases.INTEGER BLKLENPARAMETER ( BLKLEN = 128 )* ..* .. Local Scalars ..INTEGER BJ, J, NEG1, NEG2, NEGCNTDOUBLE PRECISION BSAV, DMINUS, DPLUS, GAMMA, P, T, TMPLOGICAL SAWNAN* ..* .. Intrinsic Functions ..INTRINSIC MIN, MAX* ..* .. External Functions ..LOGICAL DISNANEXTERNAL DISNAN* ..* .. Executable Statements ..NEGCNT = 0* I) upper part: L D L^T - SIGMA I = L+ D+ L+^TT = -SIGMADO 210 BJ = 1, R-1, BLKLENNEG1 = 0BSAV = TDO 21 J = BJ, MIN(BJ+BLKLEN-1, R-1)DPLUS = D( J ) + TIF( DPLUS.LT.ZERO ) NEG1 = NEG1 + 1TMP = T / DPLUST = TMP * LLD( J ) - SIGMA21 CONTINUESAWNAN = DISNAN( T )* Run a slower version of the above loop if a NaN is detected.* A NaN should occur only with a zero pivot after an infinite* pivot. In that case, substituting 1 for T/DPLUS is the* correct limit.IF( SAWNAN ) THENNEG1 = 0T = BSAVDO 22 J = BJ, MIN(BJ+BLKLEN-1, R-1)DPLUS = D( J ) + TIF( DPLUS.LT.ZERO ) NEG1 = NEG1 + 1TMP = T / DPLUSIF (DISNAN(TMP)) TMP = ONET = TMP * LLD(J) - SIGMA22 CONTINUEEND IFNEGCNT = NEGCNT + NEG1210 CONTINUE** II) lower part: L D L^T - SIGMA I = U- D- U-^TP = D( N ) - SIGMADO 230 BJ = N-1, R, -BLKLENNEG2 = 0BSAV = PDO 23 J = BJ, MAX(BJ-BLKLEN+1, R), -1DMINUS = LLD( J ) + PIF( DMINUS.LT.ZERO ) NEG2 = NEG2 + 1TMP = P / DMINUSP = TMP * D( J ) - SIGMA23 CONTINUESAWNAN = DISNAN( P )* As above, run a slower version that substitutes 1 for Inf/Inf.*IF( SAWNAN ) THENNEG2 = 0P = BSAVDO 24 J = BJ, MAX(BJ-BLKLEN+1, R), -1DMINUS = LLD( J ) + PIF( DMINUS.LT.ZERO ) NEG2 = NEG2 + 1TMP = P / DMINUSIF (DISNAN(TMP)) TMP = ONEP = TMP * D(J) - SIGMA24 CONTINUEEND IFNEGCNT = NEGCNT + NEG2230 CONTINUE** III) Twist index* T was shifted by SIGMA initially.GAMMA = (T + SIGMA) + PIF( GAMMA.LT.ZERO ) NEGCNT = NEGCNT+1DLANEG = NEGCNTEND*> \brief \b DLANGB returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of general band matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANGB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlangb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlangb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlangb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANGB( NORM, N, KL, KU, AB, LDAB,* WORK )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER KL, KU, LDAB, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANGB returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of an*> n by n band matrix A, with kl sub-diagonals and ku super-diagonals.*> \endverbatim*>*> \return DLANGB*> \verbatim*>*> DLANGB = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANGB as described*> above.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANGB is*> set to zero.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of sub-diagonals of the matrix A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of super-diagonals of the matrix A. KU >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The band matrix A, stored in rows 1 to KL+KU+1. The j-th*> column of A is stored in the j-th column of the array AB as*> follows:*> AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(n,j+kl).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KL+KU+1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I'; otherwise, WORK is not*> referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANGB( NORM, N, KL, KU, AB, LDAB,$ WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER KL, KU, LDAB, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** =====================================================================*** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, K, LDOUBLE PRECISION SCALE, SUM, VALUE, TEMP* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZERODO 20 J = 1, NDO 10 I = MAX( KU+2-J, 1 ), MIN( N+KU+1-J, KL+KU+1 )TEMP = ABS( AB( I, J ) )IF( VALUE.LT.TEMP .OR. DISNAN( TEMP ) ) VALUE = TEMP10 CONTINUE20 CONTINUEELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZERODO 40 J = 1, NSUM = ZERODO 30 I = MAX( KU+2-J, 1 ), MIN( N+KU+1-J, KL+KU+1 )SUM = SUM + ABS( AB( I, J ) )30 CONTINUEIF( VALUE.LT.SUM .OR. DISNAN( SUM ) ) VALUE = SUM40 CONTINUEELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*DO 50 I = 1, NWORK( I ) = ZERO50 CONTINUEDO 70 J = 1, NK = KU + 1 - JDO 60 I = MAX( 1, J-KU ), MIN( N, J+KL )WORK( I ) = WORK( I ) + ABS( AB( K+I, J ) )60 CONTINUE70 CONTINUEVALUE = ZERODO 80 I = 1, NTEMP = WORK( I )IF( VALUE.LT.TEMP .OR. DISNAN( TEMP ) ) VALUE = TEMP80 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEDO 90 J = 1, NL = MAX( 1, J-KU )K = KU + 1 - J + LCALL DLASSQ( MIN( N, J+KL )-L+1, AB( K, J ), 1, SCALE, SUM )90 CONTINUEVALUE = SCALE*SQRT( SUM )END IF*DLANGB = VALUERETURN** End of DLANGB*END*> \brief \b DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of a general rectangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANGE + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlange.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlange.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlange.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANGE( NORM, M, N, A, LDA, WORK )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANGE returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> real matrix A.*> \endverbatim*>*> \return DLANGE*> \verbatim*>*> DLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANGE as described*> above.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0. When M = 0,*> DLANGE is set to zero.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0. When N = 0,*> DLANGE is set to zero.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The m by n matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(M,1).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= M when NORM = 'I'; otherwise, WORK is not*> referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANGE( NORM, M, N, A, LDA, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION SCALE, SUM, VALUE, TEMP* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MIN, SQRT* ..* .. Executable Statements ..*IF( MIN( M, N ).EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZERODO 20 J = 1, NDO 10 I = 1, MTEMP = ABS( A( I, J ) )IF( VALUE.LT.TEMP .OR. DISNAN( TEMP ) ) VALUE = TEMP10 CONTINUE20 CONTINUEELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZERODO 40 J = 1, NSUM = ZERODO 30 I = 1, MSUM = SUM + ABS( A( I, J ) )30 CONTINUEIF( VALUE.LT.SUM .OR. DISNAN( SUM ) ) VALUE = SUM40 CONTINUEELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*DO 50 I = 1, MWORK( I ) = ZERO50 CONTINUEDO 70 J = 1, NDO 60 I = 1, MWORK( I ) = WORK( I ) + ABS( A( I, J ) )60 CONTINUE70 CONTINUEVALUE = ZERODO 80 I = 1, MTEMP = WORK( I )IF( VALUE.LT.TEMP .OR. DISNAN( TEMP ) ) VALUE = TEMP80 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEDO 90 J = 1, NCALL DLASSQ( M, A( 1, J ), 1, SCALE, SUM )90 CONTINUEVALUE = SCALE*SQRT( SUM )END IF*DLANGE = VALUERETURN** End of DLANGE*END*> \brief \b DLANGT returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of a general tridiagonal matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANGT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlangt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlangt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlangt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANGT( NORM, N, DL, D, DU )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), DL( * ), DU( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANGT returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> real tridiagonal matrix A.*> \endverbatim*>*> \return DLANGT*> \verbatim*>*> DLANGT = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANGT as described*> above.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANGT is*> set to zero.*> \endverbatim*>*> \param[in] DL*> \verbatim*> DL is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) sub-diagonal elements of A.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of A.*> \endverbatim*>*> \param[in] DU*> \verbatim*> DU is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) super-diagonal elements of A.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANGT( NORM, N, DL, D, DU )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DL( * ), DU( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION ANORM, SCALE, SUM, TEMP* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( N.LE.0 ) THENANORM = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*ANORM = ABS( D( N ) )DO 10 I = 1, N - 1IF( ANORM.LT.ABS( DL( I ) ) .OR. DISNAN( ABS( DL( I ) ) ) )$ ANORM = ABS(DL(I))IF( ANORM.LT.ABS( D( I ) ) .OR. DISNAN( ABS( D( I ) ) ) )$ ANORM = ABS(D(I))IF( ANORM.LT.ABS( DU( I ) ) .OR. DISNAN (ABS( DU( I ) ) ) )$ ANORM = ABS(DU(I))10 CONTINUEELSE IF( LSAME( NORM, 'O' ) .OR. NORM.EQ.'1' ) THEN** Find norm1(A).*IF( N.EQ.1 ) THENANORM = ABS( D( 1 ) )ELSEANORM = ABS( D( 1 ) )+ABS( DL( 1 ) )TEMP = ABS( D( N ) )+ABS( DU( N-1 ) )IF( ANORM .LT. TEMP .OR. DISNAN( TEMP ) ) ANORM = TEMPDO 20 I = 2, N - 1TEMP = ABS( D( I ) )+ABS( DL( I ) )+ABS( DU( I-1 ) )IF( ANORM .LT. TEMP .OR. DISNAN( TEMP ) ) ANORM = TEMP20 CONTINUEEND IFELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*IF( N.EQ.1 ) THENANORM = ABS( D( 1 ) )ELSEANORM = ABS( D( 1 ) )+ABS( DU( 1 ) )TEMP = ABS( D( N ) )+ABS( DL( N-1 ) )IF( ANORM .LT. TEMP .OR. DISNAN( TEMP ) ) ANORM = TEMPDO 30 I = 2, N - 1TEMP = ABS( D( I ) )+ABS( DU( I ) )+ABS( DL( I-1 ) )IF( ANORM .LT. TEMP .OR. DISNAN( TEMP ) ) ANORM = TEMP30 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONECALL DLASSQ( N, D, 1, SCALE, SUM )IF( N.GT.1 ) THENCALL DLASSQ( N-1, DL, 1, SCALE, SUM )CALL DLASSQ( N-1, DU, 1, SCALE, SUM )END IFANORM = SCALE*SQRT( SUM )END IF*DLANGT = ANORMRETURN** End of DLANGT*END*> \brief \b DLANHS returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of an upper Hessenberg matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANHS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlanhs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlanhs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlanhs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANHS( NORM, N, A, LDA, WORK )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANHS returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> Hessenberg matrix A.*> \endverbatim*>*> \return DLANHS*> \verbatim*>*> DLANHS = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANHS as described*> above.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANHS is*> set to zero.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The n by n upper Hessenberg matrix A; the part of A below the*> first sub-diagonal is not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(N,1).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I'; otherwise, WORK is not*> referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANHS( NORM, N, A, LDA, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MIN, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZERODO 20 J = 1, NDO 10 I = 1, MIN( N, J+1 )SUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUE20 CONTINUEELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZERODO 40 J = 1, NSUM = ZERODO 30 I = 1, MIN( N, J+1 )SUM = SUM + ABS( A( I, J ) )30 CONTINUEIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM40 CONTINUEELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*DO 50 I = 1, NWORK( I ) = ZERO50 CONTINUEDO 70 J = 1, NDO 60 I = 1, MIN( N, J+1 )WORK( I ) = WORK( I ) + ABS( A( I, J ) )60 CONTINUE70 CONTINUEVALUE = ZERODO 80 I = 1, NSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM80 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEDO 90 J = 1, NCALL DLASSQ( MIN( N, J+1 ), A( 1, J ), 1, SCALE, SUM )90 CONTINUEVALUE = SCALE*SQRT( SUM )END IF*DLANHS = VALUERETURN** End of DLANHS*END*> \brief \b DLANSB returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a symmetric band matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANSB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlansb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlansb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlansb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANSB( NORM, UPLO, N, K, AB, LDAB,* WORK )** .. Scalar Arguments ..* CHARACTER NORM, UPLO* INTEGER K, LDAB, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANSB returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of an*> n by n symmetric band matrix A, with k super-diagonals.*> \endverbatim*>*> \return DLANSB*> \verbatim*>*> DLANSB = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANSB as described*> above.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> band matrix A is supplied.*> = 'U': Upper triangular part is supplied*> = 'L': Lower triangular part is supplied*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANSB is*> set to zero.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of super-diagonals or sub-diagonals of the*> band matrix A. K >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangle of the symmetric band matrix A,*> stored in the first K+1 rows of AB. The j-th column of A is*> stored in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(k+1+i-j,j) = A(i,j) for max(1,j-k)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+k).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= K+1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,*> WORK is not referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANSB( NORM, UPLO, N, K, AB, LDAB,$ WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORM, UPLOINTEGER K, LDAB, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, LDOUBLE PRECISION ABSA, SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = MAX( K+2-J, 1 ), K + 1SUM = ABS( AB( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUE20 CONTINUEELSEDO 40 J = 1, NDO 30 I = 1, MIN( N+1-J, K+1 )SUM = ABS( AB( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM30 CONTINUE40 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.$ ( NORM.EQ.'1' ) ) THEN** Find normI(A) ( = norm1(A), since A is symmetric).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NSUM = ZEROL = K + 1 - JDO 50 I = MAX( 1, J-K ), J - 1ABSA = ABS( AB( L+I, J ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSA50 CONTINUEWORK( J ) = SUM + ABS( AB( K+1, J ) )60 CONTINUEDO 70 I = 1, NSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM70 CONTINUEELSEDO 80 I = 1, NWORK( I ) = ZERO80 CONTINUEDO 100 J = 1, NSUM = WORK( J ) + ABS( AB( 1, J ) )L = 1 - JDO 90 I = J + 1, MIN( N, J+K )ABSA = ABS( AB( L+I, J ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSA90 CONTINUEIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM100 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEIF( K.GT.0 ) THENIF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 2, NCALL DLASSQ( MIN( J-1, K ), AB( MAX( K+2-J, 1 ), J ),$ 1, SCALE, SUM )110 CONTINUEL = K + 1ELSEDO 120 J = 1, N - 1CALL DLASSQ( MIN( N-J, K ), AB( 2, J ), 1, SCALE,$ SUM )120 CONTINUEL = 1END IFSUM = 2*SUMELSEL = 1END IFCALL DLASSQ( N, AB( L, 1 ), LDAB, SCALE, SUM )VALUE = SCALE*SQRT( SUM )END IF*DLANSB = VALUERETURN** End of DLANSB*END*> \brief \b DLANSF returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a symmetric matrix in RFP format.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANSF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlansf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlansf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlansf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANSF( NORM, TRANSR, UPLO, N, A, WORK )** .. Scalar Arguments ..* CHARACTER NORM, TRANSR, UPLO* INTEGER N* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: * ), WORK( 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANSF returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> real symmetric matrix A in RFP format.*> \endverbatim*>*> \return DLANSF*> \verbatim*>*> DLANSF = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANSF as described*> above.*> \endverbatim*>*> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> Specifies whether the RFP format of A is normal or*> transposed format.*> = 'N': RFP format is Normal;*> = 'T': RFP format is Transpose.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> On entry, UPLO specifies whether the RFP matrix A came from*> an upper or lower triangular matrix as follows:*> = 'U': RFP A came from an upper triangular matrix;*> = 'L': RFP A came from a lower triangular matrix.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANSF is*> set to zero.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 );*> On entry, the upper (if UPLO = 'U') or lower (if UPLO = 'L')*> part of the symmetric matrix A stored in RFP format. See the*> "Notes" below for more details.*> Unchanged on exit.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,*> WORK is not referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim** =====================================================================DOUBLE PRECISION FUNCTION DLANSF( NORM, TRANSR, UPLO, N, A, WORK )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORM, TRANSR, UPLOINTEGER N* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: * ), WORK( 0: * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, IFM, ILU, NOE, N1, K, L, LDADOUBLE PRECISION SCALE, S, VALUE, AA, TEMP* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENDLANSF = ZERORETURNELSE IF( N.EQ.1 ) THENDLANSF = ABS( A(0) )RETURNEND IF** set noe = 1 if n is odd. if n is even set noe=0*NOE = 1IF( MOD( N, 2 ).EQ.0 )$ NOE = 0** set ifm = 0 when form='T or 't' and 1 otherwise*IFM = 1IF( LSAME( TRANSR, 'T' ) )$ IFM = 0** set ilu = 0 when uplo='U or 'u' and 1 otherwise*ILU = 1IF( LSAME( UPLO, 'U' ) )$ ILU = 0** set lda = (n+1)/2 when ifm = 0* set lda = n when ifm = 1 and noe = 1* set lda = n+1 when ifm = 1 and noe = 0*IF( IFM.EQ.1 ) THENIF( NOE.EQ.1 ) THENLDA = NELSE* noe=0LDA = N + 1END IFELSE* ifm=0LDA = ( N+1 ) / 2END IF*IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*K = ( N+1 ) / 2VALUE = ZEROIF( NOE.EQ.1 ) THEN* n is oddIF( IFM.EQ.1 ) THEN* A is n by kDO J = 0, K - 1DO I = 0, N - 1TEMP = ABS( A( I+J*LDA ) )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND DOELSE* xpose case; A is k by nDO J = 0, N - 1DO I = 0, K - 1TEMP = ABS( A( I+J*LDA ) )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND DOEND IFELSE* n is evenIF( IFM.EQ.1 ) THEN* A is n+1 by kDO J = 0, K - 1DO I = 0, NTEMP = ABS( A( I+J*LDA ) )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND DOELSE* xpose case; A is k by n+1DO J = 0, NDO I = 0, K - 1TEMP = ABS( A( I+J*LDA ) )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND DOEND IFEND IFELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.$ ( NORM.EQ.'1' ) ) THEN** Find normI(A) ( = norm1(A), since A is symmetric).*IF( IFM.EQ.1 ) THENK = N / 2IF( NOE.EQ.1 ) THEN* n is oddIF( ILU.EQ.0 ) THENDO I = 0, K - 1WORK( I ) = ZEROEND DODO J = 0, KS = ZERODO I = 0, K + J - 1AA = ABS( A( I+J*LDA ) )* -> A(i,j+k)S = S + AAWORK( I ) = WORK( I ) + AAEND DOAA = ABS( A( I+J*LDA ) )* -> A(j+k,j+k)WORK( J+K ) = S + AAIF( I.EQ.K+K )$ GO TO 10I = I + 1AA = ABS( A( I+J*LDA ) )* -> A(j,j)WORK( J ) = WORK( J ) + AAS = ZERODO L = J + 1, K - 1I = I + 1AA = ABS( A( I+J*LDA ) )* -> A(l,j)S = S + AAWORK( L ) = WORK( L ) + AAEND DOWORK( J ) = WORK( J ) + SEND DO10 CONTINUEVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOELSE* ilu = 1K = K + 1* k=(n+1)/2 for n odd and ilu=1DO I = K, N - 1WORK( I ) = ZEROEND DODO J = K - 1, 0, -1S = ZERODO I = 0, J - 2AA = ABS( A( I+J*LDA ) )* -> A(j+k,i+k)S = S + AAWORK( I+K ) = WORK( I+K ) + AAEND DOIF( J.GT.0 ) THENAA = ABS( A( I+J*LDA ) )* -> A(j+k,j+k)S = S + AAWORK( I+K ) = WORK( I+K ) + S* i=jI = I + 1END IFAA = ABS( A( I+J*LDA ) )* -> A(j,j)WORK( J ) = AAS = ZERODO L = J + 1, N - 1I = I + 1AA = ABS( A( I+J*LDA ) )* -> A(l,j)S = S + AAWORK( L ) = WORK( L ) + AAEND DOWORK( J ) = WORK( J ) + SEND DOVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND IFELSE* n is evenIF( ILU.EQ.0 ) THENDO I = 0, K - 1WORK( I ) = ZEROEND DODO J = 0, K - 1S = ZERODO I = 0, K + J - 1AA = ABS( A( I+J*LDA ) )* -> A(i,j+k)S = S + AAWORK( I ) = WORK( I ) + AAEND DOAA = ABS( A( I+J*LDA ) )* -> A(j+k,j+k)WORK( J+K ) = S + AAI = I + 1AA = ABS( A( I+J*LDA ) )* -> A(j,j)WORK( J ) = WORK( J ) + AAS = ZERODO L = J + 1, K - 1I = I + 1AA = ABS( A( I+J*LDA ) )* -> A(l,j)S = S + AAWORK( L ) = WORK( L ) + AAEND DOWORK( J ) = WORK( J ) + SEND DOVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOELSE* ilu = 1DO I = K, N - 1WORK( I ) = ZEROEND DODO J = K - 1, 0, -1S = ZERODO I = 0, J - 1AA = ABS( A( I+J*LDA ) )* -> A(j+k,i+k)S = S + AAWORK( I+K ) = WORK( I+K ) + AAEND DOAA = ABS( A( I+J*LDA ) )* -> A(j+k,j+k)S = S + AAWORK( I+K ) = WORK( I+K ) + S* i=jI = I + 1AA = ABS( A( I+J*LDA ) )* -> A(j,j)WORK( J ) = AAS = ZERODO L = J + 1, N - 1I = I + 1AA = ABS( A( I+J*LDA ) )* -> A(l,j)S = S + AAWORK( L ) = WORK( L ) + AAEND DOWORK( J ) = WORK( J ) + SEND DOVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND IFEND IFELSE* ifm=0K = N / 2IF( NOE.EQ.1 ) THEN* n is oddIF( ILU.EQ.0 ) THENN1 = K* n/2K = K + 1* k is the row size and ldaDO I = N1, N - 1WORK( I ) = ZEROEND DODO J = 0, N1 - 1S = ZERODO I = 0, K - 1AA = ABS( A( I+J*LDA ) )* A(j,n1+i)WORK( I+N1 ) = WORK( I+N1 ) + AAS = S + AAEND DOWORK( J ) = SEND DO* j=n1=k-1 is specialS = ABS( A( 0+J*LDA ) )* A(k-1,k-1)DO I = 1, K - 1AA = ABS( A( I+J*LDA ) )* A(k-1,i+n1)WORK( I+N1 ) = WORK( I+N1 ) + AAS = S + AAEND DOWORK( J ) = WORK( J ) + SDO J = K, N - 1S = ZERODO I = 0, J - K - 1AA = ABS( A( I+J*LDA ) )* A(i,j-k)WORK( I ) = WORK( I ) + AAS = S + AAEND DO* i=j-kAA = ABS( A( I+J*LDA ) )* A(j-k,j-k)S = S + AAWORK( J-K ) = WORK( J-K ) + SI = I + 1S = ABS( A( I+J*LDA ) )* A(j,j)DO L = J + 1, N - 1I = I + 1AA = ABS( A( I+J*LDA ) )* A(j,l)WORK( L ) = WORK( L ) + AAS = S + AAEND DOWORK( J ) = WORK( J ) + SEND DOVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOELSE* ilu=1K = K + 1* k=(n+1)/2 for n odd and ilu=1DO I = K, N - 1WORK( I ) = ZEROEND DODO J = 0, K - 2* processS = ZERODO I = 0, J - 1AA = ABS( A( I+J*LDA ) )* A(j,i)WORK( I ) = WORK( I ) + AAS = S + AAEND DOAA = ABS( A( I+J*LDA ) )* i=j so process of A(j,j)S = S + AAWORK( J ) = S* is initialised hereI = I + 1* i=j process A(j+k,j+k)AA = ABS( A( I+J*LDA ) )S = AADO L = K + J + 1, N - 1I = I + 1AA = ABS( A( I+J*LDA ) )* A(l,k+j)S = S + AAWORK( L ) = WORK( L ) + AAEND DOWORK( K+J ) = WORK( K+J ) + SEND DO* j=k-1 is special :process col A(k-1,0:k-1)S = ZERODO I = 0, K - 2AA = ABS( A( I+J*LDA ) )* A(k,i)WORK( I ) = WORK( I ) + AAS = S + AAEND DO* i=k-1AA = ABS( A( I+J*LDA ) )* A(k-1,k-1)S = S + AAWORK( I ) = S* done with col j=k+1DO J = K, N - 1* process col j of A = A(j,0:k-1)S = ZERODO I = 0, K - 1AA = ABS( A( I+J*LDA ) )* A(j,i)WORK( I ) = WORK( I ) + AAS = S + AAEND DOWORK( J ) = WORK( J ) + SEND DOVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND IFELSE* n is evenIF( ILU.EQ.0 ) THENDO I = K, N - 1WORK( I ) = ZEROEND DODO J = 0, K - 1S = ZERODO I = 0, K - 1AA = ABS( A( I+J*LDA ) )* A(j,i+k)WORK( I+K ) = WORK( I+K ) + AAS = S + AAEND DOWORK( J ) = SEND DO* j=kAA = ABS( A( 0+J*LDA ) )* A(k,k)S = AADO I = 1, K - 1AA = ABS( A( I+J*LDA ) )* A(k,k+i)WORK( I+K ) = WORK( I+K ) + AAS = S + AAEND DOWORK( J ) = WORK( J ) + SDO J = K + 1, N - 1S = ZERODO I = 0, J - 2 - KAA = ABS( A( I+J*LDA ) )* A(i,j-k-1)WORK( I ) = WORK( I ) + AAS = S + AAEND DO* i=j-1-kAA = ABS( A( I+J*LDA ) )* A(j-k-1,j-k-1)S = S + AAWORK( J-K-1 ) = WORK( J-K-1 ) + SI = I + 1AA = ABS( A( I+J*LDA ) )* A(j,j)S = AADO L = J + 1, N - 1I = I + 1AA = ABS( A( I+J*LDA ) )* A(j,l)WORK( L ) = WORK( L ) + AAS = S + AAEND DOWORK( J ) = WORK( J ) + SEND DO* j=nS = ZERODO I = 0, K - 2AA = ABS( A( I+J*LDA ) )* A(i,k-1)WORK( I ) = WORK( I ) + AAS = S + AAEND DO* i=k-1AA = ABS( A( I+J*LDA ) )* A(k-1,k-1)S = S + AAWORK( I ) = WORK( I ) + SVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOELSE* ilu=1DO I = K, N - 1WORK( I ) = ZEROEND DO* j=0 is special :process col A(k:n-1,k)S = ABS( A( 0 ) )* A(k,k)DO I = 1, K - 1AA = ABS( A( I ) )* A(k+i,k)WORK( I+K ) = WORK( I+K ) + AAS = S + AAEND DOWORK( K ) = WORK( K ) + SDO J = 1, K - 1* processS = ZERODO I = 0, J - 2AA = ABS( A( I+J*LDA ) )* A(j-1,i)WORK( I ) = WORK( I ) + AAS = S + AAEND DOAA = ABS( A( I+J*LDA ) )* i=j-1 so process of A(j-1,j-1)S = S + AAWORK( J-1 ) = S* is initialised hereI = I + 1* i=j process A(j+k,j+k)AA = ABS( A( I+J*LDA ) )S = AADO L = K + J + 1, N - 1I = I + 1AA = ABS( A( I+J*LDA ) )* A(l,k+j)S = S + AAWORK( L ) = WORK( L ) + AAEND DOWORK( K+J ) = WORK( K+J ) + SEND DO* j=k is special :process col A(k,0:k-1)S = ZERODO I = 0, K - 2AA = ABS( A( I+J*LDA ) )* A(k,i)WORK( I ) = WORK( I ) + AAS = S + AAEND DO* i=k-1AA = ABS( A( I+J*LDA ) )* A(k-1,k-1)S = S + AAWORK( I ) = S* done with col j=k+1DO J = K + 1, N* process col j-1 of A = A(j-1,0:k-1)S = ZERODO I = 0, K - 1AA = ABS( A( I+J*LDA ) )* A(j-1,i)WORK( I ) = WORK( I ) + AAS = S + AAEND DOWORK( J-1 ) = WORK( J-1 ) + SEND DOVALUE = WORK( 0 )DO I = 1, N-1TEMP = WORK( I )IF( VALUE .LT. TEMP .OR. DISNAN( TEMP ) )$ VALUE = TEMPEND DOEND IFEND IFEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*K = ( N+1 ) / 2SCALE = ZEROS = ONEIF( NOE.EQ.1 ) THEN* n is oddIF( IFM.EQ.1 ) THEN* A is normalIF( ILU.EQ.0 ) THEN* A is upperDO J = 0, K - 3CALL DLASSQ( K-J-2, A( K+J+1+J*LDA ), 1, SCALE, S )* L at A(k,0)END DODO J = 0, K - 1CALL DLASSQ( K+J-1, A( 0+J*LDA ), 1, SCALE, S )* trap U at A(0,0)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K-1, A( K ), LDA+1, SCALE, S )* tri L at A(k,0)CALL DLASSQ( K, A( K-1 ), LDA+1, SCALE, S )* tri U at A(k-1,0)ELSE* ilu=1 & A is lowerDO J = 0, K - 1CALL DLASSQ( N-J-1, A( J+1+J*LDA ), 1, SCALE, S )* trap L at A(0,0)END DODO J = 0, K - 2CALL DLASSQ( J, A( 0+( 1+J )*LDA ), 1, SCALE, S )* U at A(0,1)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K, A( 0 ), LDA+1, SCALE, S )* tri L at A(0,0)CALL DLASSQ( K-1, A( 0+LDA ), LDA+1, SCALE, S )* tri U at A(0,1)END IFELSE* A is xposeIF( ILU.EQ.0 ) THEN* A**T is upperDO J = 1, K - 2CALL DLASSQ( J, A( 0+( K+J )*LDA ), 1, SCALE, S )* U at A(0,k)END DODO J = 0, K - 2CALL DLASSQ( K, A( 0+J*LDA ), 1, SCALE, S )* k by k-1 rect. at A(0,0)END DODO J = 0, K - 2CALL DLASSQ( K-J-1, A( J+1+( J+K-1 )*LDA ), 1,$ SCALE, S )* L at A(0,k-1)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K-1, A( 0+K*LDA ), LDA+1, SCALE, S )* tri U at A(0,k)CALL DLASSQ( K, A( 0+( K-1 )*LDA ), LDA+1, SCALE, S )* tri L at A(0,k-1)ELSE* A**T is lowerDO J = 1, K - 1CALL DLASSQ( J, A( 0+J*LDA ), 1, SCALE, S )* U at A(0,0)END DODO J = K, N - 1CALL DLASSQ( K, A( 0+J*LDA ), 1, SCALE, S )* k by k-1 rect. at A(0,k)END DODO J = 0, K - 3CALL DLASSQ( K-J-2, A( J+2+J*LDA ), 1, SCALE, S )* L at A(1,0)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K, A( 0 ), LDA+1, SCALE, S )* tri U at A(0,0)CALL DLASSQ( K-1, A( 1 ), LDA+1, SCALE, S )* tri L at A(1,0)END IFEND IFELSE* n is evenIF( IFM.EQ.1 ) THEN* A is normalIF( ILU.EQ.0 ) THEN* A is upperDO J = 0, K - 2CALL DLASSQ( K-J-1, A( K+J+2+J*LDA ), 1, SCALE, S )* L at A(k+1,0)END DODO J = 0, K - 1CALL DLASSQ( K+J, A( 0+J*LDA ), 1, SCALE, S )* trap U at A(0,0)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K, A( K+1 ), LDA+1, SCALE, S )* tri L at A(k+1,0)CALL DLASSQ( K, A( K ), LDA+1, SCALE, S )* tri U at A(k,0)ELSE* ilu=1 & A is lowerDO J = 0, K - 1CALL DLASSQ( N-J-1, A( J+2+J*LDA ), 1, SCALE, S )* trap L at A(1,0)END DODO J = 1, K - 1CALL DLASSQ( J, A( 0+J*LDA ), 1, SCALE, S )* U at A(0,0)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K, A( 1 ), LDA+1, SCALE, S )* tri L at A(1,0)CALL DLASSQ( K, A( 0 ), LDA+1, SCALE, S )* tri U at A(0,0)END IFELSE* A is xposeIF( ILU.EQ.0 ) THEN* A**T is upperDO J = 1, K - 1CALL DLASSQ( J, A( 0+( K+1+J )*LDA ), 1, SCALE, S )* U at A(0,k+1)END DODO J = 0, K - 1CALL DLASSQ( K, A( 0+J*LDA ), 1, SCALE, S )* k by k rect. at A(0,0)END DODO J = 0, K - 2CALL DLASSQ( K-J-1, A( J+1+( J+K )*LDA ), 1, SCALE,$ S )* L at A(0,k)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K, A( 0+( K+1 )*LDA ), LDA+1, SCALE, S )* tri U at A(0,k+1)CALL DLASSQ( K, A( 0+K*LDA ), LDA+1, SCALE, S )* tri L at A(0,k)ELSE* A**T is lowerDO J = 1, K - 1CALL DLASSQ( J, A( 0+( J+1 )*LDA ), 1, SCALE, S )* U at A(0,1)END DODO J = K + 1, NCALL DLASSQ( K, A( 0+J*LDA ), 1, SCALE, S )* k by k rect. at A(0,k+1)END DODO J = 0, K - 2CALL DLASSQ( K-J-1, A( J+1+J*LDA ), 1, SCALE, S )* L at A(0,0)END DOS = S + S* double s for the off diagonal elementsCALL DLASSQ( K, A( LDA ), LDA+1, SCALE, S )* tri L at A(0,1)CALL DLASSQ( K, A( 0 ), LDA+1, SCALE, S )* tri U at A(0,0)END IFEND IFEND IFVALUE = SCALE*SQRT( S )END IF*DLANSF = VALUERETURN** End of DLANSF*END*> \brief \b DLANSP returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a symmetric matrix supplied in packed form.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANSP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlansp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlansp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlansp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANSP( NORM, UPLO, N, AP, WORK )** .. Scalar Arguments ..* CHARACTER NORM, UPLO* INTEGER N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANSP returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> real symmetric matrix A, supplied in packed form.*> \endverbatim*>*> \return DLANSP*> \verbatim*>*> DLANSP = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANSP as described*> above.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is supplied.*> = 'U': Upper triangular part of A is supplied*> = 'L': Lower triangular part of A is supplied*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANSP is*> set to zero.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangle of the symmetric matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,*> WORK is not referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANSP( NORM, UPLO, N, AP, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORM, UPLOINTEGER N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, KDOUBLE PRECISION ABSA, SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENK = 1DO 20 J = 1, NDO 10 I = K, K + J - 1SUM = ABS( AP( I ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUEK = K + J20 CONTINUEELSEK = 1DO 40 J = 1, NDO 30 I = K, K + N - JSUM = ABS( AP( I ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM30 CONTINUEK = K + N - J + 140 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.$ ( NORM.EQ.'1' ) ) THEN** Find normI(A) ( = norm1(A), since A is symmetric).*VALUE = ZEROK = 1IF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NSUM = ZERODO 50 I = 1, J - 1ABSA = ABS( AP( K ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSAK = K + 150 CONTINUEWORK( J ) = SUM + ABS( AP( K ) )K = K + 160 CONTINUEDO 70 I = 1, NSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM70 CONTINUEELSEDO 80 I = 1, NWORK( I ) = ZERO80 CONTINUEDO 100 J = 1, NSUM = WORK( J ) + ABS( AP( K ) )K = K + 1DO 90 I = J + 1, NABSA = ABS( AP( K ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSAK = K + 190 CONTINUEIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM100 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEK = 2IF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 2, NCALL DLASSQ( J-1, AP( K ), 1, SCALE, SUM )K = K + J110 CONTINUEELSEDO 120 J = 1, N - 1CALL DLASSQ( N-J, AP( K ), 1, SCALE, SUM )K = K + N - J + 1120 CONTINUEEND IFSUM = 2*SUMK = 1DO 130 I = 1, NIF( AP( K ).NE.ZERO ) THENABSA = ABS( AP( K ) )IF( SCALE.LT.ABSA ) THENSUM = ONE + SUM*( SCALE / ABSA )**2SCALE = ABSAELSESUM = SUM + ( ABSA / SCALE )**2END IFEND IFIF( LSAME( UPLO, 'U' ) ) THENK = K + I + 1ELSEK = K + N - I + 1END IF130 CONTINUEVALUE = SCALE*SQRT( SUM )END IF*DLANSP = VALUERETURN** End of DLANSP*END*> \brief \b DLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANST + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlanst.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlanst.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlanst.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANST( NORM, N, D, E )** .. Scalar Arguments ..* CHARACTER NORM* INTEGER N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANST returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> real symmetric tridiagonal matrix A.*> \endverbatim*>*> \return DLANST*> \verbatim*>*> DLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANST as described*> above.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANST is*> set to zero.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of A.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) sub-diagonal or super-diagonal elements of A.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANST( NORM, N, D, E )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORMINTEGER N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION ANORM, SCALE, SUM* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( N.LE.0 ) THENANORM = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*ANORM = ABS( D( N ) )DO 10 I = 1, N - 1SUM = ABS( D( I ) )IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUMSUM = ABS( E( I ) )IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUM10 CONTINUEELSE IF( LSAME( NORM, 'O' ) .OR. NORM.EQ.'1' .OR.$ LSAME( NORM, 'I' ) ) THEN** Find norm1(A).*IF( N.EQ.1 ) THENANORM = ABS( D( 1 ) )ELSEANORM = ABS( D( 1 ) )+ABS( E( 1 ) )SUM = ABS( E( N-1 ) )+ABS( D( N ) )IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUMDO 20 I = 2, N - 1SUM = ABS( D( I ) )+ABS( E( I ) )+ABS( E( I-1 ) )IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUM20 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEIF( N.GT.1 ) THENCALL DLASSQ( N-1, E, 1, SCALE, SUM )SUM = 2*SUMEND IFCALL DLASSQ( N, D, 1, SCALE, SUM )ANORM = SCALE*SQRT( SUM )END IF*DLANST = ANORMRETURN** End of DLANST*END*> \brief \b DLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANSY + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlansy.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlansy.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlansy.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANSY( NORM, UPLO, N, A, LDA, WORK )** .. Scalar Arguments ..* CHARACTER NORM, UPLO* INTEGER LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANSY returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> real symmetric matrix A.*> \endverbatim*>*> \return DLANSY*> \verbatim*>*> DLANSY = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANSY as described*> above.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is to be referenced.*> = 'U': Upper triangular part of A is referenced*> = 'L': Lower triangular part of A is referenced*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANSY is*> set to zero.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The symmetric matrix A. If UPLO = 'U', the leading n by n*> upper triangular part of A contains the upper triangular part*> of the matrix A, and the strictly lower triangular part of A*> is not referenced. If UPLO = 'L', the leading n by n lower*> triangular part of A contains the lower triangular part of*> the matrix A, and the strictly upper triangular part of A is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(N,1).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise,*> WORK is not referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANSY( NORM, UPLO, N, A, LDA, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER NORM, UPLOINTEGER LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION ABSA, SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = 1, JSUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUE20 CONTINUEELSEDO 40 J = 1, NDO 30 I = J, NSUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM30 CONTINUE40 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'I' ) ) .OR. ( LSAME( NORM, 'O' ) ) .OR.$ ( NORM.EQ.'1' ) ) THEN** Find normI(A) ( = norm1(A), since A is symmetric).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NSUM = ZERODO 50 I = 1, J - 1ABSA = ABS( A( I, J ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSA50 CONTINUEWORK( J ) = SUM + ABS( A( J, J ) )60 CONTINUEDO 70 I = 1, NSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM70 CONTINUEELSEDO 80 I = 1, NWORK( I ) = ZERO80 CONTINUEDO 100 J = 1, NSUM = WORK( J ) + ABS( A( J, J ) )DO 90 I = J + 1, NABSA = ABS( A( I, J ) )SUM = SUM + ABSAWORK( I ) = WORK( I ) + ABSA90 CONTINUEIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM100 CONTINUEEND IFELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*SCALE = ZEROSUM = ONEIF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 2, NCALL DLASSQ( J-1, A( 1, J ), 1, SCALE, SUM )110 CONTINUEELSEDO 120 J = 1, N - 1CALL DLASSQ( N-J, A( J+1, J ), 1, SCALE, SUM )120 CONTINUEEND IFSUM = 2*SUMCALL DLASSQ( N, A, LDA+1, SCALE, SUM )VALUE = SCALE*SQRT( SUM )END IF*DLANSY = VALUERETURN** End of DLANSY*END*> \brief \b DLANTB returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a triangular band matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANTB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlantb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlantb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlantb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANTB( NORM, UPLO, DIAG, N, K, AB,* LDAB, WORK )** .. Scalar Arguments ..* CHARACTER DIAG, NORM, UPLO* INTEGER K, LDAB, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANTB returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of an*> n by n triangular band matrix A, with ( k + 1 ) diagonals.*> \endverbatim*>*> \return DLANTB*> \verbatim*>*> DLANTB = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANTB as described*> above.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower triangular.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A is unit triangular.*> = 'N': Non-unit triangular*> = 'U': Unit triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANTB is*> set to zero.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of super-diagonals of the matrix A if UPLO = 'U',*> or the number of sub-diagonals of the matrix A if UPLO = 'L'.*> K >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangular band matrix A, stored in the*> first k+1 rows of AB. The j-th column of A is stored*> in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(k+1+i-j,j) = A(i,j) for max(1,j-k)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+k).*> Note that when DIAG = 'U', the elements of the array AB*> corresponding to the diagonal elements of the matrix A are*> not referenced, but are assumed to be one.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= K+1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I'; otherwise, WORK is not*> referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANTB( NORM, UPLO, DIAG, N, K, AB,$ LDAB, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORM, UPLOINTEGER K, LDAB, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UDIAGINTEGER I, J, LDOUBLE PRECISION SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*IF( LSAME( DIAG, 'U' ) ) THENVALUE = ONEIF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = MAX( K+2-J, 1 ), KSUM = ABS( AB( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUE20 CONTINUEELSEDO 40 J = 1, NDO 30 I = 2, MIN( N+1-J, K+1 )SUM = ABS( AB( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM30 CONTINUE40 CONTINUEEND IFELSEVALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NDO 50 I = MAX( K+2-J, 1 ), K + 1SUM = ABS( AB( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM50 CONTINUE60 CONTINUEELSEDO 80 J = 1, NDO 70 I = 1, MIN( N+1-J, K+1 )SUM = ABS( AB( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM70 CONTINUE80 CONTINUEEND IFEND IFELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZEROUDIAG = LSAME( DIAG, 'U' )IF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 1, NIF( UDIAG ) THENSUM = ONEDO 90 I = MAX( K+2-J, 1 ), KSUM = SUM + ABS( AB( I, J ) )90 CONTINUEELSESUM = ZERODO 100 I = MAX( K+2-J, 1 ), K + 1SUM = SUM + ABS( AB( I, J ) )100 CONTINUEEND IFIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM110 CONTINUEELSEDO 140 J = 1, NIF( UDIAG ) THENSUM = ONEDO 120 I = 2, MIN( N+1-J, K+1 )SUM = SUM + ABS( AB( I, J ) )120 CONTINUEELSESUM = ZERODO 130 I = 1, MIN( N+1-J, K+1 )SUM = SUM + ABS( AB( I, J ) )130 CONTINUEEND IFIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM140 CONTINUEEND IFELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*VALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENIF( LSAME( DIAG, 'U' ) ) THENDO 150 I = 1, NWORK( I ) = ONE150 CONTINUEDO 170 J = 1, NL = K + 1 - JDO 160 I = MAX( 1, J-K ), J - 1WORK( I ) = WORK( I ) + ABS( AB( L+I, J ) )160 CONTINUE170 CONTINUEELSEDO 180 I = 1, NWORK( I ) = ZERO180 CONTINUEDO 200 J = 1, NL = K + 1 - JDO 190 I = MAX( 1, J-K ), JWORK( I ) = WORK( I ) + ABS( AB( L+I, J ) )190 CONTINUE200 CONTINUEEND IFELSEIF( LSAME( DIAG, 'U' ) ) THENDO 210 I = 1, NWORK( I ) = ONE210 CONTINUEDO 230 J = 1, NL = 1 - JDO 220 I = J + 1, MIN( N, J+K )WORK( I ) = WORK( I ) + ABS( AB( L+I, J ) )220 CONTINUE230 CONTINUEELSEDO 240 I = 1, NWORK( I ) = ZERO240 CONTINUEDO 260 J = 1, NL = 1 - JDO 250 I = J, MIN( N, J+K )WORK( I ) = WORK( I ) + ABS( AB( L+I, J ) )250 CONTINUE260 CONTINUEEND IFEND IFDO 270 I = 1, NSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM270 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*IF( LSAME( UPLO, 'U' ) ) THENIF( LSAME( DIAG, 'U' ) ) THENSCALE = ONESUM = NIF( K.GT.0 ) THENDO 280 J = 2, NCALL DLASSQ( MIN( J-1, K ),$ AB( MAX( K+2-J, 1 ), J ), 1, SCALE,$ SUM )280 CONTINUEEND IFELSESCALE = ZEROSUM = ONEDO 290 J = 1, NCALL DLASSQ( MIN( J, K+1 ), AB( MAX( K+2-J, 1 ), J ),$ 1, SCALE, SUM )290 CONTINUEEND IFELSEIF( LSAME( DIAG, 'U' ) ) THENSCALE = ONESUM = NIF( K.GT.0 ) THENDO 300 J = 1, N - 1CALL DLASSQ( MIN( N-J, K ), AB( 2, J ), 1, SCALE,$ SUM )300 CONTINUEEND IFELSESCALE = ZEROSUM = ONEDO 310 J = 1, NCALL DLASSQ( MIN( N-J+1, K+1 ), AB( 1, J ), 1, SCALE,$ SUM )310 CONTINUEEND IFEND IFVALUE = SCALE*SQRT( SUM )END IF*DLANTB = VALUERETURN** End of DLANTB*END*> \brief \b DLANTP returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a triangular matrix supplied in packed form.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANTP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlantp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlantp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlantp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANTP( NORM, UPLO, DIAG, N, AP, WORK )** .. Scalar Arguments ..* CHARACTER DIAG, NORM, UPLO* INTEGER N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANTP returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> triangular matrix A, supplied in packed form.*> \endverbatim*>*> \return DLANTP*> \verbatim*>*> DLANTP = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANTP as described*> above.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower triangular.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A is unit triangular.*> = 'N': Non-unit triangular*> = 'U': Unit triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0. When N = 0, DLANTP is*> set to zero.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangular matrix A, packed columnwise in*> a linear array. The j-th column of A is stored in the array*> AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> Note that when DIAG = 'U', the elements of the array AP*> corresponding to the diagonal elements of the matrix A are*> not referenced, but are assumed to be one.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= N when NORM = 'I'; otherwise, WORK is not*> referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANTP( NORM, UPLO, DIAG, N, AP, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORM, UPLOINTEGER N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UDIAGINTEGER I, J, KDOUBLE PRECISION SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( N.EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*K = 1IF( LSAME( DIAG, 'U' ) ) THENVALUE = ONEIF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = K, K + J - 2SUM = ABS( AP( I ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUEK = K + J20 CONTINUEELSEDO 40 J = 1, NDO 30 I = K + 1, K + N - JSUM = ABS( AP( I ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM30 CONTINUEK = K + N - J + 140 CONTINUEEND IFELSEVALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NDO 50 I = K, K + J - 1SUM = ABS( AP( I ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM50 CONTINUEK = K + J60 CONTINUEELSEDO 80 J = 1, NDO 70 I = K, K + N - JSUM = ABS( AP( I ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM70 CONTINUEK = K + N - J + 180 CONTINUEEND IFEND IFELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZEROK = 1UDIAG = LSAME( DIAG, 'U' )IF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 1, NIF( UDIAG ) THENSUM = ONEDO 90 I = K, K + J - 2SUM = SUM + ABS( AP( I ) )90 CONTINUEELSESUM = ZERODO 100 I = K, K + J - 1SUM = SUM + ABS( AP( I ) )100 CONTINUEEND IFK = K + JIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM110 CONTINUEELSEDO 140 J = 1, NIF( UDIAG ) THENSUM = ONEDO 120 I = K + 1, K + N - JSUM = SUM + ABS( AP( I ) )120 CONTINUEELSESUM = ZERODO 130 I = K, K + N - JSUM = SUM + ABS( AP( I ) )130 CONTINUEEND IFK = K + N - J + 1IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM140 CONTINUEEND IFELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*K = 1IF( LSAME( UPLO, 'U' ) ) THENIF( LSAME( DIAG, 'U' ) ) THENDO 150 I = 1, NWORK( I ) = ONE150 CONTINUEDO 170 J = 1, NDO 160 I = 1, J - 1WORK( I ) = WORK( I ) + ABS( AP( K ) )K = K + 1160 CONTINUEK = K + 1170 CONTINUEELSEDO 180 I = 1, NWORK( I ) = ZERO180 CONTINUEDO 200 J = 1, NDO 190 I = 1, JWORK( I ) = WORK( I ) + ABS( AP( K ) )K = K + 1190 CONTINUE200 CONTINUEEND IFELSEIF( LSAME( DIAG, 'U' ) ) THENDO 210 I = 1, NWORK( I ) = ONE210 CONTINUEDO 230 J = 1, NK = K + 1DO 220 I = J + 1, NWORK( I ) = WORK( I ) + ABS( AP( K ) )K = K + 1220 CONTINUE230 CONTINUEELSEDO 240 I = 1, NWORK( I ) = ZERO240 CONTINUEDO 260 J = 1, NDO 250 I = J, NWORK( I ) = WORK( I ) + ABS( AP( K ) )K = K + 1250 CONTINUE260 CONTINUEEND IFEND IFVALUE = ZERODO 270 I = 1, NSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM270 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*IF( LSAME( UPLO, 'U' ) ) THENIF( LSAME( DIAG, 'U' ) ) THENSCALE = ONESUM = NK = 2DO 280 J = 2, NCALL DLASSQ( J-1, AP( K ), 1, SCALE, SUM )K = K + J280 CONTINUEELSESCALE = ZEROSUM = ONEK = 1DO 290 J = 1, NCALL DLASSQ( J, AP( K ), 1, SCALE, SUM )K = K + J290 CONTINUEEND IFELSEIF( LSAME( DIAG, 'U' ) ) THENSCALE = ONESUM = NK = 2DO 300 J = 1, N - 1CALL DLASSQ( N-J, AP( K ), 1, SCALE, SUM )K = K + N - J + 1300 CONTINUEELSESCALE = ZEROSUM = ONEK = 1DO 310 J = 1, NCALL DLASSQ( N-J+1, AP( K ), 1, SCALE, SUM )K = K + N - J + 1310 CONTINUEEND IFEND IFVALUE = SCALE*SQRT( SUM )END IF*DLANTP = VALUERETURN** End of DLANTP*END*> \brief \b DLANTR returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a trapezoidal or triangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlantr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlantr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlantr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLANTR( NORM, UPLO, DIAG, M, N, A, LDA,* WORK )** .. Scalar Arguments ..* CHARACTER DIAG, NORM, UPLO* INTEGER LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANTR returns the value of the one norm, or the Frobenius norm, or*> the infinity norm, or the element of largest absolute value of a*> trapezoidal or triangular matrix A.*> \endverbatim*>*> \return DLANTR*> \verbatim*>*> DLANTR = ( max(abs(A(i,j))), NORM = 'M' or 'm'*> (*> ( norm1(A), NORM = '1', 'O' or 'o'*> (*> ( normI(A), NORM = 'I' or 'i'*> (*> ( normF(A), NORM = 'F', 'f', 'E' or 'e'*>*> where norm1 denotes the one norm of a matrix (maximum column sum),*> normI denotes the infinity norm of a matrix (maximum row sum) and*> normF denotes the Frobenius norm of a matrix (square root of sum of*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm.*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies the value to be returned in DLANTR as described*> above.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower trapezoidal.*> = 'U': Upper trapezoidal*> = 'L': Lower trapezoidal*> Note that A is triangular instead of trapezoidal if M = N.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A has unit diagonal.*> = 'N': Non-unit diagonal*> = 'U': Unit diagonal*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0, and if*> UPLO = 'U', M <= N. When M = 0, DLANTR is set to zero.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0, and if*> UPLO = 'L', N <= M. When N = 0, DLANTR is set to zero.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The trapezoidal matrix A (A is triangular if M = N).*> If UPLO = 'U', the leading m by n upper trapezoidal part of*> the array A contains the upper trapezoidal matrix, and the*> strictly lower triangular part of A is not referenced.*> If UPLO = 'L', the leading m by n lower trapezoidal part of*> the array A contains the lower trapezoidal matrix, and the*> strictly upper triangular part of A is not referenced. Note*> that when DIAG = 'U', the diagonal elements of A are not*> referenced and are assumed to be one.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(M,1).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)),*> where LWORK >= M when NORM = 'I'; otherwise, WORK is not*> referenced.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLANTR( NORM, UPLO, DIAG, M, N, A, LDA,$ WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORM, UPLOINTEGER LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UDIAGINTEGER I, JDOUBLE PRECISION SCALE, SUM, VALUE* ..* .. External Subroutines ..EXTERNAL DLASSQ* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MIN, SQRT* ..* .. Executable Statements ..*IF( MIN( M, N ).EQ.0 ) THENVALUE = ZEROELSE IF( LSAME( NORM, 'M' ) ) THEN** Find max(abs(A(i,j))).*IF( LSAME( DIAG, 'U' ) ) THENVALUE = ONEIF( LSAME( UPLO, 'U' ) ) THENDO 20 J = 1, NDO 10 I = 1, MIN( M, J-1 )SUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM10 CONTINUE20 CONTINUEELSEDO 40 J = 1, NDO 30 I = J + 1, MSUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM30 CONTINUE40 CONTINUEEND IFELSEVALUE = ZEROIF( LSAME( UPLO, 'U' ) ) THENDO 60 J = 1, NDO 50 I = 1, MIN( M, J )SUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM50 CONTINUE60 CONTINUEELSEDO 80 J = 1, NDO 70 I = J, MSUM = ABS( A( I, J ) )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM70 CONTINUE80 CONTINUEEND IFEND IFELSE IF( ( LSAME( NORM, 'O' ) ) .OR. ( NORM.EQ.'1' ) ) THEN** Find norm1(A).*VALUE = ZEROUDIAG = LSAME( DIAG, 'U' )IF( LSAME( UPLO, 'U' ) ) THENDO 110 J = 1, NIF( ( UDIAG ) .AND. ( J.LE.M ) ) THENSUM = ONEDO 90 I = 1, J - 1SUM = SUM + ABS( A( I, J ) )90 CONTINUEELSESUM = ZERODO 100 I = 1, MIN( M, J )SUM = SUM + ABS( A( I, J ) )100 CONTINUEEND IFIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM110 CONTINUEELSEDO 140 J = 1, NIF( UDIAG ) THENSUM = ONEDO 120 I = J + 1, MSUM = SUM + ABS( A( I, J ) )120 CONTINUEELSESUM = ZERODO 130 I = J, MSUM = SUM + ABS( A( I, J ) )130 CONTINUEEND IFIF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM140 CONTINUEEND IFELSE IF( LSAME( NORM, 'I' ) ) THEN** Find normI(A).*IF( LSAME( UPLO, 'U' ) ) THENIF( LSAME( DIAG, 'U' ) ) THENDO 150 I = 1, MWORK( I ) = ONE150 CONTINUEDO 170 J = 1, NDO 160 I = 1, MIN( M, J-1 )WORK( I ) = WORK( I ) + ABS( A( I, J ) )160 CONTINUE170 CONTINUEELSEDO 180 I = 1, MWORK( I ) = ZERO180 CONTINUEDO 200 J = 1, NDO 190 I = 1, MIN( M, J )WORK( I ) = WORK( I ) + ABS( A( I, J ) )190 CONTINUE200 CONTINUEEND IFELSEIF( LSAME( DIAG, 'U' ) ) THENDO 210 I = 1, NWORK( I ) = ONE210 CONTINUEDO 220 I = N + 1, MWORK( I ) = ZERO220 CONTINUEDO 240 J = 1, NDO 230 I = J + 1, MWORK( I ) = WORK( I ) + ABS( A( I, J ) )230 CONTINUE240 CONTINUEELSEDO 250 I = 1, MWORK( I ) = ZERO250 CONTINUEDO 270 J = 1, NDO 260 I = J, MWORK( I ) = WORK( I ) + ABS( A( I, J ) )260 CONTINUE270 CONTINUEEND IFEND IFVALUE = ZERODO 280 I = 1, MSUM = WORK( I )IF( VALUE .LT. SUM .OR. DISNAN( SUM ) ) VALUE = SUM280 CONTINUEELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN** Find normF(A).*IF( LSAME( UPLO, 'U' ) ) THENIF( LSAME( DIAG, 'U' ) ) THENSCALE = ONESUM = MIN( M, N )DO 290 J = 2, NCALL DLASSQ( MIN( M, J-1 ), A( 1, J ), 1, SCALE, SUM )290 CONTINUEELSESCALE = ZEROSUM = ONEDO 300 J = 1, NCALL DLASSQ( MIN( M, J ), A( 1, J ), 1, SCALE, SUM )300 CONTINUEEND IFELSEIF( LSAME( DIAG, 'U' ) ) THENSCALE = ONESUM = MIN( M, N )DO 310 J = 1, NCALL DLASSQ( M-J, A( MIN( M, J+1 ), J ), 1, SCALE,$ SUM )310 CONTINUEELSESCALE = ZEROSUM = ONEDO 320 J = 1, NCALL DLASSQ( M-J+1, A( J, J ), 1, SCALE, SUM )320 CONTINUEEND IFEND IFVALUE = SCALE*SQRT( SUM )END IF*DLANTR = VALUERETURN** End of DLANTR*END*> \brief \b DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric matrix in standard form.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLANV2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlanv2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlanv2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlanv2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )** .. Scalar Arguments ..* DOUBLE PRECISION A, B, C, CS, D, RT1I, RT1R, RT2I, RT2R, SN* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric*> matrix in standard form:*>*> [ A B ] = [ CS -SN ] [ AA BB ] [ CS SN ]*> [ C D ] [ SN CS ] [ CC DD ] [-SN CS ]*>*> where either*> 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or*> 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex*> conjugate eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION*> On entry, the elements of the input matrix.*> On exit, they are overwritten by the elements of the*> standardised Schur form.*> \endverbatim*>*> \param[out] RT1R*> \verbatim*> RT1R is DOUBLE PRECISION*> \endverbatim*>*> \param[out] RT1I*> \verbatim*> RT1I is DOUBLE PRECISION*> \endverbatim*>*> \param[out] RT2R*> \verbatim*> RT2R is DOUBLE PRECISION*> \endverbatim*>*> \param[out] RT2I*> \verbatim*> RT2I is DOUBLE PRECISION*> The real and imaginary parts of the eigenvalues. If the*> eigenvalues are a complex conjugate pair, RT1I > 0.*> \endverbatim*>*> \param[out] CS*> \verbatim*> CS is DOUBLE PRECISION*> \endverbatim*>*> \param[out] SN*> \verbatim*> SN is DOUBLE PRECISION*> Parameters of the rotation matrix.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Modified by V. Sima, Research Institute for Informatics, Bucharest,*> Romania, to reduce the risk of cancellation errors,*> when computing real eigenvalues, and to ensure, if possible, that*> abs(RT1R) >= abs(RT2R).*> \endverbatim*>* =====================================================================SUBROUTINE DLANV2( A, B, C, D, RT1R, RT1I, RT2R, RT2I, CS, SN )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION A, B, C, CS, D, RT1I, RT1R, RT2I, RT2R, SN* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )DOUBLE PRECISION MULTPLPARAMETER ( MULTPL = 4.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, BB, BCMAX, BCMIS, CC, CS1, DD, EPS, P, SAB,$ SAC, SCALE, SIGMA, SN1, TAU, TEMP, Z* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL DLAMCH, DLAPY2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SIGN, SQRT* ..* .. Executable Statements ..*EPS = DLAMCH( 'P' )IF( C.EQ.ZERO ) THENCS = ONESN = ZEROGO TO 10*ELSE IF( B.EQ.ZERO ) THEN** Swap rows and columns*CS = ZEROSN = ONETEMP = DD = AA = TEMPB = -CC = ZEROGO TO 10ELSE IF( ( A-D ).EQ.ZERO .AND. SIGN( ONE, B ).NE.SIGN( ONE, C ) )$ THENCS = ONESN = ZEROGO TO 10ELSE*TEMP = A - DP = HALF*TEMPBCMAX = MAX( ABS( B ), ABS( C ) )BCMIS = MIN( ABS( B ), ABS( C ) )*SIGN( ONE, B )*SIGN( ONE, C )SCALE = MAX( ABS( P ), BCMAX )Z = ( P / SCALE )*P + ( BCMAX / SCALE )*BCMIS** If Z is of the order of the machine accuracy, postpone the* decision on the nature of eigenvalues*IF( Z.GE.MULTPL*EPS ) THEN** Real eigenvalues. Compute A and D.*Z = P + SIGN( SQRT( SCALE )*SQRT( Z ), P )A = D + ZD = D - ( BCMAX / Z )*BCMIS** Compute B and the rotation matrix*TAU = DLAPY2( C, Z )CS = Z / TAUSN = C / TAUB = B - CC = ZEROELSE** Complex eigenvalues, or real (almost) equal eigenvalues.* Make diagonal elements equal.*SIGMA = B + CTAU = DLAPY2( SIGMA, TEMP )CS = SQRT( HALF*( ONE+ABS( SIGMA ) / TAU ) )SN = -( P / ( TAU*CS ) )*SIGN( ONE, SIGMA )** Compute [ AA BB ] = [ A B ] [ CS -SN ]* [ CC DD ] [ C D ] [ SN CS ]*AA = A*CS + B*SNBB = -A*SN + B*CSCC = C*CS + D*SNDD = -C*SN + D*CS** Compute [ A B ] = [ CS SN ] [ AA BB ]* [ C D ] [-SN CS ] [ CC DD ]*A = AA*CS + CC*SNB = BB*CS + DD*SNC = -AA*SN + CC*CSD = -BB*SN + DD*CS*TEMP = HALF*( A+D )A = TEMPD = TEMP*IF( C.NE.ZERO ) THENIF( B.NE.ZERO ) THENIF( SIGN( ONE, B ).EQ.SIGN( ONE, C ) ) THEN** Real eigenvalues: reduce to upper triangular form*SAB = SQRT( ABS( B ) )SAC = SQRT( ABS( C ) )P = SIGN( SAB*SAC, C )TAU = ONE / SQRT( ABS( B+C ) )A = TEMP + PD = TEMP - PB = B - CC = ZEROCS1 = SAB*TAUSN1 = SAC*TAUTEMP = CS*CS1 - SN*SN1SN = CS*SN1 + SN*CS1CS = TEMPEND IFELSEB = -CC = ZEROTEMP = CSCS = -SNSN = TEMPEND IFEND IFEND IF*END IF*10 CONTINUE** Store eigenvalues in (RT1R,RT1I) and (RT2R,RT2I).*RT1R = ART2R = DIF( C.EQ.ZERO ) THENRT1I = ZERORT2I = ZEROELSERT1I = SQRT( ABS( B ) )*SQRT( ABS( C ) )RT2I = -RT1IEND IFRETURN** End of DLANV2*END*> \brief \b DLAPLL measures the linear dependence of two vectors.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAPLL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapll.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapll.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapll.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAPLL( N, X, INCX, Y, INCY, SSMIN )** .. Scalar Arguments ..* INTEGER INCX, INCY, N* DOUBLE PRECISION SSMIN* ..* .. Array Arguments ..* DOUBLE PRECISION X( * ), Y( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Given two column vectors X and Y, let*>*> A = ( X Y ).*>*> The subroutine first computes the QR factorization of A = Q*R,*> and then computes the SVD of the 2-by-2 upper triangular matrix R.*> The smaller singular value of R is returned in SSMIN, which is used*> as the measurement of the linear dependency of the vectors X and Y.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The length of the vectors X and Y.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCX)*> On entry, X contains the N-vector X.*> On exit, X is overwritten.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between successive elements of X. INCX > 0.*> \endverbatim*>*> \param[in,out] Y*> \verbatim*> Y is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCY)*> On entry, Y contains the N-vector Y.*> On exit, Y is overwritten.*> \endverbatim*>*> \param[in] INCY*> \verbatim*> INCY is INTEGER*> The increment between successive elements of Y. INCY > 0.*> \endverbatim*>*> \param[out] SSMIN*> \verbatim*> SSMIN is DOUBLE PRECISION*> The smallest singular value of the N-by-2 matrix A = ( X Y ).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAPLL( N, X, INCX, Y, INCY, SSMIN )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INCX, INCY, NDOUBLE PRECISION SSMIN* ..* .. Array Arguments ..DOUBLE PRECISION X( * ), Y( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION A11, A12, A22, C, SSMAX, TAU* ..* .. External Functions ..DOUBLE PRECISION DDOTEXTERNAL DDOT* ..* .. External Subroutines ..EXTERNAL DAXPY, DLARFG, DLAS2* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.1 ) THENSSMIN = ZERORETURNEND IF** Compute the QR factorization of the N-by-2 matrix ( X Y )*CALL DLARFG( N, X( 1 ), X( 1+INCX ), INCX, TAU )A11 = X( 1 )X( 1 ) = ONE*C = -TAU*DDOT( N, X, INCX, Y, INCY )CALL DAXPY( N, C, X, INCX, Y, INCY )*CALL DLARFG( N-1, Y( 1+INCY ), Y( 1+2*INCY ), INCY, TAU )*A12 = Y( 1 )A22 = Y( 1+INCY )** Compute the SVD of 2-by-2 Upper triangular matrix.*CALL DLAS2( A11, A12, A22, SSMIN, SSMAX )*RETURN** End of DLAPLL*END*> \brief \b DLAPMR rearranges rows of a matrix as specified by a permutation vector.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAPMR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapmr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapmr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapmr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAPMR( FORWRD, M, N, X, LDX, K )** .. Scalar Arguments ..* LOGICAL FORWRD* INTEGER LDX, M, N* ..* .. Array Arguments ..* INTEGER K( * )* DOUBLE PRECISION X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAPMR rearranges the rows of the M by N matrix X as specified*> by the permutation K(1),K(2),...,K(M) of the integers 1,...,M.*> If FORWRD = .TRUE., forward permutation:*>*> X(K(I),*) is moved X(I,*) for I = 1,2,...,M.*>*> If FORWRD = .FALSE., backward permutation:*>*> X(I,*) is moved to X(K(I),*) for I = 1,2,...,M.*> \endverbatim** Arguments:* ==========**> \param[in] FORWRD*> \verbatim*> FORWRD is LOGICAL*> = .TRUE., forward permutation*> = .FALSE., backward permutation*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix X. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix X. N >= 0.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,N)*> On entry, the M by N matrix X.*> On exit, X contains the permuted matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X, LDX >= MAX(1,M).*> \endverbatim*>*> \param[in,out] K*> \verbatim*> K is INTEGER array, dimension (M)*> On entry, K contains the permutation vector. K is used as*> internal workspace, but reset to its original value on*> output.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAPMR( FORWRD, M, N, X, LDX, K )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL FORWRDINTEGER LDX, M, N* ..* .. Array Arguments ..INTEGER K( * )DOUBLE PRECISION X( LDX, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, IN, J, JJDOUBLE PRECISION TEMP* ..* .. Executable Statements ..*IF( M.LE.1 )$ RETURN*DO 10 I = 1, MK( I ) = -K( I )10 CONTINUE*IF( FORWRD ) THEN** Forward permutation*DO 50 I = 1, M*IF( K( I ).GT.0 )$ GO TO 40*J = IK( J ) = -K( J )IN = K( J )*20 CONTINUEIF( K( IN ).GT.0 )$ GO TO 40*DO 30 JJ = 1, NTEMP = X( J, JJ )X( J, JJ ) = X( IN, JJ )X( IN, JJ ) = TEMP30 CONTINUE*K( IN ) = -K( IN )J = ININ = K( IN )GO TO 20*40 CONTINUE*50 CONTINUE*ELSE** Backward permutation*DO 90 I = 1, M*IF( K( I ).GT.0 )$ GO TO 80*K( I ) = -K( I )J = K( I )60 CONTINUEIF( J.EQ.I )$ GO TO 80*DO 70 JJ = 1, NTEMP = X( I, JJ )X( I, JJ ) = X( J, JJ )X( J, JJ ) = TEMP70 CONTINUE*K( J ) = -K( J )J = K( J )GO TO 60*80 CONTINUE*90 CONTINUE*END IF*RETURN** End of ZLAPMT*END*> \brief \b DLAPMT performs a forward or backward permutation of the columns of a matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAPMT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapmt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapmt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapmt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAPMT( FORWRD, M, N, X, LDX, K )** .. Scalar Arguments ..* LOGICAL FORWRD* INTEGER LDX, M, N* ..* .. Array Arguments ..* INTEGER K( * )* DOUBLE PRECISION X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAPMT rearranges the columns of the M by N matrix X as specified*> by the permutation K(1),K(2),...,K(N) of the integers 1,...,N.*> If FORWRD = .TRUE., forward permutation:*>*> X(*,K(J)) is moved X(*,J) for J = 1,2,...,N.*>*> If FORWRD = .FALSE., backward permutation:*>*> X(*,J) is moved to X(*,K(J)) for J = 1,2,...,N.*> \endverbatim** Arguments:* ==========**> \param[in] FORWRD*> \verbatim*> FORWRD is LOGICAL*> = .TRUE., forward permutation*> = .FALSE., backward permutation*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix X. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix X. N >= 0.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,N)*> On entry, the M by N matrix X.*> On exit, X contains the permuted matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X, LDX >= MAX(1,M).*> \endverbatim*>*> \param[in,out] K*> \verbatim*> K is INTEGER array, dimension (N)*> On entry, K contains the permutation vector. K is used as*> internal workspace, but reset to its original value on*> output.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAPMT( FORWRD, M, N, X, LDX, K )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL FORWRDINTEGER LDX, M, N* ..* .. Array Arguments ..INTEGER K( * )DOUBLE PRECISION X( LDX, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, II, IN, JDOUBLE PRECISION TEMP* ..* .. Executable Statements ..*IF( N.LE.1 )$ RETURN*DO 10 I = 1, NK( I ) = -K( I )10 CONTINUE*IF( FORWRD ) THEN** Forward permutation*DO 50 I = 1, N*IF( K( I ).GT.0 )$ GO TO 40*J = IK( J ) = -K( J )IN = K( J )*20 CONTINUEIF( K( IN ).GT.0 )$ GO TO 40*DO 30 II = 1, MTEMP = X( II, J )X( II, J ) = X( II, IN )X( II, IN ) = TEMP30 CONTINUE*K( IN ) = -K( IN )J = ININ = K( IN )GO TO 20*40 CONTINUE*50 CONTINUE*ELSE** Backward permutation*DO 90 I = 1, N*IF( K( I ).GT.0 )$ GO TO 80*K( I ) = -K( I )J = K( I )60 CONTINUEIF( J.EQ.I )$ GO TO 80*DO 70 II = 1, MTEMP = X( II, I )X( II, I ) = X( II, J )X( II, J ) = TEMP70 CONTINUE*K( J ) = -K( J )J = K( J )GO TO 60*80 CONTINUE*90 CONTINUE*END IF*RETURN** End of DLAPMT*END*> \brief \b DLAPY2 returns sqrt(x2+y2).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAPY2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapy2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapy2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapy2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLAPY2( X, Y )** .. Scalar Arguments ..* DOUBLE PRECISION X, Y* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary*> overflow.*> \endverbatim** Arguments:* ==========**> \param[in] X*> \verbatim*> X is DOUBLE PRECISION*> \endverbatim*>*> \param[in] Y*> \verbatim*> Y is DOUBLE PRECISION*> X and Y specify the values x and y.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLAPY2( X, Y )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..DOUBLE PRECISION X, Y* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION W, XABS, YABS, ZLOGICAL X_IS_NAN, Y_IS_NAN* ..* .. External Functions ..LOGICAL DISNANEXTERNAL DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*X_IS_NAN = DISNAN( X )Y_IS_NAN = DISNAN( Y )IF ( X_IS_NAN ) DLAPY2 = XIF ( Y_IS_NAN ) DLAPY2 = Y*IF ( .NOT.( X_IS_NAN.OR.Y_IS_NAN ) ) THENXABS = ABS( X )YABS = ABS( Y )W = MAX( XABS, YABS )Z = MIN( XABS, YABS )IF( Z.EQ.ZERO ) THENDLAPY2 = WELSEDLAPY2 = W*SQRT( ONE+( Z / W )**2 )END IFEND IFRETURN** End of DLAPY2*END*> \brief \b DLAPY3 returns sqrt(x2+y2+z2).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAPY3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapy3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapy3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapy3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )** .. Scalar Arguments ..* DOUBLE PRECISION X, Y, Z* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause*> unnecessary overflow.*> \endverbatim** Arguments:* ==========**> \param[in] X*> \verbatim*> X is DOUBLE PRECISION*> \endverbatim*>*> \param[in] Y*> \verbatim*> Y is DOUBLE PRECISION*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION*> X, Y and Z specify the values x, y and z.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION X, Y, Z* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION W, XABS, YABS, ZABS* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*XABS = ABS( X )YABS = ABS( Y )ZABS = ABS( Z )W = MAX( XABS, YABS, ZABS )IF( W.EQ.ZERO ) THEN* W can be zero for max(0,nan,0)* adding all three entries together will make sure* NaN will not disappear.DLAPY3 = XABS + YABS + ZABSELSEDLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2+$ ( ZABS / W )**2 )END IFRETURN** End of DLAPY3*END*> \brief \b DLAQGB scales a general band matrix, using row and column scaling factors computed by sgbequ.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQGB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqgb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqgb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqgb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQGB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,* AMAX, EQUED )** .. Scalar Arguments ..* CHARACTER EQUED* INTEGER KL, KU, LDAB, M, N* DOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQGB equilibrates a general M by N band matrix A with KL*> subdiagonals and KU superdiagonals using the row and scaling factors*> in the vectors R and C.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The number of subdiagonals within the band of A. KL >= 0.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The number of superdiagonals within the band of A. KU >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the matrix A in band storage, in rows 1 to KL+KU+1.*> The j-th column of A is stored in the j-th column of the*> array AB as follows:*> AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(m,j+kl)*>*> On exit, the equilibrated matrix, in the same storage format*> as A. See EQUED for the form of the equilibrated matrix.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDA >= KL+KU+1.*> \endverbatim*>*> \param[in] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (M)*> The row scale factors for A.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> The column scale factors for A.*> \endverbatim*>*> \param[in] ROWCND*> \verbatim*> ROWCND is DOUBLE PRECISION*> Ratio of the smallest R(i) to the largest R(i).*> \endverbatim*>*> \param[in] COLCND*> \verbatim*> COLCND is DOUBLE PRECISION*> Ratio of the smallest C(i) to the largest C(i).*> \endverbatim*>*> \param[in] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix entry.*> \endverbatim*>*> \param[out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration*> = 'R': Row equilibration, i.e., A has been premultiplied by*> diag(R).*> = 'C': Column equilibration, i.e., A has been postmultiplied*> by diag(C).*> = 'B': Both row and column equilibration, i.e., A has been*> replaced by diag(R) * A * diag(C).*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> THRESH is a threshold value used to decide if row or column scaling*> should be done based on the ratio of the row or column scaling*> factors. If ROWCND < THRESH, row scaling is done, and if*> COLCND < THRESH, column scaling is done.*>*> LARGE and SMALL are threshold values used to decide if row scaling*> should be done based on the absolute size of the largest matrix*> element. If AMAX > LARGE or AMAX < SMALL, row scaling is done.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGBauxiliary** =====================================================================SUBROUTINE DLAQGB( M, N, KL, KU, AB, LDAB, R, C, ROWCND, COLCND,$ AMAX, EQUED )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER EQUEDINTEGER KL, KU, LDAB, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), C( * ), R( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, THRESHPARAMETER ( ONE = 1.0D+0, THRESH = 0.1D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION CJ, LARGE, SMALL* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 ) THENEQUED = 'N'RETURNEND IF** Initialize LARGE and SMALL.*SMALL = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )LARGE = ONE / SMALL*IF( ROWCND.GE.THRESH .AND. AMAX.GE.SMALL .AND. AMAX.LE.LARGE )$ THEN** No row scaling*IF( COLCND.GE.THRESH ) THEN** No column scaling*EQUED = 'N'ELSE** Column scaling*DO 20 J = 1, NCJ = C( J )DO 10 I = MAX( 1, J-KU ), MIN( M, J+KL )AB( KU+1+I-J, J ) = CJ*AB( KU+1+I-J, J )10 CONTINUE20 CONTINUEEQUED = 'C'END IFELSE IF( COLCND.GE.THRESH ) THEN** Row scaling, no column scaling*DO 40 J = 1, NDO 30 I = MAX( 1, J-KU ), MIN( M, J+KL )AB( KU+1+I-J, J ) = R( I )*AB( KU+1+I-J, J )30 CONTINUE40 CONTINUEEQUED = 'R'ELSE** Row and column scaling*DO 60 J = 1, NCJ = C( J )DO 50 I = MAX( 1, J-KU ), MIN( M, J+KL )AB( KU+1+I-J, J ) = CJ*R( I )*AB( KU+1+I-J, J )50 CONTINUE60 CONTINUEEQUED = 'B'END IF*RETURN** End of DLAQGB*END*> \brief \b DLAQGE scales a general rectangular matrix, using row and column scaling factors computed by sgeequ.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQGE + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqge.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqge.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqge.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQGE( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,* EQUED )** .. Scalar Arguments ..* CHARACTER EQUED* INTEGER LDA, M, N* DOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQGE equilibrates a general M by N matrix A using the row and*> column scaling factors in the vectors R and C.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M by N matrix A.*> On exit, the equilibrated matrix. See EQUED for the form of*> the equilibrated matrix.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(M,1).*> \endverbatim*>*> \param[in] R*> \verbatim*> R is DOUBLE PRECISION array, dimension (M)*> The row scale factors for A.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (N)*> The column scale factors for A.*> \endverbatim*>*> \param[in] ROWCND*> \verbatim*> ROWCND is DOUBLE PRECISION*> Ratio of the smallest R(i) to the largest R(i).*> \endverbatim*>*> \param[in] COLCND*> \verbatim*> COLCND is DOUBLE PRECISION*> Ratio of the smallest C(i) to the largest C(i).*> \endverbatim*>*> \param[in] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix entry.*> \endverbatim*>*> \param[out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration*> = 'R': Row equilibration, i.e., A has been premultiplied by*> diag(R).*> = 'C': Column equilibration, i.e., A has been postmultiplied*> by diag(C).*> = 'B': Both row and column equilibration, i.e., A has been*> replaced by diag(R) * A * diag(C).*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> THRESH is a threshold value used to decide if row or column scaling*> should be done based on the ratio of the row or column scaling*> factors. If ROWCND < THRESH, row scaling is done, and if*> COLCND < THRESH, column scaling is done.*>*> LARGE and SMALL are threshold values used to decide if row scaling*> should be done based on the absolute size of the largest matrix*> element. If AMAX > LARGE or AMAX < SMALL, row scaling is done.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEauxiliary** =====================================================================SUBROUTINE DLAQGE( M, N, A, LDA, R, C, ROWCND, COLCND, AMAX,$ EQUED )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER EQUEDINTEGER LDA, M, NDOUBLE PRECISION AMAX, COLCND, ROWCND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * ), R( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, THRESHPARAMETER ( ONE = 1.0D+0, THRESH = 0.1D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION CJ, LARGE, SMALL* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 ) THENEQUED = 'N'RETURNEND IF** Initialize LARGE and SMALL.*SMALL = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )LARGE = ONE / SMALL*IF( ROWCND.GE.THRESH .AND. AMAX.GE.SMALL .AND. AMAX.LE.LARGE )$ THEN** No row scaling*IF( COLCND.GE.THRESH ) THEN** No column scaling*EQUED = 'N'ELSE** Column scaling*DO 20 J = 1, NCJ = C( J )DO 10 I = 1, MA( I, J ) = CJ*A( I, J )10 CONTINUE20 CONTINUEEQUED = 'C'END IFELSE IF( COLCND.GE.THRESH ) THEN** Row scaling, no column scaling*DO 40 J = 1, NDO 30 I = 1, MA( I, J ) = R( I )*A( I, J )30 CONTINUE40 CONTINUEEQUED = 'R'ELSE** Row and column scaling*DO 60 J = 1, NCJ = C( J )DO 50 I = 1, MA( I, J ) = CJ*R( I )*A( I, J )50 CONTINUE60 CONTINUEEQUED = 'B'END IF*RETURN** End of DLAQGE*END*> \brief \b DLAQP2 computes a QR factorization with column pivoting of the matrix block.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQP2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqp2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqp2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqp2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2,* WORK )** .. Scalar Arguments ..* INTEGER LDA, M, N, OFFSET* ..* .. Array Arguments ..* INTEGER JPVT( * )* DOUBLE PRECISION A( LDA, * ), TAU( * ), VN1( * ), VN2( * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQP2 computes a QR factorization with column pivoting of*> the block A(OFFSET+1:M,1:N).*> The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] OFFSET*> \verbatim*> OFFSET is INTEGER*> The number of rows of the matrix A that must be pivoted*> but no factorized. OFFSET >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, the upper triangle of block A(OFFSET+1:M,1:N) is*> the triangular factor obtained; the elements in block*> A(OFFSET+1:M,1:N) below the diagonal, together with the*> array TAU, represent the orthogonal matrix Q as a product of*> elementary reflectors. Block A(1:OFFSET,1:N) has been*> accordingly pivoted, but no factorized.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] JPVT*> \verbatim*> JPVT is INTEGER array, dimension (N)*> On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted*> to the front of A*P (a leading column); if JPVT(i) = 0,*> the i-th column of A is a free column.*> On exit, if JPVT(i) = k, then the i-th column of A*P*> was the k-th column of A.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(M,N))*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[in,out] VN1*> \verbatim*> VN1 is DOUBLE PRECISION array, dimension (N)*> The vector with the partial column norms.*> \endverbatim*>*> \param[in,out] VN2*> \verbatim*> VN2 is DOUBLE PRECISION array, dimension (N)*> The vector with the exact column norms.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain*> X. Sun, Computer Science Dept., Duke University, USA*> \n*> Partial column norm updating strategy modified on April 2011*> Z. Drmac and Z. Bujanovic, Dept. of Mathematics,*> University of Zagreb, Croatia.**> \par References:* ================*>*> LAPACK Working Note 176**> \htmlonly*> <a href="http://www.netlib.org/lapack/lawnspdf/lawn176.pdf">[PDF]</a>*> \endhtmlonly** =====================================================================SUBROUTINE DLAQP2( M, N, OFFSET, A, LDA, JPVT, TAU, VN1, VN2,$ WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER LDA, M, N, OFFSET* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), TAU( * ), VN1( * ), VN2( * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, ITEMP, J, MN, OFFPI, PVTDOUBLE PRECISION AII, TEMP, TEMP2, TOL3Z* ..* .. External Subroutines ..EXTERNAL DLARF, DLARFG, DSWAP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DNRM2EXTERNAL IDAMAX, DLAMCH, DNRM2* ..* .. Executable Statements ..*MN = MIN( M-OFFSET, N )TOL3Z = SQRT(DLAMCH('Epsilon'))** Compute factorization.*DO 20 I = 1, MN*OFFPI = OFFSET + I** Determine ith pivot column and swap if necessary.*PVT = ( I-1 ) + IDAMAX( N-I+1, VN1( I ), 1 )*IF( PVT.NE.I ) THENCALL DSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )ITEMP = JPVT( PVT )JPVT( PVT ) = JPVT( I )JPVT( I ) = ITEMPVN1( PVT ) = VN1( I )VN2( PVT ) = VN2( I )END IF** Generate elementary reflector H(i).*IF( OFFPI.LT.M ) THENCALL DLARFG( M-OFFPI+1, A( OFFPI, I ), A( OFFPI+1, I ), 1,$ TAU( I ) )ELSECALL DLARFG( 1, A( M, I ), A( M, I ), 1, TAU( I ) )END IF*IF( I.LT.N ) THEN** Apply H(i)**T to A(offset+i:m,i+1:n) from the left.*AII = A( OFFPI, I )A( OFFPI, I ) = ONECALL DLARF( 'Left', M-OFFPI+1, N-I, A( OFFPI, I ), 1,$ TAU( I ), A( OFFPI, I+1 ), LDA, WORK( 1 ) )A( OFFPI, I ) = AIIEND IF** Update partial column norms.*DO 10 J = I + 1, NIF( VN1( J ).NE.ZERO ) THEN** NOTE: The following 4 lines follow from the analysis in* Lapack Working Note 176.*TEMP = ONE - ( ABS( A( OFFPI, J ) ) / VN1( J ) )**2TEMP = MAX( TEMP, ZERO )TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2IF( TEMP2 .LE. TOL3Z ) THENIF( OFFPI.LT.M ) THENVN1( J ) = DNRM2( M-OFFPI, A( OFFPI+1, J ), 1 )VN2( J ) = VN1( J )ELSEVN1( J ) = ZEROVN2( J ) = ZEROEND IFELSEVN1( J ) = VN1( J )*SQRT( TEMP )END IFEND IF10 CONTINUE*20 CONTINUE*RETURN** End of DLAQP2*END*> \brief \b DLAQPS computes a step of QR factorization with column pivoting of a real m-by-n matrix A by using BLAS level 3.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQPS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqps.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqps.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqps.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQPS( M, N, OFFSET, NB, KB, A, LDA, JPVT, TAU, VN1,* VN2, AUXV, F, LDF )** .. Scalar Arguments ..* INTEGER KB, LDA, LDF, M, N, NB, OFFSET* ..* .. Array Arguments ..* INTEGER JPVT( * )* DOUBLE PRECISION A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * ),* $ VN1( * ), VN2( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQPS computes a step of QR factorization with column pivoting*> of a real M-by-N matrix A by using Blas-3. It tries to factorize*> NB columns from A starting from the row OFFSET+1, and updates all*> of the matrix with Blas-3 xGEMM.*>*> In some cases, due to catastrophic cancellations, it cannot*> factorize NB columns. Hence, the actual number of factorized*> columns is returned in KB.*>*> Block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0*> \endverbatim*>*> \param[in] OFFSET*> \verbatim*> OFFSET is INTEGER*> The number of rows of A that have been factorized in*> previous steps.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The number of columns to factorize.*> \endverbatim*>*> \param[out] KB*> \verbatim*> KB is INTEGER*> The number of columns actually factorized.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, block A(OFFSET+1:M,1:KB) is the triangular*> factor obtained and block A(1:OFFSET,1:N) has been*> accordingly pivoted, but no factorized.*> The rest of the matrix, block A(OFFSET+1:M,KB+1:N) has*> been updated.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] JPVT*> \verbatim*> JPVT is INTEGER array, dimension (N)*> JPVT(I) = K <==> Column K of the full matrix A has been*> permuted into position I in AP.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (KB)*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[in,out] VN1*> \verbatim*> VN1 is DOUBLE PRECISION array, dimension (N)*> The vector with the partial column norms.*> \endverbatim*>*> \param[in,out] VN2*> \verbatim*> VN2 is DOUBLE PRECISION array, dimension (N)*> The vector with the exact column norms.*> \endverbatim*>*> \param[in,out] AUXV*> \verbatim*> AUXV is DOUBLE PRECISION array, dimension (NB)*> Auxiliar vector.*> \endverbatim*>*> \param[in,out] F*> \verbatim*> F is DOUBLE PRECISION array, dimension (LDF,NB)*> Matrix F**T = L*Y**T*A.*> \endverbatim*>*> \param[in] LDF*> \verbatim*> LDF is INTEGER*> The leading dimension of the array F. LDF >= max(1,N).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain*> X. Sun, Computer Science Dept., Duke University, USA*> \n*> Partial column norm updating strategy modified on April 2011*> Z. Drmac and Z. Bujanovic, Dept. of Mathematics,*> University of Zagreb, Croatia.**> \par References:* ================*>*> LAPACK Working Note 176**> \htmlonly*> <a href="http://www.netlib.org/lapack/lawnspdf/lawn176.pdf">[PDF]</a>*> \endhtmlonly** =====================================================================SUBROUTINE DLAQPS( M, N, OFFSET, NB, KB, A, LDA, JPVT, TAU, VN1,$ VN2, AUXV, F, LDF )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER KB, LDA, LDF, M, N, NB, OFFSET* ..* .. Array Arguments ..INTEGER JPVT( * )DOUBLE PRECISION A( LDA, * ), AUXV( * ), F( LDF, * ), TAU( * ),$ VN1( * ), VN2( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER ITEMP, J, K, LASTRK, LSTICC, PVT, RKDOUBLE PRECISION AKK, TEMP, TEMP2, TOL3Z* ..* .. External Subroutines ..EXTERNAL DGEMM, DGEMV, DLARFG, DSWAP* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, NINT, SQRT* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCH, DNRM2EXTERNAL IDAMAX, DLAMCH, DNRM2* ..* .. Executable Statements ..*LASTRK = MIN( M, N+OFFSET )LSTICC = 0K = 0TOL3Z = SQRT(DLAMCH('Epsilon'))** Beginning of while loop.*10 CONTINUEIF( ( K.LT.NB ) .AND. ( LSTICC.EQ.0 ) ) THENK = K + 1RK = OFFSET + K** Determine ith pivot column and swap if necessary*PVT = ( K-1 ) + IDAMAX( N-K+1, VN1( K ), 1 )IF( PVT.NE.K ) THENCALL DSWAP( M, A( 1, PVT ), 1, A( 1, K ), 1 )CALL DSWAP( K-1, F( PVT, 1 ), LDF, F( K, 1 ), LDF )ITEMP = JPVT( PVT )JPVT( PVT ) = JPVT( K )JPVT( K ) = ITEMPVN1( PVT ) = VN1( K )VN2( PVT ) = VN2( K )END IF** Apply previous Householder reflectors to column K:* A(RK:M,K) := A(RK:M,K) - A(RK:M,1:K-1)*F(K,1:K-1)**T.*IF( K.GT.1 ) THENCALL DGEMV( 'No transpose', M-RK+1, K-1, -ONE, A( RK, 1 ),$ LDA, F( K, 1 ), LDF, ONE, A( RK, K ), 1 )END IF** Generate elementary reflector H(k).*IF( RK.LT.M ) THENCALL DLARFG( M-RK+1, A( RK, K ), A( RK+1, K ), 1, TAU( K ) )ELSECALL DLARFG( 1, A( RK, K ), A( RK, K ), 1, TAU( K ) )END IF*AKK = A( RK, K )A( RK, K ) = ONE** Compute Kth column of F:** Compute F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)**T*A(RK:M,K).*IF( K.LT.N ) THENCALL DGEMV( 'Transpose', M-RK+1, N-K, TAU( K ),$ A( RK, K+1 ), LDA, A( RK, K ), 1, ZERO,$ F( K+1, K ), 1 )END IF** Padding F(1:K,K) with zeros.*DO 20 J = 1, KF( J, K ) = ZERO20 CONTINUE** Incremental updating of F:* F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)**T* *A(RK:M,K).*IF( K.GT.1 ) THENCALL DGEMV( 'Transpose', M-RK+1, K-1, -TAU( K ), A( RK, 1 ),$ LDA, A( RK, K ), 1, ZERO, AUXV( 1 ), 1 )*CALL DGEMV( 'No transpose', N, K-1, ONE, F( 1, 1 ), LDF,$ AUXV( 1 ), 1, ONE, F( 1, K ), 1 )END IF** Update the current row of A:* A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)**T.*IF( K.LT.N ) THENCALL DGEMV( 'No transpose', N-K, K, -ONE, F( K+1, 1 ), LDF,$ A( RK, 1 ), LDA, ONE, A( RK, K+1 ), LDA )END IF** Update partial column norms.*IF( RK.LT.LASTRK ) THENDO 30 J = K + 1, NIF( VN1( J ).NE.ZERO ) THEN** NOTE: The following 4 lines follow from the analysis in* Lapack Working Note 176.*TEMP = ABS( A( RK, J ) ) / VN1( J )TEMP = MAX( ZERO, ( ONE+TEMP )*( ONE-TEMP ) )TEMP2 = TEMP*( VN1( J ) / VN2( J ) )**2IF( TEMP2 .LE. TOL3Z ) THENVN2( J ) = DBLE( LSTICC )LSTICC = JELSEVN1( J ) = VN1( J )*SQRT( TEMP )END IFEND IF30 CONTINUEEND IF*A( RK, K ) = AKK** End of while loop.*GO TO 10END IFKB = KRK = OFFSET + KB** Apply the block reflector to the rest of the matrix:* A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) -* A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)**T.*IF( KB.LT.MIN( N, M-OFFSET ) ) THENCALL DGEMM( 'No transpose', 'Transpose', M-RK, N-KB, KB, -ONE,$ A( RK+1, 1 ), LDA, F( KB+1, 1 ), LDF, ONE,$ A( RK+1, KB+1 ), LDA )END IF** Recomputation of difficult columns.*40 CONTINUEIF( LSTICC.GT.0 ) THENITEMP = NINT( VN2( LSTICC ) )VN1( LSTICC ) = DNRM2( M-RK, A( RK+1, LSTICC ), 1 )** NOTE: The computation of VN1( LSTICC ) relies on the fact that* SNRM2 does not fail on vectors with norm below the value of* SQRT(DLAMCH('S'))*VN2( LSTICC ) = VN1( LSTICC )LSTICC = ITEMPGO TO 40END IF*RETURN** End of DLAQPS*END*> \brief \b DLAQR0 computes the eigenvalues of a Hessenberg matrix, and optionally the matrices from the Schur decomposition.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQR0 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqr0.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqr0.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqr0.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,* ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N* LOGICAL WANTT, WANTZ* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQR0 computes the eigenvalues of a Hessenberg matrix H*> and, optionally, the matrices T and Z from the Schur decomposition*> H = Z T Z**T, where T is an upper quasi-triangular matrix (the*> Schur form), and Z is the orthogonal matrix of Schur vectors.*>*> Optionally Z may be postmultiplied into an input orthogonal*> matrix Q so that this routine can give the Schur factorization*> of a matrix A which has been reduced to the Hessenberg form H*> by the orthogonal matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T.*> \endverbatim** Arguments:* ==========**> \param[in] WANTT*> \verbatim*> WANTT is LOGICAL*> = .TRUE. : the full Schur form T is required;*> = .FALSE.: only eigenvalues are required.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> = .TRUE. : the matrix of Schur vectors Z is required;*> = .FALSE.: Schur vectors are not required.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H. N .GE. 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> It is assumed that H is already upper triangular in rows*> and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,*> H(ILO,ILO-1) is zero. ILO and IHI are normally set by a*> previous call to DGEBAL, and then passed to DGEHRD when the*> matrix output by DGEBAL is reduced to Hessenberg form.*> Otherwise, ILO and IHI should be set to 1 and N,*> respectively. If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.*> If N = 0, then ILO = 1 and IHI = 0.*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On entry, the upper Hessenberg matrix H.*> On exit, if INFO = 0 and WANTT is .TRUE., then H contains*> the upper quasi-triangular matrix T from the Schur*> decomposition (the Schur form); 2-by-2 diagonal blocks*> (corresponding to complex conjugate pairs of eigenvalues)*> are returned in standard form, with H(i,i) = H(i+1,i+1)*> and H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and WANTT is*> .FALSE., then the contents of H are unspecified on exit.*> (The output value of H when INFO.GT.0 is given under the*> description of INFO below.)*>*> This subroutine may explicitly set H(i,j) = 0 for i.GT.j and*> j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH .GE. max(1,N).*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (IHI)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (IHI)*> The real and imaginary parts, respectively, of the computed*> eigenvalues of H(ILO:IHI,ILO:IHI) are stored in WR(ILO:IHI)*> and WI(ILO:IHI). If two eigenvalues are computed as a*> complex conjugate pair, they are stored in consecutive*> elements of WR and WI, say the i-th and (i+1)th, with*> WI(i) .GT. 0 and WI(i+1) .LT. 0. If WANTT is .TRUE., then*> the eigenvalues are stored in the same order as on the*> diagonal of the Schur form returned in H, with*> WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal*> block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and*> WI(i+1) = -WI(i).*> \endverbatim*>*> \param[in] ILOZ*> \verbatim*> ILOZ is INTEGER*> \endverbatim*>*> \param[in] IHIZ*> \verbatim*> IHIZ is INTEGER*> Specify the rows of Z to which transformations must be*> applied if WANTZ is .TRUE..*> 1 .LE. ILOZ .LE. ILO; IHI .LE. IHIZ .LE. N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,IHI)*> If WANTZ is .FALSE., then Z is not referenced.*> If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is*> replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the*> orthogonal Schur factor of H(ILO:IHI,ILO:IHI).*> (The output value of Z when INFO.GT.0 is given under*> the description of INFO below.)*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. if WANTZ is .TRUE.*> then LDZ.GE.MAX(1,IHIZ). Otherwize, LDZ.GE.1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension LWORK*> On exit, if LWORK = -1, WORK(1) returns an estimate of*> the optimal value for LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK .GE. max(1,N)*> is sufficient, but LWORK typically as large as 6*N may*> be required for optimal performance. A workspace query*> to determine the optimal workspace size is recommended.*>*> If LWORK = -1, then DLAQR0 does a workspace query.*> In this case, DLAQR0 checks the input parameters and*> estimates the optimal workspace size for the given*> values of N, ILO and IHI. The estimate is returned*> in WORK(1). No error message related to LWORK is*> issued by XERBLA. Neither H nor Z are accessed.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> .GT. 0: if INFO = i, DLAQR0 failed to compute all of*> the eigenvalues. Elements 1:ilo-1 and i+1:n of WR*> and WI contain those eigenvalues which have been*> successfully computed. (Failures are rare.)*>*> If INFO .GT. 0 and WANT is .FALSE., then on exit,*> the remaining unconverged eigenvalues are the eigen-*> values of the upper Hessenberg matrix rows and*> columns ILO through INFO of the final, output*> value of H.*>*> If INFO .GT. 0 and WANTT is .TRUE., then on exit*>*> (*) (initial value of H)*U = U*(final value of H)*>*> where U is an orthogonal matrix. The final*> value of H is upper Hessenberg and quasi-triangular*> in rows and columns INFO+1 through IHI.*>*> If INFO .GT. 0 and WANTZ is .TRUE., then on exit*>*> (final value of Z(ILO:IHI,ILOZ:IHIZ)*> = (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U*>*> where U is the orthogonal matrix in (*) (regard-*> less of the value of WANTT.)*>*> If INFO .GT. 0 and WANTZ is .FALSE., then Z is not*> accessed.*> \endverbatim**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA**> \par References:* ================*>*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part I: Maintaining Well Focused Shifts, and Level 3*> Performance, SIAM Journal of Matrix Analysis, volume 23, pages*> 929--947, 2002.*> \n*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part II: Aggressive Early Deflation, SIAM Journal*> of Matrix Analysis, volume 23, pages 948--973, 2002.** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAQR0( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,$ ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, NLOGICAL WANTT, WANTZ* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),$ Z( LDZ, * )* ..** ================================================================** .. Parameters ..** ==== Matrices of order NTINY or smaller must be processed by* . DLAHQR because of insufficient subdiagonal scratch space.* . (This is a hard limit.) ====INTEGER NTINYPARAMETER ( NTINY = 11 )** ==== Exceptional deflation windows: try to cure rare* . slow convergence by varying the size of the* . deflation window after KEXNW iterations. ====INTEGER KEXNWPARAMETER ( KEXNW = 5 )** ==== Exceptional shifts: try to cure rare slow convergence* . with ad-hoc exceptional shifts every KEXSH iterations.* . ====INTEGER KEXSHPARAMETER ( KEXSH = 6 )** ==== The constants WILK1 and WILK2 are used to form the* . exceptional shifts. ====DOUBLE PRECISION WILK1, WILK2PARAMETER ( WILK1 = 0.75d0, WILK2 = -0.4375d0 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, BB, CC, CS, DD, SN, SS, SWAPINTEGER I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,$ KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,$ LWKOPT, NDEC, NDFL, NH, NHO, NIBBLE, NMIN, NS,$ NSMAX, NSR, NVE, NW, NWMAX, NWR, NWUPBDLOGICAL SORTEDCHARACTER JBCMPZ*2* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Local Arrays ..DOUBLE PRECISION ZDUM( 1, 1 )* ..* .. External Subroutines ..EXTERNAL DLACPY, DLAHQR, DLANV2, DLAQR3, DLAQR4, DLAQR5* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, MAX, MIN, MOD* ..* .. Executable Statements ..INFO = 0** ==== Quick return for N = 0: nothing to do. ====*IF( N.EQ.0 ) THENWORK( 1 ) = ONERETURNEND IF*IF( N.LE.NTINY ) THEN** ==== Tiny matrices must use DLAHQR. ====*LWKOPT = 1IF( LWORK.NE.-1 )$ CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,$ ILOZ, IHIZ, Z, LDZ, INFO )ELSE** ==== Use small bulge multi-shift QR with aggressive early* . deflation on larger-than-tiny matrices. ====** ==== Hope for the best. ====*INFO = 0** ==== Set up job flags for ILAENV. ====*IF( WANTT ) THENJBCMPZ( 1: 1 ) = 'S'ELSEJBCMPZ( 1: 1 ) = 'E'END IFIF( WANTZ ) THENJBCMPZ( 2: 2 ) = 'V'ELSEJBCMPZ( 2: 2 ) = 'N'END IF** ==== NWR = recommended deflation window size. At this* . point, N .GT. NTINY = 11, so there is enough* . subdiagonal workspace for NWR.GE.2 as required.* . (In fact, there is enough subdiagonal space for* . NWR.GE.3.) ====*NWR = ILAENV( 13, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )NWR = MAX( 2, NWR )NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )** ==== NSR = recommended number of simultaneous shifts.* . At this point N .GT. NTINY = 11, so there is at* . enough subdiagonal workspace for NSR to be even* . and greater than or equal to two as required. ====*NSR = ILAENV( 15, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )NSR = MAX( 2, NSR-MOD( NSR, 2 ) )** ==== Estimate optimal workspace ====** ==== Workspace query call to DLAQR3 ====*CALL DLAQR3( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,$ IHIZ, Z, LDZ, LS, LD, WR, WI, H, LDH, N, H, LDH,$ N, H, LDH, WORK, -1 )** ==== Optimal workspace = MAX(DLAQR5, DLAQR3) ====*LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )** ==== Quick return in case of workspace query. ====*IF( LWORK.EQ.-1 ) THENWORK( 1 ) = DBLE( LWKOPT )RETURNEND IF** ==== DLAHQR/DLAQR0 crossover point ====*NMIN = ILAENV( 12, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )NMIN = MAX( NTINY, NMIN )** ==== Nibble crossover point ====*NIBBLE = ILAENV( 14, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )NIBBLE = MAX( 0, NIBBLE )** ==== Accumulate reflections during ttswp? Use block* . 2-by-2 structure during matrix-matrix multiply? ====*KACC22 = ILAENV( 16, 'DLAQR0', JBCMPZ, N, ILO, IHI, LWORK )KACC22 = MAX( 0, KACC22 )KACC22 = MIN( 2, KACC22 )** ==== NWMAX = the largest possible deflation window for* . which there is sufficient workspace. ====*NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )NW = NWMAX** ==== NSMAX = the Largest number of simultaneous shifts* . for which there is sufficient workspace. ====*NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )NSMAX = NSMAX - MOD( NSMAX, 2 )** ==== NDFL: an iteration count restarted at deflation. ====*NDFL = 1** ==== ITMAX = iteration limit ====*ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )** ==== Last row and column in the active block ====*KBOT = IHI** ==== Main Loop ====*DO 80 IT = 1, ITMAX** ==== Done when KBOT falls below ILO ====*IF( KBOT.LT.ILO )$ GO TO 90** ==== Locate active block ====*DO 10 K = KBOT, ILO + 1, -1IF( H( K, K-1 ).EQ.ZERO )$ GO TO 2010 CONTINUEK = ILO20 CONTINUEKTOP = K** ==== Select deflation window size:* . Typical Case:* . If possible and advisable, nibble the entire* . active block. If not, use size MIN(NWR,NWMAX)* . or MIN(NWR+1,NWMAX) depending upon which has* . the smaller corresponding subdiagonal entry* . (a heuristic).* .* . Exceptional Case:* . If there have been no deflations in KEXNW or* . more iterations, then vary the deflation window* . size. At first, because, larger windows are,* . in general, more powerful than smaller ones,* . rapidly increase the window to the maximum possible.* . Then, gradually reduce the window size. ====*NH = KBOT - KTOP + 1NWUPBD = MIN( NH, NWMAX )IF( NDFL.LT.KEXNW ) THENNW = MIN( NWUPBD, NWR )ELSENW = MIN( NWUPBD, 2*NW )END IFIF( NW.LT.NWMAX ) THENIF( NW.GE.NH-1 ) THENNW = NHELSEKWTOP = KBOT - NW + 1IF( ABS( H( KWTOP, KWTOP-1 ) ).GT.$ ABS( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1END IFEND IFIF( NDFL.LT.KEXNW ) THENNDEC = -1ELSE IF( NDEC.GE.0 .OR. NW.GE.NWUPBD ) THENNDEC = NDEC + 1IF( NW-NDEC.LT.2 )$ NDEC = 0NW = NW - NDECEND IF** ==== Aggressive early deflation:* . split workspace under the subdiagonal into* . - an nw-by-nw work array V in the lower* . left-hand-corner,* . - an NW-by-at-least-NW-but-more-is-better* . (NW-by-NHO) horizontal work array along* . the bottom edge,* . - an at-least-NW-but-more-is-better (NHV-by-NW)* . vertical work array along the left-hand-edge.* . ====*KV = N - NW + 1KT = NW + 1NHO = ( N-NW-1 ) - KT + 1KWV = NW + 2NVE = ( N-NW ) - KWV + 1** ==== Aggressive early deflation ====*CALL DLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,$ IHIZ, Z, LDZ, LS, LD, WR, WI, H( KV, 1 ), LDH,$ NHO, H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH,$ WORK, LWORK )** ==== Adjust KBOT accounting for new deflations. ====*KBOT = KBOT - LD** ==== KS points to the shifts. ====*KS = KBOT - LS + 1** ==== Skip an expensive QR sweep if there is a (partly* . heuristic) reason to expect that many eigenvalues* . will deflate without it. Here, the QR sweep is* . skipped if many eigenvalues have just been deflated* . or if the remaining active block is small.*IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-$ KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN** ==== NS = nominal number of simultaneous shifts.* . This may be lowered (slightly) if DLAQR3* . did not provide that many shifts. ====*NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )NS = NS - MOD( NS, 2 )** ==== If there have been no deflations* . in a multiple of KEXSH iterations,* . then try exceptional shifts.* . Otherwise use shifts provided by* . DLAQR3 above or from the eigenvalues* . of a trailing principal submatrix. ====*IF( MOD( NDFL, KEXSH ).EQ.0 ) THENKS = KBOT - NS + 1DO 30 I = KBOT, MAX( KS+1, KTOP+2 ), -2SS = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )AA = WILK1*SS + H( I, I )BB = SSCC = WILK2*SSDD = AACALL DLANV2( AA, BB, CC, DD, WR( I-1 ), WI( I-1 ),$ WR( I ), WI( I ), CS, SN )30 CONTINUEIF( KS.EQ.KTOP ) THENWR( KS+1 ) = H( KS+1, KS+1 )WI( KS+1 ) = ZEROWR( KS ) = WR( KS+1 )WI( KS ) = WI( KS+1 )END IFELSE** ==== Got NS/2 or fewer shifts? Use DLAQR4 or* . DLAHQR on a trailing principal submatrix to* . get more. (Since NS.LE.NSMAX.LE.(N+6)/9,* . there is enough space below the subdiagonal* . to fit an NS-by-NS scratch array.) ====*IF( KBOT-KS+1.LE.NS / 2 ) THENKS = KBOT - NS + 1KT = N - NS + 1CALL DLACPY( 'A', NS, NS, H( KS, KS ), LDH,$ H( KT, 1 ), LDH )IF( NS.GT.NMIN ) THENCALL DLAQR4( .false., .false., NS, 1, NS,$ H( KT, 1 ), LDH, WR( KS ),$ WI( KS ), 1, 1, ZDUM, 1, WORK,$ LWORK, INF )ELSECALL DLAHQR( .false., .false., NS, 1, NS,$ H( KT, 1 ), LDH, WR( KS ),$ WI( KS ), 1, 1, ZDUM, 1, INF )END IFKS = KS + INF** ==== In case of a rare QR failure use* . eigenvalues of the trailing 2-by-2* . principal submatrix. ====*IF( KS.GE.KBOT ) THENAA = H( KBOT-1, KBOT-1 )CC = H( KBOT, KBOT-1 )BB = H( KBOT-1, KBOT )DD = H( KBOT, KBOT )CALL DLANV2( AA, BB, CC, DD, WR( KBOT-1 ),$ WI( KBOT-1 ), WR( KBOT ),$ WI( KBOT ), CS, SN )KS = KBOT - 1END IFEND IF*IF( KBOT-KS+1.GT.NS ) THEN** ==== Sort the shifts (Helps a little)* . Bubble sort keeps complex conjugate* . pairs together. ====*SORTED = .false.DO 50 K = KBOT, KS + 1, -1IF( SORTED )$ GO TO 60SORTED = .true.DO 40 I = KS, K - 1IF( ABS( WR( I ) )+ABS( WI( I ) ).LT.$ ABS( WR( I+1 ) )+ABS( WI( I+1 ) ) ) THENSORTED = .false.*SWAP = WR( I )WR( I ) = WR( I+1 )WR( I+1 ) = SWAP*SWAP = WI( I )WI( I ) = WI( I+1 )WI( I+1 ) = SWAPEND IF40 CONTINUE50 CONTINUE60 CONTINUEEND IF** ==== Shuffle shifts into pairs of real shifts* . and pairs of complex conjugate shifts* . assuming complex conjugate shifts are* . already adjacent to one another. (Yes,* . they are.) ====*DO 70 I = KBOT, KS + 2, -2IF( WI( I ).NE.-WI( I-1 ) ) THEN*SWAP = WR( I )WR( I ) = WR( I-1 )WR( I-1 ) = WR( I-2 )WR( I-2 ) = SWAP*SWAP = WI( I )WI( I ) = WI( I-1 )WI( I-1 ) = WI( I-2 )WI( I-2 ) = SWAPEND IF70 CONTINUEEND IF** ==== If there are only two shifts and both are* . real, then use only one. ====*IF( KBOT-KS+1.EQ.2 ) THENIF( WI( KBOT ).EQ.ZERO ) THENIF( ABS( WR( KBOT )-H( KBOT, KBOT ) ).LT.$ ABS( WR( KBOT-1 )-H( KBOT, KBOT ) ) ) THENWR( KBOT-1 ) = WR( KBOT )ELSEWR( KBOT ) = WR( KBOT-1 )END IFEND IFEND IF** ==== Use up to NS of the the smallest magnatiude* . shifts. If there aren't NS shifts available,* . then use them all, possibly dropping one to* . make the number of shifts even. ====*NS = MIN( NS, KBOT-KS+1 )NS = NS - MOD( NS, 2 )KS = KBOT - NS + 1** ==== Small-bulge multi-shift QR sweep:* . split workspace under the subdiagonal into* . - a KDU-by-KDU work array U in the lower* . left-hand-corner,* . - a KDU-by-at-least-KDU-but-more-is-better* . (KDU-by-NHo) horizontal work array WH along* . the bottom edge,* . - and an at-least-KDU-but-more-is-better-by-KDU* . (NVE-by-KDU) vertical work WV arrow along* . the left-hand-edge. ====*KDU = 3*NS - 3KU = N - KDU + 1KWH = KDU + 1NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1KWV = KDU + 4NVE = N - KDU - KWV + 1** ==== Small-bulge multi-shift QR sweep ====*CALL DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,$ WR( KS ), WI( KS ), H, LDH, ILOZ, IHIZ, Z,$ LDZ, WORK, 3, H( KU, 1 ), LDH, NVE,$ H( KWV, 1 ), LDH, NHO, H( KU, KWH ), LDH )END IF** ==== Note progress (or the lack of it). ====*IF( LD.GT.0 ) THENNDFL = 1ELSENDFL = NDFL + 1END IF** ==== End of main loop ====80 CONTINUE** ==== Iteration limit exceeded. Set INFO to show where* . the problem occurred and exit. ====*INFO = KBOT90 CONTINUEEND IF** ==== Return the optimal value of LWORK. ====*WORK( 1 ) = DBLE( LWKOPT )** ==== End of DLAQR0 ====*END*> \brief \b DLAQR1 sets a scalar multiple of the first column of the product of 2-by-2 or 3-by-3 matrix H and specified shifts.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQR1 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqr1.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqr1.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqr1.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQR1( N, H, LDH, SR1, SI1, SR2, SI2, V )** .. Scalar Arguments ..* DOUBLE PRECISION SI1, SI2, SR1, SR2* INTEGER LDH, N* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), V( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Given a 2-by-2 or 3-by-3 matrix H, DLAQR1 sets v to a*> scalar multiple of the first column of the product*>*> (*) K = (H - (sr1 + i*si1)*I)*(H - (sr2 + i*si2)*I)*>*> scaling to avoid overflows and most underflows. It*> is assumed that either*>*> 1) sr1 = sr2 and si1 = -si2*> or*> 2) si1 = si2 = 0.*>*> This is useful for starting double implicit shift bulges*> in the QR algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> Order of the matrix H. N must be either 2 or 3.*> \endverbatim*>*> \param[in] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> The 2-by-2 or 3-by-3 matrix H in (*).*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of H as declared in*> the calling procedure. LDH.GE.N*> \endverbatim*>*> \param[in] SR1*> \verbatim*> SR1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] SI1*> \verbatim*> SI1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] SR2*> \verbatim*> SR2 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] SI2*> \verbatim*> SI2 is DOUBLE PRECISION*> The shifts in (*).*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (N)*> A scalar multiple of the first column of the*> matrix K in (*).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA*>* =====================================================================SUBROUTINE DLAQR1( N, H, LDH, SR1, SI1, SR2, SI2, V )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..DOUBLE PRECISION SI1, SI2, SR1, SR2INTEGER LDH, N* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), V( * )* ..** ================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0d0 )* ..* .. Local Scalars ..DOUBLE PRECISION H21S, H31S, S* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..IF( N.EQ.2 ) THENS = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) )IF( S.EQ.ZERO ) THENV( 1 ) = ZEROV( 2 ) = ZEROELSEH21S = H( 2, 1 ) / SV( 1 ) = H21S*H( 1, 2 ) + ( H( 1, 1 )-SR1 )*$ ( ( H( 1, 1 )-SR2 ) / S ) - SI1*( SI2 / S )V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 )END IFELSES = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) ) +$ ABS( H( 3, 1 ) )IF( S.EQ.ZERO ) THENV( 1 ) = ZEROV( 2 ) = ZEROV( 3 ) = ZEROELSEH21S = H( 2, 1 ) / SH31S = H( 3, 1 ) / SV( 1 ) = ( H( 1, 1 )-SR1 )*( ( H( 1, 1 )-SR2 ) / S ) -$ SI1*( SI2 / S ) + H( 1, 2 )*H21S + H( 1, 3 )*H31SV( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 ) +$ H( 2, 3 )*H31SV( 3 ) = H31S*( H( 1, 1 )+H( 3, 3 )-SR1-SR2 ) +$ H21S*H( 3, 2 )END IFEND IFEND*> \brief \b DLAQR2 performs the orthogonal similarity transformation of a Hessenberg matrix to detect and deflate fully converged eigenvalues from a trailing principal submatrix (aggressive early deflation).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQR2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqr2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqr2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqr2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,* IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,* LDT, NV, WV, LDWV, WORK, LWORK )** .. Scalar Arguments ..* INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,* $ LDZ, LWORK, N, ND, NH, NS, NV, NW* LOGICAL WANTT, WANTZ* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),* $ V( LDV, * ), WORK( * ), WV( LDWV, * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQR2 is identical to DLAQR3 except that it avoids*> recursion by calling DLAHQR instead of DLAQR4.*>*> Aggressive early deflation:*>*> This subroutine accepts as input an upper Hessenberg matrix*> H and performs an orthogonal similarity transformation*> designed to detect and deflate fully converged eigenvalues from*> a trailing principal submatrix. On output H has been over-*> written by a new Hessenberg matrix that is a perturbation of*> an orthogonal similarity transformation of H. It is to be*> hoped that the final version of H has many zero subdiagonal*> entries.*> \endverbatim** Arguments:* ==========**> \param[in] WANTT*> \verbatim*> WANTT is LOGICAL*> If .TRUE., then the Hessenberg matrix H is fully updated*> so that the quasi-triangular Schur factor may be*> computed (in cooperation with the calling subroutine).*> If .FALSE., then only enough of H is updated to preserve*> the eigenvalues.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> If .TRUE., then the orthogonal matrix Z is updated so*> so that the orthogonal Schur factor may be computed*> (in cooperation with the calling subroutine).*> If .FALSE., then Z is not referenced.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H and (if WANTZ is .TRUE.) the*> order of the orthogonal matrix Z.*> \endverbatim*>*> \param[in] KTOP*> \verbatim*> KTOP is INTEGER*> It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.*> KBOT and KTOP together determine an isolated block*> along the diagonal of the Hessenberg matrix.*> \endverbatim*>*> \param[in] KBOT*> \verbatim*> KBOT is INTEGER*> It is assumed without a check that either*> KBOT = N or H(KBOT+1,KBOT)=0. KBOT and KTOP together*> determine an isolated block along the diagonal of the*> Hessenberg matrix.*> \endverbatim*>*> \param[in] NW*> \verbatim*> NW is INTEGER*> Deflation window size. 1 .LE. NW .LE. (KBOT-KTOP+1).*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On input the initial N-by-N section of H stores the*> Hessenberg matrix undergoing aggressive early deflation.*> On output H has been transformed by an orthogonal*> similarity transformation, perturbed, and the returned*> to Hessenberg form that (it is to be hoped) has some*> zero subdiagonal entries.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> Leading dimension of H just as declared in the calling*> subroutine. N .LE. LDH*> \endverbatim*>*> \param[in] ILOZ*> \verbatim*> ILOZ is INTEGER*> \endverbatim*>*> \param[in] IHIZ*> \verbatim*> IHIZ is INTEGER*> Specify the rows of Z to which transformations must be*> applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> IF WANTZ is .TRUE., then on output, the orthogonal*> similarity transformation mentioned above has been*> accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.*> If WANTZ is .FALSE., then Z is unreferenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of Z just as declared in the*> calling subroutine. 1 .LE. LDZ.*> \endverbatim*>*> \param[out] NS*> \verbatim*> NS is INTEGER*> The number of unconverged (ie approximate) eigenvalues*> returned in SR and SI that may be used as shifts by the*> calling subroutine.*> \endverbatim*>*> \param[out] ND*> \verbatim*> ND is INTEGER*> The number of converged eigenvalues uncovered by this*> subroutine.*> \endverbatim*>*> \param[out] SR*> \verbatim*> SR is DOUBLE PRECISION array, dimension (KBOT)*> \endverbatim*>*> \param[out] SI*> \verbatim*> SI is DOUBLE PRECISION array, dimension (KBOT)*> On output, the real and imaginary parts of approximate*> eigenvalues that may be used for shifts are stored in*> SR(KBOT-ND-NS+1) through SR(KBOT-ND) and*> SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.*> The real and imaginary parts of converged eigenvalues*> are stored in SR(KBOT-ND+1) through SR(KBOT) and*> SI(KBOT-ND+1) through SI(KBOT), respectively.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,NW)*> An NW-by-NW work array.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of V just as declared in the*> calling subroutine. NW .LE. LDV*> \endverbatim*>*> \param[in] NH*> \verbatim*> NH is INTEGER*> The number of columns of T. NH.GE.NW.*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,NW)*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of T just as declared in the*> calling subroutine. NW .LE. LDT*> \endverbatim*>*> \param[in] NV*> \verbatim*> NV is INTEGER*> The number of rows of work array WV available for*> workspace. NV.GE.NW.*> \endverbatim*>*> \param[out] WV*> \verbatim*> WV is DOUBLE PRECISION array, dimension (LDWV,NW)*> \endverbatim*>*> \param[in] LDWV*> \verbatim*> LDWV is INTEGER*> The leading dimension of W just as declared in the*> calling subroutine. NW .LE. LDV*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, WORK(1) is set to an estimate of the optimal value*> of LWORK for the given values of N, NW, KTOP and KBOT.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the work array WORK. LWORK = 2*NW*> suffices, but greater efficiency may result from larger*> values of LWORK.*>*> If LWORK = -1, then a workspace query is assumed; DLAQR2*> only estimates the optimal workspace size for the given*> values of N, NW, KTOP and KBOT. The estimate is returned*> in WORK(1). No error message related to LWORK is issued*> by XERBLA. Neither H nor Z are accessed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA*>* =====================================================================SUBROUTINE DLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,$ IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,$ LDT, NV, WV, LDWV, WORK, LWORK )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,$ LDZ, LWORK, N, ND, NH, NS, NV, NWLOGICAL WANTT, WANTZ* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),$ V( LDV, * ), WORK( * ), WV( LDWV, * ),$ Z( LDZ, * )* ..** ================================================================* .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,$ SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULPINTEGER I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,$ KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2,$ LWKOPTLOGICAL BULGE, SORTED* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEHRD, DGEMM, DLABAD, DLACPY, DLAHQR,$ DLANV2, DLARF, DLARFG, DLASET, DORMHR, DTREXC* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, MAX, MIN, SQRT* ..* .. Executable Statements ..** ==== Estimate optimal workspace. ====*JW = MIN( NW, KBOT-KTOP+1 )IF( JW.LE.2 ) THENLWKOPT = 1ELSE** ==== Workspace query call to DGEHRD ====*CALL DGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )LWK1 = INT( WORK( 1 ) )** ==== Workspace query call to DORMHR ====*CALL DORMHR( 'R', 'N', JW, JW, 1, JW-1, T, LDT, WORK, V, LDV,$ WORK, -1, INFO )LWK2 = INT( WORK( 1 ) )** ==== Optimal workspace ====*LWKOPT = JW + MAX( LWK1, LWK2 )END IF** ==== Quick return in case of workspace query. ====*IF( LWORK.EQ.-1 ) THENWORK( 1 ) = DBLE( LWKOPT )RETURNEND IF** ==== Nothing to do ...* ... for an empty active block ... ====NS = 0ND = 0WORK( 1 ) = ONEIF( KTOP.GT.KBOT )$ RETURN* ... nor for an empty deflation window. ====IF( NW.LT.1 )$ RETURN** ==== Machine constants ====*SAFMIN = DLAMCH( 'SAFE MINIMUM' )SAFMAX = ONE / SAFMINCALL DLABAD( SAFMIN, SAFMAX )ULP = DLAMCH( 'PRECISION' )SMLNUM = SAFMIN*( DBLE( N ) / ULP )** ==== Setup deflation window ====*JW = MIN( NW, KBOT-KTOP+1 )KWTOP = KBOT - JW + 1IF( KWTOP.EQ.KTOP ) THENS = ZEROELSES = H( KWTOP, KWTOP-1 )END IF*IF( KBOT.EQ.KWTOP ) THEN** ==== 1-by-1 deflation window: not much to do ====*SR( KWTOP ) = H( KWTOP, KWTOP )SI( KWTOP ) = ZERONS = 1ND = 0IF( ABS( S ).LE.MAX( SMLNUM, ULP*ABS( H( KWTOP, KWTOP ) ) ) )$ THENNS = 0ND = 1IF( KWTOP.GT.KTOP )$ H( KWTOP, KWTOP-1 ) = ZEROEND IFWORK( 1 ) = ONERETURNEND IF** ==== Convert to spike-triangular form. (In case of a* . rare QR failure, this routine continues to do* . aggressive early deflation using that part of* . the deflation window that converged using INFQR* . here and there to keep track.) ====*CALL DLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )CALL DCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )*CALL DLASET( 'A', JW, JW, ZERO, ONE, V, LDV )CALL DLAHQR( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),$ SI( KWTOP ), 1, JW, V, LDV, INFQR )** ==== DTREXC needs a clean margin near the diagonal ====*DO 10 J = 1, JW - 3T( J+2, J ) = ZEROT( J+3, J ) = ZERO10 CONTINUEIF( JW.GT.2 )$ T( JW, JW-2 ) = ZERO** ==== Deflation detection loop ====*NS = JWILST = INFQR + 120 CONTINUEIF( ILST.LE.NS ) THENIF( NS.EQ.1 ) THENBULGE = .FALSE.ELSEBULGE = T( NS, NS-1 ).NE.ZEROEND IF** ==== Small spike tip test for deflation ====*IF( .NOT.BULGE ) THEN** ==== Real eigenvalue ====*FOO = ABS( T( NS, NS ) )IF( FOO.EQ.ZERO )$ FOO = ABS( S )IF( ABS( S*V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) ) THEN** ==== Deflatable ====*NS = NS - 1ELSE** ==== Undeflatable. Move it up out of the way.* . (DTREXC can not fail in this case.) ====*IFST = NSCALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,$ INFO )ILST = ILST + 1END IFELSE** ==== Complex conjugate pair ====*FOO = ABS( T( NS, NS ) ) + SQRT( ABS( T( NS, NS-1 ) ) )*$ SQRT( ABS( T( NS-1, NS ) ) )IF( FOO.EQ.ZERO )$ FOO = ABS( S )IF( MAX( ABS( S*V( 1, NS ) ), ABS( S*V( 1, NS-1 ) ) ).LE.$ MAX( SMLNUM, ULP*FOO ) ) THEN** ==== Deflatable ====*NS = NS - 2ELSE** ==== Undeflatable. Move them up out of the way.* . Fortunately, DTREXC does the right thing with* . ILST in case of a rare exchange failure. ====*IFST = NSCALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,$ INFO )ILST = ILST + 2END IFEND IF** ==== End deflation detection loop ====*GO TO 20END IF** ==== Return to Hessenberg form ====*IF( NS.EQ.0 )$ S = ZERO*IF( NS.LT.JW ) THEN** ==== sorting diagonal blocks of T improves accuracy for* . graded matrices. Bubble sort deals well with* . exchange failures. ====*SORTED = .false.I = NS + 130 CONTINUEIF( SORTED )$ GO TO 50SORTED = .true.*KEND = I - 1I = INFQR + 1IF( I.EQ.NS ) THENK = I + 1ELSE IF( T( I+1, I ).EQ.ZERO ) THENK = I + 1ELSEK = I + 2END IF40 CONTINUEIF( K.LE.KEND ) THENIF( K.EQ.I+1 ) THENEVI = ABS( T( I, I ) )ELSEEVI = ABS( T( I, I ) ) + SQRT( ABS( T( I+1, I ) ) )*$ SQRT( ABS( T( I, I+1 ) ) )END IF*IF( K.EQ.KEND ) THENEVK = ABS( T( K, K ) )ELSE IF( T( K+1, K ).EQ.ZERO ) THENEVK = ABS( T( K, K ) )ELSEEVK = ABS( T( K, K ) ) + SQRT( ABS( T( K+1, K ) ) )*$ SQRT( ABS( T( K, K+1 ) ) )END IF*IF( EVI.GE.EVK ) THENI = KELSESORTED = .false.IFST = IILST = KCALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,$ INFO )IF( INFO.EQ.0 ) THENI = ILSTELSEI = KEND IFEND IFIF( I.EQ.KEND ) THENK = I + 1ELSE IF( T( I+1, I ).EQ.ZERO ) THENK = I + 1ELSEK = I + 2END IFGO TO 40END IFGO TO 3050 CONTINUEEND IF** ==== Restore shift/eigenvalue array from T ====*I = JW60 CONTINUEIF( I.GE.INFQR+1 ) THENIF( I.EQ.INFQR+1 ) THENSR( KWTOP+I-1 ) = T( I, I )SI( KWTOP+I-1 ) = ZEROI = I - 1ELSE IF( T( I, I-1 ).EQ.ZERO ) THENSR( KWTOP+I-1 ) = T( I, I )SI( KWTOP+I-1 ) = ZEROI = I - 1ELSEAA = T( I-1, I-1 )CC = T( I, I-1 )BB = T( I-1, I )DD = T( I, I )CALL DLANV2( AA, BB, CC, DD, SR( KWTOP+I-2 ),$ SI( KWTOP+I-2 ), SR( KWTOP+I-1 ),$ SI( KWTOP+I-1 ), CS, SN )I = I - 2END IFGO TO 60END IF*IF( NS.LT.JW .OR. S.EQ.ZERO ) THENIF( NS.GT.1 .AND. S.NE.ZERO ) THEN** ==== Reflect spike back into lower triangle ====*CALL DCOPY( NS, V, LDV, WORK, 1 )BETA = WORK( 1 )CALL DLARFG( NS, BETA, WORK( 2 ), 1, TAU )WORK( 1 ) = ONE*CALL DLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )*CALL DLARF( 'L', NS, JW, WORK, 1, TAU, T, LDT,$ WORK( JW+1 ) )CALL DLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,$ WORK( JW+1 ) )CALL DLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,$ WORK( JW+1 ) )*CALL DGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),$ LWORK-JW, INFO )END IF** ==== Copy updated reduced window into place ====*IF( KWTOP.GT.1 )$ H( KWTOP, KWTOP-1 ) = S*V( 1, 1 )CALL DLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )CALL DCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),$ LDH+1 )** ==== Accumulate orthogonal matrix in order update* . H and Z, if requested. ====*IF( NS.GT.1 .AND. S.NE.ZERO )$ CALL DORMHR( 'R', 'N', JW, NS, 1, NS, T, LDT, WORK, V, LDV,$ WORK( JW+1 ), LWORK-JW, INFO )** ==== Update vertical slab in H ====*IF( WANTT ) THENLTOP = 1ELSELTOP = KTOPEND IFDO 70 KROW = LTOP, KWTOP - 1, NVKLN = MIN( NV, KWTOP-KROW )CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),$ LDH, V, LDV, ZERO, WV, LDWV )CALL DLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )70 CONTINUE** ==== Update horizontal slab in H ====*IF( WANTT ) THENDO 80 KCOL = KBOT + 1, N, NHKLN = MIN( NH, N-KCOL+1 )CALL DGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,$ H( KWTOP, KCOL ), LDH, ZERO, T, LDT )CALL DLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),$ LDH )80 CONTINUEEND IF** ==== Update vertical slab in Z ====*IF( WANTZ ) THENDO 90 KROW = ILOZ, IHIZ, NVKLN = MIN( NV, IHIZ-KROW+1 )CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),$ LDZ, V, LDV, ZERO, WV, LDWV )CALL DLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),$ LDZ )90 CONTINUEEND IFEND IF** ==== Return the number of deflations ... ====*ND = JW - NS** ==== ... and the number of shifts. (Subtracting* . INFQR from the spike length takes care* . of the case of a rare QR failure while* . calculating eigenvalues of the deflation* . window.) ====*NS = NS - INFQR** ==== Return optimal workspace. ====*WORK( 1 ) = DBLE( LWKOPT )** ==== End of DLAQR2 ====*END*> \brief \b DLAQR3 performs the orthogonal similarity transformation of a Hessenberg matrix to detect and deflate fully converged eigenvalues from a trailing principal submatrix (aggressive early deflation).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQR3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqr3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqr3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqr3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,* IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,* LDT, NV, WV, LDWV, WORK, LWORK )** .. Scalar Arguments ..* INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,* $ LDZ, LWORK, N, ND, NH, NS, NV, NW* LOGICAL WANTT, WANTZ* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),* $ V( LDV, * ), WORK( * ), WV( LDWV, * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Aggressive early deflation:*>*> DLAQR3 accepts as input an upper Hessenberg matrix*> H and performs an orthogonal similarity transformation*> designed to detect and deflate fully converged eigenvalues from*> a trailing principal submatrix. On output H has been over-*> written by a new Hessenberg matrix that is a perturbation of*> an orthogonal similarity transformation of H. It is to be*> hoped that the final version of H has many zero subdiagonal*> entries.*> \endverbatim** Arguments:* ==========**> \param[in] WANTT*> \verbatim*> WANTT is LOGICAL*> If .TRUE., then the Hessenberg matrix H is fully updated*> so that the quasi-triangular Schur factor may be*> computed (in cooperation with the calling subroutine).*> If .FALSE., then only enough of H is updated to preserve*> the eigenvalues.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> If .TRUE., then the orthogonal matrix Z is updated so*> so that the orthogonal Schur factor may be computed*> (in cooperation with the calling subroutine).*> If .FALSE., then Z is not referenced.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H and (if WANTZ is .TRUE.) the*> order of the orthogonal matrix Z.*> \endverbatim*>*> \param[in] KTOP*> \verbatim*> KTOP is INTEGER*> It is assumed that either KTOP = 1 or H(KTOP,KTOP-1)=0.*> KBOT and KTOP together determine an isolated block*> along the diagonal of the Hessenberg matrix.*> \endverbatim*>*> \param[in] KBOT*> \verbatim*> KBOT is INTEGER*> It is assumed without a check that either*> KBOT = N or H(KBOT+1,KBOT)=0. KBOT and KTOP together*> determine an isolated block along the diagonal of the*> Hessenberg matrix.*> \endverbatim*>*> \param[in] NW*> \verbatim*> NW is INTEGER*> Deflation window size. 1 .LE. NW .LE. (KBOT-KTOP+1).*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On input the initial N-by-N section of H stores the*> Hessenberg matrix undergoing aggressive early deflation.*> On output H has been transformed by an orthogonal*> similarity transformation, perturbed, and the returned*> to Hessenberg form that (it is to be hoped) has some*> zero subdiagonal entries.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> Leading dimension of H just as declared in the calling*> subroutine. N .LE. LDH*> \endverbatim*>*> \param[in] ILOZ*> \verbatim*> ILOZ is INTEGER*> \endverbatim*>*> \param[in] IHIZ*> \verbatim*> IHIZ is INTEGER*> Specify the rows of Z to which transformations must be*> applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> IF WANTZ is .TRUE., then on output, the orthogonal*> similarity transformation mentioned above has been*> accumulated into Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.*> If WANTZ is .FALSE., then Z is unreferenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of Z just as declared in the*> calling subroutine. 1 .LE. LDZ.*> \endverbatim*>*> \param[out] NS*> \verbatim*> NS is INTEGER*> The number of unconverged (ie approximate) eigenvalues*> returned in SR and SI that may be used as shifts by the*> calling subroutine.*> \endverbatim*>*> \param[out] ND*> \verbatim*> ND is INTEGER*> The number of converged eigenvalues uncovered by this*> subroutine.*> \endverbatim*>*> \param[out] SR*> \verbatim*> SR is DOUBLE PRECISION array, dimension (KBOT)*> \endverbatim*>*> \param[out] SI*> \verbatim*> SI is DOUBLE PRECISION array, dimension (KBOT)*> On output, the real and imaginary parts of approximate*> eigenvalues that may be used for shifts are stored in*> SR(KBOT-ND-NS+1) through SR(KBOT-ND) and*> SI(KBOT-ND-NS+1) through SI(KBOT-ND), respectively.*> The real and imaginary parts of converged eigenvalues*> are stored in SR(KBOT-ND+1) through SR(KBOT) and*> SI(KBOT-ND+1) through SI(KBOT), respectively.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,NW)*> An NW-by-NW work array.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of V just as declared in the*> calling subroutine. NW .LE. LDV*> \endverbatim*>*> \param[in] NH*> \verbatim*> NH is INTEGER*> The number of columns of T. NH.GE.NW.*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,NW)*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of T just as declared in the*> calling subroutine. NW .LE. LDT*> \endverbatim*>*> \param[in] NV*> \verbatim*> NV is INTEGER*> The number of rows of work array WV available for*> workspace. NV.GE.NW.*> \endverbatim*>*> \param[out] WV*> \verbatim*> WV is DOUBLE PRECISION array, dimension (LDWV,NW)*> \endverbatim*>*> \param[in] LDWV*> \verbatim*> LDWV is INTEGER*> The leading dimension of W just as declared in the*> calling subroutine. NW .LE. LDV*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, WORK(1) is set to an estimate of the optimal value*> of LWORK for the given values of N, NW, KTOP and KBOT.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the work array WORK. LWORK = 2*NW*> suffices, but greater efficiency may result from larger*> values of LWORK.*>*> If LWORK = -1, then a workspace query is assumed; DLAQR3*> only estimates the optimal workspace size for the given*> values of N, NW, KTOP and KBOT. The estimate is returned*> in WORK(1). No error message related to LWORK is issued*> by XERBLA. Neither H nor Z are accessed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA*>* =====================================================================SUBROUTINE DLAQR3( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,$ IHIZ, Z, LDZ, NS, ND, SR, SI, V, LDV, NH, T,$ LDT, NV, WV, LDWV, WORK, LWORK )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER IHIZ, ILOZ, KBOT, KTOP, LDH, LDT, LDV, LDWV,$ LDZ, LWORK, N, ND, NH, NS, NV, NWLOGICAL WANTT, WANTZ* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), T( LDT, * ),$ V( LDV, * ), WORK( * ), WV( LDWV, * ),$ Z( LDZ, * )* ..** ================================================================* .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, BB, BETA, CC, CS, DD, EVI, EVK, FOO, S,$ SAFMAX, SAFMIN, SMLNUM, SN, TAU, ULPINTEGER I, IFST, ILST, INFO, INFQR, J, JW, K, KCOL,$ KEND, KLN, KROW, KWTOP, LTOP, LWK1, LWK2, LWK3,$ LWKOPT, NMINLOGICAL BULGE, SORTED* ..* .. External Functions ..DOUBLE PRECISION DLAMCHINTEGER ILAENVEXTERNAL DLAMCH, ILAENV* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEHRD, DGEMM, DLABAD, DLACPY, DLAHQR,$ DLANV2, DLAQR4, DLARF, DLARFG, DLASET, DORMHR,$ DTREXC* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, MAX, MIN, SQRT* ..* .. Executable Statements ..** ==== Estimate optimal workspace. ====*JW = MIN( NW, KBOT-KTOP+1 )IF( JW.LE.2 ) THENLWKOPT = 1ELSE** ==== Workspace query call to DGEHRD ====*CALL DGEHRD( JW, 1, JW-1, T, LDT, WORK, WORK, -1, INFO )LWK1 = INT( WORK( 1 ) )** ==== Workspace query call to DORMHR ====*CALL DORMHR( 'R', 'N', JW, JW, 1, JW-1, T, LDT, WORK, V, LDV,$ WORK, -1, INFO )LWK2 = INT( WORK( 1 ) )** ==== Workspace query call to DLAQR4 ====*CALL DLAQR4( .true., .true., JW, 1, JW, T, LDT, SR, SI, 1, JW,$ V, LDV, WORK, -1, INFQR )LWK3 = INT( WORK( 1 ) )** ==== Optimal workspace ====*LWKOPT = MAX( JW+MAX( LWK1, LWK2 ), LWK3 )END IF** ==== Quick return in case of workspace query. ====*IF( LWORK.EQ.-1 ) THENWORK( 1 ) = DBLE( LWKOPT )RETURNEND IF** ==== Nothing to do ...* ... for an empty active block ... ====NS = 0ND = 0WORK( 1 ) = ONEIF( KTOP.GT.KBOT )$ RETURN* ... nor for an empty deflation window. ====IF( NW.LT.1 )$ RETURN** ==== Machine constants ====*SAFMIN = DLAMCH( 'SAFE MINIMUM' )SAFMAX = ONE / SAFMINCALL DLABAD( SAFMIN, SAFMAX )ULP = DLAMCH( 'PRECISION' )SMLNUM = SAFMIN*( DBLE( N ) / ULP )** ==== Setup deflation window ====*JW = MIN( NW, KBOT-KTOP+1 )KWTOP = KBOT - JW + 1IF( KWTOP.EQ.KTOP ) THENS = ZEROELSES = H( KWTOP, KWTOP-1 )END IF*IF( KBOT.EQ.KWTOP ) THEN** ==== 1-by-1 deflation window: not much to do ====*SR( KWTOP ) = H( KWTOP, KWTOP )SI( KWTOP ) = ZERONS = 1ND = 0IF( ABS( S ).LE.MAX( SMLNUM, ULP*ABS( H( KWTOP, KWTOP ) ) ) )$ THENNS = 0ND = 1IF( KWTOP.GT.KTOP )$ H( KWTOP, KWTOP-1 ) = ZEROEND IFWORK( 1 ) = ONERETURNEND IF** ==== Convert to spike-triangular form. (In case of a* . rare QR failure, this routine continues to do* . aggressive early deflation using that part of* . the deflation window that converged using INFQR* . here and there to keep track.) ====*CALL DLACPY( 'U', JW, JW, H( KWTOP, KWTOP ), LDH, T, LDT )CALL DCOPY( JW-1, H( KWTOP+1, KWTOP ), LDH+1, T( 2, 1 ), LDT+1 )*CALL DLASET( 'A', JW, JW, ZERO, ONE, V, LDV )NMIN = ILAENV( 12, 'DLAQR3', 'SV', JW, 1, JW, LWORK )IF( JW.GT.NMIN ) THENCALL DLAQR4( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),$ SI( KWTOP ), 1, JW, V, LDV, WORK, LWORK, INFQR )ELSECALL DLAHQR( .true., .true., JW, 1, JW, T, LDT, SR( KWTOP ),$ SI( KWTOP ), 1, JW, V, LDV, INFQR )END IF** ==== DTREXC needs a clean margin near the diagonal ====*DO 10 J = 1, JW - 3T( J+2, J ) = ZEROT( J+3, J ) = ZERO10 CONTINUEIF( JW.GT.2 )$ T( JW, JW-2 ) = ZERO** ==== Deflation detection loop ====*NS = JWILST = INFQR + 120 CONTINUEIF( ILST.LE.NS ) THENIF( NS.EQ.1 ) THENBULGE = .FALSE.ELSEBULGE = T( NS, NS-1 ).NE.ZEROEND IF** ==== Small spike tip test for deflation ====*IF( .NOT. BULGE ) THEN** ==== Real eigenvalue ====*FOO = ABS( T( NS, NS ) )IF( FOO.EQ.ZERO )$ FOO = ABS( S )IF( ABS( S*V( 1, NS ) ).LE.MAX( SMLNUM, ULP*FOO ) ) THEN** ==== Deflatable ====*NS = NS - 1ELSE** ==== Undeflatable. Move it up out of the way.* . (DTREXC can not fail in this case.) ====*IFST = NSCALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,$ INFO )ILST = ILST + 1END IFELSE** ==== Complex conjugate pair ====*FOO = ABS( T( NS, NS ) ) + SQRT( ABS( T( NS, NS-1 ) ) )*$ SQRT( ABS( T( NS-1, NS ) ) )IF( FOO.EQ.ZERO )$ FOO = ABS( S )IF( MAX( ABS( S*V( 1, NS ) ), ABS( S*V( 1, NS-1 ) ) ).LE.$ MAX( SMLNUM, ULP*FOO ) ) THEN** ==== Deflatable ====*NS = NS - 2ELSE** ==== Undeflatable. Move them up out of the way.* . Fortunately, DTREXC does the right thing with* . ILST in case of a rare exchange failure. ====*IFST = NSCALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,$ INFO )ILST = ILST + 2END IFEND IF** ==== End deflation detection loop ====*GO TO 20END IF** ==== Return to Hessenberg form ====*IF( NS.EQ.0 )$ S = ZERO*IF( NS.LT.JW ) THEN** ==== sorting diagonal blocks of T improves accuracy for* . graded matrices. Bubble sort deals well with* . exchange failures. ====*SORTED = .false.I = NS + 130 CONTINUEIF( SORTED )$ GO TO 50SORTED = .true.*KEND = I - 1I = INFQR + 1IF( I.EQ.NS ) THENK = I + 1ELSE IF( T( I+1, I ).EQ.ZERO ) THENK = I + 1ELSEK = I + 2END IF40 CONTINUEIF( K.LE.KEND ) THENIF( K.EQ.I+1 ) THENEVI = ABS( T( I, I ) )ELSEEVI = ABS( T( I, I ) ) + SQRT( ABS( T( I+1, I ) ) )*$ SQRT( ABS( T( I, I+1 ) ) )END IF*IF( K.EQ.KEND ) THENEVK = ABS( T( K, K ) )ELSE IF( T( K+1, K ).EQ.ZERO ) THENEVK = ABS( T( K, K ) )ELSEEVK = ABS( T( K, K ) ) + SQRT( ABS( T( K+1, K ) ) )*$ SQRT( ABS( T( K, K+1 ) ) )END IF*IF( EVI.GE.EVK ) THENI = KELSESORTED = .false.IFST = IILST = KCALL DTREXC( 'V', JW, T, LDT, V, LDV, IFST, ILST, WORK,$ INFO )IF( INFO.EQ.0 ) THENI = ILSTELSEI = KEND IFEND IFIF( I.EQ.KEND ) THENK = I + 1ELSE IF( T( I+1, I ).EQ.ZERO ) THENK = I + 1ELSEK = I + 2END IFGO TO 40END IFGO TO 3050 CONTINUEEND IF** ==== Restore shift/eigenvalue array from T ====*I = JW60 CONTINUEIF( I.GE.INFQR+1 ) THENIF( I.EQ.INFQR+1 ) THENSR( KWTOP+I-1 ) = T( I, I )SI( KWTOP+I-1 ) = ZEROI = I - 1ELSE IF( T( I, I-1 ).EQ.ZERO ) THENSR( KWTOP+I-1 ) = T( I, I )SI( KWTOP+I-1 ) = ZEROI = I - 1ELSEAA = T( I-1, I-1 )CC = T( I, I-1 )BB = T( I-1, I )DD = T( I, I )CALL DLANV2( AA, BB, CC, DD, SR( KWTOP+I-2 ),$ SI( KWTOP+I-2 ), SR( KWTOP+I-1 ),$ SI( KWTOP+I-1 ), CS, SN )I = I - 2END IFGO TO 60END IF*IF( NS.LT.JW .OR. S.EQ.ZERO ) THENIF( NS.GT.1 .AND. S.NE.ZERO ) THEN** ==== Reflect spike back into lower triangle ====*CALL DCOPY( NS, V, LDV, WORK, 1 )BETA = WORK( 1 )CALL DLARFG( NS, BETA, WORK( 2 ), 1, TAU )WORK( 1 ) = ONE*CALL DLASET( 'L', JW-2, JW-2, ZERO, ZERO, T( 3, 1 ), LDT )*CALL DLARF( 'L', NS, JW, WORK, 1, TAU, T, LDT,$ WORK( JW+1 ) )CALL DLARF( 'R', NS, NS, WORK, 1, TAU, T, LDT,$ WORK( JW+1 ) )CALL DLARF( 'R', JW, NS, WORK, 1, TAU, V, LDV,$ WORK( JW+1 ) )*CALL DGEHRD( JW, 1, NS, T, LDT, WORK, WORK( JW+1 ),$ LWORK-JW, INFO )END IF** ==== Copy updated reduced window into place ====*IF( KWTOP.GT.1 )$ H( KWTOP, KWTOP-1 ) = S*V( 1, 1 )CALL DLACPY( 'U', JW, JW, T, LDT, H( KWTOP, KWTOP ), LDH )CALL DCOPY( JW-1, T( 2, 1 ), LDT+1, H( KWTOP+1, KWTOP ),$ LDH+1 )** ==== Accumulate orthogonal matrix in order update* . H and Z, if requested. ====*IF( NS.GT.1 .AND. S.NE.ZERO )$ CALL DORMHR( 'R', 'N', JW, NS, 1, NS, T, LDT, WORK, V, LDV,$ WORK( JW+1 ), LWORK-JW, INFO )** ==== Update vertical slab in H ====*IF( WANTT ) THENLTOP = 1ELSELTOP = KTOPEND IFDO 70 KROW = LTOP, KWTOP - 1, NVKLN = MIN( NV, KWTOP-KROW )CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, H( KROW, KWTOP ),$ LDH, V, LDV, ZERO, WV, LDWV )CALL DLACPY( 'A', KLN, JW, WV, LDWV, H( KROW, KWTOP ), LDH )70 CONTINUE** ==== Update horizontal slab in H ====*IF( WANTT ) THENDO 80 KCOL = KBOT + 1, N, NHKLN = MIN( NH, N-KCOL+1 )CALL DGEMM( 'C', 'N', JW, KLN, JW, ONE, V, LDV,$ H( KWTOP, KCOL ), LDH, ZERO, T, LDT )CALL DLACPY( 'A', JW, KLN, T, LDT, H( KWTOP, KCOL ),$ LDH )80 CONTINUEEND IF** ==== Update vertical slab in Z ====*IF( WANTZ ) THENDO 90 KROW = ILOZ, IHIZ, NVKLN = MIN( NV, IHIZ-KROW+1 )CALL DGEMM( 'N', 'N', KLN, JW, JW, ONE, Z( KROW, KWTOP ),$ LDZ, V, LDV, ZERO, WV, LDWV )CALL DLACPY( 'A', KLN, JW, WV, LDWV, Z( KROW, KWTOP ),$ LDZ )90 CONTINUEEND IFEND IF** ==== Return the number of deflations ... ====*ND = JW - NS** ==== ... and the number of shifts. (Subtracting* . INFQR from the spike length takes care* . of the case of a rare QR failure while* . calculating eigenvalues of the deflation* . window.) ====*NS = NS - INFQR** ==== Return optimal workspace. ====*WORK( 1 ) = DBLE( LWKOPT )** ==== End of DLAQR3 ====*END*> \brief \b DLAQR4 computes the eigenvalues of a Hessenberg matrix, and optionally the matrices from the Schur decomposition.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQR4 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqr4.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqr4.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqr4.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQR4( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,* ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, N* LOGICAL WANTT, WANTZ* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQR4 implements one level of recursion for DLAQR0.*> It is a complete implementation of the small bulge multi-shift*> QR algorithm. It may be called by DLAQR0 and, for large enough*> deflation window size, it may be called by DLAQR3. This*> subroutine is identical to DLAQR0 except that it calls DLAQR2*> instead of DLAQR3.*>*> DLAQR4 computes the eigenvalues of a Hessenberg matrix H*> and, optionally, the matrices T and Z from the Schur decomposition*> H = Z T Z**T, where T is an upper quasi-triangular matrix (the*> Schur form), and Z is the orthogonal matrix of Schur vectors.*>*> Optionally Z may be postmultiplied into an input orthogonal*> matrix Q so that this routine can give the Schur factorization*> of a matrix A which has been reduced to the Hessenberg form H*> by the orthogonal matrix Q: A = Q*H*Q**T = (QZ)*T*(QZ)**T.*> \endverbatim** Arguments:* ==========**> \param[in] WANTT*> \verbatim*> WANTT is LOGICAL*> = .TRUE. : the full Schur form T is required;*> = .FALSE.: only eigenvalues are required.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> = .TRUE. : the matrix of Schur vectors Z is required;*> = .FALSE.: Schur vectors are not required.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix H. N .GE. 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> It is assumed that H is already upper triangular in rows*> and columns 1:ILO-1 and IHI+1:N and, if ILO.GT.1,*> H(ILO,ILO-1) is zero. ILO and IHI are normally set by a*> previous call to DGEBAL, and then passed to DGEHRD when the*> matrix output by DGEBAL is reduced to Hessenberg form.*> Otherwise, ILO and IHI should be set to 1 and N,*> respectively. If N.GT.0, then 1.LE.ILO.LE.IHI.LE.N.*> If N = 0, then ILO = 1 and IHI = 0.*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On entry, the upper Hessenberg matrix H.*> On exit, if INFO = 0 and WANTT is .TRUE., then H contains*> the upper quasi-triangular matrix T from the Schur*> decomposition (the Schur form); 2-by-2 diagonal blocks*> (corresponding to complex conjugate pairs of eigenvalues)*> are returned in standard form, with H(i,i) = H(i+1,i+1)*> and H(i+1,i)*H(i,i+1).LT.0. If INFO = 0 and WANTT is*> .FALSE., then the contents of H are unspecified on exit.*> (The output value of H when INFO.GT.0 is given under the*> description of INFO below.)*>*> This subroutine may explicitly set H(i,j) = 0 for i.GT.j and*> j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> The leading dimension of the array H. LDH .GE. max(1,N).*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (IHI)*> \endverbatim*>*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (IHI)*> The real and imaginary parts, respectively, of the computed*> eigenvalues of H(ILO:IHI,ILO:IHI) are stored in WR(ILO:IHI)*> and WI(ILO:IHI). If two eigenvalues are computed as a*> complex conjugate pair, they are stored in consecutive*> elements of WR and WI, say the i-th and (i+1)th, with*> WI(i) .GT. 0 and WI(i+1) .LT. 0. If WANTT is .TRUE., then*> the eigenvalues are stored in the same order as on the*> diagonal of the Schur form returned in H, with*> WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal*> block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and*> WI(i+1) = -WI(i).*> \endverbatim*>*> \param[in] ILOZ*> \verbatim*> ILOZ is INTEGER*> \endverbatim*>*> \param[in] IHIZ*> \verbatim*> IHIZ is INTEGER*> Specify the rows of Z to which transformations must be*> applied if WANTZ is .TRUE..*> 1 .LE. ILOZ .LE. ILO; IHI .LE. IHIZ .LE. N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,IHI)*> If WANTZ is .FALSE., then Z is not referenced.*> If WANTZ is .TRUE., then Z(ILO:IHI,ILOZ:IHIZ) is*> replaced by Z(ILO:IHI,ILOZ:IHIZ)*U where U is the*> orthogonal Schur factor of H(ILO:IHI,ILO:IHI).*> (The output value of Z when INFO.GT.0 is given under*> the description of INFO below.)*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. if WANTZ is .TRUE.*> then LDZ.GE.MAX(1,IHIZ). Otherwize, LDZ.GE.1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension LWORK*> On exit, if LWORK = -1, WORK(1) returns an estimate of*> the optimal value for LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK .GE. max(1,N)*> is sufficient, but LWORK typically as large as 6*N may*> be required for optimal performance. A workspace query*> to determine the optimal workspace size is recommended.*>*> If LWORK = -1, then DLAQR4 does a workspace query.*> In this case, DLAQR4 checks the input parameters and*> estimates the optimal workspace size for the given*> values of N, ILO and IHI. The estimate is returned*> in WORK(1). No error message related to LWORK is*> issued by XERBLA. Neither H nor Z are accessed.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> .GT. 0: if INFO = i, DLAQR4 failed to compute all of*> the eigenvalues. Elements 1:ilo-1 and i+1:n of WR*> and WI contain those eigenvalues which have been*> successfully computed. (Failures are rare.)*>*> If INFO .GT. 0 and WANT is .FALSE., then on exit,*> the remaining unconverged eigenvalues are the eigen-*> values of the upper Hessenberg matrix rows and*> columns ILO through INFO of the final, output*> value of H.*>*> If INFO .GT. 0 and WANTT is .TRUE., then on exit*>*> (*) (initial value of H)*U = U*(final value of H)*>*> where U is a orthogonal matrix. The final*> value of H is upper Hessenberg and triangular in*> rows and columns INFO+1 through IHI.*>*> If INFO .GT. 0 and WANTZ is .TRUE., then on exit*>*> (final value of Z(ILO:IHI,ILOZ:IHIZ)*> = (initial value of Z(ILO:IHI,ILOZ:IHIZ)*U*>*> where U is the orthogonal matrix in (*) (regard-*> less of the value of WANTT.)*>*> If INFO .GT. 0 and WANTZ is .FALSE., then Z is not*> accessed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA**> \par References:* ================*>*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part I: Maintaining Well Focused Shifts, and Level 3*> Performance, SIAM Journal of Matrix Analysis, volume 23, pages*> 929--947, 2002.*> \n*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part II: Aggressive Early Deflation, SIAM Journal*> of Matrix Analysis, volume 23, pages 948--973, 2002.*>* =====================================================================SUBROUTINE DLAQR4( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,$ ILOZ, IHIZ, Z, LDZ, WORK, LWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, IHIZ, ILO, ILOZ, INFO, LDH, LDZ, LWORK, NLOGICAL WANTT, WANTZ* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), WI( * ), WORK( * ), WR( * ),$ Z( LDZ, * )* ..** ================================================================* .. Parameters ..** ==== Matrices of order NTINY or smaller must be processed by* . DLAHQR because of insufficient subdiagonal scratch space.* . (This is a hard limit.) ====INTEGER NTINYPARAMETER ( NTINY = 11 )** ==== Exceptional deflation windows: try to cure rare* . slow convergence by varying the size of the* . deflation window after KEXNW iterations. ====INTEGER KEXNWPARAMETER ( KEXNW = 5 )** ==== Exceptional shifts: try to cure rare slow convergence* . with ad-hoc exceptional shifts every KEXSH iterations.* . ====INTEGER KEXSHPARAMETER ( KEXSH = 6 )** ==== The constants WILK1 and WILK2 are used to form the* . exceptional shifts. ====DOUBLE PRECISION WILK1, WILK2PARAMETER ( WILK1 = 0.75d0, WILK2 = -0.4375d0 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 )* ..* .. Local Scalars ..DOUBLE PRECISION AA, BB, CC, CS, DD, SN, SS, SWAPINTEGER I, INF, IT, ITMAX, K, KACC22, KBOT, KDU, KS,$ KT, KTOP, KU, KV, KWH, KWTOP, KWV, LD, LS,$ LWKOPT, NDEC, NDFL, NH, NHO, NIBBLE, NMIN, NS,$ NSMAX, NSR, NVE, NW, NWMAX, NWR, NWUPBDLOGICAL SORTEDCHARACTER JBCMPZ*2* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Local Arrays ..DOUBLE PRECISION ZDUM( 1, 1 )* ..* .. External Subroutines ..EXTERNAL DLACPY, DLAHQR, DLANV2, DLAQR2, DLAQR5* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, MAX, MIN, MOD* ..* .. Executable Statements ..INFO = 0** ==== Quick return for N = 0: nothing to do. ====*IF( N.EQ.0 ) THENWORK( 1 ) = ONERETURNEND IF*IF( N.LE.NTINY ) THEN** ==== Tiny matrices must use DLAHQR. ====*LWKOPT = 1IF( LWORK.NE.-1 )$ CALL DLAHQR( WANTT, WANTZ, N, ILO, IHI, H, LDH, WR, WI,$ ILOZ, IHIZ, Z, LDZ, INFO )ELSE** ==== Use small bulge multi-shift QR with aggressive early* . deflation on larger-than-tiny matrices. ====** ==== Hope for the best. ====*INFO = 0** ==== Set up job flags for ILAENV. ====*IF( WANTT ) THENJBCMPZ( 1: 1 ) = 'S'ELSEJBCMPZ( 1: 1 ) = 'E'END IFIF( WANTZ ) THENJBCMPZ( 2: 2 ) = 'V'ELSEJBCMPZ( 2: 2 ) = 'N'END IF** ==== NWR = recommended deflation window size. At this* . point, N .GT. NTINY = 11, so there is enough* . subdiagonal workspace for NWR.GE.2 as required.* . (In fact, there is enough subdiagonal space for* . NWR.GE.3.) ====*NWR = ILAENV( 13, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )NWR = MAX( 2, NWR )NWR = MIN( IHI-ILO+1, ( N-1 ) / 3, NWR )** ==== NSR = recommended number of simultaneous shifts.* . At this point N .GT. NTINY = 11, so there is at* . enough subdiagonal workspace for NSR to be even* . and greater than or equal to two as required. ====*NSR = ILAENV( 15, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )NSR = MIN( NSR, ( N+6 ) / 9, IHI-ILO )NSR = MAX( 2, NSR-MOD( NSR, 2 ) )** ==== Estimate optimal workspace ====** ==== Workspace query call to DLAQR2 ====*CALL DLAQR2( WANTT, WANTZ, N, ILO, IHI, NWR+1, H, LDH, ILOZ,$ IHIZ, Z, LDZ, LS, LD, WR, WI, H, LDH, N, H, LDH,$ N, H, LDH, WORK, -1 )** ==== Optimal workspace = MAX(DLAQR5, DLAQR2) ====*LWKOPT = MAX( 3*NSR / 2, INT( WORK( 1 ) ) )** ==== Quick return in case of workspace query. ====*IF( LWORK.EQ.-1 ) THENWORK( 1 ) = DBLE( LWKOPT )RETURNEND IF** ==== DLAHQR/DLAQR0 crossover point ====*NMIN = ILAENV( 12, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )NMIN = MAX( NTINY, NMIN )** ==== Nibble crossover point ====*NIBBLE = ILAENV( 14, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )NIBBLE = MAX( 0, NIBBLE )** ==== Accumulate reflections during ttswp? Use block* . 2-by-2 structure during matrix-matrix multiply? ====*KACC22 = ILAENV( 16, 'DLAQR4', JBCMPZ, N, ILO, IHI, LWORK )KACC22 = MAX( 0, KACC22 )KACC22 = MIN( 2, KACC22 )** ==== NWMAX = the largest possible deflation window for* . which there is sufficient workspace. ====*NWMAX = MIN( ( N-1 ) / 3, LWORK / 2 )NW = NWMAX** ==== NSMAX = the Largest number of simultaneous shifts* . for which there is sufficient workspace. ====*NSMAX = MIN( ( N+6 ) / 9, 2*LWORK / 3 )NSMAX = NSMAX - MOD( NSMAX, 2 )** ==== NDFL: an iteration count restarted at deflation. ====*NDFL = 1** ==== ITMAX = iteration limit ====*ITMAX = MAX( 30, 2*KEXSH )*MAX( 10, ( IHI-ILO+1 ) )** ==== Last row and column in the active block ====*KBOT = IHI** ==== Main Loop ====*DO 80 IT = 1, ITMAX** ==== Done when KBOT falls below ILO ====*IF( KBOT.LT.ILO )$ GO TO 90** ==== Locate active block ====*DO 10 K = KBOT, ILO + 1, -1IF( H( K, K-1 ).EQ.ZERO )$ GO TO 2010 CONTINUEK = ILO20 CONTINUEKTOP = K** ==== Select deflation window size:* . Typical Case:* . If possible and advisable, nibble the entire* . active block. If not, use size MIN(NWR,NWMAX)* . or MIN(NWR+1,NWMAX) depending upon which has* . the smaller corresponding subdiagonal entry* . (a heuristic).* .* . Exceptional Case:* . If there have been no deflations in KEXNW or* . more iterations, then vary the deflation window* . size. At first, because, larger windows are,* . in general, more powerful than smaller ones,* . rapidly increase the window to the maximum possible.* . Then, gradually reduce the window size. ====*NH = KBOT - KTOP + 1NWUPBD = MIN( NH, NWMAX )IF( NDFL.LT.KEXNW ) THENNW = MIN( NWUPBD, NWR )ELSENW = MIN( NWUPBD, 2*NW )END IFIF( NW.LT.NWMAX ) THENIF( NW.GE.NH-1 ) THENNW = NHELSEKWTOP = KBOT - NW + 1IF( ABS( H( KWTOP, KWTOP-1 ) ).GT.$ ABS( H( KWTOP-1, KWTOP-2 ) ) )NW = NW + 1END IFEND IFIF( NDFL.LT.KEXNW ) THENNDEC = -1ELSE IF( NDEC.GE.0 .OR. NW.GE.NWUPBD ) THENNDEC = NDEC + 1IF( NW-NDEC.LT.2 )$ NDEC = 0NW = NW - NDECEND IF** ==== Aggressive early deflation:* . split workspace under the subdiagonal into* . - an nw-by-nw work array V in the lower* . left-hand-corner,* . - an NW-by-at-least-NW-but-more-is-better* . (NW-by-NHO) horizontal work array along* . the bottom edge,* . - an at-least-NW-but-more-is-better (NHV-by-NW)* . vertical work array along the left-hand-edge.* . ====*KV = N - NW + 1KT = NW + 1NHO = ( N-NW-1 ) - KT + 1KWV = NW + 2NVE = ( N-NW ) - KWV + 1** ==== Aggressive early deflation ====*CALL DLAQR2( WANTT, WANTZ, N, KTOP, KBOT, NW, H, LDH, ILOZ,$ IHIZ, Z, LDZ, LS, LD, WR, WI, H( KV, 1 ), LDH,$ NHO, H( KV, KT ), LDH, NVE, H( KWV, 1 ), LDH,$ WORK, LWORK )** ==== Adjust KBOT accounting for new deflations. ====*KBOT = KBOT - LD** ==== KS points to the shifts. ====*KS = KBOT - LS + 1** ==== Skip an expensive QR sweep if there is a (partly* . heuristic) reason to expect that many eigenvalues* . will deflate without it. Here, the QR sweep is* . skipped if many eigenvalues have just been deflated* . or if the remaining active block is small.*IF( ( LD.EQ.0 ) .OR. ( ( 100*LD.LE.NW*NIBBLE ) .AND. ( KBOT-$ KTOP+1.GT.MIN( NMIN, NWMAX ) ) ) ) THEN** ==== NS = nominal number of simultaneous shifts.* . This may be lowered (slightly) if DLAQR2* . did not provide that many shifts. ====*NS = MIN( NSMAX, NSR, MAX( 2, KBOT-KTOP ) )NS = NS - MOD( NS, 2 )** ==== If there have been no deflations* . in a multiple of KEXSH iterations,* . then try exceptional shifts.* . Otherwise use shifts provided by* . DLAQR2 above or from the eigenvalues* . of a trailing principal submatrix. ====*IF( MOD( NDFL, KEXSH ).EQ.0 ) THENKS = KBOT - NS + 1DO 30 I = KBOT, MAX( KS+1, KTOP+2 ), -2SS = ABS( H( I, I-1 ) ) + ABS( H( I-1, I-2 ) )AA = WILK1*SS + H( I, I )BB = SSCC = WILK2*SSDD = AACALL DLANV2( AA, BB, CC, DD, WR( I-1 ), WI( I-1 ),$ WR( I ), WI( I ), CS, SN )30 CONTINUEIF( KS.EQ.KTOP ) THENWR( KS+1 ) = H( KS+1, KS+1 )WI( KS+1 ) = ZEROWR( KS ) = WR( KS+1 )WI( KS ) = WI( KS+1 )END IFELSE** ==== Got NS/2 or fewer shifts? Use DLAHQR* . on a trailing principal submatrix to* . get more. (Since NS.LE.NSMAX.LE.(N+6)/9,* . there is enough space below the subdiagonal* . to fit an NS-by-NS scratch array.) ====*IF( KBOT-KS+1.LE.NS / 2 ) THENKS = KBOT - NS + 1KT = N - NS + 1CALL DLACPY( 'A', NS, NS, H( KS, KS ), LDH,$ H( KT, 1 ), LDH )CALL DLAHQR( .false., .false., NS, 1, NS,$ H( KT, 1 ), LDH, WR( KS ), WI( KS ),$ 1, 1, ZDUM, 1, INF )KS = KS + INF** ==== In case of a rare QR failure use* . eigenvalues of the trailing 2-by-2* . principal submatrix. ====*IF( KS.GE.KBOT ) THENAA = H( KBOT-1, KBOT-1 )CC = H( KBOT, KBOT-1 )BB = H( KBOT-1, KBOT )DD = H( KBOT, KBOT )CALL DLANV2( AA, BB, CC, DD, WR( KBOT-1 ),$ WI( KBOT-1 ), WR( KBOT ),$ WI( KBOT ), CS, SN )KS = KBOT - 1END IFEND IF*IF( KBOT-KS+1.GT.NS ) THEN** ==== Sort the shifts (Helps a little)* . Bubble sort keeps complex conjugate* . pairs together. ====*SORTED = .false.DO 50 K = KBOT, KS + 1, -1IF( SORTED )$ GO TO 60SORTED = .true.DO 40 I = KS, K - 1IF( ABS( WR( I ) )+ABS( WI( I ) ).LT.$ ABS( WR( I+1 ) )+ABS( WI( I+1 ) ) ) THENSORTED = .false.*SWAP = WR( I )WR( I ) = WR( I+1 )WR( I+1 ) = SWAP*SWAP = WI( I )WI( I ) = WI( I+1 )WI( I+1 ) = SWAPEND IF40 CONTINUE50 CONTINUE60 CONTINUEEND IF** ==== Shuffle shifts into pairs of real shifts* . and pairs of complex conjugate shifts* . assuming complex conjugate shifts are* . already adjacent to one another. (Yes,* . they are.) ====*DO 70 I = KBOT, KS + 2, -2IF( WI( I ).NE.-WI( I-1 ) ) THEN*SWAP = WR( I )WR( I ) = WR( I-1 )WR( I-1 ) = WR( I-2 )WR( I-2 ) = SWAP*SWAP = WI( I )WI( I ) = WI( I-1 )WI( I-1 ) = WI( I-2 )WI( I-2 ) = SWAPEND IF70 CONTINUEEND IF** ==== If there are only two shifts and both are* . real, then use only one. ====*IF( KBOT-KS+1.EQ.2 ) THENIF( WI( KBOT ).EQ.ZERO ) THENIF( ABS( WR( KBOT )-H( KBOT, KBOT ) ).LT.$ ABS( WR( KBOT-1 )-H( KBOT, KBOT ) ) ) THENWR( KBOT-1 ) = WR( KBOT )ELSEWR( KBOT ) = WR( KBOT-1 )END IFEND IFEND IF** ==== Use up to NS of the the smallest magnatiude* . shifts. If there aren't NS shifts available,* . then use them all, possibly dropping one to* . make the number of shifts even. ====*NS = MIN( NS, KBOT-KS+1 )NS = NS - MOD( NS, 2 )KS = KBOT - NS + 1** ==== Small-bulge multi-shift QR sweep:* . split workspace under the subdiagonal into* . - a KDU-by-KDU work array U in the lower* . left-hand-corner,* . - a KDU-by-at-least-KDU-but-more-is-better* . (KDU-by-NHo) horizontal work array WH along* . the bottom edge,* . - and an at-least-KDU-but-more-is-better-by-KDU* . (NVE-by-KDU) vertical work WV arrow along* . the left-hand-edge. ====*KDU = 3*NS - 3KU = N - KDU + 1KWH = KDU + 1NHO = ( N-KDU+1-4 ) - ( KDU+1 ) + 1KWV = KDU + 4NVE = N - KDU - KWV + 1** ==== Small-bulge multi-shift QR sweep ====*CALL DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NS,$ WR( KS ), WI( KS ), H, LDH, ILOZ, IHIZ, Z,$ LDZ, WORK, 3, H( KU, 1 ), LDH, NVE,$ H( KWV, 1 ), LDH, NHO, H( KU, KWH ), LDH )END IF** ==== Note progress (or the lack of it). ====*IF( LD.GT.0 ) THENNDFL = 1ELSENDFL = NDFL + 1END IF** ==== End of main loop ====80 CONTINUE** ==== Iteration limit exceeded. Set INFO to show where* . the problem occurred and exit. ====*INFO = KBOT90 CONTINUEEND IF** ==== Return the optimal value of LWORK. ====*WORK( 1 ) = DBLE( LWKOPT )** ==== End of DLAQR4 ====*END*> \brief \b DLAQR5 performs a single small-bulge multi-shift QR sweep.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQR5 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqr5.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqr5.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqr5.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS,* SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,* LDU, NV, WV, LDWV, NH, WH, LDWH )** .. Scalar Arguments ..* INTEGER IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,* $ LDWH, LDWV, LDZ, N, NH, NSHFTS, NV* LOGICAL WANTT, WANTZ* ..* .. Array Arguments ..* DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), U( LDU, * ),* $ V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQR5, called by DLAQR0, performs a*> single small-bulge multi-shift QR sweep.*> \endverbatim** Arguments:* ==========**> \param[in] WANTT*> \verbatim*> WANTT is LOGICAL*> WANTT = .true. if the quasi-triangular Schur factor*> is being computed. WANTT is set to .false. otherwise.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> WANTZ = .true. if the orthogonal Schur factor is being*> computed. WANTZ is set to .false. otherwise.*> \endverbatim*>*> \param[in] KACC22*> \verbatim*> KACC22 is INTEGER with value 0, 1, or 2.*> Specifies the computation mode of far-from-diagonal*> orthogonal updates.*> = 0: DLAQR5 does not accumulate reflections and does not*> use matrix-matrix multiply to update far-from-diagonal*> matrix entries.*> = 1: DLAQR5 accumulates reflections and uses matrix-matrix*> multiply to update the far-from-diagonal matrix entries.*> = 2: DLAQR5 accumulates reflections, uses matrix-matrix*> multiply to update the far-from-diagonal matrix entries,*> and takes advantage of 2-by-2 block structure during*> matrix multiplies.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> N is the order of the Hessenberg matrix H upon which this*> subroutine operates.*> \endverbatim*>*> \param[in] KTOP*> \verbatim*> KTOP is INTEGER*> \endverbatim*>*> \param[in] KBOT*> \verbatim*> KBOT is INTEGER*> These are the first and last rows and columns of an*> isolated diagonal block upon which the QR sweep is to be*> applied. It is assumed without a check that*> either KTOP = 1 or H(KTOP,KTOP-1) = 0*> and*> either KBOT = N or H(KBOT+1,KBOT) = 0.*> \endverbatim*>*> \param[in] NSHFTS*> \verbatim*> NSHFTS is INTEGER*> NSHFTS gives the number of simultaneous shifts. NSHFTS*> must be positive and even.*> \endverbatim*>*> \param[in,out] SR*> \verbatim*> SR is DOUBLE PRECISION array, dimension (NSHFTS)*> \endverbatim*>*> \param[in,out] SI*> \verbatim*> SI is DOUBLE PRECISION array, dimension (NSHFTS)*> SR contains the real parts and SI contains the imaginary*> parts of the NSHFTS shifts of origin that define the*> multi-shift QR sweep. On output SR and SI may be*> reordered.*> \endverbatim*>*> \param[in,out] H*> \verbatim*> H is DOUBLE PRECISION array, dimension (LDH,N)*> On input H contains a Hessenberg matrix. On output a*> multi-shift QR sweep with shifts SR(J)+i*SI(J) is applied*> to the isolated diagonal block in rows and columns KTOP*> through KBOT.*> \endverbatim*>*> \param[in] LDH*> \verbatim*> LDH is INTEGER*> LDH is the leading dimension of H just as declared in the*> calling procedure. LDH.GE.MAX(1,N).*> \endverbatim*>*> \param[in] ILOZ*> \verbatim*> ILOZ is INTEGER*> \endverbatim*>*> \param[in] IHIZ*> \verbatim*> IHIZ is INTEGER*> Specify the rows of Z to which transformations must be*> applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,IHIZ)*> If WANTZ = .TRUE., then the QR Sweep orthogonal*> similarity transformation is accumulated into*> Z(ILOZ:IHIZ,ILOZ:IHIZ) from the right.*> If WANTZ = .FALSE., then Z is unreferenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> LDA is the leading dimension of Z just as declared in*> the calling procedure. LDZ.GE.N.*> \endverbatim*>*> \param[out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,NSHFTS/2)*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> LDV is the leading dimension of V as declared in the*> calling procedure. LDV.GE.3.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,3*NSHFTS-3)*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> LDU is the leading dimension of U just as declared in the*> in the calling subroutine. LDU.GE.3*NSHFTS-3.*> \endverbatim*>*> \param[in] NH*> \verbatim*> NH is INTEGER*> NH is the number of columns in array WH available for*> workspace. NH.GE.1.*> \endverbatim*>*> \param[out] WH*> \verbatim*> WH is DOUBLE PRECISION array, dimension (LDWH,NH)*> \endverbatim*>*> \param[in] LDWH*> \verbatim*> LDWH is INTEGER*> Leading dimension of WH just as declared in the*> calling procedure. LDWH.GE.3*NSHFTS-3.*> \endverbatim*>*> \param[in] NV*> \verbatim*> NV is INTEGER*> NV is the number of rows in WV agailable for workspace.*> NV.GE.1.*> \endverbatim*>*> \param[out] WV*> \verbatim*> WV is DOUBLE PRECISION array, dimension (LDWV,3*NSHFTS-3)*> \endverbatim*>*> \param[in] LDWV*> \verbatim*> LDWV is INTEGER*> LDWV is the leading dimension of WV as declared in the*> in the calling subroutine. LDWV.GE.NV.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Karen Braman and Ralph Byers, Department of Mathematics,*> University of Kansas, USA**> \par References:* ================*>*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR*> Algorithm Part I: Maintaining Well Focused Shifts, and Level 3*> Performance, SIAM Journal of Matrix Analysis, volume 23, pages*> 929--947, 2002.*>* =====================================================================SUBROUTINE DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS,$ SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U,$ LDU, NV, WV, LDWV, NH, WH, LDWH )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV,$ LDWH, LDWV, LDZ, N, NH, NSHFTS, NVLOGICAL WANTT, WANTZ* ..* .. Array Arguments ..DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), U( LDU, * ),$ V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ),$ Z( LDZ, * )* ..** ================================================================* .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 )* ..* .. Local Scalars ..DOUBLE PRECISION ALPHA, BETA, H11, H12, H21, H22, REFSUM,$ SAFMAX, SAFMIN, SCL, SMLNUM, SWAP, TST1, TST2,$ ULPINTEGER I, I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN,$ JROW, JTOP, K, K1, KDU, KMS, KNZ, KRCOL, KZS,$ M, M22, MBOT, MEND, MSTART, MTOP, NBMPS, NDCOL,$ NS, NULOGICAL ACCUM, BLK22, BMP22* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..*INTRINSIC ABS, DBLE, MAX, MIN, MOD* ..* .. Local Arrays ..DOUBLE PRECISION VT( 3 )* ..* .. External Subroutines ..EXTERNAL DGEMM, DLABAD, DLACPY, DLAQR1, DLARFG, DLASET,$ DTRMM* ..* .. Executable Statements ..** ==== If there are no shifts, then there is nothing to do. ====*IF( NSHFTS.LT.2 )$ RETURN** ==== If the active block is empty or 1-by-1, then there* . is nothing to do. ====*IF( KTOP.GE.KBOT )$ RETURN** ==== Shuffle shifts into pairs of real shifts and pairs* . of complex conjugate shifts assuming complex* . conjugate shifts are already adjacent to one* . another. ====*DO 10 I = 1, NSHFTS - 2, 2IF( SI( I ).NE.-SI( I+1 ) ) THEN*SWAP = SR( I )SR( I ) = SR( I+1 )SR( I+1 ) = SR( I+2 )SR( I+2 ) = SWAP*SWAP = SI( I )SI( I ) = SI( I+1 )SI( I+1 ) = SI( I+2 )SI( I+2 ) = SWAPEND IF10 CONTINUE** ==== NSHFTS is supposed to be even, but if it is odd,* . then simply reduce it by one. The shuffle above* . ensures that the dropped shift is real and that* . the remaining shifts are paired. ====*NS = NSHFTS - MOD( NSHFTS, 2 )** ==== Machine constants for deflation ====*SAFMIN = DLAMCH( 'SAFE MINIMUM' )SAFMAX = ONE / SAFMINCALL DLABAD( SAFMIN, SAFMAX )ULP = DLAMCH( 'PRECISION' )SMLNUM = SAFMIN*( DBLE( N ) / ULP )** ==== Use accumulated reflections to update far-from-diagonal* . entries ? ====*ACCUM = ( KACC22.EQ.1 ) .OR. ( KACC22.EQ.2 )** ==== If so, exploit the 2-by-2 block structure? ====*BLK22 = ( NS.GT.2 ) .AND. ( KACC22.EQ.2 )** ==== clear trash ====*IF( KTOP+2.LE.KBOT )$ H( KTOP+2, KTOP ) = ZERO** ==== NBMPS = number of 2-shift bulges in the chain ====*NBMPS = NS / 2** ==== KDU = width of slab ====*KDU = 6*NBMPS - 3** ==== Create and chase chains of NBMPS bulges ====*DO 220 INCOL = 3*( 1-NBMPS ) + KTOP - 1, KBOT - 2, 3*NBMPS - 2NDCOL = INCOL + KDUIF( ACCUM )$ CALL DLASET( 'ALL', KDU, KDU, ZERO, ONE, U, LDU )** ==== Near-the-diagonal bulge chase. The following loop* . performs the near-the-diagonal part of a small bulge* . multi-shift QR sweep. Each 6*NBMPS-2 column diagonal* . chunk extends from column INCOL to column NDCOL* . (including both column INCOL and column NDCOL). The* . following loop chases a 3*NBMPS column long chain of* . NBMPS bulges 3*NBMPS-2 columns to the right. (INCOL* . may be less than KTOP and and NDCOL may be greater than* . KBOT indicating phantom columns from which to chase* . bulges before they are actually introduced or to which* . to chase bulges beyond column KBOT.) ====*DO 150 KRCOL = INCOL, MIN( INCOL+3*NBMPS-3, KBOT-2 )** ==== Bulges number MTOP to MBOT are active double implicit* . shift bulges. There may or may not also be small* . 2-by-2 bulge, if there is room. The inactive bulges* . (if any) must wait until the active bulges have moved* . down the diagonal to make room. The phantom matrix* . paradigm described above helps keep track. ====*MTOP = MAX( 1, ( ( KTOP-1 )-KRCOL+2 ) / 3+1 )MBOT = MIN( NBMPS, ( KBOT-KRCOL ) / 3 )M22 = MBOT + 1BMP22 = ( MBOT.LT.NBMPS ) .AND. ( KRCOL+3*( M22-1 ) ).EQ.$ ( KBOT-2 )** ==== Generate reflections to chase the chain right* . one column. (The minimum value of K is KTOP-1.) ====*DO 20 M = MTOP, MBOTK = KRCOL + 3*( M-1 )IF( K.EQ.KTOP-1 ) THENCALL DLAQR1( 3, H( KTOP, KTOP ), LDH, SR( 2*M-1 ),$ SI( 2*M-1 ), SR( 2*M ), SI( 2*M ),$ V( 1, M ) )ALPHA = V( 1, M )CALL DLARFG( 3, ALPHA, V( 2, M ), 1, V( 1, M ) )ELSEBETA = H( K+1, K )V( 2, M ) = H( K+2, K )V( 3, M ) = H( K+3, K )CALL DLARFG( 3, BETA, V( 2, M ), 1, V( 1, M ) )** ==== A Bulge may collapse because of vigilant* . deflation or destructive underflow. In the* . underflow case, try the two-small-subdiagonals* . trick to try to reinflate the bulge. ====*IF( H( K+3, K ).NE.ZERO .OR. H( K+3, K+1 ).NE.$ ZERO .OR. H( K+3, K+2 ).EQ.ZERO ) THEN** ==== Typical case: not collapsed (yet). ====*H( K+1, K ) = BETAH( K+2, K ) = ZEROH( K+3, K ) = ZEROELSE** ==== Atypical case: collapsed. Attempt to* . reintroduce ignoring H(K+1,K) and H(K+2,K).* . If the fill resulting from the new* . reflector is too large, then abandon it.* . Otherwise, use the new one. ====*CALL DLAQR1( 3, H( K+1, K+1 ), LDH, SR( 2*M-1 ),$ SI( 2*M-1 ), SR( 2*M ), SI( 2*M ),$ VT )ALPHA = VT( 1 )CALL DLARFG( 3, ALPHA, VT( 2 ), 1, VT( 1 ) )REFSUM = VT( 1 )*( H( K+1, K )+VT( 2 )*$ H( K+2, K ) )*IF( ABS( H( K+2, K )-REFSUM*VT( 2 ) )+$ ABS( REFSUM*VT( 3 ) ).GT.ULP*$ ( ABS( H( K, K ) )+ABS( H( K+1,$ K+1 ) )+ABS( H( K+2, K+2 ) ) ) ) THEN** ==== Starting a new bulge here would* . create non-negligible fill. Use* . the old one with trepidation. ====*H( K+1, K ) = BETAH( K+2, K ) = ZEROH( K+3, K ) = ZEROELSE** ==== Stating a new bulge here would* . create only negligible fill.* . Replace the old reflector with* . the new one. ====*H( K+1, K ) = H( K+1, K ) - REFSUMH( K+2, K ) = ZEROH( K+3, K ) = ZEROV( 1, M ) = VT( 1 )V( 2, M ) = VT( 2 )V( 3, M ) = VT( 3 )END IFEND IFEND IF20 CONTINUE** ==== Generate a 2-by-2 reflection, if needed. ====*K = KRCOL + 3*( M22-1 )IF( BMP22 ) THENIF( K.EQ.KTOP-1 ) THENCALL DLAQR1( 2, H( K+1, K+1 ), LDH, SR( 2*M22-1 ),$ SI( 2*M22-1 ), SR( 2*M22 ), SI( 2*M22 ),$ V( 1, M22 ) )BETA = V( 1, M22 )CALL DLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )ELSEBETA = H( K+1, K )V( 2, M22 ) = H( K+2, K )CALL DLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) )H( K+1, K ) = BETAH( K+2, K ) = ZEROEND IFEND IF** ==== Multiply H by reflections from the left ====*IF( ACCUM ) THENJBOT = MIN( NDCOL, KBOT )ELSE IF( WANTT ) THENJBOT = NELSEJBOT = KBOTEND IFDO 40 J = MAX( KTOP, KRCOL ), JBOTMEND = MIN( MBOT, ( J-KRCOL+2 ) / 3 )DO 30 M = MTOP, MENDK = KRCOL + 3*( M-1 )REFSUM = V( 1, M )*( H( K+1, J )+V( 2, M )*$ H( K+2, J )+V( 3, M )*H( K+3, J ) )H( K+1, J ) = H( K+1, J ) - REFSUMH( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M )H( K+3, J ) = H( K+3, J ) - REFSUM*V( 3, M )30 CONTINUE40 CONTINUEIF( BMP22 ) THENK = KRCOL + 3*( M22-1 )DO 50 J = MAX( K+1, KTOP ), JBOTREFSUM = V( 1, M22 )*( H( K+1, J )+V( 2, M22 )*$ H( K+2, J ) )H( K+1, J ) = H( K+1, J ) - REFSUMH( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M22 )50 CONTINUEEND IF** ==== Multiply H by reflections from the right.* . Delay filling in the last row until the* . vigilant deflation check is complete. ====*IF( ACCUM ) THENJTOP = MAX( KTOP, INCOL )ELSE IF( WANTT ) THENJTOP = 1ELSEJTOP = KTOPEND IFDO 90 M = MTOP, MBOTIF( V( 1, M ).NE.ZERO ) THENK = KRCOL + 3*( M-1 )DO 60 J = JTOP, MIN( KBOT, K+3 )REFSUM = V( 1, M )*( H( J, K+1 )+V( 2, M )*$ H( J, K+2 )+V( 3, M )*H( J, K+3 ) )H( J, K+1 ) = H( J, K+1 ) - REFSUMH( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M )H( J, K+3 ) = H( J, K+3 ) - REFSUM*V( 3, M )60 CONTINUE*IF( ACCUM ) THEN** ==== Accumulate U. (If necessary, update Z later* . with with an efficient matrix-matrix* . multiply.) ====*KMS = K - INCOLDO 70 J = MAX( 1, KTOP-INCOL ), KDUREFSUM = V( 1, M )*( U( J, KMS+1 )+V( 2, M )*$ U( J, KMS+2 )+V( 3, M )*U( J, KMS+3 ) )U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUMU( J, KMS+2 ) = U( J, KMS+2 ) - REFSUM*V( 2, M )U( J, KMS+3 ) = U( J, KMS+3 ) - REFSUM*V( 3, M )70 CONTINUEELSE IF( WANTZ ) THEN** ==== U is not accumulated, so update Z* . now by multiplying by reflections* . from the right. ====*DO 80 J = ILOZ, IHIZREFSUM = V( 1, M )*( Z( J, K+1 )+V( 2, M )*$ Z( J, K+2 )+V( 3, M )*Z( J, K+3 ) )Z( J, K+1 ) = Z( J, K+1 ) - REFSUMZ( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M )Z( J, K+3 ) = Z( J, K+3 ) - REFSUM*V( 3, M )80 CONTINUEEND IFEND IF90 CONTINUE** ==== Special case: 2-by-2 reflection (if needed) ====*K = KRCOL + 3*( M22-1 )IF( BMP22 ) THENIF ( V( 1, M22 ).NE.ZERO ) THENDO 100 J = JTOP, MIN( KBOT, K+3 )REFSUM = V( 1, M22 )*( H( J, K+1 )+V( 2, M22 )*$ H( J, K+2 ) )H( J, K+1 ) = H( J, K+1 ) - REFSUMH( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M22 )100 CONTINUE*IF( ACCUM ) THENKMS = K - INCOLDO 110 J = MAX( 1, KTOP-INCOL ), KDUREFSUM = V( 1, M22 )*( U( J, KMS+1 )+$ V( 2, M22 )*U( J, KMS+2 ) )U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUMU( J, KMS+2 ) = U( J, KMS+2 ) -$ REFSUM*V( 2, M22 )110 CONTINUEELSE IF( WANTZ ) THENDO 120 J = ILOZ, IHIZREFSUM = V( 1, M22 )*( Z( J, K+1 )+V( 2, M22 )*$ Z( J, K+2 ) )Z( J, K+1 ) = Z( J, K+1 ) - REFSUMZ( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M22 )120 CONTINUEEND IFEND IFEND IF** ==== Vigilant deflation check ====*MSTART = MTOPIF( KRCOL+3*( MSTART-1 ).LT.KTOP )$ MSTART = MSTART + 1MEND = MBOTIF( BMP22 )$ MEND = MEND + 1IF( KRCOL.EQ.KBOT-2 )$ MEND = MEND + 1DO 130 M = MSTART, MENDK = MIN( KBOT-1, KRCOL+3*( M-1 ) )** ==== The following convergence test requires that* . the tradition small-compared-to-nearby-diagonals* . criterion and the Ahues & Tisseur (LAWN 122, 1997)* . criteria both be satisfied. The latter improves* . accuracy in some examples. Falling back on an* . alternate convergence criterion when TST1 or TST2* . is zero (as done here) is traditional but probably* . unnecessary. ====*IF( H( K+1, K ).NE.ZERO ) THENTST1 = ABS( H( K, K ) ) + ABS( H( K+1, K+1 ) )IF( TST1.EQ.ZERO ) THENIF( K.GE.KTOP+1 )$ TST1 = TST1 + ABS( H( K, K-1 ) )IF( K.GE.KTOP+2 )$ TST1 = TST1 + ABS( H( K, K-2 ) )IF( K.GE.KTOP+3 )$ TST1 = TST1 + ABS( H( K, K-3 ) )IF( K.LE.KBOT-2 )$ TST1 = TST1 + ABS( H( K+2, K+1 ) )IF( K.LE.KBOT-3 )$ TST1 = TST1 + ABS( H( K+3, K+1 ) )IF( K.LE.KBOT-4 )$ TST1 = TST1 + ABS( H( K+4, K+1 ) )END IFIF( ABS( H( K+1, K ) ).LE.MAX( SMLNUM, ULP*TST1 ) )$ THENH12 = MAX( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) )H21 = MIN( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) )H11 = MAX( ABS( H( K+1, K+1 ) ),$ ABS( H( K, K )-H( K+1, K+1 ) ) )H22 = MIN( ABS( H( K+1, K+1 ) ),$ ABS( H( K, K )-H( K+1, K+1 ) ) )SCL = H11 + H12TST2 = H22*( H11 / SCL )*IF( TST2.EQ.ZERO .OR. H21*( H12 / SCL ).LE.$ MAX( SMLNUM, ULP*TST2 ) )H( K+1, K ) = ZEROEND IFEND IF130 CONTINUE** ==== Fill in the last row of each bulge. ====*MEND = MIN( NBMPS, ( KBOT-KRCOL-1 ) / 3 )DO 140 M = MTOP, MENDK = KRCOL + 3*( M-1 )REFSUM = V( 1, M )*V( 3, M )*H( K+4, K+3 )H( K+4, K+1 ) = -REFSUMH( K+4, K+2 ) = -REFSUM*V( 2, M )H( K+4, K+3 ) = H( K+4, K+3 ) - REFSUM*V( 3, M )140 CONTINUE** ==== End of near-the-diagonal bulge chase. ====*150 CONTINUE** ==== Use U (if accumulated) to update far-from-diagonal* . entries in H. If required, use U to update Z as* . well. ====*IF( ACCUM ) THENIF( WANTT ) THENJTOP = 1JBOT = NELSEJTOP = KTOPJBOT = KBOTEND IFIF( ( .NOT.BLK22 ) .OR. ( INCOL.LT.KTOP ) .OR.$ ( NDCOL.GT.KBOT ) .OR. ( NS.LE.2 ) ) THEN** ==== Updates not exploiting the 2-by-2 block* . structure of U. K1 and NU keep track of* . the location and size of U in the special* . cases of introducing bulges and chasing* . bulges off the bottom. In these special* . cases and in case the number of shifts* . is NS = 2, there is no 2-by-2 block* . structure to exploit. ====*K1 = MAX( 1, KTOP-INCOL )NU = ( KDU-MAX( 0, NDCOL-KBOT ) ) - K1 + 1** ==== Horizontal Multiply ====*DO 160 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NHJLEN = MIN( NH, JBOT-JCOL+1 )CALL DGEMM( 'C', 'N', NU, JLEN, NU, ONE, U( K1, K1 ),$ LDU, H( INCOL+K1, JCOL ), LDH, ZERO, WH,$ LDWH )CALL DLACPY( 'ALL', NU, JLEN, WH, LDWH,$ H( INCOL+K1, JCOL ), LDH )160 CONTINUE** ==== Vertical multiply ====*DO 170 JROW = JTOP, MAX( KTOP, INCOL ) - 1, NVJLEN = MIN( NV, MAX( KTOP, INCOL )-JROW )CALL DGEMM( 'N', 'N', JLEN, NU, NU, ONE,$ H( JROW, INCOL+K1 ), LDH, U( K1, K1 ),$ LDU, ZERO, WV, LDWV )CALL DLACPY( 'ALL', JLEN, NU, WV, LDWV,$ H( JROW, INCOL+K1 ), LDH )170 CONTINUE** ==== Z multiply (also vertical) ====*IF( WANTZ ) THENDO 180 JROW = ILOZ, IHIZ, NVJLEN = MIN( NV, IHIZ-JROW+1 )CALL DGEMM( 'N', 'N', JLEN, NU, NU, ONE,$ Z( JROW, INCOL+K1 ), LDZ, U( K1, K1 ),$ LDU, ZERO, WV, LDWV )CALL DLACPY( 'ALL', JLEN, NU, WV, LDWV,$ Z( JROW, INCOL+K1 ), LDZ )180 CONTINUEEND IFELSE** ==== Updates exploiting U's 2-by-2 block structure.* . (I2, I4, J2, J4 are the last rows and columns* . of the blocks.) ====*I2 = ( KDU+1 ) / 2I4 = KDUJ2 = I4 - I2J4 = KDU** ==== KZS and KNZ deal with the band of zeros* . along the diagonal of one of the triangular* . blocks. ====*KZS = ( J4-J2 ) - ( NS+1 )KNZ = NS + 1** ==== Horizontal multiply ====*DO 190 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NHJLEN = MIN( NH, JBOT-JCOL+1 )** ==== Copy bottom of H to top+KZS of scratch ====* (The first KZS rows get multiplied by zero.) ====*CALL DLACPY( 'ALL', KNZ, JLEN, H( INCOL+1+J2, JCOL ),$ LDH, WH( KZS+1, 1 ), LDWH )** ==== Multiply by U21**T ====*CALL DLASET( 'ALL', KZS, JLEN, ZERO, ZERO, WH, LDWH )CALL DTRMM( 'L', 'U', 'C', 'N', KNZ, JLEN, ONE,$ U( J2+1, 1+KZS ), LDU, WH( KZS+1, 1 ),$ LDWH )** ==== Multiply top of H by U11**T ====*CALL DGEMM( 'C', 'N', I2, JLEN, J2, ONE, U, LDU,$ H( INCOL+1, JCOL ), LDH, ONE, WH, LDWH )** ==== Copy top of H to bottom of WH ====*CALL DLACPY( 'ALL', J2, JLEN, H( INCOL+1, JCOL ), LDH,$ WH( I2+1, 1 ), LDWH )** ==== Multiply by U21**T ====*CALL DTRMM( 'L', 'L', 'C', 'N', J2, JLEN, ONE,$ U( 1, I2+1 ), LDU, WH( I2+1, 1 ), LDWH )** ==== Multiply by U22 ====*CALL DGEMM( 'C', 'N', I4-I2, JLEN, J4-J2, ONE,$ U( J2+1, I2+1 ), LDU,$ H( INCOL+1+J2, JCOL ), LDH, ONE,$ WH( I2+1, 1 ), LDWH )** ==== Copy it back ====*CALL DLACPY( 'ALL', KDU, JLEN, WH, LDWH,$ H( INCOL+1, JCOL ), LDH )190 CONTINUE** ==== Vertical multiply ====*DO 200 JROW = JTOP, MAX( INCOL, KTOP ) - 1, NVJLEN = MIN( NV, MAX( INCOL, KTOP )-JROW )** ==== Copy right of H to scratch (the first KZS* . columns get multiplied by zero) ====*CALL DLACPY( 'ALL', JLEN, KNZ, H( JROW, INCOL+1+J2 ),$ LDH, WV( 1, 1+KZS ), LDWV )** ==== Multiply by U21 ====*CALL DLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, LDWV )CALL DTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,$ U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),$ LDWV )** ==== Multiply by U11 ====*CALL DGEMM( 'N', 'N', JLEN, I2, J2, ONE,$ H( JROW, INCOL+1 ), LDH, U, LDU, ONE, WV,$ LDWV )** ==== Copy left of H to right of scratch ====*CALL DLACPY( 'ALL', JLEN, J2, H( JROW, INCOL+1 ), LDH,$ WV( 1, 1+I2 ), LDWV )** ==== Multiply by U21 ====*CALL DTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,$ U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), LDWV )** ==== Multiply by U22 ====*CALL DGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,$ H( JROW, INCOL+1+J2 ), LDH,$ U( J2+1, I2+1 ), LDU, ONE, WV( 1, 1+I2 ),$ LDWV )** ==== Copy it back ====*CALL DLACPY( 'ALL', JLEN, KDU, WV, LDWV,$ H( JROW, INCOL+1 ), LDH )200 CONTINUE** ==== Multiply Z (also vertical) ====*IF( WANTZ ) THENDO 210 JROW = ILOZ, IHIZ, NVJLEN = MIN( NV, IHIZ-JROW+1 )** ==== Copy right of Z to left of scratch (first* . KZS columns get multiplied by zero) ====*CALL DLACPY( 'ALL', JLEN, KNZ,$ Z( JROW, INCOL+1+J2 ), LDZ,$ WV( 1, 1+KZS ), LDWV )** ==== Multiply by U12 ====*CALL DLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV,$ LDWV )CALL DTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE,$ U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ),$ LDWV )** ==== Multiply by U11 ====*CALL DGEMM( 'N', 'N', JLEN, I2, J2, ONE,$ Z( JROW, INCOL+1 ), LDZ, U, LDU, ONE,$ WV, LDWV )** ==== Copy left of Z to right of scratch ====*CALL DLACPY( 'ALL', JLEN, J2, Z( JROW, INCOL+1 ),$ LDZ, WV( 1, 1+I2 ), LDWV )** ==== Multiply by U21 ====*CALL DTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE,$ U( 1, I2+1 ), LDU, WV( 1, 1+I2 ),$ LDWV )** ==== Multiply by U22 ====*CALL DGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE,$ Z( JROW, INCOL+1+J2 ), LDZ,$ U( J2+1, I2+1 ), LDU, ONE,$ WV( 1, 1+I2 ), LDWV )** ==== Copy the result back to Z ====*CALL DLACPY( 'ALL', JLEN, KDU, WV, LDWV,$ Z( JROW, INCOL+1 ), LDZ )210 CONTINUEEND IFEND IFEND IF220 CONTINUE** ==== End of DLAQR5 ====*END*> \brief \b DLAQSB scales a symmetric/Hermitian band matrix, using scaling factors computed by spbequ.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQSB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqsb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqsb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqsb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQSB( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, EQUED )** .. Scalar Arguments ..* CHARACTER EQUED, UPLO* INTEGER KD, LDAB, N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQSB equilibrates a symmetric band matrix A using the scaling*> factors in the vector S.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of super-diagonals of the matrix A if UPLO = 'U',*> or the number of sub-diagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, if INFO = 0, the triangular factor U or L from the*> Cholesky factorization A = U**T*U or A = L*L**T of the band*> matrix A, in the same storage format as A.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> The scale factors for A.*> \endverbatim*>*> \param[in] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> Ratio of the smallest S(i) to the largest S(i).*> \endverbatim*>*> \param[in] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix entry.*> \endverbatim*>*> \param[out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies whether or not equilibration was done.*> = 'N': No equilibration.*> = 'Y': Equilibration was done, i.e., A has been replaced by*> diag(S) * A * diag(S).*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> THRESH is a threshold value used to decide if scaling should be done*> based on the ratio of the scaling factors. If SCOND < THRESH,*> scaling is done.*>*> LARGE and SMALL are threshold values used to decide if scaling should*> be done based on the absolute size of the largest matrix element.*> If AMAX > LARGE or AMAX < SMALL, scaling is done.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAQSB( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, EQUED )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER EQUED, UPLOINTEGER KD, LDAB, NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, THRESHPARAMETER ( ONE = 1.0D+0, THRESH = 0.1D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION CJ, LARGE, SMALL* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 ) THENEQUED = 'N'RETURNEND IF** Initialize LARGE and SMALL.*SMALL = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )LARGE = ONE / SMALL*IF( SCOND.GE.THRESH .AND. AMAX.GE.SMALL .AND. AMAX.LE.LARGE ) THEN** No equilibration*EQUED = 'N'ELSE** Replace A by diag(S) * A * diag(S).*IF( LSAME( UPLO, 'U' ) ) THEN** Upper triangle of A is stored in band format.*DO 20 J = 1, NCJ = S( J )DO 10 I = MAX( 1, J-KD ), JAB( KD+1+I-J, J ) = CJ*S( I )*AB( KD+1+I-J, J )10 CONTINUE20 CONTINUEELSE** Lower triangle of A is stored.*DO 40 J = 1, NCJ = S( J )DO 30 I = J, MIN( N, J+KD )AB( 1+I-J, J ) = CJ*S( I )*AB( 1+I-J, J )30 CONTINUE40 CONTINUEEND IFEQUED = 'Y'END IF*RETURN** End of DLAQSB*END*> \brief \b DLAQSP scales a symmetric/Hermitian matrix in packed storage, using scaling factors computed by sppequ.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQSP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqsp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqsp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqsp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQSP( UPLO, N, AP, S, SCOND, AMAX, EQUED )** .. Scalar Arguments ..* CHARACTER EQUED, UPLO* INTEGER N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQSP equilibrates a symmetric matrix A using the scaling factors*> in the vector S.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, the equilibrated matrix: diag(S) * A * diag(S), in*> the same storage format as A.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> The scale factors for A.*> \endverbatim*>*> \param[in] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> Ratio of the smallest S(i) to the largest S(i).*> \endverbatim*>*> \param[in] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix entry.*> \endverbatim*>*> \param[out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies whether or not equilibration was done.*> = 'N': No equilibration.*> = 'Y': Equilibration was done, i.e., A has been replaced by*> diag(S) * A * diag(S).*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> THRESH is a threshold value used to decide if scaling should be done*> based on the ratio of the scaling factors. If SCOND < THRESH,*> scaling is done.*>*> LARGE and SMALL are threshold values used to decide if scaling should*> be done based on the absolute size of the largest matrix element.*> If AMAX > LARGE or AMAX < SMALL, scaling is done.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAQSP( UPLO, N, AP, S, SCOND, AMAX, EQUED )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER EQUED, UPLOINTEGER NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, THRESHPARAMETER ( ONE = 1.0D+0, THRESH = 0.1D+0 )* ..* .. Local Scalars ..INTEGER I, J, JCDOUBLE PRECISION CJ, LARGE, SMALL* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 ) THENEQUED = 'N'RETURNEND IF** Initialize LARGE and SMALL.*SMALL = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )LARGE = ONE / SMALL*IF( SCOND.GE.THRESH .AND. AMAX.GE.SMALL .AND. AMAX.LE.LARGE ) THEN** No equilibration*EQUED = 'N'ELSE** Replace A by diag(S) * A * diag(S).*IF( LSAME( UPLO, 'U' ) ) THEN** Upper triangle of A is stored.*JC = 1DO 20 J = 1, NCJ = S( J )DO 10 I = 1, JAP( JC+I-1 ) = CJ*S( I )*AP( JC+I-1 )10 CONTINUEJC = JC + J20 CONTINUEELSE** Lower triangle of A is stored.*JC = 1DO 40 J = 1, NCJ = S( J )DO 30 I = J, NAP( JC+I-J ) = CJ*S( I )*AP( JC+I-J )30 CONTINUEJC = JC + N - J + 140 CONTINUEEND IFEQUED = 'Y'END IF*RETURN** End of DLAQSP*END*> \brief \b DLAQSY scales a symmetric/Hermitian matrix, using scaling factors computed by spoequ.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQSY + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqsy.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqsy.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqsy.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQSY( UPLO, N, A, LDA, S, SCOND, AMAX, EQUED )** .. Scalar Arguments ..* CHARACTER EQUED, UPLO* INTEGER LDA, N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQSY equilibrates a symmetric matrix A using the scaling factors*> in the vector S.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n by n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n by n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if EQUED = 'Y', the equilibrated matrix:*> diag(S) * A * diag(S).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(N,1).*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> The scale factors for A.*> \endverbatim*>*> \param[in] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> Ratio of the smallest S(i) to the largest S(i).*> \endverbatim*>*> \param[in] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix entry.*> \endverbatim*>*> \param[out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies whether or not equilibration was done.*> = 'N': No equilibration.*> = 'Y': Equilibration was done, i.e., A has been replaced by*> diag(S) * A * diag(S).*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> THRESH is a threshold value used to decide if scaling should be done*> based on the ratio of the scaling factors. If SCOND < THRESH,*> scaling is done.*>*> LARGE and SMALL are threshold values used to decide if scaling should*> be done based on the absolute size of the largest matrix element.*> If AMAX > LARGE or AMAX < SMALL, scaling is done.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYauxiliary** =====================================================================SUBROUTINE DLAQSY( UPLO, N, A, LDA, S, SCOND, AMAX, EQUED )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER EQUED, UPLOINTEGER LDA, NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, THRESHPARAMETER ( ONE = 1.0D+0, THRESH = 0.1D+0 )* ..* .. Local Scalars ..INTEGER I, JDOUBLE PRECISION CJ, LARGE, SMALL* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 ) THENEQUED = 'N'RETURNEND IF** Initialize LARGE and SMALL.*SMALL = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )LARGE = ONE / SMALL*IF( SCOND.GE.THRESH .AND. AMAX.GE.SMALL .AND. AMAX.LE.LARGE ) THEN** No equilibration*EQUED = 'N'ELSE** Replace A by diag(S) * A * diag(S).*IF( LSAME( UPLO, 'U' ) ) THEN** Upper triangle of A is stored.*DO 20 J = 1, NCJ = S( J )DO 10 I = 1, JA( I, J ) = CJ*S( I )*A( I, J )10 CONTINUE20 CONTINUEELSE** Lower triangle of A is stored.*DO 40 J = 1, NCJ = S( J )DO 30 I = J, NA( I, J ) = CJ*S( I )*A( I, J )30 CONTINUE40 CONTINUEEND IFEQUED = 'Y'END IF*RETURN** End of DLAQSY*END*> \brief \b DLAQTR solves a real quasi-triangular system of equations, or a complex quasi-triangular system of special form, in real arithmetic.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAQTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqtr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqtr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqtr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,* INFO )** .. Scalar Arguments ..* LOGICAL LREAL, LTRAN* INTEGER INFO, LDT, N* DOUBLE PRECISION SCALE, W* ..* .. Array Arguments ..* DOUBLE PRECISION B( * ), T( LDT, * ), WORK( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAQTR solves the real quasi-triangular system*>*> op(T)*p = scale*c, if LREAL = .TRUE.*>*> or the complex quasi-triangular systems*>*> op(T + iB)*(p+iq) = scale*(c+id), if LREAL = .FALSE.*>*> in real arithmetic, where T is upper quasi-triangular.*> If LREAL = .FALSE., then the first diagonal block of T must be*> 1 by 1, B is the specially structured matrix*>*> B = [ b(1) b(2) ... b(n) ]*> [ w ]*> [ w ]*> [ . ]*> [ w ]*>*> op(A) = A or A**T, A**T denotes the transpose of*> matrix A.*>*> On input, X = [ c ]. On output, X = [ p ].*> [ d ] [ q ]*>*> This subroutine is designed for the condition number estimation*> in routine DTRSNA.*> \endverbatim** Arguments:* ==========**> \param[in] LTRAN*> \verbatim*> LTRAN is LOGICAL*> On entry, LTRAN specifies the option of conjugate transpose:*> = .FALSE., op(T+i*B) = T+i*B,*> = .TRUE., op(T+i*B) = (T+i*B)**T.*> \endverbatim*>*> \param[in] LREAL*> \verbatim*> LREAL is LOGICAL*> On entry, LREAL specifies the input matrix structure:*> = .FALSE., the input is complex*> = .TRUE., the input is real*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> On entry, N specifies the order of T+i*B. N >= 0.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> On entry, T contains a matrix in Schur canonical form.*> If LREAL = .FALSE., then the first diagonal block of T mu*> be 1 by 1.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the matrix T. LDT >= max(1,N).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (N)*> On entry, B contains the elements to form the matrix*> B as described above.*> If LREAL = .TRUE., B is not referenced.*> \endverbatim*>*> \param[in] W*> \verbatim*> W is DOUBLE PRECISION*> On entry, W is the diagonal element of the matrix B.*> If LREAL = .TRUE., W is not referenced.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> On exit, SCALE is the scale factor.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (2*N)*> On entry, X contains the right hand side of the system.*> On exit, X is overwritten by the solution.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> On exit, INFO is set to*> 0: successful exit.*> 1: the some diagonal 1 by 1 block has been perturbed by*> a small number SMIN to keep nonsingularity.*> 2: the some diagonal 2 by 2 block has been perturbed by*> a small number in DLALN2 to keep nonsingularity.*> NOTE: In the interests of speed, this routine does not*> check the inputs for errors.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,$ INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL LREAL, LTRANINTEGER INFO, LDT, NDOUBLE PRECISION SCALE, W* ..* .. Array Arguments ..DOUBLE PRECISION B( * ), T( LDT, * ), WORK( * ), X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANINTEGER I, IERR, J, J1, J2, JNEXT, K, N1, N2DOUBLE PRECISION BIGNUM, EPS, REC, SCALOC, SI, SMIN, SMINW,$ SMLNUM, SR, TJJ, TMP, XJ, XMAX, XNORM, Z* ..* .. Local Arrays ..DOUBLE PRECISION D( 2, 2 ), V( 2, 2 )* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DASUM, DDOT, DLAMCH, DLANGEEXTERNAL IDAMAX, DASUM, DDOT, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DAXPY, DLADIV, DLALN2, DSCAL* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Do not test the input parameters for errors*NOTRAN = .NOT.LTRANINFO = 0** Quick return if possible*IF( N.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUM*XNORM = DLANGE( 'M', N, N, T, LDT, D )IF( .NOT.LREAL )$ XNORM = MAX( XNORM, ABS( W ), DLANGE( 'M', N, 1, B, N, D ) )SMIN = MAX( SMLNUM, EPS*XNORM )** Compute 1-norm of each column of strictly upper triangular* part of T to control overflow in triangular solver.*WORK( 1 ) = ZERODO 10 J = 2, NWORK( J ) = DASUM( J-1, T( 1, J ), 1 )10 CONTINUE*IF( .NOT.LREAL ) THENDO 20 I = 2, NWORK( I ) = WORK( I ) + ABS( B( I ) )20 CONTINUEEND IF*N2 = 2*NN1 = NIF( .NOT.LREAL )$ N1 = N2K = IDAMAX( N1, X, 1 )XMAX = ABS( X( K ) )SCALE = ONE*IF( XMAX.GT.BIGNUM ) THENSCALE = BIGNUM / XMAXCALL DSCAL( N1, SCALE, X, 1 )XMAX = BIGNUMEND IF*IF( LREAL ) THEN*IF( NOTRAN ) THEN** Solve T*p = scale*c*JNEXT = NDO 30 J = N, 1, -1IF( J.GT.JNEXT )$ GO TO 30J1 = JJ2 = JJNEXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNEXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** Meet 1 by 1 diagonal block** Scale to avoid overflow when computing* x(j) = b(j)/T(j,j)*XJ = ABS( X( J1 ) )TJJ = ABS( T( J1, J1 ) )TMP = T( J1, J1 )IF( TJJ.LT.SMIN ) THENTMP = SMINTJJ = SMININFO = 1END IF*IF( XJ.EQ.ZERO )$ GO TO 30*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J1 ) = X( J1 ) / TMPXJ = ABS( X( J1 ) )** Scale x if necessary to avoid overflow when adding a* multiple of column j1 of T.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFEND IFIF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )K = IDAMAX( J1-1, X, 1 )XMAX = ABS( X( K ) )END IF*ELSE** Meet 2 by 2 diagonal block** Call 2 by 2 linear system solve, to take* care of possible overflow by scaling factor.*D( 1, 1 ) = X( J1 )D( 2, 1 ) = X( J2 )CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( N, SCALOC, X, 1 )SCALE = SCALE*SCALOCEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )** Scale V(1,1) (= X(J1)) and/or V(2,1) (=X(J2))* to avoid overflow in updating right-hand side.*XJ = MAX( ABS( V( 1, 1 ) ), ABS( V( 2, 1 ) ) )IF( XJ.GT.ONE ) THENREC = ONE / XJIF( MAX( WORK( J1 ), WORK( J2 ) ).GT.$ ( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFEND IF** Update right-hand side*IF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )K = IDAMAX( J1-1, X, 1 )XMAX = ABS( X( K ) )END IF*END IF*30 CONTINUE*ELSE** Solve T**T*p = scale*c*JNEXT = 1DO 40 J = 1, NIF( J.LT.JNEXT )$ GO TO 40J1 = JJ2 = JJNEXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNEXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1 by 1 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side element by inner product.*XJ = ABS( X( J1 ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )*XJ = ABS( X( J1 ) )TJJ = ABS( T( J1, J1 ) )TMP = T( J1, J1 )IF( TJJ.LT.SMIN ) THENTMP = SMINTJJ = SMININFO = 1END IF*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J1 ) = X( J1 ) / TMPXMAX = MAX( XMAX, ABS( X( J1 ) ) )*ELSE** 2 by 2 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side elements by inner product.*XJ = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( MAX( WORK( J2 ), WORK( J1 ) ).GT.( BIGNUM-XJ )*$ REC ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,$ 1 )D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,$ 1 )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( N, SCALOC, X, 1 )SCALE = SCALE*SCALOCEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )XMAX = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ), XMAX )*END IF40 CONTINUEEND IF*ELSE*SMINW = MAX( EPS*ABS( W ), SMIN )IF( NOTRAN ) THEN** Solve (T + iB)*(p+iq) = c+id*JNEXT = NDO 70 J = N, 1, -1IF( J.GT.JNEXT )$ GO TO 70J1 = JJ2 = JJNEXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNEXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1 by 1 diagonal block** Scale if necessary to avoid overflow in division*Z = WIF( J1.EQ.1 )$ Z = B( 1 )XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )TJJ = ABS( T( J1, J1 ) ) + ABS( Z )TMP = T( J1, J1 )IF( TJJ.LT.SMINW ) THENTMP = SMINWTJJ = SMINWINFO = 1END IF*IF( XJ.EQ.ZERO )$ GO TO 70*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFCALL DLADIV( X( J1 ), X( N+J1 ), TMP, Z, SR, SI )X( J1 ) = SRX( N+J1 ) = SIXJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )** Scale x if necessary to avoid overflow when adding a* multiple of column j1 of T.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECEND IFEND IF*IF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,$ X( N+1 ), 1 )*X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 )X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 )*XMAX = ZERODO 50 K = 1, J1 - 1XMAX = MAX( XMAX, ABS( X( K ) )+$ ABS( X( K+N ) ) )50 CONTINUEEND IF*ELSE** Meet 2 by 2 diagonal block*D( 1, 1 ) = X( J1 )D( 2, 1 ) = X( J2 )D( 1, 2 ) = X( N+J1 )D( 2, 2 ) = X( N+J2 )CALL DLALN2( .FALSE., 2, 2, SMINW, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, -W, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( 2*N, SCALOC, X, 1 )SCALE = SCALOC*SCALEEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )X( N+J1 ) = V( 1, 2 )X( N+J2 ) = V( 2, 2 )** Scale X(J1), .... to avoid overflow in* updating right hand side.*XJ = MAX( ABS( V( 1, 1 ) )+ABS( V( 1, 2 ) ),$ ABS( V( 2, 1 ) )+ABS( V( 2, 2 ) ) )IF( XJ.GT.ONE ) THENREC = ONE / XJIF( MAX( WORK( J1 ), WORK( J2 ) ).GT.$ ( BIGNUM-XMAX )*REC ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECEND IFEND IF** Update the right-hand side.*IF( J1.GT.1 ) THENCALL DAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )CALL DAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )*CALL DAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,$ X( N+1 ), 1 )CALL DAXPY( J1-1, -X( N+J2 ), T( 1, J2 ), 1,$ X( N+1 ), 1 )*X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 ) +$ B( J2 )*X( N+J2 )X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 ) -$ B( J2 )*X( J2 )*XMAX = ZERODO 60 K = 1, J1 - 1XMAX = MAX( ABS( X( K ) )+ABS( X( K+N ) ),$ XMAX )60 CONTINUEEND IF*END IF70 CONTINUE*ELSE** Solve (T + iB)**T*(p+iq) = c+id*JNEXT = 1DO 80 J = 1, NIF( J.LT.JNEXT )$ GO TO 80J1 = JJ2 = JJNEXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNEXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1 by 1 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side element by inner product.*XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*X( J1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X, 1 )X( N+J1 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,$ X( N+1 ), 1 )IF( J1.GT.1 ) THENX( J1 ) = X( J1 ) - B( J1 )*X( N+1 )X( N+J1 ) = X( N+J1 ) + B( J1 )*X( 1 )END IFXJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )*Z = WIF( J1.EQ.1 )$ Z = B( 1 )** Scale if necessary to avoid overflow in* complex division*TJJ = ABS( T( J1, J1 ) ) + ABS( Z )TMP = T( J1, J1 )IF( TJJ.LT.SMINW ) THENTMP = SMINWTJJ = SMINWINFO = 1END IF*IF( TJJ.LT.ONE ) THENIF( XJ.GT.BIGNUM*TJJ ) THENREC = ONE / XJCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFCALL DLADIV( X( J1 ), X( N+J1 ), TMP, -Z, SR, SI )X( J1 ) = SRX( J1+N ) = SIXMAX = MAX( ABS( X( J1 ) )+ABS( X( J1+N ) ), XMAX )*ELSE** 2 by 2 diagonal block** Scale if necessary to avoid overflow in forming the* right-hand side element by inner product.*XJ = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),$ ABS( X( J2 ) )+ABS( X( N+J2 ) ) )IF( XMAX.GT.ONE ) THENREC = ONE / XMAXIF( MAX( WORK( J1 ), WORK( J2 ) ).GT.$ ( BIGNUM-XJ ) / XMAX ) THENCALL DSCAL( N2, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*D( 1, 1 ) = X( J1 ) - DDOT( J1-1, T( 1, J1 ), 1, X,$ 1 )D( 2, 1 ) = X( J2 ) - DDOT( J1-1, T( 1, J2 ), 1, X,$ 1 )D( 1, 2 ) = X( N+J1 ) - DDOT( J1-1, T( 1, J1 ), 1,$ X( N+1 ), 1 )D( 2, 2 ) = X( N+J2 ) - DDOT( J1-1, T( 1, J2 ), 1,$ X( N+1 ), 1 )D( 1, 1 ) = D( 1, 1 ) - B( J1 )*X( N+1 )D( 2, 1 ) = D( 2, 1 ) - B( J2 )*X( N+1 )D( 1, 2 ) = D( 1, 2 ) + B( J1 )*X( 1 )D( 2, 2 ) = D( 2, 2 ) + B( J2 )*X( 1 )*CALL DLALN2( .TRUE., 2, 2, SMINW, ONE, T( J1, J1 ),$ LDT, ONE, ONE, D, 2, ZERO, W, V, 2,$ SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 2*IF( SCALOC.NE.ONE ) THENCALL DSCAL( N2, SCALOC, X, 1 )SCALE = SCALOC*SCALEEND IFX( J1 ) = V( 1, 1 )X( J2 ) = V( 2, 1 )X( N+J1 ) = V( 1, 2 )X( N+J2 ) = V( 2, 2 )XMAX = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),$ ABS( X( J2 ) )+ABS( X( N+J2 ) ), XMAX )*END IF*80 CONTINUE*END IF*END IF*RETURN** End of DLAQTR*END*> \brief \b DLAR1V computes the (scaled) r-th column of the inverse of the submatrix in rows b1 through bn of the tridiagonal matrix LDLT - λI.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAR1V + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlar1v.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlar1v.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlar1v.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAR1V( N, B1, BN, LAMBDA, D, L, LD, LLD,* PIVMIN, GAPTOL, Z, WANTNC, NEGCNT, ZTZ, MINGMA,* R, ISUPPZ, NRMINV, RESID, RQCORR, WORK )** .. Scalar Arguments ..* LOGICAL WANTNC* INTEGER B1, BN, N, NEGCNT, R* DOUBLE PRECISION GAPTOL, LAMBDA, MINGMA, NRMINV, PIVMIN, RESID,* $ RQCORR, ZTZ* ..* .. Array Arguments ..* INTEGER ISUPPZ( * )* DOUBLE PRECISION D( * ), L( * ), LD( * ), LLD( * ),* $ WORK( * )* DOUBLE PRECISION Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAR1V computes the (scaled) r-th column of the inverse of*> the sumbmatrix in rows B1 through BN of the tridiagonal matrix*> L D L**T - sigma I. When sigma is close to an eigenvalue, the*> computed vector is an accurate eigenvector. Usually, r corresponds*> to the index where the eigenvector is largest in magnitude.*> The following steps accomplish this computation :*> (a) Stationary qd transform, L D L**T - sigma I = L(+) D(+) L(+)**T,*> (b) Progressive qd transform, L D L**T - sigma I = U(-) D(-) U(-)**T,*> (c) Computation of the diagonal elements of the inverse of*> L D L**T - sigma I by combining the above transforms, and choosing*> r as the index where the diagonal of the inverse is (one of the)*> largest in magnitude.*> (d) Computation of the (scaled) r-th column of the inverse using the*> twisted factorization obtained by combining the top part of the*> the stationary and the bottom part of the progressive transform.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix L D L**T.*> \endverbatim*>*> \param[in] B1*> \verbatim*> B1 is INTEGER*> First index of the submatrix of L D L**T.*> \endverbatim*>*> \param[in] BN*> \verbatim*> BN is INTEGER*> Last index of the submatrix of L D L**T.*> \endverbatim*>*> \param[in] LAMBDA*> \verbatim*> LAMBDA is DOUBLE PRECISION*> The shift. In order to compute an accurate eigenvector,*> LAMBDA should be a good approximation to an eigenvalue*> of L D L**T.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the unit bidiagonal matrix*> L, in elements 1 to N-1.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the diagonal matrix D.*> \endverbatim*>*> \param[in] LD*> \verbatim*> LD is DOUBLE PRECISION array, dimension (N-1)*> The n-1 elements L(i)*D(i).*> \endverbatim*>*> \param[in] LLD*> \verbatim*> LLD is DOUBLE PRECISION array, dimension (N-1)*> The n-1 elements L(i)*L(i)*D(i).*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot in the Sturm sequence.*> \endverbatim*>*> \param[in] GAPTOL*> \verbatim*> GAPTOL is DOUBLE PRECISION*> Tolerance that indicates when eigenvector entries are negligible*> w.r.t. their contribution to the residual.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (N)*> On input, all entries of Z must be set to 0.*> On output, Z contains the (scaled) r-th column of the*> inverse. The scaling is such that Z(R) equals 1.*> \endverbatim*>*> \param[in] WANTNC*> \verbatim*> WANTNC is LOGICAL*> Specifies whether NEGCNT has to be computed.*> \endverbatim*>*> \param[out] NEGCNT*> \verbatim*> NEGCNT is INTEGER*> If WANTNC is .TRUE. then NEGCNT = the number of pivots < pivmin*> in the matrix factorization L D L**T, and NEGCNT = -1 otherwise.*> \endverbatim*>*> \param[out] ZTZ*> \verbatim*> ZTZ is DOUBLE PRECISION*> The square of the 2-norm of Z.*> \endverbatim*>*> \param[out] MINGMA*> \verbatim*> MINGMA is DOUBLE PRECISION*> The reciprocal of the largest (in magnitude) diagonal*> element of the inverse of L D L**T - sigma I.*> \endverbatim*>*> \param[in,out] R*> \verbatim*> R is INTEGER*> The twist index for the twisted factorization used to*> compute Z.*> On input, 0 <= R <= N. If R is input as 0, R is set to*> the index where (L D L**T - sigma I)^{-1} is largest*> in magnitude. If 1 <= R <= N, R is unchanged.*> On output, R contains the twist index used to compute Z.*> Ideally, R designates the position of the maximum entry in the*> eigenvector.*> \endverbatim*>*> \param[out] ISUPPZ*> \verbatim*> ISUPPZ is INTEGER array, dimension (2)*> The support of the vector in Z, i.e., the vector Z is*> nonzero only in elements ISUPPZ(1) through ISUPPZ( 2 ).*> \endverbatim*>*> \param[out] NRMINV*> \verbatim*> NRMINV is DOUBLE PRECISION*> NRMINV = 1/SQRT( ZTZ )*> \endverbatim*>*> \param[out] RESID*> \verbatim*> RESID is DOUBLE PRECISION*> The residual of the FP vector.*> RESID = ABS( MINGMA )/SQRT( ZTZ )*> \endverbatim*>*> \param[out] RQCORR*> \verbatim*> RQCORR is DOUBLE PRECISION*> The Rayleigh Quotient correction to LAMBDA.*> RQCORR = MINGMA*TMP*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLAR1V( N, B1, BN, LAMBDA, D, L, LD, LLD,$ PIVMIN, GAPTOL, Z, WANTNC, NEGCNT, ZTZ, MINGMA,$ R, ISUPPZ, NRMINV, RESID, RQCORR, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL WANTNCINTEGER B1, BN, N, NEGCNT, RDOUBLE PRECISION GAPTOL, LAMBDA, MINGMA, NRMINV, PIVMIN, RESID,$ RQCORR, ZTZ* ..* .. Array Arguments ..INTEGER ISUPPZ( * )DOUBLE PRECISION D( * ), L( * ), LD( * ), LLD( * ),$ WORK( * )DOUBLE PRECISION Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL SAWNAN1, SAWNAN2INTEGER I, INDLPL, INDP, INDS, INDUMN, NEG1, NEG2, R1,$ R2DOUBLE PRECISION DMINUS, DPLUS, EPS, S, TMP* ..* .. External Functions ..LOGICAL DISNANDOUBLE PRECISION DLAMCHEXTERNAL DISNAN, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*EPS = DLAMCH( 'Precision' )IF( R.EQ.0 ) THENR1 = B1R2 = BNELSER1 = RR2 = REND IF* Storage for LPLUSINDLPL = 0* Storage for UMINUSINDUMN = NINDS = 2*N + 1INDP = 3*N + 1IF( B1.EQ.1 ) THENWORK( INDS ) = ZEROELSEWORK( INDS+B1-1 ) = LLD( B1-1 )END IF** Compute the stationary transform (using the differential form)* until the index R2.*SAWNAN1 = .FALSE.NEG1 = 0S = WORK( INDS+B1-1 ) - LAMBDADO 50 I = B1, R1 - 1DPLUS = D( I ) + SWORK( INDLPL+I ) = LD( I ) / DPLUSIF(DPLUS.LT.ZERO) NEG1 = NEG1 + 1WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )S = WORK( INDS+I ) - LAMBDA50 CONTINUESAWNAN1 = DISNAN( S )IF( SAWNAN1 ) GOTO 60DO 51 I = R1, R2 - 1DPLUS = D( I ) + SWORK( INDLPL+I ) = LD( I ) / DPLUSWORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )S = WORK( INDS+I ) - LAMBDA51 CONTINUESAWNAN1 = DISNAN( S )*60 CONTINUEIF( SAWNAN1 ) THEN* Runs a slower version of the above loop if a NaN is detectedNEG1 = 0S = WORK( INDS+B1-1 ) - LAMBDADO 70 I = B1, R1 - 1DPLUS = D( I ) + SIF(ABS(DPLUS).LT.PIVMIN) DPLUS = -PIVMINWORK( INDLPL+I ) = LD( I ) / DPLUSIF(DPLUS.LT.ZERO) NEG1 = NEG1 + 1WORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )IF( WORK( INDLPL+I ).EQ.ZERO )$ WORK( INDS+I ) = LLD( I )S = WORK( INDS+I ) - LAMBDA70 CONTINUEDO 71 I = R1, R2 - 1DPLUS = D( I ) + SIF(ABS(DPLUS).LT.PIVMIN) DPLUS = -PIVMINWORK( INDLPL+I ) = LD( I ) / DPLUSWORK( INDS+I ) = S*WORK( INDLPL+I )*L( I )IF( WORK( INDLPL+I ).EQ.ZERO )$ WORK( INDS+I ) = LLD( I )S = WORK( INDS+I ) - LAMBDA71 CONTINUEEND IF** Compute the progressive transform (using the differential form)* until the index R1*SAWNAN2 = .FALSE.NEG2 = 0WORK( INDP+BN-1 ) = D( BN ) - LAMBDADO 80 I = BN - 1, R1, -1DMINUS = LLD( I ) + WORK( INDP+I )TMP = D( I ) / DMINUSIF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1WORK( INDUMN+I ) = L( I )*TMPWORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDA80 CONTINUETMP = WORK( INDP+R1-1 )SAWNAN2 = DISNAN( TMP )IF( SAWNAN2 ) THEN* Runs a slower version of the above loop if a NaN is detectedNEG2 = 0DO 100 I = BN-1, R1, -1DMINUS = LLD( I ) + WORK( INDP+I )IF(ABS(DMINUS).LT.PIVMIN) DMINUS = -PIVMINTMP = D( I ) / DMINUSIF(DMINUS.LT.ZERO) NEG2 = NEG2 + 1WORK( INDUMN+I ) = L( I )*TMPWORK( INDP+I-1 ) = WORK( INDP+I )*TMP - LAMBDAIF( TMP.EQ.ZERO )$ WORK( INDP+I-1 ) = D( I ) - LAMBDA100 CONTINUEEND IF** Find the index (from R1 to R2) of the largest (in magnitude)* diagonal element of the inverse*MINGMA = WORK( INDS+R1-1 ) + WORK( INDP+R1-1 )IF( MINGMA.LT.ZERO ) NEG1 = NEG1 + 1IF( WANTNC ) THENNEGCNT = NEG1 + NEG2ELSENEGCNT = -1ENDIFIF( ABS(MINGMA).EQ.ZERO )$ MINGMA = EPS*WORK( INDS+R1-1 )R = R1DO 110 I = R1, R2 - 1TMP = WORK( INDS+I ) + WORK( INDP+I )IF( TMP.EQ.ZERO )$ TMP = EPS*WORK( INDS+I )IF( ABS( TMP ).LE.ABS( MINGMA ) ) THENMINGMA = TMPR = I + 1END IF110 CONTINUE** Compute the FP vector: solve N^T v = e_r*ISUPPZ( 1 ) = B1ISUPPZ( 2 ) = BNZ( R ) = ONEZTZ = ONE** Compute the FP vector upwards from R*IF( .NOT.SAWNAN1 .AND. .NOT.SAWNAN2 ) THENDO 210 I = R-1, B1, -1Z( I ) = -( WORK( INDLPL+I )*Z( I+1 ) )IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )$ THENZ( I ) = ZEROISUPPZ( 1 ) = I + 1GOTO 220ENDIFZTZ = ZTZ + Z( I )*Z( I )210 CONTINUE220 CONTINUEELSE* Run slower loop if NaN occurred.DO 230 I = R - 1, B1, -1IF( Z( I+1 ).EQ.ZERO ) THENZ( I ) = -( LD( I+1 ) / LD( I ) )*Z( I+2 )ELSEZ( I ) = -( WORK( INDLPL+I )*Z( I+1 ) )END IFIF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )$ THENZ( I ) = ZEROISUPPZ( 1 ) = I + 1GO TO 240END IFZTZ = ZTZ + Z( I )*Z( I )230 CONTINUE240 CONTINUEENDIF* Compute the FP vector downwards from R in blocks of size BLKSIZIF( .NOT.SAWNAN1 .AND. .NOT.SAWNAN2 ) THENDO 250 I = R, BN-1Z( I+1 ) = -( WORK( INDUMN+I )*Z( I ) )IF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )$ THENZ( I+1 ) = ZEROISUPPZ( 2 ) = IGO TO 260END IFZTZ = ZTZ + Z( I+1 )*Z( I+1 )250 CONTINUE260 CONTINUEELSE* Run slower loop if NaN occurred.DO 270 I = R, BN - 1IF( Z( I ).EQ.ZERO ) THENZ( I+1 ) = -( LD( I-1 ) / LD( I ) )*Z( I-1 )ELSEZ( I+1 ) = -( WORK( INDUMN+I )*Z( I ) )END IFIF( (ABS(Z(I))+ABS(Z(I+1)))* ABS(LD(I)).LT.GAPTOL )$ THENZ( I+1 ) = ZEROISUPPZ( 2 ) = IGO TO 280END IFZTZ = ZTZ + Z( I+1 )*Z( I+1 )270 CONTINUE280 CONTINUEEND IF** Compute quantities for convergence test*TMP = ONE / ZTZNRMINV = SQRT( TMP )RESID = ABS( MINGMA )*NRMINVRQCORR = MINGMA*TMP**RETURN** End of DLAR1V*END*> \brief \b DLAR2V applies a vector of plane rotations with real cosines and real sines from both sides to a sequence of 2-by-2 symmetric/Hermitian matrices.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAR2V + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlar2v.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlar2v.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlar2v.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAR2V( N, X, Y, Z, INCX, C, S, INCC )** .. Scalar Arguments ..* INTEGER INCC, INCX, N* ..* .. Array Arguments ..* DOUBLE PRECISION C( * ), S( * ), X( * ), Y( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAR2V applies a vector of real plane rotations from both sides to*> a sequence of 2-by-2 real symmetric matrices, defined by the elements*> of the vectors x, y and z. For i = 1,2,...,n*>*> ( x(i) z(i) ) := ( c(i) s(i) ) ( x(i) z(i) ) ( c(i) -s(i) )*> ( z(i) y(i) ) ( -s(i) c(i) ) ( z(i) y(i) ) ( s(i) c(i) )*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of plane rotations to be applied.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCX)*> The vector x.*> \endverbatim*>*> \param[in,out] Y*> \verbatim*> Y is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCX)*> The vector y.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCX)*> The vector z.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between elements of X, Y and Z. INCX > 0.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (1+(N-1)*INCC)*> The cosines of the plane rotations.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (1+(N-1)*INCC)*> The sines of the plane rotations.*> \endverbatim*>*> \param[in] INCC*> \verbatim*> INCC is INTEGER*> The increment between elements of C and S. INCC > 0.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAR2V( N, X, Y, Z, INCX, C, S, INCC )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INCC, INCX, N* ..* .. Array Arguments ..DOUBLE PRECISION C( * ), S( * ), X( * ), Y( * ), Z( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, IC, IXDOUBLE PRECISION CI, SI, T1, T2, T3, T4, T5, T6, XI, YI, ZI* ..* .. Executable Statements ..*IX = 1IC = 1DO 10 I = 1, NXI = X( IX )YI = Y( IX )ZI = Z( IX )CI = C( IC )SI = S( IC )T1 = SI*ZIT2 = CI*ZIT3 = T2 - SI*XIT4 = T2 + SI*YIT5 = CI*XI + T1T6 = CI*YI - T1X( IX ) = CI*T5 + SI*T4Y( IX ) = CI*T6 - SI*T3Z( IX ) = CI*T4 - SI*T5IX = IX + INCXIC = IC + INCC10 CONTINUE** End of DLAR2V*RETURNEND*> \brief \b DLARF applies an elementary reflector to a general rectangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )** .. Scalar Arguments ..* CHARACTER SIDE* INTEGER INCV, LDC, M, N* DOUBLE PRECISION TAU* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARF applies a real elementary reflector H to a real m by n matrix*> C, from either the left or the right. H is represented in the form*>*> H = I - tau * v * v**T*>*> where tau is a real scalar and v is a real vector.*>*> If tau = 0, then H is taken to be the unit matrix.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': form H * C*> = 'R': form C * H*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension*> (1 + (M-1)*abs(INCV)) if SIDE = 'L'*> or (1 + (N-1)*abs(INCV)) if SIDE = 'R'*> The vector v in the representation of H. V is not used if*> TAU = 0.*> \endverbatim*>*> \param[in] INCV*> \verbatim*> INCV is INTEGER*> The increment between elements of v. INCV <> 0.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The value tau in the representation of H.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',*> or C * H if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L'*> or (M) if SIDE = 'R'*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDEINTEGER INCV, LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL APPLYLEFTINTEGER I, LASTV, LASTC* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILADLR, ILADLCEXTERNAL LSAME, ILADLR, ILADLC* ..* .. Executable Statements ..*APPLYLEFT = LSAME( SIDE, 'L' )LASTV = 0LASTC = 0IF( TAU.NE.ZERO ) THEN! Set up variables for scanning V. LASTV begins pointing to the end! of V.IF( APPLYLEFT ) THENLASTV = MELSELASTV = NEND IFIF( INCV.GT.0 ) THENI = 1 + (LASTV-1) * INCVELSEI = 1END IF! Look for the last non-zero row in V.DO WHILE( LASTV.GT.0 .AND. V( I ).EQ.ZERO )LASTV = LASTV - 1I = I - INCVEND DOIF( APPLYLEFT ) THEN! Scan for the last non-zero column in C(1:lastv,:).LASTC = ILADLC(LASTV, N, C, LDC)ELSE! Scan for the last non-zero row in C(:,1:lastv).LASTC = ILADLR(M, LASTV, C, LDC)END IFEND IF! Note that lastc.eq.0 renders the BLAS operations null; no special! case is needed at this level.IF( APPLYLEFT ) THEN** Form H * C*IF( LASTV.GT.0 ) THEN** w(1:lastc,1) := C(1:lastv,1:lastc)**T * v(1:lastv,1)*CALL DGEMV( 'Transpose', LASTV, LASTC, ONE, C, LDC, V, INCV,$ ZERO, WORK, 1 )** C(1:lastv,1:lastc) := C(...) - v(1:lastv,1) * w(1:lastc,1)**T*CALL DGER( LASTV, LASTC, -TAU, V, INCV, WORK, 1, C, LDC )END IFELSE** Form C * H*IF( LASTV.GT.0 ) THEN** w(1:lastc,1) := C(1:lastc,1:lastv) * v(1:lastv,1)*CALL DGEMV( 'No transpose', LASTC, LASTV, ONE, C, LDC,$ V, INCV, ZERO, WORK, 1 )** C(1:lastc,1:lastv) := C(...) - w(1:lastc,1) * v(1:lastv,1)**T*CALL DGER( LASTC, LASTV, -TAU, WORK, 1, V, INCV, C, LDC )END IFEND IFRETURN** End of DLARF*END*> \brief \b DLARFB applies a block reflector or its transpose to a general rectangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARFB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarfb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarfb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarfb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,* T, LDT, C, LDC, WORK, LDWORK )** .. Scalar Arguments ..* CHARACTER DIRECT, SIDE, STOREV, TRANS* INTEGER K, LDC, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),* $ WORK( LDWORK, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARFB applies a real block reflector H or its transpose H**T to a*> real m by n matrix C, from either the left or the right.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply H or H**T from the Left*> = 'R': apply H or H**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply H (No transpose)*> = 'T': apply H**T (Transpose)*> \endverbatim*>*> \param[in] DIRECT*> \verbatim*> DIRECT is CHARACTER*1*> Indicates how H is formed from a product of elementary*> reflectors*> = 'F': H = H(1) H(2) . . . H(k) (Forward)*> = 'B': H = H(k) . . . H(2) H(1) (Backward)*> \endverbatim*>*> \param[in] STOREV*> \verbatim*> STOREV is CHARACTER*1*> Indicates how the vectors which define the elementary*> reflectors are stored:*> = 'C': Columnwise*> = 'R': Rowwise*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The order of the matrix T (= the number of elementary*> reflectors whose product defines the block reflector).*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension*> (LDV,K) if STOREV = 'C'*> (LDV,M) if STOREV = 'R' and SIDE = 'L'*> (LDV,N) if STOREV = 'R' and SIDE = 'R'*> The matrix V. See Further Details.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);*> if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);*> if STOREV = 'R', LDV >= K.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The triangular k by k matrix T in the representation of the*> block reflector.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= K.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by H*C or H**T*C or C*H or C*H**T.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LDWORK,K)*> \endverbatim*>*> \param[in] LDWORK*> \verbatim*> LDWORK is INTEGER*> The leading dimension of the array WORK.*> If SIDE = 'L', LDWORK >= max(1,N);*> if SIDE = 'R', LDWORK >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2013**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The shape of the matrix V and the storage of the vectors which define*> the H(i) is best illustrated by the following example with n = 5 and*> k = 3. The elements equal to 1 are not stored; the corresponding*> array elements are modified but restored on exit. The rest of the*> array is not used.*>*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':*>*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )*> ( v1 1 ) ( 1 v2 v2 v2 )*> ( v1 v2 1 ) ( 1 v3 v3 )*> ( v1 v2 v3 )*> ( v1 v2 v3 )*>*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':*>*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )*> ( v1 v2 v3 ) ( v2 v2 v2 1 )*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )*> ( 1 v3 )*> ( 1 )*> \endverbatim*>* =====================================================================SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,$ T, LDT, C, LDC, WORK, LDWORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2013** .. Scalar Arguments ..CHARACTER DIRECT, SIDE, STOREV, TRANSINTEGER K, LDC, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),$ WORK( LDWORK, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..CHARACTER TRANSTINTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DTRMM* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 )$ RETURN*IF( LSAME( TRANS, 'N' ) ) THENTRANST = 'T'ELSETRANST = 'N'END IF*IF( LSAME( STOREV, 'C' ) ) THEN*IF( LSAME( DIRECT, 'F' ) ) THEN** Let V = ( V1 ) (first K rows)* ( V2 )* where V1 is unit lower triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H**T * C where C = ( C1 )* ( C2 )** W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)** W := C1**T*DO 10 J = 1, KCALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )10 CONTINUE** W := W * V1*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,$ K, ONE, V, LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C2**T * V2*CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K,$ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,$ ONE, WORK, LDWORK )END IF** W := W * T**T or W * T*CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V * W**T*IF( M.GT.K ) THEN** C2 := C2 - V2 * W**T*CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K,$ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,$ C( K+1, 1 ), LDC )END IF** W := W * V1**T*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,$ ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W**T*DO 30 J = 1, KDO 20 I = 1, NC( J, I ) = C( J, I ) - WORK( I, J )20 CONTINUE30 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H**T where C = ( C1 C2 )** W := C * V = (C1*V1 + C2*V2) (stored in WORK)** W := C1*DO 40 J = 1, KCALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )40 CONTINUE** W := W * V1*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,$ K, ONE, V, LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C2 * V2*CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K,$ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,$ ONE, WORK, LDWORK )END IF** W := W * T or W * T**T*CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V**T*IF( N.GT.K ) THEN** C2 := C2 - W * V2**T*CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,$ C( 1, K+1 ), LDC )END IF** W := W * V1**T*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,$ ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W*DO 60 J = 1, KDO 50 I = 1, MC( I, J ) = C( I, J ) - WORK( I, J )50 CONTINUE60 CONTINUEEND IF*ELSE** Let V = ( V1 )* ( V2 ) (last K rows)* where V2 is unit upper triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H**T * C where C = ( C1 )* ( C2 )** W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)** W := C2**T*DO 70 J = 1, KCALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )70 CONTINUE** W := W * V2*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,$ K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C1**T * V1*CALL DGEMM( 'Transpose', 'No transpose', N, K, M-K,$ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T**T or W * T*CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V * W**T*IF( M.GT.K ) THEN** C1 := C1 - V1 * W**T*CALL DGEMM( 'No transpose', 'Transpose', M-K, N, K,$ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )END IF** W := W * V2**T*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,$ ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )** C2 := C2 - W**T*DO 90 J = 1, KDO 80 I = 1, NC( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )80 CONTINUE90 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H**T where C = ( C1 C2 )** W := C * V = (C1*V1 + C2*V2) (stored in WORK)** W := C2*DO 100 J = 1, KCALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )100 CONTINUE** W := W * V2*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,$ K, ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C1 * V1*CALL DGEMM( 'No transpose', 'No transpose', M, K, N-K,$ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T or W * T**T*CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V**T*IF( N.GT.K ) THEN** C1 := C1 - W * V1**T*CALL DGEMM( 'No transpose', 'Transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )END IF** W := W * V2**T*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,$ ONE, V( N-K+1, 1 ), LDV, WORK, LDWORK )** C2 := C2 - W*DO 120 J = 1, KDO 110 I = 1, MC( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )110 CONTINUE120 CONTINUEEND IFEND IF*ELSE IF( LSAME( STOREV, 'R' ) ) THEN*IF( LSAME( DIRECT, 'F' ) ) THEN** Let V = ( V1 V2 ) (V1: first K columns)* where V1 is unit upper triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H**T * C where C = ( C1 )* ( C2 )** W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)** W := C1**T*DO 130 J = 1, KCALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )130 CONTINUE** W := W * V1**T*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', N, K,$ ONE, V, LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C2**T * V2**T*CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,$ C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,$ WORK, LDWORK )END IF** W := W * T**T or W * T*CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V**T * W**T*IF( M.GT.K ) THEN** C2 := C2 - V2**T * W**T*CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,$ V( 1, K+1 ), LDV, WORK, LDWORK, ONE,$ C( K+1, 1 ), LDC )END IF** W := W * V1*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', N,$ K, ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W**T*DO 150 J = 1, KDO 140 I = 1, NC( J, I ) = C( J, I ) - WORK( I, J )140 CONTINUE150 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H**T where C = ( C1 C2 )** W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)** W := C1*DO 160 J = 1, KCALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )160 CONTINUE** W := W * V1**T*CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit', M, K,$ ONE, V, LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C2 * V2**T*CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K,$ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,$ ONE, WORK, LDWORK )END IF** W := W * T or W * T**T*CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V*IF( N.GT.K ) THEN** C2 := C2 - W * V2*CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV, ONE,$ C( 1, K+1 ), LDC )END IF** W := W * V1*CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit', M,$ K, ONE, V, LDV, WORK, LDWORK )** C1 := C1 - W*DO 180 J = 1, KDO 170 I = 1, MC( I, J ) = C( I, J ) - WORK( I, J )170 CONTINUE180 CONTINUE*END IF*ELSE** Let V = ( V1 V2 ) (V2: last K columns)* where V2 is unit lower triangular.*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H**T * C where C = ( C1 )* ( C2 )** W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)** W := C2**T*DO 190 J = 1, KCALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )190 CONTINUE** W := W * V2**T*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', N, K,$ ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )IF( M.GT.K ) THEN** W := W + C1**T * V1**T*CALL DGEMM( 'Transpose', 'Transpose', N, K, M-K, ONE,$ C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T**T or W * T*CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - V**T * W**T*IF( M.GT.K ) THEN** C1 := C1 - V1**T * W**T*CALL DGEMM( 'Transpose', 'Transpose', M-K, N, K, -ONE,$ V, LDV, WORK, LDWORK, ONE, C, LDC )END IF** W := W * V2*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', N,$ K, ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )** C2 := C2 - W**T*DO 210 J = 1, KDO 200 I = 1, NC( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )200 CONTINUE210 CONTINUE*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H' where C = ( C1 C2 )** W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)** W := C2*DO 220 J = 1, KCALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )220 CONTINUE** W := W * V2**T*CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit', M, K,$ ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )IF( N.GT.K ) THEN** W := W + C1 * V1**T*CALL DGEMM( 'No transpose', 'Transpose', M, K, N-K,$ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )END IF** W := W * T or W * T**T*CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K,$ ONE, T, LDT, WORK, LDWORK )** C := C - W * V*IF( N.GT.K ) THEN** C1 := C1 - W * V1*CALL DGEMM( 'No transpose', 'No transpose', M, N-K, K,$ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )END IF** W := W * V2*CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit', M,$ K, ONE, V( 1, N-K+1 ), LDV, WORK, LDWORK )** C1 := C1 - W*DO 240 J = 1, KDO 230 I = 1, MC( I, N-K+J ) = C( I, N-K+J ) - WORK( I, J )230 CONTINUE240 CONTINUE*END IF*END IFEND IF*RETURN** End of DLARFB*END*> \brief \b DLARFG generates an elementary reflector (Householder matrix).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARFG + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarfg.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarfg.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarfg.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU )** .. Scalar Arguments ..* INTEGER INCX, N* DOUBLE PRECISION ALPHA, TAU* ..* .. Array Arguments ..* DOUBLE PRECISION X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARFG generates a real elementary reflector H of order n, such*> that*>*> H * ( alpha ) = ( beta ), H**T * H = I.*> ( x ) ( 0 )*>*> where alpha and beta are scalars, and x is an (n-1)-element real*> vector. H is represented in the form*>*> H = I - tau * ( 1 ) * ( 1 v**T ) ,*> ( v )*>*> where tau is a real scalar and v is a real (n-1)-element*> vector.*>*> If the elements of x are all zero, then tau = 0 and H is taken to be*> the unit matrix.*>*> Otherwise 1 <= tau <= 2.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the elementary reflector.*> \endverbatim*>*> \param[in,out] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> On entry, the value alpha.*> On exit, it is overwritten with the value beta.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension*> (1+(N-2)*abs(INCX))*> On entry, the vector x.*> On exit, it is overwritten with the vector v.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between elements of X. INCX > 0.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The value tau.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER INCX, NDOUBLE PRECISION ALPHA, TAU* ..* .. Array Arguments ..DOUBLE PRECISION X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER J, KNTDOUBLE PRECISION BETA, RSAFMN, SAFMIN, XNORM* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2, DNRM2EXTERNAL DLAMCH, DLAPY2, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN* ..* .. External Subroutines ..EXTERNAL DSCAL* ..* .. Executable Statements ..*IF( N.LE.1 ) THENTAU = ZERORETURNEND IF*XNORM = DNRM2( N-1, X, INCX )*IF( XNORM.EQ.ZERO ) THEN** H = I*TAU = ZEROELSE** general case*BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' )KNT = 0IF( ABS( BETA ).LT.SAFMIN ) THEN** XNORM, BETA may be inaccurate; scale X and recompute them*RSAFMN = ONE / SAFMIN10 CONTINUEKNT = KNT + 1CALL DSCAL( N-1, RSAFMN, X, INCX )BETA = BETA*RSAFMNALPHA = ALPHA*RSAFMNIF( (ABS( BETA ).LT.SAFMIN) .AND. (KNT .LT. 20) )$ GO TO 10** New BETA is at most 1, at least SAFMIN*XNORM = DNRM2( N-1, X, INCX )BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )END IFTAU = ( BETA-ALPHA ) / BETACALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )** If ALPHA is subnormal, it may lose relative accuracy*DO 20 J = 1, KNTBETA = BETA*SAFMIN20 CONTINUEALPHA = BETAEND IF*RETURN** End of DLARFG*END*> \brief \b DLARFGP generates an elementary reflector (Householder matrix) with non-negative beta.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARFGP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarfgp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarfgp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarfgp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARFGP( N, ALPHA, X, INCX, TAU )** .. Scalar Arguments ..* INTEGER INCX, N* DOUBLE PRECISION ALPHA, TAU* ..* .. Array Arguments ..* DOUBLE PRECISION X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARFGP generates a real elementary reflector H of order n, such*> that*>*> H * ( alpha ) = ( beta ), H**T * H = I.*> ( x ) ( 0 )*>*> where alpha and beta are scalars, beta is non-negative, and x is*> an (n-1)-element real vector. H is represented in the form*>*> H = I - tau * ( 1 ) * ( 1 v**T ) ,*> ( v )*>*> where tau is a real scalar and v is a real (n-1)-element*> vector.*>*> If the elements of x are all zero, then tau = 0 and H is taken to be*> the unit matrix.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the elementary reflector.*> \endverbatim*>*> \param[in,out] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> On entry, the value alpha.*> On exit, it is overwritten with the value beta.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension*> (1+(N-2)*abs(INCX))*> On entry, the vector x.*> On exit, it is overwritten with the vector v.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between elements of X. INCX > 0.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The value tau.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLARFGP( N, ALPHA, X, INCX, TAU )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER INCX, NDOUBLE PRECISION ALPHA, TAU* ..* .. Array Arguments ..DOUBLE PRECISION X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION TWO, ONE, ZEROPARAMETER ( TWO = 2.0D+0, ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER J, KNTDOUBLE PRECISION BETA, BIGNUM, SAVEALPHA, SMLNUM, XNORM* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2, DNRM2EXTERNAL DLAMCH, DLAPY2, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN* ..* .. External Subroutines ..EXTERNAL DSCAL* ..* .. Executable Statements ..*IF( N.LE.0 ) THENTAU = ZERORETURNEND IF*XNORM = DNRM2( N-1, X, INCX )*IF( XNORM.EQ.ZERO ) THEN** H = [+/-1, 0; I], sign chosen so ALPHA >= 0*IF( ALPHA.GE.ZERO ) THEN* When TAU.eq.ZERO, the vector is special-cased to be* all zeros in the application routines. We do not need* to clear it.TAU = ZEROELSE* However, the application routines rely on explicit* zero checks when TAU.ne.ZERO, and we must clear X.TAU = TWODO J = 1, N-1X( 1 + (J-1)*INCX ) = 0END DOALPHA = -ALPHAEND IFELSE** general case*BETA = SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'E' )KNT = 0IF( ABS( BETA ).LT.SMLNUM ) THEN** XNORM, BETA may be inaccurate; scale X and recompute them*BIGNUM = ONE / SMLNUM10 CONTINUEKNT = KNT + 1CALL DSCAL( N-1, BIGNUM, X, INCX )BETA = BETA*BIGNUMALPHA = ALPHA*BIGNUMIF( (ABS( BETA ).LT.SMLNUM) .AND. (KNT .LT. 20) )$ GO TO 10** New BETA is at most 1, at least SMLNUM*XNORM = DNRM2( N-1, X, INCX )BETA = SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )END IFSAVEALPHA = ALPHAALPHA = ALPHA + BETAIF( BETA.LT.ZERO ) THENBETA = -BETATAU = -ALPHA / BETAELSEALPHA = XNORM * (XNORM/ALPHA)TAU = ALPHA / BETAALPHA = -ALPHAEND IF*IF ( ABS(TAU).LE.SMLNUM ) THEN** In the case where the computed TAU ends up being a denormalized number,* it loses relative accuracy. This is a BIG problem. Solution: flush TAU* to ZERO. This explains the next IF statement.** (Bug report provided by Pat Quillen from MathWorks on Jul 29, 2009.)* (Thanks Pat. Thanks MathWorks.)*IF( SAVEALPHA.GE.ZERO ) THENTAU = ZEROELSETAU = TWODO J = 1, N-1X( 1 + (J-1)*INCX ) = 0END DOBETA = -SAVEALPHAEND IF*ELSE** This is the general case.*CALL DSCAL( N-1, ONE / ALPHA, X, INCX )*END IF** If BETA is subnormal, it may lose relative accuracy*DO 20 J = 1, KNTBETA = BETA*SMLNUM20 CONTINUEALPHA = BETAEND IF*RETURN** End of DLARFGP*END*> \brief \b DLARFT forms the triangular factor T of a block reflector H = I - vtvH** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARFT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarft.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarft.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarft.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )** .. Scalar Arguments ..* CHARACTER DIRECT, STOREV* INTEGER K, LDT, LDV, N* ..* .. Array Arguments ..* DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARFT forms the triangular factor T of a real block reflector H*> of order n, which is defined as a product of k elementary reflectors.*>*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;*>*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.*>*> If STOREV = 'C', the vector which defines the elementary reflector*> H(i) is stored in the i-th column of the array V, and*>*> H = I - V * T * V**T*>*> If STOREV = 'R', the vector which defines the elementary reflector*> H(i) is stored in the i-th row of the array V, and*>*> H = I - V**T * T * V*> \endverbatim** Arguments:* ==========**> \param[in] DIRECT*> \verbatim*> DIRECT is CHARACTER*1*> Specifies the order in which the elementary reflectors are*> multiplied to form the block reflector:*> = 'F': H = H(1) H(2) . . . H(k) (Forward)*> = 'B': H = H(k) . . . H(2) H(1) (Backward)*> \endverbatim*>*> \param[in] STOREV*> \verbatim*> STOREV is CHARACTER*1*> Specifies how the vectors which define the elementary*> reflectors are stored (see also Further Details):*> = 'C': columnwise*> = 'R': rowwise*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the block reflector H. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The order of the triangular factor T (= the number of*> elementary reflectors). K >= 1.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension*> (LDV,K) if STOREV = 'C'*> (LDV,N) if STOREV = 'R'*> The matrix V. See further details.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The k by k triangular factor T of the block reflector.*> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is*> lower triangular. The rest of the array is not used.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= K.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The shape of the matrix V and the storage of the vectors which define*> the H(i) is best illustrated by the following example with n = 5 and*> k = 3. The elements equal to 1 are not stored.*>*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':*>*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )*> ( v1 1 ) ( 1 v2 v2 v2 )*> ( v1 v2 1 ) ( 1 v3 v3 )*> ( v1 v2 v3 )*> ( v1 v2 v3 )*>*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':*>*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )*> ( v1 v2 v3 ) ( v2 v2 v2 1 )*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )*> ( 1 v3 )*> ( 1 )*> \endverbatim*>* =====================================================================SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIRECT, STOREVINTEGER K, LDT, LDV, N* ..* .. Array Arguments ..DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, PREVLASTV, LASTV* ..* .. External Subroutines ..EXTERNAL DGEMV, DTRMV* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( LSAME( DIRECT, 'F' ) ) THENPREVLASTV = NDO I = 1, KPREVLASTV = MAX( I, PREVLASTV )IF( TAU( I ).EQ.ZERO ) THEN** H(i) = I*DO J = 1, IT( J, I ) = ZEROEND DOELSE** general case*IF( LSAME( STOREV, 'C' ) ) THEN* Skip any trailing zeros.DO LASTV = N, I+1, -1IF( V( LASTV, I ).NE.ZERO ) EXITEND DODO J = 1, I-1T( J, I ) = -TAU( I ) * V( I , J )END DOJ = MIN( LASTV, PREVLASTV )** T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)**T * V(i:j,i)*CALL DGEMV( 'Transpose', J-I, I-1, -TAU( I ),$ V( I+1, 1 ), LDV, V( I+1, I ), 1, ONE,$ T( 1, I ), 1 )ELSE* Skip any trailing zeros.DO LASTV = N, I+1, -1IF( V( I, LASTV ).NE.ZERO ) EXITEND DODO J = 1, I-1T( J, I ) = -TAU( I ) * V( J , I )END DOJ = MIN( LASTV, PREVLASTV )** T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)**T*CALL DGEMV( 'No transpose', I-1, J-I, -TAU( I ),$ V( 1, I+1 ), LDV, V( I, I+1 ), LDV, ONE,$ T( 1, I ), 1 )END IF** T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)*CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,$ LDT, T( 1, I ), 1 )T( I, I ) = TAU( I )IF( I.GT.1 ) THENPREVLASTV = MAX( PREVLASTV, LASTV )ELSEPREVLASTV = LASTVEND IFEND IFEND DOELSEPREVLASTV = 1DO I = K, 1, -1IF( TAU( I ).EQ.ZERO ) THEN** H(i) = I*DO J = I, KT( J, I ) = ZEROEND DOELSE** general case*IF( I.LT.K ) THENIF( LSAME( STOREV, 'C' ) ) THEN* Skip any leading zeros.DO LASTV = 1, I-1IF( V( LASTV, I ).NE.ZERO ) EXITEND DODO J = I+1, KT( J, I ) = -TAU( I ) * V( N-K+I , J )END DOJ = MAX( LASTV, PREVLASTV )** T(i+1:k,i) = -tau(i) * V(j:n-k+i,i+1:k)**T * V(j:n-k+i,i)*CALL DGEMV( 'Transpose', N-K+I-J, K-I, -TAU( I ),$ V( J, I+1 ), LDV, V( J, I ), 1, ONE,$ T( I+1, I ), 1 )ELSE* Skip any leading zeros.DO LASTV = 1, I-1IF( V( I, LASTV ).NE.ZERO ) EXITEND DODO J = I+1, KT( J, I ) = -TAU( I ) * V( J, N-K+I )END DOJ = MAX( LASTV, PREVLASTV )** T(i+1:k,i) = -tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)**T*CALL DGEMV( 'No transpose', K-I, N-K+I-J,$ -TAU( I ), V( I+1, J ), LDV, V( I, J ), LDV,$ ONE, T( I+1, I ), 1 )END IF** T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)*CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,$ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )IF( I.GT.1 ) THENPREVLASTV = MIN( PREVLASTV, LASTV )ELSEPREVLASTV = LASTVEND IFEND IFT( I, I ) = TAU( I )END IFEND DOEND IFRETURN** End of DLARFT*END*> \brief \b DLARFX applies an elementary reflector to a general rectangular matrix, with loop unrolling when the reflector has order ≤ 10.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARFX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarfx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarfx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarfx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )** .. Scalar Arguments ..* CHARACTER SIDE* INTEGER LDC, M, N* DOUBLE PRECISION TAU* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARFX applies a real elementary reflector H to a real m by n*> matrix C, from either the left or the right. H is represented in the*> form*>*> H = I - tau * v * v**T*>*> where tau is a real scalar and v is a real vector.*>*> If tau = 0, then H is taken to be the unit matrix*>*> This version uses inline code if H has order < 11.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': form H * C*> = 'R': form C * H*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (M) if SIDE = 'L'*> or (N) if SIDE = 'R'*> The vector v in the representation of H.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The value tau in the representation of H.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',*> or C * H if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDA >= (1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L'*> or (M) if SIDE = 'R'*> WORK is not referenced if H has order < 11.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLARFX( SIDE, M, N, V, TAU, C, LDC, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDEINTEGER LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER JDOUBLE PRECISION SUM, T1, T10, T2, T3, T4, T5, T6, T7, T8, T9,$ V1, V10, V2, V3, V4, V5, V6, V7, V8, V9* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF* ..* .. Executable Statements ..*IF( TAU.EQ.ZERO )$ RETURNIF( LSAME( SIDE, 'L' ) ) THEN** Form H * C, where H has order m.*GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,$ 170, 190 )M** Code for general M*CALL DLARF( SIDE, M, N, V, 1, TAU, C, LDC, WORK )GO TO 41010 CONTINUE** Special code for 1 x 1 Householder*T1 = ONE - TAU*V( 1 )*V( 1 )DO 20 J = 1, NC( 1, J ) = T1*C( 1, J )20 CONTINUEGO TO 41030 CONTINUE** Special code for 2 x 2 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2DO 40 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T240 CONTINUEGO TO 41050 CONTINUE** Special code for 3 x 3 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3DO 60 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T360 CONTINUEGO TO 41070 CONTINUE** Special code for 4 x 4 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4DO 80 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T480 CONTINUEGO TO 41090 CONTINUE** Special code for 5 x 5 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5DO 100 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5100 CONTINUEGO TO 410110 CONTINUE** Special code for 6 x 6 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6DO 120 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6120 CONTINUEGO TO 410130 CONTINUE** Special code for 7 x 7 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7DO 140 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7140 CONTINUEGO TO 410150 CONTINUE** Special code for 8 x 8 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8DO 160 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J ) + V8*C( 8, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7C( 8, J ) = C( 8, J ) - SUM*T8160 CONTINUEGO TO 410170 CONTINUE** Special code for 9 x 9 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9DO 180 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7C( 8, J ) = C( 8, J ) - SUM*T8C( 9, J ) = C( 9, J ) - SUM*T9180 CONTINUEGO TO 410190 CONTINUE** Special code for 10 x 10 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9V10 = V( 10 )T10 = TAU*V10DO 200 J = 1, NSUM = V1*C( 1, J ) + V2*C( 2, J ) + V3*C( 3, J ) +$ V4*C( 4, J ) + V5*C( 5, J ) + V6*C( 6, J ) +$ V7*C( 7, J ) + V8*C( 8, J ) + V9*C( 9, J ) +$ V10*C( 10, J )C( 1, J ) = C( 1, J ) - SUM*T1C( 2, J ) = C( 2, J ) - SUM*T2C( 3, J ) = C( 3, J ) - SUM*T3C( 4, J ) = C( 4, J ) - SUM*T4C( 5, J ) = C( 5, J ) - SUM*T5C( 6, J ) = C( 6, J ) - SUM*T6C( 7, J ) = C( 7, J ) - SUM*T7C( 8, J ) = C( 8, J ) - SUM*T8C( 9, J ) = C( 9, J ) - SUM*T9C( 10, J ) = C( 10, J ) - SUM*T10200 CONTINUEGO TO 410ELSE** Form C * H, where H has order n.*GO TO ( 210, 230, 250, 270, 290, 310, 330, 350,$ 370, 390 )N** Code for general N*CALL DLARF( SIDE, M, N, V, 1, TAU, C, LDC, WORK )GO TO 410210 CONTINUE** Special code for 1 x 1 Householder*T1 = ONE - TAU*V( 1 )*V( 1 )DO 220 J = 1, MC( J, 1 ) = T1*C( J, 1 )220 CONTINUEGO TO 410230 CONTINUE** Special code for 2 x 2 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2DO 240 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2240 CONTINUEGO TO 410250 CONTINUE** Special code for 3 x 3 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3DO 260 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3260 CONTINUEGO TO 410270 CONTINUE** Special code for 4 x 4 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4DO 280 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4280 CONTINUEGO TO 410290 CONTINUE** Special code for 5 x 5 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5DO 300 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5300 CONTINUEGO TO 410310 CONTINUE** Special code for 6 x 6 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6DO 320 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6320 CONTINUEGO TO 410330 CONTINUE** Special code for 7 x 7 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7DO 340 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7340 CONTINUEGO TO 410350 CONTINUE** Special code for 8 x 8 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8DO 360 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 ) + V8*C( J, 8 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7C( J, 8 ) = C( J, 8 ) - SUM*T8360 CONTINUEGO TO 410370 CONTINUE** Special code for 9 x 9 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9DO 380 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7C( J, 8 ) = C( J, 8 ) - SUM*T8C( J, 9 ) = C( J, 9 ) - SUM*T9380 CONTINUEGO TO 410390 CONTINUE** Special code for 10 x 10 Householder*V1 = V( 1 )T1 = TAU*V1V2 = V( 2 )T2 = TAU*V2V3 = V( 3 )T3 = TAU*V3V4 = V( 4 )T4 = TAU*V4V5 = V( 5 )T5 = TAU*V5V6 = V( 6 )T6 = TAU*V6V7 = V( 7 )T7 = TAU*V7V8 = V( 8 )T8 = TAU*V8V9 = V( 9 )T9 = TAU*V9V10 = V( 10 )T10 = TAU*V10DO 400 J = 1, MSUM = V1*C( J, 1 ) + V2*C( J, 2 ) + V3*C( J, 3 ) +$ V4*C( J, 4 ) + V5*C( J, 5 ) + V6*C( J, 6 ) +$ V7*C( J, 7 ) + V8*C( J, 8 ) + V9*C( J, 9 ) +$ V10*C( J, 10 )C( J, 1 ) = C( J, 1 ) - SUM*T1C( J, 2 ) = C( J, 2 ) - SUM*T2C( J, 3 ) = C( J, 3 ) - SUM*T3C( J, 4 ) = C( J, 4 ) - SUM*T4C( J, 5 ) = C( J, 5 ) - SUM*T5C( J, 6 ) = C( J, 6 ) - SUM*T6C( J, 7 ) = C( J, 7 ) - SUM*T7C( J, 8 ) = C( J, 8 ) - SUM*T8C( J, 9 ) = C( J, 9 ) - SUM*T9C( J, 10 ) = C( J, 10 ) - SUM*T10400 CONTINUEGO TO 410END IF410 CONTINUERETURN** End of DLARFX*END*> \brief \b DLARGV generates a vector of plane rotations with real cosines and real sines.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARGV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlargv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlargv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlargv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARGV( N, X, INCX, Y, INCY, C, INCC )** .. Scalar Arguments ..* INTEGER INCC, INCX, INCY, N* ..* .. Array Arguments ..* DOUBLE PRECISION C( * ), X( * ), Y( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARGV generates a vector of real plane rotations, determined by*> elements of the real vectors x and y. For i = 1,2,...,n*>*> ( c(i) s(i) ) ( x(i) ) = ( a(i) )*> ( -s(i) c(i) ) ( y(i) ) = ( 0 )*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of plane rotations to be generated.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCX)*> On entry, the vector x.*> On exit, x(i) is overwritten by a(i), for i = 1,...,n.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between elements of X. INCX > 0.*> \endverbatim*>*> \param[in,out] Y*> \verbatim*> Y is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCY)*> On entry, the vector y.*> On exit, the sines of the plane rotations.*> \endverbatim*>*> \param[in] INCY*> \verbatim*> INCY is INTEGER*> The increment between elements of Y. INCY > 0.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (1+(N-1)*INCC)*> The cosines of the plane rotations.*> \endverbatim*>*> \param[in] INCC*> \verbatim*> INCC is INTEGER*> The increment between elements of C. INCC > 0.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLARGV( N, X, INCX, Y, INCY, C, INCC )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INCC, INCX, INCY, N* ..* .. Array Arguments ..DOUBLE PRECISION C( * ), X( * ), Y( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, IC, IX, IYDOUBLE PRECISION F, G, T, TT* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IX = 1IY = 1IC = 1DO 10 I = 1, NF = X( IX )G = Y( IY )IF( G.EQ.ZERO ) THENC( IC ) = ONEELSE IF( F.EQ.ZERO ) THENC( IC ) = ZEROY( IY ) = ONEX( IX ) = GELSE IF( ABS( F ).GT.ABS( G ) ) THENT = G / FTT = SQRT( ONE+T*T )C( IC ) = ONE / TTY( IY ) = T*C( IC )X( IX ) = F*TTELSET = F / GTT = SQRT( ONE+T*T )Y( IY ) = ONE / TTC( IC ) = T*Y( IY )X( IX ) = G*TTEND IFIC = IC + INCCIY = IY + INCYIX = IX + INCX10 CONTINUERETURN** End of DLARGV*END*> \brief \b DLARNV returns a vector of random numbers from a uniform or normal distribution.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARNV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarnv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarnv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarnv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARNV( IDIST, ISEED, N, X )** .. Scalar Arguments ..* INTEGER IDIST, N* ..* .. Array Arguments ..* INTEGER ISEED( 4 )* DOUBLE PRECISION X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARNV returns a vector of n random real numbers from a uniform or*> normal distribution.*> \endverbatim** Arguments:* ==========**> \param[in] IDIST*> \verbatim*> IDIST is INTEGER*> Specifies the distribution of the random numbers:*> = 1: uniform (0,1)*> = 2: uniform (-1,1)*> = 3: normal (0,1)*> \endverbatim*>*> \param[in,out] ISEED*> \verbatim*> ISEED is INTEGER array, dimension (4)*> On entry, the seed of the random number generator; the array*> elements must be between 0 and 4095, and ISEED(4) must be*> odd.*> On exit, the seed is updated.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of random numbers to be generated.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> The generated random numbers.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> This routine calls the auxiliary routine DLARUV to generate random*> real numbers from a uniform (0,1) distribution, in batches of up to*> 128 using vectorisable code. The Box-Muller method is used to*> transform numbers from a uniform to a normal distribution.*> \endverbatim*>* =====================================================================SUBROUTINE DLARNV( IDIST, ISEED, N, X )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IDIST, N* ..* .. Array Arguments ..INTEGER ISEED( 4 )DOUBLE PRECISION X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, TWOPARAMETER ( ONE = 1.0D+0, TWO = 2.0D+0 )INTEGER LVPARAMETER ( LV = 128 )DOUBLE PRECISION TWOPIPARAMETER ( TWOPI = 6.2831853071795864769252867663D+0 )* ..* .. Local Scalars ..INTEGER I, IL, IL2, IV* ..* .. Local Arrays ..DOUBLE PRECISION U( LV )* ..* .. Intrinsic Functions ..INTRINSIC COS, LOG, MIN, SQRT* ..* .. External Subroutines ..EXTERNAL DLARUV* ..* .. Executable Statements ..*DO 40 IV = 1, N, LV / 2IL = MIN( LV / 2, N-IV+1 )IF( IDIST.EQ.3 ) THENIL2 = 2*ILELSEIL2 = ILEND IF** Call DLARUV to generate IL2 numbers from a uniform (0,1)* distribution (IL2 <= LV)*CALL DLARUV( ISEED, IL2, U )*IF( IDIST.EQ.1 ) THEN** Copy generated numbers*DO 10 I = 1, ILX( IV+I-1 ) = U( I )10 CONTINUEELSE IF( IDIST.EQ.2 ) THEN** Convert generated numbers to uniform (-1,1) distribution*DO 20 I = 1, ILX( IV+I-1 ) = TWO*U( I ) - ONE20 CONTINUEELSE IF( IDIST.EQ.3 ) THEN** Convert generated numbers to normal (0,1) distribution*DO 30 I = 1, ILX( IV+I-1 ) = SQRT( -TWO*LOG( U( 2*I-1 ) ) )*$ COS( TWOPI*U( 2*I ) )30 CONTINUEEND IF40 CONTINUERETURN** End of DLARNV*END*> \brief \b DLARRA computes the splitting points with the specified threshold.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarra.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarra.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarra.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRA( N, D, E, E2, SPLTOL, TNRM,* NSPLIT, ISPLIT, INFO )** .. Scalar Arguments ..* INTEGER INFO, N, NSPLIT* DOUBLE PRECISION SPLTOL, TNRM* ..* .. Array Arguments ..* INTEGER ISPLIT( * )* DOUBLE PRECISION D( * ), E( * ), E2( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Compute the splitting points with threshold SPLTOL.*> DLARRA sets any "small" off-diagonal elements to zero.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N > 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the N diagonal elements of the tridiagonal*> matrix T.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> On entry, the first (N-1) entries contain the subdiagonal*> elements of the tridiagonal matrix T; E(N) need not be set.*> On exit, the entries E( ISPLIT( I ) ), 1 <= I <= NSPLIT,*> are set to zero, the other entries of E are untouched.*> \endverbatim*>*> \param[in,out] E2*> \verbatim*> E2 is DOUBLE PRECISION array, dimension (N)*> On entry, the first (N-1) entries contain the SQUARES of the*> subdiagonal elements of the tridiagonal matrix T;*> E2(N) need not be set.*> On exit, the entries E2( ISPLIT( I ) ),*> 1 <= I <= NSPLIT, have been set to zero*> \endverbatim*>*> \param[in] SPLTOL*> \verbatim*> SPLTOL is DOUBLE PRECISION*> The threshold for splitting. Two criteria can be used:*> SPLTOL<0 : criterion based on absolute off-diagonal value*> SPLTOL>0 : criterion that preserves relative accuracy*> \endverbatim*>*> \param[in] TNRM*> \verbatim*> TNRM is DOUBLE PRECISION*> The norm of the matrix.*> \endverbatim*>*> \param[out] NSPLIT*> \verbatim*> NSPLIT is INTEGER*> The number of blocks T splits into. 1 <= NSPLIT <= N.*> \endverbatim*>*> \param[out] ISPLIT*> \verbatim*> ISPLIT is INTEGER array, dimension (N)*> The splitting points, at which T breaks up into blocks.*> The first block consists of rows/columns 1 to ISPLIT(1),*> the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),*> etc., and the NSPLIT-th consists of rows/columns*> ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRA( N, D, E, E2, SPLTOL, TNRM,$ NSPLIT, ISPLIT, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, N, NSPLITDOUBLE PRECISION SPLTOL, TNRM* ..* .. Array Arguments ..INTEGER ISPLIT( * )DOUBLE PRECISION D( * ), E( * ), E2( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION EABS, TMP1* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF** Compute splitting pointsNSPLIT = 1IF(SPLTOL.LT.ZERO) THEN* Criterion based on absolute off-diagonal valueTMP1 = ABS(SPLTOL)* TNRMDO 9 I = 1, N-1EABS = ABS( E(I) )IF( EABS .LE. TMP1) THENE(I) = ZEROE2(I) = ZEROISPLIT( NSPLIT ) = INSPLIT = NSPLIT + 1END IF9 CONTINUEELSE* Criterion that guarantees relative accuracyDO 10 I = 1, N-1EABS = ABS( E(I) )IF( EABS .LE. SPLTOL * SQRT(ABS(D(I)))*SQRT(ABS(D(I+1))) )$ THENE(I) = ZEROE2(I) = ZEROISPLIT( NSPLIT ) = INSPLIT = NSPLIT + 1END IF10 CONTINUEENDIFISPLIT( NSPLIT ) = NRETURN** End of DLARRA*END*> \brief \b DLARRB provides limited bisection to locate eigenvalues for more accuracy.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRB( N, D, LLD, IFIRST, ILAST, RTOL1,* RTOL2, OFFSET, W, WGAP, WERR, WORK, IWORK,* PIVMIN, SPDIAM, TWIST, INFO )** .. Scalar Arguments ..* INTEGER IFIRST, ILAST, INFO, N, OFFSET, TWIST* DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPDIAM* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION D( * ), LLD( * ), W( * ),* $ WERR( * ), WGAP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Given the relatively robust representation(RRR) L D L^T, DLARRB*> does "limited" bisection to refine the eigenvalues of L D L^T,*> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial*> guesses for these eigenvalues are input in W, the corresponding estimate*> of the error in these guesses and their gaps are input in WERR*> and WGAP, respectively. During bisection, intervals*> [left, right] are maintained by storing their mid-points and*> semi-widths in the arrays W and WERR respectively.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The N diagonal elements of the diagonal matrix D.*> \endverbatim*>*> \param[in] LLD*> \verbatim*> LLD is DOUBLE PRECISION array, dimension (N-1)*> The (N-1) elements L(i)*L(i)*D(i).*> \endverbatim*>*> \param[in] IFIRST*> \verbatim*> IFIRST is INTEGER*> The index of the first eigenvalue to be computed.*> \endverbatim*>*> \param[in] ILAST*> \verbatim*> ILAST is INTEGER*> The index of the last eigenvalue to be computed.*> \endverbatim*>*> \param[in] RTOL1*> \verbatim*> RTOL1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] RTOL2*> \verbatim*> RTOL2 is DOUBLE PRECISION*> Tolerance for the convergence of the bisection intervals.*> An interval [LEFT,RIGHT] has converged if*> RIGHT-LEFT.LT.MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )*> where GAP is the (estimated) distance to the nearest*> eigenvalue.*> \endverbatim*>*> \param[in] OFFSET*> \verbatim*> OFFSET is INTEGER*> Offset for the arrays W, WGAP and WERR, i.e., the IFIRST-OFFSET*> through ILAST-OFFSET elements of these arrays are to be used.*> \endverbatim*>*> \param[in,out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are*> estimates of the eigenvalues of L D L^T indexed IFIRST through*> ILAST.*> On output, these estimates are refined.*> \endverbatim*>*> \param[in,out] WGAP*> \verbatim*> WGAP is DOUBLE PRECISION array, dimension (N-1)*> On input, the (estimated) gaps between consecutive*> eigenvalues of L D L^T, i.e., WGAP(I-OFFSET) is the gap between*> eigenvalues I and I+1. Note that if IFIRST.EQ.ILAST*> then WGAP(IFIRST-OFFSET) must be set to ZERO.*> On output, these gaps are refined.*> \endverbatim*>*> \param[in,out] WERR*> \verbatim*> WERR is DOUBLE PRECISION array, dimension (N)*> On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are*> the errors in the estimates of the corresponding elements in W.*> On output, these errors are refined.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> Workspace.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (2*N)*> Workspace.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot in the Sturm sequence.*> \endverbatim*>*> \param[in] SPDIAM*> \verbatim*> SPDIAM is DOUBLE PRECISION*> The spectral diameter of the matrix.*> \endverbatim*>*> \param[in] TWIST*> \verbatim*> TWIST is INTEGER*> The twist index for the twisted factorization that is used*> for the negcount.*> TWIST = N: Compute negcount from L D L^T - LAMBDA I = L+ D+ L+^T*> TWIST = 1: Compute negcount from L D L^T - LAMBDA I = U- D- U-^T*> TWIST = R: Compute negcount from L D L^T - LAMBDA I = N(r) D(r) N(r)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> Error flag.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRB( N, D, LLD, IFIRST, ILAST, RTOL1,$ RTOL2, OFFSET, W, WGAP, WERR, WORK, IWORK,$ PIVMIN, SPDIAM, TWIST, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER IFIRST, ILAST, INFO, N, OFFSET, TWISTDOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPDIAM* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), LLD( * ), W( * ),$ WERR( * ), WGAP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, TWO, HALFPARAMETER ( ZERO = 0.0D0, TWO = 2.0D0,$ HALF = 0.5D0 )INTEGER MAXITR* ..* .. Local Scalars ..INTEGER I, I1, II, IP, ITER, K, NEGCNT, NEXT, NINT,$ OLNINT, PREV, RDOUBLE PRECISION BACK, CVRGD, GAP, LEFT, LGAP, MID, MNWDTH,$ RGAP, RIGHT, TMP, WIDTH* ..* .. External Functions ..INTEGER DLANEGEXTERNAL DLANEG** ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF*MAXITR = INT( ( LOG( SPDIAM+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2MNWDTH = TWO * PIVMIN*R = TWISTIF((R.LT.1).OR.(R.GT.N)) R = N** Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )* for an unconverged interval is set to the index of the next unconverged* interval, and is -1 or 0 for a converged interval. Thus a linked* list of unconverged intervals is set up.*I1 = IFIRST* The number of unconverged intervalsNINT = 0* The last unconverged interval foundPREV = 0RGAP = WGAP( I1-OFFSET )DO 75 I = I1, ILASTK = 2*III = I - OFFSETLEFT = W( II ) - WERR( II )RIGHT = W( II ) + WERR( II )LGAP = RGAPRGAP = WGAP( II )GAP = MIN( LGAP, RGAP )* Make sure that [LEFT,RIGHT] contains the desired eigenvalue* Compute negcount from dstqds facto L+D+L+^T = L D L^T - LEFT** Do while( NEGCNT(LEFT).GT.I-1 )*BACK = WERR( II )20 CONTINUENEGCNT = DLANEG( N, D, LLD, LEFT, PIVMIN, R )IF( NEGCNT.GT.I-1 ) THENLEFT = LEFT - BACKBACK = TWO*BACKGO TO 20END IF** Do while( NEGCNT(RIGHT).LT.I )* Compute negcount from dstqds facto L+D+L+^T = L D L^T - RIGHT*BACK = WERR( II )50 CONTINUENEGCNT = DLANEG( N, D, LLD, RIGHT, PIVMIN, R )IF( NEGCNT.LT.I ) THENRIGHT = RIGHT + BACKBACK = TWO*BACKGO TO 50END IFWIDTH = HALF*ABS( LEFT - RIGHT )TMP = MAX( ABS( LEFT ), ABS( RIGHT ) )CVRGD = MAX(RTOL1*GAP,RTOL2*TMP)IF( WIDTH.LE.CVRGD .OR. WIDTH.LE.MNWDTH ) THEN* This interval has already converged and does not need refinement.* (Note that the gaps might change through refining the* eigenvalues, however, they can only get bigger.)* Remove it from the list.IWORK( K-1 ) = -1* Make sure that I1 always points to the first unconverged intervalIF((I.EQ.I1).AND.(I.LT.ILAST)) I1 = I + 1IF((PREV.GE.I1).AND.(I.LE.ILAST)) IWORK( 2*PREV-1 ) = I + 1ELSE* unconverged interval foundPREV = ININT = NINT + 1IWORK( K-1 ) = I + 1IWORK( K ) = NEGCNTEND IFWORK( K-1 ) = LEFTWORK( K ) = RIGHT75 CONTINUE** Do while( NINT.GT.0 ), i.e. there are still unconverged intervals* and while (ITER.LT.MAXITR)*ITER = 080 CONTINUEPREV = I1 - 1I = I1OLNINT = NINTDO 100 IP = 1, OLNINTK = 2*III = I - OFFSETRGAP = WGAP( II )LGAP = RGAPIF(II.GT.1) LGAP = WGAP( II-1 )GAP = MIN( LGAP, RGAP )NEXT = IWORK( K-1 )LEFT = WORK( K-1 )RIGHT = WORK( K )MID = HALF*( LEFT + RIGHT )* semiwidth of intervalWIDTH = RIGHT - MIDTMP = MAX( ABS( LEFT ), ABS( RIGHT ) )CVRGD = MAX(RTOL1*GAP,RTOL2*TMP)IF( ( WIDTH.LE.CVRGD ) .OR. ( WIDTH.LE.MNWDTH ).OR.$ ( ITER.EQ.MAXITR ) )THEN* reduce number of unconverged intervalsNINT = NINT - 1* Mark interval as converged.IWORK( K-1 ) = 0IF( I1.EQ.I ) THENI1 = NEXTELSE* Prev holds the last unconverged interval previously examinedIF(PREV.GE.I1) IWORK( 2*PREV-1 ) = NEXTEND IFI = NEXTGO TO 100END IFPREV = I** Perform one bisection step*NEGCNT = DLANEG( N, D, LLD, MID, PIVMIN, R )IF( NEGCNT.LE.I-1 ) THENWORK( K-1 ) = MIDELSEWORK( K ) = MIDEND IFI = NEXT100 CONTINUEITER = ITER + 1* do another loop if there are still unconverged intervals* However, in the last iteration, all intervals are accepted* since this is the best we can do.IF( ( NINT.GT.0 ).AND.(ITER.LE.MAXITR) ) GO TO 80*** At this point, all the intervals have convergedDO 110 I = IFIRST, ILASTK = 2*III = I - OFFSET* All intervals marked by '0' have been refined.IF( IWORK( K-1 ).EQ.0 ) THENW( II ) = HALF*( WORK( K-1 )+WORK( K ) )WERR( II ) = WORK( K ) - W( II )END IF110 CONTINUE*DO 111 I = IFIRST+1, ILASTK = 2*III = I - OFFSETWGAP( II-1 ) = MAX( ZERO,$ W(II) - WERR (II) - W( II-1 ) - WERR( II-1 ))111 CONTINUERETURN** End of DLARRB*END*> \brief \b DLARRC computes the number of eigenvalues of the symmetric tridiagonal matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRC( JOBT, N, VL, VU, D, E, PIVMIN,* EIGCNT, LCNT, RCNT, INFO )** .. Scalar Arguments ..* CHARACTER JOBT* INTEGER EIGCNT, INFO, LCNT, N, RCNT* DOUBLE PRECISION PIVMIN, VL, VU* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Find the number of eigenvalues of the symmetric tridiagonal matrix T*> that are in the interval (VL,VU] if JOBT = 'T', and of L D L^T*> if JOBT = 'L'.*> \endverbatim** Arguments:* ==========**> \param[in] JOBT*> \verbatim*> JOBT is CHARACTER*1*> = 'T': Compute Sturm count for matrix T.*> = 'L': Compute Sturm count for matrix L D L^T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N > 0.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> The lower bound for the eigenvalues.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> The upper bound for the eigenvalues.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> JOBT = 'T': The N diagonal elements of the tridiagonal matrix T.*> JOBT = 'L': The N diagonal elements of the diagonal matrix D.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> JOBT = 'T': The N-1 offdiagonal elements of the matrix T.*> JOBT = 'L': The N-1 offdiagonal elements of the matrix L.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot in the Sturm sequence for T.*> \endverbatim*>*> \param[out] EIGCNT*> \verbatim*> EIGCNT is INTEGER*> The number of eigenvalues of the symmetric tridiagonal matrix T*> that are in the interval (VL,VU]*> \endverbatim*>*> \param[out] LCNT*> \verbatim*> LCNT is INTEGER*> \endverbatim*>*> \param[out] RCNT*> \verbatim*> RCNT is INTEGER*> The left and right negcounts of the interval.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRC( JOBT, N, VL, VU, D, E, PIVMIN,$ EIGCNT, LCNT, RCNT, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBTINTEGER EIGCNT, INFO, LCNT, N, RCNTDOUBLE PRECISION PIVMIN, VL, VU* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER ILOGICAL MATTDOUBLE PRECISION LPIVOT, RPIVOT, SL, SU, TMP, TMP2* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF*LCNT = 0RCNT = 0EIGCNT = 0MATT = LSAME( JOBT, 'T' )IF (MATT) THEN* Sturm sequence count on TLPIVOT = D( 1 ) - VLRPIVOT = D( 1 ) - VUIF( LPIVOT.LE.ZERO ) THENLCNT = LCNT + 1ENDIFIF( RPIVOT.LE.ZERO ) THENRCNT = RCNT + 1ENDIFDO 10 I = 1, N-1TMP = E(I)**2LPIVOT = ( D( I+1 )-VL ) - TMP/LPIVOTRPIVOT = ( D( I+1 )-VU ) - TMP/RPIVOTIF( LPIVOT.LE.ZERO ) THENLCNT = LCNT + 1ENDIFIF( RPIVOT.LE.ZERO ) THENRCNT = RCNT + 1ENDIF10 CONTINUEELSE* Sturm sequence count on L D L^TSL = -VLSU = -VUDO 20 I = 1, N - 1LPIVOT = D( I ) + SLRPIVOT = D( I ) + SUIF( LPIVOT.LE.ZERO ) THENLCNT = LCNT + 1ENDIFIF( RPIVOT.LE.ZERO ) THENRCNT = RCNT + 1ENDIFTMP = E(I) * D(I) * E(I)*TMP2 = TMP / LPIVOTIF( TMP2.EQ.ZERO ) THENSL = TMP - VLELSESL = SL*TMP2 - VLEND IF*TMP2 = TMP / RPIVOTIF( TMP2.EQ.ZERO ) THENSU = TMP - VUELSESU = SU*TMP2 - VUEND IF20 CONTINUELPIVOT = D( N ) + SLRPIVOT = D( N ) + SUIF( LPIVOT.LE.ZERO ) THENLCNT = LCNT + 1ENDIFIF( RPIVOT.LE.ZERO ) THENRCNT = RCNT + 1ENDIFENDIFEIGCNT = RCNT - LCNTRETURN** end of DLARRC*END*> \brief \b DLARRD computes the eigenvalues of a symmetric tridiagonal matrix to suitable accuracy.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRD( RANGE, ORDER, N, VL, VU, IL, IU, GERS,* RELTOL, D, E, E2, PIVMIN, NSPLIT, ISPLIT,* M, W, WERR, WL, WU, IBLOCK, INDEXW,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER ORDER, RANGE* INTEGER IL, INFO, IU, M, N, NSPLIT* DOUBLE PRECISION PIVMIN, RELTOL, VL, VU, WL, WU* ..* .. Array Arguments ..* INTEGER IBLOCK( * ), INDEXW( * ),* $ ISPLIT( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), E2( * ),* $ GERS( * ), W( * ), WERR( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARRD computes the eigenvalues of a symmetric tridiagonal*> matrix T to suitable accuracy. This is an auxiliary code to be*> called from DSTEMR.*> The user may ask for all eigenvalues, all eigenvalues*> in the half-open interval (VL, VU], or the IL-th through IU-th*> eigenvalues.*>*> To avoid overflow, the matrix must be scaled so that its*> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest*> accuracy, it should not be much smaller than that.*>*> See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal*> Matrix", Report CS41, Computer Science Dept., Stanford*> University, July 21, 1966.*> \endverbatim** Arguments:* ==========**> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': ("All") all eigenvalues will be found.*> = 'V': ("Value") all eigenvalues in the half-open interval*> (VL, VU] will be found.*> = 'I': ("Index") the IL-th through IU-th eigenvalues (of the*> entire matrix) will be found.*> \endverbatim*>*> \param[in] ORDER*> \verbatim*> ORDER is CHARACTER*1*> = 'B': ("By Block") the eigenvalues will be grouped by*> split-off block (see IBLOCK, ISPLIT) and*> ordered from smallest to largest within*> the block.*> = 'E': ("Entire matrix")*> the eigenvalues for the entire matrix*> will be ordered from smallest to*> largest.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the tridiagonal matrix T. N >= 0.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. Eigenvalues less than or equal*> to VL, or greater than VU, will not be returned. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. Eigenvalues less than or equal*> to VL, or greater than VU, will not be returned. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] GERS*> \verbatim*> GERS is DOUBLE PRECISION array, dimension (2*N)*> The N Gerschgorin intervals (the i-th Gerschgorin interval*> is (GERS(2*i-1), GERS(2*i)).*> \endverbatim*>*> \param[in] RELTOL*> \verbatim*> RELTOL is DOUBLE PRECISION*> The minimum relative width of an interval. When an interval*> is narrower than RELTOL times the larger (in*> magnitude) endpoint, then it is considered to be*> sufficiently small, i.e., converged. Note: this should*> always be at least radix*machine epsilon.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) off-diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] E2*> \verbatim*> E2 is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) squared off-diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot allowed in the Sturm sequence for T.*> \endverbatim*>*> \param[in] NSPLIT*> \verbatim*> NSPLIT is INTEGER*> The number of diagonal blocks in the matrix T.*> 1 <= NSPLIT <= N.*> \endverbatim*>*> \param[in] ISPLIT*> \verbatim*> ISPLIT is INTEGER array, dimension (N)*> The splitting points, at which T breaks up into submatrices.*> The first submatrix consists of rows/columns 1 to ISPLIT(1),*> the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),*> etc., and the NSPLIT-th consists of rows/columns*> ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.*> (Only the first NSPLIT elements will actually be used, but*> since the user cannot know a priori what value NSPLIT will*> have, N words must be reserved for ISPLIT.)*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The actual number of eigenvalues found. 0 <= M <= N.*> (See also the description of INFO=2,3.)*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On exit, the first M elements of W will contain the*> eigenvalue approximations. DLARRD computes an interval*> I_j = (a_j, b_j] that includes eigenvalue j. The eigenvalue*> approximation is given as the interval midpoint*> W(j)= ( a_j + b_j)/2. The corresponding error is bounded by*> WERR(j) = abs( a_j - b_j)/2*> \endverbatim*>*> \param[out] WERR*> \verbatim*> WERR is DOUBLE PRECISION array, dimension (N)*> The error bound on the corresponding eigenvalue approximation*> in W.*> \endverbatim*>*> \param[out] WL*> \verbatim*> WL is DOUBLE PRECISION*> \endverbatim*>*> \param[out] WU*> \verbatim*> WU is DOUBLE PRECISION*> The interval (WL, WU] contains all the wanted eigenvalues.*> If RANGE='V', then WL=VL and WU=VU.*> If RANGE='A', then WL and WU are the global Gerschgorin bounds*> on the spectrum.*> If RANGE='I', then WL and WU are computed by DLAEBZ from the*> index range specified.*> \endverbatim*>*> \param[out] IBLOCK*> \verbatim*> IBLOCK is INTEGER array, dimension (N)*> At each row/column j where E(j) is zero or small, the*> matrix T is considered to split into a block diagonal*> matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which*> block (from 1 to the number of blocks) the eigenvalue W(i)*> belongs. (DLARRD may use the remaining N-M elements as*> workspace.)*> \endverbatim*>*> \param[out] INDEXW*> \verbatim*> INDEXW is INTEGER array, dimension (N)*> The indices of the eigenvalues within each block (submatrix);*> for example, INDEXW(i)= j and IBLOCK(i)=k imply that the*> i-th eigenvalue W(i) is the j-th eigenvalue in block k.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: some or all of the eigenvalues failed to converge or*> were not computed:*> =1 or 3: Bisection failed to converge for some*> eigenvalues; these eigenvalues are flagged by a*> negative block number. The effect is that the*> eigenvalues may not be as accurate as the*> absolute and relative tolerances. This is*> generally caused by unexpectedly inaccurate*> arithmetic.*> =2 or 3: RANGE='I' only: Not all of the eigenvalues*> IL:IU were found.*> Effect: M < IU+1-IL*> Cause: non-monotonic arithmetic, causing the*> Sturm sequence to be non-monotonic.*> Cure: recalculate, using RANGE='A', and pick*> out eigenvalues IL:IU. In some cases,*> increasing the PARAMETER "FUDGE" may*> make things work.*> = 4: RANGE='I', and the Gershgorin interval*> initially used was too small. No eigenvalues*> were computed.*> Probable cause: your machine has sloppy*> floating-point arithmetic.*> Cure: Increase the PARAMETER "FUDGE",*> recompile, and try again.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> FUDGE DOUBLE PRECISION, default = 2*> A "fudge factor" to widen the Gershgorin intervals. Ideally,*> a value of 1 should work, but on machines with sloppy*> arithmetic, this needs to be larger. The default for*> publicly released versions should be large enough to handle*> the worst machine around. Note that this has no effect*> on accuracy of the solution.*> \endverbatim*>*> \par Contributors:* ==================*>*> W. Kahan, University of California, Berkeley, USA \n*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA \n** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLARRD( RANGE, ORDER, N, VL, VU, IL, IU, GERS,$ RELTOL, D, E, E2, PIVMIN, NSPLIT, ISPLIT,$ M, W, WERR, WL, WU, IBLOCK, INDEXW,$ WORK, IWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER ORDER, RANGEINTEGER IL, INFO, IU, M, N, NSPLITDOUBLE PRECISION PIVMIN, RELTOL, VL, VU, WL, WU* ..* .. Array Arguments ..INTEGER IBLOCK( * ), INDEXW( * ),$ ISPLIT( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), E2( * ),$ GERS( * ), W( * ), WERR( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, HALF, FUDGEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, HALF = ONE/TWO,$ FUDGE = TWO )INTEGER ALLRNG, VALRNG, INDRNGPARAMETER ( ALLRNG = 1, VALRNG = 2, INDRNG = 3 )* ..* .. Local Scalars ..LOGICAL NCNVRG, TOOFEWINTEGER I, IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,$ IM, IN, IOFF, IOUT, IRANGE, ITMAX, ITMP1,$ ITMP2, IW, IWOFF, J, JBLK, JDISC, JE, JEE, NB,$ NWL, NWUDOUBLE PRECISION ATOLI, EPS, GL, GU, RTOLI, TMP1, TMP2,$ TNORM, UFLOW, WKILL, WLU, WUL* ..* .. Local Arrays ..INTEGER IDUMMA( 1 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCHEXTERNAL LSAME, ILAENV, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLAEBZ* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, MIN* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF** Decode RANGE*IF( LSAME( RANGE, 'A' ) ) THENIRANGE = ALLRNGELSE IF( LSAME( RANGE, 'V' ) ) THENIRANGE = VALRNGELSE IF( LSAME( RANGE, 'I' ) ) THENIRANGE = INDRNGELSEIRANGE = 0END IF** Check for Errors*IF( IRANGE.LE.0 ) THENINFO = -1ELSE IF( .NOT.(LSAME(ORDER,'B').OR.LSAME(ORDER,'E')) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( IRANGE.EQ.VALRNG ) THENIF( VL.GE.VU )$ INFO = -5ELSE IF( IRANGE.EQ.INDRNG .AND.$ ( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) ) THENINFO = -6ELSE IF( IRANGE.EQ.INDRNG .AND.$ ( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) ) THENINFO = -7END IF*IF( INFO.NE.0 ) THENRETURNEND IF* Initialize error flagsINFO = 0NCNVRG = .FALSE.TOOFEW = .FALSE.* Quick return if possibleM = 0IF( N.EQ.0 ) RETURN* Simplification:IF( IRANGE.EQ.INDRNG .AND. IL.EQ.1 .AND. IU.EQ.N ) IRANGE = 1* Get machine constantsEPS = DLAMCH( 'P' )UFLOW = DLAMCH( 'U' )* Special Case when N=1* Treat case of 1x1 matrix for quick returnIF( N.EQ.1 ) THENIF( (IRANGE.EQ.ALLRNG).OR.$ ((IRANGE.EQ.VALRNG).AND.(D(1).GT.VL).AND.(D(1).LE.VU)).OR.$ ((IRANGE.EQ.INDRNG).AND.(IL.EQ.1).AND.(IU.EQ.1)) ) THENM = 1W(1) = D(1)* The computation error of the eigenvalue is zeroWERR(1) = ZEROIBLOCK( 1 ) = 1INDEXW( 1 ) = 1ENDIFRETURNEND IF* NB is the minimum vector length for vector bisection, or 0* if only scalar is to be done.NB = ILAENV( 1, 'DSTEBZ', ' ', N, -1, -1, -1 )IF( NB.LE.1 ) NB = 0* Find global spectral radiusGL = D(1)GU = D(1)DO 5 I = 1,NGL = MIN( GL, GERS( 2*I - 1))GU = MAX( GU, GERS(2*I) )5 CONTINUE* Compute global Gerschgorin bounds and spectral diameterTNORM = MAX( ABS( GL ), ABS( GU ) )GL = GL - FUDGE*TNORM*EPS*N - FUDGE*TWO*PIVMINGU = GU + FUDGE*TNORM*EPS*N + FUDGE*TWO*PIVMIN* [JAN/28/2009] remove the line below since SPDIAM variable not use* SPDIAM = GU - GL* Input arguments for DLAEBZ:* The relative tolerance. An interval (a,b] lies within* "relative tolerance" if b-a < RELTOL*max(|a|,|b|),RTOLI = RELTOL* Set the absolute tolerance for interval convergence to zero to force* interval convergence based on relative size of the interval.* This is dangerous because intervals might not converge when RELTOL is* small. But at least a very small number should be selected so that for* strongly graded matrices, the code can get relatively accurate* eigenvalues.ATOLI = FUDGE*TWO*UFLOW + FUDGE*TWO*PIVMINIF( IRANGE.EQ.INDRNG ) THEN* RANGE='I': Compute an interval containing eigenvalues* IL through IU. The initial interval [GL,GU] from the global* Gerschgorin bounds GL and GU is refined by DLAEBZ.ITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2WORK( N+1 ) = GLWORK( N+2 ) = GLWORK( N+3 ) = GUWORK( N+4 ) = GUWORK( N+5 ) = GLWORK( N+6 ) = GUIWORK( 1 ) = -1IWORK( 2 ) = -1IWORK( 3 ) = N + 1IWORK( 4 ) = N + 1IWORK( 5 ) = IL - 1IWORK( 6 ) = IU*CALL DLAEBZ( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN,$ D, E, E2, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,$ IWORK, W, IBLOCK, IINFO )IF( IINFO .NE. 0 ) THENINFO = IINFORETURNEND IF* On exit, output intervals may not be ordered by ascending negcountIF( IWORK( 6 ).EQ.IU ) THENWL = WORK( N+1 )WLU = WORK( N+3 )NWL = IWORK( 1 )WU = WORK( N+4 )WUL = WORK( N+2 )NWU = IWORK( 4 )ELSEWL = WORK( N+2 )WLU = WORK( N+4 )NWL = IWORK( 2 )WU = WORK( N+3 )WUL = WORK( N+1 )NWU = IWORK( 3 )END IF* On exit, the interval [WL, WLU] contains a value with negcount NWL,* and [WUL, WU] contains a value with negcount NWU.IF( NWL.LT.0 .OR. NWL.GE.N .OR. NWU.LT.1 .OR. NWU.GT.N ) THENINFO = 4RETURNEND IFELSEIF( IRANGE.EQ.VALRNG ) THENWL = VLWU = VUELSEIF( IRANGE.EQ.ALLRNG ) THENWL = GLWU = GUENDIF* Find Eigenvalues -- Loop Over blocks and recompute NWL and NWU.* NWL accumulates the number of eigenvalues .le. WL,* NWU accumulates the number of eigenvalues .le. WUM = 0IEND = 0INFO = 0NWL = 0NWU = 0*DO 70 JBLK = 1, NSPLITIOFF = IENDIBEGIN = IOFF + 1IEND = ISPLIT( JBLK )IN = IEND - IOFF*IF( IN.EQ.1 ) THEN* 1x1 blockIF( WL.GE.D( IBEGIN )-PIVMIN )$ NWL = NWL + 1IF( WU.GE.D( IBEGIN )-PIVMIN )$ NWU = NWU + 1IF( IRANGE.EQ.ALLRNG .OR.$ ( WL.LT.D( IBEGIN )-PIVMIN$ .AND. WU.GE. D( IBEGIN )-PIVMIN ) ) THENM = M + 1W( M ) = D( IBEGIN )WERR(M) = ZERO* The gap for a single block doesn't matter for the later* algorithm and is assigned an arbitrary large valueIBLOCK( M ) = JBLKINDEXW( M ) = 1END IF* Disabled 2x2 case because of a failure on the following matrix* RANGE = 'I', IL = IU = 4* Original Tridiagonal, d = [* -0.150102010615740E+00* -0.849897989384260E+00* -0.128208148052635E-15* 0.128257718286320E-15* ];* e = [* -0.357171383266986E+00* -0.180411241501588E-15* -0.175152352710251E-15* ];** ELSE IF( IN.EQ.2 ) THEN** 2x2 block* DISC = SQRT( (HALF*(D(IBEGIN)-D(IEND)))**2 + E(IBEGIN)**2 )* TMP1 = HALF*(D(IBEGIN)+D(IEND))* L1 = TMP1 - DISC* IF( WL.GE. L1-PIVMIN )* $ NWL = NWL + 1* IF( WU.GE. L1-PIVMIN )* $ NWU = NWU + 1* IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L1-PIVMIN .AND. WU.GE.* $ L1-PIVMIN ) ) THEN* M = M + 1* W( M ) = L1** The uncertainty of eigenvalues of a 2x2 matrix is very small* WERR( M ) = EPS * ABS( W( M ) ) * TWO* IBLOCK( M ) = JBLK* INDEXW( M ) = 1* ENDIF* L2 = TMP1 + DISC* IF( WL.GE. L2-PIVMIN )* $ NWL = NWL + 1* IF( WU.GE. L2-PIVMIN )* $ NWU = NWU + 1* IF( IRANGE.EQ.ALLRNG .OR. ( WL.LT.L2-PIVMIN .AND. WU.GE.* $ L2-PIVMIN ) ) THEN* M = M + 1* W( M ) = L2** The uncertainty of eigenvalues of a 2x2 matrix is very small* WERR( M ) = EPS * ABS( W( M ) ) * TWO* IBLOCK( M ) = JBLK* INDEXW( M ) = 2* ENDIFELSE* General Case - block of size IN >= 2* Compute local Gerschgorin interval and use it as the initial* interval for DLAEBZGU = D( IBEGIN )GL = D( IBEGIN )TMP1 = ZERODO 40 J = IBEGIN, IENDGL = MIN( GL, GERS( 2*J - 1))GU = MAX( GU, GERS(2*J) )40 CONTINUE* [JAN/28/2009]* change SPDIAM by TNORM in lines 2 and 3 thereafter* line 1: remove computation of SPDIAM (not useful anymore)* SPDIAM = GU - GL* GL = GL - FUDGE*SPDIAM*EPS*IN - FUDGE*PIVMIN* GU = GU + FUDGE*SPDIAM*EPS*IN + FUDGE*PIVMINGL = GL - FUDGE*TNORM*EPS*IN - FUDGE*PIVMINGU = GU + FUDGE*TNORM*EPS*IN + FUDGE*PIVMIN*IF( IRANGE.GT.1 ) THENIF( GU.LT.WL ) THEN* the local block contains none of the wanted eigenvaluesNWL = NWL + INNWU = NWU + INGO TO 70END IF* refine search interval if possible, only range (WL,WU] mattersGL = MAX( GL, WL )GU = MIN( GU, WU )IF( GL.GE.GU )$ GO TO 70END IF* Find negcount of initial interval boundaries GL and GUWORK( N+1 ) = GLWORK( N+IN+1 ) = GUCALL DLAEBZ( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,$ D( IBEGIN ), E( IBEGIN ), E2( IBEGIN ),$ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,$ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )IF( IINFO .NE. 0 ) THENINFO = IINFORETURNEND IF*NWL = NWL + IWORK( 1 )NWU = NWU + IWORK( IN+1 )IWOFF = M - IWORK( 1 )* Compute EigenvaluesITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2CALL DLAEBZ( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,$ D( IBEGIN ), E( IBEGIN ), E2( IBEGIN ),$ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,$ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )IF( IINFO .NE. 0 ) THENINFO = IINFORETURNEND IF** Copy eigenvalues into W and IBLOCK* Use -JBLK for block number for unconverged eigenvalues.* Loop over the number of output intervals from DLAEBZDO 60 J = 1, IOUT* eigenvalue approximation is middle point of intervalTMP1 = HALF*( WORK( J+N )+WORK( J+IN+N ) )* semi length of error intervalTMP2 = HALF*ABS( WORK( J+N )-WORK( J+IN+N ) )IF( J.GT.IOUT-IINFO ) THEN* Flag non-convergence.NCNVRG = .TRUE.IB = -JBLKELSEIB = JBLKEND IFDO 50 JE = IWORK( J ) + 1 + IWOFF,$ IWORK( J+IN ) + IWOFFW( JE ) = TMP1WERR( JE ) = TMP2INDEXW( JE ) = JE - IWOFFIBLOCK( JE ) = IB50 CONTINUE60 CONTINUE*M = M + IMEND IF70 CONTINUE* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU* If NWL+1 < IL or NWU > IU, discard extra eigenvalues.IF( IRANGE.EQ.INDRNG ) THENIDISCL = IL - 1 - NWLIDISCU = NWU - IU*IF( IDISCL.GT.0 ) THENIM = 0DO 80 JE = 1, M* Remove some of the smallest eigenvalues from the left so that* at the end IDISCL =0. Move all eigenvalues up to the left.IF( W( JE ).LE.WLU .AND. IDISCL.GT.0 ) THENIDISCL = IDISCL - 1ELSEIM = IM + 1W( IM ) = W( JE )WERR( IM ) = WERR( JE )INDEXW( IM ) = INDEXW( JE )IBLOCK( IM ) = IBLOCK( JE )END IF80 CONTINUEM = IMEND IFIF( IDISCU.GT.0 ) THEN* Remove some of the largest eigenvalues from the right so that* at the end IDISCU =0. Move all eigenvalues up to the left.IM=M+1DO 81 JE = M, 1, -1IF( W( JE ).GE.WUL .AND. IDISCU.GT.0 ) THENIDISCU = IDISCU - 1ELSEIM = IM - 1W( IM ) = W( JE )WERR( IM ) = WERR( JE )INDEXW( IM ) = INDEXW( JE )IBLOCK( IM ) = IBLOCK( JE )END IF81 CONTINUEJEE = 0DO 82 JE = IM, MJEE = JEE + 1W( JEE ) = W( JE )WERR( JEE ) = WERR( JE )INDEXW( JEE ) = INDEXW( JE )IBLOCK( JEE ) = IBLOCK( JE )82 CONTINUEM = M-IM+1END IFIF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN* Code to deal with effects of bad arithmetic. (If N(w) is* monotone non-decreasing, this should never happen.)* Some low eigenvalues to be discarded are not in (WL,WLU],* or high eigenvalues to be discarded are not in (WUL,WU]* so just kill off the smallest IDISCL/largest IDISCU* eigenvalues, by marking the corresponding IBLOCK = 0IF( IDISCL.GT.0 ) THENWKILL = WUDO 100 JDISC = 1, IDISCLIW = 0DO 90 JE = 1, MIF( IBLOCK( JE ).NE.0 .AND.$ ( W( JE ).LT.WKILL .OR. IW.EQ.0 ) ) THENIW = JEWKILL = W( JE )END IF90 CONTINUEIBLOCK( IW ) = 0100 CONTINUEEND IFIF( IDISCU.GT.0 ) THENWKILL = WLDO 120 JDISC = 1, IDISCUIW = 0DO 110 JE = 1, MIF( IBLOCK( JE ).NE.0 .AND.$ ( W( JE ).GE.WKILL .OR. IW.EQ.0 ) ) THENIW = JEWKILL = W( JE )END IF110 CONTINUEIBLOCK( IW ) = 0120 CONTINUEEND IF* Now erase all eigenvalues with IBLOCK set to zeroIM = 0DO 130 JE = 1, MIF( IBLOCK( JE ).NE.0 ) THENIM = IM + 1W( IM ) = W( JE )WERR( IM ) = WERR( JE )INDEXW( IM ) = INDEXW( JE )IBLOCK( IM ) = IBLOCK( JE )END IF130 CONTINUEM = IMEND IFIF( IDISCL.LT.0 .OR. IDISCU.LT.0 ) THENTOOFEW = .TRUE.END IFEND IF*IF(( IRANGE.EQ.ALLRNG .AND. M.NE.N ).OR.$ ( IRANGE.EQ.INDRNG .AND. M.NE.IU-IL+1 ) ) THENTOOFEW = .TRUE.END IF* If ORDER='B', do nothing the eigenvalues are already sorted by* block.* If ORDER='E', sort the eigenvalues from smallest to largestIF( LSAME(ORDER,'E') .AND. NSPLIT.GT.1 ) THENDO 150 JE = 1, M - 1IE = 0TMP1 = W( JE )DO 140 J = JE + 1, MIF( W( J ).LT.TMP1 ) THENIE = JTMP1 = W( J )END IF140 CONTINUEIF( IE.NE.0 ) THENTMP2 = WERR( IE )ITMP1 = IBLOCK( IE )ITMP2 = INDEXW( IE )W( IE ) = W( JE )WERR( IE ) = WERR( JE )IBLOCK( IE ) = IBLOCK( JE )INDEXW( IE ) = INDEXW( JE )W( JE ) = TMP1WERR( JE ) = TMP2IBLOCK( JE ) = ITMP1INDEXW( JE ) = ITMP2END IF150 CONTINUEEND IF*INFO = 0IF( NCNVRG )$ INFO = INFO + 1IF( TOOFEW )$ INFO = INFO + 2RETURN** End of DLARRD*END*> \brief \b DLARRE given the tridiagonal matrix T, sets small off-diagonal elements to zero and for each unreduced block Ti, finds base representations and eigenvalues.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRE + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarre.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarre.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarre.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRE( RANGE, N, VL, VU, IL, IU, D, E, E2,* RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,* W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER RANGE* INTEGER IL, INFO, IU, M, N, NSPLIT* DOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),* $ INDEXW( * )* DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),* $ W( * ),WERR( * ), WGAP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> To find the desired eigenvalues of a given real symmetric*> tridiagonal matrix T, DLARRE sets any "small" off-diagonal*> elements to zero, and for each unreduced block T_i, it finds*> (a) a suitable shift at one end of the block's spectrum,*> (b) the base representation, T_i - sigma_i I = L_i D_i L_i^T, and*> (c) eigenvalues of each L_i D_i L_i^T.*> The representations and eigenvalues found are then used by*> DSTEMR to compute the eigenvectors of T.*> The accuracy varies depending on whether bisection is used to*> find a few eigenvalues or the dqds algorithm (subroutine DLASQ2) to*> conpute all and then discard any unwanted one.*> As an added benefit, DLARRE also outputs the n*> Gerschgorin intervals for the matrices L_i D_i L_i^T.*> \endverbatim** Arguments:* ==========**> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': ("All") all eigenvalues will be found.*> = 'V': ("Value") all eigenvalues in the half-open interval*> (VL, VU] will be found.*> = 'I': ("Index") the IL-th through IU-th eigenvalues (of the*> entire matrix) will be found.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N > 0.*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound for the eigenvalues.*> Eigenvalues less than or equal to VL, or greater than VU,*> will not be returned. VL < VU.*> If RANGE='I' or ='A', DLARRE computes bounds on the desired*> part of the spectrum.*> \endverbatim*>*> \param[in,out] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound for the eigenvalues.*> Eigenvalues less than or equal to VL, or greater than VU,*> will not be returned. VL < VU.*> If RANGE='I' or ='A', DLARRE computes bounds on the desired*> part of the spectrum.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the N diagonal elements of the tridiagonal*> matrix T.*> On exit, the N diagonal elements of the diagonal*> matrices D_i.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> On entry, the first (N-1) entries contain the subdiagonal*> elements of the tridiagonal matrix T; E(N) need not be set.*> On exit, E contains the subdiagonal elements of the unit*> bidiagonal matrices L_i. The entries E( ISPLIT( I ) ),*> 1 <= I <= NSPLIT, contain the base points sigma_i on output.*> \endverbatim*>*> \param[in,out] E2*> \verbatim*> E2 is DOUBLE PRECISION array, dimension (N)*> On entry, the first (N-1) entries contain the SQUARES of the*> subdiagonal elements of the tridiagonal matrix T;*> E2(N) need not be set.*> On exit, the entries E2( ISPLIT( I ) ),*> 1 <= I <= NSPLIT, have been set to zero*> \endverbatim*>*> \param[in] RTOL1*> \verbatim*> RTOL1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] RTOL2*> \verbatim*> RTOL2 is DOUBLE PRECISION*> Parameters for bisection.*> An interval [LEFT,RIGHT] has converged if*> RIGHT-LEFT.LT.MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )*> \endverbatim*>*> \param[in] SPLTOL*> \verbatim*> SPLTOL is DOUBLE PRECISION*> The threshold for splitting.*> \endverbatim*>*> \param[out] NSPLIT*> \verbatim*> NSPLIT is INTEGER*> The number of blocks T splits into. 1 <= NSPLIT <= N.*> \endverbatim*>*> \param[out] ISPLIT*> \verbatim*> ISPLIT is INTEGER array, dimension (N)*> The splitting points, at which T breaks up into blocks.*> The first block consists of rows/columns 1 to ISPLIT(1),*> the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),*> etc., and the NSPLIT-th consists of rows/columns*> ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues (of all L_i D_i L_i^T)*> found.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the eigenvalues. The*> eigenvalues of each of the blocks, L_i D_i L_i^T, are*> sorted in ascending order ( DLARRE may use the*> remaining N-M elements as workspace).*> \endverbatim*>*> \param[out] WERR*> \verbatim*> WERR is DOUBLE PRECISION array, dimension (N)*> The error bound on the corresponding eigenvalue in W.*> \endverbatim*>*> \param[out] WGAP*> \verbatim*> WGAP is DOUBLE PRECISION array, dimension (N)*> The separation from the right neighbor eigenvalue in W.*> The gap is only with respect to the eigenvalues of the same block*> as each block has its own representation tree.*> Exception: at the right end of a block we store the left gap*> \endverbatim*>*> \param[out] IBLOCK*> \verbatim*> IBLOCK is INTEGER array, dimension (N)*> The indices of the blocks (submatrices) associated with the*> corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue*> W(i) belongs to the first block from the top, =2 if W(i)*> belongs to the second block, etc.*> \endverbatim*>*> \param[out] INDEXW*> \verbatim*> INDEXW is INTEGER array, dimension (N)*> The indices of the eigenvalues within each block (submatrix);*> for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the*> i-th eigenvalue W(i) is the 10-th eigenvalue in block 2*> \endverbatim*>*> \param[out] GERS*> \verbatim*> GERS is DOUBLE PRECISION array, dimension (2*N)*> The N Gerschgorin intervals (the i-th Gerschgorin interval*> is (GERS(2*i-1), GERS(2*i)).*> \endverbatim*>*> \param[out] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot in the Sturm sequence for T.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (6*N)*> Workspace.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> Workspace.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> > 0: A problem occurred in DLARRE.*> < 0: One of the called subroutines signaled an internal problem.*> Needs inspection of the corresponding parameter IINFO*> for further information.*>*> =-1: Problem in DLARRD.*> = 2: No base representation could be found in MAXTRY iterations.*> Increasing MAXTRY and recompilation might be a remedy.*> =-3: Problem in DLARRB when computing the refined root*> representation for DLASQ2.*> =-4: Problem in DLARRB when preforming bisection on the*> desired part of the spectrum.*> =-5: Problem in DLASQ2.*> =-6: Problem in DLASQ2.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The base representations are required to suffer very little*> element growth and consequently define all their eigenvalues to*> high relative accuracy.*> \endverbatim**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA \n*>* =====================================================================SUBROUTINE DLARRE( RANGE, N, VL, VU, IL, IU, D, E, E2,$ RTOL1, RTOL2, SPLTOL, NSPLIT, ISPLIT, M,$ W, WERR, WGAP, IBLOCK, INDEXW, GERS, PIVMIN,$ WORK, IWORK, INFO )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER RANGEINTEGER IL, INFO, IU, M, N, NSPLITDOUBLE PRECISION PIVMIN, RTOL1, RTOL2, SPLTOL, VL, VU* ..* .. Array Arguments ..INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * ),$ INDEXW( * )DOUBLE PRECISION D( * ), E( * ), E2( * ), GERS( * ),$ W( * ),WERR( * ), WGAP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION FAC, FOUR, FOURTH, FUDGE, HALF, HNDRD,$ MAXGROWTH, ONE, PERT, TWO, ZEROPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, FOUR=4.0D0,$ HNDRD = 100.0D0,$ PERT = 8.0D0,$ HALF = ONE/TWO, FOURTH = ONE/FOUR, FAC= HALF,$ MAXGROWTH = 64.0D0, FUDGE = 2.0D0 )INTEGER MAXTRY, ALLRNG, INDRNG, VALRNGPARAMETER ( MAXTRY = 6, ALLRNG = 1, INDRNG = 2,$ VALRNG = 3 )* ..* .. Local Scalars ..LOGICAL FORCEB, NOREP, USEDQDINTEGER CNT, CNT1, CNT2, I, IBEGIN, IDUM, IEND, IINFO,$ IN, INDL, INDU, IRANGE, J, JBLK, MB, MM,$ WBEGIN, WENDDOUBLE PRECISION AVGAP, BSRTOL, CLWDTH, DMAX, DPIVOT, EABS,$ EMAX, EOLD, EPS, GL, GU, ISLEFT, ISRGHT, RTL,$ RTOL, S1, S2, SAFMIN, SGNDEF, SIGMA, SPDIAM,$ TAU, TMP, TMP1* ..* .. Local Arrays ..INTEGER ISEED( 4 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL DLAMCH, LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DLARNV, DLARRA, DLARRB, DLARRC, DLARRD,$ DLASQ2, DLARRK* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF** Decode RANGE*IF( LSAME( RANGE, 'A' ) ) THENIRANGE = ALLRNGELSE IF( LSAME( RANGE, 'V' ) ) THENIRANGE = VALRNGELSE IF( LSAME( RANGE, 'I' ) ) THENIRANGE = INDRNGEND IFM = 0* Get machine constantsSAFMIN = DLAMCH( 'S' )EPS = DLAMCH( 'P' )* Set parametersRTL = SQRT(EPS)BSRTOL = SQRT(EPS)* Treat case of 1x1 matrix for quick returnIF( N.EQ.1 ) THENIF( (IRANGE.EQ.ALLRNG).OR.$ ((IRANGE.EQ.VALRNG).AND.(D(1).GT.VL).AND.(D(1).LE.VU)).OR.$ ((IRANGE.EQ.INDRNG).AND.(IL.EQ.1).AND.(IU.EQ.1)) ) THENM = 1W(1) = D(1)* The computation error of the eigenvalue is zeroWERR(1) = ZEROWGAP(1) = ZEROIBLOCK( 1 ) = 1INDEXW( 1 ) = 1GERS(1) = D( 1 )GERS(2) = D( 1 )ENDIF* store the shift for the initial RRR, which is zero in this caseE(1) = ZERORETURNEND IF* General case: tridiagonal matrix of order > 1** Init WERR, WGAP. Compute Gerschgorin intervals and spectral diameter.* Compute maximum off-diagonal entry and pivmin.GL = D(1)GU = D(1)EOLD = ZEROEMAX = ZEROE(N) = ZERODO 5 I = 1,NWERR(I) = ZEROWGAP(I) = ZEROEABS = ABS( E(I) )IF( EABS .GE. EMAX ) THENEMAX = EABSEND IFTMP1 = EABS + EOLDGERS( 2*I-1) = D(I) - TMP1GL = MIN( GL, GERS( 2*I - 1))GERS( 2*I ) = D(I) + TMP1GU = MAX( GU, GERS(2*I) )EOLD = EABS5 CONTINUE* The minimum pivot allowed in the Sturm sequence for TPIVMIN = SAFMIN * MAX( ONE, EMAX**2 )* Compute spectral diameter. The Gerschgorin bounds give an* estimate that is wrong by at most a factor of SQRT(2)SPDIAM = GU - GL* Compute splitting pointsCALL DLARRA( N, D, E, E2, SPLTOL, SPDIAM,$ NSPLIT, ISPLIT, IINFO )* Can force use of bisection instead of faster DQDS.* Option left in the code for future multisection work.FORCEB = .FALSE.* Initialize USEDQD, DQDS should be used for ALLRNG unless someone* explicitly wants bisection.USEDQD = (( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB))IF( (IRANGE.EQ.ALLRNG) .AND. (.NOT. FORCEB) ) THEN* Set interval [VL,VU] that contains all eigenvaluesVL = GLVU = GUELSE* We call DLARRD to find crude approximations to the eigenvalues* in the desired range. In case IRANGE = INDRNG, we also obtain the* interval (VL,VU] that contains all the wanted eigenvalues.* An interval [LEFT,RIGHT] has converged if* RIGHT-LEFT.LT.RTOL*MAX(ABS(LEFT),ABS(RIGHT))* DLARRD needs a WORK of size 4*N, IWORK of size 3*NCALL DLARRD( RANGE, 'B', N, VL, VU, IL, IU, GERS,$ BSRTOL, D, E, E2, PIVMIN, NSPLIT, ISPLIT,$ MM, W, WERR, VL, VU, IBLOCK, INDEXW,$ WORK, IWORK, IINFO )IF( IINFO.NE.0 ) THENINFO = -1RETURNENDIF* Make sure that the entries M+1 to N in W, WERR, IBLOCK, INDEXW are 0DO 14 I = MM+1,NW( I ) = ZEROWERR( I ) = ZEROIBLOCK( I ) = 0INDEXW( I ) = 014 CONTINUEEND IF**** Loop over unreduced blocksIBEGIN = 1WBEGIN = 1DO 170 JBLK = 1, NSPLITIEND = ISPLIT( JBLK )IN = IEND - IBEGIN + 1* 1 X 1 blockIF( IN.EQ.1 ) THENIF( (IRANGE.EQ.ALLRNG).OR.( (IRANGE.EQ.VALRNG).AND.$ ( D( IBEGIN ).GT.VL ).AND.( D( IBEGIN ).LE.VU ) )$ .OR. ( (IRANGE.EQ.INDRNG).AND.(IBLOCK(WBEGIN).EQ.JBLK))$ ) THENM = M + 1W( M ) = D( IBEGIN )WERR(M) = ZERO* The gap for a single block doesn't matter for the later* algorithm and is assigned an arbitrary large valueWGAP(M) = ZEROIBLOCK( M ) = JBLKINDEXW( M ) = 1WBEGIN = WBEGIN + 1ENDIF* E( IEND ) holds the shift for the initial RRRE( IEND ) = ZEROIBEGIN = IEND + 1GO TO 170END IF** Blocks of size larger than 1x1** E( IEND ) will hold the shift for the initial RRR, for now set it =0E( IEND ) = ZERO** Find local outer bounds GL,GU for the blockGL = D(IBEGIN)GU = D(IBEGIN)DO 15 I = IBEGIN , IENDGL = MIN( GERS( 2*I-1 ), GL )GU = MAX( GERS( 2*I ), GU )15 CONTINUESPDIAM = GU - GLIF(.NOT. ((IRANGE.EQ.ALLRNG).AND.(.NOT.FORCEB)) ) THEN* Count the number of eigenvalues in the current block.MB = 0DO 20 I = WBEGIN,MMIF( IBLOCK(I).EQ.JBLK ) THENMB = MB+1ELSEGOTO 21ENDIF20 CONTINUE21 CONTINUEIF( MB.EQ.0) THEN* No eigenvalue in the current block lies in the desired range* E( IEND ) holds the shift for the initial RRRE( IEND ) = ZEROIBEGIN = IEND + 1GO TO 170ELSE* Decide whether dqds or bisection is more efficientUSEDQD = ( (MB .GT. FAC*IN) .AND. (.NOT.FORCEB) )WEND = WBEGIN + MB - 1* Calculate gaps for the current block* In later stages, when representations for individual* eigenvalues are different, we use SIGMA = E( IEND ).SIGMA = ZERODO 30 I = WBEGIN, WEND - 1WGAP( I ) = MAX( ZERO,$ W(I+1)-WERR(I+1) - (W(I)+WERR(I)) )30 CONTINUEWGAP( WEND ) = MAX( ZERO,$ VU - SIGMA - (W( WEND )+WERR( WEND )))* Find local index of the first and last desired evalue.INDL = INDEXW(WBEGIN)INDU = INDEXW( WEND )ENDIFENDIFIF(( (IRANGE.EQ.ALLRNG) .AND. (.NOT. FORCEB) ).OR.USEDQD) THEN* Case of DQDS* Find approximations to the extremal eigenvalues of the blockCALL DLARRK( IN, 1, GL, GU, D(IBEGIN),$ E2(IBEGIN), PIVMIN, RTL, TMP, TMP1, IINFO )IF( IINFO.NE.0 ) THENINFO = -1RETURNENDIFISLEFT = MAX(GL, TMP - TMP1$ - HNDRD * EPS* ABS(TMP - TMP1))CALL DLARRK( IN, IN, GL, GU, D(IBEGIN),$ E2(IBEGIN), PIVMIN, RTL, TMP, TMP1, IINFO )IF( IINFO.NE.0 ) THENINFO = -1RETURNENDIFISRGHT = MIN(GU, TMP + TMP1$ + HNDRD * EPS * ABS(TMP + TMP1))* Improve the estimate of the spectral diameterSPDIAM = ISRGHT - ISLEFTELSE* Case of bisection* Find approximations to the wanted extremal eigenvaluesISLEFT = MAX(GL, W(WBEGIN) - WERR(WBEGIN)$ - HNDRD * EPS*ABS(W(WBEGIN)- WERR(WBEGIN) ))ISRGHT = MIN(GU,W(WEND) + WERR(WEND)$ + HNDRD * EPS * ABS(W(WEND)+ WERR(WEND)))ENDIF* Decide whether the base representation for the current block* L_JBLK D_JBLK L_JBLK^T = T_JBLK - sigma_JBLK I* should be on the left or the right end of the current block.* The strategy is to shift to the end which is "more populated"* Furthermore, decide whether to use DQDS for the computation of* the eigenvalue approximations at the end of DLARRE or bisection.* dqds is chosen if all eigenvalues are desired or the number of* eigenvalues to be computed is large compared to the blocksize.IF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THEN* If all the eigenvalues have to be computed, we use dqdUSEDQD = .TRUE.* INDL is the local index of the first eigenvalue to computeINDL = 1INDU = IN* MB = number of eigenvalues to computeMB = INWEND = WBEGIN + MB - 1* Define 1/4 and 3/4 points of the spectrumS1 = ISLEFT + FOURTH * SPDIAMS2 = ISRGHT - FOURTH * SPDIAMELSE* DLARRD has computed IBLOCK and INDEXW for each eigenvalue* approximation.* choose sigmaIF( USEDQD ) THENS1 = ISLEFT + FOURTH * SPDIAMS2 = ISRGHT - FOURTH * SPDIAMELSETMP = MIN(ISRGHT,VU) - MAX(ISLEFT,VL)S1 = MAX(ISLEFT,VL) + FOURTH * TMPS2 = MIN(ISRGHT,VU) - FOURTH * TMPENDIFENDIF* Compute the negcount at the 1/4 and 3/4 pointsIF(MB.GT.1) THENCALL DLARRC( 'T', IN, S1, S2, D(IBEGIN),$ E(IBEGIN), PIVMIN, CNT, CNT1, CNT2, IINFO)ENDIFIF(MB.EQ.1) THENSIGMA = GLSGNDEF = ONEELSEIF( CNT1 - INDL .GE. INDU - CNT2 ) THENIF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THENSIGMA = MAX(ISLEFT,GL)ELSEIF( USEDQD ) THEN* use Gerschgorin bound as shift to get pos def matrix* for dqdsSIGMA = ISLEFTELSE* use approximation of the first desired eigenvalue of the* block as shiftSIGMA = MAX(ISLEFT,VL)ENDIFSGNDEF = ONEELSEIF( ( IRANGE.EQ.ALLRNG ) .AND. (.NOT.FORCEB) ) THENSIGMA = MIN(ISRGHT,GU)ELSEIF( USEDQD ) THEN* use Gerschgorin bound as shift to get neg def matrix* for dqdsSIGMA = ISRGHTELSE* use approximation of the first desired eigenvalue of the* block as shiftSIGMA = MIN(ISRGHT,VU)ENDIFSGNDEF = -ONEENDIF* An initial SIGMA has been chosen that will be used for computing* T - SIGMA I = L D L^T* Define the increment TAU of the shift in case the initial shift* needs to be refined to obtain a factorization with not too much* element growth.IF( USEDQD ) THEN* The initial SIGMA was to the outer end of the spectrum* the matrix is definite and we need not retreat.TAU = SPDIAM*EPS*N + TWO*PIVMINTAU = MAX( TAU,TWO*EPS*ABS(SIGMA) )ELSEIF(MB.GT.1) THENCLWDTH = W(WEND) + WERR(WEND) - W(WBEGIN) - WERR(WBEGIN)AVGAP = ABS(CLWDTH / DBLE(WEND-WBEGIN))IF( SGNDEF.EQ.ONE ) THENTAU = HALF*MAX(WGAP(WBEGIN),AVGAP)TAU = MAX(TAU,WERR(WBEGIN))ELSETAU = HALF*MAX(WGAP(WEND-1),AVGAP)TAU = MAX(TAU,WERR(WEND))ENDIFELSETAU = WERR(WBEGIN)ENDIFENDIF*DO 80 IDUM = 1, MAXTRY* Compute L D L^T factorization of tridiagonal matrix T - sigma I.* Store D in WORK(1:IN), L in WORK(IN+1:2*IN), and reciprocals of* pivots in WORK(2*IN+1:3*IN)DPIVOT = D( IBEGIN ) - SIGMAWORK( 1 ) = DPIVOTDMAX = ABS( WORK(1) )J = IBEGINDO 70 I = 1, IN - 1WORK( 2*IN+I ) = ONE / WORK( I )TMP = E( J )*WORK( 2*IN+I )WORK( IN+I ) = TMPDPIVOT = ( D( J+1 )-SIGMA ) - TMP*E( J )WORK( I+1 ) = DPIVOTDMAX = MAX( DMAX, ABS(DPIVOT) )J = J + 170 CONTINUE* check for element growthIF( DMAX .GT. MAXGROWTH*SPDIAM ) THENNOREP = .TRUE.ELSENOREP = .FALSE.ENDIFIF( USEDQD .AND. .NOT.NOREP ) THEN* Ensure the definiteness of the representation* All entries of D (of L D L^T) must have the same signDO 71 I = 1, INTMP = SGNDEF*WORK( I )IF( TMP.LT.ZERO ) NOREP = .TRUE.71 CONTINUEENDIFIF(NOREP) THEN* Note that in the case of IRANGE=ALLRNG, we use the Gerschgorin* shift which makes the matrix definite. So we should end up* here really only in the case of IRANGE = VALRNG or INDRNG.IF( IDUM.EQ.MAXTRY-1 ) THENIF( SGNDEF.EQ.ONE ) THEN* The fudged Gerschgorin shift should succeedSIGMA =$ GL - FUDGE*SPDIAM*EPS*N - FUDGE*TWO*PIVMINELSESIGMA =$ GU + FUDGE*SPDIAM*EPS*N + FUDGE*TWO*PIVMINEND IFELSESIGMA = SIGMA - SGNDEF * TAUTAU = TWO * TAUEND IFELSE* an initial RRR is foundGO TO 83END IF80 CONTINUE* if the program reaches this point, no base representation could be* found in MAXTRY iterations.INFO = 2RETURN83 CONTINUE* At this point, we have found an initial base representation* T - SIGMA I = L D L^T with not too much element growth.* Store the shift.E( IEND ) = SIGMA* Store D and L.CALL DCOPY( IN, WORK, 1, D( IBEGIN ), 1 )CALL DCOPY( IN-1, WORK( IN+1 ), 1, E( IBEGIN ), 1 )IF(MB.GT.1 ) THEN** Perturb each entry of the base representation by a small* (but random) relative amount to overcome difficulties with* glued matrices.*DO 122 I = 1, 4ISEED( I ) = 1122 CONTINUECALL DLARNV(2, ISEED, 2*IN-1, WORK(1))DO 125 I = 1,IN-1D(IBEGIN+I-1) = D(IBEGIN+I-1)*(ONE+EPS*PERT*WORK(I))E(IBEGIN+I-1) = E(IBEGIN+I-1)*(ONE+EPS*PERT*WORK(IN+I))125 CONTINUED(IEND) = D(IEND)*(ONE+EPS*FOUR*WORK(IN))*ENDIF** Don't update the Gerschgorin intervals because keeping track* of the updates would be too much work in DLARRV.* We update W instead and use it to locate the proper Gerschgorin* intervals.* Compute the required eigenvalues of L D L' by bisection or dqdsIF ( .NOT.USEDQD ) THEN* If DLARRD has been used, shift the eigenvalue approximations* according to their representation. This is necessary for* a uniform DLARRV since dqds computes eigenvalues of the* shifted representation. In DLARRV, W will always hold the* UNshifted eigenvalue approximation.DO 134 J=WBEGIN,WENDW(J) = W(J) - SIGMAWERR(J) = WERR(J) + ABS(W(J)) * EPS134 CONTINUE* call DLARRB to reduce eigenvalue error of the approximations* from DLARRDDO 135 I = IBEGIN, IEND-1WORK( I ) = D( I ) * E( I )**2135 CONTINUE* use bisection to find EV from INDL to INDUCALL DLARRB(IN, D(IBEGIN), WORK(IBEGIN),$ INDL, INDU, RTOL1, RTOL2, INDL-1,$ W(WBEGIN), WGAP(WBEGIN), WERR(WBEGIN),$ WORK( 2*N+1 ), IWORK, PIVMIN, SPDIAM,$ IN, IINFO )IF( IINFO .NE. 0 ) THENINFO = -4RETURNEND IF* DLARRB computes all gaps correctly except for the last one* Record distance to VU/GUWGAP( WEND ) = MAX( ZERO,$ ( VU-SIGMA ) - ( W( WEND ) + WERR( WEND ) ) )DO 138 I = INDL, INDUM = M + 1IBLOCK(M) = JBLKINDEXW(M) = I138 CONTINUEELSE* Call dqds to get all eigs (and then possibly delete unwanted* eigenvalues).* Note that dqds finds the eigenvalues of the L D L^T representation* of T to high relative accuracy. High relative accuracy* might be lost when the shift of the RRR is subtracted to obtain* the eigenvalues of T. However, T is not guaranteed to define its* eigenvalues to high relative accuracy anyway.* Set RTOL to the order of the tolerance used in DLASQ2* This is an ESTIMATED error, the worst case bound is 4*N*EPS* which is usually too large and requires unnecessary work to be* done by bisection when computing the eigenvectorsRTOL = LOG(DBLE(IN)) * FOUR * EPSJ = IBEGINDO 140 I = 1, IN - 1WORK( 2*I-1 ) = ABS( D( J ) )WORK( 2*I ) = E( J )*E( J )*WORK( 2*I-1 )J = J + 1140 CONTINUEWORK( 2*IN-1 ) = ABS( D( IEND ) )WORK( 2*IN ) = ZEROCALL DLASQ2( IN, WORK, IINFO )IF( IINFO .NE. 0 ) THEN* If IINFO = -5 then an index is part of a tight cluster* and should be changed. The index is in IWORK(1) and the* gap is in WORK(N+1)INFO = -5RETURNELSE* Test that all eigenvalues are positive as expectedDO 149 I = 1, INIF( WORK( I ).LT.ZERO ) THENINFO = -6RETURNENDIF149 CONTINUEEND IFIF( SGNDEF.GT.ZERO ) THENDO 150 I = INDL, INDUM = M + 1W( M ) = WORK( IN-I+1 )IBLOCK( M ) = JBLKINDEXW( M ) = I150 CONTINUEELSEDO 160 I = INDL, INDUM = M + 1W( M ) = -WORK( I )IBLOCK( M ) = JBLKINDEXW( M ) = I160 CONTINUEEND IFDO 165 I = M - MB + 1, M* the value of RTOL below should be the tolerance in DLASQ2WERR( I ) = RTOL * ABS( W(I) )165 CONTINUEDO 166 I = M - MB + 1, M - 1* compute the right gap between the intervalsWGAP( I ) = MAX( ZERO,$ W(I+1)-WERR(I+1) - (W(I)+WERR(I)) )166 CONTINUEWGAP( M ) = MAX( ZERO,$ ( VU-SIGMA ) - ( W( M ) + WERR( M ) ) )END IF* proceed with next blockIBEGIN = IEND + 1WBEGIN = WEND + 1170 CONTINUE*RETURN** end of DLARRE*END*> \brief \b DLARRF finds a new relatively robust representation such that at least one of the eigenvalues is relatively isolated.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRF( N, D, L, LD, CLSTRT, CLEND,* W, WGAP, WERR,* SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,* DPLUS, LPLUS, WORK, INFO )** .. Scalar Arguments ..* INTEGER CLSTRT, CLEND, INFO, N* DOUBLE PRECISION CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), DPLUS( * ), L( * ), LD( * ),* $ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Given the initial representation L D L^T and its cluster of close*> eigenvalues (in a relative measure), W( CLSTRT ), W( CLSTRT+1 ), ...*> W( CLEND ), DLARRF finds a new relatively robust representation*> L D L^T - SIGMA I = L(+) D(+) L(+)^T such that at least one of the*> eigenvalues of L(+) D(+) L(+)^T is relatively isolated.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix (subblock, if the matrix split).*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The N diagonal elements of the diagonal matrix D.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is DOUBLE PRECISION array, dimension (N-1)*> The (N-1) subdiagonal elements of the unit bidiagonal*> matrix L.*> \endverbatim*>*> \param[in] LD*> \verbatim*> LD is DOUBLE PRECISION array, dimension (N-1)*> The (N-1) elements L(i)*D(i).*> \endverbatim*>*> \param[in] CLSTRT*> \verbatim*> CLSTRT is INTEGER*> The index of the first eigenvalue in the cluster.*> \endverbatim*>*> \param[in] CLEND*> \verbatim*> CLEND is INTEGER*> The index of the last eigenvalue in the cluster.*> \endverbatim*>*> \param[in] W*> \verbatim*> W is DOUBLE PRECISION array, dimension*> dimension is >= (CLEND-CLSTRT+1)*> The eigenvalue APPROXIMATIONS of L D L^T in ascending order.*> W( CLSTRT ) through W( CLEND ) form the cluster of relatively*> close eigenalues.*> \endverbatim*>*> \param[in,out] WGAP*> \verbatim*> WGAP is DOUBLE PRECISION array, dimension*> dimension is >= (CLEND-CLSTRT+1)*> The separation from the right neighbor eigenvalue in W.*> \endverbatim*>*> \param[in] WERR*> \verbatim*> WERR is DOUBLE PRECISION array, dimension*> dimension is >= (CLEND-CLSTRT+1)*> WERR contain the semiwidth of the uncertainty*> interval of the corresponding eigenvalue APPROXIMATION in W*> \endverbatim*>*> \param[in] SPDIAM*> \verbatim*> SPDIAM is DOUBLE PRECISION*> estimate of the spectral diameter obtained from the*> Gerschgorin intervals*> \endverbatim*>*> \param[in] CLGAPL*> \verbatim*> CLGAPL is DOUBLE PRECISION*> \endverbatim*>*> \param[in] CLGAPR*> \verbatim*> CLGAPR is DOUBLE PRECISION*> absolute gap on each end of the cluster.*> Set by the calling routine to protect against shifts too close*> to eigenvalues outside the cluster.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot allowed in the Sturm sequence.*> \endverbatim*>*> \param[out] SIGMA*> \verbatim*> SIGMA is DOUBLE PRECISION*> The shift used to form L(+) D(+) L(+)^T.*> \endverbatim*>*> \param[out] DPLUS*> \verbatim*> DPLUS is DOUBLE PRECISION array, dimension (N)*> The N diagonal elements of the diagonal matrix D(+).*> \endverbatim*>*> \param[out] LPLUS*> \verbatim*> LPLUS is DOUBLE PRECISION array, dimension (N-1)*> The first (N-1) elements of LPLUS contain the subdiagonal*> elements of the unit bidiagonal matrix L(+).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> Workspace.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> Signals processing OK (=0) or failure (=1)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRF( N, D, L, LD, CLSTRT, CLEND,$ W, WGAP, WERR,$ SPDIAM, CLGAPL, CLGAPR, PIVMIN, SIGMA,$ DPLUS, LPLUS, WORK, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER CLSTRT, CLEND, INFO, NDOUBLE PRECISION CLGAPL, CLGAPR, PIVMIN, SIGMA, SPDIAM* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DPLUS( * ), L( * ), LD( * ),$ LPLUS( * ), W( * ), WGAP( * ), WERR( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION FOUR, MAXGROWTH1, MAXGROWTH2, ONE, QUART, TWOPARAMETER ( ONE = 1.0D0, TWO = 2.0D0, FOUR = 4.0D0,$ QUART = 0.25D0,$ MAXGROWTH1 = 8.D0,$ MAXGROWTH2 = 8.D0 )* ..* .. Local Scalars ..LOGICAL DORRR1, FORCER, NOFAIL, SAWNAN1, SAWNAN2, TRYRRR1INTEGER I, INDX, KTRY, KTRYMAX, SLEFT, SRIGHT, SHIFTPARAMETER ( KTRYMAX = 1, SLEFT = 1, SRIGHT = 2 )DOUBLE PRECISION AVGAP, BESTSHIFT, CLWDTH, EPS, FACT, FAIL,$ FAIL2, GROWTHBOUND, LDELTA, LDMAX, LSIGMA,$ MAX1, MAX2, MINGAP, OLDP, PROD, RDELTA, RDMAX,$ RRR1, RRR2, RSIGMA, S, SMLGROWTH, TMP, ZNM2* ..* .. External Functions ..LOGICAL DISNANDOUBLE PRECISION DLAMCHEXTERNAL DISNAN, DLAMCH* ..* .. External Subroutines ..EXTERNAL DCOPY* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF*FACT = DBLE(2**KTRYMAX)EPS = DLAMCH( 'Precision' )SHIFT = 0FORCER = .FALSE.* Note that we cannot guarantee that for any of the shifts tried,* the factorization has a small or even moderate element growth.* There could be Ritz values at both ends of the cluster and despite* backing off, there are examples where all factorizations tried* (in IEEE mode, allowing zero pivots & infinities) have INFINITE* element growth.* For this reason, we should use PIVMIN in this subroutine so that at* least the L D L^T factorization exists. It can be checked afterwards* whether the element growth caused bad residuals/orthogonality.* Decide whether the code should accept the best among all* representations despite large element growth or signal INFO=1* Setting NOFAIL to .FALSE. for quick fix for bug 113NOFAIL = .FALSE.** Compute the average gap length of the clusterCLWDTH = ABS(W(CLEND)-W(CLSTRT)) + WERR(CLEND) + WERR(CLSTRT)AVGAP = CLWDTH / DBLE(CLEND-CLSTRT)MINGAP = MIN(CLGAPL, CLGAPR)* Initial values for shifts to both ends of clusterLSIGMA = MIN(W( CLSTRT ),W( CLEND )) - WERR( CLSTRT )RSIGMA = MAX(W( CLSTRT ),W( CLEND )) + WERR( CLEND )* Use a small fudge to make sure that we really shift to the outsideLSIGMA = LSIGMA - ABS(LSIGMA)* FOUR * EPSRSIGMA = RSIGMA + ABS(RSIGMA)* FOUR * EPS* Compute upper bounds for how much to back off the initial shiftsLDMAX = QUART * MINGAP + TWO * PIVMINRDMAX = QUART * MINGAP + TWO * PIVMINLDELTA = MAX(AVGAP,WGAP( CLSTRT ))/FACTRDELTA = MAX(AVGAP,WGAP( CLEND-1 ))/FACT** Initialize the record of the best representation found*S = DLAMCH( 'S' )SMLGROWTH = ONE / SFAIL = DBLE(N-1)*MINGAP/(SPDIAM*EPS)FAIL2 = DBLE(N-1)*MINGAP/(SPDIAM*SQRT(EPS))BESTSHIFT = LSIGMA** while (KTRY <= KTRYMAX)KTRY = 0GROWTHBOUND = MAXGROWTH1*SPDIAM5 CONTINUESAWNAN1 = .FALSE.SAWNAN2 = .FALSE.* Ensure that we do not back off too much of the initial shiftsLDELTA = MIN(LDMAX,LDELTA)RDELTA = MIN(RDMAX,RDELTA)* Compute the element growth when shifting to both ends of the cluster* accept the shift if there is no element growth at one of the two ends* Left endS = -LSIGMADPLUS( 1 ) = D( 1 ) + SIF(ABS(DPLUS(1)).LT.PIVMIN) THENDPLUS(1) = -PIVMIN* Need to set SAWNAN1 because refined RRR test should not be used* in this caseSAWNAN1 = .TRUE.ENDIFMAX1 = ABS( DPLUS( 1 ) )DO 6 I = 1, N - 1LPLUS( I ) = LD( I ) / DPLUS( I )S = S*LPLUS( I )*L( I ) - LSIGMADPLUS( I+1 ) = D( I+1 ) + SIF(ABS(DPLUS(I+1)).LT.PIVMIN) THENDPLUS(I+1) = -PIVMIN* Need to set SAWNAN1 because refined RRR test should not be used* in this caseSAWNAN1 = .TRUE.ENDIFMAX1 = MAX( MAX1,ABS(DPLUS(I+1)) )6 CONTINUESAWNAN1 = SAWNAN1 .OR. DISNAN( MAX1 )IF( FORCER .OR.$ (MAX1.LE.GROWTHBOUND .AND. .NOT.SAWNAN1 ) ) THENSIGMA = LSIGMASHIFT = SLEFTGOTO 100ENDIF* Right endS = -RSIGMAWORK( 1 ) = D( 1 ) + SIF(ABS(WORK(1)).LT.PIVMIN) THENWORK(1) = -PIVMIN* Need to set SAWNAN2 because refined RRR test should not be used* in this caseSAWNAN2 = .TRUE.ENDIFMAX2 = ABS( WORK( 1 ) )DO 7 I = 1, N - 1WORK( N+I ) = LD( I ) / WORK( I )S = S*WORK( N+I )*L( I ) - RSIGMAWORK( I+1 ) = D( I+1 ) + SIF(ABS(WORK(I+1)).LT.PIVMIN) THENWORK(I+1) = -PIVMIN* Need to set SAWNAN2 because refined RRR test should not be used* in this caseSAWNAN2 = .TRUE.ENDIFMAX2 = MAX( MAX2,ABS(WORK(I+1)) )7 CONTINUESAWNAN2 = SAWNAN2 .OR. DISNAN( MAX2 )IF( FORCER .OR.$ (MAX2.LE.GROWTHBOUND .AND. .NOT.SAWNAN2 ) ) THENSIGMA = RSIGMASHIFT = SRIGHTGOTO 100ENDIF* If we are at this point, both shifts led to too much element growth* Record the better of the two shifts (provided it didn't lead to NaN)IF(SAWNAN1.AND.SAWNAN2) THEN* both MAX1 and MAX2 are NaNGOTO 50ELSEIF( .NOT.SAWNAN1 ) THENINDX = 1IF(MAX1.LE.SMLGROWTH) THENSMLGROWTH = MAX1BESTSHIFT = LSIGMAENDIFENDIFIF( .NOT.SAWNAN2 ) THENIF(SAWNAN1 .OR. MAX2.LE.MAX1) INDX = 2IF(MAX2.LE.SMLGROWTH) THENSMLGROWTH = MAX2BESTSHIFT = RSIGMAENDIFENDIFENDIF* If we are here, both the left and the right shift led to* element growth. If the element growth is moderate, then* we may still accept the representation, if it passes a* refined test for RRR. This test supposes that no NaN occurred.* Moreover, we use the refined RRR test only for isolated clusters.IF((CLWDTH.LT.MINGAP/DBLE(128)) .AND.$ (MIN(MAX1,MAX2).LT.FAIL2)$ .AND.(.NOT.SAWNAN1).AND.(.NOT.SAWNAN2)) THENDORRR1 = .TRUE.ELSEDORRR1 = .FALSE.ENDIFTRYRRR1 = .TRUE.IF( TRYRRR1 .AND. DORRR1 ) THENIF(INDX.EQ.1) THENTMP = ABS( DPLUS( N ) )ZNM2 = ONEPROD = ONEOLDP = ONEDO 15 I = N-1, 1, -1IF( PROD .LE. EPS ) THENPROD =$ ((DPLUS(I+1)*WORK(N+I+1))/(DPLUS(I)*WORK(N+I)))*OLDPELSEPROD = PROD*ABS(WORK(N+I))END IFOLDP = PRODZNM2 = ZNM2 + PROD**2TMP = MAX( TMP, ABS( DPLUS( I ) * PROD ))15 CONTINUERRR1 = TMP/( SPDIAM * SQRT( ZNM2 ) )IF (RRR1.LE.MAXGROWTH2) THENSIGMA = LSIGMASHIFT = SLEFTGOTO 100ENDIFELSE IF(INDX.EQ.2) THENTMP = ABS( WORK( N ) )ZNM2 = ONEPROD = ONEOLDP = ONEDO 16 I = N-1, 1, -1IF( PROD .LE. EPS ) THENPROD = ((WORK(I+1)*LPLUS(I+1))/(WORK(I)*LPLUS(I)))*OLDPELSEPROD = PROD*ABS(LPLUS(I))END IFOLDP = PRODZNM2 = ZNM2 + PROD**2TMP = MAX( TMP, ABS( WORK( I ) * PROD ))16 CONTINUERRR2 = TMP/( SPDIAM * SQRT( ZNM2 ) )IF (RRR2.LE.MAXGROWTH2) THENSIGMA = RSIGMASHIFT = SRIGHTGOTO 100ENDIFEND IFENDIF50 CONTINUEIF (KTRY.LT.KTRYMAX) THEN* If we are here, both shifts failed also the RRR test.* Back off to the outsideLSIGMA = MAX( LSIGMA - LDELTA,$ LSIGMA - LDMAX)RSIGMA = MIN( RSIGMA + RDELTA,$ RSIGMA + RDMAX )LDELTA = TWO * LDELTARDELTA = TWO * RDELTAKTRY = KTRY + 1GOTO 5ELSE* None of the representations investigated satisfied our* criteria. Take the best one we found.IF((SMLGROWTH.LT.FAIL).OR.NOFAIL) THENLSIGMA = BESTSHIFTRSIGMA = BESTSHIFTFORCER = .TRUE.GOTO 5ELSEINFO = 1RETURNENDIFEND IF100 CONTINUEIF (SHIFT.EQ.SLEFT) THENELSEIF (SHIFT.EQ.SRIGHT) THEN* store new L and D back into DPLUS, LPLUSCALL DCOPY( N, WORK, 1, DPLUS, 1 )CALL DCOPY( N-1, WORK(N+1), 1, LPLUS, 1 )ENDIFRETURN** End of DLARRF*END*> \brief \b DLARRJ performs refinement of the initial estimates of the eigenvalues of the matrix T.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRJ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrj.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrj.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrj.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRJ( N, D, E2, IFIRST, ILAST,* RTOL, OFFSET, W, WERR, WORK, IWORK,* PIVMIN, SPDIAM, INFO )** .. Scalar Arguments ..* INTEGER IFIRST, ILAST, INFO, N, OFFSET* DOUBLE PRECISION PIVMIN, RTOL, SPDIAM* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION D( * ), E2( * ), W( * ),* $ WERR( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Given the initial eigenvalue approximations of T, DLARRJ*> does bisection to refine the eigenvalues of T,*> W( IFIRST-OFFSET ) through W( ILAST-OFFSET ), to more accuracy. Initial*> guesses for these eigenvalues are input in W, the corresponding estimate*> of the error in these guesses in WERR. During bisection, intervals*> [left, right] are maintained by storing their mid-points and*> semi-widths in the arrays W and WERR respectively.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The N diagonal elements of T.*> \endverbatim*>*> \param[in] E2*> \verbatim*> E2 is DOUBLE PRECISION array, dimension (N-1)*> The Squares of the (N-1) subdiagonal elements of T.*> \endverbatim*>*> \param[in] IFIRST*> \verbatim*> IFIRST is INTEGER*> The index of the first eigenvalue to be computed.*> \endverbatim*>*> \param[in] ILAST*> \verbatim*> ILAST is INTEGER*> The index of the last eigenvalue to be computed.*> \endverbatim*>*> \param[in] RTOL*> \verbatim*> RTOL is DOUBLE PRECISION*> Tolerance for the convergence of the bisection intervals.*> An interval [LEFT,RIGHT] has converged if*> RIGHT-LEFT.LT.RTOL*MAX(|LEFT|,|RIGHT|).*> \endverbatim*>*> \param[in] OFFSET*> \verbatim*> OFFSET is INTEGER*> Offset for the arrays W and WERR, i.e., the IFIRST-OFFSET*> through ILAST-OFFSET elements of these arrays are to be used.*> \endverbatim*>*> \param[in,out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On input, W( IFIRST-OFFSET ) through W( ILAST-OFFSET ) are*> estimates of the eigenvalues of L D L^T indexed IFIRST through*> ILAST.*> On output, these estimates are refined.*> \endverbatim*>*> \param[in,out] WERR*> \verbatim*> WERR is DOUBLE PRECISION array, dimension (N)*> On input, WERR( IFIRST-OFFSET ) through WERR( ILAST-OFFSET ) are*> the errors in the estimates of the corresponding elements in W.*> On output, these errors are refined.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> Workspace.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (2*N)*> Workspace.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot in the Sturm sequence for T.*> \endverbatim*>*> \param[in] SPDIAM*> \verbatim*> SPDIAM is DOUBLE PRECISION*> The spectral diameter of T.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> Error flag.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRJ( N, D, E2, IFIRST, ILAST,$ RTOL, OFFSET, W, WERR, WORK, IWORK,$ PIVMIN, SPDIAM, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER IFIRST, ILAST, INFO, N, OFFSETDOUBLE PRECISION PIVMIN, RTOL, SPDIAM* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), E2( * ), W( * ),$ WERR( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, HALFPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ HALF = 0.5D0 )INTEGER MAXITR* ..* .. Local Scalars ..INTEGER CNT, I, I1, I2, II, ITER, J, K, NEXT, NINT,$ OLNINT, P, PREV, SAVI1DOUBLE PRECISION DPLUS, FAC, LEFT, MID, RIGHT, S, TMP, WIDTH** ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF*MAXITR = INT( ( LOG( SPDIAM+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2** Initialize unconverged intervals in [ WORK(2*I-1), WORK(2*I) ].* The Sturm Count, Count( WORK(2*I-1) ) is arranged to be I-1, while* Count( WORK(2*I) ) is stored in IWORK( 2*I ). The integer IWORK( 2*I-1 )* for an unconverged interval is set to the index of the next unconverged* interval, and is -1 or 0 for a converged interval. Thus a linked* list of unconverged intervals is set up.*I1 = IFIRSTI2 = ILAST* The number of unconverged intervalsNINT = 0* The last unconverged interval foundPREV = 0DO 75 I = I1, I2K = 2*III = I - OFFSETLEFT = W( II ) - WERR( II )MID = W(II)RIGHT = W( II ) + WERR( II )WIDTH = RIGHT - MIDTMP = MAX( ABS( LEFT ), ABS( RIGHT ) )* The following test prevents the test of converged intervalsIF( WIDTH.LT.RTOL*TMP ) THEN* This interval has already converged and does not need refinement.* (Note that the gaps might change through refining the* eigenvalues, however, they can only get bigger.)* Remove it from the list.IWORK( K-1 ) = -1* Make sure that I1 always points to the first unconverged intervalIF((I.EQ.I1).AND.(I.LT.I2)) I1 = I + 1IF((PREV.GE.I1).AND.(I.LE.I2)) IWORK( 2*PREV-1 ) = I + 1ELSE* unconverged interval foundPREV = I* Make sure that [LEFT,RIGHT] contains the desired eigenvalue** Do while( CNT(LEFT).GT.I-1 )*FAC = ONE20 CONTINUECNT = 0S = LEFTDPLUS = D( 1 ) - SIF( DPLUS.LT.ZERO ) CNT = CNT + 1DO 30 J = 2, NDPLUS = D( J ) - S - E2( J-1 )/DPLUSIF( DPLUS.LT.ZERO ) CNT = CNT + 130 CONTINUEIF( CNT.GT.I-1 ) THENLEFT = LEFT - WERR( II )*FACFAC = TWO*FACGO TO 20END IF** Do while( CNT(RIGHT).LT.I )*FAC = ONE50 CONTINUECNT = 0S = RIGHTDPLUS = D( 1 ) - SIF( DPLUS.LT.ZERO ) CNT = CNT + 1DO 60 J = 2, NDPLUS = D( J ) - S - E2( J-1 )/DPLUSIF( DPLUS.LT.ZERO ) CNT = CNT + 160 CONTINUEIF( CNT.LT.I ) THENRIGHT = RIGHT + WERR( II )*FACFAC = TWO*FACGO TO 50END IFNINT = NINT + 1IWORK( K-1 ) = I + 1IWORK( K ) = CNTEND IFWORK( K-1 ) = LEFTWORK( K ) = RIGHT75 CONTINUESAVI1 = I1** Do while( NINT.GT.0 ), i.e. there are still unconverged intervals* and while (ITER.LT.MAXITR)*ITER = 080 CONTINUEPREV = I1 - 1I = I1OLNINT = NINTDO 100 P = 1, OLNINTK = 2*III = I - OFFSETNEXT = IWORK( K-1 )LEFT = WORK( K-1 )RIGHT = WORK( K )MID = HALF*( LEFT + RIGHT )* semiwidth of intervalWIDTH = RIGHT - MIDTMP = MAX( ABS( LEFT ), ABS( RIGHT ) )IF( ( WIDTH.LT.RTOL*TMP ) .OR.$ (ITER.EQ.MAXITR) )THEN* reduce number of unconverged intervalsNINT = NINT - 1* Mark interval as converged.IWORK( K-1 ) = 0IF( I1.EQ.I ) THENI1 = NEXTELSE* Prev holds the last unconverged interval previously examinedIF(PREV.GE.I1) IWORK( 2*PREV-1 ) = NEXTEND IFI = NEXTGO TO 100END IFPREV = I** Perform one bisection step*CNT = 0S = MIDDPLUS = D( 1 ) - SIF( DPLUS.LT.ZERO ) CNT = CNT + 1DO 90 J = 2, NDPLUS = D( J ) - S - E2( J-1 )/DPLUSIF( DPLUS.LT.ZERO ) CNT = CNT + 190 CONTINUEIF( CNT.LE.I-1 ) THENWORK( K-1 ) = MIDELSEWORK( K ) = MIDEND IFI = NEXT100 CONTINUEITER = ITER + 1* do another loop if there are still unconverged intervals* However, in the last iteration, all intervals are accepted* since this is the best we can do.IF( ( NINT.GT.0 ).AND.(ITER.LE.MAXITR) ) GO TO 80*** At this point, all the intervals have convergedDO 110 I = SAVI1, ILASTK = 2*III = I - OFFSET* All intervals marked by '0' have been refined.IF( IWORK( K-1 ).EQ.0 ) THENW( II ) = HALF*( WORK( K-1 )+WORK( K ) )WERR( II ) = WORK( K ) - W( II )END IF110 CONTINUE*RETURN** End of DLARRJ*END*> \brief \b DLARRK computes one eigenvalue of a symmetric tridiagonal matrix T to suitable accuracy.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRK + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrk.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrk.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrk.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRK( N, IW, GL, GU,* D, E2, PIVMIN, RELTOL, W, WERR, INFO)** .. Scalar Arguments ..* INTEGER INFO, IW, N* DOUBLE PRECISION PIVMIN, RELTOL, GL, GU, W, WERR* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E2( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARRK computes one eigenvalue of a symmetric tridiagonal*> matrix T to suitable accuracy. This is an auxiliary code to be*> called from DSTEMR.*>*> To avoid overflow, the matrix must be scaled so that its*> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest*> accuracy, it should not be much smaller than that.*>*> See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal*> Matrix", Report CS41, Computer Science Dept., Stanford*> University, July 21, 1966.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the tridiagonal matrix T. N >= 0.*> \endverbatim*>*> \param[in] IW*> \verbatim*> IW is INTEGER*> The index of the eigenvalues to be returned.*> \endverbatim*>*> \param[in] GL*> \verbatim*> GL is DOUBLE PRECISION*> \endverbatim*>*> \param[in] GU*> \verbatim*> GU is DOUBLE PRECISION*> An upper and a lower bound on the eigenvalue.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] E2*> \verbatim*> E2 is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) squared off-diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot allowed in the Sturm sequence for T.*> \endverbatim*>*> \param[in] RELTOL*> \verbatim*> RELTOL is DOUBLE PRECISION*> The minimum relative width of an interval. When an interval*> is narrower than RELTOL times the larger (in*> magnitude) endpoint, then it is considered to be*> sufficiently small, i.e., converged. Note: this should*> always be at least radix*machine epsilon.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION*> \endverbatim*>*> \param[out] WERR*> \verbatim*> WERR is DOUBLE PRECISION*> The error bound on the corresponding eigenvalue approximation*> in W.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: Eigenvalue converged*> = -1: Eigenvalue did NOT converge*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> FUDGE DOUBLE PRECISION, default = 2*> A "fudge factor" to widen the Gershgorin intervals.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLARRK( N, IW, GL, GU,$ D, E2, PIVMIN, RELTOL, W, WERR, INFO)** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, IW, NDOUBLE PRECISION PIVMIN, RELTOL, GL, GU, W, WERR* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E2( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION FUDGE, HALF, TWO, ZEROPARAMETER ( HALF = 0.5D0, TWO = 2.0D0,$ FUDGE = TWO, ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER I, IT, ITMAX, NEGCNTDOUBLE PRECISION ATOLI, EPS, LEFT, MID, RIGHT, RTOLI, TMP1,$ TMP2, TNORM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 ) THENINFO = 0RETURNEND IF** Get machine constantsEPS = DLAMCH( 'P' )TNORM = MAX( ABS( GL ), ABS( GU ) )RTOLI = RELTOLATOLI = FUDGE*TWO*PIVMINITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2INFO = -1LEFT = GL - FUDGE*TNORM*EPS*N - FUDGE*TWO*PIVMINRIGHT = GU + FUDGE*TNORM*EPS*N + FUDGE*TWO*PIVMINIT = 010 CONTINUE** Check if interval converged or maximum number of iterations reached*TMP1 = ABS( RIGHT - LEFT )TMP2 = MAX( ABS(RIGHT), ABS(LEFT) )IF( TMP1.LT.MAX( ATOLI, PIVMIN, RTOLI*TMP2 ) ) THENINFO = 0GOTO 30ENDIFIF(IT.GT.ITMAX)$ GOTO 30** Count number of negative pivots for mid-point*IT = IT + 1MID = HALF * (LEFT + RIGHT)NEGCNT = 0TMP1 = D( 1 ) - MIDIF( ABS( TMP1 ).LT.PIVMIN )$ TMP1 = -PIVMINIF( TMP1.LE.ZERO )$ NEGCNT = NEGCNT + 1*DO 20 I = 2, NTMP1 = D( I ) - E2( I-1 ) / TMP1 - MIDIF( ABS( TMP1 ).LT.PIVMIN )$ TMP1 = -PIVMINIF( TMP1.LE.ZERO )$ NEGCNT = NEGCNT + 120 CONTINUEIF(NEGCNT.GE.IW) THENRIGHT = MIDELSELEFT = MIDENDIFGOTO 1030 CONTINUE** Converged or maximum number of iterations reached*W = HALF * (LEFT + RIGHT)WERR = HALF * ABS( RIGHT - LEFT )RETURN** End of DLARRK*END*> \brief \b DLARRR performs tests to decide whether the symmetric tridiagonal matrix T warrants expensive computations which guarantee high relative accuracy in the eigenvalues.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRR( N, D, E, INFO )** .. Scalar Arguments ..* INTEGER N, INFO* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * )* ..****> \par Purpose:* =============*>*> \verbatim*>*> Perform tests to decide whether the symmetric tridiagonal matrix T*> warrants expensive computations which guarantee high relative accuracy*> in the eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N > 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The N diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> On entry, the first (N-1) entries contain the subdiagonal*> elements of the tridiagonal matrix T; E(N) is set to ZERO.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> INFO = 0(default) : the matrix warrants computations preserving*> relative accuracy.*> INFO = 1 : the matrix warrants computations guaranteeing*> only absolute accuracy.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRR( N, D, E, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER N, INFO* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * )* ..*** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, RELCONDPARAMETER ( ZERO = 0.0D0,$ RELCOND = 0.999D0 )* ..* .. Local Scalars ..INTEGER ILOGICAL YESRELDOUBLE PRECISION EPS, SAFMIN, SMLNUM, RMIN, TMP, TMP2,$ OFFDIG, OFFDIG2* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 ) THENINFO = 0RETURNEND IF** As a default, do NOT go for relative-accuracy preserving computations.INFO = 1SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSRMIN = SQRT( SMLNUM )* Tests for relative accuracy** Test for scaled diagonal dominance* Scale the diagonal entries to one and check whether the sum of the* off-diagonals is less than one** The sdd relative error bounds have a 1/(1- 2*x) factor in them,* x = max(OFFDIG + OFFDIG2), so when x is close to 1/2, no relative* accuracy is promised. In the notation of the code fragment below,* 1/(1 - (OFFDIG + OFFDIG2)) is the condition number.* We don't think it is worth going into "sdd mode" unless the relative* condition number is reasonable, not 1/macheps.* The threshold should be compatible with other thresholds used in the* code. We set OFFDIG + OFFDIG2 <= .999 =: RELCOND, it corresponds* to losing at most 3 decimal digits: 1 / (1 - (OFFDIG + OFFDIG2)) <= 1000* instead of the current OFFDIG + OFFDIG2 < 1*YESREL = .TRUE.OFFDIG = ZEROTMP = SQRT(ABS(D(1)))IF (TMP.LT.RMIN) YESREL = .FALSE.IF(.NOT.YESREL) GOTO 11DO 10 I = 2, NTMP2 = SQRT(ABS(D(I)))IF (TMP2.LT.RMIN) YESREL = .FALSE.IF(.NOT.YESREL) GOTO 11OFFDIG2 = ABS(E(I-1))/(TMP*TMP2)IF(OFFDIG+OFFDIG2.GE.RELCOND) YESREL = .FALSE.IF(.NOT.YESREL) GOTO 11TMP = TMP2OFFDIG = OFFDIG210 CONTINUE11 CONTINUEIF( YESREL ) THENINFO = 0RETURNELSEENDIF*** *** MORE TO BE IMPLEMENTED ****** Test if the lower bidiagonal matrix L from T = L D L^T* (zero shift facto) is well conditioned*** Test if the upper bidiagonal matrix U from T = U D U^T* (zero shift facto) is well conditioned.* In this case, the matrix needs to be flipped and, at the end* of the eigenvector computation, the flip needs to be applied* to the computed eigenvectors (and the support)**RETURN** END OF DLARRR*END*> \brief \b DLARRV computes the eigenvectors of the tridiagonal matrix T = L D LT given L, D and the eigenvalues of L D LT.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARRV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarrv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarrv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarrv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARRV( N, VL, VU, D, L, PIVMIN,* ISPLIT, M, DOL, DOU, MINRGP,* RTOL1, RTOL2, W, WERR, WGAP,* IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,* WORK, IWORK, INFO )** .. Scalar Arguments ..* INTEGER DOL, DOU, INFO, LDZ, M, N* DOUBLE PRECISION MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU* ..* .. Array Arguments ..* INTEGER IBLOCK( * ), INDEXW( * ), ISPLIT( * ),* $ ISUPPZ( * ), IWORK( * )* DOUBLE PRECISION D( * ), GERS( * ), L( * ), W( * ), WERR( * ),* $ WGAP( * ), WORK( * )* DOUBLE PRECISION Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARRV computes the eigenvectors of the tridiagonal matrix*> T = L D L**T given L, D and APPROXIMATIONS to the eigenvalues of L D L**T.*> The input eigenvalues should have been computed by DLARRE.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> Lower bound of the interval that contains the desired*> eigenvalues. VL < VU. Needed to compute gaps on the left or right*> end of the extremal eigenvalues in the desired RANGE.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> Upper bound of the interval that contains the desired*> eigenvalues. VL < VU.*> Note: VU is currently not used by this implementation of DLARRV, VU is*> passed to DLARRV because it could be used compute gaps on the right end*> of the extremal eigenvalues. However, with not much initial accuracy in*> LAMBDA and VU, the formula can lead to an overestimation of the right gap*> and thus to inadequately early RQI 'convergence'. This is currently*> prevented this by forcing a small right gap. And so it turns out that VU*> is currently not used by this implementation of DLARRV.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the N diagonal elements of the diagonal matrix D.*> On exit, D may be overwritten.*> \endverbatim*>*> \param[in,out] L*> \verbatim*> L is DOUBLE PRECISION array, dimension (N)*> On entry, the (N-1) subdiagonal elements of the unit*> bidiagonal matrix L are in elements 1 to N-1 of L*> (if the matrix is not split.) At the end of each block*> is stored the corresponding shift as given by DLARRE.*> On exit, L is overwritten.*> \endverbatim*>*> \param[in] PIVMIN*> \verbatim*> PIVMIN is DOUBLE PRECISION*> The minimum pivot allowed in the Sturm sequence.*> \endverbatim*>*> \param[in] ISPLIT*> \verbatim*> ISPLIT is INTEGER array, dimension (N)*> The splitting points, at which T breaks up into blocks.*> The first block consists of rows/columns 1 to*> ISPLIT( 1 ), the second of rows/columns ISPLIT( 1 )+1*> through ISPLIT( 2 ), etc.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The total number of input eigenvalues. 0 <= M <= N.*> \endverbatim*>*> \param[in] DOL*> \verbatim*> DOL is INTEGER*> \endverbatim*>*> \param[in] DOU*> \verbatim*> DOU is INTEGER*> If the user wants to compute only selected eigenvectors from all*> the eigenvalues supplied, he can specify an index range DOL:DOU.*> Or else the setting DOL=1, DOU=M should be applied.*> Note that DOL and DOU refer to the order in which the eigenvalues*> are stored in W.*> If the user wants to compute only selected eigenpairs, then*> the columns DOL-1 to DOU+1 of the eigenvector space Z contain the*> computed eigenvectors. All other columns of Z are set to zero.*> \endverbatim*>*> \param[in] MINRGP*> \verbatim*> MINRGP is DOUBLE PRECISION*> \endverbatim*>*> \param[in] RTOL1*> \verbatim*> RTOL1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in] RTOL2*> \verbatim*> RTOL2 is DOUBLE PRECISION*> Parameters for bisection.*> An interval [LEFT,RIGHT] has converged if*> RIGHT-LEFT.LT.MAX( RTOL1*GAP, RTOL2*MAX(|LEFT|,|RIGHT|) )*> \endverbatim*>*> \param[in,out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements of W contain the APPROXIMATE eigenvalues for*> which eigenvectors are to be computed. The eigenvalues*> should be grouped by split-off block and ordered from*> smallest to largest within the block ( The output array*> W from DLARRE is expected here ). Furthermore, they are with*> respect to the shift of the corresponding root representation*> for their block. On exit, W holds the eigenvalues of the*> UNshifted matrix.*> \endverbatim*>*> \param[in,out] WERR*> \verbatim*> WERR is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the semiwidth of the uncertainty*> interval of the corresponding eigenvalue in W*> \endverbatim*>*> \param[in,out] WGAP*> \verbatim*> WGAP is DOUBLE PRECISION array, dimension (N)*> The separation from the right neighbor eigenvalue in W.*> \endverbatim*>*> \param[in] IBLOCK*> \verbatim*> IBLOCK is INTEGER array, dimension (N)*> The indices of the blocks (submatrices) associated with the*> corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue*> W(i) belongs to the first block from the top, =2 if W(i)*> belongs to the second block, etc.*> \endverbatim*>*> \param[in] INDEXW*> \verbatim*> INDEXW is INTEGER array, dimension (N)*> The indices of the eigenvalues within each block (submatrix);*> for example, INDEXW(i)= 10 and IBLOCK(i)=2 imply that the*> i-th eigenvalue W(i) is the 10-th eigenvalue in the second block.*> \endverbatim*>*> \param[in] GERS*> \verbatim*> GERS is DOUBLE PRECISION array, dimension (2*N)*> The N Gerschgorin intervals (the i-th Gerschgorin interval*> is (GERS(2*i-1), GERS(2*i)). The Gerschgorin intervals should*> be computed from the original UNshifted matrix.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) )*> If INFO = 0, the first M columns of Z contain the*> orthonormal eigenvectors of the matrix T*> corresponding to the input eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] ISUPPZ*> \verbatim*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )*> The support of the eigenvectors in Z, i.e., the indices*> indicating the nonzero elements in Z. The I-th eigenvector*> is nonzero only in elements ISUPPZ( 2*I-1 ) through*> ISUPPZ( 2*I ).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (12*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (7*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*>*> > 0: A problem occurred in DLARRV.*> < 0: One of the called subroutines signaled an internal problem.*> Needs inspection of the corresponding parameter IINFO*> for further information.*>*> =-1: Problem in DLARRB when refining a child's eigenvalues.*> =-2: Problem in DLARRF when computing the RRR of a child.*> When a child is inside a tight cluster, it can be difficult*> to find an RRR. A partial remedy from the user's point of*> view is to make the parameter MINRGP smaller and recompile.*> However, as the orthogonality of the computed vectors is*> proportional to 1/MINRGP, the user should be aware that*> he might be trading in precision when he decreases MINRGP.*> =-3: Problem in DLARRB when refining a single eigenvalue*> after the Rayleigh correction was rejected.*> = 5: The Rayleigh Quotient Iteration failed to converge to*> full accuracy in MAXITR steps.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERauxiliary**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DLARRV( N, VL, VU, D, L, PIVMIN,$ ISPLIT, M, DOL, DOU, MINRGP,$ RTOL1, RTOL2, W, WERR, WGAP,$ IBLOCK, INDEXW, GERS, Z, LDZ, ISUPPZ,$ WORK, IWORK, INFO )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER DOL, DOU, INFO, LDZ, M, NDOUBLE PRECISION MINRGP, PIVMIN, RTOL1, RTOL2, VL, VU* ..* .. Array Arguments ..INTEGER IBLOCK( * ), INDEXW( * ), ISPLIT( * ),$ ISUPPZ( * ), IWORK( * )DOUBLE PRECISION D( * ), GERS( * ), L( * ), W( * ), WERR( * ),$ WGAP( * ), WORK( * )DOUBLE PRECISION Z( LDZ, * )* ..** =====================================================================** .. Parameters ..INTEGER MAXITRPARAMETER ( MAXITR = 10 )DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, HALFPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, THREE = 3.0D0,$ FOUR = 4.0D0, HALF = 0.5D0)* ..* .. Local Scalars ..LOGICAL ESKIP, NEEDBS, STP2II, TRYRQC, USEDBS, USEDRQINTEGER DONE, I, IBEGIN, IDONE, IEND, II, IINDC1,$ IINDC2, IINDR, IINDWK, IINFO, IM, IN, INDEIG,$ INDLD, INDLLD, INDWRK, ISUPMN, ISUPMX, ITER,$ ITMP1, J, JBLK, K, MINIWSIZE, MINWSIZE, NCLUS,$ NDEPTH, NEGCNT, NEWCLS, NEWFST, NEWFTT, NEWLST,$ NEWSIZ, OFFSET, OLDCLS, OLDFST, OLDIEN, OLDLST,$ OLDNCL, P, PARITY, Q, WBEGIN, WEND, WINDEX,$ WINDMN, WINDPL, ZFROM, ZTO, ZUSEDL, ZUSEDU,$ ZUSEDWDOUBLE PRECISION BSTRES, BSTW, EPS, FUDGE, GAP, GAPTOL, GL, GU,$ LAMBDA, LEFT, LGAP, MINGMA, NRMINV, RESID,$ RGAP, RIGHT, RQCORR, RQTOL, SAVGAP, SGNDEF,$ SIGMA, SPDIAM, SSIGMA, TAU, TMP, TOL, ZTZ* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAR1V, DLARRB, DLARRF, DLASET,$ DSCAL* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN* ..* .. Executable Statements ..* ..INFO = 0** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF** The first N entries of WORK are reserved for the eigenvaluesINDLD = N+1INDLLD= 2*N+1INDWRK= 3*N+1MINWSIZE = 12 * NDO 5 I= 1,MINWSIZEWORK( I ) = ZERO5 CONTINUE* IWORK(IINDR+1:IINDR+N) hold the twist indices R for the* factorization used to compute the FP vectorIINDR = 0* IWORK(IINDC1+1:IINC2+N) are used to store the clusters of the current* layer and the one above.IINDC1 = NIINDC2 = 2*NIINDWK = 3*N + 1MINIWSIZE = 7 * NDO 10 I= 1,MINIWSIZEIWORK( I ) = 010 CONTINUEZUSEDL = 1IF(DOL.GT.1) THEN* Set lower bound for use of ZZUSEDL = DOL-1ENDIFZUSEDU = MIF(DOU.LT.M) THEN* Set lower bound for use of ZZUSEDU = DOU+1ENDIF* The width of the part of Z that is usedZUSEDW = ZUSEDU - ZUSEDL + 1CALL DLASET( 'Full', N, ZUSEDW, ZERO, ZERO,$ Z(1,ZUSEDL), LDZ )EPS = DLAMCH( 'Precision' )RQTOL = TWO * EPS** Set expert flags for standard code.TRYRQC = .TRUE.IF((DOL.EQ.1).AND.(DOU.EQ.M)) THENELSE* Only selected eigenpairs are computed. Since the other evalues* are not refined by RQ iteration, bisection has to compute to full* accuracy.RTOL1 = FOUR * EPSRTOL2 = FOUR * EPSENDIF* The entries WBEGIN:WEND in W, WERR, WGAP correspond to the* desired eigenvalues. The support of the nonzero eigenvector* entries is contained in the interval IBEGIN:IEND.* Remark that if k eigenpairs are desired, then the eigenvectors* are stored in k contiguous columns of Z.* DONE is the number of eigenvectors already computedDONE = 0IBEGIN = 1WBEGIN = 1DO 170 JBLK = 1, IBLOCK( M )IEND = ISPLIT( JBLK )SIGMA = L( IEND )* Find the eigenvectors of the submatrix indexed IBEGIN* through IEND.WEND = WBEGIN - 115 CONTINUEIF( WEND.LT.M ) THENIF( IBLOCK( WEND+1 ).EQ.JBLK ) THENWEND = WEND + 1GO TO 15END IFEND IFIF( WEND.LT.WBEGIN ) THENIBEGIN = IEND + 1GO TO 170ELSEIF( (WEND.LT.DOL).OR.(WBEGIN.GT.DOU) ) THENIBEGIN = IEND + 1WBEGIN = WEND + 1GO TO 170END IF* Find local spectral diameter of the blockGL = GERS( 2*IBEGIN-1 )GU = GERS( 2*IBEGIN )DO 20 I = IBEGIN+1 , IENDGL = MIN( GERS( 2*I-1 ), GL )GU = MAX( GERS( 2*I ), GU )20 CONTINUESPDIAM = GU - GL* OLDIEN is the last index of the previous blockOLDIEN = IBEGIN - 1* Calculate the size of the current blockIN = IEND - IBEGIN + 1* The number of eigenvalues in the current blockIM = WEND - WBEGIN + 1* This is for a 1x1 blockIF( IBEGIN.EQ.IEND ) THENDONE = DONE+1Z( IBEGIN, WBEGIN ) = ONEISUPPZ( 2*WBEGIN-1 ) = IBEGINISUPPZ( 2*WBEGIN ) = IBEGINW( WBEGIN ) = W( WBEGIN ) + SIGMAWORK( WBEGIN ) = W( WBEGIN )IBEGIN = IEND + 1WBEGIN = WBEGIN + 1GO TO 170END IF* The desired (shifted) eigenvalues are stored in W(WBEGIN:WEND)* Note that these can be approximations, in this case, the corresp.* entries of WERR give the size of the uncertainty interval.* The eigenvalue approximations will be refined when necessary as* high relative accuracy is required for the computation of the* corresponding eigenvectors.CALL DCOPY( IM, W( WBEGIN ), 1,$ WORK( WBEGIN ), 1 )* We store in W the eigenvalue approximations w.r.t. the original* matrix T.DO 30 I=1,IMW(WBEGIN+I-1) = W(WBEGIN+I-1)+SIGMA30 CONTINUE* NDEPTH is the current depth of the representation treeNDEPTH = 0* PARITY is either 1 or 0PARITY = 1* NCLUS is the number of clusters for the next level of the* representation tree, we start with NCLUS = 1 for the rootNCLUS = 1IWORK( IINDC1+1 ) = 1IWORK( IINDC1+2 ) = IM* IDONE is the number of eigenvectors already computed in the current* blockIDONE = 0* loop while( IDONE.LT.IM )* generate the representation tree for the current block and* compute the eigenvectors40 CONTINUEIF( IDONE.LT.IM ) THEN* This is a crude protection against infinitely deep treesIF( NDEPTH.GT.M ) THENINFO = -2RETURNENDIF* breadth first processing of the current level of the representation* tree: OLDNCL = number of clusters on current levelOLDNCL = NCLUS* reset NCLUS to count the number of child clustersNCLUS = 0*PARITY = 1 - PARITYIF( PARITY.EQ.0 ) THENOLDCLS = IINDC1NEWCLS = IINDC2ELSEOLDCLS = IINDC2NEWCLS = IINDC1END IF* Process the clusters on the current levelDO 150 I = 1, OLDNCLJ = OLDCLS + 2*I* OLDFST, OLDLST = first, last index of current cluster.* cluster indices start with 1 and are relative* to WBEGIN when accessing W, WGAP, WERR, ZOLDFST = IWORK( J-1 )OLDLST = IWORK( J )IF( NDEPTH.GT.0 ) THEN* Retrieve relatively robust representation (RRR) of cluster* that has been computed at the previous level* The RRR is stored in Z and overwritten once the eigenvectors* have been computed or when the cluster is refinedIF((DOL.EQ.1).AND.(DOU.EQ.M)) THEN* Get representation from location of the leftmost evalue* of the clusterJ = WBEGIN + OLDFST - 1ELSEIF(WBEGIN+OLDFST-1.LT.DOL) THEN* Get representation from the left end of Z arrayJ = DOL - 1ELSEIF(WBEGIN+OLDFST-1.GT.DOU) THEN* Get representation from the right end of Z arrayJ = DOUELSEJ = WBEGIN + OLDFST - 1ENDIFENDIFCALL DCOPY( IN, Z( IBEGIN, J ), 1, D( IBEGIN ), 1 )CALL DCOPY( IN-1, Z( IBEGIN, J+1 ), 1, L( IBEGIN ),$ 1 )SIGMA = Z( IEND, J+1 )* Set the corresponding entries in Z to zeroCALL DLASET( 'Full', IN, 2, ZERO, ZERO,$ Z( IBEGIN, J), LDZ )END IF* Compute DL and DLL of current RRRDO 50 J = IBEGIN, IEND-1TMP = D( J )*L( J )WORK( INDLD-1+J ) = TMPWORK( INDLLD-1+J ) = TMP*L( J )50 CONTINUEIF( NDEPTH.GT.0 ) THEN* P and Q are index of the first and last eigenvalue to compute* within the current blockP = INDEXW( WBEGIN-1+OLDFST )Q = INDEXW( WBEGIN-1+OLDLST )* Offset for the arrays WORK, WGAP and WERR, i.e., the P-OFFSET* through the Q-OFFSET elements of these arrays are to be used.* OFFSET = P-OLDFSTOFFSET = INDEXW( WBEGIN ) - 1* perform limited bisection (if necessary) to get approximate* eigenvalues to the precision needed.CALL DLARRB( IN, D( IBEGIN ),$ WORK(INDLLD+IBEGIN-1),$ P, Q, RTOL1, RTOL2, OFFSET,$ WORK(WBEGIN),WGAP(WBEGIN),WERR(WBEGIN),$ WORK( INDWRK ), IWORK( IINDWK ),$ PIVMIN, SPDIAM, IN, IINFO )IF( IINFO.NE.0 ) THENINFO = -1RETURNENDIF* We also recompute the extremal gaps. W holds all eigenvalues* of the unshifted matrix and must be used for computation* of WGAP, the entries of WORK might stem from RRRs with* different shifts. The gaps from WBEGIN-1+OLDFST to* WBEGIN-1+OLDLST are correctly computed in DLARRB.* However, we only allow the gaps to become greater since* this is what should happen when we decrease WERRIF( OLDFST.GT.1) THENWGAP( WBEGIN+OLDFST-2 ) =$ MAX(WGAP(WBEGIN+OLDFST-2),$ W(WBEGIN+OLDFST-1)-WERR(WBEGIN+OLDFST-1)$ - W(WBEGIN+OLDFST-2)-WERR(WBEGIN+OLDFST-2) )ENDIFIF( WBEGIN + OLDLST -1 .LT. WEND ) THENWGAP( WBEGIN+OLDLST-1 ) =$ MAX(WGAP(WBEGIN+OLDLST-1),$ W(WBEGIN+OLDLST)-WERR(WBEGIN+OLDLST)$ - W(WBEGIN+OLDLST-1)-WERR(WBEGIN+OLDLST-1) )ENDIF* Each time the eigenvalues in WORK get refined, we store* the newly found approximation with all shifts applied in WDO 53 J=OLDFST,OLDLSTW(WBEGIN+J-1) = WORK(WBEGIN+J-1)+SIGMA53 CONTINUEEND IF* Process the current node.NEWFST = OLDFSTDO 140 J = OLDFST, OLDLSTIF( J.EQ.OLDLST ) THEN* we are at the right end of the cluster, this is also the* boundary of the child clusterNEWLST = JELSE IF ( WGAP( WBEGIN + J -1).GE.$ MINRGP* ABS( WORK(WBEGIN + J -1) ) ) THEN* the right relative gap is big enough, the child cluster* (NEWFST,..,NEWLST) is well separated from the followingNEWLST = JELSE* inside a child cluster, the relative gap is not* big enough.GOTO 140END IF* Compute size of child cluster foundNEWSIZ = NEWLST - NEWFST + 1* NEWFTT is the place in Z where the new RRR or the computed* eigenvector is to be storedIF((DOL.EQ.1).AND.(DOU.EQ.M)) THEN* Store representation at location of the leftmost evalue* of the clusterNEWFTT = WBEGIN + NEWFST - 1ELSEIF(WBEGIN+NEWFST-1.LT.DOL) THEN* Store representation at the left end of Z arrayNEWFTT = DOL - 1ELSEIF(WBEGIN+NEWFST-1.GT.DOU) THEN* Store representation at the right end of Z arrayNEWFTT = DOUELSENEWFTT = WBEGIN + NEWFST - 1ENDIFENDIFIF( NEWSIZ.GT.1) THEN** Current child is not a singleton but a cluster.* Compute and store new representation of child.*** Compute left and right cluster gap.** LGAP and RGAP are not computed from WORK because* the eigenvalue approximations may stem from RRRs* different shifts. However, W hold all eigenvalues* of the unshifted matrix. Still, the entries in WGAP* have to be computed from WORK since the entries* in W might be of the same order so that gaps are not* exhibited correctly for very close eigenvalues.IF( NEWFST.EQ.1 ) THENLGAP = MAX( ZERO,$ W(WBEGIN)-WERR(WBEGIN) - VL )ELSELGAP = WGAP( WBEGIN+NEWFST-2 )ENDIFRGAP = WGAP( WBEGIN+NEWLST-1 )** Compute left- and rightmost eigenvalue of child* to high precision in order to shift as close* as possible and obtain as large relative gaps* as possible*DO 55 K =1,2IF(K.EQ.1) THENP = INDEXW( WBEGIN-1+NEWFST )ELSEP = INDEXW( WBEGIN-1+NEWLST )ENDIFOFFSET = INDEXW( WBEGIN ) - 1CALL DLARRB( IN, D(IBEGIN),$ WORK( INDLLD+IBEGIN-1 ),P,P,$ RQTOL, RQTOL, OFFSET,$ WORK(WBEGIN),WGAP(WBEGIN),$ WERR(WBEGIN),WORK( INDWRK ),$ IWORK( IINDWK ), PIVMIN, SPDIAM,$ IN, IINFO )55 CONTINUE*IF((WBEGIN+NEWLST-1.LT.DOL).OR.$ (WBEGIN+NEWFST-1.GT.DOU)) THEN* if the cluster contains no desired eigenvalues* skip the computation of that branch of the rep. tree** We could skip before the refinement of the extremal* eigenvalues of the child, but then the representation* tree could be different from the one when nothing is* skipped. For this reason we skip at this place.IDONE = IDONE + NEWLST - NEWFST + 1GOTO 139ENDIF** Compute RRR of child cluster.* Note that the new RRR is stored in Z** DLARRF needs LWORK = 2*NCALL DLARRF( IN, D( IBEGIN ), L( IBEGIN ),$ WORK(INDLD+IBEGIN-1),$ NEWFST, NEWLST, WORK(WBEGIN),$ WGAP(WBEGIN), WERR(WBEGIN),$ SPDIAM, LGAP, RGAP, PIVMIN, TAU,$ Z(IBEGIN, NEWFTT),Z(IBEGIN, NEWFTT+1),$ WORK( INDWRK ), IINFO )IF( IINFO.EQ.0 ) THEN* a new RRR for the cluster was found by DLARRF* update shift and store itSSIGMA = SIGMA + TAUZ( IEND, NEWFTT+1 ) = SSIGMA* WORK() are the midpoints and WERR() the semi-width* Note that the entries in W are unchanged.DO 116 K = NEWFST, NEWLSTFUDGE =$ THREE*EPS*ABS(WORK(WBEGIN+K-1))WORK( WBEGIN + K - 1 ) =$ WORK( WBEGIN + K - 1) - TAUFUDGE = FUDGE +$ FOUR*EPS*ABS(WORK(WBEGIN+K-1))* Fudge errorsWERR( WBEGIN + K - 1 ) =$ WERR( WBEGIN + K - 1 ) + FUDGE* Gaps are not fudged. Provided that WERR is small* when eigenvalues are close, a zero gap indicates* that a new representation is needed for resolving* the cluster. A fudge could lead to a wrong decision* of judging eigenvalues 'separated' which in* reality are not. This could have a negative impact* on the orthogonality of the computed eigenvectors.116 CONTINUENCLUS = NCLUS + 1K = NEWCLS + 2*NCLUSIWORK( K-1 ) = NEWFSTIWORK( K ) = NEWLSTELSEINFO = -2RETURNENDIFELSE** Compute eigenvector of singleton*ITER = 0*TOL = FOUR * LOG(DBLE(IN)) * EPS*K = NEWFSTWINDEX = WBEGIN + K - 1WINDMN = MAX(WINDEX - 1,1)WINDPL = MIN(WINDEX + 1,M)LAMBDA = WORK( WINDEX )DONE = DONE + 1* Check if eigenvector computation is to be skippedIF((WINDEX.LT.DOL).OR.$ (WINDEX.GT.DOU)) THENESKIP = .TRUE.GOTO 125ELSEESKIP = .FALSE.ENDIFLEFT = WORK( WINDEX ) - WERR( WINDEX )RIGHT = WORK( WINDEX ) + WERR( WINDEX )INDEIG = INDEXW( WINDEX )* Note that since we compute the eigenpairs for a child,* all eigenvalue approximations are w.r.t the same shift.* In this case, the entries in WORK should be used for* computing the gaps since they exhibit even very small* differences in the eigenvalues, as opposed to the* entries in W which might "look" the same.IF( K .EQ. 1) THEN* In the case RANGE='I' and with not much initial* accuracy in LAMBDA and VL, the formula* LGAP = MAX( ZERO, (SIGMA - VL) + LAMBDA )* can lead to an overestimation of the left gap and* thus to inadequately early RQI 'convergence'.* Prevent this by forcing a small left gap.LGAP = EPS*MAX(ABS(LEFT),ABS(RIGHT))ELSELGAP = WGAP(WINDMN)ENDIFIF( K .EQ. IM) THEN* In the case RANGE='I' and with not much initial* accuracy in LAMBDA and VU, the formula* can lead to an overestimation of the right gap and* thus to inadequately early RQI 'convergence'.* Prevent this by forcing a small right gap.RGAP = EPS*MAX(ABS(LEFT),ABS(RIGHT))ELSERGAP = WGAP(WINDEX)ENDIFGAP = MIN( LGAP, RGAP )IF(( K .EQ. 1).OR.(K .EQ. IM)) THEN* The eigenvector support can become wrong* because significant entries could be cut off due to a* large GAPTOL parameter in LAR1V. Prevent this.GAPTOL = ZEROELSEGAPTOL = GAP * EPSENDIFISUPMN = INISUPMX = 1* Update WGAP so that it holds the minimum gap* to the left or the right. This is crucial in the* case where bisection is used to ensure that the* eigenvalue is refined up to the required precision.* The correct value is restored afterwards.SAVGAP = WGAP(WINDEX)WGAP(WINDEX) = GAP* We want to use the Rayleigh Quotient Correction* as often as possible since it converges quadratically* when we are close enough to the desired eigenvalue.* However, the Rayleigh Quotient can have the wrong sign* and lead us away from the desired eigenvalue. In this* case, the best we can do is to use bisection.USEDBS = .FALSE.USEDRQ = .FALSE.* Bisection is initially turned off unless it is forcedNEEDBS = .NOT.TRYRQC120 CONTINUE* Check if bisection should be used to refine eigenvalueIF(NEEDBS) THEN* Take the bisection as new iterateUSEDBS = .TRUE.ITMP1 = IWORK( IINDR+WINDEX )OFFSET = INDEXW( WBEGIN ) - 1CALL DLARRB( IN, D(IBEGIN),$ WORK(INDLLD+IBEGIN-1),INDEIG,INDEIG,$ ZERO, TWO*EPS, OFFSET,$ WORK(WBEGIN),WGAP(WBEGIN),$ WERR(WBEGIN),WORK( INDWRK ),$ IWORK( IINDWK ), PIVMIN, SPDIAM,$ ITMP1, IINFO )IF( IINFO.NE.0 ) THENINFO = -3RETURNENDIFLAMBDA = WORK( WINDEX )* Reset twist index from inaccurate LAMBDA to* force computation of true MINGMAIWORK( IINDR+WINDEX ) = 0ENDIF* Given LAMBDA, compute the eigenvector.CALL DLAR1V( IN, 1, IN, LAMBDA, D( IBEGIN ),$ L( IBEGIN ), WORK(INDLD+IBEGIN-1),$ WORK(INDLLD+IBEGIN-1),$ PIVMIN, GAPTOL, Z( IBEGIN, WINDEX ),$ .NOT.USEDBS, NEGCNT, ZTZ, MINGMA,$ IWORK( IINDR+WINDEX ), ISUPPZ( 2*WINDEX-1 ),$ NRMINV, RESID, RQCORR, WORK( INDWRK ) )IF(ITER .EQ. 0) THENBSTRES = RESIDBSTW = LAMBDAELSEIF(RESID.LT.BSTRES) THENBSTRES = RESIDBSTW = LAMBDAENDIFISUPMN = MIN(ISUPMN,ISUPPZ( 2*WINDEX-1 ))ISUPMX = MAX(ISUPMX,ISUPPZ( 2*WINDEX ))ITER = ITER + 1* sin alpha <= |resid|/gap* Note that both the residual and the gap are* proportional to the matrix, so ||T|| doesn't play* a role in the quotient** Convergence test for Rayleigh-Quotient iteration* (omitted when Bisection has been used)*IF( RESID.GT.TOL*GAP .AND. ABS( RQCORR ).GT.$ RQTOL*ABS( LAMBDA ) .AND. .NOT. USEDBS)$ THEN* We need to check that the RQCORR update doesn't* move the eigenvalue away from the desired one and* towards a neighbor. -> protection with bisectionIF(INDEIG.LE.NEGCNT) THEN* The wanted eigenvalue lies to the leftSGNDEF = -ONEELSE* The wanted eigenvalue lies to the rightSGNDEF = ONEENDIF* We only use the RQCORR if it improves the* the iterate reasonably.IF( ( RQCORR*SGNDEF.GE.ZERO )$ .AND.( LAMBDA + RQCORR.LE. RIGHT)$ .AND.( LAMBDA + RQCORR.GE. LEFT)$ ) THENUSEDRQ = .TRUE.* Store new midpoint of bisection interval in WORKIF(SGNDEF.EQ.ONE) THEN* The current LAMBDA is on the left of the true* eigenvalueLEFT = LAMBDA* We prefer to assume that the error estimate* is correct. We could make the interval not* as a bracket but to be modified if the RQCORR* chooses to. In this case, the RIGHT side should* be modified as follows:* RIGHT = MAX(RIGHT, LAMBDA + RQCORR)ELSE* The current LAMBDA is on the right of the true* eigenvalueRIGHT = LAMBDA* See comment about assuming the error estimate is* correct above.* LEFT = MIN(LEFT, LAMBDA + RQCORR)ENDIFWORK( WINDEX ) =$ HALF * (RIGHT + LEFT)* Take RQCORR since it has the correct sign and* improves the iterate reasonablyLAMBDA = LAMBDA + RQCORR* Update width of error intervalWERR( WINDEX ) =$ HALF * (RIGHT-LEFT)ELSENEEDBS = .TRUE.ENDIFIF(RIGHT-LEFT.LT.RQTOL*ABS(LAMBDA)) THEN* The eigenvalue is computed to bisection accuracy* compute eigenvector and stopUSEDBS = .TRUE.GOTO 120ELSEIF( ITER.LT.MAXITR ) THENGOTO 120ELSEIF( ITER.EQ.MAXITR ) THENNEEDBS = .TRUE.GOTO 120ELSEINFO = 5RETURNEND IFELSESTP2II = .FALSE.IF(USEDRQ .AND. USEDBS .AND.$ BSTRES.LE.RESID) THENLAMBDA = BSTWSTP2II = .TRUE.ENDIFIF (STP2II) THEN* improve error angle by second stepCALL DLAR1V( IN, 1, IN, LAMBDA,$ D( IBEGIN ), L( IBEGIN ),$ WORK(INDLD+IBEGIN-1),$ WORK(INDLLD+IBEGIN-1),$ PIVMIN, GAPTOL, Z( IBEGIN, WINDEX ),$ .NOT.USEDBS, NEGCNT, ZTZ, MINGMA,$ IWORK( IINDR+WINDEX ),$ ISUPPZ( 2*WINDEX-1 ),$ NRMINV, RESID, RQCORR, WORK( INDWRK ) )ENDIFWORK( WINDEX ) = LAMBDAEND IF** Compute FP-vector support w.r.t. whole matrix*ISUPPZ( 2*WINDEX-1 ) = ISUPPZ( 2*WINDEX-1 )+OLDIENISUPPZ( 2*WINDEX ) = ISUPPZ( 2*WINDEX )+OLDIENZFROM = ISUPPZ( 2*WINDEX-1 )ZTO = ISUPPZ( 2*WINDEX )ISUPMN = ISUPMN + OLDIENISUPMX = ISUPMX + OLDIEN* Ensure vector is ok if support in the RQI has changedIF(ISUPMN.LT.ZFROM) THENDO 122 II = ISUPMN,ZFROM-1Z( II, WINDEX ) = ZERO122 CONTINUEENDIFIF(ISUPMX.GT.ZTO) THENDO 123 II = ZTO+1,ISUPMXZ( II, WINDEX ) = ZERO123 CONTINUEENDIFCALL DSCAL( ZTO-ZFROM+1, NRMINV,$ Z( ZFROM, WINDEX ), 1 )125 CONTINUE* Update WW( WINDEX ) = LAMBDA+SIGMA* Recompute the gaps on the left and right* But only allow them to become larger and not* smaller (which can only happen through "bad"* cancellation and doesn't reflect the theory* where the initial gaps are underestimated due* to WERR being too crude.)IF(.NOT.ESKIP) THENIF( K.GT.1) THENWGAP( WINDMN ) = MAX( WGAP(WINDMN),$ W(WINDEX)-WERR(WINDEX)$ - W(WINDMN)-WERR(WINDMN) )ENDIFIF( WINDEX.LT.WEND ) THENWGAP( WINDEX ) = MAX( SAVGAP,$ W( WINDPL )-WERR( WINDPL )$ - W( WINDEX )-WERR( WINDEX) )ENDIFENDIFIDONE = IDONE + 1ENDIF* here ends the code for the current child*139 CONTINUE* Proceed to any remaining child nodesNEWFST = J + 1140 CONTINUE150 CONTINUENDEPTH = NDEPTH + 1GO TO 40END IFIBEGIN = IEND + 1WBEGIN = WEND + 1170 CONTINUE*RETURN** End of DLARRV*END*> \brief \b DLARSCL2 performs reciprocal diagonal scaling on a vector.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARSCL2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarscl2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarscl2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarscl2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARSCL2 ( M, N, D, X, LDX )** .. Scalar Arguments ..* INTEGER M, N, LDX* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARSCL2 performs a reciprocal diagonal scaling on an vector:*> x <-- inv(D) * x*> where the diagonal matrix D is stored as a vector.*>*> Eventually to be replaced by BLAS_dge_diag_scale in the new BLAS*> standard.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of D and X. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of X. N >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (M)*> Diagonal matrix D, stored as a vector of length M.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,N)*> On entry, the vector X to be scaled by D.*> On exit, the scaled vector.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the vector X. LDX >= M.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DLARSCL2 ( M, N, D, X, LDX )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER M, N, LDX* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), X( LDX, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. Executable Statements ..*DO J = 1, NDO I = 1, MX( I, J ) = X( I, J ) / D( I )END DOEND DORETURNEND*> \brief \b DLARTG generates a plane rotation with real cosine and real sine.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARTG + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlartg.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlartg.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlartg.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARTG( F, G, CS, SN, R )** .. Scalar Arguments ..* DOUBLE PRECISION CS, F, G, R, SN* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARTG generate a plane rotation so that*>*> [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1.*> [ -SN CS ] [ G ] [ 0 ]*>*> This is a slower, more accurate version of the BLAS1 routine DROTG,*> with the following other differences:*> F and G are unchanged on return.*> If G=0, then CS=1 and SN=0.*> If F=0 and (G .ne. 0), then CS=0 and SN=1 without doing any*> floating point operations (saves work in DBDSQR when*> there are zeros on the diagonal).*>*> If F exceeds G in magnitude, CS will be positive.*> \endverbatim** Arguments:* ==========**> \param[in] F*> \verbatim*> F is DOUBLE PRECISION*> The first component of vector to be rotated.*> \endverbatim*>*> \param[in] G*> \verbatim*> G is DOUBLE PRECISION*> The second component of vector to be rotated.*> \endverbatim*>*> \param[out] CS*> \verbatim*> CS is DOUBLE PRECISION*> The cosine of the rotation.*> \endverbatim*>*> \param[out] SN*> \verbatim*> SN is DOUBLE PRECISION*> The sine of the rotation.*> \endverbatim*>*> \param[out] R*> \verbatim*> R is DOUBLE PRECISION*> The nonzero component of the rotated vector.*>*> This version has a few statements commented out for thread safety*> (machine parameters are computed on each entry). 10 feb 03, SJH.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLARTG( F, G, CS, SN, R )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION CS, F, G, R, SN* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..* LOGICAL FIRSTINTEGER COUNT, IDOUBLE PRECISION EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, SQRT* ..* .. Save statement ..* SAVE FIRST, SAFMX2, SAFMIN, SAFMN2* ..* .. Data statements ..* DATA FIRST / .TRUE. /* ..* .. Executable Statements ..** IF( FIRST ) THENSAFMIN = DLAMCH( 'S' )EPS = DLAMCH( 'E' )SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /$ LOG( DLAMCH( 'B' ) ) / TWO )SAFMX2 = ONE / SAFMN2* FIRST = .FALSE.* END IFIF( G.EQ.ZERO ) THENCS = ONESN = ZEROR = FELSE IF( F.EQ.ZERO ) THENCS = ZEROSN = ONER = GELSEF1 = FG1 = GSCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.GE.SAFMX2 ) THENCOUNT = 010 CONTINUECOUNT = COUNT + 1F1 = F1*SAFMN2G1 = G1*SAFMN2SCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.GE.SAFMX2 )$ GO TO 10R = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / RDO 20 I = 1, COUNTR = R*SAFMX220 CONTINUEELSE IF( SCALE.LE.SAFMN2 ) THENCOUNT = 030 CONTINUECOUNT = COUNT + 1F1 = F1*SAFMX2G1 = G1*SAFMX2SCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.LE.SAFMN2 )$ GO TO 30R = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / RDO 40 I = 1, COUNTR = R*SAFMN240 CONTINUEELSER = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / REND IFIF( ABS( F ).GT.ABS( G ) .AND. CS.LT.ZERO ) THENCS = -CSSN = -SNR = -REND IFEND IFRETURN** End of DLARTG*END*> \brief \b DLARTGP generates a plane rotation so that the diagonal is nonnegative.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARTGP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlartgp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlartgp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlartgp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARTGP( F, G, CS, SN, R )** .. Scalar Arguments ..* DOUBLE PRECISION CS, F, G, R, SN* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARTGP generates a plane rotation so that*>*> [ CS SN ] . [ F ] = [ R ] where CS**2 + SN**2 = 1.*> [ -SN CS ] [ G ] [ 0 ]*>*> This is a slower, more accurate version of the Level 1 BLAS routine DROTG,*> with the following other differences:*> F and G are unchanged on return.*> If G=0, then CS=(+/-)1 and SN=0.*> If F=0 and (G .ne. 0), then CS=0 and SN=(+/-)1.*>*> The sign is chosen so that R >= 0.*> \endverbatim** Arguments:* ==========**> \param[in] F*> \verbatim*> F is DOUBLE PRECISION*> The first component of vector to be rotated.*> \endverbatim*>*> \param[in] G*> \verbatim*> G is DOUBLE PRECISION*> The second component of vector to be rotated.*> \endverbatim*>*> \param[out] CS*> \verbatim*> CS is DOUBLE PRECISION*> The cosine of the rotation.*> \endverbatim*>*> \param[out] SN*> \verbatim*> SN is DOUBLE PRECISION*> The sine of the rotation.*> \endverbatim*>*> \param[out] R*> \verbatim*> R is DOUBLE PRECISION*> The nonzero component of the rotated vector.*>*> This version has a few statements commented out for thread safety*> (machine parameters are computed on each entry). 10 feb 03, SJH.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLARTGP( F, G, CS, SN, R )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION CS, F, G, R, SN* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..* LOGICAL FIRSTINTEGER COUNT, IDOUBLE PRECISION EPS, F1, G1, SAFMIN, SAFMN2, SAFMX2, SCALE* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, SIGN, SQRT* ..* .. Save statement ..* SAVE FIRST, SAFMX2, SAFMIN, SAFMN2* ..* .. Data statements ..* DATA FIRST / .TRUE. /* ..* .. Executable Statements ..** IF( FIRST ) THENSAFMIN = DLAMCH( 'S' )EPS = DLAMCH( 'E' )SAFMN2 = DLAMCH( 'B' )**INT( LOG( SAFMIN / EPS ) /$ LOG( DLAMCH( 'B' ) ) / TWO )SAFMX2 = ONE / SAFMN2* FIRST = .FALSE.* END IFIF( G.EQ.ZERO ) THENCS = SIGN( ONE, F )SN = ZEROR = ABS( F )ELSE IF( F.EQ.ZERO ) THENCS = ZEROSN = SIGN( ONE, G )R = ABS( G )ELSEF1 = FG1 = GSCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.GE.SAFMX2 ) THENCOUNT = 010 CONTINUECOUNT = COUNT + 1F1 = F1*SAFMN2G1 = G1*SAFMN2SCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.GE.SAFMX2 )$ GO TO 10R = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / RDO 20 I = 1, COUNTR = R*SAFMX220 CONTINUEELSE IF( SCALE.LE.SAFMN2 ) THENCOUNT = 030 CONTINUECOUNT = COUNT + 1F1 = F1*SAFMX2G1 = G1*SAFMX2SCALE = MAX( ABS( F1 ), ABS( G1 ) )IF( SCALE.LE.SAFMN2 )$ GO TO 30R = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / RDO 40 I = 1, COUNTR = R*SAFMN240 CONTINUEELSER = SQRT( F1**2+G1**2 )CS = F1 / RSN = G1 / REND IFIF( R.LT.ZERO ) THENCS = -CSSN = -SNR = -REND IFEND IFRETURN** End of DLARTGP*END*> \brief \b DLARTGS generates a plane rotation designed to introduce a bulge in implicit QR iteration for the bidiagonal SVD problem.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARTGS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlartgs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlartgs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlartgs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARTGS( X, Y, SIGMA, CS, SN )** .. Scalar Arguments ..* DOUBLE PRECISION CS, SIGMA, SN, X, Y* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARTGS generates a plane rotation designed to introduce a bulge in*> Golub-Reinsch-style implicit QR iteration for the bidiagonal SVD*> problem. X and Y are the top-row entries, and SIGMA is the shift.*> The computed CS and SN define a plane rotation satisfying*>*> [ CS SN ] . [ X^2 - SIGMA ] = [ R ],*> [ -SN CS ] [ X * Y ] [ 0 ]*>*> with R nonnegative. If X^2 - SIGMA and X * Y are 0, then the*> rotation is by PI/2.*> \endverbatim** Arguments:* ==========**> \param[in] X*> \verbatim*> X is DOUBLE PRECISION*> The (1,1) entry of an upper bidiagonal matrix.*> \endverbatim*>*> \param[in] Y*> \verbatim*> Y is DOUBLE PRECISION*> The (1,2) entry of an upper bidiagonal matrix.*> \endverbatim*>*> \param[in] SIGMA*> \verbatim*> SIGMA is DOUBLE PRECISION*> The shift.*> \endverbatim*>*> \param[out] CS*> \verbatim*> CS is DOUBLE PRECISION*> The cosine of the rotation.*> \endverbatim*>*> \param[out] SN*> \verbatim*> SN is DOUBLE PRECISION*> The sine of the rotation.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLARTGS( X, Y, SIGMA, CS, SN )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..DOUBLE PRECISION CS, SIGMA, SN, X, Y* ..** ===================================================================** .. Parameters ..DOUBLE PRECISION NEGONE, ONE, ZEROPARAMETER ( NEGONE = -1.0D0, ONE = 1.0D0, ZERO = 0.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION R, S, THRESH, W, Z* ..* .. External Subroutines ..EXTERNAL DLARTGP* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* .. Executable Statements ..*THRESH = DLAMCH('E')** Compute the first column of B**T*B - SIGMA^2*I, up to a scale* factor.*IF( (SIGMA .EQ. ZERO .AND. ABS(X) .LT. THRESH) .OR.$ (ABS(X) .EQ. SIGMA .AND. Y .EQ. ZERO) ) THENZ = ZEROW = ZEROELSE IF( SIGMA .EQ. ZERO ) THENIF( X .GE. ZERO ) THENZ = XW = YELSEZ = -XW = -YEND IFELSE IF( ABS(X) .LT. THRESH ) THENZ = -SIGMA*SIGMAW = ZEROELSEIF( X .GE. ZERO ) THENS = ONEELSES = NEGONEEND IFZ = S * (ABS(X)-SIGMA) * (S+SIGMA/X)W = S * YEND IF** Generate the rotation.* CALL DLARTGP( Z, W, CS, SN, R ) might seem more natural;* reordering the arguments ensures that if Z = 0 then the rotation* is by PI/2.*CALL DLARTGP( W, Z, SN, CS, R )*RETURN** End DLARTGS*END*> \brief \b DLARTV applies a vector of plane rotations with real cosines and real sines to the elements of a pair of vectors.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARTV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlartv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlartv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlartv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARTV( N, X, INCX, Y, INCY, C, S, INCC )** .. Scalar Arguments ..* INTEGER INCC, INCX, INCY, N* ..* .. Array Arguments ..* DOUBLE PRECISION C( * ), S( * ), X( * ), Y( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARTV applies a vector of real plane rotations to elements of the*> real vectors x and y. For i = 1,2,...,n*>*> ( x(i) ) := ( c(i) s(i) ) ( x(i) )*> ( y(i) ) ( -s(i) c(i) ) ( y(i) )*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of plane rotations to be applied.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCX)*> The vector x.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between elements of X. INCX > 0.*> \endverbatim*>*> \param[in,out] Y*> \verbatim*> Y is DOUBLE PRECISION array,*> dimension (1+(N-1)*INCY)*> The vector y.*> \endverbatim*>*> \param[in] INCY*> \verbatim*> INCY is INTEGER*> The increment between elements of Y. INCY > 0.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (1+(N-1)*INCC)*> The cosines of the plane rotations.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (1+(N-1)*INCC)*> The sines of the plane rotations.*> \endverbatim*>*> \param[in] INCC*> \verbatim*> INCC is INTEGER*> The increment between elements of C and S. INCC > 0.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLARTV( N, X, INCX, Y, INCY, C, S, INCC )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INCC, INCX, INCY, N* ..* .. Array Arguments ..DOUBLE PRECISION C( * ), S( * ), X( * ), Y( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, IC, IX, IYDOUBLE PRECISION XI, YI* ..* .. Executable Statements ..*IX = 1IY = 1IC = 1DO 10 I = 1, NXI = X( IX )YI = Y( IY )X( IX ) = C( IC )*XI + S( IC )*YIY( IY ) = C( IC )*YI - S( IC )*XIIX = IX + INCXIY = IY + INCYIC = IC + INCC10 CONTINUERETURN** End of DLARTV*END*> \brief \b DLARUV returns a vector of n random real numbers from a uniform distribution.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARUV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaruv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaruv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaruv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARUV( ISEED, N, X )** .. Scalar Arguments ..* INTEGER N* ..* .. Array Arguments ..* INTEGER ISEED( 4 )* DOUBLE PRECISION X( N )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARUV returns a vector of n random real numbers from a uniform (0,1)*> distribution (n <= 128).*>*> This is an auxiliary routine called by DLARNV and ZLARNV.*> \endverbatim** Arguments:* ==========**> \param[in,out] ISEED*> \verbatim*> ISEED is INTEGER array, dimension (4)*> On entry, the seed of the random number generator; the array*> elements must be between 0 and 4095, and ISEED(4) must be*> odd.*> On exit, the seed is updated.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of random numbers to be generated. N <= 128.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> The generated random numbers.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> This routine uses a multiplicative congruential method with modulus*> 2**48 and multiplier 33952834046453 (see G.S.Fishman,*> 'Multiplicative congruential random number generators with modulus*> 2**b: an exhaustive analysis for b = 32 and a partial analysis for*> b = 48', Math. Comp. 189, pp 331-344, 1990).*>*> 48-bit integers are stored in 4 integer array elements with 12 bits*> per element. Hence the routine is portable across machines with*> integers of 32 bits or more.*> \endverbatim*>* =====================================================================SUBROUTINE DLARUV( ISEED, N, X )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER N* ..* .. Array Arguments ..INTEGER ISEED( 4 )DOUBLE PRECISION X( N )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )INTEGER LV, IPW2DOUBLE PRECISION RPARAMETER ( LV = 128, IPW2 = 4096, R = ONE / IPW2 )* ..* .. Local Scalars ..INTEGER I, I1, I2, I3, I4, IT1, IT2, IT3, IT4, J* ..* .. Local Arrays ..INTEGER MM( LV, 4 )* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MIN, MOD* ..* .. Data statements ..DATA ( MM( 1, J ), J = 1, 4 ) / 494, 322, 2508,$ 2549 /DATA ( MM( 2, J ), J = 1, 4 ) / 2637, 789, 3754,$ 1145 /DATA ( MM( 3, J ), J = 1, 4 ) / 255, 1440, 1766,$ 2253 /DATA ( MM( 4, J ), J = 1, 4 ) / 2008, 752, 3572,$ 305 /DATA ( MM( 5, J ), J = 1, 4 ) / 1253, 2859, 2893,$ 3301 /DATA ( MM( 6, J ), J = 1, 4 ) / 3344, 123, 307,$ 1065 /DATA ( MM( 7, J ), J = 1, 4 ) / 4084, 1848, 1297,$ 3133 /DATA ( MM( 8, J ), J = 1, 4 ) / 1739, 643, 3966,$ 2913 /DATA ( MM( 9, J ), J = 1, 4 ) / 3143, 2405, 758,$ 3285 /DATA ( MM( 10, J ), J = 1, 4 ) / 3468, 2638, 2598,$ 1241 /DATA ( MM( 11, J ), J = 1, 4 ) / 688, 2344, 3406,$ 1197 /DATA ( MM( 12, J ), J = 1, 4 ) / 1657, 46, 2922,$ 3729 /DATA ( MM( 13, J ), J = 1, 4 ) / 1238, 3814, 1038,$ 2501 /DATA ( MM( 14, J ), J = 1, 4 ) / 3166, 913, 2934,$ 1673 /DATA ( MM( 15, J ), J = 1, 4 ) / 1292, 3649, 2091,$ 541 /DATA ( MM( 16, J ), J = 1, 4 ) / 3422, 339, 2451,$ 2753 /DATA ( MM( 17, J ), J = 1, 4 ) / 1270, 3808, 1580,$ 949 /DATA ( MM( 18, J ), J = 1, 4 ) / 2016, 822, 1958,$ 2361 /DATA ( MM( 19, J ), J = 1, 4 ) / 154, 2832, 2055,$ 1165 /DATA ( MM( 20, J ), J = 1, 4 ) / 2862, 3078, 1507,$ 4081 /DATA ( MM( 21, J ), J = 1, 4 ) / 697, 3633, 1078,$ 2725 /DATA ( MM( 22, J ), J = 1, 4 ) / 1706, 2970, 3273,$ 3305 /DATA ( MM( 23, J ), J = 1, 4 ) / 491, 637, 17,$ 3069 /DATA ( MM( 24, J ), J = 1, 4 ) / 931, 2249, 854,$ 3617 /DATA ( MM( 25, J ), J = 1, 4 ) / 1444, 2081, 2916,$ 3733 /DATA ( MM( 26, J ), J = 1, 4 ) / 444, 4019, 3971,$ 409 /DATA ( MM( 27, J ), J = 1, 4 ) / 3577, 1478, 2889,$ 2157 /DATA ( MM( 28, J ), J = 1, 4 ) / 3944, 242, 3831,$ 1361 /DATA ( MM( 29, J ), J = 1, 4 ) / 2184, 481, 2621,$ 3973 /DATA ( MM( 30, J ), J = 1, 4 ) / 1661, 2075, 1541,$ 1865 /DATA ( MM( 31, J ), J = 1, 4 ) / 3482, 4058, 893,$ 2525 /DATA ( MM( 32, J ), J = 1, 4 ) / 657, 622, 736,$ 1409 /DATA ( MM( 33, J ), J = 1, 4 ) / 3023, 3376, 3992,$ 3445 /DATA ( MM( 34, J ), J = 1, 4 ) / 3618, 812, 787,$ 3577 /DATA ( MM( 35, J ), J = 1, 4 ) / 1267, 234, 2125,$ 77 /DATA ( MM( 36, J ), J = 1, 4 ) / 1828, 641, 2364,$ 3761 /DATA ( MM( 37, J ), J = 1, 4 ) / 164, 4005, 2460,$ 2149 /DATA ( MM( 38, J ), J = 1, 4 ) / 3798, 1122, 257,$ 1449 /DATA ( MM( 39, J ), J = 1, 4 ) / 3087, 3135, 1574,$ 3005 /DATA ( MM( 40, J ), J = 1, 4 ) / 2400, 2640, 3912,$ 225 /DATA ( MM( 41, J ), J = 1, 4 ) / 2870, 2302, 1216,$ 85 /DATA ( MM( 42, J ), J = 1, 4 ) / 3876, 40, 3248,$ 3673 /DATA ( MM( 43, J ), J = 1, 4 ) / 1905, 1832, 3401,$ 3117 /DATA ( MM( 44, J ), J = 1, 4 ) / 1593, 2247, 2124,$ 3089 /DATA ( MM( 45, J ), J = 1, 4 ) / 1797, 2034, 2762,$ 1349 /DATA ( MM( 46, J ), J = 1, 4 ) / 1234, 2637, 149,$ 2057 /DATA ( MM( 47, J ), J = 1, 4 ) / 3460, 1287, 2245,$ 413 /DATA ( MM( 48, J ), J = 1, 4 ) / 328, 1691, 166,$ 65 /DATA ( MM( 49, J ), J = 1, 4 ) / 2861, 496, 466,$ 1845 /DATA ( MM( 50, J ), J = 1, 4 ) / 1950, 1597, 4018,$ 697 /DATA ( MM( 51, J ), J = 1, 4 ) / 617, 2394, 1399,$ 3085 /DATA ( MM( 52, J ), J = 1, 4 ) / 2070, 2584, 190,$ 3441 /DATA ( MM( 53, J ), J = 1, 4 ) / 3331, 1843, 2879,$ 1573 /DATA ( MM( 54, J ), J = 1, 4 ) / 769, 336, 153,$ 3689 /DATA ( MM( 55, J ), J = 1, 4 ) / 1558, 1472, 2320,$ 2941 /DATA ( MM( 56, J ), J = 1, 4 ) / 2412, 2407, 18,$ 929 /DATA ( MM( 57, J ), J = 1, 4 ) / 2800, 433, 712,$ 533 /DATA ( MM( 58, J ), J = 1, 4 ) / 189, 2096, 2159,$ 2841 /DATA ( MM( 59, J ), J = 1, 4 ) / 287, 1761, 2318,$ 4077 /DATA ( MM( 60, J ), J = 1, 4 ) / 2045, 2810, 2091,$ 721 /DATA ( MM( 61, J ), J = 1, 4 ) / 1227, 566, 3443,$ 2821 /DATA ( MM( 62, J ), J = 1, 4 ) / 2838, 442, 1510,$ 2249 /DATA ( MM( 63, J ), J = 1, 4 ) / 209, 41, 449,$ 2397 /DATA ( MM( 64, J ), J = 1, 4 ) / 2770, 1238, 1956,$ 2817 /DATA ( MM( 65, J ), J = 1, 4 ) / 3654, 1086, 2201,$ 245 /DATA ( MM( 66, J ), J = 1, 4 ) / 3993, 603, 3137,$ 1913 /DATA ( MM( 67, J ), J = 1, 4 ) / 192, 840, 3399,$ 1997 /DATA ( MM( 68, J ), J = 1, 4 ) / 2253, 3168, 1321,$ 3121 /DATA ( MM( 69, J ), J = 1, 4 ) / 3491, 1499, 2271,$ 997 /DATA ( MM( 70, J ), J = 1, 4 ) / 2889, 1084, 3667,$ 1833 /DATA ( MM( 71, J ), J = 1, 4 ) / 2857, 3438, 2703,$ 2877 /DATA ( MM( 72, J ), J = 1, 4 ) / 2094, 2408, 629,$ 1633 /DATA ( MM( 73, J ), J = 1, 4 ) / 1818, 1589, 2365,$ 981 /DATA ( MM( 74, J ), J = 1, 4 ) / 688, 2391, 2431,$ 2009 /DATA ( MM( 75, J ), J = 1, 4 ) / 1407, 288, 1113,$ 941 /DATA ( MM( 76, J ), J = 1, 4 ) / 634, 26, 3922,$ 2449 /DATA ( MM( 77, J ), J = 1, 4 ) / 3231, 512, 2554,$ 197 /DATA ( MM( 78, J ), J = 1, 4 ) / 815, 1456, 184,$ 2441 /DATA ( MM( 79, J ), J = 1, 4 ) / 3524, 171, 2099,$ 285 /DATA ( MM( 80, J ), J = 1, 4 ) / 1914, 1677, 3228,$ 1473 /DATA ( MM( 81, J ), J = 1, 4 ) / 516, 2657, 4012,$ 2741 /DATA ( MM( 82, J ), J = 1, 4 ) / 164, 2270, 1921,$ 3129 /DATA ( MM( 83, J ), J = 1, 4 ) / 303, 2587, 3452,$ 909 /DATA ( MM( 84, J ), J = 1, 4 ) / 2144, 2961, 3901,$ 2801 /DATA ( MM( 85, J ), J = 1, 4 ) / 3480, 1970, 572,$ 421 /DATA ( MM( 86, J ), J = 1, 4 ) / 119, 1817, 3309,$ 4073 /DATA ( MM( 87, J ), J = 1, 4 ) / 3357, 676, 3171,$ 2813 /DATA ( MM( 88, J ), J = 1, 4 ) / 837, 1410, 817,$ 2337 /DATA ( MM( 89, J ), J = 1, 4 ) / 2826, 3723, 3039,$ 1429 /DATA ( MM( 90, J ), J = 1, 4 ) / 2332, 2803, 1696,$ 1177 /DATA ( MM( 91, J ), J = 1, 4 ) / 2089, 3185, 1256,$ 1901 /DATA ( MM( 92, J ), J = 1, 4 ) / 3780, 184, 3715,$ 81 /DATA ( MM( 93, J ), J = 1, 4 ) / 1700, 663, 2077,$ 1669 /DATA ( MM( 94, J ), J = 1, 4 ) / 3712, 499, 3019,$ 2633 /DATA ( MM( 95, J ), J = 1, 4 ) / 150, 3784, 1497,$ 2269 /DATA ( MM( 96, J ), J = 1, 4 ) / 2000, 1631, 1101,$ 129 /DATA ( MM( 97, J ), J = 1, 4 ) / 3375, 1925, 717,$ 1141 /DATA ( MM( 98, J ), J = 1, 4 ) / 1621, 3912, 51,$ 249 /DATA ( MM( 99, J ), J = 1, 4 ) / 3090, 1398, 981,$ 3917 /DATA ( MM( 100, J ), J = 1, 4 ) / 3765, 1349, 1978,$ 2481 /DATA ( MM( 101, J ), J = 1, 4 ) / 1149, 1441, 1813,$ 3941 /DATA ( MM( 102, J ), J = 1, 4 ) / 3146, 2224, 3881,$ 2217 /DATA ( MM( 103, J ), J = 1, 4 ) / 33, 2411, 76,$ 2749 /DATA ( MM( 104, J ), J = 1, 4 ) / 3082, 1907, 3846,$ 3041 /DATA ( MM( 105, J ), J = 1, 4 ) / 2741, 3192, 3694,$ 1877 /DATA ( MM( 106, J ), J = 1, 4 ) / 359, 2786, 1682,$ 345 /DATA ( MM( 107, J ), J = 1, 4 ) / 3316, 382, 124,$ 2861 /DATA ( MM( 108, J ), J = 1, 4 ) / 1749, 37, 1660,$ 1809 /DATA ( MM( 109, J ), J = 1, 4 ) / 185, 759, 3997,$ 3141 /DATA ( MM( 110, J ), J = 1, 4 ) / 2784, 2948, 479,$ 2825 /DATA ( MM( 111, J ), J = 1, 4 ) / 2202, 1862, 1141,$ 157 /DATA ( MM( 112, J ), J = 1, 4 ) / 2199, 3802, 886,$ 2881 /DATA ( MM( 113, J ), J = 1, 4 ) / 1364, 2423, 3514,$ 3637 /DATA ( MM( 114, J ), J = 1, 4 ) / 1244, 2051, 1301,$ 1465 /DATA ( MM( 115, J ), J = 1, 4 ) / 2020, 2295, 3604,$ 2829 /DATA ( MM( 116, J ), J = 1, 4 ) / 3160, 1332, 1888,$ 2161 /DATA ( MM( 117, J ), J = 1, 4 ) / 2785, 1832, 1836,$ 3365 /DATA ( MM( 118, J ), J = 1, 4 ) / 2772, 2405, 1990,$ 361 /DATA ( MM( 119, J ), J = 1, 4 ) / 1217, 3638, 2058,$ 2685 /DATA ( MM( 120, J ), J = 1, 4 ) / 1822, 3661, 692,$ 3745 /DATA ( MM( 121, J ), J = 1, 4 ) / 1245, 327, 1194,$ 2325 /DATA ( MM( 122, J ), J = 1, 4 ) / 2252, 3660, 20,$ 3609 /DATA ( MM( 123, J ), J = 1, 4 ) / 3904, 716, 3285,$ 3821 /DATA ( MM( 124, J ), J = 1, 4 ) / 2774, 1842, 2046,$ 3537 /DATA ( MM( 125, J ), J = 1, 4 ) / 997, 3987, 2107,$ 517 /DATA ( MM( 126, J ), J = 1, 4 ) / 2573, 1368, 3508,$ 3017 /DATA ( MM( 127, J ), J = 1, 4 ) / 1148, 1848, 3525,$ 2141 /DATA ( MM( 128, J ), J = 1, 4 ) / 545, 2366, 3801,$ 1537 /* ..* .. Executable Statements ..*I1 = ISEED( 1 )I2 = ISEED( 2 )I3 = ISEED( 3 )I4 = ISEED( 4 )*DO 10 I = 1, MIN( N, LV )*20 CONTINUE** Multiply the seed by i-th power of the multiplier modulo 2**48*IT4 = I4*MM( I, 4 )IT3 = IT4 / IPW2IT4 = IT4 - IPW2*IT3IT3 = IT3 + I3*MM( I, 4 ) + I4*MM( I, 3 )IT2 = IT3 / IPW2IT3 = IT3 - IPW2*IT2IT2 = IT2 + I2*MM( I, 4 ) + I3*MM( I, 3 ) + I4*MM( I, 2 )IT1 = IT2 / IPW2IT2 = IT2 - IPW2*IT1IT1 = IT1 + I1*MM( I, 4 ) + I2*MM( I, 3 ) + I3*MM( I, 2 ) +$ I4*MM( I, 1 )IT1 = MOD( IT1, IPW2 )** Convert 48-bit integer to a real number in the interval (0,1)*X( I ) = R*( DBLE( IT1 )+R*( DBLE( IT2 )+R*( DBLE( IT3 )+R*$ DBLE( IT4 ) ) ) )*IF (X( I ).EQ.1.0D0) THEN* If a real number has n bits of precision, and the first* n bits of the 48-bit integer above happen to be all 1 (which* will occur about once every 2**n calls), then X( I ) will* be rounded to exactly 1.0.* Since X( I ) is not supposed to return exactly 0.0 or 1.0,* the statistically correct thing to do in this situation is* simply to iterate again.* N.B. the case X( I ) = 0.0 should not be possible.I1 = I1 + 2I2 = I2 + 2I3 = I3 + 2I4 = I4 + 2GOTO 20END IF*10 CONTINUE** Return final value of seed*ISEED( 1 ) = IT1ISEED( 2 ) = IT2ISEED( 3 ) = IT3ISEED( 4 ) = IT4RETURN** End of DLARUV*END*> \brief \b DLARZ applies an elementary reflector (as returned by stzrzf) to a general matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARZ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarz.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarz.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarz.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )** .. Scalar Arguments ..* CHARACTER SIDE* INTEGER INCV, L, LDC, M, N* DOUBLE PRECISION TAU* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARZ applies a real elementary reflector H to a real M-by-N*> matrix C, from either the left or the right. H is represented in the*> form*>*> H = I - tau * v * v**T*>*> where tau is a real scalar and v is a real vector.*>*> If tau = 0, then H is taken to be the unit matrix.*>*>*> H is a product of k elementary reflectors as returned by DTZRZF.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': form H * C*> = 'R': form C * H*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of entries of the vector V containing*> the meaningful part of the Householder vectors.*> If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (1+(L-1)*abs(INCV))*> The vector v in the representation of H as returned by*> DTZRZF. V is not used if TAU = 0.*> \endverbatim*>*> \param[in] INCV*> \verbatim*> INCV is INTEGER*> The increment between elements of v. INCV <> 0.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The value tau in the representation of H.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',*> or C * H if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L'*> or (M) if SIDE = 'R'*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*> \endverbatim*>* =====================================================================SUBROUTINE DLARZ( SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDEINTEGER INCV, L, LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGER* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C*IF( TAU.NE.ZERO ) THEN** w( 1:n ) = C( 1, 1:n )*CALL DCOPY( N, C, LDC, WORK, 1 )** w( 1:n ) = w( 1:n ) + C( m-l+1:m, 1:n )**T * v( 1:l )*CALL DGEMV( 'Transpose', L, N, ONE, C( M-L+1, 1 ), LDC, V,$ INCV, ONE, WORK, 1 )** C( 1, 1:n ) = C( 1, 1:n ) - tau * w( 1:n )*CALL DAXPY( N, -TAU, WORK, 1, C, LDC )** C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...* tau * v( 1:l ) * w( 1:n )**T*CALL DGER( L, N, -TAU, V, INCV, WORK, 1, C( M-L+1, 1 ),$ LDC )END IF*ELSE** Form C * H*IF( TAU.NE.ZERO ) THEN** w( 1:m ) = C( 1:m, 1 )*CALL DCOPY( M, C, 1, WORK, 1 )** w( 1:m ) = w( 1:m ) + C( 1:m, n-l+1:n, 1:n ) * v( 1:l )*CALL DGEMV( 'No transpose', M, L, ONE, C( 1, N-L+1 ), LDC,$ V, INCV, ONE, WORK, 1 )** C( 1:m, 1 ) = C( 1:m, 1 ) - tau * w( 1:m )*CALL DAXPY( M, -TAU, WORK, 1, C, 1 )** C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...* tau * w( 1:m ) * v( 1:l )**T*CALL DGER( M, L, -TAU, WORK, 1, V, INCV, C( 1, N-L+1 ),$ LDC )*END IF*END IF*RETURN** End of DLARZ*END*> \brief \b DLARZB applies a block reflector or its transpose to a general matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARZB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarzb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarzb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarzb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,* LDV, T, LDT, C, LDC, WORK, LDWORK )** .. Scalar Arguments ..* CHARACTER DIRECT, SIDE, STOREV, TRANS* INTEGER K, L, LDC, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),* $ WORK( LDWORK, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARZB applies a real block reflector H or its transpose H**T to*> a real distributed M-by-N C from the left or the right.*>*> Currently, only STOREV = 'R' and DIRECT = 'B' are supported.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply H or H**T from the Left*> = 'R': apply H or H**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply H (No transpose)*> = 'C': apply H**T (Transpose)*> \endverbatim*>*> \param[in] DIRECT*> \verbatim*> DIRECT is CHARACTER*1*> Indicates how H is formed from a product of elementary*> reflectors*> = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)*> = 'B': H = H(k) . . . H(2) H(1) (Backward)*> \endverbatim*>*> \param[in] STOREV*> \verbatim*> STOREV is CHARACTER*1*> Indicates how the vectors which define the elementary*> reflectors are stored:*> = 'C': Columnwise (not supported yet)*> = 'R': Rowwise*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The order of the matrix T (= the number of elementary*> reflectors whose product defines the block reflector).*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of columns of the matrix V containing the*> meaningful part of the Householder reflectors.*> If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,NV).*> If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The triangular K-by-K matrix T in the representation of the*> block reflector.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= K.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by H*C or H**T*C or C*H or C*H**T.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LDWORK,K)*> \endverbatim*>*> \param[in] LDWORK*> \verbatim*> LDWORK is INTEGER*> The leading dimension of the array WORK.*> If SIDE = 'L', LDWORK >= max(1,N);*> if SIDE = 'R', LDWORK >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*> \endverbatim*>* =====================================================================SUBROUTINE DLARZB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V,$ LDV, T, LDT, C, LDC, WORK, LDWORK )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIRECT, SIDE, STOREV, TRANSINTEGER K, L, LDC, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),$ WORK( LDWORK, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..CHARACTER TRANSTINTEGER I, INFO, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DTRMM, XERBLA* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 )$ RETURN** Check for currently supported options*INFO = 0IF( .NOT.LSAME( DIRECT, 'B' ) ) THENINFO = -3ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLARZB', -INFO )RETURNEND IF*IF( LSAME( TRANS, 'N' ) ) THENTRANST = 'T'ELSETRANST = 'N'END IF*IF( LSAME( SIDE, 'L' ) ) THEN** Form H * C or H**T * C** W( 1:n, 1:k ) = C( 1:k, 1:n )**T*DO 10 J = 1, KCALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )10 CONTINUE** W( 1:n, 1:k ) = W( 1:n, 1:k ) + ...* C( m-l+1:m, 1:n )**T * V( 1:k, 1:l )**T*IF( L.GT.0 )$ CALL DGEMM( 'Transpose', 'Transpose', N, K, L, ONE,$ C( M-L+1, 1 ), LDC, V, LDV, ONE, WORK, LDWORK )** W( 1:n, 1:k ) = W( 1:n, 1:k ) * T**T or W( 1:m, 1:k ) * T*CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit', N, K, ONE, T,$ LDT, WORK, LDWORK )** C( 1:k, 1:n ) = C( 1:k, 1:n ) - W( 1:n, 1:k )**T*DO 30 J = 1, NDO 20 I = 1, KC( I, J ) = C( I, J ) - WORK( J, I )20 CONTINUE30 CONTINUE** C( m-l+1:m, 1:n ) = C( m-l+1:m, 1:n ) - ...* V( 1:k, 1:l )**T * W( 1:n, 1:k )**T*IF( L.GT.0 )$ CALL DGEMM( 'Transpose', 'Transpose', L, N, K, -ONE, V, LDV,$ WORK, LDWORK, ONE, C( M-L+1, 1 ), LDC )*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form C * H or C * H**T** W( 1:m, 1:k ) = C( 1:m, 1:k )*DO 40 J = 1, KCALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )40 CONTINUE** W( 1:m, 1:k ) = W( 1:m, 1:k ) + ...* C( 1:m, n-l+1:n ) * V( 1:k, 1:l )**T*IF( L.GT.0 )$ CALL DGEMM( 'No transpose', 'Transpose', M, K, L, ONE,$ C( 1, N-L+1 ), LDC, V, LDV, ONE, WORK, LDWORK )** W( 1:m, 1:k ) = W( 1:m, 1:k ) * T or W( 1:m, 1:k ) * T**T*CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit', M, K, ONE, T,$ LDT, WORK, LDWORK )** C( 1:m, 1:k ) = C( 1:m, 1:k ) - W( 1:m, 1:k )*DO 60 J = 1, KDO 50 I = 1, MC( I, J ) = C( I, J ) - WORK( I, J )50 CONTINUE60 CONTINUE** C( 1:m, n-l+1:n ) = C( 1:m, n-l+1:n ) - ...* W( 1:m, 1:k ) * V( 1:k, 1:l )*IF( L.GT.0 )$ CALL DGEMM( 'No transpose', 'No transpose', M, L, K, -ONE,$ WORK, LDWORK, V, LDV, ONE, C( 1, N-L+1 ), LDC )*END IF*RETURN** End of DLARZB*END*> \brief \b DLARZT forms the triangular factor T of a block reflector H = I - vtvH.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLARZT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarzt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarzt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarzt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )** .. Scalar Arguments ..* CHARACTER DIRECT, STOREV* INTEGER K, LDT, LDV, N* ..* .. Array Arguments ..* DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLARZT forms the triangular factor T of a real block reflector*> H of order > n, which is defined as a product of k elementary*> reflectors.*>*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;*>*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.*>*> If STOREV = 'C', the vector which defines the elementary reflector*> H(i) is stored in the i-th column of the array V, and*>*> H = I - V * T * V**T*>*> If STOREV = 'R', the vector which defines the elementary reflector*> H(i) is stored in the i-th row of the array V, and*>*> H = I - V**T * T * V*>*> Currently, only STOREV = 'R' and DIRECT = 'B' are supported.*> \endverbatim** Arguments:* ==========**> \param[in] DIRECT*> \verbatim*> DIRECT is CHARACTER*1*> Specifies the order in which the elementary reflectors are*> multiplied to form the block reflector:*> = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)*> = 'B': H = H(k) . . . H(2) H(1) (Backward)*> \endverbatim*>*> \param[in] STOREV*> \verbatim*> STOREV is CHARACTER*1*> Specifies how the vectors which define the elementary*> reflectors are stored (see also Further Details):*> = 'C': columnwise (not supported yet)*> = 'R': rowwise*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the block reflector H. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The order of the triangular factor T (= the number of*> elementary reflectors). K >= 1.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension*> (LDV,K) if STOREV = 'C'*> (LDV,N) if STOREV = 'R'*> The matrix V. See further details.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The k by k triangular factor T of the block reflector.*> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is*> lower triangular. The rest of the array is not used.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= K.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*>*> The shape of the matrix V and the storage of the vectors which define*> the H(i) is best illustrated by the following example with n = 5 and*> k = 3. The elements equal to 1 are not stored; the corresponding*> array elements are modified but restored on exit. The rest of the*> array is not used.*>*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':*>*> ______V_____*> ( v1 v2 v3 ) / \*> ( v1 v2 v3 ) ( v1 v1 v1 v1 v1 . . . . 1 )*> V = ( v1 v2 v3 ) ( v2 v2 v2 v2 v2 . . . 1 )*> ( v1 v2 v3 ) ( v3 v3 v3 v3 v3 . . 1 )*> ( v1 v2 v3 )*> . . .*> . . .*> 1 . .*> 1 .*> 1*>*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':*>*> ______V_____*> 1 / \*> . 1 ( 1 . . . . v1 v1 v1 v1 v1 )*> . . 1 ( . 1 . . . v2 v2 v2 v2 v2 )*> . . . ( . . 1 . . v3 v3 v3 v3 v3 )*> . . .*> ( v1 v2 v3 )*> ( v1 v2 v3 )*> V = ( v1 v2 v3 )*> ( v1 v2 v3 )*> ( v1 v2 v3 )*> \endverbatim*>* =====================================================================SUBROUTINE DLARZT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIRECT, STOREVINTEGER K, LDT, LDV, N* ..* .. Array Arguments ..DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, INFO, J* ..* .. External Subroutines ..EXTERNAL DGEMV, DTRMV, XERBLA* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Check for currently supported options*INFO = 0IF( .NOT.LSAME( DIRECT, 'B' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( STOREV, 'R' ) ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLARZT', -INFO )RETURNEND IF*DO 20 I = K, 1, -1IF( TAU( I ).EQ.ZERO ) THEN** H(i) = I*DO 10 J = I, KT( J, I ) = ZERO10 CONTINUEELSE** general case*IF( I.LT.K ) THEN** T(i+1:k,i) = - tau(i) * V(i+1:k,1:n) * V(i,1:n)**T*CALL DGEMV( 'No transpose', K-I, N, -TAU( I ),$ V( I+1, 1 ), LDV, V( I, 1 ), LDV, ZERO,$ T( I+1, I ), 1 )** T(i+1:k,i) = T(i+1:k,i+1:k) * T(i+1:k,i)*CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,$ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )END IFT( I, I ) = TAU( I )END IF20 CONTINUERETURN** End of DLARZT*END*> \brief \b DLAS2 computes singular values of a 2-by-2 triangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAS2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlas2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlas2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlas2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX )** .. Scalar Arguments ..* DOUBLE PRECISION F, G, H, SSMAX, SSMIN* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAS2 computes the singular values of the 2-by-2 matrix*> [ F G ]*> [ 0 H ].*> On return, SSMIN is the smaller singular value and SSMAX is the*> larger singular value.*> \endverbatim** Arguments:* ==========**> \param[in] F*> \verbatim*> F is DOUBLE PRECISION*> The (1,1) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] G*> \verbatim*> G is DOUBLE PRECISION*> The (1,2) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] H*> \verbatim*> H is DOUBLE PRECISION*> The (2,2) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[out] SSMIN*> \verbatim*> SSMIN is DOUBLE PRECISION*> The smaller singular value.*> \endverbatim*>*> \param[out] SSMAX*> \verbatim*> SSMAX is DOUBLE PRECISION*> The larger singular value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Barring over/underflow, all output quantities are correct to within*> a few units in the last place (ulps), even in the absence of a guard*> digit in addition/subtraction.*>*> In IEEE arithmetic, the code works correctly if one matrix element is*> infinite.*>*> Overflow will not occur unless the largest singular value itself*> overflows, or is within a few ulps of overflow. (On machines with*> partial overflow, like the Cray, overflow may occur if the largest*> singular value is within a factor of 2 of overflow.)*>*> Underflow is harmless if underflow is gradual. Otherwise, results*> may correspond to a matrix modified by perturbations of size near*> the underflow threshold.*> \endverbatim*>* =====================================================================SUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION F, G, H, SSMAX, SSMIN* ..** ====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )* ..* .. Local Scalars ..DOUBLE PRECISION AS, AT, AU, C, FA, FHMN, FHMX, GA, HA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*FA = ABS( F )GA = ABS( G )HA = ABS( H )FHMN = MIN( FA, HA )FHMX = MAX( FA, HA )IF( FHMN.EQ.ZERO ) THENSSMIN = ZEROIF( FHMX.EQ.ZERO ) THENSSMAX = GAELSESSMAX = MAX( FHMX, GA )*SQRT( ONE+$ ( MIN( FHMX, GA ) / MAX( FHMX, GA ) )**2 )END IFELSEIF( GA.LT.FHMX ) THENAS = ONE + FHMN / FHMXAT = ( FHMX-FHMN ) / FHMXAU = ( GA / FHMX )**2C = TWO / ( SQRT( AS*AS+AU )+SQRT( AT*AT+AU ) )SSMIN = FHMN*CSSMAX = FHMX / CELSEAU = FHMX / GAIF( AU.EQ.ZERO ) THEN** Avoid possible harmful underflow if exponent range* asymmetric (true SSMIN may not underflow even if* AU underflows)*SSMIN = ( FHMN*FHMX ) / GASSMAX = GAELSEAS = ONE + FHMN / FHMXAT = ( FHMX-FHMN ) / FHMXC = ONE / ( SQRT( ONE+( AS*AU )**2 )+$ SQRT( ONE+( AT*AU )**2 ) )SSMIN = ( FHMN*C )*AUSSMIN = SSMIN + SSMINSSMAX = GA / ( C+C )END IFEND IFEND IFRETURN** End of DLAS2*END*> \brief \b DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASCL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlascl.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlascl.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlascl.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER TYPE* INTEGER INFO, KL, KU, LDA, M, N* DOUBLE PRECISION CFROM, CTO* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASCL multiplies the M by N real matrix A by the real scalar*> CTO/CFROM. This is done without over/underflow as long as the final*> result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that*> A may be full, upper triangular, lower triangular, upper Hessenberg,*> or banded.*> \endverbatim** Arguments:* ==========**> \param[in] TYPE*> \verbatim*> TYPE is CHARACTER*1*> TYPE indices the storage type of the input matrix.*> = 'G': A is a full matrix.*> = 'L': A is a lower triangular matrix.*> = 'U': A is an upper triangular matrix.*> = 'H': A is an upper Hessenberg matrix.*> = 'B': A is a symmetric band matrix with lower bandwidth KL*> and upper bandwidth KU and with the only the lower*> half stored.*> = 'Q': A is a symmetric band matrix with lower bandwidth KL*> and upper bandwidth KU and with the only the upper*> half stored.*> = 'Z': A is a band matrix with lower bandwidth KL and upper*> bandwidth KU. See DGBTRF for storage details.*> \endverbatim*>*> \param[in] KL*> \verbatim*> KL is INTEGER*> The lower bandwidth of A. Referenced only if TYPE = 'B',*> 'Q' or 'Z'.*> \endverbatim*>*> \param[in] KU*> \verbatim*> KU is INTEGER*> The upper bandwidth of A. Referenced only if TYPE = 'B',*> 'Q' or 'Z'.*> \endverbatim*>*> \param[in] CFROM*> \verbatim*> CFROM is DOUBLE PRECISION*> \endverbatim*>*> \param[in] CTO*> \verbatim*> CTO is DOUBLE PRECISION*>*> The matrix A is multiplied by CTO/CFROM. A(I,J) is computed*> without over/underflow if the final result CTO*A(I,J)/CFROM*> can be represented without over/underflow. CFROM must be*> nonzero.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The matrix to be multiplied by CTO/CFROM. See TYPE for the*> storage type.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If TYPE = 'G', 'L', 'U', 'H', LDA >= max(1,M);*> TYPE = 'B', LDA >= KL+1;*> TYPE = 'Q', LDA >= KU+1;*> TYPE = 'Z', LDA >= 2*KL+KU+1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> 0 - successful exit*> <0 - if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER TYPEINTEGER INFO, KL, KU, LDA, M, NDOUBLE PRECISION CFROM, CTO* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL DONEINTEGER I, ITYPE, J, K1, K2, K3, K4DOUBLE PRECISION BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM* ..* .. External Functions ..LOGICAL LSAME, DISNANDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH, DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input arguments*INFO = 0*IF( LSAME( TYPE, 'G' ) ) THENITYPE = 0ELSE IF( LSAME( TYPE, 'L' ) ) THENITYPE = 1ELSE IF( LSAME( TYPE, 'U' ) ) THENITYPE = 2ELSE IF( LSAME( TYPE, 'H' ) ) THENITYPE = 3ELSE IF( LSAME( TYPE, 'B' ) ) THENITYPE = 4ELSE IF( LSAME( TYPE, 'Q' ) ) THENITYPE = 5ELSE IF( LSAME( TYPE, 'Z' ) ) THENITYPE = 6ELSEITYPE = -1END IF*IF( ITYPE.EQ.-1 ) THENINFO = -1ELSE IF( CFROM.EQ.ZERO .OR. DISNAN(CFROM) ) THENINFO = -4ELSE IF( DISNAN(CTO) ) THENINFO = -5ELSE IF( M.LT.0 ) THENINFO = -6ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR.$ ( ITYPE.EQ.5 .AND. N.NE.M ) ) THENINFO = -7ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THENINFO = -9ELSE IF( ITYPE.GE.4 ) THENIF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THENINFO = -2ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.$ ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )$ THENINFO = -3ELSE 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 ) ) THENINFO = -9END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DLASCL', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. M.EQ.0 )$ RETURN** Get machine parameters*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUM*CFROMC = CFROMCTOC = CTO*10 CONTINUECFROM1 = CFROMC*SMLNUMIF( CFROM1.EQ.CFROMC ) THEN! CFROMC is an inf. Multiply by a correctly signed zero for! finite CTOC, or a NaN if CTOC is infinite.MUL = CTOC / CFROMCDONE = .TRUE.CTO1 = CTOCELSECTO1 = CTOC / BIGNUMIF( CTO1.EQ.CTOC ) THEN! CTOC is either 0 or an inf. In both cases, CTOC itself! serves as the correct multiplication factor.MUL = CTOCDONE = .TRUE.CFROMC = ONEELSE IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THENMUL = SMLNUMDONE = .FALSE.CFROMC = CFROM1ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THENMUL = BIGNUMDONE = .FALSE.CTOC = CTO1ELSEMUL = CTOC / CFROMCDONE = .TRUE.END IFEND IF*IF( ITYPE.EQ.0 ) THEN** Full matrix*DO 30 J = 1, NDO 20 I = 1, MA( I, J ) = A( I, J )*MUL20 CONTINUE30 CONTINUE*ELSE IF( ITYPE.EQ.1 ) THEN** Lower triangular matrix*DO 50 J = 1, NDO 40 I = J, MA( I, J ) = A( I, J )*MUL40 CONTINUE50 CONTINUE*ELSE IF( ITYPE.EQ.2 ) THEN** Upper triangular matrix*DO 70 J = 1, NDO 60 I = 1, MIN( J, M )A( I, J ) = A( I, J )*MUL60 CONTINUE70 CONTINUE*ELSE IF( ITYPE.EQ.3 ) THEN** Upper Hessenberg matrix*DO 90 J = 1, NDO 80 I = 1, MIN( J+1, M )A( I, J ) = A( I, J )*MUL80 CONTINUE90 CONTINUE*ELSE IF( ITYPE.EQ.4 ) THEN** Lower half of a symmetric band matrix*K3 = KL + 1K4 = N + 1DO 110 J = 1, NDO 100 I = 1, MIN( K3, K4-J )A( I, J ) = A( I, J )*MUL100 CONTINUE110 CONTINUE*ELSE IF( ITYPE.EQ.5 ) THEN** Upper half of a symmetric band matrix*K1 = KU + 2K3 = KU + 1DO 130 J = 1, NDO 120 I = MAX( K1-J, 1 ), K3A( I, J ) = A( I, J )*MUL120 CONTINUE130 CONTINUE*ELSE IF( ITYPE.EQ.6 ) THEN** Band matrix*K1 = KL + KU + 2K2 = KL + 1K3 = 2*KL + KU + 1K4 = KL + KU + 1 + MDO 150 J = 1, NDO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J )A( I, J ) = A( I, J )*MUL140 CONTINUE150 CONTINUE*END IF*IF( .NOT.DONE )$ GO TO 10*RETURN** End of DLASCL*END*> \brief \b DLASCL2 performs diagonal scaling on a vector.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASCL2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlascl2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlascl2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlascl2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASCL2 ( M, N, D, X, LDX )** .. Scalar Arguments ..* INTEGER M, N, LDX* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASCL2 performs a diagonal scaling on a vector:*> x <-- D * x*> where the diagonal matrix D is stored as a vector.*>*> Eventually to be replaced by BLAS_dge_diag_scale in the new BLAS*> standard.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of D and X. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of X. N >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, length M*> Diagonal matrix D, stored as a vector of length M.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,N)*> On entry, the vector X to be scaled by D.*> On exit, the scaled vector.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the vector X. LDX >= M.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DLASCL2 ( M, N, D, X, LDX )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER M, N, LDX* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), X( LDX, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. Executable Statements ..*DO J = 1, NDO I = 1, MX( I, J ) = X( I, J ) * D( I )END DOEND DORETURNEND*> \brief \b DLASD0 computes the singular values of a real upper bidiagonal n-by-m matrix B with diagonal d and off-diagonal e. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD0 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd0.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd0.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd0.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,* WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Using a divide and conquer approach, DLASD0 computes the singular*> value decomposition (SVD) of a real upper bidiagonal N-by-M*> matrix B with diagonal D and offdiagonal E, where M = N + SQRE.*> The algorithm computes orthogonal matrices U and VT such that*> B = U * S * VT. The singular values S are overwritten on D.*>*> A related subroutine, DLASDA, computes only the singular values,*> and optionally, the singular vectors in compact form.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> On entry, the row dimension of the upper bidiagonal matrix.*> This is also the dimension of the main diagonal array D.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> Specifies the column dimension of the bidiagonal matrix.*> = 0: The bidiagonal matrix has column dimension M = N;*> = 1: The bidiagonal matrix has column dimension M = N+1;*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry D contains the main diagonal of the bidiagonal*> matrix.*> On exit D, if INFO = 0, contains its singular values.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (M-1)*> Contains the subdiagonal entries of the bidiagonal matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU, N)*> On exit, U contains the left singular vectors.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> On entry, leading dimension of U.*> \endverbatim*>*> \param[out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT, M)*> On exit, VT**T contains the right singular vectors.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> On entry, leading dimension of VT.*> \endverbatim*>*> \param[in] SMLSIZ*> \verbatim*> SMLSIZ is INTEGER*> On entry, maximum size of the subproblems at the*> bottom of the computation tree.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (8*N)*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*M**2+2*M)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, a singular value did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD0( N, SQRE, D, E, U, LDU, VT, LDVT, SMLSIZ, IWORK,$ WORK, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, LDU, LDVT, N, SMLSIZ, SQRE* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), E( * ), U( LDU, * ), VT( LDVT, * ),$ WORK( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, I1, IC, IDXQ, IDXQC, IM1, INODE, ITEMP, IWK,$ J, LF, LL, LVL, M, NCC, ND, NDB1, NDIML, NDIMR,$ NL, NLF, NLP1, NLVL, NR, NRF, NRP1, SQREIDOUBLE PRECISION ALPHA, BETA* ..* .. External Subroutines ..EXTERNAL DLASD1, DLASDQ, DLASDT, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( N.LT.0 ) THENINFO = -1ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -2END IF*M = N + SQRE*IF( LDU.LT.N ) THENINFO = -6ELSE IF( LDVT.LT.M ) THENINFO = -8ELSE IF( SMLSIZ.LT.3 ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD0', -INFO )RETURNEND IF** If the input matrix is too small, call DLASDQ to find the SVD.*IF( N.LE.SMLSIZ ) THENCALL DLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDVT, U, LDU, U,$ LDU, WORK, INFO )RETURNEND IF** Set up the computation tree.*INODE = 1NDIML = INODE + NNDIMR = NDIML + NIDXQ = NDIMR + NIWK = IDXQ + NCALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),$ IWORK( NDIMR ), SMLSIZ )** For the nodes on bottom level of the tree, solve* their subproblems by DLASDQ.*NDB1 = ( ND+1 ) / 2NCC = 0DO 30 I = NDB1, ND** IC : center row of each node* NL : number of rows of left subproblem* NR : number of rows of right subproblem* NLF: starting row of the left subproblem* NRF: starting row of the right subproblem*I1 = I - 1IC = IWORK( INODE+I1 )NL = IWORK( NDIML+I1 )NLP1 = NL + 1NR = IWORK( NDIMR+I1 )NRP1 = NR + 1NLF = IC - NLNRF = IC + 1SQREI = 1CALL DLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ), E( NLF ),$ VT( NLF, NLF ), LDVT, U( NLF, NLF ), LDU,$ U( NLF, NLF ), LDU, WORK, INFO )IF( INFO.NE.0 ) THENRETURNEND IFITEMP = IDXQ + NLF - 2DO 10 J = 1, NLIWORK( ITEMP+J ) = J10 CONTINUEIF( I.EQ.ND ) THENSQREI = SQREELSESQREI = 1END IFNRP1 = NR + SQREICALL DLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ), E( NRF ),$ VT( NRF, NRF ), LDVT, U( NRF, NRF ), LDU,$ U( NRF, NRF ), LDU, WORK, INFO )IF( INFO.NE.0 ) THENRETURNEND IFITEMP = IDXQ + ICDO 20 J = 1, NRIWORK( ITEMP+J-1 ) = J20 CONTINUE30 CONTINUE** Now conquer each subproblem bottom-up.*DO 50 LVL = NLVL, 1, -1** Find the first node LF and last node LL on the* current level LVL.*IF( LVL.EQ.1 ) THENLF = 1LL = 1ELSELF = 2**( LVL-1 )LL = 2*LF - 1END IFDO 40 I = LF, LLIM1 = I - 1IC = IWORK( INODE+IM1 )NL = IWORK( NDIML+IM1 )NR = IWORK( NDIMR+IM1 )NLF = IC - NLIF( ( SQRE.EQ.0 ) .AND. ( I.EQ.LL ) ) THENSQREI = SQREELSESQREI = 1END IFIDXQC = IDXQ + NLF - 1ALPHA = D( IC )BETA = E( IC )CALL DLASD1( NL, NR, SQREI, D( NLF ), ALPHA, BETA,$ U( NLF, NLF ), LDU, VT( NLF, NLF ), LDVT,$ IWORK( IDXQC ), IWORK( IWK ), WORK, INFO )** Report the possible convergence failure.*IF( INFO.NE.0 ) THENRETURNEND IF40 CONTINUE50 CONTINUE*RETURN** End of DLASD0*END*> \brief \b DLASD1 computes the SVD of an upper bidiagonal matrix B of the specified size. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD1 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd1.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd1.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd1.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD1( NL, NR, SQRE, D, ALPHA, BETA, U, LDU, VT, LDVT,* IDXQ, IWORK, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDU, LDVT, NL, NR, SQRE* DOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..* INTEGER IDXQ( * ), IWORK( * )* DOUBLE PRECISION D( * ), U( LDU, * ), VT( LDVT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASD1 computes the SVD of an upper bidiagonal N-by-M matrix B,*> where N = NL + NR + 1 and M = N + SQRE. DLASD1 is called from DLASD0.*>*> A related subroutine DLASD7 handles the case in which the singular*> values (and the singular vectors in factored form) are desired.*>*> DLASD1 computes the SVD as follows:*>*> ( D1(in) 0 0 0 )*> B = U(in) * ( Z1**T a Z2**T b ) * VT(in)*> ( 0 0 D2(in) 0 )*>*> = U(out) * ( D(out) 0) * VT(out)*>*> where Z**T = (Z1**T a Z2**T b) = u**T VT**T, and u is a vector of dimension M*> with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros*> elsewhere; and the entry b is empty if SQRE = 0.*>*> The left singular vectors of the original matrix are stored in U, and*> the transpose of the right singular vectors are stored in VT, and the*> singular values are in D. The algorithm consists of three stages:*>*> The first stage consists of deflating the size of the problem*> when there are multiple singular values or when there are zeros in*> the Z vector. For each such occurrence the dimension of the*> secular equation problem is reduced by one. This stage is*> performed by the routine DLASD2.*>*> The second stage consists of calculating the updated*> singular values. This is done by finding the square roots of the*> roots of the secular equation via the routine DLASD4 (as called*> by DLASD3). This routine also calculates the singular vectors of*> the current problem.*>*> The final stage consists of computing the updated singular vectors*> directly using the updated singular values. The singular vectors*> for the current problem are multiplied with the singular vectors*> from the overall problem.*> \endverbatim** Arguments:* ==========**> \param[in] NL*> \verbatim*> NL is INTEGER*> The row dimension of the upper block. NL >= 1.*> \endverbatim*>*> \param[in] NR*> \verbatim*> NR is INTEGER*> The row dimension of the lower block. NR >= 1.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: the lower block is an NR-by-NR square matrix.*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.*>*> The bidiagonal matrix has row dimension N = NL + NR + 1,*> and column dimension M = N + SQRE.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array,*> dimension (N = NL+NR+1).*> On entry D(1:NL,1:NL) contains the singular values of the*> upper block; and D(NL+2:N) contains the singular values of*> the lower block. On exit D(1:N) contains the singular values*> of the modified matrix.*> \endverbatim*>*> \param[in,out] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> Contains the diagonal element associated with the added row.*> \endverbatim*>*> \param[in,out] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> Contains the off-diagonal element associated with the added*> row.*> \endverbatim*>*> \param[in,out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension(LDU,N)*> On entry U(1:NL, 1:NL) contains the left singular vectors of*> the upper block; U(NL+2:N, NL+2:N) contains the left singular*> vectors of the lower block. On exit U contains the left*> singular vectors of the bidiagonal matrix.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= max( 1, N ).*> \endverbatim*>*> \param[in,out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension(LDVT,M)*> where M = N + SQRE.*> On entry VT(1:NL+1, 1:NL+1)**T contains the right singular*> vectors of the upper block; VT(NL+2:M, NL+2:M)**T contains*> the right singular vectors of the lower block. On exit*> VT**T contains the right singular vectors of the*> bidiagonal matrix.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT. LDVT >= max( 1, M ).*> \endverbatim*>*> \param[in,out] IDXQ*> \verbatim*> IDXQ is INTEGER array, dimension(N)*> This contains the permutation which will reintegrate the*> subproblem just solved back into sorted order, i.e.*> D( IDXQ( I = 1, N ) ) will be in ascending order.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension( 4 * N )*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension( 3*M**2 + 2*M )*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, a singular value did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD1( NL, NR, SQRE, D, ALPHA, BETA, U, LDU, VT, LDVT,$ IDXQ, IWORK, WORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER INFO, LDU, LDVT, NL, NR, SQREDOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..INTEGER IDXQ( * ), IWORK( * )DOUBLE PRECISION D( * ), U( LDU, * ), VT( LDVT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..*DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER COLTYP, I, IDX, IDXC, IDXP, IQ, ISIGMA, IU2,$ IVT2, IZ, K, LDQ, LDU2, LDVT2, M, N, N1, N2DOUBLE PRECISION ORGNRM* ..* .. External Subroutines ..EXTERNAL DLAMRG, DLASCL, DLASD2, DLASD3, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( NL.LT.1 ) THENINFO = -1ELSE IF( NR.LT.1 ) THENINFO = -2ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD1', -INFO )RETURNEND IF*N = NL + NR + 1M = N + SQRE** The following values are for bookkeeping purposes only. They are* integer pointers which indicate the portion of the workspace* used by a particular array in DLASD2 and DLASD3.*LDU2 = NLDVT2 = M*IZ = 1ISIGMA = IZ + MIU2 = ISIGMA + NIVT2 = IU2 + LDU2*NIQ = IVT2 + LDVT2*M*IDX = 1IDXC = IDX + NCOLTYP = IDXC + NIDXP = COLTYP + N** Scale.*ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) )D( NL+1 ) = ZERODO 10 I = 1, NIF( ABS( D( I ) ).GT.ORGNRM ) THENORGNRM = ABS( D( I ) )END IF10 CONTINUECALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )ALPHA = ALPHA / ORGNRMBETA = BETA / ORGNRM** Deflate singular values.*CALL DLASD2( NL, NR, SQRE, K, D, WORK( IZ ), ALPHA, BETA, U, LDU,$ VT, LDVT, WORK( ISIGMA ), WORK( IU2 ), LDU2,$ WORK( IVT2 ), LDVT2, IWORK( IDXP ), IWORK( IDX ),$ IWORK( IDXC ), IDXQ, IWORK( COLTYP ), INFO )** Solve Secular Equation and update singular vectors.*LDQ = KCALL DLASD3( NL, NR, SQRE, K, D, WORK( IQ ), LDQ, WORK( ISIGMA ),$ U, LDU, WORK( IU2 ), LDU2, VT, LDVT, WORK( IVT2 ),$ LDVT2, IWORK( IDXC ), IWORK( COLTYP ), WORK( IZ ),$ INFO )** Report the convergence failure.*IF( INFO.NE.0 ) THENRETURNEND IF** Unscale.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )** Prepare the IDXQ sorting permutation.*N1 = KN2 = N - KCALL DLAMRG( N1, N2, D, 1, -1, IDXQ )*RETURN** End of DLASD1*END*> \brief \b DLASD2 merges the two sets of singular values together into a single sorted set. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD2( NL, NR, SQRE, K, D, Z, ALPHA, BETA, U, LDU, VT,* LDVT, DSIGMA, U2, LDU2, VT2, LDVT2, IDXP, IDX,* IDXC, IDXQ, COLTYP, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDU, LDU2, LDVT, LDVT2, NL, NR, SQRE* DOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..* INTEGER COLTYP( * ), IDX( * ), IDXC( * ), IDXP( * ),* $ IDXQ( * )* DOUBLE PRECISION D( * ), DSIGMA( * ), U( LDU, * ),* $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),* $ Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASD2 merges the two sets of singular values together into a single*> sorted set. Then it tries to deflate the size of the problem.*> There are two ways in which deflation can occur: when two or more*> singular values are close together or if there is a tiny entry in the*> Z vector. For each such occurrence the order of the related secular*> equation problem is reduced by one.*>*> DLASD2 is called from DLASD1.*> \endverbatim** Arguments:* ==========**> \param[in] NL*> \verbatim*> NL is INTEGER*> The row dimension of the upper block. NL >= 1.*> \endverbatim*>*> \param[in] NR*> \verbatim*> NR is INTEGER*> The row dimension of the lower block. NR >= 1.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: the lower block is an NR-by-NR square matrix.*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.*>*> The bidiagonal matrix has N = NL + NR + 1 rows and*> M = N + SQRE >= N columns.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER*> Contains the dimension of the non-deflated matrix,*> This is the order of the related secular equation. 1 <= K <=N.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension(N)*> On entry D contains the singular values of the two submatrices*> to be combined. On exit D contains the trailing (N-K) updated*> singular values (those which were deflated) sorted into*> increasing order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension(N)*> On exit Z contains the updating row vector in the secular*> equation.*> \endverbatim*>*> \param[in] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> Contains the diagonal element associated with the added row.*> \endverbatim*>*> \param[in] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> Contains the off-diagonal element associated with the added*> row.*> \endverbatim*>*> \param[in,out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension(LDU,N)*> On entry U contains the left singular vectors of two*> submatrices in the two square blocks with corners at (1,1),*> (NL, NL), and (NL+2, NL+2), (N,N).*> On exit U contains the trailing (N-K) updated left singular*> vectors (those which were deflated) in its last N-K columns.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= N.*> \endverbatim*>*> \param[in,out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension(LDVT,M)*> On entry VT**T contains the right singular vectors of two*> submatrices in the two square blocks with corners at (1,1),*> (NL+1, NL+1), and (NL+2, NL+2), (M,M).*> On exit VT**T contains the trailing (N-K) updated right singular*> vectors (those which were deflated) in its last N-K columns.*> In case SQRE =1, the last row of VT spans the right null*> space.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT. LDVT >= M.*> \endverbatim*>*> \param[out] DSIGMA*> \verbatim*> DSIGMA is DOUBLE PRECISION array, dimension (N)*> Contains a copy of the diagonal elements (K-1 singular values*> and one zero) in the secular equation.*> \endverbatim*>*> \param[out] U2*> \verbatim*> U2 is DOUBLE PRECISION array, dimension(LDU2,N)*> Contains a copy of the first K-1 left singular vectors which*> will be used by DLASD3 in a matrix multiply (DGEMM) to solve*> for the new left singular vectors. U2 is arranged into four*> blocks. The first block contains a column with 1 at NL+1 and*> zero everywhere else; the second block contains non-zero*> entries only at and above NL; the third contains non-zero*> entries only below NL+1; and the fourth is dense.*> \endverbatim*>*> \param[in] LDU2*> \verbatim*> LDU2 is INTEGER*> The leading dimension of the array U2. LDU2 >= N.*> \endverbatim*>*> \param[out] VT2*> \verbatim*> VT2 is DOUBLE PRECISION array, dimension(LDVT2,N)*> VT2**T contains a copy of the first K right singular vectors*> which will be used by DLASD3 in a matrix multiply (DGEMM) to*> solve for the new right singular vectors. VT2 is arranged into*> three blocks. The first block contains a row that corresponds*> to the special 0 diagonal element in SIGMA; the second block*> contains non-zeros only at and before NL +1; the third block*> contains non-zeros only at and after NL +2.*> \endverbatim*>*> \param[in] LDVT2*> \verbatim*> LDVT2 is INTEGER*> The leading dimension of the array VT2. LDVT2 >= M.*> \endverbatim*>*> \param[out] IDXP*> \verbatim*> IDXP is INTEGER array, dimension(N)*> This will contain the permutation used to place deflated*> values of D at the end of the array. On output IDXP(2:K)*> points to the nondeflated D-values and IDXP(K+1:N)*> points to the deflated singular values.*> \endverbatim*>*> \param[out] IDX*> \verbatim*> IDX is INTEGER array, dimension(N)*> This will contain the permutation used to sort the contents of*> D into ascending order.*> \endverbatim*>*> \param[out] IDXC*> \verbatim*> IDXC is INTEGER array, dimension(N)*> This will contain the permutation used to arrange the columns*> of the deflated U matrix into three groups: the first group*> contains non-zero entries only at and above NL, the second*> contains non-zero entries only below NL+2, and the third is*> dense.*> \endverbatim*>*> \param[in,out] IDXQ*> \verbatim*> IDXQ is INTEGER array, dimension(N)*> This contains the permutation which separately sorts the two*> sub-problems in D into ascending order. Note that entries in*> the first hlaf of this permutation must first be moved one*> position backward; and entries in the second half*> must first have NL+1 added to their values.*> \endverbatim*>*> \param[out] COLTYP*> \verbatim*> COLTYP is INTEGER array, dimension(N)*> As workspace, this will contain a label which will indicate*> which of the following types a column in the U2 matrix or a*> row in the VT2 matrix is:*> 1 : non-zero in the upper half only*> 2 : non-zero in the lower half only*> 3 : dense*> 4 : deflated*>*> On exit, it is an array of dimension 4, with COLTYP(I) being*> the dimension of the I-th type columns.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD2( NL, NR, SQRE, K, D, Z, ALPHA, BETA, U, LDU, VT,$ LDVT, DSIGMA, U2, LDU2, VT2, LDVT2, IDXP, IDX,$ IDXC, IDXQ, COLTYP, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, K, LDU, LDU2, LDVT, LDVT2, NL, NR, SQREDOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..INTEGER COLTYP( * ), IDX( * ), IDXC( * ), IDXP( * ),$ IDXQ( * )DOUBLE PRECISION D( * ), DSIGMA( * ), U( LDU, * ),$ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),$ Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, EIGHTPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,$ EIGHT = 8.0D+0 )* ..* .. Local Arrays ..INTEGER CTOT( 4 ), PSM( 4 )* ..* .. Local Scalars ..INTEGER CT, I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M,$ N, NLP1, NLP2DOUBLE PRECISION C, EPS, HLFTOL, S, TAU, TOL, Z1* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL DLAMCH, DLAPY2* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAMRG, DLASET, DROT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( NL.LT.1 ) THENINFO = -1ELSE IF( NR.LT.1 ) THENINFO = -2ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THENINFO = -3END IF*N = NL + NR + 1M = N + SQRE*IF( LDU.LT.N ) THENINFO = -10ELSE IF( LDVT.LT.M ) THENINFO = -12ELSE IF( LDU2.LT.N ) THENINFO = -15ELSE IF( LDVT2.LT.M ) THENINFO = -17END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD2', -INFO )RETURNEND IF*NLP1 = NL + 1NLP2 = NL + 2** Generate the first part of the vector Z; and move the singular* values in the first part of D one position backward.*Z1 = ALPHA*VT( NLP1, NLP1 )Z( 1 ) = Z1DO 10 I = NL, 1, -1Z( I+1 ) = ALPHA*VT( I, NLP1 )D( I+1 ) = D( I )IDXQ( I+1 ) = IDXQ( I ) + 110 CONTINUE** Generate the second part of the vector Z.*DO 20 I = NLP2, MZ( I ) = BETA*VT( I, NLP2 )20 CONTINUE** Initialize some reference arrays.*DO 30 I = 2, NLP1COLTYP( I ) = 130 CONTINUEDO 40 I = NLP2, NCOLTYP( I ) = 240 CONTINUE** Sort the singular values into increasing order*DO 50 I = NLP2, NIDXQ( I ) = IDXQ( I ) + NLP150 CONTINUE** DSIGMA, IDXC, IDXC, and the first column of U2* are used as storage space.*DO 60 I = 2, NDSIGMA( I ) = D( IDXQ( I ) )U2( I, 1 ) = Z( IDXQ( I ) )IDXC( I ) = COLTYP( IDXQ( I ) )60 CONTINUE*CALL DLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )*DO 70 I = 2, NIDXI = 1 + IDX( I )D( I ) = DSIGMA( IDXI )Z( I ) = U2( IDXI, 1 )COLTYP( I ) = IDXC( IDXI )70 CONTINUE** Calculate the allowable deflation tolerance*EPS = DLAMCH( 'Epsilon' )TOL = MAX( ABS( ALPHA ), ABS( BETA ) )TOL = EIGHT*EPS*MAX( ABS( D( N ) ), TOL )** There are 2 kinds of deflation -- first a value in the z-vector* is small, second two (or more) singular values are very close* together (their difference is small).** If the value in the z-vector is small, we simply permute the* array so that the corresponding singular value is moved to the* end.** If two values in the D-vector are close, we perform a two-sided* rotation designed to make one of the corresponding z-vector* entries zero, and then permute the array so that the deflated* singular value is moved to the end.** If there are multiple singular values then the problem deflates.* Here the number of equal singular values are found. As each equal* singular value is found, an elementary reflector is computed to* rotate the corresponding singular subspace so that the* corresponding components of Z are zero in this new basis.*K = 1K2 = N + 1DO 80 J = 2, NIF( ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1IDXP( K2 ) = JCOLTYP( J ) = 4IF( J.EQ.N )$ GO TO 120ELSEJPREV = JGO TO 90END IF80 CONTINUE90 CONTINUEJ = JPREV100 CONTINUEJ = J + 1IF( J.GT.N )$ GO TO 110IF( ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1IDXP( K2 ) = JCOLTYP( J ) = 4ELSE** Check if singular values are close enough to allow deflation.*IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN** Deflation is possible.*S = Z( JPREV )C = Z( J )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.*TAU = DLAPY2( C, S )C = C / TAUS = -S / TAUZ( J ) = TAUZ( JPREV ) = ZERO** Apply back the Givens rotation to the left and right* singular vector matrices.*IDXJP = IDXQ( IDX( JPREV )+1 )IDXJ = IDXQ( IDX( J )+1 )IF( IDXJP.LE.NLP1 ) THENIDXJP = IDXJP - 1END IFIF( IDXJ.LE.NLP1 ) THENIDXJ = IDXJ - 1END IFCALL DROT( N, U( 1, IDXJP ), 1, U( 1, IDXJ ), 1, C, S )CALL DROT( M, VT( IDXJP, 1 ), LDVT, VT( IDXJ, 1 ), LDVT, C,$ S )IF( COLTYP( J ).NE.COLTYP( JPREV ) ) THENCOLTYP( J ) = 3END IFCOLTYP( JPREV ) = 4K2 = K2 - 1IDXP( K2 ) = JPREVJPREV = JELSEK = K + 1U2( K, 1 ) = Z( JPREV )DSIGMA( K ) = D( JPREV )IDXP( K ) = JPREVJPREV = JEND IFEND IFGO TO 100110 CONTINUE** Record the last singular value.*K = K + 1U2( K, 1 ) = Z( JPREV )DSIGMA( K ) = D( JPREV )IDXP( K ) = JPREV*120 CONTINUE** Count up the total number of the various types of columns, then* form a permutation which positions the four column types into* four groups of uniform structure (although one or more of these* groups may be empty).*DO 130 J = 1, 4CTOT( J ) = 0130 CONTINUEDO 140 J = 2, NCT = COLTYP( J )CTOT( CT ) = CTOT( CT ) + 1140 CONTINUE** PSM(*) = Position in SubMatrix (of types 1 through 4)*PSM( 1 ) = 2PSM( 2 ) = 2 + CTOT( 1 )PSM( 3 ) = PSM( 2 ) + CTOT( 2 )PSM( 4 ) = PSM( 3 ) + CTOT( 3 )** Fill out the IDXC array so that the permutation which it induces* will place all type-1 columns first, all type-2 columns next,* then all type-3's, and finally all type-4's, starting from the* second column. This applies similarly to the rows of VT.*DO 150 J = 2, NJP = IDXP( J )CT = COLTYP( JP )IDXC( PSM( CT ) ) = JPSM( CT ) = PSM( CT ) + 1150 CONTINUE** Sort the singular values and corresponding singular vectors into* DSIGMA, U2, and VT2 respectively. The singular values/vectors* which were not deflated go into the first K slots of DSIGMA, U2,* and VT2 respectively, while those which were deflated go into the* last N - K slots, except that the first column/row will be treated* separately.*DO 160 J = 2, NJP = IDXP( J )DSIGMA( J ) = D( JP )IDXJ = IDXQ( IDX( IDXP( IDXC( J ) ) )+1 )IF( IDXJ.LE.NLP1 ) THENIDXJ = IDXJ - 1END IFCALL DCOPY( N, U( 1, IDXJ ), 1, U2( 1, J ), 1 )CALL DCOPY( M, VT( IDXJ, 1 ), LDVT, VT2( J, 1 ), LDVT2 )160 CONTINUE** Determine DSIGMA(1), DSIGMA(2) and Z(1)*DSIGMA( 1 ) = ZEROHLFTOL = TOL / TWOIF( ABS( DSIGMA( 2 ) ).LE.HLFTOL )$ DSIGMA( 2 ) = HLFTOLIF( M.GT.N ) THENZ( 1 ) = DLAPY2( Z1, Z( M ) )IF( Z( 1 ).LE.TOL ) THENC = ONES = ZEROZ( 1 ) = TOLELSEC = Z1 / Z( 1 )S = Z( M ) / Z( 1 )END IFELSEIF( ABS( Z1 ).LE.TOL ) THENZ( 1 ) = TOLELSEZ( 1 ) = Z1END IFEND IF** Move the rest of the updating row to Z.*CALL DCOPY( K-1, U2( 2, 1 ), 1, Z( 2 ), 1 )** Determine the first column of U2, the first row of VT2 and the* last row of VT.*CALL DLASET( 'A', N, 1, ZERO, ZERO, U2, LDU2 )U2( NLP1, 1 ) = ONEIF( M.GT.N ) THENDO 170 I = 1, NLP1VT( M, I ) = -S*VT( NLP1, I )VT2( 1, I ) = C*VT( NLP1, I )170 CONTINUEDO 180 I = NLP2, MVT2( 1, I ) = S*VT( M, I )VT( M, I ) = C*VT( M, I )180 CONTINUEELSECALL DCOPY( M, VT( NLP1, 1 ), LDVT, VT2( 1, 1 ), LDVT2 )END IFIF( M.GT.N ) THENCALL DCOPY( M, VT( M, 1 ), LDVT, VT2( M, 1 ), LDVT2 )END IF** The deflated singular values and their corresponding vectors go* into the back of D, U, and V respectively.*IF( N.GT.K ) THENCALL DCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 )CALL DLACPY( 'A', N, N-K, U2( 1, K+1 ), LDU2, U( 1, K+1 ),$ LDU )CALL DLACPY( 'A', N-K, M, VT2( K+1, 1 ), LDVT2, VT( K+1, 1 ),$ LDVT )END IF** Copy CTOT into COLTYP for referencing in DLASD3.*DO 190 J = 1, 4COLTYP( J ) = CTOT( J )190 CONTINUE*RETURN** End of DLASD2*END*> \brief \b DLASD3 finds all square roots of the roots of the secular equation, as defined by the values in D and Z, and then updates the singular vectors by matrix multiplication. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,* LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,* INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,* $ SQRE* ..* .. Array Arguments ..* INTEGER CTOT( * ), IDXC( * )* DOUBLE PRECISION D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),* $ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),* $ Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASD3 finds all the square roots of the roots of the secular*> equation, as defined by the values in D and Z. It makes the*> appropriate calls to DLASD4 and then updates the singular*> vectors by matrix multiplication.*>*> This code makes very mild assumptions about floating point*> arithmetic. It will work on machines with a guard digit in*> add/subtract, or on those binary machines without guard digits*> which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2.*> It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*>*> DLASD3 is called from DLASD1.*> \endverbatim** Arguments:* ==========**> \param[in] NL*> \verbatim*> NL is INTEGER*> The row dimension of the upper block. NL >= 1.*> \endverbatim*>*> \param[in] NR*> \verbatim*> NR is INTEGER*> The row dimension of the lower block. NR >= 1.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: the lower block is an NR-by-NR square matrix.*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.*>*> The bidiagonal matrix has N = NL + NR + 1 rows and*> M = N + SQRE >= N columns.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The size of the secular equation, 1 =< K = < N.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension(K)*> On exit the square roots of the roots of the secular equation,*> in ascending order.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,K)*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= K.*> \endverbatim*>*> \param[in,out] DSIGMA*> \verbatim*> DSIGMA is DOUBLE PRECISION array, dimension(K)*> The first K elements of this array contain the old roots*> of the deflated updating problem. These are the poles*> of the secular equation.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU, N)*> The last N - K columns of this matrix contain the deflated*> left singular vectors.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= N.*> \endverbatim*>*> \param[in] U2*> \verbatim*> U2 is DOUBLE PRECISION array, dimension (LDU2, N)*> The first K columns of this matrix contain the non-deflated*> left singular vectors for the split problem.*> \endverbatim*>*> \param[in] LDU2*> \verbatim*> LDU2 is INTEGER*> The leading dimension of the array U2. LDU2 >= N.*> \endverbatim*>*> \param[out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT, M)*> The last M - K columns of VT**T contain the deflated*> right singular vectors.*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> The leading dimension of the array VT. LDVT >= N.*> \endverbatim*>*> \param[in,out] VT2*> \verbatim*> VT2 is DOUBLE PRECISION array, dimension (LDVT2, N)*> The first K columns of VT2**T contain the non-deflated*> right singular vectors for the split problem.*> \endverbatim*>*> \param[in] LDVT2*> \verbatim*> LDVT2 is INTEGER*> The leading dimension of the array VT2. LDVT2 >= N.*> \endverbatim*>*> \param[in] IDXC*> \verbatim*> IDXC is INTEGER array, dimension ( N )*> The permutation used to arrange the columns of U (and rows of*> VT) into three groups: the first group contains non-zero*> entries only at and above (or before) NL +1; the second*> contains non-zero entries only at and below (or after) NL+2;*> and the third is dense. The first column of U and the row of*> VT are treated separately, however.*>*> The rows of the singular vectors found by DLASD4*> must be likewise permuted before the matrix multiplies can*> take place.*> \endverbatim*>*> \param[in] CTOT*> \verbatim*> CTOT is INTEGER array, dimension ( 4 )*> A count of the total number of the various types of columns*> in U (or rows in VT), as described in IDXC. The fourth column*> type is any column which has been deflated.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (K)*> The first K elements of this array contain the components*> of the deflation-adjusted updating row vector.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, a singular value did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD3( NL, NR, SQRE, K, D, Q, LDQ, DSIGMA, U, LDU, U2,$ LDU2, VT, LDVT, VT2, LDVT2, IDXC, CTOT, Z,$ INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INFO, K, LDQ, LDU, LDU2, LDVT, LDVT2, NL, NR,$ SQRE* ..* .. Array Arguments ..INTEGER CTOT( * ), IDXC( * )DOUBLE PRECISION D( * ), DSIGMA( * ), Q( LDQ, * ), U( LDU, * ),$ U2( LDU2, * ), VT( LDVT, * ), VT2( LDVT2, * ),$ Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZERO, NEGONEPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0,$ NEGONE = -1.0D+0 )* ..* .. Local Scalars ..INTEGER CTEMP, I, J, JC, KTEMP, M, N, NLP1, NLP2, NRP1DOUBLE PRECISION RHO, TEMP* ..* .. External Functions ..DOUBLE PRECISION DLAMC3, DNRM2EXTERNAL DLAMC3, DNRM2* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DLACPY, DLASCL, DLASD4, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( NL.LT.1 ) THENINFO = -1ELSE IF( NR.LT.1 ) THENINFO = -2ELSE IF( ( SQRE.NE.1 ) .AND. ( SQRE.NE.0 ) ) THENINFO = -3END IF*N = NL + NR + 1M = N + SQRENLP1 = NL + 1NLP2 = NL + 2*IF( ( K.LT.1 ) .OR. ( K.GT.N ) ) THENINFO = -4ELSE IF( LDQ.LT.K ) THENINFO = -7ELSE IF( LDU.LT.N ) THENINFO = -10ELSE IF( LDU2.LT.N ) THENINFO = -12ELSE IF( LDVT.LT.M ) THENINFO = -14ELSE IF( LDVT2.LT.M ) THENINFO = -16END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD3', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.1 ) THEND( 1 ) = ABS( Z( 1 ) )CALL DCOPY( M, VT2( 1, 1 ), LDVT2, VT( 1, 1 ), LDVT )IF( Z( 1 ).GT.ZERO ) THENCALL DCOPY( N, U2( 1, 1 ), 1, U( 1, 1 ), 1 )ELSEDO 10 I = 1, NU( I, 1 ) = -U2( I, 1 )10 CONTINUEEND IFRETURNEND IF** Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can* be computed with high relative accuracy (barring over/underflow).* This is a problem on machines without a guard digit in* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),* which on any of these machines zeros out the bottommost* bit of DSIGMA(I) if it is 1; this makes the subsequent* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation* occurs. On binary machines with a guard digit (almost all* machines) it does not change DSIGMA(I) at all. On hexadecimal* and decimal machines with a guard digit, it slightly* changes the bottommost bits of DSIGMA(I). It does not account* for hexadecimal or decimal machines without guard digits* (we know of none). We use a subroutine call to compute* 2*DSIGMA(I) to prevent optimizing compilers from eliminating* this code.*DO 20 I = 1, KDSIGMA( I ) = DLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )20 CONTINUE** Keep a copy of Z.*CALL DCOPY( K, Z, 1, Q, 1 )** Normalize Z.*RHO = DNRM2( K, Z, 1 )CALL DLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )RHO = RHO*RHO** Find the new singular values.*DO 30 J = 1, KCALL DLASD4( K, J, DSIGMA, Z, U( 1, J ), RHO, D( J ),$ VT( 1, J ), INFO )** If the zero finder fails, report the convergence failure.*IF( INFO.NE.0 ) THENRETURNEND IF30 CONTINUE** Compute updated Z.*DO 60 I = 1, KZ( I ) = U( I, K )*VT( I, K )DO 40 J = 1, I - 1Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /$ ( DSIGMA( I )-DSIGMA( J ) ) /$ ( DSIGMA( I )+DSIGMA( J ) ) )40 CONTINUEDO 50 J = I, K - 1Z( I ) = Z( I )*( U( I, J )*VT( I, J ) /$ ( DSIGMA( I )-DSIGMA( J+1 ) ) /$ ( DSIGMA( I )+DSIGMA( J+1 ) ) )50 CONTINUEZ( I ) = SIGN( SQRT( ABS( Z( I ) ) ), Q( I, 1 ) )60 CONTINUE** Compute left singular vectors of the modified diagonal matrix,* and store related information for the right singular vectors.*DO 90 I = 1, KVT( 1, I ) = Z( 1 ) / U( 1, I ) / VT( 1, I )U( 1, I ) = NEGONEDO 70 J = 2, KVT( J, I ) = Z( J ) / U( J, I ) / VT( J, I )U( J, I ) = DSIGMA( J )*VT( J, I )70 CONTINUETEMP = DNRM2( K, U( 1, I ), 1 )Q( 1, I ) = U( 1, I ) / TEMPDO 80 J = 2, KJC = IDXC( J )Q( J, I ) = U( JC, I ) / TEMP80 CONTINUE90 CONTINUE** Update the left singular vector matrix.*IF( K.EQ.2 ) THENCALL DGEMM( 'N', 'N', N, K, K, ONE, U2, LDU2, Q, LDQ, ZERO, U,$ LDU )GO TO 100END IFIF( CTOT( 1 ).GT.0 ) THENCALL DGEMM( 'N', 'N', NL, K, CTOT( 1 ), ONE, U2( 1, 2 ), LDU2,$ Q( 2, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )IF( CTOT( 3 ).GT.0 ) THENKTEMP = 2 + CTOT( 1 ) + CTOT( 2 )CALL DGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),$ LDU2, Q( KTEMP, 1 ), LDQ, ONE, U( 1, 1 ), LDU )END IFELSE IF( CTOT( 3 ).GT.0 ) THENKTEMP = 2 + CTOT( 1 ) + CTOT( 2 )CALL DGEMM( 'N', 'N', NL, K, CTOT( 3 ), ONE, U2( 1, KTEMP ),$ LDU2, Q( KTEMP, 1 ), LDQ, ZERO, U( 1, 1 ), LDU )ELSECALL DLACPY( 'F', NL, K, U2, LDU2, U, LDU )END IFCALL DCOPY( K, Q( 1, 1 ), LDQ, U( NLP1, 1 ), LDU )KTEMP = 2 + CTOT( 1 )CTEMP = CTOT( 2 ) + CTOT( 3 )CALL DGEMM( 'N', 'N', NR, K, CTEMP, ONE, U2( NLP2, KTEMP ), LDU2,$ Q( KTEMP, 1 ), LDQ, ZERO, U( NLP2, 1 ), LDU )** Generate the right singular vectors.*100 CONTINUEDO 120 I = 1, KTEMP = DNRM2( K, VT( 1, I ), 1 )Q( I, 1 ) = VT( 1, I ) / TEMPDO 110 J = 2, KJC = IDXC( J )Q( I, J ) = VT( JC, I ) / TEMP110 CONTINUE120 CONTINUE** Update the right singular vector matrix.*IF( K.EQ.2 ) THENCALL DGEMM( 'N', 'N', K, M, K, ONE, Q, LDQ, VT2, LDVT2, ZERO,$ VT, LDVT )RETURNEND IFKTEMP = 1 + CTOT( 1 )CALL DGEMM( 'N', 'N', K, NLP1, KTEMP, ONE, Q( 1, 1 ), LDQ,$ VT2( 1, 1 ), LDVT2, ZERO, VT( 1, 1 ), LDVT )KTEMP = 2 + CTOT( 1 ) + CTOT( 2 )IF( KTEMP.LE.LDVT2 )$ CALL DGEMM( 'N', 'N', K, NLP1, CTOT( 3 ), ONE, Q( 1, KTEMP ),$ LDQ, VT2( KTEMP, 1 ), LDVT2, ONE, VT( 1, 1 ),$ LDVT )*KTEMP = CTOT( 1 ) + 1NRP1 = NR + SQREIF( KTEMP.GT.1 ) THENDO 130 I = 1, KQ( I, KTEMP ) = Q( I, 1 )130 CONTINUEDO 140 I = NLP2, MVT2( KTEMP, I ) = VT2( 1, I )140 CONTINUEEND IFCTEMP = 1 + CTOT( 2 ) + CTOT( 3 )CALL DGEMM( 'N', 'N', K, NRP1, CTEMP, ONE, Q( 1, KTEMP ), LDQ,$ VT2( KTEMP, NLP2 ), LDVT2, ZERO, VT( 1, NLP2 ), LDVT )*RETURN** End of DLASD3*END*> \brief \b DLASD4 computes the square root of the i-th updated eigenvalue of a positive symmetric rank-one modification to a positive diagonal matrix. Used by dbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD4 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd4.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd4.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd4.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )** .. Scalar Arguments ..* INTEGER I, INFO, N* DOUBLE PRECISION RHO, SIGMA* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), DELTA( * ), WORK( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine computes the square root of the I-th updated*> eigenvalue of a positive symmetric rank-one modification to*> a positive diagonal matrix whose entries are given as the squares*> of the corresponding entries in the array d, and that*>*> 0 <= D(i) < D(j) for i < j*>*> and that RHO > 0. This is arranged by the calling routine, and is*> no loss in generality. The rank-one modified system is thus*>*> diag( D ) * diag( D ) + RHO * Z * Z_transpose.*>*> where we assume the Euclidean norm of Z is 1.*>*> The method consists of approximating the rational functions in the*> secular equation by simpler interpolating rational functions.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The length of all arrays.*> \endverbatim*>*> \param[in] I*> \verbatim*> I is INTEGER*> The index of the eigenvalue to be computed. 1 <= I <= N.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension ( N )*> The original eigenvalues. It is assumed that they are in*> order, 0 <= D(I) < D(J) for I < J.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( N )*> The components of the updating vector.*> \endverbatim*>*> \param[out] DELTA*> \verbatim*> DELTA is DOUBLE PRECISION array, dimension ( N )*> If N .ne. 1, DELTA contains (D(j) - sigma_I) in its j-th*> component. If N = 1, then DELTA(1) = 1. The vector DELTA*> contains the information necessary to construct the*> (singular) eigenvectors.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The scalar in the symmetric updating formula.*> \endverbatim*>*> \param[out] SIGMA*> \verbatim*> SIGMA is DOUBLE PRECISION*> The computed sigma_I, the I-th updated eigenvalue.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension ( N )*> If N .ne. 1, WORK contains (D(j) + sigma_I) in its j-th*> component. If N = 1, then WORK( 1 ) = 1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> > 0: if INFO = 1, the updating process failed.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> Logical variable ORGATI (origin-at-i?) is used for distinguishing*> whether D(i) or D(i+1) is treated as the origin.*>*> ORGATI = .true. origin at i*> ORGATI = .false. origin at i+1*>*> Logical variable SWTCH3 (switch-for-3-poles?) is for noting*> if we are working with THREE poles!*>*> MAXIT is the maximum number of iterations allowed for each*> eigenvalue.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ren-Cang Li, Computer Science Division, University of California*> at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD4( N, I, D, Z, DELTA, RHO, SIGMA, WORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER I, INFO, NDOUBLE PRECISION RHO, SIGMA* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DELTA( * ), WORK( * ), Z( * )* ..** =====================================================================** .. Parameters ..INTEGER MAXITPARAMETER ( MAXIT = 400 )DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOUR, EIGHT, TENPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,$ THREE = 3.0D+0, FOUR = 4.0D+0, EIGHT = 8.0D+0,$ TEN = 10.0D+0 )* ..* .. Local Scalars ..LOGICAL ORGATI, SWTCH, SWTCH3, GEOMAVGINTEGER II, IIM1, IIP1, IP1, ITER, J, NITERDOUBLE PRECISION A, B, C, DELSQ, DELSQ2, SQ2, DPHI, DPSI, DTIIM,$ DTIIP, DTIPSQ, DTISQ, DTNSQ, DTNSQ1, DW, EPS,$ ERRETM, ETA, PHI, PREW, PSI, RHOINV, SGLB,$ SGUB, TAU, TAU2, TEMP, TEMP1, TEMP2, W* ..* .. Local Arrays ..DOUBLE PRECISION DD( 3 ), ZZ( 3 )* ..* .. External Subroutines ..EXTERNAL DLAED6, DLASD5* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..** Since this routine is called in an inner loop, we do no argument* checking.** Quick return for N=1 and 2.*INFO = 0IF( N.EQ.1 ) THEN** Presumably, I=1 upon entry*SIGMA = SQRT( D( 1 )*D( 1 )+RHO*Z( 1 )*Z( 1 ) )DELTA( 1 ) = ONEWORK( 1 ) = ONERETURNEND IFIF( N.EQ.2 ) THENCALL DLASD5( I, D, Z, DELTA, RHO, SIGMA, WORK )RETURNEND IF** Compute machine epsilon*EPS = DLAMCH( 'Epsilon' )RHOINV = ONE / RHOTAU2= ZERO** The case I = N*IF( I.EQ.N ) THEN** Initialize some basic variables*II = N - 1NITER = 1** Calculate initial guess*TEMP = RHO / TWO** If ||Z||_2 is not one, then TEMP should be set to* RHO * ||Z||_2^2 / TWO*TEMP1 = TEMP / ( D( N )+SQRT( D( N )*D( N )+TEMP ) )DO 10 J = 1, NWORK( J ) = D( J ) + D( N ) + TEMP1DELTA( J ) = ( D( J )-D( N ) ) - TEMP110 CONTINUE*PSI = ZERODO 20 J = 1, N - 2PSI = PSI + Z( J )*Z( J ) / ( DELTA( J )*WORK( J ) )20 CONTINUE*C = RHOINV + PSIW = C + Z( II )*Z( II ) / ( DELTA( II )*WORK( II ) ) +$ Z( N )*Z( N ) / ( DELTA( N )*WORK( N ) )*IF( W.LE.ZERO ) THENTEMP1 = SQRT( D( N )*D( N )+RHO )TEMP = Z( N-1 )*Z( N-1 ) / ( ( D( N-1 )+TEMP1 )*$ ( D( N )-D( N-1 )+RHO / ( D( N )+TEMP1 ) ) ) +$ Z( N )*Z( N ) / RHO** The following TAU2 is to approximate* SIGMA_n^2 - D( N )*D( N )*IF( C.LE.TEMP ) THENTAU = RHOELSEDELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )B = Z( N )*Z( N )*DELSQIF( A.LT.ZERO ) THENTAU2 = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )ELSETAU2 = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )END IFTAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )END IF** It can be proved that* D(N)^2+RHO/2 <= SIGMA_n^2 < D(N)^2+TAU2 <= D(N)^2+RHO*ELSEDELSQ = ( D( N )-D( N-1 ) )*( D( N )+D( N-1 ) )A = -C*DELSQ + Z( N-1 )*Z( N-1 ) + Z( N )*Z( N )B = Z( N )*Z( N )*DELSQ** The following TAU2 is to approximate* SIGMA_n^2 - D( N )*D( N )*IF( A.LT.ZERO ) THENTAU2 = TWO*B / ( SQRT( A*A+FOUR*B*C )-A )ELSETAU2 = ( A+SQRT( A*A+FOUR*B*C ) ) / ( TWO*C )END IFTAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )** It can be proved that* D(N)^2 < D(N)^2+TAU2 < SIGMA(N)^2 < D(N)^2+RHO/2*END IF** The following TAU is to approximate SIGMA_n - D( N )** TAU = TAU2 / ( D( N )+SQRT( D( N )*D( N )+TAU2 ) )*SIGMA = D( N ) + TAUDO 30 J = 1, NDELTA( J ) = ( D( J )-D( N ) ) - TAUWORK( J ) = D( J ) + D( N ) + TAU30 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 40 J = 1, IITEMP = Z( J ) / ( DELTA( J )*WORK( J ) )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI40 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TEMP = Z( N ) / ( DELTA( N )*WORK( N ) )PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV* $ + ABS( TAU2 )*( DPSI+DPHI )*W = RHOINV + PHI + PSI** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENGO TO 240END IF** Calculate the new step*NITER = NITER + 1DTNSQ1 = WORK( N-1 )*DELTA( N-1 )DTNSQ = WORK( N )*DELTA( N )C = W - DTNSQ1*DPSI - DTNSQ*DPHIA = ( DTNSQ+DTNSQ1 )*W - DTNSQ*DTNSQ1*( DPSI+DPHI )B = DTNSQ*DTNSQ1*WIF( C.LT.ZERO )$ C = ABS( C )IF( C.EQ.ZERO ) THENETA = RHO - SIGMA*SIGMAELSE IF( A.GE.ZERO ) THENETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GT.ZERO )$ ETA = -W / ( DPSI+DPHI )TEMP = ETA - DTNSQIF( TEMP.GT.RHO )$ ETA = RHO + DTNSQ*ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )TAU = TAU + ETASIGMA = SIGMA + ETA*DO 50 J = 1, NDELTA( J ) = DELTA( J ) - ETAWORK( J ) = WORK( J ) + ETA50 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 60 J = 1, IITEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI60 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TAU2 = WORK( N )*DELTA( N )TEMP = Z( N ) / TAU2PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV* $ + ABS( TAU2 )*( DPSI+DPHI )*W = RHOINV + PHI + PSI** Main loop to update the values of the array DELTA*ITER = NITER + 1*DO 90 NITER = ITER, MAXIT** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENGO TO 240END IF** Calculate the new step*DTNSQ1 = WORK( N-1 )*DELTA( N-1 )DTNSQ = WORK( N )*DELTA( N )C = W - DTNSQ1*DPSI - DTNSQ*DPHIA = ( DTNSQ+DTNSQ1 )*W - DTNSQ1*DTNSQ*( DPSI+DPHI )B = DTNSQ1*DTNSQ*WIF( A.GE.ZERO ) THENETA = ( A+SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A-SQRT( ABS( A*A-FOUR*B*C ) ) )END IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GT.ZERO )$ ETA = -W / ( DPSI+DPHI )TEMP = ETA - DTNSQIF( TEMP.LE.ZERO )$ ETA = ETA / TWO*ETA = ETA / ( SIGMA+SQRT( ETA+SIGMA*SIGMA ) )TAU = TAU + ETASIGMA = SIGMA + ETA*DO 70 J = 1, NDELTA( J ) = DELTA( J ) - ETAWORK( J ) = WORK( J ) + ETA70 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 80 J = 1, IITEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI80 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*TAU2 = WORK( N )*DELTA( N )TEMP = Z( N ) / TAU2PHI = Z( N )*TEMPDPHI = TEMP*TEMPERRETM = EIGHT*( -PHI-PSI ) + ERRETM - PHI + RHOINV* $ + ABS( TAU2 )*( DPSI+DPHI )*W = RHOINV + PHI + PSI90 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged*INFO = 1GO TO 240** End for the case I = N*ELSE** The case for I < N*NITER = 1IP1 = I + 1** Calculate initial guess*DELSQ = ( D( IP1 )-D( I ) )*( D( IP1 )+D( I ) )DELSQ2 = DELSQ / TWOSQ2=SQRT( ( D( I )*D( I )+D( IP1 )*D( IP1 ) ) / TWO )TEMP = DELSQ2 / ( D( I )+SQ2 )DO 100 J = 1, NWORK( J ) = D( J ) + D( I ) + TEMPDELTA( J ) = ( D( J )-D( I ) ) - TEMP100 CONTINUE*PSI = ZERODO 110 J = 1, I - 1PSI = PSI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )110 CONTINUE*PHI = ZERODO 120 J = N, I + 2, -1PHI = PHI + Z( J )*Z( J ) / ( WORK( J )*DELTA( J ) )120 CONTINUEC = RHOINV + PSI + PHIW = C + Z( I )*Z( I ) / ( WORK( I )*DELTA( I ) ) +$ Z( IP1 )*Z( IP1 ) / ( WORK( IP1 )*DELTA( IP1 ) )*GEOMAVG = .FALSE.IF( W.GT.ZERO ) THEN** d(i)^2 < the ith sigma^2 < (d(i)^2+d(i+1)^2)/2** We choose d(i) as origin.*ORGATI = .TRUE.II = ISGLB = ZEROSGUB = DELSQ2 / ( D( I )+SQ2 )A = C*DELSQ + Z( I )*Z( I ) + Z( IP1 )*Z( IP1 )B = Z( I )*Z( I )*DELSQIF( A.GT.ZERO ) THENTAU2 = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )ELSETAU2 = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )END IF** TAU2 now is an estimation of SIGMA^2 - D( I )^2. The* following, however, is the corresponding estimation of* SIGMA - D( I ).*TAU = TAU2 / ( D( I )+SQRT( D( I )*D( I )+TAU2 ) )TEMP = SQRT(EPS)IF( (D(I).LE.TEMP*D(IP1)).AND.(ABS(Z(I)).LE.TEMP)$ .AND.(D(I).GT.ZERO) ) THENTAU = MIN( TEN*D(I), SGUB )GEOMAVG = .TRUE.END IFELSE** (d(i)^2+d(i+1)^2)/2 <= the ith sigma^2 < d(i+1)^2/2** We choose d(i+1) as origin.*ORGATI = .FALSE.II = IP1SGLB = -DELSQ2 / ( D( II )+SQ2 )SGUB = ZEROA = C*DELSQ - Z( I )*Z( I ) - Z( IP1 )*Z( IP1 )B = Z( IP1 )*Z( IP1 )*DELSQIF( A.LT.ZERO ) THENTAU2 = TWO*B / ( A-SQRT( ABS( A*A+FOUR*B*C ) ) )ELSETAU2 = -( A+SQRT( ABS( A*A+FOUR*B*C ) ) ) / ( TWO*C )END IF** TAU2 now is an estimation of SIGMA^2 - D( IP1 )^2. The* following, however, is the corresponding estimation of* SIGMA - D( IP1 ).*TAU = TAU2 / ( D( IP1 )+SQRT( ABS( D( IP1 )*D( IP1 )+$ TAU2 ) ) )END IF*SIGMA = D( II ) + TAUDO 130 J = 1, NWORK( J ) = D( J ) + D( II ) + TAUDELTA( J ) = ( D( J )-D( II ) ) - TAU130 CONTINUEIIM1 = II - 1IIP1 = II + 1** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 150 J = 1, IIM1TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI150 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 160 J = N, IIP1, -1TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI160 CONTINUE*W = RHOINV + PHI + PSI** W is the value of the secular function with* its ii-th element removed.*SWTCH3 = .FALSE.IF( ORGATI ) THENIF( W.LT.ZERO )$ SWTCH3 = .TRUE.ELSEIF( W.GT.ZERO )$ SWTCH3 = .TRUE.END IFIF( II.EQ.1 .OR. II.EQ.N )$ SWTCH3 = .FALSE.*TEMP = Z( II ) / ( WORK( II )*DELTA( II ) )DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = W + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV$ + THREE*ABS( TEMP )* $ + ABS( TAU2 )*DW** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THENGO TO 240END IF*IF( W.LE.ZERO ) THENSGLB = MAX( SGLB, TAU )ELSESGUB = MIN( SGUB, TAU )END IF** Calculate the new step*NITER = NITER + 1IF( .NOT.SWTCH3 ) THENDTIPSQ = WORK( IP1 )*DELTA( IP1 )DTISQ = WORK( I )*DELTA( I )IF( ORGATI ) THENC = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2ELSEC = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2END IFA = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DWB = DTIPSQ*DTISQ*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI )END IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFELSE** Interpolation using THREE most relevant poles*DTIIM = WORK( IIM1 )*DELTA( IIM1 )DTIIP = WORK( IIP1 )*DELTA( IIP1 )TEMP = RHOINV + PSI + PHIIF( ORGATI ) THENTEMP1 = Z( IIM1 ) / DTIIMTEMP1 = TEMP1*TEMP1C = ( TEMP - DTIIP*( DPSI+DPHI ) ) -$ ( D( IIM1 )-D( IIP1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )IF( DPSI.LT.TEMP1 ) THENZZ( 3 ) = DTIIP*DTIIP*DPHIELSEZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )END IFELSETEMP1 = Z( IIP1 ) / DTIIPTEMP1 = TEMP1*TEMP1C = ( TEMP - DTIIM*( DPSI+DPHI ) ) -$ ( D( IIP1 )-D( IIM1 ) )*( D( IIM1 )+D( IIP1 ) )*TEMP1IF( DPHI.LT.TEMP1 ) THENZZ( 1 ) = DTIIM*DTIIM*DPSIELSEZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )END IFZZ( 3 ) = Z( IIP1 )*Z( IIP1 )END IFZZ( 2 ) = Z( II )*Z( II )DD( 1 ) = DTIIMDD( 2 ) = DELTA( II )*WORK( II )DD( 3 ) = DTIIPCALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )*IF( INFO.NE.0 ) THEN** If INFO is not 0, i.e., DLAED6 failed, switch back* to 2 pole interpolation.*SWTCH3 = .FALSE.INFO = 0DTIPSQ = WORK( IP1 )*DELTA( IP1 )DTISQ = WORK( I )*DELTA( I )IF( ORGATI ) THENC = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2ELSEC = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2END IFA = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DWB = DTIPSQ*DTISQ*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) + DTISQ*DTISQ*( DPSI+DPHI)END IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFEND IFEND IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GE.ZERO )$ ETA = -W / DW*ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )TEMP = TAU + ETAIF( TEMP.GT.SGUB .OR. TEMP.LT.SGLB ) THENIF( W.LT.ZERO ) THENETA = ( SGUB-TAU ) / TWOELSEETA = ( SGLB-TAU ) / TWOEND IFIF( GEOMAVG ) THENIF( W .LT. ZERO ) THENIF( TAU .GT. ZERO ) THENETA = SQRT(SGUB*TAU)-TAUEND IFELSEIF( SGLB .GT. ZERO ) THENETA = SQRT(SGLB*TAU)-TAUEND IFEND IFEND IFEND IF*PREW = W*TAU = TAU + ETASIGMA = SIGMA + ETA*DO 170 J = 1, NWORK( J ) = WORK( J ) + ETADELTA( J ) = DELTA( J ) - ETA170 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 180 J = 1, IIM1TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI180 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 190 J = N, IIP1, -1TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI190 CONTINUE*TAU2 = WORK( II )*DELTA( II )TEMP = Z( II ) / TAU2DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = RHOINV + PHI + PSI + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV$ + THREE*ABS( TEMP )* $ + ABS( TAU2 )*DW*SWTCH = .FALSE.IF( ORGATI ) THENIF( -W.GT.ABS( PREW ) / TEN )$ SWTCH = .TRUE.ELSEIF( W.GT.ABS( PREW ) / TEN )$ SWTCH = .TRUE.END IF** Main loop to update the values of the array DELTA and WORK*ITER = NITER + 1*DO 230 NITER = ITER, MAXIT** Test for convergence*IF( ABS( W ).LE.EPS*ERRETM ) THEN* $ .OR. (SGUB-SGLB).LE.EIGHT*ABS(SGUB+SGLB) ) THENGO TO 240END IF*IF( W.LE.ZERO ) THENSGLB = MAX( SGLB, TAU )ELSESGUB = MIN( SGUB, TAU )END IF** Calculate the new step*IF( .NOT.SWTCH3 ) THENDTIPSQ = WORK( IP1 )*DELTA( IP1 )DTISQ = WORK( I )*DELTA( I )IF( .NOT.SWTCH ) THENIF( ORGATI ) THENC = W - DTIPSQ*DW + DELSQ*( Z( I ) / DTISQ )**2ELSEC = W - DTISQ*DW - DELSQ*( Z( IP1 ) / DTIPSQ )**2END IFELSETEMP = Z( II ) / ( WORK( II )*DELTA( II ) )IF( ORGATI ) THENDPSI = DPSI + TEMP*TEMPELSEDPHI = DPHI + TEMP*TEMPEND IFC = W - DTISQ*DPSI - DTIPSQ*DPHIEND IFA = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DWB = DTIPSQ*DTISQ*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( .NOT.SWTCH ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*$ ( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) +$ DTISQ*DTISQ*( DPSI+DPHI )END IFELSEA = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHIEND IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFELSE** Interpolation using THREE most relevant poles*DTIIM = WORK( IIM1 )*DELTA( IIM1 )DTIIP = WORK( IIP1 )*DELTA( IIP1 )TEMP = RHOINV + PSI + PHIIF( SWTCH ) THENC = TEMP - DTIIM*DPSI - DTIIP*DPHIZZ( 1 ) = DTIIM*DTIIM*DPSIZZ( 3 ) = DTIIP*DTIIP*DPHIELSEIF( ORGATI ) THENTEMP1 = Z( IIM1 ) / DTIIMTEMP1 = TEMP1*TEMP1TEMP2 = ( D( IIM1 )-D( IIP1 ) )*$ ( D( IIM1 )+D( IIP1 ) )*TEMP1C = TEMP - DTIIP*( DPSI+DPHI ) - TEMP2ZZ( 1 ) = Z( IIM1 )*Z( IIM1 )IF( DPSI.LT.TEMP1 ) THENZZ( 3 ) = DTIIP*DTIIP*DPHIELSEZZ( 3 ) = DTIIP*DTIIP*( ( DPSI-TEMP1 )+DPHI )END IFELSETEMP1 = Z( IIP1 ) / DTIIPTEMP1 = TEMP1*TEMP1TEMP2 = ( D( IIP1 )-D( IIM1 ) )*$ ( D( IIM1 )+D( IIP1 ) )*TEMP1C = TEMP - DTIIM*( DPSI+DPHI ) - TEMP2IF( DPHI.LT.TEMP1 ) THENZZ( 1 ) = DTIIM*DTIIM*DPSIELSEZZ( 1 ) = DTIIM*DTIIM*( DPSI+( DPHI-TEMP1 ) )END IFZZ( 3 ) = Z( IIP1 )*Z( IIP1 )END IFEND IFDD( 1 ) = DTIIMDD( 2 ) = DELTA( II )*WORK( II )DD( 3 ) = DTIIPCALL DLAED6( NITER, ORGATI, C, DD, ZZ, W, ETA, INFO )*IF( INFO.NE.0 ) THEN** If INFO is not 0, i.e., DLAED6 failed, switch* back to two pole interpolation*SWTCH3 = .FALSE.INFO = 0DTIPSQ = WORK( IP1 )*DELTA( IP1 )DTISQ = WORK( I )*DELTA( I )IF( .NOT.SWTCH ) THENIF( ORGATI ) THENC = W - DTIPSQ*DW + DELSQ*( Z( I )/DTISQ )**2ELSEC = W - DTISQ*DW - DELSQ*( Z( IP1 )/DTIPSQ )**2END IFELSETEMP = Z( II ) / ( WORK( II )*DELTA( II ) )IF( ORGATI ) THENDPSI = DPSI + TEMP*TEMPELSEDPHI = DPHI + TEMP*TEMPEND IFC = W - DTISQ*DPSI - DTIPSQ*DPHIEND IFA = ( DTIPSQ+DTISQ )*W - DTIPSQ*DTISQ*DWB = DTIPSQ*DTISQ*WIF( C.EQ.ZERO ) THENIF( A.EQ.ZERO ) THENIF( .NOT.SWTCH ) THENIF( ORGATI ) THENA = Z( I )*Z( I ) + DTIPSQ*DTIPSQ*$ ( DPSI+DPHI )ELSEA = Z( IP1 )*Z( IP1 ) +$ DTISQ*DTISQ*( DPSI+DPHI )END IFELSEA = DTISQ*DTISQ*DPSI + DTIPSQ*DTIPSQ*DPHIEND IFEND IFETA = B / AELSE IF( A.LE.ZERO ) THENETA = ( A-SQRT( ABS( A*A-FOUR*B*C ) ) ) / ( TWO*C )ELSEETA = TWO*B / ( A+SQRT( ABS( A*A-FOUR*B*C ) ) )END IFEND IFEND IF** Note, eta should be positive if w is negative, and* eta should be negative otherwise. However,* if for some reason caused by roundoff, eta*w > 0,* we simply use one Newton step instead. This way* will guarantee eta*w < 0.*IF( W*ETA.GE.ZERO )$ ETA = -W / DW*ETA = ETA / ( SIGMA+SQRT( SIGMA*SIGMA+ETA ) )TEMP=TAU+ETAIF( TEMP.GT.SGUB .OR. TEMP.LT.SGLB ) THENIF( W.LT.ZERO ) THENETA = ( SGUB-TAU ) / TWOELSEETA = ( SGLB-TAU ) / TWOEND IFIF( GEOMAVG ) THENIF( W .LT. ZERO ) THENIF( TAU .GT. ZERO ) THENETA = SQRT(SGUB*TAU)-TAUEND IFELSEIF( SGLB .GT. ZERO ) THENETA = SQRT(SGLB*TAU)-TAUEND IFEND IFEND IFEND IF*PREW = W*TAU = TAU + ETASIGMA = SIGMA + ETA*DO 200 J = 1, NWORK( J ) = WORK( J ) + ETADELTA( J ) = DELTA( J ) - ETA200 CONTINUE** Evaluate PSI and the derivative DPSI*DPSI = ZEROPSI = ZEROERRETM = ZERODO 210 J = 1, IIM1TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PSI = PSI + Z( J )*TEMPDPSI = DPSI + TEMP*TEMPERRETM = ERRETM + PSI210 CONTINUEERRETM = ABS( ERRETM )** Evaluate PHI and the derivative DPHI*DPHI = ZEROPHI = ZERODO 220 J = N, IIP1, -1TEMP = Z( J ) / ( WORK( J )*DELTA( J ) )PHI = PHI + Z( J )*TEMPDPHI = DPHI + TEMP*TEMPERRETM = ERRETM + PHI220 CONTINUE*TAU2 = WORK( II )*DELTA( II )TEMP = Z( II ) / TAU2DW = DPSI + DPHI + TEMP*TEMPTEMP = Z( II )*TEMPW = RHOINV + PHI + PSI + TEMPERRETM = EIGHT*( PHI-PSI ) + ERRETM + TWO*RHOINV$ + THREE*ABS( TEMP )* $ + ABS( TAU2 )*DW*IF( W*PREW.GT.ZERO .AND. ABS( W ).GT.ABS( PREW ) / TEN )$ SWTCH = .NOT.SWTCH*230 CONTINUE** Return with INFO = 1, NITER = MAXIT and not converged*INFO = 1*END IF*240 CONTINUERETURN** End of DLASD4*END*> \brief \b DLASD5 computes the square root of the i-th eigenvalue of a positive symmetric rank-one modification of a 2-by-2 diagonal matrix. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD5 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd5.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd5.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd5.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD5( I, D, Z, DELTA, RHO, DSIGMA, WORK )** .. Scalar Arguments ..* INTEGER I* DOUBLE PRECISION DSIGMA, RHO* ..* .. Array Arguments ..* DOUBLE PRECISION D( 2 ), DELTA( 2 ), WORK( 2 ), Z( 2 )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine computes the square root of the I-th eigenvalue*> of a positive symmetric rank-one modification of a 2-by-2 diagonal*> matrix*>*> diag( D ) * diag( D ) + RHO * Z * transpose(Z) .*>*> The diagonal entries in the array D are assumed to satisfy*>*> 0 <= D(i) < D(j) for i < j .*>*> We also assume RHO > 0 and that the Euclidean norm of the vector*> Z is one.*> \endverbatim** Arguments:* ==========**> \param[in] I*> \verbatim*> I is INTEGER*> The index of the eigenvalue to be computed. I = 1 or I = 2.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension ( 2 )*> The original eigenvalues. We assume 0 <= D(1) < D(2).*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( 2 )*> The components of the updating vector.*> \endverbatim*>*> \param[out] DELTA*> \verbatim*> DELTA is DOUBLE PRECISION array, dimension ( 2 )*> Contains (D(j) - sigma_I) in its j-th component.*> The vector DELTA contains the information necessary*> to construct the eigenvectors.*> \endverbatim*>*> \param[in] RHO*> \verbatim*> RHO is DOUBLE PRECISION*> The scalar in the symmetric updating formula.*> \endverbatim*>*> \param[out] DSIGMA*> \verbatim*> DSIGMA is DOUBLE PRECISION*> The computed sigma_I, the I-th updated eigenvalue.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension ( 2 )*> WORK contains (D(j) + sigma_I) in its j-th component.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ren-Cang Li, Computer Science Division, University of California*> at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD5( I, D, Z, DELTA, RHO, DSIGMA, WORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IDOUBLE PRECISION DSIGMA, RHO* ..* .. Array Arguments ..DOUBLE PRECISION D( 2 ), DELTA( 2 ), WORK( 2 ), Z( 2 )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, THREE, FOURPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,$ THREE = 3.0D+0, FOUR = 4.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION B, C, DEL, DELSQ, TAU, W* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*DEL = D( 2 ) - D( 1 )DELSQ = DEL*( D( 2 )+D( 1 ) )IF( I.EQ.1 ) THENW = ONE + FOUR*RHO*( Z( 2 )*Z( 2 ) / ( D( 1 )+THREE*D( 2 ) )-$ Z( 1 )*Z( 1 ) / ( THREE*D( 1 )+D( 2 ) ) ) / DELIF( W.GT.ZERO ) THENB = DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 1 )*Z( 1 )*DELSQ** B > ZERO, always** The following TAU is DSIGMA * DSIGMA - D( 1 ) * D( 1 )*TAU = TWO*C / ( B+SQRT( ABS( B*B-FOUR*C ) ) )** The following TAU is DSIGMA - D( 1 )*TAU = TAU / ( D( 1 )+SQRT( D( 1 )*D( 1 )+TAU ) )DSIGMA = D( 1 ) + TAUDELTA( 1 ) = -TAUDELTA( 2 ) = DEL - TAUWORK( 1 ) = TWO*D( 1 ) + TAUWORK( 2 ) = ( D( 1 )+TAU ) + D( 2 )* DELTA( 1 ) = -Z( 1 ) / TAU* DELTA( 2 ) = Z( 2 ) / ( DEL-TAU )ELSEB = -DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 2 )*Z( 2 )*DELSQ** The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )*IF( B.GT.ZERO ) THENTAU = -TWO*C / ( B+SQRT( B*B+FOUR*C ) )ELSETAU = ( B-SQRT( B*B+FOUR*C ) ) / TWOEND IF** The following TAU is DSIGMA - D( 2 )*TAU = TAU / ( D( 2 )+SQRT( ABS( D( 2 )*D( 2 )+TAU ) ) )DSIGMA = D( 2 ) + TAUDELTA( 1 ) = -( DEL+TAU )DELTA( 2 ) = -TAUWORK( 1 ) = D( 1 ) + TAU + D( 2 )WORK( 2 ) = TWO*D( 2 ) + TAU* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )* DELTA( 2 ) = -Z( 2 ) / TAUEND IF* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )* DELTA( 1 ) = DELTA( 1 ) / TEMP* DELTA( 2 ) = DELTA( 2 ) / TEMPELSE** Now I=2*B = -DELSQ + RHO*( Z( 1 )*Z( 1 )+Z( 2 )*Z( 2 ) )C = RHO*Z( 2 )*Z( 2 )*DELSQ** The following TAU is DSIGMA * DSIGMA - D( 2 ) * D( 2 )*IF( B.GT.ZERO ) THENTAU = ( B+SQRT( B*B+FOUR*C ) ) / TWOELSETAU = TWO*C / ( -B+SQRT( B*B+FOUR*C ) )END IF** The following TAU is DSIGMA - D( 2 )*TAU = TAU / ( D( 2 )+SQRT( D( 2 )*D( 2 )+TAU ) )DSIGMA = D( 2 ) + TAUDELTA( 1 ) = -( DEL+TAU )DELTA( 2 ) = -TAUWORK( 1 ) = D( 1 ) + TAU + D( 2 )WORK( 2 ) = TWO*D( 2 ) + TAU* DELTA( 1 ) = -Z( 1 ) / ( DEL+TAU )* DELTA( 2 ) = -Z( 2 ) / TAU* TEMP = SQRT( DELTA( 1 )*DELTA( 1 )+DELTA( 2 )*DELTA( 2 ) )* DELTA( 1 ) = DELTA( 1 ) / TEMP* DELTA( 2 ) = DELTA( 2 ) / TEMPEND IFRETURN** End of DLASD5*END*> \brief \b DLASD6 computes the SVD of an updated upper bidiagonal matrix obtained by merging two smaller ones by appending a row. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD6 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd6.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd6.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd6.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD6( ICOMPQ, NL, NR, SQRE, D, VF, VL, ALPHA, BETA,* IDXQ, PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM,* LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK,* IWORK, INFO )** .. Scalar Arguments ..* INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,* $ NR, SQRE* DOUBLE PRECISION ALPHA, BETA, C, S* ..* .. Array Arguments ..* INTEGER GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ),* $ PERM( * )* DOUBLE PRECISION D( * ), DIFL( * ), DIFR( * ),* $ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),* $ VF( * ), VL( * ), WORK( * ), Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASD6 computes the SVD of an updated upper bidiagonal matrix B*> obtained by merging two smaller ones by appending a row. This*> routine is used only for the problem which requires all singular*> values and optionally singular vector matrices in factored form.*> B is an N-by-M matrix with N = NL + NR + 1 and M = N + SQRE.*> A related subroutine, DLASD1, handles the case in which all singular*> values and singular vectors of the bidiagonal matrix are desired.*>*> DLASD6 computes the SVD as follows:*>*> ( D1(in) 0 0 0 )*> B = U(in) * ( Z1**T a Z2**T b ) * VT(in)*> ( 0 0 D2(in) 0 )*>*> = U(out) * ( D(out) 0) * VT(out)*>*> where Z**T = (Z1**T a Z2**T b) = u**T VT**T, and u is a vector of dimension M*> with ALPHA and BETA in the NL+1 and NL+2 th entries and zeros*> elsewhere; and the entry b is empty if SQRE = 0.*>*> The singular values of B can be computed using D1, D2, the first*> components of all the right singular vectors of the lower block, and*> the last components of all the right singular vectors of the upper*> block. These components are stored and updated in VF and VL,*> respectively, in DLASD6. Hence U and VT are not explicitly*> referenced.*>*> The singular values are stored in D. The algorithm consists of two*> stages:*>*> The first stage consists of deflating the size of the problem*> when there are multiple singular values or if there is a zero*> in the Z vector. For each such occurrence the dimension of the*> secular equation problem is reduced by one. This stage is*> performed by the routine DLASD7.*>*> The second stage consists of calculating the updated*> singular values. This is done by finding the roots of the*> secular equation via the routine DLASD4 (as called by DLASD8).*> This routine also updates VF and VL and computes the distances*> between the updated singular values and the old singular*> values.*>*> DLASD6 is called from DLASDA.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> Specifies whether singular vectors are to be computed in*> factored form:*> = 0: Compute singular values only.*> = 1: Compute singular vectors in factored form as well.*> \endverbatim*>*> \param[in] NL*> \verbatim*> NL is INTEGER*> The row dimension of the upper block. NL >= 1.*> \endverbatim*>*> \param[in] NR*> \verbatim*> NR is INTEGER*> The row dimension of the lower block. NR >= 1.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: the lower block is an NR-by-NR square matrix.*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.*>*> The bidiagonal matrix has row dimension N = NL + NR + 1,*> and column dimension M = N + SQRE.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension ( NL+NR+1 ).*> On entry D(1:NL,1:NL) contains the singular values of the*> upper block, and D(NL+2:N) contains the singular values*> of the lower block. On exit D(1:N) contains the singular*> values of the modified matrix.*> \endverbatim*>*> \param[in,out] VF*> \verbatim*> VF is DOUBLE PRECISION array, dimension ( M )*> On entry, VF(1:NL+1) contains the first components of all*> right singular vectors of the upper block; and VF(NL+2:M)*> contains the first components of all right singular vectors*> of the lower block. On exit, VF contains the first components*> of all right singular vectors of the bidiagonal matrix.*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension ( M )*> On entry, VL(1:NL+1) contains the last components of all*> right singular vectors of the upper block; and VL(NL+2:M)*> contains the last components of all right singular vectors of*> the lower block. On exit, VL contains the last components of*> all right singular vectors of the bidiagonal matrix.*> \endverbatim*>*> \param[in,out] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> Contains the diagonal element associated with the added row.*> \endverbatim*>*> \param[in,out] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> Contains the off-diagonal element associated with the added*> row.*> \endverbatim*>*> \param[in,out] IDXQ*> \verbatim*> IDXQ is INTEGER array, dimension ( N )*> This contains the permutation which will reintegrate the*> subproblem just solved back into sorted order, i.e.*> D( IDXQ( I = 1, N ) ) will be in ascending order.*> \endverbatim*>*> \param[out] PERM*> \verbatim*> PERM is INTEGER array, dimension ( N )*> The permutations (from deflation and sorting) to be applied*> to each block. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[out] GIVPTR*> \verbatim*> GIVPTR is INTEGER*> The number of Givens rotations which took place in this*> subproblem. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[out] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )*> Each pair of numbers indicates a pair of columns to take place*> in a Givens rotation. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[in] LDGCOL*> \verbatim*> LDGCOL is INTEGER*> leading dimension of GIVCOL, must be at least N.*> \endverbatim*>*> \param[out] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )*> Each number indicates the C or S value to be used in the*> corresponding Givens rotation. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[in] LDGNUM*> \verbatim*> LDGNUM is INTEGER*> The leading dimension of GIVNUM and POLES, must be at least N.*> \endverbatim*>*> \param[out] POLES*> \verbatim*> POLES is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )*> On exit, POLES(1,*) is an array containing the new singular*> values obtained from solving the secular equation, and*> POLES(2,*) is an array containing the poles in the secular*> equation. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[out] DIFL*> \verbatim*> DIFL is DOUBLE PRECISION array, dimension ( N )*> On exit, DIFL(I) is the distance between I-th updated*> (undeflated) singular value and the I-th (undeflated) old*> singular value.*> \endverbatim*>*> \param[out] DIFR*> \verbatim*> DIFR is DOUBLE PRECISION array,*> dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and*> dimension ( K ) if ICOMPQ = 0.*> On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not*> defined and will not be referenced.*>*> If ICOMPQ = 1, DIFR(1:K,2) is an array containing the*> normalizing factors for the right singular vector matrix.*>*> See DLASD8 for details on DIFL and DIFR.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( M )*> The first elements of this array contain the components*> of the deflation-adjusted updating row vector.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER*> Contains the dimension of the non-deflated matrix,*> This is the order of the related secular equation. 1 <= K <=N.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION*> C contains garbage if SQRE =0 and the C-value of a Givens*> rotation related to the right null space if SQRE = 1.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION*> S contains garbage if SQRE =0 and the S-value of a Givens*> rotation related to the right null space if SQRE = 1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension ( 4 * M )*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension ( 3 * N )*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, a singular value did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD6( ICOMPQ, NL, NR, SQRE, D, VF, VL, ALPHA, BETA,$ IDXQ, PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM,$ LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK,$ IWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,$ NR, SQREDOUBLE PRECISION ALPHA, BETA, C, S* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), IDXQ( * ), IWORK( * ),$ PERM( * )DOUBLE PRECISION D( * ), DIFL( * ), DIFR( * ),$ GIVNUM( LDGNUM, * ), POLES( LDGNUM, * ),$ VF( * ), VL( * ), WORK( * ), Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, IDX, IDXC, IDXP, ISIGMA, IVFW, IVLW, IW, M,$ N, N1, N2DOUBLE PRECISION ORGNRM* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAMRG, DLASCL, DLASD7, DLASD8, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0N = NL + NR + 1M = N + SQRE*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( NL.LT.1 ) THENINFO = -2ELSE IF( NR.LT.1 ) THENINFO = -3ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -4ELSE IF( LDGCOL.LT.N ) THENINFO = -14ELSE IF( LDGNUM.LT.N ) THENINFO = -16END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD6', -INFO )RETURNEND IF** The following values are for bookkeeping purposes only. They are* integer pointers which indicate the portion of the workspace* used by a particular array in DLASD7 and DLASD8.*ISIGMA = 1IW = ISIGMA + NIVFW = IW + MIVLW = IVFW + M*IDX = 1IDXC = IDX + NIDXP = IDXC + N** Scale.*ORGNRM = MAX( ABS( ALPHA ), ABS( BETA ) )D( NL+1 ) = ZERODO 10 I = 1, NIF( ABS( D( I ) ).GT.ORGNRM ) THENORGNRM = ABS( D( I ) )END IF10 CONTINUECALL DLASCL( 'G', 0, 0, ORGNRM, ONE, N, 1, D, N, INFO )ALPHA = ALPHA / ORGNRMBETA = BETA / ORGNRM** Sort and Deflate singular values.*CALL DLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, WORK( IW ), VF,$ WORK( IVFW ), VL, WORK( IVLW ), ALPHA, BETA,$ WORK( ISIGMA ), IWORK( IDX ), IWORK( IDXP ), IDXQ,$ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM, C, S,$ INFO )** Solve Secular Equation, compute DIFL, DIFR, and update VF, VL.*CALL DLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDGNUM,$ WORK( ISIGMA ), WORK( IW ), INFO )** Report the possible convergence failure.*IF( INFO.NE.0 ) THENRETURNEND IF** Save the poles if ICOMPQ = 1.*IF( ICOMPQ.EQ.1 ) THENCALL DCOPY( K, D, 1, POLES( 1, 1 ), 1 )CALL DCOPY( K, WORK( ISIGMA ), 1, POLES( 1, 2 ), 1 )END IF** Unscale.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, N, 1, D, N, INFO )** Prepare the IDXQ sorting permutation.*N1 = KN2 = N - KCALL DLAMRG( N1, N2, D, 1, -1, IDXQ )*RETURN** End of DLASD6*END*> \brief \b DLASD7 merges the two sets of singular values together into a single sorted set. Then it tries to deflate the size of the problem. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD7 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd7.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd7.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd7.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, ZW, VF, VFW, VL,* VLW, ALPHA, BETA, DSIGMA, IDX, IDXP, IDXQ,* PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,* C, S, INFO )** .. Scalar Arguments ..* INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,* $ NR, SQRE* DOUBLE PRECISION ALPHA, BETA, C, S* ..* .. Array Arguments ..* INTEGER GIVCOL( LDGCOL, * ), IDX( * ), IDXP( * ),* $ IDXQ( * ), PERM( * )* DOUBLE PRECISION D( * ), DSIGMA( * ), GIVNUM( LDGNUM, * ),* $ VF( * ), VFW( * ), VL( * ), VLW( * ), Z( * ),* $ ZW( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASD7 merges the two sets of singular values together into a single*> sorted set. Then it tries to deflate the size of the problem. There*> are two ways in which deflation can occur: when two or more singular*> values are close together or if there is a tiny entry in the Z*> vector. For each such occurrence the order of the related*> secular equation problem is reduced by one.*>*> DLASD7 is called from DLASD6.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> Specifies whether singular vectors are to be computed*> in compact form, as follows:*> = 0: Compute singular values only.*> = 1: Compute singular vectors of upper*> bidiagonal matrix in compact form.*> \endverbatim*>*> \param[in] NL*> \verbatim*> NL is INTEGER*> The row dimension of the upper block. NL >= 1.*> \endverbatim*>*> \param[in] NR*> \verbatim*> NR is INTEGER*> The row dimension of the lower block. NR >= 1.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: the lower block is an NR-by-NR square matrix.*> = 1: the lower block is an NR-by-(NR+1) rectangular matrix.*>*> The bidiagonal matrix has*> N = NL + NR + 1 rows and*> M = N + SQRE >= N columns.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER*> Contains the dimension of the non-deflated matrix, this is*> the order of the related secular equation. 1 <= K <=N.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension ( N )*> On entry D contains the singular values of the two submatrices*> to be combined. On exit D contains the trailing (N-K) updated*> singular values (those which were deflated) sorted into*> increasing order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( M )*> On exit Z contains the updating row vector in the secular*> equation.*> \endverbatim*>*> \param[out] ZW*> \verbatim*> ZW is DOUBLE PRECISION array, dimension ( M )*> Workspace for Z.*> \endverbatim*>*> \param[in,out] VF*> \verbatim*> VF is DOUBLE PRECISION array, dimension ( M )*> On entry, VF(1:NL+1) contains the first components of all*> right singular vectors of the upper block; and VF(NL+2:M)*> contains the first components of all right singular vectors*> of the lower block. On exit, VF contains the first components*> of all right singular vectors of the bidiagonal matrix.*> \endverbatim*>*> \param[out] VFW*> \verbatim*> VFW is DOUBLE PRECISION array, dimension ( M )*> Workspace for VF.*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension ( M )*> On entry, VL(1:NL+1) contains the last components of all*> right singular vectors of the upper block; and VL(NL+2:M)*> contains the last components of all right singular vectors*> of the lower block. On exit, VL contains the last components*> of all right singular vectors of the bidiagonal matrix.*> \endverbatim*>*> \param[out] VLW*> \verbatim*> VLW is DOUBLE PRECISION array, dimension ( M )*> Workspace for VL.*> \endverbatim*>*> \param[in] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> Contains the diagonal element associated with the added row.*> \endverbatim*>*> \param[in] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> Contains the off-diagonal element associated with the added*> row.*> \endverbatim*>*> \param[out] DSIGMA*> \verbatim*> DSIGMA is DOUBLE PRECISION array, dimension ( N )*> Contains a copy of the diagonal elements (K-1 singular values*> and one zero) in the secular equation.*> \endverbatim*>*> \param[out] IDX*> \verbatim*> IDX is INTEGER array, dimension ( N )*> This will contain the permutation used to sort the contents of*> D into ascending order.*> \endverbatim*>*> \param[out] IDXP*> \verbatim*> IDXP is INTEGER array, dimension ( N )*> This will contain the permutation used to place deflated*> values of D at the end of the array. On output IDXP(2:K)*> points to the nondeflated D-values and IDXP(K+1:N)*> points to the deflated singular values.*> \endverbatim*>*> \param[in] IDXQ*> \verbatim*> IDXQ is INTEGER array, dimension ( N )*> This contains the permutation which separately sorts the two*> sub-problems in D into ascending order. Note that entries in*> the first half of this permutation must first be moved one*> position backward; and entries in the second half*> must first have NL+1 added to their values.*> \endverbatim*>*> \param[out] PERM*> \verbatim*> PERM is INTEGER array, dimension ( N )*> The permutations (from deflation and sorting) to be applied*> to each singular block. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[out] GIVPTR*> \verbatim*> GIVPTR is INTEGER*> The number of Givens rotations which took place in this*> subproblem. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[out] GIVCOL*> \verbatim*> GIVCOL is INTEGER array, dimension ( LDGCOL, 2 )*> Each pair of numbers indicates a pair of columns to take place*> in a Givens rotation. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[in] LDGCOL*> \verbatim*> LDGCOL is INTEGER*> The leading dimension of GIVCOL, must be at least N.*> \endverbatim*>*> \param[out] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 )*> Each number indicates the C or S value to be used in the*> corresponding Givens rotation. Not referenced if ICOMPQ = 0.*> \endverbatim*>*> \param[in] LDGNUM*> \verbatim*> LDGNUM is INTEGER*> The leading dimension of GIVNUM, must be at least N.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION*> C contains garbage if SQRE =0 and the C-value of a Givens*> rotation related to the right null space if SQRE = 1.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION*> S contains garbage if SQRE =0 and the S-value of a Givens*> rotation related to the right null space if SQRE = 1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD7( ICOMPQ, NL, NR, SQRE, K, D, Z, ZW, VF, VFW, VL,$ VLW, ALPHA, BETA, DSIGMA, IDX, IDXP, IDXQ,$ PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM,$ C, S, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER GIVPTR, ICOMPQ, INFO, K, LDGCOL, LDGNUM, NL,$ NR, SQREDOUBLE PRECISION ALPHA, BETA, C, S* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), IDX( * ), IDXP( * ),$ IDXQ( * ), PERM( * )DOUBLE PRECISION D( * ), DSIGMA( * ), GIVNUM( LDGNUM, * ),$ VF( * ), VFW( * ), VL( * ), VLW( * ), Z( * ),$ ZW( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, EIGHTPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,$ EIGHT = 8.0D+0 )* ..* .. Local Scalars ..*INTEGER I, IDXI, IDXJ, IDXJP, J, JP, JPREV, K2, M, N,$ NLP1, NLP2DOUBLE PRECISION EPS, HLFTOL, TAU, TOL, Z1* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAMRG, DROT, XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLAPY2EXTERNAL DLAMCH, DLAPY2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0N = NL + NR + 1M = N + SQRE*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( NL.LT.1 ) THENINFO = -2ELSE IF( NR.LT.1 ) THENINFO = -3ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -4ELSE IF( LDGCOL.LT.N ) THENINFO = -22ELSE IF( LDGNUM.LT.N ) THENINFO = -24END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD7', -INFO )RETURNEND IF*NLP1 = NL + 1NLP2 = NL + 2IF( ICOMPQ.EQ.1 ) THENGIVPTR = 0END IF** Generate the first part of the vector Z and move the singular* values in the first part of D one position backward.*Z1 = ALPHA*VL( NLP1 )VL( NLP1 ) = ZEROTAU = VF( NLP1 )DO 10 I = NL, 1, -1Z( I+1 ) = ALPHA*VL( I )VL( I ) = ZEROVF( I+1 ) = VF( I )D( I+1 ) = D( I )IDXQ( I+1 ) = IDXQ( I ) + 110 CONTINUEVF( 1 ) = TAU** Generate the second part of the vector Z.*DO 20 I = NLP2, MZ( I ) = BETA*VF( I )VF( I ) = ZERO20 CONTINUE** Sort the singular values into increasing order*DO 30 I = NLP2, NIDXQ( I ) = IDXQ( I ) + NLP130 CONTINUE** DSIGMA, IDXC, IDXC, and ZW are used as storage space.*DO 40 I = 2, NDSIGMA( I ) = D( IDXQ( I ) )ZW( I ) = Z( IDXQ( I ) )VFW( I ) = VF( IDXQ( I ) )VLW( I ) = VL( IDXQ( I ) )40 CONTINUE*CALL DLAMRG( NL, NR, DSIGMA( 2 ), 1, 1, IDX( 2 ) )*DO 50 I = 2, NIDXI = 1 + IDX( I )D( I ) = DSIGMA( IDXI )Z( I ) = ZW( IDXI )VF( I ) = VFW( IDXI )VL( I ) = VLW( IDXI )50 CONTINUE** Calculate the allowable deflation tolerence*EPS = DLAMCH( 'Epsilon' )TOL = MAX( ABS( ALPHA ), ABS( BETA ) )TOL = EIGHT*EIGHT*EPS*MAX( ABS( D( N ) ), TOL )** There are 2 kinds of deflation -- first a value in the z-vector* is small, second two (or more) singular values are very close* together (their difference is small).** If the value in the z-vector is small, we simply permute the* array so that the corresponding singular value is moved to the* end.** If two values in the D-vector are close, we perform a two-sided* rotation designed to make one of the corresponding z-vector* entries zero, and then permute the array so that the deflated* singular value is moved to the end.** If there are multiple singular values then the problem deflates.* Here the number of equal singular values are found. As each equal* singular value is found, an elementary reflector is computed to* rotate the corresponding singular subspace so that the* corresponding components of Z are zero in this new basis.*K = 1K2 = N + 1DO 60 J = 2, NIF( ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1IDXP( K2 ) = JIF( J.EQ.N )$ GO TO 100ELSEJPREV = JGO TO 70END IF60 CONTINUE70 CONTINUEJ = JPREV80 CONTINUEJ = J + 1IF( J.GT.N )$ GO TO 90IF( ABS( Z( J ) ).LE.TOL ) THEN** Deflate due to small z component.*K2 = K2 - 1IDXP( K2 ) = JELSE** Check if singular values are close enough to allow deflation.*IF( ABS( D( J )-D( JPREV ) ).LE.TOL ) THEN** Deflation is possible.*S = Z( JPREV )C = Z( J )** Find sqrt(a**2+b**2) without overflow or* destructive underflow.*TAU = DLAPY2( C, S )Z( J ) = TAUZ( JPREV ) = ZEROC = C / TAUS = -S / TAU** Record the appropriate Givens rotation*IF( ICOMPQ.EQ.1 ) THENGIVPTR = GIVPTR + 1IDXJP = IDXQ( IDX( JPREV )+1 )IDXJ = IDXQ( IDX( J )+1 )IF( IDXJP.LE.NLP1 ) THENIDXJP = IDXJP - 1END IFIF( IDXJ.LE.NLP1 ) THENIDXJ = IDXJ - 1END IFGIVCOL( GIVPTR, 2 ) = IDXJPGIVCOL( GIVPTR, 1 ) = IDXJGIVNUM( GIVPTR, 2 ) = CGIVNUM( GIVPTR, 1 ) = SEND IFCALL DROT( 1, VF( JPREV ), 1, VF( J ), 1, C, S )CALL DROT( 1, VL( JPREV ), 1, VL( J ), 1, C, S )K2 = K2 - 1IDXP( K2 ) = JPREVJPREV = JELSEK = K + 1ZW( K ) = Z( JPREV )DSIGMA( K ) = D( JPREV )IDXP( K ) = JPREVJPREV = JEND IFEND IFGO TO 8090 CONTINUE** Record the last singular value.*K = K + 1ZW( K ) = Z( JPREV )DSIGMA( K ) = D( JPREV )IDXP( K ) = JPREV*100 CONTINUE** Sort the singular values into DSIGMA. The singular values which* were not deflated go into the first K slots of DSIGMA, except* that DSIGMA(1) is treated separately.*DO 110 J = 2, NJP = IDXP( J )DSIGMA( J ) = D( JP )VFW( J ) = VF( JP )VLW( J ) = VL( JP )110 CONTINUEIF( ICOMPQ.EQ.1 ) THENDO 120 J = 2, NJP = IDXP( J )PERM( J ) = IDXQ( IDX( JP )+1 )IF( PERM( J ).LE.NLP1 ) THENPERM( J ) = PERM( J ) - 1END IF120 CONTINUEEND IF** The deflated singular values go back into the last N - K slots of* D.*CALL DCOPY( N-K, DSIGMA( K+1 ), 1, D( K+1 ), 1 )** Determine DSIGMA(1), DSIGMA(2), Z(1), VF(1), VL(1), VF(M), and* VL(M).*DSIGMA( 1 ) = ZEROHLFTOL = TOL / TWOIF( ABS( DSIGMA( 2 ) ).LE.HLFTOL )$ DSIGMA( 2 ) = HLFTOLIF( M.GT.N ) THENZ( 1 ) = DLAPY2( Z1, Z( M ) )IF( Z( 1 ).LE.TOL ) THENC = ONES = ZEROZ( 1 ) = TOLELSEC = Z1 / Z( 1 )S = -Z( M ) / Z( 1 )END IFCALL DROT( 1, VF( M ), 1, VF( 1 ), 1, C, S )CALL DROT( 1, VL( M ), 1, VL( 1 ), 1, C, S )ELSEIF( ABS( Z1 ).LE.TOL ) THENZ( 1 ) = TOLELSEZ( 1 ) = Z1END IFEND IF** Restore Z, VF, and VL.*CALL DCOPY( K-1, ZW( 2 ), 1, Z( 2 ), 1 )CALL DCOPY( N-1, VFW( 2 ), 1, VF( 2 ), 1 )CALL DCOPY( N-1, VLW( 2 ), 1, VL( 2 ), 1 )*RETURN** End of DLASD7*END*> \brief \b DLASD8 finds the square roots of the roots of the secular equation, and stores, for each element in D, the distance to its two nearest poles. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASD8 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasd8.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasd8.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasd8.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDDIFR,* DSIGMA, WORK, INFO )** .. Scalar Arguments ..* INTEGER ICOMPQ, INFO, K, LDDIFR* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), DIFL( * ), DIFR( LDDIFR, * ),* $ DSIGMA( * ), VF( * ), VL( * ), WORK( * ),* $ Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASD8 finds the square roots of the roots of the secular equation,*> as defined by the values in DSIGMA and Z. It makes the appropriate*> calls to DLASD4, and stores, for each element in D, the distance*> to its two nearest poles (elements in DSIGMA). It also updates*> the arrays VF and VL, the first and last components of all the*> right singular vectors of the original bidiagonal matrix.*>*> DLASD8 is called from DLASD6.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> Specifies whether singular vectors are to be computed in*> factored form in the calling routine:*> = 0: Compute singular values only.*> = 1: Compute singular vectors in factored form as well.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of terms in the rational function to be solved*> by DLASD4. K >= 1.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension ( K )*> On output, D contains the updated singular values.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( K )*> On entry, the first K elements of this array contain the*> components of the deflation-adjusted updating row vector.*> On exit, Z is updated.*> \endverbatim*>*> \param[in,out] VF*> \verbatim*> VF is DOUBLE PRECISION array, dimension ( K )*> On entry, VF contains information passed through DBEDE8.*> On exit, VF contains the first K components of the first*> components of all right singular vectors of the bidiagonal*> matrix.*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension ( K )*> On entry, VL contains information passed through DBEDE8.*> On exit, VL contains the first K components of the last*> components of all right singular vectors of the bidiagonal*> matrix.*> \endverbatim*>*> \param[out] DIFL*> \verbatim*> DIFL is DOUBLE PRECISION array, dimension ( K )*> On exit, DIFL(I) = D(I) - DSIGMA(I).*> \endverbatim*>*> \param[out] DIFR*> \verbatim*> DIFR is DOUBLE PRECISION array,*> dimension ( LDDIFR, 2 ) if ICOMPQ = 1 and*> dimension ( K ) if ICOMPQ = 0.*> On exit, DIFR(I,1) = D(I) - DSIGMA(I+1), DIFR(K,1) is not*> defined and will not be referenced.*>*> If ICOMPQ = 1, DIFR(1:K,2) is an array containing the*> normalizing factors for the right singular vector matrix.*> \endverbatim*>*> \param[in] LDDIFR*> \verbatim*> LDDIFR is INTEGER*> The leading dimension of DIFR, must be at least K.*> \endverbatim*>*> \param[in,out] DSIGMA*> \verbatim*> DSIGMA is DOUBLE PRECISION array, dimension ( K )*> On entry, the first K elements of this array contain the old*> roots of the deflated updating problem. These are the poles*> of the secular equation.*> On exit, the elements of DSIGMA may be very slightly altered*> in value.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*K)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, a singular value did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASD8( ICOMPQ, K, D, Z, VF, VL, DIFL, DIFR, LDDIFR,$ DSIGMA, WORK, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER ICOMPQ, INFO, K, LDDIFR* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), DIFL( * ), DIFR( LDDIFR, * ),$ DSIGMA( * ), VF( * ), VL( * ), WORK( * ),$ Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, IWK1, IWK2, IWK2I, IWK3, IWK3I, JDOUBLE PRECISION DIFLJ, DIFRJ, DJ, DSIGJ, DSIGJP, RHO, TEMP* ..* .. External Subroutines ..EXTERNAL DCOPY, DLASCL, DLASD4, DLASET, XERBLA* ..* .. External Functions ..DOUBLE PRECISION DDOT, DLAMC3, DNRM2EXTERNAL DDOT, DLAMC3, DNRM2* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( K.LT.1 ) THENINFO = -2ELSE IF( LDDIFR.LT.K ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASD8', -INFO )RETURNEND IF** Quick return if possible*IF( K.EQ.1 ) THEND( 1 ) = ABS( Z( 1 ) )DIFL( 1 ) = D( 1 )IF( ICOMPQ.EQ.1 ) THENDIFL( 2 ) = ONEDIFR( 1, 2 ) = ONEEND IFRETURNEND IF** Modify values DSIGMA(i) to make sure all DSIGMA(i)-DSIGMA(j) can* be computed with high relative accuracy (barring over/underflow).* This is a problem on machines without a guard digit in* add/subtract (Cray XMP, Cray YMP, Cray C 90 and Cray 2).* The following code replaces DSIGMA(I) by 2*DSIGMA(I)-DSIGMA(I),* which on any of these machines zeros out the bottommost* bit of DSIGMA(I) if it is 1; this makes the subsequent* subtractions DSIGMA(I)-DSIGMA(J) unproblematic when cancellation* occurs. On binary machines with a guard digit (almost all* machines) it does not change DSIGMA(I) at all. On hexadecimal* and decimal machines with a guard digit, it slightly* changes the bottommost bits of DSIGMA(I). It does not account* for hexadecimal or decimal machines without guard digits* (we know of none). We use a subroutine call to compute* 2*DLAMBDA(I) to prevent optimizing compilers from eliminating* this code.*DO 10 I = 1, KDSIGMA( I ) = DLAMC3( DSIGMA( I ), DSIGMA( I ) ) - DSIGMA( I )10 CONTINUE** Book keeping.*IWK1 = 1IWK2 = IWK1 + KIWK3 = IWK2 + KIWK2I = IWK2 - 1IWK3I = IWK3 - 1** Normalize Z.*RHO = DNRM2( K, Z, 1 )CALL DLASCL( 'G', 0, 0, RHO, ONE, K, 1, Z, K, INFO )RHO = RHO*RHO** Initialize WORK(IWK3).*CALL DLASET( 'A', K, 1, ONE, ONE, WORK( IWK3 ), K )** Compute the updated singular values, the arrays DIFL, DIFR,* and the updated Z.*DO 40 J = 1, KCALL DLASD4( K, J, DSIGMA, Z, WORK( IWK1 ), RHO, D( J ),$ WORK( IWK2 ), INFO )** If the root finder fails, report the convergence failure.*IF( INFO.NE.0 ) THENRETURNEND IFWORK( IWK3I+J ) = WORK( IWK3I+J )*WORK( J )*WORK( IWK2I+J )DIFL( J ) = -WORK( J )DIFR( J, 1 ) = -WORK( J+1 )DO 20 I = 1, J - 1WORK( IWK3I+I ) = WORK( IWK3I+I )*WORK( I )*$ WORK( IWK2I+I ) / ( DSIGMA( I )-$ DSIGMA( J ) ) / ( DSIGMA( I )+$ DSIGMA( J ) )20 CONTINUEDO 30 I = J + 1, KWORK( IWK3I+I ) = WORK( IWK3I+I )*WORK( I )*$ WORK( IWK2I+I ) / ( DSIGMA( I )-$ DSIGMA( J ) ) / ( DSIGMA( I )+$ DSIGMA( J ) )30 CONTINUE40 CONTINUE** Compute updated Z.*DO 50 I = 1, KZ( I ) = SIGN( SQRT( ABS( WORK( IWK3I+I ) ) ), Z( I ) )50 CONTINUE** Update VF and VL.*DO 80 J = 1, KDIFLJ = DIFL( J )DJ = D( J )DSIGJ = -DSIGMA( J )IF( J.LT.K ) THENDIFRJ = -DIFR( J, 1 )DSIGJP = -DSIGMA( J+1 )END IFWORK( J ) = -Z( J ) / DIFLJ / ( DSIGMA( J )+DJ )DO 60 I = 1, J - 1WORK( I ) = Z( I ) / ( DLAMC3( DSIGMA( I ), DSIGJ )-DIFLJ )$ / ( DSIGMA( I )+DJ )60 CONTINUEDO 70 I = J + 1, KWORK( I ) = Z( I ) / ( DLAMC3( DSIGMA( I ), DSIGJP )+DIFRJ )$ / ( DSIGMA( I )+DJ )70 CONTINUETEMP = DNRM2( K, WORK, 1 )WORK( IWK2I+J ) = DDOT( K, WORK, 1, VF, 1 ) / TEMPWORK( IWK3I+J ) = DDOT( K, WORK, 1, VL, 1 ) / TEMPIF( ICOMPQ.EQ.1 ) THENDIFR( J, 2 ) = TEMPEND IF80 CONTINUE*CALL DCOPY( K, WORK( IWK2 ), 1, VF, 1 )CALL DCOPY( K, WORK( IWK3 ), 1, VL, 1 )*RETURN** End of DLASD8*END*> \brief \b DLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASDA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasda.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasda.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasda.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASDA( ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT, K,* DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL,* PERM, GIVNUM, C, S, WORK, IWORK, INFO )** .. Scalar Arguments ..* INTEGER ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE* ..* .. Array Arguments ..* INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),* $ K( * ), PERM( LDGCOL, * )* DOUBLE PRECISION C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),* $ E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),* $ S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),* $ Z( LDU, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Using a divide and conquer approach, DLASDA computes the singular*> value decomposition (SVD) of a real upper bidiagonal N-by-M matrix*> B with diagonal D and offdiagonal E, where M = N + SQRE. The*> algorithm computes the singular values in the SVD B = U * S * VT.*> The orthogonal matrices U and VT are optionally computed in*> compact form.*>*> A related subroutine, DLASD0, computes the singular values and*> the singular vectors in explicit form.*> \endverbatim** Arguments:* ==========**> \param[in] ICOMPQ*> \verbatim*> ICOMPQ is INTEGER*> Specifies whether singular vectors are to be computed*> in compact form, as follows*> = 0: Compute singular values only.*> = 1: Compute singular vectors of upper bidiagonal*> matrix in compact form.*> \endverbatim*>*> \param[in] SMLSIZ*> \verbatim*> SMLSIZ is INTEGER*> The maximum size of the subproblems at the bottom of the*> computation tree.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The row dimension of the upper bidiagonal matrix. This is*> also the dimension of the main diagonal array D.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> Specifies the column dimension of the bidiagonal matrix.*> = 0: The bidiagonal matrix has column dimension M = N;*> = 1: The bidiagonal matrix has column dimension M = N + 1.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension ( N )*> On entry D contains the main diagonal of the bidiagonal*> matrix. On exit D, if INFO = 0, contains its singular values.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension ( M-1 )*> Contains the subdiagonal entries of the bidiagonal matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[out] U*> \verbatim*> U is DOUBLE PRECISION array,*> dimension ( LDU, SMLSIZ ) if ICOMPQ = 1, and not referenced*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, U contains the left*> singular vector matrices of all subproblems at the bottom*> level.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER, LDU = > N.*> The leading dimension of arrays U, VT, DIFL, DIFR, POLES,*> GIVNUM, and Z.*> \endverbatim*>*> \param[out] VT*> \verbatim*> VT is DOUBLE PRECISION array,*> dimension ( LDU, SMLSIZ+1 ) if ICOMPQ = 1, and not referenced*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, VT**T contains the right*> singular vector matrices of all subproblems at the bottom*> level.*> \endverbatim*>*> \param[out] K*> \verbatim*> K is INTEGER array,*> dimension ( N ) if ICOMPQ = 1 and dimension 1 if ICOMPQ = 0.*> If ICOMPQ = 1, on exit, K(I) is the dimension of the I-th*> secular equation on the computation tree.*> \endverbatim*>*> \param[out] DIFL*> \verbatim*> DIFL is DOUBLE PRECISION array, dimension ( LDU, NLVL ),*> where NLVL = floor(log_2 (N/SMLSIZ))).*> \endverbatim*>*> \param[out] DIFR*> \verbatim*> DIFR is DOUBLE PRECISION array,*> dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1 and*> dimension ( N ) if ICOMPQ = 0.*> If ICOMPQ = 1, on exit, DIFL(1:N, I) and DIFR(1:N, 2 * I - 1)*> record distances between singular values on the I-th*> level and singular values on the (I -1)-th level, and*> DIFR(1:N, 2 * I ) contains the normalizing factors for*> the right singular vector matrix. See DLASD8 for details.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array,*> dimension ( LDU, NLVL ) if ICOMPQ = 1 and*> dimension ( N ) if ICOMPQ = 0.*> The first K elements of Z(1, I) contain the components of*> the deflation-adjusted updating row vector for subproblems*> on the I-th level.*> \endverbatim*>*> \param[out] POLES*> \verbatim*> POLES is DOUBLE PRECISION array,*> dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not referenced*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, POLES(1, 2*I - 1) and*> POLES(1, 2*I) contain the new and old singular values*> involved in the secular equations on the I-th level.*> \endverbatim*>*> \param[out] GIVPTR*> \verbatim*> GIVPTR is INTEGER array,*> dimension ( N ) if ICOMPQ = 1, and not referenced if*> ICOMPQ = 0. If ICOMPQ = 1, on exit, GIVPTR( I ) records*> the number of Givens rotations performed on the I-th*> problem on the computation tree.*> \endverbatim*>*> \param[out] GIVCOL*> \verbatim*> GIVCOL is INTEGER array,*> dimension ( LDGCOL, 2 * NLVL ) if ICOMPQ = 1, and not*> referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,*> GIVCOL(1, 2 *I - 1) and GIVCOL(1, 2 *I) record the locations*> of Givens rotations performed on the I-th level on the*> computation tree.*> \endverbatim*>*> \param[in] LDGCOL*> \verbatim*> LDGCOL is INTEGER, LDGCOL = > N.*> The leading dimension of arrays GIVCOL and PERM.*> \endverbatim*>*> \param[out] PERM*> \verbatim*> PERM is INTEGER array,*> dimension ( LDGCOL, NLVL ) if ICOMPQ = 1, and not referenced*> if ICOMPQ = 0. If ICOMPQ = 1, on exit, PERM(1, I) records*> permutations done on the I-th level of the computation tree.*> \endverbatim*>*> \param[out] GIVNUM*> \verbatim*> GIVNUM is DOUBLE PRECISION array,*> dimension ( LDU, 2 * NLVL ) if ICOMPQ = 1, and not*> referenced if ICOMPQ = 0. If ICOMPQ = 1, on exit, for each I,*> GIVNUM(1, 2 *I - 1) and GIVNUM(1, 2 *I) record the C- and S-*> values of Givens rotations performed on the I-th level on*> the computation tree.*> \endverbatim*>*> \param[out] C*> \verbatim*> C is DOUBLE PRECISION array,*> dimension ( N ) if ICOMPQ = 1, and dimension 1 if ICOMPQ = 0.*> If ICOMPQ = 1 and the I-th subproblem is not square, on exit,*> C( I ) contains the C-value of a Givens rotation related to*> the right null space of the I-th subproblem.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension ( N ) if*> ICOMPQ = 1, and dimension 1 if ICOMPQ = 0. If ICOMPQ = 1*> and the I-th subproblem is not square, on exit, S( I )*> contains the S-value of a Givens rotation related to*> the right null space of the I-th subproblem.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (6 * N + (SMLSIZ + 1)*(SMLSIZ + 1)).*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (7*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = 1, a singular value did not converge*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASDA( ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT, K,$ DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL,$ PERM, GIVNUM, C, S, WORK, IWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER ICOMPQ, INFO, LDGCOL, LDU, N, SMLSIZ, SQRE* ..* .. Array Arguments ..INTEGER GIVCOL( LDGCOL, * ), GIVPTR( * ), IWORK( * ),$ K( * ), PERM( LDGCOL, * )DOUBLE PRECISION C( * ), D( * ), DIFL( LDU, * ), DIFR( LDU, * ),$ E( * ), GIVNUM( LDU, * ), POLES( LDU, * ),$ S( * ), U( LDU, * ), VT( LDU, * ), WORK( * ),$ Z( LDU, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, I1, IC, IDXQ, IDXQI, IM1, INODE, ITEMP, IWK,$ J, LF, LL, LVL, LVL2, M, NCC, ND, NDB1, NDIML,$ NDIMR, NL, NLF, NLP1, NLVL, NR, NRF, NRP1, NRU,$ NWORK1, NWORK2, SMLSZP, SQREI, VF, VFI, VL, VLIDOUBLE PRECISION ALPHA, BETA* ..* .. External Subroutines ..EXTERNAL DCOPY, DLASD6, DLASDQ, DLASDT, DLASET, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( ( ICOMPQ.LT.0 ) .OR. ( ICOMPQ.GT.1 ) ) THENINFO = -1ELSE IF( SMLSIZ.LT.3 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -4ELSE IF( LDU.LT.( N+SQRE ) ) THENINFO = -8ELSE IF( LDGCOL.LT.N ) THENINFO = -17END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASDA', -INFO )RETURNEND IF*M = N + SQRE** If the input matrix is too small, call DLASDQ to find the SVD.*IF( N.LE.SMLSIZ ) THENIF( ICOMPQ.EQ.0 ) THENCALL DLASDQ( 'U', SQRE, N, 0, 0, 0, D, E, VT, LDU, U, LDU,$ U, LDU, WORK, INFO )ELSECALL DLASDQ( 'U', SQRE, N, M, N, 0, D, E, VT, LDU, U, LDU,$ U, LDU, WORK, INFO )END IFRETURNEND IF** Book-keeping and set up the computation tree.*INODE = 1NDIML = INODE + NNDIMR = NDIML + NIDXQ = NDIMR + NIWK = IDXQ + N*NCC = 0NRU = 0*SMLSZP = SMLSIZ + 1VF = 1VL = VF + MNWORK1 = VL + MNWORK2 = NWORK1 + SMLSZP*SMLSZP*CALL DLASDT( N, NLVL, ND, IWORK( INODE ), IWORK( NDIML ),$ IWORK( NDIMR ), SMLSIZ )** for the nodes on bottom level of the tree, solve* their subproblems by DLASDQ.*NDB1 = ( ND+1 ) / 2DO 30 I = NDB1, ND** IC : center row of each node* NL : number of rows of left subproblem* NR : number of rows of right subproblem* NLF: starting row of the left subproblem* NRF: starting row of the right subproblem*I1 = I - 1IC = IWORK( INODE+I1 )NL = IWORK( NDIML+I1 )NLP1 = NL + 1NR = IWORK( NDIMR+I1 )NLF = IC - NLNRF = IC + 1IDXQI = IDXQ + NLF - 2VFI = VF + NLF - 1VLI = VL + NLF - 1SQREI = 1IF( ICOMPQ.EQ.0 ) THENCALL DLASET( 'A', NLP1, NLP1, ZERO, ONE, WORK( NWORK1 ),$ SMLSZP )CALL DLASDQ( 'U', SQREI, NL, NLP1, NRU, NCC, D( NLF ),$ E( NLF ), WORK( NWORK1 ), SMLSZP,$ WORK( NWORK2 ), NL, WORK( NWORK2 ), NL,$ WORK( NWORK2 ), INFO )ITEMP = NWORK1 + NL*SMLSZPCALL DCOPY( NLP1, WORK( NWORK1 ), 1, WORK( VFI ), 1 )CALL DCOPY( NLP1, WORK( ITEMP ), 1, WORK( VLI ), 1 )ELSECALL DLASET( 'A', NL, NL, ZERO, ONE, U( NLF, 1 ), LDU )CALL DLASET( 'A', NLP1, NLP1, ZERO, ONE, VT( NLF, 1 ), LDU )CALL DLASDQ( 'U', SQREI, NL, NLP1, NL, NCC, D( NLF ),$ E( NLF ), VT( NLF, 1 ), LDU, U( NLF, 1 ), LDU,$ U( NLF, 1 ), LDU, WORK( NWORK1 ), INFO )CALL DCOPY( NLP1, VT( NLF, 1 ), 1, WORK( VFI ), 1 )CALL DCOPY( NLP1, VT( NLF, NLP1 ), 1, WORK( VLI ), 1 )END IFIF( INFO.NE.0 ) THENRETURNEND IFDO 10 J = 1, NLIWORK( IDXQI+J ) = J10 CONTINUEIF( ( I.EQ.ND ) .AND. ( SQRE.EQ.0 ) ) THENSQREI = 0ELSESQREI = 1END IFIDXQI = IDXQI + NLP1VFI = VFI + NLP1VLI = VLI + NLP1NRP1 = NR + SQREIIF( ICOMPQ.EQ.0 ) THENCALL DLASET( 'A', NRP1, NRP1, ZERO, ONE, WORK( NWORK1 ),$ SMLSZP )CALL DLASDQ( 'U', SQREI, NR, NRP1, NRU, NCC, D( NRF ),$ E( NRF ), WORK( NWORK1 ), SMLSZP,$ WORK( NWORK2 ), NR, WORK( NWORK2 ), NR,$ WORK( NWORK2 ), INFO )ITEMP = NWORK1 + ( NRP1-1 )*SMLSZPCALL DCOPY( NRP1, WORK( NWORK1 ), 1, WORK( VFI ), 1 )CALL DCOPY( NRP1, WORK( ITEMP ), 1, WORK( VLI ), 1 )ELSECALL DLASET( 'A', NR, NR, ZERO, ONE, U( NRF, 1 ), LDU )CALL DLASET( 'A', NRP1, NRP1, ZERO, ONE, VT( NRF, 1 ), LDU )CALL DLASDQ( 'U', SQREI, NR, NRP1, NR, NCC, D( NRF ),$ E( NRF ), VT( NRF, 1 ), LDU, U( NRF, 1 ), LDU,$ U( NRF, 1 ), LDU, WORK( NWORK1 ), INFO )CALL DCOPY( NRP1, VT( NRF, 1 ), 1, WORK( VFI ), 1 )CALL DCOPY( NRP1, VT( NRF, NRP1 ), 1, WORK( VLI ), 1 )END IFIF( INFO.NE.0 ) THENRETURNEND IFDO 20 J = 1, NRIWORK( IDXQI+J ) = J20 CONTINUE30 CONTINUE** Now conquer each subproblem bottom-up.*J = 2**NLVLDO 50 LVL = NLVL, 1, -1LVL2 = LVL*2 - 1** Find the first node LF and last node LL on* the current level LVL.*IF( LVL.EQ.1 ) THENLF = 1LL = 1ELSELF = 2**( LVL-1 )LL = 2*LF - 1END IFDO 40 I = LF, LLIM1 = I - 1IC = IWORK( INODE+IM1 )NL = IWORK( NDIML+IM1 )NR = IWORK( NDIMR+IM1 )NLF = IC - NLNRF = IC + 1IF( I.EQ.LL ) THENSQREI = SQREELSESQREI = 1END IFVFI = VF + NLF - 1VLI = VL + NLF - 1IDXQI = IDXQ + NLF - 1ALPHA = D( IC )BETA = E( IC )IF( ICOMPQ.EQ.0 ) THENCALL DLASD6( ICOMPQ, NL, NR, SQREI, D( NLF ),$ WORK( VFI ), WORK( VLI ), ALPHA, BETA,$ IWORK( IDXQI ), PERM, GIVPTR( 1 ), GIVCOL,$ LDGCOL, GIVNUM, LDU, POLES, DIFL, DIFR, Z,$ K( 1 ), C( 1 ), S( 1 ), WORK( NWORK1 ),$ IWORK( IWK ), INFO )ELSEJ = J - 1CALL DLASD6( ICOMPQ, NL, NR, SQREI, D( NLF ),$ WORK( VFI ), WORK( VLI ), ALPHA, BETA,$ IWORK( IDXQI ), PERM( NLF, LVL ),$ GIVPTR( J ), GIVCOL( NLF, LVL2 ), LDGCOL,$ GIVNUM( NLF, LVL2 ), LDU,$ POLES( NLF, LVL2 ), DIFL( NLF, LVL ),$ DIFR( NLF, LVL2 ), Z( NLF, LVL ), K( J ),$ C( J ), S( J ), WORK( NWORK1 ),$ IWORK( IWK ), INFO )END IFIF( INFO.NE.0 ) THENRETURNEND IF40 CONTINUE50 CONTINUE*RETURN** End of DLASDA*END*> \brief \b DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASDQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasdq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasdq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasdq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,* U, LDU, C, LDC, WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE* ..* .. Array Arguments ..* DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),* $ VT( LDVT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASDQ computes the singular value decomposition (SVD) of a real*> (upper or lower) bidiagonal matrix with diagonal D and offdiagonal*> E, accumulating the transformations if desired. Letting B denote*> the input bidiagonal matrix, the algorithm computes orthogonal*> matrices Q and P such that B = Q * S * P**T (P**T denotes the transpose*> of P). The singular values S are overwritten on D.*>*> The input matrix U is changed to U * Q if desired.*> The input matrix VT is changed to P**T * VT if desired.*> The input matrix C is changed to Q**T * C if desired.*>*> See "Computing Small Singular Values of Bidiagonal Matrices With*> Guaranteed High Relative Accuracy," by J. Demmel and W. Kahan,*> LAPACK Working Note #3, for a detailed description of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> On entry, UPLO specifies whether the input bidiagonal matrix*> is upper or lower bidiagonal, and whether it is square are*> not.*> UPLO = 'U' or 'u' B is upper bidiagonal.*> UPLO = 'L' or 'l' B is lower bidiagonal.*> \endverbatim*>*> \param[in] SQRE*> \verbatim*> SQRE is INTEGER*> = 0: then the input matrix is N-by-N.*> = 1: then the input matrix is N-by-(N+1) if UPLU = 'U' and*> (N+1)-by-N if UPLU = 'L'.*>*> The bidiagonal matrix has*> N = NL + NR + 1 rows and*> M = N + SQRE >= N columns.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> On entry, N specifies the number of rows and columns*> in the matrix. N must be at least 0.*> \endverbatim*>*> \param[in] NCVT*> \verbatim*> NCVT is INTEGER*> On entry, NCVT specifies the number of columns of*> the matrix VT. NCVT must be at least 0.*> \endverbatim*>*> \param[in] NRU*> \verbatim*> NRU is INTEGER*> On entry, NRU specifies the number of rows of*> the matrix U. NRU must be at least 0.*> \endverbatim*>*> \param[in] NCC*> \verbatim*> NCC is INTEGER*> On entry, NCC specifies the number of columns of*> the matrix C. NCC must be at least 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, D contains the diagonal entries of the*> bidiagonal matrix whose SVD is desired. On normal exit,*> D contains the singular values in ascending order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array.*> dimension is (N-1) if SQRE = 0 and N if SQRE = 1.*> On entry, the entries of E contain the offdiagonal entries*> of the bidiagonal matrix whose SVD is desired. On normal*> exit, E will contain 0. If the algorithm does not converge,*> D and E will contain the diagonal and superdiagonal entries*> of a bidiagonal matrix orthogonally equivalent to the one*> given as input.*> \endverbatim*>*> \param[in,out] VT*> \verbatim*> VT is DOUBLE PRECISION array, dimension (LDVT, NCVT)*> On entry, contains a matrix which on exit has been*> premultiplied by P**T, dimension N-by-NCVT if SQRE = 0*> and (N+1)-by-NCVT if SQRE = 1 (not referenced if NCVT=0).*> \endverbatim*>*> \param[in] LDVT*> \verbatim*> LDVT is INTEGER*> On entry, LDVT specifies the leading dimension of VT as*> declared in the calling (sub) program. LDVT must be at*> least 1. If NCVT is nonzero LDVT must also be at least N.*> \endverbatim*>*> \param[in,out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU, N)*> On entry, contains a matrix which on exit has been*> postmultiplied by Q, dimension NRU-by-N if SQRE = 0*> and NRU-by-(N+1) if SQRE = 1 (not referenced if NRU=0).*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> On entry, LDU specifies the leading dimension of U as*> declared in the calling (sub) program. LDU must be at*> least max( 1, NRU ) .*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC, NCC)*> On entry, contains an N-by-NCC matrix which on exit*> has been premultiplied by Q**T dimension N-by-NCC if SQRE = 0*> and (N+1)-by-NCC if SQRE = 1 (not referenced if NCC=0).*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> On entry, LDC specifies the leading dimension of C as*> declared in the calling (sub) program. LDC must be at*> least 1. If NCC is nonzero, LDC must also be at least N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> Workspace. Only referenced if one of NCVT, NRU, or NCC is*> nonzero, and if N is at least 2.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> On exit, a value of 0 indicates a successful exit.*> If INFO < 0, argument number -INFO is illegal.*> If INFO > 0, the algorithm did not converge, and INFO*> specifies how many superdiagonals did not converge.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASDQ( UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT,$ U, LDU, C, LDC, WORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU, SQRE* ..* .. Array Arguments ..DOUBLE PRECISION C( LDC, * ), D( * ), E( * ), U( LDU, * ),$ VT( LDVT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL ROTATEINTEGER I, ISUB, IUPLO, J, NP1, SQRE1DOUBLE PRECISION CS, R, SMIN, SN* ..* .. External Subroutines ..EXTERNAL DBDSQR, DLARTG, DLASR, DSWAP, XERBLA* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IUPLO = 0IF( LSAME( UPLO, 'U' ) )$ IUPLO = 1IF( LSAME( UPLO, 'L' ) )$ IUPLO = 2IF( IUPLO.EQ.0 ) THENINFO = -1ELSE IF( ( SQRE.LT.0 ) .OR. ( SQRE.GT.1 ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NCVT.LT.0 ) THENINFO = -4ELSE IF( NRU.LT.0 ) THENINFO = -5ELSE IF( NCC.LT.0 ) THENINFO = -6ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.$ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THENINFO = -10ELSE IF( LDU.LT.MAX( 1, NRU ) ) THENINFO = -12ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.$ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THENINFO = -14END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASDQ', -INFO )RETURNEND IFIF( N.EQ.0 )$ RETURN** ROTATE is true if any singular vectors desired, false otherwise*ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )NP1 = N + 1SQRE1 = SQRE** If matrix non-square upper bidiagonal, rotate to be lower* bidiagonal. The rotations are on the right.*IF( ( IUPLO.EQ.1 ) .AND. ( SQRE1.EQ.1 ) ) THENDO 10 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )IF( ROTATE ) THENWORK( I ) = CSWORK( N+I ) = SNEND IF10 CONTINUECALL DLARTG( D( N ), E( N ), CS, SN, R )D( N ) = RE( N ) = ZEROIF( ROTATE ) THENWORK( N ) = CSWORK( N+N ) = SNEND IFIUPLO = 2SQRE1 = 0** Update singular vectors if desired.*IF( NCVT.GT.0 )$ CALL DLASR( 'L', 'V', 'F', NP1, NCVT, WORK( 1 ),$ WORK( NP1 ), VT, LDVT )END IF** If matrix lower bidiagonal, rotate to be upper bidiagonal* by applying Givens rotations on the left.*IF( IUPLO.EQ.2 ) THENDO 20 I = 1, N - 1CALL DLARTG( D( I ), E( I ), CS, SN, R )D( I ) = RE( I ) = SN*D( I+1 )D( I+1 ) = CS*D( I+1 )IF( ROTATE ) THENWORK( I ) = CSWORK( N+I ) = SNEND IF20 CONTINUE** If matrix (N+1)-by-N lower bidiagonal, one additional* rotation is needed.*IF( SQRE1.EQ.1 ) THENCALL DLARTG( D( N ), E( N ), CS, SN, R )D( N ) = RIF( ROTATE ) THENWORK( N ) = CSWORK( N+N ) = SNEND IFEND IF** Update singular vectors if desired.*IF( NRU.GT.0 ) THENIF( SQRE1.EQ.0 ) THENCALL DLASR( 'R', 'V', 'F', NRU, N, WORK( 1 ),$ WORK( NP1 ), U, LDU )ELSECALL DLASR( 'R', 'V', 'F', NRU, NP1, WORK( 1 ),$ WORK( NP1 ), U, LDU )END IFEND IFIF( NCC.GT.0 ) THENIF( SQRE1.EQ.0 ) THENCALL DLASR( 'L', 'V', 'F', N, NCC, WORK( 1 ),$ WORK( NP1 ), C, LDC )ELSECALL DLASR( 'L', 'V', 'F', NP1, NCC, WORK( 1 ),$ WORK( NP1 ), C, LDC )END IFEND IFEND IF** Call DBDSQR to compute the SVD of the reduced real* N-by-N upper bidiagonal matrix.*CALL DBDSQR( 'U', N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C,$ LDC, WORK, INFO )** Sort the singular values into ascending order (insertion sort on* singular values, but only one transposition per singular vector)*DO 40 I = 1, N** Scan for smallest D(I).*ISUB = ISMIN = D( I )DO 30 J = I + 1, NIF( D( J ).LT.SMIN ) THENISUB = JSMIN = D( J )END IF30 CONTINUEIF( ISUB.NE.I ) THEN** Swap singular values and vectors.*D( ISUB ) = D( I )D( I ) = SMINIF( NCVT.GT.0 )$ CALL DSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( I, 1 ), LDVT )IF( NRU.GT.0 )$ CALL DSWAP( NRU, U( 1, ISUB ), 1, U( 1, I ), 1 )IF( NCC.GT.0 )$ CALL DSWAP( NCC, C( ISUB, 1 ), LDC, C( I, 1 ), LDC )END IF40 CONTINUE*RETURN** End of DLASDQ*END*> \brief \b DLASDT creates a tree of subproblems for bidiagonal divide and conquer. Used by sbdsdc.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASDT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasdt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasdt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasdt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASDT( N, LVL, ND, INODE, NDIML, NDIMR, MSUB )** .. Scalar Arguments ..* INTEGER LVL, MSUB, N, ND* ..* .. Array Arguments ..* INTEGER INODE( * ), NDIML( * ), NDIMR( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASDT creates a tree of subproblems for bidiagonal divide and*> conquer.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> On entry, the number of diagonal elements of the*> bidiagonal matrix.*> \endverbatim*>*> \param[out] LVL*> \verbatim*> LVL is INTEGER*> On exit, the number of levels on the computation tree.*> \endverbatim*>*> \param[out] ND*> \verbatim*> ND is INTEGER*> On exit, the number of nodes on the tree.*> \endverbatim*>*> \param[out] INODE*> \verbatim*> INODE is INTEGER array, dimension ( N )*> On exit, centers of subproblems.*> \endverbatim*>*> \param[out] NDIML*> \verbatim*> NDIML is INTEGER array, dimension ( N )*> On exit, row dimensions of left children.*> \endverbatim*>*> \param[out] NDIMR*> \verbatim*> NDIMR is INTEGER array, dimension ( N )*> On exit, row dimensions of right children.*> \endverbatim*>*> \param[in] MSUB*> \verbatim*> MSUB is INTEGER*> On entry, the maximum row dimension each subproblem at the*> bottom of the tree can be of.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Contributors:* ==================*>*> Ming Gu and Huan Ren, Computer Science Division, University of*> California at Berkeley, USA*>* =====================================================================SUBROUTINE DLASDT( N, LVL, ND, INODE, NDIML, NDIMR, MSUB )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER LVL, MSUB, N, ND* ..* .. Array Arguments ..INTEGER INODE( * ), NDIML( * ), NDIMR( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )* ..* .. Local Scalars ..INTEGER I, IL, IR, LLST, MAXN, NCRNT, NLVLDOUBLE PRECISION TEMP* ..* .. Intrinsic Functions ..INTRINSIC DBLE, INT, LOG, MAX* ..* .. Executable Statements ..** Find the number of levels on the tree.*MAXN = MAX( 1, N )TEMP = LOG( DBLE( MAXN ) / DBLE( MSUB+1 ) ) / LOG( TWO )LVL = INT( TEMP ) + 1*I = N / 2INODE( 1 ) = I + 1NDIML( 1 ) = INDIMR( 1 ) = N - I - 1IL = 0IR = 1LLST = 1DO 20 NLVL = 1, LVL - 1** Constructing the tree at (NLVL+1)-st level. The number of* nodes created on this level is LLST * 2.*DO 10 I = 0, LLST - 1IL = IL + 2IR = IR + 2NCRNT = LLST + INDIML( IL ) = NDIML( NCRNT ) / 2NDIMR( IL ) = NDIML( NCRNT ) - NDIML( IL ) - 1INODE( IL ) = INODE( NCRNT ) - NDIMR( IL ) - 1NDIML( IR ) = NDIMR( NCRNT ) / 2NDIMR( IR ) = NDIMR( NCRNT ) - NDIML( IR ) - 1INODE( IR ) = INODE( NCRNT ) + NDIML( IR ) + 110 CONTINUELLST = LLST*220 CONTINUEND = LLST*2 - 1*RETURN** End of DLASDT*END*> \brief \b DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASET + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaset.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaset.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaset.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER LDA, M, N* DOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASET initializes an m-by-n matrix A to BETA on the diagonal and*> ALPHA on the offdiagonals.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies the part of the matrix A to be set.*> = 'U': Upper triangular part is set; the strictly lower*> triangular part of A is not changed.*> = 'L': Lower triangular part is set; the strictly upper*> triangular part of A is not changed.*> Otherwise: All of the matrix A is set.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> The constant to which the offdiagonal elements are to be set.*> \endverbatim*>*> \param[in] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> The constant to which the diagonal elements are to be set.*> \endverbatim*>*> \param[out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On exit, the leading m-by-n submatrix of A is set as follows:*>*> if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n,*> if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n,*> otherwise, A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j,*>*> and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER LDA, M, NDOUBLE PRECISION ALPHA, BETA* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( LSAME( UPLO, 'U' ) ) THEN** Set the strictly upper triangular or trapezoidal part of the* array to ALPHA.*DO 20 J = 2, NDO 10 I = 1, MIN( J-1, M )A( I, J ) = ALPHA10 CONTINUE20 CONTINUE*ELSE IF( LSAME( UPLO, 'L' ) ) THEN** Set the strictly lower triangular or trapezoidal part of the* array to ALPHA.*DO 40 J = 1, MIN( M, N )DO 30 I = J + 1, MA( I, J ) = ALPHA30 CONTINUE40 CONTINUE*ELSE** Set the leading m-by-n submatrix to ALPHA.*DO 60 J = 1, NDO 50 I = 1, MA( I, J ) = ALPHA50 CONTINUE60 CONTINUEEND IF** Set the first min(M,N) diagonal elements to BETA.*DO 70 I = 1, MIN( M, N )A( I, I ) = BETA70 CONTINUE*RETURN** End of DLASET*END*> \brief \b DLASQ1 computes the singular values of a real square bidiagonal matrix. Used by sbdsqr.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASQ1 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq1.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq1.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq1.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASQ1( N, D, E, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASQ1 computes the singular values of a real N-by-N bidiagonal*> matrix with diagonal D and off-diagonal E. The singular values*> are computed to high relative accuracy, in the absence of*> denormalization, underflow and overflow. The algorithm was first*> presented in*>*> "Accurate singular values and differential qd algorithms" by K. V.*> Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230,*> 1994,*>*> and the present implementation is described in "An implementation of*> the dqds Algorithm (Positive Case)", LAPACK Working Note.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows and columns in the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, D contains the diagonal elements of the*> bidiagonal matrix whose SVD is desired. On normal exit,*> D contains the singular values in decreasing order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> On entry, elements E(1:N-1) contain the off-diagonal elements*> of the bidiagonal matrix whose SVD is desired.*> On exit, E is overwritten.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: the algorithm failed*> = 1, a split was marked by a positive value in E*> = 2, current block of Z not diagonalized after 100*N*> iterations (in inner while loop) On exit D and E*> represent a matrix with the same singular values*> which the calling subroutine could use to finish the*> computation, or even feed back into DLASQ1*> = 3, termination criterion of outer while loop not met*> (program created more than N unreduced blocks)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLASQ1( N, D, E, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER I, IINFODOUBLE PRECISION EPS, SCALE, SAFMIN, SIGMN, SIGMX* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAS2, DLASCL, DLASQ2, DLASRT, XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*INFO = 0IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DLASQ1', -INFO )RETURNELSE IF( N.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THEND( 1 ) = ABS( D( 1 ) )RETURNELSE IF( N.EQ.2 ) THENCALL DLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX )D( 1 ) = SIGMXD( 2 ) = SIGMNRETURNEND IF** Estimate the largest singular value.*SIGMX = ZERODO 10 I = 1, N - 1D( I ) = ABS( D( I ) )SIGMX = MAX( SIGMX, ABS( E( I ) ) )10 CONTINUED( N ) = ABS( D( N ) )** Early return if SIGMX is zero (matrix is already diagonal).*IF( SIGMX.EQ.ZERO ) THENCALL DLASRT( 'D', N, D, IINFO )RETURNEND IF*DO 20 I = 1, NSIGMX = MAX( SIGMX, D( I ) )20 CONTINUE** Copy D and E into WORK (in the Z format) and scale (squaring the* input data makes scaling by a power of the radix pointless).*EPS = DLAMCH( 'Precision' )SAFMIN = DLAMCH( 'Safe minimum' )SCALE = SQRT( EPS / SAFMIN )CALL DCOPY( N, D, 1, WORK( 1 ), 2 )CALL DCOPY( N-1, E, 1, WORK( 2 ), 2 )CALL DLASCL( 'G', 0, 0, SIGMX, SCALE, 2*N-1, 1, WORK, 2*N-1,$ IINFO )** Compute the q's and e's.*DO 30 I = 1, 2*N - 1WORK( I ) = WORK( I )**230 CONTINUEWORK( 2*N ) = ZERO*CALL DLASQ2( N, WORK, INFO )*IF( INFO.EQ.0 ) THENDO 40 I = 1, ND( I ) = SQRT( WORK( I ) )40 CONTINUECALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO )ELSE IF( INFO.EQ.2 ) THEN** Maximum number of iterations exceeded. Move data from WORK* into D and E so the calling subroutine can try to finish*DO I = 1, ND( I ) = SQRT( WORK( 2*I-1 ) )E( I ) = SQRT( WORK( 2*I ) )END DOCALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO )CALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, E, N, IINFO )END IF*RETURN** End of DLASQ1*END*> \brief \b DLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated with the qd Array Z to high relative accuracy. Used by sbdsqr and sstegr.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASQ2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASQ2( N, Z, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASQ2 computes all the eigenvalues of the symmetric positive*> definite tridiagonal matrix associated with the qd array Z to high*> relative accuracy are computed to high relative accuracy, in the*> absence of denormalization, underflow and overflow.*>*> To see the relation of Z to the tridiagonal matrix, let L be a*> unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and*> let U be an upper bidiagonal matrix with 1's above and diagonal*> Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the*> symmetric tridiagonal to which it is similar.*>*> Note : DLASQ2 defines a logical variable, IEEE, which is true*> on machines which follow ieee-754 floating-point standard in their*> handling of infinities and NaNs, and false otherwise. This variable*> is passed to DLASQ3.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of rows and columns in the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( 4*N )*> On entry Z holds the qd array. On exit, entries 1 to N hold*> the eigenvalues in decreasing order, Z( 2*N+1 ) holds the*> trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If*> N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 )*> holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of*> shifts that failed.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if the i-th argument is a scalar and had an illegal*> value, then INFO = -i, if the i-th argument is an*> array and the j-entry had an illegal value, then*> INFO = -(i*100+j)*> > 0: the algorithm failed*> = 1, a split was marked by a positive value in E*> = 2, current block of Z not diagonalized after 100*N*> iterations (in inner while loop). On exit Z holds*> a qd array with the same eigenvalues as the given Z.*> = 3, termination criterion of outer while loop not met*> (program created more than N unreduced blocks)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> Local Variables: I0:N0 defines a current unreduced segment of Z.*> The shifts are accumulated in SIGMA. Iteration count is in ITER.*> Ping-pong is controlled by PP (alternates between 0 and 1).*> \endverbatim*>* =====================================================================SUBROUTINE DLASQ2( N, Z, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION CBIASPARAMETER ( CBIAS = 1.50D0 )DOUBLE PRECISION ZERO, HALF, ONE, TWO, FOUR, HUNDRDPARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0,$ TWO = 2.0D0, FOUR = 4.0D0, HUNDRD = 100.0D0 )* ..* .. Local Scalars ..LOGICAL IEEEINTEGER I0, I1, I4, IINFO, IPN4, ITER, IWHILA, IWHILB,$ K, KMIN, N0, N1, NBIG, NDIV, NFAIL, PP, SPLT,$ TTYPEDOUBLE PRECISION D, DEE, DEEMIN, DESIG, DMIN, DMIN1, DMIN2, DN,$ DN1, DN2, E, EMAX, EMIN, EPS, G, OLDEMN, QMAX,$ QMIN, S, SAFMIN, SIGMA, T, TAU, TEMP, TOL,$ TOL2, TRACE, ZMAX, TEMPE, TEMPQ* ..* .. External Subroutines ..EXTERNAL DLASQ3, DLASRT, XERBLA* ..* .. External Functions ..INTEGER ILAENVDOUBLE PRECISION DLAMCHEXTERNAL DLAMCH, ILAENV* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input arguments.* (in case DLASQ2 is not called by DLASQ1)*INFO = 0EPS = DLAMCH( 'Precision' )SAFMIN = DLAMCH( 'Safe minimum' )TOL = EPS*HUNDRDTOL2 = TOL**2*IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DLASQ2', 1 )RETURNELSE IF( N.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THEN** 1-by-1 case.*IF( Z( 1 ).LT.ZERO ) THENINFO = -201CALL XERBLA( 'DLASQ2', 2 )END IFRETURNELSE IF( N.EQ.2 ) THEN** 2-by-2 case.*IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THENINFO = -2CALL XERBLA( 'DLASQ2', 2 )RETURNELSE IF( Z( 3 ).GT.Z( 1 ) ) THEND = Z( 3 )Z( 3 ) = Z( 1 )Z( 1 ) = DEND IFZ( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 )IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THENT = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) )S = Z( 3 )*( Z( 2 ) / T )IF( S.LE.T ) THENS = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) )ELSES = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) )END IFT = Z( 1 ) + ( S+Z( 2 ) )Z( 3 ) = Z( 3 )*( Z( 1 ) / T )Z( 1 ) = TEND IFZ( 2 ) = Z( 3 )Z( 6 ) = Z( 2 ) + Z( 1 )RETURNEND IF** Check for negative data and compute sums of q's and e's.*Z( 2*N ) = ZEROEMIN = Z( 2 )QMAX = ZEROZMAX = ZEROD = ZEROE = ZERO*DO 10 K = 1, 2*( N-1 ), 2IF( Z( K ).LT.ZERO ) THENINFO = -( 200+K )CALL XERBLA( 'DLASQ2', 2 )RETURNELSE IF( Z( K+1 ).LT.ZERO ) THENINFO = -( 200+K+1 )CALL XERBLA( 'DLASQ2', 2 )RETURNEND IFD = D + Z( K )E = E + Z( K+1 )QMAX = MAX( QMAX, Z( K ) )EMIN = MIN( EMIN, Z( K+1 ) )ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) )10 CONTINUEIF( Z( 2*N-1 ).LT.ZERO ) THENINFO = -( 200+2*N-1 )CALL XERBLA( 'DLASQ2', 2 )RETURNEND IFD = D + Z( 2*N-1 )QMAX = MAX( QMAX, Z( 2*N-1 ) )ZMAX = MAX( QMAX, ZMAX )** Check for diagonality.*IF( E.EQ.ZERO ) THENDO 20 K = 2, NZ( K ) = Z( 2*K-1 )20 CONTINUECALL DLASRT( 'D', N, Z, IINFO )Z( 2*N-1 ) = DRETURNEND IF*TRACE = D + E** Check for zero data.*IF( TRACE.EQ.ZERO ) THENZ( 2*N-1 ) = ZERORETURNEND IF** Check whether the machine is IEEE conformable.*IEEE = ILAENV( 10, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND.$ ILAENV( 11, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1** Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...).*DO 30 K = 2*N, 2, -2Z( 2*K ) = ZEROZ( 2*K-1 ) = Z( K )Z( 2*K-2 ) = ZEROZ( 2*K-3 ) = Z( K-1 )30 CONTINUE*I0 = 1N0 = N** Reverse the qd-array, if warranted.*IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THENIPN4 = 4*( I0+N0 )DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4TEMP = Z( I4-3 )Z( I4-3 ) = Z( IPN4-I4-3 )Z( IPN4-I4-3 ) = TEMPTEMP = Z( I4-1 )Z( I4-1 ) = Z( IPN4-I4-5 )Z( IPN4-I4-5 ) = TEMP40 CONTINUEEND IF** Initial split checking via dqd and Li's test.*PP = 0*DO 80 K = 1, 2*D = Z( 4*N0+PP-3 )DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4IF( Z( I4-1 ).LE.TOL2*D ) THENZ( I4-1 ) = -ZEROD = Z( I4-3 )ELSED = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) )END IF50 CONTINUE** dqd maps Z to ZZ plus Li's test.*EMIN = Z( 4*I0+PP+1 )D = Z( 4*I0+PP-3 )DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4Z( I4-2*PP-2 ) = D + Z( I4-1 )IF( Z( I4-1 ).LE.TOL2*D ) THENZ( I4-1 ) = -ZEROZ( I4-2*PP-2 ) = DZ( I4-2*PP ) = ZEROD = Z( I4+1 )ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND.$ SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THENTEMP = Z( I4+1 ) / Z( I4-2*PP-2 )Z( I4-2*PP ) = Z( I4-1 )*TEMPD = D*TEMPELSEZ( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) )D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) )END IFEMIN = MIN( EMIN, Z( I4-2*PP ) )60 CONTINUEZ( 4*N0-PP-2 ) = D** Now find qmax.*QMAX = Z( 4*I0-PP-2 )DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4QMAX = MAX( QMAX, Z( I4 ) )70 CONTINUE** Prepare for the next iteration on K.*PP = 1 - PP80 CONTINUE** Initialise variables to pass to DLASQ3.*TTYPE = 0DMIN1 = ZERODMIN2 = ZERODN = ZERODN1 = ZERODN2 = ZEROG = ZEROTAU = ZERO*ITER = 2NFAIL = 0NDIV = 2*( N0-I0 )*DO 160 IWHILA = 1, N + 1IF( N0.LT.1 )$ GO TO 170** While array unfinished do** E(N0) holds the value of SIGMA when submatrix in I0:N0* splits from the rest of the array, but is negated.*DESIG = ZEROIF( N0.EQ.N ) THENSIGMA = ZEROELSESIGMA = -Z( 4*N0-1 )END IFIF( SIGMA.LT.ZERO ) THENINFO = 1RETURNEND IF** Find last unreduced submatrix's top index I0, find QMAX and* EMIN. Find Gershgorin-type bound if Q's much greater than E's.*EMAX = ZEROIF( N0.GT.I0 ) THENEMIN = ABS( Z( 4*N0-5 ) )ELSEEMIN = ZEROEND IFQMIN = Z( 4*N0-3 )QMAX = QMINDO 90 I4 = 4*N0, 8, -4IF( Z( I4-5 ).LE.ZERO )$ GO TO 100IF( QMIN.GE.FOUR*EMAX ) THENQMIN = MIN( QMIN, Z( I4-3 ) )EMAX = MAX( EMAX, Z( I4-5 ) )END IFQMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) )EMIN = MIN( EMIN, Z( I4-5 ) )90 CONTINUEI4 = 4*100 CONTINUEI0 = I4 / 4PP = 0*IF( N0-I0.GT.1 ) THENDEE = Z( 4*I0-3 )DEEMIN = DEEKMIN = I0DO 110 I4 = 4*I0+1, 4*N0-3, 4DEE = Z( I4 )*( DEE /( DEE+Z( I4-2 ) ) )IF( DEE.LE.DEEMIN ) THENDEEMIN = DEEKMIN = ( I4+3 )/4END IF110 CONTINUEIF( (KMIN-I0)*2.LT.N0-KMIN .AND.$ DEEMIN.LE.HALF*Z(4*N0-3) ) THENIPN4 = 4*( I0+N0 )PP = 2DO 120 I4 = 4*I0, 2*( I0+N0-1 ), 4TEMP = Z( I4-3 )Z( I4-3 ) = Z( IPN4-I4-3 )Z( IPN4-I4-3 ) = TEMPTEMP = Z( I4-2 )Z( I4-2 ) = Z( IPN4-I4-2 )Z( IPN4-I4-2 ) = TEMPTEMP = Z( I4-1 )Z( I4-1 ) = Z( IPN4-I4-5 )Z( IPN4-I4-5 ) = TEMPTEMP = Z( I4 )Z( I4 ) = Z( IPN4-I4-4 )Z( IPN4-I4-4 ) = TEMP120 CONTINUEEND IFEND IF** Put -(initial shift) into DMIN.*DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) )** Now I0:N0 is unreduced.* PP = 0 for ping, PP = 1 for pong.* PP = 2 indicates that flipping was applied to the Z array and* and that the tests for deflation upon entry in DLASQ3* should not be performed.*NBIG = 100*( N0-I0+1 )DO 140 IWHILB = 1, NBIGIF( I0.GT.N0 )$ GO TO 150** While submatrix unfinished take a good dqds step.*CALL DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,$ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,$ DN2, G, TAU )*PP = 1 - PP** When EMIN is very small check for splits.*IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THENIF( Z( 4*N0 ).LE.TOL2*QMAX .OR.$ Z( 4*N0-1 ).LE.TOL2*SIGMA ) THENSPLT = I0 - 1QMAX = Z( 4*I0-3 )EMIN = Z( 4*I0-1 )OLDEMN = Z( 4*I0 )DO 130 I4 = 4*I0, 4*( N0-3 ), 4IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR.$ Z( I4-1 ).LE.TOL2*SIGMA ) THENZ( I4-1 ) = -SIGMASPLT = I4 / 4QMAX = ZEROEMIN = Z( I4+3 )OLDEMN = Z( I4+4 )ELSEQMAX = MAX( QMAX, Z( I4+1 ) )EMIN = MIN( EMIN, Z( I4-1 ) )OLDEMN = MIN( OLDEMN, Z( I4 ) )END IF130 CONTINUEZ( 4*N0-1 ) = EMINZ( 4*N0 ) = OLDEMNI0 = SPLT + 1END IFEND IF*140 CONTINUE*INFO = 2** Maximum number of iterations exceeded, restore the shift* SIGMA and place the new d's and e's in a qd array.* This might need to be done for several blocks*I1 = I0N1 = N0145 CONTINUETEMPQ = Z( 4*I0-3 )Z( 4*I0-3 ) = Z( 4*I0-3 ) + SIGMADO K = I0+1, N0TEMPE = Z( 4*K-5 )Z( 4*K-5 ) = Z( 4*K-5 ) * (TEMPQ / Z( 4*K-7 ))TEMPQ = Z( 4*K-3 )Z( 4*K-3 ) = Z( 4*K-3 ) + SIGMA + TEMPE - Z( 4*K-5 )END DO** Prepare to do this on the previous block if there is one*IF( I1.GT.1 ) THENN1 = I1-1DO WHILE( ( I1.GE.2 ) .AND. ( Z(4*I1-5).GE.ZERO ) )I1 = I1 - 1END DOSIGMA = -Z(4*N1-1)GO TO 145END IFDO K = 1, NZ( 2*K-1 ) = Z( 4*K-3 )** Only the block 1..N0 is unfinished. The rest of the e's* must be essentially zero, although sometimes other data* has been stored in them.*IF( K.LT.N0 ) THENZ( 2*K ) = Z( 4*K-1 )ELSEZ( 2*K ) = 0END IFEND DORETURN** end IWHILB*150 CONTINUE*160 CONTINUE*INFO = 3RETURN** end IWHILA*170 CONTINUE** Move q's to the front.*DO 180 K = 2, NZ( K ) = Z( 4*K-3 )180 CONTINUE** Sort and compute sum of eigenvalues.*CALL DLASRT( 'D', N, Z, IINFO )*E = ZERODO 190 K = N, 1, -1E = E + Z( K )190 CONTINUE** Store trace, sum(eigenvalues) and information on performance.*Z( 2*N+1 ) = TRACEZ( 2*N+2 ) = EZ( 2*N+3 ) = DBLE( ITER )Z( 2*N+4 ) = DBLE( NDIV ) / DBLE( N**2 )Z( 2*N+5 ) = HUNDRD*NFAIL / DBLE( ITER )RETURN** End of DLASQ2*END*> \brief \b DLASQ3 checks for deflation, computes a shift and calls dqds. Used by sbdsqr.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASQ3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,* ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,* DN2, G, TAU )** .. Scalar Arguments ..* LOGICAL IEEE* INTEGER I0, ITER, N0, NDIV, NFAIL, PP* DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,* $ QMAX, SIGMA, TAU* ..* .. Array Arguments ..* DOUBLE PRECISION Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds.*> In case of failure it changes shifts, and tries again until output*> is positive.*> \endverbatim** Arguments:* ==========**> \param[in] I0*> \verbatim*> I0 is INTEGER*> First index.*> \endverbatim*>*> \param[in,out] N0*> \verbatim*> N0 is INTEGER*> Last index.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( 4*N0 )*> Z holds the qd array.*> \endverbatim*>*> \param[in,out] PP*> \verbatim*> PP is INTEGER*> PP=0 for ping, PP=1 for pong.*> PP=2 indicates that flipping was applied to the Z array*> and that the initial tests for deflation should not be*> performed.*> \endverbatim*>*> \param[out] DMIN*> \verbatim*> DMIN is DOUBLE PRECISION*> Minimum value of d.*> \endverbatim*>*> \param[out] SIGMA*> \verbatim*> SIGMA is DOUBLE PRECISION*> Sum of shifts used in current segment.*> \endverbatim*>*> \param[in,out] DESIG*> \verbatim*> DESIG is DOUBLE PRECISION*> Lower order part of SIGMA*> \endverbatim*>*> \param[in] QMAX*> \verbatim*> QMAX is DOUBLE PRECISION*> Maximum value of q.*> \endverbatim*>*> \param[in,out] NFAIL*> \verbatim*> NFAIL is INTEGER*> Increment NFAIL by 1 each time the shift was too big.*> \endverbatim*>*> \param[in,out] ITER*> \verbatim*> ITER is INTEGER*> Increment ITER by 1 for each iteration.*> \endverbatim*>*> \param[in,out] NDIV*> \verbatim*> NDIV is INTEGER*> Increment NDIV by 1 for each division.*> \endverbatim*>*> \param[in] IEEE*> \verbatim*> IEEE is LOGICAL*> Flag for IEEE or non IEEE arithmetic (passed to DLASQ5).*> \endverbatim*>*> \param[in,out] TTYPE*> \verbatim*> TTYPE is INTEGER*> Shift type.*> \endverbatim*>*> \param[in,out] DMIN1*> \verbatim*> DMIN1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] DMIN2*> \verbatim*> DMIN2 is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] DN*> \verbatim*> DN is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] DN1*> \verbatim*> DN1 is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] DN2*> \verbatim*> DN2 is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] G*> \verbatim*> G is DOUBLE PRECISION*> \endverbatim*>*> \param[in,out] TAU*> \verbatim*> TAU is DOUBLE PRECISION*>*> These are passed as arguments in order to save their values*> between calls to DLASQ3.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL,$ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1,$ DN2, G, TAU )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..LOGICAL IEEEINTEGER I0, ITER, N0, NDIV, NFAIL, PPDOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G,$ QMAX, SIGMA, TAU* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION CBIASPARAMETER ( CBIAS = 1.50D0 )DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, HUNDRDPARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0,$ ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 )* ..* .. Local Scalars ..INTEGER IPN4, J4, N0IN, NN, TTYPEDOUBLE PRECISION EPS, S, T, TEMP, TOL, TOL2* ..* .. External Subroutines ..EXTERNAL DLASQ4, DLASQ5, DLASQ6* ..* .. External Function ..DOUBLE PRECISION DLAMCHLOGICAL DISNANEXTERNAL DISNAN, DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*N0IN = N0EPS = DLAMCH( 'Precision' )TOL = EPS*HUNDRDTOL2 = TOL**2** Check for deflation.*10 CONTINUE*IF( N0.LT.I0 )$ RETURNIF( N0.EQ.I0 )$ GO TO 20NN = 4*N0 + PPIF( N0.EQ.( I0+1 ) )$ GO TO 40** Check whether E(N0-1) is negligible, 1 eigenvalue.*IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND.$ Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) )$ GO TO 30*20 CONTINUE*Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMAN0 = N0 - 1GO TO 10** Check whether E(N0-2) is negligible, 2 eigenvalues.*30 CONTINUE*IF( Z( NN-9 ).GT.TOL2*SIGMA .AND.$ Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) )$ GO TO 50*40 CONTINUE*IF( Z( NN-3 ).GT.Z( NN-7 ) ) THENS = Z( NN-3 )Z( NN-3 ) = Z( NN-7 )Z( NN-7 ) = SEND IFT = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) )IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2.AND.T.NE.ZERO ) THENS = Z( NN-3 )*( Z( NN-5 ) / T )IF( S.LE.T ) THENS = Z( NN-3 )*( Z( NN-5 ) /$ ( T*( ONE+SQRT( ONE+S / T ) ) ) )ELSES = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) )END IFT = Z( NN-7 ) + ( S+Z( NN-5 ) )Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T )Z( NN-7 ) = TEND IFZ( 4*N0-7 ) = Z( NN-7 ) + SIGMAZ( 4*N0-3 ) = Z( NN-3 ) + SIGMAN0 = N0 - 2GO TO 10*50 CONTINUEIF( PP.EQ.2 )$ PP = 0** Reverse the qd-array, if warranted.*IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THENIF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THENIPN4 = 4*( I0+N0 )DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4TEMP = Z( J4-3 )Z( J4-3 ) = Z( IPN4-J4-3 )Z( IPN4-J4-3 ) = TEMPTEMP = Z( J4-2 )Z( J4-2 ) = Z( IPN4-J4-2 )Z( IPN4-J4-2 ) = TEMPTEMP = Z( J4-1 )Z( J4-1 ) = Z( IPN4-J4-5 )Z( IPN4-J4-5 ) = TEMPTEMP = Z( J4 )Z( J4 ) = Z( IPN4-J4-4 )Z( IPN4-J4-4 ) = TEMP60 CONTINUEIF( N0-I0.LE.4 ) THENZ( 4*N0+PP-1 ) = Z( 4*I0+PP-1 )Z( 4*N0-PP ) = Z( 4*I0-PP )END IFDMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) )Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ),$ Z( 4*I0+PP+3 ) )Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ),$ Z( 4*I0-PP+4 ) )QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) )DMIN = -ZEROEND IFEND IF** Choose a shift.*CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1,$ DN2, TAU, TTYPE, G )** Call dqds until DMIN > 0.*70 CONTINUE*CALL DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, DN,$ DN1, DN2, IEEE, EPS )*NDIV = NDIV + ( N0-I0+2 )ITER = ITER + 1** Check status.*IF( DMIN.GE.ZERO .AND. DMIN1.GE.ZERO ) THEN** Success.*GO TO 90*ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND.$ Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND.$ ABS( DN ).LT.TOL*SIGMA ) THEN** Convergence hidden by negative DN.*Z( 4*( N0-1 )-PP+2 ) = ZERODMIN = ZEROGO TO 90ELSE IF( DMIN.LT.ZERO ) THEN** TAU too big. Select new TAU and try again.*NFAIL = NFAIL + 1IF( TTYPE.LT.-22 ) THEN** Failed twice. Play it safe.*TAU = ZEROELSE IF( DMIN1.GT.ZERO ) THEN** Late failure. Gives excellent shift.*TAU = ( TAU+DMIN )*( ONE-TWO*EPS )TTYPE = TTYPE - 11ELSE** Early failure. Divide by 4.*TAU = QURTR*TAUTTYPE = TTYPE - 12END IFGO TO 70ELSE IF( DISNAN( DMIN ) ) THEN** NaN.*IF( TAU.EQ.ZERO ) THENGO TO 80ELSETAU = ZEROGO TO 70END IFELSE** Possible underflow. Play it safe.*GO TO 80END IF** Risk of underflow.*80 CONTINUECALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 )NDIV = NDIV + ( N0-I0+2 )ITER = ITER + 1TAU = ZERO*90 CONTINUEIF( TAU.LT.SIGMA ) THENDESIG = DESIG + TAUT = SIGMA + DESIGDESIG = DESIG - ( T-SIGMA )ELSET = SIGMA + TAUDESIG = SIGMA - ( T-TAU ) + DESIGEND IFSIGMA = T*RETURN** End of DLASQ3*END*> \brief \b DLASQ4 computes an approximation to the smallest eigenvalue using values of d from the previous transform. Used by sbdsqr.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASQ4 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq4.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq4.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq4.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,* DN1, DN2, TAU, TTYPE, G )** .. Scalar Arguments ..* INTEGER I0, N0, N0IN, PP, TTYPE* DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU* ..* .. Array Arguments ..* DOUBLE PRECISION Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASQ4 computes an approximation TAU to the smallest eigenvalue*> using values of d from the previous transform.*> \endverbatim** Arguments:* ==========**> \param[in] I0*> \verbatim*> I0 is INTEGER*> First index.*> \endverbatim*>*> \param[in] N0*> \verbatim*> N0 is INTEGER*> Last index.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( 4*N0 )*> Z holds the qd array.*> \endverbatim*>*> \param[in] PP*> \verbatim*> PP is INTEGER*> PP=0 for ping, PP=1 for pong.*> \endverbatim*>*> \param[in] N0IN*> \verbatim*> N0IN is INTEGER*> The value of N0 at start of EIGTEST.*> \endverbatim*>*> \param[in] DMIN*> \verbatim*> DMIN is DOUBLE PRECISION*> Minimum value of d.*> \endverbatim*>*> \param[in] DMIN1*> \verbatim*> DMIN1 is DOUBLE PRECISION*> Minimum value of d, excluding D( N0 ).*> \endverbatim*>*> \param[in] DMIN2*> \verbatim*> DMIN2 is DOUBLE PRECISION*> Minimum value of d, excluding D( N0 ) and D( N0-1 ).*> \endverbatim*>*> \param[in] DN*> \verbatim*> DN is DOUBLE PRECISION*> d(N)*> \endverbatim*>*> \param[in] DN1*> \verbatim*> DN1 is DOUBLE PRECISION*> d(N-1)*> \endverbatim*>*> \param[in] DN2*> \verbatim*> DN2 is DOUBLE PRECISION*> d(N-2)*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> This is the shift.*> \endverbatim*>*> \param[out] TTYPE*> \verbatim*> TTYPE is INTEGER*> Shift type.*> \endverbatim*>*> \param[in,out] G*> \verbatim*> G is DOUBLE PRECISION*> G is passed as an argument in order to save its value between*> calls to DLASQ4.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> CNST1 = 9/16*> \endverbatim*>* =====================================================================SUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN,$ DN1, DN2, TAU, TTYPE, G )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER I0, N0, N0IN, PP, TTYPEDOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION CNST1, CNST2, CNST3PARAMETER ( CNST1 = 0.5630D0, CNST2 = 1.010D0,$ CNST3 = 1.050D0 )DOUBLE PRECISION QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRDPARAMETER ( QURTR = 0.250D0, THIRD = 0.3330D0,$ HALF = 0.50D0, ZERO = 0.0D0, ONE = 1.0D0,$ TWO = 2.0D0, HUNDRD = 100.0D0 )* ..* .. Local Scalars ..INTEGER I4, NN, NPDOUBLE PRECISION A2, B1, B2, GAM, GAP1, GAP2, S* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** A negative DMIN forces the shift to take that absolute value* TTYPE records the type of shift.*IF( DMIN.LE.ZERO ) THENTAU = -DMINTTYPE = -1RETURNEND IF*NN = 4*N0 + PPIF( N0IN.EQ.N0 ) THEN** No eigenvalues deflated.*IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN*B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) )B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) )A2 = Z( NN-7 ) + Z( NN-5 )** Cases 2 and 3.*IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THENGAP2 = DMIN2 - A2 - DMIN2*QURTRIF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THENGAP1 = A2 - DN - ( B2 / GAP2 )*B2ELSEGAP1 = A2 - DN - ( B1+B2 )END IFIF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THENS = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN )TTYPE = -2ELSES = ZEROIF( DN.GT.B1 )$ S = DN - B1IF( A2.GT.( B1+B2 ) )$ S = MIN( S, A2-( B1+B2 ) )S = MAX( S, THIRD*DMIN )TTYPE = -3END IFELSE** Case 4.*TTYPE = -4S = QURTR*DMINIF( DMIN.EQ.DN ) THENGAM = DNA2 = ZEROIF( Z( NN-5 ) .GT. Z( NN-7 ) )$ RETURNB2 = Z( NN-5 ) / Z( NN-7 )NP = NN - 9ELSENP = NN - 2*PPGAM = DN1IF( Z( NP-4 ) .GT. Z( NP-2 ) )$ RETURNA2 = Z( NP-4 ) / Z( NP-2 )IF( Z( NN-9 ) .GT. Z( NN-11 ) )$ RETURNB2 = Z( NN-9 ) / Z( NN-11 )NP = NN - 13END IF** Approximate contribution to norm squared from I < NN-1.*A2 = A2 + B2DO 10 I4 = NP, 4*I0 - 1 + PP, -4IF( B2.EQ.ZERO )$ GO TO 20B1 = B2IF( Z( I4 ) .GT. Z( I4-2 ) )$ RETURNB2 = B2*( Z( I4 ) / Z( I4-2 ) )A2 = A2 + B2IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 )$ GO TO 2010 CONTINUE20 CONTINUEA2 = CNST3*A2** Rayleigh quotient residual bound.*IF( A2.LT.CNST1 )$ S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )END IFELSE IF( DMIN.EQ.DN2 ) THEN** Case 5.*TTYPE = -5S = QURTR*DMIN** Compute contribution to norm squared from I > NN-2.*NP = NN - 2*PPB1 = Z( NP-2 )B2 = Z( NP-6 )GAM = DN2IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 )$ RETURNA2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 )** Approximate contribution to norm squared from I < NN-2.*IF( N0-I0.GT.2 ) THENB2 = Z( NN-13 ) / Z( NN-15 )A2 = A2 + B2DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4IF( B2.EQ.ZERO )$ GO TO 40B1 = B2IF( Z( I4 ) .GT. Z( I4-2 ) )$ RETURNB2 = B2*( Z( I4 ) / Z( I4-2 ) )A2 = A2 + B2IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 )$ GO TO 4030 CONTINUE40 CONTINUEA2 = CNST3*A2END IF*IF( A2.LT.CNST1 )$ S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 )ELSE** Case 6, no information to guide us.*IF( TTYPE.EQ.-6 ) THENG = G + THIRD*( ONE-G )ELSE IF( TTYPE.EQ.-18 ) THENG = QURTR*THIRDELSEG = QURTREND IFS = G*DMINTTYPE = -6END IF*ELSE IF( N0IN.EQ.( N0+1 ) ) THEN** One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN.*IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN** Cases 7 and 8.*TTYPE = -7S = THIRD*DMIN1IF( Z( NN-5 ).GT.Z( NN-7 ) )$ RETURNB1 = Z( NN-5 ) / Z( NN-7 )B2 = B1IF( B2.EQ.ZERO )$ GO TO 60DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4A2 = B1IF( Z( I4 ).GT.Z( I4-2 ) )$ RETURNB1 = B1*( Z( I4 ) / Z( I4-2 ) )B2 = B2 + B1IF( HUNDRD*MAX( B1, A2 ).LT.B2 )$ GO TO 6050 CONTINUE60 CONTINUEB2 = SQRT( CNST3*B2 )A2 = DMIN1 / ( ONE+B2**2 )GAP2 = HALF*DMIN2 - A2IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THENS = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )ELSES = MAX( S, A2*( ONE-CNST2*B2 ) )TTYPE = -8END IFELSE** Case 9.*S = QURTR*DMIN1IF( DMIN1.EQ.DN1 )$ S = HALF*DMIN1TTYPE = -9END IF*ELSE IF( N0IN.EQ.( N0+2 ) ) THEN** Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN.** Cases 10 and 11.*IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THENTTYPE = -10S = THIRD*DMIN2IF( Z( NN-5 ).GT.Z( NN-7 ) )$ RETURNB1 = Z( NN-5 ) / Z( NN-7 )B2 = B1IF( B2.EQ.ZERO )$ GO TO 80DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4IF( Z( I4 ).GT.Z( I4-2 ) )$ RETURNB1 = B1*( Z( I4 ) / Z( I4-2 ) )B2 = B2 + B1IF( HUNDRD*B1.LT.B2 )$ GO TO 8070 CONTINUE80 CONTINUEB2 = SQRT( CNST3*B2 )A2 = DMIN2 / ( ONE+B2**2 )GAP2 = Z( NN-7 ) + Z( NN-9 ) -$ SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THENS = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) )ELSES = MAX( S, A2*( ONE-CNST2*B2 ) )END IFELSES = QURTR*DMIN2TTYPE = -11END IFELSE IF( N0IN.GT.( N0+2 ) ) THEN** Case 12, more than two eigenvalues deflated. No information.*S = ZEROTTYPE = -12END IF*TAU = SRETURN** End of DLASQ4*END*> \brief \b DLASQ5 computes one dqds transform in ping-pong form. Used by sbdsqr and sstegr.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASQ5 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq5.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq5.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq5.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, DN,* DNM1, DNM2, IEEE, EPS )** .. Scalar Arguments ..* LOGICAL IEEE* INTEGER I0, N0, PP* DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU, SIGMA, EPS* ..* .. Array Arguments ..* DOUBLE PRECISION Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASQ5 computes one dqds transform in ping-pong form, one*> version for IEEE machines another for non IEEE machines.*> \endverbatim** Arguments:* ==========**> \param[in] I0*> \verbatim*> I0 is INTEGER*> First index.*> \endverbatim*>*> \param[in] N0*> \verbatim*> N0 is INTEGER*> Last index.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( 4*N )*> Z holds the qd array. EMIN is stored in Z(4*N0) to avoid*> an extra argument.*> \endverbatim*>*> \param[in] PP*> \verbatim*> PP is INTEGER*> PP=0 for ping, PP=1 for pong.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> This is the shift.*> \endverbatim*>*> \param[in] SIGMA*> \verbatim*> SIGMA is DOUBLE PRECISION*> This is the accumulated shift up to this step.*> \endverbatim*>*> \param[out] DMIN*> \verbatim*> DMIN is DOUBLE PRECISION*> Minimum value of d.*> \endverbatim*>*> \param[out] DMIN1*> \verbatim*> DMIN1 is DOUBLE PRECISION*> Minimum value of d, excluding D( N0 ).*> \endverbatim*>*> \param[out] DMIN2*> \verbatim*> DMIN2 is DOUBLE PRECISION*> Minimum value of d, excluding D( N0 ) and D( N0-1 ).*> \endverbatim*>*> \param[out] DN*> \verbatim*> DN is DOUBLE PRECISION*> d(N0), the last value of d.*> \endverbatim*>*> \param[out] DNM1*> \verbatim*> DNM1 is DOUBLE PRECISION*> d(N0-1).*> \endverbatim*>*> \param[out] DNM2*> \verbatim*> DNM2 is DOUBLE PRECISION*> d(N0-2).*> \endverbatim*>*> \param[in] IEEE*> \verbatim*> IEEE is LOGICAL*> Flag for IEEE or non IEEE arithmetic.*> \endverbatim*>*> \param[in] EPS*> \verbatim*> EPS is DOUBLE PRECISION*> This is the value of epsilon used.*> \endverbatim*>* Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2,$ DN, DNM1, DNM2, IEEE, EPS )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..LOGICAL IEEEINTEGER I0, N0, PPDOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU,$ SIGMA, EPS* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** =====================================================================** .. Parameter ..DOUBLE PRECISION ZERO, HALFPARAMETER ( ZERO = 0.0D0, HALF = 0.5 )* ..* .. Local Scalars ..INTEGER J4, J4P2DOUBLE PRECISION D, EMIN, TEMP, DTHRESH* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( ( N0-I0-1 ).LE.0 )$ RETURN*DTHRESH = EPS*(SIGMA+TAU)IF( TAU.LT.DTHRESH*HALF ) TAU = ZEROIF( TAU.NE.ZERO ) THENJ4 = 4*I0 + PP - 3EMIN = Z( J4+4 )D = Z( J4 ) - TAUDMIN = DDMIN1 = -Z( J4 )*IF( IEEE ) THEN** Code for IEEE arithmetic.*IF( PP.EQ.0 ) THENDO 10 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-2 ) = D + Z( J4-1 )TEMP = Z( J4+1 ) / Z( J4-2 )D = D*TEMP - TAUDMIN = MIN( DMIN, D )Z( J4 ) = Z( J4-1 )*TEMPEMIN = MIN( Z( J4 ), EMIN )10 CONTINUEELSEDO 20 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-3 ) = D + Z( J4 )TEMP = Z( J4+2 ) / Z( J4-3 )D = D*TEMP - TAUDMIN = MIN( DMIN, D )Z( J4-1 ) = Z( J4 )*TEMPEMIN = MIN( Z( J4-1 ), EMIN )20 CONTINUEEND IF** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAUDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAUDMIN = MIN( DMIN, DN )*ELSE** Code for non IEEE arithmetic.*IF( PP.EQ.0 ) THENDO 30 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-2 ) = D + Z( J4-1 )IF( D.LT.ZERO ) THENRETURNELSEZ( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )D = Z( J4+1 )*( D / Z( J4-2 ) ) - TAUEND IFDMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4 ) )30 CONTINUEELSEDO 40 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-3 ) = D + Z( J4 )IF( D.LT.ZERO ) THENRETURNELSEZ( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )D = Z( J4+2 )*( D / Z( J4-3 ) ) - TAUEND IFDMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4-1 ) )40 CONTINUEEND IF** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )IF( DNM2.LT.ZERO ) THENRETURNELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAUEND IFDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )IF( DNM1.LT.ZERO ) THENRETURNELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAUEND IFDMIN = MIN( DMIN, DN )*END IFELSE* This is the version that sets d's to zero if they are small enoughJ4 = 4*I0 + PP - 3EMIN = Z( J4+4 )D = Z( J4 ) - TAUDMIN = DDMIN1 = -Z( J4 )IF( IEEE ) THEN** Code for IEEE arithmetic.*IF( PP.EQ.0 ) THENDO 50 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-2 ) = D + Z( J4-1 )TEMP = Z( J4+1 ) / Z( J4-2 )D = D*TEMP - TAUIF( D.LT.DTHRESH ) D = ZERODMIN = MIN( DMIN, D )Z( J4 ) = Z( J4-1 )*TEMPEMIN = MIN( Z( J4 ), EMIN )50 CONTINUEELSEDO 60 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-3 ) = D + Z( J4 )TEMP = Z( J4+2 ) / Z( J4-3 )D = D*TEMP - TAUIF( D.LT.DTHRESH ) D = ZERODMIN = MIN( DMIN, D )Z( J4-1 ) = Z( J4 )*TEMPEMIN = MIN( Z( J4-1 ), EMIN )60 CONTINUEEND IF** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAUDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAUDMIN = MIN( DMIN, DN )*ELSE** Code for non IEEE arithmetic.*IF( PP.EQ.0 ) THENDO 70 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-2 ) = D + Z( J4-1 )IF( D.LT.ZERO ) THENRETURNELSEZ( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )D = Z( J4+1 )*( D / Z( J4-2 ) ) - TAUEND IFIF( D.LT.DTHRESH) D = ZERODMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4 ) )70 CONTINUEELSEDO 80 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-3 ) = D + Z( J4 )IF( D.LT.ZERO ) THENRETURNELSEZ( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )D = Z( J4+2 )*( D / Z( J4-3 ) ) - TAUEND IFIF( D.LT.DTHRESH) D = ZERODMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4-1 ) )80 CONTINUEEND IF** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )IF( DNM2.LT.ZERO ) THENRETURNELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAUEND IFDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )IF( DNM1.LT.ZERO ) THENRETURNELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAUEND IFDMIN = MIN( DMIN, DN )*END IFEND IF*Z( J4+2 ) = DNZ( 4*N0-PP ) = EMINRETURN** End of DLASQ5*END*> \brief \b DLASQ6 computes one dqd transform in ping-pong form. Used by sbdsqr and sstegr.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASQ6 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasq6.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasq6.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasq6.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN,* DNM1, DNM2 )** .. Scalar Arguments ..* INTEGER I0, N0, PP* DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2* ..* .. Array Arguments ..* DOUBLE PRECISION Z( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASQ6 computes one dqd (shift equal to zero) transform in*> ping-pong form, with protection against underflow and overflow.*> \endverbatim** Arguments:* ==========**> \param[in] I0*> \verbatim*> I0 is INTEGER*> First index.*> \endverbatim*>*> \param[in] N0*> \verbatim*> N0 is INTEGER*> Last index.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension ( 4*N )*> Z holds the qd array. EMIN is stored in Z(4*N0) to avoid*> an extra argument.*> \endverbatim*>*> \param[in] PP*> \verbatim*> PP is INTEGER*> PP=0 for ping, PP=1 for pong.*> \endverbatim*>*> \param[out] DMIN*> \verbatim*> DMIN is DOUBLE PRECISION*> Minimum value of d.*> \endverbatim*>*> \param[out] DMIN1*> \verbatim*> DMIN1 is DOUBLE PRECISION*> Minimum value of d, excluding D( N0 ).*> \endverbatim*>*> \param[out] DMIN2*> \verbatim*> DMIN2 is DOUBLE PRECISION*> Minimum value of d, excluding D( N0 ) and D( N0-1 ).*> \endverbatim*>*> \param[out] DN*> \verbatim*> DN is DOUBLE PRECISION*> d(N0), the last value of d.*> \endverbatim*>*> \param[out] DNM1*> \verbatim*> DNM1 is DOUBLE PRECISION*> d(N0-1).*> \endverbatim*>*> \param[out] DNM2*> \verbatim*> DNM2 is DOUBLE PRECISION*> d(N0-2).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN,$ DNM1, DNM2 )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER I0, N0, PPDOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2* ..* .. Array Arguments ..DOUBLE PRECISION Z( * )* ..** =====================================================================** .. Parameter ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )* ..* .. Local Scalars ..INTEGER J4, J4P2DOUBLE PRECISION D, EMIN, SAFMIN, TEMP* ..* .. External Function ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( ( N0-I0-1 ).LE.0 )$ RETURN*SAFMIN = DLAMCH( 'Safe minimum' )J4 = 4*I0 + PP - 3EMIN = Z( J4+4 )D = Z( J4 )DMIN = D*IF( PP.EQ.0 ) THENDO 10 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-2 ) = D + Z( J4-1 )IF( Z( J4-2 ).EQ.ZERO ) THENZ( J4 ) = ZEROD = Z( J4+1 )DMIN = DEMIN = ZEROELSE IF( SAFMIN*Z( J4+1 ).LT.Z( J4-2 ) .AND.$ SAFMIN*Z( J4-2 ).LT.Z( J4+1 ) ) THENTEMP = Z( J4+1 ) / Z( J4-2 )Z( J4 ) = Z( J4-1 )*TEMPD = D*TEMPELSEZ( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) )D = Z( J4+1 )*( D / Z( J4-2 ) )END IFDMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4 ) )10 CONTINUEELSEDO 20 J4 = 4*I0, 4*( N0-3 ), 4Z( J4-3 ) = D + Z( J4 )IF( Z( J4-3 ).EQ.ZERO ) THENZ( J4-1 ) = ZEROD = Z( J4+2 )DMIN = DEMIN = ZEROELSE IF( SAFMIN*Z( J4+2 ).LT.Z( J4-3 ) .AND.$ SAFMIN*Z( J4-3 ).LT.Z( J4+2 ) ) THENTEMP = Z( J4+2 ) / Z( J4-3 )Z( J4-1 ) = Z( J4 )*TEMPD = D*TEMPELSEZ( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) )D = Z( J4+2 )*( D / Z( J4-3 ) )END IFDMIN = MIN( DMIN, D )EMIN = MIN( EMIN, Z( J4-1 ) )20 CONTINUEEND IF** Unroll last two steps.*DNM2 = DDMIN2 = DMINJ4 = 4*( N0-2 ) - PPJ4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM2 + Z( J4P2 )IF( Z( J4-2 ).EQ.ZERO ) THENZ( J4 ) = ZERODNM1 = Z( J4P2+2 )DMIN = DNM1EMIN = ZEROELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND.$ SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THENTEMP = Z( J4P2+2 ) / Z( J4-2 )Z( J4 ) = Z( J4P2 )*TEMPDNM1 = DNM2*TEMPELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) )END IFDMIN = MIN( DMIN, DNM1 )*DMIN1 = DMINJ4 = J4 + 4J4P2 = J4 + 2*PP - 1Z( J4-2 ) = DNM1 + Z( J4P2 )IF( Z( J4-2 ).EQ.ZERO ) THENZ( J4 ) = ZERODN = Z( J4P2+2 )DMIN = DNEMIN = ZEROELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND.$ SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THENTEMP = Z( J4P2+2 ) / Z( J4-2 )Z( J4 ) = Z( J4P2 )*TEMPDN = DNM1*TEMPELSEZ( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) )DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) )END IFDMIN = MIN( DMIN, DN )*Z( J4+2 ) = DNZ( 4*N0-PP ) = EMINRETURN** End of DLASQ6*END*> \brief \b DLASR applies a sequence of plane rotations to a general rectangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )** .. Scalar Arguments ..* CHARACTER DIRECT, PIVOT, SIDE* INTEGER LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASR applies a sequence of plane rotations to a real matrix A,*> from either the left or the right.*>*> When SIDE = 'L', the transformation takes the form*>*> A := P*A*>*> and when SIDE = 'R', the transformation takes the form*>*> A := A*P**T*>*> where P is an orthogonal matrix consisting of a sequence of z plane*> rotations, with z = M when SIDE = 'L' and z = N when SIDE = 'R',*> and P**T is the transpose of P.*>*> When DIRECT = 'F' (Forward sequence), then*>*> P = P(z-1) * ... * P(2) * P(1)*>*> and when DIRECT = 'B' (Backward sequence), then*>*> P = P(1) * P(2) * ... * P(z-1)*>*> where P(k) is a plane rotation matrix defined by the 2-by-2 rotation*>*> R(k) = ( c(k) s(k) )*> = ( -s(k) c(k) ).*>*> When PIVOT = 'V' (Variable pivot), the rotation is performed*> for the plane (k,k+1), i.e., P(k) has the form*>*> P(k) = ( 1 )*> ( ... )*> ( 1 )*> ( c(k) s(k) )*> ( -s(k) c(k) )*> ( 1 )*> ( ... )*> ( 1 )*>*> where R(k) appears as a rank-2 modification to the identity matrix in*> rows and columns k and k+1.*>*> When PIVOT = 'T' (Top pivot), the rotation is performed for the*> plane (1,k+1), so P(k) has the form*>*> P(k) = ( c(k) s(k) )*> ( 1 )*> ( ... )*> ( 1 )*> ( -s(k) c(k) )*> ( 1 )*> ( ... )*> ( 1 )*>*> where R(k) appears in rows and columns 1 and k+1.*>*> Similarly, when PIVOT = 'B' (Bottom pivot), the rotation is*> performed for the plane (k,z), giving P(k) the form*>*> P(k) = ( 1 )*> ( ... )*> ( 1 )*> ( c(k) s(k) )*> ( 1 )*> ( ... )*> ( 1 )*> ( -s(k) c(k) )*>*> where R(k) appears in rows and columns k and z. The rotations are*> performed without ever forming P(k) explicitly.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> Specifies whether the plane rotation matrix P is applied to*> A on the left or the right.*> = 'L': Left, compute A := P*A*> = 'R': Right, compute A:= A*P**T*> \endverbatim*>*> \param[in] PIVOT*> \verbatim*> PIVOT is CHARACTER*1*> Specifies the plane for which P(k) is a plane rotation*> matrix.*> = 'V': Variable pivot, the plane (k,k+1)*> = 'T': Top pivot, the plane (1,k+1)*> = 'B': Bottom pivot, the plane (k,z)*> \endverbatim*>*> \param[in] DIRECT*> \verbatim*> DIRECT is CHARACTER*1*> Specifies whether P is a forward or backward sequence of*> plane rotations.*> = 'F': Forward, P = P(z-1)*...*P(2)*P(1)*> = 'B': Backward, P = P(1)*P(2)*...*P(z-1)*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. If m <= 1, an immediate*> return is effected.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. If n <= 1, an*> immediate return is effected.*> \endverbatim*>*> \param[in] C*> \verbatim*> C is DOUBLE PRECISION array, dimension*> (M-1) if SIDE = 'L'*> (N-1) if SIDE = 'R'*> The cosines c(k) of the plane rotations.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension*> (M-1) if SIDE = 'L'*> (N-1) if SIDE = 'R'*> The sines s(k) of the plane rotations. The 2-by-2 plane*> rotation part of the matrix P(k), R(k), has the form*> R(k) = ( c(k) s(k) )*> ( -s(k) c(k) ).*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The M-by-N matrix A. On exit, A is overwritten by P*A if*> SIDE = 'R' or by A*P**T if SIDE = 'L'.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLASR( SIDE, PIVOT, DIRECT, M, N, C, S, A, LDA )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIRECT, PIVOT, SIDEINTEGER LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, INFO, JDOUBLE PRECISION CTEMP, STEMP, TEMP* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters*INFO = 0IF( .NOT.( LSAME( SIDE, 'L' ) .OR. LSAME( SIDE, 'R' ) ) ) THENINFO = 1ELSE IF( .NOT.( LSAME( PIVOT, 'V' ) .OR. LSAME( PIVOT,$ 'T' ) .OR. LSAME( PIVOT, 'B' ) ) ) THENINFO = 2ELSE IF( .NOT.( LSAME( DIRECT, 'F' ) .OR. LSAME( DIRECT, 'B' ) ) )$ THENINFO = 3ELSE IF( M.LT.0 ) THENINFO = 4ELSE IF( N.LT.0 ) THENINFO = 5ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = 9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASR ', INFO )RETURNEND IF** Quick return if possible*IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )$ RETURNIF( LSAME( SIDE, 'L' ) ) THEN** Form P * A*IF( LSAME( PIVOT, 'V' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 20 J = 1, M - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 10 I = 1, NTEMP = A( J+1, I )A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )10 CONTINUEEND IF20 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 40 J = M - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 30 I = 1, NTEMP = A( J+1, I )A( J+1, I ) = CTEMP*TEMP - STEMP*A( J, I )A( J, I ) = STEMP*TEMP + CTEMP*A( J, I )30 CONTINUEEND IF40 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'T' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 60 J = 2, MCTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 50 I = 1, NTEMP = A( J, I )A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )50 CONTINUEEND IF60 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 80 J = M, 2, -1CTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 70 I = 1, NTEMP = A( J, I )A( J, I ) = CTEMP*TEMP - STEMP*A( 1, I )A( 1, I ) = STEMP*TEMP + CTEMP*A( 1, I )70 CONTINUEEND IF80 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'B' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 100 J = 1, M - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 90 I = 1, NTEMP = A( J, I )A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMPA( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP90 CONTINUEEND IF100 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 120 J = M - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 110 I = 1, NTEMP = A( J, I )A( J, I ) = STEMP*A( M, I ) + CTEMP*TEMPA( M, I ) = CTEMP*A( M, I ) - STEMP*TEMP110 CONTINUEEND IF120 CONTINUEEND IFEND IFELSE IF( LSAME( SIDE, 'R' ) ) THEN** Form A * P**T*IF( LSAME( PIVOT, 'V' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 140 J = 1, N - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 130 I = 1, MTEMP = A( I, J+1 )A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )130 CONTINUEEND IF140 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 160 J = N - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 150 I = 1, MTEMP = A( I, J+1 )A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )150 CONTINUEEND IF160 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'T' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 180 J = 2, NCTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 170 I = 1, MTEMP = A( I, J )A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )170 CONTINUEEND IF180 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 200 J = N, 2, -1CTEMP = C( J-1 )STEMP = S( J-1 )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 190 I = 1, MTEMP = A( I, J )A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )190 CONTINUEEND IF200 CONTINUEEND IFELSE IF( LSAME( PIVOT, 'B' ) ) THENIF( LSAME( DIRECT, 'F' ) ) THENDO 220 J = 1, N - 1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 210 I = 1, MTEMP = A( I, J )A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMPA( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP210 CONTINUEEND IF220 CONTINUEELSE IF( LSAME( DIRECT, 'B' ) ) THENDO 240 J = N - 1, 1, -1CTEMP = C( J )STEMP = S( J )IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THENDO 230 I = 1, MTEMP = A( I, J )A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMPA( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP230 CONTINUEEND IF240 CONTINUEEND IFEND IFEND IF*RETURN** End of DLASR*END*> \brief \b DLASRT sorts numbers in increasing or decreasing order.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASRT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasrt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasrt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasrt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASRT( ID, N, D, INFO )** .. Scalar Arguments ..* CHARACTER ID* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Sort the numbers in D in increasing order (if ID = 'I') or*> in decreasing order (if ID = 'D' ).*>*> Use Quick Sort, reverting to Insertion sort on arrays of*> size <= 20. Dimension of STACK limits N to about 2**32.*> \endverbatim** Arguments:* ==========**> \param[in] ID*> \verbatim*> ID is CHARACTER*1*> = 'I': sort D in increasing order;*> = 'D': sort D in decreasing order.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The length of the array D.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the array to be sorted.*> On exit, D has been sorted into increasing order*> (D(1) <= ... <= D(N) ) or into decreasing order*> (D(1) >= ... >= D(N) ), depending on ID.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DLASRT( ID, N, D, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER IDINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * )* ..** =====================================================================** .. Parameters ..INTEGER SELECTPARAMETER ( SELECT = 20 )* ..* .. Local Scalars ..INTEGER DIR, ENDD, I, J, START, STKPNTDOUBLE PRECISION D1, D2, D3, DMNMX, TMP* ..* .. Local Arrays ..INTEGER STACK( 2, 32 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0DIR = -1IF( LSAME( ID, 'D' ) ) THENDIR = 0ELSE IF( LSAME( ID, 'I' ) ) THENDIR = 1END IFIF( DIR.EQ.-1 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLASRT', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.1 )$ RETURN*STKPNT = 1STACK( 1, 1 ) = 1STACK( 2, 1 ) = N10 CONTINUESTART = STACK( 1, STKPNT )ENDD = STACK( 2, STKPNT )STKPNT = STKPNT - 1IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN** Do Insertion sort on D( START:ENDD )*IF( DIR.EQ.0 ) THEN** Sort into decreasing order*DO 30 I = START + 1, ENDDDO 20 J = I, START + 1, -1IF( D( J ).GT.D( J-1 ) ) THENDMNMX = D( J )D( J ) = D( J-1 )D( J-1 ) = DMNMXELSEGO TO 30END IF20 CONTINUE30 CONTINUE*ELSE** Sort into increasing order*DO 50 I = START + 1, ENDDDO 40 J = I, START + 1, -1IF( D( J ).LT.D( J-1 ) ) THENDMNMX = D( J )D( J ) = D( J-1 )D( J-1 ) = DMNMXELSEGO TO 50END IF40 CONTINUE50 CONTINUE*END IF*ELSE IF( ENDD-START.GT.SELECT ) THEN** Partition D( START:ENDD ) and stack parts, largest one first** Choose partition entry as median of 3*D1 = D( START )D2 = D( ENDD )I = ( START+ENDD ) / 2D3 = D( I )IF( D1.LT.D2 ) THENIF( D3.LT.D1 ) THENDMNMX = D1ELSE IF( D3.LT.D2 ) THENDMNMX = D3ELSEDMNMX = D2END IFELSEIF( D3.LT.D2 ) THENDMNMX = D2ELSE IF( D3.LT.D1 ) THENDMNMX = D3ELSEDMNMX = D1END IFEND IF*IF( DIR.EQ.0 ) THEN** Sort into decreasing order*I = START - 1J = ENDD + 160 CONTINUE70 CONTINUEJ = J - 1IF( D( J ).LT.DMNMX )$ GO TO 7080 CONTINUEI = I + 1IF( D( I ).GT.DMNMX )$ GO TO 80IF( I.LT.J ) THENTMP = D( I )D( I ) = D( J )D( J ) = TMPGO TO 60END IFIF( J-START.GT.ENDD-J-1 ) THENSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDELSESTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JEND IFELSE** Sort into increasing order*I = START - 1J = ENDD + 190 CONTINUE100 CONTINUEJ = J - 1IF( D( J ).GT.DMNMX )$ GO TO 100110 CONTINUEI = I + 1IF( D( I ).LT.DMNMX )$ GO TO 110IF( I.LT.J ) THENTMP = D( I )D( I ) = D( J )D( J ) = TMPGO TO 90END IFIF( J-START.GT.ENDD-J-1 ) THENSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDELSESTKPNT = STKPNT + 1STACK( 1, STKPNT ) = J + 1STACK( 2, STKPNT ) = ENDDSTKPNT = STKPNT + 1STACK( 1, STKPNT ) = STARTSTACK( 2, STKPNT ) = JEND IFEND IFEND IFIF( STKPNT.GT.0 )$ GO TO 10RETURN** End of DLASRT*END*> \brief \b DLASSQ updates a sum of squares represented in scaled form.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASSQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlassq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlassq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlassq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASSQ( N, X, INCX, SCALE, SUMSQ )** .. Scalar Arguments ..* INTEGER INCX, N* DOUBLE PRECISION SCALE, SUMSQ* ..* .. Array Arguments ..* DOUBLE PRECISION X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASSQ returns the values scl and smsq such that*>*> ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq,*>*> where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is*> assumed to be non-negative and scl returns the value*>*> scl = max( scale, abs( x( i ) ) ).*>*> scale and sumsq must be supplied in SCALE and SUMSQ and*> scl and smsq are overwritten on SCALE and SUMSQ respectively.*>*> The routine makes only one pass through the vector x.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of elements to be used from the vector X.*> \endverbatim*>*> \param[in] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> The vector for which a scaled sum of squares is computed.*> x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between successive values of the vector X.*> INCX > 0.*> \endverbatim*>*> \param[in,out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> On entry, the value scale in the equation above.*> On exit, SCALE is overwritten with scl , the scaling factor*> for the sum of squares.*> \endverbatim*>*> \param[in,out] SUMSQ*> \verbatim*> SUMSQ is DOUBLE PRECISION*> On entry, the value sumsq in the equation above.*> On exit, SUMSQ is overwritten with smsq , the basic sum of*> squares from which scl has been factored out.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================SUBROUTINE DLASSQ( N, X, INCX, SCALE, SUMSQ )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INCX, NDOUBLE PRECISION SCALE, SUMSQ* ..* .. Array Arguments ..DOUBLE PRECISION X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER IXDOUBLE PRECISION ABSXI* ..* .. External Functions ..LOGICAL DISNANEXTERNAL DISNAN* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..*IF( N.GT.0 ) THENDO 10 IX = 1, 1 + ( N-1 )*INCX, INCXABSXI = ABS( X( IX ) )IF( ABSXI.GT.ZERO.OR.DISNAN( ABSXI ) ) THENIF( SCALE.LT.ABSXI ) THENSUMSQ = 1 + SUMSQ*( SCALE / ABSXI )**2SCALE = ABSXIELSESUMSQ = SUMSQ + ( ABSXI / SCALE )**2END IFEND IF10 CONTINUEEND IFRETURN** End of DLASSQ*END*> \brief \b DLASV2 computes the singular value decomposition of a 2-by-2 triangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASV2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasv2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasv2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasv2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL )** .. Scalar Arguments ..* DOUBLE PRECISION CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASV2 computes the singular value decomposition of a 2-by-2*> triangular matrix*> [ F G ]*> [ 0 H ].*> On return, abs(SSMAX) is the larger singular value, abs(SSMIN) is the*> smaller singular value, and (CSL,SNL) and (CSR,SNR) are the left and*> right singular vectors for abs(SSMAX), giving the decomposition*>*> [ CSL SNL ] [ F G ] [ CSR -SNR ] = [ SSMAX 0 ]*> [-SNL CSL ] [ 0 H ] [ SNR CSR ] [ 0 SSMIN ].*> \endverbatim** Arguments:* ==========**> \param[in] F*> \verbatim*> F is DOUBLE PRECISION*> The (1,1) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] G*> \verbatim*> G is DOUBLE PRECISION*> The (1,2) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[in] H*> \verbatim*> H is DOUBLE PRECISION*> The (2,2) element of the 2-by-2 matrix.*> \endverbatim*>*> \param[out] SSMIN*> \verbatim*> SSMIN is DOUBLE PRECISION*> abs(SSMIN) is the smaller singular value.*> \endverbatim*>*> \param[out] SSMAX*> \verbatim*> SSMAX is DOUBLE PRECISION*> abs(SSMAX) is the larger singular value.*> \endverbatim*>*> \param[out] SNL*> \verbatim*> SNL is DOUBLE PRECISION*> \endverbatim*>*> \param[out] CSL*> \verbatim*> CSL is DOUBLE PRECISION*> The vector (CSL, SNL) is a unit left singular vector for the*> singular value abs(SSMAX).*> \endverbatim*>*> \param[out] SNR*> \verbatim*> SNR is DOUBLE PRECISION*> \endverbatim*>*> \param[out] CSR*> \verbatim*> CSR is DOUBLE PRECISION*> The vector (CSR, SNR) is a unit right singular vector for the*> singular value abs(SSMAX).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Any input parameter may be aliased with any output parameter.*>*> Barring over/underflow and assuming a guard digit in subtraction, all*> output quantities are correct to within a few units in the last*> place (ulps).*>*> In IEEE arithmetic, the code works correctly if one matrix element is*> infinite.*>*> Overflow will not occur unless the largest singular value itself*> overflows or is within a few ulps of overflow. (On machines with*> partial overflow, like the Cray, overflow may occur if the largest*> singular value is within a factor of 2 of overflow.)*>*> Underflow is harmless if underflow is gradual. Otherwise, results*> may correspond to a matrix modified by perturbations of size near*> the underflow threshold.*> \endverbatim*>* =====================================================================SUBROUTINE DLASV2( F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION CSL, CSR, F, G, H, SNL, SNR, SSMAX, SSMIN* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D0 )DOUBLE PRECISION HALFPARAMETER ( HALF = 0.5D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D0 )DOUBLE PRECISION FOURPARAMETER ( FOUR = 4.0D0 )* ..* .. Local Scalars ..LOGICAL GASMAL, SWAPINTEGER PMAXDOUBLE PRECISION A, CLT, CRT, D, FA, FT, GA, GT, HA, HT, L, M,$ MM, R, S, SLT, SRT, T, TEMP, TSIGN, TT* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN, SQRT* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Executable Statements ..*FT = FFA = ABS( FT )HT = HHA = ABS( H )** PMAX points to the maximum absolute element of matrix* PMAX = 1 if F largest in absolute values* PMAX = 2 if G largest in absolute values* PMAX = 3 if H largest in absolute values*PMAX = 1SWAP = ( HA.GT.FA )IF( SWAP ) THENPMAX = 3TEMP = FTFT = HTHT = TEMPTEMP = FAFA = HAHA = TEMP** Now FA .ge. HA*END IFGT = GGA = ABS( GT )IF( GA.EQ.ZERO ) THEN** Diagonal matrix*SSMIN = HASSMAX = FACLT = ONECRT = ONESLT = ZEROSRT = ZEROELSEGASMAL = .TRUE.IF( GA.GT.FA ) THENPMAX = 2IF( ( FA / GA ).LT.DLAMCH( 'EPS' ) ) THEN** Case of very large GA*GASMAL = .FALSE.SSMAX = GAIF( HA.GT.ONE ) THENSSMIN = FA / ( GA / HA )ELSESSMIN = ( FA / GA )*HAEND IFCLT = ONESLT = HT / GTSRT = ONECRT = FT / GTEND IFEND IFIF( GASMAL ) THEN** Normal case*D = FA - HAIF( D.EQ.FA ) THEN** Copes with infinite F or H*L = ONEELSEL = D / FAEND IF** Note that 0 .le. L .le. 1*M = GT / FT** Note that abs(M) .le. 1/macheps*T = TWO - L** Note that T .ge. 1*MM = M*MTT = T*TS = SQRT( TT+MM )** Note that 1 .le. S .le. 1 + 1/macheps*IF( L.EQ.ZERO ) THENR = ABS( M )ELSER = SQRT( L*L+MM )END IF** Note that 0 .le. R .le. 1 + 1/macheps*A = HALF*( S+R )** Note that 1 .le. A .le. 1 + abs(M)*SSMIN = HA / ASSMAX = FA*AIF( MM.EQ.ZERO ) THEN** Note that M is very tiny*IF( L.EQ.ZERO ) THENT = SIGN( TWO, FT )*SIGN( ONE, GT )ELSET = GT / SIGN( D, FT ) + M / TEND IFELSET = ( M / ( S+T )+M / ( R+L ) )*( ONE+A )END IFL = SQRT( T*T+FOUR )CRT = TWO / LSRT = T / LCLT = ( CRT+SRT*M ) / ASLT = ( HT / FT )*SRT / AEND IFEND IFIF( SWAP ) THENCSL = SRTSNL = CRTCSR = SLTSNR = CLTELSECSL = CLTSNL = SLTCSR = CRTSNR = SRTEND IF** Correct signs of SSMAX and SSMIN*IF( PMAX.EQ.1 )$ TSIGN = SIGN( ONE, CSR )*SIGN( ONE, CSL )*SIGN( ONE, F )IF( PMAX.EQ.2 )$ TSIGN = SIGN( ONE, SNR )*SIGN( ONE, CSL )*SIGN( ONE, G )IF( PMAX.EQ.3 )$ TSIGN = SIGN( ONE, SNR )*SIGN( ONE, SNL )*SIGN( ONE, H )SSMAX = SIGN( SSMAX, TSIGN )SSMIN = SIGN( SSMIN, TSIGN*SIGN( ONE, F )*SIGN( ONE, H ) )RETURN** End of DLASV2*END*> \brief \b DLASWP performs a series of row interchanges on a general rectangular matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASWP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaswp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaswp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaswp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASWP( N, A, LDA, K1, K2, IPIV, INCX )** .. Scalar Arguments ..* INTEGER INCX, K1, K2, LDA, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASWP performs a series of row interchanges on the matrix A.*> One row interchange is initiated for each of rows K1 through K2 of A.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the matrix of column dimension N to which the row*> interchanges will be applied.*> On exit, the permuted matrix.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> \endverbatim*>*> \param[in] K1*> \verbatim*> K1 is INTEGER*> The first element of IPIV for which a row interchange will*> be done.*> \endverbatim*>*> \param[in] K2*> \verbatim*> K2 is INTEGER*> (K2-K1+1) is the number of elements of IPIV for which a row*> interchange will be done.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (K1+(K2-K1)*abs(INCX))*> The vector of pivot indices. Only the elements in positions*> K1 through K1+(K2-K1)*abs(INCX) of IPIV are accessed.*> IPIV(K1+(K-K1)*abs(INCX)) = L implies rows K and L are to be*> interchanged.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between successive values of IPIV. If INCX*> is negative, the pivots are applied in reverse order.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Modified by*> R. C. Whaley, Computer Science Dept., Univ. of Tenn., Knoxville, USA*> \endverbatim*>* =====================================================================SUBROUTINE DLASWP( N, A, LDA, K1, K2, IPIV, INCX )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER INCX, K1, K2, LDA, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, I1, I2, INC, IP, IX, IX0, J, K, N32DOUBLE PRECISION TEMP* ..* .. Executable Statements ..** Interchange row I with row IPIV(K1+(I-K1)*abs(INCX)) for each of rows* K1 through K2.*IF( INCX.GT.0 ) THENIX0 = K1I1 = K1I2 = K2INC = 1ELSE IF( INCX.LT.0 ) THENIX0 = K1 + ( K1-K2 )*INCXI1 = K2I2 = K1INC = -1ELSERETURNEND IF*N32 = ( N / 32 )*32IF( N32.NE.0 ) THENDO 30 J = 1, N32, 32IX = IX0DO 20 I = I1, I2, INCIP = IPIV( IX )IF( IP.NE.I ) THENDO 10 K = J, J + 31TEMP = A( I, K )A( I, K ) = A( IP, K )A( IP, K ) = TEMP10 CONTINUEEND IFIX = IX + INCX20 CONTINUE30 CONTINUEEND IFIF( N32.NE.N ) THENN32 = N32 + 1IX = IX0DO 50 I = I1, I2, INCIP = IPIV( IX )IF( IP.NE.I ) THENDO 40 K = N32, NTEMP = A( I, K )A( I, K ) = A( IP, K )A( IP, K ) = TEMP40 CONTINUEEND IFIX = IX + INCX50 CONTINUEEND IF*RETURN** End of DLASWP*END*> \brief \b DLASY2 solves the Sylvester matrix equation where the matrices are of order 1 or 2.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASY2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasy2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasy2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasy2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,* LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )** .. Scalar Arguments ..* LOGICAL LTRANL, LTRANR* INTEGER INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2* DOUBLE PRECISION SCALE, XNORM* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in*>*> op(TL)*X + ISGN*X*op(TR) = SCALE*B,*>*> where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or*> -1. op(T) = T or T**T, where T**T denotes the transpose of T.*> \endverbatim** Arguments:* ==========**> \param[in] LTRANL*> \verbatim*> LTRANL is LOGICAL*> On entry, LTRANL specifies the op(TL):*> = .FALSE., op(TL) = TL,*> = .TRUE., op(TL) = TL**T.*> \endverbatim*>*> \param[in] LTRANR*> \verbatim*> LTRANR is LOGICAL*> On entry, LTRANR specifies the op(TR):*> = .FALSE., op(TR) = TR,*> = .TRUE., op(TR) = TR**T.*> \endverbatim*>*> \param[in] ISGN*> \verbatim*> ISGN is INTEGER*> On entry, ISGN specifies the sign of the equation*> as described before. ISGN may only be 1 or -1.*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> On entry, N1 specifies the order of matrix TL.*> N1 may only be 0, 1 or 2.*> \endverbatim*>*> \param[in] N2*> \verbatim*> N2 is INTEGER*> On entry, N2 specifies the order of matrix TR.*> N2 may only be 0, 1 or 2.*> \endverbatim*>*> \param[in] TL*> \verbatim*> TL is DOUBLE PRECISION array, dimension (LDTL,2)*> On entry, TL contains an N1 by N1 matrix.*> \endverbatim*>*> \param[in] LDTL*> \verbatim*> LDTL is INTEGER*> The leading dimension of the matrix TL. LDTL >= max(1,N1).*> \endverbatim*>*> \param[in] TR*> \verbatim*> TR is DOUBLE PRECISION array, dimension (LDTR,2)*> On entry, TR contains an N2 by N2 matrix.*> \endverbatim*>*> \param[in] LDTR*> \verbatim*> LDTR is INTEGER*> The leading dimension of the matrix TR. LDTR >= max(1,N2).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,2)*> On entry, the N1 by N2 matrix B contains the right-hand*> side of the equation.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the matrix B. LDB >= max(1,N1).*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> On exit, SCALE contains the scale factor. SCALE is chosen*> less than or equal to 1 to prevent the solution overflowing.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,2)*> On exit, X contains the N1 by N2 solution.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the matrix X. LDX >= max(1,N1).*> \endverbatim*>*> \param[out] XNORM*> \verbatim*> XNORM is DOUBLE PRECISION*> On exit, XNORM is the infinity-norm of the solution.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> On exit, INFO is set to*> 0: successful exit.*> 1: TL and TR have too close eigenvalues, so TL or*> TR is perturbed to get a nonsingular equation.*> NOTE: In the interests of speed, this routine does not*> check the inputs for errors.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleSYauxiliary** =====================================================================SUBROUTINE DLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,$ LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..LOGICAL LTRANL, LTRANRINTEGER INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2DOUBLE PRECISION SCALE, XNORM* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TWO, HALF, EIGHTPARAMETER ( TWO = 2.0D+0, HALF = 0.5D+0, EIGHT = 8.0D+0 )* ..* .. Local Scalars ..LOGICAL BSWAP, XSWAPINTEGER I, IP, IPIV, IPSV, J, JP, JPSV, KDOUBLE PRECISION BET, EPS, GAM, L21, SGN, SMIN, SMLNUM, TAU1,$ TEMP, U11, U12, U22, XMAX* ..* .. 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 )* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DCOPY, DSWAP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. 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. /* ..* .. Executable Statements ..** Do not check the input parameters for errors*INFO = 0** Quick return if possible*IF( N1.EQ.0 .OR. N2.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSSGN = ISGN*K = N1 + N1 + N2 - 2GO TO ( 10, 20, 30, 50 )K** 1 by 1: TL11*X + SGN*X*TR11 = B11*10 CONTINUETAU1 = TL( 1, 1 ) + SGN*TR( 1, 1 )BET = ABS( TAU1 )IF( BET.LE.SMLNUM ) THENTAU1 = SMLNUMBET = SMLNUMINFO = 1END IF*SCALE = ONEGAM = ABS( B( 1, 1 ) )IF( SMLNUM*GAM.GT.BET )$ SCALE = ONE / GAM*X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / TAU1XNORM = ABS( X( 1, 1 ) )RETURN** 1 by 2:* TL11*[X11 X12] + ISGN*[X11 X12]*op[TR11 TR12] = [B11 B12]* [TR21 TR22]*20 CONTINUE*SMIN = MAX( EPS*MAX( ABS( TL( 1, 1 ) ), ABS( TR( 1, 1 ) ),$ ABS( TR( 1, 2 ) ), ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) ),$ SMLNUM )TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )TMP( 4 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )IF( LTRANR ) THENTMP( 2 ) = SGN*TR( 2, 1 )TMP( 3 ) = SGN*TR( 1, 2 )ELSETMP( 2 ) = SGN*TR( 1, 2 )TMP( 3 ) = SGN*TR( 2, 1 )END IFBTMP( 1 ) = B( 1, 1 )BTMP( 2 ) = B( 1, 2 )GO TO 40** 2 by 1:* op[TL11 TL12]*[X11] + ISGN* [X11]*TR11 = [B11]* [TL21 TL22] [X21] [X21] [B21]*30 CONTINUESMIN = MAX( EPS*MAX( ABS( TR( 1, 1 ) ), ABS( TL( 1, 1 ) ),$ ABS( TL( 1, 2 ) ), ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) ),$ SMLNUM )TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )TMP( 4 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )IF( LTRANL ) THENTMP( 2 ) = TL( 1, 2 )TMP( 3 ) = TL( 2, 1 )ELSETMP( 2 ) = TL( 2, 1 )TMP( 3 ) = TL( 1, 2 )END IFBTMP( 1 ) = B( 1, 1 )BTMP( 2 ) = B( 2, 1 )40 CONTINUE** Solve 2 by 2 system using complete pivoting.* Set pivots less than SMIN to SMIN.*IPIV = IDAMAX( 4, TMP, 1 )U11 = TMP( IPIV )IF( ABS( U11 ).LE.SMIN ) THENINFO = 1U11 = SMINEND IFU12 = TMP( LOCU12( IPIV ) )L21 = TMP( LOCL21( IPIV ) ) / U11U22 = TMP( LOCU22( IPIV ) ) - U12*L21XSWAP = XSWPIV( IPIV )BSWAP = BSWPIV( IPIV )IF( ABS( U22 ).LE.SMIN ) THENINFO = 1U22 = SMINEND IFIF( BSWAP ) THENTEMP = BTMP( 2 )BTMP( 2 ) = BTMP( 1 ) - L21*TEMPBTMP( 1 ) = TEMPELSEBTMP( 2 ) = BTMP( 2 ) - L21*BTMP( 1 )END IFSCALE = ONEIF( ( TWO*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( U22 ) .OR.$ ( TWO*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( U11 ) ) THENSCALE = HALF / MAX( ABS( BTMP( 1 ) ), ABS( BTMP( 2 ) ) )BTMP( 1 ) = BTMP( 1 )*SCALEBTMP( 2 ) = BTMP( 2 )*SCALEEND IFX2( 2 ) = BTMP( 2 ) / U22X2( 1 ) = BTMP( 1 ) / U11 - ( U12 / U11 )*X2( 2 )IF( XSWAP ) THENTEMP = X2( 2 )X2( 2 ) = X2( 1 )X2( 1 ) = TEMPEND IFX( 1, 1 ) = X2( 1 )IF( N1.EQ.1 ) THENX( 1, 2 ) = X2( 2 )XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )ELSEX( 2, 1 ) = X2( 2 )XNORM = MAX( ABS( X( 1, 1 ) ), ABS( X( 2, 1 ) ) )END IFRETURN** 2 by 2:* op[TL11 TL12]*[X11 X12] +ISGN* [X11 X12]*op[TR11 TR12] = [B11 B12]* [TL21 TL22] [X21 X22] [X21 X22] [TR21 TR22] [B21 B22]** Solve equivalent 4 by 4 system using complete pivoting.* Set pivots less than SMIN to SMIN.*50 CONTINUESMIN = MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),$ ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )SMIN = MAX( SMIN, ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),$ ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )SMIN = MAX( EPS*SMIN, SMLNUM )BTMP( 1 ) = ZEROCALL DCOPY( 16, BTMP, 0, T16, 1 )T16( 1, 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )T16( 2, 2 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )T16( 3, 3 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )T16( 4, 4 ) = TL( 2, 2 ) + SGN*TR( 2, 2 )IF( LTRANL ) THENT16( 1, 2 ) = TL( 2, 1 )T16( 2, 1 ) = TL( 1, 2 )T16( 3, 4 ) = TL( 2, 1 )T16( 4, 3 ) = TL( 1, 2 )ELSET16( 1, 2 ) = TL( 1, 2 )T16( 2, 1 ) = TL( 2, 1 )T16( 3, 4 ) = TL( 1, 2 )T16( 4, 3 ) = TL( 2, 1 )END IFIF( LTRANR ) THENT16( 1, 3 ) = SGN*TR( 1, 2 )T16( 2, 4 ) = SGN*TR( 1, 2 )T16( 3, 1 ) = SGN*TR( 2, 1 )T16( 4, 2 ) = SGN*TR( 2, 1 )ELSET16( 1, 3 ) = SGN*TR( 2, 1 )T16( 2, 4 ) = SGN*TR( 2, 1 )T16( 3, 1 ) = SGN*TR( 1, 2 )T16( 4, 2 ) = SGN*TR( 1, 2 )END IFBTMP( 1 ) = B( 1, 1 )BTMP( 2 ) = B( 2, 1 )BTMP( 3 ) = B( 1, 2 )BTMP( 4 ) = B( 2, 2 )** Perform elimination*DO 100 I = 1, 3XMAX = ZERODO 70 IP = I, 4DO 60 JP = I, 4IF( ABS( T16( IP, JP ) ).GE.XMAX ) THENXMAX = ABS( T16( IP, JP ) )IPSV = IPJPSV = JPEND IF60 CONTINUE70 CONTINUEIF( IPSV.NE.I ) THENCALL DSWAP( 4, T16( IPSV, 1 ), 4, T16( I, 1 ), 4 )TEMP = BTMP( I )BTMP( I ) = BTMP( IPSV )BTMP( IPSV ) = TEMPEND IFIF( JPSV.NE.I )$ CALL DSWAP( 4, T16( 1, JPSV ), 1, T16( 1, I ), 1 )JPIV( I ) = JPSVIF( ABS( T16( I, I ) ).LT.SMIN ) THENINFO = 1T16( I, I ) = SMINEND IFDO 90 J = I + 1, 4T16( J, I ) = T16( J, I ) / T16( I, I )BTMP( J ) = BTMP( J ) - T16( J, I )*BTMP( I )DO 80 K = I + 1, 4T16( J, K ) = T16( J, K ) - T16( J, I )*T16( I, K )80 CONTINUE90 CONTINUE100 CONTINUEIF( ABS( T16( 4, 4 ) ).LT.SMIN ) THENINFO = 1T16( 4, 4 ) = SMINEND IFSCALE = ONEIF( ( 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 ) ) ) THENSCALE = ( ONE / EIGHT ) / MAX( ABS( BTMP( 1 ) ),$ ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ), ABS( BTMP( 4 ) ) )BTMP( 1 ) = BTMP( 1 )*SCALEBTMP( 2 ) = BTMP( 2 )*SCALEBTMP( 3 ) = BTMP( 3 )*SCALEBTMP( 4 ) = BTMP( 4 )*SCALEEND IFDO 120 I = 1, 4K = 5 - ITEMP = ONE / T16( K, K )TMP( K ) = BTMP( K )*TEMPDO 110 J = K + 1, 4TMP( K ) = TMP( K ) - ( TEMP*T16( K, J ) )*TMP( J )110 CONTINUE120 CONTINUEDO 130 I = 1, 3IF( JPIV( 4-I ).NE.4-I ) THENTEMP = TMP( 4-I )TMP( 4-I ) = TMP( JPIV( 4-I ) )TMP( JPIV( 4-I ) ) = TEMPEND IF130 CONTINUEX( 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 ) ) )RETURN** End of DLASY2*END*> \brief \b DLASYF computes a partial factorization of a real symmetric matrix using the Bunch-Kaufman diagonal pivoting method.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLASYF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlasyf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlasyf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlasyf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLASYF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KB, LDA, LDW, N, NB* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), W( LDW, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLASYF computes a partial factorization of a real symmetric matrix A*> using the Bunch-Kaufman diagonal pivoting method. The partial*> factorization has the form:*>*> A = ( I U12 ) ( A11 0 ) ( I 0 ) if UPLO = 'U', or:*> ( 0 U22 ) ( 0 D ) ( U12**T U22**T )*>*> A = ( L11 0 ) ( D 0 ) ( L11**T L21**T ) if UPLO = 'L'*> ( L21 I ) ( 0 A22 ) ( 0 I )*>*> where the order of D is at most NB. The actual order is returned in*> the argument KB, and is either NB or NB-1, or N if N <= NB.*>*> DLASYF is an auxiliary routine called by DSYTRF. It uses blocked code*> (calling Level 3 BLAS) to update the submatrix A11 (if UPLO = 'U') or*> A22 (if UPLO = 'L').*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The maximum number of columns of the matrix A that should be*> factored. NB should be at least 2 to allow for 2-by-2 pivot*> blocks.*> \endverbatim*>*> \param[out] KB*> \verbatim*> KB is INTEGER*> The number of columns of A that were actually factored.*> KB is either NB-1 or NB, or N if N <= NB.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n-by-n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n-by-n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*> On exit, A contains details of the partial factorization.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D.*>*> If UPLO = 'U':*> Only the last KB elements of IPIV are set.*>*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*>*> If IPIV(k) = IPIV(k-1) < 0, then rows and columns*> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)*> is a 2-by-2 diagonal block.*>*> If UPLO = 'L':*> Only the first KB elements of IPIV are set.*>*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*>*> If IPIV(k) = IPIV(k+1) < 0, then rows and columns*> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1)*> is a 2-by-2 diagonal block.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (LDW,NB)*> \endverbatim*>*> \param[in] LDW*> \verbatim*> LDW is INTEGER*> The leading dimension of the array W. LDW >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> > 0: if INFO = k, D(k,k) is exactly zero. The factorization*> has been completed, but the block diagonal matrix D is*> exactly singular.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2013**> \ingroup doubleSYcomputational**> \par Contributors:* ==================*>*> \verbatim*>*> November 2013, Igor Kozachenko,*> Computer Science Division,*> University of California, Berkeley*> \endverbatim** =====================================================================SUBROUTINE DLASYF( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO )** -- LAPACK computational routine (version 3.5.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2013** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KB, LDA, LDW, N, NB* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), W( LDW, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION EIGHT, SEVTENPARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 )* ..* .. Local Scalars ..INTEGER IMAX, J, JB, JJ, JMAX, JP, K, KK, KKW, KP,$ KSTEP, KWDOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D11, D21, D22, R1,$ ROWMAX, T* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXEXTERNAL LSAME, IDAMAX* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMM, DGEMV, DSCAL, DSWAP* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN, SQRT* ..* .. Executable Statements ..*INFO = 0** Initialize ALPHA for use in choosing pivot block size.*ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT*IF( LSAME( UPLO, 'U' ) ) THEN** Factorize the trailing columns of A using the upper triangle* of A and working backwards, and compute the matrix W = U12*D* for use in updating A11** K is the main loop index, decreasing from N in steps of 1 or 2** KW is the column of W which corresponds to column K of A*K = N10 CONTINUEKW = NB + K - N** Exit from loop*IF( ( K.LE.N-NB+1 .AND. NB.LT.N ) .OR. K.LT.1 )$ GO TO 30** Copy column K of A to column KW of W and update it*CALL DCOPY( K, A( 1, K ), 1, W( 1, KW ), 1 )IF( K.LT.N )$ CALL DGEMV( 'No transpose', K, N-K, -ONE, A( 1, K+1 ), LDA,$ W( K, KW+1 ), LDW, ONE, W( 1, KW ), 1 )*KSTEP = 1** Determine rows and columns to be interchanged and whether* a 1-by-1 or 2-by-2 pivot block will be used*ABSAKK = ABS( W( K, KW ) )** IMAX is the row-index of the largest off-diagonal element in* column K, and COLMAX is its absolute value.* Determine both COLMAX and IMAX.*IF( K.GT.1 ) THENIMAX = IDAMAX( K-1, W( 1, KW ), 1 )COLMAX = ABS( W( IMAX, KW ) )ELSECOLMAX = ZEROEND IF*IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN** Column K is zero or underflow: set INFO and continue*IF( INFO.EQ.0 )$ INFO = KKP = KELSEIF( ABSAKK.GE.ALPHA*COLMAX ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE** Copy column IMAX to column KW-1 of W and update it*CALL DCOPY( IMAX, A( 1, IMAX ), 1, W( 1, KW-1 ), 1 )CALL DCOPY( K-IMAX, A( IMAX, IMAX+1 ), LDA,$ W( IMAX+1, KW-1 ), 1 )IF( K.LT.N )$ CALL DGEMV( 'No transpose', K, N-K, -ONE, A( 1, K+1 ),$ LDA, W( IMAX, KW+1 ), LDW, ONE,$ W( 1, KW-1 ), 1 )** JMAX is the column-index of the largest off-diagonal* element in row IMAX, and ROWMAX is its absolute value*JMAX = IMAX + IDAMAX( K-IMAX, W( IMAX+1, KW-1 ), 1 )ROWMAX = ABS( W( JMAX, KW-1 ) )IF( IMAX.GT.1 ) THENJMAX = IDAMAX( IMAX-1, W( 1, KW-1 ), 1 )ROWMAX = MAX( ROWMAX, ABS( W( JMAX, KW-1 ) ) )END IF*IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE IF( ABS( W( IMAX, KW-1 ) ).GE.ALPHA*ROWMAX ) THEN** interchange rows and columns K and IMAX, use 1-by-1* pivot block*KP = IMAX** copy column KW-1 of W to column KW of W*CALL DCOPY( K, W( 1, KW-1 ), 1, W( 1, KW ), 1 )ELSE** interchange rows and columns K-1 and IMAX, use 2-by-2* pivot block*KP = IMAXKSTEP = 2END IFEND IF** ============================================================** KK is the column of A where pivoting step stopped*KK = K - KSTEP + 1** KKW is the column of W which corresponds to column KK of A*KKW = NB + KK - N** Interchange rows and columns KP and KK.* Updated column KP is already stored in column KKW of W.*IF( KP.NE.KK ) THEN** Copy non-updated column KK to column KP of submatrix A* at step K. No need to copy element into column K* (or K and K-1 for 2-by-2 pivot) of A, since these columns* will be later overwritten.*A( KP, KP ) = A( KK, KK )CALL DCOPY( KK-1-KP, A( KP+1, KK ), 1, A( KP, KP+1 ),$ LDA )IF( KP.GT.1 )$ CALL DCOPY( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 )** Interchange rows KK and KP in last K+1 to N columns of A* (columns K (or K and K-1 for 2-by-2 pivot) of A will be* later overwritten). Interchange rows KK and KP* in last KKW to NB columns of W.*IF( K.LT.N )$ CALL DSWAP( N-K, A( KK, K+1 ), LDA, A( KP, K+1 ),$ LDA )CALL DSWAP( N-KK+1, W( KK, KKW ), LDW, W( KP, KKW ),$ LDW )END IF*IF( KSTEP.EQ.1 ) THEN** 1-by-1 pivot block D(k): column kw of W now holds** W(kw) = U(k)*D(k),** where U(k) is the k-th column of U** Store subdiag. elements of column U(k)* and 1-by-1 block D(k) in column k of A.* NOTE: Diagonal element U(k,k) is a UNIT element* and not stored.* A(k,k) := D(k,k) = W(k,kw)* A(1:k-1,k) := U(1:k-1,k) = W(1:k-1,kw)/D(k,k)*CALL DCOPY( K, W( 1, KW ), 1, A( 1, K ), 1 )R1 = ONE / A( K, K )CALL DSCAL( K-1, R1, A( 1, K ), 1 )*ELSE** 2-by-2 pivot block D(k): columns kw and kw-1 of W now hold** ( W(kw-1) W(kw) ) = ( U(k-1) U(k) )*D(k)** where U(k) and U(k-1) are the k-th and (k-1)-th columns* of U** Store U(1:k-2,k-1) and U(1:k-2,k) and 2-by-2* block D(k-1:k,k-1:k) in columns k-1 and k of A.* NOTE: 2-by-2 diagonal block U(k-1:k,k-1:k) is a UNIT* block and not stored.* A(k-1:k,k-1:k) := D(k-1:k,k-1:k) = W(k-1:k,kw-1:kw)* A(1:k-2,k-1:k) := U(1:k-2,k:k-1:k) =* = W(1:k-2,kw-1:kw) * ( D(k-1:k,k-1:k)**(-1) )*IF( K.GT.2 ) THEN** Compose the columns of the inverse of 2-by-2 pivot* block D in the following way to reduce the number* of FLOPS when we myltiply panel ( W(kw-1) W(kw) ) by* this inverse** D**(-1) = ( d11 d21 )**(-1) =* ( d21 d22 )** = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) =* ( (-d21 ) ( d11 ) )** = 1/d21 * 1/((d11/d21)*(d22/d21)-1) *** * ( ( d22/d21 ) ( -1 ) ) =* ( ( -1 ) ( d11/d21 ) )** = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) =* ( ( -1 ) ( D22 ) )** = 1/d21 * T * ( ( D11 ) ( -1 ) )* ( ( -1 ) ( D22 ) )** = D21 * ( ( D11 ) ( -1 ) )* ( ( -1 ) ( D22 ) )*D21 = W( K-1, KW )D11 = W( K, KW ) / D21D22 = W( K-1, KW-1 ) / D21T = ONE / ( D11*D22-ONE )D21 = T / D21** Update elements in columns A(k-1) and A(k) as* dot products of rows of ( W(kw-1) W(kw) ) and columns* of D**(-1)*DO 20 J = 1, K - 2A( J, K-1 ) = D21*( D11*W( J, KW-1 )-W( J, KW ) )A( J, K ) = D21*( D22*W( J, KW )-W( J, KW-1 ) )20 CONTINUEEND IF** Copy D(k) to A*A( K-1, K-1 ) = W( K-1, KW-1 )A( K-1, K ) = W( K-1, KW )A( K, K ) = W( K, KW )*END IF*END IF** Store details of the interchanges in IPIV*IF( KSTEP.EQ.1 ) THENIPIV( K ) = KPELSEIPIV( K ) = -KPIPIV( K-1 ) = -KPEND IF** Decrease K and return to the start of the main loop*K = K - KSTEPGO TO 10*30 CONTINUE** Update the upper triangle of A11 (= A(1:k,1:k)) as** A11 := A11 - U12*D*U12**T = A11 - U12*W**T** computing blocks of NB columns at a time*DO 50 J = ( ( K-1 ) / NB )*NB + 1, 1, -NBJB = MIN( NB, K-J+1 )** Update the upper triangle of the diagonal block*DO 40 JJ = J, J + JB - 1CALL DGEMV( 'No transpose', JJ-J+1, N-K, -ONE,$ A( J, K+1 ), LDA, W( JJ, KW+1 ), LDW, ONE,$ A( J, JJ ), 1 )40 CONTINUE** Update the rectangular superdiagonal block*CALL DGEMM( 'No transpose', 'Transpose', J-1, JB, N-K, -ONE,$ A( 1, K+1 ), LDA, W( J, KW+1 ), LDW, ONE,$ A( 1, J ), LDA )50 CONTINUE** Put U12 in standard form by partially undoing the interchanges* in columns k+1:n looping backwards from k+1 to n*J = K + 160 CONTINUE** Undo the interchanges (if any) of rows JJ and JP at each* step J** (Here, J is a diagonal index)JJ = JJP = IPIV( J )IF( JP.LT.0 ) THENJP = -JP* (Here, J is a diagonal index)J = J + 1END IF* (NOTE: Here, J is used to determine row length. Length N-J+1* of the rows to swap back doesn't include diagonal element)J = J + 1IF( JP.NE.JJ .AND. J.LE.N )$ CALL DSWAP( N-J+1, A( JP, J ), LDA, A( JJ, J ), LDA )IF( J.LT.N )$ GO TO 60** Set KB to the number of columns factorized*KB = N - K*ELSE** Factorize the leading columns of A using the lower triangle* of A and working forwards, and compute the matrix W = L21*D* for use in updating A22** K is the main loop index, increasing from 1 in steps of 1 or 2*K = 170 CONTINUE** Exit from loop*IF( ( K.GE.NB .AND. NB.LT.N ) .OR. K.GT.N )$ GO TO 90** Copy column K of A to column K of W and update it*CALL DCOPY( N-K+1, A( K, K ), 1, W( K, K ), 1 )CALL DGEMV( 'No transpose', N-K+1, K-1, -ONE, A( K, 1 ), LDA,$ W( K, 1 ), LDW, ONE, W( K, K ), 1 )*KSTEP = 1** Determine rows and columns to be interchanged and whether* a 1-by-1 or 2-by-2 pivot block will be used*ABSAKK = ABS( W( K, K ) )** IMAX is the row-index of the largest off-diagonal element in* column K, and COLMAX is its absolute value.* Determine both COLMAX and IMAX.*IF( K.LT.N ) THENIMAX = K + IDAMAX( N-K, W( K+1, K ), 1 )COLMAX = ABS( W( IMAX, K ) )ELSECOLMAX = ZEROEND IF*IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN** Column K is zero or underflow: set INFO and continue*IF( INFO.EQ.0 )$ INFO = KKP = KELSEIF( ABSAKK.GE.ALPHA*COLMAX ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE** Copy column IMAX to column K+1 of W and update it*CALL DCOPY( IMAX-K, A( IMAX, K ), LDA, W( K, K+1 ), 1 )CALL DCOPY( N-IMAX+1, A( IMAX, IMAX ), 1, W( IMAX, K+1 ),$ 1 )CALL DGEMV( 'No transpose', N-K+1, K-1, -ONE, A( K, 1 ),$ LDA, W( IMAX, 1 ), LDW, ONE, W( K, K+1 ), 1 )** JMAX is the column-index of the largest off-diagonal* element in row IMAX, and ROWMAX is its absolute value*JMAX = K - 1 + IDAMAX( IMAX-K, W( K, K+1 ), 1 )ROWMAX = ABS( W( JMAX, K+1 ) )IF( IMAX.LT.N ) THENJMAX = IMAX + IDAMAX( N-IMAX, W( IMAX+1, K+1 ), 1 )ROWMAX = MAX( ROWMAX, ABS( W( JMAX, K+1 ) ) )END IF*IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE IF( ABS( W( IMAX, K+1 ) ).GE.ALPHA*ROWMAX ) THEN** interchange rows and columns K and IMAX, use 1-by-1* pivot block*KP = IMAX** copy column K+1 of W to column K of W*CALL DCOPY( N-K+1, W( K, K+1 ), 1, W( K, K ), 1 )ELSE** interchange rows and columns K+1 and IMAX, use 2-by-2* pivot block*KP = IMAXKSTEP = 2END IFEND IF** ============================================================** KK is the column of A where pivoting step stopped*KK = K + KSTEP - 1** Interchange rows and columns KP and KK.* Updated column KP is already stored in column KK of W.*IF( KP.NE.KK ) THEN** Copy non-updated column KK to column KP of submatrix A* at step K. No need to copy element into column K* (or K and K+1 for 2-by-2 pivot) of A, since these columns* will be later overwritten.*A( KP, KP ) = A( KK, KK )CALL DCOPY( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ),$ LDA )IF( KP.LT.N )$ CALL DCOPY( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 )** Interchange rows KK and KP in first K-1 columns of A* (columns K (or K and K+1 for 2-by-2 pivot) of A will be* later overwritten). Interchange rows KK and KP* in first KK columns of W.*IF( K.GT.1 )$ CALL DSWAP( K-1, A( KK, 1 ), LDA, A( KP, 1 ), LDA )CALL DSWAP( KK, W( KK, 1 ), LDW, W( KP, 1 ), LDW )END IF*IF( KSTEP.EQ.1 ) THEN** 1-by-1 pivot block D(k): column k of W now holds** W(k) = L(k)*D(k),** where L(k) is the k-th column of L** Store subdiag. elements of column L(k)* and 1-by-1 block D(k) in column k of A.* (NOTE: Diagonal element L(k,k) is a UNIT element* and not stored)* A(k,k) := D(k,k) = W(k,k)* A(k+1:N,k) := L(k+1:N,k) = W(k+1:N,k)/D(k,k)*CALL DCOPY( N-K+1, W( K, K ), 1, A( K, K ), 1 )IF( K.LT.N ) THENR1 = ONE / A( K, K )CALL DSCAL( N-K, R1, A( K+1, K ), 1 )END IF*ELSE** 2-by-2 pivot block D(k): columns k and k+1 of W now hold** ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k)** where L(k) and L(k+1) are the k-th and (k+1)-th columns* of L** Store L(k+2:N,k) and L(k+2:N,k+1) and 2-by-2* block D(k:k+1,k:k+1) in columns k and k+1 of A.* (NOTE: 2-by-2 diagonal block L(k:k+1,k:k+1) is a UNIT* block and not stored)* A(k:k+1,k:k+1) := D(k:k+1,k:k+1) = W(k:k+1,k:k+1)* A(k+2:N,k:k+1) := L(k+2:N,k:k+1) =* = W(k+2:N,k:k+1) * ( D(k:k+1,k:k+1)**(-1) )*IF( K.LT.N-1 ) THEN** Compose the columns of the inverse of 2-by-2 pivot* block D in the following way to reduce the number* of FLOPS when we myltiply panel ( W(k) W(k+1) ) by* this inverse** D**(-1) = ( d11 d21 )**(-1) =* ( d21 d22 )** = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) =* ( (-d21 ) ( d11 ) )** = 1/d21 * 1/((d11/d21)*(d22/d21)-1) *** * ( ( d22/d21 ) ( -1 ) ) =* ( ( -1 ) ( d11/d21 ) )** = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) =* ( ( -1 ) ( D22 ) )** = 1/d21 * T * ( ( D11 ) ( -1 ) )* ( ( -1 ) ( D22 ) )** = D21 * ( ( D11 ) ( -1 ) )* ( ( -1 ) ( D22 ) )*D21 = W( K+1, K )D11 = W( K+1, K+1 ) / D21D22 = W( K, K ) / D21T = ONE / ( D11*D22-ONE )D21 = T / D21** Update elements in columns A(k) and A(k+1) as* dot products of rows of ( W(k) W(k+1) ) and columns* of D**(-1)*DO 80 J = K + 2, NA( J, K ) = D21*( D11*W( J, K )-W( J, K+1 ) )A( J, K+1 ) = D21*( D22*W( J, K+1 )-W( J, K ) )80 CONTINUEEND IF** Copy D(k) to A*A( K, K ) = W( K, K )A( K+1, K ) = W( K+1, K )A( K+1, K+1 ) = W( K+1, K+1 )*END IF*END IF** Store details of the interchanges in IPIV*IF( KSTEP.EQ.1 ) THENIPIV( K ) = KPELSEIPIV( K ) = -KPIPIV( K+1 ) = -KPEND IF** Increase K and return to the start of the main loop*K = K + KSTEPGO TO 70*90 CONTINUE** Update the lower triangle of A22 (= A(k:n,k:n)) as** A22 := A22 - L21*D*L21**T = A22 - L21*W**T** computing blocks of NB columns at a time*DO 110 J = K, N, NBJB = MIN( NB, N-J+1 )** Update the lower triangle of the diagonal block*DO 100 JJ = J, J + JB - 1CALL DGEMV( 'No transpose', J+JB-JJ, K-1, -ONE,$ A( JJ, 1 ), LDA, W( JJ, 1 ), LDW, ONE,$ A( JJ, JJ ), 1 )100 CONTINUE** Update the rectangular subdiagonal block*IF( J+JB.LE.N )$ CALL DGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB,$ K-1, -ONE, A( J+JB, 1 ), LDA, W( J, 1 ), LDW,$ ONE, A( J+JB, J ), LDA )110 CONTINUE** Put L21 in standard form by partially undoing the interchanges* of rows in columns 1:k-1 looping backwards from k-1 to 1*J = K - 1120 CONTINUE** Undo the interchanges (if any) of rows JJ and JP at each* step J** (Here, J is a diagonal index)JJ = JJP = IPIV( J )IF( JP.LT.0 ) THENJP = -JP* (Here, J is a diagonal index)J = J - 1END IF* (NOTE: Here, J is used to determine row length. Length J* of the rows to swap back doesn't include diagonal element)J = J - 1IF( JP.NE.JJ .AND. J.GE.1 )$ CALL DSWAP( J, A( JP, 1 ), LDA, A( JJ, 1 ), LDA )IF( J.GT.1 )$ GO TO 120** Set KB to the number of columns factorized*KB = K - 1*END IFRETURN** End of DLASYF*END*> \brief \b DLATBS solves a triangular banded system of equations.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATBS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatbs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatbs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatbs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATBS( UPLO, TRANS, DIAG, NORMIN, N, KD, AB, LDAB, X,* SCALE, CNORM, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, NORMIN, TRANS, UPLO* INTEGER INFO, KD, LDAB, N* DOUBLE PRECISION SCALE* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), CNORM( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLATBS solves one of the triangular systems*>*> A *x = s*b or A**T*x = s*b*>*> with scaling to prevent overflow, where A is an upper or lower*> triangular band matrix. Here A**T denotes the transpose of A, x and b*> are n-element vectors, and s is a scaling factor, usually less than*> or equal to 1, chosen so that the components of x will be less than*> the overflow threshold. If the unscaled problem will not cause*> overflow, the Level 2 BLAS routine DTBSV is called. If the matrix A*> is singular (A(j,j) = 0 for some j), then s is set to 0 and a*> non-trivial solution to A*x = 0 is returned.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower triangular.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the operation applied to A.*> = 'N': Solve A * x = s*b (No transpose)*> = 'T': Solve A**T* x = s*b (Transpose)*> = 'C': Solve A**T* x = s*b (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A is unit triangular.*> = 'N': Non-unit triangular*> = 'U': Unit triangular*> \endverbatim*>*> \param[in] NORMIN*> \verbatim*> NORMIN is CHARACTER*1*> Specifies whether CNORM has been set or not.*> = 'Y': CNORM contains the column norms on entry*> = 'N': CNORM is not set on entry. On exit, the norms will*> be computed and stored in CNORM.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of subdiagonals or superdiagonals in the*> triangular matrix A. KD >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangular band matrix A, stored in the*> first KD+1 rows of the array. The j-th column of A is stored*> in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> On entry, the right hand side b of the triangular system.*> On exit, X is overwritten by the solution vector x.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> The scaling factor s for the triangular system*> A * x = s*b or A**T* x = s*b.*> If SCALE = 0, the matrix A is singular or badly scaled, and*> the vector x is an exact or approximate solution to A*x = 0.*> \endverbatim*>*> \param[in,out] CNORM*> \verbatim*> CNORM is DOUBLE PRECISION array, dimension (N)*>*> If NORMIN = 'Y', CNORM is an input argument and CNORM(j)*> contains the norm of the off-diagonal part of the j-th column*> of A. If TRANS = 'N', CNORM(j) must be greater than or equal*> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)*> must be greater than or equal to the 1-norm.*>*> If NORMIN = 'N', CNORM is an output argument and CNORM(j)*> returns the 1-norm of the offdiagonal part of the j-th column*> of A.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> A rough bound on x is computed; if that is less than overflow, DTBSV*> is called, otherwise, specific code is used which checks for possible*> overflow or divide-by-zero at every operation.*>*> A columnwise scheme is used for solving A*x = b. The basic algorithm*> if A is lower triangular is*>*> x[1:n] := b[1:n]*> for j = 1, ..., n*> x(j) := x(j) / A(j,j)*> x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]*> end*>*> Define bounds on the components of x after j iterations of the loop:*> M(j) = bound on x[1:j]*> G(j) = bound on x[j+1:n]*> Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.*>*> Then for iteration j+1 we have*> M(j+1) <= G(j) / | A(j+1,j+1) |*> G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |*> <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )*>*> where CNORM(j+1) is greater than or equal to the infinity-norm of*> column j+1 of A, not counting the diagonal. Hence*>*> G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )*> 1<=i<=j*> and*>*> |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )*> 1<=i< j*>*> Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTBSV if the*> reciprocal of the largest M(j), j=1,..,n, is larger than*> max(underflow, 1/overflow).*>*> The bound on x(j) is also used to determine when a step in the*> columnwise method can be performed without fear of overflow. If*> the computed bound is greater than a large constant, x is scaled to*> prevent overflow, but if the bound overflows, x is set to 0, x(j) to*> 1, and scale to 0, and a non-trivial solution to A*x = 0 is found.*>*> Similarly, a row-wise scheme is used to solve A**T*x = b. The basic*> algorithm for A upper triangular is*>*> for j = 1, ..., n*> x(j) := ( b(j) - A[1:j-1,j]**T * x[1:j-1] ) / A(j,j)*> end*>*> We simultaneously compute two bounds*> G(j) = bound on ( b(i) - A[1:i-1,i]**T * x[1:i-1] ), 1<=i<=j*> M(j) = bound on x(i), 1<=i<=j*>*> The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we*> add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.*> Then the bound on x(j) is*>*> M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |*>*> <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )*> 1<=i<=j*>*> and we can safely call DTBSV if 1/M(n) and 1/G(n) are both greater*> than max(underflow, 1/overflow).*> \endverbatim*>* =====================================================================SUBROUTINE DLATBS( UPLO, TRANS, DIAG, NORMIN, N, KD, AB, LDAB, X,$ SCALE, CNORM, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORMIN, TRANS, UPLOINTEGER INFO, KD, LDAB, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), CNORM( * ), X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERINTEGER I, IMAX, J, JFIRST, JINC, JLAST, JLEN, MAINDDOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,$ TMAX, TSCAL, USCAL, XBND, XJ, XMAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DASUM, DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DASUM, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DTBSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )** Test the input parameters.*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.$ LSAME( NORMIN, 'N' ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( KD.LT.0 ) THENINFO = -6ELSE IF( LDAB.LT.KD+1 ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLATBS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine machine dependent parameters to control overflow.*SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )BIGNUM = ONE / SMLNUMSCALE = ONE*IF( LSAME( NORMIN, 'N' ) ) THEN** Compute the 1-norm of each column, not including the diagonal.*IF( UPPER ) THEN** A is upper triangular.*DO 10 J = 1, NJLEN = MIN( KD, J-1 )CNORM( J ) = DASUM( JLEN, AB( KD+1-JLEN, J ), 1 )10 CONTINUEELSE** A is lower triangular.*DO 20 J = 1, NJLEN = MIN( KD, N-J )IF( JLEN.GT.0 ) THENCNORM( J ) = DASUM( JLEN, AB( 2, J ), 1 )ELSECNORM( J ) = ZEROEND IF20 CONTINUEEND IFEND IF** Scale the column norms by TSCAL if the maximum element in CNORM is* greater than BIGNUM.*IMAX = IDAMAX( N, CNORM, 1 )TMAX = CNORM( IMAX )IF( TMAX.LE.BIGNUM ) THENTSCAL = ONEELSETSCAL = ONE / ( SMLNUM*TMAX )CALL DSCAL( N, TSCAL, CNORM, 1 )END IF** Compute a bound on the computed solution vector to see if the* Level 2 BLAS routine DTBSV can be used.*J = IDAMAX( N, X, 1 )XMAX = ABS( X( J ) )XBND = XMAXIF( NOTRAN ) THEN** Compute the growth in A * x = b.*IF( UPPER ) THENJFIRST = NJLAST = 1JINC = -1MAIND = KD + 1ELSEJFIRST = 1JLAST = NJINC = 1MAIND = 1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 50END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, G(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWDO 30 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** M(j) = G(j-1) / abs(A(j,j))*TJJ = ABS( AB( MAIND, J ) )XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN** G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )*GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )ELSE** G(j) could overflow, set GROW to 0.*GROW = ZEROEND IF30 CONTINUEGROW = XBNDELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 40 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** G(j) = G(j-1)*( 1 + CNORM(j) )*GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )40 CONTINUEEND IF50 CONTINUE*ELSE** Compute the growth in A**T * x = b.*IF( UPPER ) THENJFIRST = 1JLAST = NJINC = 1MAIND = KD + 1ELSEJFIRST = NJLAST = 1JINC = -1MAIND = 1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 80END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, M(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWDO 60 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )*XJ = ONE + CNORM( J )GROW = MIN( GROW, XBND / XJ )** M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))*TJJ = ABS( AB( MAIND, J ) )IF( XJ.GT.TJJ )$ XBND = XBND*( TJJ / XJ )60 CONTINUEGROW = MIN( GROW, XBND )ELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 70 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = ( 1 + CNORM(j) )*G(j-1)*XJ = ONE + CNORM( J )GROW = GROW / XJ70 CONTINUEEND IF80 CONTINUEEND IF*IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN** Use the Level 2 BLAS solve if the reciprocal of the bound on* elements of X is not too small.*CALL DTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, X, 1 )ELSE** Use a Level 1 BLAS solve, scaling intermediate results.*IF( XMAX.GT.BIGNUM ) THEN** Scale X so that its components are less than or equal to* BIGNUM in absolute value.*SCALE = BIGNUM / XMAXCALL DSCAL( N, SCALE, X, 1 )XMAX = BIGNUMEND IF*IF( NOTRAN ) THEN** Solve A * x = b*DO 110 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) / A(j,j), scaling x if necessary.*XJ = ABS( X( J ) )IF( NOUNIT ) THENTJJS = AB( MAIND, J )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 100END IFTJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by 1/b(j).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM* to avoid overflow when dividing by A(j,j).*REC = ( TJJ*BIGNUM ) / XJIF( CNORM( J ).GT.ONE ) THEN** Scale by 1/CNORM(j) to avoid overflow when* multiplying x(j) times column j.*REC = REC / CNORM( J )END IFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A*x = 0.*DO 90 I = 1, NX( I ) = ZERO90 CONTINUEX( J ) = ONEXJ = ONESCALE = ZEROXMAX = ZEROEND IF100 CONTINUE** Scale x if necessary to avoid overflow when adding a* multiple of column j of A.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN** Scale x by 1/(2*abs(x(j))).*REC = REC*HALFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN** Scale x by 1/2.*CALL DSCAL( N, HALF, X, 1 )SCALE = SCALE*HALFEND IF*IF( UPPER ) THENIF( J.GT.1 ) THEN** Compute the update* x(max(1,j-kd):j-1) := x(max(1,j-kd):j-1) -* x(j)* A(max(1,j-kd):j-1,j)*JLEN = MIN( KD, J-1 )CALL DAXPY( JLEN, -X( J )*TSCAL,$ AB( KD+1-JLEN, J ), 1, X( J-JLEN ), 1 )I = IDAMAX( J-1, X, 1 )XMAX = ABS( X( I ) )END IFELSE IF( J.LT.N ) THEN** Compute the update* x(j+1:min(j+kd,n)) := x(j+1:min(j+kd,n)) -* x(j) * A(j+1:min(j+kd,n),j)*JLEN = MIN( KD, N-J )IF( JLEN.GT.0 )$ CALL DAXPY( JLEN, -X( J )*TSCAL, AB( 2, J ), 1,$ X( J+1 ), 1 )I = J + IDAMAX( N-J, X( J+1 ), 1 )XMAX = ABS( X( I ) )END IF110 CONTINUE*ELSE** Solve A**T * x = b*DO 160 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) - sum A(k,j)*x(k).* k<>j*XJ = ABS( X( J ) )USCAL = TSCALREC = ONE / MAX( XMAX, ONE )IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN** If x(j) could overflow, scale x by 1/(2*XMAX).*REC = REC*HALFIF( NOUNIT ) THENTJJS = AB( MAIND, J )*TSCALELSETJJS = TSCALEND IFTJJ = ABS( TJJS )IF( TJJ.GT.ONE ) THEN** Divide by A(j,j) when scaling x if A(j,j) > 1.*REC = MIN( ONE, REC*TJJ )USCAL = USCAL / TJJSEND IFIF( REC.LT.ONE ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*SUMJ = ZEROIF( USCAL.EQ.ONE ) THEN** If the scaling needed for A in the dot product is 1,* call DDOT to perform the dot product.*IF( UPPER ) THENJLEN = MIN( KD, J-1 )SUMJ = DDOT( JLEN, AB( KD+1-JLEN, J ), 1,$ X( J-JLEN ), 1 )ELSEJLEN = MIN( KD, N-J )IF( JLEN.GT.0 )$ SUMJ = DDOT( JLEN, AB( 2, J ), 1, X( J+1 ), 1 )END IFELSE** Otherwise, use in-line code for the dot product.*IF( UPPER ) THENJLEN = MIN( KD, J-1 )DO 120 I = 1, JLENSUMJ = SUMJ + ( AB( KD+I-JLEN, J )*USCAL )*$ X( J-JLEN-1+I )120 CONTINUEELSEJLEN = MIN( KD, N-J )DO 130 I = 1, JLENSUMJ = SUMJ + ( AB( I+1, J )*USCAL )*X( J+I )130 CONTINUEEND IFEND IF*IF( USCAL.EQ.TSCAL ) THEN** Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)* was not used to scale the dotproduct.*X( J ) = X( J ) - SUMJXJ = ABS( X( J ) )IF( NOUNIT ) THEN** Compute x(j) = x(j) / A(j,j), scaling if necessary.*TJJS = AB( MAIND, J )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 150END IFTJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale X by 1/abs(x(j)).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.*REC = ( TJJ*BIGNUM ) / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A**T*x = 0.*DO 140 I = 1, NX( I ) = ZERO140 CONTINUEX( J ) = ONESCALE = ZEROXMAX = ZEROEND IF150 CONTINUEELSE** Compute x(j) := x(j) / A(j,j) - sumj if the dot* product has already been divided by 1/A(j,j).*X( J ) = X( J ) / TJJS - SUMJEND IFXMAX = MAX( XMAX, ABS( X( J ) ) )160 CONTINUEEND IFSCALE = SCALE / TSCALEND IF** Scale the column norms by 1/TSCAL for return.*IF( TSCAL.NE.ONE ) THENCALL DSCAL( N, ONE / TSCAL, CNORM, 1 )END IF*RETURN** End of DLATBS*END*> \brief \b DLATDF uses the LU factorization of the n-by-n matrix computed by sgetc2 and computes a contribution to the reciprocal Dif-estimate.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATDF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatdf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatdf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatdf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,* JPIV )** .. Scalar Arguments ..* INTEGER IJOB, LDZ, N* DOUBLE PRECISION RDSCAL, RDSUM* ..* .. Array Arguments ..* INTEGER IPIV( * ), JPIV( * )* DOUBLE PRECISION RHS( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLATDF uses the LU factorization of the n-by-n matrix Z computed by*> DGETC2 and computes a contribution to the reciprocal Dif-estimate*> by solving Z * x = b for x, and choosing the r.h.s. b such that*> the norm of x is as large as possible. On entry RHS = b holds the*> contribution from earlier solved sub-systems, and on return RHS = x.*>*> The factorization of Z returned by DGETC2 has the form Z = P*L*U*Q,*> where P and Q are permutation matrices. L is lower triangular with*> unit diagonal elements and U is upper triangular.*> \endverbatim** Arguments:* ==========**> \param[in] IJOB*> \verbatim*> IJOB is INTEGER*> IJOB = 2: First compute an approximative null-vector e*> of Z using DGECON, e is normalized and solve for*> Zx = +-e - f with the sign giving the greater value*> of 2-norm(x). About 5 times as expensive as Default.*> IJOB .ne. 2: Local look ahead strategy where all entries of*> the r.h.s. b is chosen as either +1 or -1 (Default).*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Z.*> \endverbatim*>*> \param[in] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> On entry, the LU part of the factorization of the n-by-n*> matrix Z computed by DGETC2: Z = P * L * U * Q*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDA >= max(1, N).*> \endverbatim*>*> \param[in,out] RHS*> \verbatim*> RHS is DOUBLE PRECISION array, dimension (N)*> On entry, RHS contains contributions from other subsystems.*> On exit, RHS contains the solution of the subsystem with*> entries acoording to the value of IJOB (see above).*> \endverbatim*>*> \param[in,out] RDSUM*> \verbatim*> RDSUM is DOUBLE PRECISION*> On entry, the sum of squares of computed contributions to*> the Dif-estimate under computation by DTGSYL, where the*> scaling factor RDSCAL (see below) has been factored out.*> On exit, the corresponding sum of squares updated with the*> contributions from the current sub-system.*> If TRANS = 'T' RDSUM is not touched.*> NOTE: RDSUM only makes sense when DTGSY2 is called by STGSYL.*> \endverbatim*>*> \param[in,out] RDSCAL*> \verbatim*> RDSCAL is DOUBLE PRECISION*> On entry, scaling factor used to prevent overflow in RDSUM.*> On exit, RDSCAL is updated w.r.t. the current contributions*> in RDSUM.*> If TRANS = 'T', RDSCAL is not touched.*> NOTE: RDSCAL only makes sense when DTGSY2 is called by*> DTGSYL.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N).*> The pivot indices; for 1 <= i <= N, row i of the*> matrix has been interchanged with row IPIV(i).*> \endverbatim*>*> \param[in] JPIV*> \verbatim*> JPIV is INTEGER array, dimension (N).*> The pivot indices; for 1 <= j <= N, column j of the*> matrix has been interchanged with column JPIV(j).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> This routine is a further developed implementation of algorithm*> BSOLVE in [1] using complete pivoting in the LU factorization.**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.**> \par References:* ================*>*> \verbatim*>*>*> [1] Bo Kagstrom and Lars Westin,*> Generalized Schur Methods with Condition Estimators for*> Solving the Generalized Sylvester Equation, IEEE Transactions*> on Automatic Control, Vol. 34, No. 7, July 1989, pp 745-751.*>*> [2] Peter Poromaa,*> On Efficient and Robust Estimators for the Separation*> between two Regular Matrix Pairs with Applications in*> Condition Estimation. Report IMINF-95.05, Departement of*> Computing Science, Umea University, S-901 87 Umea, Sweden, 1995.*> \endverbatim*>* =====================================================================SUBROUTINE DLATDF( IJOB, N, Z, LDZ, RHS, RDSUM, RDSCAL, IPIV,$ JPIV )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..INTEGER IJOB, LDZ, NDOUBLE PRECISION RDSCAL, RDSUM* ..* .. Array Arguments ..INTEGER IPIV( * ), JPIV( * )DOUBLE PRECISION RHS( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..INTEGER MAXDIMPARAMETER ( MAXDIM = 8 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER I, INFO, J, KDOUBLE PRECISION BM, BP, PMONE, SMINU, SPLUS, TEMP* ..* .. Local Arrays ..INTEGER IWORK( MAXDIM )DOUBLE PRECISION WORK( 4*MAXDIM ), XM( MAXDIM ), XP( MAXDIM )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGECON, DGESC2, DLASSQ, DLASWP,$ DSCAL* ..* .. External Functions ..DOUBLE PRECISION DASUM, DDOTEXTERNAL DASUM, DDOT* ..* .. Intrinsic Functions ..INTRINSIC ABS, SQRT* ..* .. Executable Statements ..*IF( IJOB.NE.2 ) THEN** Apply permutations IPIV to RHS*CALL DLASWP( 1, RHS, LDZ, 1, N-1, IPIV, 1 )** Solve for L-part choosing RHS either to +1 or -1.*PMONE = -ONE*DO 10 J = 1, N - 1BP = RHS( J ) + ONEBM = RHS( J ) - ONESPLUS = ONE** Look-ahead for L-part RHS(1:N-1) = + or -1, SPLUS and* SMIN computed more efficiently than in BSOLVE [1].*SPLUS = SPLUS + DDOT( N-J, Z( J+1, J ), 1, Z( J+1, J ), 1 )SMINU = DDOT( N-J, Z( J+1, J ), 1, RHS( J+1 ), 1 )SPLUS = SPLUS*RHS( J )IF( SPLUS.GT.SMINU ) THENRHS( J ) = BPELSE IF( SMINU.GT.SPLUS ) THENRHS( J ) = BMELSE** In this case the updating sums are equal and we can* choose RHS(J) +1 or -1. The first time this happens* we choose -1, thereafter +1. This is a simple way to* get good estimates of matrices like Byers well-known* example (see [1]). (Not done in BSOLVE.)*RHS( J ) = RHS( J ) + PMONEPMONE = ONEEND IF** Compute the remaining r.h.s.*TEMP = -RHS( J )CALL DAXPY( N-J, TEMP, Z( J+1, J ), 1, RHS( J+1 ), 1 )*10 CONTINUE** Solve for U-part, look-ahead for RHS(N) = +-1. This is not done* in BSOLVE and will hopefully give us a better estimate because* any ill-conditioning of the original matrix is transfered to U* and not to L. U(N, N) is an approximation to sigma_min(LU).*CALL DCOPY( N-1, RHS, 1, XP, 1 )XP( N ) = RHS( N ) + ONERHS( N ) = RHS( N ) - ONESPLUS = ZEROSMINU = ZERODO 30 I = N, 1, -1TEMP = ONE / Z( I, I )XP( I ) = XP( I )*TEMPRHS( I ) = RHS( I )*TEMPDO 20 K = I + 1, NXP( I ) = XP( I ) - XP( K )*( Z( I, K )*TEMP )RHS( I ) = RHS( I ) - RHS( K )*( Z( I, K )*TEMP )20 CONTINUESPLUS = SPLUS + ABS( XP( I ) )SMINU = SMINU + ABS( RHS( I ) )30 CONTINUEIF( SPLUS.GT.SMINU )$ CALL DCOPY( N, XP, 1, RHS, 1 )** Apply the permutations JPIV to the computed solution (RHS)*CALL DLASWP( 1, RHS, LDZ, 1, N-1, JPIV, -1 )** Compute the sum of squares*CALL DLASSQ( N, RHS, 1, RDSCAL, RDSUM )*ELSE** IJOB = 2, Compute approximate nullvector XM of Z*CALL DGECON( 'I', N, Z, LDZ, ONE, TEMP, WORK, IWORK, INFO )CALL DCOPY( N, WORK( N+1 ), 1, XM, 1 )** Compute RHS*CALL DLASWP( 1, XM, LDZ, 1, N-1, IPIV, -1 )TEMP = ONE / SQRT( DDOT( N, XM, 1, XM, 1 ) )CALL DSCAL( N, TEMP, XM, 1 )CALL DCOPY( N, XM, 1, XP, 1 )CALL DAXPY( N, ONE, RHS, 1, XP, 1 )CALL DAXPY( N, -ONE, XM, 1, RHS, 1 )CALL DGESC2( N, Z, LDZ, RHS, IPIV, JPIV, TEMP )CALL DGESC2( N, Z, LDZ, XP, IPIV, JPIV, TEMP )IF( DASUM( N, XP, 1 ).GT.DASUM( N, RHS, 1 ) )$ CALL DCOPY( N, XP, 1, RHS, 1 )** Compute the sum of squares*CALL DLASSQ( N, RHS, 1, RDSCAL, RDSUM )*END IF*RETURN** End of DLATDF*END*> \brief \b DLATPS solves a triangular system of equations with the matrix held in packed storage.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATPS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatps.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatps.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatps.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATPS( UPLO, TRANS, DIAG, NORMIN, N, AP, X, SCALE,* CNORM, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, NORMIN, TRANS, UPLO* INTEGER INFO, N* DOUBLE PRECISION SCALE* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), CNORM( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLATPS solves one of the triangular systems*>*> A *x = s*b or A**T*x = s*b*>*> with scaling to prevent overflow, where A is an upper or lower*> triangular matrix stored in packed form. Here A**T denotes the*> transpose of A, x and b are n-element vectors, and s is a scaling*> factor, usually less than or equal to 1, chosen so that the*> components of x will be less than the overflow threshold. If the*> unscaled problem will not cause overflow, the Level 2 BLAS routine*> DTPSV is called. If the matrix A is singular (A(j,j) = 0 for some j),*> then s is set to 0 and a non-trivial solution to A*x = 0 is returned.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower triangular.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the operation applied to A.*> = 'N': Solve A * x = s*b (No transpose)*> = 'T': Solve A**T* x = s*b (Transpose)*> = 'C': Solve A**T* x = s*b (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A is unit triangular.*> = 'N': Non-unit triangular*> = 'U': Unit triangular*> \endverbatim*>*> \param[in] NORMIN*> \verbatim*> NORMIN is CHARACTER*1*> Specifies whether CNORM has been set or not.*> = 'Y': CNORM contains the column norms on entry*> = 'N': CNORM is not set on entry. On exit, the norms will*> be computed and stored in CNORM.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangular matrix A, packed columnwise in*> a linear array. The j-th column of A is stored in the array*> AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> On entry, the right hand side b of the triangular system.*> On exit, X is overwritten by the solution vector x.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> The scaling factor s for the triangular system*> A * x = s*b or A**T* x = s*b.*> If SCALE = 0, the matrix A is singular or badly scaled, and*> the vector x is an exact or approximate solution to A*x = 0.*> \endverbatim*>*> \param[in,out] CNORM*> \verbatim*> CNORM is DOUBLE PRECISION array, dimension (N)*>*> If NORMIN = 'Y', CNORM is an input argument and CNORM(j)*> contains the norm of the off-diagonal part of the j-th column*> of A. If TRANS = 'N', CNORM(j) must be greater than or equal*> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)*> must be greater than or equal to the 1-norm.*>*> If NORMIN = 'N', CNORM is an output argument and CNORM(j)*> returns the 1-norm of the offdiagonal part of the j-th column*> of A.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> A rough bound on x is computed; if that is less than overflow, DTPSV*> is called, otherwise, specific code is used which checks for possible*> overflow or divide-by-zero at every operation.*>*> A columnwise scheme is used for solving A*x = b. The basic algorithm*> if A is lower triangular is*>*> x[1:n] := b[1:n]*> for j = 1, ..., n*> x(j) := x(j) / A(j,j)*> x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]*> end*>*> Define bounds on the components of x after j iterations of the loop:*> M(j) = bound on x[1:j]*> G(j) = bound on x[j+1:n]*> Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.*>*> Then for iteration j+1 we have*> M(j+1) <= G(j) / | A(j+1,j+1) |*> G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |*> <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )*>*> where CNORM(j+1) is greater than or equal to the infinity-norm of*> column j+1 of A, not counting the diagonal. Hence*>*> G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )*> 1<=i<=j*> and*>*> |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )*> 1<=i< j*>*> Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTPSV if the*> reciprocal of the largest M(j), j=1,..,n, is larger than*> max(underflow, 1/overflow).*>*> The bound on x(j) is also used to determine when a step in the*> columnwise method can be performed without fear of overflow. If*> the computed bound is greater than a large constant, x is scaled to*> prevent overflow, but if the bound overflows, x is set to 0, x(j) to*> 1, and scale to 0, and a non-trivial solution to A*x = 0 is found.*>*> Similarly, a row-wise scheme is used to solve A**T*x = b. The basic*> algorithm for A upper triangular is*>*> for j = 1, ..., n*> x(j) := ( b(j) - A[1:j-1,j]**T * x[1:j-1] ) / A(j,j)*> end*>*> We simultaneously compute two bounds*> G(j) = bound on ( b(i) - A[1:i-1,i]**T * x[1:i-1] ), 1<=i<=j*> M(j) = bound on x(i), 1<=i<=j*>*> The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we*> add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.*> Then the bound on x(j) is*>*> M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |*>*> <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )*> 1<=i<=j*>*> and we can safely call DTPSV if 1/M(n) and 1/G(n) are both greater*> than max(underflow, 1/overflow).*> \endverbatim*>* =====================================================================SUBROUTINE DLATPS( UPLO, TRANS, DIAG, NORMIN, N, AP, X, SCALE,$ CNORM, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORMIN, TRANS, UPLOINTEGER INFO, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), CNORM( * ), X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERINTEGER I, IMAX, IP, J, JFIRST, JINC, JLAST, JLENDOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,$ TMAX, TSCAL, USCAL, XBND, XJ, XMAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DASUM, DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DASUM, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )** Test the input parameters.*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.$ LSAME( NORMIN, 'N' ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLATPS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine machine dependent parameters to control overflow.*SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )BIGNUM = ONE / SMLNUMSCALE = ONE*IF( LSAME( NORMIN, 'N' ) ) THEN** Compute the 1-norm of each column, not including the diagonal.*IF( UPPER ) THEN** A is upper triangular.*IP = 1DO 10 J = 1, NCNORM( J ) = DASUM( J-1, AP( IP ), 1 )IP = IP + J10 CONTINUEELSE** A is lower triangular.*IP = 1DO 20 J = 1, N - 1CNORM( J ) = DASUM( N-J, AP( IP+1 ), 1 )IP = IP + N - J + 120 CONTINUECNORM( N ) = ZEROEND IFEND IF** Scale the column norms by TSCAL if the maximum element in CNORM is* greater than BIGNUM.*IMAX = IDAMAX( N, CNORM, 1 )TMAX = CNORM( IMAX )IF( TMAX.LE.BIGNUM ) THENTSCAL = ONEELSETSCAL = ONE / ( SMLNUM*TMAX )CALL DSCAL( N, TSCAL, CNORM, 1 )END IF** Compute a bound on the computed solution vector to see if the* Level 2 BLAS routine DTPSV can be used.*J = IDAMAX( N, X, 1 )XMAX = ABS( X( J ) )XBND = XMAXIF( NOTRAN ) THEN** Compute the growth in A * x = b.*IF( UPPER ) THENJFIRST = NJLAST = 1JINC = -1ELSEJFIRST = 1JLAST = NJINC = 1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 50END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, G(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWIP = JFIRST*( JFIRST+1 ) / 2JLEN = NDO 30 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** M(j) = G(j-1) / abs(A(j,j))*TJJ = ABS( AP( IP ) )XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN** G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )*GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )ELSE** G(j) could overflow, set GROW to 0.*GROW = ZEROEND IFIP = IP + JINC*JLENJLEN = JLEN - 130 CONTINUEGROW = XBNDELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 40 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** G(j) = G(j-1)*( 1 + CNORM(j) )*GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )40 CONTINUEEND IF50 CONTINUE*ELSE** Compute the growth in A**T * x = b.*IF( UPPER ) THENJFIRST = 1JLAST = NJINC = 1ELSEJFIRST = NJLAST = 1JINC = -1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 80END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, M(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWIP = JFIRST*( JFIRST+1 ) / 2JLEN = 1DO 60 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )*XJ = ONE + CNORM( J )GROW = MIN( GROW, XBND / XJ )** M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))*TJJ = ABS( AP( IP ) )IF( XJ.GT.TJJ )$ XBND = XBND*( TJJ / XJ )JLEN = JLEN + 1IP = IP + JINC*JLEN60 CONTINUEGROW = MIN( GROW, XBND )ELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 70 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = ( 1 + CNORM(j) )*G(j-1)*XJ = ONE + CNORM( J )GROW = GROW / XJ70 CONTINUEEND IF80 CONTINUEEND IF*IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN** Use the Level 2 BLAS solve if the reciprocal of the bound on* elements of X is not too small.*CALL DTPSV( UPLO, TRANS, DIAG, N, AP, X, 1 )ELSE** Use a Level 1 BLAS solve, scaling intermediate results.*IF( XMAX.GT.BIGNUM ) THEN** Scale X so that its components are less than or equal to* BIGNUM in absolute value.*SCALE = BIGNUM / XMAXCALL DSCAL( N, SCALE, X, 1 )XMAX = BIGNUMEND IF*IF( NOTRAN ) THEN** Solve A * x = b*IP = JFIRST*( JFIRST+1 ) / 2DO 110 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) / A(j,j), scaling x if necessary.*XJ = ABS( X( J ) )IF( NOUNIT ) THENTJJS = AP( IP )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 100END IFTJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by 1/b(j).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM* to avoid overflow when dividing by A(j,j).*REC = ( TJJ*BIGNUM ) / XJIF( CNORM( J ).GT.ONE ) THEN** Scale by 1/CNORM(j) to avoid overflow when* multiplying x(j) times column j.*REC = REC / CNORM( J )END IFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A*x = 0.*DO 90 I = 1, NX( I ) = ZERO90 CONTINUEX( J ) = ONEXJ = ONESCALE = ZEROXMAX = ZEROEND IF100 CONTINUE** Scale x if necessary to avoid overflow when adding a* multiple of column j of A.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN** Scale x by 1/(2*abs(x(j))).*REC = REC*HALFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN** Scale x by 1/2.*CALL DSCAL( N, HALF, X, 1 )SCALE = SCALE*HALFEND IF*IF( UPPER ) THENIF( J.GT.1 ) THEN** Compute the update* x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)*CALL DAXPY( J-1, -X( J )*TSCAL, AP( IP-J+1 ), 1, X,$ 1 )I = IDAMAX( J-1, X, 1 )XMAX = ABS( X( I ) )END IFIP = IP - JELSEIF( J.LT.N ) THEN** Compute the update* x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)*CALL DAXPY( N-J, -X( J )*TSCAL, AP( IP+1 ), 1,$ X( J+1 ), 1 )I = J + IDAMAX( N-J, X( J+1 ), 1 )XMAX = ABS( X( I ) )END IFIP = IP + N - J + 1END IF110 CONTINUE*ELSE** Solve A**T * x = b*IP = JFIRST*( JFIRST+1 ) / 2JLEN = 1DO 160 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) - sum A(k,j)*x(k).* k<>j*XJ = ABS( X( J ) )USCAL = TSCALREC = ONE / MAX( XMAX, ONE )IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN** If x(j) could overflow, scale x by 1/(2*XMAX).*REC = REC*HALFIF( NOUNIT ) THENTJJS = AP( IP )*TSCALELSETJJS = TSCALEND IFTJJ = ABS( TJJS )IF( TJJ.GT.ONE ) THEN** Divide by A(j,j) when scaling x if A(j,j) > 1.*REC = MIN( ONE, REC*TJJ )USCAL = USCAL / TJJSEND IFIF( REC.LT.ONE ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*SUMJ = ZEROIF( USCAL.EQ.ONE ) THEN** If the scaling needed for A in the dot product is 1,* call DDOT to perform the dot product.*IF( UPPER ) THENSUMJ = DDOT( J-1, AP( IP-J+1 ), 1, X, 1 )ELSE IF( J.LT.N ) THENSUMJ = DDOT( N-J, AP( IP+1 ), 1, X( J+1 ), 1 )END IFELSE** Otherwise, use in-line code for the dot product.*IF( UPPER ) THENDO 120 I = 1, J - 1SUMJ = SUMJ + ( AP( IP-J+I )*USCAL )*X( I )120 CONTINUEELSE IF( J.LT.N ) THENDO 130 I = 1, N - JSUMJ = SUMJ + ( AP( IP+I )*USCAL )*X( J+I )130 CONTINUEEND IFEND IF*IF( USCAL.EQ.TSCAL ) THEN** Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)* was not used to scale the dotproduct.*X( J ) = X( J ) - SUMJXJ = ABS( X( J ) )IF( NOUNIT ) THEN** Compute x(j) = x(j) / A(j,j), scaling if necessary.*TJJS = AP( IP )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 150END IFTJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale X by 1/abs(x(j)).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.*REC = ( TJJ*BIGNUM ) / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A**T*x = 0.*DO 140 I = 1, NX( I ) = ZERO140 CONTINUEX( J ) = ONESCALE = ZEROXMAX = ZEROEND IF150 CONTINUEELSE** Compute x(j) := x(j) / A(j,j) - sumj if the dot* product has already been divided by 1/A(j,j).*X( J ) = X( J ) / TJJS - SUMJEND IFXMAX = MAX( XMAX, ABS( X( J ) ) )JLEN = JLEN + 1IP = IP + JINC*JLEN160 CONTINUEEND IFSCALE = SCALE / TSCALEND IF** Scale the column norms by 1/TSCAL for return.*IF( TSCAL.NE.ONE ) THENCALL DSCAL( N, ONE / TSCAL, CNORM, 1 )END IF*RETURN** End of DLATPS*END*> \brief \b DLATRD reduces the first nb rows and columns of a symmetric/Hermitian matrix A to real tridiagonal form by an orthogonal similarity transformation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER LDA, LDW, N, NB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), E( * ), TAU( * ), W( LDW, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLATRD reduces NB rows and columns of a real symmetric matrix A to*> symmetric tridiagonal form by an orthogonal similarity*> transformation Q**T * A * Q, and returns the matrices V and W which are*> needed to apply the transformation to the unreduced part of A.*>*> If UPLO = 'U', DLATRD reduces the last NB rows and columns of a*> matrix, of which the upper triangle is supplied;*> if UPLO = 'L', DLATRD reduces the first NB rows and columns of a*> matrix, of which the lower triangle is supplied.*>*> This is an auxiliary routine called by DSYTRD.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The number of rows and columns to be reduced.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n-by-n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n-by-n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*> On exit:*> if UPLO = 'U', the last NB columns have been reduced to*> tridiagonal form, with the diagonal elements overwriting*> the diagonal elements of A; the elements above the diagonal*> with the array TAU, represent the orthogonal matrix Q as a*> product of elementary reflectors;*> if UPLO = 'L', the first NB columns have been reduced to*> tridiagonal form, with the diagonal elements overwriting*> the diagonal elements of A; the elements below the diagonal*> with the array TAU, represent the orthogonal matrix Q as a*> product of elementary reflectors.*> See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= (1,N).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> If UPLO = 'U', E(n-nb:n-1) contains the superdiagonal*> elements of the last NB columns of the reduced matrix;*> if UPLO = 'L', E(1:nb) contains the subdiagonal elements of*> the first NB columns of the reduced matrix.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> The scalar factors of the elementary reflectors, stored in*> TAU(n-nb:n-1) if UPLO = 'U', and in TAU(1:nb) if UPLO = 'L'.*> See Further Details.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (LDW,NB)*> The n-by-nb matrix W required to update the unreduced part*> of A.*> \endverbatim*>*> \param[in] LDW*> \verbatim*> LDW is INTEGER*> The leading dimension of the array W. LDW >= max(1,N).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(n) H(n-1) . . . H(n-nb+1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(i:n) = 0 and v(i-1) = 1; v(1:i-1) is stored on exit in A(1:i-1,i),*> and tau in TAU(i-1).*>*> If UPLO = 'L', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(1) H(2) . . . H(nb).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i) = 0 and v(i+1) = 1; v(i+1:n) is stored on exit in A(i+1:n,i),*> and tau in TAU(i).*>*> The elements of the vectors v together form the n-by-nb matrix V*> which is needed, with W, to apply the transformation to the unreduced*> part of the matrix, using a symmetric rank-2k update of the form:*> A := A - V*W**T - W*V**T.*>*> The contents of A on exit are illustrated by the following examples*> with n = 5 and nb = 2:*>*> if UPLO = 'U': if UPLO = 'L':*>*> ( a a a v4 v5 ) ( d )*> ( a a v4 v5 ) ( 1 d )*> ( a 1 v5 ) ( v1 1 a )*> ( d 1 ) ( v1 v2 a a )*> ( d ) ( v1 v2 a a a )*>*> where d denotes a diagonal element of the reduced matrix, a denotes*> an element of the original matrix that is unchanged, and vi denotes*> an element of the vector defining H(i).*> \endverbatim*>* =====================================================================SUBROUTINE DLATRD( UPLO, N, NB, A, LDA, E, TAU, W, LDW )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER LDA, LDW, N, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), E( * ), TAU( * ), W( LDW, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, HALFPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )* ..* .. Local Scalars ..INTEGER I, IWDOUBLE PRECISION ALPHA* ..* .. External Subroutines ..EXTERNAL DAXPY, DGEMV, DLARFG, DSCAL, DSYMV* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 )$ RETURN*IF( LSAME( UPLO, 'U' ) ) THEN** Reduce last NB columns of upper triangle*DO 10 I = N, N - NB + 1, -1IW = I - N + NBIF( I.LT.N ) THEN** Update A(1:i,i)*CALL DGEMV( 'No transpose', I, N-I, -ONE, A( 1, I+1 ),$ LDA, W( I, IW+1 ), LDW, ONE, A( 1, I ), 1 )CALL DGEMV( 'No transpose', I, N-I, -ONE, W( 1, IW+1 ),$ LDW, A( I, I+1 ), LDA, ONE, A( 1, I ), 1 )END IFIF( I.GT.1 ) THEN** Generate elementary reflector H(i) to annihilate* A(1:i-2,i)*CALL DLARFG( I-1, A( I-1, I ), A( 1, I ), 1, TAU( I-1 ) )E( I-1 ) = A( I-1, I )A( I-1, I ) = ONE** Compute W(1:i-1,i)*CALL DSYMV( 'Upper', I-1, ONE, A, LDA, A( 1, I ), 1,$ ZERO, W( 1, IW ), 1 )IF( I.LT.N ) THENCALL DGEMV( 'Transpose', I-1, N-I, ONE, W( 1, IW+1 ),$ LDW, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )CALL DGEMV( 'No transpose', I-1, N-I, -ONE,$ A( 1, I+1 ), LDA, W( I+1, IW ), 1, ONE,$ W( 1, IW ), 1 )CALL DGEMV( 'Transpose', I-1, N-I, ONE, A( 1, I+1 ),$ LDA, A( 1, I ), 1, ZERO, W( I+1, IW ), 1 )CALL DGEMV( 'No transpose', I-1, N-I, -ONE,$ W( 1, IW+1 ), LDW, W( I+1, IW ), 1, ONE,$ W( 1, IW ), 1 )END IFCALL DSCAL( I-1, TAU( I-1 ), W( 1, IW ), 1 )ALPHA = -HALF*TAU( I-1 )*DDOT( I-1, W( 1, IW ), 1,$ A( 1, I ), 1 )CALL DAXPY( I-1, ALPHA, A( 1, I ), 1, W( 1, IW ), 1 )END IF*10 CONTINUEELSE** Reduce first NB columns of lower triangle*DO 20 I = 1, NB** Update A(i:n,i)*CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, A( I, 1 ),$ LDA, W( I, 1 ), LDW, ONE, A( I, I ), 1 )CALL DGEMV( 'No transpose', N-I+1, I-1, -ONE, W( I, 1 ),$ LDW, A( I, 1 ), LDA, ONE, A( I, I ), 1 )IF( I.LT.N ) THEN** Generate elementary reflector H(i) to annihilate* A(i+2:n,i)*CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,$ TAU( I ) )E( I ) = A( I+1, I )A( I+1, I ) = ONE** Compute W(i+1:n,i)*CALL DSYMV( 'Lower', N-I, ONE, A( I+1, I+1 ), LDA,$ A( I+1, I ), 1, ZERO, W( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I, I-1, ONE, W( I+1, 1 ), LDW,$ A( I+1, I ), 1, ZERO, W( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, A( I+1, 1 ),$ LDA, W( 1, I ), 1, ONE, W( I+1, I ), 1 )CALL DGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,$ A( I+1, I ), 1, ZERO, W( 1, I ), 1 )CALL DGEMV( 'No transpose', N-I, I-1, -ONE, W( I+1, 1 ),$ LDW, W( 1, I ), 1, ONE, W( I+1, I ), 1 )CALL DSCAL( N-I, TAU( I ), W( I+1, I ), 1 )ALPHA = -HALF*TAU( I )*DDOT( N-I, W( I+1, I ), 1,$ A( I+1, I ), 1 )CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, W( I+1, I ), 1 )END IF*20 CONTINUEEND IF*RETURN** End of DLATRD*END*> \brief \b DLATRS solves a triangular system of equations with the scale factor set to prevent overflow.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,* CNORM, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, NORMIN, TRANS, UPLO* INTEGER INFO, LDA, N* DOUBLE PRECISION SCALE* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), CNORM( * ), X( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLATRS solves one of the triangular systems*>*> A *x = s*b or A**T *x = s*b*>*> with scaling to prevent overflow. Here A is an upper or lower*> triangular matrix, A**T denotes the transpose of A, x and b are*> n-element vectors, and s is a scaling factor, usually less than*> or equal to 1, chosen so that the components of x will be less than*> the overflow threshold. If the unscaled problem will not cause*> overflow, the Level 2 BLAS routine DTRSV is called. If the matrix A*> is singular (A(j,j) = 0 for some j), then s is set to 0 and a*> non-trivial solution to A*x = 0 is returned.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower triangular.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the operation applied to A.*> = 'N': Solve A * x = s*b (No transpose)*> = 'T': Solve A**T* x = s*b (Transpose)*> = 'C': Solve A**T* x = s*b (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A is unit triangular.*> = 'N': Non-unit triangular*> = 'U': Unit triangular*> \endverbatim*>*> \param[in] NORMIN*> \verbatim*> NORMIN is CHARACTER*1*> Specifies whether CNORM has been set or not.*> = 'Y': CNORM contains the column norms on entry*> = 'N': CNORM is not set on entry. On exit, the norms will*> be computed and stored in CNORM.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The triangular matrix A. If UPLO = 'U', the leading n by n*> upper triangular part of the array A contains the upper*> triangular matrix, and the strictly lower triangular part of*> A is not referenced. If UPLO = 'L', the leading n by n lower*> triangular part of the array A contains the lower triangular*> matrix, and the strictly upper triangular part of A is not*> referenced. If DIAG = 'U', the diagonal elements of A are*> also not referenced and are assumed to be 1.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max (1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (N)*> On entry, the right hand side b of the triangular system.*> On exit, X is overwritten by the solution vector x.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> The scaling factor s for the triangular system*> A * x = s*b or A**T* x = s*b.*> If SCALE = 0, the matrix A is singular or badly scaled, and*> the vector x is an exact or approximate solution to A*x = 0.*> \endverbatim*>*> \param[in,out] CNORM*> \verbatim*> CNORM is DOUBLE PRECISION array, dimension (N)*>*> If NORMIN = 'Y', CNORM is an input argument and CNORM(j)*> contains the norm of the off-diagonal part of the j-th column*> of A. If TRANS = 'N', CNORM(j) must be greater than or equal*> to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)*> must be greater than or equal to the 1-norm.*>*> If NORMIN = 'N', CNORM is an output argument and CNORM(j)*> returns the 1-norm of the offdiagonal part of the j-th column*> of A.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> A rough bound on x is computed; if that is less than overflow, DTRSV*> is called, otherwise, specific code is used which checks for possible*> overflow or divide-by-zero at every operation.*>*> A columnwise scheme is used for solving A*x = b. The basic algorithm*> if A is lower triangular is*>*> x[1:n] := b[1:n]*> for j = 1, ..., n*> x(j) := x(j) / A(j,j)*> x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]*> end*>*> Define bounds on the components of x after j iterations of the loop:*> M(j) = bound on x[1:j]*> G(j) = bound on x[j+1:n]*> Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.*>*> Then for iteration j+1 we have*> M(j+1) <= G(j) / | A(j+1,j+1) |*> G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |*> <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )*>*> where CNORM(j+1) is greater than or equal to the infinity-norm of*> column j+1 of A, not counting the diagonal. Hence*>*> G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )*> 1<=i<=j*> and*>*> |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )*> 1<=i< j*>*> Since |x(j)| <= M(j), we use the Level 2 BLAS routine DTRSV if the*> reciprocal of the largest M(j), j=1,..,n, is larger than*> max(underflow, 1/overflow).*>*> The bound on x(j) is also used to determine when a step in the*> columnwise method can be performed without fear of overflow. If*> the computed bound is greater than a large constant, x is scaled to*> prevent overflow, but if the bound overflows, x is set to 0, x(j) to*> 1, and scale to 0, and a non-trivial solution to A*x = 0 is found.*>*> Similarly, a row-wise scheme is used to solve A**T*x = b. The basic*> algorithm for A upper triangular is*>*> for j = 1, ..., n*> x(j) := ( b(j) - A[1:j-1,j]**T * x[1:j-1] ) / A(j,j)*> end*>*> We simultaneously compute two bounds*> G(j) = bound on ( b(i) - A[1:i-1,i]**T * x[1:i-1] ), 1<=i<=j*> M(j) = bound on x(i), 1<=i<=j*>*> The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we*> add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.*> Then the bound on x(j) is*>*> M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |*>*> <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )*> 1<=i<=j*>*> and we can safely call DTRSV if 1/M(n) and 1/G(n) are both greater*> than max(underflow, 1/overflow).*> \endverbatim*>* =====================================================================SUBROUTINE DLATRS( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,$ CNORM, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORMIN, TRANS, UPLOINTEGER INFO, LDA, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), CNORM( * ), X( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, HALF, ONEPARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERINTEGER I, IMAX, J, JFIRST, JINC, JLASTDOUBLE PRECISION BIGNUM, GROW, REC, SMLNUM, SUMJ, TJJ, TJJS,$ TMAX, TSCAL, USCAL, XBND, XJ, XMAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DASUM, DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DASUM, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DTRSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )** Test the input parameters.*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( .NOT.LSAME( NORMIN, 'Y' ) .AND. .NOT.$ LSAME( NORMIN, 'N' ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLATRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine machine dependent parameters to control overflow.*SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )BIGNUM = ONE / SMLNUMSCALE = ONE*IF( LSAME( NORMIN, 'N' ) ) THEN** Compute the 1-norm of each column, not including the diagonal.*IF( UPPER ) THEN** A is upper triangular.*DO 10 J = 1, NCNORM( J ) = DASUM( J-1, A( 1, J ), 1 )10 CONTINUEELSE** A is lower triangular.*DO 20 J = 1, N - 1CNORM( J ) = DASUM( N-J, A( J+1, J ), 1 )20 CONTINUECNORM( N ) = ZEROEND IFEND IF** Scale the column norms by TSCAL if the maximum element in CNORM is* greater than BIGNUM.*IMAX = IDAMAX( N, CNORM, 1 )TMAX = CNORM( IMAX )IF( TMAX.LE.BIGNUM ) THENTSCAL = ONEELSETSCAL = ONE / ( SMLNUM*TMAX )CALL DSCAL( N, TSCAL, CNORM, 1 )END IF** Compute a bound on the computed solution vector to see if the* Level 2 BLAS routine DTRSV can be used.*J = IDAMAX( N, X, 1 )XMAX = ABS( X( J ) )XBND = XMAXIF( NOTRAN ) THEN** Compute the growth in A * x = b.*IF( UPPER ) THENJFIRST = NJLAST = 1JINC = -1ELSEJFIRST = 1JLAST = NJINC = 1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 50END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, G(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWDO 30 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** M(j) = G(j-1) / abs(A(j,j))*TJJ = ABS( A( J, J ) )XBND = MIN( XBND, MIN( ONE, TJJ )*GROW )IF( TJJ+CNORM( J ).GE.SMLNUM ) THEN** G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )*GROW = GROW*( TJJ / ( TJJ+CNORM( J ) ) )ELSE** G(j) could overflow, set GROW to 0.*GROW = ZEROEND IF30 CONTINUEGROW = XBNDELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 40 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 50** G(j) = G(j-1)*( 1 + CNORM(j) )*GROW = GROW*( ONE / ( ONE+CNORM( J ) ) )40 CONTINUEEND IF50 CONTINUE*ELSE** Compute the growth in A**T * x = b.*IF( UPPER ) THENJFIRST = 1JLAST = NJINC = 1ELSEJFIRST = NJLAST = 1JINC = -1END IF*IF( TSCAL.NE.ONE ) THENGROW = ZEROGO TO 80END IF*IF( NOUNIT ) THEN** A is non-unit triangular.** Compute GROW = 1/G(j) and XBND = 1/M(j).* Initially, M(0) = max{x(i), i=1,...,n}.*GROW = ONE / MAX( XBND, SMLNUM )XBND = GROWDO 60 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )*XJ = ONE + CNORM( J )GROW = MIN( GROW, XBND / XJ )** M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))*TJJ = ABS( A( J, J ) )IF( XJ.GT.TJJ )$ XBND = XBND*( TJJ / XJ )60 CONTINUEGROW = MIN( GROW, XBND )ELSE** A is unit triangular.** Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.*GROW = MIN( ONE, ONE / MAX( XBND, SMLNUM ) )DO 70 J = JFIRST, JLAST, JINC** Exit the loop if the growth factor is too small.*IF( GROW.LE.SMLNUM )$ GO TO 80** G(j) = ( 1 + CNORM(j) )*G(j-1)*XJ = ONE + CNORM( J )GROW = GROW / XJ70 CONTINUEEND IF80 CONTINUEEND IF*IF( ( GROW*TSCAL ).GT.SMLNUM ) THEN** Use the Level 2 BLAS solve if the reciprocal of the bound on* elements of X is not too small.*CALL DTRSV( UPLO, TRANS, DIAG, N, A, LDA, X, 1 )ELSE** Use a Level 1 BLAS solve, scaling intermediate results.*IF( XMAX.GT.BIGNUM ) THEN** Scale X so that its components are less than or equal to* BIGNUM in absolute value.*SCALE = BIGNUM / XMAXCALL DSCAL( N, SCALE, X, 1 )XMAX = BIGNUMEND IF*IF( NOTRAN ) THEN** Solve A * x = b*DO 110 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) / A(j,j), scaling x if necessary.*XJ = ABS( X( J ) )IF( NOUNIT ) THENTJJS = A( J, J )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 100END IFTJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by 1/b(j).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM* to avoid overflow when dividing by A(j,j).*REC = ( TJJ*BIGNUM ) / XJIF( CNORM( J ).GT.ONE ) THEN** Scale by 1/CNORM(j) to avoid overflow when* multiplying x(j) times column j.*REC = REC / CNORM( J )END IFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSXJ = ABS( X( J ) )ELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A*x = 0.*DO 90 I = 1, NX( I ) = ZERO90 CONTINUEX( J ) = ONEXJ = ONESCALE = ZEROXMAX = ZEROEND IF100 CONTINUE** Scale x if necessary to avoid overflow when adding a* multiple of column j of A.*IF( XJ.GT.ONE ) THENREC = ONE / XJIF( CNORM( J ).GT.( BIGNUM-XMAX )*REC ) THEN** Scale x by 1/(2*abs(x(j))).*REC = REC*HALFCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECEND IFELSE IF( XJ*CNORM( J ).GT.( BIGNUM-XMAX ) ) THEN** Scale x by 1/2.*CALL DSCAL( N, HALF, X, 1 )SCALE = SCALE*HALFEND IF*IF( UPPER ) THENIF( J.GT.1 ) THEN** Compute the update* x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)*CALL DAXPY( J-1, -X( J )*TSCAL, A( 1, J ), 1, X,$ 1 )I = IDAMAX( J-1, X, 1 )XMAX = ABS( X( I ) )END IFELSEIF( J.LT.N ) THEN** Compute the update* x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)*CALL DAXPY( N-J, -X( J )*TSCAL, A( J+1, J ), 1,$ X( J+1 ), 1 )I = J + IDAMAX( N-J, X( J+1 ), 1 )XMAX = ABS( X( I ) )END IFEND IF110 CONTINUE*ELSE** Solve A**T * x = b*DO 160 J = JFIRST, JLAST, JINC** Compute x(j) = b(j) - sum A(k,j)*x(k).* k<>j*XJ = ABS( X( J ) )USCAL = TSCALREC = ONE / MAX( XMAX, ONE )IF( CNORM( J ).GT.( BIGNUM-XJ )*REC ) THEN** If x(j) could overflow, scale x by 1/(2*XMAX).*REC = REC*HALFIF( NOUNIT ) THENTJJS = A( J, J )*TSCALELSETJJS = TSCALEND IFTJJ = ABS( TJJS )IF( TJJ.GT.ONE ) THEN** Divide by A(j,j) when scaling x if A(j,j) > 1.*REC = MIN( ONE, REC*TJJ )USCAL = USCAL / TJJSEND IFIF( REC.LT.ONE ) THENCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IF*SUMJ = ZEROIF( USCAL.EQ.ONE ) THEN** If the scaling needed for A in the dot product is 1,* call DDOT to perform the dot product.*IF( UPPER ) THENSUMJ = DDOT( J-1, A( 1, J ), 1, X, 1 )ELSE IF( J.LT.N ) THENSUMJ = DDOT( N-J, A( J+1, J ), 1, X( J+1 ), 1 )END IFELSE** Otherwise, use in-line code for the dot product.*IF( UPPER ) THENDO 120 I = 1, J - 1SUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )120 CONTINUEELSE IF( J.LT.N ) THENDO 130 I = J + 1, NSUMJ = SUMJ + ( A( I, J )*USCAL )*X( I )130 CONTINUEEND IFEND IF*IF( USCAL.EQ.TSCAL ) THEN** Compute x(j) := ( x(j) - sumj ) / A(j,j) if 1/A(j,j)* was not used to scale the dotproduct.*X( J ) = X( J ) - SUMJXJ = ABS( X( J ) )IF( NOUNIT ) THENTJJS = A( J, J )*TSCALELSETJJS = TSCALIF( TSCAL.EQ.ONE )$ GO TO 150END IF** Compute x(j) = x(j) / A(j,j), scaling if necessary.*TJJ = ABS( TJJS )IF( TJJ.GT.SMLNUM ) THEN** abs(A(j,j)) > SMLNUM:*IF( TJJ.LT.ONE ) THENIF( XJ.GT.TJJ*BIGNUM ) THEN** Scale X by 1/abs(x(j)).*REC = ONE / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFEND IFX( J ) = X( J ) / TJJSELSE IF( TJJ.GT.ZERO ) THEN** 0 < abs(A(j,j)) <= SMLNUM:*IF( XJ.GT.TJJ*BIGNUM ) THEN** Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.*REC = ( TJJ*BIGNUM ) / XJCALL DSCAL( N, REC, X, 1 )SCALE = SCALE*RECXMAX = XMAX*RECEND IFX( J ) = X( J ) / TJJSELSE** A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and* scale = 0, and compute a solution to A**T*x = 0.*DO 140 I = 1, NX( I ) = ZERO140 CONTINUEX( J ) = ONESCALE = ZEROXMAX = ZEROEND IF150 CONTINUEELSE** Compute x(j) := x(j) / A(j,j) - sumj if the dot* product has already been divided by 1/A(j,j).*X( J ) = X( J ) / TJJS - SUMJEND IFXMAX = MAX( XMAX, ABS( X( J ) ) )160 CONTINUEEND IFSCALE = SCALE / TSCALEND IF** Scale the column norms by 1/TSCAL for return.*IF( TSCAL.NE.ONE ) THENCALL DSCAL( N, ONE / TSCAL, CNORM, 1 )END IF*RETURN** End of DLATRS*END*> \brief \b DLATRZ factors an upper trapezoidal matrix by means of orthogonal transformations.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATRZ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatrz.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatrz.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatrz.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATRZ( M, N, L, A, LDA, TAU, WORK )** .. Scalar Arguments ..* INTEGER L, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLATRZ factors the M-by-(M+L) real upper trapezoidal matrix*> [ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R 0 ) * Z, by means*> of orthogonal transformations. Z is an (M+L)-by-(M+L) orthogonal*> matrix and, R and A1 are M-by-M upper triangular matrices.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of columns of the matrix A containing the*> meaningful part of the Householder vectors. N-M >= L >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the leading M-by-N upper trapezoidal part of the*> array A must contain the matrix to be factorized.*> On exit, the leading M-by-M upper triangular part of A*> contains the upper triangular matrix R, and elements N-L+1 to*> N of the first M rows of A, with the array TAU, represent the*> orthogonal matrix Z as a product of M elementary reflectors.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (M)*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (M)*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*>*> The factorization is obtained by Householder's method. The kth*> transformation matrix, Z( k ), which is used to introduce zeros into*> the ( m - k + 1 )th row of A, is given in the form*>*> Z( k ) = ( I 0 ),*> ( 0 T( k ) )*>*> where*>*> T( k ) = I - tau*u( k )*u( k )**T, u( k ) = ( 1 ),*> ( 0 )*> ( z( k ) )*>*> tau is a scalar and z( k ) is an l element vector. tau and z( k )*> are chosen to annihilate the elements of the kth row of A2.*>*> The scalar tau is returned in the kth element of TAU and the vector*> u( k ) in the kth row of A2, such that the elements of z( k ) are*> in a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in*> the upper triangular part of A1.*>*> Z is given by*>*> Z = Z( 1 ) * Z( 2 ) * ... * Z( m ).*> \endverbatim*>* =====================================================================SUBROUTINE DLATRZ( M, N, L, A, LDA, TAU, WORK )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER L, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I* ..* .. External Subroutines ..EXTERNAL DLARFG, DLARZ* ..* .. Executable Statements ..** Test the input arguments** Quick return if possible*IF( M.EQ.0 ) THENRETURNELSE IF( M.EQ.N ) THENDO 10 I = 1, NTAU( I ) = ZERO10 CONTINUERETURNEND IF*DO 20 I = M, 1, -1** Generate elementary reflector H(i) to annihilate* [ A(i,i) A(i,n-l+1:n) ]*CALL DLARFG( L+1, A( I, I ), A( I, N-L+1 ), LDA, TAU( I ) )** Apply H(i) to A(1:i-1,i:n) from the right*CALL DLARZ( 'Right', I-1, N-I+1, L, A( I, N-L+1 ), LDA,$ TAU( I ), A( 1, I ), LDA, WORK )*20 CONTINUE*RETURN** End of DLATRZ*END*> \brief \b DLATZM** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLATZM + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlatzm.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlatzm.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlatzm.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLATZM( SIDE, M, N, V, INCV, TAU, C1, C2, LDC, WORK )** .. Scalar Arguments ..* CHARACTER SIDE* INTEGER INCV, LDC, M, N* DOUBLE PRECISION TAU* ..* .. Array Arguments ..* DOUBLE PRECISION C1( LDC, * ), C2( LDC, * ), V( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DORMRZ.*>*> DLATZM applies a Householder matrix generated by DTZRQF to a matrix.*>*> Let P = I - tau*u*u**T, u = ( 1 ),*> ( v )*> where v is an (m-1) vector if SIDE = 'L', or a (n-1) vector if*> SIDE = 'R'.*>*> If SIDE equals 'L', let*> C = [ C1 ] 1*> [ C2 ] m-1*> n*> Then C is overwritten by P*C.*>*> If SIDE equals 'R', let*> C = [ C1, C2 ] m*> 1 n-1*> Then C is overwritten by C*P.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': form P * C*> = 'R': form C * P*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension*> (1 + (M-1)*abs(INCV)) if SIDE = 'L'*> (1 + (N-1)*abs(INCV)) if SIDE = 'R'*> The vector v in the representation of P. V is not used*> if TAU = 0.*> \endverbatim*>*> \param[in] INCV*> \verbatim*> INCV is INTEGER*> The increment between elements of v. INCV <> 0*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION*> The value tau in the representation of P.*> \endverbatim*>*> \param[in,out] C1*> \verbatim*> C1 is DOUBLE PRECISION array, dimension*> (LDC,N) if SIDE = 'L'*> (M,1) if SIDE = 'R'*> On entry, the n-vector C1 if SIDE = 'L', or the m-vector C1*> if SIDE = 'R'.*>*> On exit, the first row of P*C if SIDE = 'L', or the first*> column of C*P if SIDE = 'R'.*> \endverbatim*>*> \param[in,out] C2*> \verbatim*> C2 is DOUBLE PRECISION array, dimension*> (LDC, N) if SIDE = 'L'*> (LDC, N-1) if SIDE = 'R'*> On entry, the (m - 1) x n matrix C2 if SIDE = 'L', or the*> m x (n - 1) matrix C2 if SIDE = 'R'.*>*> On exit, rows 2:m of P*C if SIDE = 'L', or columns 2:m of C*P*> if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the arrays C1 and C2. LDC >= (1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L'*> (M) if SIDE = 'R'*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DLATZM( SIDE, M, N, V, INCV, TAU, C1, C2, LDC, WORK )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDEINTEGER INCV, LDC, M, NDOUBLE PRECISION TAU* ..* .. Array Arguments ..DOUBLE PRECISION C1( LDC, * ), C2( LDC, * ), V( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGER* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..*IF( ( MIN( M, N ).EQ.0 ) .OR. ( TAU.EQ.ZERO ) )$ RETURN*IF( LSAME( SIDE, 'L' ) ) THEN** w := (C1 + v**T * C2)**T*CALL DCOPY( N, C1, LDC, WORK, 1 )CALL DGEMV( 'Transpose', M-1, N, ONE, C2, LDC, V, INCV, ONE,$ WORK, 1 )** [ C1 ] := [ C1 ] - tau* [ 1 ] * w**T* [ C2 ] [ C2 ] [ v ]*CALL DAXPY( N, -TAU, WORK, 1, C1, LDC )CALL DGER( M-1, N, -TAU, V, INCV, WORK, 1, C2, LDC )*ELSE IF( LSAME( SIDE, 'R' ) ) THEN** w := C1 + C2 * v*CALL DCOPY( M, C1, 1, WORK, 1 )CALL DGEMV( 'No transpose', M, N-1, ONE, C2, LDC, V, INCV, ONE,$ WORK, 1 )** [ C1, C2 ] := [ C1, C2 ] - tau* w * [ 1 , v**T]*CALL DAXPY( M, -TAU, WORK, 1, C1, 1 )CALL DGER( M, N-1, -TAU, WORK, 1, V, INCV, C2, LDC )END IF*RETURN** End of DLATZM*END*> \brief \b DLAUU2 computes the product UUH or LHL, where U and L are upper or lower triangular matrices (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAUU2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlauu2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlauu2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlauu2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAUU2( UPLO, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAUU2 computes the product U * U**T or L**T * L, where the triangular*> factor U or L is stored in the upper or lower triangular part of*> the array A.*>*> If UPLO = 'U' or 'u' then the upper triangle of the result is stored,*> overwriting the factor U in A.*> If UPLO = 'L' or 'l' then the lower triangle of the result is stored,*> overwriting the factor L in A.*>*> This is the unblocked form of the algorithm, calling Level 2 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the triangular factor stored in the array A*> is upper or lower triangular:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the triangular factor U or L. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the triangular factor U or L.*> On exit, if UPLO = 'U', the upper triangle of A is*> overwritten with the upper triangle of the product U * U**T;*> if UPLO = 'L', the lower triangle of A is overwritten with*> the lower triangle of the product L**T * L.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAUU2( UPLO, N, A, LDA, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER IDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. External Subroutines ..EXTERNAL DGEMV, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAUU2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( UPPER ) THEN** Compute the product U * U**T.*DO 10 I = 1, NAII = A( I, I )IF( I.LT.N ) THENA( I, I ) = DDOT( N-I+1, A( I, I ), LDA, A( I, I ), LDA )CALL DGEMV( 'No transpose', I-1, N-I, ONE, A( 1, I+1 ),$ LDA, A( I, I+1 ), LDA, AII, A( 1, I ), 1 )ELSECALL DSCAL( I, AII, A( 1, I ), 1 )END IF10 CONTINUE*ELSE** Compute the product L**T * L.*DO 20 I = 1, NAII = A( I, I )IF( I.LT.N ) THENA( I, I ) = DDOT( N-I+1, A( I, I ), 1, A( I, I ), 1 )CALL DGEMV( 'Transpose', N-I, I-1, ONE, A( I+1, 1 ), LDA,$ A( I+1, I ), 1, AII, A( I, 1 ), LDA )ELSECALL DSCAL( I, AII, A( I, 1 ), LDA )END IF20 CONTINUEEND IF*RETURN** End of DLAUU2*END*> \brief \b DLAUUM computes the product UUH or LHL, where U and L are upper or lower triangular matrices (blocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DLAUUM + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlauum.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlauum.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlauum.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DLAUUM( UPLO, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DLAUUM computes the product U * U**T or L**T * L, where the triangular*> factor U or L is stored in the upper or lower triangular part of*> the array A.*>*> If UPLO = 'U' or 'u' then the upper triangle of the result is stored,*> overwriting the factor U in A.*> If UPLO = 'L' or 'l' then the lower triangle of the result is stored,*> overwriting the factor L in A.*>*> This is the blocked form of the algorithm, calling Level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the triangular factor stored in the array A*> is upper or lower triangular:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the triangular factor U or L. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the triangular factor U or L.*> On exit, if UPLO = 'U', the upper triangle of A is*> overwritten with the upper triangle of the product U * U**T;*> if UPLO = 'L', the lower triangle of A is overwritten with*> the lower triangle of the product L**T * L.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DLAUUM( UPLO, N, A, LDA, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IB, NB* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DGEMM, DLAUU2, DSYRK, DTRMM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DLAUUM', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine the block size for this environment.*NB = ILAENV( 1, 'DLAUUM', UPLO, N, -1, -1, -1 )*IF( NB.LE.1 .OR. NB.GE.N ) THEN** Use unblocked code*CALL DLAUU2( UPLO, N, A, LDA, INFO )ELSE** Use blocked code*IF( UPPER ) THEN** Compute the product U * U**T.*DO 10 I = 1, N, NBIB = MIN( NB, N-I+1 )CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Non-unit',$ I-1, IB, ONE, A( I, I ), LDA, A( 1, I ),$ LDA )CALL DLAUU2( 'Upper', IB, A( I, I ), LDA, INFO )IF( I+IB.LE.N ) THENCALL DGEMM( 'No transpose', 'Transpose', I-1, IB,$ N-I-IB+1, ONE, A( 1, I+IB ), LDA,$ A( I, I+IB ), LDA, ONE, A( 1, I ), LDA )CALL DSYRK( 'Upper', 'No transpose', IB, N-I-IB+1,$ ONE, A( I, I+IB ), LDA, ONE, A( I, I ),$ LDA )END IF10 CONTINUEELSE** Compute the product L**T * L.*DO 20 I = 1, N, NBIB = MIN( NB, N-I+1 )CALL DTRMM( 'Left', 'Lower', 'Transpose', 'Non-unit', IB,$ I-1, ONE, A( I, I ), LDA, A( I, 1 ), LDA )CALL DLAUU2( 'Lower', IB, A( I, I ), LDA, INFO )IF( I+IB.LE.N ) THENCALL DGEMM( 'Transpose', 'No transpose', IB, I-1,$ N-I-IB+1, ONE, A( I+IB, I ), LDA,$ A( I+IB, 1 ), LDA, ONE, A( I, 1 ), LDA )CALL DSYRK( 'Lower', 'Transpose', IB, N-I-IB+1, ONE,$ A( I+IB, I ), LDA, ONE, A( I, I ), LDA )END IF20 CONTINUEEND IFEND IF*RETURN** End of DLAUUM*END*> \brief \b DOPGTR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DOPGTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dopgtr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dopgtr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dopgtr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DOPGTR( UPLO, N, AP, TAU, Q, LDQ, WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDQ, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), Q( LDQ, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DOPGTR generates a real orthogonal matrix Q which is defined as the*> product of n-1 elementary reflectors H(i) of order n, as returned by*> DSPTRD using packed storage:*>*> if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),*>*> if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangular packed storage used in previous*> call to DSPTRD;*> = 'L': Lower triangular packed storage used in previous*> call to DSPTRD.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix Q. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The vectors which define the elementary reflectors, as*> returned by DSPTRD.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DSPTRD.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> The N-by-N orthogonal matrix Q.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N-1)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DOPGTR( UPLO, N, AP, TAU, Q, LDQ, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDQ, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), Q( LDQ, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IINFO, IJ, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DORG2L, DORG2R, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDQ.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DOPGTR', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( UPPER ) THEN** Q was determined by a call to DSPTRD with UPLO = 'U'** Unpack the vectors which define the elementary reflectors and* set the last row and column of Q equal to those of the unit* matrix*IJ = 2DO 20 J = 1, N - 1DO 10 I = 1, J - 1Q( I, J ) = AP( IJ )IJ = IJ + 110 CONTINUEIJ = IJ + 2Q( N, J ) = ZERO20 CONTINUEDO 30 I = 1, N - 1Q( I, N ) = ZERO30 CONTINUEQ( N, N ) = ONE** Generate Q(1:n-1,1:n-1)*CALL DORG2L( N-1, N-1, N-1, Q, LDQ, TAU, WORK, IINFO )*ELSE** Q was determined by a call to DSPTRD with UPLO = 'L'.** Unpack the vectors which define the elementary reflectors and* set the first row and column of Q equal to those of the unit* matrix*Q( 1, 1 ) = ONEDO 40 I = 2, NQ( I, 1 ) = ZERO40 CONTINUEIJ = 3DO 60 J = 2, NQ( 1, J ) = ZERODO 50 I = J + 1, NQ( I, J ) = AP( IJ )IJ = IJ + 150 CONTINUEIJ = IJ + 260 CONTINUEIF( N.GT.1 ) THEN** Generate Q(2:n,2:n)*CALL DORG2R( N-1, N-1, N-1, Q( 2, 2 ), LDQ, TAU, WORK,$ IINFO )END IFEND IFRETURN** End of DOPGTR*END*> \brief \b DOPMTR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DOPMTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dopmtr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dopmtr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dopmtr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DOPMTR( SIDE, UPLO, TRANS, M, N, AP, TAU, C, LDC, WORK,* INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS, UPLO* INTEGER INFO, LDC, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DOPMTR overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix of order nq, with nq = m if*> SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of*> nq-1 elementary reflectors, as returned by DSPTRD using packed*> storage:*>*> if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1);*>*> if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1).*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangular packed storage used in previous*> call to DSPTRD;*> = 'L': Lower triangular packed storage used in previous*> call to DSPTRD.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension*> (M*(M+1)/2) if SIDE = 'L'*> (N*(N+1)/2) if SIDE = 'R'*> The vectors which define the elementary reflectors, as*> returned by DSPTRD. AP is modified by the routine but*> restored on exit.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (M-1) if SIDE = 'L'*> or (N-1) if SIDE = 'R'*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DSPTRD.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L'*> (M) if SIDE = 'R'*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DOPMTR( SIDE, UPLO, TRANS, M, N, AP, TAU, C, LDC, WORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANS, UPLOINTEGER INFO, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL FORWRD, LEFT, NOTRAN, UPPERINTEGER I, I1, I2, I3, IC, II, JC, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )UPPER = LSAME( UPLO, 'U' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DOPMTR', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN*IF( UPPER ) THEN** Q was determined by a call to DSPTRD with UPLO = 'U'*FORWRD = ( LEFT .AND. NOTRAN ) .OR.$ ( .NOT.LEFT .AND. .NOT.NOTRAN )*IF( FORWRD ) THENI1 = 1I2 = NQ - 1I3 = 1II = 2ELSEI1 = NQ - 1I2 = 1I3 = -1II = NQ*( NQ+1 ) / 2 - 1END IF*IF( LEFT ) THENNI = NELSEMI = MEND IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(1:i,1:n)*MI = IELSE** H(i) is applied to C(1:m,1:i)*NI = IEND IF** Apply H(i)*AII = AP( II )AP( II ) = ONECALL DLARF( SIDE, MI, NI, AP( II-I+1 ), 1, TAU( I ), C, LDC,$ WORK )AP( II ) = AII*IF( FORWRD ) THENII = II + I + 2ELSEII = II - I - 1END IF10 CONTINUEELSE** Q was determined by a call to DSPTRD with UPLO = 'L'.*FORWRD = ( LEFT .AND. .NOT.NOTRAN ) .OR.$ ( .NOT.LEFT .AND. NOTRAN )*IF( FORWRD ) THENI1 = 1I2 = NQ - 1I3 = 1II = 2ELSEI1 = NQ - 1I2 = 1I3 = -1II = NQ*( NQ+1 ) / 2 - 1END IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 20 I = I1, I2, I3AII = AP( II )AP( II ) = ONEIF( LEFT ) THEN** H(i) is applied to C(i+1:m,1:n)*MI = M - IIC = I + 1ELSE** H(i) is applied to C(1:m,i+1:n)*NI = N - IJC = I + 1END IF** Apply H(i)*CALL DLARF( SIDE, MI, NI, AP( II ), 1, TAU( I ),$ C( IC, JC ), LDC, WORK )AP( II ) = AII*IF( FORWRD ) THENII = II + NQ - I + 1ELSEII = II - NQ + I - 2END IF20 CONTINUEEND IFRETURN** End of DOPMTR*END*> \brief \b DORBDB** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORBDB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorbdb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorbdb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorbdb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12,* X21, LDX21, X22, LDX22, THETA, PHI, TAUP1,* TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIGNS, TRANS* INTEGER INFO, LDX11, LDX12, LDX21, LDX22, LWORK, M, P,* $ Q* ..* .. Array Arguments ..* DOUBLE PRECISION PHI( * ), THETA( * )* DOUBLE PRECISION TAUP1( * ), TAUP2( * ), TAUQ1( * ), TAUQ2( * ),* $ WORK( * ), X11( LDX11, * ), X12( LDX12, * ),* $ X21( LDX21, * ), X22( LDX22, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORBDB simultaneously bidiagonalizes the blocks of an M-by-M*> partitioned orthogonal matrix X:*>*> [ B11 | B12 0 0 ]*> [ X11 | X12 ] [ P1 | ] [ 0 | 0 -I 0 ] [ Q1 | ]**T*> X = [-----------] = [---------] [----------------] [---------] .*> [ X21 | X22 ] [ | P2 ] [ B21 | B22 0 0 ] [ | Q2 ]*> [ 0 | 0 0 I ]*>*> X11 is P-by-Q. Q must be no larger than P, M-P, or M-Q. (If this is*> not the case, then X must be transposed and/or permuted. This can be*> done in constant time using the TRANS and SIGNS options. See DORCSD*> for details.)*>*> The orthogonal matrices P1, P2, Q1, and Q2 are P-by-P, (M-P)-by-*> (M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. They are*> represented implicitly by Householder vectors.*>*> B11, B12, B21, and B22 are Q-by-Q bidiagonal matrices represented*> implicitly by angles THETA, PHI.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*> = 'T': X, U1, U2, V1T, and V2T are stored in row-major*> order;*> otherwise: X, U1, U2, V1T, and V2T are stored in column-*> major order.*> \endverbatim*>*> \param[in] SIGNS*> \verbatim*> SIGNS is CHARACTER*> = 'O': The lower-left block is made nonpositive (the*> "other" convention);*> otherwise: The upper-right block is made nonpositive (the*> "default" convention).*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows and columns in X.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows in X11 and X12. 0 <= P <= M.*> \endverbatim*>*> \param[in] Q*> \verbatim*> Q is INTEGER*> The number of columns in X11 and X21. 0 <= Q <=*> MIN(P,M-P,M-Q).*> \endverbatim*>*> \param[in,out] X11*> \verbatim*> X11 is DOUBLE PRECISION array, dimension (LDX11,Q)*> On entry, the top-left block of the orthogonal matrix to be*> reduced. On exit, the form depends on TRANS:*> If TRANS = 'N', then*> the columns of tril(X11) specify reflectors for P1,*> the rows of triu(X11,1) specify reflectors for Q1;*> else TRANS = 'T', and*> the rows of triu(X11) specify reflectors for P1,*> the columns of tril(X11,-1) specify reflectors for Q1.*> \endverbatim*>*> \param[in] LDX11*> \verbatim*> LDX11 is INTEGER*> The leading dimension of X11. If TRANS = 'N', then LDX11 >=*> P; else LDX11 >= Q.*> \endverbatim*>*> \param[in,out] X12*> \verbatim*> X12 is DOUBLE PRECISION array, dimension (LDX12,M-Q)*> On entry, the top-right block of the orthogonal matrix to*> be reduced. On exit, the form depends on TRANS:*> If TRANS = 'N', then*> the rows of triu(X12) specify the first P reflectors for*> Q2;*> else TRANS = 'T', and*> the columns of tril(X12) specify the first P reflectors*> for Q2.*> \endverbatim*>*> \param[in] LDX12*> \verbatim*> LDX12 is INTEGER*> The leading dimension of X12. If TRANS = 'N', then LDX12 >=*> P; else LDX11 >= M-Q.*> \endverbatim*>*> \param[in,out] X21*> \verbatim*> X21 is DOUBLE PRECISION array, dimension (LDX21,Q)*> On entry, the bottom-left block of the orthogonal matrix to*> be reduced. On exit, the form depends on TRANS:*> If TRANS = 'N', then*> the columns of tril(X21) specify reflectors for P2;*> else TRANS = 'T', and*> the rows of triu(X21) specify reflectors for P2.*> \endverbatim*>*> \param[in] LDX21*> \verbatim*> LDX21 is INTEGER*> The leading dimension of X21. If TRANS = 'N', then LDX21 >=*> M-P; else LDX21 >= Q.*> \endverbatim*>*> \param[in,out] X22*> \verbatim*> X22 is DOUBLE PRECISION array, dimension (LDX22,M-Q)*> On entry, the bottom-right block of the orthogonal matrix to*> be reduced. On exit, the form depends on TRANS:*> If TRANS = 'N', then*> the rows of triu(X22(Q+1:M-P,P+1:M-Q)) specify the last*> M-P-Q reflectors for Q2,*> else TRANS = 'T', and*> the columns of tril(X22(P+1:M-Q,Q+1:M-P)) specify the last*> M-P-Q reflectors for P2.*> \endverbatim*>*> \param[in] LDX22*> \verbatim*> LDX22 is INTEGER*> The leading dimension of X22. If TRANS = 'N', then LDX22 >=*> M-P; else LDX22 >= M-Q.*> \endverbatim*>*> \param[out] THETA*> \verbatim*> THETA is DOUBLE PRECISION array, dimension (Q)*> The entries of the bidiagonal blocks B11, B12, B21, B22 can*> be computed from the angles THETA and PHI. See Further*> Details.*> \endverbatim*>*> \param[out] PHI*> \verbatim*> PHI is DOUBLE PRECISION array, dimension (Q-1)*> The entries of the bidiagonal blocks B11, B12, B21, B22 can*> be computed from the angles THETA and PHI. See Further*> Details.*> \endverbatim*>*> \param[out] TAUP1*> \verbatim*> TAUP1 is DOUBLE PRECISION array, dimension (P)*> The scalar factors of the elementary reflectors that define*> P1.*> \endverbatim*>*> \param[out] TAUP2*> \verbatim*> TAUP2 is DOUBLE PRECISION array, dimension (M-P)*> The scalar factors of the elementary reflectors that define*> P2.*> \endverbatim*>*> \param[out] TAUQ1*> \verbatim*> TAUQ1 is DOUBLE PRECISION array, dimension (Q)*> The scalar factors of the elementary reflectors that define*> Q1.*> \endverbatim*>*> \param[out] TAUQ2*> \verbatim*> TAUQ2 is DOUBLE PRECISION array, dimension (M-Q)*> The scalar factors of the elementary reflectors that define*> Q2.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= M-Q.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The bidiagonal blocks B11, B12, B21, and B22 are represented*> implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ...,*> PHI(Q-1). B11 and B21 are upper bidiagonal, while B21 and B22 are*> lower bidiagonal. Every entry in each bidiagonal band is a product*> of a sine or cosine of a THETA with a sine or cosine of a PHI. See*> [1] or DORCSD for details.*>*> P1, P2, Q1, and Q2 are represented as products of elementary*> reflectors. See DORCSD for details on generating P1, P2, Q1, and Q2*> using DORGQR and DORGLQ.*> \endverbatim**> \par References:* ================*>*> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.*> Algorithms, 50(1):33-65, 2009.*>* =====================================================================SUBROUTINE DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12,$ X21, LDX21, X22, LDX22, THETA, PHI, TAUP1,$ TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIGNS, TRANSINTEGER INFO, LDX11, LDX12, LDX21, LDX22, LWORK, M, P,$ Q* ..* .. Array Arguments ..DOUBLE PRECISION PHI( * ), THETA( * )DOUBLE PRECISION TAUP1( * ), TAUP2( * ), TAUQ1( * ), TAUQ2( * ),$ WORK( * ), X11( LDX11, * ), X12( LDX12, * ),$ X21( LDX21, * ), X22( LDX22, * )* ..** ====================================================================** .. Parameters ..DOUBLE PRECISION REALONEPARAMETER ( REALONE = 1.0D0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL COLMAJOR, LQUERYINTEGER I, LWORKMIN, LWORKOPTDOUBLE PRECISION Z1, Z2, Z3, Z4* ..* .. External Subroutines ..EXTERNAL DAXPY, DLARF, DLARFGP, DSCAL, XERBLA* ..* .. External Functions ..DOUBLE PRECISION DNRM2LOGICAL LSAMEEXTERNAL DNRM2, LSAME* ..* .. Intrinsic FunctionsINTRINSIC ATAN2, COS, MAX, SIN* ..* .. Executable Statements ..** Test input arguments*INFO = 0COLMAJOR = .NOT. LSAME( TRANS, 'T' )IF( .NOT. LSAME( SIGNS, 'O' ) ) THENZ1 = REALONEZ2 = REALONEZ3 = REALONEZ4 = REALONEELSEZ1 = REALONEZ2 = -REALONEZ3 = REALONEZ4 = -REALONEEND IFLQUERY = LWORK .EQ. -1*IF( M .LT. 0 ) THENINFO = -3ELSE IF( P .LT. 0 .OR. P .GT. M ) THENINFO = -4ELSE IF( Q .LT. 0 .OR. Q .GT. P .OR. Q .GT. M-P .OR.$ Q .GT. M-Q ) THENINFO = -5ELSE IF( COLMAJOR .AND. LDX11 .LT. MAX( 1, P ) ) THENINFO = -7ELSE IF( .NOT.COLMAJOR .AND. LDX11 .LT. MAX( 1, Q ) ) THENINFO = -7ELSE IF( COLMAJOR .AND. LDX12 .LT. MAX( 1, P ) ) THENINFO = -9ELSE IF( .NOT.COLMAJOR .AND. LDX12 .LT. MAX( 1, M-Q ) ) THENINFO = -9ELSE IF( COLMAJOR .AND. LDX21 .LT. MAX( 1, M-P ) ) THENINFO = -11ELSE IF( .NOT.COLMAJOR .AND. LDX21 .LT. MAX( 1, Q ) ) THENINFO = -11ELSE IF( COLMAJOR .AND. LDX22 .LT. MAX( 1, M-P ) ) THENINFO = -13ELSE IF( .NOT.COLMAJOR .AND. LDX22 .LT. MAX( 1, M-Q ) ) THENINFO = -13END IF** Compute workspace*IF( INFO .EQ. 0 ) THENLWORKOPT = M - QLWORKMIN = M - QWORK(1) = LWORKOPTIF( LWORK .LT. LWORKMIN .AND. .NOT. LQUERY ) THENINFO = -21END IFEND IFIF( INFO .NE. 0 ) THENCALL XERBLA( 'xORBDB', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Handle column-major and row-major separately*IF( COLMAJOR ) THEN** Reduce columns 1, ..., Q of X11, X12, X21, and X22*DO I = 1, Q*IF( I .EQ. 1 ) THENCALL DSCAL( P-I+1, Z1, X11(I,I), 1 )ELSECALL DSCAL( P-I+1, Z1*COS(PHI(I-1)), X11(I,I), 1 )CALL DAXPY( P-I+1, -Z1*Z3*Z4*SIN(PHI(I-1)), X12(I,I-1),$ 1, X11(I,I), 1 )END IFIF( I .EQ. 1 ) THENCALL DSCAL( M-P-I+1, Z2, X21(I,I), 1 )ELSECALL DSCAL( M-P-I+1, Z2*COS(PHI(I-1)), X21(I,I), 1 )CALL DAXPY( M-P-I+1, -Z2*Z3*Z4*SIN(PHI(I-1)), X22(I,I-1),$ 1, X21(I,I), 1 )END IF*THETA(I) = ATAN2( DNRM2( M-P-I+1, X21(I,I), 1 ),$ DNRM2( P-I+1, X11(I,I), 1 ) )*IF( P .GT. I ) THENCALL DLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) )ELSE IF( P .EQ. I ) THENCALL DLARFGP( P-I+1, X11(I,I), X11(I,I), 1, TAUP1(I) )END IFX11(I,I) = ONEIF ( M-P .GT. I ) THENCALL DLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1,$ TAUP2(I) )ELSE IF ( M-P .EQ. I ) THENCALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I), 1, TAUP2(I) )END IFX21(I,I) = ONE*IF ( Q .GT. I ) THENCALL DLARF( 'L', P-I+1, Q-I, X11(I,I), 1, TAUP1(I),$ X11(I,I+1), LDX11, WORK )END IFIF ( M-Q+1 .GT. I ) THENCALL DLARF( 'L', P-I+1, M-Q-I+1, X11(I,I), 1, TAUP1(I),$ X12(I,I), LDX12, WORK )END IFIF ( Q .GT. I ) THENCALL DLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, TAUP2(I),$ X21(I,I+1), LDX21, WORK )END IFIF ( M-Q+1 .GT. I ) THENCALL DLARF( 'L', M-P-I+1, M-Q-I+1, X21(I,I), 1, TAUP2(I),$ X22(I,I), LDX22, WORK )END IF*IF( I .LT. Q ) THENCALL DSCAL( Q-I, -Z1*Z3*SIN(THETA(I)), X11(I,I+1),$ LDX11 )CALL DAXPY( Q-I, Z2*Z3*COS(THETA(I)), X21(I,I+1), LDX21,$ X11(I,I+1), LDX11 )END IFCALL DSCAL( M-Q-I+1, -Z1*Z4*SIN(THETA(I)), X12(I,I), LDX12 )CALL DAXPY( M-Q-I+1, Z2*Z4*COS(THETA(I)), X22(I,I), LDX22,$ X12(I,I), LDX12 )*IF( I .LT. Q )$ PHI(I) = ATAN2( DNRM2( Q-I, X11(I,I+1), LDX11 ),$ DNRM2( M-Q-I+1, X12(I,I), LDX12 ) )*IF( I .LT. Q ) THENIF ( Q-I .EQ. 1 ) THENCALL DLARFGP( Q-I, X11(I,I+1), X11(I,I+1), LDX11,$ TAUQ1(I) )ELSECALL DLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11,$ TAUQ1(I) )END IFX11(I,I+1) = ONEEND IFIF ( Q+I-1 .LT. M ) THENIF ( M-Q .EQ. I ) THENCALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12,$ TAUQ2(I) )ELSECALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12,$ TAUQ2(I) )END IFEND IFX12(I,I) = ONE*IF( I .LT. Q ) THENCALL DLARF( 'R', P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I),$ X11(I+1,I+1), LDX11, WORK )CALL DLARF( 'R', M-P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I),$ X21(I+1,I+1), LDX21, WORK )END IFIF ( P .GT. I ) THENCALL DLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I),$ X12(I+1,I), LDX12, WORK )END IFIF ( M-P .GT. I ) THENCALL DLARF( 'R', M-P-I, M-Q-I+1, X12(I,I), LDX12,$ TAUQ2(I), X22(I+1,I), LDX22, WORK )END IF*END DO** Reduce columns Q + 1, ..., P of X12, X22*DO I = Q + 1, P*CALL DSCAL( M-Q-I+1, -Z1*Z4, X12(I,I), LDX12 )IF ( I .GE. M-Q ) THENCALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12,$ TAUQ2(I) )ELSECALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12,$ TAUQ2(I) )END IFX12(I,I) = ONE*IF ( P .GT. I ) THENCALL DLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I),$ X12(I+1,I), LDX12, WORK )END IFIF( M-P-Q .GE. 1 )$ CALL DLARF( 'R', M-P-Q, M-Q-I+1, X12(I,I), LDX12,$ TAUQ2(I), X22(Q+1,I), LDX22, WORK )*END DO** Reduce columns P + 1, ..., M - Q of X12, X22*DO I = 1, M - P - Q*CALL DSCAL( M-P-Q-I+1, Z2*Z4, X22(Q+I,P+I), LDX22 )IF ( I .EQ. M-P-Q ) THENCALL DLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I),$ LDX22, TAUQ2(P+I) )ELSECALL DLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I+1),$ LDX22, TAUQ2(P+I) )END IFX22(Q+I,P+I) = ONEIF ( I .LT. M-P-Q ) THENCALL DLARF( 'R', M-P-Q-I, M-P-Q-I+1, X22(Q+I,P+I), LDX22,$ TAUQ2(P+I), X22(Q+I+1,P+I), LDX22, WORK )END IF*END DO*ELSE** Reduce columns 1, ..., Q of X11, X12, X21, X22*DO I = 1, Q*IF( I .EQ. 1 ) THENCALL DSCAL( P-I+1, Z1, X11(I,I), LDX11 )ELSECALL DSCAL( P-I+1, Z1*COS(PHI(I-1)), X11(I,I), LDX11 )CALL DAXPY( P-I+1, -Z1*Z3*Z4*SIN(PHI(I-1)), X12(I-1,I),$ LDX12, X11(I,I), LDX11 )END IFIF( I .EQ. 1 ) THENCALL DSCAL( M-P-I+1, Z2, X21(I,I), LDX21 )ELSECALL DSCAL( M-P-I+1, Z2*COS(PHI(I-1)), X21(I,I), LDX21 )CALL DAXPY( M-P-I+1, -Z2*Z3*Z4*SIN(PHI(I-1)), X22(I-1,I),$ LDX22, X21(I,I), LDX21 )END IF*THETA(I) = ATAN2( DNRM2( M-P-I+1, X21(I,I), LDX21 ),$ DNRM2( P-I+1, X11(I,I), LDX11 ) )*CALL DLARFGP( P-I+1, X11(I,I), X11(I,I+1), LDX11, TAUP1(I) )X11(I,I) = ONEIF ( I .EQ. M-P ) THENCALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I), LDX21,$ TAUP2(I) )ELSECALL DLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21,$ TAUP2(I) )END IFX21(I,I) = ONE*IF ( Q .GT. I ) THENCALL DLARF( 'R', Q-I, P-I+1, X11(I,I), LDX11, TAUP1(I),$ X11(I+1,I), LDX11, WORK )END IFIF ( M-Q+1 .GT. I ) THENCALL DLARF( 'R', M-Q-I+1, P-I+1, X11(I,I), LDX11,$ TAUP1(I), X12(I,I), LDX12, WORK )END IFIF ( Q .GT. I ) THENCALL DLARF( 'R', Q-I, M-P-I+1, X21(I,I), LDX21, TAUP2(I),$ X21(I+1,I), LDX21, WORK )END IFIF ( M-Q+1 .GT. I ) THENCALL DLARF( 'R', M-Q-I+1, M-P-I+1, X21(I,I), LDX21,$ TAUP2(I), X22(I,I), LDX22, WORK )END IF*IF( I .LT. Q ) THENCALL DSCAL( Q-I, -Z1*Z3*SIN(THETA(I)), X11(I+1,I), 1 )CALL DAXPY( Q-I, Z2*Z3*COS(THETA(I)), X21(I+1,I), 1,$ X11(I+1,I), 1 )END IFCALL DSCAL( M-Q-I+1, -Z1*Z4*SIN(THETA(I)), X12(I,I), 1 )CALL DAXPY( M-Q-I+1, Z2*Z4*COS(THETA(I)), X22(I,I), 1,$ X12(I,I), 1 )*IF( I .LT. Q )$ PHI(I) = ATAN2( DNRM2( Q-I, X11(I+1,I), 1 ),$ DNRM2( M-Q-I+1, X12(I,I), 1 ) )*IF( I .LT. Q ) THENIF ( Q-I .EQ. 1) THENCALL DLARFGP( Q-I, X11(I+1,I), X11(I+1,I), 1,$ TAUQ1(I) )ELSECALL DLARFGP( Q-I, X11(I+1,I), X11(I+2,I), 1,$ TAUQ1(I) )END IFX11(I+1,I) = ONEEND IFIF ( M-Q .GT. I ) THENCALL DLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1,$ TAUQ2(I) )ELSECALL DLARFGP( M-Q-I+1, X12(I,I), X12(I,I), 1,$ TAUQ2(I) )END IFX12(I,I) = ONE*IF( I .LT. Q ) THENCALL DLARF( 'L', Q-I, P-I, X11(I+1,I), 1, TAUQ1(I),$ X11(I+1,I+1), LDX11, WORK )CALL DLARF( 'L', Q-I, M-P-I, X11(I+1,I), 1, TAUQ1(I),$ X21(I+1,I+1), LDX21, WORK )END IFCALL DLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, TAUQ2(I),$ X12(I,I+1), LDX12, WORK )IF ( M-P-I .GT. 0 ) THENCALL DLARF( 'L', M-Q-I+1, M-P-I, X12(I,I), 1, TAUQ2(I),$ X22(I,I+1), LDX22, WORK )END IF*END DO** Reduce columns Q + 1, ..., P of X12, X22*DO I = Q + 1, P*CALL DSCAL( M-Q-I+1, -Z1*Z4, X12(I,I), 1 )CALL DLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) )X12(I,I) = ONE*IF ( P .GT. I ) THENCALL DLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, TAUQ2(I),$ X12(I,I+1), LDX12, WORK )END IFIF( M-P-Q .GE. 1 )$ CALL DLARF( 'L', M-Q-I+1, M-P-Q, X12(I,I), 1, TAUQ2(I),$ X22(I,Q+1), LDX22, WORK )*END DO** Reduce columns P + 1, ..., M - Q of X12, X22*DO I = 1, M - P - Q*CALL DSCAL( M-P-Q-I+1, Z2*Z4, X22(P+I,Q+I), 1 )IF ( M-P-Q .EQ. I ) THENCALL DLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I,Q+I), 1,$ TAUQ2(P+I) )ELSECALL DLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I+1,Q+I), 1,$ TAUQ2(P+I) )CALL DLARF( 'L', M-P-Q-I+1, M-P-Q-I, X22(P+I,Q+I), 1,$ TAUQ2(P+I), X22(P+I,Q+I+1), LDX22, WORK )END IFX22(P+I,Q+I) = ONE*END DO*END IF*RETURN** End of DORBDB*END*> \brief \b DORCSD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORCSD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorcsd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorcsd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorcsd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** RECURSIVE SUBROUTINE DORCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS,* SIGNS, M, P, Q, X11, LDX11, X12,* LDX12, X21, LDX21, X22, LDX22, THETA,* U1, LDU1, U2, LDU2, V1T, LDV1T, V2T,* LDV2T, WORK, LWORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, SIGNS, TRANS* INTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LDX11, LDX12,* $ LDX21, LDX22, LWORK, M, P, Q* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION THETA( * )* DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),* $ V2T( LDV2T, * ), WORK( * ), X11( LDX11, * ),* $ X12( LDX12, * ), X21( LDX21, * ), X22( LDX22,* $ * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORCSD computes the CS decomposition of an M-by-M partitioned*> orthogonal matrix X:*>*> [ I 0 0 | 0 0 0 ]*> [ 0 C 0 | 0 -S 0 ]*> [ X11 | X12 ] [ U1 | ] [ 0 0 0 | 0 0 -I ] [ V1 | ]**T*> X = [-----------] = [---------] [---------------------] [---------] .*> [ X21 | X22 ] [ | U2 ] [ 0 0 0 | I 0 0 ] [ | V2 ]*> [ 0 S 0 | 0 C 0 ]*> [ 0 0 I | 0 0 0 ]*>*> X11 is P-by-Q. The orthogonal matrices U1, U2, V1, and V2 are P-by-P,*> (M-P)-by-(M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. C and S are*> R-by-R nonnegative diagonal matrices satisfying C^2 + S^2 = I, in*> which R = MIN(P,M-P,Q,M-Q).*> \endverbatim** Arguments:* ==========**> \param[in] JOBU1*> \verbatim*> JOBU1 is CHARACTER*> = 'Y': U1 is computed;*> otherwise: U1 is not computed.*> \endverbatim*>*> \param[in] JOBU2*> \verbatim*> JOBU2 is CHARACTER*> = 'Y': U2 is computed;*> otherwise: U2 is not computed.*> \endverbatim*>*> \param[in] JOBV1T*> \verbatim*> JOBV1T is CHARACTER*> = 'Y': V1T is computed;*> otherwise: V1T is not computed.*> \endverbatim*>*> \param[in] JOBV2T*> \verbatim*> JOBV2T is CHARACTER*> = 'Y': V2T is computed;*> otherwise: V2T is not computed.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*> = 'T': X, U1, U2, V1T, and V2T are stored in row-major*> order;*> otherwise: X, U1, U2, V1T, and V2T are stored in column-*> major order.*> \endverbatim*>*> \param[in] SIGNS*> \verbatim*> SIGNS is CHARACTER*> = 'O': The lower-left block is made nonpositive (the*> "other" convention);*> otherwise: The upper-right block is made nonpositive (the*> "default" convention).*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows and columns in X.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows in X11 and X12. 0 <= P <= M.*> \endverbatim*>*> \param[in] Q*> \verbatim*> Q is INTEGER*> The number of columns in X11 and X21. 0 <= Q <= M.*> \endverbatim*>*> \param[in,out] X11*> \verbatim*> X11 is DOUBLE PRECISION array, dimension (LDX11,Q)*> On entry, part of the orthogonal matrix whose CSD is desired.*> \endverbatim*>*> \param[in] LDX11*> \verbatim*> LDX11 is INTEGER*> The leading dimension of X11. LDX11 >= MAX(1,P).*> \endverbatim*>*> \param[in,out] X12*> \verbatim*> X12 is DOUBLE PRECISION array, dimension (LDX12,M-Q)*> On entry, part of the orthogonal matrix whose CSD is desired.*> \endverbatim*>*> \param[in] LDX12*> \verbatim*> LDX12 is INTEGER*> The leading dimension of X12. LDX12 >= MAX(1,P).*> \endverbatim*>*> \param[in,out] X21*> \verbatim*> X21 is DOUBLE PRECISION array, dimension (LDX21,Q)*> On entry, part of the orthogonal matrix whose CSD is desired.*> \endverbatim*>*> \param[in] LDX21*> \verbatim*> LDX21 is INTEGER*> The leading dimension of X11. LDX21 >= MAX(1,M-P).*> \endverbatim*>*> \param[in,out] X22*> \verbatim*> X22 is DOUBLE PRECISION array, dimension (LDX22,M-Q)*> On entry, part of the orthogonal matrix whose CSD is desired.*> \endverbatim*>*> \param[in] LDX22*> \verbatim*> LDX22 is INTEGER*> The leading dimension of X11. LDX22 >= MAX(1,M-P).*> \endverbatim*>*> \param[out] THETA*> \verbatim*> THETA is DOUBLE PRECISION array, dimension (R), in which R =*> MIN(P,M-P,Q,M-Q).*> C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and*> S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ).*> \endverbatim*>*> \param[out] U1*> \verbatim*> U1 is DOUBLE PRECISION array, dimension (LDU1,P)*> If JOBU1 = 'Y', U1 contains the P-by-P orthogonal matrix U1.*> \endverbatim*>*> \param[in] LDU1*> \verbatim*> LDU1 is INTEGER*> The leading dimension of U1. If JOBU1 = 'Y', LDU1 >=*> MAX(1,P).*> \endverbatim*>*> \param[out] U2*> \verbatim*> U2 is DOUBLE PRECISION array, dimension (LDU2,M-P)*> If JOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) orthogonal*> matrix U2.*> \endverbatim*>*> \param[in] LDU2*> \verbatim*> LDU2 is INTEGER*> The leading dimension of U2. If JOBU2 = 'Y', LDU2 >=*> MAX(1,M-P).*> \endverbatim*>*> \param[out] V1T*> \verbatim*> V1T is DOUBLE PRECISION array, dimension (LDV1T,Q)*> If JOBV1T = 'Y', V1T contains the Q-by-Q matrix orthogonal*> matrix V1**T.*> \endverbatim*>*> \param[in] LDV1T*> \verbatim*> LDV1T is INTEGER*> The leading dimension of V1T. If JOBV1T = 'Y', LDV1T >=*> MAX(1,Q).*> \endverbatim*>*> \param[out] V2T*> \verbatim*> V2T is DOUBLE PRECISION array, dimension (LDV2T,M-Q)*> If JOBV2T = 'Y', V2T contains the (M-Q)-by-(M-Q) orthogonal*> matrix V2**T.*> \endverbatim*>*> \param[in] LDV2T*> \verbatim*> LDV2T is INTEGER*> The leading dimension of V2T. If JOBV2T = 'Y', LDV2T >=*> MAX(1,M-Q).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> If INFO > 0 on exit, WORK(2:R) contains the values PHI(1),*> ..., PHI(R-1) that, together with THETA(1), ..., THETA(R),*> define the matrix in intermediate bidiagonal-block form*> remaining after nonconvergence. INFO specifies the number*> of nonzero PHI's.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the work array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (M-MIN(P, M-P, Q, M-Q))*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: DBBCSD did not converge. See the description of WORK*> above for details.*> \endverbatim**> \par References:* ================*>*> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.*> Algorithms, 50(1):33-65, 2009.** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERcomputational** =====================================================================RECURSIVE SUBROUTINE DORCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS,$ SIGNS, M, P, Q, X11, LDX11, X12,$ LDX12, X21, LDX21, X22, LDX22, THETA,$ U1, LDU1, U2, LDU2, V1T, LDV1T, V2T,$ LDV2T, WORK, LWORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, SIGNS, TRANSINTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LDX11, LDX12,$ LDX21, LDX22, LWORK, M, P, Q* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION THETA( * )DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),$ V2T( LDV2T, * ), WORK( * ), X11( LDX11, * ),$ X12( LDX12, * ), X21( LDX21, * ), X22( LDX22,$ * )* ..** ===================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D0,$ ZERO = 0.0D0 )* ..* .. Local Scalars ..CHARACTER TRANST, SIGNSTINTEGER CHILDINFO, I, IB11D, IB11E, IB12D, IB12E,$ IB21D, IB21E, IB22D, IB22E, IBBCSD, IORBDB,$ IORGLQ, IORGQR, IPHI, ITAUP1, ITAUP2, ITAUQ1,$ ITAUQ2, J, LBBCSDWORK, LBBCSDWORKMIN,$ LBBCSDWORKOPT, LORBDBWORK, LORBDBWORKMIN,$ LORBDBWORKOPT, LORGLQWORK, LORGLQWORKMIN,$ LORGLQWORKOPT, LORGQRWORK, LORGQRWORKMIN,$ LORGQRWORKOPT, LWORKMIN, LWORKOPTLOGICAL COLMAJOR, DEFAULTSIGNS, LQUERY, WANTU1, WANTU2,$ WANTV1T, WANTV2T* ..* .. External Subroutines ..EXTERNAL DBBCSD, DLACPY, DLAPMR, DLAPMT,$ DORBDB, DORGLQ, DORGQR, XERBLA* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Intrinsic FunctionsINTRINSIC INT, MAX, MIN* ..* .. Executable Statements ..** Test input arguments*INFO = 0WANTU1 = LSAME( JOBU1, 'Y' )WANTU2 = LSAME( JOBU2, 'Y' )WANTV1T = LSAME( JOBV1T, 'Y' )WANTV2T = LSAME( JOBV2T, 'Y' )COLMAJOR = .NOT. LSAME( TRANS, 'T' )DEFAULTSIGNS = .NOT. LSAME( SIGNS, 'O' )LQUERY = LWORK .EQ. -1IF( M .LT. 0 ) THENINFO = -7ELSE IF( P .LT. 0 .OR. P .GT. M ) THENINFO = -8ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THENINFO = -9ELSE IF ( COLMAJOR .AND. LDX11 .LT. MAX( 1, P ) ) THENINFO = -11ELSE IF (.NOT. COLMAJOR .AND. LDX11 .LT. MAX( 1, Q ) ) THENINFO = -11ELSE IF (COLMAJOR .AND. LDX12 .LT. MAX( 1, P ) ) THENINFO = -13ELSE IF (.NOT. COLMAJOR .AND. LDX12 .LT. MAX( 1, M-Q ) ) THENINFO = -13ELSE IF (COLMAJOR .AND. LDX21 .LT. MAX( 1, M-P ) ) THENINFO = -15ELSE IF (.NOT. COLMAJOR .AND. LDX21 .LT. MAX( 1, Q ) ) THENINFO = -15ELSE IF (COLMAJOR .AND. LDX22 .LT. MAX( 1, M-P ) ) THENINFO = -17ELSE IF (.NOT. COLMAJOR .AND. LDX22 .LT. MAX( 1, M-Q ) ) THENINFO = -17ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THENINFO = -20ELSE IF( WANTU2 .AND. LDU2 .LT. M-P ) THENINFO = -22ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THENINFO = -24ELSE IF( WANTV2T .AND. LDV2T .LT. M-Q ) THENINFO = -26END IF** Work with transpose if convenient*IF( INFO .EQ. 0 .AND. MIN( P, M-P ) .LT. MIN( Q, M-Q ) ) THENIF( COLMAJOR ) THENTRANST = 'T'ELSETRANST = 'N'END IFIF( DEFAULTSIGNS ) THENSIGNST = 'O'ELSESIGNST = 'D'END IFCALL DORCSD( JOBV1T, JOBV2T, JOBU1, JOBU2, TRANST, SIGNST, M,$ Q, P, X11, LDX11, X21, LDX21, X12, LDX12, X22,$ LDX22, THETA, V1T, LDV1T, V2T, LDV2T, U1, LDU1,$ U2, LDU2, WORK, LWORK, IWORK, INFO )RETURNEND IF** Work with permutation [ 0 I; I 0 ] * X * [ 0 I; I 0 ] if* convenient*IF( INFO .EQ. 0 .AND. M-Q .LT. Q ) THENIF( DEFAULTSIGNS ) THENSIGNST = 'O'ELSESIGNST = 'D'END IFCALL DORCSD( JOBU2, JOBU1, JOBV2T, JOBV1T, TRANS, SIGNST, M,$ M-P, M-Q, X22, LDX22, X21, LDX21, X12, LDX12, X11,$ LDX11, THETA, U2, LDU2, U1, LDU1, V2T, LDV2T, V1T,$ LDV1T, WORK, LWORK, IWORK, INFO )RETURNEND IF** Compute workspace*IF( INFO .EQ. 0 ) THEN*IPHI = 2ITAUP1 = IPHI + MAX( 1, Q - 1 )ITAUP2 = ITAUP1 + MAX( 1, P )ITAUQ1 = ITAUP2 + MAX( 1, M - P )ITAUQ2 = ITAUQ1 + MAX( 1, Q )IORGQR = ITAUQ2 + MAX( 1, M - Q )CALL DORGQR( M-Q, M-Q, M-Q, U1, MAX(1,M-Q), U1, WORK, -1,$ CHILDINFO )LORGQRWORKOPT = INT( WORK(1) )LORGQRWORKMIN = MAX( 1, M - Q )IORGLQ = ITAUQ2 + MAX( 1, M - Q )CALL DORGLQ( M-Q, M-Q, M-Q, U1, MAX(1,M-Q), U1, WORK, -1,$ CHILDINFO )LORGLQWORKOPT = INT( WORK(1) )LORGLQWORKMIN = MAX( 1, M - Q )IORBDB = ITAUQ2 + MAX( 1, M - Q )CALL DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12,$ X21, LDX21, X22, LDX22, THETA, V1T, U1, U2, V1T,$ V2T, WORK, -1, CHILDINFO )LORBDBWORKOPT = INT( WORK(1) )LORBDBWORKMIN = LORBDBWORKOPTIB11D = ITAUQ2 + MAX( 1, M - Q )IB11E = IB11D + MAX( 1, Q )IB12D = IB11E + MAX( 1, Q - 1 )IB12E = IB12D + MAX( 1, Q )IB21D = IB12E + MAX( 1, Q - 1 )IB21E = IB21D + MAX( 1, Q )IB22D = IB21E + MAX( 1, Q - 1 )IB22E = IB22D + MAX( 1, Q )IBBCSD = IB22E + MAX( 1, Q - 1 )CALL DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q,$ THETA, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T,$ LDV2T, U1, U1, U1, U1, U1, U1, U1, U1, WORK, -1,$ CHILDINFO )LBBCSDWORKOPT = INT( WORK(1) )LBBCSDWORKMIN = LBBCSDWORKOPTLWORKOPT = MAX( IORGQR + LORGQRWORKOPT, IORGLQ + LORGLQWORKOPT,$ IORBDB + LORBDBWORKOPT, IBBCSD + LBBCSDWORKOPT ) - 1LWORKMIN = MAX( IORGQR + LORGQRWORKMIN, IORGLQ + LORGLQWORKMIN,$ IORBDB + LORBDBWORKOPT, IBBCSD + LBBCSDWORKMIN ) - 1WORK(1) = MAX(LWORKOPT,LWORKMIN)*IF( LWORK .LT. LWORKMIN .AND. .NOT. LQUERY ) THENINFO = -22ELSELORGQRWORK = LWORK - IORGQR + 1LORGLQWORK = LWORK - IORGLQ + 1LORBDBWORK = LWORK - IORBDB + 1LBBCSDWORK = LWORK - IBBCSD + 1END IFEND IF** Abort if any illegal arguments*IF( INFO .NE. 0 ) THENCALL XERBLA( 'DORCSD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Transform to bidiagonal block form*CALL DORBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, X21,$ LDX21, X22, LDX22, THETA, WORK(IPHI), WORK(ITAUP1),$ WORK(ITAUP2), WORK(ITAUQ1), WORK(ITAUQ2),$ WORK(IORBDB), LORBDBWORK, CHILDINFO )** Accumulate Householder reflectors*IF( COLMAJOR ) THENIF( WANTU1 .AND. P .GT. 0 ) THENCALL DLACPY( 'L', P, Q, X11, LDX11, U1, LDU1 )CALL DORGQR( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGQR),$ LORGQRWORK, INFO)END IFIF( WANTU2 .AND. M-P .GT. 0 ) THENCALL DLACPY( 'L', M-P, Q, X21, LDX21, U2, LDU2 )CALL DORGQR( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2),$ WORK(IORGQR), LORGQRWORK, INFO )END IFIF( WANTV1T .AND. Q .GT. 0 ) THENCALL DLACPY( 'U', Q-1, Q-1, X11(1,2), LDX11, V1T(2,2),$ LDV1T )V1T(1, 1) = ONEDO J = 2, QV1T(1,J) = ZEROV1T(J,1) = ZEROEND DOCALL DORGLQ( Q-1, Q-1, Q-1, V1T(2,2), LDV1T, WORK(ITAUQ1),$ WORK(IORGLQ), LORGLQWORK, INFO )END IFIF( WANTV2T .AND. M-Q .GT. 0 ) THENCALL DLACPY( 'U', P, M-Q, X12, LDX12, V2T, LDV2T )IF (M-P .GT. Q) ThenCALL DLACPY( 'U', M-P-Q, M-P-Q, X22(Q+1,P+1), LDX22,$ V2T(P+1,P+1), LDV2T )END IFIF (M .GT. Q) THENCALL DORGLQ( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2),$ WORK(IORGLQ), LORGLQWORK, INFO )END IFEND IFELSEIF( WANTU1 .AND. P .GT. 0 ) THENCALL DLACPY( 'U', Q, P, X11, LDX11, U1, LDU1 )CALL DORGLQ( P, P, Q, U1, LDU1, WORK(ITAUP1), WORK(IORGLQ),$ LORGLQWORK, INFO)END IFIF( WANTU2 .AND. M-P .GT. 0 ) THENCALL DLACPY( 'U', Q, M-P, X21, LDX21, U2, LDU2 )CALL DORGLQ( M-P, M-P, Q, U2, LDU2, WORK(ITAUP2),$ WORK(IORGLQ), LORGLQWORK, INFO )END IFIF( WANTV1T .AND. Q .GT. 0 ) THENCALL DLACPY( 'L', Q-1, Q-1, X11(2,1), LDX11, V1T(2,2),$ LDV1T )V1T(1, 1) = ONEDO J = 2, QV1T(1,J) = ZEROV1T(J,1) = ZEROEND DOCALL DORGQR( Q-1, Q-1, Q-1, V1T(2,2), LDV1T, WORK(ITAUQ1),$ WORK(IORGQR), LORGQRWORK, INFO )END IFIF( WANTV2T .AND. M-Q .GT. 0 ) THENCALL DLACPY( 'L', M-Q, P, X12, LDX12, V2T, LDV2T )CALL DLACPY( 'L', M-P-Q, M-P-Q, X22(P+1,Q+1), LDX22,$ V2T(P+1,P+1), LDV2T )CALL DORGQR( M-Q, M-Q, M-Q, V2T, LDV2T, WORK(ITAUQ2),$ WORK(IORGQR), LORGQRWORK, INFO )END IFEND IF** Compute the CSD of the matrix in bidiagonal-block form*CALL DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, THETA,$ WORK(IPHI), U1, LDU1, U2, LDU2, V1T, LDV1T, V2T,$ LDV2T, WORK(IB11D), WORK(IB11E), WORK(IB12D),$ WORK(IB12E), WORK(IB21D), WORK(IB21E), WORK(IB22D),$ WORK(IB22E), WORK(IBBCSD), LBBCSDWORK, INFO )** Permute rows and columns to place identity submatrices in top-* left corner of (1,1)-block and/or bottom-right corner of (1,2)-* block and/or bottom-right corner of (2,1)-block and/or top-left* corner of (2,2)-block*IF( Q .GT. 0 .AND. WANTU2 ) THENDO I = 1, QIWORK(I) = M - P - Q + IEND DODO I = Q + 1, M - PIWORK(I) = I - QEND DOIF( COLMAJOR ) THENCALL DLAPMT( .FALSE., M-P, M-P, U2, LDU2, IWORK )ELSECALL DLAPMR( .FALSE., M-P, M-P, U2, LDU2, IWORK )END IFEND IFIF( M .GT. 0 .AND. WANTV2T ) THENDO I = 1, PIWORK(I) = M - P - Q + IEND DODO I = P + 1, M - QIWORK(I) = I - PEND DOIF( .NOT. COLMAJOR ) THENCALL DLAPMT( .FALSE., M-Q, M-Q, V2T, LDV2T, IWORK )ELSECALL DLAPMR( .FALSE., M-Q, M-Q, V2T, LDV2T, IWORK )END IFEND IF*RETURN** End DORCSD*END*> \brief \b DORG2L generates all or part of the orthogonal matrix Q from a QL factorization determined by sgeqlf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORG2L + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorg2l.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorg2l.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorg2l.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORG2L( M, N, K, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORG2L generates an m by n real matrix Q with orthonormal columns,*> which is defined as the last n columns of a product of k elementary*> reflectors of order m*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGEQLF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. M >= N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. N >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the (n-k+i)-th column must contain the vector which*> defines the elementary reflector H(i), for i = 1,2,...,k, as*> returned by DGEQLF in the last k columns of its array*> argument A.*> On exit, the m by n matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQLF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORG2L( M, N, K, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, II, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORG2L', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN** Initialise columns 1:n-k to columns of the unit matrix*DO 20 J = 1, N - KDO 10 L = 1, MA( L, J ) = ZERO10 CONTINUEA( M-N+J, J ) = ONE20 CONTINUE*DO 40 I = 1, KII = N - K + I** Apply H(i) to A(1:m-k+i,1:n-k+i) from the left*A( M-N+II, II ) = ONECALL DLARF( 'Left', M-N+II, II-1, A( 1, II ), 1, TAU( I ), A,$ LDA, WORK )CALL DSCAL( M-N+II-1, -TAU( I ), A( 1, II ), 1 )A( M-N+II, II ) = ONE - TAU( I )** Set A(m-k+i+1:m,n-k+i) to zero*DO 30 L = M - N + II + 1, MA( L, II ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORG2L*END*> \brief \b DORG2R generates all or part of the orthogonal matrix Q from a QR factorization determined by sgeqrf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORG2R + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorg2r.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorg2r.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorg2r.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORG2R( M, N, K, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORG2R generates an m by n real matrix Q with orthonormal columns,*> which is defined as the first n columns of a product of k elementary*> reflectors of order m*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGEQRF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. M >= N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. N >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the i-th column must contain the vector which*> defines the elementary reflector H(i), for i = 1,2,...,k, as*> returned by DGEQRF in the first k columns of its array*> argument A.*> On exit, the m-by-n matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQRF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORG2R( M, N, K, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORG2R', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN** Initialise columns k+1:n to columns of the unit matrix*DO 20 J = K + 1, NDO 10 L = 1, MA( L, J ) = ZERO10 CONTINUEA( J, J ) = ONE20 CONTINUE*DO 40 I = K, 1, -1** Apply H(i) to A(i:m,i:n) from the left*IF( I.LT.N ) THENA( I, I ) = ONECALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1, TAU( I ),$ A( I, I+1 ), LDA, WORK )END IFIF( I.LT.M )$ CALL DSCAL( M-I, -TAU( I ), A( I+1, I ), 1 )A( I, I ) = ONE - TAU( I )** Set A(1:i-1,i) to zero*DO 30 L = 1, I - 1A( L, I ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORG2R*END*> \brief \b DORGBR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGBR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgbr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgbr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgbr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER VECT* INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGBR generates one of the real orthogonal matrices Q or P**T*> determined by DGEBRD when reducing a real matrix A to bidiagonal*> form: A = Q * B * P**T. Q and P**T are defined as products of*> elementary reflectors H(i) or G(i) respectively.*>*> If VECT = 'Q', A is assumed to have been an M-by-K matrix, and Q*> is of order M:*> if m >= k, Q = H(1) H(2) . . . H(k) and DORGBR returns the first n*> columns of Q, where m >= n >= k;*> if m < k, Q = H(1) H(2) . . . H(m-1) and DORGBR returns Q as an*> M-by-M matrix.*>*> If VECT = 'P', A is assumed to have been a K-by-N matrix, and P**T*> is of order N:*> if k < n, P**T = G(k) . . . G(2) G(1) and DORGBR returns the first m*> rows of P**T, where n >= m >= k;*> if k >= n, P**T = G(n-1) . . . G(2) G(1) and DORGBR returns P**T as*> an N-by-N matrix.*> \endverbatim** Arguments:* ==========**> \param[in] VECT*> \verbatim*> VECT is CHARACTER*1*> Specifies whether the matrix Q or the matrix P**T is*> required, as defined in the transformation applied by DGEBRD:*> = 'Q': generate Q;*> = 'P': generate P**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q or P**T to be returned.*> M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q or P**T to be returned.*> N >= 0.*> If VECT = 'Q', M >= N >= min(M,K);*> if VECT = 'P', N >= M >= min(N,K).*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> If VECT = 'Q', the number of columns in the original M-by-K*> matrix reduced by DGEBRD.*> If VECT = 'P', the number of rows in the original K-by-N*> matrix reduced by DGEBRD.*> K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the vectors which define the elementary reflectors,*> as returned by DGEBRD.*> On exit, the M-by-N matrix Q or P**T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension*> (min(M,K)) if VECT = 'Q'*> (min(N,K)) if VECT = 'P'*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i) or G(i), which determines Q or P**T, as*> returned by DGEBRD in its array argument TAUQ or TAUP.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,min(M,N)).*> For optimum performance LWORK >= min(M,N)*NB, where NB*> is the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleGBcomputational** =====================================================================SUBROUTINE DORGBR( VECT, M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER VECTINTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WANTQINTEGER I, IINFO, J, LWKOPT, MN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DORGLQ, DORGQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0WANTQ = LSAME( VECT, 'Q' )MN = MIN( M, N )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'P' ) ) THENINFO = -1ELSE IF( M.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 .OR. ( WANTQ .AND. ( N.GT.M .OR. N.LT.MIN( M,$ K ) ) ) .OR. ( .NOT.WANTQ .AND. ( M.GT.N .OR. M.LT.$ MIN( N, K ) ) ) ) THENINFO = -3ELSE IF( K.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LWORK.LT.MAX( 1, MN ) .AND. .NOT.LQUERY ) THENINFO = -9END IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = 1IF( WANTQ ) THENIF( M.GE.K ) THENCALL DORGQR( M, N, K, A, LDA, TAU, WORK, -1, IINFO )ELSEIF( M.GT.1 ) THENCALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,$ -1, IINFO )END IFEND IFELSEIF( K.LT.N ) THENCALL DORGLQ( M, N, K, A, LDA, TAU, WORK, -1, IINFO )ELSEIF( N.GT.1 ) THENCALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,$ -1, IINFO )END IFEND IFEND IFLWKOPT = WORK( 1 )LWKOPT = MAX (LWKOPT, MN)END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGBR', -INFO )RETURNELSE IF( LQUERY ) THENWORK( 1 ) = LWKOPTRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( WANTQ ) THEN** Form Q, determined by a call to DGEBRD to reduce an m-by-k* matrix*IF( M.GE.K ) THEN** If m >= k, assume m >= n >= k*CALL DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )*ELSE** If m < k, assume m = n** Shift the vectors which define the elementary reflectors one* column to the right, and set the first row and column of Q* to those of the unit matrix*DO 20 J = M, 2, -1A( 1, J ) = ZERODO 10 I = J + 1, MA( I, J ) = A( I, J-1 )10 CONTINUE20 CONTINUEA( 1, 1 ) = ONEDO 30 I = 2, MA( I, 1 ) = ZERO30 CONTINUEIF( M.GT.1 ) THEN** Form Q(2:m,2:m)*CALL DORGQR( M-1, M-1, M-1, A( 2, 2 ), LDA, TAU, WORK,$ LWORK, IINFO )END IFEND IFELSE** Form P**T, determined by a call to DGEBRD to reduce a k-by-n* matrix*IF( K.LT.N ) THEN** If k < n, assume k <= m <= n*CALL DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, IINFO )*ELSE** If k >= n, assume m = n** Shift the vectors which define the elementary reflectors one* row downward, and set the first row and column of P**T to* those of the unit matrix*A( 1, 1 ) = ONEDO 40 I = 2, NA( I, 1 ) = ZERO40 CONTINUEDO 60 J = 2, NDO 50 I = J - 1, 2, -1A( I, J ) = A( I-1, J )50 CONTINUEA( 1, J ) = ZERO60 CONTINUEIF( N.GT.1 ) THEN** Form P**T(2:n,2:n)*CALL DORGLQ( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,$ LWORK, IINFO )END IFEND IFEND IFWORK( 1 ) = LWKOPTRETURN** End of DORGBR*END*> \brief \b DORGHR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGHR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorghr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorghr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorghr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGHR( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER IHI, ILO, INFO, LDA, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGHR generates a real orthogonal matrix Q which is defined as the*> product of IHI-ILO elementary reflectors of order N, as returned by*> DGEHRD:*>*> Q = H(ilo) H(ilo+1) . . . H(ihi-1).*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix Q. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*>*> ILO and IHI must have the same values as in the previous call*> of DGEHRD. Q is equal to the unit matrix except in the*> submatrix Q(ilo+1:ihi,ilo+1:ihi).*> 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the vectors which define the elementary reflectors,*> as returned by DGEHRD.*> On exit, the N-by-N orthogonal matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEHRD.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= IHI-ILO.*> For optimum performance LWORK >= (IHI-ILO)*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGHR( N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER IHI, ILO, INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IINFO, J, LWKOPT, NB, NH* ..* .. External Subroutines ..EXTERNAL DORGQR, XERBLA* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NH = IHI - ILOLQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -1ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, N ) ) THENINFO = -2ELSE IF( IHI.LT.MIN( ILO, N ) .OR. IHI.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, NH ) .AND. .NOT.LQUERY ) THENINFO = -8END IF*IF( INFO.EQ.0 ) THENNB = ILAENV( 1, 'DORGQR', ' ', NH, NH, NH, -1 )LWKOPT = MAX( 1, NH )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGHR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF** Shift the vectors which define the elementary reflectors one* column to the right, and set the first ilo and the last n-ihi* rows and columns to those of the unit matrix*DO 40 J = IHI, ILO + 1, -1DO 10 I = 1, J - 1A( I, J ) = ZERO10 CONTINUEDO 20 I = J + 1, IHIA( I, J ) = A( I, J-1 )20 CONTINUEDO 30 I = IHI + 1, NA( I, J ) = ZERO30 CONTINUE40 CONTINUEDO 60 J = 1, ILODO 50 I = 1, NA( I, J ) = ZERO50 CONTINUEA( J, J ) = ONE60 CONTINUEDO 80 J = IHI + 1, NDO 70 I = 1, NA( I, J ) = ZERO70 CONTINUEA( J, J ) = ONE80 CONTINUE*IF( NH.GT.0 ) THEN** Generate Q(ilo+1:ihi,ilo+1:ihi)*CALL DORGQR( NH, NH, NH, A( ILO+1, ILO+1 ), LDA, TAU( ILO ),$ WORK, LWORK, IINFO )END IFWORK( 1 ) = LWKOPTRETURN** End of DORGHR*END*> \brief \b DORGL2** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGL2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgl2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgl2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgl2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGL2( M, N, K, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGL2 generates an m by n real matrix Q with orthonormal rows,*> which is defined as the first m rows of a product of k elementary*> reflectors of order n*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGELQF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. N >= M.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. M >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the i-th row must contain the vector which defines*> the elementary reflector H(i), for i = 1,2,...,k, as returned*> by DGELQF in the first k rows of its array argument A.*> On exit, the m-by-n matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGELQF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (M)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGL2( M, N, K, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGL2', -INFO )RETURNEND IF** Quick return if possible*IF( M.LE.0 )$ RETURN*IF( K.LT.M ) THEN** Initialise rows k+1:m to rows of the unit matrix*DO 20 J = 1, NDO 10 L = K + 1, MA( L, J ) = ZERO10 CONTINUEIF( J.GT.K .AND. J.LE.M )$ A( J, J ) = ONE20 CONTINUEEND IF*DO 40 I = K, 1, -1** Apply H(i) to A(i:m,i:n) from the right*IF( I.LT.N ) THENIF( I.LT.M ) THENA( I, I ) = ONECALL DLARF( 'Right', M-I, N-I+1, A( I, I ), LDA,$ TAU( I ), A( I+1, I ), LDA, WORK )END IFCALL DSCAL( N-I, -TAU( I ), A( I, I+1 ), LDA )END IFA( I, I ) = ONE - TAU( I )** Set A(i,1:i-1) to zero*DO 30 L = 1, I - 1A( I, L ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORGL2*END*> \brief \b DORGLQ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGLQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorglq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorglq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorglq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGLQ generates an M-by-N real matrix Q with orthonormal rows,*> which is defined as the first M rows of a product of K elementary*> reflectors of order N*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGELQF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. N >= M.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. M >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the i-th row must contain the vector which defines*> the elementary reflector H(i), for i = 1,2,...,k, as returned*> by DGELQF in the first k rows of its array argument A.*> On exit, the M-by-N matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGELQF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,M).*> For optimum performance LWORK >= M*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGLQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,$ LWKOPT, NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORGL2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DORGLQ', ' ', M, N, K, -1 )LWKOPT = MAX( 1, M )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGLQ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.LE.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = MIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DORGLQ', ' ', M, N, K, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORGLQ', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the last block.* The first kk rows are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )** Set A(kk+1:m,1:kk) to zero.*DO 20 J = 1, KKDO 10 I = KK + 1, MA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the last or only block.*IF( KK.LT.M )$ CALL DORGL2( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,$ TAU( KK+1 ), WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = KI + 1, 1, -NBIB = MIN( NB, K-I+1 )IF( I+IB.LE.M ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Rowwise', N-I+1, IB, A( I, I ),$ LDA, TAU( I ), WORK, LDWORK )** Apply H**T to A(i+ib:m,i:n) from the right*CALL DLARFB( 'Right', 'Transpose', 'Forward', 'Rowwise',$ M-I-IB+1, N-I+1, IB, A( I, I ), LDA, WORK,$ LDWORK, A( I+IB, I ), LDA, WORK( IB+1 ),$ LDWORK )END IF** Apply H**T to columns i:n of current block*CALL DORGL2( IB, N-I+1, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )** Set columns 1:i-1 of current block to zero*DO 40 J = 1, I - 1DO 30 L = I, I + IB - 1A( L, J ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGLQ*END*> \brief \b DORGQL** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGQL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgql.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgql.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgql.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGQL generates an M-by-N real matrix Q with orthonormal columns,*> which is defined as the last N columns of a product of K elementary*> reflectors of order M*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGEQLF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. M >= N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. N >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the (n-k+i)-th column must contain the vector which*> defines the elementary reflector H(i), for i = 1,2,...,k, as*> returned by DGEQLF in the last k columns of its array*> argument A.*> On exit, the M-by-N matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQLF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> For optimum performance LWORK >= N*NB, where NB is the*> optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGQL( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, J, KK, L, LDWORK, LWKOPT,$ NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORG2L, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IF*IF( INFO.EQ.0 ) THENIF( N.EQ.0 ) THENLWKOPT = 1ELSENB = ILAENV( 1, 'DORGQL', ' ', M, N, K, -1 )LWKOPT = N*NBEND IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -8END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGQL', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.0 ) THENRETURNEND IF*NBMIN = 2NX = 0IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DORGQL', ' ', M, N, K, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORGQL', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the first block.* The last kk columns are handled by the block method.*KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )** Set A(m-kk+1:m,1:n-kk) to zero.*DO 20 J = 1, N - KKDO 10 I = M - KK + 1, MA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the first or only block.*CALL DORG2L( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = K - KK + 1, K, NBIB = MIN( NB, K-I+1 )IF( N-K+I.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Columnwise', M-K+I+IB-1, IB,$ A( 1, N-K+I ), LDA, TAU( I ), WORK, LDWORK )** Apply H to A(1:m-k+i+ib-1,1:n-k+i-1) from the left*CALL DLARFB( 'Left', 'No transpose', 'Backward',$ 'Columnwise', M-K+I+IB-1, N-K+I-1, IB,$ A( 1, N-K+I ), LDA, WORK, LDWORK, A, LDA,$ WORK( IB+1 ), LDWORK )END IF** Apply H to rows 1:m-k+i+ib-1 of current block*CALL DORG2L( M-K+I+IB-1, IB, IB, A( 1, N-K+I ), LDA,$ TAU( I ), WORK, IINFO )** Set rows m-k+i+ib:m of current block to zero*DO 40 J = N - K + I, N - K + I + IB - 1DO 30 L = M - K + I + IB, MA( L, J ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGQL*END*> \brief \b DORGQR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGQR generates an M-by-N real matrix Q with orthonormal columns,*> which is defined as the first N columns of a product of K elementary*> reflectors of order M*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGEQRF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. M >= N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. N >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the i-th column must contain the vector which*> defines the elementary reflector H(i), for i = 1,2,...,k, as*> returned by DGEQRF in the first k columns of its array*> argument A.*> On exit, the M-by-N matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQRF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> For optimum performance LWORK >= N*NB, where NB is the*> optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGQR( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IINFO, IWS, J, KI, KK, L, LDWORK,$ LWKOPT, NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORG2R, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NB = ILAENV( 1, 'DORGQR', ' ', M, N, K, -1 )LWKOPT = MAX( 1, N )*NBWORK( 1 ) = LWKOPTLQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 .OR. N.GT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.N ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGQR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2NX = 0IWS = NIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DORGQR', ' ', M, N, K, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORGQR', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the last block.* The first kk columns are handled by the block method.*KI = ( ( K-NX-1 ) / NB )*NBKK = MIN( K, KI+NB )** Set A(1:kk,kk+1:n) to zero.*DO 20 J = KK + 1, NDO 10 I = 1, KKA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the last or only block.*IF( KK.LT.N )$ CALL DORG2R( M-KK, N-KK, K-KK, A( KK+1, KK+1 ), LDA,$ TAU( KK+1 ), WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = KI + 1, 1, -NBIB = MIN( NB, K-I+1 )IF( I+IB.LE.N ) THEN** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Columnwise', M-I+1, IB,$ A( I, I ), LDA, TAU( I ), WORK, LDWORK )** Apply H to A(i:m,i+ib:n) from the left*CALL DLARFB( 'Left', 'No transpose', 'Forward',$ 'Columnwise', M-I+1, N-I-IB+1, IB,$ A( I, I ), LDA, WORK, LDWORK, A( I, I+IB ),$ LDA, WORK( IB+1 ), LDWORK )END IF** Apply H to rows i:m of current block*CALL DORG2R( M-I+1, IB, IB, A( I, I ), LDA, TAU( I ), WORK,$ IINFO )** Set rows 1:i-1 of current block to zero*DO 40 J = I, I + IB - 1DO 30 L = 1, I - 1A( L, J ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGQR*END*> \brief \b DORGR2 generates all or part of the orthogonal matrix Q from an RQ factorization determined by sgerqf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGR2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgr2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgr2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgr2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGR2( M, N, K, A, LDA, TAU, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGR2 generates an m by n real matrix Q with orthonormal rows,*> which is defined as the last m rows of a product of k elementary*> reflectors of order n*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGERQF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. N >= M.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. M >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the (m-k+i)-th row must contain the vector which*> defines the elementary reflector H(i), for i = 1,2,...,k, as*> returned by DGERQF in the last k rows of its array argument*> A.*> On exit, the m by n matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGERQF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (M)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGR2( M, N, K, A, LDA, TAU, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, II, J, L* ..* .. External Subroutines ..EXTERNAL DLARF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORGR2', -INFO )RETURNEND IF** Quick return if possible*IF( M.LE.0 )$ RETURN*IF( K.LT.M ) THEN** Initialise rows 1:m-k to rows of the unit matrix*DO 20 J = 1, NDO 10 L = 1, M - KA( L, J ) = ZERO10 CONTINUEIF( J.GT.N-M .AND. J.LE.N-K )$ A( M-N+J, J ) = ONE20 CONTINUEEND IF*DO 40 I = 1, KII = M - K + I** Apply H(i) to A(1:m-k+i,1:n-k+i) from the right*A( II, N-M+II ) = ONECALL DLARF( 'Right', II-1, N-M+II, A( II, 1 ), LDA, TAU( I ),$ A, LDA, WORK )CALL DSCAL( N-M+II-1, -TAU( I ), A( II, 1 ), LDA )A( II, N-M+II ) = ONE - TAU( I )** Set A(m-k+i,n-k+i+1:n) to zero*DO 30 L = N - M + II + 1, NA( II, L ) = ZERO30 CONTINUE40 CONTINUERETURN** End of DORGR2*END*> \brief \b DORGRQ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGRQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgrq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgrq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgrq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGRQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGRQ generates an M-by-N real matrix Q with orthonormal rows,*> which is defined as the last M rows of a product of K elementary*> reflectors of order N*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGERQF.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix Q. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix Q. N >= M.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines the*> matrix Q. M >= K >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the (m-k+i)-th row must contain the vector which*> defines the elementary reflector H(i), for i = 1,2,...,k, as*> returned by DGERQF in the last k rows of its array argument*> A.*> On exit, the M-by-N matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The first dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGERQF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,M).*> For optimum performance LWORK >= M*NB, where NB is the*> optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument has an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGRQ( M, N, K, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, K, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, II, IINFO, IWS, J, KK, L, LDWORK,$ LWKOPT, NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORGR2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( K.LT.0 .OR. K.GT.M ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -5END IF*IF( INFO.EQ.0 ) THENIF( M.LE.0 ) THENLWKOPT = 1ELSENB = ILAENV( 1, 'DORGRQ', ' ', M, N, K, -1 )LWKOPT = M*NBEND IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.MAX( 1, M ) .AND. .NOT.LQUERY ) THENINFO = -8END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGRQ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.LE.0 ) THENRETURNEND IF*NBMIN = 2NX = 0IWS = MIF( NB.GT.1 .AND. NB.LT.K ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DORGRQ', ' ', M, N, K, -1 ) )IF( NX.LT.K ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORGRQ', ' ', M, N, K, -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.K .AND. NX.LT.K ) THEN** Use blocked code after the first block.* The last kk rows are handled by the block method.*KK = MIN( K, ( ( K-NX+NB-1 ) / NB )*NB )** Set A(1:m-kk,n-kk+1:n) to zero.*DO 20 J = N - KK + 1, NDO 10 I = 1, M - KKA( I, J ) = ZERO10 CONTINUE20 CONTINUEELSEKK = 0END IF** Use unblocked code for the first or only block.*CALL DORGR2( M-KK, N-KK, K-KK, A, LDA, TAU, WORK, IINFO )*IF( KK.GT.0 ) THEN** Use blocked code*DO 50 I = K - KK + 1, K, NBIB = MIN( NB, K-I+1 )II = M - K + IIF( II.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Rowwise', N-K+I+IB-1, IB,$ A( II, 1 ), LDA, TAU( I ), WORK, LDWORK )** Apply H**T to A(1:m-k+i-1,1:n-k+i+ib-1) from the right*CALL DLARFB( 'Right', 'Transpose', 'Backward', 'Rowwise',$ II-1, N-K+I+IB-1, IB, A( II, 1 ), LDA, WORK,$ LDWORK, A, LDA, WORK( IB+1 ), LDWORK )END IF** Apply H**T to columns 1:n-k+i+ib-1 of current block*CALL DORGR2( IB, N-K+I+IB-1, IB, A( II, 1 ), LDA, TAU( I ),$ WORK, IINFO )** Set columns n-k+i+ib:n of current block to zero*DO 40 L = N - K + I + IB, NDO 30 J = II, II + IB - 1A( J, L ) = ZERO30 CONTINUE40 CONTINUE50 CONTINUEEND IF*WORK( 1 ) = IWSRETURN** End of DORGRQ*END*> \brief \b DORGTR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORGTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorgtr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorgtr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorgtr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORGTR generates a real orthogonal matrix Q which is defined as the*> product of n-1 elementary reflectors of order N, as returned by*> DSYTRD:*>*> if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),*>*> if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A contains elementary reflectors*> from DSYTRD;*> = 'L': Lower triangle of A contains elementary reflectors*> from DSYTRD.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix Q. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the vectors which define the elementary reflectors,*> as returned by DSYTRD.*> On exit, the N-by-N orthogonal matrix Q.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DSYTRD.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N-1).*> For optimum performance LWORK >= (N-1)*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORGTR( UPLO, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPERINTEGER I, IINFO, J, LWKOPT, NB* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORGQL, DORGQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LWORK.LT.MAX( 1, N-1 ) .AND. .NOT.LQUERY ) THENINFO = -7END IF*IF( INFO.EQ.0 ) THENIF( UPPER ) THENNB = ILAENV( 1, 'DORGQL', ' ', N-1, N-1, N-1, -1 )ELSENB = ILAENV( 1, 'DORGQR', ' ', N-1, N-1, N-1, -1 )END IFLWKOPT = MAX( 1, N-1 )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORGTR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( UPPER ) THEN** Q was determined by a call to DSYTRD with UPLO = 'U'** Shift the vectors which define the elementary reflectors one* column to the left, and set the last row and column of Q to* those of the unit matrix*DO 20 J = 1, N - 1DO 10 I = 1, J - 1A( I, J ) = A( I, J+1 )10 CONTINUEA( N, J ) = ZERO20 CONTINUEDO 30 I = 1, N - 1A( I, N ) = ZERO30 CONTINUEA( N, N ) = ONE** Generate Q(1:n-1,1:n-1)*CALL DORGQL( N-1, N-1, N-1, A, LDA, TAU, WORK, LWORK, IINFO )*ELSE** Q was determined by a call to DSYTRD with UPLO = 'L'.** Shift the vectors which define the elementary reflectors one* column to the right, and set the first row and column of Q to* those of the unit matrix*DO 50 J = N, 2, -1A( 1, J ) = ZERODO 40 I = J + 1, NA( I, J ) = A( I, J-1 )40 CONTINUE50 CONTINUEA( 1, 1 ) = ONEDO 60 I = 2, NA( I, 1 ) = ZERO60 CONTINUEIF( N.GT.1 ) THEN** Generate Q(2:n,2:n)*CALL DORGQR( N-1, N-1, N-1, A( 2, 2 ), LDA, TAU, WORK,$ LWORK, IINFO )END IFEND IFWORK( 1 ) = LWKOPTRETURN** End of DORGTR*END*> \brief \b DORM2L multiplies a general matrix by the orthogonal matrix from a QL factorization determined by sgeqlf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORM2L + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorm2l.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorm2l.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorm2l.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORM2L overwrites the general real m by n matrix C with*>*> Q * C if SIDE = 'L' and TRANS = 'N', or*>*> Q**T * C if SIDE = 'L' and TRANS = 'T', or*>*> C * Q if SIDE = 'R' and TRANS = 'N', or*>*> C * Q**T if SIDE = 'R' and TRANS = 'T',*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGEQLF. Q is of order m if SIDE = 'L' and of order n*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left*> = 'R': apply Q or Q**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply Q (No transpose)*> = 'T': apply Q**T (Transpose)*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,K)*> The i-th column must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGEQLF in the last k columns of its array argument A.*> A is modified by the routine but restored on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If SIDE = 'L', LDA >= max(1,M);*> if SIDE = 'R', LDA >= max(1,N).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQLF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L',*> (M) if SIDE = 'R'*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LEFT, NOTRANINTEGER I, I1, I2, I3, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORM2L', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) )$ THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NELSEMI = MEND IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(1:m-k+i,1:n)*MI = M - K + IELSE** H(i) is applied to C(1:m,1:n-k+i)*NI = N - K + IEND IF** Apply H(i)*AII = A( NQ-K+I, I )A( NQ-K+I, I ) = ONECALL DLARF( SIDE, MI, NI, A( 1, I ), 1, TAU( I ), C, LDC,$ WORK )A( NQ-K+I, I ) = AII10 CONTINUERETURN** End of DORM2L*END*> \brief \b DORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sgeqrf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORM2R + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorm2r.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorm2r.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorm2r.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORM2R overwrites the general real m by n matrix C with*>*> Q * C if SIDE = 'L' and TRANS = 'N', or*>*> Q**T* C if SIDE = 'L' and TRANS = 'T', or*>*> C * Q if SIDE = 'R' and TRANS = 'N', or*>*> C * Q**T if SIDE = 'R' and TRANS = 'T',*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGEQRF. Q is of order m if SIDE = 'L' and of order n*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left*> = 'R': apply Q or Q**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply Q (No transpose)*> = 'T': apply Q**T (Transpose)*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,K)*> The i-th column must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGEQRF in the first k columns of its array argument A.*> A is modified by the routine but restored on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If SIDE = 'L', LDA >= max(1,M);*> if SIDE = 'R', LDA >= max(1,N).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQRF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L',*> (M) if SIDE = 'R'*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LEFT, NOTRANINTEGER I, I1, I2, I3, IC, JC, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORM2R', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. ( .NOT.LEFT .AND. NOTRAN ) )$ THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H(i) is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H(i)*AII = A( I, I )A( I, I ) = ONECALL DLARF( SIDE, MI, NI, A( I, I ), 1, TAU( I ), C( IC, JC ),$ LDC, WORK )A( I, I ) = AII10 CONTINUERETURN** End of DORM2R*END*> \brief \b DORMBR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMBR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormbr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormbr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormbr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,* LDC, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS, VECT* INTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> If VECT = 'Q', DORMBR overwrites the general real M-by-N matrix C*> with*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> If VECT = 'P', DORMBR overwrites the general real M-by-N matrix C*> with*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': P * C C * P*> TRANS = 'T': P**T * C C * P**T*>*> Here Q and P**T are the orthogonal matrices determined by DGEBRD when*> reducing a real matrix A to bidiagonal form: A = Q * B * P**T. Q and*> P**T are defined as products of elementary reflectors H(i) and G(i)*> respectively.*>*> Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Thus nq is the*> order of the orthogonal matrix Q or P**T that is applied.*>*> If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:*> if nq >= k, Q = H(1) H(2) . . . H(k);*> if nq < k, Q = H(1) H(2) . . . H(nq-1).*>*> If VECT = 'P', A is assumed to have been a K-by-NQ matrix:*> if k < nq, P = G(1) G(2) . . . G(k);*> if k >= nq, P = G(1) G(2) . . . G(nq-1).*> \endverbatim** Arguments:* ==========**> \param[in] VECT*> \verbatim*> VECT is CHARACTER*1*> = 'Q': apply Q or Q**T;*> = 'P': apply P or P**T.*> \endverbatim*>*> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q, Q**T, P or P**T from the Left;*> = 'R': apply Q, Q**T, P or P**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q or P;*> = 'T': Transpose, apply Q**T or P**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> If VECT = 'Q', the number of columns in the original*> matrix reduced by DGEBRD.*> If VECT = 'P', the number of rows in the original*> matrix reduced by DGEBRD.*> K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,min(nq,K)) if VECT = 'Q'*> (LDA,nq) if VECT = 'P'*> The vectors which define the elementary reflectors H(i) and*> G(i), whose products determine the matrices Q and P, as*> returned by DGEBRD.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If VECT = 'Q', LDA >= max(1,nq);*> if VECT = 'P', LDA >= max(1,min(nq,K)).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (min(nq,K))*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i) or G(i) which determines Q or P, as returned*> by DGEBRD in the array argument TAUQ or TAUP.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q*> or P*C or P**T*C or C*P or C*P**T.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For optimum performance LWORK >= N*NB if SIDE = 'L', and*> LWORK >= M*NB if SIDE = 'R', where NB is the optimal*> blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMBR( VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C,$ LDC, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANS, VECTINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL APPLYQ, LEFT, LQUERY, NOTRANCHARACTER TRANSTINTEGER I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORMLQ, DORMQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0APPLYQ = LSAME( VECT, 'Q' )LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q or P and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.APPLYQ .AND. .NOT.LSAME( VECT, 'P' ) ) THENINFO = -1ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -2ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( K.LT.0 ) THENINFO = -6ELSE IF( ( APPLYQ .AND. LDA.LT.MAX( 1, NQ ) ) .OR.$ ( .NOT.APPLYQ .AND. LDA.LT.MAX( 1, MIN( NQ, K ) ) ) )$ THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -13END IF*IF( INFO.EQ.0 ) THENIF( APPLYQ ) THENIF( LEFT ) THENNB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M-1, N, M-1,$ -1 )ELSENB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N-1, N-1,$ -1 )END IFELSEIF( LEFT ) THENNB = ILAENV( 1, 'DORMLQ', SIDE // TRANS, M-1, N, M-1,$ -1 )ELSENB = ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N-1, N-1,$ -1 )END IFEND IFLWKOPT = MAX( 1, NW )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMBR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*WORK( 1 ) = 1IF( M.EQ.0 .OR. N.EQ.0 )$ RETURN*IF( APPLYQ ) THEN** Apply Q*IF( NQ.GE.K ) THEN** Q was determined by a call to DGEBRD with nq >= k*CALL DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, IINFO )ELSE IF( NQ.GT.1 ) THEN** Q was determined by a call to DGEBRD with nq < k*IF( LEFT ) THENMI = M - 1NI = NI1 = 2I2 = 1ELSEMI = MNI = N - 1I1 = 1I2 = 2END IFCALL DORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,$ C( I1, I2 ), LDC, WORK, LWORK, IINFO )END IFELSE** Apply P*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IFIF( NQ.GT.K ) THEN** P was determined by a call to DGEBRD with nq > k*CALL DORMLQ( SIDE, TRANST, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, IINFO )ELSE IF( NQ.GT.1 ) THEN** P was determined by a call to DGEBRD with nq <= k*IF( LEFT ) THENMI = M - 1NI = NI1 = 2I2 = 1ELSEMI = MNI = N - 1I1 = 1I2 = 2END IFCALL DORMLQ( SIDE, TRANST, MI, NI, NQ-1, A( 1, 2 ), LDA,$ TAU, C( I1, I2 ), LDC, WORK, LWORK, IINFO )END IFEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMBR*END*> \brief \b DORMHR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMHR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormhr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormhr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormhr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMHR( SIDE, TRANS, M, N, ILO, IHI, A, LDA, TAU, C,* LDC, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER IHI, ILO, INFO, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMHR overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix of order nq, with nq = m if*> SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of*> IHI-ILO elementary reflectors, as returned by DGEHRD:*>*> Q = H(ilo) H(ilo+1) . . . H(ihi-1).*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*>*> ILO and IHI must have the same values as in the previous call*> of DGEHRD. Q is equal to the unit matrix except in the*> submatrix Q(ilo+1:ihi,ilo+1:ihi).*> If SIDE = 'L', then 1 <= ILO <= IHI <= M, if M > 0, and*> ILO = 1 and IHI = 0, if M = 0;*> if SIDE = 'R', then 1 <= ILO <= IHI <= N, if N > 0, and*> ILO = 1 and IHI = 0, if N = 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L'*> (LDA,N) if SIDE = 'R'*> The vectors which define the elementary reflectors, as*> returned by DGEHRD.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> LDA >= max(1,M) if SIDE = 'L'; LDA >= max(1,N) if SIDE = 'R'.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension*> (M-1) if SIDE = 'L'*> (N-1) if SIDE = 'R'*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEHRD.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For optimum performance LWORK >= N*NB if SIDE = 'L', and*> LWORK >= M*NB if SIDE = 'R', where NB is the optimal*> blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMHR( SIDE, TRANS, M, N, ILO, IHI, A, LDA, TAU, C,$ LDC, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER IHI, ILO, INFO, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LEFT, LQUERYINTEGER I1, I2, IINFO, LWKOPT, MI, NB, NH, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORMQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0NH = IHI - ILOLEFT = LSAME( SIDE, 'L' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.LSAME( TRANS, 'T' ) )$ THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( ILO.LT.1 .OR. ILO.GT.MAX( 1, NQ ) ) THENINFO = -5ELSE IF( IHI.LT.MIN( ILO, NQ ) .OR. IHI.GT.NQ ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -13END IF*IF( INFO.EQ.0 ) THENIF( LEFT ) THENNB = ILAENV( 1, 'DORMQR', SIDE // TRANS, NH, N, NH, -1 )ELSENB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M, NH, NH, -1 )END IFLWKOPT = MAX( 1, NW )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMHR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. NH.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( LEFT ) THENMI = NHNI = NI1 = ILO + 1I2 = 1ELSEMI = MNI = NHI1 = 1I2 = ILO + 1END IF*CALL DORMQR( SIDE, TRANS, MI, NI, NH, A( ILO+1, ILO ), LDA,$ TAU( ILO ), C( I1, I2 ), LDC, WORK, LWORK, IINFO )*WORK( 1 ) = LWKOPTRETURN** End of DORMHR*END*> \brief \b DORML2 multiplies a general matrix by the orthogonal matrix from a LQ factorization determined by sgelqf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORML2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dorml2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dorml2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dorml2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORML2 overwrites the general real m by n matrix C with*>*> Q * C if SIDE = 'L' and TRANS = 'N', or*>*> Q**T* C if SIDE = 'L' and TRANS = 'T', or*>*> C * Q if SIDE = 'R' and TRANS = 'N', or*>*> C * Q**T if SIDE = 'R' and TRANS = 'T',*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGELQF. Q is of order m if SIDE = 'L' and of order n*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left*> = 'R': apply Q or Q**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply Q (No transpose)*> = 'T': apply Q**T (Transpose)*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L',*> (LDA,N) if SIDE = 'R'*> The i-th row must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGELQF in the first k rows of its array argument A.*> A is modified by the routine but restored on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,K).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGELQF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L',*> (M) if SIDE = 'R'*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LEFT, NOTRANINTEGER I, I1, I2, I3, IC, JC, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORML2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. NOTRAN ) .OR. ( .NOT.LEFT .AND. .NOT.NOTRAN ) )$ THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H(i) is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H(i)*AII = A( I, I )A( I, I ) = ONECALL DLARF( SIDE, MI, NI, A( I, I ), LDA, TAU( I ),$ C( IC, JC ), LDC, WORK )A( I, I ) = AII10 CONTINUERETURN** End of DORML2*END*> \brief \b DORMLQ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMLQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormlq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormlq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormlq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMLQ overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGELQF. Q is of order M if SIDE = 'L' and of order N*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L',*> (LDA,N) if SIDE = 'R'*> The i-th row must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGELQF in the first k rows of its array argument A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,K).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGELQF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMLQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER NBMAX, LDT, TSIZEPARAMETER ( NBMAX = 64, LDT = NBMAX+1,$ TSIZE = LDT*NBMAX )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANCHARACTER TRANSTINTEGER I, I1, I2, I3, IB, IC, IINFO, IWT, JC, LDWORK,$ LWKOPT, MI, NB, NBMIN, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORML2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*NB = MIN( NBMAX, ILAENV( 1, 'DORMLQ', SIDE // TRANS, M, N, K,$ -1 ) )LWKOPT = MAX( 1, NW )*NB + TSIZEWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMLQ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIF( LWORK.LT.NW*NB+TSIZE ) THENNB = (LWORK-TSIZE) / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMLQ', SIDE // TRANS, M, N, K,$ -1 ) )END IFEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORML2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,$ IINFO )ELSE** Use blocked code*IWT = 1 + NW*NBIF( ( LEFT .AND. NOTRAN ) .OR.$ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Rowwise', NQ-I+1, IB, A( I, I ),$ LDA, TAU( I ), WORK( IWT ), LDT )IF( LEFT ) THEN** H or H**T is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H or H**T is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H or H**T*CALL DLARFB( SIDE, TRANST, 'Forward', 'Rowwise', MI, NI, IB,$ A( I, I ), LDA, WORK( IWT ), LDT,$ C( IC, JC ), LDC, WORK, LDWORK )10 CONTINUEEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMLQ*END*> \brief \b DORMQL** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMQL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormql.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormql.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormql.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMQL overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(k) . . . H(2) H(1)*>*> as returned by DGEQLF. Q is of order M if SIDE = 'L' and of order N*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,K)*> The i-th column must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGEQLF in the last k columns of its array argument A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If SIDE = 'L', LDA >= max(1,M);*> if SIDE = 'R', LDA >= max(1,N).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQLF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMQL( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER NBMAX, LDT, TSIZEPARAMETER ( NBMAX = 64, LDT = NBMAX+1,$ TSIZE = LDT*NBMAX )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANINTEGER I, I1, I2, I3, IB, IINFO, IWT, LDWORK, LWKOPT,$ MI, NB, NBMIN, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORM2L, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = MAX( 1, N )ELSENQ = NNW = MAX( 1, M )END IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.NW .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*IF( M.EQ.0 .OR. N.EQ.0 ) THENLWKOPT = 1ELSENB = MIN( NBMAX, ILAENV( 1, 'DORMQL', SIDE // TRANS, M, N,$ K, -1 ) )LWKOPT = NW*NB + TSIZEEND IFWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMQL', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENRETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIF( LWORK.LT.NW*NB+TSIZE ) THENNB = (LWORK-TSIZE) / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMQL', SIDE // TRANS, M, N, K,$ -1 ) )END IFEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORM2L( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,$ IINFO )ELSE** Use blocked code*IWT = 1 + NW*NBIF( ( LEFT .AND. NOTRAN ) .OR.$ ( .NOT.LEFT .AND. .NOT.NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NELSEMI = MEND IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Columnwise', NQ-K+I+IB-1, IB,$ A( 1, I ), LDA, TAU( I ), WORK( IWT ), LDT )IF( LEFT ) THEN** H or H**T is applied to C(1:m-k+i+ib-1,1:n)*MI = M - K + I + IB - 1ELSE** H or H**T is applied to C(1:m,1:n-k+i+ib-1)*NI = N - K + I + IB - 1END IF** Apply H or H**T*CALL DLARFB( SIDE, TRANS, 'Backward', 'Columnwise', MI, NI,$ IB, A( 1, I ), LDA, WORK( IWT ), LDT, C, LDC,$ WORK, LDWORK )10 CONTINUEEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMQL*END*> \brief \b DORMQR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMQR overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,K)*> The i-th column must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGEQRF in the first k columns of its array argument A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If SIDE = 'L', LDA >= max(1,M);*> if SIDE = 'R', LDA >= max(1,N).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGEQRF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMQR( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER NBMAX, LDT, TSIZEPARAMETER ( NBMAX = 64, LDT = NBMAX+1,$ TSIZE = LDT*NBMAX )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANINTEGER I, I1, I2, I3, IB, IC, IINFO, IWT, JC, LDWORK,$ LWKOPT, MI, NB, NBMIN, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORM2R, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*NB = MIN( NBMAX, ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N, K,$ -1 ) )LWKOPT = MAX( 1, NW )*NB + TSIZEWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMQR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIF( LWORK.LT.NW*NB+TSIZE ) THENNB = (LWORK-TSIZE) / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMQR', SIDE // TRANS, M, N, K,$ -1 ) )END IFEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORM2R( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,$ IINFO )ELSE** Use blocked code*IWT = 1 + NW*NBIF( ( LEFT .AND. .NOT.NOTRAN ) .OR.$ ( .NOT.LEFT .AND. NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NJC = 1ELSEMI = MIC = 1END IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i) H(i+1) . . . H(i+ib-1)*CALL DLARFT( 'Forward', 'Columnwise', NQ-I+1, IB, A( I, I ),$ LDA, TAU( I ), WORK( IWT ), LDT )IF( LEFT ) THEN** H or H**T is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H or H**T is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H or H**T*CALL DLARFB( SIDE, TRANS, 'Forward', 'Columnwise', MI, NI,$ IB, A( I, I ), LDA, WORK( IWT ), LDT,$ C( IC, JC ), LDC, WORK, LDWORK )10 CONTINUEEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMQR*END*> \brief \b DORMR2 multiplies a general matrix by the orthogonal matrix from a RQ factorization determined by sgerqf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMR2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormr2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormr2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormr2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMR2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMR2 overwrites the general real m by n matrix C with*>*> Q * C if SIDE = 'L' and TRANS = 'N', or*>*> Q**T* C if SIDE = 'L' and TRANS = 'T', or*>*> C * Q if SIDE = 'R' and TRANS = 'N', or*>*> C * Q**T if SIDE = 'R' and TRANS = 'T',*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGERQF. Q is of order m if SIDE = 'L' and of order n*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left*> = 'R': apply Q or Q**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply Q (No transpose)*> = 'T': apply Q' (Transpose)*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L',*> (LDA,N) if SIDE = 'R'*> The i-th row must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGERQF in the last k rows of its array argument A.*> A is modified by the routine but restored on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,K).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGERQF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m by n matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L',*> (M) if SIDE = 'R'*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMR2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LEFT, NOTRANINTEGER I, I1, I2, I3, MI, NI, NQDOUBLE PRECISION AII* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORMR2', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. .NOT.NOTRAN ) .OR. ( .NOT.LEFT .AND. NOTRAN ) )$ THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NELSEMI = MEND IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) is applied to C(1:m-k+i,1:n)*MI = M - K + IELSE** H(i) is applied to C(1:m,1:n-k+i)*NI = N - K + IEND IF** Apply H(i)*AII = A( I, NQ-K+I )A( I, NQ-K+I ) = ONECALL DLARF( SIDE, MI, NI, A( I, 1 ), LDA, TAU( I ), C, LDC,$ WORK )A( I, NQ-K+I ) = AII10 CONTINUERETURN** End of DORMR2*END*> \brief \b DORMR3 multiplies a general matrix by the orthogonal matrix from a RZ factorization determined by stzrzf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMR3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormr3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormr3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormr3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, L, LDA, LDC, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMR3 overwrites the general real m by n matrix C with*>*> Q * C if SIDE = 'L' and TRANS = 'N', or*>*> Q**T* C if SIDE = 'L' and TRANS = 'C', or*>*> C * Q if SIDE = 'R' and TRANS = 'N', or*>*> C * Q**T if SIDE = 'R' and TRANS = 'C',*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DTZRZF. Q is of order m if SIDE = 'L' and of order n*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left*> = 'R': apply Q or Q**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply Q (No transpose)*> = 'T': apply Q**T (Transpose)*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of columns of the matrix A containing*> the meaningful part of the Householder reflectors.*> If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L',*> (LDA,N) if SIDE = 'R'*> The i-th row must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DTZRZF in the last k rows of its array argument A.*> A is modified by the routine but restored on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,K).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DTZRZF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the m-by-n matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (N) if SIDE = 'L',*> (M) if SIDE = 'R'*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*> \endverbatim*>* =====================================================================SUBROUTINE DORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, L, LDA, LDC, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LEFT, NOTRANINTEGER I, I1, I2, I3, IC, JA, JC, MI, NI, NQ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLARZ, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )** NQ is the order of Q*IF( LEFT ) THENNQ = MELSENQ = NEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.$ ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DORMR3', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 )$ RETURN*IF( ( LEFT .AND. .NOT.NOTRAN .OR. .NOT.LEFT .AND. NOTRAN ) ) THENI1 = 1I2 = KI3 = 1ELSEI1 = KI2 = 1I3 = -1END IF*IF( LEFT ) THENNI = NJA = M - L + 1JC = 1ELSEMI = MJA = N - L + 1IC = 1END IF*DO 10 I = I1, I2, I3IF( LEFT ) THEN** H(i) or H(i)**T is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H(i) or H(i)**T is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H(i) or H(i)**T*CALL DLARZ( SIDE, MI, NI, L, A( I, JA ), LDA, TAU( I ),$ C( IC, JC ), LDC, WORK )*10 CONTINUE*RETURN** End of DORMR3*END*> \brief \b DORMRQ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMRQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormrq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormrq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormrq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMRQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMRQ overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DGERQF. Q is of order M if SIDE = 'L' and of order N*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L',*> (LDA,N) if SIDE = 'R'*> The i-th row must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DGERQF in the last k rows of its array argument A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,K).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DGERQF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMRQ( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC,$ WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER NBMAX, LDT, TSIZEPARAMETER ( NBMAX = 64, LDT = NBMAX+1,$ TSIZE = LDT*NBMAX )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANCHARACTER TRANSTINTEGER I, I1, I2, I3, IB, IINFO, IWT, LDWORK, LWKOPT,$ MI, NB, NBMIN, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARFB, DLARFT, DORMR2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = MAX( 1, N )ELSENQ = NNW = MAX( 1, M )END IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.NW .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*IF( M.EQ.0 .OR. N.EQ.0 ) THENLWKOPT = 1ELSENB = MIN( NBMAX, ILAENV( 1, 'DORMRQ', SIDE // TRANS, M, N,$ K, -1 ) )LWKOPT = NW*NB + TSIZEEND IFWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMRQ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENRETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIF( LWORK.LT.NW*NB+TSIZE ) THENNB = (LWORK-TSIZE) / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMRQ', SIDE // TRANS, M, N, K,$ -1 ) )END IFEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORMR2( SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK,$ IINFO )ELSE** Use blocked code*IWT = 1 + NW*NBIF( ( LEFT .AND. .NOT.NOTRAN ) .OR.$ ( .NOT.LEFT .AND. NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NELSEMI = MEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARFT( 'Backward', 'Rowwise', NQ-K+I+IB-1, IB,$ A( I, 1 ), LDA, TAU( I ), WORK( IWT ), LDT )IF( LEFT ) THEN** H or H**T is applied to C(1:m-k+i+ib-1,1:n)*MI = M - K + I + IB - 1ELSE** H or H**T is applied to C(1:m,1:n-k+i+ib-1)*NI = N - K + I + IB - 1END IF** Apply H or H**T*CALL DLARFB( SIDE, TRANST, 'Backward', 'Rowwise', MI, NI,$ IB, A( I, 1 ), LDA, WORK( IWT ), LDT, C, LDC,$ WORK, LDWORK )10 CONTINUEEND IFWORK( 1 ) = LWKOPTRETURN** End of DORMRQ*END*> \brief \b DORMRZ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMRZ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormrz.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormrz.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormrz.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMRZ( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, L, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMRZ overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix defined as the product of k*> elementary reflectors*>*> Q = H(1) H(2) . . . H(k)*>*> as returned by DTZRZF. Q is of order M if SIDE = 'L' and of order N*> if SIDE = 'R'.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> If SIDE = 'L', M >= K >= 0;*> if SIDE = 'R', N >= K >= 0.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of columns of the matrix A containing*> the meaningful part of the Householder reflectors.*> If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L',*> (LDA,N) if SIDE = 'R'*> The i-th row must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> DTZRZF in the last k rows of its array argument A.*> A is modified by the routine but restored on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,K).*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (K)*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DTZRZF.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For good performance, LWORK should generally be larger.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*> \endverbatim*>* =====================================================================SUBROUTINE DORMRZ( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,$ WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, L, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER NBMAX, LDT, TSIZEPARAMETER ( NBMAX = 64, LDT = NBMAX+1,$ TSIZE = LDT*NBMAX )* ..* .. Local Scalars ..LOGICAL LEFT, LQUERY, NOTRANCHARACTER TRANSTINTEGER I, I1, I2, I3, IB, IC, IINFO, IWT, JA, JC,$ LDWORK, LWKOPT, MI, NB, NBMIN, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLARZB, DLARZT, DORMR3, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = MAX( 1, N )ELSENQ = NNW = MAX( 1, M )END IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 .OR. K.GT.NQ ) THENINFO = -5ELSE IF( L.LT.0 .OR. ( LEFT .AND. ( L.GT.M ) ) .OR.$ ( .NOT.LEFT .AND. ( L.GT.N ) ) ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, K ) ) THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -13END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*IF( M.EQ.0 .OR. N.EQ.0 ) THENLWKOPT = 1ELSENB = MIN( NBMAX, ILAENV( 1, 'DORMRQ', SIDE // TRANS, M, N,$ K, -1 ) )LWKOPT = NW*NB + TSIZEEND IFWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMRZ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NBMIN = 2LDWORK = NWIF( NB.GT.1 .AND. NB.LT.K ) THENIF( LWORK.LT.NW*NB+TSIZE ) THENNB = (LWORK-TSIZE) / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DORMRQ', SIDE // TRANS, M, N, K,$ -1 ) )END IFEND IF*IF( NB.LT.NBMIN .OR. NB.GE.K ) THEN** Use unblocked code*CALL DORMR3( SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC,$ WORK, IINFO )ELSE** Use blocked code*IWT = 1 + NW*NBIF( ( LEFT .AND. .NOT.NOTRAN ) .OR.$ ( .NOT.LEFT .AND. NOTRAN ) ) THENI1 = 1I2 = KI3 = NBELSEI1 = ( ( K-1 ) / NB )*NB + 1I2 = 1I3 = -NBEND IF*IF( LEFT ) THENNI = NJC = 1JA = M - L + 1ELSEMI = MIC = 1JA = N - L + 1END IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF*DO 10 I = I1, I2, I3IB = MIN( NB, K-I+1 )** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARZT( 'Backward', 'Rowwise', L, IB, A( I, JA ), LDA,$ TAU( I ), WORK( IWT ), LDT )*IF( LEFT ) THEN** H or H**T is applied to C(i:m,1:n)*MI = M - I + 1IC = IELSE** H or H**T is applied to C(1:m,i:n)*NI = N - I + 1JC = IEND IF** Apply H or H**T*CALL DLARZB( SIDE, TRANST, 'Backward', 'Rowwise', MI, NI,$ IB, L, A( I, JA ), LDA, WORK( IWT ), LDT,$ C( IC, JC ), LDC, WORK, LDWORK )10 CONTINUE*END IF*WORK( 1 ) = LWKOPT*RETURN** End of DORMRZ*END*> \brief \b DORMTR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DORMTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dormtr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dormtr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dormtr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DORMTR( SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC,* WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS, UPLO* INTEGER INFO, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DORMTR overwrites the general real M-by-N matrix C with*>*> SIDE = 'L' SIDE = 'R'*> TRANS = 'N': Q * C C * Q*> TRANS = 'T': Q**T * C C * Q**T*>*> where Q is a real orthogonal matrix of order nq, with nq = m if*> SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of*> nq-1 elementary reflectors, as returned by DSYTRD:*>*> if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1);*>*> if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1).*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A contains elementary reflectors*> from DSYTRD;*> = 'L': Lower triangle of A contains elementary reflectors*> from DSYTRD.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix C. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,M) if SIDE = 'L'*> (LDA,N) if SIDE = 'R'*> The vectors which define the elementary reflectors, as*> returned by DSYTRD.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> LDA >= max(1,M) if SIDE = 'L'; LDA >= max(1,N) if SIDE = 'R'.*> \endverbatim*>*> \param[in] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension*> (M-1) if SIDE = 'L'*> (N-1) if SIDE = 'R'*> TAU(i) must contain the scalar factor of the elementary*> reflector H(i), as returned by DSYTRD.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N matrix C.*> On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If SIDE = 'L', LWORK >= max(1,N);*> if SIDE = 'R', LWORK >= max(1,M).*> For optimum performance LWORK >= N*NB if SIDE = 'L', and*> LWORK >= M*NB if SIDE = 'R', where NB is the optimal*> blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DORMTR( SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC,$ WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER SIDE, TRANS, UPLOINTEGER INFO, LDA, LDC, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( LDC, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LEFT, LQUERY, UPPERINTEGER I1, I2, IINFO, LWKOPT, MI, NB, NI, NQ, NW* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DORMQL, DORMQR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LEFT = LSAME( SIDE, 'L' )UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 )** NQ is the order of Q and NW is the minimum dimension of WORK*IF( LEFT ) THENNQ = MNW = NELSENQ = NNW = MEND IFIF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.LSAME( TRANS, 'T' ) )$ THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NQ ) ) THENINFO = -7ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LWORK.LT.MAX( 1, NW ) .AND. .NOT.LQUERY ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THENIF( UPPER ) THENIF( LEFT ) THENNB = ILAENV( 1, 'DORMQL', SIDE // TRANS, M-1, N, M-1,$ -1 )ELSENB = ILAENV( 1, 'DORMQL', SIDE // TRANS, M, N-1, N-1,$ -1 )END IFELSEIF( LEFT ) THENNB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M-1, N, M-1,$ -1 )ELSENB = ILAENV( 1, 'DORMQR', SIDE // TRANS, M, N-1, N-1,$ -1 )END IFEND IFLWKOPT = MAX( 1, NW )*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DORMTR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 .OR. NQ.EQ.1 ) THENWORK( 1 ) = 1RETURNEND IF*IF( LEFT ) THENMI = M - 1NI = NELSEMI = MNI = N - 1END IF*IF( UPPER ) THEN** Q was determined by a call to DSYTRD with UPLO = 'U'*CALL DORMQL( SIDE, TRANS, MI, NI, NQ-1, A( 1, 2 ), LDA, TAU, C,$ LDC, WORK, LWORK, IINFO )ELSE** Q was determined by a call to DSYTRD with UPLO = 'L'*IF( LEFT ) THENI1 = 2I2 = 1ELSEI1 = 1I2 = 2END IFCALL DORMQR( SIDE, TRANS, MI, NI, NQ-1, A( 2, 1 ), LDA, TAU,$ C( I1, I2 ), LDC, WORK, LWORK, IINFO )END IFWORK( 1 ) = LWKOPTRETURN** End of DORMTR*END*> \brief \b DPBCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBCON( UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBCON estimates the reciprocal of the condition number (in the*> 1-norm) of a real symmetric positive definite band matrix using the*> Cholesky factorization A = U**T*U or A = L*L**T computed by DPBTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangular factor stored in AB;*> = 'L': Lower triangular factor stored in AB.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T of the band matrix A, stored in the*> first KD+1 rows of the array. The j-th column of U or L is*> stored in the j-th column of the array AB as follows:*> if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;*> if UPLO ='L', AB(1+i-j,j) = L(i,j) for j<=i<=min(n,j+kd).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> The 1-norm (or infinity-norm) of the symmetric band matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an*> estimate of the 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPBCON( UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERCHARACTER NORMININTEGER IX, KASEDOUBLE PRECISION AINVNM, SCALE, SCALEL, SCALEU, SMLNUM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL LSAME, IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATBS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( LDAB.LT.KD+1 ) THENINFO = -5ELSE IF( ANORM.LT.ZERO ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the 1-norm of the inverse.*KASE = 0NORMIN = 'N'10 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( UPPER ) THEN** Multiply by inv(U**T).*CALL DLATBS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,$ KD, AB, LDAB, WORK, SCALEL, WORK( 2*N+1 ),$ INFO )NORMIN = 'Y'** Multiply by inv(U).*CALL DLATBS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ KD, AB, LDAB, WORK, SCALEU, WORK( 2*N+1 ),$ INFO )ELSE** Multiply by inv(L).*CALL DLATBS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,$ KD, AB, LDAB, WORK, SCALEL, WORK( 2*N+1 ),$ INFO )NORMIN = 'Y'** Multiply by inv(L**T).*CALL DLATBS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N,$ KD, AB, LDAB, WORK, SCALEU, WORK( 2*N+1 ),$ INFO )END IF** Multiply by 1/SCALE if doing so will not cause overflow.*SCALE = SCALEL*SCALEUIF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*20 CONTINUE*RETURN** End of DPBCON*END*> \brief \b DPBEQU** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBEQU + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbequ.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbequ.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbequ.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBEQU( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBEQU computes row and column scalings intended to equilibrate a*> symmetric positive definite band matrix A and reduce its condition*> number (with respect to the two-norm). S contains the scale factors,*> S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with*> elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This*> choice of S puts the condition number of B within a factor N of the*> smallest possible condition number over all possible diagonal*> scalings.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangular of A is stored;*> = 'L': Lower triangular of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangle of the symmetric band matrix A,*> stored in the first KD+1 rows of the array. The j-th column*> of A is stored in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array A. LDAB >= KD+1.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, S contains the scale factors for A.*> \endverbatim*>*> \param[out] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> If INFO = 0, S contains the ratio of the smallest S(i) to*> the largest S(i). If SCOND >= 0.1 and AMAX is neither too*> large nor too small, it is not worth scaling by S.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, the i-th diagonal element is nonpositive.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPBEQU( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, JDOUBLE PRECISION SMIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( LDAB.LT.KD+1 ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBEQU', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSCOND = ONEAMAX = ZERORETURNEND IF*IF( UPPER ) THENJ = KD + 1ELSEJ = 1END IF** Initialize SMIN and AMAX.*S( 1 ) = AB( J, 1 )SMIN = S( 1 )AMAX = S( 1 )** Find the minimum and maximum diagonal elements.*DO 10 I = 2, NS( I ) = AB( J, I )SMIN = MIN( SMIN, S( I ) )AMAX = MAX( AMAX, S( I ) )10 CONTINUE*IF( SMIN.LE.ZERO ) THEN** Find the first non-positive diagonal element and return.*DO 20 I = 1, NIF( S( I ).LE.ZERO ) THENINFO = IRETURNEND IF20 CONTINUEELSE** Set the scale factors to the reciprocals* of the diagonal elements.*DO 30 I = 1, NS( I ) = ONE / SQRT( S( I ) )30 CONTINUE** Compute SCOND = min(S(I)) / max(S(I))*SCOND = SQRT( SMIN ) / SQRT( AMAX )END IFRETURN** End of DPBEQU*END*> \brief \b DPBRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B,* LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, LDAFB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is symmetric positive definite*> and banded, and provides error bounds and backward error estimates*> for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangle of the symmetric band matrix A,*> stored in the first KD+1 rows of the array. The j-th column*> of A is stored in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in] AFB*> \verbatim*> AFB is DOUBLE PRECISION array, dimension (LDAFB,N)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T of the band matrix A as computed by*> DPBTRF, in the same storage format as A (see AB).*> \endverbatim*>*> \param[in] LDAFB*> \verbatim*> LDAFB is INTEGER*> The leading dimension of the array AFB. LDAFB >= KD+1.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DPBTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B,$ LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, LDAFB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER COUNT, I, J, K, KASE, L, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DPBTRS, DSBMV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KD+1 ) THENINFO = -6ELSE IF( LDAFB.LT.KD+1 ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = MIN( N+1, 2*KD+2 )EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - A * X*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DSBMV( UPLO, N, KD, -ONE, AB, LDAB, X( 1, J ), 1, ONE,$ WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(A)*abs(X) + abs(B).*IF( UPPER ) THENDO 50 K = 1, NS = ZEROXK = ABS( X( K, J ) )L = KD + 1 - KDO 40 I = MAX( 1, K-KD ), K - 1WORK( I ) = WORK( I ) + ABS( AB( L+I, K ) )*XKS = S + ABS( AB( L+I, K ) )*ABS( X( I, J ) )40 CONTINUEWORK( K ) = WORK( K ) + ABS( AB( KD+1, K ) )*XK + S50 CONTINUEELSEDO 70 K = 1, NS = ZEROXK = ABS( X( K, J ) )WORK( K ) = WORK( K ) + ABS( AB( 1, K ) )*XKL = 1 - KDO 60 I = K + 1, MIN( N, K+KD )WORK( I ) = WORK( I ) + ABS( AB( L+I, K ) )*XKS = S + ABS( AB( L+I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DPBTRS( UPLO, N, KD, 1, AFB, LDAFB, WORK( N+1 ), N,$ INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(A))** ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(A) is the inverse of A* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(A)*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(A) * diag(W),* where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(A**T).*CALL DPBTRS( UPLO, N, KD, 1, AFB, LDAFB, WORK( N+1 ), N,$ INFO )DO 110 I = 1, NWORK( N+I ) = WORK( N+I )*WORK( I )110 CONTINUEELSE IF( KASE.EQ.2 ) THEN** Multiply by inv(A)*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( N+I )*WORK( I )120 CONTINUECALL DPBTRS( UPLO, N, KD, 1, AFB, LDAFB, WORK( N+1 ), N,$ INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DPBRFS*END*> \brief \b DPBSTF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBSTF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbstf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbstf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbstf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBSTF( UPLO, N, KD, AB, LDAB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBSTF computes a split Cholesky factorization of a real*> symmetric positive definite band matrix A.*>*> This routine is designed to be used in conjunction with DSBGST.*>*> The factorization has the form A = S**T*S where S is a band matrix*> of the same bandwidth as A and the following structure:*>*> S = ( U )*> ( M L )*>*> where U is upper triangular of order m = (n+kd)/2, and L is lower*> triangular of order n-m.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first kd+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, if INFO = 0, the factor S from the split Cholesky*> factorization A = S**T*S. See Further Details.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the factorization could not be completed,*> because the updated element a(i,i) was negative; the*> matrix A is not positive definite.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> N = 7, KD = 2:*>*> S = ( s11 s12 s13 )*> ( s22 s23 s24 )*> ( s33 s34 )*> ( s44 )*> ( s53 s54 s55 )*> ( s64 s65 s66 )*> ( s75 s76 s77 )*>*> If UPLO = 'U', the array AB holds:*>*> on entry: on exit:*>*> * * a13 a24 a35 a46 a57 * * s13 s24 s53 s64 s75*> * a12 a23 a34 a45 a56 a67 * s12 s23 s34 s54 s65 s76*> a11 a22 a33 a44 a55 a66 a77 s11 s22 s33 s44 s55 s66 s77*>*> If UPLO = 'L', the array AB holds:*>*> on entry: on exit:*>*> a11 a22 a33 a44 a55 a66 a77 s11 s22 s33 s44 s55 s66 s77*> a21 a32 a43 a54 a65 a76 * s12 s23 s34 s54 s65 s76 **> a31 a42 a53 a64 a64 * * s13 s24 s53 s64 s75 * **>*> Array elements marked * are not used by the routine.*> \endverbatim*>* =====================================================================SUBROUTINE DPBSTF( UPLO, N, KD, AB, LDAB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, KLD, KM, MDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSYR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( LDAB.LT.KD+1 ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBSTF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*KLD = MAX( 1, LDAB-1 )** Set the splitting point m.*M = ( N+KD ) / 2*IF( UPPER ) THEN** Factorize A(m+1:n,m+1:n) as L**T*L, and update A(1:m,1:m).*DO 10 J = N, M + 1, -1** Compute s(j,j) and test for non-positive-definiteness.*AJJ = AB( KD+1, J )IF( AJJ.LE.ZERO )$ GO TO 50AJJ = SQRT( AJJ )AB( KD+1, J ) = AJJKM = MIN( J-1, KD )** Compute elements j-km:j-1 of the j-th column and update the* the leading submatrix within the band.*CALL DSCAL( KM, ONE / AJJ, AB( KD+1-KM, J ), 1 )CALL DSYR( 'Upper', KM, -ONE, AB( KD+1-KM, J ), 1,$ AB( KD+1, J-KM ), KLD )10 CONTINUE** Factorize the updated submatrix A(1:m,1:m) as U**T*U.*DO 20 J = 1, M** Compute s(j,j) and test for non-positive-definiteness.*AJJ = AB( KD+1, J )IF( AJJ.LE.ZERO )$ GO TO 50AJJ = SQRT( AJJ )AB( KD+1, J ) = AJJKM = MIN( KD, M-J )** Compute elements j+1:j+km of the j-th row and update the* trailing submatrix within the band.*IF( KM.GT.0 ) THENCALL DSCAL( KM, ONE / AJJ, AB( KD, J+1 ), KLD )CALL DSYR( 'Upper', KM, -ONE, AB( KD, J+1 ), KLD,$ AB( KD+1, J+1 ), KLD )END IF20 CONTINUEELSE** Factorize A(m+1:n,m+1:n) as L**T*L, and update A(1:m,1:m).*DO 30 J = N, M + 1, -1** Compute s(j,j) and test for non-positive-definiteness.*AJJ = AB( 1, J )IF( AJJ.LE.ZERO )$ GO TO 50AJJ = SQRT( AJJ )AB( 1, J ) = AJJKM = MIN( J-1, KD )** Compute elements j-km:j-1 of the j-th row and update the* trailing submatrix within the band.*CALL DSCAL( KM, ONE / AJJ, AB( KM+1, J-KM ), KLD )CALL DSYR( 'Lower', KM, -ONE, AB( KM+1, J-KM ), KLD,$ AB( 1, J-KM ), KLD )30 CONTINUE** Factorize the updated submatrix A(1:m,1:m) as U**T*U.*DO 40 J = 1, M** Compute s(j,j) and test for non-positive-definiteness.*AJJ = AB( 1, J )IF( AJJ.LE.ZERO )$ GO TO 50AJJ = SQRT( AJJ )AB( 1, J ) = AJJKM = MIN( KD, M-J )** Compute elements j+1:j+km of the j-th column and update the* trailing submatrix within the band.*IF( KM.GT.0 ) THENCALL DSCAL( KM, ONE / AJJ, AB( 2, J ), 1 )CALL DSYR( 'Lower', KM, -ONE, AB( 2, J ), 1,$ AB( 1, J+1 ), KLD )END IF40 CONTINUEEND IFRETURN*50 CONTINUEINFO = JRETURN** End of DPBSTF*END*> \brief <b> DPBSV computes the solution to system of linear equations A * X = B for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBSV( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBSV computes the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric positive definite band matrix and X*> and B are N-by-NRHS matrices.*>*> The Cholesky decomposition is used to factor A as*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular band matrix, and L is a lower*> triangular band matrix, with the same number of superdiagonals or*> subdiagonals as A. The factored form of A is then used to solve the*> system of equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(KD+1+i-j,j) = A(i,j) for max(1,j-KD)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(N,j+KD).*> See below for further details.*>*> On exit, if INFO = 0, the triangular factor U or L from the*> Cholesky factorization A = U**T*U or A = L*L**T of the band*> matrix A, in the same storage format as A.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i of A is not*> positive definite, so the factorization could not be*> completed, and the solution has not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> N = 6, KD = 2, and UPLO = 'U':*>*> On entry: On exit:*>*> * * a13 a24 a35 a46 * * u13 u24 u35 u46*> * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56*> a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66*>*> Similarly, if UPLO = 'L' the format of A is as follows:*>*> On entry: On exit:*>*> a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66*> a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 **> a31 a42 a53 a64 * * l31 l42 l53 l64 * **>*> Array elements marked * are not used by the routine.*> \endverbatim*>* =====================================================================SUBROUTINE DPBSV( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..** =====================================================================** .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPBTRF, DPBTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KD+1 ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBSV ', -INFO )RETURNEND IF** Compute the Cholesky factorization A = U**T*U or A = L*L**T.*CALL DPBTRF( UPLO, N, KD, AB, LDAB, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )*END IFRETURN** End of DPBSV*END*> \brief <b> DPBSVX computes the solution to system of linear equations A * X = B for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbsvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbsvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbsvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBSVX( FACT, UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB,* EQUED, S, B, LDB, X, LDX, RCOND, FERR, BERR,* WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER EQUED, FACT, UPLO* INTEGER INFO, KD, LDAB, LDAFB, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), S( * ), WORK( * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to*> compute the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric positive definite band matrix and X*> and B are N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'E', real scaling factors are computed to equilibrate*> the system:*> diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B*> Whether or not the system will be equilibrated depends on the*> scaling of the matrix A, but if equilibration is used, A is*> overwritten by diag(S)*A*diag(S) and B by diag(S)*B.*>*> 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to*> factor the matrix A (after equilibration if FACT = 'E') as*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular band matrix, and L is a lower*> triangular band matrix.*>*> 3. If the leading i-by-i principal minor is not positive definite,*> then the routine returns with INFO = i. Otherwise, the factored*> form of A is used to estimate the condition number of the matrix*> A. If the reciprocal of the condition number is less than machine*> precision, INFO = N+1 is returned as a warning, but the routine*> still goes on to solve for X and compute error bounds as*> described below.*>*> 4. The system of equations is solved for X using the factored form*> of A.*>*> 5. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*>*> 6. If equilibration was used, the matrix X is premultiplied by*> diag(S) so that it solves the original system before*> equilibration.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of the matrix A is*> supplied on entry, and if not, whether the matrix A should be*> equilibrated before it is factored.*> = 'F': On entry, AFB contains the factored form of A.*> If EQUED = 'Y', the matrix A has been equilibrated*> with scaling factors given by S. AB and AFB will not*> be modified.*> = 'N': The matrix A will be copied to AFB and factored.*> = 'E': The matrix A will be equilibrated if necessary, then*> copied to AFB and factored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right-hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array, except*> if FACT = 'F' and EQUED = 'Y', then A must contain the*> equilibrated matrix diag(S)*A*diag(S). The j-th column of A*> is stored in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(KD+1+i-j,j) = A(i,j) for max(1,j-KD)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(N,j+KD).*> See below for further details.*>*> On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by*> diag(S)*A*diag(S).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array A. LDAB >= KD+1.*> \endverbatim*>*> \param[in,out] AFB*> \verbatim*> AFB is DOUBLE PRECISION array, dimension (LDAFB,N)*> If FACT = 'F', then AFB is an input argument and on entry*> contains the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T of the band matrix*> A, in the same storage format as A (see AB). If EQUED = 'Y',*> then AFB is the factored form of the equilibrated matrix A.*>*> If FACT = 'N', then AFB is an output argument and on exit*> returns the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T.*>*> If FACT = 'E', then AFB is an output argument and on exit*> returns the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T of the equilibrated*> matrix A (see the description of A for the form of the*> equilibrated matrix).*> \endverbatim*>*> \param[in] LDAFB*> \verbatim*> LDAFB is INTEGER*> The leading dimension of the array AFB. LDAFB >= KD+1.*> \endverbatim*>*> \param[in,out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration (always true if FACT = 'N').*> = 'Y': Equilibration was done, i.e., A has been replaced by*> diag(S) * A * diag(S).*> EQUED is an input argument if FACT = 'F'; otherwise, it is an*> output argument.*> \endverbatim*>*> \param[in,out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> The scale factors for A; not accessed if EQUED = 'N'. S is*> an input argument if FACT = 'F'; otherwise, S is an output*> argument. If FACT = 'F' and EQUED = 'Y', each element of S*> must be positive.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',*> B is overwritten by diag(S) * B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to*> the original system of equations. Note that if EQUED = 'Y',*> A and B are modified on exit, and the solution to the*> equilibrated system is inv(diag(S))*X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A after equilibration (if done). If RCOND is less than the*> machine precision (in particular, if RCOND = 0), the matrix*> is singular to working precision. This condition is*> indicated by a return code of INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: the leading minor of order i of A is*> not positive definite, so the factorization*> could not be completed, and the solution has not*> been computed. RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleOTHERsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> N = 6, KD = 2, and UPLO = 'U':*>*> Two-dimensional storage of the symmetric matrix A:*>*> a11 a12 a13*> a22 a23 a24*> a33 a34 a35*> a44 a45 a46*> a55 a56*> (aij=conjg(aji)) a66*>*> Band storage of the upper triangle of A:*>*> * * a13 a24 a35 a46*> * a12 a23 a34 a45 a56*> a11 a22 a33 a44 a55 a66*>*> Similarly, if UPLO = 'L' the format of A is as follows:*>*> a11 a22 a33 a44 a55 a66*> a21 a32 a43 a54 a65 **> a31 a42 a53 a64 * **>*> Array elements marked * are not used by the routine.*> \endverbatim*>* =====================================================================SUBROUTINE DPBSVX( FACT, UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB,$ EQUED, S, B, LDB, X, LDX, RCOND, FERR, BERR,$ WORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER EQUED, FACT, UPLOINTEGER INFO, KD, LDAB, LDAFB, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),$ BERR( * ), FERR( * ), S( * ), WORK( * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL EQUIL, NOFACT, RCEQU, UPPERINTEGER I, INFEQU, J, J1, J2DOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSBEXTERNAL LSAME, DLAMCH, DLANSB* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAQSB, DPBCON, DPBEQU, DPBRFS,$ DPBTRF, DPBTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )EQUIL = LSAME( FACT, 'E' )UPPER = LSAME( UPLO, 'U' )IF( NOFACT .OR. EQUIL ) THENEQUED = 'N'RCEQU = .FALSE.ELSERCEQU = LSAME( EQUED, 'Y' )SMLNUM = DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMEND IF** Test the input parameters.*IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )$ THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KD.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.KD+1 ) THENINFO = -7ELSE IF( LDAFB.LT.KD+1 ) THENINFO = -9ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.$ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THENINFO = -10ELSEIF( RCEQU ) THENSMIN = BIGNUMSMAX = ZERODO 10 J = 1, NSMIN = MIN( SMIN, S( J ) )SMAX = MAX( SMAX, S( J ) )10 CONTINUEIF( SMIN.LE.ZERO ) THENINFO = -11ELSE IF( N.GT.0 ) THENSCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )ELSESCOND = ONEEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDB.LT.MAX( 1, N ) ) THENINFO = -13ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -15END IFEND IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DPBSVX', -INFO )RETURNEND IF*IF( EQUIL ) THEN** Compute row and column scalings to equilibrate the matrix A.*CALL DPBEQU( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, INFEQU )IF( INFEQU.EQ.0 ) THEN** Equilibrate the matrix.*CALL DLAQSB( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, EQUED )RCEQU = LSAME( EQUED, 'Y' )END IFEND IF** Scale the right-hand side.*IF( RCEQU ) THENDO 30 J = 1, NRHSDO 20 I = 1, NB( I, J ) = S( I )*B( I, J )20 CONTINUE30 CONTINUEEND IF*IF( NOFACT .OR. EQUIL ) THEN** Compute the Cholesky factorization A = U**T *U or A = L*L**T.*IF( UPPER ) THENDO 40 J = 1, NJ1 = MAX( J-KD, 1 )CALL DCOPY( J-J1+1, AB( KD+1-J+J1, J ), 1,$ AFB( KD+1-J+J1, J ), 1 )40 CONTINUEELSEDO 50 J = 1, NJ2 = MIN( J+KD, N )CALL DCOPY( J2-J+1, AB( 1, J ), 1, AFB( 1, J ), 1 )50 CONTINUEEND IF*CALL DPBTRF( UPLO, N, KD, AFB, LDAFB, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*ANORM = DLANSB( '1', UPLO, N, KD, AB, LDAB, WORK )** Compute the reciprocal of the condition number of A.*CALL DPBCON( UPLO, N, KD, AFB, LDAFB, ANORM, RCOND, WORK, IWORK,$ INFO )** Compute the solution matrix X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DPBTRS( UPLO, N, KD, NRHS, AFB, LDAFB, X, LDX, INFO )** Use iterative refinement to improve the computed solution and* compute error bounds and backward error estimates for it.*CALL DPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B, LDB, X,$ LDX, FERR, BERR, WORK, IWORK, INFO )** Transform the solution matrix X to a solution of the original* system.*IF( RCEQU ) THENDO 70 J = 1, NRHSDO 60 I = 1, NX( I, J ) = S( I )*X( I, J )60 CONTINUE70 CONTINUEDO 80 J = 1, NRHSFERR( J ) = FERR( J ) / SCOND80 CONTINUEEND IF** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*RETURN** End of DPBSVX*END*> \brief \b DPBTF2 computes the Cholesky factorization of a symmetric/Hermitian positive definite band matrix (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBTF2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbtf2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbtf2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbtf2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBTF2( UPLO, N, KD, AB, LDAB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBTF2 computes the Cholesky factorization of a real symmetric*> positive definite band matrix A.*>*> The factorization has the form*> A = U**T * U , if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix, U**T is the transpose of U, and*> L is lower triangular.*>*> This is the unblocked version of the algorithm, calling Level 2 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of super-diagonals of the matrix A if UPLO = 'U',*> or the number of sub-diagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, if INFO = 0, the triangular factor U or L from the*> Cholesky factorization A = U**T*U or A = L*L**T of the band*> matrix A, in the same storage format as A.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> > 0: if INFO = k, the leading minor of order k is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> N = 6, KD = 2, and UPLO = 'U':*>*> On entry: On exit:*>*> * * a13 a24 a35 a46 * * u13 u24 u35 u46*> * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56*> a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66*>*> Similarly, if UPLO = 'L' the format of A is as follows:*>*> On entry: On exit:*>*> a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66*> a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 **> a31 a42 a53 a64 * * l31 l42 l53 l64 * **>*> Array elements marked * are not used by the routine.*> \endverbatim*>* =====================================================================SUBROUTINE DPBTF2( UPLO, N, KD, AB, LDAB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, KLD, KNDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSYR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( LDAB.LT.KD+1 ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBTF2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*KLD = MAX( 1, LDAB-1 )*IF( UPPER ) THEN** Compute the Cholesky factorization A = U**T*U.*DO 10 J = 1, N** Compute U(J,J) and test for non-positive-definiteness.*AJJ = AB( KD+1, J )IF( AJJ.LE.ZERO )$ GO TO 30AJJ = SQRT( AJJ )AB( KD+1, J ) = AJJ** Compute elements J+1:J+KN of row J and update the* trailing submatrix within the band.*KN = MIN( KD, N-J )IF( KN.GT.0 ) THENCALL DSCAL( KN, ONE / AJJ, AB( KD, J+1 ), KLD )CALL DSYR( 'Upper', KN, -ONE, AB( KD, J+1 ), KLD,$ AB( KD+1, J+1 ), KLD )END IF10 CONTINUEELSE** Compute the Cholesky factorization A = L*L**T.*DO 20 J = 1, N** Compute L(J,J) and test for non-positive-definiteness.*AJJ = AB( 1, J )IF( AJJ.LE.ZERO )$ GO TO 30AJJ = SQRT( AJJ )AB( 1, J ) = AJJ** Compute elements J+1:J+KN of column J and update the* trailing submatrix within the band.*KN = MIN( KD, N-J )IF( KN.GT.0 ) THENCALL DSCAL( KN, ONE / AJJ, AB( 2, J ), 1 )CALL DSYR( 'Lower', KN, -ONE, AB( 2, J ), 1,$ AB( 1, J+1 ), KLD )END IF20 CONTINUEEND IFRETURN*30 CONTINUEINFO = JRETURN** End of DPBTF2*END*> \brief \b DPBTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbtrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbtrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbtrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBTRF( UPLO, N, KD, AB, LDAB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBTRF computes the Cholesky factorization of a real symmetric*> positive definite band matrix A.*>*> The factorization has the form*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, if INFO = 0, the triangular factor U or L from the*> Cholesky factorization A = U**T*U or A = L*L**T of the band*> matrix A, in the same storage format as A.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The band storage scheme is illustrated by the following example, when*> N = 6, KD = 2, and UPLO = 'U':*>*> On entry: On exit:*>*> * * a13 a24 a35 a46 * * u13 u24 u35 u46*> * a12 a23 a34 a45 a56 * u12 u23 u34 u45 u56*> a11 a22 a33 a44 a55 a66 u11 u22 u33 u44 u55 u66*>*> Similarly, if UPLO = 'L' the format of A is as follows:*>*> On entry: On exit:*>*> a11 a22 a33 a44 a55 a66 l11 l22 l33 l44 l55 l66*> a21 a32 a43 a54 a65 * l21 l32 l43 l54 l65 **> a31 a42 a53 a64 * * l31 l42 l53 l64 * **>*> Array elements marked * are not used by the routine.*> \endverbatim**> \par Contributors:* ==================*>*> Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989** =====================================================================SUBROUTINE DPBTRF( UPLO, N, KD, AB, LDAB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )INTEGER NBMAX, LDWORKPARAMETER ( NBMAX = 32, LDWORK = NBMAX+1 )* ..* .. Local Scalars ..INTEGER I, I2, I3, IB, II, J, JJ, NB* ..* .. Local Arrays ..DOUBLE PRECISION WORK( LDWORK, NBMAX )* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DGEMM, DPBTF2, DPOTF2, DSYRK, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( ( .NOT.LSAME( UPLO, 'U' ) ) .AND.$ ( .NOT.LSAME( UPLO, 'L' ) ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( LDAB.LT.KD+1 ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine the block size for this environment*NB = ILAENV( 1, 'DPBTRF', UPLO, N, KD, -1, -1 )** The block size must not exceed the semi-bandwidth KD, and must not* exceed the limit set by the size of the local array WORK.*NB = MIN( NB, NBMAX )*IF( NB.LE.1 .OR. NB.GT.KD ) THEN** Use unblocked code*CALL DPBTF2( UPLO, N, KD, AB, LDAB, INFO )ELSE** Use blocked code*IF( LSAME( UPLO, 'U' ) ) THEN** Compute the Cholesky factorization of a symmetric band* matrix, given the upper triangle of the matrix in band* storage.** Zero the upper triangle of the work array.*DO 20 J = 1, NBDO 10 I = 1, J - 1WORK( I, J ) = ZERO10 CONTINUE20 CONTINUE** Process the band matrix one diagonal block at a time.*DO 70 I = 1, N, NBIB = MIN( NB, N-I+1 )** Factorize the diagonal block*CALL DPOTF2( UPLO, IB, AB( KD+1, I ), LDAB-1, II )IF( II.NE.0 ) THENINFO = I + II - 1GO TO 150END IFIF( I+IB.LE.N ) THEN** Update the relevant part of the trailing submatrix.* If A11 denotes the diagonal block which has just been* factorized, then we need to update the remaining* blocks in the diagram:** A11 A12 A13* A22 A23* A33** The numbers of rows and columns in the partitioning* are IB, I2, I3 respectively. The blocks A12, A22 and* A23 are empty if IB = KD. The upper triangle of A13* lies outside the band.*I2 = MIN( KD-IB, N-I-IB+1 )I3 = MIN( IB, N-I-KD+1 )*IF( I2.GT.0 ) THEN** Update A12*CALL DTRSM( 'Left', 'Upper', 'Transpose',$ 'Non-unit', IB, I2, ONE, AB( KD+1, I ),$ LDAB-1, AB( KD+1-IB, I+IB ), LDAB-1 )** Update A22*CALL DSYRK( 'Upper', 'Transpose', I2, IB, -ONE,$ AB( KD+1-IB, I+IB ), LDAB-1, ONE,$ AB( KD+1, I+IB ), LDAB-1 )END IF*IF( I3.GT.0 ) THEN** Copy the lower triangle of A13 into the work array.*DO 40 JJ = 1, I3DO 30 II = JJ, IBWORK( II, JJ ) = AB( II-JJ+1, JJ+I+KD-1 )30 CONTINUE40 CONTINUE** Update A13 (in the work array).*CALL DTRSM( 'Left', 'Upper', 'Transpose',$ 'Non-unit', IB, I3, ONE, AB( KD+1, I ),$ LDAB-1, WORK, LDWORK )** Update A23*IF( I2.GT.0 )$ CALL DGEMM( 'Transpose', 'No Transpose', I2, I3,$ IB, -ONE, AB( KD+1-IB, I+IB ),$ LDAB-1, WORK, LDWORK, ONE,$ AB( 1+IB, I+KD ), LDAB-1 )** Update A33*CALL DSYRK( 'Upper', 'Transpose', I3, IB, -ONE,$ WORK, LDWORK, ONE, AB( KD+1, I+KD ),$ LDAB-1 )** Copy the lower triangle of A13 back into place.*DO 60 JJ = 1, I3DO 50 II = JJ, IBAB( II-JJ+1, JJ+I+KD-1 ) = WORK( II, JJ )50 CONTINUE60 CONTINUEEND IFEND IF70 CONTINUEELSE** Compute the Cholesky factorization of a symmetric band* matrix, given the lower triangle of the matrix in band* storage.** Zero the lower triangle of the work array.*DO 90 J = 1, NBDO 80 I = J + 1, NBWORK( I, J ) = ZERO80 CONTINUE90 CONTINUE** Process the band matrix one diagonal block at a time.*DO 140 I = 1, N, NBIB = MIN( NB, N-I+1 )** Factorize the diagonal block*CALL DPOTF2( UPLO, IB, AB( 1, I ), LDAB-1, II )IF( II.NE.0 ) THENINFO = I + II - 1GO TO 150END IFIF( I+IB.LE.N ) THEN** Update the relevant part of the trailing submatrix.* If A11 denotes the diagonal block which has just been* factorized, then we need to update the remaining* blocks in the diagram:** A11* A21 A22* A31 A32 A33** The numbers of rows and columns in the partitioning* are IB, I2, I3 respectively. The blocks A21, A22 and* A32 are empty if IB = KD. The lower triangle of A31* lies outside the band.*I2 = MIN( KD-IB, N-I-IB+1 )I3 = MIN( IB, N-I-KD+1 )*IF( I2.GT.0 ) THEN** Update A21*CALL DTRSM( 'Right', 'Lower', 'Transpose',$ 'Non-unit', I2, IB, ONE, AB( 1, I ),$ LDAB-1, AB( 1+IB, I ), LDAB-1 )** Update A22*CALL DSYRK( 'Lower', 'No Transpose', I2, IB, -ONE,$ AB( 1+IB, I ), LDAB-1, ONE,$ AB( 1, I+IB ), LDAB-1 )END IF*IF( I3.GT.0 ) THEN** Copy the upper triangle of A31 into the work array.*DO 110 JJ = 1, IBDO 100 II = 1, MIN( JJ, I3 )WORK( II, JJ ) = AB( KD+1-JJ+II, JJ+I-1 )100 CONTINUE110 CONTINUE** Update A31 (in the work array).*CALL DTRSM( 'Right', 'Lower', 'Transpose',$ 'Non-unit', I3, IB, ONE, AB( 1, I ),$ LDAB-1, WORK, LDWORK )** Update A32*IF( I2.GT.0 )$ CALL DGEMM( 'No transpose', 'Transpose', I3, I2,$ IB, -ONE, WORK, LDWORK,$ AB( 1+IB, I ), LDAB-1, ONE,$ AB( 1+KD-IB, I+IB ), LDAB-1 )** Update A33*CALL DSYRK( 'Lower', 'No Transpose', I3, IB, -ONE,$ WORK, LDWORK, ONE, AB( 1, I+KD ),$ LDAB-1 )** Copy the upper triangle of A31 back into place.*DO 130 JJ = 1, IBDO 120 II = 1, MIN( JJ, I3 )AB( KD+1-JJ+II, JJ+I-1 ) = WORK( II, JJ )120 CONTINUE130 CONTINUEEND IFEND IF140 CONTINUEEND IFEND IFRETURN*150 CONTINUERETURN** End of DPBTRF*END*> \brief \b DPBTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPBTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpbtrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpbtrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpbtrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, KD, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPBTRS solves a system of linear equations A*X = B with a symmetric*> positive definite band matrix A using the Cholesky factorization*> A = U**T*U or A = L*L**T computed by DPBTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangular factor stored in AB;*> = 'L': Lower triangular factor stored in AB.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T of the band matrix A, stored in the*> first KD+1 rows of the array. The j-th column of U or L is*> stored in the j-th column of the array AB as follows:*> if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;*> if UPLO ='L', AB(1+i-j,j) = L(i,j) for j<=i<=min(n,j+kd).*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPBTRS( UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, KD, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL UPPERINTEGER J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTBSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( KD.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KD+1 ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPBTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( UPPER ) THEN** Solve A*X = B where A = U**T *U.*DO 10 J = 1, NRHS** Solve U**T *X = B, overwriting B with X.*CALL DTBSV( 'Upper', 'Transpose', 'Non-unit', N, KD, AB,$ LDAB, B( 1, J ), 1 )** Solve U*X = B, overwriting B with X.*CALL DTBSV( 'Upper', 'No transpose', 'Non-unit', N, KD, AB,$ LDAB, B( 1, J ), 1 )10 CONTINUEELSE** Solve A*X = B where A = L*L**T.*DO 20 J = 1, NRHS** Solve L*X = B, overwriting B with X.*CALL DTBSV( 'Lower', 'No transpose', 'Non-unit', N, KD, AB,$ LDAB, B( 1, J ), 1 )** Solve L**T *X = B, overwriting B with X.*CALL DTBSV( 'Lower', 'Transpose', 'Non-unit', N, KD, AB,$ LDAB, B( 1, J ), 1 )20 CONTINUEEND IF*RETURN** End of DPBTRS*END*> \brief \b DPFTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPFTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpftrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpftrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpftrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPFTRF( TRANSR, UPLO, N, A, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER N, INFO* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: * )***> \par Purpose:* =============*>*> \verbatim*>*> DPFTRF computes the Cholesky factorization of a real symmetric*> positive definite matrix A.*>*> The factorization has the form*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular.*>*> This is the block version of the algorithm, calling Level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': The Normal TRANSR of RFP A is stored;*> = 'T': The Transpose TRANSR of RFP A is stored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of RFP A is stored;*> = 'L': Lower triangle of RFP A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 );*> On entry, the symmetric matrix A in RFP format. RFP format is*> described by TRANSR, UPLO, and N as follows: If TRANSR = 'N'*> then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is*> (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is*> the transpose of RFP A as defined when*> TRANSR = 'N'. The contents of RFP A are defined by UPLO as*> follows: If UPLO = 'U' the RFP A contains the NT elements of*> upper packed A. If UPLO = 'L' the RFP A contains the elements*> of lower packed A. The LDA of RFP A is (N+1)/2 when TRANSR =*> 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and N*> is odd. See the Note below for more details.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization RFP A = U**T*U or RFP A = L*L**T.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim*>* =====================================================================SUBROUTINE DPFTRF( TRANSR, UPLO, N, A, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER N, INFO* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: * )** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER N1, N2, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DSYRK, DPOTRF, DTRSM* ..* .. Intrinsic Functions ..INTRINSIC MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPFTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** If N is odd, set NISODD = .TRUE.* If N is even, set K = N/2 and NISODD = .FALSE.*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.ELSENISODD = .TRUE.END IF** Set N1 and N2 depending on LOWER*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF** start execution: there are eight cases*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:n1-1) )* T1 -> a(0,0), T2 -> a(0,1), S -> a(n1,0)* T1 -> a(0), T2 -> a(n), S -> a(n1)*CALL DPOTRF( 'L', N1, A( 0 ), N, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'R', 'L', 'T', 'N', N2, N1, ONE, A( 0 ), N,$ A( N1 ), N )CALL DSYRK( 'U', 'N', N2, N1, -ONE, A( N1 ), N, ONE,$ A( N ), N )CALL DPOTRF( 'U', N2, A( N ), N, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1*ELSE** SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:n2-1)* T1 -> a(n1+1,0), T2 -> a(n1,0), S -> a(0,0)* T1 -> a(n2), T2 -> a(n1), S -> a(0)*CALL DPOTRF( 'L', N1, A( N2 ), N, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'L', 'L', 'N', 'N', N1, N2, ONE, A( N2 ), N,$ A( 0 ), N )CALL DSYRK( 'U', 'T', N2, N1, -ONE, A( 0 ), N, ONE,$ A( N1 ), N )CALL DPOTRF( 'U', N2, A( N1 ), N, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE and N is odd* T1 -> A(0,0) , T2 -> A(1,0) , S -> A(0,n1)* T1 -> a(0+0) , T2 -> a(1+0) , S -> a(0+n1*n1); lda=n1*CALL DPOTRF( 'U', N1, A( 0 ), N1, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'L', 'U', 'T', 'N', N1, N2, ONE, A( 0 ), N1,$ A( N1*N1 ), N1 )CALL DSYRK( 'L', 'T', N2, N1, -ONE, A( N1*N1 ), N1, ONE,$ A( 1 ), N1 )CALL DPOTRF( 'L', N2, A( 1 ), N1, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1*ELSE** SRPA for UPPER, TRANSPOSE and N is odd* T1 -> A(0,n1+1), T2 -> A(0,n1), S -> A(0,0)* T1 -> a(n2*n2), T2 -> a(n1*n2), S -> a(0); lda = n2*CALL DPOTRF( 'U', N1, A( N2*N2 ), N2, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'R', 'U', 'N', 'N', N2, N1, ONE, A( N2*N2 ),$ N2, A( 0 ), N2 )CALL DSYRK( 'L', 'N', N2, N1, -ONE, A( 0 ), N2, ONE,$ A( N1*N2 ), N2 )CALL DPOTRF( 'L', N2, A( N1*N2 ), N2, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0)* T1 -> a(1), T2 -> a(0), S -> a(k+1)*CALL DPOTRF( 'L', K, A( 1 ), N+1, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'R', 'L', 'T', 'N', K, K, ONE, A( 1 ), N+1,$ A( K+1 ), N+1 )CALL DSYRK( 'U', 'N', K, K, -ONE, A( K+1 ), N+1, ONE,$ A( 0 ), N+1 )CALL DPOTRF( 'U', K, A( 0 ), N+1, INFO )IF( INFO.GT.0 )$ INFO = INFO + K*ELSE** SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0)* T1 -> a(k+1), T2 -> a(k), S -> a(0)*CALL DPOTRF( 'L', K, A( K+1 ), N+1, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'L', 'L', 'N', 'N', K, K, ONE, A( K+1 ),$ N+1, A( 0 ), N+1 )CALL DSYRK( 'U', 'T', K, K, -ONE, A( 0 ), N+1, ONE,$ A( K ), N+1 )CALL DPOTRF( 'U', K, A( K ), N+1, INFO )IF( INFO.GT.0 )$ INFO = INFO + K*END IF*ELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE and N is even (see paper)* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1)* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k*CALL DPOTRF( 'U', K, A( 0+K ), K, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'L', 'U', 'T', 'N', K, K, ONE, A( K ), N1,$ A( K*( K+1 ) ), K )CALL DSYRK( 'L', 'T', K, K, -ONE, A( K*( K+1 ) ), K, ONE,$ A( 0 ), K )CALL DPOTRF( 'L', K, A( 0 ), K, INFO )IF( INFO.GT.0 )$ INFO = INFO + K*ELSE** SRPA for UPPER, TRANSPOSE and N is even (see paper)* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0)* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k*CALL DPOTRF( 'U', K, A( K*( K+1 ) ), K, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRSM( 'R', 'U', 'N', 'N', K, K, ONE,$ A( K*( K+1 ) ), K, A( 0 ), K )CALL DSYRK( 'L', 'N', K, K, -ONE, A( 0 ), K, ONE,$ A( K*K ), K )CALL DPOTRF( 'L', K, A( K*K ), K, INFO )IF( INFO.GT.0 )$ INFO = INFO + K*END IF*END IF*END IF*RETURN** End of DPFTRF*END*> \brief \b DPFTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPFTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpftri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpftri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpftri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPFTRI( TRANSR, UPLO, N, A, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER INFO, N* .. Array Arguments ..* DOUBLE PRECISION A( 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPFTRI computes the inverse of a (real) symmetric positive definite*> matrix A using the Cholesky factorization A = U**T*U or A = L*L**T*> computed by DPFTRF.*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': The Normal TRANSR of RFP A is stored;*> = 'T': The Transpose TRANSR of RFP A is stored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 )*> On entry, the symmetric matrix A in RFP format. RFP format is*> described by TRANSR, UPLO, and N as follows: If TRANSR = 'N'*> then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is*> (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is*> the transpose of RFP A as defined when*> TRANSR = 'N'. The contents of RFP A are defined by UPLO as*> follows: If UPLO = 'U' the RFP A contains the nt elements of*> upper packed A. If UPLO = 'L' the RFP A contains the elements*> of lower packed A. The LDA of RFP A is (N+1)/2 when TRANSR =*> 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and N*> is odd. See the Note below for more details.*>*> On exit, the symmetric inverse of the original matrix, in the*> same storage format.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the (i,i) element of the factor U or L is*> zero, and the inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim*>* =====================================================================SUBROUTINE DPFTRI( TRANSR, UPLO, N, A, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER INFO, N* .. Array Arguments ..DOUBLE PRECISION A( 0: * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER N1, N2, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DTFTRI, DLAUUM, DTRMM, DSYRK* ..* .. Intrinsic Functions ..INTRINSIC MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPFTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Invert the triangular Cholesky factor U or L.*CALL DTFTRI( TRANSR, UPLO, 'N', N, A, INFO )IF( INFO.GT.0 )$ RETURN** If N is odd, set NISODD = .TRUE.* If N is even, set K = N/2 and NISODD = .FALSE.*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.ELSENISODD = .TRUE.END IF** Set N1 and N2 depending on LOWER*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF** Start execution of triangular matrix multiply: inv(U)*inv(U)^C or* inv(L)^C*inv(L). There are eight cases.*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:N1-1) )* T1 -> a(0,0), T2 -> a(0,1), S -> a(N1,0)* T1 -> a(0), T2 -> a(n), S -> a(N1)*CALL DLAUUM( 'L', N1, A( 0 ), N, INFO )CALL DSYRK( 'L', 'T', N1, N2, ONE, A( N1 ), N, ONE,$ A( 0 ), N )CALL DTRMM( 'L', 'U', 'N', 'N', N2, N1, ONE, A( N ), N,$ A( N1 ), N )CALL DLAUUM( 'U', N2, A( N ), N, INFO )*ELSE** SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:N2-1)* T1 -> a(N1+1,0), T2 -> a(N1,0), S -> a(0,0)* T1 -> a(N2), T2 -> a(N1), S -> a(0)*CALL DLAUUM( 'L', N1, A( N2 ), N, INFO )CALL DSYRK( 'L', 'N', N1, N2, ONE, A( 0 ), N, ONE,$ A( N2 ), N )CALL DTRMM( 'R', 'U', 'T', 'N', N1, N2, ONE, A( N1 ), N,$ A( 0 ), N )CALL DLAUUM( 'U', N2, A( N1 ), N, INFO )*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE, and N is odd* T1 -> a(0), T2 -> a(1), S -> a(0+N1*N1)*CALL DLAUUM( 'U', N1, A( 0 ), N1, INFO )CALL DSYRK( 'U', 'N', N1, N2, ONE, A( N1*N1 ), N1, ONE,$ A( 0 ), N1 )CALL DTRMM( 'R', 'L', 'N', 'N', N1, N2, ONE, A( 1 ), N1,$ A( N1*N1 ), N1 )CALL DLAUUM( 'L', N2, A( 1 ), N1, INFO )*ELSE** SRPA for UPPER, TRANSPOSE, and N is odd* T1 -> a(0+N2*N2), T2 -> a(0+N1*N2), S -> a(0)*CALL DLAUUM( 'U', N1, A( N2*N2 ), N2, INFO )CALL DSYRK( 'U', 'T', N1, N2, ONE, A( 0 ), N2, ONE,$ A( N2*N2 ), N2 )CALL DTRMM( 'L', 'L', 'T', 'N', N2, N1, ONE, A( N1*N2 ),$ N2, A( 0 ), N2 )CALL DLAUUM( 'L', N2, A( N1*N2 ), N2, INFO )*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0)* T1 -> a(1), T2 -> a(0), S -> a(k+1)*CALL DLAUUM( 'L', K, A( 1 ), N+1, INFO )CALL DSYRK( 'L', 'T', K, K, ONE, A( K+1 ), N+1, ONE,$ A( 1 ), N+1 )CALL DTRMM( 'L', 'U', 'N', 'N', K, K, ONE, A( 0 ), N+1,$ A( K+1 ), N+1 )CALL DLAUUM( 'U', K, A( 0 ), N+1, INFO )*ELSE** SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0)* T1 -> a(k+1), T2 -> a(k), S -> a(0)*CALL DLAUUM( 'L', K, A( K+1 ), N+1, INFO )CALL DSYRK( 'L', 'N', K, K, ONE, A( 0 ), N+1, ONE,$ A( K+1 ), N+1 )CALL DTRMM( 'R', 'U', 'T', 'N', K, K, ONE, A( K ), N+1,$ A( 0 ), N+1 )CALL DLAUUM( 'U', K, A( K ), N+1, INFO )*END IF*ELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE, and N is even (see paper)* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1),* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k*CALL DLAUUM( 'U', K, A( K ), K, INFO )CALL DSYRK( 'U', 'N', K, K, ONE, A( K*( K+1 ) ), K, ONE,$ A( K ), K )CALL DTRMM( 'R', 'L', 'N', 'N', K, K, ONE, A( 0 ), K,$ A( K*( K+1 ) ), K )CALL DLAUUM( 'L', K, A( 0 ), K, INFO )*ELSE** SRPA for UPPER, TRANSPOSE, and N is even (see paper)* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0),* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k*CALL DLAUUM( 'U', K, A( K*( K+1 ) ), K, INFO )CALL DSYRK( 'U', 'T', K, K, ONE, A( 0 ), K, ONE,$ A( K*( K+1 ) ), K )CALL DTRMM( 'L', 'L', 'T', 'N', K, K, ONE, A( K*K ), K,$ A( 0 ), K )CALL DLAUUM( 'L', K, A( K*K ), K, INFO )*END IF*END IF*END IF*RETURN** End of DPFTRI*END*> \brief \b DPFTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPFTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpftrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpftrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpftrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPFTRS( TRANSR, UPLO, N, NRHS, A, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPFTRS solves a system of linear equations A*X = B with a symmetric*> positive definite matrix A using the Cholesky factorization*> A = U**T*U or A = L*L**T computed by DPFTRF.*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': The Normal TRANSR of RFP A is stored;*> = 'T': The Transpose TRANSR of RFP A is stored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of RFP A is stored;*> = 'L': Lower triangle of RFP A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ).*> The triangular factor U or L from the Cholesky factorization*> of RFP A = U**T*U or RFP A = L*L**T, as computed by DPFTRF.*> See note below for more details about RFP A.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim*>* =====================================================================SUBROUTINE DPFTRS( TRANSR, UPLO, N, NRHS, A, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, NORMALTRANSR* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DTFSM* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPFTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN** start execution: there are two triangular solves*IF( LOWER ) THENCALL DTFSM( TRANSR, 'L', UPLO, 'N', 'N', N, NRHS, ONE, A, B,$ LDB )CALL DTFSM( TRANSR, 'L', UPLO, 'T', 'N', N, NRHS, ONE, A, B,$ LDB )ELSECALL DTFSM( TRANSR, 'L', UPLO, 'T', 'N', N, NRHS, ONE, A, B,$ LDB )CALL DTFSM( TRANSR, 'L', UPLO, 'N', 'N', N, NRHS, ONE, A, B,$ LDB )END IF*RETURN** End of DPFTRS*END*> \brief \b DPOCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpocon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpocon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpocon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOCON estimates the reciprocal of the condition number (in the*> 1-norm) of a real symmetric positive definite matrix using the*> Cholesky factorization A = U**T*U or A = L*L**T computed by DPOTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T, as computed by DPOTRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> The 1-norm (or infinity-norm) of the symmetric matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an*> estimate of the 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOCON( UPLO, N, A, LDA, ANORM, RCOND, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERCHARACTER NORMININTEGER IX, KASEDOUBLE PRECISION AINVNM, SCALE, SCALEL, SCALEU, SMLNUM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL LSAME, IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATRS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( ANORM.LT.ZERO ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the 1-norm of inv(A).*KASE = 0NORMIN = 'N'10 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( UPPER ) THEN** Multiply by inv(U**T).*CALL DLATRS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N, A,$ LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO )NORMIN = 'Y'** Multiply by inv(U).*CALL DLATRS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ A, LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO )ELSE** Multiply by inv(L).*CALL DLATRS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,$ A, LDA, WORK, SCALEL, WORK( 2*N+1 ), INFO )NORMIN = 'Y'** Multiply by inv(L**T).*CALL DLATRS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N, A,$ LDA, WORK, SCALEU, WORK( 2*N+1 ), INFO )END IF** Multiply by 1/SCALE if doing so will not cause overflow.*SCALE = SCALEL*SCALEUIF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*20 CONTINUERETURN** End of DPOCON*END*> \brief \b DPOEQU** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOEQU + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpoequ.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpoequ.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpoequ.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOEQU( N, A, LDA, S, SCOND, AMAX, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOEQU computes row and column scalings intended to equilibrate a*> symmetric positive definite matrix A and reduce its condition number*> (with respect to the two-norm). S contains the scale factors,*> S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with*> elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This*> choice of S puts the condition number of B within a factor N of the*> smallest possible condition number over all possible diagonal*> scalings.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The N-by-N symmetric positive definite matrix whose scaling*> factors are to be computed. Only the diagonal elements of A*> are referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, S contains the scale factors for A.*> \endverbatim*>*> \param[out] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> If INFO = 0, S contains the ratio of the smallest S(i) to*> the largest S(i). If SCOND >= 0.1 and AMAX is neither too*> large nor too small, it is not worth scaling by S.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element is nonpositive.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOEQU( N, A, LDA, S, SCOND, AMAX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION SMIN* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOEQU', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSCOND = ONEAMAX = ZERORETURNEND IF** Find the minimum and maximum diagonal elements.*S( 1 ) = A( 1, 1 )SMIN = S( 1 )AMAX = S( 1 )DO 10 I = 2, NS( I ) = A( I, I )SMIN = MIN( SMIN, S( I ) )AMAX = MAX( AMAX, S( I ) )10 CONTINUE*IF( SMIN.LE.ZERO ) THEN** Find the first non-positive diagonal element and return.*DO 20 I = 1, NIF( S( I ).LE.ZERO ) THENINFO = IRETURNEND IF20 CONTINUEELSE** Set the scale factors to the reciprocals* of the diagonal elements.*DO 30 I = 1, NS( I ) = ONE / SQRT( S( I ) )30 CONTINUE** Compute SCOND = min(S(I)) / max(S(I))*SCOND = SQRT( SMIN ) / SQRT( AMAX )END IFRETURN** End of DPOEQU*END*> \brief \b DPOEQUB** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOEQUB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpoequb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpoequb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpoequb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOEQUB( N, A, LDA, S, SCOND, AMAX, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOEQUB computes row and column scalings intended to equilibrate a*> symmetric positive definite matrix A and reduce its condition number*> (with respect to the two-norm). S contains the scale factors,*> S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with*> elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This*> choice of S puts the condition number of B within a factor N of the*> smallest possible condition number over all possible diagonal*> scalings.*>*> This routine differs from DPOEQU by restricting the scaling factors*> to a power of the radix. Barring over- and underflow, scaling by*> these factors introduces no additional rounding errors. However, the*> scaled diagonal entries are no longer approximately 1 but lie*> between sqrt(radix) and 1/sqrt(radix).*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The N-by-N symmetric positive definite matrix whose scaling*> factors are to be computed. Only the diagonal elements of A*> are referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, S contains the scale factors for A.*> \endverbatim*>*> \param[out] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> If INFO = 0, S contains the ratio of the smallest S(i) to*> the largest S(i). If SCOND >= 0.1 and AMAX is neither too*> large nor too small, it is not worth scaling by S.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element is nonpositive.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOEQUB( N, A, LDA, S, SCOND, AMAX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..INTEGER IDOUBLE PRECISION SMIN, BASE, TMP* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT, LOG, INT* ..* .. Executable Statements ..** Test the input parameters.** Positive definite only performs 1 pass of equilibration.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOEQUB', -INFO )RETURNEND IF** Quick return if possible.*IF( N.EQ.0 ) THENSCOND = ONEAMAX = ZERORETURNEND IFBASE = DLAMCH( 'B' )TMP = -0.5D+0 / LOG ( BASE )** Find the minimum and maximum diagonal elements.*S( 1 ) = A( 1, 1 )SMIN = S( 1 )AMAX = S( 1 )DO 10 I = 2, NS( I ) = A( I, I )SMIN = MIN( SMIN, S( I ) )AMAX = MAX( AMAX, S( I ) )10 CONTINUE*IF( SMIN.LE.ZERO ) THEN** Find the first non-positive diagonal element and return.*DO 20 I = 1, NIF( S( I ).LE.ZERO ) THENINFO = IRETURNEND IF20 CONTINUEELSE** Set the scale factors to the reciprocals* of the diagonal elements.*DO 30 I = 1, NS( I ) = BASE ** INT( TMP * LOG( S( I ) ) )30 CONTINUE** Compute SCOND = min(S(I)) / max(S(I)).*SCOND = SQRT( SMIN ) / SQRT( AMAX )END IF*RETURN** End of DPOEQUB*END*> \brief \b DPORFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPORFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dporfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dporfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dporfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPORFS( UPLO, N, NRHS, A, LDA, AF, LDAF, B, LDB, X,* LDX, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPORFS improves the computed solution to a system of linear*> equations when the coefficient matrix is symmetric positive definite,*> and provides error bounds and backward error estimates for the*> solution.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The symmetric matrix A. If UPLO = 'U', the leading N-by-N*> upper triangular part of A contains the upper triangular part*> of the matrix A, and the strictly lower triangular part of A*> is not referenced. If UPLO = 'L', the leading N-by-N lower*> triangular part of A contains the lower triangular part of*> the matrix A, and the strictly upper triangular part of A is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] AF*> \verbatim*> AF is DOUBLE PRECISION array, dimension (LDAF,N)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T, as computed by DPOTRF.*> \endverbatim*>*> \param[in] LDAF*> \verbatim*> LDAF is INTEGER*> The leading dimension of the array AF. LDAF >= max(1,N).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DPOTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPORFS( UPLO, N, NRHS, A, LDA, AF, LDAF, B, LDB, X,$ LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER COUNT, I, J, K, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DPOTRS, DSYMV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPORFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - A * X*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DSYMV( UPLO, N, -ONE, A, LDA, X( 1, J ), 1, ONE,$ WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(A)*abs(X) + abs(B).*IF( UPPER ) THENDO 50 K = 1, NS = ZEROXK = ABS( X( K, J ) )DO 40 I = 1, K - 1WORK( I ) = WORK( I ) + ABS( A( I, K ) )*XKS = S + ABS( A( I, K ) )*ABS( X( I, J ) )40 CONTINUEWORK( K ) = WORK( K ) + ABS( A( K, K ) )*XK + S50 CONTINUEELSEDO 70 K = 1, NS = ZEROXK = ABS( X( K, J ) )WORK( K ) = WORK( K ) + ABS( A( K, K ) )*XKDO 60 I = K + 1, NWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XKS = S + ABS( A( I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DPOTRS( UPLO, N, 1, AF, LDAF, WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(A))** ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(A) is the inverse of A* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(A)*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(A) * diag(W),* where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(A**T).*CALL DPOTRS( UPLO, N, 1, AF, LDAF, WORK( N+1 ), N, INFO )DO 110 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )110 CONTINUEELSE IF( KASE.EQ.2 ) THEN** Multiply by inv(A)*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )120 CONTINUECALL DPOTRS( UPLO, N, 1, AF, LDAF, WORK( N+1 ), N, INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DPORFS*END*> \brief <b> DPOSV computes the solution to system of linear equations A * X = B for PO matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dposv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dposv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dposv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOSV( UPLO, N, NRHS, A, LDA, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOSV computes the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric positive definite matrix and X and B*> are N-by-NRHS matrices.*>*> The Cholesky decomposition is used to factor A as*> A = U**T* U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is a lower triangular*> matrix. The factored form of A is then used to solve the system of*> equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i of A is not*> positive definite, so the factorization could not be*> completed, and the solution has not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOsolve** =====================================================================SUBROUTINE DPOSV( UPLO, N, NRHS, A, LDA, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPOTRF, DPOTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOSV ', -INFO )RETURNEND IF** Compute the Cholesky factorization A = U**T*U or A = L*L**T.*CALL DPOTRF( UPLO, N, A, LDA, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )*END IFRETURN** End of DPOSV*END*> \brief <b> DPOSVX computes the solution to system of linear equations A * X = B for PO matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dposvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dposvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dposvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOSVX( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, EQUED,* S, B, LDB, X, LDX, RCOND, FERR, BERR, WORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER EQUED, FACT, UPLO* INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), S( * ), WORK( * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to*> compute the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric positive definite matrix and X and B*> are N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'E', real scaling factors are computed to equilibrate*> the system:*> diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B*> Whether or not the system will be equilibrated depends on the*> scaling of the matrix A, but if equilibration is used, A is*> overwritten by diag(S)*A*diag(S) and B by diag(S)*B.*>*> 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to*> factor the matrix A (after equilibration if FACT = 'E') as*> A = U**T* U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is a lower triangular*> matrix.*>*> 3. If the leading i-by-i principal minor is not positive definite,*> then the routine returns with INFO = i. Otherwise, the factored*> form of A is used to estimate the condition number of the matrix*> A. If the reciprocal of the condition number is less than machine*> precision, INFO = N+1 is returned as a warning, but the routine*> still goes on to solve for X and compute error bounds as*> described below.*>*> 4. The system of equations is solved for X using the factored form*> of A.*>*> 5. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*>*> 6. If equilibration was used, the matrix X is premultiplied by*> diag(S) so that it solves the original system before*> equilibration.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of the matrix A is*> supplied on entry, and if not, whether the matrix A should be*> equilibrated before it is factored.*> = 'F': On entry, AF contains the factored form of A.*> If EQUED = 'Y', the matrix A has been equilibrated*> with scaling factors given by S. A and AF will not*> be modified.*> = 'N': The matrix A will be copied to AF and factored.*> = 'E': The matrix A will be equilibrated if necessary, then*> copied to AF and factored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A, except if FACT = 'F' and*> EQUED = 'Y', then A must contain the equilibrated matrix*> diag(S)*A*diag(S). If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced. A is not modified if*> FACT = 'F' or 'N', or if FACT = 'E' and EQUED = 'N' on exit.*>*> On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by*> diag(S)*A*diag(S).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] AF*> \verbatim*> AF is DOUBLE PRECISION array, dimension (LDAF,N)*> If FACT = 'F', then AF is an input argument and on entry*> contains the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T, in the same storage*> format as A. If EQUED .ne. 'N', then AF is the factored form*> of the equilibrated matrix diag(S)*A*diag(S).*>*> If FACT = 'N', then AF is an output argument and on exit*> returns the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T of the original*> matrix A.*>*> If FACT = 'E', then AF is an output argument and on exit*> returns the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T of the equilibrated*> matrix A (see the description of A for the form of the*> equilibrated matrix).*> \endverbatim*>*> \param[in] LDAF*> \verbatim*> LDAF is INTEGER*> The leading dimension of the array AF. LDAF >= max(1,N).*> \endverbatim*>*> \param[in,out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration (always true if FACT = 'N').*> = 'Y': Equilibration was done, i.e., A has been replaced by*> diag(S) * A * diag(S).*> EQUED is an input argument if FACT = 'F'; otherwise, it is an*> output argument.*> \endverbatim*>*> \param[in,out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> The scale factors for A; not accessed if EQUED = 'N'. S is*> an input argument if FACT = 'F'; otherwise, S is an output*> argument. If FACT = 'F' and EQUED = 'Y', each element of S*> must be positive.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',*> B is overwritten by diag(S) * B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to*> the original system of equations. Note that if EQUED = 'Y',*> A and B are modified on exit, and the solution to the*> equilibrated system is inv(diag(S))*X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A after equilibration (if done). If RCOND is less than the*> machine precision (in particular, if RCOND = 0), the matrix*> is singular to working precision. This condition is*> indicated by a return code of INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: the leading minor of order i of A is*> not positive definite, so the factorization*> could not be completed, and the solution has not*> been computed. RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doublePOsolve** =====================================================================SUBROUTINE DPOSVX( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, EQUED,$ S, B, LDB, X, LDX, RCOND, FERR, BERR, WORK,$ IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER EQUED, FACT, UPLOINTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), FERR( * ), S( * ), WORK( * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL EQUIL, NOFACT, RCEQUINTEGER I, INFEQU, JDOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, DLAMCH, DLANSY* ..* .. External Subroutines ..EXTERNAL DLACPY, DLAQSY, DPOCON, DPOEQU, DPORFS, DPOTRF,$ DPOTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )EQUIL = LSAME( FACT, 'E' )IF( NOFACT .OR. EQUIL ) THENEQUED = 'N'RCEQU = .FALSE.ELSERCEQU = LSAME( EQUED, 'Y' )SMLNUM = DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMEND IF** Test the input parameters.*IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )$ THENINFO = -1ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )$ THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.$ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THENINFO = -9ELSEIF( RCEQU ) THENSMIN = BIGNUMSMAX = ZERODO 10 J = 1, NSMIN = MIN( SMIN, S( J ) )SMAX = MAX( SMAX, S( J ) )10 CONTINUEIF( SMIN.LE.ZERO ) THENINFO = -10ELSE IF( N.GT.0 ) THENSCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )ELSESCOND = ONEEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDB.LT.MAX( 1, N ) ) THENINFO = -12ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -14END IFEND IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DPOSVX', -INFO )RETURNEND IF*IF( EQUIL ) THEN** Compute row and column scalings to equilibrate the matrix A.*CALL DPOEQU( N, A, LDA, S, SCOND, AMAX, INFEQU )IF( INFEQU.EQ.0 ) THEN** Equilibrate the matrix.*CALL DLAQSY( UPLO, N, A, LDA, S, SCOND, AMAX, EQUED )RCEQU = LSAME( EQUED, 'Y' )END IFEND IF** Scale the right hand side.*IF( RCEQU ) THENDO 30 J = 1, NRHSDO 20 I = 1, NB( I, J ) = S( I )*B( I, J )20 CONTINUE30 CONTINUEEND IF*IF( NOFACT .OR. EQUIL ) THEN** Compute the Cholesky factorization A = U**T *U or A = L*L**T.*CALL DLACPY( UPLO, N, N, A, LDA, AF, LDAF )CALL DPOTRF( UPLO, N, AF, LDAF, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*ANORM = DLANSY( '1', UPLO, N, A, LDA, WORK )** Compute the reciprocal of the condition number of A.*CALL DPOCON( UPLO, N, AF, LDAF, ANORM, RCOND, WORK, IWORK, INFO )** Compute the solution matrix X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DPOTRS( UPLO, N, NRHS, AF, LDAF, X, LDX, INFO )** Use iterative refinement to improve the computed solution and* compute error bounds and backward error estimates for it.*CALL DPORFS( UPLO, N, NRHS, A, LDA, AF, LDAF, B, LDB, X, LDX,$ FERR, BERR, WORK, IWORK, INFO )** Transform the solution matrix X to a solution of the original* system.*IF( RCEQU ) THENDO 50 J = 1, NRHSDO 40 I = 1, NX( I, J ) = S( I )*X( I, J )40 CONTINUE50 CONTINUEDO 60 J = 1, NRHSFERR( J ) = FERR( J ) / SCOND60 CONTINUEEND IF** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*RETURN** End of DPOSVX*END*> \brief \b DPOTF2 computes the Cholesky factorization of a symmetric/Hermitian positive definite matrix (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOTF2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpotf2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpotf2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpotf2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOTF2( UPLO, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOTF2 computes the Cholesky factorization of a real symmetric*> positive definite matrix A.*>*> The factorization has the form*> A = U**T * U , if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular.*>*> This is the unblocked version of the algorithm, calling Level 2 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n by n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n by n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization A = U**T *U or A = L*L**T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> > 0: if INFO = k, the leading minor of order k is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOTF2( UPLO, N, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER JDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAME, DISNANDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT, DISNAN* ..* .. External Subroutines ..EXTERNAL DGEMV, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOTF2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( UPPER ) THEN** Compute the Cholesky factorization A = U**T *U.*DO 10 J = 1, N** Compute U(J,J) and test for non-positive-definiteness.*AJJ = A( J, J ) - DDOT( J-1, A( 1, J ), 1, A( 1, J ), 1 )IF( AJJ.LE.ZERO.OR.DISNAN( AJJ ) ) THENA( J, J ) = AJJGO TO 30END IFAJJ = SQRT( AJJ )A( J, J ) = AJJ** Compute elements J+1:N of row J.*IF( J.LT.N ) THENCALL DGEMV( 'Transpose', J-1, N-J, -ONE, A( 1, J+1 ),$ LDA, A( 1, J ), 1, ONE, A( J, J+1 ), LDA )CALL DSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )END IF10 CONTINUEELSE** Compute the Cholesky factorization A = L*L**T.*DO 20 J = 1, N** Compute L(J,J) and test for non-positive-definiteness.*AJJ = A( J, J ) - DDOT( J-1, A( J, 1 ), LDA, A( J, 1 ),$ LDA )IF( AJJ.LE.ZERO.OR.DISNAN( AJJ ) ) THENA( J, J ) = AJJGO TO 30END IFAJJ = SQRT( AJJ )A( J, J ) = AJJ** Compute elements J+1:N of column J.*IF( J.LT.N ) THENCALL DGEMV( 'No transpose', N-J, J-1, -ONE, A( J+1, 1 ),$ LDA, A( J, 1 ), LDA, ONE, A( J+1, J ), 1 )CALL DSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )END IF20 CONTINUEEND IFGO TO 40*30 CONTINUEINFO = J*40 CONTINUERETURN** End of DPOTF2*END*> \brief \b DPOTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpotrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpotrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpotrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOTRF( UPLO, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOTRF computes the Cholesky factorization of a real symmetric*> positive definite matrix A.*>*> The factorization has the form*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular.*>*> This is the block version of the algorithm, calling Level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOTRF( UPLO, N, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, JB, NB* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DGEMM, DPOTRF2, DSYRK, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine the block size for this environment.*NB = ILAENV( 1, 'DPOTRF', UPLO, N, -1, -1, -1 )IF( NB.LE.1 .OR. NB.GE.N ) THEN** Use unblocked code.*CALL DPOTRF2( UPLO, N, A, LDA, INFO )ELSE** Use blocked code.*IF( UPPER ) THEN** Compute the Cholesky factorization A = U**T*U.*DO 10 J = 1, N, NB** Update and factorize the current diagonal block and test* for non-positive-definiteness.*JB = MIN( NB, N-J+1 )CALL DSYRK( 'Upper', 'Transpose', JB, J-1, -ONE,$ A( 1, J ), LDA, ONE, A( J, J ), LDA )CALL DPOTRF2( 'Upper', JB, A( J, J ), LDA, INFO )IF( INFO.NE.0 )$ GO TO 30IF( J+JB.LE.N ) THEN** Compute the current block row.*CALL DGEMM( 'Transpose', 'No transpose', JB, N-J-JB+1,$ J-1, -ONE, A( 1, J ), LDA, A( 1, J+JB ),$ LDA, ONE, A( J, J+JB ), LDA )CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit',$ JB, N-J-JB+1, ONE, A( J, J ), LDA,$ A( J, J+JB ), LDA )END IF10 CONTINUE*ELSE** Compute the Cholesky factorization A = L*L**T.*DO 20 J = 1, N, NB** Update and factorize the current diagonal block and test* for non-positive-definiteness.*JB = MIN( NB, N-J+1 )CALL DSYRK( 'Lower', 'No transpose', JB, J-1, -ONE,$ A( J, 1 ), LDA, ONE, A( J, J ), LDA )CALL DPOTRF2( 'Lower', JB, A( J, J ), LDA, INFO )IF( INFO.NE.0 )$ GO TO 30IF( J+JB.LE.N ) THEN** Compute the current block column.*CALL DGEMM( 'No transpose', 'Transpose', N-J-JB+1, JB,$ J-1, -ONE, A( J+JB, 1 ), LDA, A( J, 1 ),$ LDA, ONE, A( J+JB, J ), LDA )CALL DTRSM( 'Right', 'Lower', 'Transpose', 'Non-unit',$ N-J-JB+1, JB, ONE, A( J, J ), LDA,$ A( J+JB, J ), LDA )END IF20 CONTINUEEND IFEND IFGO TO 40*30 CONTINUEINFO = INFO + J - 1*40 CONTINUERETURN** End of DPOTRF*END*> \brief \b DPOTRF2** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/** Definition:* ===========** RECURSIVE SUBROUTINE DPOTRF2( UPLO, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* REAL A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOTRF2 computes the Cholesky factorization of a real symmetric*> positive definite matrix A using the recursive algorithm.*>*> The factorization has the form*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular.*>*> This is the recursive version of the algorithm. It divides*> the matrix into four submatrices:*>*> [ A11 | A12 ] where A11 is n1 by n1 and A22 is n2 by n2*> A = [ -----|----- ] with n1 = n/2*> [ A21 | A22 ] n2 = n-n1*>*> The subroutine calls itself to factor A11. Update and scale A21*> or A12, update A22 then calls itself to factor A22.*>*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================RECURSIVE SUBROUTINE DPOTRF2( UPLO, N, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER N1, N2, IINFO* ..* .. External Functions ..LOGICAL LSAME, DISNANEXTERNAL LSAME, DISNAN* ..* .. External Subroutines ..EXTERNAL DSYRK, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOTRF2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** N=1 case*IF( N.EQ.1 ) THEN** Test for non-positive-definiteness*IF( A( 1, 1 ).LE.ZERO.OR.DISNAN( A( 1, 1 ) ) ) THENINFO = 1RETURNEND IF** Factor*A( 1, 1 ) = SQRT( A( 1, 1 ) )** Use recursive code*ELSEN1 = N/2N2 = N-N1** Factor A11*CALL DPOTRF2( UPLO, N1, A( 1, 1 ), LDA, IINFO )IF ( IINFO.NE.0 ) THENINFO = IINFORETURNEND IF** Compute the Cholesky factorization A = U**T*U*IF( UPPER ) THEN** Update and scale A12*CALL DTRSM( 'L', 'U', 'T', 'N', N1, N2, ONE,$ A( 1, 1 ), LDA, A( 1, N1+1 ), LDA )** Update and factor A22*CALL DSYRK( UPLO, 'T', N2, N1, -ONE, A( 1, N1+1 ), LDA,$ ONE, A( N1+1, N1+1 ), LDA )CALL DPOTRF2( UPLO, N2, A( N1+1, N1+1 ), LDA, IINFO )IF ( IINFO.NE.0 ) THENINFO = IINFO + N1RETURNEND IF** Compute the Cholesky factorization A = L*L**T*ELSE** Update and scale A21*CALL DTRSM( 'R', 'L', 'T', 'N', N2, N1, ONE,$ A( 1, 1 ), LDA, A( N1+1, 1 ), LDA )** Update and factor A22*CALL DSYRK( UPLO, 'N', N2, N1, -ONE, A( N1+1, 1 ), LDA,$ ONE, A( N1+1, N1+1 ), LDA )CALL DPOTRF2( UPLO, N2, A( N1+1, N1+1 ), LDA, IINFO )IF ( IINFO.NE.0 ) THENINFO = IINFO + N1RETURNEND IFEND IFEND IFRETURN** End of DPOTRF2*END*> \brief \b DPOTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpotri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpotri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpotri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOTRI( UPLO, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOTRI computes the inverse of a real symmetric positive definite*> matrix A using the Cholesky factorization A = U**T*U or A = L*L**T*> computed by DPOTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T, as computed by*> DPOTRF.*> On exit, the upper or lower triangle of the (symmetric)*> inverse of A, overwriting the input factor U or L.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the (i,i) element of the factor U or L is*> zero, and the inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOTRI( UPLO, N, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLAUUM, DTRTRI, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Invert the triangular Cholesky factor U or L.*CALL DTRTRI( UPLO, 'Non-unit', N, A, LDA, INFO )IF( INFO.GT.0 )$ RETURN** Form inv(U) * inv(U)**T or inv(L)**T * inv(L).*CALL DLAUUM( UPLO, N, A, LDA, INFO )*RETURN** End of DPOTRI*END*> \brief \b DPOTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPOTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpotrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpotrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpotrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPOTRS solves a system of linear equations A*X = B with a symmetric*> positive definite matrix A using the Cholesky factorization*> A = U**T*U or A = L*L**T computed by DPOTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T, as computed by DPOTRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePOcomputational** =====================================================================SUBROUTINE DPOTRS( UPLO, N, NRHS, A, LDA, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPER* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPOTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( UPPER ) THEN** Solve A*X = B where A = U**T *U.** Solve U**T *X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Upper', 'Transpose', 'Non-unit', N, NRHS,$ ONE, A, LDA, B, LDB )** Solve U*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,$ NRHS, ONE, A, LDA, B, LDB )ELSE** Solve A*X = B where A = L*L**T.** Solve L*X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Lower', 'No transpose', 'Non-unit', N,$ NRHS, ONE, A, LDA, B, LDB )** Solve L**T *X = B, overwriting B with X.*CALL DTRSM( 'Left', 'Lower', 'Transpose', 'Non-unit', N, NRHS,$ ONE, A, LDA, B, LDB )END IF*RETURN** End of DPOTRS*END*> \brief \b DPPCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dppcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dppcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dppcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPCON( UPLO, N, AP, ANORM, RCOND, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPCON estimates the reciprocal of the condition number (in the*> 1-norm) of a real symmetric positive definite packed matrix using*> the Cholesky factorization A = U**T*U or A = L*L**T computed by*> DPPTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T, packed columnwise in a linear*> array. The j-th column of U or L is stored in the array AP*> as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> The 1-norm (or infinity-norm) of the symmetric matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an*> estimate of the 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPPCON( UPLO, N, AP, ANORM, RCOND, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERCHARACTER NORMININTEGER IX, KASEDOUBLE PRECISION AINVNM, SCALE, SCALEL, SCALEU, SMLNUM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL LSAME, IDAMAX, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATPS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ANORM.LT.ZERO ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF*SMLNUM = DLAMCH( 'Safe minimum' )** Estimate the 1-norm of the inverse.*KASE = 0NORMIN = 'N'10 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( UPPER ) THEN** Multiply by inv(U**T).*CALL DLATPS( 'Upper', 'Transpose', 'Non-unit', NORMIN, N,$ AP, WORK, SCALEL, WORK( 2*N+1 ), INFO )NORMIN = 'Y'** Multiply by inv(U).*CALL DLATPS( 'Upper', 'No transpose', 'Non-unit', NORMIN, N,$ AP, WORK, SCALEU, WORK( 2*N+1 ), INFO )ELSE** Multiply by inv(L).*CALL DLATPS( 'Lower', 'No transpose', 'Non-unit', NORMIN, N,$ AP, WORK, SCALEL, WORK( 2*N+1 ), INFO )NORMIN = 'Y'** Multiply by inv(L**T).*CALL DLATPS( 'Lower', 'Transpose', 'Non-unit', NORMIN, N,$ AP, WORK, SCALEU, WORK( 2*N+1 ), INFO )END IF** Multiply by 1/SCALE if doing so will not cause overflow.*SCALE = SCALEL*SCALEUIF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )IF( SCALE.LT.ABS( WORK( IX ) )*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*20 CONTINUERETURN** End of DPPCON*END*> \brief \b DPPEQU** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPEQU + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dppequ.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dppequ.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dppequ.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPEQU( UPLO, N, AP, S, SCOND, AMAX, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* DOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), S( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPEQU computes row and column scalings intended to equilibrate a*> symmetric positive definite matrix A in packed storage and reduce*> its condition number (with respect to the two-norm). S contains the*> scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix*> B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.*> This choice of S puts the condition number of B within a factor N of*> the smallest possible condition number over all possible diagonal*> scalings.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangle of the symmetric matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, S contains the scale factors for A.*> \endverbatim*>*> \param[out] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> If INFO = 0, S contains the ratio of the smallest S(i) to*> the largest S(i). If SCOND >= 0.1 and AMAX is neither too*> large nor too small, it is not worth scaling by S.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Absolute value of largest matrix element. If AMAX is very*> close to overflow or very close to underflow, the matrix*> should be scaled.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element is nonpositive.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPPEQU( UPLO, N, AP, S, SCOND, AMAX, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, NDOUBLE PRECISION AMAX, SCOND* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), S( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, JJDOUBLE PRECISION SMIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPEQU', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENSCOND = ONEAMAX = ZERORETURNEND IF** Initialize SMIN and AMAX.*S( 1 ) = AP( 1 )SMIN = S( 1 )AMAX = S( 1 )*IF( UPPER ) THEN** UPLO = 'U': Upper triangle of A is stored.* Find the minimum and maximum diagonal elements.*JJ = 1DO 10 I = 2, NJJ = JJ + IS( I ) = AP( JJ )SMIN = MIN( SMIN, S( I ) )AMAX = MAX( AMAX, S( I ) )10 CONTINUE*ELSE** UPLO = 'L': Lower triangle of A is stored.* Find the minimum and maximum diagonal elements.*JJ = 1DO 20 I = 2, NJJ = JJ + N - I + 2S( I ) = AP( JJ )SMIN = MIN( SMIN, S( I ) )AMAX = MAX( AMAX, S( I ) )20 CONTINUEEND IF*IF( SMIN.LE.ZERO ) THEN** Find the first non-positive diagonal element and return.*DO 30 I = 1, NIF( S( I ).LE.ZERO ) THENINFO = IRETURNEND IF30 CONTINUEELSE** Set the scale factors to the reciprocals* of the diagonal elements.*DO 40 I = 1, NS( I ) = ONE / SQRT( S( I ) )40 CONTINUE** Compute SCOND = min(S(I)) / max(S(I))*SCOND = SQRT( SMIN ) / SQRT( AMAX )END IFRETURN** End of DPPEQU*END*> \brief \b DPPRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpprfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpprfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpprfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPRFS( UPLO, N, NRHS, AP, AFP, B, LDB, X, LDX, FERR,* BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),* $ FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is symmetric positive definite*> and packed, and provides error bounds and backward error estimates*> for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangle of the symmetric matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in] AFP*> \verbatim*> AFP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T, as computed by DPPTRF/ZPPTRF,*> packed columnwise in a linear array in the same format as A*> (see AP).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DPPTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPPRFS( UPLO, N, NRHS, AP, AFP, B, LDB, X, LDX, FERR,$ BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER COUNT, I, IK, J, K, KASE, KK, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DPPTRS, DSPMV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - A * X*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DSPMV( UPLO, N, -ONE, AP, X( 1, J ), 1, ONE, WORK( N+1 ),$ 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(A)*abs(X) + abs(B).*KK = 1IF( UPPER ) THENDO 50 K = 1, NS = ZEROXK = ABS( X( K, J ) )IK = KKDO 40 I = 1, K - 1WORK( I ) = WORK( I ) + ABS( AP( IK ) )*XKS = S + ABS( AP( IK ) )*ABS( X( I, J ) )IK = IK + 140 CONTINUEWORK( K ) = WORK( K ) + ABS( AP( KK+K-1 ) )*XK + SKK = KK + K50 CONTINUEELSEDO 70 K = 1, NS = ZEROXK = ABS( X( K, J ) )WORK( K ) = WORK( K ) + ABS( AP( KK ) )*XKIK = KK + 1DO 60 I = K + 1, NWORK( I ) = WORK( I ) + ABS( AP( IK ) )*XKS = S + ABS( AP( IK ) )*ABS( X( I, J ) )IK = IK + 160 CONTINUEWORK( K ) = WORK( K ) + SKK = KK + ( N-K+1 )70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DPPTRS( UPLO, N, 1, AFP, WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(A))** ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(A) is the inverse of A* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(A)*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(A) * diag(W),* where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(A**T).*CALL DPPTRS( UPLO, N, 1, AFP, WORK( N+1 ), N, INFO )DO 110 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )110 CONTINUEELSE IF( KASE.EQ.2 ) THEN** Multiply by inv(A)*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )120 CONTINUECALL DPPTRS( UPLO, N, 1, AFP, WORK( N+1 ), N, INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DPPRFS*END*> \brief <b> DPPSV computes the solution to system of linear equations A * X = B for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dppsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dppsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dppsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPSV( UPLO, N, NRHS, AP, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPSV computes the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric positive definite matrix stored in*> packed format and X and B are N-by-NRHS matrices.*>*> The Cholesky decomposition is used to factor A as*> A = U**T* U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is a lower triangular*> matrix. The factored form of A is then used to solve the system of*> equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> See below for further details.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T, in the same storage*> format as A.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i of A is not*> positive definite, so the factorization could not be*> completed, and the solution has not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The packed storage scheme is illustrated by the following example*> when N = 4, UPLO = 'U':*>*> Two-dimensional storage of the symmetric matrix A:*>*> a11 a12 a13 a14*> a22 a23 a24*> a33 a34 (aij = conjg(aji))*> a44*>*> Packed storage of the upper triangle of A:*>*> AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]*> \endverbatim*>* =====================================================================SUBROUTINE DPPSV( UPLO, N, NRHS, AP, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), B( LDB, * )* ..** =====================================================================** .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPPTRF, DPPTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPSV ', -INFO )RETURNEND IF** Compute the Cholesky factorization A = U**T*U or A = L*L**T.*CALL DPPTRF( UPLO, N, AP, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DPPTRS( UPLO, N, NRHS, AP, B, LDB, INFO )*END IFRETURN** End of DPPSV*END*> \brief <b> DPPSVX computes the solution to system of linear equations A * X = B for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dppsvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dppsvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dppsvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPSVX( FACT, UPLO, N, NRHS, AP, AFP, EQUED, S, B, LDB,* X, LDX, RCOND, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER EQUED, FACT, UPLO* INTEGER INFO, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),* $ FERR( * ), S( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPSVX uses the Cholesky factorization A = U**T*U or A = L*L**T to*> compute the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric positive definite matrix stored in*> packed format and X and B are N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'E', real scaling factors are computed to equilibrate*> the system:*> diag(S) * A * diag(S) * inv(diag(S)) * X = diag(S) * B*> Whether or not the system will be equilibrated depends on the*> scaling of the matrix A, but if equilibration is used, A is*> overwritten by diag(S)*A*diag(S) and B by diag(S)*B.*>*> 2. If FACT = 'N' or 'E', the Cholesky decomposition is used to*> factor the matrix A (after equilibration if FACT = 'E') as*> A = U**T* U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is a lower triangular*> matrix.*>*> 3. If the leading i-by-i principal minor is not positive definite,*> then the routine returns with INFO = i. Otherwise, the factored*> form of A is used to estimate the condition number of the matrix*> A. If the reciprocal of the condition number is less than machine*> precision, INFO = N+1 is returned as a warning, but the routine*> still goes on to solve for X and compute error bounds as*> described below.*>*> 4. The system of equations is solved for X using the factored form*> of A.*>*> 5. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*>*> 6. If equilibration was used, the matrix X is premultiplied by*> diag(S) so that it solves the original system before*> equilibration.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of the matrix A is*> supplied on entry, and if not, whether the matrix A should be*> equilibrated before it is factored.*> = 'F': On entry, AFP contains the factored form of A.*> If EQUED = 'Y', the matrix A has been equilibrated*> with scaling factors given by S. AP and AFP will not*> be modified.*> = 'N': The matrix A will be copied to AFP and factored.*> = 'E': The matrix A will be equilibrated if necessary, then*> copied to AFP and factored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array, except if FACT = 'F'*> and EQUED = 'Y', then A must contain the equilibrated matrix*> diag(S)*A*diag(S). The j-th column of A is stored in the*> array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> See below for further details. A is not modified if*> FACT = 'F' or 'N', or if FACT = 'E' and EQUED = 'N' on exit.*>*> On exit, if FACT = 'E' and EQUED = 'Y', A is overwritten by*> diag(S)*A*diag(S).*> \endverbatim*>*> \param[in,out] AFP*> \verbatim*> AFP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> If FACT = 'F', then AFP is an input argument and on entry*> contains the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T, in the same storage*> format as A. If EQUED .ne. 'N', then AFP is the factored*> form of the equilibrated matrix A.*>*> If FACT = 'N', then AFP is an output argument and on exit*> returns the triangular factor U or L from the Cholesky*> factorization A = U**T * U or A = L * L**T of the original*> matrix A.*>*> If FACT = 'E', then AFP is an output argument and on exit*> returns the triangular factor U or L from the Cholesky*> factorization A = U**T * U or A = L * L**T of the equilibrated*> matrix A (see the description of AP for the form of the*> equilibrated matrix).*> \endverbatim*>*> \param[in,out] EQUED*> \verbatim*> EQUED is CHARACTER*1*> Specifies the form of equilibration that was done.*> = 'N': No equilibration (always true if FACT = 'N').*> = 'Y': Equilibration was done, i.e., A has been replaced by*> diag(S) * A * diag(S).*> EQUED is an input argument if FACT = 'F'; otherwise, it is an*> output argument.*> \endverbatim*>*> \param[in,out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> The scale factors for A; not accessed if EQUED = 'N'. S is*> an input argument if FACT = 'F'; otherwise, S is an output*> argument. If FACT = 'F' and EQUED = 'Y', each element of S*> must be positive.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if EQUED = 'N', B is not modified; if EQUED = 'Y',*> B is overwritten by diag(S) * B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X to*> the original system of equations. Note that if EQUED = 'Y',*> A and B are modified on exit, and the solution to the*> equilibrated system is inv(diag(S))*X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A after equilibration (if done). If RCOND is less than the*> machine precision (in particular, if RCOND = 0), the matrix*> is singular to working precision. This condition is*> indicated by a return code of INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: the leading minor of order i of A is*> not positive definite, so the factorization*> could not be completed, and the solution has not*> been computed. RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleOTHERsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The packed storage scheme is illustrated by the following example*> when N = 4, UPLO = 'U':*>*> Two-dimensional storage of the symmetric matrix A:*>*> a11 a12 a13 a14*> a22 a23 a24*> a33 a34 (aij = conjg(aji))*> a44*>*> Packed storage of the upper triangle of A:*>*> AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]*> \endverbatim*>* =====================================================================SUBROUTINE DPPSVX( FACT, UPLO, N, NRHS, AP, AFP, EQUED, S, B, LDB,$ X, LDX, RCOND, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER EQUED, FACT, UPLOINTEGER INFO, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),$ FERR( * ), S( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL EQUIL, NOFACT, RCEQUINTEGER I, INFEQU, JDOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSPEXTERNAL LSAME, DLAMCH, DLANSP* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DLAQSP, DPPCON, DPPEQU, DPPRFS,$ DPPTRF, DPPTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..*INFO = 0NOFACT = LSAME( FACT, 'N' )EQUIL = LSAME( FACT, 'E' )IF( NOFACT .OR. EQUIL ) THENEQUED = 'N'RCEQU = .FALSE.ELSERCEQU = LSAME( EQUED, 'Y' )SMLNUM = DLAMCH( 'Safe minimum' )BIGNUM = ONE / SMLNUMEND IF** Test the input parameters.*IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )$ THENINFO = -1ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )$ THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.$ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THENINFO = -7ELSEIF( RCEQU ) THENSMIN = BIGNUMSMAX = ZERODO 10 J = 1, NSMIN = MIN( SMIN, S( J ) )SMAX = MAX( SMAX, S( J ) )10 CONTINUEIF( SMIN.LE.ZERO ) THENINFO = -8ELSE IF( N.GT.0 ) THENSCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )ELSESCOND = ONEEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -12END IFEND IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DPPSVX', -INFO )RETURNEND IF*IF( EQUIL ) THEN** Compute row and column scalings to equilibrate the matrix A.*CALL DPPEQU( UPLO, N, AP, S, SCOND, AMAX, INFEQU )IF( INFEQU.EQ.0 ) THEN** Equilibrate the matrix.*CALL DLAQSP( UPLO, N, AP, S, SCOND, AMAX, EQUED )RCEQU = LSAME( EQUED, 'Y' )END IFEND IF** Scale the right-hand side.*IF( RCEQU ) THENDO 30 J = 1, NRHSDO 20 I = 1, NB( I, J ) = S( I )*B( I, J )20 CONTINUE30 CONTINUEEND IF*IF( NOFACT .OR. EQUIL ) THEN** Compute the Cholesky factorization A = U**T * U or A = L * L**T.*CALL DCOPY( N*( N+1 ) / 2, AP, 1, AFP, 1 )CALL DPPTRF( UPLO, N, AFP, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*ANORM = DLANSP( 'I', UPLO, N, AP, WORK )** Compute the reciprocal of the condition number of A.*CALL DPPCON( UPLO, N, AFP, ANORM, RCOND, WORK, IWORK, INFO )** Compute the solution matrix X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DPPTRS( UPLO, N, NRHS, AFP, X, LDX, INFO )** Use iterative refinement to improve the computed solution and* compute error bounds and backward error estimates for it.*CALL DPPRFS( UPLO, N, NRHS, AP, AFP, B, LDB, X, LDX, FERR, BERR,$ WORK, IWORK, INFO )** Transform the solution matrix X to a solution of the original* system.*IF( RCEQU ) THENDO 50 J = 1, NRHSDO 40 I = 1, NX( I, J ) = S( I )*X( I, J )40 CONTINUE50 CONTINUEDO 60 J = 1, NRHSFERR( J ) = FERR( J ) / SCOND60 CONTINUEEND IF** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*RETURN** End of DPPSVX*END*> \brief \b DPPTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpptrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpptrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpptrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPTRF( UPLO, N, AP, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPTRF computes the Cholesky factorization of a real symmetric*> positive definite matrix A stored in packed format.*>*> The factorization has the form*> A = U**T * U, if UPLO = 'U', or*> A = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> See below for further details.*>*> On exit, if INFO = 0, the triangular factor U or L from the*> Cholesky factorization A = U**T*U or A = L*L**T, in the same*> storage format as A.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i is not*> positive definite, and the factorization could not be*> completed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The packed storage scheme is illustrated by the following example*> when N = 4, UPLO = 'U':*>*> Two-dimensional storage of the symmetric matrix A:*>*> a11 a12 a13 a14*> a22 a23 a24*> a33 a34 (aij = aji)*> a44*>*> Packed storage of the upper triangle of A:*>*> AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]*> \endverbatim*>* =====================================================================SUBROUTINE DPPTRF( UPLO, N, AP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, JC, JJDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. External Subroutines ..EXTERNAL DSCAL, DSPR, DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( UPPER ) THEN** Compute the Cholesky factorization A = U**T*U.*JJ = 0DO 10 J = 1, NJC = JJ + 1JJ = JJ + J** Compute elements 1:J-1 of column J.*IF( J.GT.1 )$ CALL DTPSV( 'Upper', 'Transpose', 'Non-unit', J-1, AP,$ AP( JC ), 1 )** Compute U(J,J) and test for non-positive-definiteness.*AJJ = AP( JJ ) - DDOT( J-1, AP( JC ), 1, AP( JC ), 1 )IF( AJJ.LE.ZERO ) THENAP( JJ ) = AJJGO TO 30END IFAP( JJ ) = SQRT( AJJ )10 CONTINUEELSE** Compute the Cholesky factorization A = L*L**T.*JJ = 1DO 20 J = 1, N** Compute L(J,J) and test for non-positive-definiteness.*AJJ = AP( JJ )IF( AJJ.LE.ZERO ) THENAP( JJ ) = AJJGO TO 30END IFAJJ = SQRT( AJJ )AP( JJ ) = AJJ** Compute elements J+1:N of column J and update the trailing* submatrix.*IF( J.LT.N ) THENCALL DSCAL( N-J, ONE / AJJ, AP( JJ+1 ), 1 )CALL DSPR( 'Lower', N-J, -ONE, AP( JJ+1 ), 1,$ AP( JJ+N-J+1 ) )JJ = JJ + N - J + 1END IF20 CONTINUEEND IFGO TO 40*30 CONTINUEINFO = J*40 CONTINUERETURN** End of DPPTRF*END*> \brief \b DPPTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpptri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpptri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpptri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPTRI( UPLO, N, AP, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPTRI computes the inverse of a real symmetric positive definite*> matrix A using the Cholesky factorization A = U**T*U or A = L*L**T*> computed by DPPTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangular factor is stored in AP;*> = 'L': Lower triangular factor is stored in AP.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the triangular factor U or L from the Cholesky*> factorization A = U**T*U or A = L*L**T, packed columnwise as*> a linear array. The j-th column of U or L is stored in the*> array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n.*>*> On exit, the upper or lower triangle of the (symmetric)*> inverse of A, overwriting the input factor U or L.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the (i,i) element of the factor U or L is*> zero, and the inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPPTRI( UPLO, N, AP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, JC, JJ, JJNDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. External Subroutines ..EXTERNAL DSCAL, DSPR, DTPMV, DTPTRI, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Invert the triangular Cholesky factor U or L.*CALL DTPTRI( UPLO, 'Non-unit', N, AP, INFO )IF( INFO.GT.0 )$ RETURN*IF( UPPER ) THEN** Compute the product inv(U) * inv(U)**T.*JJ = 0DO 10 J = 1, NJC = JJ + 1JJ = JJ + JIF( J.GT.1 )$ CALL DSPR( 'Upper', J-1, ONE, AP( JC ), 1, AP )AJJ = AP( JJ )CALL DSCAL( J, AJJ, AP( JC ), 1 )10 CONTINUE*ELSE** Compute the product inv(L)**T * inv(L).*JJ = 1DO 20 J = 1, NJJN = JJ + N - J + 1AP( JJ ) = DDOT( N-J+1, AP( JJ ), 1, AP( JJ ), 1 )IF( J.LT.N )$ CALL DTPMV( 'Lower', 'Transpose', 'Non-unit', N-J,$ AP( JJN ), AP( JJ+1 ), 1 )JJ = JJN20 CONTINUEEND IF*RETURN** End of DPPTRI*END*> \brief \b DPPTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPPTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpptrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpptrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpptrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPPTRS( UPLO, N, NRHS, AP, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPPTRS solves a system of linear equations A*X = B with a symmetric*> positive definite matrix A in packed storage using the Cholesky*> factorization A = U**T*U or A = L*L**T computed by DPPTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The triangular factor U or L from the Cholesky factorization*> A = U**T*U or A = L*L**T, packed columnwise in a linear*> array. The j-th column of U or L is stored in the array AP*> as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPPTRS( UPLO, N, NRHS, AP, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), B( LDB, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL UPPERINTEGER I* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPPTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( UPPER ) THEN** Solve A*X = B where A = U**T * U.*DO 10 I = 1, NRHS** Solve U**T *X = B, overwriting B with X.*CALL DTPSV( 'Upper', 'Transpose', 'Non-unit', N, AP,$ B( 1, I ), 1 )** Solve U*X = B, overwriting B with X.*CALL DTPSV( 'Upper', 'No transpose', 'Non-unit', N, AP,$ B( 1, I ), 1 )10 CONTINUEELSE** Solve A*X = B where A = L * L**T.*DO 20 I = 1, NRHS** Solve L*Y = B, overwriting B with X.*CALL DTPSV( 'Lower', 'No transpose', 'Non-unit', N, AP,$ B( 1, I ), 1 )** Solve L**T *X = Y, overwriting B with X.*CALL DTPSV( 'Lower', 'Transpose', 'Non-unit', N, AP,$ B( 1, I ), 1 )20 CONTINUEEND IF*RETURN** End of DPPTRS*END*> \brief \b DPSTF2 computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPSTF2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpstf2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpstf2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpstf2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPSTF2( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )** .. Scalar Arguments ..* DOUBLE PRECISION TOL* INTEGER INFO, LDA, N, RANK* CHARACTER UPLO* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), WORK( 2*N )* INTEGER PIV( N )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPSTF2 computes the Cholesky factorization with complete*> pivoting of a real symmetric positive semidefinite matrix A.*>*> The factorization has the form*> P**T * A * P = U**T * U , if UPLO = 'U',*> P**T * A * P = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular, and*> P is stored as vector PIV.*>*> This algorithm does not attempt to check that A is positive*> semidefinite. This version of the algorithm calls level 2 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n by n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n by n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization as above.*> \endverbatim*>*> \param[out] PIV*> \verbatim*> PIV is INTEGER array, dimension (N)*> PIV is such that the nonzero entries are P( PIV(K), K ) = 1.*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The rank of A given by the number of steps the algorithm*> completed.*> \endverbatim*>*> \param[in] TOL*> \verbatim*> TOL is DOUBLE PRECISION*> User defined tolerance. If TOL < 0, then N*U*MAX( A( K,K ) )*> will be used. The algorithm terminates at the (K-1)st step*> if the pivot <= TOL.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> Work space.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> < 0: If INFO = -K, the K-th argument had an illegal value,*> = 0: algorithm completed successfully, and*> > 0: the matrix A is either rank deficient with computed rank*> as returned in RANK, or is not positive semidefinite. See*> Section 7 of LAPACK Working Note #161 for further*> information.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPSTF2( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION TOLINTEGER INFO, LDA, N, RANKCHARACTER UPLO* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( 2*N )INTEGER PIV( N )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION AJJ, DSTOP, DTEMPINTEGER I, ITEMP, J, PVTLOGICAL UPPER* ..* .. External Functions ..DOUBLE PRECISION DLAMCHLOGICAL LSAME, DISNANEXTERNAL DLAMCH, LSAME, DISNAN* ..* .. External Subroutines ..EXTERNAL DGEMV, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT, MAXLOC* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPSTF2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Initialize PIV*DO 100 I = 1, NPIV( I ) = I100 CONTINUE** Compute stopping value*PVT = 1AJJ = A( PVT, PVT )DO I = 2, NIF( A( I, I ).GT.AJJ ) THENPVT = IAJJ = A( PVT, PVT )END IFEND DOIF( AJJ.LE.ZERO.OR.DISNAN( AJJ ) ) THENRANK = 0INFO = 1GO TO 170END IF** Compute stopping value if not supplied*IF( TOL.LT.ZERO ) THENDSTOP = N * DLAMCH( 'Epsilon' ) * AJJELSEDSTOP = TOLEND IF** Set first half of WORK to zero, holds dot products*DO 110 I = 1, NWORK( I ) = 0110 CONTINUE*IF( UPPER ) THEN** Compute the Cholesky factorization P**T * A * P = U**T * U*DO 130 J = 1, N** Find pivot, test for exit, else swap rows and columns* Update dot products, compute possible pivots which are* stored in the second half of WORK*DO 120 I = J, N*IF( J.GT.1 ) THENWORK( I ) = WORK( I ) + A( J-1, I )**2END IFWORK( N+I ) = A( I, I ) - WORK( I )*120 CONTINUE*IF( J.GT.1 ) THENITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )PVT = ITEMP + J - 1AJJ = WORK( N+PVT )IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THENA( J, J ) = AJJGO TO 160END IFEND IF*IF( J.NE.PVT ) THEN** Pivot OK, so can now swap pivot rows and columns*A( PVT, PVT ) = A( J, J )CALL DSWAP( J-1, A( 1, J ), 1, A( 1, PVT ), 1 )IF( PVT.LT.N )$ CALL DSWAP( N-PVT, A( J, PVT+1 ), LDA,$ A( PVT, PVT+1 ), LDA )CALL DSWAP( PVT-J-1, A( J, J+1 ), LDA, A( J+1, PVT ), 1 )** Swap dot products and PIV*DTEMP = WORK( J )WORK( J ) = WORK( PVT )WORK( PVT ) = DTEMPITEMP = PIV( PVT )PIV( PVT ) = PIV( J )PIV( J ) = ITEMPEND IF*AJJ = SQRT( AJJ )A( J, J ) = AJJ** Compute elements J+1:N of row J*IF( J.LT.N ) THENCALL DGEMV( 'Trans', J-1, N-J, -ONE, A( 1, J+1 ), LDA,$ A( 1, J ), 1, ONE, A( J, J+1 ), LDA )CALL DSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )END IF*130 CONTINUE*ELSE** Compute the Cholesky factorization P**T * A * P = L * L**T*DO 150 J = 1, N** Find pivot, test for exit, else swap rows and columns* Update dot products, compute possible pivots which are* stored in the second half of WORK*DO 140 I = J, N*IF( J.GT.1 ) THENWORK( I ) = WORK( I ) + A( I, J-1 )**2END IFWORK( N+I ) = A( I, I ) - WORK( I )*140 CONTINUE*IF( J.GT.1 ) THENITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )PVT = ITEMP + J - 1AJJ = WORK( N+PVT )IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THENA( J, J ) = AJJGO TO 160END IFEND IF*IF( J.NE.PVT ) THEN** Pivot OK, so can now swap pivot rows and columns*A( PVT, PVT ) = A( J, J )CALL DSWAP( J-1, A( J, 1 ), LDA, A( PVT, 1 ), LDA )IF( PVT.LT.N )$ CALL DSWAP( N-PVT, A( PVT+1, J ), 1, A( PVT+1, PVT ),$ 1 )CALL DSWAP( PVT-J-1, A( J+1, J ), 1, A( PVT, J+1 ), LDA )** Swap dot products and PIV*DTEMP = WORK( J )WORK( J ) = WORK( PVT )WORK( PVT ) = DTEMPITEMP = PIV( PVT )PIV( PVT ) = PIV( J )PIV( J ) = ITEMPEND IF*AJJ = SQRT( AJJ )A( J, J ) = AJJ** Compute elements J+1:N of column J*IF( J.LT.N ) THENCALL DGEMV( 'No Trans', N-J, J-1, -ONE, A( J+1, 1 ), LDA,$ A( J, 1 ), LDA, ONE, A( J+1, J ), 1 )CALL DSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )END IF*150 CONTINUE*END IF** Ran to completion, A has full rank*RANK = N*GO TO 170160 CONTINUE** Rank is number of steps completed. Set INFO = 1 to signal* that the factorization cannot be used to solve a system.*RANK = J - 1INFO = 1*170 CONTINUERETURN** End of DPSTF2*END*> \brief \b DPSTRF computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix.*** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPSTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpstrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpstrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpstrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPSTRF( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )** .. Scalar Arguments ..* DOUBLE PRECISION TOL* INTEGER INFO, LDA, N, RANK* CHARACTER UPLO* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), WORK( 2*N )* INTEGER PIV( N )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPSTRF computes the Cholesky factorization with complete*> pivoting of a real symmetric positive semidefinite matrix A.*>*> The factorization has the form*> P**T * A * P = U**T * U , if UPLO = 'U',*> P**T * A * P = L * L**T, if UPLO = 'L',*> where U is an upper triangular matrix and L is lower triangular, and*> P is stored as vector PIV.*>*> This algorithm does not attempt to check that A is positive*> semidefinite. This version of the algorithm calls level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n by n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n by n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the factor U or L from the Cholesky*> factorization as above.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] PIV*> \verbatim*> PIV is INTEGER array, dimension (N)*> PIV is such that the nonzero entries are P( PIV(K), K ) = 1.*> \endverbatim*>*> \param[out] RANK*> \verbatim*> RANK is INTEGER*> The rank of A given by the number of steps the algorithm*> completed.*> \endverbatim*>*> \param[in] TOL*> \verbatim*> TOL is DOUBLE PRECISION*> User defined tolerance. If TOL < 0, then N*U*MAX( A(K,K) )*> will be used. The algorithm terminates at the (K-1)st step*> if the pivot <= TOL.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> Work space.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> < 0: If INFO = -K, the K-th argument had an illegal value,*> = 0: algorithm completed successfully, and*> > 0: the matrix A is either rank deficient with computed rank*> as returned in RANK, or is not positive semidefinite. See*> Section 7 of LAPACK Working Note #161 for further*> information.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DPSTRF( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION TOLINTEGER INFO, LDA, N, RANKCHARACTER UPLO* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), WORK( 2*N )INTEGER PIV( N )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..DOUBLE PRECISION AJJ, DSTOP, DTEMPINTEGER I, ITEMP, J, JB, K, NB, PVTLOGICAL UPPER* ..* .. External Functions ..DOUBLE PRECISION DLAMCHINTEGER ILAENVLOGICAL LSAME, DISNANEXTERNAL DLAMCH, ILAENV, LSAME, DISNAN* ..* .. External Subroutines ..EXTERNAL DGEMV, DPSTF2, DSCAL, DSWAP, DSYRK, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT, MAXLOC* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPSTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get block size*NB = ILAENV( 1, 'DPOTRF', UPLO, N, -1, -1, -1 )IF( NB.LE.1 .OR. NB.GE.N ) THEN** Use unblocked code*CALL DPSTF2( UPLO, N, A( 1, 1 ), LDA, PIV, RANK, TOL, WORK,$ INFO )GO TO 200*ELSE** Initialize PIV*DO 100 I = 1, NPIV( I ) = I100 CONTINUE** Compute stopping value*PVT = 1AJJ = A( PVT, PVT )DO I = 2, NIF( A( I, I ).GT.AJJ ) THENPVT = IAJJ = A( PVT, PVT )END IFEND DOIF( AJJ.LE.ZERO.OR.DISNAN( AJJ ) ) THENRANK = 0INFO = 1GO TO 200END IF** Compute stopping value if not supplied*IF( TOL.LT.ZERO ) THENDSTOP = N * DLAMCH( 'Epsilon' ) * AJJELSEDSTOP = TOLEND IF**IF( UPPER ) THEN** Compute the Cholesky factorization P**T * A * P = U**T * U*DO 140 K = 1, N, NB** Account for last block not being NB wide*JB = MIN( NB, N-K+1 )** Set relevant part of first half of WORK to zero,* holds dot products*DO 110 I = K, NWORK( I ) = 0110 CONTINUE*DO 130 J = K, K + JB - 1** Find pivot, test for exit, else swap rows and columns* Update dot products, compute possible pivots which are* stored in the second half of WORK*DO 120 I = J, N*IF( J.GT.K ) THENWORK( I ) = WORK( I ) + A( J-1, I )**2END IFWORK( N+I ) = A( I, I ) - WORK( I )*120 CONTINUE*IF( J.GT.1 ) THENITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )PVT = ITEMP + J - 1AJJ = WORK( N+PVT )IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THENA( J, J ) = AJJGO TO 190END IFEND IF*IF( J.NE.PVT ) THEN** Pivot OK, so can now swap pivot rows and columns*A( PVT, PVT ) = A( J, J )CALL DSWAP( J-1, A( 1, J ), 1, A( 1, PVT ), 1 )IF( PVT.LT.N )$ CALL DSWAP( N-PVT, A( J, PVT+1 ), LDA,$ A( PVT, PVT+1 ), LDA )CALL DSWAP( PVT-J-1, A( J, J+1 ), LDA,$ A( J+1, PVT ), 1 )** Swap dot products and PIV*DTEMP = WORK( J )WORK( J ) = WORK( PVT )WORK( PVT ) = DTEMPITEMP = PIV( PVT )PIV( PVT ) = PIV( J )PIV( J ) = ITEMPEND IF*AJJ = SQRT( AJJ )A( J, J ) = AJJ** Compute elements J+1:N of row J.*IF( J.LT.N ) THENCALL DGEMV( 'Trans', J-K, N-J, -ONE, A( K, J+1 ),$ LDA, A( K, J ), 1, ONE, A( J, J+1 ),$ LDA )CALL DSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )END IF*130 CONTINUE** Update trailing matrix, J already incremented*IF( K+JB.LE.N ) THENCALL DSYRK( 'Upper', 'Trans', N-J+1, JB, -ONE,$ A( K, J ), LDA, ONE, A( J, J ), LDA )END IF*140 CONTINUE*ELSE** Compute the Cholesky factorization P**T * A * P = L * L**T*DO 180 K = 1, N, NB** Account for last block not being NB wide*JB = MIN( NB, N-K+1 )** Set relevant part of first half of WORK to zero,* holds dot products*DO 150 I = K, NWORK( I ) = 0150 CONTINUE*DO 170 J = K, K + JB - 1** Find pivot, test for exit, else swap rows and columns* Update dot products, compute possible pivots which are* stored in the second half of WORK*DO 160 I = J, N*IF( J.GT.K ) THENWORK( I ) = WORK( I ) + A( I, J-1 )**2END IFWORK( N+I ) = A( I, I ) - WORK( I )*160 CONTINUE*IF( J.GT.1 ) THENITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )PVT = ITEMP + J - 1AJJ = WORK( N+PVT )IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THENA( J, J ) = AJJGO TO 190END IFEND IF*IF( J.NE.PVT ) THEN** Pivot OK, so can now swap pivot rows and columns*A( PVT, PVT ) = A( J, J )CALL DSWAP( J-1, A( J, 1 ), LDA, A( PVT, 1 ), LDA )IF( PVT.LT.N )$ CALL DSWAP( N-PVT, A( PVT+1, J ), 1,$ A( PVT+1, PVT ), 1 )CALL DSWAP( PVT-J-1, A( J+1, J ), 1, A( PVT, J+1 ),$ LDA )** Swap dot products and PIV*DTEMP = WORK( J )WORK( J ) = WORK( PVT )WORK( PVT ) = DTEMPITEMP = PIV( PVT )PIV( PVT ) = PIV( J )PIV( J ) = ITEMPEND IF*AJJ = SQRT( AJJ )A( J, J ) = AJJ** Compute elements J+1:N of column J.*IF( J.LT.N ) THENCALL DGEMV( 'No Trans', N-J, J-K, -ONE,$ A( J+1, K ), LDA, A( J, K ), LDA, ONE,$ A( J+1, J ), 1 )CALL DSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )END IF*170 CONTINUE** Update trailing matrix, J already incremented*IF( K+JB.LE.N ) THENCALL DSYRK( 'Lower', 'No Trans', N-J+1, JB, -ONE,$ A( J, K ), LDA, ONE, A( J, J ), LDA )END IF*180 CONTINUE*END IFEND IF** Ran to completion, A has full rank*RANK = N*GO TO 200190 CONTINUE** Rank is the number of steps completed. Set INFO = 1 to signal* that the factorization cannot be used to solve a system.*RANK = J - 1INFO = 1*200 CONTINUERETURN** End of DPSTRF*END*> \brief \b DPTCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dptcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dptcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dptcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTCON( N, D, E, ANORM, RCOND, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTCON computes the reciprocal of the condition number (in the*> 1-norm) of a real symmetric positive definite tridiagonal matrix*> using the factorization A = L*D*L**T or A = U**T*D*U computed by*> DPTTRF.*>*> Norm(inv(A)) is computed by a direct method, and the reciprocal of*> the condition number is computed as*> RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the diagonal matrix D from the*> factorization of A, as computed by DPTTRF.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) off-diagonal elements of the unit bidiagonal factor*> U or L from the factorization of A, as computed by DPTTRF.*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> The 1-norm of the original matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is the*> 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The method used is described in Nicholas J. Higham, "Efficient*> Algorithms for Computing the Condition Number of a Tridiagonal*> Matrix", SIAM J. Sci. Stat. Comput., Vol. 7, No. 1, January 1986.*> \endverbatim*>* =====================================================================SUBROUTINE DPTCON( N, D, E, ANORM, RCOND, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, IXDOUBLE PRECISION AINVNM* ..* .. External Functions ..INTEGER IDAMAXEXTERNAL IDAMAX* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Test the input arguments.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( ANORM.LT.ZERO ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPTCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.EQ.ZERO ) THENRETURNEND IF** Check that D(1:N) is positive.*DO 10 I = 1, NIF( D( I ).LE.ZERO )$ RETURN10 CONTINUE** Solve M(A) * x = e, where M(A) = (m(i,j)) is given by** m(i,j) = abs(A(i,j)), i = j,* m(i,j) = -abs(A(i,j)), i .ne. j,** and e = [ 1, 1, ..., 1 ]**T. Note M(A) = M(L)*D*M(L)**T.** Solve M(L) * x = e.*WORK( 1 ) = ONEDO 20 I = 2, NWORK( I ) = ONE + WORK( I-1 )*ABS( E( I-1 ) )20 CONTINUE** Solve D * M(L)**T * x = b.*WORK( N ) = WORK( N ) / D( N )DO 30 I = N - 1, 1, -1WORK( I ) = WORK( I ) / D( I ) + WORK( I+1 )*ABS( E( I ) )30 CONTINUE** Compute AINVNM = max(x(i)), 1<=i<=n.*IX = IDAMAX( N, WORK, 1 )AINVNM = ABS( WORK( IX ) )** Compute the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*RETURN** End of DPTCON*END*> \brief \b DPTEQR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTEQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpteqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpteqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpteqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )** .. Scalar Arguments ..* CHARACTER COMPZ* INTEGER INFO, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTEQR computes all eigenvalues and, optionally, eigenvectors of a*> symmetric positive definite tridiagonal matrix by first factoring the*> matrix using DPTTRF, and then calling DBDSQR to compute the singular*> values of the bidiagonal factor.*>*> This routine computes the eigenvalues of the positive definite*> tridiagonal matrix to high relative accuracy. This means that if the*> eigenvalues range over many orders of magnitude in size, then the*> small eigenvalues and corresponding eigenvectors will be computed*> more accurately than, for example, with the standard QR method.*>*> The eigenvectors of a full or band symmetric positive definite matrix*> can also be found if DSYTRD, DSPTRD, or DSBTRD has been used to*> reduce this matrix to tridiagonal form. (The reduction to tridiagonal*> form, however, may preclude the possibility of obtaining high*> relative accuracy in the small eigenvalues of the original matrix, if*> these eigenvalues range over many orders of magnitude.)*> \endverbatim** Arguments:* ==========**> \param[in] COMPZ*> \verbatim*> COMPZ is CHARACTER*1*> = 'N': Compute eigenvalues only.*> = 'V': Compute eigenvectors of original symmetric*> matrix also. Array Z contains the orthogonal*> matrix used to reduce the original matrix to*> tridiagonal form.*> = 'I': Compute eigenvectors of tridiagonal matrix also.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal*> matrix.*> On normal exit, D contains the eigenvalues, in descending*> order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> On entry, if COMPZ = 'V', the orthogonal matrix used in the*> reduction to tridiagonal form.*> On exit, if COMPZ = 'V', the orthonormal eigenvectors of the*> original symmetric matrix;*> if COMPZ = 'I', the orthonormal eigenvectors of the*> tridiagonal matrix.*> If INFO > 0 on exit, Z contains the eigenvectors associated*> with only the stored eigenvalues.*> If COMPZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> COMPZ = 'V' or 'I', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, and i is:*> <= N the Cholesky factorization of the matrix could*> not be performed because the i-th principal minor*> was not positive definite.*> > N the SVD algorithm failed to converge;*> if INFO = N+i, i off-diagonal elements of the*> bidiagonal factor did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTcomputational** =====================================================================SUBROUTINE DPTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER COMPZINTEGER INFO, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DBDSQR, DLASET, DPTTRF, XERBLA* ..* .. Local Arrays ..DOUBLE PRECISION C( 1, 1 ), VT( 1, 1 )* ..* .. Local Scalars ..INTEGER I, ICOMPZ, NRU* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( LSAME( COMPZ, 'N' ) ) THENICOMPZ = 0ELSE IF( LSAME( COMPZ, 'V' ) ) THENICOMPZ = 1ELSE IF( LSAME( COMPZ, 'I' ) ) THENICOMPZ = 2ELSEICOMPZ = -1END IFIF( ICOMPZ.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,$ N ) ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPTEQR', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ICOMPZ.GT.0 )$ Z( 1, 1 ) = ONERETURNEND IFIF( ICOMPZ.EQ.2 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )** Call DPTTRF to factor the matrix.*CALL DPTTRF( N, D, E, INFO )IF( INFO.NE.0 )$ RETURNDO 10 I = 1, ND( I ) = SQRT( D( I ) )10 CONTINUEDO 20 I = 1, N - 1E( I ) = E( I )*D( I )20 CONTINUE** Call DBDSQR to compute the singular values/vectors of the* bidiagonal factor.*IF( ICOMPZ.GT.0 ) THENNRU = NELSENRU = 0END IFCALL DBDSQR( 'Lower', N, 0, NRU, 0, D, E, VT, 1, Z, LDZ, C, 1,$ WORK, INFO )** Square the singular values.*IF( INFO.EQ.0 ) THENDO 30 I = 1, ND( I ) = D( I )*D( I )30 CONTINUEELSEINFO = N + INFOEND IF*RETURN** End of DPTEQR*END*> \brief \b DPTRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dptrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dptrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dptrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTRFS( N, NRHS, D, E, DF, EF, B, LDB, X, LDX, FERR,* BERR, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),* $ E( * ), EF( * ), FERR( * ), WORK( * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is symmetric positive definite*> and tridiagonal, and provides error bounds and backward error*> estimates for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the tridiagonal matrix A.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the tridiagonal matrix A.*> \endverbatim*>*> \param[in] DF*> \verbatim*> DF is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the diagonal matrix D from the*> factorization computed by DPTTRF.*> \endverbatim*>*> \param[in] EF*> \verbatim*> EF is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the unit bidiagonal factor*> L from the factorization computed by DPTTRF.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DPTTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j).*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTcomputational** =====================================================================SUBROUTINE DPTRFS( N, NRHS, D, E, DF, EF, B, LDB, X, LDX, FERR,$ BERR, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),$ E( * ), EF( * ), FERR( * ), WORK( * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..INTEGER COUNT, I, IX, J, NZDOUBLE PRECISION BI, CX, DX, EPS, EX, LSTRES, S, SAFE1, SAFE2,$ SAFMIN* ..* .. External Subroutines ..EXTERNAL DAXPY, DPTTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DLAMCHEXTERNAL IDAMAX, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( NRHS.LT.0 ) THENINFO = -2ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPTRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = 4EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 90 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - A * X. Also compute* abs(A)*abs(x) + abs(b) for use in the backward error bound.*IF( N.EQ.1 ) THENBI = B( 1, J )DX = D( 1 )*X( 1, J )WORK( N+1 ) = BI - DXWORK( 1 ) = ABS( BI ) + ABS( DX )ELSEBI = B( 1, J )DX = D( 1 )*X( 1, J )EX = E( 1 )*X( 2, J )WORK( N+1 ) = BI - DX - EXWORK( 1 ) = ABS( BI ) + ABS( DX ) + ABS( EX )DO 30 I = 2, N - 1BI = B( I, J )CX = E( I-1 )*X( I-1, J )DX = D( I )*X( I, J )EX = E( I )*X( I+1, J )WORK( N+I ) = BI - CX - DX - EXWORK( I ) = ABS( BI ) + ABS( CX ) + ABS( DX ) + ABS( EX )30 CONTINUEBI = B( N, J )CX = E( N-1 )*X( N-1, J )DX = D( N )*X( N, J )WORK( N+N ) = BI - CX - DXWORK( N ) = ABS( BI ) + ABS( CX ) + ABS( DX )END IF** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*S = ZERODO 40 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF40 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DPTTRS( N, 1, DF, EF, WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(A))** ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(A) is the inverse of A* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(A)*abs(X) + abs(B) is less than SAFE2.*DO 50 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF50 CONTINUEIX = IDAMAX( N, WORK, 1 )FERR( J ) = WORK( IX )** Estimate the norm of inv(A).** Solve M(A) * x = e, where M(A) = (m(i,j)) is given by** m(i,j) = abs(A(i,j)), i = j,* m(i,j) = -abs(A(i,j)), i .ne. j,** and e = [ 1, 1, ..., 1 ]**T. Note M(A) = M(L)*D*M(L)**T.** Solve M(L) * x = e.*WORK( 1 ) = ONEDO 60 I = 2, NWORK( I ) = ONE + WORK( I-1 )*ABS( EF( I-1 ) )60 CONTINUE** Solve D * M(L)**T * x = b.*WORK( N ) = WORK( N ) / DF( N )DO 70 I = N - 1, 1, -1WORK( I ) = WORK( I ) / DF( I ) + WORK( I+1 )*ABS( EF( I ) )70 CONTINUE** Compute norm(inv(A)) = max(x(i)), 1<=i<=n.*IX = IDAMAX( N, WORK, 1 )FERR( J ) = FERR( J )*ABS( WORK( IX ) )** Normalize error.*LSTRES = ZERODO 80 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )80 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*90 CONTINUE*RETURN** End of DPTRFS*END*> \brief <b> DPTSV computes the solution to system of linear equations A * X = B for PT matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dptsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dptsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dptsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTSV( N, NRHS, D, E, B, LDB, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTSV computes the solution to a real system of linear equations*> A*X = B, where A is an N-by-N symmetric positive definite tridiagonal*> matrix, and X and B are N-by-NRHS matrices.*>*> A is factored as A = L*D*L**T, and the factored form of A is then*> used to solve the system of equations.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix*> A. On exit, the n diagonal elements of the diagonal matrix*> D from the factorization A = L*D*L**T.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix A. On exit, the (n-1) subdiagonal elements of the*> unit bidiagonal factor L from the L*D*L**T factorization of*> A. (E can also be regarded as the superdiagonal of the unit*> bidiagonal factor U from the U**T*D*U factorization of A.)*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the leading minor of order i is not*> positive definite, and the solution has not been*> computed. The factorization has not been completed*> unless i = N.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTsolve** =====================================================================SUBROUTINE DPTSV( N, NRHS, D, E, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), D( * ), E( * )* ..** =====================================================================** .. External Subroutines ..EXTERNAL DPTTRF, DPTTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( NRHS.LT.0 ) THENINFO = -2ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPTSV ', -INFO )RETURNEND IF** Compute the L*D*L**T (or U**T*D*U) factorization of A.*CALL DPTTRF( N, D, E, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DPTTRS( N, NRHS, D, E, B, LDB, INFO )END IFRETURN** End of DPTSV*END*> \brief <b> DPTSVX computes the solution to system of linear equations A * X = B for PT matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dptsvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dptsvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dptsvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTSVX( FACT, N, NRHS, D, E, DF, EF, B, LDB, X, LDX,* RCOND, FERR, BERR, WORK, INFO )** .. Scalar Arguments ..* CHARACTER FACT* INTEGER INFO, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),* $ E( * ), EF( * ), FERR( * ), WORK( * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTSVX uses the factorization A = L*D*L**T to compute the solution*> to a real system of linear equations A*X = B, where A is an N-by-N*> symmetric positive definite tridiagonal matrix and X and B are*> N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'N', the matrix A is factored as A = L*D*L**T, where L*> is a unit lower bidiagonal matrix and D is diagonal. The*> factorization can also be regarded as having the form*> A = U**T*D*U.*>*> 2. If the leading i-by-i principal minor is not positive definite,*> then the routine returns with INFO = i. Otherwise, the factored*> form of A is used to estimate the condition number of the matrix*> A. If the reciprocal of the condition number is less than machine*> precision, INFO = N+1 is returned as a warning, but the routine*> still goes on to solve for X and compute error bounds as*> described below.*>*> 3. The system of equations is solved for X using the factored form*> of A.*>*> 4. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of A has been*> supplied on entry.*> = 'F': On entry, DF and EF contain the factored form of A.*> D, E, DF, and EF will not be modified.*> = 'N': The matrix A will be copied to DF and EF and*> factored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the tridiagonal matrix A.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the tridiagonal matrix A.*> \endverbatim*>*> \param[in,out] DF*> \verbatim*> DF is DOUBLE PRECISION array, dimension (N)*> If FACT = 'F', then DF is an input argument and on entry*> contains the n diagonal elements of the diagonal matrix D*> from the L*D*L**T factorization of A.*> If FACT = 'N', then DF is an output argument and on exit*> contains the n diagonal elements of the diagonal matrix D*> from the L*D*L**T factorization of A.*> \endverbatim*>*> \param[in,out] EF*> \verbatim*> EF is DOUBLE PRECISION array, dimension (N-1)*> If FACT = 'F', then EF is an input argument and on entry*> contains the (n-1) subdiagonal elements of the unit*> bidiagonal factor L from the L*D*L**T factorization of A.*> If FACT = 'N', then EF is an output argument and on exit*> contains the (n-1) subdiagonal elements of the unit*> bidiagonal factor L from the L*D*L**T factorization of A.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The N-by-NRHS right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 of INFO = N+1, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal condition number of the matrix A. If RCOND*> is less than the machine precision (in particular, if*> RCOND = 0), the matrix is singular to working precision.*> This condition is indicated by a return code of INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j).*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in any*> element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: the leading minor of order i of A is*> not positive definite, so the factorization*> could not be completed, and the solution has not*> been computed. RCOND = 0 is returned.*> = N+1: U is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTsolve** =====================================================================SUBROUTINE DPTSVX( FACT, N, NRHS, D, E, DF, EF, B, LDB, X, LDX,$ RCOND, FERR, BERR, WORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER FACTINTEGER INFO, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), BERR( * ), D( * ), DF( * ),$ E( * ), EF( * ), FERR( * ), WORK( * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOFACTDOUBLE PRECISION ANORM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DPTCON, DPTRFS, DPTTRF, DPTTRS,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOFACT = LSAME( FACT, 'N' )IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPTSVX', -INFO )RETURNEND IF*IF( NOFACT ) THEN** Compute the L*D*L**T (or U**T*D*U) factorization of A.*CALL DCOPY( N, D, 1, DF, 1 )IF( N.GT.1 )$ CALL DCOPY( N-1, E, 1, EF, 1 )CALL DPTTRF( N, DF, EF, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*ANORM = DLANST( '1', N, D, E )** Compute the reciprocal of the condition number of A.*CALL DPTCON( N, DF, EF, ANORM, RCOND, WORK, INFO )** Compute the solution vectors X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DPTTRS( N, NRHS, DF, EF, X, LDX, INFO )** Use iterative refinement to improve the computed solutions and* compute error bounds and backward error estimates for them.*CALL DPTRFS( N, NRHS, D, E, DF, EF, B, LDB, X, LDX, FERR, BERR,$ WORK, INFO )** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*RETURN** End of DPTSVX*END*> \brief \b DPTTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpttrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpttrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpttrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTTRF( N, D, E, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTTRF computes the L*D*L**T factorization of a real symmetric*> positive definite tridiagonal matrix A. The factorization may also*> be regarded as having the form A = U**T*D*U.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix*> A. On exit, the n diagonal elements of the diagonal matrix*> D from the L*D*L**T factorization of A.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix A. On exit, the (n-1) subdiagonal elements of the*> unit bidiagonal factor L from the L*D*L**T factorization of A.*> E can also be regarded as the superdiagonal of the unit*> bidiagonal factor U from the U**T*D*U factorization of A.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> > 0: if INFO = k, the leading minor of order k is not*> positive definite; if k < N, the factorization could not*> be completed, while if k = N, the factorization was*> completed, but D(N) <= 0.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTcomputational** =====================================================================SUBROUTINE DPTTRF( N, D, E, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, I4DOUBLE PRECISION EI* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DPTTRF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Compute the L*D*L**T (or U**T*D*U) factorization of A.*I4 = MOD( N-1, 4 )DO 10 I = 1, I4IF( D( I ).LE.ZERO ) THENINFO = IGO TO 30END IFEI = E( I )E( I ) = EI / D( I )D( I+1 ) = D( I+1 ) - E( I )*EI10 CONTINUE*DO 20 I = I4 + 1, N - 4, 4** Drop out of the loop if d(i) <= 0: the matrix is not positive* definite.*IF( D( I ).LE.ZERO ) THENINFO = IGO TO 30END IF** Solve for e(i) and d(i+1).*EI = E( I )E( I ) = EI / D( I )D( I+1 ) = D( I+1 ) - E( I )*EI*IF( D( I+1 ).LE.ZERO ) THENINFO = I + 1GO TO 30END IF** Solve for e(i+1) and d(i+2).*EI = E( I+1 )E( I+1 ) = EI / D( I+1 )D( I+2 ) = D( I+2 ) - E( I+1 )*EI*IF( D( I+2 ).LE.ZERO ) THENINFO = I + 2GO TO 30END IF** Solve for e(i+2) and d(i+3).*EI = E( I+2 )E( I+2 ) = EI / D( I+2 )D( I+3 ) = D( I+3 ) - E( I+2 )*EI*IF( D( I+3 ).LE.ZERO ) THENINFO = I + 3GO TO 30END IF** Solve for e(i+3) and d(i+4).*EI = E( I+3 )E( I+3 ) = EI / D( I+3 )D( I+4 ) = D( I+4 ) - E( I+3 )*EI20 CONTINUE** Check d(n) for positive definiteness.*IF( D( N ).LE.ZERO )$ INFO = N*30 CONTINUERETURN** End of DPTTRF*END*> \brief \b DPTTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dpttrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dpttrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dpttrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTTRS( N, NRHS, D, E, B, LDB, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTTRS solves a tridiagonal system of the form*> A * X = B*> using the L*D*L**T factorization of A computed by DPTTRF. D is a*> diagonal matrix specified in the vector D, L is a unit bidiagonal*> matrix whose subdiagonal is specified in the vector E, and X and B*> are N by NRHS matrices.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the tridiagonal matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the diagonal matrix D from the*> L*D*L**T factorization of A.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the unit bidiagonal factor*> L from the L*D*L**T factorization of A. E can also be regarded*> as the superdiagonal of the unit bidiagonal factor U from the*> factorization A = U**T*D*U.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side vectors B for the system of*> linear equations.*> On exit, the solution vectors, X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTcomputational** =====================================================================SUBROUTINE DPTTRS( N, NRHS, D, E, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), D( * ), E( * )* ..** =====================================================================** .. Local Scalars ..INTEGER J, JB, NB* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. External Subroutines ..EXTERNAL DPTTS2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments.*INFO = 0IF( N.LT.0 ) THENINFO = -1ELSE IF( NRHS.LT.0 ) THENINFO = -2ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DPTTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN** Determine the number of right-hand sides to solve at a time.*IF( NRHS.EQ.1 ) THENNB = 1ELSENB = MAX( 1, ILAENV( 1, 'DPTTRS', ' ', N, NRHS, -1, -1 ) )END IF*IF( NB.GE.NRHS ) THENCALL DPTTS2( N, NRHS, D, E, B, LDB )ELSEDO 10 J = 1, NRHS, NBJB = MIN( NRHS-J+1, NB )CALL DPTTS2( N, JB, D, E, B( 1, J ), LDB )10 CONTINUEEND IF*RETURN** End of DPTTRS*END*> \brief \b DPTTS2 solves a tridiagonal system of the form AX=B using the L D LH factorization computed by spttrf.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DPTTS2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dptts2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dptts2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dptts2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DPTTS2( N, NRHS, D, E, B, LDB )** .. Scalar Arguments ..* INTEGER LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION B( LDB, * ), D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DPTTS2 solves a tridiagonal system of the form*> A * X = B*> using the L*D*L**T factorization of A computed by DPTTRF. D is a*> diagonal matrix specified in the vector D, L is a unit bidiagonal*> matrix whose subdiagonal is specified in the vector E, and X and B*> are N by NRHS matrices.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the tridiagonal matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the diagonal matrix D from the*> L*D*L**T factorization of A.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the unit bidiagonal factor*> L from the L*D*L**T factorization of A. E can also be regarded*> as the superdiagonal of the unit bidiagonal factor U from the*> factorization A = U**T*D*U.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side vectors B for the system of*> linear equations.*> On exit, the solution vectors, X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doublePTcomputational** =====================================================================SUBROUTINE DPTTS2( N, NRHS, D, E, B, LDB )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION B( LDB, * ), D( * ), E( * )* ..** =====================================================================** .. Local Scalars ..INTEGER I, J* ..* .. External Subroutines ..EXTERNAL DSCAL* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.1 ) THENIF( N.EQ.1 )$ CALL DSCAL( NRHS, 1.D0 / D( 1 ), B, LDB )RETURNEND IF** Solve A * X = B using the factorization A = L*D*L**T,* overwriting each right hand side vector with its solution.*DO 30 J = 1, NRHS** Solve L * x = b.*DO 10 I = 2, NB( I, J ) = B( I, J ) - B( I-1, J )*E( I-1 )10 CONTINUE** Solve D * L**T * x = b.*B( N, J ) = B( N, J ) / D( N )DO 20 I = N - 1, 1, -1B( I, J ) = B( I, J ) / D( I ) - B( I+1, J )*E( I )20 CONTINUE30 CONTINUE*RETURN** End of DPTTS2*END*> \brief \b DRSCL multiplies a vector by the reciprocal of a real scalar.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DRSCL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/drscl.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/drscl.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/drscl.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DRSCL( N, SA, SX, INCX )** .. Scalar Arguments ..* INTEGER INCX, N* DOUBLE PRECISION SA* ..* .. Array Arguments ..* DOUBLE PRECISION SX( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DRSCL multiplies an n-element real vector x by the real scalar 1/a.*> This is done without overflow or underflow as long as*> the final result x/a does not overflow or underflow.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The number of components of the vector x.*> \endverbatim*>*> \param[in] SA*> \verbatim*> SA is DOUBLE PRECISION*> The scalar a which is used to divide each component of x.*> SA must be >= 0, or the subroutine will divide by zero.*> \endverbatim*>*> \param[in,out] SX*> \verbatim*> SX is DOUBLE PRECISION array, dimension*> (1+(N-1)*abs(INCX))*> The n-element vector x.*> \endverbatim*>*> \param[in] INCX*> \verbatim*> INCX is INTEGER*> The increment between successive values of the vector SX.*> > 0: SX(1) = X(1) and SX(1+(i-1)*INCX) = x(i), 1< i<= n*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERauxiliary** =====================================================================SUBROUTINE DRSCL( N, SA, SX, INCX )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER INCX, NDOUBLE PRECISION SA* ..* .. Array Arguments ..DOUBLE PRECISION SX( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL DONEDOUBLE PRECISION BIGNUM, CDEN, CDEN1, CNUM, CNUM1, MUL, SMLNUM* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DSCAL, DLABAD* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Quick return if possible*IF( N.LE.0 )$ RETURN** Get machine parameters*SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )** Initialize the denominator to SA and the numerator to 1.*CDEN = SACNUM = ONE*10 CONTINUECDEN1 = CDEN*SMLNUMCNUM1 = CNUM / BIGNUMIF( ABS( CDEN1 ).GT.ABS( CNUM ) .AND. CNUM.NE.ZERO ) THEN** Pre-multiply X by SMLNUM if CDEN is large compared to CNUM.*MUL = SMLNUMDONE = .FALSE.CDEN = CDEN1ELSE IF( ABS( CNUM1 ).GT.ABS( CDEN ) ) THEN** Pre-multiply X by BIGNUM if CDEN is small compared to CNUM.*MUL = BIGNUMDONE = .FALSE.CNUM = CNUM1ELSE** Multiply X by CNUM / CDEN and return.*MUL = CNUM / CDENDONE = .TRUE.END IF** Scale the vector X by MUL*CALL DSCAL( N, MUL, SX, INCX )*IF( .NOT.DONE )$ GO TO 10*RETURN** End of DRSCL*END*> \brief <b> DSBEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBEV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbev.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbev.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbev.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBEV( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,* INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, KD, LDAB, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBEV computes all the eigenvalues and, optionally, eigenvectors of*> a real symmetric band matrix A.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, AB is overwritten by values generated during the*> reduction to tridiagonal form. If UPLO = 'U', the first*> superdiagonal and the diagonal of the tridiagonal matrix T*> are returned in rows KD and KD+1 of AB, and if UPLO = 'L',*> the diagonal and first subdiagonal of T are returned in the*> first two rows of AB.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD + 1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal*> eigenvectors of the matrix A, with the i-th column of Z*> holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (max(1,3*N-2))*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of an intermediate tridiagonal*> form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSBEV( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,$ INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, KD, LDAB, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LOWER, WANTZINTEGER IINFO, IMAX, INDE, INDWRK, ISCALEDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSBEXTERNAL LSAME, DLAMCH, DLANSB* ..* .. External Subroutines ..EXTERNAL DLASCL, DSBTRD, DSCAL, DSTEQR, DSTERF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LOWER = LSAME( UPLO, 'L' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KD.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KD+1 ) THENINFO = -6ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -9END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSBEV ', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( LOWER ) THENW( 1 ) = AB( 1, 1 )ELSEW( 1 ) = AB( KD+1, 1 )END IFIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSB( 'M', UPLO, N, KD, AB, LDAB, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENIF( LOWER ) THENCALL DLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )ELSECALL DLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )END IFEND IF** Call DSBTRD to reduce symmetric band matrix to tridiagonal form.*INDE = 1INDWRK = INDE + NCALL DSBTRD( JOBZ, UPLO, N, KD, AB, LDAB, W, WORK( INDE ), Z, LDZ,$ WORK( INDWRK ), IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, call SSTEQR.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DSTEQR( JOBZ, N, W, WORK( INDE ), Z, LDZ, WORK( INDWRK ),$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = NELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF*RETURN** End of DSBEV*END*> \brief <b> DSBEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBEVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbevd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbevd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbevd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBEVD( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,* LWORK, IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, KD, LDAB, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBEVD computes all the eigenvalues and, optionally, eigenvectors of*> a real symmetric band matrix A. If eigenvectors are desired, it uses*> a divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, AB is overwritten by values generated during the*> reduction to tridiagonal form. If UPLO = 'U', the first*> superdiagonal and the diagonal of the tridiagonal matrix T*> are returned in rows KD and KD+1 of AB, and if UPLO = 'L',*> the diagonal and first subdiagonal of T are returned in the*> first two rows of AB.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD + 1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal*> eigenvectors of the matrix A, with the i-th column of Z*> holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array,*> dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> IF N <= 1, LWORK must be at least 1.*> If JOBZ = 'N' and N > 2, LWORK must be at least 2*N.*> If JOBZ = 'V' and N > 2, LWORK must be at least*> ( 1 + 5*N + 2*N**2 ).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If JOBZ = 'N' or N <= 1, LIWORK must be at least 1.*> If JOBZ = 'V' and N > 2, LIWORK must be at least 3 + 5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of an intermediate tridiagonal*> form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSBEVD( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,$ LWORK, IWORK, LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, KD, LDAB, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, LQUERY, WANTZINTEGER IINFO, INDE, INDWK2, INDWRK, ISCALE, LIWMIN,$ LLWRK2, LWMINDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSBEXTERNAL LSAME, DLAMCH, DLANSB* ..* .. External Subroutines ..EXTERNAL DGEMM, DLACPY, DLASCL, DSBTRD, DSCAL, DSTEDC,$ DSTERF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LOWER = LSAME( UPLO, 'L' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0IF( N.LE.1 ) THENLIWMIN = 1LWMIN = 1ELSEIF( WANTZ ) THENLIWMIN = 3 + 5*NLWMIN = 1 + 5*N + 2*N**2ELSELIWMIN = 1LWMIN = 2*NEND IFEND IFIF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KD.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KD+1 ) THENINFO = -6ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -9END IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -11ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -13END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSBEVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENW( 1 ) = AB( 1, 1 )IF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSB( 'M', UPLO, N, KD, AB, LDAB, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENIF( LOWER ) THENCALL DLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )ELSECALL DLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )END IFEND IF** Call DSBTRD to reduce symmetric band matrix to tridiagonal form.*INDE = 1INDWRK = INDE + NINDWK2 = INDWRK + N*NLLWRK2 = LWORK - INDWK2 + 1CALL DSBTRD( JOBZ, UPLO, N, KD, AB, LDAB, W, WORK( INDE ), Z, LDZ,$ WORK( INDWRK ), IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, call SSTEDC.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,$ WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )CALL DGEMM( 'N', 'N', N, N, N, ONE, Z, LDZ, WORK( INDWRK ), N,$ ZERO, WORK( INDWK2 ), N )CALL DLACPY( 'A', N, N, WORK( INDWK2 ), N, Z, LDZ )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 )$ CALL DSCAL( N, ONE / SIGMA, W, 1 )*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMINRETURN** End of DSBEVD*END*> \brief <b> DSBEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBEVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbevx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbevx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbevx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, VL,* VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,* IFAIL, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, IU, KD, LDAB, LDQ, LDZ, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), Q( LDQ, * ), W( * ), WORK( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBEVX computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric band matrix A. Eigenvalues and eigenvectors can*> be selected by specifying either a range of values or a range of*> indices for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found;*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found;*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*>*> On exit, AB is overwritten by values generated during the*> reduction to tridiagonal form. If UPLO = 'U', the first*> superdiagonal and the diagonal of the tridiagonal matrix T*> are returned in rows KD and KD+1 of AB, and if UPLO = 'L',*> the diagonal and first subdiagonal of T are returned in the*> first two rows of AB.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD + 1.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> If JOBZ = 'V', the N-by-N orthogonal matrix used in the*> reduction to tridiagonal form.*> If JOBZ = 'N', the array Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. If JOBZ = 'V', then*> LDQ >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing AB to tridiagonal form.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*>*> See "Computing Small Singular Values of Bidiagonal Matrices*> with Guaranteed High Relative Accuracy," by Demmel and*> Kahan, LAPACK Working Note #3.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the selected eigenvalues in*> ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If an eigenvector fails to converge, then that column of Z*> contains the latest approximation to the eigenvector, and the*> index of the eigenvector is returned in IFAIL.*> If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (7*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (N)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvectors that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, then i eigenvectors failed to converge.*> Their indices are stored in array IFAIL.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSBEVX( JOBZ, RANGE, UPLO, N, KD, AB, LDAB, Q, LDQ, VL,$ VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,$ IFAIL, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, IU, KD, LDAB, LDQ, LDZ, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), Q( LDQ, * ), W( * ), WORK( * ),$ Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, LOWER, TEST, VALEIG, WANTZCHARACTER ORDERINTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,$ INDISP, INDIWO, INDWRK, ISCALE, ITMP1, J, JJ,$ NSPLITDOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,$ SIGMA, SMLNUM, TMP1, VLL, VUU* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSBEXTERNAL LSAME, DLAMCH, DLANSB* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DLACPY, DLASCL, DSBTRD, DSCAL,$ DSTEBZ, DSTEIN, DSTEQR, DSTERF, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )LOWER = LSAME( UPLO, 'L' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( KD.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.KD+1 ) THENINFO = -7ELSE IF( WANTZ .AND. LDQ.LT.MAX( 1, N ) ) THENINFO = -9ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -11ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -12ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -13END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )$ INFO = -18END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSBEVX', -INFO )RETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENM = 1IF( LOWER ) THENTMP1 = AB( 1, 1 )ELSETMP1 = AB( KD+1, 1 )END IFIF( VALEIG ) THENIF( .NOT.( VL.LT.TMP1 .AND. VU.GE.TMP1 ) )$ M = 0END IFIF( M.EQ.1 ) THENW( 1 ) = TMP1IF( WANTZ )$ Z( 1, 1 ) = ONEEND IFRETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )** Scale matrix to allowable range, if necessary.*ISCALE = 0ABSTLL = ABSTOLIF( VALEIG ) THENVLL = VLVUU = VUELSEVLL = ZEROVUU = ZEROEND IFANRM = DLANSB( 'M', UPLO, N, KD, AB, LDAB, WORK )IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENIF( LOWER ) THENCALL DLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )ELSECALL DLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )END IFIF( ABSTOL.GT.0 )$ ABSTLL = ABSTOL*SIGMAIF( VALEIG ) THENVLL = VL*SIGMAVUU = VU*SIGMAEND IFEND IF** Call DSBTRD to reduce symmetric band matrix to tridiagonal form.*INDD = 1INDE = INDD + NINDWRK = INDE + NCALL DSBTRD( JOBZ, UPLO, N, KD, AB, LDAB, WORK( INDD ),$ WORK( INDE ), Q, LDQ, WORK( INDWRK ), IINFO )** If all eigenvalues are desired and ABSTOL is less than or equal* to zero, then call DSTERF or SSTEQR. If this fails for some* eigenvalue, then try DSTEBZ.*TEST = .FALSE.IF (INDEIG) THENIF (IL.EQ.1 .AND. IU.EQ.N) THENTEST = .TRUE.END IFEND IFIF ((ALLEIG .OR. TEST) .AND. (ABSTOL.LE.ZERO)) THENCALL DCOPY( N, WORK( INDD ), 1, W, 1 )INDEE = INDWRK + 2*NIF( .NOT.WANTZ ) THENCALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTERF( N, W, WORK( INDEE ), INFO )ELSECALL DLACPY( 'A', N, N, Q, LDQ, Z, LDZ )CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,$ WORK( INDWRK ), INFO )IF( INFO.EQ.0 ) THENDO 10 I = 1, NIFAIL( I ) = 010 CONTINUEEND IFEND IFIF( INFO.EQ.0 ) THENM = NGO TO 30END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFINDIBL = 1INDISP = INDIBL + NINDIWO = INDISP + NCALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,$ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,$ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),$ IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,$ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,$ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )** Apply orthogonal matrix used in reduction to tridiagonal* form to eigenvectors returned by DSTEIN.*DO 20 J = 1, MCALL DCOPY( N, Z( 1, J ), 1, WORK( 1 ), 1 )CALL DGEMV( 'N', N, N, ONE, Q, LDQ, WORK, 1, ZERO,$ Z( 1, J ), 1 )20 CONTINUEEND IF** If matrix was scaled, then rescale eigenvalues appropriately.*30 CONTINUEIF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = MELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** If eigenvalues are not in order, then sort them, along with* eigenvectors.*IF( WANTZ ) THENDO 50 J = 1, M - 1I = 0TMP1 = W( J )DO 40 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF40 CONTINUE*IF( I.NE.0 ) THENITMP1 = IWORK( INDIBL+I-1 )W( I ) = W( J )IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )W( J ) = TMP1IWORK( INDIBL+J-1 ) = ITMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )IF( INFO.NE.0 ) THENITMP1 = IFAIL( I )IFAIL( I ) = IFAIL( J )IFAIL( J ) = ITMP1END IFEND IF50 CONTINUEEND IF*RETURN** End of DSBEVX*END*> \brief \b DSBGST** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBGST + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbgst.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbgst.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbgst.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,* LDX, WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO, VECT* INTEGER INFO, KA, KB, LDAB, LDBB, LDX, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), WORK( * ),* $ X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBGST reduces a real symmetric-definite banded generalized*> eigenproblem A*x = lambda*B*x to standard form C*y = lambda*y,*> such that C has the same bandwidth as A.*>*> B must have been previously factorized as S**T*S by DPBSTF, using a*> split Cholesky factorization. A is overwritten by C = X**T*A*X, where*> X = S**(-1)*Q and Q is an orthogonal matrix chosen to preserve the*> bandwidth of A.*> \endverbatim** Arguments:* ==========**> \param[in] VECT*> \verbatim*> VECT is CHARACTER*1*> = 'N': do not form the transformation matrix X;*> = 'V': form X.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] KA*> \verbatim*> KA is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KA >= 0.*> \endverbatim*>*> \param[in] KB*> \verbatim*> KB is INTEGER*> The number of superdiagonals of the matrix B if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KA >= KB >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first ka+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).*>*> On exit, the transformed matrix X**T*A*X, stored in the same*> format as A.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KA+1.*> \endverbatim*>*> \param[in] BB*> \verbatim*> BB is DOUBLE PRECISION array, dimension (LDBB,N)*> The banded factor S from the split Cholesky factorization of*> B, as returned by DPBSTF, stored in the first KB+1 rows of*> the array.*> \endverbatim*>*> \param[in] LDBB*> \verbatim*> LDBB is INTEGER*> The leading dimension of the array BB. LDBB >= KB+1.*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,N)*> If VECT = 'V', the n-by-n matrix X.*> If VECT = 'N', the array X is not referenced.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X.*> LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,$ LDX, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLO, VECTINTEGER INFO, KA, KB, LDAB, LDBB, LDX, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), WORK( * ),$ X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPDATE, UPPER, WANTXINTEGER I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K,$ KA1, KB1, KBT, L, M, NR, NRT, NXDOUBLE PRECISION BII, RA, RA1, T* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGER, DLAR2V, DLARGV, DLARTG, DLARTV, DLASET,$ DROT, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*WANTX = LSAME( VECT, 'V' )UPPER = LSAME( UPLO, 'U' )KA1 = KA + 1KB1 = KB + 1INFO = 0IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KA.LT.0 ) THENINFO = -4ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THENINFO = -5ELSE IF( LDAB.LT.KA+1 ) THENINFO = -7ELSE IF( LDBB.LT.KB+1 ) THENINFO = -9ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSBGST', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*INCA = LDAB*KA1** Initialize X to the unit matrix, if needed*IF( WANTX )$ CALL DLASET( 'Full', N, N, ZERO, ONE, X, LDX )** Set M to the splitting point m. It must be the same value as is* used in DPBSTF. The chosen value allows the arrays WORK and RWORK* to be of dimension (N).*M = ( N+KB ) / 2** The routine works in two phases, corresponding to the two halves* of the split Cholesky factorization of B as S**T*S where** S = ( U )* ( M L )** with U upper triangular of order m, and L lower triangular of* order n-m. S has the same bandwidth as B.** S is treated as a product of elementary matrices:** S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n)** where S(i) is determined by the i-th row of S.** In phase 1, the index i takes the values n, n-1, ... , m+1;* in phase 2, it takes the values 1, 2, ... , m.** For each value of i, the current matrix A is updated by forming* inv(S(i))**T*A*inv(S(i)). This creates a triangular bulge outside* the band of A. The bulge is then pushed down toward the bottom of* A in phase 1, and up toward the top of A in phase 2, by applying* plane rotations.** There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1* of them are linearly independent, so annihilating a bulge requires* only 2*kb-1 plane rotations. The rotations are divided into a 1st* set of kb-1 rotations, and a 2nd set of kb rotations.** Wherever possible, rotations are generated and applied in vector* operations of length NR between the indices J1 and J2 (sometimes* replaced by modified values NRT, J1T or J2T).** The cosines and sines of the rotations are stored in the array* WORK. The cosines of the 1st set of rotations are stored in* elements n+2:n+m-kb-1 and the sines of the 1st set in elements* 2:m-kb-1; the cosines of the 2nd set are stored in elements* n+m-kb+1:2*n and the sines of the second set in elements m-kb+1:n.** The bulges are not formed explicitly; nonzero elements outside the* band are created only when they are required for generating new* rotations; they are stored in the array WORK, in positions where* they are later overwritten by the sines of the rotations which* annihilate them.** **************************** Phase 1 ******************************* The logical structure of this phase is:** UPDATE = .TRUE.* DO I = N, M + 1, -1* use S(i) to update A and create a new bulge* apply rotations to push all bulges KA positions downward* END DO* UPDATE = .FALSE.* DO I = M + KA + 1, N - 1* apply rotations to push all bulges KA positions downward* END DO** To avoid duplicating code, the two loops are merged.*UPDATE = .TRUE.I = N + 110 CONTINUEIF( UPDATE ) THENI = I - 1KBT = MIN( KB, I-1 )I0 = I - 1I1 = MIN( N, I+KA )I2 = I - KBT + KA1IF( I.LT.M+1 ) THENUPDATE = .FALSE.I = I + 1I0 = MIF( KA.EQ.0 )$ GO TO 480GO TO 10END IFELSEI = I + KAIF( I.GT.N-1 )$ GO TO 480END IF*IF( UPPER ) THEN** Transform A, working with the upper triangle*IF( UPDATE ) THEN** Form inv(S(i))**T * A * inv(S(i))*BII = BB( KB1, I )DO 20 J = I, I1AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII20 CONTINUEDO 30 J = MAX( 1, I-KA ), IAB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII30 CONTINUEDO 60 K = I - KBT, I - 1DO 40 J = I - KBT, KAB( J-K+KA1, K ) = AB( J-K+KA1, K ) -$ BB( J-I+KB1, I )*AB( K-I+KA1, I ) -$ BB( K-I+KB1, I )*AB( J-I+KA1, I ) +$ AB( KA1, I )*BB( J-I+KB1, I )*$ BB( K-I+KB1, I )40 CONTINUEDO 50 J = MAX( 1, I-KA ), I - KBT - 1AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -$ BB( K-I+KB1, I )*AB( J-I+KA1, I )50 CONTINUE60 CONTINUEDO 80 J = I, I1DO 70 K = MAX( J-KA, I-KBT ), I - 1AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -$ BB( K-I+KB1, I )*AB( I-J+KA1, J )70 CONTINUE80 CONTINUE*IF( WANTX ) THEN** post-multiply X by inv(S(i))*CALL DSCAL( N-M, ONE / BII, X( M+1, I ), 1 )IF( KBT.GT.0 )$ CALL DGER( N-M, KBT, -ONE, X( M+1, I ), 1,$ BB( KB1-KBT, I ), 1, X( M+1, I-KBT ), LDX )END IF** store a(i,i1) in RA1 for use in next loop over K*RA1 = AB( I-I1+KA1, I1 )END IF** Generate and apply vectors of rotations to chase all the* existing bulges KA positions down toward the bottom of the* band*DO 130 K = 1, KB - 1IF( UPDATE ) THEN** Determine the rotations which would annihilate the bulge* which has in theory just been created*IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN** generate rotation to annihilate a(i,i-k+ka+1)*CALL DLARTG( AB( K+1, I-K+KA ), RA1,$ WORK( N+I-K+KA-M ), WORK( I-K+KA-M ),$ RA )** create nonzero element a(i-k,i-k+ka+1) outside the* band and store it in WORK(i-k)*T = -BB( KB1-K, I )*RA1WORK( I-K ) = WORK( N+I-K+KA-M )*T -$ WORK( I-K+KA-M )*AB( 1, I-K+KA )AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +$ WORK( N+I-K+KA-M )*AB( 1, I-K+KA )RA1 = RAEND IFEND IFJ2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1NR = ( N-J2+KA ) / KA1J1 = J2 + ( NR-1 )*KA1IF( UPDATE ) THENJ2T = MAX( J2, I+2*KA-K+1 )ELSEJ2T = J2END IFNRT = ( N-J2T+KA ) / KA1DO 90 J = J2T, J1, KA1** create nonzero element a(j-ka,j+1) outside the band* and store it in WORK(j-m)*WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )AB( 1, J+1 ) = WORK( N+J-M )*AB( 1, J+1 )90 CONTINUE** generate rotations in 1st set to annihilate elements which* have been created outside the band*IF( NRT.GT.0 )$ CALL DLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,$ WORK( N+J2T-M ), KA1 )IF( NR.GT.0 ) THEN** apply rotations in 1st set from the right*DO 100 L = 1, KA - 1CALL DLARTV( NR, AB( KA1-L, J2 ), INCA,$ AB( KA-L, J2+1 ), INCA, WORK( N+J2-M ),$ WORK( J2-M ), KA1 )100 CONTINUE** apply rotations in 1st set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),$ AB( KA, J2+1 ), INCA, WORK( N+J2-M ),$ WORK( J2-M ), KA1 )*END IF** start applying rotations in 1st set from the left*DO 110 L = KA - 1, KB - K + 1, -1NRT = ( N-J2+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J2+KA1-L ), INCA,$ AB( L+1, J2+KA1-L ), INCA,$ WORK( N+J2-M ), WORK( J2-M ), KA1 )110 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 1st set*DO 120 J = J2, J1, KA1CALL DROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,$ WORK( N+J-M ), WORK( J-M ) )120 CONTINUEEND IF130 CONTINUE*IF( UPDATE ) THENIF( I2.LE.N .AND. KBT.GT.0 ) THEN** create nonzero element a(i-kbt,i-kbt+ka+1) outside the* band and store it in WORK(i-kbt)*WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1END IFEND IF*DO 170 K = KB, 1, -1IF( UPDATE ) THENJ2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1ELSEJ2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1END IF** finish applying rotations in 2nd set from the left*DO 140 L = KB - K, 1, -1NRT = ( N-J2+KA+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J2-L+1 ), INCA,$ AB( L+1, J2-L+1 ), INCA, WORK( N+J2-KA ),$ WORK( J2-KA ), KA1 )140 CONTINUENR = ( N-J2+KA ) / KA1J1 = J2 + ( NR-1 )*KA1DO 150 J = J1, J2, -KA1WORK( J ) = WORK( J-KA )WORK( N+J ) = WORK( N+J-KA )150 CONTINUEDO 160 J = J2, J1, KA1** create nonzero element a(j-ka,j+1) outside the band* and store it in WORK(j)*WORK( J ) = WORK( J )*AB( 1, J+1 )AB( 1, J+1 ) = WORK( N+J )*AB( 1, J+1 )160 CONTINUEIF( UPDATE ) THENIF( I-K.LT.N-KA .AND. K.LE.KBT )$ WORK( I-K+KA ) = WORK( I-K )END IF170 CONTINUE*DO 210 K = KB, 1, -1J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1NR = ( N-J2+KA ) / KA1J1 = J2 + ( NR-1 )*KA1IF( NR.GT.0 ) THEN** generate rotations in 2nd set to annihilate elements* which have been created outside the band*CALL DLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1,$ WORK( N+J2 ), KA1 )** apply rotations in 2nd set from the right*DO 180 L = 1, KA - 1CALL DLARTV( NR, AB( KA1-L, J2 ), INCA,$ AB( KA-L, J2+1 ), INCA, WORK( N+J2 ),$ WORK( J2 ), KA1 )180 CONTINUE** apply rotations in 2nd set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),$ AB( KA, J2+1 ), INCA, WORK( N+J2 ),$ WORK( J2 ), KA1 )*END IF** start applying rotations in 2nd set from the left*DO 190 L = KA - 1, KB - K + 1, -1NRT = ( N-J2+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J2+KA1-L ), INCA,$ AB( L+1, J2+KA1-L ), INCA, WORK( N+J2 ),$ WORK( J2 ), KA1 )190 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 2nd set*DO 200 J = J2, J1, KA1CALL DROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,$ WORK( N+J ), WORK( J ) )200 CONTINUEEND IF210 CONTINUE*DO 230 K = 1, KB - 1J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1** finish applying rotations in 1st set from the left*DO 220 L = KB - K, 1, -1NRT = ( N-J2+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J2+KA1-L ), INCA,$ AB( L+1, J2+KA1-L ), INCA,$ WORK( N+J2-M ), WORK( J2-M ), KA1 )220 CONTINUE230 CONTINUE*IF( KB.GT.1 ) THENDO 240 J = N - 1, I - KB + 2*KA + 1, -1WORK( N+J-M ) = WORK( N+J-KA-M )WORK( J-M ) = WORK( J-KA-M )240 CONTINUEEND IF*ELSE** Transform A, working with the lower triangle*IF( UPDATE ) THEN** Form inv(S(i))**T * A * inv(S(i))*BII = BB( 1, I )DO 250 J = I, I1AB( J-I+1, I ) = AB( J-I+1, I ) / BII250 CONTINUEDO 260 J = MAX( 1, I-KA ), IAB( I-J+1, J ) = AB( I-J+1, J ) / BII260 CONTINUEDO 290 K = I - KBT, I - 1DO 270 J = I - KBT, KAB( K-J+1, J ) = AB( K-J+1, J ) -$ BB( I-J+1, J )*AB( I-K+1, K ) -$ BB( I-K+1, K )*AB( I-J+1, J ) +$ AB( 1, I )*BB( I-J+1, J )*$ BB( I-K+1, K )270 CONTINUEDO 280 J = MAX( 1, I-KA ), I - KBT - 1AB( K-J+1, J ) = AB( K-J+1, J ) -$ BB( I-K+1, K )*AB( I-J+1, J )280 CONTINUE290 CONTINUEDO 310 J = I, I1DO 300 K = MAX( J-KA, I-KBT ), I - 1AB( J-K+1, K ) = AB( J-K+1, K ) -$ BB( I-K+1, K )*AB( J-I+1, I )300 CONTINUE310 CONTINUE*IF( WANTX ) THEN** post-multiply X by inv(S(i))*CALL DSCAL( N-M, ONE / BII, X( M+1, I ), 1 )IF( KBT.GT.0 )$ CALL DGER( N-M, KBT, -ONE, X( M+1, I ), 1,$ BB( KBT+1, I-KBT ), LDBB-1,$ X( M+1, I-KBT ), LDX )END IF** store a(i1,i) in RA1 for use in next loop over K*RA1 = AB( I1-I+1, I )END IF** Generate and apply vectors of rotations to chase all the* existing bulges KA positions down toward the bottom of the* band*DO 360 K = 1, KB - 1IF( UPDATE ) THEN** Determine the rotations which would annihilate the bulge* which has in theory just been created*IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN** generate rotation to annihilate a(i-k+ka+1,i)*CALL DLARTG( AB( KA1-K, I ), RA1, WORK( N+I-K+KA-M ),$ WORK( I-K+KA-M ), RA )** create nonzero element a(i-k+ka+1,i-k) outside the* band and store it in WORK(i-k)*T = -BB( K+1, I-K )*RA1WORK( I-K ) = WORK( N+I-K+KA-M )*T -$ WORK( I-K+KA-M )*AB( KA1, I-K )AB( KA1, I-K ) = WORK( I-K+KA-M )*T +$ WORK( N+I-K+KA-M )*AB( KA1, I-K )RA1 = RAEND IFEND IFJ2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1NR = ( N-J2+KA ) / KA1J1 = J2 + ( NR-1 )*KA1IF( UPDATE ) THENJ2T = MAX( J2, I+2*KA-K+1 )ELSEJ2T = J2END IFNRT = ( N-J2T+KA ) / KA1DO 320 J = J2T, J1, KA1** create nonzero element a(j+1,j-ka) outside the band* and store it in WORK(j-m)*WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 )AB( KA1, J-KA+1 ) = WORK( N+J-M )*AB( KA1, J-KA+1 )320 CONTINUE** generate rotations in 1st set to annihilate elements which* have been created outside the band*IF( NRT.GT.0 )$ CALL DLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ),$ KA1, WORK( N+J2T-M ), KA1 )IF( NR.GT.0 ) THEN** apply rotations in 1st set from the left*DO 330 L = 1, KA - 1CALL DLARTV( NR, AB( L+1, J2-L ), INCA,$ AB( L+2, J2-L ), INCA, WORK( N+J2-M ),$ WORK( J2-M ), KA1 )330 CONTINUE** apply rotations in 1st set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),$ INCA, WORK( N+J2-M ), WORK( J2-M ), KA1 )*END IF** start applying rotations in 1st set from the right*DO 340 L = KA - 1, KB - K + 1, -1NRT = ( N-J2+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J2 ), INCA,$ AB( KA1-L, J2+1 ), INCA, WORK( N+J2-M ),$ WORK( J2-M ), KA1 )340 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 1st set*DO 350 J = J2, J1, KA1CALL DROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,$ WORK( N+J-M ), WORK( J-M ) )350 CONTINUEEND IF360 CONTINUE*IF( UPDATE ) THENIF( I2.LE.N .AND. KBT.GT.0 ) THEN** create nonzero element a(i-kbt+ka+1,i-kbt) outside the* band and store it in WORK(i-kbt)*WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1END IFEND IF*DO 400 K = KB, 1, -1IF( UPDATE ) THENJ2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1ELSEJ2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1END IF** finish applying rotations in 2nd set from the right*DO 370 L = KB - K, 1, -1NRT = ( N-J2+KA+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA,$ AB( KA1-L, J2-KA+1 ), INCA,$ WORK( N+J2-KA ), WORK( J2-KA ), KA1 )370 CONTINUENR = ( N-J2+KA ) / KA1J1 = J2 + ( NR-1 )*KA1DO 380 J = J1, J2, -KA1WORK( J ) = WORK( J-KA )WORK( N+J ) = WORK( N+J-KA )380 CONTINUEDO 390 J = J2, J1, KA1** create nonzero element a(j+1,j-ka) outside the band* and store it in WORK(j)*WORK( J ) = WORK( J )*AB( KA1, J-KA+1 )AB( KA1, J-KA+1 ) = WORK( N+J )*AB( KA1, J-KA+1 )390 CONTINUEIF( UPDATE ) THENIF( I-K.LT.N-KA .AND. K.LE.KBT )$ WORK( I-K+KA ) = WORK( I-K )END IF400 CONTINUE*DO 440 K = KB, 1, -1J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1NR = ( N-J2+KA ) / KA1J1 = J2 + ( NR-1 )*KA1IF( NR.GT.0 ) THEN** generate rotations in 2nd set to annihilate elements* which have been created outside the band*CALL DLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1,$ WORK( N+J2 ), KA1 )** apply rotations in 2nd set from the left*DO 410 L = 1, KA - 1CALL DLARTV( NR, AB( L+1, J2-L ), INCA,$ AB( L+2, J2-L ), INCA, WORK( N+J2 ),$ WORK( J2 ), KA1 )410 CONTINUE** apply rotations in 2nd set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),$ INCA, WORK( N+J2 ), WORK( J2 ), KA1 )*END IF** start applying rotations in 2nd set from the right*DO 420 L = KA - 1, KB - K + 1, -1NRT = ( N-J2+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J2 ), INCA,$ AB( KA1-L, J2+1 ), INCA, WORK( N+J2 ),$ WORK( J2 ), KA1 )420 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 2nd set*DO 430 J = J2, J1, KA1CALL DROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,$ WORK( N+J ), WORK( J ) )430 CONTINUEEND IF440 CONTINUE*DO 460 K = 1, KB - 1J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1** finish applying rotations in 1st set from the right*DO 450 L = KB - K, 1, -1NRT = ( N-J2+L ) / KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J2 ), INCA,$ AB( KA1-L, J2+1 ), INCA, WORK( N+J2-M ),$ WORK( J2-M ), KA1 )450 CONTINUE460 CONTINUE*IF( KB.GT.1 ) THENDO 470 J = N - 1, I - KB + 2*KA + 1, -1WORK( N+J-M ) = WORK( N+J-KA-M )WORK( J-M ) = WORK( J-KA-M )470 CONTINUEEND IF*END IF*GO TO 10*480 CONTINUE** **************************** Phase 2 ******************************* The logical structure of this phase is:** UPDATE = .TRUE.* DO I = 1, M* use S(i) to update A and create a new bulge* apply rotations to push all bulges KA positions upward* END DO* UPDATE = .FALSE.* DO I = M - KA - 1, 2, -1* apply rotations to push all bulges KA positions upward* END DO** To avoid duplicating code, the two loops are merged.*UPDATE = .TRUE.I = 0490 CONTINUEIF( UPDATE ) THENI = I + 1KBT = MIN( KB, M-I )I0 = I + 1I1 = MAX( 1, I-KA )I2 = I + KBT - KA1IF( I.GT.M ) THENUPDATE = .FALSE.I = I - 1I0 = M + 1IF( KA.EQ.0 )$ RETURNGO TO 490END IFELSEI = I - KAIF( I.LT.2 )$ RETURNEND IF*IF( I.LT.M-KBT ) THENNX = MELSENX = NEND IF*IF( UPPER ) THEN** Transform A, working with the upper triangle*IF( UPDATE ) THEN** Form inv(S(i))**T * A * inv(S(i))*BII = BB( KB1, I )DO 500 J = I1, IAB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII500 CONTINUEDO 510 J = I, MIN( N, I+KA )AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII510 CONTINUEDO 540 K = I + 1, I + KBTDO 520 J = K, I + KBTAB( K-J+KA1, J ) = AB( K-J+KA1, J ) -$ BB( I-J+KB1, J )*AB( I-K+KA1, K ) -$ BB( I-K+KB1, K )*AB( I-J+KA1, J ) +$ AB( KA1, I )*BB( I-J+KB1, J )*$ BB( I-K+KB1, K )520 CONTINUEDO 530 J = I + KBT + 1, MIN( N, I+KA )AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -$ BB( I-K+KB1, K )*AB( I-J+KA1, J )530 CONTINUE540 CONTINUEDO 560 J = I1, IDO 550 K = I + 1, MIN( J+KA, I+KBT )AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -$ BB( I-K+KB1, K )*AB( J-I+KA1, I )550 CONTINUE560 CONTINUE*IF( WANTX ) THEN** post-multiply X by inv(S(i))*CALL DSCAL( NX, ONE / BII, X( 1, I ), 1 )IF( KBT.GT.0 )$ CALL DGER( NX, KBT, -ONE, X( 1, I ), 1, BB( KB, I+1 ),$ LDBB-1, X( 1, I+1 ), LDX )END IF** store a(i1,i) in RA1 for use in next loop over K*RA1 = AB( I1-I+KA1, I )END IF** Generate and apply vectors of rotations to chase all the* existing bulges KA positions up toward the top of the band*DO 610 K = 1, KB - 1IF( UPDATE ) THEN** Determine the rotations which would annihilate the bulge* which has in theory just been created*IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN** generate rotation to annihilate a(i+k-ka-1,i)*CALL DLARTG( AB( K+1, I ), RA1, WORK( N+I+K-KA ),$ WORK( I+K-KA ), RA )** create nonzero element a(i+k-ka-1,i+k) outside the* band and store it in WORK(m-kb+i+k)*T = -BB( KB1-K, I+K )*RA1WORK( M-KB+I+K ) = WORK( N+I+K-KA )*T -$ WORK( I+K-KA )*AB( 1, I+K )AB( 1, I+K ) = WORK( I+K-KA )*T +$ WORK( N+I+K-KA )*AB( 1, I+K )RA1 = RAEND IFEND IFJ2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1NR = ( J2+KA-1 ) / KA1J1 = J2 - ( NR-1 )*KA1IF( UPDATE ) THENJ2T = MIN( J2, I-2*KA+K-1 )ELSEJ2T = J2END IFNRT = ( J2T+KA-1 ) / KA1DO 570 J = J1, J2T, KA1** create nonzero element a(j-1,j+ka) outside the band* and store it in WORK(j)*WORK( J ) = WORK( J )*AB( 1, J+KA-1 )AB( 1, J+KA-1 ) = WORK( N+J )*AB( 1, J+KA-1 )570 CONTINUE** generate rotations in 1st set to annihilate elements which* have been created outside the band*IF( NRT.GT.0 )$ CALL DLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1,$ WORK( N+J1 ), KA1 )IF( NR.GT.0 ) THEN** apply rotations in 1st set from the left*DO 580 L = 1, KA - 1CALL DLARTV( NR, AB( KA1-L, J1+L ), INCA,$ AB( KA-L, J1+L ), INCA, WORK( N+J1 ),$ WORK( J1 ), KA1 )580 CONTINUE** apply rotations in 1st set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),$ AB( KA, J1 ), INCA, WORK( N+J1 ),$ WORK( J1 ), KA1 )*END IF** start applying rotations in 1st set from the right*DO 590 L = KA - 1, KB - K + 1, -1NRT = ( J2+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J1T ), INCA,$ AB( L+1, J1T-1 ), INCA, WORK( N+J1T ),$ WORK( J1T ), KA1 )590 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 1st set*DO 600 J = J1, J2, KA1CALL DROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,$ WORK( N+J ), WORK( J ) )600 CONTINUEEND IF610 CONTINUE*IF( UPDATE ) THENIF( I2.GT.0 .AND. KBT.GT.0 ) THEN** create nonzero element a(i+kbt-ka-1,i+kbt) outside the* band and store it in WORK(m-kb+i+kbt)*WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1END IFEND IF*DO 650 K = KB, 1, -1IF( UPDATE ) THENJ2 = I + K + 1 - MAX( 2, K+I0-M )*KA1ELSEJ2 = I + K + 1 - MAX( 1, K+I0-M )*KA1END IF** finish applying rotations in 2nd set from the right*DO 620 L = KB - K, 1, -1NRT = ( J2+KA+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J1T+KA ), INCA,$ AB( L+1, J1T+KA-1 ), INCA,$ WORK( N+M-KB+J1T+KA ),$ WORK( M-KB+J1T+KA ), KA1 )620 CONTINUENR = ( J2+KA-1 ) / KA1J1 = J2 - ( NR-1 )*KA1DO 630 J = J1, J2, KA1WORK( M-KB+J ) = WORK( M-KB+J+KA )WORK( N+M-KB+J ) = WORK( N+M-KB+J+KA )630 CONTINUEDO 640 J = J1, J2, KA1** create nonzero element a(j-1,j+ka) outside the band* and store it in WORK(m-kb+j)*WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 )AB( 1, J+KA-1 ) = WORK( N+M-KB+J )*AB( 1, J+KA-1 )640 CONTINUEIF( UPDATE ) THENIF( I+K.GT.KA1 .AND. K.LE.KBT )$ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )END IF650 CONTINUE*DO 690 K = KB, 1, -1J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1NR = ( J2+KA-1 ) / KA1J1 = J2 - ( NR-1 )*KA1IF( NR.GT.0 ) THEN** generate rotations in 2nd set to annihilate elements* which have been created outside the band*CALL DLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ),$ KA1, WORK( N+M-KB+J1 ), KA1 )** apply rotations in 2nd set from the left*DO 660 L = 1, KA - 1CALL DLARTV( NR, AB( KA1-L, J1+L ), INCA,$ AB( KA-L, J1+L ), INCA,$ WORK( N+M-KB+J1 ), WORK( M-KB+J1 ), KA1 )660 CONTINUE** apply rotations in 2nd set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),$ AB( KA, J1 ), INCA, WORK( N+M-KB+J1 ),$ WORK( M-KB+J1 ), KA1 )*END IF** start applying rotations in 2nd set from the right*DO 670 L = KA - 1, KB - K + 1, -1NRT = ( J2+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J1T ), INCA,$ AB( L+1, J1T-1 ), INCA,$ WORK( N+M-KB+J1T ), WORK( M-KB+J1T ),$ KA1 )670 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 2nd set*DO 680 J = J1, J2, KA1CALL DROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,$ WORK( N+M-KB+J ), WORK( M-KB+J ) )680 CONTINUEEND IF690 CONTINUE*DO 710 K = 1, KB - 1J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1** finish applying rotations in 1st set from the right*DO 700 L = KB - K, 1, -1NRT = ( J2+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L, J1T ), INCA,$ AB( L+1, J1T-1 ), INCA, WORK( N+J1T ),$ WORK( J1T ), KA1 )700 CONTINUE710 CONTINUE*IF( KB.GT.1 ) THENDO 720 J = 2, MIN( I+KB, M ) - 2*KA - 1WORK( N+J ) = WORK( N+J+KA )WORK( J ) = WORK( J+KA )720 CONTINUEEND IF*ELSE** Transform A, working with the lower triangle*IF( UPDATE ) THEN** Form inv(S(i))**T * A * inv(S(i))*BII = BB( 1, I )DO 730 J = I1, IAB( I-J+1, J ) = AB( I-J+1, J ) / BII730 CONTINUEDO 740 J = I, MIN( N, I+KA )AB( J-I+1, I ) = AB( J-I+1, I ) / BII740 CONTINUEDO 770 K = I + 1, I + KBTDO 750 J = K, I + KBTAB( J-K+1, K ) = AB( J-K+1, K ) -$ BB( J-I+1, I )*AB( K-I+1, I ) -$ BB( K-I+1, I )*AB( J-I+1, I ) +$ AB( 1, I )*BB( J-I+1, I )*$ BB( K-I+1, I )750 CONTINUEDO 760 J = I + KBT + 1, MIN( N, I+KA )AB( J-K+1, K ) = AB( J-K+1, K ) -$ BB( K-I+1, I )*AB( J-I+1, I )760 CONTINUE770 CONTINUEDO 790 J = I1, IDO 780 K = I + 1, MIN( J+KA, I+KBT )AB( K-J+1, J ) = AB( K-J+1, J ) -$ BB( K-I+1, I )*AB( I-J+1, J )780 CONTINUE790 CONTINUE*IF( WANTX ) THEN** post-multiply X by inv(S(i))*CALL DSCAL( NX, ONE / BII, X( 1, I ), 1 )IF( KBT.GT.0 )$ CALL DGER( NX, KBT, -ONE, X( 1, I ), 1, BB( 2, I ), 1,$ X( 1, I+1 ), LDX )END IF** store a(i,i1) in RA1 for use in next loop over K*RA1 = AB( I-I1+1, I1 )END IF** Generate and apply vectors of rotations to chase all the* existing bulges KA positions up toward the top of the band*DO 840 K = 1, KB - 1IF( UPDATE ) THEN** Determine the rotations which would annihilate the bulge* which has in theory just been created*IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN** generate rotation to annihilate a(i,i+k-ka-1)*CALL DLARTG( AB( KA1-K, I+K-KA ), RA1,$ WORK( N+I+K-KA ), WORK( I+K-KA ), RA )** create nonzero element a(i+k,i+k-ka-1) outside the* band and store it in WORK(m-kb+i+k)*T = -BB( K+1, I )*RA1WORK( M-KB+I+K ) = WORK( N+I+K-KA )*T -$ WORK( I+K-KA )*AB( KA1, I+K-KA )AB( KA1, I+K-KA ) = WORK( I+K-KA )*T +$ WORK( N+I+K-KA )*AB( KA1, I+K-KA )RA1 = RAEND IFEND IFJ2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1NR = ( J2+KA-1 ) / KA1J1 = J2 - ( NR-1 )*KA1IF( UPDATE ) THENJ2T = MIN( J2, I-2*KA+K-1 )ELSEJ2T = J2END IFNRT = ( J2T+KA-1 ) / KA1DO 800 J = J1, J2T, KA1** create nonzero element a(j+ka,j-1) outside the band* and store it in WORK(j)*WORK( J ) = WORK( J )*AB( KA1, J-1 )AB( KA1, J-1 ) = WORK( N+J )*AB( KA1, J-1 )800 CONTINUE** generate rotations in 1st set to annihilate elements which* have been created outside the band*IF( NRT.GT.0 )$ CALL DLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1,$ WORK( N+J1 ), KA1 )IF( NR.GT.0 ) THEN** apply rotations in 1st set from the right*DO 810 L = 1, KA - 1CALL DLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),$ INCA, WORK( N+J1 ), WORK( J1 ), KA1 )810 CONTINUE** apply rotations in 1st set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),$ AB( 2, J1-1 ), INCA, WORK( N+J1 ),$ WORK( J1 ), KA1 )*END IF** start applying rotations in 1st set from the left*DO 820 L = KA - 1, KB - K + 1, -1NRT = ( J2+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,$ AB( KA1-L, J1T-KA1+L ), INCA,$ WORK( N+J1T ), WORK( J1T ), KA1 )820 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 1st set*DO 830 J = J1, J2, KA1CALL DROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,$ WORK( N+J ), WORK( J ) )830 CONTINUEEND IF840 CONTINUE*IF( UPDATE ) THENIF( I2.GT.0 .AND. KBT.GT.0 ) THEN** create nonzero element a(i+kbt,i+kbt-ka-1) outside the* band and store it in WORK(m-kb+i+kbt)*WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1END IFEND IF*DO 880 K = KB, 1, -1IF( UPDATE ) THENJ2 = I + K + 1 - MAX( 2, K+I0-M )*KA1ELSEJ2 = I + K + 1 - MAX( 1, K+I0-M )*KA1END IF** finish applying rotations in 2nd set from the left*DO 850 L = KB - K, 1, -1NRT = ( J2+KA+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA,$ AB( KA1-L, J1T+L-1 ), INCA,$ WORK( N+M-KB+J1T+KA ),$ WORK( M-KB+J1T+KA ), KA1 )850 CONTINUENR = ( J2+KA-1 ) / KA1J1 = J2 - ( NR-1 )*KA1DO 860 J = J1, J2, KA1WORK( M-KB+J ) = WORK( M-KB+J+KA )WORK( N+M-KB+J ) = WORK( N+M-KB+J+KA )860 CONTINUEDO 870 J = J1, J2, KA1** create nonzero element a(j+ka,j-1) outside the band* and store it in WORK(m-kb+j)*WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 )AB( KA1, J-1 ) = WORK( N+M-KB+J )*AB( KA1, J-1 )870 CONTINUEIF( UPDATE ) THENIF( I+K.GT.KA1 .AND. K.LE.KBT )$ WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )END IF880 CONTINUE*DO 920 K = KB, 1, -1J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1NR = ( J2+KA-1 ) / KA1J1 = J2 - ( NR-1 )*KA1IF( NR.GT.0 ) THEN** generate rotations in 2nd set to annihilate elements* which have been created outside the band*CALL DLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ),$ KA1, WORK( N+M-KB+J1 ), KA1 )** apply rotations in 2nd set from the right*DO 890 L = 1, KA - 1CALL DLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),$ INCA, WORK( N+M-KB+J1 ), WORK( M-KB+J1 ),$ KA1 )890 CONTINUE** apply rotations in 2nd set from both sides to diagonal* blocks*CALL DLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),$ AB( 2, J1-1 ), INCA, WORK( N+M-KB+J1 ),$ WORK( M-KB+J1 ), KA1 )*END IF** start applying rotations in 2nd set from the left*DO 900 L = KA - 1, KB - K + 1, -1NRT = ( J2+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,$ AB( KA1-L, J1T-KA1+L ), INCA,$ WORK( N+M-KB+J1T ), WORK( M-KB+J1T ),$ KA1 )900 CONTINUE*IF( WANTX ) THEN** post-multiply X by product of rotations in 2nd set*DO 910 J = J1, J2, KA1CALL DROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,$ WORK( N+M-KB+J ), WORK( M-KB+J ) )910 CONTINUEEND IF920 CONTINUE*DO 940 K = 1, KB - 1J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1** finish applying rotations in 1st set from the left*DO 930 L = KB - K, 1, -1NRT = ( J2+L-1 ) / KA1J1T = J2 - ( NRT-1 )*KA1IF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,$ AB( KA1-L, J1T-KA1+L ), INCA,$ WORK( N+J1T ), WORK( J1T ), KA1 )930 CONTINUE940 CONTINUE*IF( KB.GT.1 ) THENDO 950 J = 2, MIN( I+KB, M ) - 2*KA - 1WORK( N+J ) = WORK( N+J+KA )WORK( J ) = WORK( J+KA )950 CONTINUEEND IF*END IF*GO TO 490** End of DSBGST*END*> \brief \b DSBGV** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBGV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbgv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbgv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbgv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBGV( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W, Z,* LDZ, WORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, KA, KB, LDAB, LDBB, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), W( * ),* $ WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBGV computes all the eigenvalues, and optionally, the eigenvectors*> of a real generalized symmetric-definite banded eigenproblem, of*> the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric*> and banded, and B is also positive definite.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] KA*> \verbatim*> KA is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KA >= 0.*> \endverbatim*>*> \param[in] KB*> \verbatim*> KB is INTEGER*> The number of superdiagonals of the matrix B if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KB >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first ka+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).*>*> On exit, the contents of AB are destroyed.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KA+1.*> \endverbatim*>*> \param[in,out] BB*> \verbatim*> BB is DOUBLE PRECISION array, dimension (LDBB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix B, stored in the first kb+1 rows of the array. The*> j-th column of B is stored in the j-th column of the array BB*> as follows:*> if UPLO = 'U', BB(kb+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;*> if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).*>*> On exit, the factor S from the split Cholesky factorization*> B = S**T*S, as returned by DPBSTF.*> \endverbatim*>*> \param[in] LDBB*> \verbatim*> LDBB is INTEGER*> The leading dimension of the array BB. LDBB >= KB+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of*> eigenvectors, with the i-th column of Z holding the*> eigenvector associated with W(i). The eigenvectors are*> normalized so that Z**T*B*Z = I.*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is:*> <= N: the algorithm failed to converge:*> i off-diagonal elements of an intermediate*> tridiagonal form did not converge to zero;*> > N: if INFO = N + i, for 1 <= i <= N, then DPBSTF*> returned INFO = i: B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSBGV( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W, Z,$ LDZ, WORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, KA, KB, LDAB, LDBB, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), W( * ),$ WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL UPPER, WANTZCHARACTER VECTINTEGER IINFO, INDE, INDWRK* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPBSTF, DSBGST, DSBTRD, DSTEQR, DSTERF, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KA.LT.0 ) THENINFO = -4ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THENINFO = -5ELSE IF( LDAB.LT.KA+1 ) THENINFO = -7ELSE IF( LDBB.LT.KB+1 ) THENINFO = -9ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSBGV ', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form a split Cholesky factorization of B.*CALL DPBSTF( UPLO, N, KB, BB, LDBB, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem.*INDE = 1INDWRK = INDE + NCALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,$ WORK( INDWRK ), IINFO )** Reduce to tridiagonal form.*IF( WANTZ ) THENVECT = 'U'ELSEVECT = 'N'END IFCALL DSBTRD( VECT, UPLO, N, KA, AB, LDAB, W, WORK( INDE ), Z, LDZ,$ WORK( INDWRK ), IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, call SSTEQR.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DSTEQR( JOBZ, N, W, WORK( INDE ), Z, LDZ, WORK( INDWRK ),$ INFO )END IFRETURN** End of DSBGV*END*> \brief \b DSBGVD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBGVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbgvd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbgvd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbgvd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBGVD( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W,* Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, KA, KB, LDAB, LDBB, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), W( * ),* $ WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBGVD computes all the eigenvalues, and optionally, the eigenvectors*> of a real generalized symmetric-definite banded eigenproblem, of the*> form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric and*> banded, and B is also positive definite. If eigenvectors are*> desired, it uses a divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] KA*> \verbatim*> KA is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KA >= 0.*> \endverbatim*>*> \param[in] KB*> \verbatim*> KB is INTEGER*> The number of superdiagonals of the matrix B if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KB >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first ka+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).*>*> On exit, the contents of AB are destroyed.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KA+1.*> \endverbatim*>*> \param[in,out] BB*> \verbatim*> BB is DOUBLE PRECISION array, dimension (LDBB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix B, stored in the first kb+1 rows of the array. The*> j-th column of B is stored in the j-th column of the array BB*> as follows:*> if UPLO = 'U', BB(ka+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;*> if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).*>*> On exit, the factor S from the split Cholesky factorization*> B = S**T*S, as returned by DPBSTF.*> \endverbatim*>*> \param[in] LDBB*> \verbatim*> LDBB is INTEGER*> The leading dimension of the array BB. LDBB >= KB+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of*> eigenvectors, with the i-th column of Z holding the*> eigenvector associated with W(i). The eigenvectors are*> normalized so Z**T*B*Z = I.*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N <= 1, LWORK >= 1.*> If JOBZ = 'N' and N > 1, LWORK >= 2*N.*> If JOBZ = 'V' and N > 1, LWORK >= 1 + 5*N + 2*N**2.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if LIWORK > 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If JOBZ = 'N' or N <= 1, LIWORK >= 1.*> If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is:*> <= N: the algorithm failed to converge:*> i off-diagonal elements of an intermediate*> tridiagonal form did not converge to zero;*> > N: if INFO = N + i, for 1 <= i <= N, then DPBSTF*> returned INFO = i: B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA** =====================================================================SUBROUTINE DSBGVD( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, W,$ Z, LDZ, WORK, LWORK, IWORK, LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, KA, KB, LDAB, LDBB, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), W( * ),$ WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPER, WANTZCHARACTER VECTINTEGER IINFO, INDE, INDWK2, INDWRK, LIWMIN, LLWRK2,$ LWMIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMM, DLACPY, DPBSTF, DSBGST, DSBTRD, DSTEDC,$ DSTERF, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0IF( N.LE.1 ) THENLIWMIN = 1LWMIN = 1ELSE IF( WANTZ ) THENLIWMIN = 3 + 5*NLWMIN = 1 + 5*N + 2*N**2ELSELIWMIN = 1LWMIN = 2*NEND IF*IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KA.LT.0 ) THENINFO = -4ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THENINFO = -5ELSE IF( LDAB.LT.KA+1 ) THENINFO = -7ELSE IF( LDBB.LT.KB+1 ) THENINFO = -9ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -12END IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -14ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -16END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSBGVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form a split Cholesky factorization of B.*CALL DPBSTF( UPLO, N, KB, BB, LDBB, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem.*INDE = 1INDWRK = INDE + NINDWK2 = INDWRK + N*NLLWRK2 = LWORK - INDWK2 + 1CALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Z, LDZ,$ WORK, IINFO )** Reduce to tridiagonal form.*IF( WANTZ ) THENVECT = 'U'ELSEVECT = 'N'END IFCALL DSBTRD( VECT, UPLO, N, KA, AB, LDAB, W, WORK( INDE ), Z, LDZ,$ WORK( INDWRK ), IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, call SSTEDC.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,$ WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )CALL DGEMM( 'N', 'N', N, N, N, ONE, Z, LDZ, WORK( INDWRK ), N,$ ZERO, WORK( INDWK2 ), N )CALL DLACPY( 'A', N, N, WORK( INDWK2 ), N, Z, LDZ )END IF*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DSBGVD*END*> \brief \b DSBGVX** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBGVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbgvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbgvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbgvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBGVX( JOBZ, RANGE, UPLO, N, KA, KB, AB, LDAB, BB,* LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,* LDZ, WORK, IWORK, IFAIL, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, IU, KA, KB, LDAB, LDBB, LDQ, LDZ, M,* $ N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), Q( LDQ, * ),* $ W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBGVX computes selected eigenvalues, and optionally, eigenvectors*> of a real generalized symmetric-definite banded eigenproblem, of*> the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric*> and banded, and B is also positive definite. Eigenvalues and*> eigenvectors can be selected by specifying either all eigenvalues,*> a range of values or a range of indices for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] KA*> \verbatim*> KA is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KA >= 0.*> \endverbatim*>*> \param[in] KB*> \verbatim*> KB is INTEGER*> The number of superdiagonals of the matrix B if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KB >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first ka+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).*>*> On exit, the contents of AB are destroyed.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KA+1.*> \endverbatim*>*> \param[in,out] BB*> \verbatim*> BB is DOUBLE PRECISION array, dimension (LDBB, N)*> On entry, the upper or lower triangle of the symmetric band*> matrix B, stored in the first kb+1 rows of the array. The*> j-th column of B is stored in the j-th column of the array BB*> as follows:*> if UPLO = 'U', BB(ka+1+i-j,j) = B(i,j) for max(1,j-kb)<=i<=j;*> if UPLO = 'L', BB(1+i-j,j) = B(i,j) for j<=i<=min(n,j+kb).*>*> On exit, the factor S from the split Cholesky factorization*> B = S**T*S, as returned by DPBSTF.*> \endverbatim*>*> \param[in] LDBB*> \verbatim*> LDBB is INTEGER*> The leading dimension of the array BB. LDBB >= KB+1.*> \endverbatim*>*> \param[out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ, N)*> If JOBZ = 'V', the n-by-n matrix used in the reduction of*> A*x = (lambda)*B*x to standard form, i.e. C*x = (lambda)*x,*> and consequently C to tridiagonal form.*> If JOBZ = 'N', the array Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. If JOBZ = 'N',*> LDQ >= 1. If JOBZ = 'V', LDQ >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*>*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*>*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*>*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*>*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing A to tridiagonal form.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of*> eigenvectors, with the i-th column of Z holding the*> eigenvector associated with W(i). The eigenvectors are*> normalized so Z**T*B*Z = I.*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (7*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (M)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvalues that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0 : successful exit*> < 0 : if INFO = -i, the i-th argument had an illegal value*> <= N: if INFO = i, then i eigenvectors failed to converge.*> Their indices are stored in IFAIL.*> > N : DPBSTF returned an error code; i.e.,*> if INFO = N + i, for 1 <= i <= N, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA** =====================================================================SUBROUTINE DSBGVX( JOBZ, RANGE, UPLO, N, KA, KB, AB, LDAB, BB,$ LDBB, Q, LDQ, VL, VU, IL, IU, ABSTOL, M, W, Z,$ LDZ, WORK, IWORK, IFAIL, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, IU, KA, KB, LDAB, LDBB, LDQ, LDZ, M,$ NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION AB( LDAB, * ), BB( LDBB, * ), Q( LDQ, * ),$ W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, TEST, UPPER, VALEIG, WANTZCHARACTER ORDER, VECTINTEGER I, IINFO, INDD, INDE, INDEE, INDIBL, INDISP,$ INDIWO, INDWRK, ITMP1, J, JJ, NSPLITDOUBLE PRECISION TMP1* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DGEMV, DLACPY, DPBSTF, DSBGST, DSBTRD,$ DSTEBZ, DSTEIN, DSTEQR, DSTERF, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( KA.LT.0 ) THENINFO = -5ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THENINFO = -6ELSE IF( LDAB.LT.KA+1 ) THENINFO = -8ELSE IF( LDBB.LT.KB+1 ) THENINFO = -10ELSE IF( LDQ.LT.1 .OR. ( WANTZ .AND. LDQ.LT.N ) ) THENINFO = -12ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -14ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -15ELSE IF ( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -16END IFEND IFEND IFIF( INFO.EQ.0) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -21END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSBGVX', -INFO )RETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN** Form a split Cholesky factorization of B.*CALL DPBSTF( UPLO, N, KB, BB, LDBB, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem.*CALL DSBGST( JOBZ, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, Q, LDQ,$ WORK, IINFO )** Reduce symmetric band matrix to tridiagonal form.*INDD = 1INDE = INDD + NINDWRK = INDE + NIF( WANTZ ) THENVECT = 'U'ELSEVECT = 'N'END IFCALL DSBTRD( VECT, UPLO, N, KA, AB, LDAB, WORK( INDD ),$ WORK( INDE ), Q, LDQ, WORK( INDWRK ), IINFO )** If all eigenvalues are desired and ABSTOL is less than or equal* to zero, then call DSTERF or SSTEQR. If this fails for some* eigenvalue, then try DSTEBZ.*TEST = .FALSE.IF( INDEIG ) THENIF( IL.EQ.1 .AND. IU.EQ.N ) THENTEST = .TRUE.END IFEND IFIF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THENCALL DCOPY( N, WORK( INDD ), 1, W, 1 )INDEE = INDWRK + 2*NCALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDEE ), INFO )ELSECALL DLACPY( 'A', N, N, Q, LDQ, Z, LDZ )CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,$ WORK( INDWRK ), INFO )IF( INFO.EQ.0 ) THENDO 10 I = 1, NIFAIL( I ) = 010 CONTINUEEND IFEND IFIF( INFO.EQ.0 ) THENM = NGO TO 30END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired,* call DSTEIN.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFINDIBL = 1INDISP = INDIBL + NINDIWO = INDISP + NCALL DSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL,$ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,$ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),$ IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,$ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,$ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )** Apply transformation matrix used in reduction to tridiagonal* form to eigenvectors returned by DSTEIN.*DO 20 J = 1, MCALL DCOPY( N, Z( 1, J ), 1, WORK( 1 ), 1 )CALL DGEMV( 'N', N, N, ONE, Q, LDQ, WORK, 1, ZERO,$ Z( 1, J ), 1 )20 CONTINUEEND IF*30 CONTINUE** If eigenvalues are not in order, then sort them, along with* eigenvectors.*IF( WANTZ ) THENDO 50 J = 1, M - 1I = 0TMP1 = W( J )DO 40 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF40 CONTINUE*IF( I.NE.0 ) THENITMP1 = IWORK( INDIBL+I-1 )W( I ) = W( J )IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )W( J ) = TMP1IWORK( INDIBL+J-1 ) = ITMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )IF( INFO.NE.0 ) THENITMP1 = IFAIL( I )IFAIL( I ) = IFAIL( J )IFAIL( J ) = ITMP1END IFEND IF50 CONTINUEEND IF*RETURN** End of DSBGVX*END*> \brief \b DSBTRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSBTRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsbtrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsbtrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsbtrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSBTRD( VECT, UPLO, N, KD, AB, LDAB, D, E, Q, LDQ,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO, VECT* INTEGER INFO, KD, LDAB, LDQ, N* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), D( * ), E( * ), Q( LDQ, * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSBTRD reduces a real symmetric band matrix A to symmetric*> tridiagonal form T by an orthogonal similarity transformation:*> Q**T * A * Q = T.*> \endverbatim** Arguments:* ==========**> \param[in] VECT*> \verbatim*> VECT is CHARACTER*1*> = 'N': do not form Q;*> = 'V': form Q;*> = 'U': update a matrix X, by forming X*Q.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals of the matrix A if UPLO = 'U',*> or the number of subdiagonals if UPLO = 'L'. KD >= 0.*> \endverbatim*>*> \param[in,out] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> On entry, the upper or lower triangle of the symmetric band*> matrix A, stored in the first KD+1 rows of the array. The*> j-th column of A is stored in the j-th column of the array AB*> as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> On exit, the diagonal elements of AB are overwritten by the*> diagonal elements of the tridiagonal matrix T; if KD > 0, the*> elements on the first superdiagonal (if UPLO = 'U') or the*> first subdiagonal (if UPLO = 'L') are overwritten by the*> off-diagonal elements of T; the rest of AB is overwritten by*> values generated during the reduction.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The off-diagonal elements of the tridiagonal matrix T:*> E(i) = T(i,i+1) if UPLO = 'U'; E(i) = T(i+1,i) if UPLO = 'L'.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if VECT = 'U', then Q must contain an N-by-N*> matrix X; if VECT = 'N' or 'V', then Q need not be set.*>*> On exit:*> if VECT = 'V', Q contains the N-by-N orthogonal matrix Q;*> if VECT = 'U', Q contains the product X*Q;*> if VECT = 'N', the array Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q.*> LDQ >= 1, and LDQ >= N if VECT = 'V' or 'U'.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> Modified by Linda Kaufman, Bell Labs.*> \endverbatim*>* =====================================================================SUBROUTINE DSBTRD( VECT, UPLO, N, KD, AB, LDAB, D, E, Q, LDQ,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLO, VECTINTEGER INFO, KD, LDAB, LDQ, N* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), D( * ), E( * ), Q( LDQ, * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL INITQ, UPPER, WANTQINTEGER I, I2, IBL, INCA, INCX, IQAEND, IQB, IQEND, J,$ J1, J1END, J1INC, J2, JEND, JIN, JINC, K, KD1,$ KDM1, KDN, L, LAST, LEND, NQ, NR, NRTDOUBLE PRECISION TEMP* ..* .. External Subroutines ..EXTERNAL DLAR2V, DLARGV, DLARTG, DLARTV, DLASET, DROT,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Test the input parameters*INITQ = LSAME( VECT, 'V' )WANTQ = INITQ .OR. LSAME( VECT, 'U' )UPPER = LSAME( UPLO, 'U' )KD1 = KD + 1KDM1 = KD - 1INCX = LDAB - 1IQEND = 1*INFO = 0IF( .NOT.WANTQ .AND. .NOT.LSAME( VECT, 'N' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( KD.LT.0 ) THENINFO = -4ELSE IF( LDAB.LT.KD1 ) THENINFO = -6ELSE IF( LDQ.LT.MAX( 1, N ) .AND. WANTQ ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSBTRD', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Initialize Q to the unit matrix, if needed*IF( INITQ )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )** Wherever possible, plane rotations are generated and applied in* vector operations of length NR over the index set J1:J2:KD1.** The cosines and sines of the plane rotations are stored in the* arrays D and WORK.*INCA = KD1*LDABKDN = MIN( N-1, KD )IF( UPPER ) THEN*IF( KD.GT.1 ) THEN** Reduce to tridiagonal form, working with upper triangle*NR = 0J1 = KDN + 2J2 = 1*DO 90 I = 1, N - 2** Reduce i-th row of matrix to tridiagonal form*DO 80 K = KDN + 1, 2, -1J1 = J1 + KDNJ2 = J2 + KDN*IF( NR.GT.0 ) THEN** generate plane rotations to annihilate nonzero* elements which have been created outside the band*CALL DLARGV( NR, AB( 1, J1-1 ), INCA, WORK( J1 ),$ KD1, D( J1 ), KD1 )** apply rotations from the right*** Dependent on the the number of diagonals either* DLARTV or DROT is used*IF( NR.GE.2*KD-1 ) THENDO 10 L = 1, KD - 1CALL DLARTV( NR, AB( L+1, J1-1 ), INCA,$ AB( L, J1 ), INCA, D( J1 ),$ WORK( J1 ), KD1 )10 CONTINUE*ELSEJEND = J1 + ( NR-1 )*KD1DO 20 JINC = J1, JEND, KD1CALL DROT( KDM1, AB( 2, JINC-1 ), 1,$ AB( 1, JINC ), 1, D( JINC ),$ WORK( JINC ) )20 CONTINUEEND IFEND IF**IF( K.GT.2 ) THENIF( K.LE.N-I+1 ) THEN** generate plane rotation to annihilate a(i,i+k-1)* within the band*CALL DLARTG( AB( KD-K+3, I+K-2 ),$ AB( KD-K+2, I+K-1 ), D( I+K-1 ),$ WORK( I+K-1 ), TEMP )AB( KD-K+3, I+K-2 ) = TEMP** apply rotation from the right*CALL DROT( K-3, AB( KD-K+4, I+K-2 ), 1,$ AB( KD-K+3, I+K-1 ), 1, D( I+K-1 ),$ WORK( I+K-1 ) )END IFNR = NR + 1J1 = J1 - KDN - 1END IF** apply plane rotations from both sides to diagonal* blocks*IF( NR.GT.0 )$ CALL DLAR2V( NR, AB( KD1, J1-1 ), AB( KD1, J1 ),$ AB( KD, J1 ), INCA, D( J1 ),$ WORK( J1 ), KD1 )** apply plane rotations from the left*IF( NR.GT.0 ) THENIF( 2*KD-1.LT.NR ) THEN** Dependent on the the number of diagonals either* DLARTV or DROT is used*DO 30 L = 1, KD - 1IF( J2+L.GT.N ) THENNRT = NR - 1ELSENRT = NREND IFIF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( KD-L, J1+L ), INCA,$ AB( KD-L+1, J1+L ), INCA,$ D( J1 ), WORK( J1 ), KD1 )30 CONTINUEELSEJ1END = J1 + KD1*( NR-2 )IF( J1END.GE.J1 ) THENDO 40 JIN = J1, J1END, KD1CALL DROT( KD-1, AB( KD-1, JIN+1 ), INCX,$ AB( KD, JIN+1 ), INCX,$ D( JIN ), WORK( JIN ) )40 CONTINUEEND IFLEND = MIN( KDM1, N-J2 )LAST = J1END + KD1IF( LEND.GT.0 )$ CALL DROT( LEND, AB( KD-1, LAST+1 ), INCX,$ AB( KD, LAST+1 ), INCX, D( LAST ),$ WORK( LAST ) )END IFEND IF*IF( WANTQ ) THEN** accumulate product of plane rotations in Q*IF( INITQ ) THEN** take advantage of the fact that Q was* initially the Identity matrix*IQEND = MAX( IQEND, J2 )I2 = MAX( 0, K-3 )IQAEND = 1 + I*KDIF( K.EQ.2 )$ IQAEND = IQAEND + KDIQAEND = MIN( IQAEND, IQEND )DO 50 J = J1, J2, KD1IBL = I - I2 / KDM1I2 = I2 + 1IQB = MAX( 1, J-IBL )NQ = 1 + IQAEND - IQBIQAEND = MIN( IQAEND+KD, IQEND )CALL DROT( NQ, Q( IQB, J-1 ), 1, Q( IQB, J ),$ 1, D( J ), WORK( J ) )50 CONTINUEELSE*DO 60 J = J1, J2, KD1CALL DROT( N, Q( 1, J-1 ), 1, Q( 1, J ), 1,$ D( J ), WORK( J ) )60 CONTINUEEND IF*END IF*IF( J2+KDN.GT.N ) THEN** adjust J2 to keep within the bounds of the matrix*NR = NR - 1J2 = J2 - KDN - 1END IF*DO 70 J = J1, J2, KD1** create nonzero element a(j-1,j+kd) outside the band* and store it in WORK*WORK( J+KD ) = WORK( J )*AB( 1, J+KD )AB( 1, J+KD ) = D( J )*AB( 1, J+KD )70 CONTINUE80 CONTINUE90 CONTINUEEND IF*IF( KD.GT.0 ) THEN** copy off-diagonal elements to E*DO 100 I = 1, N - 1E( I ) = AB( KD, I+1 )100 CONTINUEELSE** set E to zero if original matrix was diagonal*DO 110 I = 1, N - 1E( I ) = ZERO110 CONTINUEEND IF** copy diagonal elements to D*DO 120 I = 1, ND( I ) = AB( KD1, I )120 CONTINUE*ELSE*IF( KD.GT.1 ) THEN** Reduce to tridiagonal form, working with lower triangle*NR = 0J1 = KDN + 2J2 = 1*DO 210 I = 1, N - 2** Reduce i-th column of matrix to tridiagonal form*DO 200 K = KDN + 1, 2, -1J1 = J1 + KDNJ2 = J2 + KDN*IF( NR.GT.0 ) THEN** generate plane rotations to annihilate nonzero* elements which have been created outside the band*CALL DLARGV( NR, AB( KD1, J1-KD1 ), INCA,$ WORK( J1 ), KD1, D( J1 ), KD1 )** apply plane rotations from one side*** Dependent on the the number of diagonals either* DLARTV or DROT is used*IF( NR.GT.2*KD-1 ) THENDO 130 L = 1, KD - 1CALL DLARTV( NR, AB( KD1-L, J1-KD1+L ), INCA,$ AB( KD1-L+1, J1-KD1+L ), INCA,$ D( J1 ), WORK( J1 ), KD1 )130 CONTINUEELSEJEND = J1 + KD1*( NR-1 )DO 140 JINC = J1, JEND, KD1CALL DROT( KDM1, AB( KD, JINC-KD ), INCX,$ AB( KD1, JINC-KD ), INCX,$ D( JINC ), WORK( JINC ) )140 CONTINUEEND IF*END IF*IF( K.GT.2 ) THENIF( K.LE.N-I+1 ) THEN** generate plane rotation to annihilate a(i+k-1,i)* within the band*CALL DLARTG( AB( K-1, I ), AB( K, I ),$ D( I+K-1 ), WORK( I+K-1 ), TEMP )AB( K-1, I ) = TEMP** apply rotation from the left*CALL DROT( K-3, AB( K-2, I+1 ), LDAB-1,$ AB( K-1, I+1 ), LDAB-1, D( I+K-1 ),$ WORK( I+K-1 ) )END IFNR = NR + 1J1 = J1 - KDN - 1END IF** apply plane rotations from both sides to diagonal* blocks*IF( NR.GT.0 )$ CALL DLAR2V( NR, AB( 1, J1-1 ), AB( 1, J1 ),$ AB( 2, J1-1 ), INCA, D( J1 ),$ WORK( J1 ), KD1 )** apply plane rotations from the right*** Dependent on the the number of diagonals either* DLARTV or DROT is used*IF( NR.GT.0 ) THENIF( NR.GT.2*KD-1 ) THENDO 150 L = 1, KD - 1IF( J2+L.GT.N ) THENNRT = NR - 1ELSENRT = NREND IFIF( NRT.GT.0 )$ CALL DLARTV( NRT, AB( L+2, J1-1 ), INCA,$ AB( L+1, J1 ), INCA, D( J1 ),$ WORK( J1 ), KD1 )150 CONTINUEELSEJ1END = J1 + KD1*( NR-2 )IF( J1END.GE.J1 ) THENDO 160 J1INC = J1, J1END, KD1CALL DROT( KDM1, AB( 3, J1INC-1 ), 1,$ AB( 2, J1INC ), 1, D( J1INC ),$ WORK( J1INC ) )160 CONTINUEEND IFLEND = MIN( KDM1, N-J2 )LAST = J1END + KD1IF( LEND.GT.0 )$ CALL DROT( LEND, AB( 3, LAST-1 ), 1,$ AB( 2, LAST ), 1, D( LAST ),$ WORK( LAST ) )END IFEND IF***IF( WANTQ ) THEN** accumulate product of plane rotations in Q*IF( INITQ ) THEN** take advantage of the fact that Q was* initially the Identity matrix*IQEND = MAX( IQEND, J2 )I2 = MAX( 0, K-3 )IQAEND = 1 + I*KDIF( K.EQ.2 )$ IQAEND = IQAEND + KDIQAEND = MIN( IQAEND, IQEND )DO 170 J = J1, J2, KD1IBL = I - I2 / KDM1I2 = I2 + 1IQB = MAX( 1, J-IBL )NQ = 1 + IQAEND - IQBIQAEND = MIN( IQAEND+KD, IQEND )CALL DROT( NQ, Q( IQB, J-1 ), 1, Q( IQB, J ),$ 1, D( J ), WORK( J ) )170 CONTINUEELSE*DO 180 J = J1, J2, KD1CALL DROT( N, Q( 1, J-1 ), 1, Q( 1, J ), 1,$ D( J ), WORK( J ) )180 CONTINUEEND IFEND IF*IF( J2+KDN.GT.N ) THEN** adjust J2 to keep within the bounds of the matrix*NR = NR - 1J2 = J2 - KDN - 1END IF*DO 190 J = J1, J2, KD1** create nonzero element a(j+kd,j-1) outside the* band and store it in WORK*WORK( J+KD ) = WORK( J )*AB( KD1, J )AB( KD1, J ) = D( J )*AB( KD1, J )190 CONTINUE200 CONTINUE210 CONTINUEEND IF*IF( KD.GT.0 ) THEN** copy off-diagonal elements to E*DO 220 I = 1, N - 1E( I ) = AB( 2, I )220 CONTINUEELSE** set E to zero if original matrix was diagonal*DO 230 I = 1, N - 1E( I ) = ZERO230 CONTINUEEND IF** copy diagonal elements to D*DO 240 I = 1, ND( I ) = AB( 1, I )240 CONTINUEEND IF*RETURN** End of DSBTRD*END*> \brief \b DSFRK performs a symmetric rank-k operation for matrix in RFP format.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSFRK + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsfrk.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsfrk.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsfrk.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSFRK( TRANSR, UPLO, TRANS, N, K, ALPHA, A, LDA, BETA,* C )** .. Scalar Arguments ..* DOUBLE PRECISION ALPHA, BETA* INTEGER K, LDA, N* CHARACTER TRANS, TRANSR, UPLO* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), C( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Level 3 BLAS like routine for C in RFP Format.*>*> DSFRK performs one of the symmetric rank--k operations*>*> C := alpha*A*A**T + beta*C,*>*> or*>*> C := alpha*A**T*A + beta*C,*>*> where alpha and beta are real scalars, C is an n--by--n symmetric*> matrix and A is an n--by--k matrix in the first case and a k--by--n*> matrix in the second case.*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': The Normal Form of RFP A is stored;*> = 'T': The Transpose Form of RFP A is stored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> On entry, UPLO specifies whether the upper or lower*> triangular part of the array C is to be referenced as*> follows:*>*> UPLO = 'U' or 'u' Only the upper triangular part of C*> is to be referenced.*>*> UPLO = 'L' or 'l' Only the lower triangular part of C*> is to be referenced.*>*> Unchanged on exit.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> On entry, TRANS specifies the operation to be performed as*> follows:*>*> TRANS = 'N' or 'n' C := alpha*A*A**T + beta*C.*>*> TRANS = 'T' or 't' C := alpha*A**T*A + beta*C.*>*> Unchanged on exit.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> On entry, N specifies the order of the matrix C. N must be*> at least zero.*> Unchanged on exit.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> On entry with TRANS = 'N' or 'n', K specifies the number*> of columns of the matrix A, and on entry with TRANS = 'T'*> or 't', K specifies the number of rows of the matrix A. K*> must be at least zero.*> Unchanged on exit.*> \endverbatim*>*> \param[in] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> On entry, ALPHA specifies the scalar alpha.*> Unchanged on exit.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,ka)*> where KA*> is K when TRANS = 'N' or 'n', and is N otherwise. Before*> entry with TRANS = 'N' or 'n', the leading N--by--K part of*> the array A must contain the matrix A, otherwise the leading*> K--by--N part of the array A must contain the matrix A.*> Unchanged on exit.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> On entry, LDA specifies the first dimension of A as declared*> in the calling (sub) program. When TRANS = 'N' or 'n'*> then LDA must be at least max( 1, n ), otherwise LDA must*> be at least max( 1, k ).*> Unchanged on exit.*> \endverbatim*>*> \param[in] BETA*> \verbatim*> BETA is DOUBLE PRECISION*> On entry, BETA specifies the scalar beta.*> Unchanged on exit.*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (NT)*> NT = N*(N+1)/2. On entry, the symmetric matrix C in RFP*> Format. RFP Format is described by TRANSR, UPLO and N.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSFRK( TRANSR, UPLO, TRANS, N, K, ALPHA, A, LDA, BETA,$ C )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..DOUBLE PRECISION ALPHA, BETAINTEGER K, LDA, NCHARACTER TRANS, TRANSR, UPLO* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), C( * )* ..** =====================================================================** ..* .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, NORMALTRANSR, NISODD, NOTRANSINTEGER INFO, NROWA, J, NK, N1, N2* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DGEMM, DSYRK* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )NOTRANS = LSAME( TRANS, 'N' )*IF( NOTRANS ) THENNROWA = NELSENROWA = KEND IF*IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( .NOT.NOTRANS .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, NROWA ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSFRK ', -INFO )RETURNEND IF** Quick return if possible.** The quick return case: ((ALPHA.EQ.0).AND.(BETA.NE.ZERO)) is not* done (it is in DSYRK for example) and left in the general case.*IF( ( N.EQ.0 ) .OR. ( ( ( ALPHA.EQ.ZERO ) .OR. ( K.EQ.0 ) ) .AND.$ ( BETA.EQ.ONE ) ) )RETURN*IF( ( ALPHA.EQ.ZERO ) .AND. ( BETA.EQ.ZERO ) ) THENDO J = 1, ( ( N*( N+1 ) ) / 2 )C( J ) = ZEROEND DORETURNEND IF** C is N-by-N.* If N is odd, set NISODD = .TRUE., and N1 and N2.* If N is even, NISODD = .FALSE., and NK.*IF( MOD( N, 2 ).EQ.0 ) THENNISODD = .FALSE.NK = N / 2ELSENISODD = .TRUE.IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IFEND IF*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** N is odd, TRANSR = 'N', and UPLO = 'L'*IF( NOTRANS ) THEN** N is odd, TRANSR = 'N', UPLO = 'L', and TRANS = 'N'*CALL DSYRK( 'L', 'N', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( 1 ), N )CALL DSYRK( 'U', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA,$ BETA, C( N+1 ), N )CALL DGEMM( 'N', 'T', N2, N1, K, ALPHA, A( N1+1, 1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( N1+1 ), N )*ELSE** N is odd, TRANSR = 'N', UPLO = 'L', and TRANS = 'T'*CALL DSYRK( 'L', 'T', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( 1 ), N )CALL DSYRK( 'U', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA,$ BETA, C( N+1 ), N )CALL DGEMM( 'T', 'N', N2, N1, K, ALPHA, A( 1, N1+1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( N1+1 ), N )*END IF*ELSE** N is odd, TRANSR = 'N', and UPLO = 'U'*IF( NOTRANS ) THEN** N is odd, TRANSR = 'N', UPLO = 'U', and TRANS = 'N'*CALL DSYRK( 'L', 'N', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( N2+1 ), N )CALL DSYRK( 'U', 'N', N2, K, ALPHA, A( N2, 1 ), LDA,$ BETA, C( N1+1 ), N )CALL DGEMM( 'N', 'T', N1, N2, K, ALPHA, A( 1, 1 ),$ LDA, A( N2, 1 ), LDA, BETA, C( 1 ), N )*ELSE** N is odd, TRANSR = 'N', UPLO = 'U', and TRANS = 'T'*CALL DSYRK( 'L', 'T', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( N2+1 ), N )CALL DSYRK( 'U', 'T', N2, K, ALPHA, A( 1, N2 ), LDA,$ BETA, C( N1+1 ), N )CALL DGEMM( 'T', 'N', N1, N2, K, ALPHA, A( 1, 1 ),$ LDA, A( 1, N2 ), LDA, BETA, C( 1 ), N )*END IF*END IF*ELSE** N is odd, and TRANSR = 'T'*IF( LOWER ) THEN** N is odd, TRANSR = 'T', and UPLO = 'L'*IF( NOTRANS ) THEN** N is odd, TRANSR = 'T', UPLO = 'L', and TRANS = 'N'*CALL DSYRK( 'U', 'N', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( 1 ), N1 )CALL DSYRK( 'L', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA,$ BETA, C( 2 ), N1 )CALL DGEMM( 'N', 'T', N1, N2, K, ALPHA, A( 1, 1 ),$ LDA, A( N1+1, 1 ), LDA, BETA,$ C( N1*N1+1 ), N1 )*ELSE** N is odd, TRANSR = 'T', UPLO = 'L', and TRANS = 'T'*CALL DSYRK( 'U', 'T', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( 1 ), N1 )CALL DSYRK( 'L', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA,$ BETA, C( 2 ), N1 )CALL DGEMM( 'T', 'N', N1, N2, K, ALPHA, A( 1, 1 ),$ LDA, A( 1, N1+1 ), LDA, BETA,$ C( N1*N1+1 ), N1 )*END IF*ELSE** N is odd, TRANSR = 'T', and UPLO = 'U'*IF( NOTRANS ) THEN** N is odd, TRANSR = 'T', UPLO = 'U', and TRANS = 'N'*CALL DSYRK( 'U', 'N', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( N2*N2+1 ), N2 )CALL DSYRK( 'L', 'N', N2, K, ALPHA, A( N1+1, 1 ), LDA,$ BETA, C( N1*N2+1 ), N2 )CALL DGEMM( 'N', 'T', N2, N1, K, ALPHA, A( N1+1, 1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( 1 ), N2 )*ELSE** N is odd, TRANSR = 'T', UPLO = 'U', and TRANS = 'T'*CALL DSYRK( 'U', 'T', N1, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( N2*N2+1 ), N2 )CALL DSYRK( 'L', 'T', N2, K, ALPHA, A( 1, N1+1 ), LDA,$ BETA, C( N1*N2+1 ), N2 )CALL DGEMM( 'T', 'N', N2, N1, K, ALPHA, A( 1, N1+1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( 1 ), N2 )*END IF*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** N is even, TRANSR = 'N', and UPLO = 'L'*IF( NOTRANS ) THEN** N is even, TRANSR = 'N', UPLO = 'L', and TRANS = 'N'*CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( 2 ), N+1 )CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA,$ BETA, C( 1 ), N+1 )CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( NK+1, 1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( NK+2 ),$ N+1 )*ELSE** N is even, TRANSR = 'N', UPLO = 'L', and TRANS = 'T'*CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( 2 ), N+1 )CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA,$ BETA, C( 1 ), N+1 )CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, NK+1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( NK+2 ),$ N+1 )*END IF*ELSE** N is even, TRANSR = 'N', and UPLO = 'U'*IF( NOTRANS ) THEN** N is even, TRANSR = 'N', UPLO = 'U', and TRANS = 'N'*CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( NK+2 ), N+1 )CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA,$ BETA, C( NK+1 ), N+1 )CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( 1, 1 ),$ LDA, A( NK+1, 1 ), LDA, BETA, C( 1 ),$ N+1 )*ELSE** N is even, TRANSR = 'N', UPLO = 'U', and TRANS = 'T'*CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( NK+2 ), N+1 )CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA,$ BETA, C( NK+1 ), N+1 )CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, 1 ),$ LDA, A( 1, NK+1 ), LDA, BETA, C( 1 ),$ N+1 )*END IF*END IF*ELSE** N is even, and TRANSR = 'T'*IF( LOWER ) THEN** N is even, TRANSR = 'T', and UPLO = 'L'*IF( NOTRANS ) THEN** N is even, TRANSR = 'T', UPLO = 'L', and TRANS = 'N'*CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( NK+1 ), NK )CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA,$ BETA, C( 1 ), NK )CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( 1, 1 ),$ LDA, A( NK+1, 1 ), LDA, BETA,$ C( ( ( NK+1 )*NK )+1 ), NK )*ELSE** N is even, TRANSR = 'T', UPLO = 'L', and TRANS = 'T'*CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( NK+1 ), NK )CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA,$ BETA, C( 1 ), NK )CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, 1 ),$ LDA, A( 1, NK+1 ), LDA, BETA,$ C( ( ( NK+1 )*NK )+1 ), NK )*END IF*ELSE** N is even, TRANSR = 'T', and UPLO = 'U'*IF( NOTRANS ) THEN** N is even, TRANSR = 'T', UPLO = 'U', and TRANS = 'N'*CALL DSYRK( 'U', 'N', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( NK*( NK+1 )+1 ), NK )CALL DSYRK( 'L', 'N', NK, K, ALPHA, A( NK+1, 1 ), LDA,$ BETA, C( NK*NK+1 ), NK )CALL DGEMM( 'N', 'T', NK, NK, K, ALPHA, A( NK+1, 1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( 1 ), NK )*ELSE** N is even, TRANSR = 'T', UPLO = 'U', and TRANS = 'T'*CALL DSYRK( 'U', 'T', NK, K, ALPHA, A( 1, 1 ), LDA,$ BETA, C( NK*( NK+1 )+1 ), NK )CALL DSYRK( 'L', 'T', NK, K, ALPHA, A( 1, NK+1 ), LDA,$ BETA, C( NK*NK+1 ), NK )CALL DGEMM( 'T', 'N', NK, NK, K, ALPHA, A( 1, NK+1 ),$ LDA, A( 1, 1 ), LDA, BETA, C( 1 ), NK )*END IF*END IF*END IF*END IF*RETURN** End of DSFRK*END*> \brief \b DSPCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPCON( UPLO, N, AP, IPIV, ANORM, RCOND, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION AP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPCON estimates the reciprocal of the condition number (in the*> 1-norm) of a real symmetric packed matrix A using the factorization*> A = U*D*U**T or A = L*D*L**T computed by DSPTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The block diagonal matrix D and the multipliers used to*> obtain the factor U or L as computed by DSPTRF, stored as a*> packed triangular matrix.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSPTRF.*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> The 1-norm of the original matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an*> estimate of the 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSPCON( UPLO, N, AP, IPIV, ANORM, RCOND, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IP, KASEDOUBLE PRECISION AINVNM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLACN2, DSPTRS, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ANORM.LT.ZERO ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.LE.ZERO ) THENRETURNEND IF** Check that the diagonal matrix D is nonsingular.*IF( UPPER ) THEN** Upper triangular storage: examine D from bottom to top*IP = N*( N+1 ) / 2DO 10 I = N, 1, -1IF( IPIV( I ).GT.0 .AND. AP( IP ).EQ.ZERO )$ RETURNIP = IP - I10 CONTINUEELSE** Lower triangular storage: examine D from top to bottom.*IP = 1DO 20 I = 1, NIF( IPIV( I ).GT.0 .AND. AP( IP ).EQ.ZERO )$ RETURNIP = IP + N - I + 120 CONTINUEEND IF** Estimate the 1-norm of the inverse.*KASE = 030 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THEN** Multiply by inv(L*D*L**T) or inv(U*D*U**T).*CALL DSPTRS( UPLO, N, 1, AP, IPIV, WORK, N, INFO )GO TO 30END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*RETURN** End of DSPCON*END*> \brief <b> DSPEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPEV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspev.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspev.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspev.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPEV( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPEV computes all the eigenvalues and, optionally, eigenvectors of a*> real symmetric matrix A in packed storage.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, AP is overwritten by values generated during the*> reduction to tridiagonal form. If UPLO = 'U', the diagonal*> and first superdiagonal of the tridiagonal matrix T overwrite*> the corresponding elements of A, and if UPLO = 'L', the*> diagonal and first subdiagonal of T overwrite the*> corresponding elements of A.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal*> eigenvectors of the matrix A, with the i-th column of Z*> holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of an intermediate tridiagonal*> form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSPEV( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL WANTZINTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALEDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSPEXTERNAL LSAME, DLAMCH, DLANSP* ..* .. External Subroutines ..EXTERNAL DOPGTR, DSCAL, DSPTRD, DSTEQR, DSTERF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) )$ THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -7END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSPEV ', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENW( 1 ) = AP( 1 )IF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSP( 'M', UPLO, N, AP, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )END IF** Call DSPTRD to reduce symmetric packed matrix to tridiagonal form.*INDE = 1INDTAU = INDE + NCALL DSPTRD( UPLO, N, AP, W, WORK( INDE ), WORK( INDTAU ), IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, first call* DOPGTR to generate the orthogonal matrix, then call DSTEQR.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSEINDWRK = INDTAU + NCALL DOPGTR( UPLO, N, AP, WORK( INDTAU ), Z, LDZ,$ WORK( INDWRK ), IINFO )CALL DSTEQR( JOBZ, N, W, WORK( INDE ), Z, LDZ, WORK( INDTAU ),$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = NELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF*RETURN** End of DSPEV*END*> \brief <b> DSPEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPEVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspevd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspevd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspevd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPEVD( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK,* IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPEVD computes all the eigenvalues and, optionally, eigenvectors*> of a real symmetric matrix A in packed storage. If eigenvectors are*> desired, it uses a divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, AP is overwritten by values generated during the*> reduction to tridiagonal form. If UPLO = 'U', the diagonal*> and first superdiagonal of the tridiagonal matrix T overwrite*> the corresponding elements of A, and if UPLO = 'L', the*> diagonal and first subdiagonal of T overwrite the*> corresponding elements of A.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal*> eigenvectors of the matrix A, with the i-th column of Z*> holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the required LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N <= 1, LWORK must be at least 1.*> If JOBZ = 'N' and N > 1, LWORK must be at least 2*N.*> If JOBZ = 'V' and N > 1, LWORK must be at least*> 1 + 6*N + N**2.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the required sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the required LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If JOBZ = 'N' or N <= 1, LIWORK must be at least 1.*> If JOBZ = 'V' and N > 1, LIWORK must be at least 3 + 5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the required sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of an intermediate tridiagonal*> form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSPEVD( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK,$ IWORK, LIWORK, INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WANTZINTEGER IINFO, INDE, INDTAU, INDWRK, ISCALE, LIWMIN,$ LLWORK, LWMINDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSPEXTERNAL LSAME, DLAMCH, DLANSP* ..* .. External Subroutines ..EXTERNAL DOPMTR, DSCAL, DSPTRD, DSTEDC, DSTERF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) )$ THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -7END IF*IF( INFO.EQ.0 ) THENIF( N.LE.1 ) THENLIWMIN = 1LWMIN = 1ELSEIF( WANTZ ) THENLIWMIN = 3 + 5*NLWMIN = 1 + 6*N + N**2ELSELIWMIN = 1LWMIN = 2*NEND IFEND IFIWORK( 1 ) = LIWMINWORK( 1 ) = LWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -9ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -11END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSPEVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENW( 1 ) = AP( 1 )IF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSP( 'M', UPLO, N, AP, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )END IF** Call DSPTRD to reduce symmetric packed matrix to tridiagonal form.*INDE = 1INDTAU = INDE + NCALL DSPTRD( UPLO, N, AP, W, WORK( INDE ), WORK( INDTAU ), IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, first call* DSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the* tridiagonal matrix, then call DOPMTR to multiply it by the* Householder transformations represented in AP.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSEINDWRK = INDTAU + NLLWORK = LWORK - INDWRK + 1CALL DSTEDC( 'I', N, W, WORK( INDE ), Z, LDZ, WORK( INDWRK ),$ LLWORK, IWORK, LIWORK, INFO )CALL DOPMTR( 'L', UPLO, 'N', N, N, AP, WORK( INDTAU ), Z, LDZ,$ WORK( INDWRK ), IINFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 )$ CALL DSCAL( N, ONE / SIGMA, W, 1 )*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMINRETURN** End of DSPEVD*END*> \brief <b> DSPEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPEVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspevx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspevx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspevx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,* ABSTOL, M, W, Z, LDZ, WORK, IWORK, IFAIL,* INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, IU, LDZ, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPEVX computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric matrix A in packed storage. Eigenvalues/vectors*> can be selected by specifying either a range of values or a range of*> indices for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found;*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found;*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, AP is overwritten by values generated during the*> reduction to tridiagonal form. If UPLO = 'U', the diagonal*> and first superdiagonal of the tridiagonal matrix T overwrite*> the corresponding elements of A, and if UPLO = 'L', the*> diagonal and first subdiagonal of T overwrite the*> corresponding elements of A.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing AP to tridiagonal form.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*>*> See "Computing Small Singular Values of Bidiagonal Matrices*> with Guaranteed High Relative Accuracy," by Demmel and*> Kahan, LAPACK Working Note #3.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the selected eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If an eigenvector fails to converge, then that column of Z*> contains the latest approximation to the eigenvector, and the*> index of the eigenvector is returned in IFAIL.*> If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (8*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (N)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvectors that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, then i eigenvectors failed to converge.*> Their indices are stored in array IFAIL.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU,$ ABSTOL, M, W, Z, LDZ, WORK, IWORK, IFAIL,$ INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, IU, LDZ, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION AP( * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZCHARACTER ORDERINTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,$ INDISP, INDIWO, INDTAU, INDWRK, ISCALE, ITMP1,$ J, JJ, NSPLITDOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,$ SIGMA, SMLNUM, TMP1, VLL, VUU* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSPEXTERNAL LSAME, DLAMCH, DLANSP* ..* .. External Subroutines ..EXTERNAL DCOPY, DOPGTR, DOPMTR, DSCAL, DSPTRD, DSTEBZ,$ DSTEIN, DSTEQR, DSTERF, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( .NOT.( LSAME( UPLO, 'L' ) .OR. LSAME( UPLO, 'U' ) ) )$ THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -7ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -8ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -9END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )$ INFO = -14END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSPEVX', -INFO )RETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ALLEIG .OR. INDEIG ) THENM = 1W( 1 ) = AP( 1 )ELSEIF( VL.LT.AP( 1 ) .AND. VU.GE.AP( 1 ) ) THENM = 1W( 1 ) = AP( 1 )END IFEND IFIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )** Scale matrix to allowable range, if necessary.*ISCALE = 0ABSTLL = ABSTOLIF( VALEIG ) THENVLL = VLVUU = VUELSEVLL = ZEROVUU = ZEROEND IFANRM = DLANSP( 'M', UPLO, N, AP, WORK )IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( ( N*( N+1 ) ) / 2, SIGMA, AP, 1 )IF( ABSTOL.GT.0 )$ ABSTLL = ABSTOL*SIGMAIF( VALEIG ) THENVLL = VL*SIGMAVUU = VU*SIGMAEND IFEND IF** Call DSPTRD to reduce symmetric packed matrix to tridiagonal form.*INDTAU = 1INDE = INDTAU + NINDD = INDE + NINDWRK = INDD + NCALL DSPTRD( UPLO, N, AP, WORK( INDD ), WORK( INDE ),$ WORK( INDTAU ), IINFO )** If all eigenvalues are desired and ABSTOL is less than or equal* to zero, then call DSTERF or DOPGTR and SSTEQR. If this fails* for some eigenvalue, then try DSTEBZ.*TEST = .FALSE.IF (INDEIG) THENIF (IL.EQ.1 .AND. IU.EQ.N) THENTEST = .TRUE.END IFEND IFIF ((ALLEIG .OR. TEST) .AND. (ABSTOL.LE.ZERO)) THENCALL DCOPY( N, WORK( INDD ), 1, W, 1 )INDEE = INDWRK + 2*NIF( .NOT.WANTZ ) THENCALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTERF( N, W, WORK( INDEE ), INFO )ELSECALL DOPGTR( UPLO, N, AP, WORK( INDTAU ), Z, LDZ,$ WORK( INDWRK ), IINFO )CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,$ WORK( INDWRK ), INFO )IF( INFO.EQ.0 ) THENDO 10 I = 1, NIFAIL( I ) = 010 CONTINUEEND IFEND IFIF( INFO.EQ.0 ) THENM = NGO TO 20END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFINDIBL = 1INDISP = INDIBL + NINDIWO = INDISP + NCALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,$ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,$ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),$ IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,$ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,$ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )** Apply orthogonal matrix used in reduction to tridiagonal* form to eigenvectors returned by DSTEIN.*CALL DOPMTR( 'L', UPLO, 'N', N, M, AP, WORK( INDTAU ), Z, LDZ,$ WORK( INDWRK ), IINFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*20 CONTINUEIF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = MELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** If eigenvalues are not in order, then sort them, along with* eigenvectors.*IF( WANTZ ) THENDO 40 J = 1, M - 1I = 0TMP1 = W( J )DO 30 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF30 CONTINUE*IF( I.NE.0 ) THENITMP1 = IWORK( INDIBL+I-1 )W( I ) = W( J )IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )W( J ) = TMP1IWORK( INDIBL+J-1 ) = ITMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )IF( INFO.NE.0 ) THENITMP1 = IFAIL( I )IFAIL( I ) = IFAIL( J )IFAIL( J ) = ITMP1END IFEND IF40 CONTINUEEND IF*RETURN** End of DSPEVX*END*> \brief \b DSPGST** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPGST + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspgst.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspgst.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspgst.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPGST( ITYPE, UPLO, N, AP, BP, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, ITYPE, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), BP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPGST reduces a real symmetric-definite generalized eigenproblem*> to standard form, using packed storage.*>*> If ITYPE = 1, the problem is A*x = lambda*B*x,*> and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)*>*> If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or*> B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L.*>*> B must have been previously factorized as U**T*U or L*L**T by DPPTRF.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);*> = 2 or 3: compute U*A*U**T or L**T*A*L.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored and B is factored as*> U**T*U;*> = 'L': Lower triangle of A is stored and B is factored as*> L*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, if INFO = 0, the transformed matrix, stored in the*> same format as A.*> \endverbatim*>*> \param[in] BP*> \verbatim*> BP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The triangular factor from the Cholesky factorization of B,*> stored in the same format as A, as returned by DPPTRF.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSPGST( ITYPE, UPLO, N, AP, BP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, ITYPE, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), BP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, HALFPARAMETER ( ONE = 1.0D0, HALF = 0.5D0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, J1, J1J1, JJ, K, K1, K1K1, KKDOUBLE PRECISION AJJ, AKK, BJJ, BKK, CT* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DSPMV, DSPR2, DTPMV, DTPSV,$ XERBLA* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPGST', -INFO )RETURNEND IF*IF( ITYPE.EQ.1 ) THENIF( UPPER ) THEN** Compute inv(U**T)*A*inv(U)** J1 and JJ are the indices of A(1,j) and A(j,j)*JJ = 0DO 10 J = 1, NJ1 = JJ + 1JJ = JJ + J** Compute the j-th column of the upper triangle of A*BJJ = BP( JJ )CALL DTPSV( UPLO, 'Transpose', 'Nonunit', J, BP,$ AP( J1 ), 1 )CALL DSPMV( UPLO, J-1, -ONE, AP, BP( J1 ), 1, ONE,$ AP( J1 ), 1 )CALL DSCAL( J-1, ONE / BJJ, AP( J1 ), 1 )AP( JJ ) = ( AP( JJ )-DDOT( J-1, AP( J1 ), 1, BP( J1 ),$ 1 ) ) / BJJ10 CONTINUEELSE** Compute inv(L)*A*inv(L**T)** KK and K1K1 are the indices of A(k,k) and A(k+1,k+1)*KK = 1DO 20 K = 1, NK1K1 = KK + N - K + 1** Update the lower triangle of A(k:n,k:n)*AKK = AP( KK )BKK = BP( KK )AKK = AKK / BKK**2AP( KK ) = AKKIF( K.LT.N ) THENCALL DSCAL( N-K, ONE / BKK, AP( KK+1 ), 1 )CT = -HALF*AKKCALL DAXPY( N-K, CT, BP( KK+1 ), 1, AP( KK+1 ), 1 )CALL DSPR2( UPLO, N-K, -ONE, AP( KK+1 ), 1,$ BP( KK+1 ), 1, AP( K1K1 ) )CALL DAXPY( N-K, CT, BP( KK+1 ), 1, AP( KK+1 ), 1 )CALL DTPSV( UPLO, 'No transpose', 'Non-unit', N-K,$ BP( K1K1 ), AP( KK+1 ), 1 )END IFKK = K1K120 CONTINUEEND IFELSEIF( UPPER ) THEN** Compute U*A*U**T** K1 and KK are the indices of A(1,k) and A(k,k)*KK = 0DO 30 K = 1, NK1 = KK + 1KK = KK + K** Update the upper triangle of A(1:k,1:k)*AKK = AP( KK )BKK = BP( KK )CALL DTPMV( UPLO, 'No transpose', 'Non-unit', K-1, BP,$ AP( K1 ), 1 )CT = HALF*AKKCALL DAXPY( K-1, CT, BP( K1 ), 1, AP( K1 ), 1 )CALL DSPR2( UPLO, K-1, ONE, AP( K1 ), 1, BP( K1 ), 1,$ AP )CALL DAXPY( K-1, CT, BP( K1 ), 1, AP( K1 ), 1 )CALL DSCAL( K-1, BKK, AP( K1 ), 1 )AP( KK ) = AKK*BKK**230 CONTINUEELSE** Compute L**T *A*L** JJ and J1J1 are the indices of A(j,j) and A(j+1,j+1)*JJ = 1DO 40 J = 1, NJ1J1 = JJ + N - J + 1** Compute the j-th column of the lower triangle of A*AJJ = AP( JJ )BJJ = BP( JJ )AP( JJ ) = AJJ*BJJ + DDOT( N-J, AP( JJ+1 ), 1,$ BP( JJ+1 ), 1 )CALL DSCAL( N-J, BJJ, AP( JJ+1 ), 1 )CALL DSPMV( UPLO, N-J, ONE, AP( J1J1 ), BP( JJ+1 ), 1,$ ONE, AP( JJ+1 ), 1 )CALL DTPMV( UPLO, 'Transpose', 'Non-unit', N-J+1,$ BP( JJ ), AP( JJ ), 1 )JJ = J1J140 CONTINUEEND IFEND IFRETURN** End of DSPGST*END*> \brief \b DSPGV** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPGV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspgv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspgv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspgv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPGV( ITYPE, JOBZ, UPLO, N, AP, BP, W, Z, LDZ, WORK,* INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, ITYPE, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPGV computes all the eigenvalues and, optionally, the eigenvectors*> of a real generalized symmetric-definite eigenproblem, of the form*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x.*> Here A and B are assumed to be symmetric, stored in packed format,*> and B is also positive definite.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> Specifies the problem type to be solved:*> = 1: A*x = (lambda)*B*x*> = 2: A*B*x = (lambda)*x*> = 3: B*A*x = (lambda)*x*> \endverbatim*>*> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, the contents of AP are destroyed.*> \endverbatim*>*> \param[in,out] BP*> \verbatim*> BP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> B, packed columnwise in a linear array. The j-th column of B*> is stored in the array BP as follows:*> if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j;*> if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n.*>*> On exit, the triangular factor U or L from the Cholesky*> factorization B = U**T*U or B = L*L**T, in the same storage*> format as B.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of*> eigenvectors. The eigenvectors are normalized as follows:*> if ITYPE = 1 or 2, Z**T*B*Z = I;*> if ITYPE = 3, Z**T*inv(B)*Z = I.*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: DPPTRF or DSPEV returned an error code:*> <= N: if INFO = i, DSPEV failed to converge;*> i off-diagonal elements of an intermediate*> tridiagonal form did not converge to zero.*> > N: if INFO = n + i, for 1 <= i <= n, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSPGV( ITYPE, JOBZ, UPLO, N, AP, BP, W, Z, LDZ, WORK,$ INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, ITYPE, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),$ Z( LDZ, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL UPPER, WANTZCHARACTER TRANSINTEGER J, NEIG* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPPTRF, DSPEV, DSPGST, DTPMV, DTPSV, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )*INFO = 0IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPGV ', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form a Cholesky factorization of B.*CALL DPPTRF( UPLO, N, BP, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem and solve.*CALL DSPGST( ITYPE, UPLO, N, AP, BP, INFO )CALL DSPEV( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, INFO )*IF( WANTZ ) THEN** Backtransform eigenvectors to the original problem.*NEIG = NIF( INFO.GT.0 )$ NEIG = INFO - 1IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN** For A*x=(lambda)*B*x and A*B*x=(lambda)*x;* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y*IF( UPPER ) THENTRANS = 'N'ELSETRANS = 'T'END IF*DO 10 J = 1, NEIGCALL DTPSV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),$ 1 )10 CONTINUE*ELSE IF( ITYPE.EQ.3 ) THEN** For B*A*x=(lambda)*x;* backtransform eigenvectors: x = L*y or U**T*y*IF( UPPER ) THENTRANS = 'T'ELSETRANS = 'N'END IF*DO 20 J = 1, NEIGCALL DTPMV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),$ 1 )20 CONTINUEEND IFEND IFRETURN** End of DSPGV*END*> \brief \b DSPGVD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPGVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspgvd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspgvd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspgvd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPGVD( ITYPE, JOBZ, UPLO, N, AP, BP, W, Z, LDZ, WORK,* LWORK, IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, ITYPE, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPGVD computes all the eigenvalues, and optionally, the eigenvectors*> of a real generalized symmetric-definite eigenproblem, of the form*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and*> B are assumed to be symmetric, stored in packed format, and B is also*> positive definite.*> If eigenvectors are desired, it uses a divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> Specifies the problem type to be solved:*> = 1: A*x = (lambda)*B*x*> = 2: A*B*x = (lambda)*x*> = 3: B*A*x = (lambda)*x*> \endverbatim*>*> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, the contents of AP are destroyed.*> \endverbatim*>*> \param[in,out] BP*> \verbatim*> BP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> B, packed columnwise in a linear array. The j-th column of B*> is stored in the array BP as follows:*> if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j;*> if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n.*>*> On exit, the triangular factor U or L from the Cholesky*> factorization B = U**T*U or B = L*L**T, in the same storage*> format as B.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the matrix Z of*> eigenvectors. The eigenvectors are normalized as follows:*> if ITYPE = 1 or 2, Z**T*B*Z = I;*> if ITYPE = 3, Z**T*inv(B)*Z = I.*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the required LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N <= 1, LWORK >= 1.*> If JOBZ = 'N' and N > 1, LWORK >= 2*N.*> If JOBZ = 'V' and N > 1, LWORK >= 1 + 6*N + 2*N**2.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the required sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the required LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If JOBZ = 'N' or N <= 1, LIWORK >= 1.*> If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the required sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: DPPTRF or DSPEVD returned an error code:*> <= N: if INFO = i, DSPEVD failed to converge;*> i off-diagonal elements of an intermediate*> tridiagonal form did not converge to zero;*> > N: if INFO = N + i, for 1 <= i <= N, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA** =====================================================================SUBROUTINE DSPGVD( ITYPE, JOBZ, UPLO, N, AP, BP, W, Z, LDZ, WORK,$ LWORK, IWORK, LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, ITYPE, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),$ Z( LDZ, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERY, UPPER, WANTZCHARACTER TRANSINTEGER J, LIWMIN, LWMIN, NEIG* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPPTRF, DSPEVD, DSPGST, DTPMV, DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -9END IF*IF( INFO.EQ.0 ) THENIF( N.LE.1 ) THENLIWMIN = 1LWMIN = 1ELSEIF( WANTZ ) THENLIWMIN = 3 + 5*NLWMIN = 1 + 6*N + 2*N**2ELSELIWMIN = 1LWMIN = 2*NEND IFEND IFWORK( 1 ) = LWMINIWORK( 1 ) = LIWMINIF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -11ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -13END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSPGVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form a Cholesky factorization of BP.*CALL DPPTRF( UPLO, N, BP, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem and solve.*CALL DSPGST( ITYPE, UPLO, N, AP, BP, INFO )CALL DSPEVD( JOBZ, UPLO, N, AP, W, Z, LDZ, WORK, LWORK, IWORK,$ LIWORK, INFO )LWMIN = MAX( DBLE( LWMIN ), DBLE( WORK( 1 ) ) )LIWMIN = MAX( DBLE( LIWMIN ), DBLE( IWORK( 1 ) ) )*IF( WANTZ ) THEN** Backtransform eigenvectors to the original problem.*NEIG = NIF( INFO.GT.0 )$ NEIG = INFO - 1IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN** For A*x=(lambda)*B*x and A*B*x=(lambda)*x;* backtransform eigenvectors: x = inv(L)**T *y or inv(U)*y*IF( UPPER ) THENTRANS = 'N'ELSETRANS = 'T'END IF*DO 10 J = 1, NEIGCALL DTPSV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),$ 1 )10 CONTINUE*ELSE IF( ITYPE.EQ.3 ) THEN** For B*A*x=(lambda)*x;* backtransform eigenvectors: x = L*y or U**T *y*IF( UPPER ) THENTRANS = 'T'ELSETRANS = 'N'END IF*DO 20 J = 1, NEIGCALL DTPMV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),$ 1 )20 CONTINUEEND IFEND IF*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DSPGVD*END*> \brief \b DSPGVX** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPGVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspgvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspgvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspgvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPGVX( ITYPE, JOBZ, RANGE, UPLO, N, AP, BP, VL, VU,* IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,* IFAIL, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, ITYPE, IU, LDZ, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPGVX computes selected eigenvalues, and optionally, eigenvectors*> of a real generalized symmetric-definite eigenproblem, of the form*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A*> and B are assumed to be symmetric, stored in packed storage, and B*> is also positive definite. Eigenvalues and eigenvectors can be*> selected by specifying either a range of values or a range of indices*> for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> Specifies the problem type to be solved:*> = 1: A*x = (lambda)*B*x*> = 2: A*B*x = (lambda)*x*> = 3: B*A*x = (lambda)*x*> \endverbatim*>*> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A and B are stored;*> = 'L': Lower triangle of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix pencil (A,B). N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, the contents of AP are destroyed.*> \endverbatim*>*> \param[in,out] BP*> \verbatim*> BP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> B, packed columnwise in a linear array. The j-th column of B*> is stored in the array BP as follows:*> if UPLO = 'U', BP(i + (j-1)*j/2) = B(i,j) for 1<=i<=j;*> if UPLO = 'L', BP(i + (j-1)*(2*n-j)/2) = B(i,j) for j<=i<=n.*>*> On exit, the triangular factor U or L from the Cholesky*> factorization B = U**T*U or B = L*L**T, in the same storage*> format as B.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*>*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*>*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*>*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*>*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing A to tridiagonal form.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On normal exit, the first M elements contain the selected*> eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))*> If JOBZ = 'N', then Z is not referenced.*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> The eigenvectors are normalized as follows:*> if ITYPE = 1 or 2, Z**T*B*Z = I;*> if ITYPE = 3, Z**T*inv(B)*Z = I.*>*> If an eigenvector fails to converge, then that column of Z*> contains the latest approximation to the eigenvector, and the*> index of the eigenvector is returned in IFAIL.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (8*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (N)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvectors that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: DPPTRF or DSPEVX returned an error code:*> <= N: if INFO = i, DSPEVX failed to converge;*> i eigenvectors failed to converge. Their indices*> are stored in array IFAIL.*> > N: if INFO = N + i, for 1 <= i <= N, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA** =====================================================================SUBROUTINE DSPGVX( ITYPE, JOBZ, RANGE, UPLO, N, AP, BP, VL, VU,$ IL, IU, ABSTOL, M, W, Z, LDZ, WORK, IWORK,$ IFAIL, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, ITYPE, IU, LDZ, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION AP( * ), BP( * ), W( * ), WORK( * ),$ Z( LDZ, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL ALLEIG, INDEIG, UPPER, VALEIG, WANTZCHARACTER TRANSINTEGER J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPPTRF, DSPEVX, DSPGST, DTPMV, DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MIN* ..* .. Executable Statements ..** Test the input parameters.*UPPER = LSAME( UPLO, 'U' )WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*INFO = 0IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -3ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL ) THENINFO = -9END IFELSE IF( INDEIG ) THENIF( IL.LT.1 ) THENINFO = -10ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -11END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -16END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSPGVX', -INFO )RETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN** Form a Cholesky factorization of B.*CALL DPPTRF( UPLO, N, BP, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem and solve.*CALL DSPGST( ITYPE, UPLO, N, AP, BP, INFO )CALL DSPEVX( JOBZ, RANGE, UPLO, N, AP, VL, VU, IL, IU, ABSTOL, M,$ W, Z, LDZ, WORK, IWORK, IFAIL, INFO )*IF( WANTZ ) THEN** Backtransform eigenvectors to the original problem.*IF( INFO.GT.0 )$ M = INFO - 1IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN** For A*x=(lambda)*B*x and A*B*x=(lambda)*x;* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y*IF( UPPER ) THENTRANS = 'N'ELSETRANS = 'T'END IF*DO 10 J = 1, MCALL DTPSV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),$ 1 )10 CONTINUE*ELSE IF( ITYPE.EQ.3 ) THEN** For B*A*x=(lambda)*x;* backtransform eigenvectors: x = L*y or U**T*y*IF( UPPER ) THENTRANS = 'T'ELSETRANS = 'N'END IF*DO 20 J = 1, MCALL DTPMV( UPLO, TRANS, 'Non-unit', N, BP, Z( 1, J ),$ 1 )20 CONTINUEEND IFEND IF*RETURN** End of DSPGVX*END*> \brief \b DSPRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsprfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsprfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsprfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPRFS( UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X, LDX,* FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),* $ FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is symmetric indefinite*> and packed, and provides error bounds and backward error estimates*> for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangle of the symmetric matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in] AFP*> \verbatim*> AFP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The factored form of the matrix A. AFP contains the block*> diagonal matrix D and the multipliers used to obtain the*> factor U or L from the factorization A = U*D*U**T or*> A = L*D*L**T as computed by DSPTRF, stored as a packed*> triangular matrix.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSPTRF.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DSPTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSPRFS( UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X, LDX,$ FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER COUNT, I, IK, J, K, KASE, KK, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DSPMV, DSPTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - A * X*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DSPMV( UPLO, N, -ONE, AP, X( 1, J ), 1, ONE, WORK( N+1 ),$ 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(A)*abs(X) + abs(B).*KK = 1IF( UPPER ) THENDO 50 K = 1, NS = ZEROXK = ABS( X( K, J ) )IK = KKDO 40 I = 1, K - 1WORK( I ) = WORK( I ) + ABS( AP( IK ) )*XKS = S + ABS( AP( IK ) )*ABS( X( I, J ) )IK = IK + 140 CONTINUEWORK( K ) = WORK( K ) + ABS( AP( KK+K-1 ) )*XK + SKK = KK + K50 CONTINUEELSEDO 70 K = 1, NS = ZEROXK = ABS( X( K, J ) )WORK( K ) = WORK( K ) + ABS( AP( KK ) )*XKIK = KK + 1DO 60 I = K + 1, NWORK( I ) = WORK( I ) + ABS( AP( IK ) )*XKS = S + ABS( AP( IK ) )*ABS( X( I, J ) )IK = IK + 160 CONTINUEWORK( K ) = WORK( K ) + SKK = KK + ( N-K+1 )70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DSPTRS( UPLO, N, 1, AFP, IPIV, WORK( N+1 ), N, INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(A))** ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(A) is the inverse of A* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(A)*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(A) * diag(W),* where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(A**T).*CALL DSPTRS( UPLO, N, 1, AFP, IPIV, WORK( N+1 ), N,$ INFO )DO 110 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )110 CONTINUEELSE IF( KASE.EQ.2 ) THEN** Multiply by inv(A)*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )120 CONTINUECALL DSPTRS( UPLO, N, 1, AFP, IPIV, WORK( N+1 ), N,$ INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DSPRFS*END*> \brief <b> DSPSV computes the solution to system of linear equations A * X = B for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspsv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspsv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspsv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPSV( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AP( * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPSV computes the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric matrix stored in packed format and X*> and B are N-by-NRHS matrices.*>*> The diagonal pivoting method is used to factor A as*> A = U * D * U**T, if UPLO = 'U', or*> A = L * D * L**T, if UPLO = 'L',*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices, D is symmetric and block diagonal with 1-by-1*> and 2-by-2 diagonal blocks. The factored form of A is then used to*> solve the system of equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> See below for further details.*>*> On exit, the block diagonal matrix D and the multipliers used*> to obtain the factor U or L from the factorization*> A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as*> a packed triangular matrix in the same storage format as A.*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D, as*> determined by DSPTRF. If IPIV(k) > 0, then rows and columns*> k and IPIV(k) were interchanged, and D(k,k) is a 1-by-1*> diagonal block. If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0,*> then rows and columns k-1 and -IPIV(k) were interchanged and*> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. If UPLO = 'L' and*> IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and*> -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2*> diagonal block.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) is exactly zero. The factorization*> has been completed, but the block diagonal matrix D is*> exactly singular, so the solution could not be*> computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The packed storage scheme is illustrated by the following example*> when N = 4, UPLO = 'U':*>*> Two-dimensional storage of the symmetric matrix A:*>*> a11 a12 a13 a14*> a22 a23 a24*> a33 a34 (aij = aji)*> a44*>*> Packed storage of the upper triangle of A:*>*> AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]*> \endverbatim*>* =====================================================================SUBROUTINE DSPSV( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AP( * ), B( LDB, * )* ..** =====================================================================** .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSPTRF, DSPTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPSV ', -INFO )RETURNEND IF** Compute the factorization A = U*D*U**T or A = L*D*L**T.*CALL DSPTRF( UPLO, N, AP, IPIV, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*CALL DSPTRS( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )*END IFRETURN** End of DSPSV*END*> \brief <b> DSPSVX computes the solution to system of linear equations A * X = B for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dspsvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dspsvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dspsvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPSVX( FACT, UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X,* LDX, RCOND, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER FACT, UPLO* INTEGER INFO, LDB, LDX, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),* $ FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPSVX uses the diagonal pivoting factorization A = U*D*U**T or*> A = L*D*L**T to compute the solution to a real system of linear*> equations A * X = B, where A is an N-by-N symmetric matrix stored*> in packed format and X and B are N-by-NRHS matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'N', the diagonal pivoting method is used to factor A as*> A = U * D * U**T, if UPLO = 'U', or*> A = L * D * L**T, if UPLO = 'L',*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices and D is symmetric and block diagonal with*> 1-by-1 and 2-by-2 diagonal blocks.*>*> 2. If some D(i,i)=0, so that D is exactly singular, then the routine*> returns with INFO = i. Otherwise, the factored form of A is used*> to estimate the condition number of the matrix A. If the*> reciprocal of the condition number is less than machine precision,*> INFO = N+1 is returned as a warning, but the routine still goes on*> to solve for X and compute error bounds as described below.*>*> 3. The system of equations is solved for X using the factored form*> of A.*>*> 4. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of A has been*> supplied on entry.*> = 'F': On entry, AFP and IPIV contain the factored form of*> A. AP, AFP and IPIV will not be modified.*> = 'N': The matrix A will be copied to AFP and factored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangle of the symmetric matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*> See below for further details.*> \endverbatim*>*> \param[in,out] AFP*> \verbatim*> AFP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> If FACT = 'F', then AFP is an input argument and on entry*> contains the block diagonal matrix D and the multipliers used*> to obtain the factor U or L from the factorization*> A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as*> a packed triangular matrix in the same storage format as A.*>*> If FACT = 'N', then AFP is an output argument and on exit*> contains the block diagonal matrix D and the multipliers used*> to obtain the factor U or L from the factorization*> A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as*> a packed triangular matrix in the same storage format as A.*> \endverbatim*>*> \param[in,out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> If FACT = 'F', then IPIV is an input argument and on entry*> contains details of the interchanges and the block structure*> of D, as determined by DSPTRF.*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and*> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)*> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =*> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were*> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.*>*> If FACT = 'N', then IPIV is an output argument and on exit*> contains details of the interchanges and the block structure*> of D, as determined by DSPTRF.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The N-by-NRHS right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A. If RCOND is less than the machine precision (in*> particular, if RCOND = 0), the matrix is singular to working*> precision. This condition is indicated by a return code of*> INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: D(i,i) is exactly zero. The factorization*> has been completed but the factor D is exactly*> singular, so the solution and error bounds could*> not be computed. RCOND = 0 is returned.*> = N+1: D is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleOTHERsolve**> \par Further Details:* =====================*>*> \verbatim*>*> The packed storage scheme is illustrated by the following example*> when N = 4, UPLO = 'U':*>*> Two-dimensional storage of the symmetric matrix A:*>*> a11 a12 a13 a14*> a22 a23 a24*> a33 a34 (aij = aji)*> a44*>*> Packed storage of the upper triangle of A:*>*> AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]*> \endverbatim*>* =====================================================================SUBROUTINE DSPSVX( FACT, UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X,$ LDX, RCOND, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER FACT, UPLOINTEGER INFO, LDB, LDX, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION AFP( * ), AP( * ), B( LDB, * ), BERR( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOFACTDOUBLE PRECISION ANORM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSPEXTERNAL LSAME, DLAMCH, DLANSP* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DSPCON, DSPRFS, DSPTRF, DSPTRS,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOFACT = LSAME( FACT, 'N' )IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )$ THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPSVX', -INFO )RETURNEND IF*IF( NOFACT ) THEN** Compute the factorization A = U*D*U**T or A = L*D*L**T.*CALL DCOPY( N*( N+1 ) / 2, AP, 1, AFP, 1 )CALL DSPTRF( UPLO, N, AFP, IPIV, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*ANORM = DLANSP( 'I', UPLO, N, AP, WORK )** Compute the reciprocal of the condition number of A.*CALL DSPCON( UPLO, N, AFP, IPIV, ANORM, RCOND, WORK, IWORK, INFO )** Compute the solution vectors X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DSPTRS( UPLO, N, NRHS, AFP, IPIV, X, LDX, INFO )** Use iterative refinement to improve the computed solutions and* compute error bounds and backward error estimates for them.*CALL DSPRFS( UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X, LDX, FERR,$ BERR, WORK, IWORK, INFO )** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*RETURN** End of DSPSVX*END*> \brief \b DSPTRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPTRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsptrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsptrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsptrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPTRD( UPLO, N, AP, D, E, TAU, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), D( * ), E( * ), TAU( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPTRD reduces a real symmetric matrix A stored in packed form to*> symmetric tridiagonal form T by an orthogonal similarity*> transformation: Q**T * A * Q = T.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*> On exit, if UPLO = 'U', the diagonal and first superdiagonal*> of A are overwritten by the corresponding elements of the*> tridiagonal matrix T, and the elements above the first*> superdiagonal, with the array TAU, represent the orthogonal*> matrix Q as a product of elementary reflectors; if UPLO*> = 'L', the diagonal and first subdiagonal of A are over-*> written by the corresponding elements of the tridiagonal*> matrix T, and the elements below the first subdiagonal, with*> the array TAU, represent the orthogonal matrix Q as a product*> of elementary reflectors. See Further Details.*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of the tridiagonal matrix T:*> D(i) = A(i,i).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The off-diagonal elements of the tridiagonal matrix T:*> E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(n-1) . . . H(2) H(1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in AP,*> overwriting A(1:i-1,i+1), and tau is stored in TAU(i).*>*> If UPLO = 'L', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(1) H(2) . . . H(n-1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in AP,*> overwriting A(i+2:n,i), and tau is stored in TAU(i).*> \endverbatim*>* =====================================================================SUBROUTINE DSPTRD( UPLO, N, AP, D, E, TAU, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), D( * ), E( * ), TAU( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZERO, HALFPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0,$ HALF = 1.0D0 / 2.0D0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, I1, I1I1, IIDOUBLE PRECISION ALPHA, TAUI* ..* .. External Subroutines ..EXTERNAL DAXPY, DLARFG, DSPMV, DSPR2, XERBLA* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPTRD', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN*IF( UPPER ) THEN** Reduce the upper triangle of A.* I1 is the index in AP of A(1,I+1).*I1 = N*( N-1 ) / 2 + 1DO 10 I = N - 1, 1, -1** Generate elementary reflector H(i) = I - tau * v * v**T* to annihilate A(1:i-1,i+1)*CALL DLARFG( I, AP( I1+I-1 ), AP( I1 ), 1, TAUI )E( I ) = AP( I1+I-1 )*IF( TAUI.NE.ZERO ) THEN** Apply H(i) from both sides to A(1:i,1:i)*AP( I1+I-1 ) = ONE** Compute y := tau * A * v storing y in TAU(1:i)*CALL DSPMV( UPLO, I, TAUI, AP, AP( I1 ), 1, ZERO, TAU,$ 1 )** Compute w := y - 1/2 * tau * (y**T *v) * v*ALPHA = -HALF*TAUI*DDOT( I, TAU, 1, AP( I1 ), 1 )CALL DAXPY( I, ALPHA, AP( I1 ), 1, TAU, 1 )** Apply the transformation as a rank-2 update:* A := A - v * w**T - w * v**T*CALL DSPR2( UPLO, I, -ONE, AP( I1 ), 1, TAU, 1, AP )*AP( I1+I-1 ) = E( I )END IFD( I+1 ) = AP( I1+I )TAU( I ) = TAUII1 = I1 - I10 CONTINUED( 1 ) = AP( 1 )ELSE** Reduce the lower triangle of A. II is the index in AP of* A(i,i) and I1I1 is the index of A(i+1,i+1).*II = 1DO 20 I = 1, N - 1I1I1 = II + N - I + 1** Generate elementary reflector H(i) = I - tau * v * v**T* to annihilate A(i+2:n,i)*CALL DLARFG( N-I, AP( II+1 ), AP( II+2 ), 1, TAUI )E( I ) = AP( II+1 )*IF( TAUI.NE.ZERO ) THEN** Apply H(i) from both sides to A(i+1:n,i+1:n)*AP( II+1 ) = ONE** Compute y := tau * A * v storing y in TAU(i:n-1)*CALL DSPMV( UPLO, N-I, TAUI, AP( I1I1 ), AP( II+1 ), 1,$ ZERO, TAU( I ), 1 )** Compute w := y - 1/2 * tau * (y**T *v) * v*ALPHA = -HALF*TAUI*DDOT( N-I, TAU( I ), 1, AP( II+1 ),$ 1 )CALL DAXPY( N-I, ALPHA, AP( II+1 ), 1, TAU( I ), 1 )** Apply the transformation as a rank-2 update:* A := A - v * w**T - w * v**T*CALL DSPR2( UPLO, N-I, -ONE, AP( II+1 ), 1, TAU( I ), 1,$ AP( I1I1 ) )*AP( II+1 ) = E( I )END IFD( I ) = AP( II )TAU( I ) = TAUIII = I1I120 CONTINUED( N ) = AP( II )END IF*RETURN** End of DSPTRD*END*> \brief \b DSPTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsptrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsptrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsptrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPTRF( UPLO, N, AP, IPIV, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPTRF computes the factorization of a real symmetric matrix A stored*> in packed format using the Bunch-Kaufman diagonal pivoting method:*>*> A = U*D*U**T or A = L*D*L**T*>*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices, and D is symmetric and block diagonal with*> 1-by-1 and 2-by-2 diagonal blocks.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangle of the symmetric matrix*> A, packed columnwise in a linear array. The j-th column of A*> is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*>*> On exit, the block diagonal matrix D and the multipliers used*> to obtain the factor U or L, stored as a packed triangular*> matrix overwriting A (see below for further details).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D.*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and*> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)*> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =*> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were*> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) is exactly zero. The factorization*> has been completed, but the block diagonal matrix D is*> exactly singular, and division by zero will occur if it*> is used to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', then A = U*D*U**T, where*> U = P(n)*U(n)* ... *P(k)U(k)* ...,*> i.e., U is a product of terms P(k)*U(k), where k decreases from n to*> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1*> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as*> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such*> that if the diagonal block D(k) is of order s (s = 1 or 2), then*>*> ( I v 0 ) k-s*> U(k) = ( 0 I 0 ) s*> ( 0 0 I ) n-k*> k-s s n-k*>*> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).*> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),*> and A(k,k), and v overwrites A(1:k-2,k-1:k).*>*> If UPLO = 'L', then A = L*D*L**T, where*> L = P(1)*L(1)* ... *P(k)*L(k)* ...,*> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to*> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1*> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as*> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such*> that if the diagonal block D(k) is of order s (s = 1 or 2), then*>*> ( I 0 0 ) k-1*> L(k) = ( 0 I 0 ) s*> ( 0 v I ) n-k-s+1*> k-1 s n-k-s+1*>*> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).*> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),*> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).*> \endverbatim**> \par Contributors:* ==================*>*> J. Lewis, Boeing Computer Services Company*>* =====================================================================SUBROUTINE DSPTRF( UPLO, N, AP, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION EIGHT, SEVTENPARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IMAX, J, JMAX, K, KC, KK, KNC, KP, KPC,$ KSTEP, KX, NPPDOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D11, D12, D21, D22, R1,$ ROWMAX, T, WK, WKM1, WKP1* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXEXTERNAL LSAME, IDAMAX* ..* .. External Subroutines ..EXTERNAL DSCAL, DSPR, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPTRF', -INFO )RETURNEND IF** Initialize ALPHA for use in choosing pivot block size.*ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT*IF( UPPER ) THEN** Factorize A as U*D*U**T using the upper triangle of A** K is the main loop index, decreasing from N to 1 in steps of* 1 or 2*K = NKC = ( N-1 )*N / 2 + 110 CONTINUEKNC = KC** If K < 1, exit from loop*IF( K.LT.1 )$ GO TO 110KSTEP = 1** Determine rows and columns to be interchanged and whether* a 1-by-1 or 2-by-2 pivot block will be used*ABSAKK = ABS( AP( KC+K-1 ) )** IMAX is the row-index of the largest off-diagonal element in* column K, and COLMAX is its absolute value*IF( K.GT.1 ) THENIMAX = IDAMAX( K-1, AP( KC ), 1 )COLMAX = ABS( AP( KC+IMAX-1 ) )ELSECOLMAX = ZEROEND IF*IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN** Column K is zero: set INFO and continue*IF( INFO.EQ.0 )$ INFO = KKP = KELSEIF( ABSAKK.GE.ALPHA*COLMAX ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE*ROWMAX = ZEROJMAX = IMAXKX = IMAX*( IMAX+1 ) / 2 + IMAXDO 20 J = IMAX + 1, KIF( ABS( AP( KX ) ).GT.ROWMAX ) THENROWMAX = ABS( AP( KX ) )JMAX = JEND IFKX = KX + J20 CONTINUEKPC = ( IMAX-1 )*IMAX / 2 + 1IF( IMAX.GT.1 ) THENJMAX = IDAMAX( IMAX-1, AP( KPC ), 1 )ROWMAX = MAX( ROWMAX, ABS( AP( KPC+JMAX-1 ) ) )END IF*IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE IF( ABS( AP( KPC+IMAX-1 ) ).GE.ALPHA*ROWMAX ) THEN** interchange rows and columns K and IMAX, use 1-by-1* pivot block*KP = IMAXELSE** interchange rows and columns K-1 and IMAX, use 2-by-2* pivot block*KP = IMAXKSTEP = 2END IFEND IF*KK = K - KSTEP + 1IF( KSTEP.EQ.2 )$ KNC = KNC - K + 1IF( KP.NE.KK ) THEN** Interchange rows and columns KK and KP in the leading* submatrix A(1:k,1:k)*CALL DSWAP( KP-1, AP( KNC ), 1, AP( KPC ), 1 )KX = KPC + KP - 1DO 30 J = KP + 1, KK - 1KX = KX + J - 1T = AP( KNC+J-1 )AP( KNC+J-1 ) = AP( KX )AP( KX ) = T30 CONTINUET = AP( KNC+KK-1 )AP( KNC+KK-1 ) = AP( KPC+KP-1 )AP( KPC+KP-1 ) = TIF( KSTEP.EQ.2 ) THENT = AP( KC+K-2 )AP( KC+K-2 ) = AP( KC+KP-1 )AP( KC+KP-1 ) = TEND IFEND IF** Update the leading submatrix*IF( KSTEP.EQ.1 ) THEN** 1-by-1 pivot block D(k): column k now holds** W(k) = U(k)*D(k)** where U(k) is the k-th column of U** Perform a rank-1 update of A(1:k-1,1:k-1) as** A := A - U(k)*D(k)*U(k)**T = A - W(k)*1/D(k)*W(k)**T*R1 = ONE / AP( KC+K-1 )CALL DSPR( UPLO, K-1, -R1, AP( KC ), 1, AP )** Store U(k) in column k*CALL DSCAL( K-1, R1, AP( KC ), 1 )ELSE** 2-by-2 pivot block D(k): columns k and k-1 now hold** ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)** where U(k) and U(k-1) are the k-th and (k-1)-th columns* of U** Perform a rank-2 update of A(1:k-2,1:k-2) as** A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T* = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )**T*IF( K.GT.2 ) THEN*D12 = AP( K-1+( K-1 )*K / 2 )D22 = AP( K-1+( K-2 )*( K-1 ) / 2 ) / D12D11 = AP( K+( K-1 )*K / 2 ) / D12T = ONE / ( D11*D22-ONE )D12 = T / D12*DO 50 J = K - 2, 1, -1WKM1 = D12*( D11*AP( J+( K-2 )*( K-1 ) / 2 )-$ AP( J+( K-1 )*K / 2 ) )WK = D12*( D22*AP( J+( K-1 )*K / 2 )-$ AP( J+( K-2 )*( K-1 ) / 2 ) )DO 40 I = J, 1, -1AP( I+( J-1 )*J / 2 ) = AP( I+( J-1 )*J / 2 ) -$ AP( I+( K-1 )*K / 2 )*WK -$ AP( I+( K-2 )*( K-1 ) / 2 )*WKM140 CONTINUEAP( J+( K-1 )*K / 2 ) = WKAP( J+( K-2 )*( K-1 ) / 2 ) = WKM150 CONTINUE*END IF*END IFEND IF** Store details of the interchanges in IPIV*IF( KSTEP.EQ.1 ) THENIPIV( K ) = KPELSEIPIV( K ) = -KPIPIV( K-1 ) = -KPEND IF** Decrease K and return to the start of the main loop*K = K - KSTEPKC = KNC - KGO TO 10*ELSE** Factorize A as L*D*L**T using the lower triangle of A** K is the main loop index, increasing from 1 to N in steps of* 1 or 2*K = 1KC = 1NPP = N*( N+1 ) / 260 CONTINUEKNC = KC** If K > N, exit from loop*IF( K.GT.N )$ GO TO 110KSTEP = 1** Determine rows and columns to be interchanged and whether* a 1-by-1 or 2-by-2 pivot block will be used*ABSAKK = ABS( AP( KC ) )** IMAX is the row-index of the largest off-diagonal element in* column K, and COLMAX is its absolute value*IF( K.LT.N ) THENIMAX = K + IDAMAX( N-K, AP( KC+1 ), 1 )COLMAX = ABS( AP( KC+IMAX-K ) )ELSECOLMAX = ZEROEND IF*IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN** Column K is zero: set INFO and continue*IF( INFO.EQ.0 )$ INFO = KKP = KELSEIF( ABSAKK.GE.ALPHA*COLMAX ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE** JMAX is the column-index of the largest off-diagonal* element in row IMAX, and ROWMAX is its absolute value*ROWMAX = ZEROKX = KC + IMAX - KDO 70 J = K, IMAX - 1IF( ABS( AP( KX ) ).GT.ROWMAX ) THENROWMAX = ABS( AP( KX ) )JMAX = JEND IFKX = KX + N - J70 CONTINUEKPC = NPP - ( N-IMAX+1 )*( N-IMAX+2 ) / 2 + 1IF( IMAX.LT.N ) THENJMAX = IMAX + IDAMAX( N-IMAX, AP( KPC+1 ), 1 )ROWMAX = MAX( ROWMAX, ABS( AP( KPC+JMAX-IMAX ) ) )END IF*IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE IF( ABS( AP( KPC ) ).GE.ALPHA*ROWMAX ) THEN** interchange rows and columns K and IMAX, use 1-by-1* pivot block*KP = IMAXELSE** interchange rows and columns K+1 and IMAX, use 2-by-2* pivot block*KP = IMAXKSTEP = 2END IFEND IF*KK = K + KSTEP - 1IF( KSTEP.EQ.2 )$ KNC = KNC + N - K + 1IF( KP.NE.KK ) THEN** Interchange rows and columns KK and KP in the trailing* submatrix A(k:n,k:n)*IF( KP.LT.N )$ CALL DSWAP( N-KP, AP( KNC+KP-KK+1 ), 1, AP( KPC+1 ),$ 1 )KX = KNC + KP - KKDO 80 J = KK + 1, KP - 1KX = KX + N - J + 1T = AP( KNC+J-KK )AP( KNC+J-KK ) = AP( KX )AP( KX ) = T80 CONTINUET = AP( KNC )AP( KNC ) = AP( KPC )AP( KPC ) = TIF( KSTEP.EQ.2 ) THENT = AP( KC+1 )AP( KC+1 ) = AP( KC+KP-K )AP( KC+KP-K ) = TEND IFEND IF** Update the trailing submatrix*IF( KSTEP.EQ.1 ) THEN** 1-by-1 pivot block D(k): column k now holds** W(k) = L(k)*D(k)** where L(k) is the k-th column of L*IF( K.LT.N ) THEN** Perform a rank-1 update of A(k+1:n,k+1:n) as** A := A - L(k)*D(k)*L(k)**T = A - W(k)*(1/D(k))*W(k)**T*R1 = ONE / AP( KC )CALL DSPR( UPLO, N-K, -R1, AP( KC+1 ), 1,$ AP( KC+N-K+1 ) )** Store L(k) in column K*CALL DSCAL( N-K, R1, AP( KC+1 ), 1 )END IFELSE** 2-by-2 pivot block D(k): columns K and K+1 now hold** ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k)** where L(k) and L(k+1) are the k-th and (k+1)-th columns* of L*IF( K.LT.N-1 ) THEN** Perform a rank-2 update of A(k+2:n,k+2:n) as** A := A - ( L(k) L(k+1) )*D(k)*( L(k) L(k+1) )**T* = A - ( W(k) W(k+1) )*inv(D(k))*( W(k) W(k+1) )**T** where L(k) and L(k+1) are the k-th and (k+1)-th* columns of L*D21 = AP( K+1+( K-1 )*( 2*N-K ) / 2 )D11 = AP( K+1+K*( 2*N-K-1 ) / 2 ) / D21D22 = AP( K+( K-1 )*( 2*N-K ) / 2 ) / D21T = ONE / ( D11*D22-ONE )D21 = T / D21*DO 100 J = K + 2, NWK = D21*( D11*AP( J+( K-1 )*( 2*N-K ) / 2 )-$ AP( J+K*( 2*N-K-1 ) / 2 ) )WKP1 = D21*( D22*AP( J+K*( 2*N-K-1 ) / 2 )-$ AP( J+( K-1 )*( 2*N-K ) / 2 ) )*DO 90 I = J, NAP( I+( J-1 )*( 2*N-J ) / 2 ) = AP( I+( J-1 )*$ ( 2*N-J ) / 2 ) - AP( I+( K-1 )*( 2*N-K ) /$ 2 )*WK - AP( I+K*( 2*N-K-1 ) / 2 )*WKP190 CONTINUE*AP( J+( K-1 )*( 2*N-K ) / 2 ) = WKAP( J+K*( 2*N-K-1 ) / 2 ) = WKP1*100 CONTINUEEND IFEND IFEND IF** Store details of the interchanges in IPIV*IF( KSTEP.EQ.1 ) THENIPIV( K ) = KPELSEIPIV( K ) = -KPIPIV( K+1 ) = -KPEND IF** Increase K and return to the start of the main loop*K = K + KSTEPKC = KNC + N - K + 2GO TO 60*END IF*110 CONTINUERETURN** End of DSPTRF*END*> \brief \b DSPTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsptri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsptri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsptri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPTRI( UPLO, N, AP, IPIV, WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPTRI computes the inverse of a real symmetric indefinite matrix*> A in packed storage using the factorization A = U*D*U**T or*> A = L*D*L**T computed by DSPTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the block diagonal matrix D and the multipliers*> used to obtain the factor U or L as computed by DSPTRF,*> stored as a packed triangular matrix.*>*> On exit, if INFO = 0, the (symmetric) inverse of the original*> matrix, stored as a packed triangular matrix. The j-th column*> of inv(A) is stored in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = inv(A)(i,j) for 1<=i<=j;*> if UPLO = 'L',*> AP(i + (j-1)*(2n-j)/2) = inv(A)(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSPTRF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its*> inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSPTRI( UPLO, N, AP, IPIV, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, K, KC, KCNEXT, KP, KPC, KSTEP, KX, NPPDOUBLE PRECISION AK, AKKP1, AKP1, D, T, TEMP* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. External Subroutines ..EXTERNAL DCOPY, DSPMV, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Check that the diagonal matrix D is nonsingular.*IF( UPPER ) THEN** Upper triangular storage: examine D from bottom to top*KP = N*( N+1 ) / 2DO 10 INFO = N, 1, -1IF( IPIV( INFO ).GT.0 .AND. AP( KP ).EQ.ZERO )$ RETURNKP = KP - INFO10 CONTINUEELSE** Lower triangular storage: examine D from top to bottom.*KP = 1DO 20 INFO = 1, NIF( IPIV( INFO ).GT.0 .AND. AP( KP ).EQ.ZERO )$ RETURNKP = KP + N - INFO + 120 CONTINUEEND IFINFO = 0*IF( UPPER ) THEN** Compute inv(A) from the factorization A = U*D*U**T.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = 1KC = 130 CONTINUE** If K > N, exit from loop.*IF( K.GT.N )$ GO TO 50*KCNEXT = KC + KIF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Invert the diagonal block.*AP( KC+K-1 ) = ONE / AP( KC+K-1 )** Compute column K of the inverse.*IF( K.GT.1 ) THENCALL DCOPY( K-1, AP( KC ), 1, WORK, 1 )CALL DSPMV( UPLO, K-1, -ONE, AP, WORK, 1, ZERO, AP( KC ),$ 1 )AP( KC+K-1 ) = AP( KC+K-1 ) -$ DDOT( K-1, WORK, 1, AP( KC ), 1 )END IFKSTEP = 1ELSE** 2 x 2 diagonal block** Invert the diagonal block.*T = ABS( AP( KCNEXT+K-1 ) )AK = AP( KC+K-1 ) / TAKP1 = AP( KCNEXT+K ) / TAKKP1 = AP( KCNEXT+K-1 ) / TD = T*( AK*AKP1-ONE )AP( KC+K-1 ) = AKP1 / DAP( KCNEXT+K ) = AK / DAP( KCNEXT+K-1 ) = -AKKP1 / D** Compute columns K and K+1 of the inverse.*IF( K.GT.1 ) THENCALL DCOPY( K-1, AP( KC ), 1, WORK, 1 )CALL DSPMV( UPLO, K-1, -ONE, AP, WORK, 1, ZERO, AP( KC ),$ 1 )AP( KC+K-1 ) = AP( KC+K-1 ) -$ DDOT( K-1, WORK, 1, AP( KC ), 1 )AP( KCNEXT+K-1 ) = AP( KCNEXT+K-1 ) -$ DDOT( K-1, AP( KC ), 1, AP( KCNEXT ),$ 1 )CALL DCOPY( K-1, AP( KCNEXT ), 1, WORK, 1 )CALL DSPMV( UPLO, K-1, -ONE, AP, WORK, 1, ZERO,$ AP( KCNEXT ), 1 )AP( KCNEXT+K ) = AP( KCNEXT+K ) -$ DDOT( K-1, WORK, 1, AP( KCNEXT ), 1 )END IFKSTEP = 2KCNEXT = KCNEXT + K + 1END IF*KP = ABS( IPIV( K ) )IF( KP.NE.K ) THEN** Interchange rows and columns K and KP in the leading* submatrix A(1:k+1,1:k+1)*KPC = ( KP-1 )*KP / 2 + 1CALL DSWAP( KP-1, AP( KC ), 1, AP( KPC ), 1 )KX = KPC + KP - 1DO 40 J = KP + 1, K - 1KX = KX + J - 1TEMP = AP( KC+J-1 )AP( KC+J-1 ) = AP( KX )AP( KX ) = TEMP40 CONTINUETEMP = AP( KC+K-1 )AP( KC+K-1 ) = AP( KPC+KP-1 )AP( KPC+KP-1 ) = TEMPIF( KSTEP.EQ.2 ) THENTEMP = AP( KC+K+K-1 )AP( KC+K+K-1 ) = AP( KC+K+KP-1 )AP( KC+K+KP-1 ) = TEMPEND IFEND IF*K = K + KSTEPKC = KCNEXTGO TO 3050 CONTINUE*ELSE** Compute inv(A) from the factorization A = L*D*L**T.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*NPP = N*( N+1 ) / 2K = NKC = NPP60 CONTINUE** If K < 1, exit from loop.*IF( K.LT.1 )$ GO TO 80*KCNEXT = KC - ( N-K+2 )IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Invert the diagonal block.*AP( KC ) = ONE / AP( KC )** Compute column K of the inverse.*IF( K.LT.N ) THENCALL DCOPY( N-K, AP( KC+1 ), 1, WORK, 1 )CALL DSPMV( UPLO, N-K, -ONE, AP( KC+N-K+1 ), WORK, 1,$ ZERO, AP( KC+1 ), 1 )AP( KC ) = AP( KC ) - DDOT( N-K, WORK, 1, AP( KC+1 ), 1 )END IFKSTEP = 1ELSE** 2 x 2 diagonal block** Invert the diagonal block.*T = ABS( AP( KCNEXT+1 ) )AK = AP( KCNEXT ) / TAKP1 = AP( KC ) / TAKKP1 = AP( KCNEXT+1 ) / TD = T*( AK*AKP1-ONE )AP( KCNEXT ) = AKP1 / DAP( KC ) = AK / DAP( KCNEXT+1 ) = -AKKP1 / D** Compute columns K-1 and K of the inverse.*IF( K.LT.N ) THENCALL DCOPY( N-K, AP( KC+1 ), 1, WORK, 1 )CALL DSPMV( UPLO, N-K, -ONE, AP( KC+( N-K+1 ) ), WORK, 1,$ ZERO, AP( KC+1 ), 1 )AP( KC ) = AP( KC ) - DDOT( N-K, WORK, 1, AP( KC+1 ), 1 )AP( KCNEXT+1 ) = AP( KCNEXT+1 ) -$ DDOT( N-K, AP( KC+1 ), 1,$ AP( KCNEXT+2 ), 1 )CALL DCOPY( N-K, AP( KCNEXT+2 ), 1, WORK, 1 )CALL DSPMV( UPLO, N-K, -ONE, AP( KC+( N-K+1 ) ), WORK, 1,$ ZERO, AP( KCNEXT+2 ), 1 )AP( KCNEXT ) = AP( KCNEXT ) -$ DDOT( N-K, WORK, 1, AP( KCNEXT+2 ), 1 )END IFKSTEP = 2KCNEXT = KCNEXT - ( N-K+3 )END IF*KP = ABS( IPIV( K ) )IF( KP.NE.K ) THEN** Interchange rows and columns K and KP in the trailing* submatrix A(k-1:n,k-1:n)*KPC = NPP - ( N-KP+1 )*( N-KP+2 ) / 2 + 1IF( KP.LT.N )$ CALL DSWAP( N-KP, AP( KC+KP-K+1 ), 1, AP( KPC+1 ), 1 )KX = KC + KP - KDO 70 J = K + 1, KP - 1KX = KX + N - J + 1TEMP = AP( KC+J-K )AP( KC+J-K ) = AP( KX )AP( KX ) = TEMP70 CONTINUETEMP = AP( KC )AP( KC ) = AP( KPC )AP( KPC ) = TEMPIF( KSTEP.EQ.2 ) THENTEMP = AP( KC-N+K-1 )AP( KC-N+K-1 ) = AP( KC-N+KP-1 )AP( KC-N+KP-1 ) = TEMPEND IFEND IF*K = K - KSTEPKC = KCNEXTGO TO 6080 CONTINUEEND IF*RETURN** End of DSPTRI*END*> \brief \b DSPTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSPTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsptrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsptrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsptrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSPTRS( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION AP( * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSPTRS solves a system of linear equations A*X = B with a real*> symmetric matrix A stored in packed format using the factorization*> A = U*D*U**T or A = L*D*L**T computed by DSPTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The block diagonal matrix D and the multipliers used to*> obtain the factor U or L as computed by DSPTRF, stored as a*> packed triangular matrix.*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSPTRF.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSPTRS( UPLO, N, NRHS, AP, IPIV, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION AP( * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, K, KC, KPDOUBLE PRECISION AK, AKM1, AKM1K, BK, BKM1, DENOM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSPTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( UPPER ) THEN** Solve A*X = B, where A = U*D*U**T.** First solve U*D*X = B, overwriting B with X.** K is the main loop index, decreasing from N to 1 in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = NKC = N*( N+1 ) / 2 + 110 CONTINUE** If K < 1, exit from loop.*IF( K.LT.1 )$ GO TO 30*KC = KC - KIF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(U(K)), where U(K) is the transformation* stored in column K of A.*CALL DGER( K-1, NRHS, -ONE, AP( KC ), 1, B( K, 1 ), LDB,$ B( 1, 1 ), LDB )** Multiply by the inverse of the diagonal block.*CALL DSCAL( NRHS, ONE / AP( KC+K-1 ), B( K, 1 ), LDB )K = K - 1ELSE** 2 x 2 diagonal block** Interchange rows K-1 and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K-1 )$ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(U(K)), where U(K) is the transformation* stored in columns K-1 and K of A.*CALL DGER( K-2, NRHS, -ONE, AP( KC ), 1, B( K, 1 ), LDB,$ B( 1, 1 ), LDB )CALL DGER( K-2, NRHS, -ONE, AP( KC-( K-1 ) ), 1,$ B( K-1, 1 ), LDB, B( 1, 1 ), LDB )** Multiply by the inverse of the diagonal block.*AKM1K = AP( KC+K-2 )AKM1 = AP( KC-1 ) / AKM1KAK = AP( KC+K-1 ) / AKM1KDENOM = AKM1*AK - ONEDO 20 J = 1, NRHSBKM1 = B( K-1, J ) / AKM1KBK = B( K, J ) / AKM1KB( K-1, J ) = ( AK*BKM1-BK ) / DENOMB( K, J ) = ( AKM1*BK-BKM1 ) / DENOM20 CONTINUEKC = KC - K + 1K = K - 2END IF*GO TO 1030 CONTINUE** Next solve U**T*X = B, overwriting B with X.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = 1KC = 140 CONTINUE** If K > N, exit from loop.*IF( K.GT.N )$ GO TO 50*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Multiply by inv(U**T(K)), where U(K) is the transformation* stored in column K of A.*CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, LDB, AP( KC ),$ 1, ONE, B( K, 1 ), LDB )** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )KC = KC + KK = K + 1ELSE** 2 x 2 diagonal block** Multiply by inv(U**T(K+1)), where U(K+1) is the transformation* stored in columns K and K+1 of A.*CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, LDB, AP( KC ),$ 1, ONE, B( K, 1 ), LDB )CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, LDB,$ AP( KC+K ), 1, ONE, B( K+1, 1 ), LDB )** Interchange rows K and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )KC = KC + 2*K + 1K = K + 2END IF*GO TO 4050 CONTINUE*ELSE** Solve A*X = B, where A = L*D*L**T.** First solve L*D*X = B, overwriting B with X.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = 1KC = 160 CONTINUE** If K > N, exit from loop.*IF( K.GT.N )$ GO TO 80*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(L(K)), where L(K) is the transformation* stored in column K of A.*IF( K.LT.N )$ CALL DGER( N-K, NRHS, -ONE, AP( KC+1 ), 1, B( K, 1 ),$ LDB, B( K+1, 1 ), LDB )** Multiply by the inverse of the diagonal block.*CALL DSCAL( NRHS, ONE / AP( KC ), B( K, 1 ), LDB )KC = KC + N - K + 1K = K + 1ELSE** 2 x 2 diagonal block** Interchange rows K+1 and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K+1 )$ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(L(K)), where L(K) is the transformation* stored in columns K and K+1 of A.*IF( K.LT.N-1 ) THENCALL DGER( N-K-1, NRHS, -ONE, AP( KC+2 ), 1, B( K, 1 ),$ LDB, B( K+2, 1 ), LDB )CALL DGER( N-K-1, NRHS, -ONE, AP( KC+N-K+2 ), 1,$ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB )END IF** Multiply by the inverse of the diagonal block.*AKM1K = AP( KC+1 )AKM1 = AP( KC ) / AKM1KAK = AP( KC+N-K+1 ) / AKM1KDENOM = AKM1*AK - ONEDO 70 J = 1, NRHSBKM1 = B( K, J ) / AKM1KBK = B( K+1, J ) / AKM1KB( K, J ) = ( AK*BKM1-BK ) / DENOMB( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM70 CONTINUEKC = KC + 2*( N-K ) + 1K = K + 2END IF*GO TO 6080 CONTINUE** Next solve L**T*X = B, overwriting B with X.** K is the main loop index, decreasing from N to 1 in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = NKC = N*( N+1 ) / 2 + 190 CONTINUE** If K < 1, exit from loop.*IF( K.LT.1 )$ GO TO 100*KC = KC - ( N-K+1 )IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Multiply by inv(L**T(K)), where L(K) is the transformation* stored in column K of A.*IF( K.LT.N )$ CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ),$ LDB, AP( KC+1 ), 1, ONE, B( K, 1 ), LDB )** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K = K - 1ELSE** 2 x 2 diagonal block** Multiply by inv(L**T(K-1)), where L(K-1) is the transformation* stored in columns K-1 and K of A.*IF( K.LT.N ) THENCALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ),$ LDB, AP( KC+1 ), 1, ONE, B( K, 1 ), LDB )CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ),$ LDB, AP( KC-( N-K ) ), 1, ONE, B( K-1, 1 ),$ LDB )END IF** Interchange rows K and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )KC = KC - ( N-K+2 )K = K - 2END IF*GO TO 90100 CONTINUEEND IF*RETURN** End of DSPTRS*END*> \brief \b DSTEBZ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEBZ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstebz.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstebz.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstebz.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E,* M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER ORDER, RANGE* INTEGER IL, INFO, IU, M, N, NSPLIT* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEBZ computes the eigenvalues of a symmetric tridiagonal*> matrix T. The user may ask for all eigenvalues, all eigenvalues*> in the half-open interval (VL, VU], or the IL-th through IU-th*> eigenvalues.*>*> To avoid overflow, the matrix must be scaled so that its*> largest element is no greater than overflow**(1/2) * underflow**(1/4) in absolute value, and for greatest*> accuracy, it should not be much smaller than that.*>*> See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal*> Matrix", Report CS41, Computer Science Dept., Stanford*> University, July 21, 1966.*> \endverbatim** Arguments:* ==========**> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': ("All") all eigenvalues will be found.*> = 'V': ("Value") all eigenvalues in the half-open interval*> (VL, VU] will be found.*> = 'I': ("Index") the IL-th through IU-th eigenvalues (of the*> entire matrix) will be found.*> \endverbatim*>*> \param[in] ORDER*> \verbatim*> ORDER is CHARACTER*1*> = 'B': ("By Block") the eigenvalues will be grouped by*> split-off block (see IBLOCK, ISPLIT) and*> ordered from smallest to largest within*> the block.*> = 'E': ("Entire matrix")*> the eigenvalues for the entire matrix*> will be ordered from smallest to*> largest.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the tridiagonal matrix T. N >= 0.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*>*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. Eigenvalues less than or equal*> to VL, or greater than VU, will not be returned. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*>*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. Eigenvalues less than or equal*> to VL, or greater than VU, will not be returned. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*>*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*>*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute tolerance for the eigenvalues. An eigenvalue*> (or cluster) is considered to be located if it has been*> determined to lie in an interval whose width is ABSTOL or*> less. If ABSTOL is less than or equal to zero, then ULP*|T|*> will be used, where |T| means the 1-norm of T.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) off-diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The actual number of eigenvalues found. 0 <= M <= N.*> (See also the description of INFO=2,3.)*> \endverbatim*>*> \param[out] NSPLIT*> \verbatim*> NSPLIT is INTEGER*> The number of diagonal blocks in the matrix T.*> 1 <= NSPLIT <= N.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On exit, the first M elements of W will contain the*> eigenvalues. (DSTEBZ may use the remaining N-M elements as*> workspace.)*> \endverbatim*>*> \param[out] IBLOCK*> \verbatim*> IBLOCK is INTEGER array, dimension (N)*> At each row/column j where E(j) is zero or small, the*> matrix T is considered to split into a block diagonal*> matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which*> block (from 1 to the number of blocks) the eigenvalue W(i)*> belongs. (DSTEBZ may use the remaining N-M elements as*> workspace.)*> \endverbatim*>*> \param[out] ISPLIT*> \verbatim*> ISPLIT is INTEGER array, dimension (N)*> The splitting points, at which T breaks up into submatrices.*> The first submatrix consists of rows/columns 1 to ISPLIT(1),*> the second of rows/columns ISPLIT(1)+1 through ISPLIT(2),*> etc., and the NSPLIT-th consists of rows/columns*> ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N.*> (Only the first NSPLIT elements will actually be used, but*> since the user cannot know a priori what value NSPLIT will*> have, N words must be reserved for ISPLIT.)*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (4*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: some or all of the eigenvalues failed to converge or*> were not computed:*> =1 or 3: Bisection failed to converge for some*> eigenvalues; these eigenvalues are flagged by a*> negative block number. The effect is that the*> eigenvalues may not be as accurate as the*> absolute and relative tolerances. This is*> generally caused by unexpectedly inaccurate*> arithmetic.*> =2 or 3: RANGE='I' only: Not all of the eigenvalues*> IL:IU were found.*> Effect: M < IU+1-IL*> Cause: non-monotonic arithmetic, causing the*> Sturm sequence to be non-monotonic.*> Cure: recalculate, using RANGE='A', and pick*> out eigenvalues IL:IU. In some cases,*> increasing the PARAMETER "FUDGE" may*> make things work.*> = 4: RANGE='I', and the Gershgorin interval*> initially used was too small. No eigenvalues*> were computed.*> Probable cause: your machine has sloppy*> floating-point arithmetic.*> Cure: Increase the PARAMETER "FUDGE",*> recompile, and try again.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> RELFAC DOUBLE PRECISION, default = 2.0e0*> The relative tolerance. An interval (a,b] lies within*> "relative tolerance" if b-a < RELFAC*ulp*max(|a|,|b|),*> where "ulp" is the machine precision (distance from 1 to*> the next larger floating point number.)*>*> FUDGE DOUBLE PRECISION, default = 2*> A "fudge factor" to widen the Gershgorin intervals. Ideally,*> a value of 1 should work, but on machines with sloppy*> arithmetic, this needs to be larger. The default for*> publicly released versions should be large enough to handle*> the worst machine around. Note that this has no effect*> on accuracy of the solution.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DSTEBZ( RANGE, ORDER, N, VL, VU, IL, IU, ABSTOL, D, E,$ M, NSPLIT, W, IBLOCK, ISPLIT, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER ORDER, RANGEINTEGER IL, INFO, IU, M, N, NSPLITDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IBLOCK( * ), ISPLIT( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, HALFPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ HALF = 1.0D0 / TWO )DOUBLE PRECISION FUDGE, RELFACPARAMETER ( FUDGE = 2.1D0, RELFAC = 2.0D0 )* ..* .. Local Scalars ..LOGICAL NCNVRG, TOOFEWINTEGER IB, IBEGIN, IDISCL, IDISCU, IE, IEND, IINFO,$ IM, IN, IOFF, IORDER, IOUT, IRANGE, ITMAX,$ ITMP1, IW, IWOFF, J, JB, JDISC, JE, NB, NWL,$ NWUDOUBLE PRECISION ATOLI, BNORM, GL, GU, PIVMIN, RTOLI, SAFEMN,$ TMP1, TMP2, TNORM, ULP, WKILL, WL, WLU, WU, WUL* ..* .. Local Arrays ..INTEGER IDUMMA( 1 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCHEXTERNAL LSAME, ILAENV, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLAEBZ, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT* ..* .. Executable Statements ..*INFO = 0** Decode RANGE*IF( LSAME( RANGE, 'A' ) ) THENIRANGE = 1ELSE IF( LSAME( RANGE, 'V' ) ) THENIRANGE = 2ELSE IF( LSAME( RANGE, 'I' ) ) THENIRANGE = 3ELSEIRANGE = 0END IF** Decode ORDER*IF( LSAME( ORDER, 'B' ) ) THENIORDER = 2ELSE IF( LSAME( ORDER, 'E' ) ) THENIORDER = 1ELSEIORDER = 0END IF** Check for Errors*IF( IRANGE.LE.0 ) THENINFO = -1ELSE IF( IORDER.LE.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( IRANGE.EQ.2 ) THENIF( VL.GE.VU )$ INFO = -5ELSE IF( IRANGE.EQ.3 .AND. ( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) )$ THENINFO = -6ELSE IF( IRANGE.EQ.3 .AND. ( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) )$ THENINFO = -7END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEBZ', -INFO )RETURNEND IF** Initialize error flags*INFO = 0NCNVRG = .FALSE.TOOFEW = .FALSE.** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN** Simplifications:*IF( IRANGE.EQ.3 .AND. IL.EQ.1 .AND. IU.EQ.N )$ IRANGE = 1** Get machine constants* NB is the minimum vector length for vector bisection, or 0* if only scalar is to be done.*SAFEMN = DLAMCH( 'S' )ULP = DLAMCH( 'P' )RTOLI = ULP*RELFACNB = ILAENV( 1, 'DSTEBZ', ' ', N, -1, -1, -1 )IF( NB.LE.1 )$ NB = 0** Special Case when N=1*IF( N.EQ.1 ) THENNSPLIT = 1ISPLIT( 1 ) = 1IF( IRANGE.EQ.2 .AND. ( VL.GE.D( 1 ) .OR. VU.LT.D( 1 ) ) ) THENM = 0ELSEW( 1 ) = D( 1 )IBLOCK( 1 ) = 1M = 1END IFRETURNEND IF** Compute Splitting Points*NSPLIT = 1WORK( N ) = ZEROPIVMIN = ONE*DO 10 J = 2, NTMP1 = E( J-1 )**2IF( ABS( D( J )*D( J-1 ) )*ULP**2+SAFEMN.GT.TMP1 ) THENISPLIT( NSPLIT ) = J - 1NSPLIT = NSPLIT + 1WORK( J-1 ) = ZEROELSEWORK( J-1 ) = TMP1PIVMIN = MAX( PIVMIN, TMP1 )END IF10 CONTINUEISPLIT( NSPLIT ) = NPIVMIN = PIVMIN*SAFEMN** Compute Interval and ATOLI*IF( IRANGE.EQ.3 ) THEN** RANGE='I': Compute the interval containing eigenvalues* IL through IU.** Compute Gershgorin interval for entire (split) matrix* and use it as the initial interval*GU = D( 1 )GL = D( 1 )TMP1 = ZERO*DO 20 J = 1, N - 1TMP2 = SQRT( WORK( J ) )GU = MAX( GU, D( J )+TMP1+TMP2 )GL = MIN( GL, D( J )-TMP1-TMP2 )TMP1 = TMP220 CONTINUE*GU = MAX( GU, D( N )+TMP1 )GL = MIN( GL, D( N )-TMP1 )TNORM = MAX( ABS( GL ), ABS( GU ) )GL = GL - FUDGE*TNORM*ULP*N - FUDGE*TWO*PIVMINGU = GU + FUDGE*TNORM*ULP*N + FUDGE*PIVMIN** Compute Iteration parameters*ITMAX = INT( ( LOG( TNORM+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2IF( ABSTOL.LE.ZERO ) THENATOLI = ULP*TNORMELSEATOLI = ABSTOLEND IF*WORK( N+1 ) = GLWORK( N+2 ) = GLWORK( N+3 ) = GUWORK( N+4 ) = GUWORK( N+5 ) = GLWORK( N+6 ) = GUIWORK( 1 ) = -1IWORK( 2 ) = -1IWORK( 3 ) = N + 1IWORK( 4 ) = N + 1IWORK( 5 ) = IL - 1IWORK( 6 ) = IU*CALL DLAEBZ( 3, ITMAX, N, 2, 2, NB, ATOLI, RTOLI, PIVMIN, D, E,$ WORK, IWORK( 5 ), WORK( N+1 ), WORK( N+5 ), IOUT,$ IWORK, W, IBLOCK, IINFO )*IF( IWORK( 6 ).EQ.IU ) THENWL = WORK( N+1 )WLU = WORK( N+3 )NWL = IWORK( 1 )WU = WORK( N+4 )WUL = WORK( N+2 )NWU = IWORK( 4 )ELSEWL = WORK( N+2 )WLU = WORK( N+4 )NWL = IWORK( 2 )WU = WORK( N+3 )WUL = WORK( N+1 )NWU = IWORK( 3 )END IF*IF( NWL.LT.0 .OR. NWL.GE.N .OR. NWU.LT.1 .OR. NWU.GT.N ) THENINFO = 4RETURNEND IFELSE** RANGE='A' or 'V' -- Set ATOLI*TNORM = MAX( ABS( D( 1 ) )+ABS( E( 1 ) ),$ ABS( D( N ) )+ABS( E( N-1 ) ) )*DO 30 J = 2, N - 1TNORM = MAX( TNORM, ABS( D( J ) )+ABS( E( J-1 ) )+$ ABS( E( J ) ) )30 CONTINUE*IF( ABSTOL.LE.ZERO ) THENATOLI = ULP*TNORMELSEATOLI = ABSTOLEND IF*IF( IRANGE.EQ.2 ) THENWL = VLWU = VUELSEWL = ZEROWU = ZEROEND IFEND IF** Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU.* NWL accumulates the number of eigenvalues .le. WL,* NWU accumulates the number of eigenvalues .le. WU*M = 0IEND = 0INFO = 0NWL = 0NWU = 0*DO 70 JB = 1, NSPLITIOFF = IENDIBEGIN = IOFF + 1IEND = ISPLIT( JB )IN = IEND - IOFF*IF( IN.EQ.1 ) THEN** Special Case -- IN=1*IF( IRANGE.EQ.1 .OR. WL.GE.D( IBEGIN )-PIVMIN )$ NWL = NWL + 1IF( IRANGE.EQ.1 .OR. WU.GE.D( IBEGIN )-PIVMIN )$ NWU = NWU + 1IF( IRANGE.EQ.1 .OR. ( WL.LT.D( IBEGIN )-PIVMIN .AND. WU.GE.$ D( IBEGIN )-PIVMIN ) ) THENM = M + 1W( M ) = D( IBEGIN )IBLOCK( M ) = JBEND IFELSE** General Case -- IN > 1** Compute Gershgorin Interval* and use it as the initial interval*GU = D( IBEGIN )GL = D( IBEGIN )TMP1 = ZERO*DO 40 J = IBEGIN, IEND - 1TMP2 = ABS( E( J ) )GU = MAX( GU, D( J )+TMP1+TMP2 )GL = MIN( GL, D( J )-TMP1-TMP2 )TMP1 = TMP240 CONTINUE*GU = MAX( GU, D( IEND )+TMP1 )GL = MIN( GL, D( IEND )-TMP1 )BNORM = MAX( ABS( GL ), ABS( GU ) )GL = GL - FUDGE*BNORM*ULP*IN - FUDGE*PIVMINGU = GU + FUDGE*BNORM*ULP*IN + FUDGE*PIVMIN** Compute ATOLI for the current submatrix*IF( ABSTOL.LE.ZERO ) THENATOLI = ULP*MAX( ABS( GL ), ABS( GU ) )ELSEATOLI = ABSTOLEND IF*IF( IRANGE.GT.1 ) THENIF( GU.LT.WL ) THENNWL = NWL + INNWU = NWU + INGO TO 70END IFGL = MAX( GL, WL )GU = MIN( GU, WU )IF( GL.GE.GU )$ GO TO 70END IF** Set Up Initial Interval*WORK( N+1 ) = GLWORK( N+IN+1 ) = GUCALL DLAEBZ( 1, 0, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,$ D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),$ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IM,$ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )*NWL = NWL + IWORK( 1 )NWU = NWU + IWORK( IN+1 )IWOFF = M - IWORK( 1 )** Compute Eigenvalues*ITMAX = INT( ( LOG( GU-GL+PIVMIN )-LOG( PIVMIN ) ) /$ LOG( TWO ) ) + 2CALL DLAEBZ( 2, ITMAX, IN, IN, 1, NB, ATOLI, RTOLI, PIVMIN,$ D( IBEGIN ), E( IBEGIN ), WORK( IBEGIN ),$ IDUMMA, WORK( N+1 ), WORK( N+2*IN+1 ), IOUT,$ IWORK, W( M+1 ), IBLOCK( M+1 ), IINFO )** Copy Eigenvalues Into W and IBLOCK* Use -JB for block number for unconverged eigenvalues.*DO 60 J = 1, IOUTTMP1 = HALF*( WORK( J+N )+WORK( J+IN+N ) )** Flag non-convergence.*IF( J.GT.IOUT-IINFO ) THENNCNVRG = .TRUE.IB = -JBELSEIB = JBEND IFDO 50 JE = IWORK( J ) + 1 + IWOFF,$ IWORK( J+IN ) + IWOFFW( JE ) = TMP1IBLOCK( JE ) = IB50 CONTINUE60 CONTINUE*M = M + IMEND IF70 CONTINUE** If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU* If NWL+1 < IL or NWU > IU, discard extra eigenvalues.*IF( IRANGE.EQ.3 ) THENIM = 0IDISCL = IL - 1 - NWLIDISCU = NWU - IU*IF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THENDO 80 JE = 1, MIF( W( JE ).LE.WLU .AND. IDISCL.GT.0 ) THENIDISCL = IDISCL - 1ELSE IF( W( JE ).GE.WUL .AND. IDISCU.GT.0 ) THENIDISCU = IDISCU - 1ELSEIM = IM + 1W( IM ) = W( JE )IBLOCK( IM ) = IBLOCK( JE )END IF80 CONTINUEM = IMEND IFIF( IDISCL.GT.0 .OR. IDISCU.GT.0 ) THEN** Code to deal with effects of bad arithmetic:* Some low eigenvalues to be discarded are not in (WL,WLU],* or high eigenvalues to be discarded are not in (WUL,WU]* so just kill off the smallest IDISCL/largest IDISCU* eigenvalues, by simply finding the smallest/largest* eigenvalue(s).** (If N(w) is monotone non-decreasing, this should never* happen.)*IF( IDISCL.GT.0 ) THENWKILL = WUDO 100 JDISC = 1, IDISCLIW = 0DO 90 JE = 1, MIF( IBLOCK( JE ).NE.0 .AND.$ ( W( JE ).LT.WKILL .OR. IW.EQ.0 ) ) THENIW = JEWKILL = W( JE )END IF90 CONTINUEIBLOCK( IW ) = 0100 CONTINUEEND IFIF( IDISCU.GT.0 ) THEN*WKILL = WLDO 120 JDISC = 1, IDISCUIW = 0DO 110 JE = 1, MIF( IBLOCK( JE ).NE.0 .AND.$ ( W( JE ).GT.WKILL .OR. IW.EQ.0 ) ) THENIW = JEWKILL = W( JE )END IF110 CONTINUEIBLOCK( IW ) = 0120 CONTINUEEND IFIM = 0DO 130 JE = 1, MIF( IBLOCK( JE ).NE.0 ) THENIM = IM + 1W( IM ) = W( JE )IBLOCK( IM ) = IBLOCK( JE )END IF130 CONTINUEM = IMEND IFIF( IDISCL.LT.0 .OR. IDISCU.LT.0 ) THENTOOFEW = .TRUE.END IFEND IF** If ORDER='B', do nothing -- the eigenvalues are already sorted* by block.* If ORDER='E', sort the eigenvalues from smallest to largest*IF( IORDER.EQ.1 .AND. NSPLIT.GT.1 ) THENDO 150 JE = 1, M - 1IE = 0TMP1 = W( JE )DO 140 J = JE + 1, MIF( W( J ).LT.TMP1 ) THENIE = JTMP1 = W( J )END IF140 CONTINUE*IF( IE.NE.0 ) THENITMP1 = IBLOCK( IE )W( IE ) = W( JE )IBLOCK( IE ) = IBLOCK( JE )W( JE ) = TMP1IBLOCK( JE ) = ITMP1END IF150 CONTINUEEND IF*INFO = 0IF( NCNVRG )$ INFO = INFO + 1IF( TOOFEW )$ INFO = INFO + 2RETURN** End of DSTEBZ*END*> \brief \b DSTEDC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEDC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstedc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstedc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstedc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEDC( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,* LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER COMPZ* INTEGER INFO, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEDC computes all eigenvalues and, optionally, eigenvectors of a*> symmetric tridiagonal matrix using the divide and conquer method.*> The eigenvectors of a full or band real symmetric matrix can also be*> found if DSYTRD or DSPTRD or DSBTRD has been used to reduce this*> matrix to tridiagonal form.*>*> This code makes very mild assumptions about floating point*> arithmetic. It will work on machines with a guard digit in*> add/subtract, or on those binary machines without guard digits*> which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or Cray-2.*> It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none. See DLAED3 for details.*> \endverbatim** Arguments:* ==========**> \param[in] COMPZ*> \verbatim*> COMPZ is CHARACTER*1*> = 'N': Compute eigenvalues only.*> = 'I': Compute eigenvectors of tridiagonal matrix also.*> = 'V': Compute eigenvectors of original dense symmetric*> matrix also. On entry, Z contains the orthogonal*> matrix used to reduce the original matrix to*> tridiagonal form.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The dimension of the symmetric tridiagonal matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the diagonal elements of the tridiagonal matrix.*> On exit, if INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the subdiagonal elements of the tridiagonal matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> On entry, if COMPZ = 'V', then Z contains the orthogonal*> matrix used in the reduction to tridiagonal form.*> On exit, if INFO = 0, then if COMPZ = 'V', Z contains the*> orthonormal eigenvectors of the original symmetric matrix,*> and if COMPZ = 'I', Z contains the orthonormal eigenvectors*> of the symmetric tridiagonal matrix.*> If COMPZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1.*> If eigenvectors are desired, then LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If COMPZ = 'N' or N <= 1 then LWORK must be at least 1.*> If COMPZ = 'V' and N > 1 then LWORK must be at least*> ( 1 + 3*N + 2*N*lg N + 4*N**2 ),*> where lg( N ) = smallest integer k such*> that 2**k >= N.*> If COMPZ = 'I' and N > 1 then LWORK must be at least*> ( 1 + 4*N + N**2 ).*> Note that for COMPZ = 'I' or 'V', then if N is less than or*> equal to the minimum divide size, usually 25, then LWORK need*> only be max(1,2*(N-1)).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If COMPZ = 'N' or N <= 1 then LIWORK must be at least 1.*> If COMPZ = 'V' and N > 1 then LIWORK must be at least*> ( 6 + 6*N + 5*N*lg N ).*> If COMPZ = 'I' and N > 1 then LIWORK must be at least*> ( 3 + 5*N ).*> Note that for COMPZ = 'I' or 'V', then if N is less than or*> equal to the minimum divide size, usually 25, then LIWORK*> need only be 1.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the IWORK array,*> returns this value as the first entry of the IWORK array, and*> no error message related to LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: The algorithm failed to compute an eigenvalue while*> working on the submatrix lying in rows and columns*> INFO/(N+1) through mod(INFO,N+1).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup auxOTHERcomputational**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA \n*> Modified by Francoise Tisseur, University of Tennessee*>* =====================================================================SUBROUTINE DSTEDC( COMPZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,$ LIWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER COMPZINTEGER INFO, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER FINISH, I, ICOMPZ, II, J, K, LGN, LIWMIN,$ LWMIN, M, SMLSIZ, START, STOREZ, STRTRWDOUBLE PRECISION EPS, ORGNRM, P, TINY* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, ILAENV, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DGEMM, DLACPY, DLAED0, DLASCL, DLASET, DLASRT,$ DSTEQR, DSTERF, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, INT, LOG, MAX, MOD, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*IF( LSAME( COMPZ, 'N' ) ) THENICOMPZ = 0ELSE IF( LSAME( COMPZ, 'V' ) ) THENICOMPZ = 1ELSE IF( LSAME( COMPZ, 'I' ) ) THENICOMPZ = 2ELSEICOMPZ = -1END IFIF( ICOMPZ.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ( LDZ.LT.1 ) .OR.$ ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1, N ) ) ) THENINFO = -6END IF*IF( INFO.EQ.0 ) THEN** Compute the workspace requirements*SMLSIZ = ILAENV( 9, 'DSTEDC', ' ', 0, 0, 0, 0 )IF( N.LE.1 .OR. ICOMPZ.EQ.0 ) THENLIWMIN = 1LWMIN = 1ELSE IF( N.LE.SMLSIZ ) THENLIWMIN = 1LWMIN = 2*( N - 1 )ELSELGN = INT( LOG( DBLE( N ) )/LOG( TWO ) )IF( 2**LGN.LT.N )$ LGN = LGN + 1IF( 2**LGN.LT.N )$ LGN = LGN + 1IF( ICOMPZ.EQ.1 ) THENLWMIN = 1 + 3*N + 2*N*LGN + 4*N**2LIWMIN = 6 + 6*N + 5*N*LGNELSE IF( ICOMPZ.EQ.2 ) THENLWMIN = 1 + 4*N + N**2LIWMIN = 3 + 5*NEND IFEND IFWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( LWORK.LT.LWMIN .AND. .NOT. LQUERY ) THENINFO = -8ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT. LQUERY ) THENINFO = -10END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEDC', -INFO )RETURNELSE IF (LQUERY) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURNIF( N.EQ.1 ) THENIF( ICOMPZ.NE.0 )$ Z( 1, 1 ) = ONERETURNEND IF** If the following conditional clause is removed, then the routine* will use the Divide and Conquer routine to compute only the* eigenvalues, which requires (3N + 3N**2) real workspace and* (2 + 5N + 2N lg(N)) integer workspace.* Since on many architectures DSTERF is much faster than any other* algorithm for finding eigenvalues only, it is used here* as the default. If the conditional clause is removed, then* information on the size of workspace needs to be changed.** If COMPZ = 'N', use DSTERF to compute the eigenvalues.*IF( ICOMPZ.EQ.0 ) THENCALL DSTERF( N, D, E, INFO )GO TO 50END IF** If N is smaller than the minimum divide size (SMLSIZ+1), then* solve the problem with another solver.*IF( N.LE.SMLSIZ ) THEN*CALL DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )*ELSE** If COMPZ = 'V', the Z matrix must be stored elsewhere for later* use.*IF( ICOMPZ.EQ.1 ) THENSTOREZ = 1 + N*NELSESTOREZ = 1END IF*IF( ICOMPZ.EQ.2 ) THENCALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )END IF** Scale.*ORGNRM = DLANST( 'M', N, D, E )IF( ORGNRM.EQ.ZERO )$ GO TO 50*EPS = DLAMCH( 'Epsilon' )*START = 1** while ( START <= N )*10 CONTINUEIF( START.LE.N ) THEN** Let FINISH be the position of the next subdiagonal entry* such that E( FINISH ) <= TINY or FINISH = N if no such* subdiagonal exists. The matrix identified by the elements* between START and FINISH constitutes an independent* sub-problem.*FINISH = START20 CONTINUEIF( FINISH.LT.N ) THENTINY = EPS*SQRT( ABS( D( FINISH ) ) )*$ SQRT( ABS( D( FINISH+1 ) ) )IF( ABS( E( FINISH ) ).GT.TINY ) THENFINISH = FINISH + 1GO TO 20END IFEND IF** (Sub) Problem determined. Compute its size and solve it.*M = FINISH - START + 1IF( M.EQ.1 ) THENSTART = FINISH + 1GO TO 10END IFIF( M.GT.SMLSIZ ) THEN** Scale.*ORGNRM = DLANST( 'M', M, D( START ), E( START ) )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, M, 1, D( START ), M,$ INFO )CALL DLASCL( 'G', 0, 0, ORGNRM, ONE, M-1, 1, E( START ),$ M-1, INFO )*IF( ICOMPZ.EQ.1 ) THENSTRTRW = 1ELSESTRTRW = STARTEND IFCALL DLAED0( ICOMPZ, N, M, D( START ), E( START ),$ Z( STRTRW, START ), LDZ, WORK( 1 ), N,$ WORK( STOREZ ), IWORK, INFO )IF( INFO.NE.0 ) THENINFO = ( INFO / ( M+1 )+START-1 )*( N+1 ) +$ MOD( INFO, ( M+1 ) ) + START - 1GO TO 50END IF** Scale back.*CALL DLASCL( 'G', 0, 0, ONE, ORGNRM, M, 1, D( START ), M,$ INFO )*ELSEIF( ICOMPZ.EQ.1 ) THEN** Since QR won't update a Z matrix which is larger than* the length of D, we must solve the sub-problem in a* workspace and then multiply back into Z.*CALL DSTEQR( 'I', M, D( START ), E( START ), WORK, M,$ WORK( M*M+1 ), INFO )CALL DLACPY( 'A', N, M, Z( 1, START ), LDZ,$ WORK( STOREZ ), N )CALL DGEMM( 'N', 'N', N, M, M, ONE,$ WORK( STOREZ ), N, WORK, M, ZERO,$ Z( 1, START ), LDZ )ELSE IF( ICOMPZ.EQ.2 ) THENCALL DSTEQR( 'I', M, D( START ), E( START ),$ Z( START, START ), LDZ, WORK, INFO )ELSECALL DSTERF( M, D( START ), E( START ), INFO )END IFIF( INFO.NE.0 ) THENINFO = START*( N+1 ) + FINISHGO TO 50END IFEND IF*START = FINISH + 1GO TO 10END IF** endwhile*IF( ICOMPZ.EQ.0 ) THEN** Use Quick Sort*CALL DLASRT( 'I', N, D, INFO )*ELSE** Use Selection Sort to minimize swaps of eigenvectors*DO 40 II = 2, NI = II - 1K = IP = D( I )DO 30 J = II, NIF( D( J ).LT.P ) THENK = JP = D( J )END IF30 CONTINUEIF( K.NE.I ) THEND( K ) = D( I )D( I ) = PCALL DSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )END IF40 CONTINUEEND IFEND IF*50 CONTINUEWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DSTEDC*END*> \brief \b DSTEGR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEGR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstegr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstegr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstegr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEGR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,* ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,* LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE* INTEGER IL, INFO, IU, LDZ, LIWORK, LWORK, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER ISUPPZ( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )* DOUBLE PRECISION Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEGR computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric tridiagonal matrix T. Any such unreduced matrix has*> a well defined set of pairwise different real eigenvalues, the corresponding*> real eigenvectors are pairwise orthogonal.*>*> The spectrum may be computed either completely or partially by specifying*> either an interval (VL,VU] or a range of indices IL:IU for the desired*> eigenvalues.*>*> DSTEGR is a compatibility wrapper around the improved DSTEMR routine.*> See DSTEMR for further details.*>*> One important change is that the ABSTOL parameter no longer provides any*> benefit and hence is no longer used.*>*> Note : DSTEGR and DSTEMR work only on machines which follow*> IEEE-754 floating-point standard in their handling of infinities and*> NaNs. Normal execution may create these exceptiona values and hence*> may abort due to a floating point exception in environments which*> do not conform to the IEEE-754 standard.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the N diagonal elements of the tridiagonal matrix*> T. On exit, D is overwritten.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> On entry, the (N-1) subdiagonal elements of the tridiagonal*> matrix T in elements 1 to N-1 of E. E(N) need not be set on*> input, but is used internally as workspace.*> On exit, E is overwritten.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*>*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*>*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*>*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*>*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> Unused. Was the absolute error tolerance for the*> eigenvalues/eigenvectors in previous versions.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the selected eigenvalues in*> ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) )*> If JOBZ = 'V', and if INFO = 0, then the first M columns of Z*> contain the orthonormal eigenvectors of the matrix T*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> Supplying N columns is always safe.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', then LDZ >= max(1,N).*> \endverbatim*>*> \param[out] ISUPPZ*> \verbatim*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )*> The support of the eigenvectors in Z, i.e., the indices*> indicating the nonzero elements in Z. The i-th computed eigenvector*> is nonzero only in elements ISUPPZ( 2*i-1 ) through*> ISUPPZ( 2*i ). This is relevant in the case when the matrix*> is split. ISUPPZ is only accessed when JOBZ is 'V' and N > 0.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns the optimal*> (and minimal) LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,18*N)*> if JOBZ = 'V', and LWORK >= max(1,12*N) if JOBZ = 'N'.*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (LIWORK)*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK. LIWORK >= max(1,10*N)*> if the eigenvectors are desired, and LIWORK >= max(1,8*N)*> if only the eigenvalues are to be computed.*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the IWORK array,*> returns this value as the first entry of the IWORK array, and*> no error message related to LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> On exit, INFO*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = 1X, internal error in DLARRE,*> if INFO = 2X, internal error in DLARRV.*> Here, the digit X = ABS( IINFO ) < 10, where IINFO is*> the nonzero error code returned by DLARRE or*> DLARRV, respectively.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Inderjit Dhillon, IBM Almaden, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, LBNL/NERSC, USA \n** =====================================================================SUBROUTINE DSTEGR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,$ ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,$ LIWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGEINTEGER IL, INFO, IU, LDZ, LIWORK, LWORK, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER ISUPPZ( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )DOUBLE PRECISION Z( LDZ, * )* ..** =====================================================================** .. Local Scalars ..LOGICAL TRYRAC* ..* .. External Subroutines ..EXTERNAL DSTEMR* ..* .. Executable Statements ..INFO = 0TRYRAC = .FALSE.CALL DSTEMR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,$ M, W, Z, LDZ, N, ISUPPZ, TRYRAC, WORK, LWORK,$ IWORK, LIWORK, INFO )** End of DSTEGR*END*> \brief \b DSTEIN** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEIN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstein.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstein.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstein.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK,* IWORK, IFAIL, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDZ, M, N* ..* .. Array Arguments ..* INTEGER IBLOCK( * ), IFAIL( * ), ISPLIT( * ),* $ IWORK( * )* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEIN computes the eigenvectors of a real symmetric tridiagonal*> matrix T corresponding to specified eigenvalues, using inverse*> iteration.*>*> The maximum number of iterations allowed for each eigenvector is*> specified by an internal parameter MAXITS (currently set to 5).*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The n diagonal elements of the tridiagonal matrix T.*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The (n-1) subdiagonal elements of the tridiagonal matrix*> T, in elements 1 to N-1.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of eigenvectors to be found. 0 <= M <= N.*> \endverbatim*>*> \param[in] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements of W contain the eigenvalues for*> which eigenvectors are to be computed. The eigenvalues*> should be grouped by split-off block and ordered from*> smallest to largest within the block. ( The output array*> W from DSTEBZ with ORDER = 'B' is expected here. )*> \endverbatim*>*> \param[in] IBLOCK*> \verbatim*> IBLOCK is INTEGER array, dimension (N)*> The submatrix indices associated with the corresponding*> eigenvalues in W; IBLOCK(i)=1 if eigenvalue W(i) belongs to*> the first submatrix from the top, =2 if W(i) belongs to*> the second submatrix, etc. ( The output array IBLOCK*> from DSTEBZ is expected here. )*> \endverbatim*>*> \param[in] ISPLIT*> \verbatim*> ISPLIT is INTEGER array, dimension (N)*> The splitting points, at which T breaks up into submatrices.*> The first submatrix consists of rows/columns 1 to*> ISPLIT( 1 ), the second of rows/columns ISPLIT( 1 )+1*> through ISPLIT( 2 ), etc.*> ( The output array ISPLIT from DSTEBZ is expected here. )*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, M)*> The computed eigenvectors. The eigenvector associated*> with the eigenvalue W(i) is stored in the i-th column of*> Z. Any vector which fails to converge is set to its current*> iterate after MAXITS iterations.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (5*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (M)*> On normal exit, all elements of IFAIL are zero.*> If one or more eigenvectors fail to converge after*> MAXITS iterations, then their indices are stored in*> array IFAIL.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, then i eigenvectors failed to converge*> in MAXITS iterations. Their indices are stored in*> array IFAIL.*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> MAXITS INTEGER, default = 5*> The maximum number of iterations performed.*>*> EXTRA INTEGER, default = 2*> The number of iterations performed after norm growth*> criterion is satisfied, should be at least 1.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK,$ IWORK, IFAIL, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDZ, M, N* ..* .. Array Arguments ..INTEGER IBLOCK( * ), IFAIL( * ), ISPLIT( * ),$ IWORK( * )DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TEN, ODM3, ODM1PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TEN = 1.0D+1,$ ODM3 = 1.0D-3, ODM1 = 1.0D-1 )INTEGER MAXITS, EXTRAPARAMETER ( MAXITS = 5, EXTRA = 2 )* ..* .. Local Scalars ..INTEGER B1, BLKSIZ, BN, GPIND, I, IINFO, INDRV1,$ INDRV2, INDRV3, INDRV4, INDRV5, ITS, J, J1,$ JBLK, JMAX, NBLK, NRMCHKDOUBLE PRECISION DTPCRT, EPS, EPS1, NRM, ONENRM, ORTOL, PERTOL,$ SCL, SEP, TOL, XJ, XJM, ZTR* ..* .. Local Arrays ..INTEGER ISEED( 4 )* ..* .. External Functions ..INTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCH, DNRM2EXTERNAL IDAMAX, DDOT, DLAMCH, DNRM2* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLAGTF, DLAGTS, DLARNV, DSCAL,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0DO 10 I = 1, MIFAIL( I ) = 010 CONTINUE*IF( N.LT.0 ) THENINFO = -1ELSE IF( M.LT.0 .OR. M.GT.N ) THENINFO = -4ELSE IF( LDZ.LT.MAX( 1, N ) ) THENINFO = -9ELSEDO 20 J = 2, MIF( IBLOCK( J ).LT.IBLOCK( J-1 ) ) THENINFO = -6GO TO 30END IFIF( IBLOCK( J ).EQ.IBLOCK( J-1 ) .AND. W( J ).LT.W( J-1 ) )$ THENINFO = -5GO TO 30END IF20 CONTINUE30 CONTINUEEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEIN', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. M.EQ.0 ) THENRETURNELSE IF( N.EQ.1 ) THENZ( 1, 1 ) = ONERETURNEND IF** Get machine constants.*EPS = DLAMCH( 'Precision' )** Initialize seed for random number generator DLARNV.*DO 40 I = 1, 4ISEED( I ) = 140 CONTINUE** Initialize pointers.*INDRV1 = 0INDRV2 = INDRV1 + NINDRV3 = INDRV2 + NINDRV4 = INDRV3 + NINDRV5 = INDRV4 + N** Compute eigenvectors of matrix blocks.*J1 = 1DO 160 NBLK = 1, IBLOCK( M )** Find starting and ending indices of block nblk.*IF( NBLK.EQ.1 ) THENB1 = 1ELSEB1 = ISPLIT( NBLK-1 ) + 1END IFBN = ISPLIT( NBLK )BLKSIZ = BN - B1 + 1IF( BLKSIZ.EQ.1 )$ GO TO 60GPIND = J1** Compute reorthogonalization criterion and stopping criterion.*ONENRM = ABS( D( B1 ) ) + ABS( E( B1 ) )ONENRM = MAX( ONENRM, ABS( D( BN ) )+ABS( E( BN-1 ) ) )DO 50 I = B1 + 1, BN - 1ONENRM = MAX( ONENRM, ABS( D( I ) )+ABS( E( I-1 ) )+$ ABS( E( I ) ) )50 CONTINUEORTOL = ODM3*ONENRM*DTPCRT = SQRT( ODM1 / BLKSIZ )** Loop through eigenvalues of block nblk.*60 CONTINUEJBLK = 0DO 150 J = J1, MIF( IBLOCK( J ).NE.NBLK ) THENJ1 = JGO TO 160END IFJBLK = JBLK + 1XJ = W( J )** Skip all the work if the block size is one.*IF( BLKSIZ.EQ.1 ) THENWORK( INDRV1+1 ) = ONEGO TO 120END IF** If eigenvalues j and j-1 are too close, add a relatively* small perturbation.*IF( JBLK.GT.1 ) THENEPS1 = ABS( EPS*XJ )PERTOL = TEN*EPS1SEP = XJ - XJMIF( SEP.LT.PERTOL )$ XJ = XJM + PERTOLEND IF*ITS = 0NRMCHK = 0** Get random starting vector.*CALL DLARNV( 2, ISEED, BLKSIZ, WORK( INDRV1+1 ) )** Copy the matrix T so it won't be destroyed in factorization.*CALL DCOPY( BLKSIZ, D( B1 ), 1, WORK( INDRV4+1 ), 1 )CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV2+2 ), 1 )CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV3+1 ), 1 )** Compute LU factors with partial pivoting ( PT = LU )*TOL = ZEROCALL DLAGTF( BLKSIZ, WORK( INDRV4+1 ), XJ, WORK( INDRV2+2 ),$ WORK( INDRV3+1 ), TOL, WORK( INDRV5+1 ), IWORK,$ IINFO )** Update iteration count.*70 CONTINUEITS = ITS + 1IF( ITS.GT.MAXITS )$ GO TO 100** Normalize and scale the righthand side vector Pb.*JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )SCL = BLKSIZ*ONENRM*MAX( EPS,$ ABS( WORK( INDRV4+BLKSIZ ) ) ) /$ ABS( WORK( INDRV1+JMAX ) )CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )** Solve the system LU = Pb.*CALL DLAGTS( -1, BLKSIZ, WORK( INDRV4+1 ), WORK( INDRV2+2 ),$ WORK( INDRV3+1 ), WORK( INDRV5+1 ), IWORK,$ WORK( INDRV1+1 ), TOL, IINFO )** Reorthogonalize by modified Gram-Schmidt if eigenvalues are* close enough.*IF( JBLK.EQ.1 )$ GO TO 90IF( ABS( XJ-XJM ).GT.ORTOL )$ GPIND = JIF( GPIND.NE.J ) THENDO 80 I = GPIND, J - 1ZTR = -DDOT( BLKSIZ, WORK( INDRV1+1 ), 1, Z( B1, I ),$ 1 )CALL DAXPY( BLKSIZ, ZTR, Z( B1, I ), 1,$ WORK( INDRV1+1 ), 1 )80 CONTINUEEND IF** Check the infinity norm of the iterate.*90 CONTINUEJMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )NRM = ABS( WORK( INDRV1+JMAX ) )** Continue for additional iterations after norm reaches* stopping criterion.*IF( NRM.LT.DTPCRT )$ GO TO 70NRMCHK = NRMCHK + 1IF( NRMCHK.LT.EXTRA+1 )$ GO TO 70*GO TO 110** If stopping criterion was not satisfied, update info and* store eigenvector number in array ifail.*100 CONTINUEINFO = INFO + 1IFAIL( INFO ) = J** Accept iterate as jth eigenvector.*110 CONTINUESCL = ONE / DNRM2( BLKSIZ, WORK( INDRV1+1 ), 1 )JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )IF( WORK( INDRV1+JMAX ).LT.ZERO )$ SCL = -SCLCALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )120 CONTINUEDO 130 I = 1, NZ( I, J ) = ZERO130 CONTINUEDO 140 I = 1, BLKSIZZ( B1+I-1, J ) = WORK( INDRV1+I )140 CONTINUE** Save the shift to check eigenvalue spacing at next* iteration.*XJM = XJ*150 CONTINUE160 CONTINUE*RETURN** End of DSTEIN*END*> \brief \b DSTEMR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEMR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstemr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstemr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstemr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEMR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,* M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,* IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE* LOGICAL TRYRAC* INTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, N* DOUBLE PRECISION VL, VU* ..* .. Array Arguments ..* INTEGER ISUPPZ( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )* DOUBLE PRECISION Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEMR computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric tridiagonal matrix T. Any such unreduced matrix has*> a well defined set of pairwise different real eigenvalues, the corresponding*> real eigenvectors are pairwise orthogonal.*>*> The spectrum may be computed either completely or partially by specifying*> either an interval (VL,VU] or a range of indices IL:IU for the desired*> eigenvalues.*>*> Depending on the number of desired eigenvalues, these are computed either*> by bisection or the dqds algorithm. Numerically orthogonal eigenvectors are*> computed by the use of various suitable L D L^T factorizations near clusters*> of close eigenvalues (referred to as RRRs, Relatively Robust*> Representations). An informal sketch of the algorithm follows.*>*> For each unreduced block (submatrix) of T,*> (a) Compute T - sigma I = L D L^T, so that L and D*> define all the wanted eigenvalues to high relative accuracy.*> This means that small relative changes in the entries of D and L*> cause only small relative changes in the eigenvalues and*> eigenvectors. The standard (unfactored) representation of the*> tridiagonal matrix T does not have this property in general.*> (b) Compute the eigenvalues to suitable accuracy.*> If the eigenvectors are desired, the algorithm attains full*> accuracy of the computed eigenvalues only right before*> the corresponding vectors have to be computed, see steps c) and d).*> (c) For each cluster of close eigenvalues, select a new*> shift close to the cluster, find a new factorization, and refine*> the shifted eigenvalues to suitable accuracy.*> (d) For each eigenvalue with a large enough relative separation compute*> the corresponding eigenvector by forming a rank revealing twisted*> factorization. Go back to (c) for any clusters that remain.*>*> For more details, see:*> - Inderjit S. Dhillon and Beresford N. Parlett: "Multiple representations*> to compute orthogonal eigenvectors of symmetric tridiagonal matrices,"*> Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.*> - Inderjit Dhillon and Beresford Parlett: "Orthogonal Eigenvectors and*> Relative Gaps," SIAM Journal on Matrix Analysis and Applications, Vol. 25,*> 2004. Also LAPACK Working Note 154.*> - Inderjit Dhillon: "A new O(n^2) algorithm for the symmetric*> tridiagonal eigenvalue/eigenvector problem",*> Computer Science Division Technical Report No. UCB/CSD-97-971,*> UC Berkeley, May 1997.*>*> Further Details*> 1.DSTEMR works only on machines which follow IEEE-754*> floating-point standard in their handling of infinities and NaNs.*> This permits the use of efficient inner loops avoiding a check for*> zero divisors.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the N diagonal elements of the tridiagonal matrix*> T. On exit, D is overwritten.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> On entry, the (N-1) subdiagonal elements of the tridiagonal*> matrix T in elements 1 to N-1 of E. E(N) need not be set on*> input, but is used internally as workspace.*> On exit, E is overwritten.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*>*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*>*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*>*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*>*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the selected eigenvalues in*> ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) )*> If JOBZ = 'V', and if INFO = 0, then the first M columns of Z*> contain the orthonormal eigenvectors of the matrix T*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and can be computed with a workspace*> query by setting NZC = -1, see below.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', then LDZ >= max(1,N).*> \endverbatim*>*> \param[in] NZC*> \verbatim*> NZC is INTEGER*> The number of eigenvectors to be held in the array Z.*> If RANGE = 'A', then NZC >= max(1,N).*> If RANGE = 'V', then NZC >= the number of eigenvalues in (VL,VU].*> If RANGE = 'I', then NZC >= IU-IL+1.*> If NZC = -1, then a workspace query is assumed; the*> routine calculates the number of columns of the array Z that*> are needed to hold the eigenvectors.*> This value is returned as the first entry of the Z array, and*> no error message related to NZC is issued by XERBLA.*> \endverbatim*>*> \param[out] ISUPPZ*> \verbatim*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )*> The support of the eigenvectors in Z, i.e., the indices*> indicating the nonzero elements in Z. The i-th computed eigenvector*> is nonzero only in elements ISUPPZ( 2*i-1 ) through*> ISUPPZ( 2*i ). This is relevant in the case when the matrix*> is split. ISUPPZ is only accessed when JOBZ is 'V' and N > 0.*> \endverbatim*>*> \param[in,out] TRYRAC*> \verbatim*> TRYRAC is LOGICAL*> If TRYRAC.EQ..TRUE., indicates that the code should check whether*> the tridiagonal matrix defines its eigenvalues to high relative*> accuracy. If so, the code uses relative-accuracy preserving*> algorithms that might be (a bit) slower depending on the matrix.*> If the matrix does not define its eigenvalues to high relative*> accuracy, the code can uses possibly faster algorithms.*> If TRYRAC.EQ..FALSE., the code is not required to guarantee*> relatively accurate eigenvalues and can use the fastest possible*> techniques.*> On exit, a .TRUE. TRYRAC will be set to .FALSE. if the matrix*> does not define its eigenvalues to high relative accuracy.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns the optimal*> (and minimal) LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,18*N)*> if JOBZ = 'V', and LWORK >= max(1,12*N) if JOBZ = 'N'.*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (LIWORK)*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK. LIWORK >= max(1,10*N)*> if the eigenvectors are desired, and LIWORK >= max(1,8*N)*> if only the eigenvalues are to be computed.*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the IWORK array,*> returns this value as the first entry of the IWORK array, and*> no error message related to LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> On exit, INFO*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = 1X, internal error in DLARRE,*> if INFO = 2X, internal error in DLARRV.*> Here, the digit X = ABS( IINFO ) < 10, where IINFO is*> the nonzero error code returned by DLARRE or*> DLARRV, respectively.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> Beresford Parlett, University of California, Berkeley, USA \n*> Jim Demmel, University of California, Berkeley, USA \n*> Inderjit Dhillon, University of Texas, Austin, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Christof Voemel, University of California, Berkeley, USA** =====================================================================SUBROUTINE DSTEMR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU,$ M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK,$ IWORK, LIWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGELOGICAL TRYRACINTEGER IL, INFO, IU, LDZ, NZC, LIWORK, LWORK, M, NDOUBLE PRECISION VL, VU* ..* .. Array Arguments ..INTEGER ISUPPZ( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * )DOUBLE PRECISION Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, FOUR, MINRGPPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0,$ FOUR = 4.0D0,$ MINRGP = 1.0D-3 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, LQUERY, VALEIG, WANTZ, ZQUERYINTEGER I, IBEGIN, IEND, IFIRST, IIL, IINDBL, IINDW,$ IINDWK, IINFO, IINSPL, IIU, ILAST, IN, INDD,$ INDE2, INDERR, INDGP, INDGRS, INDWRK, ITMP,$ ITMP2, J, JBLK, JJ, LIWMIN, LWMIN, NSPLIT,$ NZCMIN, OFFSET, WBEGIN, WENDDOUBLE PRECISION BIGNUM, CS, EPS, PIVMIN, R1, R2, RMAX, RMIN,$ RTOL1, RTOL2, SAFMIN, SCALE, SMLNUM, SN,$ THRESH, TMP, TNRM, WL, WU* ..* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAE2, DLAEV2, DLARRC, DLARRE, DLARRJ,$ DLARRR, DLARRV, DLASRT, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*LQUERY = ( ( LWORK.EQ.-1 ).OR.( LIWORK.EQ.-1 ) )ZQUERY = ( NZC.EQ.-1 )* DSTEMR needs WORK of size 6*N, IWORK of size 3*N.* In addition, DLARRE needs WORK of size 6*N, IWORK of size 5*N.* Furthermore, DLARRV needs WORK of size 12*N, IWORK of size 7*N.IF( WANTZ ) THENLWMIN = 18*NLIWMIN = 10*NELSE* need less workspace if only the eigenvalues are wantedLWMIN = 12*NLIWMIN = 8*NENDIFWL = ZEROWU = ZEROIIL = 0IIU = 0NSPLIT = 0IF( VALEIG ) THEN* We do not reference VL, VU in the cases RANGE = 'I','A'* The interval (WL, WU] contains all the wanted eigenvalues.* It is either given by the user or computed in DLARRE.WL = VLWU = VUELSEIF( INDEIG ) THEN* We do not reference IL, IU in the cases RANGE = 'V','A'IIL = ILIIU = IUENDIF*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( VALEIG .AND. N.GT.0 .AND. WU.LE.WL ) THENINFO = -7ELSE IF( INDEIG .AND. ( IIL.LT.1 .OR. IIL.GT.N ) ) THENINFO = -8ELSE IF( INDEIG .AND. ( IIU.LT.IIL .OR. IIU.GT.N ) ) THENINFO = -9ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -13ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -17ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -19END IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( WANTZ .AND. ALLEIG ) THENNZCMIN = NELSE IF( WANTZ .AND. VALEIG ) THENCALL DLARRC( 'T', N, VL, VU, D, E, SAFMIN,$ NZCMIN, ITMP, ITMP2, INFO )ELSE IF( WANTZ .AND. INDEIG ) THENNZCMIN = IIU-IIL+1ELSE* WANTZ .EQ. FALSE.NZCMIN = 0ENDIFIF( ZQUERY .AND. INFO.EQ.0 ) THENZ( 1,1 ) = NZCMINELSE IF( NZC.LT.NZCMIN .AND. .NOT.ZQUERY ) THENINFO = -14END IFEND IFIF( INFO.NE.0 ) THEN*CALL XERBLA( 'DSTEMR', -INFO )*RETURNELSE IF( LQUERY .OR. ZQUERY ) THENRETURNEND IF** Handle N = 0, 1, and 2 cases immediately*M = 0IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ALLEIG .OR. INDEIG ) THENM = 1W( 1 ) = D( 1 )ELSEIF( WL.LT.D( 1 ) .AND. WU.GE.D( 1 ) ) THENM = 1W( 1 ) = D( 1 )END IFEND IFIF( WANTZ.AND.(.NOT.ZQUERY) ) THENZ( 1, 1 ) = ONEISUPPZ(1) = 1ISUPPZ(2) = 1END IFRETURNEND IF*IF( N.EQ.2 ) THENIF( .NOT.WANTZ ) THENCALL DLAE2( D(1), E(1), D(2), R1, R2 )ELSE IF( WANTZ.AND.(.NOT.ZQUERY) ) THENCALL DLAEV2( D(1), E(1), D(2), R1, R2, CS, SN )END IFIF( ALLEIG.OR.$ (VALEIG.AND.(R2.GT.WL).AND.$ (R2.LE.WU)).OR.$ (INDEIG.AND.(IIL.EQ.1)) ) THENM = M+1W( M ) = R2IF( WANTZ.AND.(.NOT.ZQUERY) ) THENZ( 1, M ) = -SNZ( 2, M ) = CS* Note: At most one of SN and CS can be zero.IF (SN.NE.ZERO) THENIF (CS.NE.ZERO) THENISUPPZ(2*M-1) = 1ISUPPZ(2*M) = 2ELSEISUPPZ(2*M-1) = 1ISUPPZ(2*M) = 1END IFELSEISUPPZ(2*M-1) = 2ISUPPZ(2*M) = 2END IFENDIFENDIFIF( ALLEIG.OR.$ (VALEIG.AND.(R1.GT.WL).AND.$ (R1.LE.WU)).OR.$ (INDEIG.AND.(IIU.EQ.2)) ) THENM = M+1W( M ) = R1IF( WANTZ.AND.(.NOT.ZQUERY) ) THENZ( 1, M ) = CSZ( 2, M ) = SN* Note: At most one of SN and CS can be zero.IF (SN.NE.ZERO) THENIF (CS.NE.ZERO) THENISUPPZ(2*M-1) = 1ISUPPZ(2*M) = 2ELSEISUPPZ(2*M-1) = 1ISUPPZ(2*M) = 1END IFELSEISUPPZ(2*M-1) = 2ISUPPZ(2*M) = 2END IFENDIFENDIFELSE* Continue with general NINDGRS = 1INDERR = 2*N + 1INDGP = 3*N + 1INDD = 4*N + 1INDE2 = 5*N + 1INDWRK = 6*N + 1*IINSPL = 1IINDBL = N + 1IINDW = 2*N + 1IINDWK = 3*N + 1** Scale matrix to allowable range, if necessary.* The allowable range is related to the PIVMIN parameter; see the* comments in DLARRD. The preference for scaling small values* up is heuristic; we expect users' matrices not to be close to the* RMAX threshold.*SCALE = ONETNRM = DLANST( 'M', N, D, E )IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THENSCALE = RMIN / TNRMELSE IF( TNRM.GT.RMAX ) THENSCALE = RMAX / TNRMEND IFIF( SCALE.NE.ONE ) THENCALL DSCAL( N, SCALE, D, 1 )CALL DSCAL( N-1, SCALE, E, 1 )TNRM = TNRM*SCALEIF( VALEIG ) THEN* If eigenvalues in interval have to be found,* scale (WL, WU] accordinglyWL = WL*SCALEWU = WU*SCALEENDIFEND IF** Compute the desired eigenvalues of the tridiagonal after splitting* into smaller subblocks if the corresponding off-diagonal elements* are small* THRESH is the splitting parameter for DLARRE* A negative THRESH forces the old splitting criterion based on the* size of the off-diagonal. A positive THRESH switches to splitting* which preserves relative accuracy.*IF( TRYRAC ) THEN* Test whether the matrix warrants the more expensive relative approach.CALL DLARRR( N, D, E, IINFO )ELSE* The user does not care about relative accurately eigenvaluesIINFO = -1ENDIF* Set the splitting criterionIF (IINFO.EQ.0) THENTHRESH = EPSELSETHRESH = -EPS* relative accuracy is desired but T does not guarantee itTRYRAC = .FALSE.ENDIF*IF( TRYRAC ) THEN* Copy original diagonal, needed to guarantee relative accuracyCALL DCOPY(N,D,1,WORK(INDD),1)ENDIF* Store the squares of the offdiagonal values of TDO 5 J = 1, N-1WORK( INDE2+J-1 ) = E(J)**25 CONTINUE* Set the tolerance parameters for bisectionIF( .NOT.WANTZ ) THEN* DLARRE computes the eigenvalues to full precision.RTOL1 = FOUR * EPSRTOL2 = FOUR * EPSELSE* DLARRE computes the eigenvalues to less than full precision.* DLARRV will refine the eigenvalue approximations, and we can* need less accurate initial bisection in DLARRE.* Note: these settings do only affect the subset case and DLARRERTOL1 = SQRT(EPS)RTOL2 = MAX( SQRT(EPS)*5.0D-3, FOUR * EPS )ENDIFCALL DLARRE( RANGE, N, WL, WU, IIL, IIU, D, E,$ WORK(INDE2), RTOL1, RTOL2, THRESH, NSPLIT,$ IWORK( IINSPL ), M, W, WORK( INDERR ),$ WORK( INDGP ), IWORK( IINDBL ),$ IWORK( IINDW ), WORK( INDGRS ), PIVMIN,$ WORK( INDWRK ), IWORK( IINDWK ), IINFO )IF( IINFO.NE.0 ) THENINFO = 10 + ABS( IINFO )RETURNEND IF* Note that if RANGE .NE. 'V', DLARRE computes bounds on the desired* part of the spectrum. All desired eigenvalues are contained in* (WL,WU]IF( WANTZ ) THEN** Compute the desired eigenvectors corresponding to the computed* eigenvalues*CALL DLARRV( N, WL, WU, D, E,$ PIVMIN, IWORK( IINSPL ), M,$ 1, M, MINRGP, RTOL1, RTOL2,$ W, WORK( INDERR ), WORK( INDGP ), IWORK( IINDBL ),$ IWORK( IINDW ), WORK( INDGRS ), Z, LDZ,$ ISUPPZ, WORK( INDWRK ), IWORK( IINDWK ), IINFO )IF( IINFO.NE.0 ) THENINFO = 20 + ABS( IINFO )RETURNEND IFELSE* DLARRE computes eigenvalues of the (shifted) root representation* DLARRV returns the eigenvalues of the unshifted matrix.* However, if the eigenvectors are not desired by the user, we need* to apply the corresponding shifts from DLARRE to obtain the* eigenvalues of the original matrix.DO 20 J = 1, MITMP = IWORK( IINDBL+J-1 )W( J ) = W( J ) + E( IWORK( IINSPL+ITMP-1 ) )20 CONTINUEEND IF*IF ( TRYRAC ) THEN* Refine computed eigenvalues so that they are relatively accurate* with respect to the original matrix T.IBEGIN = 1WBEGIN = 1DO 39 JBLK = 1, IWORK( IINDBL+M-1 )IEND = IWORK( IINSPL+JBLK-1 )IN = IEND - IBEGIN + 1WEND = WBEGIN - 1* check if any eigenvalues have to be refined in this block36 CONTINUEIF( WEND.LT.M ) THENIF( IWORK( IINDBL+WEND ).EQ.JBLK ) THENWEND = WEND + 1GO TO 36END IFEND IFIF( WEND.LT.WBEGIN ) THENIBEGIN = IEND + 1GO TO 39END IFOFFSET = IWORK(IINDW+WBEGIN-1)-1IFIRST = IWORK(IINDW+WBEGIN-1)ILAST = IWORK(IINDW+WEND-1)RTOL2 = FOUR * EPSCALL DLARRJ( IN,$ WORK(INDD+IBEGIN-1), WORK(INDE2+IBEGIN-1),$ IFIRST, ILAST, RTOL2, OFFSET, W(WBEGIN),$ WORK( INDERR+WBEGIN-1 ),$ WORK( INDWRK ), IWORK( IINDWK ), PIVMIN,$ TNRM, IINFO )IBEGIN = IEND + 1WBEGIN = WEND + 139 CONTINUEENDIF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( SCALE.NE.ONE ) THENCALL DSCAL( M, ONE / SCALE, W, 1 )END IFEND IF** If eigenvalues are not in increasing order, then sort them,* possibly along with eigenvectors.*IF( NSPLIT.GT.1 .OR. N.EQ.2 ) THENIF( .NOT. WANTZ ) THENCALL DLASRT( 'I', M, W, IINFO )IF( IINFO.NE.0 ) THENINFO = 3RETURNEND IFELSEDO 60 J = 1, M - 1I = 0TMP = W( J )DO 50 JJ = J + 1, MIF( W( JJ ).LT.TMP ) THENI = JJTMP = W( JJ )END IF50 CONTINUEIF( I.NE.0 ) THENW( I ) = W( J )W( J ) = TMPIF( WANTZ ) THENCALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )ITMP = ISUPPZ( 2*I-1 )ISUPPZ( 2*I-1 ) = ISUPPZ( 2*J-1 )ISUPPZ( 2*J-1 ) = ITMPITMP = ISUPPZ( 2*I )ISUPPZ( 2*I ) = ISUPPZ( 2*J )ISUPPZ( 2*J ) = ITMPEND IFEND IF60 CONTINUEEND IFENDIF**WORK( 1 ) = LWMINIWORK( 1 ) = LIWMINRETURN** End of DSTEMR*END*> \brief \b DSTEQR** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEQR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsteqr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsteqr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsteqr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )** .. Scalar Arguments ..* CHARACTER COMPZ* INTEGER INFO, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEQR computes all eigenvalues and, optionally, eigenvectors of a*> symmetric tridiagonal matrix using the implicit QL or QR method.*> The eigenvectors of a full or band symmetric matrix can also be found*> if DSYTRD or DSPTRD or DSBTRD has been used to reduce this matrix to*> tridiagonal form.*> \endverbatim** Arguments:* ==========**> \param[in] COMPZ*> \verbatim*> COMPZ is CHARACTER*1*> = 'N': Compute eigenvalues only.*> = 'V': Compute eigenvalues and eigenvectors of the original*> symmetric matrix. On entry, Z must contain the*> orthogonal matrix used to reduce the original matrix*> to tridiagonal form.*> = 'I': Compute eigenvalues and eigenvectors of the*> tridiagonal matrix. Z is initialized to the identity*> matrix.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the diagonal elements of the tridiagonal matrix.*> On exit, if INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> On entry, if COMPZ = 'V', then Z contains the orthogonal*> matrix used in the reduction to tridiagonal form.*> On exit, if INFO = 0, then if COMPZ = 'V', Z contains the*> orthonormal eigenvectors of the original symmetric matrix,*> and if COMPZ = 'I', Z contains the orthonormal eigenvectors*> of the symmetric tridiagonal matrix.*> If COMPZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> eigenvectors are desired, then LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (max(1,2*N-2))*> If COMPZ = 'N', then WORK is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: the algorithm has failed to find all the eigenvalues in*> a total of 30*N iterations; if INFO = i, then i*> elements of E have not converged to zero; on exit, D*> and E contain the elements of a symmetric tridiagonal*> matrix which is orthogonally similar to the original*> matrix.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER COMPZINTEGER INFO, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, THREEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0 )INTEGER MAXITPARAMETER ( MAXIT = 30 )* ..* .. Local Scalars ..INTEGER I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,$ LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,$ NM1, NMAXITDOUBLE PRECISION ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,$ S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANST, DLAPY2EXTERNAL LSAME, DLAMCH, DLANST, DLAPY2* ..* .. External Subroutines ..EXTERNAL DLAE2, DLAEV2, DLARTG, DLASCL, DLASET, DLASR,$ DLASRT, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0*IF( LSAME( COMPZ, 'N' ) ) THENICOMPZ = 0ELSE IF( LSAME( COMPZ, 'V' ) ) THENICOMPZ = 1ELSE IF( LSAME( COMPZ, 'I' ) ) THENICOMPZ = 2ELSEICOMPZ = -1END IFIF( ICOMPZ.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( ( LDZ.LT.1 ) .OR. ( ICOMPZ.GT.0 .AND. LDZ.LT.MAX( 1,$ N ) ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEQR', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ICOMPZ.EQ.2 )$ Z( 1, 1 ) = ONERETURNEND IF** Determine the unit roundoff and over/underflow thresholds.*EPS = DLAMCH( 'E' )EPS2 = EPS**2SAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINSSFMAX = SQRT( SAFMAX ) / THREESSFMIN = SQRT( SAFMIN ) / EPS2** Compute the eigenvalues and eigenvectors of the tridiagonal* matrix.*IF( ICOMPZ.EQ.2 )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )*NMAXIT = N*MAXITJTOT = 0** Determine where the matrix splits and choose QL or QR iteration* for each block, according to whether top or bottom diagonal* element is smaller.*L1 = 1NM1 = N - 1*10 CONTINUEIF( L1.GT.N )$ GO TO 160IF( L1.GT.1 )$ E( L1-1 ) = ZEROIF( L1.LE.NM1 ) THENDO 20 M = L1, NM1TST = ABS( E( M ) )IF( TST.EQ.ZERO )$ GO TO 30IF( TST.LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+$ 1 ) ) ) )*EPS ) THENE( M ) = ZEROGO TO 30END IF20 CONTINUEEND IFM = N*30 CONTINUEL = L1LSV = LLEND = MLENDSV = LENDL1 = M + 1IF( LEND.EQ.L )$ GO TO 10** Scale submatrix in rows and columns L to LEND*ANORM = DLANST( 'M', LEND-L+1, D( L ), E( L ) )ISCALE = 0IF( ANORM.EQ.ZERO )$ GO TO 10IF( ANORM.GT.SSFMAX ) THENISCALE = 1CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,$ INFO )ELSE IF( ANORM.LT.SSFMIN ) THENISCALE = 2CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,$ INFO )END IF** Choose between QL and QR iteration*IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THENLEND = LSVL = LENDSVEND IF*IF( LEND.GT.L ) THEN** QL Iteration** Look for small subdiagonal element.*40 CONTINUEIF( L.NE.LEND ) THENLENDM1 = LEND - 1DO 50 M = L, LENDM1TST = ABS( E( M ) )**2IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M+1 ) )+$ SAFMIN )GO TO 6050 CONTINUEEND IF*M = LEND*60 CONTINUEIF( M.LT.LEND )$ E( M ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 80** If remaining matrix is 2-by-2, use DLAE2 or SLAEV2* to compute its eigensystem.*IF( M.EQ.L+1 ) THENIF( ICOMPZ.GT.0 ) THENCALL DLAEV2( D( L ), E( L ), D( L+1 ), RT1, RT2, C, S )WORK( L ) = CWORK( N-1+L ) = SCALL DLASR( 'R', 'V', 'B', N, 2, WORK( L ),$ WORK( N-1+L ), Z( 1, L ), LDZ )ELSECALL DLAE2( D( L ), E( L ), D( L+1 ), RT1, RT2 )END IFD( L ) = RT1D( L+1 ) = RT2E( L ) = ZEROL = L + 2IF( L.LE.LEND )$ GO TO 40GO TO 140END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 140JTOT = JTOT + 1** Form shift.*G = ( D( L+1 )-P ) / ( TWO*E( L ) )R = DLAPY2( G, ONE )G = D( M ) - P + ( E( L ) / ( G+SIGN( R, G ) ) )*S = ONEC = ONEP = ZERO** Inner loop*MM1 = M - 1DO 70 I = MM1, L, -1F = S*E( I )B = C*E( I )CALL DLARTG( G, F, C, S, R )IF( I.NE.M-1 )$ E( I+1 ) = RG = D( I+1 ) - PR = ( D( I )-G )*S + TWO*C*BP = S*RD( I+1 ) = G + PG = C*R - B** If eigenvectors are desired, then save rotations.*IF( ICOMPZ.GT.0 ) THENWORK( I ) = CWORK( N-1+I ) = -SEND IF*70 CONTINUE** If eigenvectors are desired, then apply saved rotations.*IF( ICOMPZ.GT.0 ) THENMM = M - L + 1CALL DLASR( 'R', 'V', 'B', N, MM, WORK( L ), WORK( N-1+L ),$ Z( 1, L ), LDZ )END IF*D( L ) = D( L ) - PE( L ) = GGO TO 40** Eigenvalue found.*80 CONTINUED( L ) = P*L = L + 1IF( L.LE.LEND )$ GO TO 40GO TO 140*ELSE** QR Iteration** Look for small superdiagonal element.*90 CONTINUEIF( L.NE.LEND ) THENLENDP1 = LEND + 1DO 100 M = L, LENDP1, -1TST = ABS( E( M-1 ) )**2IF( TST.LE.( EPS2*ABS( D( M ) ) )*ABS( D( M-1 ) )+$ SAFMIN )GO TO 110100 CONTINUEEND IF*M = LEND*110 CONTINUEIF( M.GT.LEND )$ E( M-1 ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 130** If remaining matrix is 2-by-2, use DLAE2 or SLAEV2* to compute its eigensystem.*IF( M.EQ.L-1 ) THENIF( ICOMPZ.GT.0 ) THENCALL DLAEV2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2, C, S )WORK( M ) = CWORK( N-1+M ) = SCALL DLASR( 'R', 'V', 'F', N, 2, WORK( M ),$ WORK( N-1+M ), Z( 1, L-1 ), LDZ )ELSECALL DLAE2( D( L-1 ), E( L-1 ), D( L ), RT1, RT2 )END IFD( L-1 ) = RT1D( L ) = RT2E( L-1 ) = ZEROL = L - 2IF( L.GE.LEND )$ GO TO 90GO TO 140END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 140JTOT = JTOT + 1** Form shift.*G = ( D( L-1 )-P ) / ( TWO*E( L-1 ) )R = DLAPY2( G, ONE )G = D( M ) - P + ( E( L-1 ) / ( G+SIGN( R, G ) ) )*S = ONEC = ONEP = ZERO** Inner loop*LM1 = L - 1DO 120 I = M, LM1F = S*E( I )B = C*E( I )CALL DLARTG( G, F, C, S, R )IF( I.NE.M )$ E( I-1 ) = RG = D( I ) - PR = ( D( I+1 )-G )*S + TWO*C*BP = S*RD( I ) = G + PG = C*R - B** If eigenvectors are desired, then save rotations.*IF( ICOMPZ.GT.0 ) THENWORK( I ) = CWORK( N-1+I ) = SEND IF*120 CONTINUE** If eigenvectors are desired, then apply saved rotations.*IF( ICOMPZ.GT.0 ) THENMM = L - M + 1CALL DLASR( 'R', 'V', 'F', N, MM, WORK( M ), WORK( N-1+M ),$ Z( 1, M ), LDZ )END IF*D( L ) = D( L ) - PE( LM1 ) = GGO TO 90** Eigenvalue found.*130 CONTINUED( L ) = P*L = L - 1IF( L.GE.LEND )$ GO TO 90GO TO 140*END IF** Undo scaling if necessary*140 CONTINUEIF( ISCALE.EQ.1 ) THENCALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV, 1, E( LSV ),$ N, INFO )ELSE IF( ISCALE.EQ.2 ) THENCALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV, 1, E( LSV ),$ N, INFO )END IF** Check for no convergence to an eigenvalue after a total* of N*MAXIT iterations.*IF( JTOT.LT.NMAXIT )$ GO TO 10DO 150 I = 1, N - 1IF( E( I ).NE.ZERO )$ INFO = INFO + 1150 CONTINUEGO TO 190** Order eigenvalues and eigenvectors.*160 CONTINUEIF( ICOMPZ.EQ.0 ) THEN** Use Quick Sort*CALL DLASRT( 'I', N, D, INFO )*ELSE** Use Selection Sort to minimize swaps of eigenvectors*DO 180 II = 2, NI = II - 1K = IP = D( I )DO 170 J = II, NIF( D( J ).LT.P ) THENK = JP = D( J )END IF170 CONTINUEIF( K.NE.I ) THEND( K ) = D( I )D( I ) = PCALL DSWAP( N, Z( 1, I ), 1, Z( 1, K ), 1 )END IF180 CONTINUEEND IF*190 CONTINUERETURN** End of DSTEQR*END*> \brief \b DSTERF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTERF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsterf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsterf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsterf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTERF( N, D, E, INFO )** .. Scalar Arguments ..* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTERF computes all eigenvalues of a symmetric tridiagonal matrix*> using the Pal-Walker-Kahan variant of the QL or QR algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix.*> On exit, if INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix.*> On exit, E has been destroyed.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: the algorithm failed to find all of the eigenvalues in*> a total of 30*N iterations; if INFO = i, then i*> elements of E have not converged to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================SUBROUTINE DSTERF( N, D, E, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWO, THREEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,$ THREE = 3.0D0 )INTEGER MAXITPARAMETER ( MAXIT = 30 )* ..* .. Local Scalars ..INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,$ NMAXITDOUBLE PRECISION ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,$ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,$ SIGMA, SSFMAX, SSFMIN, RMAX* ..* .. External Functions ..DOUBLE PRECISION DLAMCH, DLANST, DLAPY2EXTERNAL DLAMCH, DLANST, DLAPY2* ..* .. External Subroutines ..EXTERNAL DLAE2, DLASCL, DLASRT, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, SIGN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0** Quick return if possible*IF( N.LT.0 ) THENINFO = -1CALL XERBLA( 'DSTERF', -INFO )RETURNEND IFIF( N.LE.1 )$ RETURN** Determine the unit roundoff for this environment.*EPS = DLAMCH( 'E' )EPS2 = EPS**2SAFMIN = DLAMCH( 'S' )SAFMAX = ONE / SAFMINSSFMAX = SQRT( SAFMAX ) / THREESSFMIN = SQRT( SAFMIN ) / EPS2RMAX = DLAMCH( 'O' )** Compute the eigenvalues of the tridiagonal matrix.*NMAXIT = N*MAXITSIGMA = ZEROJTOT = 0** Determine where the matrix splits and choose QL or QR iteration* for each block, according to whether top or bottom diagonal* element is smaller.*L1 = 1*10 CONTINUEIF( L1.GT.N )$ GO TO 170IF( L1.GT.1 )$ E( L1-1 ) = ZERODO 20 M = L1, N - 1IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+$ 1 ) ) ) )*EPS ) THENE( M ) = ZEROGO TO 30END IF20 CONTINUEM = N*30 CONTINUEL = L1LSV = LLEND = MLENDSV = LENDL1 = M + 1IF( LEND.EQ.L )$ GO TO 10** Scale submatrix in rows and columns L to LEND*ANORM = DLANST( 'M', LEND-L+1, D( L ), E( L ) )ISCALE = 0IF( ANORM.EQ.ZERO )$ GO TO 10IF( (ANORM.GT.SSFMAX) ) THENISCALE = 1CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,$ INFO )ELSE IF( ANORM.LT.SSFMIN ) THENISCALE = 2CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,$ INFO )CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,$ INFO )END IF*DO 40 I = L, LEND - 1E( I ) = E( I )**240 CONTINUE** Choose between QL and QR iteration*IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THENLEND = LSVL = LENDSVEND IF*IF( LEND.GE.L ) THEN** QL Iteration** Look for small subdiagonal element.*50 CONTINUEIF( L.NE.LEND ) THENDO 60 M = L, LEND - 1IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) )$ GO TO 7060 CONTINUEEND IFM = LEND*70 CONTINUEIF( M.LT.LEND )$ E( M ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 90** If remaining matrix is 2 by 2, use DLAE2 to compute its* eigenvalues.*IF( M.EQ.L+1 ) THENRTE = SQRT( E( L ) )CALL DLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )D( L ) = RT1D( L+1 ) = RT2E( L ) = ZEROL = L + 2IF( L.LE.LEND )$ GO TO 50GO TO 150END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 150JTOT = JTOT + 1** Form shift.*RTE = SQRT( E( L ) )SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )R = DLAPY2( SIGMA, ONE )SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )*C = ONES = ZEROGAMMA = D( M ) - SIGMAP = GAMMA*GAMMA** Inner loop*DO 80 I = M - 1, L, -1BB = E( I )R = P + BBIF( I.NE.M-1 )$ E( I+1 ) = S*ROLDC = CC = P / RS = BB / ROLDGAM = GAMMAALPHA = D( I )GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAMD( I+1 ) = OLDGAM + ( ALPHA-GAMMA )IF( C.NE.ZERO ) THENP = ( GAMMA*GAMMA ) / CELSEP = OLDC*BBEND IF80 CONTINUE*E( L ) = S*PD( L ) = SIGMA + GAMMAGO TO 50** Eigenvalue found.*90 CONTINUED( L ) = P*L = L + 1IF( L.LE.LEND )$ GO TO 50GO TO 150*ELSE** QR Iteration** Look for small superdiagonal element.*100 CONTINUEDO 110 M = L, LEND + 1, -1IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) )$ GO TO 120110 CONTINUEM = LEND*120 CONTINUEIF( M.GT.LEND )$ E( M-1 ) = ZEROP = D( L )IF( M.EQ.L )$ GO TO 140** If remaining matrix is 2 by 2, use DLAE2 to compute its* eigenvalues.*IF( M.EQ.L-1 ) THENRTE = SQRT( E( L-1 ) )CALL DLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )D( L ) = RT1D( L-1 ) = RT2E( L-1 ) = ZEROL = L - 2IF( L.GE.LEND )$ GO TO 100GO TO 150END IF*IF( JTOT.EQ.NMAXIT )$ GO TO 150JTOT = JTOT + 1** Form shift.*RTE = SQRT( E( L-1 ) )SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )R = DLAPY2( SIGMA, ONE )SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )*C = ONES = ZEROGAMMA = D( M ) - SIGMAP = GAMMA*GAMMA** Inner loop*DO 130 I = M, L - 1BB = E( I )R = P + BBIF( I.NE.M )$ E( I-1 ) = S*ROLDC = CC = P / RS = BB / ROLDGAM = GAMMAALPHA = D( I+1 )GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAMD( I ) = OLDGAM + ( ALPHA-GAMMA )IF( C.NE.ZERO ) THENP = ( GAMMA*GAMMA ) / CELSEP = OLDC*BBEND IF130 CONTINUE*E( L-1 ) = S*PD( L ) = SIGMA + GAMMAGO TO 100** Eigenvalue found.*140 CONTINUED( L ) = P*L = L - 1IF( L.GE.LEND )$ GO TO 100GO TO 150*END IF** Undo scaling if necessary*150 CONTINUEIF( ISCALE.EQ.1 )$ CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )IF( ISCALE.EQ.2 )$ CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,$ D( LSV ), N, INFO )** Check for no convergence to an eigenvalue after a total* of N*MAXIT iterations.*IF( JTOT.LT.NMAXIT )$ GO TO 10DO 160 I = 1, N - 1IF( E( I ).NE.ZERO )$ INFO = INFO + 1160 CONTINUEGO TO 180** Sort eigenvalues in increasing order.*170 CONTINUECALL DLASRT( 'I', N, D, INFO )*180 CONTINUERETURN** End of DSTERF*END*> \brief <b> DSTEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstev.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstev.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstev.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEV( JOBZ, N, D, E, Z, LDZ, WORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ* INTEGER INFO, LDZ, N* ..* .. Array Arguments ..* DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEV computes all eigenvalues and, optionally, eigenvectors of a*> real symmetric tridiagonal matrix A.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix*> A.*> On exit, if INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix A, stored in elements 1 to N-1 of E.*> On exit, the contents of E are destroyed.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal*> eigenvectors of the matrix A, with the i-th column of Z*> holding the eigenvector associated with D(i).*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (max(1,2*N-2))*> If JOBZ = 'N', WORK is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of E did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSTEV( JOBZ, N, D, E, Z, LDZ, WORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZINTEGER INFO, LDZ, N* ..* .. Array Arguments ..DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL WANTZINTEGER IMAX, ISCALEDOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,$ TNRM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DSCAL, DSTEQR, DSTERF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -6END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEV ', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ISCALE = 0TNRM = DLANST( 'M', N, D, E )IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / TNRMELSE IF( TNRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / TNRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( N, SIGMA, D, 1 )CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )END IF** For eigenvalues only, call DSTERF. For eigenvalues and* eigenvectors, call DSTEQR.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, D, E, INFO )ELSECALL DSTEQR( 'I', N, D, E, Z, LDZ, WORK, INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = NELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, D, 1 )END IF*RETURN** End of DSTEV*END*> \brief <b> DSTEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstevd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstevd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstevd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEVD( JOBZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,* LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ* INTEGER INFO, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEVD computes all eigenvalues and, optionally, eigenvectors of a*> real symmetric tridiagonal matrix. If eigenvectors are desired, it*> uses a divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix*> A.*> On exit, if INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix A, stored in elements 1 to N-1 of E.*> On exit, the contents of E are destroyed.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, N)*> If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal*> eigenvectors of the matrix A, with the i-th column of Z*> holding the eigenvector associated with D(i).*> If JOBZ = 'N', then Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array,*> dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If JOBZ = 'N' or N <= 1 then LWORK must be at least 1.*> If JOBZ = 'V' and N > 1 then LWORK must be at least*> ( 1 + 4*N + N**2 ).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If JOBZ = 'N' or N <= 1 then LIWORK must be at least 1.*> If JOBZ = 'V' and N > 1 then LIWORK must be at least 3+5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of E did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSTEVD( JOBZ, N, D, E, Z, LDZ, WORK, LWORK, IWORK,$ LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZINTEGER INFO, LDZ, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LQUERY, WANTZINTEGER ISCALE, LIWMIN, LWMINDOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,$ TNRM* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DSCAL, DSTEDC, DSTERF, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0LIWMIN = 1LWMIN = 1IF( N.GT.1 .AND. WANTZ ) THENLWMIN = 1 + 4*N + N**2LIWMIN = 3 + 5*NEND IF*IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -6END IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -8ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -10END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ISCALE = 0TNRM = DLANST( 'M', N, D, E )IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / TNRMELSE IF( TNRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / TNRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( N, SIGMA, D, 1 )CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )END IF** For eigenvalues only, call DSTERF. For eigenvalues and* eigenvectors, call DSTEDC.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, D, E, INFO )ELSECALL DSTEDC( 'I', N, D, E, Z, LDZ, WORK, LWORK, IWORK, LIWORK,$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 )$ CALL DSCAL( N, ONE / SIGMA, D, 1 )*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DSTEVD*END*> \brief <b> DSTEVR computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEVR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstevr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstevr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstevr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,* M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,* LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE* INTEGER IL, INFO, IU, LDZ, LIWORK, LWORK, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER ISUPPZ( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEVR computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric tridiagonal matrix T. Eigenvalues and*> eigenvectors can be selected by specifying either a range of values*> or a range of indices for the desired eigenvalues.*>*> Whenever possible, DSTEVR calls DSTEMR to compute the*> eigenspectrum using Relatively Robust Representations. DSTEMR*> computes eigenvalues by the dqds algorithm, while orthogonal*> eigenvectors are computed from various "good" L D L^T representations*> (also known as Relatively Robust Representations). Gram-Schmidt*> orthogonalization is avoided as far as possible. More specifically,*> the various steps of the algorithm are as follows. For the i-th*> unreduced block of T,*> (a) Compute T - sigma_i = L_i D_i L_i^T, such that L_i D_i L_i^T*> is a relatively robust representation,*> (b) Compute the eigenvalues, lambda_j, of L_i D_i L_i^T to high*> relative accuracy by the dqds algorithm,*> (c) If there is a cluster of close eigenvalues, "choose" sigma_i*> close to the cluster, and go to step (a),*> (d) Given the approximate eigenvalue lambda_j of L_i D_i L_i^T,*> compute the corresponding eigenvector by forming a*> rank-revealing twisted factorization.*> The desired accuracy of the output can be specified by the input*> parameter ABSTOL.*>*> For more details, see "A new O(n^2) algorithm for the symmetric*> tridiagonal eigenvalue/eigenvector problem", by Inderjit Dhillon,*> Computer Science Division Technical Report No. UCB//CSD-97-971,*> UC Berkeley, May 1997.*>*>*> Note 1 : DSTEVR calls DSTEMR when the full spectrum is requested*> on machines which conform to the ieee-754 floating point standard.*> DSTEVR calls DSTEBZ and DSTEIN on non-ieee machines and*> when partial spectrum requests are made.*>*> Normal execution of DSTEMR may create NaNs and infinities and*> hence may abort due to a floating point exception in environments*> which do not handle NaNs and infinities in the ieee standard default*> manner.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and*> DSTEIN are called*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix*> A.*> On exit, D may be multiplied by a constant factor chosen*> to avoid over/underflow in computing the eigenvalues.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (max(1,N-1))*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix A in elements 1 to N-1 of E.*> On exit, E may be multiplied by a constant factor chosen*> to avoid over/underflow in computing the eigenvalues.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing A to tridiagonal form.*>*> See "Computing Small Singular Values of Bidiagonal Matrices*> with Guaranteed High Relative Accuracy," by Demmel and*> Kahan, LAPACK Working Note #3.*>*> If high relative accuracy is important, set ABSTOL to*> DLAMCH( 'Safe minimum' ). Doing so will guarantee that*> eigenvalues are computed to high relative accuracy when*> possible in future releases. The current code does not*> make any guarantees about high relative accuracy, but*> future releases will. See J. Barlow and J. Demmel,*> "Computing Accurate Eigensystems of Scaled Diagonally*> Dominant Matrices", LAPACK Working Note #7, for a discussion*> of which matrices define their eigenvalues to high relative*> accuracy.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the selected eigenvalues in*> ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) )*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] ISUPPZ*> \verbatim*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )*> The support of the eigenvectors in Z, i.e., the indices*> indicating the nonzero elements in Z. The i-th eigenvector*> is nonzero only in elements ISUPPZ( 2*i-1 ) through*> ISUPPZ( 2*i ).*> Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal (and*> minimal) LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,20*N).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal (and*> minimal) LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK. LIWORK >= max(1,10*N).*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: Internal error*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen**> \par Contributors:* ==================*>*> Inderjit Dhillon, IBM Almaden, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Ken Stanley, Computer Science Division, University of*> California at Berkeley, USA \n*>* =====================================================================SUBROUTINE DSTEVR( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,$ M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK,$ LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGEINTEGER IL, INFO, IU, LDZ, LIWORK, LWORK, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER ISUPPZ( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, TEST, LQUERY, VALEIG, WANTZ,$ TRYRACCHARACTER ORDERINTEGER I, IEEEOK, IMAX, INDIBL, INDIFL, INDISP,$ INDIWO, ISCALE, ITMP1, J, JJ, LIWMIN, LWMIN,$ NSPLITDOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,$ TMP1, TNRM, VLL, VUU* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, ILAENV, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DSCAL, DSTEBZ, DSTEMR, DSTEIN, DSTERF,$ DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..*** Test the input parameters.*IEEEOK = ILAENV( 10, 'DSTEVR', 'N', 1, 2, 3, 4 )*WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LIWORK.EQ.-1 ) )LWMIN = MAX( 1, 20*N )LIWMIN = MAX( 1, 10*N )**INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -7ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -8ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -9END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -14END IFEND IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -17ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -19END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEVR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ALLEIG .OR. INDEIG ) THENM = 1W( 1 ) = D( 1 )ELSEIF( VL.LT.D( 1 ) .AND. VU.GE.D( 1 ) ) THENM = 1W( 1 ) = D( 1 )END IFEND IFIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )*** Scale matrix to allowable range, if necessary.*ISCALE = 0IF( VALEIG ) THENVLL = VLVUU = VUEND IF*TNRM = DLANST( 'M', N, D, E )IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / TNRMELSE IF( TNRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / TNRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( N, SIGMA, D, 1 )CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )IF( VALEIG ) THENVLL = VL*SIGMAVUU = VU*SIGMAEND IFEND IF* Initialize indices into workspaces. Note: These indices are used only* if DSTERF or DSTEMR fail.* IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and* stores the block indices of each of the M<=N eigenvalues.INDIBL = 1* IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and* stores the starting and finishing indices of each block.INDISP = INDIBL + N* IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors* that corresponding to eigenvectors that fail to converge in* DSTEIN. This information is discarded; if any fail, the driver* returns INFO > 0.INDIFL = INDISP + N* INDIWO is the offset of the remaining integer workspace.INDIWO = INDISP + N** If all eigenvalues are desired, then* call DSTERF or DSTEMR. If this fails for some eigenvalue, then* try DSTEBZ.**TEST = .FALSE.IF( INDEIG ) THENIF( IL.EQ.1 .AND. IU.EQ.N ) THENTEST = .TRUE.END IFEND IFIF( ( ALLEIG .OR. TEST ) .AND. IEEEOK.EQ.1 ) THENCALL DCOPY( N-1, E( 1 ), 1, WORK( 1 ), 1 )IF( .NOT.WANTZ ) THENCALL DCOPY( N, D, 1, W, 1 )CALL DSTERF( N, W, WORK, INFO )ELSECALL DCOPY( N, D, 1, WORK( N+1 ), 1 )IF (ABSTOL .LE. TWO*N*EPS) THENTRYRAC = .TRUE.ELSETRYRAC = .FALSE.END IFCALL DSTEMR( JOBZ, 'A', N, WORK( N+1 ), WORK, VL, VU, IL,$ IU, M, W, Z, LDZ, N, ISUPPZ, TRYRAC,$ WORK( 2*N+1 ), LWORK-2*N, IWORK, LIWORK, INFO )*END IFIF( INFO.EQ.0 ) THENM = NGO TO 10END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired, DSTEIN.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFCALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTOL, D, E, M,$ NSPLIT, W, IWORK( INDIBL ), IWORK( INDISP ), WORK,$ IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, D, E, M, W, IWORK( INDIBL ), IWORK( INDISP ),$ Z, LDZ, WORK, IWORK( INDIWO ), IWORK( INDIFL ),$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*10 CONTINUEIF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = MELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** If eigenvalues are not in order, then sort them, along with* eigenvectors.*IF( WANTZ ) THENDO 30 J = 1, M - 1I = 0TMP1 = W( J )DO 20 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF20 CONTINUE*IF( I.NE.0 ) THENITMP1 = IWORK( I )W( I ) = W( J )IWORK( I ) = IWORK( J )W( J ) = TMP1IWORK( J ) = ITMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )END IF30 CONTINUEEND IF** Causes problems with tests 19 & 20:* IF (wantz .and. INDEIG ) Z( 1,1) = Z(1,1) / 1.002 + .002**WORK( 1 ) = LWMINIWORK( 1 ) = LIWMINRETURN** End of DSTEVR*END*> \brief <b> DSTEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSTEVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstevx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstevx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstevx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,* M, W, Z, LDZ, WORK, IWORK, IFAIL, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE* INTEGER IL, INFO, IU, LDZ, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSTEVX computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric tridiagonal matrix A. Eigenvalues and*> eigenvectors can be selected by specifying either a range of values*> or a range of indices for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix. N >= 0.*> \endverbatim*>*> \param[in,out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> On entry, the n diagonal elements of the tridiagonal matrix*> A.*> On exit, D may be multiplied by a constant factor chosen*> to avoid over/underflow in computing the eigenvalues.*> \endverbatim*>*> \param[in,out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (max(1,N-1))*> On entry, the (n-1) subdiagonal elements of the tridiagonal*> matrix A in elements 1 to N-1 of E.*> On exit, E may be multiplied by a constant factor chosen*> to avoid over/underflow in computing the eigenvalues.*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less*> than or equal to zero, then EPS*|T| will be used in*> its place, where |T| is the 1-norm of the tridiagonal*> matrix.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*>*> See "Computing Small Singular Values of Bidiagonal Matrices*> with Guaranteed High Relative Accuracy," by Demmel and*> Kahan, LAPACK Working Note #3.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the selected eigenvalues in*> ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) )*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If an eigenvector fails to converge (INFO > 0), then that*> column of Z contains the latest approximation to the*> eigenvector, and the index of the eigenvector is returned*> in IFAIL. If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (5*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (N)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvectors that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, then i eigenvectors failed to converge.*> Their indices are stored in array IFAIL.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHEReigen** =====================================================================SUBROUTINE DSTEVX( JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL,$ M, W, Z, LDZ, WORK, IWORK, IFAIL, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGEINTEGER IL, INFO, IU, LDZ, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, TEST, VALEIG, WANTZCHARACTER ORDERINTEGER I, IMAX, INDIBL, INDISP, INDIWO, INDWRK,$ ISCALE, ITMP1, J, JJ, NSPLITDOUBLE PRECISION BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,$ TMP1, TNRM, VLL, VUU* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCH, DLANSTEXTERNAL LSAME, DLAMCH, DLANST* ..* .. External Subroutines ..EXTERNAL DCOPY, DSCAL, DSTEBZ, DSTEIN, DSTEQR, DSTERF,$ DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -7ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -8ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -9END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) )$ INFO = -14END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSTEVX', -INFO )RETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( ALLEIG .OR. INDEIG ) THENM = 1W( 1 ) = D( 1 )ELSEIF( VL.LT.D( 1 ) .AND. VU.GE.D( 1 ) ) THENM = 1W( 1 ) = D( 1 )END IFEND IFIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )** Scale matrix to allowable range, if necessary.*ISCALE = 0IF( VALEIG ) THENVLL = VLVUU = VUELSEVLL = ZEROVUU = ZEROEND IFTNRM = DLANST( 'M', N, D, E )IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / TNRMELSE IF( TNRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / TNRMEND IFIF( ISCALE.EQ.1 ) THENCALL DSCAL( N, SIGMA, D, 1 )CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )IF( VALEIG ) THENVLL = VL*SIGMAVUU = VU*SIGMAEND IFEND IF** If all eigenvalues are desired and ABSTOL is less than zero, then* call DSTERF or SSTEQR. If this fails for some eigenvalue, then* try DSTEBZ.*TEST = .FALSE.IF( INDEIG ) THENIF( IL.EQ.1 .AND. IU.EQ.N ) THENTEST = .TRUE.END IFEND IFIF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THENCALL DCOPY( N, D, 1, W, 1 )CALL DCOPY( N-1, E( 1 ), 1, WORK( 1 ), 1 )INDWRK = N + 1IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK, INFO )ELSECALL DSTEQR( 'I', N, W, WORK, Z, LDZ, WORK( INDWRK ), INFO )IF( INFO.EQ.0 ) THENDO 10 I = 1, NIFAIL( I ) = 010 CONTINUEEND IFEND IFIF( INFO.EQ.0 ) THENM = NGO TO 20END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFINDWRK = 1INDIBL = 1INDISP = INDIBL + NINDIWO = INDISP + NCALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTOL, D, E, M,$ NSPLIT, W, IWORK( INDIBL ), IWORK( INDISP ),$ WORK( INDWRK ), IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, D, E, M, W, IWORK( INDIBL ), IWORK( INDISP ),$ Z, LDZ, WORK( INDWRK ), IWORK( INDIWO ), IFAIL,$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*20 CONTINUEIF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = MELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** If eigenvalues are not in order, then sort them, along with* eigenvectors.*IF( WANTZ ) THENDO 40 J = 1, M - 1I = 0TMP1 = W( J )DO 30 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF30 CONTINUE*IF( I.NE.0 ) THENITMP1 = IWORK( INDIBL+I-1 )W( I ) = W( J )IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )W( J ) = TMP1IWORK( INDIBL+J-1 ) = ITMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )IF( INFO.NE.0 ) THENITMP1 = IFAIL( I )IFAIL( I ) = IFAIL( J )IFAIL( J ) = ITMP1END IFEND IF40 CONTINUEEND IF*RETURN** End of DSTEVX*END*> \brief \b DSYCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsycon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsycon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsycon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYCON( UPLO, N, A, LDA, IPIV, ANORM, RCOND, WORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* DOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYCON estimates the reciprocal of the condition number (in the*> 1-norm) of a real symmetric matrix A using the factorization*> A = U*D*U**T or A = L*D*L**T computed by DSYTRF.*>*> An estimate is obtained for norm(inv(A)), and the reciprocal of the*> condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The block diagonal matrix D and the multipliers used to*> obtain the factor U or L as computed by DSYTRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[in] ANORM*> \verbatim*> ANORM is DOUBLE PRECISION*> The 1-norm of the original matrix A.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an*> estimate of the 1-norm of inv(A) computed in this routine.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYCON( UPLO, N, A, LDA, IPIV, ANORM, RCOND, WORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, NDOUBLE PRECISION ANORM, RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, KASEDOUBLE PRECISION AINVNM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLACN2, DSYTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( ANORM.LT.ZERO ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYCON', -INFO )RETURNEND IF** Quick return if possible*RCOND = ZEROIF( N.EQ.0 ) THENRCOND = ONERETURNELSE IF( ANORM.LE.ZERO ) THENRETURNEND IF** Check that the diagonal matrix D is nonsingular.*IF( UPPER ) THEN** Upper triangular storage: examine D from bottom to top*DO 10 I = N, 1, -1IF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.ZERO )$ RETURN10 CONTINUEELSE** Lower triangular storage: examine D from top to bottom.*DO 20 I = 1, NIF( IPIV( I ).GT.0 .AND. A( I, I ).EQ.ZERO )$ RETURN20 CONTINUEEND IF** Estimate the 1-norm of the inverse.*KASE = 030 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THEN** Multiply by inv(L*D*L**T) or inv(U*D*U**T).*CALL DSYTRS( UPLO, N, 1, A, LDA, IPIV, WORK, N, INFO )GO TO 30END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / AINVNM ) / ANORM*RETURN** End of DSYCON*END*> \brief \b DSYCONV** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYCONV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyconv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyconv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyconv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYCONV( UPLO, WAY, N, A, LDA, IPIV, E, INFO )** .. Scalar Arguments ..* CHARACTER UPLO, WAY* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), E( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYCONV convert A given by TRF into L and D and vice-versa.*> Get Non-diag elements of D (returned in workspace) and*> apply or reverse permutation done in TRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] WAY*> \verbatim*> WAY is CHARACTER*1*> = 'C': Convert*> = 'R': Revert*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The block diagonal matrix D and the multipliers used to*> obtain the factor U or L as computed by DSYTRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N)*> E stores the supdiagonal/subdiagonal of the symmetric 1-by-1*> or 2-by-2 block diagonal matrix D in LDLT.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYCONV( UPLO, WAY, N, A, LDA, IPIV, E, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLO, WAYINTEGER INFO, LDA, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), E( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME** .. External Subroutines ..EXTERNAL XERBLA* .. Local Scalars ..LOGICAL UPPER, CONVERTINTEGER I, IP, JDOUBLE PRECISION TEMP* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )CONVERT = LSAME( WAY, 'C' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.CONVERT .AND. .NOT.LSAME( WAY, 'R' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYCONV', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( UPPER ) THEN** A is UPPER** Convert A (A is upper)** Convert VALUE*IF ( CONVERT ) THENI=NE(1)=ZERODO WHILE ( I .GT. 1 )IF( IPIV(I) .LT. 0 ) THENE(I)=A(I-1,I)E(I-1)=ZEROA(I-1,I)=ZEROI=I-1ELSEE(I)=ZEROENDIFI=I-1END DO** Convert PERMUTATIONS*I=NDO WHILE ( I .GE. 1 )IF( IPIV(I) .GT. 0) THENIP=IPIV(I)IF( I .LT. N) THENDO 12 J= I+1,NTEMP=A(IP,J)A(IP,J)=A(I,J)A(I,J)=TEMP12 CONTINUEENDIFELSEIP=-IPIV(I)IF( I .LT. N) THENDO 13 J= I+1,NTEMP=A(IP,J)A(IP,J)=A(I-1,J)A(I-1,J)=TEMP13 CONTINUEENDIFI=I-1ENDIFI=I-1END DOELSE** Revert A (A is upper)*** Revert PERMUTATIONS*I=1DO WHILE ( I .LE. N )IF( IPIV(I) .GT. 0 ) THENIP=IPIV(I)IF( I .LT. N) THENDO J= I+1,NTEMP=A(IP,J)A(IP,J)=A(I,J)A(I,J)=TEMPEND DOENDIFELSEIP=-IPIV(I)I=I+1IF( I .LT. N) THENDO J= I+1,NTEMP=A(IP,J)A(IP,J)=A(I-1,J)A(I-1,J)=TEMPEND DOENDIFENDIFI=I+1END DO** Revert VALUE*I=NDO WHILE ( I .GT. 1 )IF( IPIV(I) .LT. 0 ) THENA(I-1,I)=E(I)I=I-1ENDIFI=I-1END DOEND IFELSE** A is LOWER*IF ( CONVERT ) THEN** Convert A (A is lower)*** Convert VALUE*I=1E(N)=ZERODO WHILE ( I .LE. N )IF( I.LT.N .AND. IPIV(I) .LT. 0 ) THENE(I)=A(I+1,I)E(I+1)=ZEROA(I+1,I)=ZEROI=I+1ELSEE(I)=ZEROENDIFI=I+1END DO** Convert PERMUTATIONS*I=1DO WHILE ( I .LE. N )IF( IPIV(I) .GT. 0 ) THENIP=IPIV(I)IF (I .GT. 1) THENDO 22 J= 1,I-1TEMP=A(IP,J)A(IP,J)=A(I,J)A(I,J)=TEMP22 CONTINUEENDIFELSEIP=-IPIV(I)IF (I .GT. 1) THENDO 23 J= 1,I-1TEMP=A(IP,J)A(IP,J)=A(I+1,J)A(I+1,J)=TEMP23 CONTINUEENDIFI=I+1ENDIFI=I+1END DOELSE** Revert A (A is lower)*** Revert PERMUTATIONS*I=NDO WHILE ( I .GE. 1 )IF( IPIV(I) .GT. 0 ) THENIP=IPIV(I)IF (I .GT. 1) THENDO J= 1,I-1TEMP=A(I,J)A(I,J)=A(IP,J)A(IP,J)=TEMPEND DOENDIFELSEIP=-IPIV(I)I=I-1IF (I .GT. 1) THENDO J= 1,I-1TEMP=A(I+1,J)A(I+1,J)=A(IP,J)A(IP,J)=TEMPEND DOENDIFENDIFI=I-1END DO** Revert VALUE*I=1DO WHILE ( I .LE. N-1 )IF( IPIV(I) .LT. 0 ) THENA(I+1,I)=E(I)I=I+1ENDIFI=I+1END DOEND IFEND IFRETURN** End of DSYCONV*END*> \brief \b DSYEQUB** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYEQUB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyequb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyequb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyequb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, N* DOUBLE PRECISION AMAX, SCOND* CHARACTER UPLO* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), S( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYEQUB computes row and column scalings intended to equilibrate a*> symmetric matrix A (with respect to the Euclidean norm) and reduce*> its condition number. The scale factors S are computed by the BIN*> algorithm (see references) so that the scaled matrix B with elements*> B(i,j) = S(i)*A(i,j)*S(j) has a condition number within a factor N of*> the smallest possible condition number over all possible diagonal*> scalings.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The N-by-N symmetric matrix whose scaling factors are to be*> computed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, S contains the scale factors for A.*> \endverbatim*>*> \param[out] SCOND*> \verbatim*> SCOND is DOUBLE PRECISION*> If INFO = 0, S contains the ratio of the smallest S(i) to*> the largest S(i). If SCOND >= 0.1 and AMAX is neither too*> large nor too small, it is not worth scaling by S.*> \endverbatim*>*> \param[out] AMAX*> \verbatim*> AMAX is DOUBLE PRECISION*> Largest absolute value of any matrix element. If AMAX is*> very close to overflow or very close to underflow, the*> matrix should be scaled.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element is nonpositive.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleSYcomputational**> \par References:* ================*>*> Livne, O.E. and Golub, G.H., "Scaling by Binormalization", \n*> Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004. \n*> DOI 10.1023/B:NUMA.0000016606.32820.69 \n*> Tech report version: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.3.1679*>* =====================================================================SUBROUTINE DSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..INTEGER INFO, LDA, NDOUBLE PRECISION AMAX, SCONDCHARACTER UPLO* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), S( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )INTEGER MAX_ITERPARAMETER ( MAX_ITER = 100 )* ..* .. Local Scalars ..INTEGER I, J, ITERDOUBLE PRECISION AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,$ SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQLOGICAL UP* ..* .. External Functions ..DOUBLE PRECISION DLAMCHLOGICAL LSAMEEXTERNAL DLAMCH, LSAME* ..* .. External Subroutines ..EXTERNAL DLASSQ, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF ( .NOT. ( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -1ELSE IF ( N .LT. 0 ) THENINFO = -2ELSE IF ( LDA .LT. MAX( 1, N ) ) THENINFO = -4END IFIF ( INFO .NE. 0 ) THENCALL XERBLA( 'DSYEQUB', -INFO )RETURNEND IFUP = LSAME( UPLO, 'U' )AMAX = ZERO** Quick return if possible.*IF ( N .EQ. 0 ) THENSCOND = ONERETURNEND IFDO I = 1, NS( I ) = ZEROEND DOAMAX = ZEROIF ( UP ) THENDO J = 1, NDO I = 1, J-1S( I ) = MAX( S( I ), ABS( A( I, J ) ) )S( J ) = MAX( S( J ), ABS( A( I, J ) ) )AMAX = MAX( AMAX, ABS( A( I, J ) ) )END DOS( J ) = MAX( S( J ), ABS( A( J, J ) ) )AMAX = MAX( AMAX, ABS( A( J, J ) ) )END DOELSEDO J = 1, NS( J ) = MAX( S( J ), ABS( A( J, J ) ) )AMAX = MAX( AMAX, ABS( A( J, J ) ) )DO I = J+1, NS( I ) = MAX( S( I ), ABS( A( I, J ) ) )S( J ) = MAX( S( J ), ABS( A( I, J ) ) )AMAX = MAX( AMAX, ABS( A( I, J ) ) )END DOEND DOEND IFDO J = 1, NS( J ) = 1.0D0 / S( J )END DOTOL = ONE / SQRT( 2.0D0 * N )DO ITER = 1, MAX_ITERSCALE = 0.0D0SUMSQ = 0.0D0* beta = |A|sDO I = 1, NWORK( I ) = ZEROEND DOIF ( UP ) THENDO J = 1, NDO I = 1, J-1WORK( I ) = WORK( I ) + ABS( A( I, J ) ) * S( J )WORK( J ) = WORK( J ) + ABS( A( I, J ) ) * S( I )END DOWORK( J ) = WORK( J ) + ABS( A( J, J ) ) * S( J )END DOELSEDO J = 1, NWORK( J ) = WORK( J ) + ABS( A( J, J ) ) * S( J )DO I = J+1, NWORK( I ) = WORK( I ) + ABS( A( I, J ) ) * S( J )WORK( J ) = WORK( J ) + ABS( A( I, J ) ) * S( I )END DOEND DOEND IF* avg = s^T beta / nAVG = 0.0D0DO I = 1, NAVG = AVG + S( I )*WORK( I )END DOAVG = AVG / NSTD = 0.0D0DO I = N+1, 2*NWORK( I ) = S( I-N ) * WORK( I-N ) - AVGEND DOCALL DLASSQ( N, WORK( N+1 ), 1, SCALE, SUMSQ )STD = SCALE * SQRT( SUMSQ / N )IF ( STD .LT. TOL * AVG ) GOTO 999DO I = 1, NT = ABS( A( I, I ) )SI = S( I )C2 = ( N-1 ) * TC1 = ( N-2 ) * ( WORK( I ) - T*SI )C0 = -(T*SI)*SI + 2*WORK( I )*SI - N*AVGD = C1*C1 - 4*C0*C2IF ( D .LE. 0 ) THENINFO = -1RETURNEND IFSI = -2*C0 / ( C1 + SQRT( D ) )D = SI - S( I )U = ZEROIF ( UP ) THENDO J = 1, IT = ABS( A( J, I ) )U = U + S( J )*TWORK( J ) = WORK( J ) + D*TEND DODO J = I+1,NT = ABS( A( I, J ) )U = U + S( J )*TWORK( J ) = WORK( J ) + D*TEND DOELSEDO J = 1, IT = ABS( A( I, J ) )U = U + S( J )*TWORK( J ) = WORK( J ) + D*TEND DODO J = I+1,NT = ABS( A( J, I ) )U = U + S( J )*TWORK( J ) = WORK( J ) + D*TEND DOEND IFAVG = AVG + ( U + WORK( I ) ) * D / NS( I ) = SIEND DOEND DO999 CONTINUESMLNUM = DLAMCH( 'SAFEMIN' )BIGNUM = ONE / SMLNUMSMIN = BIGNUMSMAX = ZEROT = ONE / SQRT( AVG )BASE = DLAMCH( 'B' )U = ONE / LOG( BASE )DO I = 1, NS( I ) = BASE ** INT( U * LOG( S( I ) * T ) )SMIN = MIN( SMIN, S( I ) )SMAX = MAX( SMAX, S( I ) )END DOSCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )*END*> \brief <b> DSYEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYEV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyev.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyev.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyev.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYEV computes all eigenvalues and, optionally, eigenvectors of a*> real symmetric matrix A.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*> On exit, if JOBZ = 'V', then if INFO = 0, A contains the*> orthonormal eigenvectors of the matrix A.*> If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')*> or the upper triangle (if UPLO='U') of A, including the*> diagonal, is destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of the array WORK. LWORK >= max(1,3*N-1).*> For optimal efficiency, LWORK >= (NB+2)*N,*> where NB is the blocksize for DSYTRD returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the algorithm failed to converge; i*> off-diagonal elements of an intermediate tridiagonal*> form did not converge to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYeigen** =====================================================================SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )* ..* .. Local Scalars ..LOGICAL LOWER, LQUERY, WANTZINTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,$ LLWORK, LWKOPT, NBDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, ILAENV, DLAMCH, DLANSY* ..* .. External Subroutines ..EXTERNAL DLASCL, DORGTR, DSCAL, DSTEQR, DSTERF, DSYTRD,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LOWER = LSAME( UPLO, 'L' )LQUERY = ( LWORK.EQ.-1 )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IF*IF( INFO.EQ.0 ) THENNB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )LWKOPT = MAX( 1, ( NB+2 )*N )WORK( 1 ) = LWKOPT*IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )$ INFO = -8END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYEV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENRETURNEND IF*IF( N.EQ.1 ) THENW( 1 ) = A( 1, 1 )WORK( 1 ) = 2IF( WANTZ )$ A( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 )$ CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )** Call DSYTRD to reduce symmetric matrix to tridiagonal form.*INDE = 1INDTAU = INDE + NINDWRK = INDTAU + NLLWORK = LWORK - INDWRK + 1CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),$ WORK( INDWRK ), LLWORK, IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, first call* DORGTR to generate the orthogonal matrix, then call DSTEQR.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),$ LLWORK, IINFO )CALL DSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),$ INFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = NELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** Set WORK(1) to optimal workspace size.*WORK( 1 ) = LWKOPT*RETURN** End of DSYEV*END*> \brief <b> DSYEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYEVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyevd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyevd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyevd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK,* LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, LDA, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYEVD computes all eigenvalues and, optionally, eigenvectors of a*> real symmetric matrix A. If eigenvectors are desired, it uses a*> divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*>*> Because of large use of BLAS of level 3, DSYEVD needs N**2 more*> workspace than DSYEVX.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*> On exit, if JOBZ = 'V', then if INFO = 0, A contains the*> orthonormal eigenvectors of the matrix A.*> If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')*> or the upper triangle (if UPLO='U') of A, including the*> diagonal, is destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array,*> dimension (LWORK)*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N <= 1, LWORK must be at least 1.*> If JOBZ = 'N' and N > 1, LWORK must be at least 2*N+1.*> If JOBZ = 'V' and N > 1, LWORK must be at least*> 1 + 6*N + 2*N**2.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If N <= 1, LIWORK must be at least 1.*> If JOBZ = 'N' and N > 1, LIWORK must be at least 1.*> If JOBZ = 'V' and N > 1, LIWORK must be at least 3 + 5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i and JOBZ = 'N', then the algorithm failed*> to converge; i off-diagonal elements of an intermediate*> tridiagonal form did not converge to zero;*> if INFO = i and JOBZ = 'V', then the algorithm failed*> to compute an eigenvalue while working on the submatrix*> lying in rows and columns INFO/(N+1) through*> mod(INFO,N+1).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYeigen**> \par Contributors:* ==================*>*> Jeff Rutter, Computer Science Division, University of California*> at Berkeley, USA \n*> Modified by Francoise Tisseur, University of Tennessee \n*> Modified description of INFO. Sven, 16 Feb 05. \n*>* =====================================================================SUBROUTINE DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK,$ LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, LDA, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..*LOGICAL LOWER, LQUERY, WANTZINTEGER IINFO, INDE, INDTAU, INDWK2, INDWRK, ISCALE,$ LIOPT, LIWMIN, LLWORK, LLWRK2, LOPT, LWMINDOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,$ SMLNUM* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, DLAMCH, DLANSY, ILAENV* ..* .. External Subroutines ..EXTERNAL DLACPY, DLASCL, DORMTR, DSCAL, DSTEDC, DSTERF,$ DSYTRD, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )LOWER = LSAME( UPLO, 'L' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IF*IF( INFO.EQ.0 ) THENIF( N.LE.1 ) THENLIWMIN = 1LWMIN = 1LOPT = LWMINLIOPT = LIWMINELSEIF( WANTZ ) THENLIWMIN = 3 + 5*NLWMIN = 1 + 6*N + 2*N**2ELSELIWMIN = 1LWMIN = 2*N + 1END IFLOPT = MAX( LWMIN, 2*N +$ ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) )LIOPT = LIWMINEND IFWORK( 1 ) = LOPTIWORK( 1 ) = LIOPT*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -8ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -10END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYEVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENW( 1 ) = A( 1, 1 )IF( WANTZ )$ A( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = SQRT( BIGNUM )** Scale matrix to allowable range, if necessary.*ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )ISCALE = 0IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 )$ CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )** Call DSYTRD to reduce symmetric matrix to tridiagonal form.*INDE = 1INDTAU = INDE + NINDWRK = INDTAU + NLLWORK = LWORK - INDWRK + 1INDWK2 = INDWRK + N*NLLWRK2 = LWORK - INDWK2 + 1*CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),$ WORK( INDWRK ), LLWORK, IINFO )** For eigenvalues only, call DSTERF. For eigenvectors, first call* DSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the* tridiagonal matrix, then call DORMTR to multiply it by the* Householder transformations stored in A.*IF( .NOT.WANTZ ) THENCALL DSTERF( N, W, WORK( INDE ), INFO )ELSECALL DSTEDC( 'I', N, W, WORK( INDE ), WORK( INDWRK ), N,$ WORK( INDWK2 ), LLWRK2, IWORK, LIWORK, INFO )CALL DORMTR( 'L', UPLO, 'N', N, N, A, LDA, WORK( INDTAU ),$ WORK( INDWRK ), N, WORK( INDWK2 ), LLWRK2, IINFO )CALL DLACPY( 'A', N, N, WORK( INDWRK ), N, A, LDA )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*IF( ISCALE.EQ.1 )$ CALL DSCAL( N, ONE / SIGMA, W, 1 )*WORK( 1 ) = LOPTIWORK( 1 ) = LIOPT*RETURN** End of DSYEVD*END*> \brief <b> DSYEVR computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYEVR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyevr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyevr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyevr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,* ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,* IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LWORK, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER ISUPPZ( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYEVR computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric matrix A. Eigenvalues and eigenvectors can be*> selected by specifying either a range of values or a range of*> indices for the desired eigenvalues.*>*> DSYEVR first reduces the matrix A to tridiagonal form T with a call*> to DSYTRD. Then, whenever possible, DSYEVR calls DSTEMR to compute*> the eigenspectrum using Relatively Robust Representations. DSTEMR*> computes eigenvalues by the dqds algorithm, while orthogonal*> eigenvectors are computed from various "good" L D L^T representations*> (also known as Relatively Robust Representations). Gram-Schmidt*> orthogonalization is avoided as far as possible. More specifically,*> the various steps of the algorithm are as follows.*>*> For each unreduced block (submatrix) of T,*> (a) Compute T - sigma I = L D L^T, so that L and D*> define all the wanted eigenvalues to high relative accuracy.*> This means that small relative changes in the entries of D and L*> cause only small relative changes in the eigenvalues and*> eigenvectors. The standard (unfactored) representation of the*> tridiagonal matrix T does not have this property in general.*> (b) Compute the eigenvalues to suitable accuracy.*> If the eigenvectors are desired, the algorithm attains full*> accuracy of the computed eigenvalues only right before*> the corresponding vectors have to be computed, see steps c) and d).*> (c) For each cluster of close eigenvalues, select a new*> shift close to the cluster, find a new factorization, and refine*> the shifted eigenvalues to suitable accuracy.*> (d) For each eigenvalue with a large enough relative separation compute*> the corresponding eigenvector by forming a rank revealing twisted*> factorization. Go back to (c) for any clusters that remain.*>*> The desired accuracy of the output can be specified by the input*> parameter ABSTOL.*>*> For more details, see DSTEMR's documentation and:*> - Inderjit S. Dhillon and Beresford N. Parlett: "Multiple representations*> to compute orthogonal eigenvectors of symmetric tridiagonal matrices,"*> Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.*> - Inderjit Dhillon and Beresford Parlett: "Orthogonal Eigenvectors and*> Relative Gaps," SIAM Journal on Matrix Analysis and Applications, Vol. 25,*> 2004. Also LAPACK Working Note 154.*> - Inderjit Dhillon: "A new O(n^2) algorithm for the symmetric*> tridiagonal eigenvalue/eigenvector problem",*> Computer Science Division Technical Report No. UCB/CSD-97-971,*> UC Berkeley, May 1997.*>*>*> Note 1 : DSYEVR calls DSTEMR when the full spectrum is requested*> on machines which conform to the ieee-754 floating point standard.*> DSYEVR calls DSTEBZ and DSTEIN on non-ieee machines and*> when partial spectrum requests are made.*>*> Normal execution of DSTEMR may create NaNs and infinities and*> hence may abort due to a floating point exception in environments*> which do not handle NaNs and infinities in the ieee standard default*> manner.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and*> DSTEIN are called*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*> On exit, the lower triangle (if UPLO='L') or the upper*> triangle (if UPLO='U') of A, including the diagonal, is*> destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing A to tridiagonal form.*>*> See "Computing Small Singular Values of Bidiagonal Matrices*> with Guaranteed High Relative Accuracy," by Demmel and*> Kahan, LAPACK Working Note #3.*>*> If high relative accuracy is important, set ABSTOL to*> DLAMCH( 'Safe minimum' ). Doing so will guarantee that*> eigenvalues are computed to high relative accuracy when*> possible in future releases. The current code does not*> make any guarantees about high relative accuracy, but*> future releases will. See J. Barlow and J. Demmel,*> "Computing Accurate Eigensystems of Scaled Diagonally*> Dominant Matrices", LAPACK Working Note #7, for a discussion*> of which matrices define their eigenvalues to high relative*> accuracy.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> The first M elements contain the selected eigenvalues in*> ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> Supplying N columns is always safe.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] ISUPPZ*> \verbatim*> ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )*> The support of the eigenvectors in Z, i.e., the indices*> indicating the nonzero elements in Z. The i-th eigenvector*> is nonzero only in elements ISUPPZ( 2*i-1 ) through*> ISUPPZ( 2*i ). This is an output of DSTEMR (tridiagonal*> matrix). The support of the eigenvectors of A is typically*> 1:N because of the orthogonal transformations applied by DORMTR.*> Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,26*N).*> For optimal efficiency, LWORK >= (NB+6)*N,*> where NB is the max of the blocksize for DSYTRD and DORMTR*> returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK. LIWORK >= max(1,10*N).*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the IWORK array,*> returns this value as the first entry of the IWORK array, and*> no error message related to LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: Internal error*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleSYeigen**> \par Contributors:* ==================*>*> Inderjit Dhillon, IBM Almaden, USA \n*> Osni Marques, LBNL/NERSC, USA \n*> Ken Stanley, Computer Science Division, University of*> California at Berkeley, USA \n*> Jason Riedy, Computer Science Division, University of*> California at Berkeley, USA \n*>* =====================================================================SUBROUTINE DSYEVR( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,$ ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK,$ IWORK, LIWORK, INFO )** -- LAPACK driver routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LWORK, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER ISUPPZ( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, VALEIG, WANTZ,$ TRYRACCHARACTER ORDERINTEGER I, IEEEOK, IINFO, IMAX, INDD, INDDD, INDE,$ INDEE, INDIBL, INDIFL, INDISP, INDIWO, INDTAU,$ INDWK, INDWKN, ISCALE, J, JJ, LIWMIN,$ LLWORK, LLWRKN, LWKOPT, LWMIN, NB, NSPLITDOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,$ SIGMA, SMLNUM, TMP1, VLL, VUU* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, ILAENV, DLAMCH, DLANSY* ..* .. External Subroutines ..EXTERNAL DCOPY, DORMTR, DSCAL, DSTEBZ, DSTEMR, DSTEIN,$ DSTERF, DSWAP, DSYTRD, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*IEEEOK = ILAENV( 10, 'DSYEVR', 'N', 1, 2, 3, 4 )*LOWER = LSAME( UPLO, 'L' )WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )*LQUERY = ( ( LWORK.EQ.-1 ) .OR. ( LIWORK.EQ.-1 ) )*LWMIN = MAX( 1, 26*N )LIWMIN = MAX( 1, 10*N )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -8ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -9ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -10END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -15ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -18ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -20END IFEND IF*IF( INFO.EQ.0 ) THENNB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )NB = MAX( NB, ILAENV( 1, 'DORMTR', UPLO, N, -1, -1, -1 ) )LWKOPT = MAX( ( NB+1 )*N, LWMIN )WORK( 1 ) = LWKOPTIWORK( 1 ) = LIWMINEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYEVR', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*IF( N.EQ.1 ) THENWORK( 1 ) = 7IF( ALLEIG .OR. INDEIG ) THENM = 1W( 1 ) = A( 1, 1 )ELSEIF( VL.LT.A( 1, 1 ) .AND. VU.GE.A( 1, 1 ) ) THENM = 1W( 1 ) = A( 1, 1 )END IFEND IFIF( WANTZ ) THENZ( 1, 1 ) = ONEISUPPZ( 1 ) = 1ISUPPZ( 2 ) = 1END IFRETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )** Scale matrix to allowable range, if necessary.*ISCALE = 0ABSTLL = ABSTOLIF (VALEIG) THENVLL = VLVUU = VUEND IFANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENIF( LOWER ) THENDO 10 J = 1, NCALL DSCAL( N-J+1, SIGMA, A( J, J ), 1 )10 CONTINUEELSEDO 20 J = 1, NCALL DSCAL( J, SIGMA, A( 1, J ), 1 )20 CONTINUEEND IFIF( ABSTOL.GT.0 )$ ABSTLL = ABSTOL*SIGMAIF( VALEIG ) THENVLL = VL*SIGMAVUU = VU*SIGMAEND IFEND IF* Initialize indices into workspaces. Note: The IWORK indices are* used only if DSTERF or DSTEMR fail.* WORK(INDTAU:INDTAU+N-1) stores the scalar factors of the* elementary reflectors used in DSYTRD.INDTAU = 1* WORK(INDD:INDD+N-1) stores the tridiagonal's diagonal entries.INDD = INDTAU + N* WORK(INDE:INDE+N-1) stores the off-diagonal entries of the* tridiagonal matrix from DSYTRD.INDE = INDD + N* WORK(INDDD:INDDD+N-1) is a copy of the diagonal entries over* -written by DSTEMR (the DSTERF path copies the diagonal to W).INDDD = INDE + N* WORK(INDEE:INDEE+N-1) is a copy of the off-diagonal entries over* -written while computing the eigenvalues in DSTERF and DSTEMR.INDEE = INDDD + N* INDWK is the starting offset of the left-over workspace, and* LLWORK is the remaining workspace size.INDWK = INDEE + NLLWORK = LWORK - INDWK + 1* IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and* stores the block indices of each of the M<=N eigenvalues.INDIBL = 1* IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and* stores the starting and finishing indices of each block.INDISP = INDIBL + N* IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors* that corresponding to eigenvectors that fail to converge in* DSTEIN. This information is discarded; if any fail, the driver* returns INFO > 0.INDIFL = INDISP + N* INDIWO is the offset of the remaining integer workspace.INDIWO = INDIFL + N** Call DSYTRD to reduce symmetric matrix to tridiagonal form.*CALL DSYTRD( UPLO, N, A, LDA, WORK( INDD ), WORK( INDE ),$ WORK( INDTAU ), WORK( INDWK ), LLWORK, IINFO )** If all eigenvalues are desired* then call DSTERF or DSTEMR and DORMTR.*IF( ( ALLEIG .OR. ( INDEIG .AND. IL.EQ.1 .AND. IU.EQ.N ) ) .AND.$ IEEEOK.EQ.1 ) THENIF( .NOT.WANTZ ) THENCALL DCOPY( N, WORK( INDD ), 1, W, 1 )CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTERF( N, W, WORK( INDEE ), INFO )ELSECALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DCOPY( N, WORK( INDD ), 1, WORK( INDDD ), 1 )*IF (ABSTOL .LE. TWO*N*EPS) THENTRYRAC = .TRUE.ELSETRYRAC = .FALSE.END IFCALL DSTEMR( JOBZ, 'A', N, WORK( INDDD ), WORK( INDEE ),$ VL, VU, IL, IU, M, W, Z, LDZ, N, ISUPPZ,$ TRYRAC, WORK( INDWK ), LWORK, IWORK, LIWORK,$ INFO )**** Apply orthogonal matrix used in reduction to tridiagonal* form to eigenvectors returned by DSTEMR.*IF( WANTZ .AND. INFO.EQ.0 ) THENINDWKN = INDELLWRKN = LWORK - INDWKN + 1CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA,$ WORK( INDTAU ), Z, LDZ, WORK( INDWKN ),$ LLWRKN, IINFO )END IFEND IF**IF( INFO.EQ.0 ) THEN* Everything worked. Skip DSTEBZ/DSTEIN. IWORK(:) are* undefined.M = NGO TO 30END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired, DSTEIN.* Also call DSTEBZ and DSTEIN if DSTEMR fails.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFCALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,$ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,$ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWK ),$ IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,$ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,$ WORK( INDWK ), IWORK( INDIWO ), IWORK( INDIFL ),$ INFO )** Apply orthogonal matrix used in reduction to tridiagonal* form to eigenvectors returned by DSTEIN.*INDWKN = INDELLWRKN = LWORK - INDWKN + 1CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA, WORK( INDTAU ), Z,$ LDZ, WORK( INDWKN ), LLWRKN, IINFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.** Jump here if DSTEMR/DSTEIN succeeded.30 CONTINUEIF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = MELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** If eigenvalues are not in order, then sort them, along with* eigenvectors. Note: We do not sort the IFAIL portion of IWORK.* It may not be initialized (if DSTEMR/DSTEIN succeeded), and we do* not return this detailed information to the user.*IF( WANTZ ) THENDO 50 J = 1, M - 1I = 0TMP1 = W( J )DO 40 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF40 CONTINUE*IF( I.NE.0 ) THENW( I ) = W( J )W( J ) = TMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )END IF50 CONTINUEEND IF** Set WORK(1) to optimal workspace size.*WORK( 1 ) = LWKOPTIWORK( 1 ) = LIWMIN*RETURN** End of DSYEVR*END*> \brief <b> DSYEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYEVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyevx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyevx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyevx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,* ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,* IFAIL, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYEVX computes selected eigenvalues and, optionally, eigenvectors*> of a real symmetric matrix A. Eigenvalues and eigenvectors can be*> selected by specifying either a range of values or a range of indices*> for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*> On exit, the lower triangle (if UPLO='L') or the upper*> triangle (if UPLO='U') of A, including the diagonal, is*> destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing A to tridiagonal form.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*>*> See "Computing Small Singular Values of Bidiagonal Matrices*> with Guaranteed High Relative Accuracy," by Demmel and*> Kahan, LAPACK Working Note #3.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On normal exit, the first M elements contain the selected*> eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> If an eigenvector fails to converge, then that column of Z*> contains the latest approximation to the eigenvector, and the*> index of the eigenvector is returned in IFAIL.*> If JOBZ = 'N', then Z is not referenced.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of the array WORK. LWORK >= 1, when N <= 1;*> otherwise 8*N.*> For optimal efficiency, LWORK >= (NB+3)*N,*> where NB is the max of the blocksize for DSYTRD and DORMTR*> returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (N)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvectors that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, then i eigenvectors failed to converge.*> Their indices are stored in array IFAIL.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleSYeigen** =====================================================================SUBROUTINE DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU,$ ABSTOL, M, W, Z, LDZ, WORK, LWORK, IWORK,$ IFAIL, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,$ WANTZCHARACTER ORDERINTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,$ INDISP, INDIWO, INDTAU, INDWKN, INDWRK, ISCALE,$ ITMP1, J, JJ, LLWORK, LLWRKN, LWKMIN,$ LWKOPT, NB, NSPLITDOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,$ SIGMA, SMLNUM, TMP1, VLL, VUU* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, ILAENV, DLAMCH, DLANSY* ..* .. External Subroutines ..EXTERNAL DCOPY, DLACPY, DORGTR, DORMTR, DSCAL, DSTEBZ,$ DSTEIN, DSTEQR, DSTERF, DSWAP, DSYTRD, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Test the input parameters.*LOWER = LSAME( UPLO, 'L' )WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )LQUERY = ( LWORK.EQ.-1 )*INFO = 0IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -2ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -8ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -9ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -10END IFEND IFEND IFIF( INFO.EQ.0 ) THENIF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -15END IFEND IF*IF( INFO.EQ.0 ) THENIF( N.LE.1 ) THENLWKMIN = 1WORK( 1 ) = LWKMINELSELWKMIN = 8*NNB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )NB = MAX( NB, ILAENV( 1, 'DORMTR', UPLO, N, -1, -1, -1 ) )LWKOPT = MAX( LWKMIN, ( NB + 3 )*N )WORK( 1 ) = LWKOPTEND IF*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY )$ INFO = -17END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYEVX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 ) THENRETURNEND IF*IF( N.EQ.1 ) THENIF( ALLEIG .OR. INDEIG ) THENM = 1W( 1 ) = A( 1, 1 )ELSEIF( VL.LT.A( 1, 1 ) .AND. VU.GE.A( 1, 1 ) ) THENM = 1W( 1 ) = A( 1, 1 )END IFEND IFIF( WANTZ )$ Z( 1, 1 ) = ONERETURNEND IF** Get machine constants.*SAFMIN = DLAMCH( 'Safe minimum' )EPS = DLAMCH( 'Precision' )SMLNUM = SAFMIN / EPSBIGNUM = ONE / SMLNUMRMIN = SQRT( SMLNUM )RMAX = MIN( SQRT( BIGNUM ), ONE / SQRT( SQRT( SAFMIN ) ) )** Scale matrix to allowable range, if necessary.*ISCALE = 0ABSTLL = ABSTOLIF( VALEIG ) THENVLL = VLVUU = VUEND IFANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THENISCALE = 1SIGMA = RMIN / ANRMELSE IF( ANRM.GT.RMAX ) THENISCALE = 1SIGMA = RMAX / ANRMEND IFIF( ISCALE.EQ.1 ) THENIF( LOWER ) THENDO 10 J = 1, NCALL DSCAL( N-J+1, SIGMA, A( J, J ), 1 )10 CONTINUEELSEDO 20 J = 1, NCALL DSCAL( J, SIGMA, A( 1, J ), 1 )20 CONTINUEEND IFIF( ABSTOL.GT.0 )$ ABSTLL = ABSTOL*SIGMAIF( VALEIG ) THENVLL = VL*SIGMAVUU = VU*SIGMAEND IFEND IF** Call DSYTRD to reduce symmetric matrix to tridiagonal form.*INDTAU = 1INDE = INDTAU + NINDD = INDE + NINDWRK = INDD + NLLWORK = LWORK - INDWRK + 1CALL DSYTRD( UPLO, N, A, LDA, WORK( INDD ), WORK( INDE ),$ WORK( INDTAU ), WORK( INDWRK ), LLWORK, IINFO )** If all eigenvalues are desired and ABSTOL is less than or equal to* zero, then call DSTERF or DORGTR and SSTEQR. If this fails for* some eigenvalue, then try DSTEBZ.*TEST = .FALSE.IF( INDEIG ) THENIF( IL.EQ.1 .AND. IU.EQ.N ) THENTEST = .TRUE.END IFEND IFIF( ( ALLEIG .OR. TEST ) .AND. ( ABSTOL.LE.ZERO ) ) THENCALL DCOPY( N, WORK( INDD ), 1, W, 1 )INDEE = INDWRK + 2*NIF( .NOT.WANTZ ) THENCALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTERF( N, W, WORK( INDEE ), INFO )ELSECALL DLACPY( 'A', N, N, A, LDA, Z, LDZ )CALL DORGTR( UPLO, N, Z, LDZ, WORK( INDTAU ),$ WORK( INDWRK ), LLWORK, IINFO )CALL DCOPY( N-1, WORK( INDE ), 1, WORK( INDEE ), 1 )CALL DSTEQR( JOBZ, N, W, WORK( INDEE ), Z, LDZ,$ WORK( INDWRK ), INFO )IF( INFO.EQ.0 ) THENDO 30 I = 1, NIFAIL( I ) = 030 CONTINUEEND IFEND IFIF( INFO.EQ.0 ) THENM = NGO TO 40END IFINFO = 0END IF** Otherwise, call DSTEBZ and, if eigenvectors are desired, SSTEIN.*IF( WANTZ ) THENORDER = 'B'ELSEORDER = 'E'END IFINDIBL = 1INDISP = INDIBL + NINDIWO = INDISP + NCALL DSTEBZ( RANGE, ORDER, N, VLL, VUU, IL, IU, ABSTLL,$ WORK( INDD ), WORK( INDE ), M, NSPLIT, W,$ IWORK( INDIBL ), IWORK( INDISP ), WORK( INDWRK ),$ IWORK( INDIWO ), INFO )*IF( WANTZ ) THENCALL DSTEIN( N, WORK( INDD ), WORK( INDE ), M, W,$ IWORK( INDIBL ), IWORK( INDISP ), Z, LDZ,$ WORK( INDWRK ), IWORK( INDIWO ), IFAIL, INFO )** Apply orthogonal matrix used in reduction to tridiagonal* form to eigenvectors returned by DSTEIN.*INDWKN = INDELLWRKN = LWORK - INDWKN + 1CALL DORMTR( 'L', UPLO, 'N', N, M, A, LDA, WORK( INDTAU ), Z,$ LDZ, WORK( INDWKN ), LLWRKN, IINFO )END IF** If matrix was scaled, then rescale eigenvalues appropriately.*40 CONTINUEIF( ISCALE.EQ.1 ) THENIF( INFO.EQ.0 ) THENIMAX = MELSEIMAX = INFO - 1END IFCALL DSCAL( IMAX, ONE / SIGMA, W, 1 )END IF** If eigenvalues are not in order, then sort them, along with* eigenvectors.*IF( WANTZ ) THENDO 60 J = 1, M - 1I = 0TMP1 = W( J )DO 50 JJ = J + 1, MIF( W( JJ ).LT.TMP1 ) THENI = JJTMP1 = W( JJ )END IF50 CONTINUE*IF( I.NE.0 ) THENITMP1 = IWORK( INDIBL+I-1 )W( I ) = W( J )IWORK( INDIBL+I-1 ) = IWORK( INDIBL+J-1 )W( J ) = TMP1IWORK( INDIBL+J-1 ) = ITMP1CALL DSWAP( N, Z( 1, I ), 1, Z( 1, J ), 1 )IF( INFO.NE.0 ) THENITMP1 = IFAIL( I )IFAIL( I ) = IFAIL( J )IFAIL( J ) = ITMP1END IFEND IF60 CONTINUEEND IF** Set WORK(1) to optimal workspace size.*WORK( 1 ) = LWKOPT*RETURN** End of DSYEVX*END*> \brief \b DSYGS2 reduces a symmetric definite generalized eigenproblem to standard form, using the factorization results obtained from spotrf (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYGS2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsygs2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsygs2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsygs2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, ITYPE, LDA, LDB, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYGS2 reduces a real symmetric-definite generalized eigenproblem*> to standard form.*>*> If ITYPE = 1, the problem is A*x = lambda*B*x,*> and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)*>*> If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or*> B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T *A*L.*>*> B must have been previously factorized as U**T *U or L*L**T by DPOTRF.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);*> = 2 or 3: compute U*A*U**T or L**T *A*L.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored, and how B has been factorized.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n by n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n by n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the transformed matrix, stored in the*> same format as A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> The triangular factor from the Cholesky factorization of B,*> as returned by DPOTRF.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, ITYPE, LDA, LDB, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, HALFPARAMETER ( ONE = 1.0D0, HALF = 0.5D0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER KDOUBLE PRECISION AKK, BKK, CT* ..* .. External Subroutines ..EXTERNAL DAXPY, DSCAL, DSYR2, DTRMV, DTRSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYGS2', -INFO )RETURNEND IF*IF( ITYPE.EQ.1 ) THENIF( UPPER ) THEN** Compute inv(U**T)*A*inv(U)*DO 10 K = 1, N** Update the upper triangle of A(k:n,k:n)*AKK = A( K, K )BKK = B( K, K )AKK = AKK / BKK**2A( K, K ) = AKKIF( K.LT.N ) THENCALL DSCAL( N-K, ONE / BKK, A( K, K+1 ), LDA )CT = -HALF*AKKCALL DAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),$ LDA )CALL DSYR2( UPLO, N-K, -ONE, A( K, K+1 ), LDA,$ B( K, K+1 ), LDB, A( K+1, K+1 ), LDA )CALL DAXPY( N-K, CT, B( K, K+1 ), LDB, A( K, K+1 ),$ LDA )CALL DTRSV( UPLO, 'Transpose', 'Non-unit', N-K,$ B( K+1, K+1 ), LDB, A( K, K+1 ), LDA )END IF10 CONTINUEELSE** Compute inv(L)*A*inv(L**T)*DO 20 K = 1, N** Update the lower triangle of A(k:n,k:n)*AKK = A( K, K )BKK = B( K, K )AKK = AKK / BKK**2A( K, K ) = AKKIF( K.LT.N ) THENCALL DSCAL( N-K, ONE / BKK, A( K+1, K ), 1 )CT = -HALF*AKKCALL DAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )CALL DSYR2( UPLO, N-K, -ONE, A( K+1, K ), 1,$ B( K+1, K ), 1, A( K+1, K+1 ), LDA )CALL DAXPY( N-K, CT, B( K+1, K ), 1, A( K+1, K ), 1 )CALL DTRSV( UPLO, 'No transpose', 'Non-unit', N-K,$ B( K+1, K+1 ), LDB, A( K+1, K ), 1 )END IF20 CONTINUEEND IFELSEIF( UPPER ) THEN** Compute U*A*U**T*DO 30 K = 1, N** Update the upper triangle of A(1:k,1:k)*AKK = A( K, K )BKK = B( K, K )CALL DTRMV( UPLO, 'No transpose', 'Non-unit', K-1, B,$ LDB, A( 1, K ), 1 )CT = HALF*AKKCALL DAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )CALL DSYR2( UPLO, K-1, ONE, A( 1, K ), 1, B( 1, K ), 1,$ A, LDA )CALL DAXPY( K-1, CT, B( 1, K ), 1, A( 1, K ), 1 )CALL DSCAL( K-1, BKK, A( 1, K ), 1 )A( K, K ) = AKK*BKK**230 CONTINUEELSE** Compute L**T *A*L*DO 40 K = 1, N** Update the lower triangle of A(1:k,1:k)*AKK = A( K, K )BKK = B( K, K )CALL DTRMV( UPLO, 'Transpose', 'Non-unit', K-1, B, LDB,$ A( K, 1 ), LDA )CT = HALF*AKKCALL DAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )CALL DSYR2( UPLO, K-1, ONE, A( K, 1 ), LDA, B( K, 1 ),$ LDB, A, LDA )CALL DAXPY( K-1, CT, B( K, 1 ), LDB, A( K, 1 ), LDA )CALL DSCAL( K-1, BKK, A( K, 1 ), LDA )A( K, K ) = AKK*BKK**240 CONTINUEEND IFEND IFRETURN** End of DSYGS2*END*> \brief \b DSYGST** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYGST + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsygst.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsygst.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsygst.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, ITYPE, LDA, LDB, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYGST reduces a real symmetric-definite generalized eigenproblem*> to standard form.*>*> If ITYPE = 1, the problem is A*x = lambda*B*x,*> and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T)*>*> If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or*> B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L.*>*> B must have been previously factorized as U**T*U or L*L**T by DPOTRF.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T);*> = 2 or 3: compute U*A*U**T or L**T*A*L.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored and B is factored as*> U**T*U;*> = 'L': Lower triangle of A is stored and B is factored as*> L*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the transformed matrix, stored in the*> same format as A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> The triangular factor from the Cholesky factorization of B,*> as returned by DPOTRF.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, ITYPE, LDA, LDB, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, HALFPARAMETER ( ONE = 1.0D0, HALF = 0.5D0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER K, KB, NB* ..* .. External Subroutines ..EXTERNAL DSYGS2, DSYMM, DSYR2K, DTRMM, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYGST', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Determine the block size for this environment.*NB = ILAENV( 1, 'DSYGST', UPLO, N, -1, -1, -1 )*IF( NB.LE.1 .OR. NB.GE.N ) THEN** Use unblocked code*CALL DSYGS2( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )ELSE** Use blocked code*IF( ITYPE.EQ.1 ) THENIF( UPPER ) THEN** Compute inv(U**T)*A*inv(U)*DO 10 K = 1, N, NBKB = MIN( N-K+1, NB )** Update the upper triangle of A(k:n,k:n)*CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,$ B( K, K ), LDB, INFO )IF( K+KB.LE.N ) THENCALL DTRSM( 'Left', UPLO, 'Transpose', 'Non-unit',$ KB, N-K-KB+1, ONE, B( K, K ), LDB,$ A( K, K+KB ), LDA )CALL DSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,$ A( K, K ), LDA, B( K, K+KB ), LDB, ONE,$ A( K, K+KB ), LDA )CALL DSYR2K( UPLO, 'Transpose', N-K-KB+1, KB, -ONE,$ A( K, K+KB ), LDA, B( K, K+KB ), LDB,$ ONE, A( K+KB, K+KB ), LDA )CALL DSYMM( 'Left', UPLO, KB, N-K-KB+1, -HALF,$ A( K, K ), LDA, B( K, K+KB ), LDB, ONE,$ A( K, K+KB ), LDA )CALL DTRSM( 'Right', UPLO, 'No transpose',$ 'Non-unit', KB, N-K-KB+1, ONE,$ B( K+KB, K+KB ), LDB, A( K, K+KB ),$ LDA )END IF10 CONTINUEELSE** Compute inv(L)*A*inv(L**T)*DO 20 K = 1, N, NBKB = MIN( N-K+1, NB )** Update the lower triangle of A(k:n,k:n)*CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,$ B( K, K ), LDB, INFO )IF( K+KB.LE.N ) THENCALL DTRSM( 'Right', UPLO, 'Transpose', 'Non-unit',$ N-K-KB+1, KB, ONE, B( K, K ), LDB,$ A( K+KB, K ), LDA )CALL DSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,$ A( K, K ), LDA, B( K+KB, K ), LDB, ONE,$ A( K+KB, K ), LDA )CALL DSYR2K( UPLO, 'No transpose', N-K-KB+1, KB,$ -ONE, A( K+KB, K ), LDA, B( K+KB, K ),$ LDB, ONE, A( K+KB, K+KB ), LDA )CALL DSYMM( 'Right', UPLO, N-K-KB+1, KB, -HALF,$ A( K, K ), LDA, B( K+KB, K ), LDB, ONE,$ A( K+KB, K ), LDA )CALL DTRSM( 'Left', UPLO, 'No transpose',$ 'Non-unit', N-K-KB+1, KB, ONE,$ B( K+KB, K+KB ), LDB, A( K+KB, K ),$ LDA )END IF20 CONTINUEEND IFELSEIF( UPPER ) THEN** Compute U*A*U**T*DO 30 K = 1, N, NBKB = MIN( N-K+1, NB )** Update the upper triangle of A(1:k+kb-1,1:k+kb-1)*CALL DTRMM( 'Left', UPLO, 'No transpose', 'Non-unit',$ K-1, KB, ONE, B, LDB, A( 1, K ), LDA )CALL DSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),$ LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA )CALL DSYR2K( UPLO, 'No transpose', K-1, KB, ONE,$ A( 1, K ), LDA, B( 1, K ), LDB, ONE, A,$ LDA )CALL DSYMM( 'Right', UPLO, K-1, KB, HALF, A( K, K ),$ LDA, B( 1, K ), LDB, ONE, A( 1, K ), LDA )CALL DTRMM( 'Right', UPLO, 'Transpose', 'Non-unit',$ K-1, KB, ONE, B( K, K ), LDB, A( 1, K ),$ LDA )CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,$ B( K, K ), LDB, INFO )30 CONTINUEELSE** Compute L**T*A*L*DO 40 K = 1, N, NBKB = MIN( N-K+1, NB )** Update the lower triangle of A(1:k+kb-1,1:k+kb-1)*CALL DTRMM( 'Right', UPLO, 'No transpose', 'Non-unit',$ KB, K-1, ONE, B, LDB, A( K, 1 ), LDA )CALL DSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),$ LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA )CALL DSYR2K( UPLO, 'Transpose', K-1, KB, ONE,$ A( K, 1 ), LDA, B( K, 1 ), LDB, ONE, A,$ LDA )CALL DSYMM( 'Left', UPLO, KB, K-1, HALF, A( K, K ),$ LDA, B( K, 1 ), LDB, ONE, A( K, 1 ), LDA )CALL DTRMM( 'Left', UPLO, 'Transpose', 'Non-unit', KB,$ K-1, ONE, B( K, K ), LDB, A( K, 1 ), LDA )CALL DSYGS2( ITYPE, UPLO, KB, A( K, K ), LDA,$ B( K, K ), LDB, INFO )40 CONTINUEEND IFEND IFEND IFRETURN** End of DSYGST*END*> \brief \b DSYGV** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYGV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsygv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsygv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsygv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,* LWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, ITYPE, LDA, LDB, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYGV computes all the eigenvalues, and optionally, the eigenvectors*> of a real generalized symmetric-definite eigenproblem, of the form*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x.*> Here A and B are assumed to be symmetric and B is also*> positive definite.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> Specifies the problem type to be solved:*> = 1: A*x = (lambda)*B*x*> = 2: A*B*x = (lambda)*x*> = 3: B*A*x = (lambda)*x*> \endverbatim*>*> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*>*> On exit, if JOBZ = 'V', then if INFO = 0, A contains the*> matrix Z of eigenvectors. The eigenvectors are normalized*> as follows:*> if ITYPE = 1 or 2, Z**T*B*Z = I;*> if ITYPE = 3, Z**T*inv(B)*Z = I.*> If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')*> or the lower triangle (if UPLO='L') of A, including the*> diagonal, is destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the symmetric positive definite matrix B.*> If UPLO = 'U', the leading N-by-N upper triangular part of B*> contains the upper triangular part of the matrix B.*> If UPLO = 'L', the leading N-by-N lower triangular part of B*> contains the lower triangular part of the matrix B.*>*> On exit, if INFO <= N, the part of B containing the matrix is*> overwritten by the triangular factor U or L from the Cholesky*> factorization B = U**T*U or B = L*L**T.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of the array WORK. LWORK >= max(1,3*N-1).*> For optimal efficiency, LWORK >= (NB+2)*N,*> where NB is the blocksize for DSYTRD returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: DPOTRF or DSYEV returned an error code:*> <= N: if INFO = i, DSYEV failed to converge;*> i off-diagonal elements of an intermediate*> tridiagonal form did not converge to zero;*> > N: if INFO = N + i, for 1 <= i <= N, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYeigen** =====================================================================SUBROUTINE DSYGV( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,$ LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, ITYPE, LDA, LDB, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPER, WANTZCHARACTER TRANSINTEGER LWKMIN, LWKOPT, NB, NEIG* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DPOTRF, DSYEV, DSYGST, DTRMM, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 )*INFO = 0IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IF*IF( INFO.EQ.0 ) THENLWKMIN = MAX( 1, 3*N - 1 )NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )LWKOPT = MAX( LWKMIN, ( NB + 2 )*N )WORK( 1 ) = LWKOPT*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -11END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYGV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form a Cholesky factorization of B.*CALL DPOTRF( UPLO, N, B, LDB, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem and solve.*CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )CALL DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )*IF( WANTZ ) THEN** Backtransform eigenvectors to the original problem.*NEIG = NIF( INFO.GT.0 )$ NEIG = INFO - 1IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN** For A*x=(lambda)*B*x and A*B*x=(lambda)*x;* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y*IF( UPPER ) THENTRANS = 'N'ELSETRANS = 'T'END IF*CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,$ B, LDB, A, LDA )*ELSE IF( ITYPE.EQ.3 ) THEN** For B*A*x=(lambda)*x;* backtransform eigenvectors: x = L*y or U**T*y*IF( UPPER ) THENTRANS = 'T'ELSETRANS = 'N'END IF*CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, NEIG, ONE,$ B, LDB, A, LDA )END IFEND IF*WORK( 1 ) = LWKOPTRETURN** End of DSYGV*END*> \brief \b DSYGVD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYGVD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsygvd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsygvd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsygvd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYGVD( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,* LWORK, IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, UPLO* INTEGER INFO, ITYPE, LDA, LDB, LIWORK, LWORK, N* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYGVD computes all the eigenvalues, and optionally, the eigenvectors*> of a real generalized symmetric-definite eigenproblem, of the form*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and*> B are assumed to be symmetric and B is also positive definite.*> If eigenvectors are desired, it uses a divide and conquer algorithm.*>*> The divide and conquer algorithm makes very mild assumptions about*> floating point arithmetic. It will work on machines with a guard*> digit in add/subtract, or on those binary machines without guard*> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or*> Cray-2. It could conceivably fail on hexadecimal or decimal machines*> without guard digits, but we know of none.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> Specifies the problem type to be solved:*> = 1: A*x = (lambda)*B*x*> = 2: A*B*x = (lambda)*x*> = 3: B*A*x = (lambda)*x*> \endverbatim*>*> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangles of A and B are stored;*> = 'L': Lower triangles of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*>*> On exit, if JOBZ = 'V', then if INFO = 0, A contains the*> matrix Z of eigenvectors. The eigenvectors are normalized*> as follows:*> if ITYPE = 1 or 2, Z**T*B*Z = I;*> if ITYPE = 3, Z**T*inv(B)*Z = I.*> If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')*> or the lower triangle (if UPLO='L') of A, including the*> diagonal, is destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the symmetric matrix B. If UPLO = 'U', the*> leading N-by-N upper triangular part of B contains the*> upper triangular part of the matrix B. If UPLO = 'L',*> the leading N-by-N lower triangular part of B contains*> the lower triangular part of the matrix B.*>*> On exit, if INFO <= N, the part of B containing the matrix is*> overwritten by the triangular factor U or L from the Cholesky*> factorization B = U**T*U or B = L*L**T.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> If INFO = 0, the eigenvalues in ascending order.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If N <= 1, LWORK >= 1.*> If JOBZ = 'N' and N > 1, LWORK >= 2*N+1.*> If JOBZ = 'V' and N > 1, LWORK >= 1 + 6*N + 2*N**2.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal sizes of the WORK and IWORK*> arrays, returns these values as the first entries of the WORK*> and IWORK arrays, and no error message related to LWORK or*> LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If N <= 1, LIWORK >= 1.*> If JOBZ = 'N' and N > 1, LIWORK >= 1.*> If JOBZ = 'V' and N > 1, LIWORK >= 3 + 5*N.*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal sizes of the WORK and*> IWORK arrays, returns these values as the first entries of*> the WORK and IWORK arrays, and no error message related to*> LWORK or LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: DPOTRF or DSYEVD returned an error code:*> <= N: if INFO = i and JOBZ = 'N', then the algorithm*> failed to converge; i off-diagonal elements of an*> intermediate tridiagonal form did not converge to*> zero;*> if INFO = i and JOBZ = 'V', then the algorithm*> failed to compute an eigenvalue while working on*> the submatrix lying in rows and columns INFO/(N+1)*> through mod(INFO,N+1);*> > N: if INFO = N + i, for 1 <= i <= N, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYeigen**> \par Further Details:* =====================*>*> \verbatim*>*> Modified so that no backsubstitution is performed if DSYEVD fails to*> converge (NEIG in old code could be greater than N causing out of*> bounds reference to A - reported by Ralf Meyer). Also corrected the*> description of INFO and the test on ITYPE. Sven, 16 Feb 05.*> \endverbatim**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA*>* =====================================================================SUBROUTINE DSYGVD( ITYPE, JOBZ, UPLO, N, A, LDA, B, LDB, W, WORK,$ LWORK, IWORK, LIWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBZ, UPLOINTEGER INFO, ITYPE, LDA, LDB, LIWORK, LWORK, N* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPER, WANTZCHARACTER TRANSINTEGER LIOPT, LIWMIN, LOPT, LWMIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DPOTRF, DSYEVD, DSYGST, DTRMM, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX* ..* .. Executable Statements ..** Test the input parameters.*WANTZ = LSAME( JOBZ, 'V' )UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*INFO = 0IF( N.LE.1 ) THENLIWMIN = 1LWMIN = 1ELSE IF( WANTZ ) THENLIWMIN = 3 + 5*NLWMIN = 1 + 6*N + 2*N**2ELSELIWMIN = 1LWMIN = 2*N + 1END IFLOPT = LWMINLIOPT = LIWMINIF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LOPTIWORK( 1 ) = LIOPT*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -11ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -13END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYGVD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Form a Cholesky factorization of B.*CALL DPOTRF( UPLO, N, B, LDB, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem and solve.*CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )CALL DSYEVD( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK, LIWORK,$ INFO )LOPT = MAX( DBLE( LOPT ), DBLE( WORK( 1 ) ) )LIOPT = MAX( DBLE( LIOPT ), DBLE( IWORK( 1 ) ) )*IF( WANTZ .AND. INFO.EQ.0 ) THEN** Backtransform eigenvectors to the original problem.*IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN** For A*x=(lambda)*B*x and A*B*x=(lambda)*x;* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y*IF( UPPER ) THENTRANS = 'N'ELSETRANS = 'T'END IF*CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, N, ONE,$ B, LDB, A, LDA )*ELSE IF( ITYPE.EQ.3 ) THEN** For B*A*x=(lambda)*x;* backtransform eigenvectors: x = L*y or U**T*y*IF( UPPER ) THENTRANS = 'T'ELSETRANS = 'N'END IF*CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, N, ONE,$ B, LDB, A, LDA )END IFEND IF*WORK( 1 ) = LOPTIWORK( 1 ) = LIOPT*RETURN** End of DSYGVD*END*> \brief \b DSYGVX** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYGVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsygvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsygvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsygvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYGVX( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB,* VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,* LWORK, IWORK, IFAIL, INFO )** .. Scalar Arguments ..* CHARACTER JOBZ, RANGE, UPLO* INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N* DOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..* INTEGER IFAIL( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ),* $ Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYGVX computes selected eigenvalues, and optionally, eigenvectors*> of a real generalized symmetric-definite eigenproblem, of the form*> A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A*> and B are assumed to be symmetric and B is also positive definite.*> Eigenvalues and eigenvectors can be selected by specifying either a*> range of values or a range of indices for the desired eigenvalues.*> \endverbatim** Arguments:* ==========**> \param[in] ITYPE*> \verbatim*> ITYPE is INTEGER*> Specifies the problem type to be solved:*> = 1: A*x = (lambda)*B*x*> = 2: A*B*x = (lambda)*x*> = 3: B*A*x = (lambda)*x*> \endverbatim*>*> \param[in] JOBZ*> \verbatim*> JOBZ is CHARACTER*1*> = 'N': Compute eigenvalues only;*> = 'V': Compute eigenvalues and eigenvectors.*> \endverbatim*>*> \param[in] RANGE*> \verbatim*> RANGE is CHARACTER*1*> = 'A': all eigenvalues will be found.*> = 'V': all eigenvalues in the half-open interval (VL,VU]*> will be found.*> = 'I': the IL-th through IU-th eigenvalues will be found.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A and B are stored;*> = 'L': Lower triangle of A and B are stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix pencil (A,B). N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, N)*> On entry, the symmetric matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of A contains the*> upper triangular part of the matrix A. If UPLO = 'L',*> the leading N-by-N lower triangular part of A contains*> the lower triangular part of the matrix A.*>*> On exit, the lower triangle (if UPLO='L') or the upper*> triangle (if UPLO='U') of A, including the diagonal, is*> destroyed.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, the symmetric matrix B. If UPLO = 'U', the*> leading N-by-N upper triangular part of B contains the*> upper triangular part of the matrix B. If UPLO = 'L',*> the leading N-by-N lower triangular part of B contains*> the lower triangular part of the matrix B.*>*> On exit, if INFO <= N, the part of B containing the matrix is*> overwritten by the triangular factor U or L from the Cholesky*> factorization B = U**T*U or B = L*L**T.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION*> If RANGE='V', the lower bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] VU*> \verbatim*> VU is DOUBLE PRECISION*> If RANGE='V', the upper bound of the interval to*> be searched for eigenvalues. VL < VU.*> Not referenced if RANGE = 'A' or 'I'.*> \endverbatim*>*> \param[in] IL*> \verbatim*> IL is INTEGER*> If RANGE='I', the index of the*> smallest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] IU*> \verbatim*> IU is INTEGER*> If RANGE='I', the index of the*> largest eigenvalue to be returned.*> 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.*> Not referenced if RANGE = 'A' or 'V'.*> \endverbatim*>*> \param[in] ABSTOL*> \verbatim*> ABSTOL is DOUBLE PRECISION*> The absolute error tolerance for the eigenvalues.*> An approximate eigenvalue is accepted as converged*> when it is determined to lie in an interval [a,b]*> of width less than or equal to*>*> ABSTOL + EPS * max( |a|,|b| ) ,*>*> where EPS is the machine precision. If ABSTOL is less than*> or equal to zero, then EPS*|T| will be used in its place,*> where |T| is the 1-norm of the tridiagonal matrix obtained*> by reducing C to tridiagonal form, where C is the symmetric*> matrix of the standard symmetric problem to which the*> generalized problem is transformed.*>*> Eigenvalues will be computed most accurately when ABSTOL is*> set to twice the underflow threshold 2*DLAMCH('S'), not zero.*> If this routine returns with INFO>0, indicating that some*> eigenvectors did not converge, try setting ABSTOL to*> 2*DLAMCH('S').*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The total number of eigenvalues found. 0 <= M <= N.*> If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.*> \endverbatim*>*> \param[out] W*> \verbatim*> W is DOUBLE PRECISION array, dimension (N)*> On normal exit, the first M elements contain the selected*> eigenvalues in ascending order.*> \endverbatim*>*> \param[out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M))*> If JOBZ = 'N', then Z is not referenced.*> If JOBZ = 'V', then if INFO = 0, the first M columns of Z*> contain the orthonormal eigenvectors of the matrix A*> corresponding to the selected eigenvalues, with the i-th*> column of Z holding the eigenvector associated with W(i).*> The eigenvectors are normalized as follows:*> if ITYPE = 1 or 2, Z**T*B*Z = I;*> if ITYPE = 3, Z**T*inv(B)*Z = I.*>*> If an eigenvector fails to converge, then that column of Z*> contains the latest approximation to the eigenvector, and the*> index of the eigenvector is returned in IFAIL.*> Note: the user must ensure that at least max(1,M) columns are*> supplied in the array Z; if RANGE = 'V', the exact value of M*> is not known in advance and an upper bound must be used.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1, and if*> JOBZ = 'V', LDZ >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of the array WORK. LWORK >= max(1,8*N).*> For optimal efficiency, LWORK >= (NB+3)*N,*> where NB is the blocksize for DSYTRD returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (5*N)*> \endverbatim*>*> \param[out] IFAIL*> \verbatim*> IFAIL is INTEGER array, dimension (N)*> If JOBZ = 'V', then if INFO = 0, the first M elements of*> IFAIL are zero. If INFO > 0, then IFAIL contains the*> indices of the eigenvectors that failed to converge.*> If JOBZ = 'N', then IFAIL is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: DPOTRF or DSYEVX returned an error code:*> <= N: if INFO = i, DSYEVX failed to converge;*> i eigenvectors failed to converge. Their indices*> are stored in array IFAIL.*> > N: if INFO = N + i, for 1 <= i <= N, then the leading*> minor of order i of B is not positive definite.*> The factorization of B could not be completed and*> no eigenvalues or eigenvectors were computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleSYeigen**> \par Contributors:* ==================*>*> Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA** =====================================================================SUBROUTINE DSYGVX( ITYPE, JOBZ, RANGE, UPLO, N, A, LDA, B, LDB,$ VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, WORK,$ LWORK, IWORK, IFAIL, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER JOBZ, RANGE, UPLOINTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, NDOUBLE PRECISION ABSTOL, VL, VU* ..* .. Array Arguments ..INTEGER IFAIL( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), W( * ), WORK( * ),$ Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZCHARACTER TRANSINTEGER LWKMIN, LWKOPT, NB* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DPOTRF, DSYEVX, DSYGST, DTRMM, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*UPPER = LSAME( UPLO, 'U' )WANTZ = LSAME( JOBZ, 'V' )ALLEIG = LSAME( RANGE, 'A' )VALEIG = LSAME( RANGE, 'V' )INDEIG = LSAME( RANGE, 'I' )LQUERY = ( LWORK.EQ.-1 )*INFO = 0IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THENINFO = -1ELSE IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( ALLEIG .OR. VALEIG .OR. INDEIG ) ) THENINFO = -3ELSE IF( .NOT.( UPPER .OR. LSAME( UPLO, 'L' ) ) ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSEIF( VALEIG ) THENIF( N.GT.0 .AND. VU.LE.VL )$ INFO = -11ELSE IF( INDEIG ) THENIF( IL.LT.1 .OR. IL.GT.MAX( 1, N ) ) THENINFO = -12ELSE IF( IU.LT.MIN( N, IL ) .OR. IU.GT.N ) THENINFO = -13END IFEND IFEND IFIF (INFO.EQ.0) THENIF (LDZ.LT.1 .OR. (WANTZ .AND. LDZ.LT.N)) THENINFO = -18END IFEND IF*IF( INFO.EQ.0 ) THENLWKMIN = MAX( 1, 8*N )NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )LWKOPT = MAX( LWKMIN, ( NB + 3 )*N )WORK( 1 ) = LWKOPT*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -20END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYGVX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*M = 0IF( N.EQ.0 ) THENRETURNEND IF** Form a Cholesky factorization of B.*CALL DPOTRF( UPLO, N, B, LDB, INFO )IF( INFO.NE.0 ) THENINFO = N + INFORETURNEND IF** Transform problem to standard eigenvalue problem and solve.*CALL DSYGST( ITYPE, UPLO, N, A, LDA, B, LDB, INFO )CALL DSYEVX( JOBZ, RANGE, UPLO, N, A, LDA, VL, VU, IL, IU, ABSTOL,$ M, W, Z, LDZ, WORK, LWORK, IWORK, IFAIL, INFO )*IF( WANTZ ) THEN** Backtransform eigenvectors to the original problem.*IF( INFO.GT.0 )$ M = INFO - 1IF( ITYPE.EQ.1 .OR. ITYPE.EQ.2 ) THEN** For A*x=(lambda)*B*x and A*B*x=(lambda)*x;* backtransform eigenvectors: x = inv(L)**T*y or inv(U)*y*IF( UPPER ) THENTRANS = 'N'ELSETRANS = 'T'END IF*CALL DTRSM( 'Left', UPLO, TRANS, 'Non-unit', N, M, ONE, B,$ LDB, Z, LDZ )*ELSE IF( ITYPE.EQ.3 ) THEN** For B*A*x=(lambda)*x;* backtransform eigenvectors: x = L*y or U**T*y*IF( UPPER ) THENTRANS = 'T'ELSETRANS = 'N'END IF*CALL DTRMM( 'Left', UPLO, TRANS, 'Non-unit', N, M, ONE, B,$ LDB, Z, LDZ )END IFEND IF** Set WORK(1) to optimal workspace size.*WORK( 1 ) = LWKOPT*RETURN** End of DSYGVX*END*> \brief \b DSYRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYRFS( UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,* X, LDX, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYRFS improves the computed solution to a system of linear*> equations when the coefficient matrix is symmetric indefinite, and*> provides error bounds and backward error estimates for the solution.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The symmetric matrix A. If UPLO = 'U', the leading N-by-N*> upper triangular part of A contains the upper triangular part*> of the matrix A, and the strictly lower triangular part of A*> is not referenced. If UPLO = 'L', the leading N-by-N lower*> triangular part of A contains the lower triangular part of*> the matrix A, and the strictly upper triangular part of A is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] AF*> \verbatim*> AF is DOUBLE PRECISION array, dimension (LDAF,N)*> The factored form of the matrix A. AF contains the block*> diagonal matrix D and the multipliers used to obtain the*> factor U or L from the factorization A = U*D*U**T or*> A = L*D*L**T as computed by DSYTRF.*> \endverbatim*>*> \param[in] LDAF*> \verbatim*> LDAF is INTEGER*> The leading dimension of the array AF. LDAF >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> On entry, the solution matrix X, as computed by DSYTRS.*> On exit, the improved solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim**> \par Internal Parameters:* =========================*>*> \verbatim*> ITMAX is the maximum number of steps of iterative refinement.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYRFS( UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB,$ X, LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDAF, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..INTEGER ITMAXPARAMETER ( ITMAX = 5 )DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )DOUBLE PRECISION TWOPARAMETER ( TWO = 2.0D+0 )DOUBLE PRECISION THREEPARAMETER ( THREE = 3.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER COUNT, I, J, K, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DSYMV, DSYTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 140 J = 1, NRHS*COUNT = 1LSTRES = THREE20 CONTINUE** Loop until stopping criterion is satisfied.** Compute residual R = B - A * X*CALL DCOPY( N, B( 1, J ), 1, WORK( N+1 ), 1 )CALL DSYMV( UPLO, N, -ONE, A, LDA, X( 1, J ), 1, ONE,$ WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 30 I = 1, NWORK( I ) = ABS( B( I, J ) )30 CONTINUE** Compute abs(A)*abs(X) + abs(B).*IF( UPPER ) THENDO 50 K = 1, NS = ZEROXK = ABS( X( K, J ) )DO 40 I = 1, K - 1WORK( I ) = WORK( I ) + ABS( A( I, K ) )*XKS = S + ABS( A( I, K ) )*ABS( X( I, J ) )40 CONTINUEWORK( K ) = WORK( K ) + ABS( A( K, K ) )*XK + S50 CONTINUEELSEDO 70 K = 1, NS = ZEROXK = ABS( X( K, J ) )WORK( K ) = WORK( K ) + ABS( A( K, K ) )*XKDO 60 I = K + 1, NWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XKS = S + ABS( A( I, K ) )*ABS( X( I, J ) )60 CONTINUEWORK( K ) = WORK( K ) + S70 CONTINUEEND IFS = ZERODO 80 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF80 CONTINUEBERR( J ) = S** Test stopping criterion. Continue iterating if* 1) The residual BERR(J) is larger than machine epsilon, and* 2) BERR(J) decreased by at least a factor of 2 during the* last iteration, and* 3) At most ITMAX iterations tried.*IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.$ COUNT.LE.ITMAX ) THEN** Update solution and try again.*CALL DSYTRS( UPLO, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )LSTRES = BERR( J )COUNT = COUNT + 1GO TO 20END IF** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(A))** ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(A) is the inverse of A* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(A)*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(A) * diag(W),* where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) )))*DO 90 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF90 CONTINUE*KASE = 0100 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(A**T).*CALL DSYTRS( UPLO, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )DO 110 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )110 CONTINUEELSE IF( KASE.EQ.2 ) THEN** Multiply by inv(A)*diag(W).*DO 120 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )120 CONTINUECALL DSYTRS( UPLO, N, 1, AF, LDAF, IPIV, WORK( N+1 ), N,$ INFO )END IFGO TO 100END IF** Normalize error.*LSTRES = ZERODO 130 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )130 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*140 CONTINUE*RETURN** End of DSYRFS*END*> \brief <b> DSYSV computes the solution to system of linear equations A * X = B for SY matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYSV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsysv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsysv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsysv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYSV( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK,* LWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDB, LWORK, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYSV computes the solution to a real system of linear equations*> A * X = B,*> where A is an N-by-N symmetric matrix and X and B are N-by-NRHS*> matrices.*>*> The diagonal pivoting method is used to factor A as*> A = U * D * U**T, if UPLO = 'U', or*> A = L * D * L**T, if UPLO = 'L',*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices, and D is symmetric and block diagonal with*> 1-by-1 and 2-by-2 diagonal blocks. The factored form of A is then*> used to solve the system of equations A * X = B.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, if INFO = 0, the block diagonal matrix D and the*> multipliers used to obtain the factor U or L from the*> factorization A = U*D*U**T or A = L*D*L**T as computed by*> DSYTRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D, as*> determined by DSYTRF. If IPIV(k) > 0, then rows and columns*> k and IPIV(k) were interchanged, and D(k,k) is a 1-by-1*> diagonal block. If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0,*> then rows and columns k-1 and -IPIV(k) were interchanged and*> D(k-1:k,k-1:k) is a 2-by-2 diagonal block. If UPLO = 'L' and*> IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and*> -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2*> diagonal block.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the N-by-NRHS right hand side matrix B.*> On exit, if INFO = 0, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of WORK. LWORK >= 1, and for best performance*> LWORK >= max(1,N*NB), where NB is the optimal blocksize for*> DSYTRF.*> for LWORK < N, TRS will be done with Level BLAS 2*> for LWORK >= N, TRS will be done with Level BLAS 3*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) is exactly zero. The factorization*> has been completed, but the block diagonal matrix D is*> exactly singular, so the solution could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYsolve** =====================================================================SUBROUTINE DSYSV( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, WORK,$ LWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDB, LWORK, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERYINTEGER LWKOPT* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DSYTRF, DSYTRS, DSYTRS2* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THENINFO = -10END IF*IF( INFO.EQ.0 ) THENIF( N.EQ.0 ) THENLWKOPT = 1ELSECALL DSYTRF( UPLO, N, A, LDA, IPIV, WORK, -1, INFO )LWKOPT = WORK(1)END IFWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYSV ', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Compute the factorization A = U*D*U**T or A = L*D*L**T.*CALL DSYTRF( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )IF( INFO.EQ.0 ) THEN** Solve the system A*X = B, overwriting B with X.*IF ( LWORK.LT.N ) THEN** Solve with TRS ( Use Level BLAS 2)*CALL DSYTRS( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO )*ELSE** Solve with TRS2 ( Use Level BLAS 3)*CALL DSYTRS2( UPLO,N,NRHS,A,LDA,IPIV,B,LDB,WORK,INFO )*END IF*END IF*WORK( 1 ) = LWKOPT*RETURN** End of DSYSV*END*> \brief <b> DSYSVX computes the solution to system of linear equations A * X = B for SY matrices</b>** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYSVX + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsysvx.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsysvx.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsysvx.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYSVX( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B,* LDB, X, LDX, RCOND, FERR, BERR, WORK, LWORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER FACT, UPLO* INTEGER INFO, LDA, LDAF, LDB, LDX, LWORK, N, NRHS* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IPIV( * ), IWORK( * )* DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),* $ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYSVX uses the diagonal pivoting factorization to compute the*> solution to a real system of linear equations A * X = B,*> where A is an N-by-N symmetric matrix and X and B are N-by-NRHS*> matrices.*>*> Error bounds on the solution and a condition estimate are also*> provided.*> \endverbatim**> \par Description:* =================*>*> \verbatim*>*> The following steps are performed:*>*> 1. If FACT = 'N', the diagonal pivoting method is used to factor A.*> The form of the factorization is*> A = U * D * U**T, if UPLO = 'U', or*> A = L * D * L**T, if UPLO = 'L',*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices, and D is symmetric and block diagonal with*> 1-by-1 and 2-by-2 diagonal blocks.*>*> 2. If some D(i,i)=0, so that D is exactly singular, then the routine*> returns with INFO = i. Otherwise, the factored form of A is used*> to estimate the condition number of the matrix A. If the*> reciprocal of the condition number is less than machine precision,*> INFO = N+1 is returned as a warning, but the routine still goes on*> to solve for X and compute error bounds as described below.*>*> 3. The system of equations is solved for X using the factored form*> of A.*>*> 4. Iterative refinement is applied to improve the computed solution*> matrix and calculate error bounds and backward error estimates*> for it.*> \endverbatim** Arguments:* ==========**> \param[in] FACT*> \verbatim*> FACT is CHARACTER*1*> Specifies whether or not the factored form of A has been*> supplied on entry.*> = 'F': On entry, AF and IPIV contain the factored form of*> A. AF and IPIV will not be modified.*> = 'N': The matrix A will be copied to AF and factored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of linear equations, i.e., the order of the*> matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The symmetric matrix A. If UPLO = 'U', the leading N-by-N*> upper triangular part of A contains the upper triangular part*> of the matrix A, and the strictly lower triangular part of A*> is not referenced. If UPLO = 'L', the leading N-by-N lower*> triangular part of A contains the lower triangular part of*> the matrix A, and the strictly upper triangular part of A is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] AF*> \verbatim*> AF is DOUBLE PRECISION array, dimension (LDAF,N)*> If FACT = 'F', then AF is an input argument and on entry*> contains the block diagonal matrix D and the multipliers used*> to obtain the factor U or L from the factorization*> A = U*D*U**T or A = L*D*L**T as computed by DSYTRF.*>*> If FACT = 'N', then AF is an output argument and on exit*> returns the block diagonal matrix D and the multipliers used*> to obtain the factor U or L from the factorization*> A = U*D*U**T or A = L*D*L**T.*> \endverbatim*>*> \param[in] LDAF*> \verbatim*> LDAF is INTEGER*> The leading dimension of the array AF. LDAF >= max(1,N).*> \endverbatim*>*> \param[in,out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> If FACT = 'F', then IPIV is an input argument and on entry*> contains details of the interchanges and the block structure*> of D, as determined by DSYTRF.*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and*> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)*> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =*> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were*> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.*>*> If FACT = 'N', then IPIV is an output argument and on exit*> contains details of the interchanges and the block structure*> of D, as determined by DSYTRF.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The N-by-NRHS right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> If INFO = 0 or INFO = N+1, the N-by-NRHS solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The estimate of the reciprocal condition number of the matrix*> A. If RCOND is less than the machine precision (in*> particular, if RCOND = 0), the matrix is singular to working*> precision. This condition is indicated by a return code of*> INFO > 0.*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of WORK. LWORK >= max(1,3*N), and for best*> performance, when FACT = 'N', LWORK >= max(1,3*N,N*NB), where*> NB is the optimal blocksize for DSYTRF.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, and i is*> <= N: D(i,i) is exactly zero. The factorization*> has been completed but the factor D is exactly*> singular, so the solution and error bounds could*> not be computed. RCOND = 0 is returned.*> = N+1: D is nonsingular, but RCOND is less than machine*> precision, meaning that the matrix is singular*> to working precision. Nevertheless, the*> solution and error bounds are computed because*> there are a number of situations where the*> computed solution can be more accurate than the*> value of RCOND would suggest.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleSYsolve** =====================================================================SUBROUTINE DSYSVX( FACT, UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B,$ LDB, X, LDX, RCOND, FERR, BERR, WORK, LWORK,$ IWORK, INFO )** -- LAPACK driver routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER FACT, UPLOINTEGER INFO, LDA, LDAF, LDB, LDX, LWORK, N, NRHSDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IPIV( * ), IWORK( * )DOUBLE PRECISION A( LDA, * ), AF( LDAF, * ), B( LDB, * ),$ BERR( * ), FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, NOFACTINTEGER LWKOPT, NBDOUBLE PRECISION ANORM* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVDOUBLE PRECISION DLAMCH, DLANSYEXTERNAL LSAME, ILAENV, DLAMCH, DLANSY* ..* .. External Subroutines ..EXTERNAL DLACPY, DSYCON, DSYRFS, DSYTRF, DSYTRS, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOFACT = LSAME( FACT, 'N' )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) )$ THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( NRHS.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDAF.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -11ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -13ELSE IF( LWORK.LT.MAX( 1, 3*N ) .AND. .NOT.LQUERY ) THENINFO = -18END IF*IF( INFO.EQ.0 ) THENLWKOPT = MAX( 1, 3*N )IF( NOFACT ) THENNB = ILAENV( 1, 'DSYTRF', UPLO, N, -1, -1, -1 )LWKOPT = MAX( LWKOPT, N*NB )END IFWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYSVX', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF*IF( NOFACT ) THEN** Compute the factorization A = U*D*U**T or A = L*D*L**T.*CALL DLACPY( UPLO, N, N, A, LDA, AF, LDAF )CALL DSYTRF( UPLO, N, AF, LDAF, IPIV, WORK, LWORK, INFO )** Return if INFO is non-zero.*IF( INFO.GT.0 )THENRCOND = ZERORETURNEND IFEND IF** Compute the norm of the matrix A.*ANORM = DLANSY( 'I', UPLO, N, A, LDA, WORK )** Compute the reciprocal of the condition number of A.*CALL DSYCON( UPLO, N, AF, LDAF, IPIV, ANORM, RCOND, WORK, IWORK,$ INFO )** Compute the solution vectors X.*CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )CALL DSYTRS( UPLO, N, NRHS, AF, LDAF, IPIV, X, LDX, INFO )** Use iterative refinement to improve the computed solutions and* compute error bounds and backward error estimates for them.*CALL DSYRFS( UPLO, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB, X,$ LDX, FERR, BERR, WORK, IWORK, INFO )** Set INFO = N+1 if the matrix is singular to working precision.*IF( RCOND.LT.DLAMCH( 'Epsilon' ) )$ INFO = N + 1*WORK( 1 ) = LWKOPT*RETURN** End of DSYSVX*END*> \brief \b DSYSWAPR applies an elementary permutation on the rows and columns of a symmetric matrix.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYSWAPR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyswapr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyswapr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyswapr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYSWAPR( UPLO, N, A, LDA, I1, I2)** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER I1, I2, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, N )***> \par Purpose:* =============*>*> \verbatim*>*> DSYSWAPR applies an elementary permutation on the rows and the columns of*> a symmetric matrix.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the NB diagonal matrix D and the multipliers*> used to obtain the factor U or L as computed by DSYTRF.*>*> On exit, if INFO = 0, the (symmetric) inverse of the original*> matrix. If UPLO = 'U', the upper triangular part of the*> inverse is formed and the part of A below the diagonal is not*> referenced; if UPLO = 'L' the lower triangular part of the*> inverse is formed and the part of A above the diagonal is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] I1*> \verbatim*> I1 is INTEGER*> Index of the first row to swap*> \endverbatim*>*> \param[in] I2*> \verbatim*> I2 is INTEGER*> Index of the second row to swap*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYauxiliary** =====================================================================SUBROUTINE DSYSWAPR( UPLO, N, A, LDA, I1, I2)** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER I1, I2, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, N )** =====================================================================** ..* .. Local Scalars ..LOGICAL UPPERINTEGER IDOUBLE PRECISION TMP** .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSWAP* ..* .. Executable Statements ..*UPPER = LSAME( UPLO, 'U' )IF (UPPER) THEN** UPPER* first swap* - swap column I1 and I2 from I1 to I1-1CALL DSWAP( I1-1, A(1,I1), 1, A(1,I2), 1 )** second swap :* - swap A(I1,I1) and A(I2,I2)* - swap row I1 from I1+1 to I2-1 with col I2 from I1+1 to I2-1TMP=A(I1,I1)A(I1,I1)=A(I2,I2)A(I2,I2)=TMP*DO I=1,I2-I1-1TMP=A(I1,I1+I)A(I1,I1+I)=A(I1+I,I2)A(I1+I,I2)=TMPEND DO** third swap* - swap row I1 and I2 from I2+1 to NDO I=I2+1,NTMP=A(I1,I)A(I1,I)=A(I2,I)A(I2,I)=TMPEND DO*ELSE** LOWER* first swap* - swap row I1 and I2 from I1 to I1-1CALL DSWAP( I1-1, A(I1,1), LDA, A(I2,1), LDA )** second swap :* - swap A(I1,I1) and A(I2,I2)* - swap col I1 from I1+1 to I2-1 with row I2 from I1+1 to I2-1TMP=A(I1,I1)A(I1,I1)=A(I2,I2)A(I2,I2)=TMP*DO I=1,I2-I1-1TMP=A(I1+I,I1)A(I1+I,I1)=A(I2,I1+I)A(I2,I1+I)=TMPEND DO** third swap* - swap col I1 and I2 from I2+1 to NDO I=I2+1,NTMP=A(I,I1)A(I,I1)=A(I,I2)A(I,I2)=TMPEND DO*ENDIFEND SUBROUTINE DSYSWAPR*> \brief \b DSYTD2 reduces a symmetric matrix to real symmetric tridiagonal form by an orthogonal similarity transformation (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTD2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytd2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytd2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytd2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal*> form T by an orthogonal similarity transformation: Q**T * A * Q = T.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n-by-n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n-by-n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*> On exit, if UPLO = 'U', the diagonal and first superdiagonal*> of A are overwritten by the corresponding elements of the*> tridiagonal matrix T, and the elements above the first*> superdiagonal, with the array TAU, represent the orthogonal*> matrix Q as a product of elementary reflectors; if UPLO*> = 'L', the diagonal and first subdiagonal of A are over-*> written by the corresponding elements of the tridiagonal*> matrix T, and the elements below the first subdiagonal, with*> the array TAU, represent the orthogonal matrix Q as a product*> of elementary reflectors. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of the tridiagonal matrix T:*> D(i) = A(i,i).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The off-diagonal elements of the tridiagonal matrix T:*> E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(n-1) . . . H(2) H(1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in*> A(1:i-1,i+1), and tau in TAU(i).*>*> If UPLO = 'L', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(1) H(2) . . . H(n-1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),*> and tau in TAU(i).*>*> The contents of A on exit are illustrated by the following examples*> with n = 5:*>*> if UPLO = 'U': if UPLO = 'L':*>*> ( d e v2 v3 v4 ) ( d )*> ( d e v3 v4 ) ( e d )*> ( d e v4 ) ( v1 e d )*> ( d e ) ( v1 v2 e d )*> ( d ) ( v1 v2 v3 e d )*>*> where d and e denote diagonal and off-diagonal elements of T, and vi*> denotes an element of the vector defining H(i).*> \endverbatim*>* =====================================================================SUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZERO, HALFPARAMETER ( ONE = 1.0D0, ZERO = 0.0D0,$ HALF = 1.0D0 / 2.0D0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER IDOUBLE PRECISION ALPHA, TAUI* ..* .. External Subroutines ..EXTERNAL DAXPY, DLARFG, DSYMV, DSYR2, XERBLA* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTD2', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.0 )$ RETURN*IF( UPPER ) THEN** Reduce the upper triangle of A*DO 10 I = N - 1, 1, -1** Generate elementary reflector H(i) = I - tau * v * v**T* to annihilate A(1:i-1,i+1)*CALL DLARFG( I, A( I, I+1 ), A( 1, I+1 ), 1, TAUI )E( I ) = A( I, I+1 )*IF( TAUI.NE.ZERO ) THEN** Apply H(i) from both sides to A(1:i,1:i)*A( I, I+1 ) = ONE** Compute x := tau * A * v storing x in TAU(1:i)*CALL DSYMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO,$ TAU, 1 )** Compute w := x - 1/2 * tau * (x**T * v) * v*ALPHA = -HALF*TAUI*DDOT( I, TAU, 1, A( 1, I+1 ), 1 )CALL DAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )** Apply the transformation as a rank-2 update:* A := A - v * w**T - w * v**T*CALL DSYR2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A,$ LDA )*A( I, I+1 ) = E( I )END IFD( I+1 ) = A( I+1, I+1 )TAU( I ) = TAUI10 CONTINUED( 1 ) = A( 1, 1 )ELSE** Reduce the lower triangle of A*DO 20 I = 1, N - 1** Generate elementary reflector H(i) = I - tau * v * v**T* to annihilate A(i+2:n,i)*CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1,$ TAUI )E( I ) = A( I+1, I )*IF( TAUI.NE.ZERO ) THEN** Apply H(i) from both sides to A(i+1:n,i+1:n)*A( I+1, I ) = ONE** Compute x := tau * A * v storing y in TAU(i:n-1)*CALL DSYMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA,$ A( I+1, I ), 1, ZERO, TAU( I ), 1 )** Compute w := x - 1/2 * tau * (x**T * v) * v*ALPHA = -HALF*TAUI*DDOT( N-I, TAU( I ), 1, A( I+1, I ),$ 1 )CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )** Apply the transformation as a rank-2 update:* A := A - v * w**T - w * v**T*CALL DSYR2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1,$ A( I+1, I+1 ), LDA )*A( I+1, I ) = E( I )END IFD( I ) = A( I, I )TAU( I ) = TAUI20 CONTINUED( N ) = A( N, N )END IF*RETURN** End of DSYTD2*END*> \brief \b DSYTF2 computes the factorization of a real symmetric indefinite matrix, using the diagonal pivoting method (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTF2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytf2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytf2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytf2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTF2( UPLO, N, A, LDA, IPIV, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTF2 computes the factorization of a real symmetric matrix A using*> the Bunch-Kaufman diagonal pivoting method:*>*> A = U*D*U**T or A = L*D*L**T*>*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices, U**T is the transpose of U, and D is symmetric and*> block diagonal with 1-by-1 and 2-by-2 diagonal blocks.*>*> This is the unblocked version of the algorithm, calling Level 2 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the upper or lower triangular part of the*> symmetric matrix A is stored:*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> n-by-n upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n-by-n lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, the block diagonal matrix D and the multipliers used*> to obtain the factor U or L (see below for further details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D.*>*> If UPLO = 'U':*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*>*> If IPIV(k) = IPIV(k-1) < 0, then rows and columns*> k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)*> is a 2-by-2 diagonal block.*>*> If UPLO = 'L':*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*>*> If IPIV(k) = IPIV(k+1) < 0, then rows and columns*> k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1)*> is a 2-by-2 diagonal block.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> > 0: if INFO = k, D(k,k) is exactly zero. The factorization*> has been completed, but the block diagonal matrix D is*> exactly singular, and division by zero will occur if it*> is used to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', then A = U*D*U**T, where*> U = P(n)*U(n)* ... *P(k)U(k)* ...,*> i.e., U is a product of terms P(k)*U(k), where k decreases from n to*> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1*> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as*> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such*> that if the diagonal block D(k) is of order s (s = 1 or 2), then*>*> ( I v 0 ) k-s*> U(k) = ( 0 I 0 ) s*> ( 0 0 I ) n-k*> k-s s n-k*>*> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).*> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),*> and A(k,k), and v overwrites A(1:k-2,k-1:k).*>*> If UPLO = 'L', then A = L*D*L**T, where*> L = P(1)*L(1)* ... *P(k)*L(k)* ...,*> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to*> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1*> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as*> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such*> that if the diagonal block D(k) is of order s (s = 1 or 2), then*>*> ( I 0 0 ) k-1*> L(k) = ( 0 I 0 ) s*> ( 0 v I ) n-k-s+1*> k-1 s n-k-s+1*>*> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).*> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),*> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).*> \endverbatim**> \par Contributors:* ==================*>*> \verbatim*>*> 09-29-06 - patch from*> Bobby Cheng, MathWorks*>*> Replace l.204 and l.372*> IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN*> by*> IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. DISNAN(ABSAKK) ) THEN*>*> 01-01-96 - Based on modifications by*> J. Lewis, Boeing Computer Services Company*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA*> 1-96 - Based on modifications by J. Lewis, Boeing Computer Services*> Company*> \endverbatim** =====================================================================SUBROUTINE DSYTF2( UPLO, N, A, LDA, IPIV, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION EIGHT, SEVTENPARAMETER ( EIGHT = 8.0D+0, SEVTEN = 17.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IMAX, J, JMAX, K, KK, KP, KSTEPDOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D11, D12, D21, D22, R1,$ ROWMAX, T, WK, WKM1, WKP1* ..* .. External Functions ..LOGICAL LSAME, DISNANINTEGER IDAMAXEXTERNAL LSAME, IDAMAX, DISNAN* ..* .. External Subroutines ..EXTERNAL DSCAL, DSWAP, DSYR, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTF2', -INFO )RETURNEND IF** Initialize ALPHA for use in choosing pivot block size.*ALPHA = ( ONE+SQRT( SEVTEN ) ) / EIGHT*IF( UPPER ) THEN** Factorize A as U*D*U**T using the upper triangle of A** K is the main loop index, decreasing from N to 1 in steps of* 1 or 2*K = N10 CONTINUE** If K < 1, exit from loop*IF( K.LT.1 )$ GO TO 70KSTEP = 1** Determine rows and columns to be interchanged and whether* a 1-by-1 or 2-by-2 pivot block will be used*ABSAKK = ABS( A( K, K ) )** IMAX is the row-index of the largest off-diagonal element in* column K, and COLMAX is its absolute value.* Determine both COLMAX and IMAX.*IF( K.GT.1 ) THENIMAX = IDAMAX( K-1, A( 1, K ), 1 )COLMAX = ABS( A( IMAX, K ) )ELSECOLMAX = ZEROEND IF*IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. DISNAN(ABSAKK) ) THEN** Column K is zero or underflow, or contains a NaN:* set INFO and continue*IF( INFO.EQ.0 )$ INFO = KKP = KELSEIF( ABSAKK.GE.ALPHA*COLMAX ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE** JMAX is the column-index of the largest off-diagonal* element in row IMAX, and ROWMAX is its absolute value*JMAX = IMAX + IDAMAX( K-IMAX, A( IMAX, IMAX+1 ), LDA )ROWMAX = ABS( A( IMAX, JMAX ) )IF( IMAX.GT.1 ) THENJMAX = IDAMAX( IMAX-1, A( 1, IMAX ), 1 )ROWMAX = MAX( ROWMAX, ABS( A( JMAX, IMAX ) ) )END IF*IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE IF( ABS( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX ) THEN** interchange rows and columns K and IMAX, use 1-by-1* pivot block*KP = IMAXELSE** interchange rows and columns K-1 and IMAX, use 2-by-2* pivot block*KP = IMAXKSTEP = 2END IFEND IF*KK = K - KSTEP + 1IF( KP.NE.KK ) THEN** Interchange rows and columns KK and KP in the leading* submatrix A(1:k,1:k)*CALL DSWAP( KP-1, A( 1, KK ), 1, A( 1, KP ), 1 )CALL DSWAP( KK-KP-1, A( KP+1, KK ), 1, A( KP, KP+1 ),$ LDA )T = A( KK, KK )A( KK, KK ) = A( KP, KP )A( KP, KP ) = TIF( KSTEP.EQ.2 ) THENT = A( K-1, K )A( K-1, K ) = A( KP, K )A( KP, K ) = TEND IFEND IF** Update the leading submatrix*IF( KSTEP.EQ.1 ) THEN** 1-by-1 pivot block D(k): column k now holds** W(k) = U(k)*D(k)** where U(k) is the k-th column of U** Perform a rank-1 update of A(1:k-1,1:k-1) as** A := A - U(k)*D(k)*U(k)**T = A - W(k)*1/D(k)*W(k)**T*R1 = ONE / A( K, K )CALL DSYR( UPLO, K-1, -R1, A( 1, K ), 1, A, LDA )** Store U(k) in column k*CALL DSCAL( K-1, R1, A( 1, K ), 1 )ELSE** 2-by-2 pivot block D(k): columns k and k-1 now hold** ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)** where U(k) and U(k-1) are the k-th and (k-1)-th columns* of U** Perform a rank-2 update of A(1:k-2,1:k-2) as** A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T* = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )**T*IF( K.GT.2 ) THEN*D12 = A( K-1, K )D22 = A( K-1, K-1 ) / D12D11 = A( K, K ) / D12T = ONE / ( D11*D22-ONE )D12 = T / D12*DO 30 J = K - 2, 1, -1WKM1 = D12*( D11*A( J, K-1 )-A( J, K ) )WK = D12*( D22*A( J, K )-A( J, K-1 ) )DO 20 I = J, 1, -1A( I, J ) = A( I, J ) - A( I, K )*WK -$ A( I, K-1 )*WKM120 CONTINUEA( J, K ) = WKA( J, K-1 ) = WKM130 CONTINUE*END IF*END IFEND IF** Store details of the interchanges in IPIV*IF( KSTEP.EQ.1 ) THENIPIV( K ) = KPELSEIPIV( K ) = -KPIPIV( K-1 ) = -KPEND IF** Decrease K and return to the start of the main loop*K = K - KSTEPGO TO 10*ELSE** Factorize A as L*D*L**T using the lower triangle of A** K is the main loop index, increasing from 1 to N in steps of* 1 or 2*K = 140 CONTINUE** If K > N, exit from loop*IF( K.GT.N )$ GO TO 70KSTEP = 1** Determine rows and columns to be interchanged and whether* a 1-by-1 or 2-by-2 pivot block will be used*ABSAKK = ABS( A( K, K ) )** IMAX is the row-index of the largest off-diagonal element in* column K, and COLMAX is its absolute value.* Determine both COLMAX and IMAX.*IF( K.LT.N ) THENIMAX = K + IDAMAX( N-K, A( K+1, K ), 1 )COLMAX = ABS( A( IMAX, K ) )ELSECOLMAX = ZEROEND IF*IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. DISNAN(ABSAKK) ) THEN** Column K is zero or underflow, or contains a NaN:* set INFO and continue*IF( INFO.EQ.0 )$ INFO = KKP = KELSEIF( ABSAKK.GE.ALPHA*COLMAX ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE** JMAX is the column-index of the largest off-diagonal* element in row IMAX, and ROWMAX is its absolute value*JMAX = K - 1 + IDAMAX( IMAX-K, A( IMAX, K ), LDA )ROWMAX = ABS( A( IMAX, JMAX ) )IF( IMAX.LT.N ) THENJMAX = IMAX + IDAMAX( N-IMAX, A( IMAX+1, IMAX ), 1 )ROWMAX = MAX( ROWMAX, ABS( A( JMAX, IMAX ) ) )END IF*IF( ABSAKK.GE.ALPHA*COLMAX*( COLMAX / ROWMAX ) ) THEN** no interchange, use 1-by-1 pivot block*KP = KELSE IF( ABS( A( IMAX, IMAX ) ).GE.ALPHA*ROWMAX ) THEN** interchange rows and columns K and IMAX, use 1-by-1* pivot block*KP = IMAXELSE** interchange rows and columns K+1 and IMAX, use 2-by-2* pivot block*KP = IMAXKSTEP = 2END IFEND IF*KK = K + KSTEP - 1IF( KP.NE.KK ) THEN** Interchange rows and columns KK and KP in the trailing* submatrix A(k:n,k:n)*IF( KP.LT.N )$ CALL DSWAP( N-KP, A( KP+1, KK ), 1, A( KP+1, KP ), 1 )CALL DSWAP( KP-KK-1, A( KK+1, KK ), 1, A( KP, KK+1 ),$ LDA )T = A( KK, KK )A( KK, KK ) = A( KP, KP )A( KP, KP ) = TIF( KSTEP.EQ.2 ) THENT = A( K+1, K )A( K+1, K ) = A( KP, K )A( KP, K ) = TEND IFEND IF** Update the trailing submatrix*IF( KSTEP.EQ.1 ) THEN** 1-by-1 pivot block D(k): column k now holds** W(k) = L(k)*D(k)** where L(k) is the k-th column of L*IF( K.LT.N ) THEN** Perform a rank-1 update of A(k+1:n,k+1:n) as** A := A - L(k)*D(k)*L(k)**T = A - W(k)*(1/D(k))*W(k)**T*D11 = ONE / A( K, K )CALL DSYR( UPLO, N-K, -D11, A( K+1, K ), 1,$ A( K+1, K+1 ), LDA )** Store L(k) in column K*CALL DSCAL( N-K, D11, A( K+1, K ), 1 )END IFELSE** 2-by-2 pivot block D(k)*IF( K.LT.N-1 ) THEN** Perform a rank-2 update of A(k+2:n,k+2:n) as** A := A - ( (A(k) A(k+1))*D(k)**(-1) ) * (A(k) A(k+1))**T** where L(k) and L(k+1) are the k-th and (k+1)-th* columns of L*D21 = A( K+1, K )D11 = A( K+1, K+1 ) / D21D22 = A( K, K ) / D21T = ONE / ( D11*D22-ONE )D21 = T / D21*DO 60 J = K + 2, N*WK = D21*( D11*A( J, K )-A( J, K+1 ) )WKP1 = D21*( D22*A( J, K+1 )-A( J, K ) )*DO 50 I = J, NA( I, J ) = A( I, J ) - A( I, K )*WK -$ A( I, K+1 )*WKP150 CONTINUE*A( J, K ) = WKA( J, K+1 ) = WKP1*60 CONTINUEEND IFEND IFEND IF** Store details of the interchanges in IPIV*IF( KSTEP.EQ.1 ) THENIPIV( K ) = KPELSEIPIV( K ) = -KPIPIV( K+1 ) = -KPEND IF** Increase K and return to the start of the main loop*K = K + KSTEPGO TO 40*END IF*70 CONTINUE*RETURN** End of DSYTF2*END*> \brief \b DSYTRD** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRD + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrd.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrd.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrd.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRD reduces a real symmetric matrix A to real symmetric*> tridiagonal form T by an orthogonal similarity transformation:*> Q**T * A * Q = T.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*> On exit, if UPLO = 'U', the diagonal and first superdiagonal*> of A are overwritten by the corresponding elements of the*> tridiagonal matrix T, and the elements above the first*> superdiagonal, with the array TAU, represent the orthogonal*> matrix Q as a product of elementary reflectors; if UPLO*> = 'L', the diagonal and first subdiagonal of A are over-*> written by the corresponding elements of the tridiagonal*> matrix T, and the elements below the first subdiagonal, with*> the array TAU, represent the orthogonal matrix Q as a product*> of elementary reflectors. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (N)*> The diagonal elements of the tridiagonal matrix T:*> D(i) = A(i,i).*> \endverbatim*>*> \param[out] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (N-1)*> The off-diagonal elements of the tridiagonal matrix T:*> E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (N-1)*> The scalar factors of the elementary reflectors (see Further*> Details).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= 1.*> For optimum performance LWORK >= N*NB, where NB is the*> optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(n-1) . . . H(2) H(1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in*> A(1:i-1,i+1), and tau in TAU(i).*>*> If UPLO = 'L', the matrix Q is represented as a product of elementary*> reflectors*>*> Q = H(1) H(2) . . . H(n-1).*>*> Each H(i) has the form*>*> H(i) = I - tau * v * v**T*>*> where tau is a real scalar, and v is a real vector with*> v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),*> and tau in TAU(i).*>*> The contents of A on exit are illustrated by the following examples*> with n = 5:*>*> if UPLO = 'U': if UPLO = 'L':*>*> ( d e v2 v3 v4 ) ( d )*> ( d e v3 v4 ) ( e d )*> ( d e v4 ) ( v1 e d )*> ( d e ) ( v1 v2 e d )*> ( d ) ( v1 v2 v3 e d )*>*> where d and e denote diagonal and off-diagonal elements of T, and vi*> denotes an element of the vector defining H(i).*> \endverbatim*>* =====================================================================SUBROUTINE DSYTRD( UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, UPPERINTEGER I, IINFO, IWS, J, KK, LDWORK, LWKOPT, NB,$ NBMIN, NX* ..* .. External Subroutines ..EXTERNAL DLATRD, DSYR2K, DSYTD2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. Executable Statements ..** Test the input parameters*INFO = 0UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THENINFO = -9END IF*IF( INFO.EQ.0 ) THEN** Determine the block size.*NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRD', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENWORK( 1 ) = 1RETURNEND IF*NX = NIWS = 1IF( NB.GT.1 .AND. NB.LT.N ) THEN** Determine when to cross over from blocked to unblocked code* (last block is always handled by unblocked code).*NX = MAX( NB, ILAENV( 3, 'DSYTRD', UPLO, N, -1, -1, -1 ) )IF( NX.LT.N ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = NIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: determine the* minimum value of NB, and reduce NB or force use of* unblocked code by setting NX = N.*NB = MAX( LWORK / LDWORK, 1 )NBMIN = ILAENV( 2, 'DSYTRD', UPLO, N, -1, -1, -1 )IF( NB.LT.NBMIN )$ NX = NEND IFELSENX = NEND IFELSENB = 1END IF*IF( UPPER ) THEN** Reduce the upper triangle of A.* Columns 1:kk are handled by the unblocked method.*KK = N - ( ( N-NX+NB-1 ) / NB )*NBDO 20 I = N - NB + 1, KK + 1, -NB** Reduce columns i:i+nb-1 to tridiagonal form and form the* matrix W which is needed to update the unreduced part of* the matrix*CALL DLATRD( UPLO, I+NB-1, NB, A, LDA, E, TAU, WORK,$ LDWORK )** Update the unreduced submatrix A(1:i-1,1:i-1), using an* update of the form: A := A - V*W**T - W*V**T*CALL DSYR2K( UPLO, 'No transpose', I-1, NB, -ONE, A( 1, I ),$ LDA, WORK, LDWORK, ONE, A, LDA )** Copy superdiagonal elements back into A, and diagonal* elements into D*DO 10 J = I, I + NB - 1A( J-1, J ) = E( J-1 )D( J ) = A( J, J )10 CONTINUE20 CONTINUE** Use unblocked code to reduce the last or only block*CALL DSYTD2( UPLO, KK, A, LDA, D, E, TAU, IINFO )ELSE** Reduce the lower triangle of A*DO 40 I = 1, N - NX, NB** Reduce columns i:i+nb-1 to tridiagonal form and form the* matrix W which is needed to update the unreduced part of* the matrix*CALL DLATRD( UPLO, N-I+1, NB, A( I, I ), LDA, E( I ),$ TAU( I ), WORK, LDWORK )** Update the unreduced submatrix A(i+ib:n,i+ib:n), using* an update of the form: A := A - V*W**T - W*V**T*CALL DSYR2K( UPLO, 'No transpose', N-I-NB+1, NB, -ONE,$ A( I+NB, I ), LDA, WORK( NB+1 ), LDWORK, ONE,$ A( I+NB, I+NB ), LDA )** Copy subdiagonal elements back into A, and diagonal* elements into D*DO 30 J = I, I + NB - 1A( J+1, J ) = E( J )D( J ) = A( J, J )30 CONTINUE40 CONTINUE** Use unblocked code to reduce the last or only block*CALL DSYTD2( UPLO, N-I+1, A( I, I ), LDA, D( I ), E( I ),$ TAU( I ), IINFO )END IF*WORK( 1 ) = LWKOPTRETURN** End of DSYTRD*END*> \brief \b DSYTRF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRF( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRF computes the factorization of a real symmetric matrix A using*> the Bunch-Kaufman diagonal pivoting method. The form of the*> factorization is*>*> A = U*D*U**T or A = L*D*L**T*>*> where U (or L) is a product of permutation and unit upper (lower)*> triangular matrices, and D is symmetric and block diagonal with*> 1-by-1 and 2-by-2 diagonal blocks.*>*> This is the blocked version of the algorithm, calling Level 3 BLAS.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the symmetric matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*>*> On exit, the block diagonal matrix D and the multipliers used*> to obtain the factor U or L (see below for further details).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D.*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were*> interchanged and D(k,k) is a 1-by-1 diagonal block.*> If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and*> columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)*> is a 2-by-2 diagonal block. If UPLO = 'L' and IPIV(k) =*> IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were*> interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The length of WORK. LWORK >=1. For best performance*> LWORK >= N*NB, where NB is the block size returned by ILAENV.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) is exactly zero. The factorization*> has been completed, but the block diagonal matrix D is*> exactly singular, and division by zero will occur if it*> is used to solve a system of equations.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> If UPLO = 'U', then A = U*D*U**T, where*> U = P(n)*U(n)* ... *P(k)U(k)* ...,*> i.e., U is a product of terms P(k)*U(k), where k decreases from n to*> 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1*> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as*> defined by IPIV(k), and U(k) is a unit upper triangular matrix, such*> that if the diagonal block D(k) is of order s (s = 1 or 2), then*>*> ( I v 0 ) k-s*> U(k) = ( 0 I 0 ) s*> ( 0 0 I ) n-k*> k-s s n-k*>*> If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).*> If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),*> and A(k,k), and v overwrites A(1:k-2,k-1:k).*>*> If UPLO = 'L', then A = L*D*L**T, where*> L = P(1)*L(1)* ... *P(k)*L(k)* ...,*> i.e., L is a product of terms P(k)*L(k), where k increases from 1 to*> n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1*> and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as*> defined by IPIV(k), and L(k) is a unit lower triangular matrix, such*> that if the diagonal block D(k) is of order s (s = 1 or 2), then*>*> ( I 0 0 ) k-1*> L(k) = ( 0 I 0 ) s*> ( 0 v I ) n-k-s+1*> k-1 s n-k-s+1*>*> If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).*> If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),*> and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).*> \endverbatim*>* =====================================================================SUBROUTINE DSYTRF( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL LQUERY, UPPERINTEGER IINFO, IWS, J, K, KB, LDWORK, LWKOPT, NB, NBMIN* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DLASYF, DSYTF2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LWORK.LT.1 .AND. .NOT.LQUERY ) THENINFO = -7END IF*IF( INFO.EQ.0 ) THEN** Determine the block size*NB = ILAENV( 1, 'DSYTRF', UPLO, N, -1, -1, -1 )LWKOPT = N*NBWORK( 1 ) = LWKOPTEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF*NBMIN = 2LDWORK = NIF( NB.GT.1 .AND. NB.LT.N ) THENIWS = LDWORK*NBIF( LWORK.LT.IWS ) THENNB = MAX( LWORK / LDWORK, 1 )NBMIN = MAX( 2, ILAENV( 2, 'DSYTRF', UPLO, N, -1, -1, -1 ) )END IFELSEIWS = 1END IFIF( NB.LT.NBMIN )$ NB = N*IF( UPPER ) THEN** Factorize A as U*D*U**T using the upper triangle of A** K is the main loop index, decreasing from N to 1 in steps of* KB, where KB is the number of columns factorized by DLASYF;* KB is either NB or NB-1, or K for the last block*K = N10 CONTINUE** If K < 1, exit from loop*IF( K.LT.1 )$ GO TO 40*IF( K.GT.NB ) THEN** Factorize columns k-kb+1:k of A and use blocked code to* update columns 1:k-kb*CALL DLASYF( UPLO, K, NB, KB, A, LDA, IPIV, WORK, LDWORK,$ IINFO )ELSE** Use unblocked code to factorize columns 1:k of A*CALL DSYTF2( UPLO, K, A, LDA, IPIV, IINFO )KB = KEND IF** Set INFO on the first occurrence of a zero pivot*IF( INFO.EQ.0 .AND. IINFO.GT.0 )$ INFO = IINFO** Decrease K and return to the start of the main loop*K = K - KBGO TO 10*ELSE** Factorize A as L*D*L**T using the lower triangle of A** K is the main loop index, increasing from 1 to N in steps of* KB, where KB is the number of columns factorized by DLASYF;* KB is either NB or NB-1, or N-K+1 for the last block*K = 120 CONTINUE** If K > N, exit from loop*IF( K.GT.N )$ GO TO 40*IF( K.LE.N-NB ) THEN** Factorize columns k:k+kb-1 of A and use blocked code to* update columns k+kb:n*CALL DLASYF( UPLO, N-K+1, NB, KB, A( K, K ), LDA, IPIV( K ),$ WORK, LDWORK, IINFO )ELSE** Use unblocked code to factorize columns k:n of A*CALL DSYTF2( UPLO, N-K+1, A( K, K ), LDA, IPIV( K ), IINFO )KB = N - K + 1END IF** Set INFO on the first occurrence of a zero pivot*IF( INFO.EQ.0 .AND. IINFO.GT.0 )$ INFO = IINFO + K - 1** Adjust IPIV*DO 30 J = K, K + KB - 1IF( IPIV( J ).GT.0 ) THENIPIV( J ) = IPIV( J ) + K - 1ELSEIPIV( J ) = IPIV( J ) - K + 1END IF30 CONTINUE** Increase K and return to the start of the main loop*K = K + KBGO TO 20*END IF*40 CONTINUEWORK( 1 ) = LWKOPTRETURN** End of DSYTRF*END*> \brief \b DSYTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRI( UPLO, N, A, LDA, IPIV, WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRI computes the inverse of a real symmetric indefinite matrix*> A using the factorization A = U*D*U**T or A = L*D*L**T computed by*> DSYTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the block diagonal matrix D and the multipliers*> used to obtain the factor U or L as computed by DSYTRF.*>*> On exit, if INFO = 0, the (symmetric) inverse of the original*> matrix. If UPLO = 'U', the upper triangular part of the*> inverse is formed and the part of A below the diagonal is not*> referenced; if UPLO = 'L' the lower triangular part of the*> inverse is formed and the part of A above the diagonal is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its*> inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYTRI( UPLO, N, A, LDA, IPIV, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER K, KP, KSTEPDOUBLE PRECISION AK, AKKP1, AKP1, D, T, TEMP* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOTEXTERNAL LSAME, DDOT* ..* .. External Subroutines ..EXTERNAL DCOPY, DSWAP, DSYMV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Check that the diagonal matrix D is nonsingular.*IF( UPPER ) THEN** Upper triangular storage: examine D from bottom to top*DO 10 INFO = N, 1, -1IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.ZERO )$ RETURN10 CONTINUEELSE** Lower triangular storage: examine D from top to bottom.*DO 20 INFO = 1, NIF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.ZERO )$ RETURN20 CONTINUEEND IFINFO = 0*IF( UPPER ) THEN** Compute inv(A) from the factorization A = U*D*U**T.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = 130 CONTINUE** If K > N, exit from loop.*IF( K.GT.N )$ GO TO 40*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Invert the diagonal block.*A( K, K ) = ONE / A( K, K )** Compute column K of the inverse.*IF( K.GT.1 ) THENCALL DCOPY( K-1, A( 1, K ), 1, WORK, 1 )CALL DSYMV( UPLO, K-1, -ONE, A, LDA, WORK, 1, ZERO,$ A( 1, K ), 1 )A( K, K ) = A( K, K ) - DDOT( K-1, WORK, 1, A( 1, K ),$ 1 )END IFKSTEP = 1ELSE** 2 x 2 diagonal block** Invert the diagonal block.*T = ABS( A( K, K+1 ) )AK = A( K, K ) / TAKP1 = A( K+1, K+1 ) / TAKKP1 = A( K, K+1 ) / TD = T*( AK*AKP1-ONE )A( K, K ) = AKP1 / DA( K+1, K+1 ) = AK / DA( K, K+1 ) = -AKKP1 / D** Compute columns K and K+1 of the inverse.*IF( K.GT.1 ) THENCALL DCOPY( K-1, A( 1, K ), 1, WORK, 1 )CALL DSYMV( UPLO, K-1, -ONE, A, LDA, WORK, 1, ZERO,$ A( 1, K ), 1 )A( K, K ) = A( K, K ) - DDOT( K-1, WORK, 1, A( 1, K ),$ 1 )A( K, K+1 ) = A( K, K+1 ) -$ DDOT( K-1, A( 1, K ), 1, A( 1, K+1 ), 1 )CALL DCOPY( K-1, A( 1, K+1 ), 1, WORK, 1 )CALL DSYMV( UPLO, K-1, -ONE, A, LDA, WORK, 1, ZERO,$ A( 1, K+1 ), 1 )A( K+1, K+1 ) = A( K+1, K+1 ) -$ DDOT( K-1, WORK, 1, A( 1, K+1 ), 1 )END IFKSTEP = 2END IF*KP = ABS( IPIV( K ) )IF( KP.NE.K ) THEN** Interchange rows and columns K and KP in the leading* submatrix A(1:k+1,1:k+1)*CALL DSWAP( KP-1, A( 1, K ), 1, A( 1, KP ), 1 )CALL DSWAP( K-KP-1, A( KP+1, K ), 1, A( KP, KP+1 ), LDA )TEMP = A( K, K )A( K, K ) = A( KP, KP )A( KP, KP ) = TEMPIF( KSTEP.EQ.2 ) THENTEMP = A( K, K+1 )A( K, K+1 ) = A( KP, K+1 )A( KP, K+1 ) = TEMPEND IFEND IF*K = K + KSTEPGO TO 3040 CONTINUE*ELSE** Compute inv(A) from the factorization A = L*D*L**T.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = N50 CONTINUE** If K < 1, exit from loop.*IF( K.LT.1 )$ GO TO 60*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Invert the diagonal block.*A( K, K ) = ONE / A( K, K )** Compute column K of the inverse.*IF( K.LT.N ) THENCALL DCOPY( N-K, A( K+1, K ), 1, WORK, 1 )CALL DSYMV( UPLO, N-K, -ONE, A( K+1, K+1 ), LDA, WORK, 1,$ ZERO, A( K+1, K ), 1 )A( K, K ) = A( K, K ) - DDOT( N-K, WORK, 1, A( K+1, K ),$ 1 )END IFKSTEP = 1ELSE** 2 x 2 diagonal block** Invert the diagonal block.*T = ABS( A( K, K-1 ) )AK = A( K-1, K-1 ) / TAKP1 = A( K, K ) / TAKKP1 = A( K, K-1 ) / TD = T*( AK*AKP1-ONE )A( K-1, K-1 ) = AKP1 / DA( K, K ) = AK / DA( K, K-1 ) = -AKKP1 / D** Compute columns K-1 and K of the inverse.*IF( K.LT.N ) THENCALL DCOPY( N-K, A( K+1, K ), 1, WORK, 1 )CALL DSYMV( UPLO, N-K, -ONE, A( K+1, K+1 ), LDA, WORK, 1,$ ZERO, A( K+1, K ), 1 )A( K, K ) = A( K, K ) - DDOT( N-K, WORK, 1, A( K+1, K ),$ 1 )A( K, K-1 ) = A( K, K-1 ) -$ DDOT( N-K, A( K+1, K ), 1, A( K+1, K-1 ),$ 1 )CALL DCOPY( N-K, A( K+1, K-1 ), 1, WORK, 1 )CALL DSYMV( UPLO, N-K, -ONE, A( K+1, K+1 ), LDA, WORK, 1,$ ZERO, A( K+1, K-1 ), 1 )A( K-1, K-1 ) = A( K-1, K-1 ) -$ DDOT( N-K, WORK, 1, A( K+1, K-1 ), 1 )END IFKSTEP = 2END IF*KP = ABS( IPIV( K ) )IF( KP.NE.K ) THEN** Interchange rows and columns K and KP in the trailing* submatrix A(k-1:n,k-1:n)*IF( KP.LT.N )$ CALL DSWAP( N-KP, A( KP+1, K ), 1, A( KP+1, KP ), 1 )CALL DSWAP( KP-K-1, A( K+1, K ), 1, A( KP, K+1 ), LDA )TEMP = A( K, K )A( K, K ) = A( KP, KP )A( KP, KP ) = TEMPIF( KSTEP.EQ.2 ) THENTEMP = A( K, K-1 )A( K, K-1 ) = A( KP, K-1 )A( KP, K-1 ) = TEMPEND IFEND IF*K = K - KSTEPGO TO 5060 CONTINUEEND IF*RETURN** End of DSYTRI*END*> \brief \b DSYTRI2** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRI2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytri2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytri2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytri2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRI2( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRI2 computes the inverse of a DOUBLE PRECISION symmetric indefinite matrix*> A using the factorization A = U*D*U**T or A = L*D*L**T computed by*> DSYTRF. DSYTRI2 sets the LEADING DIMENSION of the workspace*> before calling DSYTRI2X that actually computes the inverse.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the NB diagonal matrix D and the multipliers*> used to obtain the factor U or L as computed by DSYTRF.*>*> On exit, if INFO = 0, the (symmetric) inverse of the original*> matrix. If UPLO = 'U', the upper triangular part of the*> inverse is formed and the part of A below the diagonal is not*> referenced; if UPLO = 'L' the lower triangular part of the*> inverse is formed and the part of A above the diagonal is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the NB structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N+NB+1)*(NB+3)*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> WORK is size >= (N+NB+1)*(NB+3)*> If LDWORK = -1, then a workspace query is assumed; the routine*> calculates:*> - the optimal size of the WORK array, returns*> this value as the first entry of the WORK array,*> - and no error message related to LDWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its*> inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYTRI2( UPLO, N, A, LDA, IPIV, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LWORK, N* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Local Scalars ..LOGICAL UPPER, LQUERYINTEGER MINSIZE, NBMAX* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DSYTRI, DSYTRI2X, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )LQUERY = ( LWORK.EQ.-1 )* Get blocksizeNBMAX = ILAENV( 1, 'DSYTRF', UPLO, N, -1, -1, -1 )IF ( NBMAX .GE. N ) THENMINSIZE = NELSEMINSIZE = (N+NBMAX+1)*(NBMAX+3)END IF*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF (LWORK .LT. MINSIZE .AND. .NOT.LQUERY ) THENINFO = -7END IF** Quick return if possible**IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRI2', -INFO )RETURNELSE IF( LQUERY ) THENWORK(1)=MINSIZERETURNEND IFIF( N.EQ.0 )$ RETURNIF( NBMAX .GE. N ) THENCALL DSYTRI( UPLO, N, A, LDA, IPIV, WORK, INFO )ELSECALL DSYTRI2X( UPLO, N, A, LDA, IPIV, WORK, NBMAX, INFO )END IFRETURN** End of DSYTRI2*END*> \brief \b DSYTRI2X** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRI2X + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytri2x.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytri2x.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytri2x.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRI2X( UPLO, N, A, LDA, IPIV, WORK, NB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, N, NB* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), WORK( N+NB+1,* )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRI2X computes the inverse of a real symmetric indefinite matrix*> A using the factorization A = U*D*U**T or A = L*D*L**T computed by*> DSYTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the NNB diagonal matrix D and the multipliers*> used to obtain the factor U or L as computed by DSYTRF.*>*> On exit, if INFO = 0, the (symmetric) inverse of the original*> matrix. If UPLO = 'U', the upper triangular part of the*> inverse is formed and the part of A below the diagonal is not*> referenced; if UPLO = 'L' the lower triangular part of the*> inverse is formed and the part of A above the diagonal is*> not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the NNB structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N+NB+1,NB+3)*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> Block size*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its*> inverse could not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYTRI2X( UPLO, N, A, LDA, IPIV, WORK, NB, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, N, NB* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), WORK( N+NB+1,* )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IINFO, IP, K, CUT, NNBINTEGER COUNTINTEGER J, U11, INVDDOUBLE PRECISION AK, AKKP1, AKP1, D, TDOUBLE PRECISION U01_I_J, U01_IP1_JDOUBLE PRECISION U11_I_J, U11_IP1_J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSYCONV, XERBLA, DTRTRIEXTERNAL DGEMM, DTRMM, DSYSWAPR* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IF** Quick return if possible**IF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRI2X', -INFO )RETURNEND IFIF( N.EQ.0 )$ RETURN** Convert A* Workspace got Non-diag elements of D*CALL DSYCONV( UPLO, 'C', N, A, LDA, IPIV, WORK, IINFO )** Check that the diagonal matrix D is nonsingular.*IF( UPPER ) THEN** Upper triangular storage: examine D from bottom to top*DO INFO = N, 1, -1IF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.ZERO )$ RETURNEND DOELSE** Lower triangular storage: examine D from top to bottom.*DO INFO = 1, NIF( IPIV( INFO ).GT.0 .AND. A( INFO, INFO ).EQ.ZERO )$ RETURNEND DOEND IFINFO = 0** Splitting Workspace* U01 is a block (N,NB+1)* The first element of U01 is in WORK(1,1)* U11 is a block (NB+1,NB+1)* The first element of U11 is in WORK(N+1,1)U11 = N* INVD is a block (N,2)* The first element of INVD is in WORK(1,INVD)INVD = NB+2IF( UPPER ) THEN** invA = P * inv(U**T)*inv(D)*inv(U)*P**T.*CALL DTRTRI( UPLO, 'U', N, A, LDA, INFO )** inv(D) and inv(D)*inv(U)*K=1DO WHILE ( K .LE. N )IF( IPIV( K ).GT.0 ) THEN* 1 x 1 diagonal NNBWORK(K,INVD) = ONE / A( K, K )WORK(K,INVD+1) = 0K=K+1ELSE* 2 x 2 diagonal NNBT = WORK(K+1,1)AK = A( K, K ) / TAKP1 = A( K+1, K+1 ) / TAKKP1 = WORK(K+1,1) / TD = T*( AK*AKP1-ONE )WORK(K,INVD) = AKP1 / DWORK(K+1,INVD+1) = AK / DWORK(K,INVD+1) = -AKKP1 / DWORK(K+1,INVD) = -AKKP1 / DK=K+2END IFEND DO** inv(U**T) = (inv(U))**T** inv(U**T)*inv(D)*inv(U)*CUT=NDO WHILE (CUT .GT. 0)NNB=NBIF (CUT .LE. NNB) THENNNB=CUTELSECOUNT = 0* count negative elements,DO I=CUT+1-NNB,CUTIF (IPIV(I) .LT. 0) COUNT=COUNT+1END DO* need a even number for a clear cutIF (MOD(COUNT,2) .EQ. 1) NNB=NNB+1END IFCUT=CUT-NNB** U01 Block*DO I=1,CUTDO J=1,NNBWORK(I,J)=A(I,CUT+J)END DOEND DO** U11 Block*DO I=1,NNBWORK(U11+I,I)=ONEDO J=1,I-1WORK(U11+I,J)=ZEROEND DODO J=I+1,NNBWORK(U11+I,J)=A(CUT+I,CUT+J)END DOEND DO** invD*U01*I=1DO WHILE (I .LE. CUT)IF (IPIV(I) > 0) THENDO J=1,NNBWORK(I,J)=WORK(I,INVD)*WORK(I,J)END DOI=I+1ELSEDO J=1,NNBU01_I_J = WORK(I,J)U01_IP1_J = WORK(I+1,J)WORK(I,J)=WORK(I,INVD)*U01_I_J+$ WORK(I,INVD+1)*U01_IP1_JWORK(I+1,J)=WORK(I+1,INVD)*U01_I_J+$ WORK(I+1,INVD+1)*U01_IP1_JEND DOI=I+2END IFEND DO** invD1*U11*I=1DO WHILE (I .LE. NNB)IF (IPIV(CUT+I) > 0) THENDO J=I,NNBWORK(U11+I,J)=WORK(CUT+I,INVD)*WORK(U11+I,J)END DOI=I+1ELSEDO J=I,NNBU11_I_J = WORK(U11+I,J)U11_IP1_J = WORK(U11+I+1,J)WORK(U11+I,J)=WORK(CUT+I,INVD)*WORK(U11+I,J) +$ WORK(CUT+I,INVD+1)*WORK(U11+I+1,J)WORK(U11+I+1,J)=WORK(CUT+I+1,INVD)*U11_I_J+$ WORK(CUT+I+1,INVD+1)*U11_IP1_JEND DOI=I+2END IFEND DO** U11**T*invD1*U11->U11*CALL DTRMM('L','U','T','U',NNB, NNB,$ ONE,A(CUT+1,CUT+1),LDA,WORK(U11+1,1),N+NB+1)*DO I=1,NNBDO J=I,NNBA(CUT+I,CUT+J)=WORK(U11+I,J)END DOEND DO** U01**T*invD*U01->A(CUT+I,CUT+J)*CALL DGEMM('T','N',NNB,NNB,CUT,ONE,A(1,CUT+1),LDA,$ WORK,N+NB+1, ZERO, WORK(U11+1,1), N+NB+1)** U11 = U11**T*invD1*U11 + U01**T*invD*U01*DO I=1,NNBDO J=I,NNBA(CUT+I,CUT+J)=A(CUT+I,CUT+J)+WORK(U11+I,J)END DOEND DO** U01 = U00**T*invD0*U01*CALL DTRMM('L',UPLO,'T','U',CUT, NNB,$ ONE,A,LDA,WORK,N+NB+1)** Update U01*DO I=1,CUTDO J=1,NNBA(I,CUT+J)=WORK(I,J)END DOEND DO** Next Block*END DO** Apply PERMUTATIONS P and P**T: P * inv(U**T)*inv(D)*inv(U) *P**T*I=1DO WHILE ( I .LE. N )IF( IPIV(I) .GT. 0 ) THENIP=IPIV(I)IF (I .LT. IP) CALL DSYSWAPR( UPLO, N, A, LDA, I ,IP )IF (I .GT. IP) CALL DSYSWAPR( UPLO, N, A, LDA, IP ,I )ELSEIP=-IPIV(I)I=I+1IF ( (I-1) .LT. IP)$ CALL DSYSWAPR( UPLO, N, A, LDA, I-1 ,IP )IF ( (I-1) .GT. IP)$ CALL DSYSWAPR( UPLO, N, A, LDA, IP ,I-1 )ENDIFI=I+1END DOELSE** LOWER...** invA = P * inv(U**T)*inv(D)*inv(U)*P**T.*CALL DTRTRI( UPLO, 'U', N, A, LDA, INFO )** inv(D) and inv(D)*inv(U)*K=NDO WHILE ( K .GE. 1 )IF( IPIV( K ).GT.0 ) THEN* 1 x 1 diagonal NNBWORK(K,INVD) = ONE / A( K, K )WORK(K,INVD+1) = 0K=K-1ELSE* 2 x 2 diagonal NNBT = WORK(K-1,1)AK = A( K-1, K-1 ) / TAKP1 = A( K, K ) / TAKKP1 = WORK(K-1,1) / TD = T*( AK*AKP1-ONE )WORK(K-1,INVD) = AKP1 / DWORK(K,INVD) = AK / DWORK(K,INVD+1) = -AKKP1 / DWORK(K-1,INVD+1) = -AKKP1 / DK=K-2END IFEND DO** inv(U**T) = (inv(U))**T** inv(U**T)*inv(D)*inv(U)*CUT=0DO WHILE (CUT .LT. N)NNB=NBIF (CUT + NNB .GT. N) THENNNB=N-CUTELSECOUNT = 0* count negative elements,DO I=CUT+1,CUT+NNBIF (IPIV(I) .LT. 0) COUNT=COUNT+1END DO* need a even number for a clear cutIF (MOD(COUNT,2) .EQ. 1) NNB=NNB+1END IF* L21 BlockDO I=1,N-CUT-NNBDO J=1,NNBWORK(I,J)=A(CUT+NNB+I,CUT+J)END DOEND DO* L11 BlockDO I=1,NNBWORK(U11+I,I)=ONEDO J=I+1,NNBWORK(U11+I,J)=ZEROEND DODO J=1,I-1WORK(U11+I,J)=A(CUT+I,CUT+J)END DOEND DO** invD*L21*I=N-CUT-NNBDO WHILE (I .GE. 1)IF (IPIV(CUT+NNB+I) > 0) THENDO J=1,NNBWORK(I,J)=WORK(CUT+NNB+I,INVD)*WORK(I,J)END DOI=I-1ELSEDO J=1,NNBU01_I_J = WORK(I,J)U01_IP1_J = WORK(I-1,J)WORK(I,J)=WORK(CUT+NNB+I,INVD)*U01_I_J+$ WORK(CUT+NNB+I,INVD+1)*U01_IP1_JWORK(I-1,J)=WORK(CUT+NNB+I-1,INVD+1)*U01_I_J+$ WORK(CUT+NNB+I-1,INVD)*U01_IP1_JEND DOI=I-2END IFEND DO** invD1*L11*I=NNBDO WHILE (I .GE. 1)IF (IPIV(CUT+I) > 0) THENDO J=1,NNBWORK(U11+I,J)=WORK(CUT+I,INVD)*WORK(U11+I,J)END DOI=I-1ELSEDO J=1,NNBU11_I_J = WORK(U11+I,J)U11_IP1_J = WORK(U11+I-1,J)WORK(U11+I,J)=WORK(CUT+I,INVD)*WORK(U11+I,J) +$ WORK(CUT+I,INVD+1)*U11_IP1_JWORK(U11+I-1,J)=WORK(CUT+I-1,INVD+1)*U11_I_J+$ WORK(CUT+I-1,INVD)*U11_IP1_JEND DOI=I-2END IFEND DO** L11**T*invD1*L11->L11*CALL DTRMM('L',UPLO,'T','U',NNB, NNB,$ ONE,A(CUT+1,CUT+1),LDA,WORK(U11+1,1),N+NB+1)*DO I=1,NNBDO J=1,IA(CUT+I,CUT+J)=WORK(U11+I,J)END DOEND DO*IF ( (CUT+NNB) .LT. N ) THEN** L21**T*invD2*L21->A(CUT+I,CUT+J)*CALL DGEMM('T','N',NNB,NNB,N-NNB-CUT,ONE,A(CUT+NNB+1,CUT+1)$ ,LDA,WORK,N+NB+1, ZERO, WORK(U11+1,1), N+NB+1)** L11 = L11**T*invD1*L11 + U01**T*invD*U01*DO I=1,NNBDO J=1,IA(CUT+I,CUT+J)=A(CUT+I,CUT+J)+WORK(U11+I,J)END DOEND DO** L01 = L22**T*invD2*L21*CALL DTRMM('L',UPLO,'T','U', N-NNB-CUT, NNB,$ ONE,A(CUT+NNB+1,CUT+NNB+1),LDA,WORK,N+NB+1)** Update L21*DO I=1,N-CUT-NNBDO J=1,NNBA(CUT+NNB+I,CUT+J)=WORK(I,J)END DOEND DOELSE** L11 = L11**T*invD1*L11*DO I=1,NNBDO J=1,IA(CUT+I,CUT+J)=WORK(U11+I,J)END DOEND DOEND IF** Next Block*CUT=CUT+NNBEND DO** Apply PERMUTATIONS P and P**T: P * inv(U**T)*inv(D)*inv(U) *P**T*I=NDO WHILE ( I .GE. 1 )IF( IPIV(I) .GT. 0 ) THENIP=IPIV(I)IF (I .LT. IP) CALL DSYSWAPR( UPLO, N, A, LDA, I ,IP )IF (I .GT. IP) CALL DSYSWAPR( UPLO, N, A, LDA, IP ,I )ELSEIP=-IPIV(I)IF ( I .LT. IP) CALL DSYSWAPR( UPLO, N, A, LDA, I ,IP )IF ( I .GT. IP) CALL DSYSWAPR( UPLO, N, A, LDA, IP, I )I=I-1ENDIFI=I-1END DOEND IF*RETURN** End of DSYTRI2X*END*> \brief \b DSYTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRS( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRS solves a system of linear equations A*X = B with a real*> symmetric matrix A using the factorization A = U*D*U**T or*> A = L*D*L**T computed by DSYTRF.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The block diagonal matrix D and the multipliers used to*> obtain the factor U or L as computed by DSYTRF.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYTRS( UPLO, N, NRHS, A, LDA, IPIV, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER J, K, KPDOUBLE PRECISION AK, AKM1, AKM1K, BK, BKM1, DENOM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMV, DGER, DSCAL, DSWAP, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN*IF( UPPER ) THEN** Solve A*X = B, where A = U*D*U**T.** First solve U*D*X = B, overwriting B with X.** K is the main loop index, decreasing from N to 1 in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = N10 CONTINUE** If K < 1, exit from loop.*IF( K.LT.1 )$ GO TO 30*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(U(K)), where U(K) is the transformation* stored in column K of A.*CALL DGER( K-1, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB,$ B( 1, 1 ), LDB )** Multiply by the inverse of the diagonal block.*CALL DSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB )K = K - 1ELSE** 2 x 2 diagonal block** Interchange rows K-1 and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K-1 )$ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(U(K)), where U(K) is the transformation* stored in columns K-1 and K of A.*CALL DGER( K-2, NRHS, -ONE, A( 1, K ), 1, B( K, 1 ), LDB,$ B( 1, 1 ), LDB )CALL DGER( K-2, NRHS, -ONE, A( 1, K-1 ), 1, B( K-1, 1 ),$ LDB, B( 1, 1 ), LDB )** Multiply by the inverse of the diagonal block.*AKM1K = A( K-1, K )AKM1 = A( K-1, K-1 ) / AKM1KAK = A( K, K ) / AKM1KDENOM = AKM1*AK - ONEDO 20 J = 1, NRHSBKM1 = B( K-1, J ) / AKM1KBK = B( K, J ) / AKM1KB( K-1, J ) = ( AK*BKM1-BK ) / DENOMB( K, J ) = ( AKM1*BK-BKM1 ) / DENOM20 CONTINUEK = K - 2END IF*GO TO 1030 CONTINUE** Next solve U**T *X = B, overwriting B with X.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = 140 CONTINUE** If K > N, exit from loop.*IF( K.GT.N )$ GO TO 50*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Multiply by inv(U**T(K)), where U(K) is the transformation* stored in column K of A.*CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, LDB, A( 1, K ),$ 1, ONE, B( K, 1 ), LDB )** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K = K + 1ELSE** 2 x 2 diagonal block** Multiply by inv(U**T(K+1)), where U(K+1) is the transformation* stored in columns K and K+1 of A.*CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, LDB, A( 1, K ),$ 1, ONE, B( K, 1 ), LDB )CALL DGEMV( 'Transpose', K-1, NRHS, -ONE, B, LDB,$ A( 1, K+1 ), 1, ONE, B( K+1, 1 ), LDB )** Interchange rows K and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K = K + 2END IF*GO TO 4050 CONTINUE*ELSE** Solve A*X = B, where A = L*D*L**T.** First solve L*D*X = B, overwriting B with X.** K is the main loop index, increasing from 1 to N in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = 160 CONTINUE** If K > N, exit from loop.*IF( K.GT.N )$ GO TO 80*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(L(K)), where L(K) is the transformation* stored in column K of A.*IF( K.LT.N )$ CALL DGER( N-K, NRHS, -ONE, A( K+1, K ), 1, B( K, 1 ),$ LDB, B( K+1, 1 ), LDB )** Multiply by the inverse of the diagonal block.*CALL DSCAL( NRHS, ONE / A( K, K ), B( K, 1 ), LDB )K = K + 1ELSE** 2 x 2 diagonal block** Interchange rows K+1 and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K+1 )$ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )** Multiply by inv(L(K)), where L(K) is the transformation* stored in columns K and K+1 of A.*IF( K.LT.N-1 ) THENCALL DGER( N-K-1, NRHS, -ONE, A( K+2, K ), 1, B( K, 1 ),$ LDB, B( K+2, 1 ), LDB )CALL DGER( N-K-1, NRHS, -ONE, A( K+2, K+1 ), 1,$ B( K+1, 1 ), LDB, B( K+2, 1 ), LDB )END IF** Multiply by the inverse of the diagonal block.*AKM1K = A( K+1, K )AKM1 = A( K, K ) / AKM1KAK = A( K+1, K+1 ) / AKM1KDENOM = AKM1*AK - ONEDO 70 J = 1, NRHSBKM1 = B( K, J ) / AKM1KBK = B( K+1, J ) / AKM1KB( K, J ) = ( AK*BKM1-BK ) / DENOMB( K+1, J ) = ( AKM1*BK-BKM1 ) / DENOM70 CONTINUEK = K + 2END IF*GO TO 6080 CONTINUE** Next solve L**T *X = B, overwriting B with X.** K is the main loop index, decreasing from N to 1 in steps of* 1 or 2, depending on the size of the diagonal blocks.*K = N90 CONTINUE** If K < 1, exit from loop.*IF( K.LT.1 )$ GO TO 100*IF( IPIV( K ).GT.0 ) THEN** 1 x 1 diagonal block** Multiply by inv(L**T(K)), where L(K) is the transformation* stored in column K of A.*IF( K.LT.N )$ CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ),$ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB )** Interchange rows K and IPIV(K).*KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K = K - 1ELSE** 2 x 2 diagonal block** Multiply by inv(L**T(K-1)), where L(K-1) is the transformation* stored in columns K-1 and K of A.*IF( K.LT.N ) THENCALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ),$ LDB, A( K+1, K ), 1, ONE, B( K, 1 ), LDB )CALL DGEMV( 'Transpose', N-K, NRHS, -ONE, B( K+1, 1 ),$ LDB, A( K+1, K-1 ), 1, ONE, B( K-1, 1 ),$ LDB )END IF** Interchange rows K and -IPIV(K).*KP = -IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K = K - 2END IF*GO TO 90100 CONTINUEEND IF*RETURN** End of DSYTRS*END*> \brief \b DSYTRS2** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DSYTRS2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrs2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrs2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrs2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,* WORK, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* INTEGER IPIV( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DSYTRS2 solves a system of linear equations A*X = B with a real*> symmetric matrix A using the factorization A = U*D*U**T or*> A = L*D*L**T computed by DSYTRF and converted by DSYCONV.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the details of the factorization are stored*> as an upper or lower triangular matrix.*> = 'U': Upper triangular, form is A = U*D*U**T;*> = 'L': Lower triangular, form is A = L*D*L**T.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The block diagonal matrix D and the multipliers used to*> obtain the factor U or L as computed by DSYTRF.*> Note that A is input / output. This might be counter-intuitive,*> and one may think that A is input only. A is input / output. This*> is because, at the start of the subroutine, we permute A in a*> "better" form and then we permute A back to its original form at*> the end.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] IPIV*> \verbatim*> IPIV is INTEGER array, dimension (N)*> Details of the interchanges and the block structure of D*> as determined by DSYTRF.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DSYTRS2( UPLO, N, NRHS, A, LDA, IPIV, B, LDB,$ WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..INTEGER IPIV( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL UPPERINTEGER I, IINFO, J, K, KPDOUBLE PRECISION AK, AKM1, AKM1K, BK, BKM1, DENOM* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DSYCONV, DSWAP, DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..*INFO = 0UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( NRHS.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DSYTRS2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 )$ RETURN** Convert A*CALL DSYCONV( UPLO, 'C', N, A, LDA, IPIV, WORK, IINFO )*IF( UPPER ) THEN** Solve A*X = B, where A = U*D*U**T.** P**T * BK=NDO WHILE ( K .GE. 1 )IF( IPIV( K ).GT.0 ) THEN* 1 x 1 diagonal block* Interchange rows K and IPIV(K).KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K=K-1ELSE* 2 x 2 diagonal block* Interchange rows K-1 and -IPIV(K).KP = -IPIV( K )IF( KP.EQ.-IPIV( K-1 ) )$ CALL DSWAP( NRHS, B( K-1, 1 ), LDB, B( KP, 1 ), LDB )K=K-2END IFEND DO** Compute (U \P**T * B) -> B [ (U \P**T * B) ]*CALL DTRSM('L','U','N','U',N,NRHS,ONE,A,LDA,B,LDB)** Compute D \ B -> B [ D \ (U \P**T * B) ]*I=NDO WHILE ( I .GE. 1 )IF( IPIV(I) .GT. 0 ) THENCALL DSCAL( NRHS, ONE / A( I, I ), B( I, 1 ), LDB )ELSEIF ( I .GT. 1) THENIF ( IPIV(I-1) .EQ. IPIV(I) ) THENAKM1K = WORK(I)AKM1 = A( I-1, I-1 ) / AKM1KAK = A( I, I ) / AKM1KDENOM = AKM1*AK - ONEDO 15 J = 1, NRHSBKM1 = B( I-1, J ) / AKM1KBK = B( I, J ) / AKM1KB( I-1, J ) = ( AK*BKM1-BK ) / DENOMB( I, J ) = ( AKM1*BK-BKM1 ) / DENOM15 CONTINUEI = I - 1ENDIFENDIFI = I - 1END DO** Compute (U**T \ B) -> B [ U**T \ (D \ (U \P**T * B) ) ]*CALL DTRSM('L','U','T','U',N,NRHS,ONE,A,LDA,B,LDB)** P * B [ P * (U**T \ (D \ (U \P**T * B) )) ]*K=1DO WHILE ( K .LE. N )IF( IPIV( K ).GT.0 ) THEN* 1 x 1 diagonal block* Interchange rows K and IPIV(K).KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K=K+1ELSE* 2 x 2 diagonal block* Interchange rows K-1 and -IPIV(K).KP = -IPIV( K )IF( K .LT. N .AND. KP.EQ.-IPIV( K+1 ) )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K=K+2ENDIFEND DO*ELSE** Solve A*X = B, where A = L*D*L**T.** P**T * BK=1DO WHILE ( K .LE. N )IF( IPIV( K ).GT.0 ) THEN* 1 x 1 diagonal block* Interchange rows K and IPIV(K).KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K=K+1ELSE* 2 x 2 diagonal block* Interchange rows K and -IPIV(K+1).KP = -IPIV( K+1 )IF( KP.EQ.-IPIV( K ) )$ CALL DSWAP( NRHS, B( K+1, 1 ), LDB, B( KP, 1 ), LDB )K=K+2ENDIFEND DO** Compute (L \P**T * B) -> B [ (L \P**T * B) ]*CALL DTRSM('L','L','N','U',N,NRHS,ONE,A,LDA,B,LDB)** Compute D \ B -> B [ D \ (L \P**T * B) ]*I=1DO WHILE ( I .LE. N )IF( IPIV(I) .GT. 0 ) THENCALL DSCAL( NRHS, ONE / A( I, I ), B( I, 1 ), LDB )ELSEAKM1K = WORK(I)AKM1 = A( I, I ) / AKM1KAK = A( I+1, I+1 ) / AKM1KDENOM = AKM1*AK - ONEDO 25 J = 1, NRHSBKM1 = B( I, J ) / AKM1KBK = B( I+1, J ) / AKM1KB( I, J ) = ( AK*BKM1-BK ) / DENOMB( I+1, J ) = ( AKM1*BK-BKM1 ) / DENOM25 CONTINUEI = I + 1ENDIFI = I + 1END DO** Compute (L**T \ B) -> B [ L**T \ (D \ (L \P**T * B) ) ]*CALL DTRSM('L','L','T','U',N,NRHS,ONE,A,LDA,B,LDB)** P * B [ P * (L**T \ (D \ (L \P**T * B) )) ]*K=NDO WHILE ( K .GE. 1 )IF( IPIV( K ).GT.0 ) THEN* 1 x 1 diagonal block* Interchange rows K and IPIV(K).KP = IPIV( K )IF( KP.NE.K )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K=K-1ELSE* 2 x 2 diagonal block* Interchange rows K-1 and -IPIV(K).KP = -IPIV( K )IF( K.GT.1 .AND. KP.EQ.-IPIV( K-1 ) )$ CALL DSWAP( NRHS, B( K, 1 ), LDB, B( KP, 1 ), LDB )K=K-2ENDIFEND DO*END IF** Revert A*CALL DSYCONV( UPLO, 'R', N, A, LDA, IPIV, WORK, IINFO )*RETURN** End of DSYTRS2*END*> \brief \b DTBCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTBCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtbcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtbcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtbcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTBCON( NORM, UPLO, DIAG, N, KD, AB, LDAB, RCOND, WORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, NORM, UPLO* INTEGER INFO, KD, LDAB, N* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTBCON estimates the reciprocal of the condition number of a*> triangular band matrix A, in either the 1-norm or the infinity-norm.*>*> The norm of A is computed and an estimate is obtained for*> norm(inv(A)), then the reciprocal of the condition number is*> computed as*> RCOND = 1 / ( norm(A) * norm(inv(A)) ).*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies whether the 1-norm condition number or the*> infinity-norm condition number is required:*> = '1' or 'O': 1-norm;*> = 'I': Infinity-norm.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals or subdiagonals of the*> triangular band matrix A. KD >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangular band matrix A, stored in the*> first kd+1 rows of the array. The j-th column of A is stored*> in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> If DIAG = 'U', the diagonal elements of A are not referenced*> and are assumed to be 1.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(norm(A) * norm(inv(A))).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTBCON( NORM, UPLO, DIAG, N, KD, AB, LDAB, RCOND, WORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORM, UPLOINTEGER INFO, KD, LDAB, NDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, ONENRM, UPPERCHARACTER NORMININTEGER IX, KASE, KASE1DOUBLE PRECISION AINVNM, ANORM, SCALE, SMLNUM, XNORM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLANTBEXTERNAL LSAME, IDAMAX, DLAMCH, DLANTB* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATBS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )NOUNIT = LSAME( DIAG, 'N' )*IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( KD.LT.0 ) THENINFO = -5ELSE IF( LDAB.LT.KD+1 ) THENINFO = -7END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTBCON', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENRCOND = ONERETURNEND IF*RCOND = ZEROSMLNUM = DLAMCH( 'Safe minimum' )*DBLE( MAX( 1, N ) )** Compute the norm of the triangular matrix A.*ANORM = DLANTB( NORM, UPLO, DIAG, N, KD, AB, LDAB, WORK )** Continue only if ANORM > 0.*IF( ANORM.GT.ZERO ) THEN** Estimate the norm of the inverse of A.*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 010 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(A).*CALL DLATBS( UPLO, 'No transpose', DIAG, NORMIN, N, KD,$ AB, LDAB, WORK, SCALE, WORK( 2*N+1 ), INFO )ELSE** Multiply by inv(A**T).*CALL DLATBS( UPLO, 'Transpose', DIAG, NORMIN, N, KD, AB,$ LDAB, WORK, SCALE, WORK( 2*N+1 ), INFO )END IFNORMIN = 'Y'** Multiply by 1/SCALE if doing so will not cause overflow.*IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )XNORM = ABS( WORK( IX ) )IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / ANORM ) / AINVNMEND IF*20 CONTINUERETURN** End of DTBCON*END*> \brief \b DTBRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTBRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtbrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtbrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtbrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTBRFS( UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B,* LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, TRANS, UPLO* INTEGER INFO, KD, LDAB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AB( LDAB, * ), B( LDB, * ), BERR( * ),* $ FERR( * ), WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTBRFS provides error bounds and backward error estimates for the*> solution to a system of linear equations with a triangular band*> coefficient matrix.*>*> The solution matrix X must be computed by DTBTRS or some other*> means before entering this routine. DTBRFS does not do iterative*> refinement because doing so cannot improve the backward error.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals or subdiagonals of the*> triangular band matrix A. KD >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangular band matrix A, stored in the*> first kd+1 rows of the array. The j-th column of A is stored*> in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> If DIAG = 'U', the diagonal elements of A are not referenced*> and are assumed to be 1.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> The solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTBRFS( UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B,$ LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, TRANS, UPLOINTEGER INFO, KD, LDAB, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AB( LDAB, * ), B( LDB, * ), BERR( * ),$ FERR( * ), WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERCHARACTER TRANSTINTEGER I, J, K, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DTBMV, DTBSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( KD.LT.0 ) THENINFO = -5ELSE IF( NRHS.LT.0 ) THENINFO = -6ELSE IF( LDAB.LT.KD+1 ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -12END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTBRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = KD + 2EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 250 J = 1, NRHS** Compute residual R = B - op(A) * X,* where op(A) = A or A**T, depending on TRANS.*CALL DCOPY( N, X( 1, J ), 1, WORK( N+1 ), 1 )CALL DTBMV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, WORK( N+1 ),$ 1 )CALL DAXPY( N, -ONE, B( 1, J ), 1, WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 20 I = 1, NWORK( I ) = ABS( B( I, J ) )20 CONTINUE*IF( NOTRAN ) THEN** Compute abs(A)*abs(X) + abs(B).*IF( UPPER ) THENIF( NOUNIT ) THENDO 40 K = 1, NXK = ABS( X( K, J ) )DO 30 I = MAX( 1, K-KD ), KWORK( I ) = WORK( I ) +$ ABS( AB( KD+1+I-K, K ) )*XK30 CONTINUE40 CONTINUEELSEDO 60 K = 1, NXK = ABS( X( K, J ) )DO 50 I = MAX( 1, K-KD ), K - 1WORK( I ) = WORK( I ) +$ ABS( AB( KD+1+I-K, K ) )*XK50 CONTINUEWORK( K ) = WORK( K ) + XK60 CONTINUEEND IFELSEIF( NOUNIT ) THENDO 80 K = 1, NXK = ABS( X( K, J ) )DO 70 I = K, MIN( N, K+KD )WORK( I ) = WORK( I ) + ABS( AB( 1+I-K, K ) )*XK70 CONTINUE80 CONTINUEELSEDO 100 K = 1, NXK = ABS( X( K, J ) )DO 90 I = K + 1, MIN( N, K+KD )WORK( I ) = WORK( I ) + ABS( AB( 1+I-K, K ) )*XK90 CONTINUEWORK( K ) = WORK( K ) + XK100 CONTINUEEND IFEND IFELSE** Compute abs(A**T)*abs(X) + abs(B).*IF( UPPER ) THENIF( NOUNIT ) THENDO 120 K = 1, NS = ZERODO 110 I = MAX( 1, K-KD ), KS = S + ABS( AB( KD+1+I-K, K ) )*$ ABS( X( I, J ) )110 CONTINUEWORK( K ) = WORK( K ) + S120 CONTINUEELSEDO 140 K = 1, NS = ABS( X( K, J ) )DO 130 I = MAX( 1, K-KD ), K - 1S = S + ABS( AB( KD+1+I-K, K ) )*$ ABS( X( I, J ) )130 CONTINUEWORK( K ) = WORK( K ) + S140 CONTINUEEND IFELSEIF( NOUNIT ) THENDO 160 K = 1, NS = ZERODO 150 I = K, MIN( N, K+KD )S = S + ABS( AB( 1+I-K, K ) )*ABS( X( I, J ) )150 CONTINUEWORK( K ) = WORK( K ) + S160 CONTINUEELSEDO 180 K = 1, NS = ABS( X( K, J ) )DO 170 I = K + 1, MIN( N, K+KD )S = S + ABS( AB( 1+I-K, K ) )*ABS( X( I, J ) )170 CONTINUEWORK( K ) = WORK( K ) + S180 CONTINUEEND IFEND IFEND IFS = ZERODO 190 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF190 CONTINUEBERR( J ) = S** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 200 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF200 CONTINUE*KASE = 0210 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DTBSV( UPLO, TRANST, DIAG, N, KD, AB, LDAB,$ WORK( N+1 ), 1 )DO 220 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )220 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 230 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )230 CONTINUECALL DTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB,$ WORK( N+1 ), 1 )END IFGO TO 210END IF** Normalize error.*LSTRES = ZERODO 240 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )240 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*250 CONTINUE*RETURN** End of DTBRFS*END*> \brief \b DTBTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTBTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtbtrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtbtrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtbtrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTBTRS( UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B,* LDB, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, TRANS, UPLO* INTEGER INFO, KD, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTBTRS solves a triangular system of the form*>*> A * X = B or A**T * X = B,*>*> where A is a triangular band matrix of order N, and B is an*> N-by NRHS matrix. A check is made to verify that A is nonsingular.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] KD*> \verbatim*> KD is INTEGER*> The number of superdiagonals or subdiagonals of the*> triangular band matrix A. KD >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] AB*> \verbatim*> AB is DOUBLE PRECISION array, dimension (LDAB,N)*> The upper or lower triangular band matrix A, stored in the*> first kd+1 rows of AB. The j-th column of A is stored*> in the j-th column of the array AB as follows:*> if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;*> if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).*> If DIAG = 'U', the diagonal elements of A are not referenced*> and are assumed to be 1.*> \endverbatim*>*> \param[in] LDAB*> \verbatim*> LDAB is INTEGER*> The leading dimension of the array AB. LDAB >= KD+1.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, if INFO = 0, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element of A is zero,*> indicating that the matrix is singular and the*> solutions X have not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTBTRS( UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B,$ LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, TRANS, UPLOINTEGER INFO, KD, LDAB, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION AB( LDAB, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, UPPERINTEGER J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTBSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOUNIT = LSAME( DIAG, 'N' )UPPER = LSAME( UPLO, 'U' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.$ LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( KD.LT.0 ) THENINFO = -5ELSE IF( NRHS.LT.0 ) THENINFO = -6ELSE IF( LDAB.LT.KD+1 ) THENINFO = -8ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTBTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Check for singularity.*IF( NOUNIT ) THENIF( UPPER ) THENDO 10 INFO = 1, NIF( AB( KD+1, INFO ).EQ.ZERO )$ RETURN10 CONTINUEELSEDO 20 INFO = 1, NIF( AB( 1, INFO ).EQ.ZERO )$ RETURN20 CONTINUEEND IFEND IFINFO = 0** Solve A * X = B or A**T * X = B.*DO 30 J = 1, NRHSCALL DTBSV( UPLO, TRANS, DIAG, N, KD, AB, LDAB, B( 1, J ), 1 )30 CONTINUE*RETURN** End of DTBTRS*END*> \brief \b DTFSM solves a matrix equation (one operand is a triangular matrix in RFP format).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTFSM + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtfsm.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtfsm.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtfsm.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTFSM( TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A,* B, LDB )** .. Scalar Arguments ..* CHARACTER TRANSR, DIAG, SIDE, TRANS, UPLO* INTEGER LDB, M, N* DOUBLE PRECISION ALPHA* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: * ), B( 0: LDB-1, 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> Level 3 BLAS like routine for A in RFP Format.*>*> DTFSM solves the matrix equation*>*> op( A )*X = alpha*B or X*op( A ) = alpha*B*>*> where alpha is a scalar, X and B are m by n matrices, A is a unit, or*> non-unit, upper or lower triangular matrix and op( A ) is one of*>*> op( A ) = A or op( A ) = A**T.*>*> A is in Rectangular Full Packed (RFP) Format.*>*> The matrix X is overwritten on B.*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': The Normal Form of RFP A is stored;*> = 'T': The Transpose Form of RFP A is stored.*> \endverbatim*>*> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> On entry, SIDE specifies whether op( A ) appears on the left*> or right of X as follows:*>*> SIDE = 'L' or 'l' op( A )*X = alpha*B.*>*> SIDE = 'R' or 'r' X*op( A ) = alpha*B.*>*> Unchanged on exit.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> On entry, UPLO specifies whether the RFP matrix A came from*> an upper or lower triangular matrix as follows:*> UPLO = 'U' or 'u' RFP A came from an upper triangular matrix*> UPLO = 'L' or 'l' RFP A came from a lower triangular matrix*>*> Unchanged on exit.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> On entry, TRANS specifies the form of op( A ) to be used*> in the matrix multiplication as follows:*>*> TRANS = 'N' or 'n' op( A ) = A.*>*> TRANS = 'T' or 't' op( A ) = A'.*>*> Unchanged on exit.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> On entry, DIAG specifies whether or not RFP A is unit*> triangular as follows:*>*> DIAG = 'U' or 'u' A is assumed to be unit triangular.*>*> DIAG = 'N' or 'n' A is not assumed to be unit*> triangular.*>*> Unchanged on exit.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> On entry, M specifies the number of rows of B. M must be at*> least zero.*> Unchanged on exit.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> On entry, N specifies the number of columns of B. N must be*> at least zero.*> Unchanged on exit.*> \endverbatim*>*> \param[in] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION*> On entry, ALPHA specifies the scalar alpha. When alpha is*> zero then A is not referenced and B need not be set before*> entry.*> Unchanged on exit.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (NT)*> NT = N*(N+1)/2. On entry, the matrix A in RFP Format.*> RFP Format is described by TRANSR, UPLO and N as follows:*> If TRANSR='N' then RFP A is (0:N,0:K-1) when N is even;*> K=N/2. RFP A is (0:N-1,0:K) when N is odd; K=N/2. If*> TRANSR = 'T' then RFP is the transpose of RFP A as*> defined when TRANSR = 'N'. The contents of RFP A are defined*> by UPLO as follows: If UPLO = 'U' the RFP A contains the NT*> elements of upper packed A either in normal or*> transpose Format. If UPLO = 'L' the RFP A contains*> the NT elements of lower packed A either in normal or*> transpose Format. The LDA of RFP A is (N+1)/2 when*> TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is*> even and is N when is odd.*> See the Note below for more details. Unchanged on exit.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> Before entry, the leading m by n part of the array B must*> contain the right-hand side matrix B, and on exit is*> overwritten by the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> On entry, LDB specifies the first dimension of B as declared*> in the calling (sub) program. LDB must be at least*> max( 1, m ).*> Unchanged on exit.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim** =====================================================================SUBROUTINE DTFSM( TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A,$ B, LDB )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, DIAG, SIDE, TRANS, UPLOINTEGER LDB, M, NDOUBLE PRECISION ALPHA* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: * ), B( 0: LDB-1, 0: * )* ..** =====================================================================** ..* .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, LSIDE, MISODD, NISODD, NORMALTRANSR,$ NOTRANSINTEGER M1, M2, N1, N2, K, INFO, I, J* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DGEMM, DTRSM* ..* .. Intrinsic Functions ..INTRINSIC MAX, MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LSIDE = LSAME( SIDE, 'L' )LOWER = LSAME( UPLO, 'L' )NOTRANS = LSAME( TRANS, 'N' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LSIDE .AND. .NOT.LSAME( SIDE, 'R' ) ) THENINFO = -2ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -3ELSE IF( .NOT.NOTRANS .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -4ELSE IF( .NOT.LSAME( DIAG, 'N' ) .AND. .NOT.LSAME( DIAG, 'U' ) )$ THENINFO = -5ELSE IF( M.LT.0 ) THENINFO = -6ELSE IF( N.LT.0 ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, M ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTFSM ', -INFO )RETURNEND IF** Quick return when ( (N.EQ.0).OR.(M.EQ.0) )*IF( ( M.EQ.0 ) .OR. ( N.EQ.0 ) )$ RETURN** Quick return when ALPHA.EQ.(0D+0)*IF( ALPHA.EQ.ZERO ) THENDO 20 J = 0, N - 1DO 10 I = 0, M - 1B( I, J ) = ZERO10 CONTINUE20 CONTINUERETURNEND IF*IF( LSIDE ) THEN** SIDE = 'L'** A is M-by-M.* If M is odd, set NISODD = .TRUE., and M1 and M2.* If M is even, NISODD = .FALSE., and M.*IF( MOD( M, 2 ).EQ.0 ) THENMISODD = .FALSE.K = M / 2ELSEMISODD = .TRUE.IF( LOWER ) THENM2 = M / 2M1 = M - M2ELSEM1 = M / 2M2 = M - M1END IFEND IF**IF( MISODD ) THEN** SIDE = 'L' and N is odd*IF( NORMALTRANSR ) THEN** SIDE = 'L', N is odd, and TRANSR = 'N'*IF( LOWER ) THEN** SIDE ='L', N is odd, TRANSR = 'N', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'L', and* TRANS = 'N'*IF( M.EQ.1 ) THENCALL DTRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,$ A, M, B, LDB )ELSECALL DTRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,$ A( 0 ), M, B, LDB )CALL DGEMM( 'N', 'N', M2, N, M1, -ONE, A( M1 ),$ M, B, LDB, ALPHA, B( M1, 0 ), LDB )CALL DTRSM( 'L', 'U', 'T', DIAG, M2, N, ONE,$ A( M ), M, B( M1, 0 ), LDB )END IF*ELSE** SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'L', and* TRANS = 'T'*IF( M.EQ.1 ) THENCALL DTRSM( 'L', 'L', 'T', DIAG, M1, N, ALPHA,$ A( 0 ), M, B, LDB )ELSECALL DTRSM( 'L', 'U', 'N', DIAG, M2, N, ALPHA,$ A( M ), M, B( M1, 0 ), LDB )CALL DGEMM( 'T', 'N', M1, N, M2, -ONE, A( M1 ),$ M, B( M1, 0 ), LDB, ALPHA, B, LDB )CALL DTRSM( 'L', 'L', 'T', DIAG, M1, N, ONE,$ A( 0 ), M, B, LDB )END IF*END IF*ELSE** SIDE ='L', N is odd, TRANSR = 'N', and UPLO = 'U'*IF( .NOT.NOTRANS ) THEN** SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'U', and* TRANS = 'N'*CALL DTRSM( 'L', 'L', 'N', DIAG, M1, N, ALPHA,$ A( M2 ), M, B, LDB )CALL DGEMM( 'T', 'N', M2, N, M1, -ONE, A( 0 ), M,$ B, LDB, ALPHA, B( M1, 0 ), LDB )CALL DTRSM( 'L', 'U', 'T', DIAG, M2, N, ONE,$ A( M1 ), M, B( M1, 0 ), LDB )*ELSE** SIDE ='L', N is odd, TRANSR = 'N', UPLO = 'U', and* TRANS = 'T'*CALL DTRSM( 'L', 'U', 'N', DIAG, M2, N, ALPHA,$ A( M1 ), M, B( M1, 0 ), LDB )CALL DGEMM( 'N', 'N', M1, N, M2, -ONE, A( 0 ), M,$ B( M1, 0 ), LDB, ALPHA, B, LDB )CALL DTRSM( 'L', 'L', 'T', DIAG, M1, N, ONE,$ A( M2 ), M, B, LDB )*END IF*END IF*ELSE** SIDE = 'L', N is odd, and TRANSR = 'T'*IF( LOWER ) THEN** SIDE ='L', N is odd, TRANSR = 'T', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'L', and* TRANS = 'N'*IF( M.EQ.1 ) THENCALL DTRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,$ A( 0 ), M1, B, LDB )ELSECALL DTRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,$ A( 0 ), M1, B, LDB )CALL DGEMM( 'T', 'N', M2, N, M1, -ONE,$ A( M1*M1 ), M1, B, LDB, ALPHA,$ B( M1, 0 ), LDB )CALL DTRSM( 'L', 'L', 'N', DIAG, M2, N, ONE,$ A( 1 ), M1, B( M1, 0 ), LDB )END IF*ELSE** SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'L', and* TRANS = 'T'*IF( M.EQ.1 ) THENCALL DTRSM( 'L', 'U', 'N', DIAG, M1, N, ALPHA,$ A( 0 ), M1, B, LDB )ELSECALL DTRSM( 'L', 'L', 'T', DIAG, M2, N, ALPHA,$ A( 1 ), M1, B( M1, 0 ), LDB )CALL DGEMM( 'N', 'N', M1, N, M2, -ONE,$ A( M1*M1 ), M1, B( M1, 0 ), LDB,$ ALPHA, B, LDB )CALL DTRSM( 'L', 'U', 'N', DIAG, M1, N, ONE,$ A( 0 ), M1, B, LDB )END IF*END IF*ELSE** SIDE ='L', N is odd, TRANSR = 'T', and UPLO = 'U'*IF( .NOT.NOTRANS ) THEN** SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'U', and* TRANS = 'N'*CALL DTRSM( 'L', 'U', 'T', DIAG, M1, N, ALPHA,$ A( M2*M2 ), M2, B, LDB )CALL DGEMM( 'N', 'N', M2, N, M1, -ONE, A( 0 ), M2,$ B, LDB, ALPHA, B( M1, 0 ), LDB )CALL DTRSM( 'L', 'L', 'N', DIAG, M2, N, ONE,$ A( M1*M2 ), M2, B( M1, 0 ), LDB )*ELSE** SIDE ='L', N is odd, TRANSR = 'T', UPLO = 'U', and* TRANS = 'T'*CALL DTRSM( 'L', 'L', 'T', DIAG, M2, N, ALPHA,$ A( M1*M2 ), M2, B( M1, 0 ), LDB )CALL DGEMM( 'T', 'N', M1, N, M2, -ONE, A( 0 ), M2,$ B( M1, 0 ), LDB, ALPHA, B, LDB )CALL DTRSM( 'L', 'U', 'N', DIAG, M1, N, ONE,$ A( M2*M2 ), M2, B, LDB )*END IF*END IF*END IF*ELSE** SIDE = 'L' and N is even*IF( NORMALTRANSR ) THEN** SIDE = 'L', N is even, and TRANSR = 'N'*IF( LOWER ) THEN** SIDE ='L', N is even, TRANSR = 'N', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='L', N is even, TRANSR = 'N', UPLO = 'L',* and TRANS = 'N'*CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ALPHA,$ A( 1 ), M+1, B, LDB )CALL DGEMM( 'N', 'N', K, N, K, -ONE, A( K+1 ),$ M+1, B, LDB, ALPHA, B( K, 0 ), LDB )CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ONE,$ A( 0 ), M+1, B( K, 0 ), LDB )*ELSE** SIDE ='L', N is even, TRANSR = 'N', UPLO = 'L',* and TRANS = 'T'*CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ALPHA,$ A( 0 ), M+1, B( K, 0 ), LDB )CALL DGEMM( 'T', 'N', K, N, K, -ONE, A( K+1 ),$ M+1, B( K, 0 ), LDB, ALPHA, B, LDB )CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ONE,$ A( 1 ), M+1, B, LDB )*END IF*ELSE** SIDE ='L', N is even, TRANSR = 'N', and UPLO = 'U'*IF( .NOT.NOTRANS ) THEN** SIDE ='L', N is even, TRANSR = 'N', UPLO = 'U',* and TRANS = 'N'*CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ALPHA,$ A( K+1 ), M+1, B, LDB )CALL DGEMM( 'T', 'N', K, N, K, -ONE, A( 0 ), M+1,$ B, LDB, ALPHA, B( K, 0 ), LDB )CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ONE,$ A( K ), M+1, B( K, 0 ), LDB )*ELSE** SIDE ='L', N is even, TRANSR = 'N', UPLO = 'U',* and TRANS = 'T'CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ALPHA,$ A( K ), M+1, B( K, 0 ), LDB )CALL DGEMM( 'N', 'N', K, N, K, -ONE, A( 0 ), M+1,$ B( K, 0 ), LDB, ALPHA, B, LDB )CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ONE,$ A( K+1 ), M+1, B, LDB )*END IF*END IF*ELSE** SIDE = 'L', N is even, and TRANSR = 'T'*IF( LOWER ) THEN** SIDE ='L', N is even, TRANSR = 'T', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='L', N is even, TRANSR = 'T', UPLO = 'L',* and TRANS = 'N'*CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ALPHA,$ A( K ), K, B, LDB )CALL DGEMM( 'T', 'N', K, N, K, -ONE,$ A( K*( K+1 ) ), K, B, LDB, ALPHA,$ B( K, 0 ), LDB )CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ONE,$ A( 0 ), K, B( K, 0 ), LDB )*ELSE** SIDE ='L', N is even, TRANSR = 'T', UPLO = 'L',* and TRANS = 'T'*CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ALPHA,$ A( 0 ), K, B( K, 0 ), LDB )CALL DGEMM( 'N', 'N', K, N, K, -ONE,$ A( K*( K+1 ) ), K, B( K, 0 ), LDB,$ ALPHA, B, LDB )CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ONE,$ A( K ), K, B, LDB )*END IF*ELSE** SIDE ='L', N is even, TRANSR = 'T', and UPLO = 'U'*IF( .NOT.NOTRANS ) THEN** SIDE ='L', N is even, TRANSR = 'T', UPLO = 'U',* and TRANS = 'N'*CALL DTRSM( 'L', 'U', 'T', DIAG, K, N, ALPHA,$ A( K*( K+1 ) ), K, B, LDB )CALL DGEMM( 'N', 'N', K, N, K, -ONE, A( 0 ), K, B,$ LDB, ALPHA, B( K, 0 ), LDB )CALL DTRSM( 'L', 'L', 'N', DIAG, K, N, ONE,$ A( K*K ), K, B( K, 0 ), LDB )*ELSE** SIDE ='L', N is even, TRANSR = 'T', UPLO = 'U',* and TRANS = 'T'*CALL DTRSM( 'L', 'L', 'T', DIAG, K, N, ALPHA,$ A( K*K ), K, B( K, 0 ), LDB )CALL DGEMM( 'T', 'N', K, N, K, -ONE, A( 0 ), K,$ B( K, 0 ), LDB, ALPHA, B, LDB )CALL DTRSM( 'L', 'U', 'N', DIAG, K, N, ONE,$ A( K*( K+1 ) ), K, B, LDB )*END IF*END IF*END IF*END IF*ELSE** SIDE = 'R'** A is N-by-N.* If N is odd, set NISODD = .TRUE., and N1 and N2.* If N is even, NISODD = .FALSE., and K.*IF( MOD( N, 2 ).EQ.0 ) THENNISODD = .FALSE.K = N / 2ELSENISODD = .TRUE.IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IFEND IF*IF( NISODD ) THEN** SIDE = 'R' and N is odd*IF( NORMALTRANSR ) THEN** SIDE = 'R', N is odd, and TRANSR = 'N'*IF( LOWER ) THEN** SIDE ='R', N is odd, TRANSR = 'N', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'L', and* TRANS = 'N'*CALL DTRSM( 'R', 'U', 'T', DIAG, M, N2, ALPHA,$ A( N ), N, B( 0, N1 ), LDB )CALL DGEMM( 'N', 'N', M, N1, N2, -ONE, B( 0, N1 ),$ LDB, A( N1 ), N, ALPHA, B( 0, 0 ),$ LDB )CALL DTRSM( 'R', 'L', 'N', DIAG, M, N1, ONE,$ A( 0 ), N, B( 0, 0 ), LDB )*ELSE** SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'L', and* TRANS = 'T'*CALL DTRSM( 'R', 'L', 'T', DIAG, M, N1, ALPHA,$ A( 0 ), N, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'T', M, N2, N1, -ONE, B( 0, 0 ),$ LDB, A( N1 ), N, ALPHA, B( 0, N1 ),$ LDB )CALL DTRSM( 'R', 'U', 'N', DIAG, M, N2, ONE,$ A( N ), N, B( 0, N1 ), LDB )*END IF*ELSE** SIDE ='R', N is odd, TRANSR = 'N', and UPLO = 'U'*IF( NOTRANS ) THEN** SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'U', and* TRANS = 'N'*CALL DTRSM( 'R', 'L', 'T', DIAG, M, N1, ALPHA,$ A( N2 ), N, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'N', M, N2, N1, -ONE, B( 0, 0 ),$ LDB, A( 0 ), N, ALPHA, B( 0, N1 ),$ LDB )CALL DTRSM( 'R', 'U', 'N', DIAG, M, N2, ONE,$ A( N1 ), N, B( 0, N1 ), LDB )*ELSE** SIDE ='R', N is odd, TRANSR = 'N', UPLO = 'U', and* TRANS = 'T'*CALL DTRSM( 'R', 'U', 'T', DIAG, M, N2, ALPHA,$ A( N1 ), N, B( 0, N1 ), LDB )CALL DGEMM( 'N', 'T', M, N1, N2, -ONE, B( 0, N1 ),$ LDB, A( 0 ), N, ALPHA, B( 0, 0 ), LDB )CALL DTRSM( 'R', 'L', 'N', DIAG, M, N1, ONE,$ A( N2 ), N, B( 0, 0 ), LDB )*END IF*END IF*ELSE** SIDE = 'R', N is odd, and TRANSR = 'T'*IF( LOWER ) THEN** SIDE ='R', N is odd, TRANSR = 'T', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'L', and* TRANS = 'N'*CALL DTRSM( 'R', 'L', 'N', DIAG, M, N2, ALPHA,$ A( 1 ), N1, B( 0, N1 ), LDB )CALL DGEMM( 'N', 'T', M, N1, N2, -ONE, B( 0, N1 ),$ LDB, A( N1*N1 ), N1, ALPHA, B( 0, 0 ),$ LDB )CALL DTRSM( 'R', 'U', 'T', DIAG, M, N1, ONE,$ A( 0 ), N1, B( 0, 0 ), LDB )*ELSE** SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'L', and* TRANS = 'T'*CALL DTRSM( 'R', 'U', 'N', DIAG, M, N1, ALPHA,$ A( 0 ), N1, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'N', M, N2, N1, -ONE, B( 0, 0 ),$ LDB, A( N1*N1 ), N1, ALPHA, B( 0, N1 ),$ LDB )CALL DTRSM( 'R', 'L', 'T', DIAG, M, N2, ONE,$ A( 1 ), N1, B( 0, N1 ), LDB )*END IF*ELSE** SIDE ='R', N is odd, TRANSR = 'T', and UPLO = 'U'*IF( NOTRANS ) THEN** SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'U', and* TRANS = 'N'*CALL DTRSM( 'R', 'U', 'N', DIAG, M, N1, ALPHA,$ A( N2*N2 ), N2, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'T', M, N2, N1, -ONE, B( 0, 0 ),$ LDB, A( 0 ), N2, ALPHA, B( 0, N1 ),$ LDB )CALL DTRSM( 'R', 'L', 'T', DIAG, M, N2, ONE,$ A( N1*N2 ), N2, B( 0, N1 ), LDB )*ELSE** SIDE ='R', N is odd, TRANSR = 'T', UPLO = 'U', and* TRANS = 'T'*CALL DTRSM( 'R', 'L', 'N', DIAG, M, N2, ALPHA,$ A( N1*N2 ), N2, B( 0, N1 ), LDB )CALL DGEMM( 'N', 'N', M, N1, N2, -ONE, B( 0, N1 ),$ LDB, A( 0 ), N2, ALPHA, B( 0, 0 ),$ LDB )CALL DTRSM( 'R', 'U', 'T', DIAG, M, N1, ONE,$ A( N2*N2 ), N2, B( 0, 0 ), LDB )*END IF*END IF*END IF*ELSE** SIDE = 'R' and N is even*IF( NORMALTRANSR ) THEN** SIDE = 'R', N is even, and TRANSR = 'N'*IF( LOWER ) THEN** SIDE ='R', N is even, TRANSR = 'N', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='R', N is even, TRANSR = 'N', UPLO = 'L',* and TRANS = 'N'*CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ALPHA,$ A( 0 ), N+1, B( 0, K ), LDB )CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, K ),$ LDB, A( K+1 ), N+1, ALPHA, B( 0, 0 ),$ LDB )CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ONE,$ A( 1 ), N+1, B( 0, 0 ), LDB )*ELSE** SIDE ='R', N is even, TRANSR = 'N', UPLO = 'L',* and TRANS = 'T'*CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ALPHA,$ A( 1 ), N+1, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, 0 ),$ LDB, A( K+1 ), N+1, ALPHA, B( 0, K ),$ LDB )CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ONE,$ A( 0 ), N+1, B( 0, K ), LDB )*END IF*ELSE** SIDE ='R', N is even, TRANSR = 'N', and UPLO = 'U'*IF( NOTRANS ) THEN** SIDE ='R', N is even, TRANSR = 'N', UPLO = 'U',* and TRANS = 'N'*CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ALPHA,$ A( K+1 ), N+1, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, 0 ),$ LDB, A( 0 ), N+1, ALPHA, B( 0, K ),$ LDB )CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ONE,$ A( K ), N+1, B( 0, K ), LDB )*ELSE** SIDE ='R', N is even, TRANSR = 'N', UPLO = 'U',* and TRANS = 'T'*CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ALPHA,$ A( K ), N+1, B( 0, K ), LDB )CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, K ),$ LDB, A( 0 ), N+1, ALPHA, B( 0, 0 ),$ LDB )CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ONE,$ A( K+1 ), N+1, B( 0, 0 ), LDB )*END IF*END IF*ELSE** SIDE = 'R', N is even, and TRANSR = 'T'*IF( LOWER ) THEN** SIDE ='R', N is even, TRANSR = 'T', and UPLO = 'L'*IF( NOTRANS ) THEN** SIDE ='R', N is even, TRANSR = 'T', UPLO = 'L',* and TRANS = 'N'*CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ALPHA,$ A( 0 ), K, B( 0, K ), LDB )CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, K ),$ LDB, A( ( K+1 )*K ), K, ALPHA,$ B( 0, 0 ), LDB )CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ONE,$ A( K ), K, B( 0, 0 ), LDB )*ELSE** SIDE ='R', N is even, TRANSR = 'T', UPLO = 'L',* and TRANS = 'T'*CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ALPHA,$ A( K ), K, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, 0 ),$ LDB, A( ( K+1 )*K ), K, ALPHA,$ B( 0, K ), LDB )CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ONE,$ A( 0 ), K, B( 0, K ), LDB )*END IF*ELSE** SIDE ='R', N is even, TRANSR = 'T', and UPLO = 'U'*IF( NOTRANS ) THEN** SIDE ='R', N is even, TRANSR = 'T', UPLO = 'U',* and TRANS = 'N'*CALL DTRSM( 'R', 'U', 'N', DIAG, M, K, ALPHA,$ A( ( K+1 )*K ), K, B( 0, 0 ), LDB )CALL DGEMM( 'N', 'T', M, K, K, -ONE, B( 0, 0 ),$ LDB, A( 0 ), K, ALPHA, B( 0, K ), LDB )CALL DTRSM( 'R', 'L', 'T', DIAG, M, K, ONE,$ A( K*K ), K, B( 0, K ), LDB )*ELSE** SIDE ='R', N is even, TRANSR = 'T', UPLO = 'U',* and TRANS = 'T'*CALL DTRSM( 'R', 'L', 'N', DIAG, M, K, ALPHA,$ A( K*K ), K, B( 0, K ), LDB )CALL DGEMM( 'N', 'N', M, K, K, -ONE, B( 0, K ),$ LDB, A( 0 ), K, ALPHA, B( 0, 0 ), LDB )CALL DTRSM( 'R', 'U', 'T', DIAG, M, K, ONE,$ A( ( K+1 )*K ), K, B( 0, 0 ), LDB )*END IF*END IF*END IF*END IFEND IF*RETURN** End of DTFSM*END*> \brief \b DTFTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTFTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtftri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtftri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtftri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTFTRI( TRANSR, UPLO, DIAG, N, A, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO, DIAG* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTFTRI computes the inverse of a triangular matrix A stored in RFP*> format.*>*> This is a Level 3 BLAS version of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': The Normal TRANSR of RFP A is stored;*> = 'T': The Transpose TRANSR of RFP A is stored.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (0:nt-1);*> nt=N*(N+1)/2. On entry, the triangular factor of a Hermitian*> Positive Definite matrix A in RFP format. RFP format is*> described by TRANSR, UPLO, and N as follows: If TRANSR = 'N'*> then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is*> (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is*> the transpose of RFP A as defined when*> TRANSR = 'N'. The contents of RFP A are defined by UPLO as*> follows: If UPLO = 'U' the RFP A contains the nt elements of*> upper packed A; If UPLO = 'L' the RFP A contains the nt*> elements of lower packed A. The LDA of RFP A is (N+1)/2 when*> TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is*> even and N is odd. See the Note below for more details.*>*> On exit, the (triangular) inverse of the original matrix, in*> the same storage format.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, A(i,i) is exactly zero. The triangular*> matrix is singular and its inverse can not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim*>* =====================================================================SUBROUTINE DTFTRI( TRANSR, UPLO, DIAG, N, A, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLO, DIAGINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER N1, N2, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA, DTRMM, DTRTRI* ..* .. Intrinsic Functions ..INTRINSIC MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( .NOT.LSAME( DIAG, 'N' ) .AND. .NOT.LSAME( DIAG, 'U' ) )$ THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTFTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** If N is odd, set NISODD = .TRUE.* If N is even, set K = N/2 and NISODD = .FALSE.*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.ELSENISODD = .TRUE.END IF** Set N1 and N2 depending on LOWER*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF*** start execution: there are eight cases*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:n1-1) )* T1 -> a(0,0), T2 -> a(0,1), S -> a(n1,0)* T1 -> a(0), T2 -> a(n), S -> a(n1)*CALL DTRTRI( 'L', DIAG, N1, A( 0 ), N, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'L', 'N', DIAG, N2, N1, -ONE, A( 0 ),$ N, A( N1 ), N )CALL DTRTRI( 'U', DIAG, N2, A( N ), N, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'U', 'T', DIAG, N2, N1, ONE, A( N ), N,$ A( N1 ), N )*ELSE** SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:n2-1)* T1 -> a(n1+1,0), T2 -> a(n1,0), S -> a(0,0)* T1 -> a(n2), T2 -> a(n1), S -> a(0)*CALL DTRTRI( 'L', DIAG, N1, A( N2 ), N, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'L', 'T', DIAG, N1, N2, -ONE, A( N2 ),$ N, A( 0 ), N )CALL DTRTRI( 'U', DIAG, N2, A( N1 ), N, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'U', 'N', DIAG, N1, N2, ONE, A( N1 ),$ N, A( 0 ), N )*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE and N is odd* T1 -> a(0), T2 -> a(1), S -> a(0+n1*n1)*CALL DTRTRI( 'U', DIAG, N1, A( 0 ), N1, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'U', 'N', DIAG, N1, N2, -ONE, A( 0 ),$ N1, A( N1*N1 ), N1 )CALL DTRTRI( 'L', DIAG, N2, A( 1 ), N1, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'L', 'T', DIAG, N1, N2, ONE, A( 1 ),$ N1, A( N1*N1 ), N1 )*ELSE** SRPA for UPPER, TRANSPOSE and N is odd* T1 -> a(0+n2*n2), T2 -> a(0+n1*n2), S -> a(0)*CALL DTRTRI( 'U', DIAG, N1, A( N2*N2 ), N2, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'U', 'T', DIAG, N2, N1, -ONE,$ A( N2*N2 ), N2, A( 0 ), N2 )CALL DTRTRI( 'L', DIAG, N2, A( N1*N2 ), N2, INFO )IF( INFO.GT.0 )$ INFO = INFO + N1IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'L', 'N', DIAG, N2, N1, ONE,$ A( N1*N2 ), N2, A( 0 ), N2 )END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0)* T1 -> a(1), T2 -> a(0), S -> a(k+1)*CALL DTRTRI( 'L', DIAG, K, A( 1 ), N+1, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'L', 'N', DIAG, K, K, -ONE, A( 1 ),$ N+1, A( K+1 ), N+1 )CALL DTRTRI( 'U', DIAG, K, A( 0 ), N+1, INFO )IF( INFO.GT.0 )$ INFO = INFO + KIF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'U', 'T', DIAG, K, K, ONE, A( 0 ), N+1,$ A( K+1 ), N+1 )*ELSE** SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0)* T1 -> a(k+1), T2 -> a(k), S -> a(0)*CALL DTRTRI( 'L', DIAG, K, A( K+1 ), N+1, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'L', 'T', DIAG, K, K, -ONE, A( K+1 ),$ N+1, A( 0 ), N+1 )CALL DTRTRI( 'U', DIAG, K, A( K ), N+1, INFO )IF( INFO.GT.0 )$ INFO = INFO + KIF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'U', 'N', DIAG, K, K, ONE, A( K ), N+1,$ A( 0 ), N+1 )END IFELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE and N is even (see paper)* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1)* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k*CALL DTRTRI( 'U', DIAG, K, A( K ), K, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'U', 'N', DIAG, K, K, -ONE, A( K ), K,$ A( K*( K+1 ) ), K )CALL DTRTRI( 'L', DIAG, K, A( 0 ), K, INFO )IF( INFO.GT.0 )$ INFO = INFO + KIF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'L', 'T', DIAG, K, K, ONE, A( 0 ), K,$ A( K*( K+1 ) ), K )ELSE** SRPA for UPPER, TRANSPOSE and N is even (see paper)* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0)* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k*CALL DTRTRI( 'U', DIAG, K, A( K*( K+1 ) ), K, INFO )IF( INFO.GT.0 )$ RETURNCALL DTRMM( 'R', 'U', 'T', DIAG, K, K, -ONE,$ A( K*( K+1 ) ), K, A( 0 ), K )CALL DTRTRI( 'L', DIAG, K, A( K*K ), K, INFO )IF( INFO.GT.0 )$ INFO = INFO + KIF( INFO.GT.0 )$ RETURNCALL DTRMM( 'L', 'L', 'N', DIAG, K, K, ONE, A( K*K ), K,$ A( 0 ), K )END IFEND IFEND IF*RETURN** End of DTFTRI*END*> \brief \b DTFTTP copies a triangular matrix from the rectangular full packed format (TF) to the standard packed format (TP).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTFTTP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtfttp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtfttp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtfttp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTFTTP( TRANSR, UPLO, N, ARF, AP, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( 0: * ), ARF( 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTFTTP copies a triangular matrix A from rectangular full packed*> format (TF) to standard packed format (TP).*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': ARF is in Normal format;*> = 'T': ARF is in Transpose format;*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] ARF*> \verbatim*> ARF is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ),*> On entry, the upper or lower triangular matrix A stored in*> RFP format. For a further discussion see Notes below.*> \endverbatim*>*> \param[out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ),*> On exit, the upper or lower triangular matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim*>* =====================================================================SUBROUTINE DTFTTP( TRANSR, UPLO, N, ARF, AP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( 0: * ), ARF( 0: * )* ..** =====================================================================** .. Parameters ..* ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER N1, N2, K, NTINTEGER I, J, IJINTEGER IJP, JP, LDA, JS* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTFTTP', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( NORMALTRANSR ) THENAP( 0 ) = ARF( 0 )ELSEAP( 0 ) = ARF( 0 )END IFRETURNEND IF** Size of array ARF(0:NT-1)*NT = N*( N+1 ) / 2** Set N1 and N2 depending on LOWER*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF** If N is odd, set NISODD = .TRUE.* If N is even, set K = N/2 and NISODD = .FALSE.** set lda of ARF^C; ARF^C is (0:(N+1)/2-1,0:N-noe)* where noe = 0 if n is even, noe = 1 if n is odd*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.LDA = N + 1ELSENISODD = .TRUE.LDA = NEND IF** ARF^C has lda rows and n+1-noe cols*IF( .NOT.NORMALTRANSR )$ LDA = ( N+1 ) / 2** start execution: there are eight cases*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:n1-1) )* T1 -> a(0,0), T2 -> a(0,1), S -> a(n1,0)* T1 -> a(0), T2 -> a(n), S -> a(n1); lda = n*IJP = 0JP = 0DO J = 0, N2DO I = J, N - 1IJ = I + JPAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJP = JP + LDAEND DODO I = 0, N2 - 1DO J = 1 + I, N2IJ = I + J*LDAAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOEND DO*ELSE** SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:n2-1)* T1 -> a(n1+1,0), T2 -> a(n1,0), S -> a(0,0)* T1 -> a(n2), T2 -> a(n1), S -> a(0)*IJP = 0DO J = 0, N1 - 1IJ = N2 + JDO I = 0, JAP( IJP ) = ARF( IJ )IJP = IJP + 1IJ = IJ + LDAEND DOEND DOJS = 0DO J = N1, N - 1IJ = JSDO IJ = JS, JS + JAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJS = JS + LDAEND DO*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE and N is odd* T1 -> A(0,0) , T2 -> A(1,0) , S -> A(0,n1)* T1 -> a(0+0) , T2 -> a(1+0) , S -> a(0+n1*n1); lda=n1*IJP = 0DO I = 0, N2DO IJ = I*( LDA+1 ), N*LDA - 1, LDAAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOEND DOJS = 1DO J = 0, N2 - 1DO IJ = JS, JS + N2 - J - 1AP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJS = JS + LDA + 1END DO*ELSE** SRPA for UPPER, TRANSPOSE and N is odd* T1 -> A(0,n1+1), T2 -> A(0,n1), S -> A(0,0)* T1 -> a(n2*n2), T2 -> a(n1*n2), S -> a(0); lda = n2*IJP = 0JS = N2*LDADO J = 0, N1 - 1DO IJ = JS, JS + JAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJS = JS + LDAEND DODO I = 0, N1DO IJ = I, I + ( N1+I )*LDA, LDAAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOEND DO*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0)* T1 -> a(1), T2 -> a(0), S -> a(k+1)*IJP = 0JP = 0DO J = 0, K - 1DO I = J, N - 1IJ = 1 + I + JPAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJP = JP + LDAEND DODO I = 0, K - 1DO J = I, K - 1IJ = I + J*LDAAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOEND DO*ELSE** SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) )* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0)* T1 -> a(k+1), T2 -> a(k), S -> a(0)*IJP = 0DO J = 0, K - 1IJ = K + 1 + JDO I = 0, JAP( IJP ) = ARF( IJ )IJP = IJP + 1IJ = IJ + LDAEND DOEND DOJS = 0DO J = K, N - 1IJ = JSDO IJ = JS, JS + JAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJS = JS + LDAEND DO*END IF*ELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** SRPA for LOWER, TRANSPOSE and N is even (see paper)* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1)* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k*IJP = 0DO I = 0, K - 1DO IJ = I + ( I+1 )*LDA, ( N+1 )*LDA - 1, LDAAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOEND DOJS = 0DO J = 0, K - 1DO IJ = JS, JS + K - J - 1AP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJS = JS + LDA + 1END DO*ELSE** SRPA for UPPER, TRANSPOSE and N is even (see paper)* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0)* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k*IJP = 0JS = ( K+1 )*LDADO J = 0, K - 1DO IJ = JS, JS + JAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOJS = JS + LDAEND DODO I = 0, K - 1DO IJ = I, I + ( K+I )*LDA, LDAAP( IJP ) = ARF( IJ )IJP = IJP + 1END DOEND DO*END IF*END IF*END IF*RETURN** End of DTFTTP*END*> \brief \b DTFTTR copies a triangular matrix from the rectangular full packed format (TF) to the standard full format (TR).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTFTTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtfttr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtfttr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtfttr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTFTTR( TRANSR, UPLO, N, ARF, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER INFO, N, LDA* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: LDA-1, 0: * ), ARF( 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTFTTR copies a triangular matrix A from rectangular full packed*> format (TF) to standard full format (TR).*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': ARF is in Normal format;*> = 'T': ARF is in Transpose format.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices ARF and A. N >= 0.*> \endverbatim*>*> \param[in] ARF*> \verbatim*> ARF is DOUBLE PRECISION array, dimension (N*(N+1)/2).*> On entry, the upper (if UPLO = 'U') or lower (if UPLO = 'L')*> matrix A in RFP format. See the "Notes" below for more*> details.*> \endverbatim*>*> \param[out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On exit, the triangular matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of the array A contains*> the upper triangular matrix, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of the array A contains*> the lower triangular matrix, and the strictly upper*> triangular part of A is not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim** =====================================================================SUBROUTINE DTFTTR( TRANSR, UPLO, N, ARF, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER INFO, N, LDA* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: LDA-1, 0: * ), ARF( 0: * )* ..** =====================================================================** ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER N1, N2, K, NT, NX2, NP1X2INTEGER I, J, L, IJ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTFTTR', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.1 ) THENIF( N.EQ.1 ) THENA( 0, 0 ) = ARF( 0 )END IFRETURNEND IF** Size of array ARF(0:nt-1)*NT = N*( N+1 ) / 2** set N1 and N2 depending on LOWER: for N even N1=N2=K*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF** If N is odd, set NISODD = .TRUE., LDA=N+1 and A is (N+1)--by--K2.* If N is even, set K = N/2 and NISODD = .FALSE., LDA=N and A is* N--by--(N+1)/2.*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.IF( .NOT.LOWER )$ NP1X2 = N + N + 2ELSENISODD = .TRUE.IF( .NOT.LOWER )$ NX2 = N + NEND IF*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** N is odd, TRANSR = 'N', and UPLO = 'L'*IJ = 0DO J = 0, N2DO I = N1, N2 + JA( N2+J, I ) = ARF( IJ )IJ = IJ + 1END DODO I = J, N - 1A( I, J ) = ARF( IJ )IJ = IJ + 1END DOEND DO*ELSE** N is odd, TRANSR = 'N', and UPLO = 'U'*IJ = NT - NDO J = N - 1, N1, -1DO I = 0, JA( I, J ) = ARF( IJ )IJ = IJ + 1END DODO L = J - N1, N1 - 1A( J-N1, L ) = ARF( IJ )IJ = IJ + 1END DOIJ = IJ - NX2END DO*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** N is odd, TRANSR = 'T', and UPLO = 'L'*IJ = 0DO J = 0, N2 - 1DO I = 0, JA( J, I ) = ARF( IJ )IJ = IJ + 1END DODO I = N1 + J, N - 1A( I, N1+J ) = ARF( IJ )IJ = IJ + 1END DOEND DODO J = N2, N - 1DO I = 0, N1 - 1A( J, I ) = ARF( IJ )IJ = IJ + 1END DOEND DO*ELSE** N is odd, TRANSR = 'T', and UPLO = 'U'*IJ = 0DO J = 0, N1DO I = N1, N - 1A( J, I ) = ARF( IJ )IJ = IJ + 1END DOEND DODO J = 0, N1 - 1DO I = 0, JA( I, J ) = ARF( IJ )IJ = IJ + 1END DODO L = N2 + J, N - 1A( N2+J, L ) = ARF( IJ )IJ = IJ + 1END DOEND DO*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** N is even, TRANSR = 'N', and UPLO = 'L'*IJ = 0DO J = 0, K - 1DO I = K, K + JA( K+J, I ) = ARF( IJ )IJ = IJ + 1END DODO I = J, N - 1A( I, J ) = ARF( IJ )IJ = IJ + 1END DOEND DO*ELSE** N is even, TRANSR = 'N', and UPLO = 'U'*IJ = NT - N - 1DO J = N - 1, K, -1DO I = 0, JA( I, J ) = ARF( IJ )IJ = IJ + 1END DODO L = J - K, K - 1A( J-K, L ) = ARF( IJ )IJ = IJ + 1END DOIJ = IJ - NP1X2END DO*END IF*ELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** N is even, TRANSR = 'T', and UPLO = 'L'*IJ = 0J = KDO I = K, N - 1A( I, J ) = ARF( IJ )IJ = IJ + 1END DODO J = 0, K - 2DO I = 0, JA( J, I ) = ARF( IJ )IJ = IJ + 1END DODO I = K + 1 + J, N - 1A( I, K+1+J ) = ARF( IJ )IJ = IJ + 1END DOEND DODO J = K - 1, N - 1DO I = 0, K - 1A( J, I ) = ARF( IJ )IJ = IJ + 1END DOEND DO*ELSE** N is even, TRANSR = 'T', and UPLO = 'U'*IJ = 0DO J = 0, KDO I = K, N - 1A( J, I ) = ARF( IJ )IJ = IJ + 1END DOEND DODO J = 0, K - 2DO I = 0, JA( I, J ) = ARF( IJ )IJ = IJ + 1END DODO L = K + 1 + J, N - 1A( K+1+J, L ) = ARF( IJ )IJ = IJ + 1END DOEND DO* Note that here, on exit of the loop, J = K-1DO I = 0, JA( I, J ) = ARF( IJ )IJ = IJ + 1END DO*END IF*END IF*END IF*RETURN** End of DTFTTR*END*> \brief \b DTGEVC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGEVC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgevc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgevc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgevc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,* LDVL, VR, LDVR, MM, M, WORK, INFO )** .. Scalar Arguments ..* CHARACTER HOWMNY, SIDE* INTEGER INFO, LDP, LDS, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..* LOGICAL SELECT( * )* DOUBLE PRECISION P( LDP, * ), S( LDS, * ), VL( LDVL, * ),* $ VR( LDVR, * ), WORK( * )* ..****> \par Purpose:* =============*>*> \verbatim*>*> DTGEVC computes some or all of the right and/or left eigenvectors of*> a pair of real matrices (S,P), where S is a quasi-triangular matrix*> and P is upper triangular. Matrix pairs of this type are produced by*> the generalized Schur factorization of a matrix pair (A,B):*>*> A = Q*S*Z**T, B = Q*P*Z**T*>*> as computed by DGGHRD + DHGEQZ.*>*> The right eigenvector x and the left eigenvector y of (S,P)*> corresponding to an eigenvalue w are defined by:*>*> S*x = w*P*x, (y**H)*S = w*(y**H)*P,*>*> where y**H denotes the conjugate tranpose of y.*> The eigenvalues are not input to this routine, but are computed*> directly from the diagonal blocks of S and P.*>*> This routine returns the matrices X and/or Y of right and left*> eigenvectors of (S,P), or the products Z*X and/or Q*Y,*> where Z and Q are input matrices.*> If Q and Z are the orthogonal factors from the generalized Schur*> factorization of a matrix pair (A,B), then Z*X and Q*Y*> are the matrices of right and left eigenvectors of (A,B).*>*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'R': compute right eigenvectors only;*> = 'L': compute left eigenvectors only;*> = 'B': compute both right and left eigenvectors.*> \endverbatim*>*> \param[in] HOWMNY*> \verbatim*> HOWMNY is CHARACTER*1*> = 'A': compute all right and/or left eigenvectors;*> = 'B': compute all right and/or left eigenvectors,*> backtransformed by the matrices in VR and/or VL;*> = 'S': compute selected right and/or left eigenvectors,*> specified by the logical array SELECT.*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> If HOWMNY='S', SELECT specifies the eigenvectors to be*> computed. If w(j) is a real eigenvalue, the corresponding*> real eigenvector is computed if SELECT(j) is .TRUE..*> If w(j) and w(j+1) are the real and imaginary parts of a*> complex eigenvalue, the corresponding complex eigenvector*> is computed if either SELECT(j) or SELECT(j+1) is .TRUE.,*> and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is*> set to .FALSE..*> Not referenced if HOWMNY = 'A' or 'B'.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices S and P. N >= 0.*> \endverbatim*>*> \param[in] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (LDS,N)*> The upper quasi-triangular matrix S from a generalized Schur*> factorization, as computed by DHGEQZ.*> \endverbatim*>*> \param[in] LDS*> \verbatim*> LDS is INTEGER*> The leading dimension of array S. LDS >= max(1,N).*> \endverbatim*>*> \param[in] P*> \verbatim*> P is DOUBLE PRECISION array, dimension (LDP,N)*> The upper triangular matrix P from a generalized Schur*> factorization, as computed by DHGEQZ.*> 2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks*> of S must be in positive diagonal form.*> \endverbatim*>*> \param[in] LDP*> \verbatim*> LDP is INTEGER*> The leading dimension of array P. LDP >= max(1,N).*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,MM)*> On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must*> contain an N-by-N matrix Q (usually the orthogonal matrix Q*> of left Schur vectors returned by DHGEQZ).*> On exit, if SIDE = 'L' or 'B', VL contains:*> if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);*> if HOWMNY = 'B', the matrix Q*Y;*> if HOWMNY = 'S', the left eigenvectors of (S,P) specified by*> SELECT, stored consecutively in the columns of*> VL, in the same order as their eigenvalues.*>*> A complex eigenvector corresponding to a complex eigenvalue*> is stored in two consecutive columns, the first holding the*> real part, and the second the imaginary part.*>*> Not referenced if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of array VL. LDVL >= 1, and if*> SIDE = 'L' or 'B', LDVL >= N.*> \endverbatim*>*> \param[in,out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,MM)*> On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must*> contain an N-by-N matrix Z (usually the orthogonal matrix Z*> of right Schur vectors returned by DHGEQZ).*>*> On exit, if SIDE = 'R' or 'B', VR contains:*> if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);*> if HOWMNY = 'B' or 'b', the matrix Z*X;*> if HOWMNY = 'S' or 's', the right eigenvectors of (S,P)*> specified by SELECT, stored consecutively in the*> columns of VR, in the same order as their*> eigenvalues.*>*> A complex eigenvector corresponding to a complex eigenvalue*> is stored in two consecutive columns, the first holding the*> real part and the second the imaginary part.*>*> Not referenced if SIDE = 'L'.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR. LDVR >= 1, and if*> SIDE = 'R' or 'B', LDVR >= N.*> \endverbatim*>*> \param[in] MM*> \verbatim*> MM is INTEGER*> The number of columns in the arrays VL and/or VR. MM >= M.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The number of columns in the arrays VL and/or VR actually*> used to store the eigenvectors. If HOWMNY = 'A' or 'B', M*> is set to N. Each selected real eigenvector occupies one*> column and each selected complex eigenvector occupies two*> columns.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (6*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit.*> < 0: if INFO = -i, the i-th argument had an illegal value.*> > 0: the 2-by-2 block (INFO:INFO+1) does not have a complex*> eigenvalue.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> Allocation of workspace:*> ---------- -- ---------*>*> WORK( j ) = 1-norm of j-th column of A, above the diagonal*> WORK( N+j ) = 1-norm of j-th column of B, above the diagonal*> WORK( 2*N+1:3*N ) = real part of eigenvector*> WORK( 3*N+1:4*N ) = imaginary part of eigenvector*> WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector*> WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector*>*> Rowwise vs. columnwise solution methods:*> ------- -- ---------- -------- -------*>*> Finding a generalized eigenvector consists basically of solving the*> singular triangular system*>*> (A - w B) x = 0 (for right) or: (A - w B)**H y = 0 (for left)*>*> Consider finding the i-th right eigenvector (assume all eigenvalues*> are real). The equation to be solved is:*> n i*> 0 = sum C(j,k) v(k) = sum C(j,k) v(k) for j = i,. . .,1*> k=j k=j*>*> where C = (A - w B) (The components v(i+1:n) are 0.)*>*> The "rowwise" method is:*>*> (1) v(i) := 1*> for j = i-1,. . .,1:*> i*> (2) compute s = - sum C(j,k) v(k) and*> k=j+1*>*> (3) v(j) := s / C(j,j)*>*> Step 2 is sometimes called the "dot product" step, since it is an*> inner product between the j-th row and the portion of the eigenvector*> that has been computed so far.*>*> The "columnwise" method consists basically in doing the sums*> for all the rows in parallel. As each v(j) is computed, the*> contribution of v(j) times the j-th column of C is added to the*> partial sums. Since FORTRAN arrays are stored columnwise, this has*> the advantage that at each step, the elements of C that are accessed*> are adjacent to one another, whereas with the rowwise method, the*> elements accessed at a step are spaced LDS (and LDP) words apart.*>*> When finding left eigenvectors, the matrix in question is the*> transpose of the one in storage, so the rowwise method then*> actually accesses columns of A and B at each step, and so is the*> preferred method.*> \endverbatim*>* =====================================================================SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,$ LDVL, VR, LDVR, MM, M, WORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER HOWMNY, SIDEINTEGER INFO, LDP, LDS, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )DOUBLE PRECISION P( LDP, * ), S( LDS, * ), VL( LDVL, * ),$ VR( LDVR, * ), WORK( * )* ..*** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, SAFETYPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0,$ SAFETY = 1.0D+2 )* ..* .. Local Scalars ..LOGICAL COMPL, COMPR, IL2BY2, ILABAD, ILALL, ILBACK,$ ILBBAD, ILCOMP, ILCPLX, LSA, LSBINTEGER I, IBEG, IEIG, IEND, IHWMNY, IINFO, IM, ISIDE,$ J, JA, JC, JE, JR, JW, NA, NWDOUBLE PRECISION ACOEF, ACOEFA, ANORM, ASCALE, BCOEFA, BCOEFI,$ BCOEFR, BIG, BIGNUM, BNORM, BSCALE, CIM2A,$ CIM2B, CIMAGA, CIMAGB, CRE2A, CRE2B, CREALA,$ CREALB, DMIN, SAFMIN, SALFAR, SBETA, SCALE,$ SMALL, TEMP, TEMP2, TEMP2I, TEMP2R, ULP, XMAX,$ XSCALE* ..* .. Local Arrays ..DOUBLE PRECISION BDIAG( 2 ), SUM( 2, 2 ), SUMS( 2, 2 ),$ SUMP( 2, 2 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. External Subroutines ..EXTERNAL DGEMV, DLABAD, DLACPY, DLAG2, DLALN2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Decode and Test the input parameters*IF( LSAME( HOWMNY, 'A' ) ) THENIHWMNY = 1ILALL = .TRUE.ILBACK = .FALSE.ELSE IF( LSAME( HOWMNY, 'S' ) ) THENIHWMNY = 2ILALL = .FALSE.ILBACK = .FALSE.ELSE IF( LSAME( HOWMNY, 'B' ) ) THENIHWMNY = 3ILALL = .TRUE.ILBACK = .TRUE.ELSEIHWMNY = -1ILALL = .TRUE.END IF*IF( LSAME( SIDE, 'R' ) ) THENISIDE = 1COMPL = .FALSE.COMPR = .TRUE.ELSE IF( LSAME( SIDE, 'L' ) ) THENISIDE = 2COMPL = .TRUE.COMPR = .FALSE.ELSE IF( LSAME( SIDE, 'B' ) ) THENISIDE = 3COMPL = .TRUE.COMPR = .TRUE.ELSEISIDE = -1END IF*INFO = 0IF( ISIDE.LT.0 ) THENINFO = -1ELSE IF( IHWMNY.LT.0 ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDS.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDP.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTGEVC', -INFO )RETURNEND IF** Count the number of eigenvectors to be computed*IF( .NOT.ILALL ) THENIM = 0ILCPLX = .FALSE.DO 10 J = 1, NIF( ILCPLX ) THENILCPLX = .FALSE.GO TO 10END IFIF( J.LT.N ) THENIF( S( J+1, J ).NE.ZERO )$ ILCPLX = .TRUE.END IFIF( ILCPLX ) THENIF( SELECT( J ) .OR. SELECT( J+1 ) )$ IM = IM + 2ELSEIF( SELECT( J ) )$ IM = IM + 1END IF10 CONTINUEELSEIM = NEND IF** Check 2-by-2 diagonal blocks of A, B*ILABAD = .FALSE.ILBBAD = .FALSE.DO 20 J = 1, N - 1IF( S( J+1, J ).NE.ZERO ) THENIF( P( J, J ).EQ.ZERO .OR. P( J+1, J+1 ).EQ.ZERO .OR.$ P( J, J+1 ).NE.ZERO )ILBBAD = .TRUE.IF( J.LT.N-1 ) THENIF( S( J+2, J+1 ).NE.ZERO )$ ILABAD = .TRUE.END IFEND IF20 CONTINUE*IF( ILABAD ) THENINFO = -5ELSE IF( ILBBAD ) THENINFO = -7ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THENINFO = -10ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THENINFO = -12ELSE IF( MM.LT.IM ) THENINFO = -13END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTGEVC', -INFO )RETURNEND IF** Quick return if possible*M = IMIF( N.EQ.0 )$ RETURN** Machine Constants*SAFMIN = DLAMCH( 'Safe minimum' )BIG = ONE / SAFMINCALL DLABAD( SAFMIN, BIG )ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )SMALL = SAFMIN*N / ULPBIG = ONE / SMALLBIGNUM = ONE / ( SAFMIN*N )** Compute the 1-norm of each column of the strictly upper triangular* part (i.e., excluding all elements belonging to the diagonal* blocks) of A and B to check for possible overflow in the* triangular solver.*ANORM = ABS( S( 1, 1 ) )IF( N.GT.1 )$ ANORM = ANORM + ABS( S( 2, 1 ) )BNORM = ABS( P( 1, 1 ) )WORK( 1 ) = ZEROWORK( N+1 ) = ZERO*DO 50 J = 2, NTEMP = ZEROTEMP2 = ZEROIF( S( J, J-1 ).EQ.ZERO ) THENIEND = J - 1ELSEIEND = J - 2END IFDO 30 I = 1, IENDTEMP = TEMP + ABS( S( I, J ) )TEMP2 = TEMP2 + ABS( P( I, J ) )30 CONTINUEWORK( J ) = TEMPWORK( N+J ) = TEMP2DO 40 I = IEND + 1, MIN( J+1, N )TEMP = TEMP + ABS( S( I, J ) )TEMP2 = TEMP2 + ABS( P( I, J ) )40 CONTINUEANORM = MAX( ANORM, TEMP )BNORM = MAX( BNORM, TEMP2 )50 CONTINUE*ASCALE = ONE / MAX( ANORM, SAFMIN )BSCALE = ONE / MAX( BNORM, SAFMIN )** Left eigenvectors*IF( COMPL ) THENIEIG = 0** Main loop over eigenvalues*ILCPLX = .FALSE.DO 220 JE = 1, N** Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or* (b) this would be the second of a complex pair.* Check for complex eigenvalue, so as to be sure of which* entry(-ies) of SELECT to look at.*IF( ILCPLX ) THENILCPLX = .FALSE.GO TO 220END IFNW = 1IF( JE.LT.N ) THENIF( S( JE+1, JE ).NE.ZERO ) THENILCPLX = .TRUE.NW = 2END IFEND IFIF( ILALL ) THENILCOMP = .TRUE.ELSE IF( ILCPLX ) THENILCOMP = SELECT( JE ) .OR. SELECT( JE+1 )ELSEILCOMP = SELECT( JE )END IFIF( .NOT.ILCOMP )$ GO TO 220** Decide if (a) singular pencil, (b) real eigenvalue, or* (c) complex eigenvalue.*IF( .NOT.ILCPLX ) THENIF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.$ ABS( P( JE, JE ) ).LE.SAFMIN ) THEN** Singular matrix pencil -- return unit eigenvector*IEIG = IEIG + 1DO 60 JR = 1, NVL( JR, IEIG ) = ZERO60 CONTINUEVL( IEIG, IEIG ) = ONEGO TO 220END IFEND IF** Clear vector*DO 70 JR = 1, NW*NWORK( 2*N+JR ) = ZERO70 CONTINUE* T* Compute coefficients in ( a A - b B ) y = 0* a is ACOEF* b is BCOEFR + i*BCOEFI*IF( .NOT.ILCPLX ) THEN** Real eigenvalue*TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,$ ABS( P( JE, JE ) )*BSCALE, SAFMIN )SALFAR = ( TEMP*S( JE, JE ) )*ASCALESBETA = ( TEMP*P( JE, JE ) )*BSCALEACOEF = SBETA*ASCALEBCOEFR = SALFAR*BSCALEBCOEFI = ZERO** Scale to avoid underflow*SCALE = ONELSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALLLSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.$ SMALLIF( LSA )$ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )IF( LSB )$ SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*$ MIN( BNORM, BIG ) )IF( LSA .OR. LSB ) THENSCALE = MIN( SCALE, ONE /$ ( SAFMIN*MAX( ONE, ABS( ACOEF ),$ ABS( BCOEFR ) ) ) )IF( LSA ) THENACOEF = ASCALE*( SCALE*SBETA )ELSEACOEF = SCALE*ACOEFEND IFIF( LSB ) THENBCOEFR = BSCALE*( SCALE*SALFAR )ELSEBCOEFR = SCALE*BCOEFREND IFEND IFACOEFA = ABS( ACOEF )BCOEFA = ABS( BCOEFR )** First component is 1*WORK( 2*N+JE ) = ONEXMAX = ONEELSE** Complex eigenvalue*CALL DLAG2( S( JE, JE ), LDS, P( JE, JE ), LDP,$ SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,$ BCOEFI )BCOEFI = -BCOEFIIF( BCOEFI.EQ.ZERO ) THENINFO = JERETURNEND IF** Scale to avoid over/underflow*ACOEFA = ABS( ACOEF )BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )SCALE = ONEIF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )$ SCALE = ( SAFMIN / ULP ) / ACOEFAIF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )$ SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )IF( SAFMIN*ACOEFA.GT.ASCALE )$ SCALE = ASCALE / ( SAFMIN*ACOEFA )IF( SAFMIN*BCOEFA.GT.BSCALE )$ SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )IF( SCALE.NE.ONE ) THENACOEF = SCALE*ACOEFACOEFA = ABS( ACOEF )BCOEFR = SCALE*BCOEFRBCOEFI = SCALE*BCOEFIBCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )END IF** Compute first two components of eigenvector*TEMP = ACOEF*S( JE+1, JE )TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )TEMP2I = -BCOEFI*P( JE, JE )IF( ABS( TEMP ).GT.ABS( TEMP2R )+ABS( TEMP2I ) ) THENWORK( 2*N+JE ) = ONEWORK( 3*N+JE ) = ZEROWORK( 2*N+JE+1 ) = -TEMP2R / TEMPWORK( 3*N+JE+1 ) = -TEMP2I / TEMPELSEWORK( 2*N+JE+1 ) = ONEWORK( 3*N+JE+1 ) = ZEROTEMP = ACOEF*S( JE, JE+1 )WORK( 2*N+JE ) = ( BCOEFR*P( JE+1, JE+1 )-ACOEF*$ S( JE+1, JE+1 ) ) / TEMPWORK( 3*N+JE ) = BCOEFI*P( JE+1, JE+1 ) / TEMPEND IFXMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),$ ABS( WORK( 2*N+JE+1 ) )+ABS( WORK( 3*N+JE+1 ) ) )END IF*DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )** T* Triangular solve of (a A - b B) y = 0** T* (rowwise in (a A - b B) , or columnwise in (a A - b B) )*IL2BY2 = .FALSE.*DO 160 J = JE + NW, NIF( IL2BY2 ) THENIL2BY2 = .FALSE.GO TO 160END IF*NA = 1BDIAG( 1 ) = P( J, J )IF( J.LT.N ) THENIF( S( J+1, J ).NE.ZERO ) THENIL2BY2 = .TRUE.BDIAG( 2 ) = P( J+1, J+1 )NA = 2END IFEND IF** Check whether scaling is necessary for dot products*XSCALE = ONE / MAX( ONE, XMAX )TEMP = MAX( WORK( J ), WORK( N+J ),$ ACOEFA*WORK( J )+BCOEFA*WORK( N+J ) )IF( IL2BY2 )$ TEMP = MAX( TEMP, WORK( J+1 ), WORK( N+J+1 ),$ ACOEFA*WORK( J+1 )+BCOEFA*WORK( N+J+1 ) )IF( TEMP.GT.BIGNUM*XSCALE ) THENDO 90 JW = 0, NW - 1DO 80 JR = JE, J - 1WORK( ( JW+2 )*N+JR ) = XSCALE*$ WORK( ( JW+2 )*N+JR )80 CONTINUE90 CONTINUEXMAX = XMAX*XSCALEEND IF** Compute dot products** j-1* SUM = sum conjg( a*S(k,j) - b*P(k,j) )*x(k)* k=je** To reduce the op count, this is done as** _ j-1 _ j-1* a*conjg( sum S(k,j)*x(k) ) - b*conjg( sum P(k,j)*x(k) )* k=je k=je** which may cause underflow problems if A or B are close* to underflow. (E.g., less than SMALL.)**DO 120 JW = 1, NWDO 110 JA = 1, NASUMS( JA, JW ) = ZEROSUMP( JA, JW ) = ZERO*DO 100 JR = JE, J - 1SUMS( JA, JW ) = SUMS( JA, JW ) +$ S( JR, J+JA-1 )*$ WORK( ( JW+1 )*N+JR )SUMP( JA, JW ) = SUMP( JA, JW ) +$ P( JR, J+JA-1 )*$ WORK( ( JW+1 )*N+JR )100 CONTINUE110 CONTINUE120 CONTINUE*DO 130 JA = 1, NAIF( ILCPLX ) THENSUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +$ BCOEFR*SUMP( JA, 1 ) -$ BCOEFI*SUMP( JA, 2 )SUM( JA, 2 ) = -ACOEF*SUMS( JA, 2 ) +$ BCOEFR*SUMP( JA, 2 ) +$ BCOEFI*SUMP( JA, 1 )ELSESUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +$ BCOEFR*SUMP( JA, 1 )END IF130 CONTINUE** T* Solve ( a A - b B ) y = SUM(,)* with scaling and perturbation of the denominator*CALL DLALN2( .TRUE., NA, NW, DMIN, ACOEF, S( J, J ), LDS,$ BDIAG( 1 ), BDIAG( 2 ), SUM, 2, BCOEFR,$ BCOEFI, WORK( 2*N+J ), N, SCALE, TEMP,$ IINFO )IF( SCALE.LT.ONE ) THENDO 150 JW = 0, NW - 1DO 140 JR = JE, J - 1WORK( ( JW+2 )*N+JR ) = SCALE*$ WORK( ( JW+2 )*N+JR )140 CONTINUE150 CONTINUEXMAX = SCALE*XMAXEND IFXMAX = MAX( XMAX, TEMP )160 CONTINUE** Copy eigenvector to VL, back transforming if* HOWMNY='B'.*IEIG = IEIG + 1IF( ILBACK ) THENDO 170 JW = 0, NW - 1CALL DGEMV( 'N', N, N+1-JE, ONE, VL( 1, JE ), LDVL,$ WORK( ( JW+2 )*N+JE ), 1, ZERO,$ WORK( ( JW+4 )*N+1 ), 1 )170 CONTINUECALL DLACPY( ' ', N, NW, WORK( 4*N+1 ), N, VL( 1, JE ),$ LDVL )IBEG = 1ELSECALL DLACPY( ' ', N, NW, WORK( 2*N+1 ), N, VL( 1, IEIG ),$ LDVL )IBEG = JEEND IF** Scale eigenvector*XMAX = ZEROIF( ILCPLX ) THENDO 180 J = IBEG, NXMAX = MAX( XMAX, ABS( VL( J, IEIG ) )+$ ABS( VL( J, IEIG+1 ) ) )180 CONTINUEELSEDO 190 J = IBEG, NXMAX = MAX( XMAX, ABS( VL( J, IEIG ) ) )190 CONTINUEEND IF*IF( XMAX.GT.SAFMIN ) THENXSCALE = ONE / XMAX*DO 210 JW = 0, NW - 1DO 200 JR = IBEG, NVL( JR, IEIG+JW ) = XSCALE*VL( JR, IEIG+JW )200 CONTINUE210 CONTINUEEND IFIEIG = IEIG + NW - 1*220 CONTINUEEND IF** Right eigenvectors*IF( COMPR ) THENIEIG = IM + 1** Main loop over eigenvalues*ILCPLX = .FALSE.DO 500 JE = N, 1, -1** Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or* (b) this would be the second of a complex pair.* Check for complex eigenvalue, so as to be sure of which* entry(-ies) of SELECT to look at -- if complex, SELECT(JE)* or SELECT(JE-1).* If this is a complex pair, the 2-by-2 diagonal block* corresponding to the eigenvalue is in rows/columns JE-1:JE*IF( ILCPLX ) THENILCPLX = .FALSE.GO TO 500END IFNW = 1IF( JE.GT.1 ) THENIF( S( JE, JE-1 ).NE.ZERO ) THENILCPLX = .TRUE.NW = 2END IFEND IFIF( ILALL ) THENILCOMP = .TRUE.ELSE IF( ILCPLX ) THENILCOMP = SELECT( JE ) .OR. SELECT( JE-1 )ELSEILCOMP = SELECT( JE )END IFIF( .NOT.ILCOMP )$ GO TO 500** Decide if (a) singular pencil, (b) real eigenvalue, or* (c) complex eigenvalue.*IF( .NOT.ILCPLX ) THENIF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.$ ABS( P( JE, JE ) ).LE.SAFMIN ) THEN** Singular matrix pencil -- unit eigenvector*IEIG = IEIG - 1DO 230 JR = 1, NVR( JR, IEIG ) = ZERO230 CONTINUEVR( IEIG, IEIG ) = ONEGO TO 500END IFEND IF** Clear vector*DO 250 JW = 0, NW - 1DO 240 JR = 1, NWORK( ( JW+2 )*N+JR ) = ZERO240 CONTINUE250 CONTINUE** Compute coefficients in ( a A - b B ) x = 0* a is ACOEF* b is BCOEFR + i*BCOEFI*IF( .NOT.ILCPLX ) THEN** Real eigenvalue*TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,$ ABS( P( JE, JE ) )*BSCALE, SAFMIN )SALFAR = ( TEMP*S( JE, JE ) )*ASCALESBETA = ( TEMP*P( JE, JE ) )*BSCALEACOEF = SBETA*ASCALEBCOEFR = SALFAR*BSCALEBCOEFI = ZERO** Scale to avoid underflow*SCALE = ONELSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALLLSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.$ SMALLIF( LSA )$ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )IF( LSB )$ SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*$ MIN( BNORM, BIG ) )IF( LSA .OR. LSB ) THENSCALE = MIN( SCALE, ONE /$ ( SAFMIN*MAX( ONE, ABS( ACOEF ),$ ABS( BCOEFR ) ) ) )IF( LSA ) THENACOEF = ASCALE*( SCALE*SBETA )ELSEACOEF = SCALE*ACOEFEND IFIF( LSB ) THENBCOEFR = BSCALE*( SCALE*SALFAR )ELSEBCOEFR = SCALE*BCOEFREND IFEND IFACOEFA = ABS( ACOEF )BCOEFA = ABS( BCOEFR )** First component is 1*WORK( 2*N+JE ) = ONEXMAX = ONE** Compute contribution from column JE of A and B to sum* (See "Further Details", above.)*DO 260 JR = 1, JE - 1WORK( 2*N+JR ) = BCOEFR*P( JR, JE ) -$ ACOEF*S( JR, JE )260 CONTINUEELSE** Complex eigenvalue*CALL DLAG2( S( JE-1, JE-1 ), LDS, P( JE-1, JE-1 ), LDP,$ SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,$ BCOEFI )IF( BCOEFI.EQ.ZERO ) THENINFO = JE - 1RETURNEND IF** Scale to avoid over/underflow*ACOEFA = ABS( ACOEF )BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )SCALE = ONEIF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )$ SCALE = ( SAFMIN / ULP ) / ACOEFAIF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )$ SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )IF( SAFMIN*ACOEFA.GT.ASCALE )$ SCALE = ASCALE / ( SAFMIN*ACOEFA )IF( SAFMIN*BCOEFA.GT.BSCALE )$ SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )IF( SCALE.NE.ONE ) THENACOEF = SCALE*ACOEFACOEFA = ABS( ACOEF )BCOEFR = SCALE*BCOEFRBCOEFI = SCALE*BCOEFIBCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )END IF** Compute first two components of eigenvector* and contribution to sums*TEMP = ACOEF*S( JE, JE-1 )TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )TEMP2I = -BCOEFI*P( JE, JE )IF( ABS( TEMP ).GE.ABS( TEMP2R )+ABS( TEMP2I ) ) THENWORK( 2*N+JE ) = ONEWORK( 3*N+JE ) = ZEROWORK( 2*N+JE-1 ) = -TEMP2R / TEMPWORK( 3*N+JE-1 ) = -TEMP2I / TEMPELSEWORK( 2*N+JE-1 ) = ONEWORK( 3*N+JE-1 ) = ZEROTEMP = ACOEF*S( JE-1, JE )WORK( 2*N+JE ) = ( BCOEFR*P( JE-1, JE-1 )-ACOEF*$ S( JE-1, JE-1 ) ) / TEMPWORK( 3*N+JE ) = BCOEFI*P( JE-1, JE-1 ) / TEMPEND IF*XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),$ ABS( WORK( 2*N+JE-1 ) )+ABS( WORK( 3*N+JE-1 ) ) )** Compute contribution from columns JE and JE-1* of A and B to the sums.*CREALA = ACOEF*WORK( 2*N+JE-1 )CIMAGA = ACOEF*WORK( 3*N+JE-1 )CREALB = BCOEFR*WORK( 2*N+JE-1 ) -$ BCOEFI*WORK( 3*N+JE-1 )CIMAGB = BCOEFI*WORK( 2*N+JE-1 ) +$ BCOEFR*WORK( 3*N+JE-1 )CRE2A = ACOEF*WORK( 2*N+JE )CIM2A = ACOEF*WORK( 3*N+JE )CRE2B = BCOEFR*WORK( 2*N+JE ) - BCOEFI*WORK( 3*N+JE )CIM2B = BCOEFI*WORK( 2*N+JE ) + BCOEFR*WORK( 3*N+JE )DO 270 JR = 1, JE - 2WORK( 2*N+JR ) = -CREALA*S( JR, JE-1 ) +$ CREALB*P( JR, JE-1 ) -$ CRE2A*S( JR, JE ) + CRE2B*P( JR, JE )WORK( 3*N+JR ) = -CIMAGA*S( JR, JE-1 ) +$ CIMAGB*P( JR, JE-1 ) -$ CIM2A*S( JR, JE ) + CIM2B*P( JR, JE )270 CONTINUEEND IF*DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )** Columnwise triangular solve of (a A - b B) x = 0*IL2BY2 = .FALSE.DO 370 J = JE - NW, 1, -1** If a 2-by-2 block, is in position j-1:j, wait until* next iteration to process it (when it will be j:j+1)*IF( .NOT.IL2BY2 .AND. J.GT.1 ) THENIF( S( J, J-1 ).NE.ZERO ) THENIL2BY2 = .TRUE.GO TO 370END IFEND IFBDIAG( 1 ) = P( J, J )IF( IL2BY2 ) THENNA = 2BDIAG( 2 ) = P( J+1, J+1 )ELSENA = 1END IF** Compute x(j) (and x(j+1), if 2-by-2 block)*CALL DLALN2( .FALSE., NA, NW, DMIN, ACOEF, S( J, J ),$ LDS, BDIAG( 1 ), BDIAG( 2 ), WORK( 2*N+J ),$ N, BCOEFR, BCOEFI, SUM, 2, SCALE, TEMP,$ IINFO )IF( SCALE.LT.ONE ) THEN*DO 290 JW = 0, NW - 1DO 280 JR = 1, JEWORK( ( JW+2 )*N+JR ) = SCALE*$ WORK( ( JW+2 )*N+JR )280 CONTINUE290 CONTINUEEND IFXMAX = MAX( SCALE*XMAX, TEMP )*DO 310 JW = 1, NWDO 300 JA = 1, NAWORK( ( JW+1 )*N+J+JA-1 ) = SUM( JA, JW )300 CONTINUE310 CONTINUE** w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling*IF( J.GT.1 ) THEN** Check whether scaling is necessary for sum.*XSCALE = ONE / MAX( ONE, XMAX )TEMP = ACOEFA*WORK( J ) + BCOEFA*WORK( N+J )IF( IL2BY2 )$ TEMP = MAX( TEMP, ACOEFA*WORK( J+1 )+BCOEFA*$ WORK( N+J+1 ) )TEMP = MAX( TEMP, ACOEFA, BCOEFA )IF( TEMP.GT.BIGNUM*XSCALE ) THEN*DO 330 JW = 0, NW - 1DO 320 JR = 1, JEWORK( ( JW+2 )*N+JR ) = XSCALE*$ WORK( ( JW+2 )*N+JR )320 CONTINUE330 CONTINUEXMAX = XMAX*XSCALEEND IF** Compute the contributions of the off-diagonals of* column j (and j+1, if 2-by-2 block) of A and B to the* sums.**DO 360 JA = 1, NAIF( ILCPLX ) THENCREALA = ACOEF*WORK( 2*N+J+JA-1 )CIMAGA = ACOEF*WORK( 3*N+J+JA-1 )CREALB = BCOEFR*WORK( 2*N+J+JA-1 ) -$ BCOEFI*WORK( 3*N+J+JA-1 )CIMAGB = BCOEFI*WORK( 2*N+J+JA-1 ) +$ BCOEFR*WORK( 3*N+J+JA-1 )DO 340 JR = 1, J - 1WORK( 2*N+JR ) = WORK( 2*N+JR ) -$ CREALA*S( JR, J+JA-1 ) +$ CREALB*P( JR, J+JA-1 )WORK( 3*N+JR ) = WORK( 3*N+JR ) -$ CIMAGA*S( JR, J+JA-1 ) +$ CIMAGB*P( JR, J+JA-1 )340 CONTINUEELSECREALA = ACOEF*WORK( 2*N+J+JA-1 )CREALB = BCOEFR*WORK( 2*N+J+JA-1 )DO 350 JR = 1, J - 1WORK( 2*N+JR ) = WORK( 2*N+JR ) -$ CREALA*S( JR, J+JA-1 ) +$ CREALB*P( JR, J+JA-1 )350 CONTINUEEND IF360 CONTINUEEND IF*IL2BY2 = .FALSE.370 CONTINUE** Copy eigenvector to VR, back transforming if* HOWMNY='B'.*IEIG = IEIG - NWIF( ILBACK ) THEN*DO 410 JW = 0, NW - 1DO 380 JR = 1, NWORK( ( JW+4 )*N+JR ) = WORK( ( JW+2 )*N+1 )*$ VR( JR, 1 )380 CONTINUE** A series of compiler directives to defeat* vectorization for the next loop**DO 400 JC = 2, JEDO 390 JR = 1, NWORK( ( JW+4 )*N+JR ) = WORK( ( JW+4 )*N+JR ) +$ WORK( ( JW+2 )*N+JC )*VR( JR, JC )390 CONTINUE400 CONTINUE410 CONTINUE*DO 430 JW = 0, NW - 1DO 420 JR = 1, NVR( JR, IEIG+JW ) = WORK( ( JW+4 )*N+JR )420 CONTINUE430 CONTINUE*IEND = NELSEDO 450 JW = 0, NW - 1DO 440 JR = 1, NVR( JR, IEIG+JW ) = WORK( ( JW+2 )*N+JR )440 CONTINUE450 CONTINUE*IEND = JEEND IF** Scale eigenvector*XMAX = ZEROIF( ILCPLX ) THENDO 460 J = 1, IENDXMAX = MAX( XMAX, ABS( VR( J, IEIG ) )+$ ABS( VR( J, IEIG+1 ) ) )460 CONTINUEELSEDO 470 J = 1, IENDXMAX = MAX( XMAX, ABS( VR( J, IEIG ) ) )470 CONTINUEEND IF*IF( XMAX.GT.SAFMIN ) THENXSCALE = ONE / XMAXDO 490 JW = 0, NW - 1DO 480 JR = 1, IENDVR( JR, IEIG+JW ) = XSCALE*VR( JR, IEIG+JW )480 CONTINUE490 CONTINUEEND IF500 CONTINUEEND IF*RETURN** End of DTGEVC*END*> \brief \b DTGEX2 swaps adjacent diagonal blocks in an upper (quasi) triangular matrix pair by an orthogonal equivalence transformation.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGEX2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgex2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgex2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgex2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,* LDZ, J1, N1, N2, WORK, LWORK, INFO )** .. Scalar Arguments ..* LOGICAL WANTQ, WANTZ* INTEGER INFO, J1, LDA, LDB, LDQ, LDZ, LWORK, N, N1, N2* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),* $ WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGEX2 swaps adjacent diagonal blocks (A11, B11) and (A22, B22)*> of size 1-by-1 or 2-by-2 in an upper (quasi) triangular matrix pair*> (A, B) by an orthogonal equivalence transformation.*>*> (A, B) must be in generalized real Schur canonical form (as returned*> by DGGES), i.e. A is block upper triangular with 1-by-1 and 2-by-2*> diagonal blocks. B is upper triangular.*>*> Optionally, the matrices Q and Z of generalized Schur vectors are*> updated.*>*> Q(in) * A(in) * Z(in)**T = Q(out) * A(out) * Z(out)**T*> Q(in) * B(in) * Z(in)**T = Q(out) * B(out) * Z(out)**T*>*> \endverbatim** Arguments:* ==========**> \param[in] WANTQ*> \verbatim*> WANTQ is LOGICAL*> .TRUE. : update the left transformation matrix Q;*> .FALSE.: do not update Q.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> .TRUE. : update the right transformation matrix Z;*> .FALSE.: do not update Z.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimensions (LDA,N)*> On entry, the matrix A in the pair (A, B).*> On exit, the updated matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimensions (LDB,N)*> On entry, the matrix B in the pair (A, B).*> On exit, the updated matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if WANTQ = .TRUE., the orthogonal matrix Q.*> On exit, the updated matrix Q.*> Not referenced if WANTQ = .FALSE..*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= 1.*> If WANTQ = .TRUE., LDQ >= N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> On entry, if WANTZ =.TRUE., the orthogonal matrix Z.*> On exit, the updated matrix Z.*> Not referenced if WANTZ = .FALSE..*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1.*> If WANTZ = .TRUE., LDZ >= N.*> \endverbatim*>*> \param[in] J1*> \verbatim*> J1 is INTEGER*> The index to the first block (A11, B11). 1 <= J1 <= N.*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> The order of the first block (A11, B11). N1 = 0, 1 or 2.*> \endverbatim*>*> \param[in] N2*> \verbatim*> N2 is INTEGER*> The order of the second block (A22, B22). N2 = 0, 1 or 2.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)).*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> LWORK >= MAX( 1, N*(N2+N1), (N2+N1)*(N2+N1)*2 )*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> =0: Successful exit*> >0: If INFO = 1, the transformed matrix (A, B) would be*> too far from generalized Schur form; the blocks are*> not swapped and (A, B) and (Q, Z) are unchanged.*> The problem of swapping is too ill-conditioned.*> <0: If INFO = -16: LWORK is too small. Appropriate value*> for LWORK is returned in WORK(1).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEauxiliary**> \par Further Details:* =====================*>*> In the current code both weak and strong stability tests are*> performed. The user can omit the strong stability test by changing*> the internal logical parameter WANDS to .FALSE.. See ref. [2] for*> details.**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.**> \par References:* ================*>*> \verbatim*>*> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the*> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in*> M.S. Moonen et al (eds), Linear Algebra for Large Scale and*> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.*>*> [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified*> Eigenvalues of a Regular Matrix Pair (A, B) and Condition*> Estimation: Theory, Algorithms and Software,*> Report UMINF - 94.04, Department of Computing Science, Umea*> University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working*> Note 87. To appear in Numerical Algorithms, 1996.*> \endverbatim*>* =====================================================================SUBROUTINE DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, J1, N1, N2, WORK, LWORK, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL WANTQ, WANTZINTEGER INFO, J1, LDA, LDB, LDQ, LDZ, LWORK, N, N1, N2* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),$ WORK( * ), Z( LDZ, * )* ..** =====================================================================* Replaced various illegal calls to DCOPY by calls to DLASET, or by DO* loops. Sven Hammarling, 1/5/02.** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )DOUBLE PRECISION TWENTYPARAMETER ( TWENTY = 2.0D+01 )INTEGER LDSTPARAMETER ( LDST = 4 )LOGICAL WANDSPARAMETER ( WANDS = .TRUE. )* ..* .. Local Scalars ..LOGICAL DTRONG, WEAKINTEGER I, IDUM, LINFO, MDOUBLE PRECISION BQRA21, BRQA21, DDUM, DNORM, DSCALE, DSUM, EPS,$ F, G, SA, SB, SCALE, SMLNUM, SS, THRESH, WS* ..* .. Local Arrays ..INTEGER IWORK( LDST )DOUBLE PRECISION AI( 2 ), AR( 2 ), BE( 2 ), IR( LDST, LDST ),$ IRCOP( LDST, LDST ), LI( LDST, LDST ),$ LICOP( LDST, LDST ), S( LDST, LDST ),$ SCPY( LDST, LDST ), T( LDST, LDST ),$ TAUL( LDST ), TAUR( LDST ), TCPY( LDST, LDST )* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. External Subroutines ..EXTERNAL DGEMM, DGEQR2, DGERQ2, DLACPY, DLAGV2, DLARTG,$ DLASET, DLASSQ, DORG2R, DORGR2, DORM2R, DORMR2,$ DROT, DSCAL, DTGSY2* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..*INFO = 0** Quick return if possible*IF( N.LE.1 .OR. N1.LE.0 .OR. N2.LE.0 )$ RETURNIF( N1.GT.N .OR. ( J1+N1 ).GT.N )$ RETURNM = N1 + N2IF( LWORK.LT.MAX( 1, N*M, M*M*2 ) ) THENINFO = -16WORK( 1 ) = MAX( 1, N*M, M*M*2 )RETURNEND IF*WEAK = .FALSE.DTRONG = .FALSE.** Make a local copy of selected block*CALL DLASET( 'Full', LDST, LDST, ZERO, ZERO, LI, LDST )CALL DLASET( 'Full', LDST, LDST, ZERO, ZERO, IR, LDST )CALL DLACPY( 'Full', M, M, A( J1, J1 ), LDA, S, LDST )CALL DLACPY( 'Full', M, M, B( J1, J1 ), LDB, T, LDST )** Compute threshold for testing acceptance of swapping.*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSDSCALE = ZERODSUM = ONECALL DLACPY( 'Full', M, M, S, LDST, WORK, M )CALL DLASSQ( M*M, WORK, 1, DSCALE, DSUM )CALL DLACPY( 'Full', M, M, T, LDST, WORK, M )CALL DLASSQ( M*M, WORK, 1, DSCALE, DSUM )DNORM = DSCALE*SQRT( DSUM )** THRES has been changed from* THRESH = MAX( TEN*EPS*SA, SMLNUM )* to* THRESH = MAX( TWENTY*EPS*SA, SMLNUM )* on 04/01/10.* "Bug" reported by Ondra Kamenik, confirmed by Julie Langou, fixed by* Jim Demmel and Guillaume Revy. See forum post 1783.*THRESH = MAX( TWENTY*EPS*DNORM, SMLNUM )*IF( M.EQ.2 ) THEN** CASE 1: Swap 1-by-1 and 1-by-1 blocks.** Compute orthogonal QL and RQ that swap 1-by-1 and 1-by-1 blocks* using Givens rotations and perform the swap tentatively.*F = S( 2, 2 )*T( 1, 1 ) - T( 2, 2 )*S( 1, 1 )G = S( 2, 2 )*T( 1, 2 ) - T( 2, 2 )*S( 1, 2 )SB = ABS( T( 2, 2 ) )SA = ABS( S( 2, 2 ) )CALL DLARTG( F, G, IR( 1, 2 ), IR( 1, 1 ), DDUM )IR( 2, 1 ) = -IR( 1, 2 )IR( 2, 2 ) = IR( 1, 1 )CALL DROT( 2, S( 1, 1 ), 1, S( 1, 2 ), 1, IR( 1, 1 ),$ IR( 2, 1 ) )CALL DROT( 2, T( 1, 1 ), 1, T( 1, 2 ), 1, IR( 1, 1 ),$ IR( 2, 1 ) )IF( SA.GE.SB ) THENCALL DLARTG( S( 1, 1 ), S( 2, 1 ), LI( 1, 1 ), LI( 2, 1 ),$ DDUM )ELSECALL DLARTG( T( 1, 1 ), T( 2, 1 ), LI( 1, 1 ), LI( 2, 1 ),$ DDUM )END IFCALL DROT( 2, S( 1, 1 ), LDST, S( 2, 1 ), LDST, LI( 1, 1 ),$ LI( 2, 1 ) )CALL DROT( 2, T( 1, 1 ), LDST, T( 2, 1 ), LDST, LI( 1, 1 ),$ LI( 2, 1 ) )LI( 2, 2 ) = LI( 1, 1 )LI( 1, 2 ) = -LI( 2, 1 )** Weak stability test:* |S21| + |T21| <= O(EPS * F-norm((S, T)))*WS = ABS( S( 2, 1 ) ) + ABS( T( 2, 1 ) )WEAK = WS.LE.THRESHIF( .NOT.WEAK )$ GO TO 70*IF( WANDS ) THEN** Strong stability test:* F-norm((A-QL**T*S*QR, B-QL**T*T*QR)) <= O(EPS*F-norm((A,B)))*CALL DLACPY( 'Full', M, M, A( J1, J1 ), LDA, WORK( M*M+1 ),$ M )CALL DGEMM( 'N', 'N', M, M, M, ONE, LI, LDST, S, LDST, ZERO,$ WORK, M )CALL DGEMM( 'N', 'T', M, M, M, -ONE, WORK, M, IR, LDST, ONE,$ WORK( M*M+1 ), M )DSCALE = ZERODSUM = ONECALL DLASSQ( M*M, WORK( M*M+1 ), 1, DSCALE, DSUM )*CALL DLACPY( 'Full', M, M, B( J1, J1 ), LDB, WORK( M*M+1 ),$ M )CALL DGEMM( 'N', 'N', M, M, M, ONE, LI, LDST, T, LDST, ZERO,$ WORK, M )CALL DGEMM( 'N', 'T', M, M, M, -ONE, WORK, M, IR, LDST, ONE,$ WORK( M*M+1 ), M )CALL DLASSQ( M*M, WORK( M*M+1 ), 1, DSCALE, DSUM )SS = DSCALE*SQRT( DSUM )DTRONG = SS.LE.THRESHIF( .NOT.DTRONG )$ GO TO 70END IF** Update (A(J1:J1+M-1, M+J1:N), B(J1:J1+M-1, M+J1:N)) and* (A(1:J1-1, J1:J1+M), B(1:J1-1, J1:J1+M)).*CALL DROT( J1+1, A( 1, J1 ), 1, A( 1, J1+1 ), 1, IR( 1, 1 ),$ IR( 2, 1 ) )CALL DROT( J1+1, B( 1, J1 ), 1, B( 1, J1+1 ), 1, IR( 1, 1 ),$ IR( 2, 1 ) )CALL DROT( N-J1+1, A( J1, J1 ), LDA, A( J1+1, J1 ), LDA,$ LI( 1, 1 ), LI( 2, 1 ) )CALL DROT( N-J1+1, B( J1, J1 ), LDB, B( J1+1, J1 ), LDB,$ LI( 1, 1 ), LI( 2, 1 ) )** Set N1-by-N2 (2,1) - blocks to ZERO.*A( J1+1, J1 ) = ZEROB( J1+1, J1 ) = ZERO** Accumulate transformations into Q and Z if requested.*IF( WANTZ )$ CALL DROT( N, Z( 1, J1 ), 1, Z( 1, J1+1 ), 1, IR( 1, 1 ),$ IR( 2, 1 ) )IF( WANTQ )$ CALL DROT( N, Q( 1, J1 ), 1, Q( 1, J1+1 ), 1, LI( 1, 1 ),$ LI( 2, 1 ) )** Exit with INFO = 0 if swap was successfully performed.*RETURN*ELSE** CASE 2: Swap 1-by-1 and 2-by-2 blocks, or 2-by-2* and 2-by-2 blocks.** Solve the generalized Sylvester equation* S11 * R - L * S22 = SCALE * S12* T11 * R - L * T22 = SCALE * T12* for R and L. Solutions in LI and IR.*CALL DLACPY( 'Full', N1, N2, T( 1, N1+1 ), LDST, LI, LDST )CALL DLACPY( 'Full', N1, N2, S( 1, N1+1 ), LDST,$ IR( N2+1, N1+1 ), LDST )CALL DTGSY2( 'N', 0, N1, N2, S, LDST, S( N1+1, N1+1 ), LDST,$ IR( N2+1, N1+1 ), LDST, T, LDST, T( N1+1, N1+1 ),$ LDST, LI, LDST, SCALE, DSUM, DSCALE, IWORK, IDUM,$ LINFO )** Compute orthogonal matrix QL:** QL**T * LI = [ TL ]* [ 0 ]* where* LI = [ -L ]* [ SCALE * identity(N2) ]*DO 10 I = 1, N2CALL DSCAL( N1, -ONE, LI( 1, I ), 1 )LI( N1+I, I ) = SCALE10 CONTINUECALL DGEQR2( M, N2, LI, LDST, TAUL, WORK, LINFO )IF( LINFO.NE.0 )$ GO TO 70CALL DORG2R( M, M, N2, LI, LDST, TAUL, WORK, LINFO )IF( LINFO.NE.0 )$ GO TO 70** Compute orthogonal matrix RQ:** IR * RQ**T = [ 0 TR],** where IR = [ SCALE * identity(N1), R ]*DO 20 I = 1, N1IR( N2+I, I ) = SCALE20 CONTINUECALL DGERQ2( N1, M, IR( N2+1, 1 ), LDST, TAUR, WORK, LINFO )IF( LINFO.NE.0 )$ GO TO 70CALL DORGR2( M, M, N1, IR, LDST, TAUR, WORK, LINFO )IF( LINFO.NE.0 )$ GO TO 70** Perform the swapping tentatively:*CALL DGEMM( 'T', 'N', M, M, M, ONE, LI, LDST, S, LDST, ZERO,$ WORK, M )CALL DGEMM( 'N', 'T', M, M, M, ONE, WORK, M, IR, LDST, ZERO, S,$ LDST )CALL DGEMM( 'T', 'N', M, M, M, ONE, LI, LDST, T, LDST, ZERO,$ WORK, M )CALL DGEMM( 'N', 'T', M, M, M, ONE, WORK, M, IR, LDST, ZERO, T,$ LDST )CALL DLACPY( 'F', M, M, S, LDST, SCPY, LDST )CALL DLACPY( 'F', M, M, T, LDST, TCPY, LDST )CALL DLACPY( 'F', M, M, IR, LDST, IRCOP, LDST )CALL DLACPY( 'F', M, M, LI, LDST, LICOP, LDST )** Triangularize the B-part by an RQ factorization.* Apply transformation (from left) to A-part, giving S.*CALL DGERQ2( M, M, T, LDST, TAUR, WORK, LINFO )IF( LINFO.NE.0 )$ GO TO 70CALL DORMR2( 'R', 'T', M, M, M, T, LDST, TAUR, S, LDST, WORK,$ LINFO )IF( LINFO.NE.0 )$ GO TO 70CALL DORMR2( 'L', 'N', M, M, M, T, LDST, TAUR, IR, LDST, WORK,$ LINFO )IF( LINFO.NE.0 )$ GO TO 70** Compute F-norm(S21) in BRQA21. (T21 is 0.)*DSCALE = ZERODSUM = ONEDO 30 I = 1, N2CALL DLASSQ( N1, S( N2+1, I ), 1, DSCALE, DSUM )30 CONTINUEBRQA21 = DSCALE*SQRT( DSUM )** Triangularize the B-part by a QR factorization.* Apply transformation (from right) to A-part, giving S.*CALL DGEQR2( M, M, TCPY, LDST, TAUL, WORK, LINFO )IF( LINFO.NE.0 )$ GO TO 70CALL DORM2R( 'L', 'T', M, M, M, TCPY, LDST, TAUL, SCPY, LDST,$ WORK, INFO )CALL DORM2R( 'R', 'N', M, M, M, TCPY, LDST, TAUL, LICOP, LDST,$ WORK, INFO )IF( LINFO.NE.0 )$ GO TO 70** Compute F-norm(S21) in BQRA21. (T21 is 0.)*DSCALE = ZERODSUM = ONEDO 40 I = 1, N2CALL DLASSQ( N1, SCPY( N2+1, I ), 1, DSCALE, DSUM )40 CONTINUEBQRA21 = DSCALE*SQRT( DSUM )** Decide which method to use.* Weak stability test:* F-norm(S21) <= O(EPS * F-norm((S, T)))*IF( BQRA21.LE.BRQA21 .AND. BQRA21.LE.THRESH ) THENCALL DLACPY( 'F', M, M, SCPY, LDST, S, LDST )CALL DLACPY( 'F', M, M, TCPY, LDST, T, LDST )CALL DLACPY( 'F', M, M, IRCOP, LDST, IR, LDST )CALL DLACPY( 'F', M, M, LICOP, LDST, LI, LDST )ELSE IF( BRQA21.GE.THRESH ) THENGO TO 70END IF** Set lower triangle of B-part to zero*CALL DLASET( 'Lower', M-1, M-1, ZERO, ZERO, T(2,1), LDST )*IF( WANDS ) THEN** Strong stability test:* F-norm((A-QL*S*QR**T, B-QL*T*QR**T)) <= O(EPS*F-norm((A,B)))*CALL DLACPY( 'Full', M, M, A( J1, J1 ), LDA, WORK( M*M+1 ),$ M )CALL DGEMM( 'N', 'N', M, M, M, ONE, LI, LDST, S, LDST, ZERO,$ WORK, M )CALL DGEMM( 'N', 'N', M, M, M, -ONE, WORK, M, IR, LDST, ONE,$ WORK( M*M+1 ), M )DSCALE = ZERODSUM = ONECALL DLASSQ( M*M, WORK( M*M+1 ), 1, DSCALE, DSUM )*CALL DLACPY( 'Full', M, M, B( J1, J1 ), LDB, WORK( M*M+1 ),$ M )CALL DGEMM( 'N', 'N', M, M, M, ONE, LI, LDST, T, LDST, ZERO,$ WORK, M )CALL DGEMM( 'N', 'N', M, M, M, -ONE, WORK, M, IR, LDST, ONE,$ WORK( M*M+1 ), M )CALL DLASSQ( M*M, WORK( M*M+1 ), 1, DSCALE, DSUM )SS = DSCALE*SQRT( DSUM )DTRONG = ( SS.LE.THRESH )IF( .NOT.DTRONG )$ GO TO 70*END IF** If the swap is accepted ("weakly" and "strongly"), apply the* transformations and set N1-by-N2 (2,1)-block to zero.*CALL DLASET( 'Full', N1, N2, ZERO, ZERO, S(N2+1,1), LDST )** copy back M-by-M diagonal block starting at index J1 of (A, B)*CALL DLACPY( 'F', M, M, S, LDST, A( J1, J1 ), LDA )CALL DLACPY( 'F', M, M, T, LDST, B( J1, J1 ), LDB )CALL DLASET( 'Full', LDST, LDST, ZERO, ZERO, T, LDST )** Standardize existing 2-by-2 blocks.*CALL DLASET( 'Full', M, M, ZERO, ZERO, WORK, M )WORK( 1 ) = ONET( 1, 1 ) = ONEIDUM = LWORK - M*M - 2IF( N2.GT.1 ) THENCALL DLAGV2( A( J1, J1 ), LDA, B( J1, J1 ), LDB, AR, AI, BE,$ WORK( 1 ), WORK( 2 ), T( 1, 1 ), T( 2, 1 ) )WORK( M+1 ) = -WORK( 2 )WORK( M+2 ) = WORK( 1 )T( N2, N2 ) = T( 1, 1 )T( 1, 2 ) = -T( 2, 1 )END IFWORK( M*M ) = ONET( M, M ) = ONE*IF( N1.GT.1 ) THENCALL DLAGV2( A( J1+N2, J1+N2 ), LDA, B( J1+N2, J1+N2 ), LDB,$ TAUR, TAUL, WORK( M*M+1 ), WORK( N2*M+N2+1 ),$ WORK( N2*M+N2+2 ), T( N2+1, N2+1 ),$ T( M, M-1 ) )WORK( M*M ) = WORK( N2*M+N2+1 )WORK( M*M-1 ) = -WORK( N2*M+N2+2 )T( M, M ) = T( N2+1, N2+1 )T( M-1, M ) = -T( M, M-1 )END IFCALL DGEMM( 'T', 'N', N2, N1, N2, ONE, WORK, M, A( J1, J1+N2 ),$ LDA, ZERO, WORK( M*M+1 ), N2 )CALL DLACPY( 'Full', N2, N1, WORK( M*M+1 ), N2, A( J1, J1+N2 ),$ LDA )CALL DGEMM( 'T', 'N', N2, N1, N2, ONE, WORK, M, B( J1, J1+N2 ),$ LDB, ZERO, WORK( M*M+1 ), N2 )CALL DLACPY( 'Full', N2, N1, WORK( M*M+1 ), N2, B( J1, J1+N2 ),$ LDB )CALL DGEMM( 'N', 'N', M, M, M, ONE, LI, LDST, WORK, M, ZERO,$ WORK( M*M+1 ), M )CALL DLACPY( 'Full', M, M, WORK( M*M+1 ), M, LI, LDST )CALL DGEMM( 'N', 'N', N2, N1, N1, ONE, A( J1, J1+N2 ), LDA,$ T( N2+1, N2+1 ), LDST, ZERO, WORK, N2 )CALL DLACPY( 'Full', N2, N1, WORK, N2, A( J1, J1+N2 ), LDA )CALL DGEMM( 'N', 'N', N2, N1, N1, ONE, B( J1, J1+N2 ), LDB,$ T( N2+1, N2+1 ), LDST, ZERO, WORK, N2 )CALL DLACPY( 'Full', N2, N1, WORK, N2, B( J1, J1+N2 ), LDB )CALL DGEMM( 'T', 'N', M, M, M, ONE, IR, LDST, T, LDST, ZERO,$ WORK, M )CALL DLACPY( 'Full', M, M, WORK, M, IR, LDST )** Accumulate transformations into Q and Z if requested.*IF( WANTQ ) THENCALL DGEMM( 'N', 'N', N, M, M, ONE, Q( 1, J1 ), LDQ, LI,$ LDST, ZERO, WORK, N )CALL DLACPY( 'Full', N, M, WORK, N, Q( 1, J1 ), LDQ )*END IF*IF( WANTZ ) THENCALL DGEMM( 'N', 'N', N, M, M, ONE, Z( 1, J1 ), LDZ, IR,$ LDST, ZERO, WORK, N )CALL DLACPY( 'Full', N, M, WORK, N, Z( 1, J1 ), LDZ )*END IF** Update (A(J1:J1+M-1, M+J1:N), B(J1:J1+M-1, M+J1:N)) and* (A(1:J1-1, J1:J1+M), B(1:J1-1, J1:J1+M)).*I = J1 + MIF( I.LE.N ) THENCALL DGEMM( 'T', 'N', M, N-I+1, M, ONE, LI, LDST,$ A( J1, I ), LDA, ZERO, WORK, M )CALL DLACPY( 'Full', M, N-I+1, WORK, M, A( J1, I ), LDA )CALL DGEMM( 'T', 'N', M, N-I+1, M, ONE, LI, LDST,$ B( J1, I ), LDB, ZERO, WORK, M )CALL DLACPY( 'Full', M, N-I+1, WORK, M, B( J1, I ), LDB )END IFI = J1 - 1IF( I.GT.0 ) THENCALL DGEMM( 'N', 'N', I, M, M, ONE, A( 1, J1 ), LDA, IR,$ LDST, ZERO, WORK, I )CALL DLACPY( 'Full', I, M, WORK, I, A( 1, J1 ), LDA )CALL DGEMM( 'N', 'N', I, M, M, ONE, B( 1, J1 ), LDB, IR,$ LDST, ZERO, WORK, I )CALL DLACPY( 'Full', I, M, WORK, I, B( 1, J1 ), LDB )END IF** Exit with INFO = 0 if swap was successfully performed.*RETURN*END IF** Exit with INFO = 1 if swap was rejected.*70 CONTINUE*INFO = 1RETURN** End of DTGEX2*END*> \brief \b DTGEXC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGEXC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgexc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgexc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgexc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGEXC( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,* LDZ, IFST, ILST, WORK, LWORK, INFO )** .. Scalar Arguments ..* LOGICAL WANTQ, WANTZ* INTEGER IFST, ILST, INFO, LDA, LDB, LDQ, LDZ, LWORK, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),* $ WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGEXC reorders the generalized real Schur decomposition of a real*> matrix pair (A,B) using an orthogonal equivalence transformation*>*> (A, B) = Q * (A, B) * Z**T,*>*> so that the diagonal block of (A, B) with row index IFST is moved*> to row ILST.*>*> (A, B) must be in generalized real Schur canonical form (as returned*> by DGGES), i.e. A is block upper triangular with 1-by-1 and 2-by-2*> diagonal blocks. B is upper triangular.*>*> Optionally, the matrices Q and Z of generalized Schur vectors are*> updated.*>*> Q(in) * A(in) * Z(in)**T = Q(out) * A(out) * Z(out)**T*> Q(in) * B(in) * Z(in)**T = Q(out) * B(out) * Z(out)**T*>*> \endverbatim** Arguments:* ==========**> \param[in] WANTQ*> \verbatim*> WANTQ is LOGICAL*> .TRUE. : update the left transformation matrix Q;*> .FALSE.: do not update Q.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> .TRUE. : update the right transformation matrix Z;*> .FALSE.: do not update Z.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the matrix A in generalized real Schur canonical*> form.*> On exit, the updated matrix A, again in generalized*> real Schur canonical form.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the matrix B in generalized real Schur canonical*> form (A,B).*> On exit, the updated matrix B, again in generalized*> real Schur canonical form (A,B).*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if WANTQ = .TRUE., the orthogonal matrix Q.*> On exit, the updated matrix Q.*> If WANTQ = .FALSE., Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= 1.*> If WANTQ = .TRUE., LDQ >= N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> On entry, if WANTZ = .TRUE., the orthogonal matrix Z.*> On exit, the updated matrix Z.*> If WANTZ = .FALSE., Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1.*> If WANTZ = .TRUE., LDZ >= N.*> \endverbatim*>*> \param[in,out] IFST*> \verbatim*> IFST is INTEGER*> \endverbatim*>*> \param[in,out] ILST*> \verbatim*> ILST is INTEGER*> Specify the reordering of the diagonal blocks of (A, B).*> The block with row index IFST is moved to row ILST, by a*> sequence of swapping between adjacent blocks.*> On exit, if IFST pointed on entry to the second row of*> a 2-by-2 block, it is changed to point to the first row;*> ILST always points to the first row of the block in its*> final position (which may differ from its input value by*> +1 or -1). 1 <= IFST, ILST <= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> LWORK >= 1 when N <= 1, otherwise LWORK >= 4*N + 16.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> =0: successful exit.*> <0: if INFO = -i, the i-th argument had an illegal value.*> =1: The transformed matrix pair (A, B) would be too far*> from generalized Schur form; the problem is ill-*> conditioned. (A, B) may have been partially reordered,*> and ILST points to the first row of the current*> position of the block being moved.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleGEcomputational**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.**> \par References:* ================*>*> \verbatim*>*> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the*> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in*> M.S. Moonen et al (eds), Linear Algebra for Large Scale and*> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.*> \endverbatim*>* =====================================================================SUBROUTINE DTGEXC( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, IFST, ILST, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..LOGICAL WANTQ, WANTZINTEGER IFST, ILST, INFO, LDA, LDB, LDQ, LDZ, LWORK, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),$ WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER HERE, LWMIN, NBF, NBL, NBNEXT* ..* .. External Subroutines ..EXTERNAL DTGEX2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Decode and test input arguments.*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDQ.LT.1 .OR. WANTQ .AND. ( LDQ.LT.MAX( 1, N ) ) ) THENINFO = -9ELSE IF( LDZ.LT.1 .OR. WANTZ .AND. ( LDZ.LT.MAX( 1, N ) ) ) THENINFO = -11ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THENINFO = -12ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THENINFO = -13END IF*IF( INFO.EQ.0 ) THENIF( N.LE.1 ) THENLWMIN = 1ELSELWMIN = 4*N + 16END IFWORK(1) = LWMIN*IF (LWORK.LT.LWMIN .AND. .NOT.LQUERY) THENINFO = -15END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTGEXC', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.LE.1 )$ RETURN** Determine the first row of the specified block and find out* if it is 1-by-1 or 2-by-2.*IF( IFST.GT.1 ) THENIF( A( IFST, IFST-1 ).NE.ZERO )$ IFST = IFST - 1END IFNBF = 1IF( IFST.LT.N ) THENIF( A( IFST+1, IFST ).NE.ZERO )$ NBF = 2END IF** Determine the first row of the final block* and find out if it is 1-by-1 or 2-by-2.*IF( ILST.GT.1 ) THENIF( A( ILST, ILST-1 ).NE.ZERO )$ ILST = ILST - 1END IFNBL = 1IF( ILST.LT.N ) THENIF( A( ILST+1, ILST ).NE.ZERO )$ NBL = 2END IFIF( IFST.EQ.ILST )$ RETURN*IF( IFST.LT.ILST ) THEN** Update ILST.*IF( NBF.EQ.2 .AND. NBL.EQ.1 )$ ILST = ILST - 1IF( NBF.EQ.1 .AND. NBL.EQ.2 )$ ILST = ILST + 1*HERE = IFST*10 CONTINUE** Swap with next one below.*IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN** Current block either 1-by-1 or 2-by-2.*NBNEXT = 1IF( HERE+NBF+1.LE.N ) THENIF( A( HERE+NBF+1, HERE+NBF ).NE.ZERO )$ NBNEXT = 2END IFCALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, HERE, NBF, NBNEXT, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + NBNEXT** Test if 2-by-2 block breaks into two 1-by-1 blocks.*IF( NBF.EQ.2 ) THENIF( A( HERE+1, HERE ).EQ.ZERO )$ NBF = 3END IF*ELSE** Current block consists of two 1-by-1 blocks, each of which* must be swapped individually.*NBNEXT = 1IF( HERE+3.LE.N ) THENIF( A( HERE+3, HERE+2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, HERE+1, 1, NBNEXT, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFIF( NBNEXT.EQ.1 ) THEN** Swap two 1-by-1 blocks.*CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, HERE, 1, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + 1*ELSE** Recompute NBNEXT in case of 2-by-2 split.*IF( A( HERE+2, HERE+1 ).EQ.ZERO )$ NBNEXT = 1IF( NBNEXT.EQ.2 ) THEN** 2-by-2 block did not split.*CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, HERE, 1, NBNEXT, WORK, LWORK,$ INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + 2ELSE** 2-by-2 block did split.*CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + 1CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + 1END IF*END IFEND IFIF( HERE.LT.ILST )$ GO TO 10ELSEHERE = IFST*20 CONTINUE** Swap with next one below.*IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN** Current block either 1-by-1 or 2-by-2.*NBNEXT = 1IF( HERE.GE.3 ) THENIF( A( HERE-1, HERE-2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, HERE-NBNEXT, NBNEXT, NBF, WORK, LWORK,$ INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - NBNEXT** Test if 2-by-2 block breaks into two 1-by-1 blocks.*IF( NBF.EQ.2 ) THENIF( A( HERE+1, HERE ).EQ.ZERO )$ NBF = 3END IF*ELSE** Current block consists of two 1-by-1 blocks, each of which* must be swapped individually.*NBNEXT = 1IF( HERE.GE.3 ) THENIF( A( HERE-1, HERE-2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, HERE-NBNEXT, NBNEXT, 1, WORK, LWORK,$ INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFIF( NBNEXT.EQ.1 ) THEN** Swap two 1-by-1 blocks.*CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,$ LDZ, HERE, NBNEXT, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - 1ELSE** Recompute NBNEXT in case of 2-by-2 split.*IF( A( HERE, HERE-1 ).EQ.ZERO )$ NBNEXT = 1IF( NBNEXT.EQ.2 ) THEN** 2-by-2 block did not split.*CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, HERE-1, 2, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - 2ELSE** 2-by-2 block did split.*CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - 1CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - 1END IFEND IFEND IFIF( HERE.GT.ILST )$ GO TO 20END IFILST = HEREWORK( 1 ) = LWMINRETURN** End of DTGEXC*END*> \brief \b DTGSEN** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGSEN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsen.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsen.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsen.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGSEN( IJOB, WANTQ, WANTZ, SELECT, N, A, LDA, B, LDB,* ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, M, PL,* PR, DIF, WORK, LWORK, IWORK, LIWORK, INFO )** .. Scalar Arguments ..* LOGICAL WANTQ, WANTZ* INTEGER IJOB, INFO, LDA, LDB, LDQ, LDZ, LIWORK, LWORK,* $ M, N* DOUBLE PRECISION PL, PR* ..* .. Array Arguments ..* LOGICAL SELECT( * )* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),* $ B( LDB, * ), BETA( * ), DIF( * ), Q( LDQ, * ),* $ WORK( * ), Z( LDZ, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGSEN reorders the generalized real Schur decomposition of a real*> matrix pair (A, B) (in terms of an orthonormal equivalence trans-*> formation Q**T * (A, B) * Z), so that a selected cluster of eigenvalues*> appears in the leading diagonal blocks of the upper quasi-triangular*> matrix A and the upper triangular B. The leading columns of Q and*> Z form orthonormal bases of the corresponding left and right eigen-*> spaces (deflating subspaces). (A, B) must be in generalized real*> Schur canonical form (as returned by DGGES), i.e. A is block upper*> triangular with 1-by-1 and 2-by-2 diagonal blocks. B is upper*> triangular.*>*> DTGSEN also computes the generalized eigenvalues*>*> w(j) = (ALPHAR(j) + i*ALPHAI(j))/BETA(j)*>*> of the reordered matrix pair (A, B).*>*> Optionally, DTGSEN computes the estimates of reciprocal condition*> numbers for eigenvalues and eigenspaces. These are Difu[(A11,B11),*> (A22,B22)] and Difl[(A11,B11), (A22,B22)], i.e. the separation(s)*> between the matrix pairs (A11, B11) and (A22,B22) that correspond to*> the selected cluster and the eigenvalues outside the cluster, resp.,*> and norms of "projections" onto left and right eigenspaces w.r.t.*> the selected cluster in the (1,1)-block.*> \endverbatim** Arguments:* ==========**> \param[in] IJOB*> \verbatim*> IJOB is INTEGER*> Specifies whether condition numbers are required for the*> cluster of eigenvalues (PL and PR) or the deflating subspaces*> (Difu and Difl):*> =0: Only reorder w.r.t. SELECT. No extras.*> =1: Reciprocal of norms of "projections" onto left and right*> eigenspaces w.r.t. the selected cluster (PL and PR).*> =2: Upper bounds on Difu and Difl. F-norm-based estimate*> (DIF(1:2)).*> =3: Estimate of Difu and Difl. 1-norm-based estimate*> (DIF(1:2)).*> About 5 times as expensive as IJOB = 2.*> =4: Compute PL, PR and DIF (i.e. 0, 1 and 2 above): Economic*> version to get it all.*> =5: Compute PL, PR and DIF (i.e. 0, 1 and 3 above)*> \endverbatim*>*> \param[in] WANTQ*> \verbatim*> WANTQ is LOGICAL*> .TRUE. : update the left transformation matrix Q;*> .FALSE.: do not update Q.*> \endverbatim*>*> \param[in] WANTZ*> \verbatim*> WANTZ is LOGICAL*> .TRUE. : update the right transformation matrix Z;*> .FALSE.: do not update Z.*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> SELECT specifies the eigenvalues in the selected cluster.*> To select a real eigenvalue w(j), SELECT(j) must be set to*> .TRUE.. To select a complex conjugate pair of eigenvalues*> w(j) and w(j+1), corresponding to a 2-by-2 diagonal block,*> either SELECT(j) or SELECT(j+1) or both must be set to*> .TRUE.; a complex conjugate pair of eigenvalues must be*> either both included in the cluster or both excluded.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension(LDA,N)*> On entry, the upper quasi-triangular matrix A, with (A, B) in*> generalized real Schur canonical form.*> On exit, A is overwritten by the reordered matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension(LDB,N)*> On entry, the upper triangular matrix B, with (A, B) in*> generalized real Schur canonical form.*> On exit, B is overwritten by the reordered matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] ALPHAR*> \verbatim*> ALPHAR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] ALPHAI*> \verbatim*> ALPHAI is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*>*> On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will*> be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i*> and BETA(j),j=1,...,N are the diagonals of the complex Schur*> form (S,T) that would result if the 2-by-2 diagonal blocks of*> the real generalized Schur form of (A,B) were further reduced*> to triangular form using complex unitary transformations.*> If ALPHAI(j) is zero, then the j-th eigenvalue is real; if*> positive, then the j-th and (j+1)-st eigenvalues are a*> complex conjugate pair, with ALPHAI(j+1) negative.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if WANTQ = .TRUE., Q is an N-by-N matrix.*> On exit, Q has been postmultiplied by the left orthogonal*> transformation matrix which reorder (A, B); The leading M*> columns of Q form orthonormal bases for the specified pair of*> left eigenspaces (deflating subspaces).*> If WANTQ = .FALSE., Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= 1;*> and if WANTQ = .TRUE., LDQ >= N.*> \endverbatim*>*> \param[in,out] Z*> \verbatim*> Z is DOUBLE PRECISION array, dimension (LDZ,N)*> On entry, if WANTZ = .TRUE., Z is an N-by-N matrix.*> On exit, Z has been postmultiplied by the left orthogonal*> transformation matrix which reorder (A, B); The leading M*> columns of Z form orthonormal bases for the specified pair of*> left eigenspaces (deflating subspaces).*> If WANTZ = .FALSE., Z is not referenced.*> \endverbatim*>*> \param[in] LDZ*> \verbatim*> LDZ is INTEGER*> The leading dimension of the array Z. LDZ >= 1;*> If WANTZ = .TRUE., LDZ >= N.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The dimension of the specified pair of left and right eigen-*> spaces (deflating subspaces). 0 <= M <= N.*> \endverbatim*>*> \param[out] PL*> \verbatim*> PL is DOUBLE PRECISION*> \endverbatim*>*> \param[out] PR*> \verbatim*> PR is DOUBLE PRECISION*>*> If IJOB = 1, 4 or 5, PL, PR are lower bounds on the*> reciprocal of the norm of "projections" onto left and right*> eigenspaces with respect to the selected cluster.*> 0 < PL, PR <= 1.*> If M = 0 or M = N, PL = PR = 1.*> If IJOB = 0, 2 or 3, PL and PR are not referenced.*> \endverbatim*>*> \param[out] DIF*> \verbatim*> DIF is DOUBLE PRECISION array, dimension (2).*> If IJOB >= 2, DIF(1:2) store the estimates of Difu and Difl.*> If IJOB = 2 or 4, DIF(1:2) are F-norm-based upper bounds on*> Difu and Difl. If IJOB = 3 or 5, DIF(1:2) are 1-norm-based*> estimates of Difu and Difl.*> If M = 0 or N, DIF(1:2) = F-norm([A, B]).*> If IJOB = 0 or 1, DIF is not referenced.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= 4*N+16.*> If IJOB = 1, 2 or 4, LWORK >= MAX(4*N+16, 2*M*(N-M)).*> If IJOB = 3 or 5, LWORK >= MAX(4*N+16, 4*M*(N-M)).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK. LIWORK >= 1.*> If IJOB = 1, 2 or 4, LIWORK >= N+6.*> If IJOB = 3 or 5, LIWORK >= MAX(2*M*(N-M), N+6).*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the IWORK array,*> returns this value as the first entry of the IWORK array, and*> no error message related to LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> =0: Successful exit.*> <0: If INFO = -i, the i-th argument had an illegal value.*> =1: Reordering of (A, B) failed because the transformed*> matrix pair (A, B) would be too far from generalized*> Schur form; the problem is very ill-conditioned.*> (A, B) may have been partially reordered.*> If requested, 0 is returned in DIF(*), PL and PR.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> DTGSEN first collects the selected eigenvalues by computing*> orthogonal U and W that move them to the top left corner of (A, B).*> In other words, the selected eigenvalues are the eigenvalues of*> (A11, B11) in:*>*> U**T*(A, B)*W = (A11 A12) (B11 B12) n1*> ( 0 A22),( 0 B22) n2*> n1 n2 n1 n2*>*> where N = n1+n2 and U**T means the transpose of U. The first n1 columns*> of U and W span the specified pair of left and right eigenspaces*> (deflating subspaces) of (A, B).*>*> If (A, B) has been obtained from the generalized real Schur*> decomposition of a matrix pair (C, D) = Q*(A, B)*Z**T, then the*> reordered generalized real Schur form of (C, D) is given by*>*> (C, D) = (Q*U)*(U**T*(A, B)*W)*(Z*W)**T,*>*> and the first n1 columns of Q*U and Z*W span the corresponding*> deflating subspaces of (C, D) (Q and Z store Q*U and Z*W, resp.).*>*> Note that if the selected eigenvalue is sufficiently ill-conditioned,*> then its value may differ significantly from its value before*> reordering.*>*> The reciprocal condition numbers of the left and right eigenspaces*> spanned by the first n1 columns of U and W (or Q*U and Z*W) may*> be returned in DIF(1:2), corresponding to Difu and Difl, resp.*>*> The Difu and Difl are defined as:*>*> Difu[(A11, B11), (A22, B22)] = sigma-min( Zu )*> and*> Difl[(A11, B11), (A22, B22)] = Difu[(A22, B22), (A11, B11)],*>*> where sigma-min(Zu) is the smallest singular value of the*> (2*n1*n2)-by-(2*n1*n2) matrix*>*> Zu = [ kron(In2, A11) -kron(A22**T, In1) ]*> [ kron(In2, B11) -kron(B22**T, In1) ].*>*> Here, Inx is the identity matrix of size nx and A22**T is the*> transpose of A22. kron(X, Y) is the Kronecker product between*> the matrices X and Y.*>*> When DIF(2) is small, small changes in (A, B) can cause large changes*> in the deflating subspace. An approximate (asymptotic) bound on the*> maximum angular error in the computed deflating subspaces is*>*> EPS * norm((A, B)) / DIF(2),*>*> where EPS is the machine precision.*>*> The reciprocal norm of the projectors on the left and right*> eigenspaces associated with (A11, B11) may be returned in PL and PR.*> They are computed as follows. First we compute L and R so that*> P*(A, B)*Q is block diagonal, where*>*> P = ( I -L ) n1 Q = ( I R ) n1*> ( 0 I ) n2 and ( 0 I ) n2*> n1 n2 n1 n2*>*> and (L, R) is the solution to the generalized Sylvester equation*>*> A11*R - L*A22 = -A12*> B11*R - L*B22 = -B12*>*> Then PL = (F-norm(L)**2+1)**(-1/2) and PR = (F-norm(R)**2+1)**(-1/2).*> An approximate (asymptotic) bound on the average absolute error of*> the selected eigenvalues is*>*> EPS * norm((A, B)) / PL.*>*> There are also global error bounds which valid for perturbations up*> to a certain restriction: A lower bound (x) on the smallest*> F-norm(E,F) for which an eigenvalue of (A11, B11) may move and*> coalesce with an eigenvalue of (A22, B22) under perturbation (E,F),*> (i.e. (A + E, B + F), is*>*> x = min(Difu,Difl)/((1/(PL*PL)+1/(PR*PR))**(1/2)+2*max(1/PL,1/PR)).*>*> An approximate bound on x can be computed from DIF(1:2), PL and PR.*>*> If y = ( F-norm(E,F) / x) <= 1, the angles between the perturbed*> (L', R') and unperturbed (L, R) left and right deflating subspaces*> associated with the selected cluster in the (1,1)-blocks can be*> bounded as*>*> max-angle(L, L') <= arctan( y * PL / (1 - y * (1 - PL * PL)**(1/2))*> max-angle(R, R') <= arctan( y * PR / (1 - y * (1 - PR * PR)**(1/2))*>*> See LAPACK User's Guide section 4.11 or the following references*> for more information.*>*> Note that if the default method for computing the Frobenius-norm-*> based estimate DIF is not wanted (see DLATDF), then the parameter*> IDIFJB (see below) should be changed from 3 to 4 (routine DLATDF*> (IJOB = 2 will be used)). See DTGSYL for more details.*> \endverbatim**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.**> \par References:* ================*>*> \verbatim*>*> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the*> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in*> M.S. Moonen et al (eds), Linear Algebra for Large Scale and*> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.*>*> [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified*> Eigenvalues of a Regular Matrix Pair (A, B) and Condition*> Estimation: Theory, Algorithms and Software,*> Report UMINF - 94.04, Department of Computing Science, Umea*> University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working*> Note 87. To appear in Numerical Algorithms, 1996.*>*> [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software*> for Solving the Generalized Sylvester Equation and Estimating the*> Separation between Regular Matrix Pairs, Report UMINF - 93.23,*> Department of Computing Science, Umea University, S-901 87 Umea,*> Sweden, December 1993, Revised April 1994, Also as LAPACK Working*> Note 75. To appear in ACM Trans. on Math. Software, Vol 22, No 1,*> 1996.*> \endverbatim*>* =====================================================================SUBROUTINE DTGSEN( IJOB, WANTQ, WANTZ, SELECT, N, A, LDA, B, LDB,$ ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, M, PL,$ PR, DIF, WORK, LWORK, IWORK, LIWORK, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..LOGICAL WANTQ, WANTZINTEGER IJOB, INFO, LDA, LDB, LDQ, LDZ, LIWORK, LWORK,$ M, NDOUBLE PRECISION PL, PR* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), ALPHAI( * ), ALPHAR( * ),$ B( LDB, * ), BETA( * ), DIF( * ), Q( LDQ, * ),$ WORK( * ), Z( LDZ, * )* ..** =====================================================================** .. Parameters ..INTEGER IDIFJBPARAMETER ( IDIFJB = 3 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, PAIR, SWAP, WANTD, WANTD1, WANTD2,$ WANTPINTEGER I, IERR, IJB, K, KASE, KK, KS, LIWMIN, LWMIN,$ MN2, N1, N2DOUBLE PRECISION DSCALE, DSUM, EPS, RDSCAL, SMLNUM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DLACN2, DLACPY, DLAG2, DLASSQ, DTGEXC, DTGSYL,$ XERBLA* ..* .. External Functions ..DOUBLE PRECISION DLAMCHEXTERNAL DLAMCH* ..* .. Intrinsic Functions ..INTRINSIC MAX, SIGN, SQRT* ..* .. Executable Statements ..** Decode and test the input parameters*INFO = 0LQUERY = ( LWORK.EQ.-1 .OR. LIWORK.EQ.-1 )*IF( IJOB.LT.0 .OR. IJOB.GT.5 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -14ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THENINFO = -16END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTGSEN', -INFO )RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSIERR = 0*WANTP = IJOB.EQ.1 .OR. IJOB.GE.4WANTD1 = IJOB.EQ.2 .OR. IJOB.EQ.4WANTD2 = IJOB.EQ.3 .OR. IJOB.EQ.5WANTD = WANTD1 .OR. WANTD2** Set M to the dimension of the specified pair of deflating* subspaces.*M = 0PAIR = .FALSE.IF( .NOT.LQUERY .OR. IJOB.NE.0 ) THENDO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSEIF( K.LT.N ) THENIF( A( K+1, K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) )$ M = M + 2END IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEEND IF*IF( IJOB.EQ.1 .OR. IJOB.EQ.2 .OR. IJOB.EQ.4 ) THENLWMIN = MAX( 1, 4*N+16, 2*M*( N-M ) )LIWMIN = MAX( 1, N+6 )ELSE IF( IJOB.EQ.3 .OR. IJOB.EQ.5 ) THENLWMIN = MAX( 1, 4*N+16, 4*M*( N-M ) )LIWMIN = MAX( 1, 2*M*( N-M ), N+6 )ELSELWMIN = MAX( 1, 4*N+16 )LIWMIN = 1END IF*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -22ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -24END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTGSEN', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible.*IF( M.EQ.N .OR. M.EQ.0 ) THENIF( WANTP ) THENPL = ONEPR = ONEEND IFIF( WANTD ) THENDSCALE = ZERODSUM = ONEDO 20 I = 1, NCALL DLASSQ( N, A( 1, I ), 1, DSCALE, DSUM )CALL DLASSQ( N, B( 1, I ), 1, DSCALE, DSUM )20 CONTINUEDIF( 1 ) = DSCALE*SQRT( DSUM )DIF( 2 ) = DIF( 1 )END IFGO TO 60END IF** Collect the selected blocks at the top-left corner of (A, B).*KS = 0PAIR = .FALSE.DO 30 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSE*SWAP = SELECT( K )IF( K.LT.N ) THENIF( A( K+1, K ).NE.ZERO ) THENPAIR = .TRUE.SWAP = SWAP .OR. SELECT( K+1 )END IFEND IF*IF( SWAP ) THENKS = KS + 1** Swap the K-th block to position KS.* Perform the reordering of diagonal blocks in (A, B)* by orthogonal transformation matrices and update* Q and Z accordingly (if requested):*KK = KIF( K.NE.KS )$ CALL DTGEXC( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,$ Z, LDZ, KK, KS, WORK, LWORK, IERR )*IF( IERR.GT.0 ) THEN** Swap is rejected: exit.*INFO = 1IF( WANTP ) THENPL = ZEROPR = ZEROEND IFIF( WANTD ) THENDIF( 1 ) = ZERODIF( 2 ) = ZEROEND IFGO TO 60END IF*IF( PAIR )$ KS = KS + 1END IFEND IF30 CONTINUEIF( WANTP ) THEN** Solve generalized Sylvester equation for R and L* and compute PL and PR.*N1 = MN2 = N - MI = N1 + 1IJB = 0CALL DLACPY( 'Full', N1, N2, A( 1, I ), LDA, WORK, N1 )CALL DLACPY( 'Full', N1, N2, B( 1, I ), LDB, WORK( N1*N2+1 ),$ N1 )CALL DTGSYL( 'N', IJB, N1, N2, A, LDA, A( I, I ), LDA, WORK,$ N1, B, LDB, B( I, I ), LDB, WORK( N1*N2+1 ), N1,$ DSCALE, DIF( 1 ), WORK( N1*N2*2+1 ),$ LWORK-2*N1*N2, IWORK, IERR )** Estimate the reciprocal of norms of "projections" onto left* and right eigenspaces.*RDSCAL = ZERODSUM = ONECALL DLASSQ( N1*N2, WORK, 1, RDSCAL, DSUM )PL = RDSCAL*SQRT( DSUM )IF( PL.EQ.ZERO ) THENPL = ONEELSEPL = DSCALE / ( SQRT( DSCALE*DSCALE / PL+PL )*SQRT( PL ) )END IFRDSCAL = ZERODSUM = ONECALL DLASSQ( N1*N2, WORK( N1*N2+1 ), 1, RDSCAL, DSUM )PR = RDSCAL*SQRT( DSUM )IF( PR.EQ.ZERO ) THENPR = ONEELSEPR = DSCALE / ( SQRT( DSCALE*DSCALE / PR+PR )*SQRT( PR ) )END IFEND IF*IF( WANTD ) THEN** Compute estimates of Difu and Difl.*IF( WANTD1 ) THENN1 = MN2 = N - MI = N1 + 1IJB = IDIFJB** Frobenius norm-based Difu-estimate.*CALL DTGSYL( 'N', IJB, N1, N2, A, LDA, A( I, I ), LDA, WORK,$ N1, B, LDB, B( I, I ), LDB, WORK( N1*N2+1 ),$ N1, DSCALE, DIF( 1 ), WORK( 2*N1*N2+1 ),$ LWORK-2*N1*N2, IWORK, IERR )** Frobenius norm-based Difl-estimate.*CALL DTGSYL( 'N', IJB, N2, N1, A( I, I ), LDA, A, LDA, WORK,$ N2, B( I, I ), LDB, B, LDB, WORK( N1*N2+1 ),$ N2, DSCALE, DIF( 2 ), WORK( 2*N1*N2+1 ),$ LWORK-2*N1*N2, IWORK, IERR )ELSE*** Compute 1-norm-based estimates of Difu and Difl using* reversed communication with DLACN2. In each step a* generalized Sylvester equation or a transposed variant* is solved.*KASE = 0N1 = MN2 = N - MI = N1 + 1IJB = 0MN2 = 2*N1*N2** 1-norm-based estimate of Difu.*40 CONTINUECALL DLACN2( MN2, WORK( MN2+1 ), WORK, IWORK, DIF( 1 ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Solve generalized Sylvester equation.*CALL DTGSYL( 'N', IJB, N1, N2, A, LDA, A( I, I ), LDA,$ WORK, N1, B, LDB, B( I, I ), LDB,$ WORK( N1*N2+1 ), N1, DSCALE, DIF( 1 ),$ WORK( 2*N1*N2+1 ), LWORK-2*N1*N2, IWORK,$ IERR )ELSE** Solve the transposed variant.*CALL DTGSYL( 'T', IJB, N1, N2, A, LDA, A( I, I ), LDA,$ WORK, N1, B, LDB, B( I, I ), LDB,$ WORK( N1*N2+1 ), N1, DSCALE, DIF( 1 ),$ WORK( 2*N1*N2+1 ), LWORK-2*N1*N2, IWORK,$ IERR )END IFGO TO 40END IFDIF( 1 ) = DSCALE / DIF( 1 )** 1-norm-based estimate of Difl.*50 CONTINUECALL DLACN2( MN2, WORK( MN2+1 ), WORK, IWORK, DIF( 2 ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Solve generalized Sylvester equation.*CALL DTGSYL( 'N', IJB, N2, N1, A( I, I ), LDA, A, LDA,$ WORK, N2, B( I, I ), LDB, B, LDB,$ WORK( N1*N2+1 ), N2, DSCALE, DIF( 2 ),$ WORK( 2*N1*N2+1 ), LWORK-2*N1*N2, IWORK,$ IERR )ELSE** Solve the transposed variant.*CALL DTGSYL( 'T', IJB, N2, N1, A( I, I ), LDA, A, LDA,$ WORK, N2, B( I, I ), LDB, B, LDB,$ WORK( N1*N2+1 ), N2, DSCALE, DIF( 2 ),$ WORK( 2*N1*N2+1 ), LWORK-2*N1*N2, IWORK,$ IERR )END IFGO TO 50END IFDIF( 2 ) = DSCALE / DIF( 2 )*END IFEND IF*60 CONTINUE** Compute generalized eigenvalues of reordered pair (A, B) and* normalize the generalized Schur form.*PAIR = .FALSE.DO 80 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSE*IF( K.LT.N ) THENIF( A( K+1, K ).NE.ZERO ) THENPAIR = .TRUE.END IFEND IF*IF( PAIR ) THEN** Compute the eigenvalue(s) at position K.*WORK( 1 ) = A( K, K )WORK( 2 ) = A( K+1, K )WORK( 3 ) = A( K, K+1 )WORK( 4 ) = A( K+1, K+1 )WORK( 5 ) = B( K, K )WORK( 6 ) = B( K+1, K )WORK( 7 ) = B( K, K+1 )WORK( 8 ) = B( K+1, K+1 )CALL DLAG2( WORK, 2, WORK( 5 ), 2, SMLNUM*EPS, BETA( K ),$ BETA( K+1 ), ALPHAR( K ), ALPHAR( K+1 ),$ ALPHAI( K ) )ALPHAI( K+1 ) = -ALPHAI( K )*ELSE*IF( SIGN( ONE, B( K, K ) ).LT.ZERO ) THEN** If B(K,K) is negative, make it positive*DO 70 I = 1, NA( K, I ) = -A( K, I )B( K, I ) = -B( K, I )IF( WANTQ ) Q( I, K ) = -Q( I, K )70 CONTINUEEND IF*ALPHAR( K ) = A( K, K )ALPHAI( K ) = ZEROBETA( K ) = B( K, K )*END IFEND IF80 CONTINUE*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DTGSEN*END*> \brief \b DTGSJA** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGSJA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsja.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsja.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsja.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B,* LDB, TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV,* Q, LDQ, WORK, NCYCLE, INFO )** .. Scalar Arguments ..* CHARACTER JOBQ, JOBU, JOBV* INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N,* $ NCYCLE, P* DOUBLE PRECISION TOLA, TOLB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), ALPHA( * ), B( LDB, * ),* $ BETA( * ), Q( LDQ, * ), U( LDU, * ),* $ V( LDV, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGSJA computes the generalized singular value decomposition (GSVD)*> of two real upper triangular (or trapezoidal) matrices A and B.*>*> On entry, it is assumed that matrices A and B have the following*> forms, which may be obtained by the preprocessing subroutine DGGSVP*> from a general M-by-N matrix A and P-by-N matrix B:*>*> N-K-L K L*> A = K ( 0 A12 A13 ) if M-K-L >= 0;*> L ( 0 0 A23 )*> M-K-L ( 0 0 0 )*>*> N-K-L K L*> A = K ( 0 A12 A13 ) if M-K-L < 0;*> M-K ( 0 0 A23 )*>*> N-K-L K L*> B = L ( 0 0 B13 )*> P-L ( 0 0 0 )*>*> where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular*> upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0,*> otherwise A23 is (M-K)-by-L upper trapezoidal.*>*> On exit,*>*> U**T *A*Q = D1*( 0 R ), V**T *B*Q = D2*( 0 R ),*>*> where U, V and Q are orthogonal matrices.*> R is a nonsingular upper triangular matrix, and D1 and D2 are*> ``diagonal'' matrices, which are of the following structures:*>*> If M-K-L >= 0,*>*> K L*> D1 = K ( I 0 )*> L ( 0 C )*> M-K-L ( 0 0 )*>*> K L*> D2 = L ( 0 S )*> P-L ( 0 0 )*>*> N-K-L K L*> ( 0 R ) = K ( 0 R11 R12 ) K*> L ( 0 0 R22 ) L*>*> where*>*> C = diag( ALPHA(K+1), ... , ALPHA(K+L) ),*> S = diag( BETA(K+1), ... , BETA(K+L) ),*> C**2 + S**2 = I.*>*> R is stored in A(1:K+L,N-K-L+1:N) on exit.*>*> If M-K-L < 0,*>*> K M-K K+L-M*> D1 = K ( I 0 0 )*> M-K ( 0 C 0 )*>*> K M-K K+L-M*> D2 = M-K ( 0 S 0 )*> K+L-M ( 0 0 I )*> P-L ( 0 0 0 )*>*> N-K-L K M-K K+L-M*> ( 0 R ) = K ( 0 R11 R12 R13 )*> M-K ( 0 0 R22 R23 )*> K+L-M ( 0 0 0 R33 )*>*> where*> C = diag( ALPHA(K+1), ... , ALPHA(M) ),*> S = diag( BETA(K+1), ... , BETA(M) ),*> C**2 + S**2 = I.*>*> R = ( R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N) and R33 is stored*> ( 0 R22 R23 )*> in B(M-K+1:L,N+M-K-L+1:N) on exit.*>*> The computation of the orthogonal transformation matrices U, V or Q*> is optional. These matrices may either be formed explicitly, or they*> may be postmultiplied into input matrices U1, V1, or Q1.*> \endverbatim** Arguments:* ==========**> \param[in] JOBU*> \verbatim*> JOBU is CHARACTER*1*> = 'U': U must contain an orthogonal matrix U1 on entry, and*> the product U1*U is returned;*> = 'I': U is initialized to the unit matrix, and the*> orthogonal matrix U is returned;*> = 'N': U is not computed.*> \endverbatim*>*> \param[in] JOBV*> \verbatim*> JOBV is CHARACTER*1*> = 'V': V must contain an orthogonal matrix V1 on entry, and*> the product V1*V is returned;*> = 'I': V is initialized to the unit matrix, and the*> orthogonal matrix V is returned;*> = 'N': V is not computed.*> \endverbatim*>*> \param[in] JOBQ*> \verbatim*> JOBQ is CHARACTER*1*> = 'Q': Q must contain an orthogonal matrix Q1 on entry, and*> the product Q1*Q is returned;*> = 'I': Q is initialized to the unit matrix, and the*> orthogonal matrix Q is returned;*> = 'N': Q is not computed.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] P*> \verbatim*> P is INTEGER*> The number of rows of the matrix B. P >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrices A and B. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*>*> K and L specify the subblocks in the input matrices A and B:*> A23 = A(K+1:MIN(K+L,M),N-L+1:N) and B13 = B(1:L,N-L+1:N)*> of A and B, whose GSVD is going to be computed by DTGSJA.*> See Further Details.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the M-by-N matrix A.*> On exit, A(N-K+1:N,1:MIN(K+L,M) ) contains the triangular*> matrix R or part of R. See Purpose for details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the P-by-N matrix B.*> On exit, if necessary, B(M-K+1:L,N+M-K-L+1:N) contains*> a part of R. See Purpose for details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,P).*> \endverbatim*>*> \param[in] TOLA*> \verbatim*> TOLA is DOUBLE PRECISION*> \endverbatim*>*> \param[in] TOLB*> \verbatim*> TOLB is DOUBLE PRECISION*>*> TOLA and TOLB are the convergence criteria for the Jacobi-*> Kogbetliantz iteration procedure. Generally, they are the*> same as used in the preprocessing step, say*> TOLA = max(M,N)*norm(A)*MAZHEPS,*> TOLB = max(P,N)*norm(B)*MAZHEPS.*> \endverbatim*>*> \param[out] ALPHA*> \verbatim*> ALPHA is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] BETA*> \verbatim*> BETA is DOUBLE PRECISION array, dimension (N)*>*> On exit, ALPHA and BETA contain the generalized singular*> value pairs of A and B;*> ALPHA(1:K) = 1,*> BETA(1:K) = 0,*> and if M-K-L >= 0,*> ALPHA(K+1:K+L) = diag(C),*> BETA(K+1:K+L) = diag(S),*> or if M-K-L < 0,*> ALPHA(K+1:M)= C, ALPHA(M+1:K+L)= 0*> BETA(K+1:M) = S, BETA(M+1:K+L) = 1.*> Furthermore, if K+L < N,*> ALPHA(K+L+1:N) = 0 and*> BETA(K+L+1:N) = 0.*> \endverbatim*>*> \param[in,out] U*> \verbatim*> U is DOUBLE PRECISION array, dimension (LDU,M)*> On entry, if JOBU = 'U', U must contain a matrix U1 (usually*> the orthogonal matrix returned by DGGSVP).*> On exit,*> if JOBU = 'I', U contains the orthogonal matrix U;*> if JOBU = 'U', U contains the product U1*U.*> If JOBU = 'N', U is not referenced.*> \endverbatim*>*> \param[in] LDU*> \verbatim*> LDU is INTEGER*> The leading dimension of the array U. LDU >= max(1,M) if*> JOBU = 'U'; LDU >= 1 otherwise.*> \endverbatim*>*> \param[in,out] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDV,P)*> On entry, if JOBV = 'V', V must contain a matrix V1 (usually*> the orthogonal matrix returned by DGGSVP).*> On exit,*> if JOBV = 'I', V contains the orthogonal matrix V;*> if JOBV = 'V', V contains the product V1*V.*> If JOBV = 'N', V is not referenced.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V. LDV >= max(1,P) if*> JOBV = 'V'; LDV >= 1 otherwise.*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if JOBQ = 'Q', Q must contain a matrix Q1 (usually*> the orthogonal matrix returned by DGGSVP).*> On exit,*> if JOBQ = 'I', Q contains the orthogonal matrix Q;*> if JOBQ = 'Q', Q contains the product Q1*Q.*> If JOBQ = 'N', Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= max(1,N) if*> JOBQ = 'Q'; LDQ >= 1 otherwise.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (2*N)*> \endverbatim*>*> \param[out] NCYCLE*> \verbatim*> NCYCLE is INTEGER*> The number of cycles required for convergence.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value.*> = 1: the procedure does not converge after MAXIT cycles.*> \endverbatim*>*> \verbatim*> Internal Parameters*> ===================*>*> MAXIT INTEGER*> MAXIT specifies the total loops that the iterative procedure*> may take. If after MAXIT cycles, the routine fails to*> converge, we return INFO = 1.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> DTGSJA essentially uses a variant of Kogbetliantz algorithm to reduce*> min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L*> matrix B13 to the form:*>*> U1**T *A13*Q1 = C1*R1; V1**T *B13*Q1 = S1*R1,*>*> where U1, V1 and Q1 are orthogonal matrix, and Z**T is the transpose*> of Z. C1 and S1 are diagonal matrices satisfying*>*> C1**2 + S1**2 = I,*>*> and R1 is an L-by-L nonsingular upper triangular matrix.*> \endverbatim*>* =====================================================================SUBROUTINE DTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B,$ LDB, TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV,$ Q, LDQ, WORK, NCYCLE, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER JOBQ, JOBU, JOBVINTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N,$ NCYCLE, PDOUBLE PRECISION TOLA, TOLB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), ALPHA( * ), B( LDB, * ),$ BETA( * ), Q( LDQ, * ), U( LDU, * ),$ V( LDV, * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER MAXITPARAMETER ( MAXIT = 40 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..*LOGICAL INITQ, INITU, INITV, UPPER, WANTQ, WANTU, WANTVINTEGER I, J, KCYCLEDOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, ERROR,$ GAMMA, RWK, SNQ, SNU, SNV, SSMIN* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DCOPY, DLAGS2, DLAPLL, DLARTG, DLASET, DROT,$ DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, MIN* ..* .. Executable Statements ..** Decode and test the input parameters*INITU = LSAME( JOBU, 'I' )WANTU = INITU .OR. LSAME( JOBU, 'U' )*INITV = LSAME( JOBV, 'I' )WANTV = INITV .OR. LSAME( JOBV, 'V' )*INITQ = LSAME( JOBQ, 'I' )WANTQ = INITQ .OR. LSAME( JOBQ, 'Q' )*INFO = 0IF( .NOT.( INITU .OR. WANTU .OR. LSAME( JOBU, 'N' ) ) ) THENINFO = -1ELSE IF( .NOT.( INITV .OR. WANTV .OR. LSAME( JOBV, 'N' ) ) ) THENINFO = -2ELSE IF( .NOT.( INITQ .OR. WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( P.LT.0 ) THENINFO = -5ELSE IF( N.LT.0 ) THENINFO = -6ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LDB.LT.MAX( 1, P ) ) THENINFO = -12ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THENINFO = -18ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THENINFO = -20ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -22END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTGSJA', -INFO )RETURNEND IF** Initialize U, V and Q, if necessary*IF( INITU )$ CALL DLASET( 'Full', M, M, ZERO, ONE, U, LDU )IF( INITV )$ CALL DLASET( 'Full', P, P, ZERO, ONE, V, LDV )IF( INITQ )$ CALL DLASET( 'Full', N, N, ZERO, ONE, Q, LDQ )** Loop until convergence*UPPER = .FALSE.DO 40 KCYCLE = 1, MAXIT*UPPER = .NOT.UPPER*DO 20 I = 1, L - 1DO 10 J = I + 1, L*A1 = ZEROA2 = ZEROA3 = ZEROIF( K+I.LE.M )$ A1 = A( K+I, N-L+I )IF( K+J.LE.M )$ A3 = A( K+J, N-L+J )*B1 = B( I, N-L+I )B3 = B( J, N-L+J )*IF( UPPER ) THENIF( K+I.LE.M )$ A2 = A( K+I, N-L+J )B2 = B( I, N-L+J )ELSEIF( K+J.LE.M )$ A2 = A( K+J, N-L+I )B2 = B( J, N-L+I )END IF*CALL DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU,$ CSV, SNV, CSQ, SNQ )** Update (K+I)-th and (K+J)-th rows of matrix A: U**T *A*IF( K+J.LE.M )$ CALL DROT( L, A( K+J, N-L+1 ), LDA, A( K+I, N-L+1 ),$ LDA, CSU, SNU )** Update I-th and J-th rows of matrix B: V**T *B*CALL DROT( L, B( J, N-L+1 ), LDB, B( I, N-L+1 ), LDB,$ CSV, SNV )** Update (N-L+I)-th and (N-L+J)-th columns of matrices* A and B: A*Q and B*Q*CALL DROT( MIN( K+L, M ), A( 1, N-L+J ), 1,$ A( 1, N-L+I ), 1, CSQ, SNQ )*CALL DROT( L, B( 1, N-L+J ), 1, B( 1, N-L+I ), 1, CSQ,$ SNQ )*IF( UPPER ) THENIF( K+I.LE.M )$ A( K+I, N-L+J ) = ZEROB( I, N-L+J ) = ZEROELSEIF( K+J.LE.M )$ A( K+J, N-L+I ) = ZEROB( J, N-L+I ) = ZEROEND IF** Update orthogonal matrices U, V, Q, if desired.*IF( WANTU .AND. K+J.LE.M )$ CALL DROT( M, U( 1, K+J ), 1, U( 1, K+I ), 1, CSU,$ SNU )*IF( WANTV )$ CALL DROT( P, V( 1, J ), 1, V( 1, I ), 1, CSV, SNV )*IF( WANTQ )$ CALL DROT( N, Q( 1, N-L+J ), 1, Q( 1, N-L+I ), 1, CSQ,$ SNQ )*10 CONTINUE20 CONTINUE*IF( .NOT.UPPER ) THEN** The matrices A13 and B13 were lower triangular at the start* of the cycle, and are now upper triangular.** Convergence test: test the parallelism of the corresponding* rows of A and B.*ERROR = ZERODO 30 I = 1, MIN( L, M-K )CALL DCOPY( L-I+1, A( K+I, N-L+I ), LDA, WORK, 1 )CALL DCOPY( L-I+1, B( I, N-L+I ), LDB, WORK( L+1 ), 1 )CALL DLAPLL( L-I+1, WORK, 1, WORK( L+1 ), 1, SSMIN )ERROR = MAX( ERROR, SSMIN )30 CONTINUE*IF( ABS( ERROR ).LE.MIN( TOLA, TOLB ) )$ GO TO 50END IF** End of cycle loop*40 CONTINUE** The algorithm has not converged after MAXIT cycles.*INFO = 1GO TO 100*50 CONTINUE** If ERROR <= MIN(TOLA,TOLB), then the algorithm has converged.* Compute the generalized singular value pairs (ALPHA, BETA), and* set the triangular matrix R to array A.*DO 60 I = 1, KALPHA( I ) = ONEBETA( I ) = ZERO60 CONTINUE*DO 70 I = 1, MIN( L, M-K )*A1 = A( K+I, N-L+I )B1 = B( I, N-L+I )*IF( A1.NE.ZERO ) THENGAMMA = B1 / A1** change sign if necessary*IF( GAMMA.LT.ZERO ) THENCALL DSCAL( L-I+1, -ONE, B( I, N-L+I ), LDB )IF( WANTV )$ CALL DSCAL( P, -ONE, V( 1, I ), 1 )END IF*CALL DLARTG( ABS( GAMMA ), ONE, BETA( K+I ), ALPHA( K+I ),$ RWK )*IF( ALPHA( K+I ).GE.BETA( K+I ) ) THENCALL DSCAL( L-I+1, ONE / ALPHA( K+I ), A( K+I, N-L+I ),$ LDA )ELSECALL DSCAL( L-I+1, ONE / BETA( K+I ), B( I, N-L+I ),$ LDB )CALL DCOPY( L-I+1, B( I, N-L+I ), LDB, A( K+I, N-L+I ),$ LDA )END IF*ELSE*ALPHA( K+I ) = ZEROBETA( K+I ) = ONECALL DCOPY( L-I+1, B( I, N-L+I ), LDB, A( K+I, N-L+I ),$ LDA )*END IF*70 CONTINUE** Post-assignment*DO 80 I = M + 1, K + LALPHA( I ) = ZEROBETA( I ) = ONE80 CONTINUE*IF( K+L.LT.N ) THENDO 90 I = K + L + 1, NALPHA( I ) = ZEROBETA( I ) = ZERO90 CONTINUEEND IF*100 CONTINUENCYCLE = KCYCLERETURN** End of DTGSJA*END*> \brief \b DTGSNA** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGSNA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsna.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsna.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsna.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGSNA( JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,* LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER HOWMNY, JOB* INTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, M, MM, N* ..* .. Array Arguments ..* LOGICAL SELECT( * )* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), DIF( * ), S( * ),* $ VL( LDVL, * ), VR( LDVR, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGSNA estimates reciprocal condition numbers for specified*> eigenvalues and/or eigenvectors of a matrix pair (A, B) in*> generalized real Schur canonical form (or of any matrix pair*> (Q*A*Z**T, Q*B*Z**T) with orthogonal matrices Q and Z, where*> Z**T denotes the transpose of Z.*>*> (A, B) must be in generalized real Schur form (as returned by DGGES),*> i.e. A is block upper triangular with 1-by-1 and 2-by-2 diagonal*> blocks. B is upper triangular.*>*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies whether condition numbers are required for*> eigenvalues (S) or eigenvectors (DIF):*> = 'E': for eigenvalues only (S);*> = 'V': for eigenvectors only (DIF);*> = 'B': for both eigenvalues and eigenvectors (S and DIF).*> \endverbatim*>*> \param[in] HOWMNY*> \verbatim*> HOWMNY is CHARACTER*1*> = 'A': compute condition numbers for all eigenpairs;*> = 'S': compute condition numbers for selected eigenpairs*> specified by the array SELECT.*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> If HOWMNY = 'S', SELECT specifies the eigenpairs for which*> condition numbers are required. To select condition numbers*> for the eigenpair corresponding to a real eigenvalue w(j),*> SELECT(j) must be set to .TRUE.. To select condition numbers*> corresponding to a complex conjugate pair of eigenvalues w(j)*> and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be*> set to .TRUE..*> If HOWMNY = 'A', SELECT is not referenced.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the square matrix pair (A, B). N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The upper quasi-triangular matrix A in the pair (A,B).*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> The upper triangular matrix B in the pair (A,B).*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,M)*> If JOB = 'E' or 'B', VL must contain left eigenvectors of*> (A, B), corresponding to the eigenpairs specified by HOWMNY*> and SELECT. The eigenvectors must be stored in consecutive*> columns of VL, as returned by DTGEVC.*> If JOB = 'V', VL is not referenced.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL. LDVL >= 1.*> If JOB = 'E' or 'B', LDVL >= N.*> \endverbatim*>*> \param[in] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,M)*> If JOB = 'E' or 'B', VR must contain right eigenvectors of*> (A, B), corresponding to the eigenpairs specified by HOWMNY*> and SELECT. The eigenvectors must be stored in consecutive*> columns ov VR, as returned by DTGEVC.*> If JOB = 'V', VR is not referenced.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR. LDVR >= 1.*> If JOB = 'E' or 'B', LDVR >= N.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (MM)*> If JOB = 'E' or 'B', the reciprocal condition numbers of the*> selected eigenvalues, stored in consecutive elements of the*> array. For a complex conjugate pair of eigenvalues two*> consecutive elements of S are set to the same value. Thus*> S(j), DIF(j), and the j-th columns of VL and VR all*> correspond to the same eigenpair (but not in general the*> j-th eigenpair, unless all eigenpairs are selected).*> If JOB = 'V', S is not referenced.*> \endverbatim*>*> \param[out] DIF*> \verbatim*> DIF is DOUBLE PRECISION array, dimension (MM)*> If JOB = 'V' or 'B', the estimated reciprocal condition*> numbers of the selected eigenvectors, stored in consecutive*> elements of the array. For a complex eigenvector two*> consecutive elements of DIF are set to the same value. If*> the eigenvalues cannot be reordered to compute DIF(j), DIF(j)*> is set to 0; this can only occur when the true value would be*> very small anyway.*> If JOB = 'E', DIF is not referenced.*> \endverbatim*>*> \param[in] MM*> \verbatim*> MM is INTEGER*> The number of elements in the arrays S and DIF. MM >= M.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The number of elements of the arrays S and DIF used to store*> the specified condition numbers; for each selected real*> eigenvalue one element is used, and for each selected complex*> conjugate pair of eigenvalues, two elements are used.*> If HOWMNY = 'A', M is set to N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,N).*> If JOB = 'V' or 'B' LWORK >= 2*N*(N+2)+16.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N + 6)*> If JOB = 'E', IWORK is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> =0: Successful exit*> <0: If INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The reciprocal of the condition number of a generalized eigenvalue*> w = (a, b) is defined as*>*> S(w) = (|u**TAv|**2 + |u**TBv|**2)**(1/2) / (norm(u)*norm(v))*>*> where u and v are the left and right eigenvectors of (A, B)*> corresponding to w; |z| denotes the absolute value of the complex*> number, and norm(u) denotes the 2-norm of the vector u.*> The pair (a, b) corresponds to an eigenvalue w = a/b (= u**TAv/u**TBv)*> of the matrix pair (A, B). If both a and b equal zero, then (A B) is*> singular and S(I) = -1 is returned.*>*> An approximate error bound on the chordal distance between the i-th*> computed generalized eigenvalue w and the corresponding exact*> eigenvalue lambda is*>*> chord(w, lambda) <= EPS * norm(A, B) / S(I)*>*> where EPS is the machine precision.*>*> The reciprocal of the condition number DIF(i) of right eigenvector u*> and left eigenvector v corresponding to the generalized eigenvalue w*> is defined as follows:*>*> a) If the i-th eigenvalue w = (a,b) is real*>*> Suppose U and V are orthogonal transformations such that*>*> U**T*(A, B)*V = (S, T) = ( a * ) ( b * ) 1*> ( 0 S22 ),( 0 T22 ) n-1*> 1 n-1 1 n-1*>*> Then the reciprocal condition number DIF(i) is*>*> Difl((a, b), (S22, T22)) = sigma-min( Zl ),*>*> where sigma-min(Zl) denotes the smallest singular value of the*> 2(n-1)-by-2(n-1) matrix*>*> Zl = [ kron(a, In-1) -kron(1, S22) ]*> [ kron(b, In-1) -kron(1, T22) ] .*>*> Here In-1 is the identity matrix of size n-1. kron(X, Y) is the*> Kronecker product between the matrices X and Y.*>*> Note that if the default method for computing DIF(i) is wanted*> (see DLATDF), then the parameter DIFDRI (see below) should be*> changed from 3 to 4 (routine DLATDF(IJOB = 2 will be used)).*> See DTGSYL for more details.*>*> b) If the i-th and (i+1)-th eigenvalues are complex conjugate pair,*>*> Suppose U and V are orthogonal transformations such that*>*> U**T*(A, B)*V = (S, T) = ( S11 * ) ( T11 * ) 2*> ( 0 S22 ),( 0 T22) n-2*> 2 n-2 2 n-2*>*> and (S11, T11) corresponds to the complex conjugate eigenvalue*> pair (w, conjg(w)). There exist unitary matrices U1 and V1 such*> that*>*> U1**T*S11*V1 = ( s11 s12 ) and U1**T*T11*V1 = ( t11 t12 )*> ( 0 s22 ) ( 0 t22 )*>*> where the generalized eigenvalues w = s11/t11 and*> conjg(w) = s22/t22.*>*> Then the reciprocal condition number DIF(i) is bounded by*>*> min( d1, max( 1, |real(s11)/real(s22)| )*d2 )*>*> where, d1 = Difl((s11, t11), (s22, t22)) = sigma-min(Z1), where*> Z1 is the complex 2-by-2 matrix*>*> Z1 = [ s11 -s22 ]*> [ t11 -t22 ],*>*> This is done by computing (using real arithmetic) the*> roots of the characteristical polynomial det(Z1**T * Z1 - lambda I),*> where Z1**T denotes the transpose of Z1 and det(X) denotes*> the determinant of X.*>*> and d2 is an upper bound on Difl((S11, T11), (S22, T22)), i.e. an*> upper bound on sigma-min(Z2), where Z2 is (2n-2)-by-(2n-2)*>*> Z2 = [ kron(S11**T, In-2) -kron(I2, S22) ]*> [ kron(T11**T, In-2) -kron(I2, T22) ]*>*> Note that if the default method for computing DIF is wanted (see*> DLATDF), then the parameter DIFDRI (see below) should be changed*> from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). See DTGSYL*> for more details.*>*> For each eigenvalue/vector specified by SELECT, DIF stores a*> Frobenius norm-based estimate of Difl.*>*> An approximate error bound for the i-th computed eigenvector VL(i) or*> VR(i) is given by*>*> EPS * norm(A, B) / DIF(i).*>*> See ref. [2-3] for more details and further references.*> \endverbatim**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.**> \par References:* ================*>*> \verbatim*>*> [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the*> Generalized Real Schur Form of a Regular Matrix Pair (A, B), in*> M.S. Moonen et al (eds), Linear Algebra for Large Scale and*> Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.*>*> [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified*> Eigenvalues of a Regular Matrix Pair (A, B) and Condition*> Estimation: Theory, Algorithms and Software,*> Report UMINF - 94.04, Department of Computing Science, Umea*> University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working*> Note 87. To appear in Numerical Algorithms, 1996.*>*> [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software*> for Solving the Generalized Sylvester Equation and Estimating the*> Separation between Regular Matrix Pairs, Report UMINF - 93.23,*> Department of Computing Science, Umea University, S-901 87 Umea,*> Sweden, December 1993, Revised April 1994, Also as LAPACK Working*> Note 75. To appear in ACM Trans. on Math. Software, Vol 22,*> No 1, 1996.*> \endverbatim*>* =====================================================================SUBROUTINE DTGSNA( JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL,$ LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER HOWMNY, JOBINTEGER INFO, LDA, LDB, LDVL, LDVR, LWORK, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), DIF( * ), S( * ),$ VL( LDVL, * ), VR( LDVR, * ), WORK( * )* ..** =====================================================================** .. Parameters ..INTEGER DIFDRIPARAMETER ( DIFDRI = 3 )DOUBLE PRECISION ZERO, ONE, TWO, FOURPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,$ FOUR = 4.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, PAIR, SOMCON, WANTBH, WANTDF, WANTSINTEGER I, IERR, IFST, ILST, IZ, K, KS, LWMIN, N1, N2DOUBLE PRECISION ALPHAI, ALPHAR, ALPRQT, BETA, C1, C2, COND,$ EPS, LNRM, RNRM, ROOT1, ROOT2, SCALE, SMLNUM,$ TMPII, TMPIR, TMPRI, TMPRR, UHAV, UHAVI, UHBV,$ UHBVI* ..* .. Local Arrays ..DOUBLE PRECISION DUMMY( 1 ), DUMMY1( 1 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOT, DLAMCH, DLAPY2, DNRM2EXTERNAL LSAME, DDOT, DLAMCH, DLAPY2, DNRM2* ..* .. External Subroutines ..EXTERNAL DGEMV, DLACPY, DLAG2, DTGEXC, DTGSYL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN, SQRT* ..* .. Executable Statements ..** Decode and test the input parameters*WANTBH = LSAME( JOB, 'B' )WANTS = LSAME( JOB, 'E' ) .OR. WANTBHWANTDF = LSAME( JOB, 'V' ) .OR. WANTBH*SOMCON = LSAME( HOWMNY, 'S' )*INFO = 0LQUERY = ( LWORK.EQ.-1 )*IF( .NOT.WANTS .AND. .NOT.WANTDF ) THENINFO = -1ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( WANTS .AND. LDVL.LT.N ) THENINFO = -10ELSE IF( WANTS .AND. LDVR.LT.N ) THENINFO = -12ELSE** Set M to the number of eigenpairs for which condition numbers* are required, and test MM.*IF( SOMCON ) THENM = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSEIF( K.LT.N ) THENIF( A( K+1, K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) )$ M = M + 2END IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEELSEM = NEND IF*IF( N.EQ.0 ) THENLWMIN = 1ELSE IF( LSAME( JOB, 'V' ) .OR. LSAME( JOB, 'B' ) ) THENLWMIN = 2*N*( N + 2 ) + 16ELSELWMIN = NEND IFWORK( 1 ) = LWMIN*IF( MM.LT.M ) THENINFO = -15ELSE IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -18END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTGSNA', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSKS = 0PAIR = .FALSE.*DO 20 K = 1, N** Determine whether A(k,k) begins a 1-by-1 or 2-by-2 block.*IF( PAIR ) THENPAIR = .FALSE.GO TO 20ELSEIF( K.LT.N )$ PAIR = A( K+1, K ).NE.ZEROEND IF** Determine whether condition numbers are required for the k-th* eigenpair.*IF( SOMCON ) THENIF( PAIR ) THENIF( .NOT.SELECT( K ) .AND. .NOT.SELECT( K+1 ) )$ GO TO 20ELSEIF( .NOT.SELECT( K ) )$ GO TO 20END IFEND IF*KS = KS + 1*IF( WANTS ) THEN** Compute the reciprocal condition number of the k-th* eigenvalue.*IF( PAIR ) THEN** Complex eigenvalue pair.*RNRM = DLAPY2( DNRM2( N, VR( 1, KS ), 1 ),$ DNRM2( N, VR( 1, KS+1 ), 1 ) )LNRM = DLAPY2( DNRM2( N, VL( 1, KS ), 1 ),$ DNRM2( N, VL( 1, KS+1 ), 1 ) )CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS ), 1, ZERO,$ WORK, 1 )TMPRR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )TMPRI = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS+1 ), 1,$ ZERO, WORK, 1 )TMPII = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )TMPIR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )UHAV = TMPRR + TMPIIUHAVI = TMPIR - TMPRICALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS ), 1, ZERO,$ WORK, 1 )TMPRR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )TMPRI = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS+1 ), 1,$ ZERO, WORK, 1 )TMPII = DDOT( N, WORK, 1, VL( 1, KS+1 ), 1 )TMPIR = DDOT( N, WORK, 1, VL( 1, KS ), 1 )UHBV = TMPRR + TMPIIUHBVI = TMPIR - TMPRIUHAV = DLAPY2( UHAV, UHAVI )UHBV = DLAPY2( UHBV, UHBVI )COND = DLAPY2( UHAV, UHBV )S( KS ) = COND / ( RNRM*LNRM )S( KS+1 ) = S( KS )*ELSE** Real eigenvalue.*RNRM = DNRM2( N, VR( 1, KS ), 1 )LNRM = DNRM2( N, VL( 1, KS ), 1 )CALL DGEMV( 'N', N, N, ONE, A, LDA, VR( 1, KS ), 1, ZERO,$ WORK, 1 )UHAV = DDOT( N, WORK, 1, VL( 1, KS ), 1 )CALL DGEMV( 'N', N, N, ONE, B, LDB, VR( 1, KS ), 1, ZERO,$ WORK, 1 )UHBV = DDOT( N, WORK, 1, VL( 1, KS ), 1 )COND = DLAPY2( UHAV, UHBV )IF( COND.EQ.ZERO ) THENS( KS ) = -ONEELSES( KS ) = COND / ( RNRM*LNRM )END IFEND IFEND IF*IF( WANTDF ) THENIF( N.EQ.1 ) THENDIF( KS ) = DLAPY2( A( 1, 1 ), B( 1, 1 ) )GO TO 20END IF** Estimate the reciprocal condition number of the k-th* eigenvectors.IF( PAIR ) THEN** Copy the 2-by 2 pencil beginning at (A(k,k), B(k, k)).* Compute the eigenvalue(s) at position K.*WORK( 1 ) = A( K, K )WORK( 2 ) = A( K+1, K )WORK( 3 ) = A( K, K+1 )WORK( 4 ) = A( K+1, K+1 )WORK( 5 ) = B( K, K )WORK( 6 ) = B( K+1, K )WORK( 7 ) = B( K, K+1 )WORK( 8 ) = B( K+1, K+1 )CALL DLAG2( WORK, 2, WORK( 5 ), 2, SMLNUM*EPS, BETA,$ DUMMY1( 1 ), ALPHAR, DUMMY( 1 ), ALPHAI )ALPRQT = ONEC1 = TWO*( ALPHAR*ALPHAR+ALPHAI*ALPHAI+BETA*BETA )C2 = FOUR*BETA*BETA*ALPHAI*ALPHAIROOT1 = C1 + SQRT( C1*C1-4.0D0*C2 )ROOT2 = C2 / ROOT1ROOT1 = ROOT1 / TWOCOND = MIN( SQRT( ROOT1 ), SQRT( ROOT2 ) )END IF** Copy the matrix (A, B) to the array WORK and swap the* diagonal block beginning at A(k,k) to the (1,1) position.*CALL DLACPY( 'Full', N, N, A, LDA, WORK, N )CALL DLACPY( 'Full', N, N, B, LDB, WORK( N*N+1 ), N )IFST = KILST = 1*CALL DTGEXC( .FALSE., .FALSE., N, WORK, N, WORK( N*N+1 ), N,$ DUMMY, 1, DUMMY1, 1, IFST, ILST,$ WORK( N*N*2+1 ), LWORK-2*N*N, IERR )*IF( IERR.GT.0 ) THEN** Ill-conditioned problem - swap rejected.*DIF( KS ) = ZEROELSE** Reordering successful, solve generalized Sylvester* equation for R and L,* A22 * R - L * A11 = A12* B22 * R - L * B11 = B12,* and compute estimate of Difl((A11,B11), (A22, B22)).*N1 = 1IF( WORK( 2 ).NE.ZERO )$ N1 = 2N2 = N - N1IF( N2.EQ.0 ) THENDIF( KS ) = CONDELSEI = N*N + 1IZ = 2*N*N + 1CALL DTGSYL( 'N', DIFDRI, N2, N1, WORK( N*N1+N1+1 ),$ N, WORK, N, WORK( N1+1 ), N,$ WORK( N*N1+N1+I ), N, WORK( I ), N,$ WORK( N1+I ), N, SCALE, DIF( KS ),$ WORK( IZ+1 ), LWORK-2*N*N, IWORK, IERR )*IF( PAIR )$ DIF( KS ) = MIN( MAX( ONE, ALPRQT )*DIF( KS ),$ COND )END IFEND IFIF( PAIR )$ DIF( KS+1 ) = DIF( KS )END IFIF( PAIR )$ KS = KS + 1*20 CONTINUEWORK( 1 ) = LWMINRETURN** End of DTGSNA*END*> \brief \b DTGSY2 solves the generalized Sylvester equation (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGSY2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsy2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsy2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsy2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGSY2( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,* LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL,* IWORK, PQ, INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF, M, N,* $ PQ* DOUBLE PRECISION RDSCAL, RDSUM, SCALE* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),* $ D( LDD, * ), E( LDE, * ), F( LDF, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGSY2 solves the generalized Sylvester equation:*>*> A * R - L * B = scale * C (1)*> D * R - L * E = scale * F,*>*> using Level 1 and 2 BLAS. where R and L are unknown M-by-N matrices,*> (A, D), (B, E) and (C, F) are given matrix pairs of size M-by-M,*> N-by-N and M-by-N, respectively, with real entries. (A, D) and (B, E)*> must be in generalized Schur canonical form, i.e. A, B are upper*> quasi triangular and D, E are upper triangular. The solution (R, L)*> overwrites (C, F). 0 <= SCALE <= 1 is an output scaling factor*> chosen to avoid overflow.*>*> In matrix notation solving equation (1) corresponds to solve*> Z*x = scale*b, where Z is defined as*>*> Z = [ kron(In, A) -kron(B**T, Im) ] (2)*> [ kron(In, D) -kron(E**T, Im) ],*>*> Ik is the identity matrix of size k and X**T is the transpose of X.*> kron(X, Y) is the Kronecker product between the matrices X and Y.*> In the process of solving (1), we solve a number of such systems*> where Dim(In), Dim(In) = 1 or 2.*>*> If TRANS = 'T', solve the transposed system Z**T*y = scale*b for y,*> which is equivalent to solve for R and L in*>*> A**T * R + D**T * L = scale * C (3)*> R * B**T + L * E**T = scale * -F*>*> This case is used to compute an estimate of Dif[(A, D), (B, E)] =*> sigma_min(Z) using reverse communicaton with DLACON.*>*> DTGSY2 also (IJOB >= 1) contributes to the computation in DTGSYL*> of an upper bound on the separation between to matrix pairs. Then*> the input (A, D), (B, E) are sub-pencils of the matrix pair in*> DTGSYL. See DTGSYL for details.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N', solve the generalized Sylvester equation (1).*> = 'T': solve the 'transposed' system (3).*> \endverbatim*>*> \param[in] IJOB*> \verbatim*> IJOB is INTEGER*> Specifies what kind of functionality to be performed.*> = 0: solve (1) only.*> = 1: A contribution from this subsystem to a Frobenius*> norm-based estimate of the separation between two matrix*> pairs is computed. (look ahead strategy is used).*> = 2: A contribution from this subsystem to a Frobenius*> norm-based estimate of the separation between two matrix*> pairs is computed. (DGECON on sub-systems is used.)*> Not referenced if TRANS = 'T'.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> On entry, M specifies the order of A and D, and the row*> dimension of C, F, R and L.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> On entry, N specifies the order of B and E, and the column*> dimension of C, F, R and L.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, M)*> On entry, A contains an upper quasi triangular matrix.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the matrix A. LDA >= max(1, M).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> On entry, B contains an upper quasi triangular matrix.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the matrix B. LDB >= max(1, N).*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC, N)*> On entry, C contains the right-hand-side of the first matrix*> equation in (1).*> On exit, if IJOB = 0, C has been overwritten by the*> solution R.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the matrix C. LDC >= max(1, M).*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (LDD, M)*> On entry, D contains an upper triangular matrix.*> \endverbatim*>*> \param[in] LDD*> \verbatim*> LDD is INTEGER*> The leading dimension of the matrix D. LDD >= max(1, M).*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (LDE, N)*> On entry, E contains an upper triangular matrix.*> \endverbatim*>*> \param[in] LDE*> \verbatim*> LDE is INTEGER*> The leading dimension of the matrix E. LDE >= max(1, N).*> \endverbatim*>*> \param[in,out] F*> \verbatim*> F is DOUBLE PRECISION array, dimension (LDF, N)*> On entry, F contains the right-hand-side of the second matrix*> equation in (1).*> On exit, if IJOB = 0, F has been overwritten by the*> solution L.*> \endverbatim*>*> \param[in] LDF*> \verbatim*> LDF is INTEGER*> The leading dimension of the matrix F. LDF >= max(1, M).*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> On exit, 0 <= SCALE <= 1. If 0 < SCALE < 1, the solutions*> R and L (C and F on entry) will hold the solutions to a*> slightly perturbed system but the input matrices A, B, D and*> E have not been changed. If SCALE = 0, R and L will hold the*> solutions to the homogeneous system with C = F = 0. Normally,*> SCALE = 1.*> \endverbatim*>*> \param[in,out] RDSUM*> \verbatim*> RDSUM is DOUBLE PRECISION*> On entry, the sum of squares of computed contributions to*> the Dif-estimate under computation by DTGSYL, where the*> scaling factor RDSCAL (see below) has been factored out.*> On exit, the corresponding sum of squares updated with the*> contributions from the current sub-system.*> If TRANS = 'T' RDSUM is not touched.*> NOTE: RDSUM only makes sense when DTGSY2 is called by DTGSYL.*> \endverbatim*>*> \param[in,out] RDSCAL*> \verbatim*> RDSCAL is DOUBLE PRECISION*> On entry, scaling factor used to prevent overflow in RDSUM.*> On exit, RDSCAL is updated w.r.t. the current contributions*> in RDSUM.*> If TRANS = 'T', RDSCAL is not touched.*> NOTE: RDSCAL only makes sense when DTGSY2 is called by*> DTGSYL.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (M+N+2)*> \endverbatim*>*> \param[out] PQ*> \verbatim*> PQ is INTEGER*> On exit, the number of subsystems (of size 2-by-2, 4-by-4 and*> 8-by-8) solved by this routine.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> On exit, if INFO is set to*> =0: Successful exit*> <0: If INFO = -i, the i-th argument had an illegal value.*> >0: The matrix pairs (A, D) and (B, E) have common or very*> close eigenvalues.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYauxiliary**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.** =====================================================================SUBROUTINE DTGSY2( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,$ LDD, E, LDE, F, LDF, SCALE, RDSUM, RDSCAL,$ IWORK, PQ, INFO )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF, M, N,$ PQDOUBLE PRECISION RDSCAL, RDSUM, SCALE* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),$ D( LDD, * ), E( LDE, * ), F( LDF, * )* ..** =====================================================================* Replaced various illegal calls to DCOPY by calls to DLASET.* Sven Hammarling, 27/5/02.** .. Parameters ..INTEGER LDZPARAMETER ( LDZ = 8 )DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRANINTEGER I, IE, IERR, II, IS, ISP1, J, JE, JJ, JS, JSP1,$ K, MB, NB, P, Q, ZDIMDOUBLE PRECISION ALPHA, SCALOC* ..* .. Local Arrays ..INTEGER IPIV( LDZ ), JPIV( LDZ )DOUBLE PRECISION RHS( LDZ ), Z( LDZ, LDZ )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMM, DGEMV, DGER, DGESC2,$ DGETC2, DLASET, DLATDF, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Decode and test input parameters*INFO = 0IERR = 0NOTRAN = LSAME( TRANS, 'N' )IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -1ELSE IF( NOTRAN ) THENIF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.2 ) ) THENINFO = -2END IFEND IFIF( INFO.EQ.0 ) THENIF( M.LE.0 ) THENINFO = -3ELSE IF( N.LE.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LDD.LT.MAX( 1, M ) ) THENINFO = -12ELSE IF( LDE.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDF.LT.MAX( 1, M ) ) THENINFO = -16END IFEND IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTGSY2', -INFO )RETURNEND IF** Determine block structure of A*PQ = 0P = 0I = 110 CONTINUEIF( I.GT.M )$ GO TO 20P = P + 1IWORK( P ) = IIF( I.EQ.M )$ GO TO 20IF( A( I+1, I ).NE.ZERO ) THENI = I + 2ELSEI = I + 1END IFGO TO 1020 CONTINUEIWORK( P+1 ) = M + 1** Determine block structure of B*Q = P + 1J = 130 CONTINUEIF( J.GT.N )$ GO TO 40Q = Q + 1IWORK( Q ) = JIF( J.EQ.N )$ GO TO 40IF( B( J+1, J ).NE.ZERO ) THENJ = J + 2ELSEJ = J + 1END IFGO TO 3040 CONTINUEIWORK( Q+1 ) = N + 1PQ = P*( Q-P-1 )*IF( NOTRAN ) THEN** Solve (I, J) - subsystem* A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)* D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)* for I = P, P - 1, ..., 1; J = 1, 2, ..., Q*SCALE = ONESCALOC = ONEDO 120 J = P + 2, QJS = IWORK( J )JSP1 = JS + 1JE = IWORK( J+1 ) - 1NB = JE - JS + 1DO 110 I = P, 1, -1*IS = IWORK( I )ISP1 = IS + 1IE = IWORK( I+1 ) - 1MB = IE - IS + 1ZDIM = MB*NB*2*IF( ( MB.EQ.1 ) .AND. ( NB.EQ.1 ) ) THEN** Build a 2-by-2 system Z * x = RHS*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = D( IS, IS )Z( 1, 2 ) = -B( JS, JS )Z( 2, 2 ) = -E( JS, JS )** Set up right hand side(s)*RHS( 1 ) = C( IS, JS )RHS( 2 ) = F( IS, JS )** Solve Z * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERR*IF( IJOB.EQ.0 ) THENCALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,$ SCALOC )IF( SCALOC.NE.ONE ) THENDO 50 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )50 CONTINUESCALE = SCALE*SCALOCEND IFELSECALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,$ RDSCAL, IPIV, JPIV )END IF** Unpack solution vector(s)*C( IS, JS ) = RHS( 1 )F( IS, JS ) = RHS( 2 )** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( I.GT.1 ) THENALPHA = -RHS( 1 )CALL DAXPY( IS-1, ALPHA, A( 1, IS ), 1, C( 1, JS ),$ 1 )CALL DAXPY( IS-1, ALPHA, D( 1, IS ), 1, F( 1, JS ),$ 1 )END IFIF( J.LT.Q ) THENCALL DAXPY( N-JE, RHS( 2 ), B( JS, JE+1 ), LDB,$ C( IS, JE+1 ), LDC )CALL DAXPY( N-JE, RHS( 2 ), E( JS, JE+1 ), LDE,$ F( IS, JE+1 ), LDF )END IF*ELSE IF( ( MB.EQ.1 ) .AND. ( NB.EQ.2 ) ) THEN** Build a 4-by-4 system Z * x = RHS*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = ZEROZ( 3, 1 ) = D( IS, IS )Z( 4, 1 ) = ZERO*Z( 1, 2 ) = ZEROZ( 2, 2 ) = A( IS, IS )Z( 3, 2 ) = ZEROZ( 4, 2 ) = D( IS, IS )*Z( 1, 3 ) = -B( JS, JS )Z( 2, 3 ) = -B( JS, JSP1 )Z( 3, 3 ) = -E( JS, JS )Z( 4, 3 ) = -E( JS, JSP1 )*Z( 1, 4 ) = -B( JSP1, JS )Z( 2, 4 ) = -B( JSP1, JSP1 )Z( 3, 4 ) = ZEROZ( 4, 4 ) = -E( JSP1, JSP1 )** Set up right hand side(s)*RHS( 1 ) = C( IS, JS )RHS( 2 ) = C( IS, JSP1 )RHS( 3 ) = F( IS, JS )RHS( 4 ) = F( IS, JSP1 )** Solve Z * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERR*IF( IJOB.EQ.0 ) THENCALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,$ SCALOC )IF( SCALOC.NE.ONE ) THENDO 60 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )60 CONTINUESCALE = SCALE*SCALOCEND IFELSECALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,$ RDSCAL, IPIV, JPIV )END IF** Unpack solution vector(s)*C( IS, JS ) = RHS( 1 )C( IS, JSP1 ) = RHS( 2 )F( IS, JS ) = RHS( 3 )F( IS, JSP1 ) = RHS( 4 )** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( I.GT.1 ) THENCALL DGER( IS-1, NB, -ONE, A( 1, IS ), 1, RHS( 1 ),$ 1, C( 1, JS ), LDC )CALL DGER( IS-1, NB, -ONE, D( 1, IS ), 1, RHS( 1 ),$ 1, F( 1, JS ), LDF )END IFIF( J.LT.Q ) THENCALL DAXPY( N-JE, RHS( 3 ), B( JS, JE+1 ), LDB,$ C( IS, JE+1 ), LDC )CALL DAXPY( N-JE, RHS( 3 ), E( JS, JE+1 ), LDE,$ F( IS, JE+1 ), LDF )CALL DAXPY( N-JE, RHS( 4 ), B( JSP1, JE+1 ), LDB,$ C( IS, JE+1 ), LDC )CALL DAXPY( N-JE, RHS( 4 ), E( JSP1, JE+1 ), LDE,$ F( IS, JE+1 ), LDF )END IF*ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.1 ) ) THEN** Build a 4-by-4 system Z * x = RHS*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = A( ISP1, IS )Z( 3, 1 ) = D( IS, IS )Z( 4, 1 ) = ZERO*Z( 1, 2 ) = A( IS, ISP1 )Z( 2, 2 ) = A( ISP1, ISP1 )Z( 3, 2 ) = D( IS, ISP1 )Z( 4, 2 ) = D( ISP1, ISP1 )*Z( 1, 3 ) = -B( JS, JS )Z( 2, 3 ) = ZEROZ( 3, 3 ) = -E( JS, JS )Z( 4, 3 ) = ZERO*Z( 1, 4 ) = ZEROZ( 2, 4 ) = -B( JS, JS )Z( 3, 4 ) = ZEROZ( 4, 4 ) = -E( JS, JS )** Set up right hand side(s)*RHS( 1 ) = C( IS, JS )RHS( 2 ) = C( ISP1, JS )RHS( 3 ) = F( IS, JS )RHS( 4 ) = F( ISP1, JS )** Solve Z * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERRIF( IJOB.EQ.0 ) THENCALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,$ SCALOC )IF( SCALOC.NE.ONE ) THENDO 70 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )70 CONTINUESCALE = SCALE*SCALOCEND IFELSECALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,$ RDSCAL, IPIV, JPIV )END IF** Unpack solution vector(s)*C( IS, JS ) = RHS( 1 )C( ISP1, JS ) = RHS( 2 )F( IS, JS ) = RHS( 3 )F( ISP1, JS ) = RHS( 4 )** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( I.GT.1 ) THENCALL DGEMV( 'N', IS-1, MB, -ONE, A( 1, IS ), LDA,$ RHS( 1 ), 1, ONE, C( 1, JS ), 1 )CALL DGEMV( 'N', IS-1, MB, -ONE, D( 1, IS ), LDD,$ RHS( 1 ), 1, ONE, F( 1, JS ), 1 )END IFIF( J.LT.Q ) THENCALL DGER( MB, N-JE, ONE, RHS( 3 ), 1,$ B( JS, JE+1 ), LDB, C( IS, JE+1 ), LDC )CALL DGER( MB, N-JE, ONE, RHS( 3 ), 1,$ E( JS, JE+1 ), LDE, F( IS, JE+1 ), LDF )END IF*ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.2 ) ) THEN** Build an 8-by-8 system Z * x = RHS*CALL DLASET( 'F', LDZ, LDZ, ZERO, ZERO, Z, LDZ )*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = A( ISP1, IS )Z( 5, 1 ) = D( IS, IS )*Z( 1, 2 ) = A( IS, ISP1 )Z( 2, 2 ) = A( ISP1, ISP1 )Z( 5, 2 ) = D( IS, ISP1 )Z( 6, 2 ) = D( ISP1, ISP1 )*Z( 3, 3 ) = A( IS, IS )Z( 4, 3 ) = A( ISP1, IS )Z( 7, 3 ) = D( IS, IS )*Z( 3, 4 ) = A( IS, ISP1 )Z( 4, 4 ) = A( ISP1, ISP1 )Z( 7, 4 ) = D( IS, ISP1 )Z( 8, 4 ) = D( ISP1, ISP1 )*Z( 1, 5 ) = -B( JS, JS )Z( 3, 5 ) = -B( JS, JSP1 )Z( 5, 5 ) = -E( JS, JS )Z( 7, 5 ) = -E( JS, JSP1 )*Z( 2, 6 ) = -B( JS, JS )Z( 4, 6 ) = -B( JS, JSP1 )Z( 6, 6 ) = -E( JS, JS )Z( 8, 6 ) = -E( JS, JSP1 )*Z( 1, 7 ) = -B( JSP1, JS )Z( 3, 7 ) = -B( JSP1, JSP1 )Z( 7, 7 ) = -E( JSP1, JSP1 )*Z( 2, 8 ) = -B( JSP1, JS )Z( 4, 8 ) = -B( JSP1, JSP1 )Z( 8, 8 ) = -E( JSP1, JSP1 )** Set up right hand side(s)*K = 1II = MB*NB + 1DO 80 JJ = 0, NB - 1CALL DCOPY( MB, C( IS, JS+JJ ), 1, RHS( K ), 1 )CALL DCOPY( MB, F( IS, JS+JJ ), 1, RHS( II ), 1 )K = K + MBII = II + MB80 CONTINUE** Solve Z * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERRIF( IJOB.EQ.0 ) THENCALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV,$ SCALOC )IF( SCALOC.NE.ONE ) THENDO 90 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )90 CONTINUESCALE = SCALE*SCALOCEND IFELSECALL DLATDF( IJOB, ZDIM, Z, LDZ, RHS, RDSUM,$ RDSCAL, IPIV, JPIV )END IF** Unpack solution vector(s)*K = 1II = MB*NB + 1DO 100 JJ = 0, NB - 1CALL DCOPY( MB, RHS( K ), 1, C( IS, JS+JJ ), 1 )CALL DCOPY( MB, RHS( II ), 1, F( IS, JS+JJ ), 1 )K = K + MBII = II + MB100 CONTINUE** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( I.GT.1 ) THENCALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,$ A( 1, IS ), LDA, RHS( 1 ), MB, ONE,$ C( 1, JS ), LDC )CALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,$ D( 1, IS ), LDD, RHS( 1 ), MB, ONE,$ F( 1, JS ), LDF )END IFIF( J.LT.Q ) THENK = MB*NB + 1CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE, RHS( K ),$ MB, B( JS, JE+1 ), LDB, ONE,$ C( IS, JE+1 ), LDC )CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE, RHS( K ),$ MB, E( JS, JE+1 ), LDE, ONE,$ F( IS, JE+1 ), LDF )END IF*END IF*110 CONTINUE120 CONTINUEELSE** Solve (I, J) - subsystem* A(I, I)**T * R(I, J) + D(I, I)**T * L(J, J) = C(I, J)* R(I, I) * B(J, J) + L(I, J) * E(J, J) = -F(I, J)* for I = 1, 2, ..., P, J = Q, Q - 1, ..., 1*SCALE = ONESCALOC = ONEDO 200 I = 1, P*IS = IWORK( I )ISP1 = IS + 1IE = IWORK ( I+1 ) - 1MB = IE - IS + 1DO 190 J = Q, P + 2, -1*JS = IWORK( J )JSP1 = JS + 1JE = IWORK( J+1 ) - 1NB = JE - JS + 1ZDIM = MB*NB*2IF( ( MB.EQ.1 ) .AND. ( NB.EQ.1 ) ) THEN** Build a 2-by-2 system Z**T * x = RHS*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = -B( JS, JS )Z( 1, 2 ) = D( IS, IS )Z( 2, 2 ) = -E( JS, JS )** Set up right hand side(s)*RHS( 1 ) = C( IS, JS )RHS( 2 ) = F( IS, JS )** Solve Z**T * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERR*CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )IF( SCALOC.NE.ONE ) THENDO 130 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )130 CONTINUESCALE = SCALE*SCALOCEND IF** Unpack solution vector(s)*C( IS, JS ) = RHS( 1 )F( IS, JS ) = RHS( 2 )** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( J.GT.P+2 ) THENALPHA = RHS( 1 )CALL DAXPY( JS-1, ALPHA, B( 1, JS ), 1, F( IS, 1 ),$ LDF )ALPHA = RHS( 2 )CALL DAXPY( JS-1, ALPHA, E( 1, JS ), 1, F( IS, 1 ),$ LDF )END IFIF( I.LT.P ) THENALPHA = -RHS( 1 )CALL DAXPY( M-IE, ALPHA, A( IS, IE+1 ), LDA,$ C( IE+1, JS ), 1 )ALPHA = -RHS( 2 )CALL DAXPY( M-IE, ALPHA, D( IS, IE+1 ), LDD,$ C( IE+1, JS ), 1 )END IF*ELSE IF( ( MB.EQ.1 ) .AND. ( NB.EQ.2 ) ) THEN** Build a 4-by-4 system Z**T * x = RHS*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = ZEROZ( 3, 1 ) = -B( JS, JS )Z( 4, 1 ) = -B( JSP1, JS )*Z( 1, 2 ) = ZEROZ( 2, 2 ) = A( IS, IS )Z( 3, 2 ) = -B( JS, JSP1 )Z( 4, 2 ) = -B( JSP1, JSP1 )*Z( 1, 3 ) = D( IS, IS )Z( 2, 3 ) = ZEROZ( 3, 3 ) = -E( JS, JS )Z( 4, 3 ) = ZERO*Z( 1, 4 ) = ZEROZ( 2, 4 ) = D( IS, IS )Z( 3, 4 ) = -E( JS, JSP1 )Z( 4, 4 ) = -E( JSP1, JSP1 )** Set up right hand side(s)*RHS( 1 ) = C( IS, JS )RHS( 2 ) = C( IS, JSP1 )RHS( 3 ) = F( IS, JS )RHS( 4 ) = F( IS, JSP1 )** Solve Z**T * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERRCALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )IF( SCALOC.NE.ONE ) THENDO 140 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )140 CONTINUESCALE = SCALE*SCALOCEND IF** Unpack solution vector(s)*C( IS, JS ) = RHS( 1 )C( IS, JSP1 ) = RHS( 2 )F( IS, JS ) = RHS( 3 )F( IS, JSP1 ) = RHS( 4 )** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( J.GT.P+2 ) THENCALL DAXPY( JS-1, RHS( 1 ), B( 1, JS ), 1,$ F( IS, 1 ), LDF )CALL DAXPY( JS-1, RHS( 2 ), B( 1, JSP1 ), 1,$ F( IS, 1 ), LDF )CALL DAXPY( JS-1, RHS( 3 ), E( 1, JS ), 1,$ F( IS, 1 ), LDF )CALL DAXPY( JS-1, RHS( 4 ), E( 1, JSP1 ), 1,$ F( IS, 1 ), LDF )END IFIF( I.LT.P ) THENCALL DGER( M-IE, NB, -ONE, A( IS, IE+1 ), LDA,$ RHS( 1 ), 1, C( IE+1, JS ), LDC )CALL DGER( M-IE, NB, -ONE, D( IS, IE+1 ), LDD,$ RHS( 3 ), 1, C( IE+1, JS ), LDC )END IF*ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.1 ) ) THEN** Build a 4-by-4 system Z**T * x = RHS*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = A( IS, ISP1 )Z( 3, 1 ) = -B( JS, JS )Z( 4, 1 ) = ZERO*Z( 1, 2 ) = A( ISP1, IS )Z( 2, 2 ) = A( ISP1, ISP1 )Z( 3, 2 ) = ZEROZ( 4, 2 ) = -B( JS, JS )*Z( 1, 3 ) = D( IS, IS )Z( 2, 3 ) = D( IS, ISP1 )Z( 3, 3 ) = -E( JS, JS )Z( 4, 3 ) = ZERO*Z( 1, 4 ) = ZEROZ( 2, 4 ) = D( ISP1, ISP1 )Z( 3, 4 ) = ZEROZ( 4, 4 ) = -E( JS, JS )** Set up right hand side(s)*RHS( 1 ) = C( IS, JS )RHS( 2 ) = C( ISP1, JS )RHS( 3 ) = F( IS, JS )RHS( 4 ) = F( ISP1, JS )** Solve Z**T * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERR*CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )IF( SCALOC.NE.ONE ) THENDO 150 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )150 CONTINUESCALE = SCALE*SCALOCEND IF** Unpack solution vector(s)*C( IS, JS ) = RHS( 1 )C( ISP1, JS ) = RHS( 2 )F( IS, JS ) = RHS( 3 )F( ISP1, JS ) = RHS( 4 )** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( J.GT.P+2 ) THENCALL DGER( MB, JS-1, ONE, RHS( 1 ), 1, B( 1, JS ),$ 1, F( IS, 1 ), LDF )CALL DGER( MB, JS-1, ONE, RHS( 3 ), 1, E( 1, JS ),$ 1, F( IS, 1 ), LDF )END IFIF( I.LT.P ) THENCALL DGEMV( 'T', MB, M-IE, -ONE, A( IS, IE+1 ),$ LDA, RHS( 1 ), 1, ONE, C( IE+1, JS ),$ 1 )CALL DGEMV( 'T', MB, M-IE, -ONE, D( IS, IE+1 ),$ LDD, RHS( 3 ), 1, ONE, C( IE+1, JS ),$ 1 )END IF*ELSE IF( ( MB.EQ.2 ) .AND. ( NB.EQ.2 ) ) THEN** Build an 8-by-8 system Z**T * x = RHS*CALL DLASET( 'F', LDZ, LDZ, ZERO, ZERO, Z, LDZ )*Z( 1, 1 ) = A( IS, IS )Z( 2, 1 ) = A( IS, ISP1 )Z( 5, 1 ) = -B( JS, JS )Z( 7, 1 ) = -B( JSP1, JS )*Z( 1, 2 ) = A( ISP1, IS )Z( 2, 2 ) = A( ISP1, ISP1 )Z( 6, 2 ) = -B( JS, JS )Z( 8, 2 ) = -B( JSP1, JS )*Z( 3, 3 ) = A( IS, IS )Z( 4, 3 ) = A( IS, ISP1 )Z( 5, 3 ) = -B( JS, JSP1 )Z( 7, 3 ) = -B( JSP1, JSP1 )*Z( 3, 4 ) = A( ISP1, IS )Z( 4, 4 ) = A( ISP1, ISP1 )Z( 6, 4 ) = -B( JS, JSP1 )Z( 8, 4 ) = -B( JSP1, JSP1 )*Z( 1, 5 ) = D( IS, IS )Z( 2, 5 ) = D( IS, ISP1 )Z( 5, 5 ) = -E( JS, JS )*Z( 2, 6 ) = D( ISP1, ISP1 )Z( 6, 6 ) = -E( JS, JS )*Z( 3, 7 ) = D( IS, IS )Z( 4, 7 ) = D( IS, ISP1 )Z( 5, 7 ) = -E( JS, JSP1 )Z( 7, 7 ) = -E( JSP1, JSP1 )*Z( 4, 8 ) = D( ISP1, ISP1 )Z( 6, 8 ) = -E( JS, JSP1 )Z( 8, 8 ) = -E( JSP1, JSP1 )** Set up right hand side(s)*K = 1II = MB*NB + 1DO 160 JJ = 0, NB - 1CALL DCOPY( MB, C( IS, JS+JJ ), 1, RHS( K ), 1 )CALL DCOPY( MB, F( IS, JS+JJ ), 1, RHS( II ), 1 )K = K + MBII = II + MB160 CONTINUE*** Solve Z**T * x = RHS*CALL DGETC2( ZDIM, Z, LDZ, IPIV, JPIV, IERR )IF( IERR.GT.0 )$ INFO = IERR*CALL DGESC2( ZDIM, Z, LDZ, RHS, IPIV, JPIV, SCALOC )IF( SCALOC.NE.ONE ) THENDO 170 K = 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )170 CONTINUESCALE = SCALE*SCALOCEND IF** Unpack solution vector(s)*K = 1II = MB*NB + 1DO 180 JJ = 0, NB - 1CALL DCOPY( MB, RHS( K ), 1, C( IS, JS+JJ ), 1 )CALL DCOPY( MB, RHS( II ), 1, F( IS, JS+JJ ), 1 )K = K + MBII = II + MB180 CONTINUE** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( J.GT.P+2 ) THENCALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE,$ C( IS, JS ), LDC, B( 1, JS ), LDB, ONE,$ F( IS, 1 ), LDF )CALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE,$ F( IS, JS ), LDF, E( 1, JS ), LDE, ONE,$ F( IS, 1 ), LDF )END IFIF( I.LT.P ) THENCALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,$ A( IS, IE+1 ), LDA, C( IS, JS ), LDC,$ ONE, C( IE+1, JS ), LDC )CALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,$ D( IS, IE+1 ), LDD, F( IS, JS ), LDF,$ ONE, C( IE+1, JS ), LDC )END IF*END IF*190 CONTINUE200 CONTINUE*END IFRETURN** End of DTGSY2*END*> \brief \b DTGSYL** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTGSYL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgsyl.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgsyl.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgsyl.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,* LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER TRANS* INTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,* $ LWORK, M, N* DOUBLE PRECISION DIF, SCALE* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),* $ D( LDD, * ), E( LDE, * ), F( LDF, * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTGSYL solves the generalized Sylvester equation:*>*> A * R - L * B = scale * C (1)*> D * R - L * E = scale * F*>*> where R and L are unknown m-by-n matrices, (A, D), (B, E) and*> (C, F) are given matrix pairs of size m-by-m, n-by-n and m-by-n,*> respectively, with real entries. (A, D) and (B, E) must be in*> generalized (real) Schur canonical form, i.e. A, B are upper quasi*> triangular and D, E are upper triangular.*>*> The solution (R, L) overwrites (C, F). 0 <= SCALE <= 1 is an output*> scaling factor chosen to avoid overflow.*>*> In matrix notation (1) is equivalent to solve Zx = scale b, where*> Z is defined as*>*> Z = [ kron(In, A) -kron(B**T, Im) ] (2)*> [ kron(In, D) -kron(E**T, Im) ].*>*> Here Ik is the identity matrix of size k and X**T is the transpose of*> X. kron(X, Y) is the Kronecker product between the matrices X and Y.*>*> If TRANS = 'T', DTGSYL solves the transposed system Z**T*y = scale*b,*> which is equivalent to solve for R and L in*>*> A**T * R + D**T * L = scale * C (3)*> R * B**T + L * E**T = scale * -F*>*> This case (TRANS = 'T') is used to compute an one-norm-based estimate*> of Dif[(A,D), (B,E)], the separation between the matrix pairs (A,D)*> and (B,E), using DLACON.*>*> If IJOB >= 1, DTGSYL computes a Frobenius norm-based estimate*> of Dif[(A,D),(B,E)]. That is, the reciprocal of a lower bound on the*> reciprocal of the smallest singular value of Z. See [1-2] for more*> information.*>*> This is a level 3 BLAS algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N', solve the generalized Sylvester equation (1).*> = 'T', solve the 'transposed' system (3).*> \endverbatim*>*> \param[in] IJOB*> \verbatim*> IJOB is INTEGER*> Specifies what kind of functionality to be performed.*> =0: solve (1) only.*> =1: The functionality of 0 and 3.*> =2: The functionality of 0 and 4.*> =3: Only an estimate of Dif[(A,D), (B,E)] is computed.*> (look ahead strategy IJOB = 1 is used).*> =4: Only an estimate of Dif[(A,D), (B,E)] is computed.*> ( DGECON on sub-systems is used ).*> Not referenced if TRANS = 'T'.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The order of the matrices A and D, and the row dimension of*> the matrices C, F, R and L.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices B and E, and the column dimension*> of the matrices C, F, R and L.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA, M)*> The upper quasi triangular matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1, M).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB, N)*> The upper quasi triangular matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1, N).*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC, N)*> On entry, C contains the right-hand-side of the first matrix*> equation in (1) or (3).*> On exit, if IJOB = 0, 1 or 2, C has been overwritten by*> the solution R. If IJOB = 3 or 4 and TRANS = 'N', C holds R,*> the solution achieved during the computation of the*> Dif-estimate.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1, M).*> \endverbatim*>*> \param[in] D*> \verbatim*> D is DOUBLE PRECISION array, dimension (LDD, M)*> The upper triangular matrix D.*> \endverbatim*>*> \param[in] LDD*> \verbatim*> LDD is INTEGER*> The leading dimension of the array D. LDD >= max(1, M).*> \endverbatim*>*> \param[in] E*> \verbatim*> E is DOUBLE PRECISION array, dimension (LDE, N)*> The upper triangular matrix E.*> \endverbatim*>*> \param[in] LDE*> \verbatim*> LDE is INTEGER*> The leading dimension of the array E. LDE >= max(1, N).*> \endverbatim*>*> \param[in,out] F*> \verbatim*> F is DOUBLE PRECISION array, dimension (LDF, N)*> On entry, F contains the right-hand-side of the second matrix*> equation in (1) or (3).*> On exit, if IJOB = 0, 1 or 2, F has been overwritten by*> the solution L. If IJOB = 3 or 4 and TRANS = 'N', F holds L,*> the solution achieved during the computation of the*> Dif-estimate.*> \endverbatim*>*> \param[in] LDF*> \verbatim*> LDF is INTEGER*> The leading dimension of the array F. LDF >= max(1, M).*> \endverbatim*>*> \param[out] DIF*> \verbatim*> DIF is DOUBLE PRECISION*> On exit DIF is the reciprocal of a lower bound of the*> reciprocal of the Dif-function, i.e. DIF is an upper bound of*> Dif[(A,D), (B,E)] = sigma_min(Z), where Z as in (2).*> IF IJOB = 0 or TRANS = 'T', DIF is not touched.*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> On exit SCALE is the scaling factor in (1) or (3).*> If 0 < SCALE < 1, C and F hold the solutions R and L, resp.,*> to a slightly perturbed system but the input matrices A, B, D*> and E have not been changed. If SCALE = 0, C and F hold the*> solutions R and L, respectively, to the homogeneous system*> with C = F = 0. Normally, SCALE = 1.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK > = 1.*> If IJOB = 1 or 2 and TRANS = 'N', LWORK >= max(1,2*M*N).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (M+N+6)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> =0: successful exit*> <0: If INFO = -i, the i-th argument had an illegal value.*> >0: (A, D) and (B, E) have common or close eigenvalues.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational**> \par Contributors:* ==================*>*> Bo Kagstrom and Peter Poromaa, Department of Computing Science,*> Umea University, S-901 87 Umea, Sweden.**> \par References:* ================*>*> \verbatim*>*> [1] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software*> for Solving the Generalized Sylvester Equation and Estimating the*> Separation between Regular Matrix Pairs, Report UMINF - 93.23,*> Department of Computing Science, Umea University, S-901 87 Umea,*> Sweden, December 1993, Revised April 1994, Also as LAPACK Working*> Note 75. To appear in ACM Trans. on Math. Software, Vol 22,*> No 1, 1996.*>*> [2] B. Kagstrom, A Perturbation Analysis of the Generalized Sylvester*> Equation (AR - LB, DR - LE ) = (C, F), SIAM J. Matrix Anal.*> Appl., 15(4):1045-1060, 1994*>*> [3] B. Kagstrom and L. Westin, Generalized Schur Methods with*> Condition Estimators for Solving the Generalized Sylvester*> Equation, IEEE Transactions on Automatic Control, Vol. 34, No. 7,*> July 1989, pp 745-751.*> \endverbatim*>* =====================================================================SUBROUTINE DTGSYL( TRANS, IJOB, M, N, A, LDA, B, LDB, C, LDC, D,$ LDD, E, LDE, F, LDF, SCALE, DIF, WORK, LWORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSINTEGER IJOB, INFO, LDA, LDB, LDC, LDD, LDE, LDF,$ LWORK, M, NDOUBLE PRECISION DIF, SCALE* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),$ D( LDD, * ), E( LDE, * ), F( LDF, * ),$ WORK( * )* ..** =====================================================================* Replaced various illegal calls to DCOPY by calls to DLASET.* Sven Hammarling, 1/5/02.** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, NOTRANINTEGER I, IE, IFUNC, IROUND, IS, ISOLVE, J, JE, JS, K,$ LINFO, LWMIN, MB, NB, P, PPQQ, PQ, QDOUBLE PRECISION DSCALE, DSUM, SCALE2, SCALOC* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DGEMM, DLACPY, DLASET, DSCAL, DTGSY2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC DBLE, MAX, SQRT* ..* .. Executable Statements ..** Decode and test input parameters*INFO = 0NOTRAN = LSAME( TRANS, 'N' )LQUERY = ( LWORK.EQ.-1 )*IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) ) THENINFO = -1ELSE IF( NOTRAN ) THENIF( ( IJOB.LT.0 ) .OR. ( IJOB.GT.4 ) ) THENINFO = -2END IFEND IFIF( INFO.EQ.0 ) THENIF( M.LE.0 ) THENINFO = -3ELSE IF( N.LE.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -10ELSE IF( LDD.LT.MAX( 1, M ) ) THENINFO = -12ELSE IF( LDE.LT.MAX( 1, N ) ) THENINFO = -14ELSE IF( LDF.LT.MAX( 1, M ) ) THENINFO = -16END IFEND IF*IF( INFO.EQ.0 ) THENIF( NOTRAN ) THENIF( IJOB.EQ.1 .OR. IJOB.EQ.2 ) THENLWMIN = MAX( 1, 2*M*N )ELSELWMIN = 1END IFELSELWMIN = 1END IFWORK( 1 ) = LWMIN*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -20END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTGSYL', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) THENSCALE = 1IF( NOTRAN ) THENIF( IJOB.NE.0 ) THENDIF = 0END IFEND IFRETURNEND IF** Determine optimal block sizes MB and NB*MB = ILAENV( 2, 'DTGSYL', TRANS, M, N, -1, -1 )NB = ILAENV( 5, 'DTGSYL', TRANS, M, N, -1, -1 )*ISOLVE = 1IFUNC = 0IF( NOTRAN ) THENIF( IJOB.GE.3 ) THENIFUNC = IJOB - 2CALL DLASET( 'F', M, N, ZERO, ZERO, C, LDC )CALL DLASET( 'F', M, N, ZERO, ZERO, F, LDF )ELSE IF( IJOB.GE.1 ) THENISOLVE = 2END IFEND IF*IF( ( MB.LE.1 .AND. NB.LE.1 ) .OR. ( MB.GE.M .AND. NB.GE.N ) )$ THEN*DO 30 IROUND = 1, ISOLVE** Use unblocked Level 2 solver*DSCALE = ZERODSUM = ONEPQ = 0CALL DTGSY2( TRANS, IFUNC, M, N, A, LDA, B, LDB, C, LDC, D,$ LDD, E, LDE, F, LDF, SCALE, DSUM, DSCALE,$ IWORK, PQ, INFO )IF( DSCALE.NE.ZERO ) THENIF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THENDIF = SQRT( DBLE( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )ELSEDIF = SQRT( DBLE( PQ ) ) / ( DSCALE*SQRT( DSUM ) )END IFEND IF*IF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THENIF( NOTRAN ) THENIFUNC = IJOBEND IFSCALE2 = SCALECALL DLACPY( 'F', M, N, C, LDC, WORK, M )CALL DLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )CALL DLASET( 'F', M, N, ZERO, ZERO, C, LDC )CALL DLASET( 'F', M, N, ZERO, ZERO, F, LDF )ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THENCALL DLACPY( 'F', M, N, WORK, M, C, LDC )CALL DLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )SCALE = SCALE2END IF30 CONTINUE*RETURNEND IF** Determine block structure of A*P = 0I = 140 CONTINUEIF( I.GT.M )$ GO TO 50P = P + 1IWORK( P ) = II = I + MBIF( I.GE.M )$ GO TO 50IF( A( I, I-1 ).NE.ZERO )$ I = I + 1GO TO 4050 CONTINUE*IWORK( P+1 ) = M + 1IF( IWORK( P ).EQ.IWORK( P+1 ) )$ P = P - 1** Determine block structure of B*Q = P + 1J = 160 CONTINUEIF( J.GT.N )$ GO TO 70Q = Q + 1IWORK( Q ) = JJ = J + NBIF( J.GE.N )$ GO TO 70IF( B( J, J-1 ).NE.ZERO )$ J = J + 1GO TO 6070 CONTINUE*IWORK( Q+1 ) = N + 1IF( IWORK( Q ).EQ.IWORK( Q+1 ) )$ Q = Q - 1*IF( NOTRAN ) THEN*DO 150 IROUND = 1, ISOLVE** Solve (I, J)-subsystem* A(I, I) * R(I, J) - L(I, J) * B(J, J) = C(I, J)* D(I, I) * R(I, J) - L(I, J) * E(J, J) = F(I, J)* for I = P, P - 1,..., 1; J = 1, 2,..., Q*DSCALE = ZERODSUM = ONEPQ = 0SCALE = ONEDO 130 J = P + 2, QJS = IWORK( J )JE = IWORK( J+1 ) - 1NB = JE - JS + 1DO 120 I = P, 1, -1IS = IWORK( I )IE = IWORK( I+1 ) - 1MB = IE - IS + 1PPQQ = 0CALL DTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,$ B( JS, JS ), LDB, C( IS, JS ), LDC,$ D( IS, IS ), LDD, E( JS, JS ), LDE,$ F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,$ IWORK( Q+2 ), PPQQ, LINFO )IF( LINFO.GT.0 )$ INFO = LINFO*PQ = PQ + PPQQIF( SCALOC.NE.ONE ) THENDO 80 K = 1, JS - 1CALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )80 CONTINUEDO 90 K = JS, JECALL DSCAL( IS-1, SCALOC, C( 1, K ), 1 )CALL DSCAL( IS-1, SCALOC, F( 1, K ), 1 )90 CONTINUEDO 100 K = JS, JECALL DSCAL( M-IE, SCALOC, C( IE+1, K ), 1 )CALL DSCAL( M-IE, SCALOC, F( IE+1, K ), 1 )100 CONTINUEDO 110 K = JE + 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )110 CONTINUESCALE = SCALE*SCALOCEND IF** Substitute R(I, J) and L(I, J) into remaining* equation.*IF( I.GT.1 ) THENCALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,$ A( 1, IS ), LDA, C( IS, JS ), LDC, ONE,$ C( 1, JS ), LDC )CALL DGEMM( 'N', 'N', IS-1, NB, MB, -ONE,$ D( 1, IS ), LDD, C( IS, JS ), LDC, ONE,$ F( 1, JS ), LDF )END IFIF( J.LT.Q ) THENCALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE,$ F( IS, JS ), LDF, B( JS, JE+1 ), LDB,$ ONE, C( IS, JE+1 ), LDC )CALL DGEMM( 'N', 'N', MB, N-JE, NB, ONE,$ F( IS, JS ), LDF, E( JS, JE+1 ), LDE,$ ONE, F( IS, JE+1 ), LDF )END IF120 CONTINUE130 CONTINUEIF( DSCALE.NE.ZERO ) THENIF( IJOB.EQ.1 .OR. IJOB.EQ.3 ) THENDIF = SQRT( DBLE( 2*M*N ) ) / ( DSCALE*SQRT( DSUM ) )ELSEDIF = SQRT( DBLE( PQ ) ) / ( DSCALE*SQRT( DSUM ) )END IFEND IFIF( ISOLVE.EQ.2 .AND. IROUND.EQ.1 ) THENIF( NOTRAN ) THENIFUNC = IJOBEND IFSCALE2 = SCALECALL DLACPY( 'F', M, N, C, LDC, WORK, M )CALL DLACPY( 'F', M, N, F, LDF, WORK( M*N+1 ), M )CALL DLASET( 'F', M, N, ZERO, ZERO, C, LDC )CALL DLASET( 'F', M, N, ZERO, ZERO, F, LDF )ELSE IF( ISOLVE.EQ.2 .AND. IROUND.EQ.2 ) THENCALL DLACPY( 'F', M, N, WORK, M, C, LDC )CALL DLACPY( 'F', M, N, WORK( M*N+1 ), M, F, LDF )SCALE = SCALE2END IF150 CONTINUE*ELSE** Solve transposed (I, J)-subsystem* A(I, I)**T * R(I, J) + D(I, I)**T * L(I, J) = C(I, J)* R(I, J) * B(J, J)**T + L(I, J) * E(J, J)**T = -F(I, J)* for I = 1,2,..., P; J = Q, Q-1,..., 1*SCALE = ONEDO 210 I = 1, PIS = IWORK( I )IE = IWORK( I+1 ) - 1MB = IE - IS + 1DO 200 J = Q, P + 2, -1JS = IWORK( J )JE = IWORK( J+1 ) - 1NB = JE - JS + 1CALL DTGSY2( TRANS, IFUNC, MB, NB, A( IS, IS ), LDA,$ B( JS, JS ), LDB, C( IS, JS ), LDC,$ D( IS, IS ), LDD, E( JS, JS ), LDE,$ F( IS, JS ), LDF, SCALOC, DSUM, DSCALE,$ IWORK( Q+2 ), PPQQ, LINFO )IF( LINFO.GT.0 )$ INFO = LINFOIF( SCALOC.NE.ONE ) THENDO 160 K = 1, JS - 1CALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )160 CONTINUEDO 170 K = JS, JECALL DSCAL( IS-1, SCALOC, C( 1, K ), 1 )CALL DSCAL( IS-1, SCALOC, F( 1, K ), 1 )170 CONTINUEDO 180 K = JS, JECALL DSCAL( M-IE, SCALOC, C( IE+1, K ), 1 )CALL DSCAL( M-IE, SCALOC, F( IE+1, K ), 1 )180 CONTINUEDO 190 K = JE + 1, NCALL DSCAL( M, SCALOC, C( 1, K ), 1 )CALL DSCAL( M, SCALOC, F( 1, K ), 1 )190 CONTINUESCALE = SCALE*SCALOCEND IF** Substitute R(I, J) and L(I, J) into remaining equation.*IF( J.GT.P+2 ) THENCALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE, C( IS, JS ),$ LDC, B( 1, JS ), LDB, ONE, F( IS, 1 ),$ LDF )CALL DGEMM( 'N', 'T', MB, JS-1, NB, ONE, F( IS, JS ),$ LDF, E( 1, JS ), LDE, ONE, F( IS, 1 ),$ LDF )END IFIF( I.LT.P ) THENCALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,$ A( IS, IE+1 ), LDA, C( IS, JS ), LDC, ONE,$ C( IE+1, JS ), LDC )CALL DGEMM( 'T', 'N', M-IE, NB, MB, -ONE,$ D( IS, IE+1 ), LDD, F( IS, JS ), LDF, ONE,$ C( IE+1, JS ), LDC )END IF200 CONTINUE210 CONTINUE*END IF*WORK( 1 ) = LWMIN*RETURN** End of DTGSYL*END*> \brief \b DTPCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtpcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtpcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtpcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPCON( NORM, UPLO, DIAG, N, AP, RCOND, WORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER DIAG, NORM, UPLO* INTEGER INFO, N* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AP( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPCON estimates the reciprocal of the condition number of a packed*> triangular matrix A, in either the 1-norm or the infinity-norm.*>*> The norm of A is computed and an estimate is obtained for*> norm(inv(A)), then the reciprocal of the condition number is*> computed as*> RCOND = 1 / ( norm(A) * norm(inv(A)) ).*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies whether the 1-norm condition number or the*> infinity-norm condition number is required:*> = '1' or 'O': 1-norm;*> = 'I': Infinity-norm.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangular matrix A, packed columnwise in*> a linear array. The j-th column of A is stored in the array*> AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> If DIAG = 'U', the diagonal elements of A are not referenced*> and are assumed to be 1.*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(norm(A) * norm(inv(A))).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTPCON( NORM, UPLO, DIAG, N, AP, RCOND, WORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORM, UPLOINTEGER INFO, NDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AP( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, ONENRM, UPPERCHARACTER NORMININTEGER IX, KASE, KASE1DOUBLE PRECISION AINVNM, ANORM, SCALE, SMLNUM, XNORM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLANTPEXTERNAL LSAME, IDAMAX, DLAMCH, DLANTP* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATPS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )NOUNIT = LSAME( DIAG, 'N' )*IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPCON', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENRCOND = ONERETURNEND IF*RCOND = ZEROSMLNUM = DLAMCH( 'Safe minimum' )*DBLE( MAX( 1, N ) )** Compute the norm of the triangular matrix A.*ANORM = DLANTP( NORM, UPLO, DIAG, N, AP, WORK )** Continue only if ANORM > 0.*IF( ANORM.GT.ZERO ) THEN** Estimate the norm of the inverse of A.*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 010 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(A).*CALL DLATPS( UPLO, 'No transpose', DIAG, NORMIN, N, AP,$ WORK, SCALE, WORK( 2*N+1 ), INFO )ELSE** Multiply by inv(A**T).*CALL DLATPS( UPLO, 'Transpose', DIAG, NORMIN, N, AP,$ WORK, SCALE, WORK( 2*N+1 ), INFO )END IFNORMIN = 'Y'** Multiply by 1/SCALE if doing so will not cause overflow.*IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )XNORM = ABS( WORK( IX ) )IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / ANORM ) / AINVNMEND IF*20 CONTINUERETURN** End of DTPCON*END*> \brief \b DTPMQRT** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPMQRT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtpmqrt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtpmqrt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtpmqrt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPMQRT( SIDE, TRANS, M, N, K, L, NB, V, LDV, T, LDT,* A, LDA, B, LDB, WORK, INFO )** .. Scalar Arguments ..* CHARACTER SIDE, TRANS* INTEGER INFO, K, LDV, LDA, LDB, M, N, L, NB, LDT* ..* .. Array Arguments ..* DOUBLE PRECISION V( LDV, * ), A( LDA, * ), B( LDB, * ),* $ T( LDT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPMQRT applies a real orthogonal matrix Q obtained from a*> "triangular-pentagonal" real block reflector H to a general*> real matrix C, which consists of two blocks A and B.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply Q or Q**T from the Left;*> = 'R': apply Q or Q**T from the Right.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': No transpose, apply Q;*> = 'T': Transpose, apply Q**T.*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix B. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix B. N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The number of elementary reflectors whose product defines*> the matrix Q.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The order of the trapezoidal part of V.*> K >= L >= 0. See Further Details.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The block size used for the storage of T. K >= NB >= 1.*> This must be the same value of NB used to generate T*> in CTPQRT.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension (LDA,K)*> The i-th column must contain the vector which defines the*> elementary reflector H(i), for i = 1,2,...,k, as returned by*> CTPQRT in B. See Further Details.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If SIDE = 'L', LDV >= max(1,M);*> if SIDE = 'R', LDV >= max(1,N).*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The upper triangular factors of the block reflectors*> as returned by CTPQRT, stored as a NB-by-K matrix.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= NB.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,N) if SIDE = 'L' or*> (LDA,K) if SIDE = 'R'*> On entry, the K-by-N or M-by-K matrix A.*> On exit, A is overwritten by the corresponding block of*> Q*C or Q**T*C or C*Q or C*Q**T. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If SIDE = 'L', LDC >= max(1,K);*> If SIDE = 'R', LDC >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the M-by-N matrix B.*> On exit, B is overwritten by the corresponding block of*> Q*C or Q**T*C or C*Q or C*Q**T. See Further Details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B.*> LDB >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array. The dimension of WORK is*> N*NB if SIDE = 'L', or M*NB if SIDE = 'R'.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The columns of the pentagonal matrix V contain the elementary reflectors*> H(1), H(2), ..., H(K); V is composed of a rectangular block V1 and a*> trapezoidal block V2:*>*> V = [V1]*> [V2].*>*> The size of the trapezoidal block V2 is determined by the parameter L,*> where 0 <= L <= K; V2 is upper trapezoidal, consisting of the first L*> rows of a K-by-K upper triangular matrix. If L=K, V2 is upper triangular;*> if L=0, there is no trapezoidal block, hence V = V1 is rectangular.*>*> If SIDE = 'L': C = [A] where A is K-by-N, B is M-by-N and V is M-by-K.*> [B]*>*> If SIDE = 'R': C = [A B] where A is M-by-K, B is M-by-N and V is N-by-K.*>*> The real orthogonal matrix Q is formed from V and T.*>*> If TRANS='N' and SIDE='L', C is on exit replaced with Q * C.*>*> If TRANS='T' and SIDE='L', C is on exit replaced with Q**T * C.*>*> If TRANS='N' and SIDE='R', C is on exit replaced with C * Q.*>*> If TRANS='T' and SIDE='R', C is on exit replaced with C * Q**T.*> \endverbatim*>* =====================================================================SUBROUTINE DTPMQRT( SIDE, TRANS, M, N, K, L, NB, V, LDV, T, LDT,$ A, LDA, B, LDB, WORK, INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..CHARACTER SIDE, TRANSINTEGER INFO, K, LDV, LDA, LDB, M, N, L, NB, LDT* ..* .. Array Arguments ..DOUBLE PRECISION V( LDV, * ), A( LDA, * ), B( LDB, * ),$ T( LDT, * ), WORK( * )* ..** =====================================================================** ..* .. Local Scalars ..LOGICAL LEFT, RIGHT, TRAN, NOTRANINTEGER I, IB, MB, LB, KF, LDAQ, LDVQ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTPRFB, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** .. Test the input arguments ..*INFO = 0LEFT = LSAME( SIDE, 'L' )RIGHT = LSAME( SIDE, 'R' )TRAN = LSAME( TRANS, 'T' )NOTRAN = LSAME( TRANS, 'N' )*IF ( LEFT ) THENLDVQ = MAX( 1, M )LDAQ = MAX( 1, K )ELSE IF ( RIGHT ) THENLDVQ = MAX( 1, N )LDAQ = MAX( 1, M )END IFIF( .NOT.LEFT .AND. .NOT.RIGHT ) THENINFO = -1ELSE IF( .NOT.TRAN .AND. .NOT.NOTRAN ) THENINFO = -2ELSE IF( M.LT.0 ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( K.LT.0 ) THENINFO = -5ELSE IF( L.LT.0 .OR. L.GT.K ) THENINFO = -6ELSE IF( NB.LT.1 .OR. (NB.GT.K .AND. K.GT.0) ) THENINFO = -7ELSE IF( LDV.LT.LDVQ ) THENINFO = -9ELSE IF( LDT.LT.NB ) THENINFO = -11ELSE IF( LDA.LT.LDAQ ) THENINFO = -13ELSE IF( LDB.LT.MAX( 1, M ) ) THENINFO = -15END IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTPMQRT', -INFO )RETURNEND IF** .. Quick return if possible ..*IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 ) RETURN*IF( LEFT .AND. TRAN ) THEN*DO I = 1, K, NBIB = MIN( NB, K-I+1 )MB = MIN( M-L+I+IB-1, M )IF( I.GE.L ) THENLB = 0ELSELB = MB-M+L-I+1END IFCALL DTPRFB( 'L', 'T', 'F', 'C', MB, N, IB, LB,$ V( 1, I ), LDV, T( 1, I ), LDT,$ A( I, 1 ), LDA, B, LDB, WORK, IB )END DO*ELSE IF( RIGHT .AND. NOTRAN ) THEN*DO I = 1, K, NBIB = MIN( NB, K-I+1 )MB = MIN( N-L+I+IB-1, N )IF( I.GE.L ) THENLB = 0ELSELB = MB-N+L-I+1END IFCALL DTPRFB( 'R', 'N', 'F', 'C', M, MB, IB, LB,$ V( 1, I ), LDV, T( 1, I ), LDT,$ A( 1, I ), LDA, B, LDB, WORK, M )END DO*ELSE IF( LEFT .AND. NOTRAN ) THEN*KF = ((K-1)/NB)*NB+1DO I = KF, 1, -NBIB = MIN( NB, K-I+1 )MB = MIN( M-L+I+IB-1, M )IF( I.GE.L ) THENLB = 0ELSELB = MB-M+L-I+1END IFCALL DTPRFB( 'L', 'N', 'F', 'C', MB, N, IB, LB,$ V( 1, I ), LDV, T( 1, I ), LDT,$ A( I, 1 ), LDA, B, LDB, WORK, IB )END DO*ELSE IF( RIGHT .AND. TRAN ) THEN*KF = ((K-1)/NB)*NB+1DO I = KF, 1, -NBIB = MIN( NB, K-I+1 )MB = MIN( N-L+I+IB-1, N )IF( I.GE.L ) THENLB = 0ELSELB = MB-N+L-I+1END IFCALL DTPRFB( 'R', 'T', 'F', 'C', M, MB, IB, LB,$ V( 1, I ), LDV, T( 1, I ), LDT,$ A( 1, I ), LDA, B, LDB, WORK, M )END DO*END IF*RETURN** End of DTPMQRT*END*> \brief \b DTPQRT** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPQRT + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtpqrt.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtpqrt.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtpqrt.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPQRT( M, N, L, NB, A, LDA, B, LDB, T, LDT, WORK,* INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LDT, N, M, L, NB* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPQRT computes a blocked QR factorization of a real*> "triangular-pentagonal" matrix C, which is composed of a*> triangular block A and pentagonal block B, using the compact*> WY representation for Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix B.*> M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix B, and the order of the*> triangular matrix A.*> N >= 0.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of rows of the upper trapezoidal part of B.*> MIN(M,N) >= L >= 0. See Further Details.*> \endverbatim*>*> \param[in] NB*> \verbatim*> NB is INTEGER*> The block size to be used in the blocked QR. N >= NB >= 1.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the upper triangular N-by-N matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the upper triangular matrix R.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the pentagonal M-by-N matrix B. The first M-L rows*> are rectangular, and the last L rows are upper trapezoidal.*> On exit, B contains the pentagonal matrix V. See Further Details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,M).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The upper triangular block reflectors stored in compact form*> as a sequence of upper triangular blocks. See Further Details.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= NB.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (NB*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The input matrix C is a (N+M)-by-N matrix*>*> C = [ A ]*> [ B ]*>*> where A is an upper triangular N-by-N matrix, and B is M-by-N pentagonal*> matrix consisting of a (M-L)-by-N rectangular matrix B1 on top of a L-by-N*> upper trapezoidal matrix B2:*>*> B = [ B1 ] <- (M-L)-by-N rectangular*> [ B2 ] <- L-by-N upper trapezoidal.*>*> The upper trapezoidal matrix B2 consists of the first L rows of a*> N-by-N upper triangular matrix, where 0 <= L <= MIN(M,N). If L=0,*> B is rectangular M-by-N; if M=L=N, B is upper triangular.*>*> The matrix W stores the elementary reflectors H(i) in the i-th column*> below the diagonal (of A) in the (N+M)-by-N input matrix C*>*> C = [ A ] <- upper triangular N-by-N*> [ B ] <- M-by-N pentagonal*>*> so that W can be represented as*>*> W = [ I ] <- identity, N-by-N*> [ V ] <- M-by-N, same form as B.*>*> Thus, all of information needed for W is contained on exit in B, which*> we call V above. Note that V has the same form as B; that is,*>*> V = [ V1 ] <- (M-L)-by-N rectangular*> [ V2 ] <- L-by-N upper trapezoidal.*>*> The columns of V represent the vectors which define the H(i)'s.*>*> The number of blocks is B = ceiling(N/NB), where each*> block is of order NB except for the last block, which is of order*> IB = N - (B-1)*NB. For each of the B blocks, a upper triangular block*> reflector factor is computed: T1, T2, ..., TB. The NB-by-NB (and IB-by-IB*> for the last block) T's are stored in the NB-by-N matrix T as*>*> T = [T1 T2 ... TB].*> \endverbatim*>* =====================================================================SUBROUTINE DTPQRT( M, N, L, NB, A, LDA, B, LDB, T, LDT, WORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LDT, N, M, L, NB* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * ), WORK( * )* ..** =====================================================================** ..* .. Local Scalars ..INTEGER I, IB, LB, MB, IINFO* ..* .. External Subroutines ..EXTERNAL DTPQRT2, DTPRFB, XERBLA* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( L.LT.0 .OR. (L.GT.MIN(M,N) .AND. MIN(M,N).GE.0)) THENINFO = -3ELSE IF( NB.LT.1 .OR. (NB.GT.N .AND. N.GT.0)) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDB.LT.MAX( 1, M ) ) THENINFO = -8ELSE IF( LDT.LT.NB ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPQRT', -INFO )RETURNEND IF** Quick return if possible*IF( M.EQ.0 .OR. N.EQ.0 ) RETURN*DO I = 1, N, NB** Compute the QR factorization of the current block*IB = MIN( N-I+1, NB )MB = MIN( M-L+I+IB-1, M )IF( I.GE.L ) THENLB = 0ELSELB = MB-M+L-I+1END IF*CALL DTPQRT2( MB, IB, LB, A(I,I), LDA, B( 1, I ), LDB,$ T(1, I ), LDT, IINFO )** Update by applying H**T to B(:,I+IB:N) from the left*IF( I+IB.LE.N ) THENCALL DTPRFB( 'L', 'T', 'F', 'C', MB, N-I-IB+1, IB, LB,$ B( 1, I ), LDB, T( 1, I ), LDT,$ A( I, I+IB ), LDA, B( 1, I+IB ), LDB,$ WORK, IB )END IFEND DORETURN** End of DTPQRT*END*> \brief \b DTPQRT2 computes a QR factorization of a real or complex "triangular-pentagonal" matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPQRT2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtpqrt2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtpqrt2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtpqrt2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPQRT2( M, N, L, A, LDA, B, LDB, T, LDT, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LDB, LDT, N, M, L* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPQRT2 computes a QR factorization of a real "triangular-pentagonal"*> matrix C, which is composed of a triangular block A and pentagonal block B,*> using the compact WY representation for Q.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The total number of rows of the matrix B.*> M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix B, and the order of*> the triangular matrix A.*> N >= 0.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The number of rows of the upper trapezoidal part of B.*> MIN(M,N) >= L >= 0. See Further Details.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the upper triangular N-by-N matrix A.*> On exit, the elements on and above the diagonal of the array*> contain the upper triangular matrix R.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the pentagonal M-by-N matrix B. The first M-L rows*> are rectangular, and the last L rows are upper trapezoidal.*> On exit, B contains the pentagonal matrix V. See Further Details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,M).*> \endverbatim*>*> \param[out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The N-by-N upper triangular factor T of the block reflector.*> See Further Details.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The input matrix C is a (N+M)-by-N matrix*>*> C = [ A ]*> [ B ]*>*> where A is an upper triangular N-by-N matrix, and B is M-by-N pentagonal*> matrix consisting of a (M-L)-by-N rectangular matrix B1 on top of a L-by-N*> upper trapezoidal matrix B2:*>*> B = [ B1 ] <- (M-L)-by-N rectangular*> [ B2 ] <- L-by-N upper trapezoidal.*>*> The upper trapezoidal matrix B2 consists of the first L rows of a*> N-by-N upper triangular matrix, where 0 <= L <= MIN(M,N). If L=0,*> B is rectangular M-by-N; if M=L=N, B is upper triangular.*>*> The matrix W stores the elementary reflectors H(i) in the i-th column*> below the diagonal (of A) in the (N+M)-by-N input matrix C*>*> C = [ A ] <- upper triangular N-by-N*> [ B ] <- M-by-N pentagonal*>*> so that W can be represented as*>*> W = [ I ] <- identity, N-by-N*> [ V ] <- M-by-N, same form as B.*>*> Thus, all of information needed for W is contained on exit in B, which*> we call V above. Note that V has the same form as B; that is,*>*> V = [ V1 ] <- (M-L)-by-N rectangular*> [ V2 ] <- L-by-N upper trapezoidal.*>*> The columns of V represent the vectors which define the H(i)'s.*> The (M+N)-by-(M+N) block reflector H is then given by*>*> H = I - W * T * W**T*>*> where W^H is the conjugate transpose of W and T is the upper triangular*> factor of the block reflector.*> \endverbatim*>* =====================================================================SUBROUTINE DTPQRT2( M, N, L, A, LDA, B, LDB, T, LDT, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, LDB, LDT, N, M, L* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER( ONE = 1.0, ZERO = 0.0 )* ..* .. Local Scalars ..INTEGER I, J, P, MP, NPDOUBLE PRECISION ALPHA* ..* .. External Subroutines ..EXTERNAL DLARFG, DGEMV, DGER, DTRMV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input arguments*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( L.LT.0 .OR. L.GT.MIN(M,N) ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, M ) ) THENINFO = -7ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPQRT2', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. M.EQ.0 ) RETURN*DO I = 1, N** Generate elementary reflector H(I) to annihilate B(:,I)*P = M-L+MIN( L, I )CALL DLARFG( P+1, A( I, I ), B( 1, I ), 1, T( I, 1 ) )IF( I.LT.N ) THEN** W(1:N-I) := C(I:M,I+1:N)^H * C(I:M,I) [use W = T(:,N)]*DO J = 1, N-IT( J, N ) = (A( I, I+J ))END DOCALL DGEMV( 'T', P, N-I, ONE, B( 1, I+1 ), LDB,$ B( 1, I ), 1, ONE, T( 1, N ), 1 )** C(I:M,I+1:N) = C(I:m,I+1:N) + alpha*C(I:M,I)*W(1:N-1)^H*ALPHA = -(T( I, 1 ))DO J = 1, N-IA( I, I+J ) = A( I, I+J ) + ALPHA*(T( J, N ))END DOCALL DGER( P, N-I, ALPHA, B( 1, I ), 1,$ T( 1, N ), 1, B( 1, I+1 ), LDB )END IFEND DO*DO I = 2, N** T(1:I-1,I) := C(I:M,1:I-1)^H * (alpha * C(I:M,I))*ALPHA = -T( I, 1 )DO J = 1, I-1T( J, I ) = ZEROEND DOP = MIN( I-1, L )MP = MIN( M-L+1, M )NP = MIN( P+1, N )** Triangular part of B2*DO J = 1, PT( J, I ) = ALPHA*B( M-L+J, I )END DOCALL DTRMV( 'U', 'T', 'N', P, B( MP, 1 ), LDB,$ T( 1, I ), 1 )** Rectangular part of B2*CALL DGEMV( 'T', L, I-1-P, ALPHA, B( MP, NP ), LDB,$ B( MP, I ), 1, ZERO, T( NP, I ), 1 )** B1*CALL DGEMV( 'T', M-L, I-1, ALPHA, B, LDB, B( 1, I ), 1,$ ONE, T( 1, I ), 1 )** T(1:I-1,I) := T(1:I-1,1:I-1) * T(1:I-1,I)*CALL DTRMV( 'U', 'N', 'N', I-1, T, LDT, T( 1, I ), 1 )** T(I,I) = tau(I)*T( I, I ) = T( I, 1 )T( I, 1 ) = ZEROEND DO** End of DTPQRT2*END*> \brief \b DTPRFB applies a real or complex "triangular-pentagonal" blocked reflector to a real or complex matrix, which is composed of two blocks.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPRFB + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtprfb.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtprfb.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtprfb.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPRFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L,* V, LDV, T, LDT, A, LDA, B, LDB, WORK, LDWORK )** .. Scalar Arguments ..* CHARACTER DIRECT, SIDE, STOREV, TRANS* INTEGER K, L, LDA, LDB, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * ),* $ V( LDV, * ), WORK( LDWORK, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPRFB applies a real "triangular-pentagonal" block reflector H or its*> transpose H**T to a real matrix C, which is composed of two*> blocks A and B, either from the left or right.*>*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'L': apply H or H**T from the Left*> = 'R': apply H or H**T from the Right*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> = 'N': apply H (No transpose)*> = 'T': apply H**T (Transpose)*> \endverbatim*>*> \param[in] DIRECT*> \verbatim*> DIRECT is CHARACTER*1*> Indicates how H is formed from a product of elementary*> reflectors*> = 'F': H = H(1) H(2) . . . H(k) (Forward)*> = 'B': H = H(k) . . . H(2) H(1) (Backward)*> \endverbatim*>*> \param[in] STOREV*> \verbatim*> STOREV is CHARACTER*1*> Indicates how the vectors which define the elementary*> reflectors are stored:*> = 'C': Columns*> = 'R': Rows*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix B.*> M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix B.*> N >= 0.*> \endverbatim*>*> \param[in] K*> \verbatim*> K is INTEGER*> The order of the matrix T, i.e. the number of elementary*> reflectors whose product defines the block reflector.*> K >= 0.*> \endverbatim*>*> \param[in] L*> \verbatim*> L is INTEGER*> The order of the trapezoidal part of V.*> K >= L >= 0. See Further Details.*> \endverbatim*>*> \param[in] V*> \verbatim*> V is DOUBLE PRECISION array, dimension*> (LDV,K) if STOREV = 'C'*> (LDV,M) if STOREV = 'R' and SIDE = 'L'*> (LDV,N) if STOREV = 'R' and SIDE = 'R'*> The pentagonal matrix V, which contains the elementary reflectors*> H(1), H(2), ..., H(K). See Further Details.*> \endverbatim*>*> \param[in] LDV*> \verbatim*> LDV is INTEGER*> The leading dimension of the array V.*> If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);*> if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);*> if STOREV = 'R', LDV >= K.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,K)*> The triangular K-by-K matrix T in the representation of the*> block reflector.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T.*> LDT >= K.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension*> (LDA,N) if SIDE = 'L' or (LDA,K) if SIDE = 'R'*> On entry, the K-by-N or M-by-K matrix A.*> On exit, A is overwritten by the corresponding block of*> H*C or H**T*C or C*H or C*H**T. See Further Details.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A.*> If SIDE = 'L', LDC >= max(1,K);*> If SIDE = 'R', LDC >= max(1,M).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> On entry, the M-by-N matrix B.*> On exit, B is overwritten by the corresponding block of*> H*C or H**T*C or C*H or C*H**T. See Further Details.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B.*> LDB >= max(1,M).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension*> (LDWORK,N) if SIDE = 'L',*> (LDWORK,K) if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDWORK*> \verbatim*> LDWORK is INTEGER*> The leading dimension of the array WORK.*> If SIDE = 'L', LDWORK >= K;*> if SIDE = 'R', LDWORK >= M.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The matrix C is a composite matrix formed from blocks A and B.*> The block B is of size M-by-N; if SIDE = 'R', A is of size M-by-K,*> and if SIDE = 'L', A is of size K-by-N.*>*> If SIDE = 'R' and DIRECT = 'F', C = [A B].*>*> If SIDE = 'L' and DIRECT = 'F', C = [A]*> [B].*>*> If SIDE = 'R' and DIRECT = 'B', C = [B A].*>*> If SIDE = 'L' and DIRECT = 'B', C = [B]*> [A].*>*> The pentagonal matrix V is composed of a rectangular block V1 and a*> trapezoidal block V2. The size of the trapezoidal block is determined by*> the parameter L, where 0<=L<=K. If L=K, the V2 block of V is triangular;*> if L=0, there is no trapezoidal block, thus V = V1 is rectangular.*>*> If DIRECT = 'F' and STOREV = 'C': V = [V1]*> [V2]*> - V2 is upper trapezoidal (first L rows of K-by-K upper triangular)*>*> If DIRECT = 'F' and STOREV = 'R': V = [V1 V2]*>*> - V2 is lower trapezoidal (first L columns of K-by-K lower triangular)*>*> If DIRECT = 'B' and STOREV = 'C': V = [V2]*> [V1]*> - V2 is lower trapezoidal (last L rows of K-by-K lower triangular)*>*> If DIRECT = 'B' and STOREV = 'R': V = [V2 V1]*>*> - V2 is upper trapezoidal (last L columns of K-by-K upper triangular)*>*> If STOREV = 'C' and SIDE = 'L', V is M-by-K with V2 L-by-K.*>*> If STOREV = 'C' and SIDE = 'R', V is N-by-K with V2 L-by-K.*>*> If STOREV = 'R' and SIDE = 'L', V is K-by-M with V2 K-by-L.*>*> If STOREV = 'R' and SIDE = 'R', V is K-by-N with V2 K-by-L.*> \endverbatim*>* =====================================================================SUBROUTINE DTPRFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, L,$ V, LDV, T, LDT, A, LDA, B, LDB, WORK, LDWORK )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIRECT, SIDE, STOREV, TRANSINTEGER K, L, LDA, LDB, LDT, LDV, LDWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), T( LDT, * ),$ V( LDV, * ), WORK( LDWORK, * )* ..** ==========================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0, ZERO = 0.0 )* ..* .. Local Scalars ..INTEGER I, J, MP, NP, KPLOGICAL LEFT, FORWARD, COLUMN, RIGHT, BACKWARD, ROW* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DGEMM, DTRMM* ..* .. Executable Statements ..** Quick return if possible*IF( M.LE.0 .OR. N.LE.0 .OR. K.LE.0 .OR. L.LT.0 ) RETURN*IF( LSAME( STOREV, 'C' ) ) THENCOLUMN = .TRUE.ROW = .FALSE.ELSE IF ( LSAME( STOREV, 'R' ) ) THENCOLUMN = .FALSE.ROW = .TRUE.ELSECOLUMN = .FALSE.ROW = .FALSE.END IF*IF( LSAME( SIDE, 'L' ) ) THENLEFT = .TRUE.RIGHT = .FALSE.ELSE IF( LSAME( SIDE, 'R' ) ) THENLEFT = .FALSE.RIGHT = .TRUE.ELSELEFT = .FALSE.RIGHT = .FALSE.END IF*IF( LSAME( DIRECT, 'F' ) ) THENFORWARD = .TRUE.BACKWARD = .FALSE.ELSE IF( LSAME( DIRECT, 'B' ) ) THENFORWARD = .FALSE.BACKWARD = .TRUE.ELSEFORWARD = .FALSE.BACKWARD = .FALSE.END IF** ---------------------------------------------------------------------------*IF( COLUMN .AND. FORWARD .AND. LEFT ) THEN** ---------------------------------------------------------------------------** Let W = [ I ] (K-by-K)* [ V ] (M-by-K)** Form H C or H**T C where C = [ A ] (K-by-N)* [ B ] (M-by-N)** H = I - W T W**T or H**T = I - W T**T W**T** A = A - T (A + V**T B) or A = A - T**T (A + V**T B)* B = B - V T (A + V**T B) or B = B - V T**T (A + V**T B)** ---------------------------------------------------------------------------*MP = MIN( M-L+1, M )KP = MIN( L+1, K )*DO J = 1, NDO I = 1, LWORK( I, J ) = B( M-L+I, J )END DOEND DOCALL DTRMM( 'L', 'U', 'T', 'N', L, N, ONE, V( MP, 1 ), LDV,$ WORK, LDWORK )CALL DGEMM( 'T', 'N', L, N, M-L, ONE, V, LDV, B, LDB,$ ONE, WORK, LDWORK )CALL DGEMM( 'T', 'N', K-L, N, M, ONE, V( 1, KP ), LDV,$ B, LDB, ZERO, WORK( KP, 1 ), LDWORK )*DO J = 1, NDO I = 1, KWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'L', 'U', TRANS, 'N', K, N, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, NDO I = 1, KA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'N', 'N', M-L, N, K, -ONE, V, LDV, WORK, LDWORK,$ ONE, B, LDB )CALL DGEMM( 'N', 'N', L, N, K-L, -ONE, V( MP, KP ), LDV,$ WORK( KP, 1 ), LDWORK, ONE, B( MP, 1 ), LDB )CALL DTRMM( 'L', 'U', 'N', 'N', L, N, ONE, V( MP, 1 ), LDV,$ WORK, LDWORK )DO J = 1, NDO I = 1, LB( M-L+I, J ) = B( M-L+I, J ) - WORK( I, J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( COLUMN .AND. FORWARD .AND. RIGHT ) THEN** ---------------------------------------------------------------------------** Let W = [ I ] (K-by-K)* [ V ] (N-by-K)** Form C H or C H**T where C = [ A B ] (A is M-by-K, B is M-by-N)** H = I - W T W**T or H**T = I - W T**T W**T** A = A - (A + B V) T or A = A - (A + B V) T**T* B = B - (A + B V) T V**T or B = B - (A + B V) T**T V**T** ---------------------------------------------------------------------------*NP = MIN( N-L+1, N )KP = MIN( L+1, K )*DO J = 1, LDO I = 1, MWORK( I, J ) = B( I, N-L+J )END DOEND DOCALL DTRMM( 'R', 'U', 'N', 'N', M, L, ONE, V( NP, 1 ), LDV,$ WORK, LDWORK )CALL DGEMM( 'N', 'N', M, L, N-L, ONE, B, LDB,$ V, LDV, ONE, WORK, LDWORK )CALL DGEMM( 'N', 'N', M, K-L, N, ONE, B, LDB,$ V( 1, KP ), LDV, ZERO, WORK( 1, KP ), LDWORK )*DO J = 1, KDO I = 1, MWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'R', 'U', TRANS, 'N', M, K, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, KDO I = 1, MA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'N', 'T', M, N-L, K, -ONE, WORK, LDWORK,$ V, LDV, ONE, B, LDB )CALL DGEMM( 'N', 'T', M, L, K-L, -ONE, WORK( 1, KP ), LDWORK,$ V( NP, KP ), LDV, ONE, B( 1, NP ), LDB )CALL DTRMM( 'R', 'U', 'T', 'N', M, L, ONE, V( NP, 1 ), LDV,$ WORK, LDWORK )DO J = 1, LDO I = 1, MB( I, N-L+J ) = B( I, N-L+J ) - WORK( I, J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( COLUMN .AND. BACKWARD .AND. LEFT ) THEN** ---------------------------------------------------------------------------** Let W = [ V ] (M-by-K)* [ I ] (K-by-K)** Form H C or H**T C where C = [ B ] (M-by-N)* [ A ] (K-by-N)** H = I - W T W**T or H**T = I - W T**T W**T** A = A - T (A + V**T B) or A = A - T**T (A + V**T B)* B = B - V T (A + V**T B) or B = B - V T**T (A + V**T B)** ---------------------------------------------------------------------------*MP = MIN( L+1, M )KP = MIN( K-L+1, K )*DO J = 1, NDO I = 1, LWORK( K-L+I, J ) = B( I, J )END DOEND DO*CALL DTRMM( 'L', 'L', 'T', 'N', L, N, ONE, V( 1, KP ), LDV,$ WORK( KP, 1 ), LDWORK )CALL DGEMM( 'T', 'N', L, N, M-L, ONE, V( MP, KP ), LDV,$ B( MP, 1 ), LDB, ONE, WORK( KP, 1 ), LDWORK )CALL DGEMM( 'T', 'N', K-L, N, M, ONE, V, LDV,$ B, LDB, ZERO, WORK, LDWORK )*DO J = 1, NDO I = 1, KWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'L', 'L', TRANS, 'N', K, N, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, NDO I = 1, KA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'N', 'N', M-L, N, K, -ONE, V( MP, 1 ), LDV,$ WORK, LDWORK, ONE, B( MP, 1 ), LDB )CALL DGEMM( 'N', 'N', L, N, K-L, -ONE, V, LDV,$ WORK, LDWORK, ONE, B, LDB )CALL DTRMM( 'L', 'L', 'N', 'N', L, N, ONE, V( 1, KP ), LDV,$ WORK( KP, 1 ), LDWORK )DO J = 1, NDO I = 1, LB( I, J ) = B( I, J ) - WORK( K-L+I, J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( COLUMN .AND. BACKWARD .AND. RIGHT ) THEN** ---------------------------------------------------------------------------** Let W = [ V ] (N-by-K)* [ I ] (K-by-K)** Form C H or C H**T where C = [ B A ] (B is M-by-N, A is M-by-K)** H = I - W T W**T or H**T = I - W T**T W**T** A = A - (A + B V) T or A = A - (A + B V) T**T* B = B - (A + B V) T V**T or B = B - (A + B V) T**T V**T** ---------------------------------------------------------------------------*NP = MIN( L+1, N )KP = MIN( K-L+1, K )*DO J = 1, LDO I = 1, MWORK( I, K-L+J ) = B( I, J )END DOEND DOCALL DTRMM( 'R', 'L', 'N', 'N', M, L, ONE, V( 1, KP ), LDV,$ WORK( 1, KP ), LDWORK )CALL DGEMM( 'N', 'N', M, L, N-L, ONE, B( 1, NP ), LDB,$ V( NP, KP ), LDV, ONE, WORK( 1, KP ), LDWORK )CALL DGEMM( 'N', 'N', M, K-L, N, ONE, B, LDB,$ V, LDV, ZERO, WORK, LDWORK )*DO J = 1, KDO I = 1, MWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'R', 'L', TRANS, 'N', M, K, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, KDO I = 1, MA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'N', 'T', M, N-L, K, -ONE, WORK, LDWORK,$ V( NP, 1 ), LDV, ONE, B( 1, NP ), LDB )CALL DGEMM( 'N', 'T', M, L, K-L, -ONE, WORK, LDWORK,$ V, LDV, ONE, B, LDB )CALL DTRMM( 'R', 'L', 'T', 'N', M, L, ONE, V( 1, KP ), LDV,$ WORK( 1, KP ), LDWORK )DO J = 1, LDO I = 1, MB( I, J ) = B( I, J ) - WORK( I, K-L+J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( ROW .AND. FORWARD .AND. LEFT ) THEN** ---------------------------------------------------------------------------** Let W = [ I V ] ( I is K-by-K, V is K-by-M )** Form H C or H**T C where C = [ A ] (K-by-N)* [ B ] (M-by-N)** H = I - W**T T W or H**T = I - W**T T**T W** A = A - T (A + V B) or A = A - T**T (A + V B)* B = B - V**T T (A + V B) or B = B - V**T T**T (A + V B)** ---------------------------------------------------------------------------*MP = MIN( M-L+1, M )KP = MIN( L+1, K )*DO J = 1, NDO I = 1, LWORK( I, J ) = B( M-L+I, J )END DOEND DOCALL DTRMM( 'L', 'L', 'N', 'N', L, N, ONE, V( 1, MP ), LDV,$ WORK, LDB )CALL DGEMM( 'N', 'N', L, N, M-L, ONE, V, LDV,B, LDB,$ ONE, WORK, LDWORK )CALL DGEMM( 'N', 'N', K-L, N, M, ONE, V( KP, 1 ), LDV,$ B, LDB, ZERO, WORK( KP, 1 ), LDWORK )*DO J = 1, NDO I = 1, KWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'L', 'U', TRANS, 'N', K, N, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, NDO I = 1, KA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'T', 'N', M-L, N, K, -ONE, V, LDV, WORK, LDWORK,$ ONE, B, LDB )CALL DGEMM( 'T', 'N', L, N, K-L, -ONE, V( KP, MP ), LDV,$ WORK( KP, 1 ), LDWORK, ONE, B( MP, 1 ), LDB )CALL DTRMM( 'L', 'L', 'T', 'N', L, N, ONE, V( 1, MP ), LDV,$ WORK, LDWORK )DO J = 1, NDO I = 1, LB( M-L+I, J ) = B( M-L+I, J ) - WORK( I, J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( ROW .AND. FORWARD .AND. RIGHT ) THEN** ---------------------------------------------------------------------------** Let W = [ I V ] ( I is K-by-K, V is K-by-N )** Form C H or C H**T where C = [ A B ] (A is M-by-K, B is M-by-N)** H = I - W**T T W or H**T = I - W**T T**T W** A = A - (A + B V**T) T or A = A - (A + B V**T) T**T* B = B - (A + B V**T) T V or B = B - (A + B V**T) T**T V** ---------------------------------------------------------------------------*NP = MIN( N-L+1, N )KP = MIN( L+1, K )*DO J = 1, LDO I = 1, MWORK( I, J ) = B( I, N-L+J )END DOEND DOCALL DTRMM( 'R', 'L', 'T', 'N', M, L, ONE, V( 1, NP ), LDV,$ WORK, LDWORK )CALL DGEMM( 'N', 'T', M, L, N-L, ONE, B, LDB, V, LDV,$ ONE, WORK, LDWORK )CALL DGEMM( 'N', 'T', M, K-L, N, ONE, B, LDB,$ V( KP, 1 ), LDV, ZERO, WORK( 1, KP ), LDWORK )*DO J = 1, KDO I = 1, MWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'R', 'U', TRANS, 'N', M, K, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, KDO I = 1, MA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'N', 'N', M, N-L, K, -ONE, WORK, LDWORK,$ V, LDV, ONE, B, LDB )CALL DGEMM( 'N', 'N', M, L, K-L, -ONE, WORK( 1, KP ), LDWORK,$ V( KP, NP ), LDV, ONE, B( 1, NP ), LDB )CALL DTRMM( 'R', 'L', 'N', 'N', M, L, ONE, V( 1, NP ), LDV,$ WORK, LDWORK )DO J = 1, LDO I = 1, MB( I, N-L+J ) = B( I, N-L+J ) - WORK( I, J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( ROW .AND. BACKWARD .AND. LEFT ) THEN** ---------------------------------------------------------------------------** Let W = [ V I ] ( I is K-by-K, V is K-by-M )** Form H C or H**T C where C = [ B ] (M-by-N)* [ A ] (K-by-N)** H = I - W**T T W or H**T = I - W**T T**T W** A = A - T (A + V B) or A = A - T**T (A + V B)* B = B - V**T T (A + V B) or B = B - V**T T**T (A + V B)** ---------------------------------------------------------------------------*MP = MIN( L+1, M )KP = MIN( K-L+1, K )*DO J = 1, NDO I = 1, LWORK( K-L+I, J ) = B( I, J )END DOEND DOCALL DTRMM( 'L', 'U', 'N', 'N', L, N, ONE, V( KP, 1 ), LDV,$ WORK( KP, 1 ), LDWORK )CALL DGEMM( 'N', 'N', L, N, M-L, ONE, V( KP, MP ), LDV,$ B( MP, 1 ), LDB, ONE, WORK( KP, 1 ), LDWORK )CALL DGEMM( 'N', 'N', K-L, N, M, ONE, V, LDV, B, LDB,$ ZERO, WORK, LDWORK )*DO J = 1, NDO I = 1, KWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'L', 'L ', TRANS, 'N', K, N, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, NDO I = 1, KA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'T', 'N', M-L, N, K, -ONE, V( 1, MP ), LDV,$ WORK, LDWORK, ONE, B( MP, 1 ), LDB )CALL DGEMM( 'T', 'N', L, N, K-L, -ONE, V, LDV,$ WORK, LDWORK, ONE, B, LDB )CALL DTRMM( 'L', 'U', 'T', 'N', L, N, ONE, V( KP, 1 ), LDV,$ WORK( KP, 1 ), LDWORK )DO J = 1, NDO I = 1, LB( I, J ) = B( I, J ) - WORK( K-L+I, J )END DOEND DO** ---------------------------------------------------------------------------*ELSE IF( ROW .AND. BACKWARD .AND. RIGHT ) THEN** ---------------------------------------------------------------------------** Let W = [ V I ] ( I is K-by-K, V is K-by-N )** Form C H or C H**T where C = [ B A ] (A is M-by-K, B is M-by-N)** H = I - W**T T W or H**T = I - W**T T**T W** A = A - (A + B V**T) T or A = A - (A + B V**T) T**T* B = B - (A + B V**T) T V or B = B - (A + B V**T) T**T V** ---------------------------------------------------------------------------*NP = MIN( L+1, N )KP = MIN( K-L+1, K )*DO J = 1, LDO I = 1, MWORK( I, K-L+J ) = B( I, J )END DOEND DOCALL DTRMM( 'R', 'U', 'T', 'N', M, L, ONE, V( KP, 1 ), LDV,$ WORK( 1, KP ), LDWORK )CALL DGEMM( 'N', 'T', M, L, N-L, ONE, B( 1, NP ), LDB,$ V( KP, NP ), LDV, ONE, WORK( 1, KP ), LDWORK )CALL DGEMM( 'N', 'T', M, K-L, N, ONE, B, LDB, V, LDV,$ ZERO, WORK, LDWORK )*DO J = 1, KDO I = 1, MWORK( I, J ) = WORK( I, J ) + A( I, J )END DOEND DO*CALL DTRMM( 'R', 'L', TRANS, 'N', M, K, ONE, T, LDT,$ WORK, LDWORK )*DO J = 1, KDO I = 1, MA( I, J ) = A( I, J ) - WORK( I, J )END DOEND DO*CALL DGEMM( 'N', 'N', M, N-L, K, -ONE, WORK, LDWORK,$ V( 1, NP ), LDV, ONE, B( 1, NP ), LDB )CALL DGEMM( 'N', 'N', M, L, K-L , -ONE, WORK, LDWORK,$ V, LDV, ONE, B, LDB )CALL DTRMM( 'R', 'U', 'N', 'N', M, L, ONE, V( KP, 1 ), LDV,$ WORK( 1, KP ), LDWORK )DO J = 1, LDO I = 1, MB( I, J ) = B( I, J ) - WORK( I, K-L+J )END DOEND DO*END IF*RETURN** End of DTPRFB*END*> \brief \b DTPRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtprfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtprfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtprfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPRFS( UPLO, TRANS, DIAG, N, NRHS, AP, B, LDB, X, LDX,* FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, TRANS, UPLO* INTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION AP( * ), B( LDB, * ), BERR( * ), FERR( * ),* $ WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPRFS provides error bounds and backward error estimates for the*> solution to a system of linear equations with a triangular packed*> coefficient matrix.*>*> The solution matrix X must be computed by DTPTRS or some other*> means before entering this routine. DTPRFS does not do iterative*> refinement because doing so cannot improve the backward error.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangular matrix A, packed columnwise in*> a linear array. The j-th column of A is stored in the array*> AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*> If DIAG = 'U', the diagonal elements of A are not referenced*> and are assumed to be 1.*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> The solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTPRFS( UPLO, TRANS, DIAG, N, NRHS, AP, B, LDB, X, LDX,$ FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, TRANS, UPLOINTEGER INFO, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION AP( * ), B( LDB, * ), BERR( * ), FERR( * ),$ WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERCHARACTER TRANSTINTEGER I, J, K, KASE, KC, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DTPMV, DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -10END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 250 J = 1, NRHS** Compute residual R = B - op(A) * X,* where op(A) = A or A**T, depending on TRANS.*CALL DCOPY( N, X( 1, J ), 1, WORK( N+1 ), 1 )CALL DTPMV( UPLO, TRANS, DIAG, N, AP, WORK( N+1 ), 1 )CALL DAXPY( N, -ONE, B( 1, J ), 1, WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 20 I = 1, NWORK( I ) = ABS( B( I, J ) )20 CONTINUE*IF( NOTRAN ) THEN** Compute abs(A)*abs(X) + abs(B).*IF( UPPER ) THENKC = 1IF( NOUNIT ) THENDO 40 K = 1, NXK = ABS( X( K, J ) )DO 30 I = 1, KWORK( I ) = WORK( I ) + ABS( AP( KC+I-1 ) )*XK30 CONTINUEKC = KC + K40 CONTINUEELSEDO 60 K = 1, NXK = ABS( X( K, J ) )DO 50 I = 1, K - 1WORK( I ) = WORK( I ) + ABS( AP( KC+I-1 ) )*XK50 CONTINUEWORK( K ) = WORK( K ) + XKKC = KC + K60 CONTINUEEND IFELSEKC = 1IF( NOUNIT ) THENDO 80 K = 1, NXK = ABS( X( K, J ) )DO 70 I = K, NWORK( I ) = WORK( I ) + ABS( AP( KC+I-K ) )*XK70 CONTINUEKC = KC + N - K + 180 CONTINUEELSEDO 100 K = 1, NXK = ABS( X( K, J ) )DO 90 I = K + 1, NWORK( I ) = WORK( I ) + ABS( AP( KC+I-K ) )*XK90 CONTINUEWORK( K ) = WORK( K ) + XKKC = KC + N - K + 1100 CONTINUEEND IFEND IFELSE** Compute abs(A**T)*abs(X) + abs(B).*IF( UPPER ) THENKC = 1IF( NOUNIT ) THENDO 120 K = 1, NS = ZERODO 110 I = 1, KS = S + ABS( AP( KC+I-1 ) )*ABS( X( I, J ) )110 CONTINUEWORK( K ) = WORK( K ) + SKC = KC + K120 CONTINUEELSEDO 140 K = 1, NS = ABS( X( K, J ) )DO 130 I = 1, K - 1S = S + ABS( AP( KC+I-1 ) )*ABS( X( I, J ) )130 CONTINUEWORK( K ) = WORK( K ) + SKC = KC + K140 CONTINUEEND IFELSEKC = 1IF( NOUNIT ) THENDO 160 K = 1, NS = ZERODO 150 I = K, NS = S + ABS( AP( KC+I-K ) )*ABS( X( I, J ) )150 CONTINUEWORK( K ) = WORK( K ) + SKC = KC + N - K + 1160 CONTINUEELSEDO 180 K = 1, NS = ABS( X( K, J ) )DO 170 I = K + 1, NS = S + ABS( AP( KC+I-K ) )*ABS( X( I, J ) )170 CONTINUEWORK( K ) = WORK( K ) + SKC = KC + N - K + 1180 CONTINUEEND IFEND IFEND IFS = ZERODO 190 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF190 CONTINUEBERR( J ) = S** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 200 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF200 CONTINUE*KASE = 0210 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DTPSV( UPLO, TRANST, DIAG, N, AP, WORK( N+1 ), 1 )DO 220 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )220 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 230 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )230 CONTINUECALL DTPSV( UPLO, TRANS, DIAG, N, AP, WORK( N+1 ), 1 )END IFGO TO 210END IF** Normalize error.*LSTRES = ZERODO 240 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )240 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*250 CONTINUE*RETURN** End of DTPRFS*END*> \brief \b DTPTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtptri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtptri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtptri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPTRI( UPLO, DIAG, N, AP, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPTRI computes the inverse of a real upper or lower triangular*> matrix A stored in packed format.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On entry, the upper or lower triangular matrix A, stored*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*((2*n-j)/2) = A(i,j) for j<=i<=n.*> See below for further details.*> On exit, the (triangular) inverse of the original matrix, in*> the same packed storage format.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, A(i,i) is exactly zero. The triangular*> matrix is singular and its inverse can not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> A triangular matrix A can be transferred to packed storage using one*> of the following program segments:*>*> UPLO = 'U': UPLO = 'L':*>*> JC = 1 JC = 1*> DO 2 J = 1, N DO 2 J = 1, N*> DO 1 I = 1, J DO 1 I = J, N*> AP(JC+I-1) = A(I,J) AP(JC+I-J) = A(I,J)*> 1 CONTINUE 1 CONTINUE*> JC = JC + J JC = JC + N - J + 1*> 2 CONTINUE 2 CONTINUE*> \endverbatim*>* =====================================================================SUBROUTINE DTPTRI( UPLO, DIAG, N, AP, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, UPLOINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, UPPERINTEGER J, JC, JCLAST, JJDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DTPMV, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOUNIT = LSAME( DIAG, 'N' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPTRI', -INFO )RETURNEND IF** Check for singularity if non-unit.*IF( NOUNIT ) THENIF( UPPER ) THENJJ = 0DO 10 INFO = 1, NJJ = JJ + INFOIF( AP( JJ ).EQ.ZERO )$ RETURN10 CONTINUEELSEJJ = 1DO 20 INFO = 1, NIF( AP( JJ ).EQ.ZERO )$ RETURNJJ = JJ + N - INFO + 120 CONTINUEEND IFINFO = 0END IF*IF( UPPER ) THEN** Compute inverse of upper triangular matrix.*JC = 1DO 30 J = 1, NIF( NOUNIT ) THENAP( JC+J-1 ) = ONE / AP( JC+J-1 )AJJ = -AP( JC+J-1 )ELSEAJJ = -ONEEND IF** Compute elements 1:j-1 of j-th column.*CALL DTPMV( 'Upper', 'No transpose', DIAG, J-1, AP,$ AP( JC ), 1 )CALL DSCAL( J-1, AJJ, AP( JC ), 1 )JC = JC + J30 CONTINUE*ELSE** Compute inverse of lower triangular matrix.*JC = N*( N+1 ) / 2DO 40 J = N, 1, -1IF( NOUNIT ) THENAP( JC ) = ONE / AP( JC )AJJ = -AP( JC )ELSEAJJ = -ONEEND IFIF( J.LT.N ) THEN** Compute elements j+1:n of j-th column.*CALL DTPMV( 'Lower', 'No transpose', DIAG, N-J,$ AP( JCLAST ), AP( JC+1 ), 1 )CALL DSCAL( N-J, AJJ, AP( JC+1 ), 1 )END IFJCLAST = JCJC = JC - N + J - 240 CONTINUEEND IF*RETURN** End of DTPTRI*END*> \brief \b DTPTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtptrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtptrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtptrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPTRS( UPLO, TRANS, DIAG, N, NRHS, AP, B, LDB, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, TRANS, UPLO* INTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION AP( * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPTRS solves a triangular system of the form*>*> A * X = B or A**T * X = B,*>*> where A is a triangular matrix of order N stored in packed format,*> and B is an N-by-NRHS matrix. A check is made to verify that A is*> nonsingular.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> The upper or lower triangular matrix A, packed columnwise in*> a linear array. The j-th column of A is stored in the array*> AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, if INFO = 0, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element of A is zero,*> indicating that the matrix is singular and the*> solutions X have not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTPTRS( UPLO, TRANS, DIAG, N, NRHS, AP, B, LDB, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, TRANS, UPLOINTEGER INFO, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION AP( * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, UPPERINTEGER J, JC* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTPSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOUNIT = LSAME( DIAG, 'N' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.$ LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Check for singularity.*IF( NOUNIT ) THENIF( UPPER ) THENJC = 1DO 10 INFO = 1, NIF( AP( JC+INFO-1 ).EQ.ZERO )$ RETURNJC = JC + INFO10 CONTINUEELSEJC = 1DO 20 INFO = 1, NIF( AP( JC ).EQ.ZERO )$ RETURNJC = JC + N - INFO + 120 CONTINUEEND IFEND IFINFO = 0** Solve A * x = b or A**T * x = b.*DO 30 J = 1, NRHSCALL DTPSV( UPLO, TRANS, DIAG, N, AP, B( 1, J ), 1 )30 CONTINUE*RETURN** End of DTPTRS*END*> \brief \b DTPTTF copies a triangular matrix from the standard packed format (TP) to the rectangular full packed format (TF).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPTTF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtpttf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtpttf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtpttf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPTTF( TRANSR, UPLO, N, AP, ARF, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER INFO, N* ..* .. Array Arguments ..* DOUBLE PRECISION AP( 0: * ), ARF( 0: * )***> \par Purpose:* =============*>*> \verbatim*>*> DTPTTF copies a triangular matrix A from standard packed format (TP)*> to rectangular full packed format (TF).*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': ARF in Normal format is wanted;*> = 'T': ARF in Conjugate-transpose format is wanted.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ),*> On entry, the upper or lower triangular matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[out] ARF*> \verbatim*> ARF is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ),*> On exit, the upper or lower triangular matrix A stored in*> RFP format. For a further discussion see Notes below.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim*>* =====================================================================SUBROUTINE DTPTTF( TRANSR, UPLO, N, AP, ARF, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER INFO, N* ..* .. Array Arguments ..DOUBLE PRECISION AP( 0: * ), ARF( 0: * )** =====================================================================** .. Parameters ..* ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER N1, N2, K, NTINTEGER I, J, IJINTEGER IJP, JP, LDA, JS* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPTTF', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( NORMALTRANSR ) THENARF( 0 ) = AP( 0 )ELSEARF( 0 ) = AP( 0 )END IFRETURNEND IF** Size of array ARF(0:NT-1)*NT = N*( N+1 ) / 2** Set N1 and N2 depending on LOWER*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF** If N is odd, set NISODD = .TRUE.* If N is even, set K = N/2 and NISODD = .FALSE.** set lda of ARF^C; ARF^C is (0:(N+1)/2-1,0:N-noe)* where noe = 0 if n is even, noe = 1 if n is odd*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.LDA = N + 1ELSENISODD = .TRUE.LDA = NEND IF** ARF^C has lda rows and n+1-noe cols*IF( .NOT.NORMALTRANSR )$ LDA = ( N+1 ) / 2** start execution: there are eight cases*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** N is odd, TRANSR = 'N', and UPLO = 'L'*IJP = 0JP = 0DO J = 0, N2DO I = J, N - 1IJ = I + JPARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJP = JP + LDAEND DODO I = 0, N2 - 1DO J = 1 + I, N2IJ = I + J*LDAARF( IJ ) = AP( IJP )IJP = IJP + 1END DOEND DO*ELSE** N is odd, TRANSR = 'N', and UPLO = 'U'*IJP = 0DO J = 0, N1 - 1IJ = N2 + JDO I = 0, JARF( IJ ) = AP( IJP )IJP = IJP + 1IJ = IJ + LDAEND DOEND DOJS = 0DO J = N1, N - 1IJ = JSDO IJ = JS, JS + JARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJS = JS + LDAEND DO*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** N is odd, TRANSR = 'T', and UPLO = 'L'*IJP = 0DO I = 0, N2DO IJ = I*( LDA+1 ), N*LDA - 1, LDAARF( IJ ) = AP( IJP )IJP = IJP + 1END DOEND DOJS = 1DO J = 0, N2 - 1DO IJ = JS, JS + N2 - J - 1ARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJS = JS + LDA + 1END DO*ELSE** N is odd, TRANSR = 'T', and UPLO = 'U'*IJP = 0JS = N2*LDADO J = 0, N1 - 1DO IJ = JS, JS + JARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJS = JS + LDAEND DODO I = 0, N1DO IJ = I, I + ( N1+I )*LDA, LDAARF( IJ ) = AP( IJP )IJP = IJP + 1END DOEND DO*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** N is even, TRANSR = 'N', and UPLO = 'L'*IJP = 0JP = 0DO J = 0, K - 1DO I = J, N - 1IJ = 1 + I + JPARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJP = JP + LDAEND DODO I = 0, K - 1DO J = I, K - 1IJ = I + J*LDAARF( IJ ) = AP( IJP )IJP = IJP + 1END DOEND DO*ELSE** N is even, TRANSR = 'N', and UPLO = 'U'*IJP = 0DO J = 0, K - 1IJ = K + 1 + JDO I = 0, JARF( IJ ) = AP( IJP )IJP = IJP + 1IJ = IJ + LDAEND DOEND DOJS = 0DO J = K, N - 1IJ = JSDO IJ = JS, JS + JARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJS = JS + LDAEND DO*END IF*ELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** N is even, TRANSR = 'T', and UPLO = 'L'*IJP = 0DO I = 0, K - 1DO IJ = I + ( I+1 )*LDA, ( N+1 )*LDA - 1, LDAARF( IJ ) = AP( IJP )IJP = IJP + 1END DOEND DOJS = 0DO J = 0, K - 1DO IJ = JS, JS + K - J - 1ARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJS = JS + LDA + 1END DO*ELSE** N is even, TRANSR = 'T', and UPLO = 'U'*IJP = 0JS = ( K+1 )*LDADO J = 0, K - 1DO IJ = JS, JS + JARF( IJ ) = AP( IJP )IJP = IJP + 1END DOJS = JS + LDAEND DODO I = 0, K - 1DO IJ = I, I + ( K+I )*LDA, LDAARF( IJ ) = AP( IJP )IJP = IJP + 1END DOEND DO*END IF*END IF*END IF*RETURN** End of DTPTTF*END*> \brief \b DTPTTR copies a triangular matrix from the standard packed format (TP) to the standard full format (TR).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTPTTR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtpttr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtpttr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtpttr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTPTTR( UPLO, N, AP, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N, LDA* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), AP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTPTTR copies a triangular matrix A from standard packed format (TP)*> to standard full format (TR).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular.*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ),*> On entry, the upper or lower triangular matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension ( LDA, N )*> On exit, the triangular matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTPTTR( UPLO, N, AP, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N, LDA* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), AP( * )* ..** =====================================================================** .. Parameters ..* ..* .. Local Scalars ..LOGICAL LOWERINTEGER I, J, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0LOWER = LSAME( UPLO, 'L' )IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTPTTR', -INFO )RETURNEND IF*IF( LOWER ) THENK = 0DO J = 1, NDO I = J, NK = K + 1A( I, J ) = AP( K )END DOEND DOELSEK = 0DO J = 1, NDO I = 1, JK = K + 1A( I, J ) = AP( K )END DOEND DOEND IF**RETURN** End of DTPTTR*END*> \brief \b DTRCON** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRCON + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrcon.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrcon.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrcon.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRCON( NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK,* IWORK, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, NORM, UPLO* INTEGER INFO, LDA, N* DOUBLE PRECISION RCOND* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRCON estimates the reciprocal of the condition number of a*> triangular matrix A, in either the 1-norm or the infinity-norm.*>*> The norm of A is computed and an estimate is obtained for*> norm(inv(A)), then the reciprocal of the condition number is*> computed as*> RCOND = 1 / ( norm(A) * norm(inv(A)) ).*> \endverbatim** Arguments:* ==========**> \param[in] NORM*> \verbatim*> NORM is CHARACTER*1*> Specifies whether the 1-norm condition number or the*> infinity-norm condition number is required:*> = '1' or 'O': 1-norm;*> = 'I': Infinity-norm.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The triangular matrix A. If UPLO = 'U', the leading N-by-N*> upper triangular part of the array A contains the upper*> triangular matrix, and the strictly lower triangular part of*> A is not referenced. If UPLO = 'L', the leading N-by-N lower*> triangular part of the array A contains the lower triangular*> matrix, and the strictly upper triangular part of A is not*> referenced. If DIAG = 'U', the diagonal elements of A are*> also not referenced and are assumed to be 1.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] RCOND*> \verbatim*> RCOND is DOUBLE PRECISION*> The reciprocal of the condition number of the matrix A,*> computed as RCOND = 1/(norm(A) * norm(inv(A))).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTRCON( NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK,$ IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, NORM, UPLOINTEGER INFO, LDA, NDOUBLE PRECISION RCOND* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, ONENRM, UPPERCHARACTER NORMININTEGER IX, KASE, KASE1DOUBLE PRECISION AINVNM, ANORM, SCALE, SMLNUM, XNORM* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DLAMCH, DLANTREXTERNAL LSAME, IDAMAX, DLAMCH, DLANTR* ..* .. External Subroutines ..EXTERNAL DLACN2, DLATRS, DRSCL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' )NOUNIT = LSAME( DIAG, 'N' )*IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THENINFO = -1ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -6END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRCON', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 ) THENRCOND = ONERETURNEND IF*RCOND = ZEROSMLNUM = DLAMCH( 'Safe minimum' )*DBLE( MAX( 1, N ) )** Compute the norm of the triangular matrix A.*ANORM = DLANTR( NORM, UPLO, DIAG, N, N, A, LDA, WORK )** Continue only if ANORM > 0.*IF( ANORM.GT.ZERO ) THEN** Estimate the norm of the inverse of A.*AINVNM = ZERONORMIN = 'N'IF( ONENRM ) THENKASE1 = 1ELSEKASE1 = 2END IFKASE = 010 CONTINUECALL DLACN2( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.KASE1 ) THEN** Multiply by inv(A).*CALL DLATRS( UPLO, 'No transpose', DIAG, NORMIN, N, A,$ LDA, WORK, SCALE, WORK( 2*N+1 ), INFO )ELSE** Multiply by inv(A**T).*CALL DLATRS( UPLO, 'Transpose', DIAG, NORMIN, N, A, LDA,$ WORK, SCALE, WORK( 2*N+1 ), INFO )END IFNORMIN = 'Y'** Multiply by 1/SCALE if doing so will not cause overflow.*IF( SCALE.NE.ONE ) THENIX = IDAMAX( N, WORK, 1 )XNORM = ABS( WORK( IX ) )IF( SCALE.LT.XNORM*SMLNUM .OR. SCALE.EQ.ZERO )$ GO TO 20CALL DRSCL( N, SCALE, WORK, 1 )END IFGO TO 10END IF** Compute the estimate of the reciprocal condition number.*IF( AINVNM.NE.ZERO )$ RCOND = ( ONE / ANORM ) / AINVNMEND IF*20 CONTINUERETURN** End of DTRCON*END*> \brief \b DTREVC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTREVC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrevc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrevc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrevc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,* LDVR, MM, M, WORK, INFO )** .. Scalar Arguments ..* CHARACTER HOWMNY, SIDE* INTEGER INFO, LDT, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..* LOGICAL SELECT( * )* DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTREVC computes some or all of the right and/or left eigenvectors of*> a real upper quasi-triangular matrix T.*> Matrices of this type are produced by the Schur factorization of*> a real general matrix: A = Q*T*Q**T, as computed by DHSEQR.*>*> The right eigenvector x and the left eigenvector y of T corresponding*> to an eigenvalue w are defined by:*>*> T*x = w*x, (y**H)*T = w*(y**H)*>*> where y**H denotes the conjugate transpose of y.*> The eigenvalues are not input to this routine, but are read directly*> from the diagonal blocks of T.*>*> This routine returns the matrices X and/or Y of right and left*> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an*> input matrix. If Q is the orthogonal factor that reduces a matrix*> A to Schur form T, then Q*X and Q*Y are the matrices of right and*> left eigenvectors of A.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'R': compute right eigenvectors only;*> = 'L': compute left eigenvectors only;*> = 'B': compute both right and left eigenvectors.*> \endverbatim*>*> \param[in] HOWMNY*> \verbatim*> HOWMNY is CHARACTER*1*> = 'A': compute all right and/or left eigenvectors;*> = 'B': compute all right and/or left eigenvectors,*> backtransformed by the matrices in VR and/or VL;*> = 'S': compute selected right and/or left eigenvectors,*> as indicated by the logical array SELECT.*> \endverbatim*>*> \param[in,out] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> If HOWMNY = 'S', SELECT specifies the eigenvectors to be*> computed.*> If w(j) is a real eigenvalue, the corresponding real*> eigenvector is computed if SELECT(j) is .TRUE..*> If w(j) and w(j+1) are the real and imaginary parts of a*> complex eigenvalue, the corresponding complex eigenvector is*> computed if either SELECT(j) or SELECT(j+1) is .TRUE., and*> on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to*> .FALSE..*> Not referenced if HOWMNY = 'A' or 'B'.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T. N >= 0.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The upper quasi-triangular matrix T in Schur canonical form.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,MM)*> On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must*> contain an N-by-N matrix Q (usually the orthogonal matrix Q*> of Schur vectors returned by DHSEQR).*> On exit, if SIDE = 'L' or 'B', VL contains:*> if HOWMNY = 'A', the matrix Y of left eigenvectors of T;*> if HOWMNY = 'B', the matrix Q*Y;*> if HOWMNY = 'S', the left eigenvectors of T specified by*> SELECT, stored consecutively in the columns*> of VL, in the same order as their*> eigenvalues.*> A complex eigenvector corresponding to a complex eigenvalue*> is stored in two consecutive columns, the first holding the*> real part, and the second the imaginary part.*> Not referenced if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL. LDVL >= 1, and if*> SIDE = 'L' or 'B', LDVL >= N.*> \endverbatim*>*> \param[in,out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,MM)*> On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must*> contain an N-by-N matrix Q (usually the orthogonal matrix Q*> of Schur vectors returned by DHSEQR).*> On exit, if SIDE = 'R' or 'B', VR contains:*> if HOWMNY = 'A', the matrix X of right eigenvectors of T;*> if HOWMNY = 'B', the matrix Q*X;*> if HOWMNY = 'S', the right eigenvectors of T specified by*> SELECT, stored consecutively in the columns*> of VR, in the same order as their*> eigenvalues.*> A complex eigenvector corresponding to a complex eigenvalue*> is stored in two consecutive columns, the first holding the*> real part and the second the imaginary part.*> Not referenced if SIDE = 'L'.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR. LDVR >= 1, and if*> SIDE = 'R' or 'B', LDVR >= N.*> \endverbatim*>*> \param[in] MM*> \verbatim*> MM is INTEGER*> The number of columns in the arrays VL and/or VR. MM >= M.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The number of columns in the arrays VL and/or VR actually*> used to store the eigenvectors.*> If HOWMNY = 'A' or 'B', M is set to N.*> Each selected real eigenvector occupies one column and each*> selected complex eigenvector occupies two columns.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The algorithm used in this program is basically backward (forward)*> substitution, with scaling to make the the code robust against*> possible overflow.*>*> Each eigenvector is normalized so that the element of largest*> magnitude has magnitude 1; here the magnitude of a complex number*> (x,y) is taken to be |x| + |y|.*> \endverbatim*>* =====================================================================SUBROUTINE DTREVC( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,$ LDVR, MM, M, WORK, INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..CHARACTER HOWMNY, SIDEINTEGER INFO, LDT, LDVL, LDVR, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL ALLV, BOTHV, LEFTV, OVER, PAIR, RIGHTV, SOMEVINTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI, N2DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,$ SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,$ XNORM* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAXDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DLABAD, DAXPY, DCOPY, DGEMV, DLALN2, DSCAL,$ XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Local Arrays ..DOUBLE PRECISION X( 2, 2 )* ..* .. Executable Statements ..** Decode and test the input parameters*BOTHV = LSAME( SIDE, 'B' )RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHVLEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV*ALLV = LSAME( HOWMNY, 'A' )OVER = LSAME( HOWMNY, 'B' )SOMEV = LSAME( HOWMNY, 'S' )*INFO = 0IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -1ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THENINFO = -8ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THENINFO = -10ELSE** Set M to the number of columns required to store the selected* eigenvectors, standardize the array SELECT if necessary, and* test MM.*IF( SOMEV ) THENM = 0PAIR = .FALSE.DO 10 J = 1, NIF( PAIR ) THENPAIR = .FALSE.SELECT( J ) = .FALSE.ELSEIF( J.LT.N ) THENIF( T( J+1, J ).EQ.ZERO ) THENIF( SELECT( J ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( J ) .OR. SELECT( J+1 ) ) THENSELECT( J ) = .TRUE.M = M + 2END IFEND IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEELSEM = NEND IF*IF( MM.LT.M ) THENINFO = -11END IFEND IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTREVC', -INFO )RETURNEND IF** Quick return if possible.*IF( N.EQ.0 )$ RETURN** Set the constants to control overflow.*UNFL = DLAMCH( 'Safe minimum' )OVFL = ONE / UNFLCALL DLABAD( UNFL, OVFL )ULP = DLAMCH( 'Precision' )SMLNUM = UNFL*( N / ULP )BIGNUM = ( ONE-ULP ) / SMLNUM** Compute 1-norm of each column of strictly upper triangular* part of T to control overflow in triangular solver.*WORK( 1 ) = ZERODO 30 J = 2, NWORK( J ) = ZERODO 20 I = 1, J - 1WORK( J ) = WORK( J ) + ABS( T( I, J ) )20 CONTINUE30 CONTINUE** Index IP is used to specify the real or complex eigenvalue:* IP = 0, real eigenvalue,* 1, first of conjugate complex pair: (wr,wi)* -1, second of conjugate complex pair: (wr,wi)*N2 = 2*N*IF( RIGHTV ) THEN** Compute right eigenvectors.*IP = 0IS = MDO 140 KI = N, 1, -1*IF( IP.EQ.1 )$ GO TO 130IF( KI.EQ.1 )$ GO TO 40IF( T( KI, KI-1 ).EQ.ZERO )$ GO TO 40IP = -1*40 CONTINUEIF( SOMEV ) THENIF( IP.EQ.0 ) THENIF( .NOT.SELECT( KI ) )$ GO TO 130ELSEIF( .NOT.SELECT( KI-1 ) )$ GO TO 130END IFEND IF** Compute the KI-th eigenvalue (WR,WI).*WR = T( KI, KI )WI = ZEROIF( IP.NE.0 )$ WI = SQRT( ABS( T( KI, KI-1 ) ) )*$ SQRT( ABS( T( KI-1, KI ) ) )SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )*IF( IP.EQ.0 ) THEN** Real right eigenvector*WORK( KI+N ) = ONE** Form right-hand side*DO 50 K = 1, KI - 1WORK( K+N ) = -T( K, KI )50 CONTINUE** Solve the upper quasi-triangular system:* (T(1:KI-1,1:KI-1) - WR)*X = SCALE*WORK.*JNXT = KI - 1DO 60 J = KI - 1, 1, -1IF( J.GT.JNXT )$ GO TO 60J1 = JJ2 = JJNXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block*CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale X(1,1) to avoid overflow when updating* the right-hand side.*IF( XNORM.GT.ONE ) THENIF( WORK( J ).GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )WORK( J+N ) = X( 1, 1 )** Update right-hand side*CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )*ELSE** 2-by-2 diagonal block*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE,$ T( J-1, J-1 ), LDT, ONE, ONE,$ WORK( J-1+N ), N, WR, ZERO, X, 2,$ SCALE, XNORM, IERR )** Scale X(1,1) and X(2,1) to avoid overflow when* updating the right-hand side.*IF( XNORM.GT.ONE ) THENBETA = MAX( WORK( J-1 ), WORK( J ) )IF( BETA.GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMX( 2, 1 ) = X( 2, 1 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )WORK( J-1+N ) = X( 1, 1 )WORK( J+N ) = X( 2, 1 )** Update right-hand side*CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )END IF60 CONTINUE** Copy the vector x or Q*x to VR and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS ), 1 )*II = IDAMAX( KI, VR( 1, IS ), 1 )REMAX = ONE / ABS( VR( II, IS ) )CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )*DO 70 K = KI + 1, NVR( K, IS ) = ZERO70 CONTINUEELSEIF( KI.GT.1 )$ CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,$ WORK( 1+N ), 1, WORK( KI+N ),$ VR( 1, KI ), 1 )*II = IDAMAX( N, VR( 1, KI ), 1 )REMAX = ONE / ABS( VR( II, KI ) )CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )END IF*ELSE** Complex right eigenvector.** Initial solve* [ (T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I* WI)]*X = 0.* [ (T(KI,KI-1) T(KI,KI) ) ]*IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THENWORK( KI-1+N ) = ONEWORK( KI+N2 ) = WI / T( KI-1, KI )ELSEWORK( KI-1+N ) = -WI / T( KI, KI-1 )WORK( KI+N2 ) = ONEEND IFWORK( KI+N ) = ZEROWORK( KI-1+N2 ) = ZERO** Form right-hand side*DO 80 K = 1, KI - 2WORK( K+N ) = -WORK( KI-1+N )*T( K, KI-1 )WORK( K+N2 ) = -WORK( KI+N2 )*T( K, KI )80 CONTINUE** Solve upper quasi-triangular system:* (T(1:KI-2,1:KI-2) - (WR+i*WI))*X = SCALE*(WORK+i*WORK2)*JNXT = KI - 2DO 90 J = KI - 2, 1, -1IF( J.GT.JNXT )$ GO TO 90J1 = JJ2 = JJNXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block*CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR, WI,$ X, 2, SCALE, XNORM, IERR )** Scale X(1,1) and X(1,2) to avoid overflow when* updating the right-hand side.*IF( XNORM.GT.ONE ) THENIF( WORK( J ).GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMX( 1, 2 ) = X( 1, 2 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )END IFWORK( J+N ) = X( 1, 1 )WORK( J+N2 ) = X( 1, 2 )** Update the right-hand side*CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,$ WORK( 1+N2 ), 1 )*ELSE** 2-by-2 diagonal block*CALL DLALN2( .FALSE., 2, 2, SMIN, ONE,$ T( J-1, J-1 ), LDT, ONE, ONE,$ WORK( J-1+N ), N, WR, WI, X, 2, SCALE,$ XNORM, IERR )** Scale X to avoid overflow when updating* the right-hand side.*IF( XNORM.GT.ONE ) THENBETA = MAX( WORK( J-1 ), WORK( J ) )IF( BETA.GT.BIGNUM / XNORM ) THENREC = ONE / XNORMX( 1, 1 ) = X( 1, 1 )*RECX( 1, 2 ) = X( 1, 2 )*RECX( 2, 1 ) = X( 2, 1 )*RECX( 2, 2 ) = X( 2, 2 )*RECSCALE = SCALE*RECEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( KI, SCALE, WORK( 1+N ), 1 )CALL DSCAL( KI, SCALE, WORK( 1+N2 ), 1 )END IFWORK( J-1+N ) = X( 1, 1 )WORK( J+N ) = X( 2, 1 )WORK( J-1+N2 ) = X( 1, 2 )WORK( J+N2 ) = X( 2, 2 )** Update the right-hand side*CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,$ WORK( 1+N ), 1 )CALL DAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,$ WORK( 1+N2 ), 1 )CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,$ WORK( 1+N2 ), 1 )END IF90 CONTINUE** Copy the vector x or Q*x to VR and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( KI, WORK( 1+N ), 1, VR( 1, IS-1 ), 1 )CALL DCOPY( KI, WORK( 1+N2 ), 1, VR( 1, IS ), 1 )*EMAX = ZERODO 100 K = 1, KIEMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+$ ABS( VR( K, IS ) ) )100 CONTINUE*REMAX = ONE / EMAXCALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )*DO 110 K = KI + 1, NVR( K, IS-1 ) = ZEROVR( K, IS ) = ZERO110 CONTINUE*ELSE*IF( KI.GT.2 ) THENCALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,$ WORK( 1+N ), 1, WORK( KI-1+N ),$ VR( 1, KI-1 ), 1 )CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,$ WORK( 1+N2 ), 1, WORK( KI+N2 ),$ VR( 1, KI ), 1 )ELSECALL DSCAL( N, WORK( KI-1+N ), VR( 1, KI-1 ), 1 )CALL DSCAL( N, WORK( KI+N2 ), VR( 1, KI ), 1 )END IF*EMAX = ZERODO 120 K = 1, NEMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+$ ABS( VR( K, KI ) ) )120 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )END IFEND IF*IS = IS - 1IF( IP.NE.0 )$ IS = IS - 1130 CONTINUEIF( IP.EQ.1 )$ IP = 0IF( IP.EQ.-1 )$ IP = 1140 CONTINUEEND IF*IF( LEFTV ) THEN** Compute left eigenvectors.*IP = 0IS = 1DO 260 KI = 1, N*IF( IP.EQ.-1 )$ GO TO 250IF( KI.EQ.N )$ GO TO 150IF( T( KI+1, KI ).EQ.ZERO )$ GO TO 150IP = 1*150 CONTINUEIF( SOMEV ) THENIF( .NOT.SELECT( KI ) )$ GO TO 250END IF** Compute the KI-th eigenvalue (WR,WI).*WR = T( KI, KI )WI = ZEROIF( IP.NE.0 )$ WI = SQRT( ABS( T( KI, KI+1 ) ) )*$ SQRT( ABS( T( KI+1, KI ) ) )SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )*IF( IP.EQ.0 ) THEN** Real left eigenvector.*WORK( KI+N ) = ONE** Form right-hand side*DO 160 K = KI + 1, NWORK( K+N ) = -T( KI, K )160 CONTINUE** Solve the quasi-triangular system:* (T(KI+1:N,KI+1:N) - WR)**T*X = SCALE*WORK*VMAX = ONEVCRIT = BIGNUM*JNXT = KI + 1DO 170 J = KI + 1, NIF( J.LT.JNXT )$ GO TO 170J1 = JJ2 = JJNXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side.*IF( WORK( J ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-1, T( KI+1, J ), 1,$ WORK( KI+1+N ), 1 )** Solve (T(J,J)-WR)**T*X = WORK*CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )WORK( J+N ) = X( 1, 1 )VMAX = MAX( ABS( WORK( J+N ) ), VMAX )VCRIT = BIGNUM / VMAX*ELSE** 2-by-2 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side.*BETA = MAX( WORK( J ), WORK( J+1 ) )IF( BETA.GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-1, T( KI+1, J ), 1,$ WORK( KI+1+N ), 1 )*WORK( J+1+N ) = WORK( J+1+N ) -$ DDOT( J-KI-1, T( KI+1, J+1 ), 1,$ WORK( KI+1+N ), 1 )** Solve* [T(J,J)-WR T(J,J+1) ]**T * X = SCALE*( WORK1 )* [T(J+1,J) T(J+1,J+1)-WR] ( WORK2 )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )WORK( J+N ) = X( 1, 1 )WORK( J+1+N ) = X( 2, 1 )*VMAX = MAX( ABS( WORK( J+N ) ),$ ABS( WORK( J+1+N ) ), VMAX )VCRIT = BIGNUM / VMAX*END IF170 CONTINUE** Copy the vector x or Q*x to VL and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )*II = IDAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1REMAX = ONE / ABS( VL( II, IS ) )CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )*DO 180 K = 1, KI - 1VL( K, IS ) = ZERO180 CONTINUE*ELSE*IF( KI.LT.N )$ CALL DGEMV( 'N', N, N-KI, ONE, VL( 1, KI+1 ), LDVL,$ WORK( KI+1+N ), 1, WORK( KI+N ),$ VL( 1, KI ), 1 )*II = IDAMAX( N, VL( 1, KI ), 1 )REMAX = ONE / ABS( VL( II, KI ) )CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )*END IF*ELSE** Complex left eigenvector.** Initial solve:* ((T(KI,KI) T(KI,KI+1) )**T - (WR - I* WI))*X = 0.* ((T(KI+1,KI) T(KI+1,KI+1)) )*IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THENWORK( KI+N ) = WI / T( KI, KI+1 )WORK( KI+1+N2 ) = ONEELSEWORK( KI+N ) = ONEWORK( KI+1+N2 ) = -WI / T( KI+1, KI )END IFWORK( KI+1+N ) = ZEROWORK( KI+N2 ) = ZERO** Form right-hand side*DO 190 K = KI + 2, NWORK( K+N ) = -WORK( KI+N )*T( KI, K )WORK( K+N2 ) = -WORK( KI+1+N2 )*T( KI+1, K )190 CONTINUE** Solve complex quasi-triangular system:* ( T(KI+2,N:KI+2,N) - (WR-i*WI) )*X = WORK1+i*WORK2*VMAX = ONEVCRIT = BIGNUM*JNXT = KI + 2DO 200 J = KI + 2, NIF( J.LT.JNXT )$ GO TO 200J1 = JJ2 = JJNXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block** Scale if necessary to avoid overflow when* forming the right-hand side elements.*IF( WORK( J ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N ), 1 )WORK( J+N2 ) = WORK( J+N2 ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N2 ), 1 )** Solve (T(J,J)-(WR-i*WI))*(X11+i*X12)= WK+I*WK2*CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ -WI, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )END IFWORK( J+N ) = X( 1, 1 )WORK( J+N2 ) = X( 1, 2 )VMAX = MAX( ABS( WORK( J+N ) ),$ ABS( WORK( J+N2 ) ), VMAX )VCRIT = BIGNUM / VMAX*ELSE** 2-by-2 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side elements.*BETA = MAX( WORK( J ), WORK( J+1 ) )IF( BETA.GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, REC, WORK( KI+N2 ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+N ) = WORK( J+N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N ), 1 )*WORK( J+N2 ) = WORK( J+N2 ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+N2 ), 1 )*WORK( J+1+N ) = WORK( J+1+N ) -$ DDOT( J-KI-2, T( KI+2, J+1 ), 1,$ WORK( KI+2+N ), 1 )*WORK( J+1+N2 ) = WORK( J+1+N2 ) -$ DDOT( J-KI-2, T( KI+2, J+1 ), 1,$ WORK( KI+2+N2 ), 1 )** Solve 2-by-2 complex linear equation* ([T(j,j) T(j,j+1) ]**T-(wr-i*wi)*I)*X = SCALE*B* ([T(j+1,j) T(j+1,j+1)] )*CALL DLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+N ), N, WR,$ -WI, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( N-KI+1, SCALE, WORK( KI+N ), 1 )CALL DSCAL( N-KI+1, SCALE, WORK( KI+N2 ), 1 )END IFWORK( J+N ) = X( 1, 1 )WORK( J+N2 ) = X( 1, 2 )WORK( J+1+N ) = X( 2, 1 )WORK( J+1+N2 ) = X( 2, 2 )VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),$ ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ), VMAX )VCRIT = BIGNUM / VMAX*END IF200 CONTINUE** Copy the vector x or Q*x to VL and normalize.*IF( .NOT.OVER ) THENCALL DCOPY( N-KI+1, WORK( KI+N ), 1, VL( KI, IS ), 1 )CALL DCOPY( N-KI+1, WORK( KI+N2 ), 1, VL( KI, IS+1 ),$ 1 )*EMAX = ZERODO 220 K = KI, NEMAX = MAX( EMAX, ABS( VL( K, IS ) )+$ ABS( VL( K, IS+1 ) ) )220 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )*DO 230 K = 1, KI - 1VL( K, IS ) = ZEROVL( K, IS+1 ) = ZERO230 CONTINUEELSEIF( KI.LT.N-1 ) THENCALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),$ LDVL, WORK( KI+2+N ), 1, WORK( KI+N ),$ VL( 1, KI ), 1 )CALL DGEMV( 'N', N, N-KI-1, ONE, VL( 1, KI+2 ),$ LDVL, WORK( KI+2+N2 ), 1,$ WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )ELSECALL DSCAL( N, WORK( KI+N ), VL( 1, KI ), 1 )CALL DSCAL( N, WORK( KI+1+N2 ), VL( 1, KI+1 ), 1 )END IF*EMAX = ZERODO 240 K = 1, NEMAX = MAX( EMAX, ABS( VL( K, KI ) )+$ ABS( VL( K, KI+1 ) ) )240 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N, REMAX, VL( 1, KI ), 1 )CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )*END IF*END IF*IS = IS + 1IF( IP.NE.0 )$ IS = IS + 1250 CONTINUEIF( IP.EQ.-1 )$ IP = 0IF( IP.EQ.1 )$ IP = -1*260 CONTINUE*END IF*RETURN** End of DTREVC*END*> \brief \b DTREVC3** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTREVC3 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrevc3.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrevc3.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrevc3.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,* VR, LDVR, MM, M, WORK, LWORK, INFO )** .. Scalar Arguments ..* CHARACTER HOWMNY, SIDE* INTEGER INFO, LDT, LDVL, LDVR, LWORK, M, MM, N* ..* .. Array Arguments ..* LOGICAL SELECT( * )* DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),* $ WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTREVC3 computes some or all of the right and/or left eigenvectors of*> a real upper quasi-triangular matrix T.*> Matrices of this type are produced by the Schur factorization of*> a real general matrix: A = Q*T*Q**T, as computed by DHSEQR.*>*> The right eigenvector x and the left eigenvector y of T corresponding*> to an eigenvalue w are defined by:*>*> T*x = w*x, (y**H)*T = w*(y**H)*>*> where y**H denotes the conjugate transpose of y.*> The eigenvalues are not input to this routine, but are read directly*> from the diagonal blocks of T.*>*> This routine returns the matrices X and/or Y of right and left*> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an*> input matrix. If Q is the orthogonal factor that reduces a matrix*> A to Schur form T, then Q*X and Q*Y are the matrices of right and*> left eigenvectors of A.*>*> This uses a Level 3 BLAS version of the back transformation.*> \endverbatim** Arguments:* ==========**> \param[in] SIDE*> \verbatim*> SIDE is CHARACTER*1*> = 'R': compute right eigenvectors only;*> = 'L': compute left eigenvectors only;*> = 'B': compute both right and left eigenvectors.*> \endverbatim*>*> \param[in] HOWMNY*> \verbatim*> HOWMNY is CHARACTER*1*> = 'A': compute all right and/or left eigenvectors;*> = 'B': compute all right and/or left eigenvectors,*> backtransformed by the matrices in VR and/or VL;*> = 'S': compute selected right and/or left eigenvectors,*> as indicated by the logical array SELECT.*> \endverbatim*>*> \param[in,out] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> If HOWMNY = 'S', SELECT specifies the eigenvectors to be*> computed.*> If w(j) is a real eigenvalue, the corresponding real*> eigenvector is computed if SELECT(j) is .TRUE..*> If w(j) and w(j+1) are the real and imaginary parts of a*> complex eigenvalue, the corresponding complex eigenvector is*> computed if either SELECT(j) or SELECT(j+1) is .TRUE., and*> on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to*> .FALSE..*> Not referenced if HOWMNY = 'A' or 'B'.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T. N >= 0.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The upper quasi-triangular matrix T in Schur canonical form.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[in,out] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,MM)*> On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must*> contain an N-by-N matrix Q (usually the orthogonal matrix Q*> of Schur vectors returned by DHSEQR).*> On exit, if SIDE = 'L' or 'B', VL contains:*> if HOWMNY = 'A', the matrix Y of left eigenvectors of T;*> if HOWMNY = 'B', the matrix Q*Y;*> if HOWMNY = 'S', the left eigenvectors of T specified by*> SELECT, stored consecutively in the columns*> of VL, in the same order as their*> eigenvalues.*> A complex eigenvector corresponding to a complex eigenvalue*> is stored in two consecutive columns, the first holding the*> real part, and the second the imaginary part.*> Not referenced if SIDE = 'R'.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL.*> LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.*> \endverbatim*>*> \param[in,out] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,MM)*> On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must*> contain an N-by-N matrix Q (usually the orthogonal matrix Q*> of Schur vectors returned by DHSEQR).*> On exit, if SIDE = 'R' or 'B', VR contains:*> if HOWMNY = 'A', the matrix X of right eigenvectors of T;*> if HOWMNY = 'B', the matrix Q*X;*> if HOWMNY = 'S', the right eigenvectors of T specified by*> SELECT, stored consecutively in the columns*> of VR, in the same order as their*> eigenvalues.*> A complex eigenvector corresponding to a complex eigenvalue*> is stored in two consecutive columns, the first holding the*> real part and the second the imaginary part.*> Not referenced if SIDE = 'L'.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR.*> LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.*> \endverbatim*>*> \param[in] MM*> \verbatim*> MM is INTEGER*> The number of columns in the arrays VL and/or VR. MM >= M.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The number of columns in the arrays VL and/or VR actually*> used to store the eigenvectors.*> If HOWMNY = 'A' or 'B', M is set to N.*> Each selected real eigenvector occupies one column and each*> selected complex eigenvector occupies two columns.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of array WORK. LWORK >= max(1,3*N).*> For optimum performance, LWORK >= N + 2*N*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017** @precisions fortran d -> s**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The algorithm used in this program is basically backward (forward)*> substitution, with scaling to make the the code robust against*> possible overflow.*>*> Each eigenvector is normalized so that the element of largest*> magnitude has magnitude 1; here the magnitude of a complex number*> (x,y) is taken to be |x| + |y|.*> \endverbatim*>* =====================================================================SUBROUTINE DTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,$ VR, LDVR, MM, M, WORK, LWORK, INFO )IMPLICIT NONE** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..CHARACTER HOWMNY, SIDEINTEGER INFO, LDT, LDVL, LDVR, LWORK, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )DOUBLE PRECISION T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),$ WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )INTEGER NBMIN, NBMAXPARAMETER ( NBMIN = 8, NBMAX = 128 )* ..* .. Local Scalars ..LOGICAL ALLV, BOTHV, LEFTV, LQUERY, OVER, PAIR,$ RIGHTV, SOMEVINTEGER I, IERR, II, IP, IS, J, J1, J2, JNXT, K, KI,$ IV, MAXWRK, NB, KI2DOUBLE PRECISION BETA, BIGNUM, EMAX, OVFL, REC, REMAX, SCALE,$ SMIN, SMLNUM, ULP, UNFL, VCRIT, VMAX, WI, WR,$ XNORM* ..* .. External Functions ..LOGICAL LSAMEINTEGER IDAMAX, ILAENVDOUBLE PRECISION DDOT, DLAMCHEXTERNAL LSAME, IDAMAX, ILAENV, DDOT, DLAMCH* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DLALN2, DSCAL, XERBLA,$ DGEMM, DLASET, DLABAD, DLACPY* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Local Arrays ..DOUBLE PRECISION X( 2, 2 )INTEGER ISCOMPLEX( NBMAX )* ..* .. Executable Statements ..** Decode and test the input parameters*BOTHV = LSAME( SIDE, 'B' )RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHVLEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV*ALLV = LSAME( HOWMNY, 'A' )OVER = LSAME( HOWMNY, 'B' )SOMEV = LSAME( HOWMNY, 'S' )*INFO = 0NB = ILAENV( 1, 'DTREVC', SIDE // HOWMNY, N, -1, -1, -1 )MAXWRK = N + 2*N*NBWORK(1) = MAXWRKLQUERY = ( LWORK.EQ.-1 )IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THENINFO = -1ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THENINFO = -8ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THENINFO = -10ELSE IF( LWORK.LT.MAX( 1, 3*N ) .AND. .NOT.LQUERY ) THENINFO = -14ELSE** Set M to the number of columns required to store the selected* eigenvectors, standardize the array SELECT if necessary, and* test MM.*IF( SOMEV ) THENM = 0PAIR = .FALSE.DO 10 J = 1, NIF( PAIR ) THENPAIR = .FALSE.SELECT( J ) = .FALSE.ELSEIF( J.LT.N ) THENIF( T( J+1, J ).EQ.ZERO ) THENIF( SELECT( J ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( J ) .OR. SELECT( J+1 ) ) THENSELECT( J ) = .TRUE.M = M + 2END IFEND IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEELSEM = NEND IF*IF( MM.LT.M ) THENINFO = -11END IFEND IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTREVC3', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible.*IF( N.EQ.0 )$ RETURN** Use blocked version of back-transformation if sufficient workspace.* Zero-out the workspace to avoid potential NaN propagation.*IF( OVER .AND. LWORK .GE. N + 2*N*NBMIN ) THENNB = (LWORK - N) / (2*N)NB = MIN( NB, NBMAX )CALL DLASET( 'F', N, 1+2*NB, ZERO, ZERO, WORK, N )ELSENB = 1END IF** Set the constants to control overflow.*UNFL = DLAMCH( 'Safe minimum' )OVFL = ONE / UNFLCALL DLABAD( UNFL, OVFL )ULP = DLAMCH( 'Precision' )SMLNUM = UNFL*( N / ULP )BIGNUM = ( ONE-ULP ) / SMLNUM** Compute 1-norm of each column of strictly upper triangular* part of T to control overflow in triangular solver.*WORK( 1 ) = ZERODO 30 J = 2, NWORK( J ) = ZERODO 20 I = 1, J - 1WORK( J ) = WORK( J ) + ABS( T( I, J ) )20 CONTINUE30 CONTINUE** Index IP is used to specify the real or complex eigenvalue:* IP = 0, real eigenvalue,* 1, first of conjugate complex pair: (wr,wi)* -1, second of conjugate complex pair: (wr,wi)* ISCOMPLEX array stores IP for each column in current block.*IF( RIGHTV ) THEN** ============================================================* Compute right eigenvectors.** IV is index of column in current block.* For complex right vector, uses IV-1 for real part and IV for complex part.* Non-blocked version always uses IV=2;* blocked version starts with IV=NB, goes down to 1 or 2.* (Note the "0-th" column is used for 1-norms computed above.)IV = 2IF( NB.GT.2 ) THENIV = NBEND IFIP = 0IS = MDO 140 KI = N, 1, -1IF( IP.EQ.-1 ) THEN* previous iteration (ki+1) was second of conjugate pair,* so this ki is first of conjugate pair; skip to end of loopIP = 1GO TO 140ELSE IF( KI.EQ.1 ) THEN* last column, so this ki must be real eigenvalueIP = 0ELSE IF( T( KI, KI-1 ).EQ.ZERO ) THEN* zero on sub-diagonal, so this ki is real eigenvalueIP = 0ELSE* non-zero on sub-diagonal, so this ki is second of conjugate pairIP = -1END IFIF( SOMEV ) THENIF( IP.EQ.0 ) THENIF( .NOT.SELECT( KI ) )$ GO TO 140ELSEIF( .NOT.SELECT( KI-1 ) )$ GO TO 140END IFEND IF** Compute the KI-th eigenvalue (WR,WI).*WR = T( KI, KI )WI = ZEROIF( IP.NE.0 )$ WI = SQRT( ABS( T( KI, KI-1 ) ) )*$ SQRT( ABS( T( KI-1, KI ) ) )SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )*IF( IP.EQ.0 ) THEN** --------------------------------------------------------* Real right eigenvector*WORK( KI + IV*N ) = ONE** Form right-hand side.*DO 50 K = 1, KI - 1WORK( K + IV*N ) = -T( K, KI )50 CONTINUE** Solve upper quasi-triangular system:* [ T(1:KI-1,1:KI-1) - WR ]*X = SCALE*WORK.*JNXT = KI - 1DO 60 J = KI - 1, 1, -1IF( J.GT.JNXT )$ GO TO 60J1 = JJ2 = JJNXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block*CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+IV*N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale X(1,1) to avoid overflow when updating* the right-hand side.*IF( XNORM.GT.ONE ) THENIF( WORK( J ).GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( KI, SCALE, WORK( 1+IV*N ), 1 )WORK( J+IV*N ) = X( 1, 1 )** Update right-hand side*CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,$ WORK( 1+IV*N ), 1 )*ELSE** 2-by-2 diagonal block*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE,$ T( J-1, J-1 ), LDT, ONE, ONE,$ WORK( J-1+IV*N ), N, WR, ZERO, X, 2,$ SCALE, XNORM, IERR )** Scale X(1,1) and X(2,1) to avoid overflow when* updating the right-hand side.*IF( XNORM.GT.ONE ) THENBETA = MAX( WORK( J-1 ), WORK( J ) )IF( BETA.GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMX( 2, 1 ) = X( 2, 1 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( KI, SCALE, WORK( 1+IV*N ), 1 )WORK( J-1+IV*N ) = X( 1, 1 )WORK( J +IV*N ) = X( 2, 1 )** Update right-hand side*CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,$ WORK( 1+IV*N ), 1 )CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,$ WORK( 1+IV*N ), 1 )END IF60 CONTINUE** Copy the vector x or Q*x to VR and normalize.*IF( .NOT.OVER ) THEN* ------------------------------* no back-transform: copy x to VR and normalize.CALL DCOPY( KI, WORK( 1 + IV*N ), 1, VR( 1, IS ), 1 )*II = IDAMAX( KI, VR( 1, IS ), 1 )REMAX = ONE / ABS( VR( II, IS ) )CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )*DO 70 K = KI + 1, NVR( K, IS ) = ZERO70 CONTINUE*ELSE IF( NB.EQ.1 ) THEN* ------------------------------* version 1: back-transform each vector with GEMV, Q*x.IF( KI.GT.1 )$ CALL DGEMV( 'N', N, KI-1, ONE, VR, LDVR,$ WORK( 1 + IV*N ), 1, WORK( KI + IV*N ),$ VR( 1, KI ), 1 )*II = IDAMAX( N, VR( 1, KI ), 1 )REMAX = ONE / ABS( VR( II, KI ) )CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )*ELSE* ------------------------------* version 2: back-transform block of vectors with GEMM* zero out below vectorDO K = KI + 1, NWORK( K + IV*N ) = ZEROEND DOISCOMPLEX( IV ) = IP* back-transform and normalization is done belowEND IFELSE** --------------------------------------------------------* Complex right eigenvector.** Initial solve* [ ( T(KI-1,KI-1) T(KI-1,KI) ) - (WR + I*WI) ]*X = 0.* [ ( T(KI, KI-1) T(KI, KI) ) ]*IF( ABS( T( KI-1, KI ) ).GE.ABS( T( KI, KI-1 ) ) ) THENWORK( KI-1 + (IV-1)*N ) = ONEWORK( KI + (IV )*N ) = WI / T( KI-1, KI )ELSEWORK( KI-1 + (IV-1)*N ) = -WI / T( KI, KI-1 )WORK( KI + (IV )*N ) = ONEEND IFWORK( KI + (IV-1)*N ) = ZEROWORK( KI-1 + (IV )*N ) = ZERO** Form right-hand side.*DO 80 K = 1, KI - 2WORK( K+(IV-1)*N ) = -WORK( KI-1+(IV-1)*N )*T(K,KI-1)WORK( K+(IV )*N ) = -WORK( KI +(IV )*N )*T(K,KI )80 CONTINUE** Solve upper quasi-triangular system:* [ T(1:KI-2,1:KI-2) - (WR+i*WI) ]*X = SCALE*(WORK+i*WORK2)*JNXT = KI - 2DO 90 J = KI - 2, 1, -1IF( J.GT.JNXT )$ GO TO 90J1 = JJ2 = JJNXT = J - 1IF( J.GT.1 ) THENIF( T( J, J-1 ).NE.ZERO ) THENJ1 = J - 1JNXT = J - 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block*CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+(IV-1)*N ), N,$ WR, WI, X, 2, SCALE, XNORM, IERR )** Scale X(1,1) and X(1,2) to avoid overflow when* updating the right-hand side.*IF( XNORM.GT.ONE ) THENIF( WORK( J ).GT.BIGNUM / XNORM ) THENX( 1, 1 ) = X( 1, 1 ) / XNORMX( 1, 2 ) = X( 1, 2 ) / XNORMSCALE = SCALE / XNORMEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( KI, SCALE, WORK( 1+(IV-1)*N ), 1 )CALL DSCAL( KI, SCALE, WORK( 1+(IV )*N ), 1 )END IFWORK( J+(IV-1)*N ) = X( 1, 1 )WORK( J+(IV )*N ) = X( 1, 2 )** Update the right-hand side*CALL DAXPY( J-1, -X( 1, 1 ), T( 1, J ), 1,$ WORK( 1+(IV-1)*N ), 1 )CALL DAXPY( J-1, -X( 1, 2 ), T( 1, J ), 1,$ WORK( 1+(IV )*N ), 1 )*ELSE** 2-by-2 diagonal block*CALL DLALN2( .FALSE., 2, 2, SMIN, ONE,$ T( J-1, J-1 ), LDT, ONE, ONE,$ WORK( J-1+(IV-1)*N ), N, WR, WI, X, 2,$ SCALE, XNORM, IERR )** Scale X to avoid overflow when updating* the right-hand side.*IF( XNORM.GT.ONE ) THENBETA = MAX( WORK( J-1 ), WORK( J ) )IF( BETA.GT.BIGNUM / XNORM ) THENREC = ONE / XNORMX( 1, 1 ) = X( 1, 1 )*RECX( 1, 2 ) = X( 1, 2 )*RECX( 2, 1 ) = X( 2, 1 )*RECX( 2, 2 ) = X( 2, 2 )*RECSCALE = SCALE*RECEND IFEND IF** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( KI, SCALE, WORK( 1+(IV-1)*N ), 1 )CALL DSCAL( KI, SCALE, WORK( 1+(IV )*N ), 1 )END IFWORK( J-1+(IV-1)*N ) = X( 1, 1 )WORK( J +(IV-1)*N ) = X( 2, 1 )WORK( J-1+(IV )*N ) = X( 1, 2 )WORK( J +(IV )*N ) = X( 2, 2 )** Update the right-hand side*CALL DAXPY( J-2, -X( 1, 1 ), T( 1, J-1 ), 1,$ WORK( 1+(IV-1)*N ), 1 )CALL DAXPY( J-2, -X( 2, 1 ), T( 1, J ), 1,$ WORK( 1+(IV-1)*N ), 1 )CALL DAXPY( J-2, -X( 1, 2 ), T( 1, J-1 ), 1,$ WORK( 1+(IV )*N ), 1 )CALL DAXPY( J-2, -X( 2, 2 ), T( 1, J ), 1,$ WORK( 1+(IV )*N ), 1 )END IF90 CONTINUE** Copy the vector x or Q*x to VR and normalize.*IF( .NOT.OVER ) THEN* ------------------------------* no back-transform: copy x to VR and normalize.CALL DCOPY( KI, WORK( 1+(IV-1)*N ), 1, VR(1,IS-1), 1 )CALL DCOPY( KI, WORK( 1+(IV )*N ), 1, VR(1,IS ), 1 )*EMAX = ZERODO 100 K = 1, KIEMAX = MAX( EMAX, ABS( VR( K, IS-1 ) )+$ ABS( VR( K, IS ) ) )100 CONTINUEREMAX = ONE / EMAXCALL DSCAL( KI, REMAX, VR( 1, IS-1 ), 1 )CALL DSCAL( KI, REMAX, VR( 1, IS ), 1 )*DO 110 K = KI + 1, NVR( K, IS-1 ) = ZEROVR( K, IS ) = ZERO110 CONTINUE*ELSE IF( NB.EQ.1 ) THEN* ------------------------------* version 1: back-transform each vector with GEMV, Q*x.IF( KI.GT.2 ) THENCALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,$ WORK( 1 + (IV-1)*N ), 1,$ WORK( KI-1 + (IV-1)*N ), VR(1,KI-1), 1)CALL DGEMV( 'N', N, KI-2, ONE, VR, LDVR,$ WORK( 1 + (IV)*N ), 1,$ WORK( KI + (IV)*N ), VR( 1, KI ), 1 )ELSECALL DSCAL( N, WORK(KI-1+(IV-1)*N), VR(1,KI-1), 1)CALL DSCAL( N, WORK(KI +(IV )*N), VR(1,KI ), 1)END IF*EMAX = ZERODO 120 K = 1, NEMAX = MAX( EMAX, ABS( VR( K, KI-1 ) )+$ ABS( VR( K, KI ) ) )120 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N, REMAX, VR( 1, KI-1 ), 1 )CALL DSCAL( N, REMAX, VR( 1, KI ), 1 )*ELSE* ------------------------------* version 2: back-transform block of vectors with GEMM* zero out below vectorDO K = KI + 1, NWORK( K + (IV-1)*N ) = ZEROWORK( K + (IV )*N ) = ZEROEND DOISCOMPLEX( IV-1 ) = -IPISCOMPLEX( IV ) = IPIV = IV - 1* back-transform and normalization is done belowEND IFEND IFIF( NB.GT.1 ) THEN* --------------------------------------------------------* Blocked version of back-transform* For complex case, KI2 includes both vectors (KI-1 and KI)IF( IP.EQ.0 ) THENKI2 = KIELSEKI2 = KI - 1END IF* Columns IV:NB of work are valid vectors.* When the number of vectors stored reaches NB-1 or NB,* or if this was last vector, do the GEMMIF( (IV.LE.2) .OR. (KI2.EQ.1) ) THENCALL DGEMM( 'N', 'N', N, NB-IV+1, KI2+NB-IV, ONE,$ VR, LDVR,$ WORK( 1 + (IV)*N ), N,$ ZERO,$ WORK( 1 + (NB+IV)*N ), N )* normalize vectorsDO K = IV, NBIF( ISCOMPLEX(K).EQ.0 ) THEN* real eigenvectorII = IDAMAX( N, WORK( 1 + (NB+K)*N ), 1 )REMAX = ONE / ABS( WORK( II + (NB+K)*N ) )ELSE IF( ISCOMPLEX(K).EQ.1 ) THEN* first eigenvector of conjugate pairEMAX = ZERODO II = 1, NEMAX = MAX( EMAX,$ ABS( WORK( II + (NB+K )*N ) )+$ ABS( WORK( II + (NB+K+1)*N ) ) )END DOREMAX = ONE / EMAX* else if ISCOMPLEX(K).EQ.-1* second eigenvector of conjugate pair* reuse same REMAX as previous KEND IFCALL DSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )END DOCALL DLACPY( 'F', N, NB-IV+1,$ WORK( 1 + (NB+IV)*N ), N,$ VR( 1, KI2 ), LDVR )IV = NBELSEIV = IV - 1END IFEND IF ! blocked back-transform*IS = IS - 1IF( IP.NE.0 )$ IS = IS - 1140 CONTINUEEND IFIF( LEFTV ) THEN** ============================================================* Compute left eigenvectors.** IV is index of column in current block.* For complex left vector, uses IV for real part and IV+1 for complex part.* Non-blocked version always uses IV=1;* blocked version starts with IV=1, goes up to NB-1 or NB.* (Note the "0-th" column is used for 1-norms computed above.)IV = 1IP = 0IS = 1DO 260 KI = 1, NIF( IP.EQ.1 ) THEN* previous iteration (ki-1) was first of conjugate pair,* so this ki is second of conjugate pair; skip to end of loopIP = -1GO TO 260ELSE IF( KI.EQ.N ) THEN* last column, so this ki must be real eigenvalueIP = 0ELSE IF( T( KI+1, KI ).EQ.ZERO ) THEN* zero on sub-diagonal, so this ki is real eigenvalueIP = 0ELSE* non-zero on sub-diagonal, so this ki is first of conjugate pairIP = 1END IF*IF( SOMEV ) THENIF( .NOT.SELECT( KI ) )$ GO TO 260END IF** Compute the KI-th eigenvalue (WR,WI).*WR = T( KI, KI )WI = ZEROIF( IP.NE.0 )$ WI = SQRT( ABS( T( KI, KI+1 ) ) )*$ SQRT( ABS( T( KI+1, KI ) ) )SMIN = MAX( ULP*( ABS( WR )+ABS( WI ) ), SMLNUM )*IF( IP.EQ.0 ) THEN** --------------------------------------------------------* Real left eigenvector*WORK( KI + IV*N ) = ONE** Form right-hand side.*DO 160 K = KI + 1, NWORK( K + IV*N ) = -T( KI, K )160 CONTINUE** Solve transposed quasi-triangular system:* [ T(KI+1:N,KI+1:N) - WR ]**T * X = SCALE*WORK*VMAX = ONEVCRIT = BIGNUM*JNXT = KI + 1DO 170 J = KI + 1, NIF( J.LT.JNXT )$ GO TO 170J1 = JJ2 = JJNXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side.*IF( WORK( J ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+IV*N ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+IV*N ) = WORK( J+IV*N ) -$ DDOT( J-KI-1, T( KI+1, J ), 1,$ WORK( KI+1+IV*N ), 1 )** Solve [ T(J,J) - WR ]**T * X = WORK*CALL DLALN2( .FALSE., 1, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+IV*N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( N-KI+1, SCALE, WORK( KI+IV*N ), 1 )WORK( J+IV*N ) = X( 1, 1 )VMAX = MAX( ABS( WORK( J+IV*N ) ), VMAX )VCRIT = BIGNUM / VMAX*ELSE** 2-by-2 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side.*BETA = MAX( WORK( J ), WORK( J+1 ) )IF( BETA.GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK( KI+IV*N ), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+IV*N ) = WORK( J+IV*N ) -$ DDOT( J-KI-1, T( KI+1, J ), 1,$ WORK( KI+1+IV*N ), 1 )*WORK( J+1+IV*N ) = WORK( J+1+IV*N ) -$ DDOT( J-KI-1, T( KI+1, J+1 ), 1,$ WORK( KI+1+IV*N ), 1 )** Solve* [ T(J,J)-WR T(J,J+1) ]**T * X = SCALE*( WORK1 )* [ T(J+1,J) T(J+1,J+1)-WR ] ( WORK2 )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+IV*N ), N, WR,$ ZERO, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE )$ CALL DSCAL( N-KI+1, SCALE, WORK( KI+IV*N ), 1 )WORK( J +IV*N ) = X( 1, 1 )WORK( J+1+IV*N ) = X( 2, 1 )*VMAX = MAX( ABS( WORK( J +IV*N ) ),$ ABS( WORK( J+1+IV*N ) ), VMAX )VCRIT = BIGNUM / VMAX*END IF170 CONTINUE** Copy the vector x or Q*x to VL and normalize.*IF( .NOT.OVER ) THEN* ------------------------------* no back-transform: copy x to VL and normalize.CALL DCOPY( N-KI+1, WORK( KI + IV*N ), 1,$ VL( KI, IS ), 1 )*II = IDAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1REMAX = ONE / ABS( VL( II, IS ) )CALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )*DO 180 K = 1, KI - 1VL( K, IS ) = ZERO180 CONTINUE*ELSE IF( NB.EQ.1 ) THEN* ------------------------------* version 1: back-transform each vector with GEMV, Q*x.IF( KI.LT.N )$ CALL DGEMV( 'N', N, N-KI, ONE,$ VL( 1, KI+1 ), LDVL,$ WORK( KI+1 + IV*N ), 1,$ WORK( KI + IV*N ), VL( 1, KI ), 1 )*II = IDAMAX( N, VL( 1, KI ), 1 )REMAX = ONE / ABS( VL( II, KI ) )CALL DSCAL( N, REMAX, VL( 1, KI ), 1 )*ELSE* ------------------------------* version 2: back-transform block of vectors with GEMM* zero out above vector* could go from KI-NV+1 to KI-1DO K = 1, KI - 1WORK( K + IV*N ) = ZEROEND DOISCOMPLEX( IV ) = IP* back-transform and normalization is done belowEND IFELSE** --------------------------------------------------------* Complex left eigenvector.** Initial solve:* [ ( T(KI,KI) T(KI,KI+1) )**T - (WR - I* WI) ]*X = 0.* [ ( T(KI+1,KI) T(KI+1,KI+1) ) ]*IF( ABS( T( KI, KI+1 ) ).GE.ABS( T( KI+1, KI ) ) ) THENWORK( KI + (IV )*N ) = WI / T( KI, KI+1 )WORK( KI+1 + (IV+1)*N ) = ONEELSEWORK( KI + (IV )*N ) = ONEWORK( KI+1 + (IV+1)*N ) = -WI / T( KI+1, KI )END IFWORK( KI+1 + (IV )*N ) = ZEROWORK( KI + (IV+1)*N ) = ZERO** Form right-hand side.*DO 190 K = KI + 2, NWORK( K+(IV )*N ) = -WORK( KI +(IV )*N )*T(KI, K)WORK( K+(IV+1)*N ) = -WORK( KI+1+(IV+1)*N )*T(KI+1,K)190 CONTINUE** Solve transposed quasi-triangular system:* [ T(KI+2:N,KI+2:N)**T - (WR-i*WI) ]*X = WORK1+i*WORK2*VMAX = ONEVCRIT = BIGNUM*JNXT = KI + 2DO 200 J = KI + 2, NIF( J.LT.JNXT )$ GO TO 200J1 = JJ2 = JJNXT = J + 1IF( J.LT.N ) THENIF( T( J+1, J ).NE.ZERO ) THENJ2 = J + 1JNXT = J + 2END IFEND IF*IF( J1.EQ.J2 ) THEN** 1-by-1 diagonal block** Scale if necessary to avoid overflow when* forming the right-hand side elements.*IF( WORK( J ).GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK(KI+(IV )*N), 1 )CALL DSCAL( N-KI+1, REC, WORK(KI+(IV+1)*N), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J+(IV )*N ) = WORK( J+(IV)*N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+(IV)*N ), 1 )WORK( J+(IV+1)*N ) = WORK( J+(IV+1)*N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+(IV+1)*N ), 1 )** Solve [ T(J,J)-(WR-i*WI) ]*(X11+i*X12)= WK+I*WK2*CALL DLALN2( .FALSE., 1, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+IV*N ), N, WR,$ -WI, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV )*N), 1)CALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV+1)*N), 1)END IFWORK( J+(IV )*N ) = X( 1, 1 )WORK( J+(IV+1)*N ) = X( 1, 2 )VMAX = MAX( ABS( WORK( J+(IV )*N ) ),$ ABS( WORK( J+(IV+1)*N ) ), VMAX )VCRIT = BIGNUM / VMAX*ELSE** 2-by-2 diagonal block** Scale if necessary to avoid overflow when forming* the right-hand side elements.*BETA = MAX( WORK( J ), WORK( J+1 ) )IF( BETA.GT.VCRIT ) THENREC = ONE / VMAXCALL DSCAL( N-KI+1, REC, WORK(KI+(IV )*N), 1 )CALL DSCAL( N-KI+1, REC, WORK(KI+(IV+1)*N), 1 )VMAX = ONEVCRIT = BIGNUMEND IF*WORK( J +(IV )*N ) = WORK( J+(IV)*N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+(IV)*N ), 1 )*WORK( J +(IV+1)*N ) = WORK( J+(IV+1)*N ) -$ DDOT( J-KI-2, T( KI+2, J ), 1,$ WORK( KI+2+(IV+1)*N ), 1 )*WORK( J+1+(IV )*N ) = WORK( J+1+(IV)*N ) -$ DDOT( J-KI-2, T( KI+2, J+1 ), 1,$ WORK( KI+2+(IV)*N ), 1 )*WORK( J+1+(IV+1)*N ) = WORK( J+1+(IV+1)*N ) -$ DDOT( J-KI-2, T( KI+2, J+1 ), 1,$ WORK( KI+2+(IV+1)*N ), 1 )** Solve 2-by-2 complex linear equation* [ (T(j,j) T(j,j+1) )**T - (wr-i*wi)*I ]*X = SCALE*B* [ (T(j+1,j) T(j+1,j+1)) ]*CALL DLALN2( .TRUE., 2, 2, SMIN, ONE, T( J, J ),$ LDT, ONE, ONE, WORK( J+IV*N ), N, WR,$ -WI, X, 2, SCALE, XNORM, IERR )** Scale if necessary*IF( SCALE.NE.ONE ) THENCALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV )*N), 1)CALL DSCAL( N-KI+1, SCALE, WORK(KI+(IV+1)*N), 1)END IFWORK( J +(IV )*N ) = X( 1, 1 )WORK( J +(IV+1)*N ) = X( 1, 2 )WORK( J+1+(IV )*N ) = X( 2, 1 )WORK( J+1+(IV+1)*N ) = X( 2, 2 )VMAX = MAX( ABS( X( 1, 1 ) ), ABS( X( 1, 2 ) ),$ ABS( X( 2, 1 ) ), ABS( X( 2, 2 ) ),$ VMAX )VCRIT = BIGNUM / VMAX*END IF200 CONTINUE** Copy the vector x or Q*x to VL and normalize.*IF( .NOT.OVER ) THEN* ------------------------------* no back-transform: copy x to VL and normalize.CALL DCOPY( N-KI+1, WORK( KI + (IV )*N ), 1,$ VL( KI, IS ), 1 )CALL DCOPY( N-KI+1, WORK( KI + (IV+1)*N ), 1,$ VL( KI, IS+1 ), 1 )*EMAX = ZERODO 220 K = KI, NEMAX = MAX( EMAX, ABS( VL( K, IS ) )+$ ABS( VL( K, IS+1 ) ) )220 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )CALL DSCAL( N-KI+1, REMAX, VL( KI, IS+1 ), 1 )*DO 230 K = 1, KI - 1VL( K, IS ) = ZEROVL( K, IS+1 ) = ZERO230 CONTINUE*ELSE IF( NB.EQ.1 ) THEN* ------------------------------* version 1: back-transform each vector with GEMV, Q*x.IF( KI.LT.N-1 ) THENCALL DGEMV( 'N', N, N-KI-1, ONE,$ VL( 1, KI+2 ), LDVL,$ WORK( KI+2 + (IV)*N ), 1,$ WORK( KI + (IV)*N ),$ VL( 1, KI ), 1 )CALL DGEMV( 'N', N, N-KI-1, ONE,$ VL( 1, KI+2 ), LDVL,$ WORK( KI+2 + (IV+1)*N ), 1,$ WORK( KI+1 + (IV+1)*N ),$ VL( 1, KI+1 ), 1 )ELSECALL DSCAL( N, WORK(KI+ (IV )*N), VL(1, KI ), 1)CALL DSCAL( N, WORK(KI+1+(IV+1)*N), VL(1, KI+1), 1)END IF*EMAX = ZERODO 240 K = 1, NEMAX = MAX( EMAX, ABS( VL( K, KI ) )+$ ABS( VL( K, KI+1 ) ) )240 CONTINUEREMAX = ONE / EMAXCALL DSCAL( N, REMAX, VL( 1, KI ), 1 )CALL DSCAL( N, REMAX, VL( 1, KI+1 ), 1 )*ELSE* ------------------------------* version 2: back-transform block of vectors with GEMM* zero out above vector* could go from KI-NV+1 to KI-1DO K = 1, KI - 1WORK( K + (IV )*N ) = ZEROWORK( K + (IV+1)*N ) = ZEROEND DOISCOMPLEX( IV ) = IPISCOMPLEX( IV+1 ) = -IPIV = IV + 1* back-transform and normalization is done belowEND IFEND IFIF( NB.GT.1 ) THEN* --------------------------------------------------------* Blocked version of back-transform* For complex case, KI2 includes both vectors (KI and KI+1)IF( IP.EQ.0 ) THENKI2 = KIELSEKI2 = KI + 1END IF* Columns 1:IV of work are valid vectors.* When the number of vectors stored reaches NB-1 or NB,* or if this was last vector, do the GEMMIF( (IV.GE.NB-1) .OR. (KI2.EQ.N) ) THENCALL DGEMM( 'N', 'N', N, IV, N-KI2+IV, ONE,$ VL( 1, KI2-IV+1 ), LDVL,$ WORK( KI2-IV+1 + (1)*N ), N,$ ZERO,$ WORK( 1 + (NB+1)*N ), N )* normalize vectorsDO K = 1, IVIF( ISCOMPLEX(K).EQ.0) THEN* real eigenvectorII = IDAMAX( N, WORK( 1 + (NB+K)*N ), 1 )REMAX = ONE / ABS( WORK( II + (NB+K)*N ) )ELSE IF( ISCOMPLEX(K).EQ.1) THEN* first eigenvector of conjugate pairEMAX = ZERODO II = 1, NEMAX = MAX( EMAX,$ ABS( WORK( II + (NB+K )*N ) )+$ ABS( WORK( II + (NB+K+1)*N ) ) )END DOREMAX = ONE / EMAX* else if ISCOMPLEX(K).EQ.-1* second eigenvector of conjugate pair* reuse same REMAX as previous KEND IFCALL DSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )END DOCALL DLACPY( 'F', N, IV,$ WORK( 1 + (NB+1)*N ), N,$ VL( 1, KI2-IV+1 ), LDVL )IV = 1ELSEIV = IV + 1END IFEND IF ! blocked back-transform*IS = IS + 1IF( IP.NE.0 )$ IS = IS + 1260 CONTINUEEND IF*RETURN** End of DTREVC3*END*> \brief \b DTREXC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTREXC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrexc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrexc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrexc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, WORK,* INFO )** .. Scalar Arguments ..* CHARACTER COMPQ* INTEGER IFST, ILST, INFO, LDQ, LDT, N* ..* .. Array Arguments ..* DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTREXC reorders the real Schur factorization of a real matrix*> A = Q*T*Q**T, so that the diagonal block of T with row index IFST is*> moved to row ILST.*>*> The real Schur form T is reordered by an orthogonal similarity*> transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors*> is updated by postmultiplying it with Z.*>*> T must be in Schur canonical form (as returned by DHSEQR), that is,*> block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each*> 2-by-2 diagonal block has its diagonal elements equal and its*> off-diagonal elements of opposite sign.*> \endverbatim** Arguments:* ==========**> \param[in] COMPQ*> \verbatim*> COMPQ is CHARACTER*1*> = 'V': update the matrix Q of Schur vectors;*> = 'N': do not update Q.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T. N >= 0.*> If N == 0 arguments ILST and IFST may be any value.*> \endverbatim*>*> \param[in,out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> On entry, the upper quasi-triangular matrix T, in Schur*> Schur canonical form.*> On exit, the reordered upper quasi-triangular matrix, again*> in Schur canonical form.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if COMPQ = 'V', the matrix Q of Schur vectors.*> On exit, if COMPQ = 'V', Q has been postmultiplied by the*> orthogonal transformation matrix Z which reorders T.*> If COMPQ = 'N', Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q. LDQ >= 1, and if*> COMPQ = 'V', LDQ >= max(1,N).*> \endverbatim*>*> \param[in,out] IFST*> \verbatim*> IFST is INTEGER*> \endverbatim*>*> \param[in,out] ILST*> \verbatim*> ILST is INTEGER*>*> Specify the reordering of the diagonal blocks of T.*> The block with row index IFST is moved to row ILST, by a*> sequence of transpositions between adjacent blocks.*> On exit, if IFST pointed on entry to the second row of a*> 2-by-2 block, it is changed to point to the first row; ILST*> always points to the first row of the block in its final*> position (which may differ from its input value by +1 or -1).*> 1 <= IFST <= N; 1 <= ILST <= N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> = 1: two adjacent blocks were too close to swap (the problem*> is very ill-conditioned); T may have been partially*> reordered, and ILST points to the first row of the*> current position of the block being moved.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTREXC( COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, WORK,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER COMPQINTEGER IFST, ILST, INFO, LDQ, LDT, N* ..* .. Array Arguments ..DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL WANTQINTEGER HERE, NBF, NBL, NBNEXT* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DLAEXC, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Decode and test the input arguments.*INFO = 0WANTQ = LSAME( COMPQ, 'V' )IF( .NOT.WANTQ .AND. .NOT.LSAME( COMPQ, 'N' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -4ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) ) THENINFO = -6ELSE IF(( IFST.LT.1 .OR. IFST.GT.N ).AND.( N.GT.0 )) THENINFO = -7ELSE IF(( ILST.LT.1 .OR. ILST.GT.N ).AND.( N.GT.0 )) THENINFO = -8END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTREXC', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.1 )$ RETURN** Determine the first row of specified block* and find out it is 1 by 1 or 2 by 2.*IF( IFST.GT.1 ) THENIF( T( IFST, IFST-1 ).NE.ZERO )$ IFST = IFST - 1END IFNBF = 1IF( IFST.LT.N ) THENIF( T( IFST+1, IFST ).NE.ZERO )$ NBF = 2END IF** Determine the first row of the final block* and find out it is 1 by 1 or 2 by 2.*IF( ILST.GT.1 ) THENIF( T( ILST, ILST-1 ).NE.ZERO )$ ILST = ILST - 1END IFNBL = 1IF( ILST.LT.N ) THENIF( T( ILST+1, ILST ).NE.ZERO )$ NBL = 2END IF*IF( IFST.EQ.ILST )$ RETURN*IF( IFST.LT.ILST ) THEN** Update ILST*IF( NBF.EQ.2 .AND. NBL.EQ.1 )$ ILST = ILST - 1IF( NBF.EQ.1 .AND. NBL.EQ.2 )$ ILST = ILST + 1*HERE = IFST*10 CONTINUE** Swap block with next one below*IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN** Current block either 1 by 1 or 2 by 2*NBNEXT = 1IF( HERE+NBF+1.LE.N ) THENIF( T( HERE+NBF+1, HERE+NBF ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBF, NBNEXT,$ WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + NBNEXT** Test if 2 by 2 block breaks into two 1 by 1 blocks*IF( NBF.EQ.2 ) THENIF( T( HERE+1, HERE ).EQ.ZERO )$ NBF = 3END IF*ELSE** Current block consists of two 1 by 1 blocks each of which* must be swapped individually*NBNEXT = 1IF( HERE+3.LE.N ) THENIF( T( HERE+3, HERE+2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, NBNEXT,$ WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFIF( NBNEXT.EQ.1 ) THEN** Swap two 1 by 1 blocks, no problems possible*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, NBNEXT,$ WORK, INFO )HERE = HERE + 1ELSE** Recompute NBNEXT in case 2 by 2 split*IF( T( HERE+2, HERE+1 ).EQ.ZERO )$ NBNEXT = 1IF( NBNEXT.EQ.2 ) THEN** 2 by 2 Block did not split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1,$ NBNEXT, WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE + 2ELSE** 2 by 2 Block did split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,$ WORK, INFO )CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE+1, 1, 1,$ WORK, INFO )HERE = HERE + 2END IFEND IFEND IFIF( HERE.LT.ILST )$ GO TO 10*ELSE*HERE = IFST20 CONTINUE** Swap block with next one above*IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN** Current block either 1 by 1 or 2 by 2*NBNEXT = 1IF( HERE.GE.3 ) THENIF( T( HERE-1, HERE-2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,$ NBF, WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - NBNEXT** Test if 2 by 2 block breaks into two 1 by 1 blocks*IF( NBF.EQ.2 ) THENIF( T( HERE+1, HERE ).EQ.ZERO )$ NBF = 3END IF*ELSE** Current block consists of two 1 by 1 blocks each of which* must be swapped individually*NBNEXT = 1IF( HERE.GE.3 ) THENIF( T( HERE-1, HERE-2 ).NE.ZERO )$ NBNEXT = 2END IFCALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-NBNEXT, NBNEXT,$ 1, WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFIF( NBNEXT.EQ.1 ) THEN** Swap two 1 by 1 blocks, no problems possible*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, NBNEXT, 1,$ WORK, INFO )HERE = HERE - 1ELSE** Recompute NBNEXT in case 2 by 2 split*IF( T( HERE, HERE-1 ).EQ.ZERO )$ NBNEXT = 1IF( NBNEXT.EQ.2 ) THEN** 2 by 2 Block did not split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 2, 1,$ WORK, INFO )IF( INFO.NE.0 ) THENILST = HERERETURNEND IFHERE = HERE - 2ELSE** 2 by 2 Block did split*CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE, 1, 1,$ WORK, INFO )CALL DLAEXC( WANTQ, N, T, LDT, Q, LDQ, HERE-1, 1, 1,$ WORK, INFO )HERE = HERE - 2END IFEND IFEND IFIF( HERE.GT.ILST )$ GO TO 20END IFILST = HERE*RETURN** End of DTREXC*END*> \brief \b DTRRFS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRRFS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrrfs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrrfs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrrfs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRRFS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB, X,* LDX, FERR, BERR, WORK, IWORK, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, TRANS, UPLO* INTEGER INFO, LDA, LDB, LDX, N, NRHS* ..* .. Array Arguments ..* INTEGER IWORK( * )* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), BERR( * ), FERR( * ),* $ WORK( * ), X( LDX, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRRFS provides error bounds and backward error estimates for the*> solution to a system of linear equations with a triangular*> coefficient matrix.*>*> The solution matrix X must be computed by DTRTRS or some other*> means before entering this routine. DTRRFS does not do iterative*> refinement because doing so cannot improve the backward error.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrices B and X. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The triangular matrix A. If UPLO = 'U', the leading N-by-N*> upper triangular part of the array A contains the upper*> triangular matrix, and the strictly lower triangular part of*> A is not referenced. If UPLO = 'L', the leading N-by-N lower*> triangular part of the array A contains the lower triangular*> matrix, and the strictly upper triangular part of A is not*> referenced. If DIAG = 'U', the diagonal elements of A are*> also not referenced and are assumed to be 1.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> The right hand side matrix B.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in] X*> \verbatim*> X is DOUBLE PRECISION array, dimension (LDX,NRHS)*> The solution matrix X.*> \endverbatim*>*> \param[in] LDX*> \verbatim*> LDX is INTEGER*> The leading dimension of the array X. LDX >= max(1,N).*> \endverbatim*>*> \param[out] FERR*> \verbatim*> FERR is DOUBLE PRECISION array, dimension (NRHS)*> The estimated forward error bound for each solution vector*> X(j) (the j-th column of the solution matrix X).*> If XTRUE is the true solution corresponding to X(j), FERR(j)*> is an estimated upper bound for the magnitude of the largest*> element in (X(j) - XTRUE) divided by the magnitude of the*> largest element in X(j). The estimate is as reliable as*> the estimate for RCOND, and is almost always a slight*> overestimate of the true error.*> \endverbatim*>*> \param[out] BERR*> \verbatim*> BERR is DOUBLE PRECISION array, dimension (NRHS)*> The componentwise relative backward error of each solution*> vector X(j) (i.e., the smallest relative change in*> any element of A or B that makes X(j) an exact solution).*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (3*N)*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (N)*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTRRFS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB, X,$ LDX, FERR, BERR, WORK, IWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, TRANS, UPLOINTEGER INFO, LDA, LDB, LDX, N, NRHS* ..* .. Array Arguments ..INTEGER IWORK( * )DOUBLE PRECISION A( LDA, * ), B( LDB, * ), BERR( * ), FERR( * ),$ WORK( * ), X( LDX, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRAN, NOUNIT, UPPERCHARACTER TRANSTINTEGER I, J, K, KASE, NZDOUBLE PRECISION EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DLACN2, DTRMV, DTRSV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLAMCHEXTERNAL LSAME, DLAMCH* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOTRAN = LSAME( TRANS, 'N' )NOUNIT = LSAME( DIAG, 'N' )*IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.$ LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDX.LT.MAX( 1, N ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRRFS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 .OR. NRHS.EQ.0 ) THENDO 10 J = 1, NRHSFERR( J ) = ZEROBERR( J ) = ZERO10 CONTINUERETURNEND IF*IF( NOTRAN ) THENTRANST = 'T'ELSETRANST = 'N'END IF** NZ = maximum number of nonzero elements in each row of A, plus 1*NZ = N + 1EPS = DLAMCH( 'Epsilon' )SAFMIN = DLAMCH( 'Safe minimum' )SAFE1 = NZ*SAFMINSAFE2 = SAFE1 / EPS** Do for each right hand side*DO 250 J = 1, NRHS** Compute residual R = B - op(A) * X,* where op(A) = A or A**T, depending on TRANS.*CALL DCOPY( N, X( 1, J ), 1, WORK( N+1 ), 1 )CALL DTRMV( UPLO, TRANS, DIAG, N, A, LDA, WORK( N+1 ), 1 )CALL DAXPY( N, -ONE, B( 1, J ), 1, WORK( N+1 ), 1 )** Compute componentwise relative backward error from formula** max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )** where abs(Z) is the componentwise absolute value of the matrix* or vector Z. If the i-th component of the denominator is less* than SAFE2, then SAFE1 is added to the i-th components of the* numerator and denominator before dividing.*DO 20 I = 1, NWORK( I ) = ABS( B( I, J ) )20 CONTINUE*IF( NOTRAN ) THEN** Compute abs(A)*abs(X) + abs(B).*IF( UPPER ) THENIF( NOUNIT ) THENDO 40 K = 1, NXK = ABS( X( K, J ) )DO 30 I = 1, KWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XK30 CONTINUE40 CONTINUEELSEDO 60 K = 1, NXK = ABS( X( K, J ) )DO 50 I = 1, K - 1WORK( I ) = WORK( I ) + ABS( A( I, K ) )*XK50 CONTINUEWORK( K ) = WORK( K ) + XK60 CONTINUEEND IFELSEIF( NOUNIT ) THENDO 80 K = 1, NXK = ABS( X( K, J ) )DO 70 I = K, NWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XK70 CONTINUE80 CONTINUEELSEDO 100 K = 1, NXK = ABS( X( K, J ) )DO 90 I = K + 1, NWORK( I ) = WORK( I ) + ABS( A( I, K ) )*XK90 CONTINUEWORK( K ) = WORK( K ) + XK100 CONTINUEEND IFEND IFELSE** Compute abs(A**T)*abs(X) + abs(B).*IF( UPPER ) THENIF( NOUNIT ) THENDO 120 K = 1, NS = ZERODO 110 I = 1, KS = S + ABS( A( I, K ) )*ABS( X( I, J ) )110 CONTINUEWORK( K ) = WORK( K ) + S120 CONTINUEELSEDO 140 K = 1, NS = ABS( X( K, J ) )DO 130 I = 1, K - 1S = S + ABS( A( I, K ) )*ABS( X( I, J ) )130 CONTINUEWORK( K ) = WORK( K ) + S140 CONTINUEEND IFELSEIF( NOUNIT ) THENDO 160 K = 1, NS = ZERODO 150 I = K, NS = S + ABS( A( I, K ) )*ABS( X( I, J ) )150 CONTINUEWORK( K ) = WORK( K ) + S160 CONTINUEELSEDO 180 K = 1, NS = ABS( X( K, J ) )DO 170 I = K + 1, NS = S + ABS( A( I, K ) )*ABS( X( I, J ) )170 CONTINUEWORK( K ) = WORK( K ) + S180 CONTINUEEND IFEND IFEND IFS = ZERODO 190 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENS = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )ELSES = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /$ ( WORK( I )+SAFE1 ) )END IF190 CONTINUEBERR( J ) = S** Bound error from formula** norm(X - XTRUE) / norm(X) .le. FERR =* norm( abs(inv(op(A)))** ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)** where* norm(Z) is the magnitude of the largest component of Z* inv(op(A)) is the inverse of op(A)* abs(Z) is the componentwise absolute value of the matrix or* vector Z* NZ is the maximum number of nonzeros in any row of A, plus 1* EPS is machine epsilon** The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))* is incremented by SAFE1 if the i-th component of* abs(op(A))*abs(X) + abs(B) is less than SAFE2.** Use DLACN2 to estimate the infinity-norm of the matrix* inv(op(A)) * diag(W),* where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))*DO 200 I = 1, NIF( WORK( I ).GT.SAFE2 ) THENWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )ELSEWORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1END IF200 CONTINUE*KASE = 0210 CONTINUECALL DLACN2( N, WORK( 2*N+1 ), WORK( N+1 ), IWORK, FERR( J ),$ KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Multiply by diag(W)*inv(op(A)**T).*CALL DTRSV( UPLO, TRANST, DIAG, N, A, LDA, WORK( N+1 ),$ 1 )DO 220 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )220 CONTINUEELSE** Multiply by inv(op(A))*diag(W).*DO 230 I = 1, NWORK( N+I ) = WORK( I )*WORK( N+I )230 CONTINUECALL DTRSV( UPLO, TRANS, DIAG, N, A, LDA, WORK( N+1 ),$ 1 )END IFGO TO 210END IF** Normalize error.*LSTRES = ZERODO 240 I = 1, NLSTRES = MAX( LSTRES, ABS( X( I, J ) ) )240 CONTINUEIF( LSTRES.NE.ZERO )$ FERR( J ) = FERR( J ) / LSTRES*250 CONTINUE*RETURN** End of DTRRFS*END*> \brief \b DTRSEN** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRSEN + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrsen.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrsen.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrsen.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI,* M, S, SEP, WORK, LWORK, IWORK, LIWORK, INFO )** .. Scalar Arguments ..* CHARACTER COMPQ, JOB* INTEGER INFO, LDQ, LDT, LIWORK, LWORK, M, N* DOUBLE PRECISION S, SEP* ..* .. Array Arguments ..* LOGICAL SELECT( * )* INTEGER IWORK( * )* DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WI( * ), WORK( * ),* $ WR( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRSEN reorders the real Schur factorization of a real matrix*> A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in*> the leading diagonal blocks of the upper quasi-triangular matrix T,*> and the leading columns of Q form an orthonormal basis of the*> corresponding right invariant subspace.*>*> Optionally the routine computes the reciprocal condition numbers of*> the cluster of eigenvalues and/or the invariant subspace.*>*> T must be in Schur canonical form (as returned by DHSEQR), that is,*> block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each*> 2-by-2 diagonal block has its diagonal elements equal and its*> off-diagonal elements of opposite sign.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies whether condition numbers are required for the*> cluster of eigenvalues (S) or the invariant subspace (SEP):*> = 'N': none;*> = 'E': for eigenvalues only (S);*> = 'V': for invariant subspace only (SEP);*> = 'B': for both eigenvalues and invariant subspace (S and*> SEP).*> \endverbatim*>*> \param[in] COMPQ*> \verbatim*> COMPQ is CHARACTER*1*> = 'V': update the matrix Q of Schur vectors;*> = 'N': do not update Q.*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> SELECT specifies the eigenvalues in the selected cluster. To*> select a real eigenvalue w(j), SELECT(j) must be set to*> .TRUE.. To select a complex conjugate pair of eigenvalues*> w(j) and w(j+1), corresponding to a 2-by-2 diagonal block,*> either SELECT(j) or SELECT(j+1) or both must be set to*> .TRUE.; a complex conjugate pair of eigenvalues must be*> either both included in the cluster or both excluded.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T. N >= 0.*> \endverbatim*>*> \param[in,out] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> On entry, the upper quasi-triangular matrix T, in Schur*> canonical form.*> On exit, T is overwritten by the reordered matrix T, again in*> Schur canonical form, with the selected eigenvalues in the*> leading diagonal blocks.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[in,out] Q*> \verbatim*> Q is DOUBLE PRECISION array, dimension (LDQ,N)*> On entry, if COMPQ = 'V', the matrix Q of Schur vectors.*> On exit, if COMPQ = 'V', Q has been postmultiplied by the*> orthogonal transformation matrix which reorders T; the*> leading M columns of Q form an orthonormal basis for the*> specified invariant subspace.*> If COMPQ = 'N', Q is not referenced.*> \endverbatim*>*> \param[in] LDQ*> \verbatim*> LDQ is INTEGER*> The leading dimension of the array Q.*> LDQ >= 1; and if COMPQ = 'V', LDQ >= N.*> \endverbatim*>*> \param[out] WR*> \verbatim*> WR is DOUBLE PRECISION array, dimension (N)*> \endverbatim*> \param[out] WI*> \verbatim*> WI is DOUBLE PRECISION array, dimension (N)*>*> The real and imaginary parts, respectively, of the reordered*> eigenvalues of T. The eigenvalues are stored in the same*> order as on the diagonal of T, with WR(i) = T(i,i) and, if*> T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0 and*> WI(i+1) = -WI(i). Note that if a complex eigenvalue is*> sufficiently ill-conditioned, then its value may differ*> significantly from its value before reordering.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The dimension of the specified invariant subspace.*> 0 < = M <= N.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION*> If JOB = 'E' or 'B', S is a lower bound on the reciprocal*> condition number for the selected cluster of eigenvalues.*> S cannot underestimate the true reciprocal condition number*> by more than a factor of sqrt(N). If M = 0 or N, S = 1.*> If JOB = 'N' or 'V', S is not referenced.*> \endverbatim*>*> \param[out] SEP*> \verbatim*> SEP is DOUBLE PRECISION*> If JOB = 'V' or 'B', SEP is the estimated reciprocal*> condition number of the specified invariant subspace. If*> M = 0 or N, SEP = norm(T).*> If JOB = 'N' or 'E', SEP is not referenced.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK.*> If JOB = 'N', LWORK >= max(1,N);*> if JOB = 'E', LWORK >= max(1,M*(N-M));*> if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)).*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))*> On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.*> \endverbatim*>*> \param[in] LIWORK*> \verbatim*> LIWORK is INTEGER*> The dimension of the array IWORK.*> If JOB = 'N' or 'E', LIWORK >= 1;*> if JOB = 'V' or 'B', LIWORK >= max(1,M*(N-M)).*>*> If LIWORK = -1, then a workspace query is assumed; the*> routine only calculates the optimal size of the IWORK array,*> returns this value as the first entry of the IWORK array, and*> no error message related to LIWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> = 1: reordering of T failed because some eigenvalues are too*> close to separate (the problem is very ill-conditioned);*> T may have been partially reordered, and WR and WI*> contain the eigenvalues in the same order as in T; S and*> SEP (if requested) are set to zero.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> DTRSEN first collects the selected eigenvalues by computing an*> orthogonal transformation Z to move them to the top left corner of T.*> In other words, the selected eigenvalues are the eigenvalues of T11*> in:*>*> Z**T * T * Z = ( T11 T12 ) n1*> ( 0 T22 ) n2*> n1 n2*>*> where N = n1+n2 and Z**T means the transpose of Z. The first n1 columns*> of Z span the specified invariant subspace of T.*>*> If T has been obtained from the real Schur factorization of a matrix*> A = Q*T*Q**T, then the reordered real Schur factorization of A is given*> by A = (Q*Z)*(Z**T*T*Z)*(Q*Z)**T, and the first n1 columns of Q*Z span*> the corresponding invariant subspace of A.*>*> The reciprocal condition number of the average of the eigenvalues of*> T11 may be returned in S. S lies between 0 (very badly conditioned)*> and 1 (very well conditioned). It is computed as follows. First we*> compute R so that*>*> P = ( I R ) n1*> ( 0 0 ) n2*> n1 n2*>*> is the projector on the invariant subspace associated with T11.*> R is the solution of the Sylvester equation:*>*> T11*R - R*T22 = T12.*>*> Let F-norm(M) denote the Frobenius-norm of M and 2-norm(M) denote*> the two-norm of M. Then S is computed as the lower bound*>*> (1 + F-norm(R)**2)**(-1/2)*>*> on the reciprocal of 2-norm(P), the true reciprocal condition number.*> S cannot underestimate 1 / 2-norm(P) by more than a factor of*> sqrt(N).*>*> An approximate error bound for the computed average of the*> eigenvalues of T11 is*>*> EPS * norm(T) / S*>*> where EPS is the machine precision.*>*> The reciprocal condition number of the right invariant subspace*> spanned by the first n1 columns of Z (or of Q*Z) is returned in SEP.*> SEP is defined as the separation of T11 and T22:*>*> sep( T11, T22 ) = sigma-min( C )*>*> where sigma-min(C) is the smallest singular value of the*> n1*n2-by-n1*n2 matrix*>*> C = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )*>*> I(m) is an m by m identity matrix, and kprod denotes the Kronecker*> product. We estimate sigma-min(C) by the reciprocal of an estimate of*> the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C)*> cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2).*>*> When SEP is small, small changes in T can cause large changes in*> the invariant subspace. An approximate bound on the maximum angular*> error in the computed right invariant subspace is*>*> EPS * norm(T) / SEP*> \endverbatim*>* =====================================================================SUBROUTINE DTRSEN( JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI,$ M, S, SEP, WORK, LWORK, IWORK, LIWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..CHARACTER COMPQ, JOBINTEGER INFO, LDQ, LDT, LIWORK, LWORK, M, NDOUBLE PRECISION S, SEP* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IWORK( * )DOUBLE PRECISION Q( LDQ, * ), T( LDT, * ), WI( * ), WORK( * ),$ WR( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERY, PAIR, SWAP, WANTBH, WANTQ, WANTS,$ WANTSPINTEGER IERR, K, KASE, KK, KS, LIWMIN, LWMIN, N1, N2,$ NNDOUBLE PRECISION EST, RNORM, SCALE* ..* .. Local Arrays ..INTEGER ISAVE( 3 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DLANGEEXTERNAL LSAME, DLANGE* ..* .. External Subroutines ..EXTERNAL DLACN2, DLACPY, DTREXC, DTRSYL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode and test the input parameters*WANTBH = LSAME( JOB, 'B' )WANTS = LSAME( JOB, 'E' ) .OR. WANTBHWANTSP = LSAME( JOB, 'V' ) .OR. WANTBHWANTQ = LSAME( COMPQ, 'V' )*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.WANTS .AND. .NOT.WANTSP )$ THENINFO = -1ELSE IF( .NOT.LSAME( COMPQ, 'N' ) .AND. .NOT.WANTQ ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THENINFO = -8ELSE** Set M to the dimension of the specified invariant subspace,* and test LWORK and LIWORK.*M = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSEIF( K.LT.N ) THENIF( T( K+1, K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) )$ M = M + 2END IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUE*N1 = MN2 = N - MNN = N1*N2*IF( WANTSP ) THENLWMIN = MAX( 1, 2*NN )LIWMIN = MAX( 1, NN )ELSE IF( LSAME( JOB, 'N' ) ) THENLWMIN = MAX( 1, N )LIWMIN = 1ELSE IF( LSAME( JOB, 'E' ) ) THENLWMIN = MAX( 1, NN )LIWMIN = 1END IF*IF( LWORK.LT.LWMIN .AND. .NOT.LQUERY ) THENINFO = -15ELSE IF( LIWORK.LT.LIWMIN .AND. .NOT.LQUERY ) THENINFO = -17END IFEND IF*IF( INFO.EQ.0 ) THENWORK( 1 ) = LWMINIWORK( 1 ) = LIWMINEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTRSEN', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible.*IF( M.EQ.N .OR. M.EQ.0 ) THENIF( WANTS )$ S = ONEIF( WANTSP )$ SEP = DLANGE( '1', N, N, T, LDT, WORK )GO TO 40END IF** Collect the selected blocks at the top-left corner of T.*KS = 0PAIR = .FALSE.DO 20 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSESWAP = SELECT( K )IF( K.LT.N ) THENIF( T( K+1, K ).NE.ZERO ) THENPAIR = .TRUE.SWAP = SWAP .OR. SELECT( K+1 )END IFEND IFIF( SWAP ) THENKS = KS + 1** Swap the K-th block to position KS.*IERR = 0KK = KIF( K.NE.KS )$ CALL DTREXC( COMPQ, N, T, LDT, Q, LDQ, KK, KS, WORK,$ IERR )IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN** Blocks too close to swap: exit.*INFO = 1IF( WANTS )$ S = ZEROIF( WANTSP )$ SEP = ZEROGO TO 40END IFIF( PAIR )$ KS = KS + 1END IFEND IF20 CONTINUE*IF( WANTS ) THEN** Solve Sylvester equation for R:** T11*R - R*T22 = scale*T12*CALL DLACPY( 'F', N1, N2, T( 1, N1+1 ), LDT, WORK, N1 )CALL DTRSYL( 'N', 'N', -1, N1, N2, T, LDT, T( N1+1, N1+1 ),$ LDT, WORK, N1, SCALE, IERR )** Estimate the reciprocal of the condition number of the cluster* of eigenvalues.*RNORM = DLANGE( 'F', N1, N2, WORK, N1, WORK )IF( RNORM.EQ.ZERO ) THENS = ONEELSES = SCALE / ( SQRT( SCALE*SCALE / RNORM+RNORM )*$ SQRT( RNORM ) )END IFEND IF*IF( WANTSP ) THEN** Estimate sep(T11,T22).*EST = ZEROKASE = 030 CONTINUECALL DLACN2( NN, WORK( NN+1 ), WORK, IWORK, EST, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THEN** Solve T11*R - R*T22 = scale*X.*CALL DTRSYL( 'N', 'N', -1, N1, N2, T, LDT,$ T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,$ IERR )ELSE** Solve T11**T*R - R*T22**T = scale*X.*CALL DTRSYL( 'T', 'T', -1, N1, N2, T, LDT,$ T( N1+1, N1+1 ), LDT, WORK, N1, SCALE,$ IERR )END IFGO TO 30END IF*SEP = SCALE / ESTEND IF*40 CONTINUE** Store the output eigenvalues in WR and WI.*DO 50 K = 1, NWR( K ) = T( K, K )WI( K ) = ZERO50 CONTINUEDO 60 K = 1, N - 1IF( T( K+1, K ).NE.ZERO ) THENWI( K ) = SQRT( ABS( T( K, K+1 ) ) )*$ SQRT( ABS( T( K+1, K ) ) )WI( K+1 ) = -WI( K )END IF60 CONTINUE*WORK( 1 ) = LWMINIWORK( 1 ) = LIWMIN*RETURN** End of DTRSEN*END*> \brief \b DTRSNA** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRSNA + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrsna.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrsna.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrsna.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRSNA( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,* LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK,* INFO )** .. Scalar Arguments ..* CHARACTER HOWMNY, JOB* INTEGER INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N* ..* .. Array Arguments ..* LOGICAL SELECT( * )* INTEGER IWORK( * )* DOUBLE PRECISION S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),* $ VR( LDVR, * ), WORK( LDWORK, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRSNA estimates reciprocal condition numbers for specified*> eigenvalues and/or right eigenvectors of a real upper*> quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q*> orthogonal).*>*> T must be in Schur canonical form (as returned by DHSEQR), that is,*> block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each*> 2-by-2 diagonal block has its diagonal elements equal and its*> off-diagonal elements of opposite sign.*> \endverbatim** Arguments:* ==========**> \param[in] JOB*> \verbatim*> JOB is CHARACTER*1*> Specifies whether condition numbers are required for*> eigenvalues (S) or eigenvectors (SEP):*> = 'E': for eigenvalues only (S);*> = 'V': for eigenvectors only (SEP);*> = 'B': for both eigenvalues and eigenvectors (S and SEP).*> \endverbatim*>*> \param[in] HOWMNY*> \verbatim*> HOWMNY is CHARACTER*1*> = 'A': compute condition numbers for all eigenpairs;*> = 'S': compute condition numbers for selected eigenpairs*> specified by the array SELECT.*> \endverbatim*>*> \param[in] SELECT*> \verbatim*> SELECT is LOGICAL array, dimension (N)*> If HOWMNY = 'S', SELECT specifies the eigenpairs for which*> condition numbers are required. To select condition numbers*> for the eigenpair corresponding to a real eigenvalue w(j),*> SELECT(j) must be set to .TRUE.. To select condition numbers*> corresponding to a complex conjugate pair of eigenvalues w(j)*> and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be*> set to .TRUE..*> If HOWMNY = 'A', SELECT is not referenced.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix T. N >= 0.*> \endverbatim*>*> \param[in] T*> \verbatim*> T is DOUBLE PRECISION array, dimension (LDT,N)*> The upper quasi-triangular matrix T, in Schur canonical form.*> \endverbatim*>*> \param[in] LDT*> \verbatim*> LDT is INTEGER*> The leading dimension of the array T. LDT >= max(1,N).*> \endverbatim*>*> \param[in] VL*> \verbatim*> VL is DOUBLE PRECISION array, dimension (LDVL,M)*> If JOB = 'E' or 'B', VL must contain left eigenvectors of T*> (or of any Q*T*Q**T with Q orthogonal), corresponding to the*> eigenpairs specified by HOWMNY and SELECT. The eigenvectors*> must be stored in consecutive columns of VL, as returned by*> DHSEIN or DTREVC.*> If JOB = 'V', VL is not referenced.*> \endverbatim*>*> \param[in] LDVL*> \verbatim*> LDVL is INTEGER*> The leading dimension of the array VL.*> LDVL >= 1; and if JOB = 'E' or 'B', LDVL >= N.*> \endverbatim*>*> \param[in] VR*> \verbatim*> VR is DOUBLE PRECISION array, dimension (LDVR,M)*> If JOB = 'E' or 'B', VR must contain right eigenvectors of T*> (or of any Q*T*Q**T with Q orthogonal), corresponding to the*> eigenpairs specified by HOWMNY and SELECT. The eigenvectors*> must be stored in consecutive columns of VR, as returned by*> DHSEIN or DTREVC.*> If JOB = 'V', VR is not referenced.*> \endverbatim*>*> \param[in] LDVR*> \verbatim*> LDVR is INTEGER*> The leading dimension of the array VR.*> LDVR >= 1; and if JOB = 'E' or 'B', LDVR >= N.*> \endverbatim*>*> \param[out] S*> \verbatim*> S is DOUBLE PRECISION array, dimension (MM)*> If JOB = 'E' or 'B', the reciprocal condition numbers of the*> selected eigenvalues, stored in consecutive elements of the*> array. For a complex conjugate pair of eigenvalues two*> consecutive elements of S are set to the same value. Thus*> S(j), SEP(j), and the j-th columns of VL and VR all*> correspond to the same eigenpair (but not in general the*> j-th eigenpair, unless all eigenpairs are selected).*> If JOB = 'V', S is not referenced.*> \endverbatim*>*> \param[out] SEP*> \verbatim*> SEP is DOUBLE PRECISION array, dimension (MM)*> If JOB = 'V' or 'B', the estimated reciprocal condition*> numbers of the selected eigenvectors, stored in consecutive*> elements of the array. For a complex eigenvector two*> consecutive elements of SEP are set to the same value. If*> the eigenvalues cannot be reordered to compute SEP(j), SEP(j)*> is set to 0; this can only occur when the true value would be*> very small anyway.*> If JOB = 'E', SEP is not referenced.*> \endverbatim*>*> \param[in] MM*> \verbatim*> MM is INTEGER*> The number of elements in the arrays S (if JOB = 'E' or 'B')*> and/or SEP (if JOB = 'V' or 'B'). MM >= M.*> \endverbatim*>*> \param[out] M*> \verbatim*> M is INTEGER*> The number of elements of the arrays S and/or SEP actually*> used to store the estimated condition numbers.*> If HOWMNY = 'A', M is set to N.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (LDWORK,N+6)*> If JOB = 'E', WORK is not referenced.*> \endverbatim*>*> \param[in] LDWORK*> \verbatim*> LDWORK is INTEGER*> The leading dimension of the array WORK.*> LDWORK >= 1; and if JOB = 'V' or 'B', LDWORK >= N.*> \endverbatim*>*> \param[out] IWORK*> \verbatim*> IWORK is INTEGER array, dimension (2*(N-1))*> If JOB = 'E', IWORK is not referenced.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The reciprocal of the condition number of an eigenvalue lambda is*> defined as*>*> S(lambda) = |v**T*u| / (norm(u)*norm(v))*>*> where u and v are the right and left eigenvectors of T corresponding*> to lambda; v**T denotes the transpose of v, and norm(u)*> denotes the Euclidean norm. These reciprocal condition numbers always*> lie between zero (very badly conditioned) and one (very well*> conditioned). If n = 1, S(lambda) is defined to be 1.*>*> An approximate error bound for a computed eigenvalue W(i) is given by*>*> EPS * norm(T) / S(i)*>*> where EPS is the machine precision.*>*> The reciprocal of the condition number of the right eigenvector u*> corresponding to lambda is defined as follows. Suppose*>*> T = ( lambda c )*> ( 0 T22 )*>*> Then the reciprocal condition number is*>*> SEP( lambda, T22 ) = sigma-min( T22 - lambda*I )*>*> where sigma-min denotes the smallest singular value. We approximate*> the smallest singular value by the reciprocal of an estimate of the*> one-norm of the inverse of T22 - lambda*I. If n = 1, SEP(1) is*> defined to be abs(T(1,1)).*>*> An approximate error bound for a computed right eigenvector VR(i)*> is given by*>*> EPS * norm(T) / SEP(i)*> \endverbatim*>* =====================================================================SUBROUTINE DTRSNA( JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,$ LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK,$ INFO )** -- LAPACK computational routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..CHARACTER HOWMNY, JOBINTEGER INFO, LDT, LDVL, LDVR, LDWORK, M, MM, N* ..* .. Array Arguments ..LOGICAL SELECT( * )INTEGER IWORK( * )DOUBLE PRECISION S( * ), SEP( * ), T( LDT, * ), VL( LDVL, * ),$ VR( LDVR, * ), WORK( LDWORK, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONE, TWOPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )* ..* .. Local Scalars ..LOGICAL PAIR, SOMCON, WANTBH, WANTS, WANTSPINTEGER I, IERR, IFST, ILST, J, K, KASE, KS, N2, NNDOUBLE PRECISION BIGNUM, COND, CS, DELTA, DUMM, EPS, EST, LNRM,$ MU, PROD, PROD1, PROD2, RNRM, SCALE, SMLNUM, SN* ..* .. Local Arrays ..INTEGER ISAVE( 3 )DOUBLE PRECISION DUMMY( 1 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOT, DLAMCH, DLAPY2, DNRM2EXTERNAL LSAME, DDOT, DLAMCH, DLAPY2, DNRM2* ..* .. External Subroutines ..EXTERNAL DLABAD, DLACN2, DLACPY, DLAQTR, DTREXC, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, MAX, SQRT* ..* .. Executable Statements ..** Decode and test the input parameters*WANTBH = LSAME( JOB, 'B' )WANTS = LSAME( JOB, 'E' ) .OR. WANTBHWANTSP = LSAME( JOB, 'V' ) .OR. WANTBH*SOMCON = LSAME( HOWMNY, 'S' )*INFO = 0IF( .NOT.WANTS .AND. .NOT.WANTSP ) THENINFO = -1ELSE IF( .NOT.LSAME( HOWMNY, 'A' ) .AND. .NOT.SOMCON ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( LDT.LT.MAX( 1, N ) ) THENINFO = -6ELSE IF( LDVL.LT.1 .OR. ( WANTS .AND. LDVL.LT.N ) ) THENINFO = -8ELSE IF( LDVR.LT.1 .OR. ( WANTS .AND. LDVR.LT.N ) ) THENINFO = -10ELSE** Set M to the number of eigenpairs for which condition numbers* are required, and test MM.*IF( SOMCON ) THENM = 0PAIR = .FALSE.DO 10 K = 1, NIF( PAIR ) THENPAIR = .FALSE.ELSEIF( K.LT.N ) THENIF( T( K+1, K ).EQ.ZERO ) THENIF( SELECT( K ) )$ M = M + 1ELSEPAIR = .TRUE.IF( SELECT( K ) .OR. SELECT( K+1 ) )$ M = M + 2END IFELSEIF( SELECT( N ) )$ M = M + 1END IFEND IF10 CONTINUEELSEM = NEND IF*IF( MM.LT.M ) THENINFO = -13ELSE IF( LDWORK.LT.1 .OR. ( WANTSP .AND. LDWORK.LT.N ) ) THENINFO = -16END IFEND IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRSNA', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN*IF( N.EQ.1 ) THENIF( SOMCON ) THENIF( .NOT.SELECT( 1 ) )$ RETURNEND IFIF( WANTS )$ S( 1 ) = ONEIF( WANTSP )$ SEP( 1 ) = ABS( T( 1, 1 ) )RETURNEND IF** Get machine constants*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' ) / EPSBIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )*KS = 0PAIR = .FALSE.DO 60 K = 1, N** Determine whether T(k,k) begins a 1-by-1 or 2-by-2 block.*IF( PAIR ) THENPAIR = .FALSE.GO TO 60ELSEIF( K.LT.N )$ PAIR = T( K+1, K ).NE.ZEROEND IF** Determine whether condition numbers are required for the k-th* eigenpair.*IF( SOMCON ) THENIF( PAIR ) THENIF( .NOT.SELECT( K ) .AND. .NOT.SELECT( K+1 ) )$ GO TO 60ELSEIF( .NOT.SELECT( K ) )$ GO TO 60END IFEND IF*KS = KS + 1*IF( WANTS ) THEN** Compute the reciprocal condition number of the k-th* eigenvalue.*IF( .NOT.PAIR ) THEN** Real eigenvalue.*PROD = DDOT( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )RNRM = DNRM2( N, VR( 1, KS ), 1 )LNRM = DNRM2( N, VL( 1, KS ), 1 )S( KS ) = ABS( PROD ) / ( RNRM*LNRM )ELSE** Complex eigenvalue.*PROD1 = DDOT( N, VR( 1, KS ), 1, VL( 1, KS ), 1 )PROD1 = PROD1 + DDOT( N, VR( 1, KS+1 ), 1, VL( 1, KS+1 ),$ 1 )PROD2 = DDOT( N, VL( 1, KS ), 1, VR( 1, KS+1 ), 1 )PROD2 = PROD2 - DDOT( N, VL( 1, KS+1 ), 1, VR( 1, KS ),$ 1 )RNRM = DLAPY2( DNRM2( N, VR( 1, KS ), 1 ),$ DNRM2( N, VR( 1, KS+1 ), 1 ) )LNRM = DLAPY2( DNRM2( N, VL( 1, KS ), 1 ),$ DNRM2( N, VL( 1, KS+1 ), 1 ) )COND = DLAPY2( PROD1, PROD2 ) / ( RNRM*LNRM )S( KS ) = CONDS( KS+1 ) = CONDEND IFEND IF*IF( WANTSP ) THEN** Estimate the reciprocal condition number of the k-th* eigenvector.** Copy the matrix T to the array WORK and swap the diagonal* block beginning at T(k,k) to the (1,1) position.*CALL DLACPY( 'Full', N, N, T, LDT, WORK, LDWORK )IFST = KILST = 1CALL DTREXC( 'No Q', N, WORK, LDWORK, DUMMY, 1, IFST, ILST,$ WORK( 1, N+1 ), IERR )*IF( IERR.EQ.1 .OR. IERR.EQ.2 ) THEN** Could not swap because blocks not well separated*SCALE = ONEEST = BIGNUMELSE** Reordering successful*IF( WORK( 2, 1 ).EQ.ZERO ) THEN** Form C = T22 - lambda*I in WORK(2:N,2:N).*DO 20 I = 2, NWORK( I, I ) = WORK( I, I ) - WORK( 1, 1 )20 CONTINUEN2 = 1NN = N - 1ELSE** Triangularize the 2 by 2 block by unitary* transformation U = [ cs i*ss ]* [ i*ss cs ].* such that the (1,1) position of WORK is complex* eigenvalue lambda with positive imaginary part. (2,2)* position of WORK is the complex eigenvalue lambda* with negative imaginary part.*MU = SQRT( ABS( WORK( 1, 2 ) ) )*$ SQRT( ABS( WORK( 2, 1 ) ) )DELTA = DLAPY2( MU, WORK( 2, 1 ) )CS = MU / DELTASN = -WORK( 2, 1 ) / DELTA** Form** C**T = WORK(2:N,2:N) + i*[rwork(1) ..... rwork(n-1) ]* [ mu ]* [ .. ]* [ .. ]* [ mu ]* where C**T is transpose of matrix C,* and RWORK is stored starting in the N+1-st column of* WORK.*DO 30 J = 3, NWORK( 2, J ) = CS*WORK( 2, J )WORK( J, J ) = WORK( J, J ) - WORK( 1, 1 )30 CONTINUEWORK( 2, 2 ) = ZERO*WORK( 1, N+1 ) = TWO*MUDO 40 I = 2, N - 1WORK( I, N+1 ) = SN*WORK( 1, I+1 )40 CONTINUEN2 = 2NN = 2*( N-1 )END IF** Estimate norm(inv(C**T))*EST = ZEROKASE = 050 CONTINUECALL DLACN2( NN, WORK( 1, N+2 ), WORK( 1, N+4 ), IWORK,$ EST, KASE, ISAVE )IF( KASE.NE.0 ) THENIF( KASE.EQ.1 ) THENIF( N2.EQ.1 ) THEN** Real eigenvalue: solve C**T*x = scale*c.*CALL DLAQTR( .TRUE., .TRUE., N-1, WORK( 2, 2 ),$ LDWORK, DUMMY, DUMM, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )ELSE** Complex eigenvalue: solve* C**T*(p+iq) = scale*(c+id) in real arithmetic.*CALL DLAQTR( .TRUE., .FALSE., N-1, WORK( 2, 2 ),$ LDWORK, WORK( 1, N+1 ), MU, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )END IFELSEIF( N2.EQ.1 ) THEN** Real eigenvalue: solve C*x = scale*c.*CALL DLAQTR( .FALSE., .TRUE., N-1, WORK( 2, 2 ),$ LDWORK, DUMMY, DUMM, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )ELSE** Complex eigenvalue: solve* C*(p+iq) = scale*(c+id) in real arithmetic.*CALL DLAQTR( .FALSE., .FALSE., N-1,$ WORK( 2, 2 ), LDWORK,$ WORK( 1, N+1 ), MU, SCALE,$ WORK( 1, N+4 ), WORK( 1, N+6 ),$ IERR )*END IFEND IF*GO TO 50END IFEND IF*SEP( KS ) = SCALE / MAX( EST, SMLNUM )IF( PAIR )$ SEP( KS+1 ) = SEP( KS )END IF*IF( PAIR )$ KS = KS + 1*60 CONTINUERETURN** End of DTRSNA*END*> \brief \b DTRSYL** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRSYL + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrsyl.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrsyl.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrsyl.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,* LDC, SCALE, INFO )** .. Scalar Arguments ..* CHARACTER TRANA, TRANB* INTEGER INFO, ISGN, LDA, LDB, LDC, M, N* DOUBLE PRECISION SCALE* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRSYL solves the real Sylvester matrix equation:*>*> op(A)*X + X*op(B) = scale*C or*> op(A)*X - X*op(B) = scale*C,*>*> where op(A) = A or A**T, and A and B are both upper quasi-*> triangular. A is M-by-M and B is N-by-N; the right hand side C and*> the solution X are M-by-N; and scale is an output scale factor, set*> <= 1 to avoid overflow in X.*>*> A and B must be in Schur canonical form (as returned by DHSEQR), that*> is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;*> each 2-by-2 diagonal block has its diagonal elements equal and its*> off-diagonal elements of opposite sign.*> \endverbatim** Arguments:* ==========**> \param[in] TRANA*> \verbatim*> TRANA is CHARACTER*1*> Specifies the option op(A):*> = 'N': op(A) = A (No transpose)*> = 'T': op(A) = A**T (Transpose)*> = 'C': op(A) = A**H (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] TRANB*> \verbatim*> TRANB is CHARACTER*1*> Specifies the option op(B):*> = 'N': op(B) = B (No transpose)*> = 'T': op(B) = B**T (Transpose)*> = 'C': op(B) = B**H (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] ISGN*> \verbatim*> ISGN is INTEGER*> Specifies the sign in the equation:*> = +1: solve op(A)*X + X*op(B) = scale*C*> = -1: solve op(A)*X - X*op(B) = scale*C*> \endverbatim*>*> \param[in] M*> \verbatim*> M is INTEGER*> The order of the matrix A, and the number of rows in the*> matrices X and C. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix B, and the number of columns in the*> matrices X and C. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,M)*> The upper quasi-triangular matrix A, in Schur canonical form.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[in] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,N)*> The upper quasi-triangular matrix B, in Schur canonical form.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[in,out] C*> \verbatim*> C is DOUBLE PRECISION array, dimension (LDC,N)*> On entry, the M-by-N right hand side matrix C.*> On exit, C is overwritten by the solution matrix X.*> \endverbatim*>*> \param[in] LDC*> \verbatim*> LDC is INTEGER*> The leading dimension of the array C. LDC >= max(1,M)*> \endverbatim*>*> \param[out] SCALE*> \verbatim*> SCALE is DOUBLE PRECISION*> The scale factor, scale, set <= 1 to avoid overflow in X.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> = 1: A and B have common or very close eigenvalues; perturbed*> values were used to solve the equation (but the matrices*> A and B are unchanged).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleSYcomputational** =====================================================================SUBROUTINE DTRSYL( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,$ LDC, SCALE, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANA, TRANBINTEGER INFO, ISGN, LDA, LDB, LDC, M, NDOUBLE PRECISION SCALE* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOTRNA, NOTRNBINTEGER IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXTDOUBLE PRECISION A11, BIGNUM, DA11, DB, EPS, SCALOC, SGN, SMIN,$ SMLNUM, SUML, SUMR, XNORM* ..* .. Local Arrays ..DOUBLE PRECISION DUM( 1 ), VEC( 2, 2 ), X( 2, 2 )* ..* .. External Functions ..LOGICAL LSAMEDOUBLE PRECISION DDOT, DLAMCH, DLANGEEXTERNAL LSAME, DDOT, DLAMCH, DLANGE* ..* .. External Subroutines ..EXTERNAL DLABAD, DLALN2, DLASY2, DSCAL, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC ABS, DBLE, MAX, MIN* ..* .. Executable Statements ..** Decode and Test input parameters*NOTRNA = LSAME( TRANA, 'N' )NOTRNB = LSAME( TRANB, 'N' )*INFO = 0IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND. .NOT.$ LSAME( TRANA, 'C' ) ) THENINFO = -1ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'T' ) .AND. .NOT.$ LSAME( TRANB, 'C' ) ) THENINFO = -2ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THENINFO = -3ELSE IF( M.LT.0 ) THENINFO = -4ELSE IF( N.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9ELSE IF( LDC.LT.MAX( 1, M ) ) THENINFO = -11END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRSYL', -INFO )RETURNEND IF** Quick return if possible*SCALE = ONEIF( M.EQ.0 .OR. N.EQ.0 )$ RETURN** Set constants to control overflow*EPS = DLAMCH( 'P' )SMLNUM = DLAMCH( 'S' )BIGNUM = ONE / SMLNUMCALL DLABAD( SMLNUM, BIGNUM )SMLNUM = SMLNUM*DBLE( M*N ) / EPSBIGNUM = ONE / SMLNUM*SMIN = MAX( SMLNUM, EPS*DLANGE( 'M', M, M, A, LDA, DUM ),$ EPS*DLANGE( 'M', N, N, B, LDB, DUM ) )*SGN = ISGN*IF( NOTRNA .AND. NOTRNB ) THEN** Solve A*X + ISGN*X*B = scale*C.** The (K,L)th block of X is determined starting from* bottom-left corner column by column by** A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)** Where* M L-1* R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(J,L)].* I=K+1 J=1** Start column loop (index = L)* L1 (L2) : column index of the first (first) row of X(K,L).*LNEXT = 1DO 60 L = 1, NIF( L.LT.LNEXT )$ GO TO 60IF( L.EQ.N ) THENL1 = LL2 = LELSEIF( B( L+1, L ).NE.ZERO ) THENL1 = LL2 = L + 1LNEXT = L + 2ELSEL1 = LL2 = LLNEXT = L + 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L).*KNEXT = MDO 50 K = M, 1, -1IF( K.GT.KNEXT )$ GO TO 50IF( K.EQ.1 ) THENK1 = KK2 = KELSEIF( A( K, K-1 ).NE.ZERO ) THENK1 = K - 1K2 = KKNEXT = K - 2ELSEK1 = KK2 = KKNEXT = K - 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 10 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )10 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 20 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )20 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 30 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )30 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .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*IF( SCALOC.NE.ONE ) THENDO 40 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )40 CONTINUESCALE = SCALE*SCALOCEND IFC( 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*50 CONTINUE*60 CONTINUE*ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN** Solve A**T *X + ISGN*X*B = scale*C.** The (K,L)th block of X is determined starting from* upper-left corner column by column by** A(K,K)**T*X(K,L) + ISGN*X(K,L)*B(L,L) = C(K,L) - R(K,L)** Where* K-1 T L-1* R(K,L) = SUM [A(I,K)**T*X(I,L)] +ISGN*SUM [X(K,J)*B(J,L)]* I=1 J=1** Start column loop (index = L)* L1 (L2): column index of the first (last) row of X(K,L)*LNEXT = 1DO 120 L = 1, NIF( L.LT.LNEXT )$ GO TO 120IF( L.EQ.N ) THENL1 = LL2 = LELSEIF( B( L+1, L ).NE.ZERO ) THENL1 = LL2 = L + 1LNEXT = L + 2ELSEL1 = LL2 = LLNEXT = L + 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L)*KNEXT = 1DO 110 K = 1, MIF( K.LT.KNEXT )$ GO TO 110IF( K.EQ.M ) THENK1 = KK2 = KELSEIF( A( K+1, K ).NE.ZERO ) THENK1 = KK2 = K + 1KNEXT = K + 2ELSEK1 = KK2 = KKNEXT = K + 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 70 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )70 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 80 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )80 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 90 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )90 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ), 1 )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L2 ), 1 )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ), 1 )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L2 ), 1 )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .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*IF( SCALOC.NE.ONE ) THENDO 100 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )100 CONTINUESCALE = SCALE*SCALOCEND IFC( 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*110 CONTINUE120 CONTINUE*ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN** Solve A**T*X + ISGN*X*B**T = scale*C.** The (K,L)th block of X is determined starting from* top-right corner column by column by** A(K,K)**T*X(K,L) + ISGN*X(K,L)*B(L,L)**T = C(K,L) - R(K,L)** Where* K-1 N* R(K,L) = SUM [A(I,K)**T*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)**T].* I=1 J=L+1** Start column loop (index = L)* L1 (L2): column index of the first (last) row of X(K,L)*LNEXT = NDO 180 L = N, 1, -1IF( L.GT.LNEXT )$ GO TO 180IF( L.EQ.1 ) THENL1 = LL2 = LELSEIF( B( L, L-1 ).NE.ZERO ) THENL1 = L - 1L2 = LLNEXT = L - 2ELSEL1 = LL2 = LLNEXT = L - 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L)*KNEXT = 1DO 170 K = 1, MIF( K.LT.KNEXT )$ GO TO 170IF( K.EQ.M ) THENK1 = KK2 = KELSEIF( A( K+1, K ).NE.ZERO ) THENK1 = KK2 = K + 1KNEXT = K + 2ELSEK1 = KK2 = KKNEXT = K + 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,$ B( L1, MIN( L1+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 130 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )130 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 140 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )140 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 150 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )150 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .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*IF( SCALOC.NE.ONE ) THENDO 160 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )160 CONTINUESCALE = SCALE*SCALOCEND IFC( 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*170 CONTINUE180 CONTINUE*ELSE IF( NOTRNA .AND. .NOT.NOTRNB ) THEN** Solve A*X + ISGN*X*B**T = scale*C.** The (K,L)th block of X is determined starting from* bottom-right corner column by column by** A(K,K)*X(K,L) + ISGN*X(K,L)*B(L,L)**T = C(K,L) - R(K,L)** Where* M N* R(K,L) = SUM [A(K,I)*X(I,L)] + ISGN*SUM [X(K,J)*B(L,J)**T].* I=K+1 J=L+1** Start column loop (index = L)* L1 (L2): column index of the first (last) row of X(K,L)*LNEXT = NDO 240 L = N, 1, -1IF( L.GT.LNEXT )$ GO TO 240IF( L.EQ.1 ) THENL1 = LL2 = LELSEIF( B( L, L-1 ).NE.ZERO ) THENL1 = L - 1L2 = LLNEXT = L - 2ELSEL1 = LL2 = LLNEXT = L - 1END IFEND IF** Start row loop (index = K)* K1 (K2): row index of the first (last) row of X(K,L)*KNEXT = MDO 230 K = M, 1, -1IF( K.GT.KNEXT )$ GO TO 230IF( K.EQ.1 ) THENK1 = KK2 = KELSEIF( A( K, K-1 ).NE.ZERO ) THENK1 = K - 1K2 = KKNEXT = K - 2ELSEK1 = KK2 = KKNEXT = K - 1END IFEND IF*IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THENSUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( N-L1, C( K1, MIN( L1+1, N ) ), LDC,$ B( L1, MIN( L1+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )SCALOC = ONE*A11 = A( K1, K1 ) + SGN*B( L1, L1 )DA11 = ABS( A11 )IF( DA11.LE.SMIN ) THENA11 = SMINDA11 = SMININFO = 1END IFDB = ABS( VEC( 1, 1 ) )IF( DA11.LT.ONE .AND. DB.GT.ONE ) THENIF( DB.GT.BIGNUM*DA11 )$ SCALOC = ONE / DBEND IFX( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11*IF( SCALOC.NE.ONE ) THENDO 190 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )190 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )*ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),$ LDA, ONE, ONE, VEC, 2, -SGN*B( L1, L1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 200 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )200 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K2, L1 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = SGN*( C( K1, L1 )-( SUML+SGN*SUMR ) )*SUML = DDOT( M-K1, A( K1, MIN( K1+1, M ) ), LDA,$ C( MIN( K1+1, M ), L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = SGN*( C( K1, L2 )-( SUML+SGN*SUMR ) )*CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, B( L1, L1 ),$ LDB, ONE, ONE, VEC, 2, -SGN*A( K1, K1 ),$ ZERO, X, 2, SCALOC, XNORM, IERR )IF( IERR.NE.0 )$ INFO = 1*IF( SCALOC.NE.ONE ) THENDO 210 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )210 CONTINUESCALE = SCALE*SCALOCEND IFC( K1, L1 ) = X( 1, 1 )C( K1, L2 ) = X( 2, 1 )*ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 1, 1 ) = C( K1, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K1, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( N-L2, C( K1, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 1, 2 ) = C( K1, L2 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L1 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L1, MIN( L2+1, N ) ), LDB )VEC( 2, 1 ) = C( K2, L1 ) - ( SUML+SGN*SUMR )*SUML = DDOT( M-K2, A( K2, MIN( K2+1, M ) ), LDA,$ C( MIN( K2+1, M ), L2 ), 1 )SUMR = DDOT( N-L2, C( K2, MIN( L2+1, N ) ), LDC,$ B( L2, MIN( L2+1, N ) ), LDB )VEC( 2, 2 ) = C( K2, L2 ) - ( SUML+SGN*SUMR )*CALL DLASY2( .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*IF( SCALOC.NE.ONE ) THENDO 220 J = 1, NCALL DSCAL( M, SCALOC, C( 1, J ), 1 )220 CONTINUESCALE = SCALE*SCALOCEND IFC( 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*230 CONTINUE240 CONTINUE*END IF*RETURN** End of DTRSYL*END*> \brief \b DTRTI2 computes the inverse of a triangular matrix (unblocked algorithm).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRTI2 + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrti2.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrti2.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrti2.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRTI2 computes the inverse of a real upper or lower triangular*> matrix.*>*> This is the Level 2 BLAS version of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> Specifies whether the matrix A is upper or lower triangular.*> = 'U': Upper triangular*> = 'L': Lower triangular*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> Specifies whether or not the matrix A is unit triangular.*> = 'N': Non-unit triangular*> = 'U': Unit triangular*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the triangular matrix A. If UPLO = 'U', the*> leading n by n upper triangular part of the array A contains*> the upper triangular matrix, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading n by n lower triangular part of the array A contains*> the lower triangular matrix, and the strictly upper*> triangular part of A is not referenced. If DIAG = 'U', the*> diagonal elements of A are also not referenced and are*> assumed to be 1.*>*> On exit, the (triangular) inverse of the original matrix, in*> the same storage format.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -k, the k-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTRTI2( UPLO, DIAG, N, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONEPARAMETER ( ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, UPPERINTEGER JDOUBLE PRECISION AJJ* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DSCAL, DTRMV, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOUNIT = LSAME( DIAG, 'N' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRTI2', -INFO )RETURNEND IF*IF( UPPER ) THEN** Compute inverse of upper triangular matrix.*DO 10 J = 1, NIF( NOUNIT ) THENA( J, J ) = ONE / A( J, J )AJJ = -A( J, J )ELSEAJJ = -ONEEND IF** Compute elements 1:j-1 of j-th column.*CALL DTRMV( 'Upper', 'No transpose', DIAG, J-1, A, LDA,$ A( 1, J ), 1 )CALL DSCAL( J-1, AJJ, A( 1, J ), 1 )10 CONTINUEELSE** Compute inverse of lower triangular matrix.*DO 20 J = N, 1, -1IF( NOUNIT ) THENA( J, J ) = ONE / A( J, J )AJJ = -A( J, J )ELSEAJJ = -ONEEND IFIF( J.LT.N ) THEN** Compute elements j+1:n of j-th column.*CALL DTRMV( 'Lower', 'No transpose', DIAG, N-J,$ A( J+1, J+1 ), LDA, A( J+1, J ), 1 )CALL DSCAL( N-J, AJJ, A( J+1, J ), 1 )END IF20 CONTINUEEND IF*RETURN** End of DTRTI2*END*> \brief \b DTRTRI** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRTRI + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrtri.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrtri.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrtri.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRTRI( UPLO, DIAG, N, A, LDA, INFO )** .. Scalar Arguments ..* CHARACTER DIAG, UPLO* INTEGER INFO, LDA, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRTRI computes the inverse of a real upper or lower triangular*> matrix A.*>*> This is the Level 3 BLAS version of the algorithm.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the triangular matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of the array A contains*> the upper triangular matrix, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of the array A contains*> the lower triangular matrix, and the strictly upper*> triangular part of A is not referenced. If DIAG = 'U', the*> diagonal elements of A are also not referenced and are*> assumed to be 1.*> On exit, the (triangular) inverse of the original matrix, in*> the same storage format.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, A(i,i) is exactly zero. The triangular*> matrix is singular and its inverse can not be computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTRTRI( UPLO, DIAG, N, A, LDA, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, UPLOINTEGER INFO, LDA, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT, UPPERINTEGER J, JB, NB, NN* ..* .. External Functions ..LOGICAL LSAMEINTEGER ILAENVEXTERNAL LSAME, ILAENV* ..* .. External Subroutines ..EXTERNAL DTRMM, DTRSM, DTRTI2, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0UPPER = LSAME( UPLO, 'U' )NOUNIT = LSAME( DIAG, 'N' )IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRTRI', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Check for singularity if non-unit.*IF( NOUNIT ) THENDO 10 INFO = 1, NIF( A( INFO, INFO ).EQ.ZERO )$ RETURN10 CONTINUEINFO = 0END IF** Determine the block size for this environment.*NB = ILAENV( 1, 'DTRTRI', UPLO // DIAG, N, -1, -1, -1 )IF( NB.LE.1 .OR. NB.GE.N ) THEN** Use unblocked code*CALL DTRTI2( UPLO, DIAG, N, A, LDA, INFO )ELSE** Use blocked code*IF( UPPER ) THEN** Compute inverse of upper triangular matrix*DO 20 J = 1, N, NBJB = MIN( NB, N-J+1 )** Compute rows 1:j-1 of current block column*CALL DTRMM( 'Left', 'Upper', 'No transpose', DIAG, J-1,$ JB, ONE, A, LDA, A( 1, J ), LDA )CALL DTRSM( 'Right', 'Upper', 'No transpose', DIAG, J-1,$ JB, -ONE, A( J, J ), LDA, A( 1, J ), LDA )** Compute inverse of current diagonal block*CALL DTRTI2( 'Upper', DIAG, JB, A( J, J ), LDA, INFO )20 CONTINUEELSE** Compute inverse of lower triangular matrix*NN = ( ( N-1 ) / NB )*NB + 1DO 30 J = NN, 1, -NBJB = MIN( NB, N-J+1 )IF( J+JB.LE.N ) THEN** Compute rows j+jb:n of current block column*CALL DTRMM( 'Left', 'Lower', 'No transpose', DIAG,$ N-J-JB+1, JB, ONE, A( J+JB, J+JB ), LDA,$ A( J+JB, J ), LDA )CALL DTRSM( 'Right', 'Lower', 'No transpose', DIAG,$ N-J-JB+1, JB, -ONE, A( J, J ), LDA,$ A( J+JB, J ), LDA )END IF** Compute inverse of current diagonal block*CALL DTRTI2( 'Lower', DIAG, JB, A( J, J ), LDA, INFO )30 CONTINUEEND IFEND IF*RETURN** End of DTRTRI*END*> \brief \b DTRTRS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRTRS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrtrs.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrtrs.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrtrs.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRTRS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB,* INFO )** .. Scalar Arguments ..* CHARACTER DIAG, TRANS, UPLO* INTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRTRS solves a triangular system of the form*>*> A * X = B or A**T * X = B,*>*> where A is a triangular matrix of order N, and B is an N-by-NRHS*> matrix. A check is made to verify that A is nonsingular.*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular;*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] TRANS*> \verbatim*> TRANS is CHARACTER*1*> Specifies the form of the system of equations:*> = 'N': A * X = B (No transpose)*> = 'T': A**T * X = B (Transpose)*> = 'C': A**H * X = B (Conjugate transpose = Transpose)*> \endverbatim*>*> \param[in] DIAG*> \verbatim*> DIAG is CHARACTER*1*> = 'N': A is non-unit triangular;*> = 'U': A is unit triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] NRHS*> \verbatim*> NRHS is INTEGER*> The number of right hand sides, i.e., the number of columns*> of the matrix B. NRHS >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The triangular matrix A. If UPLO = 'U', the leading N-by-N*> upper triangular part of the array A contains the upper*> triangular matrix, and the strictly lower triangular part of*> A is not referenced. If UPLO = 'L', the leading N-by-N lower*> triangular part of the array A contains the lower triangular*> matrix, and the strictly upper triangular part of A is not*> referenced. If DIAG = 'U', the diagonal elements of A are*> also not referenced and are assumed to be 1.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[in,out] B*> \verbatim*> B is DOUBLE PRECISION array, dimension (LDB,NRHS)*> On entry, the right hand side matrix B.*> On exit, if INFO = 0, the solution matrix X.*> \endverbatim*>*> \param[in] LDB*> \verbatim*> LDB is INTEGER*> The leading dimension of the array B. LDB >= max(1,N).*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> > 0: if INFO = i, the i-th diagonal element of A is zero,*> indicating that the matrix is singular and the solutions*> X have not been computed.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTRTRS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB,$ INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER DIAG, TRANS, UPLOINTEGER INFO, LDA, LDB, N, NRHS* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), B( LDB, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZERO, ONEPARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )* ..* .. Local Scalars ..LOGICAL NOUNIT* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL DTRSM, XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NOUNIT = LSAME( DIAG, 'N' )IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LSAME( UPLO, 'L' ) ) THENINFO = -1ELSE IF( .NOT.LSAME( TRANS, 'N' ) .AND. .NOT.$ LSAME( TRANS, 'T' ) .AND. .NOT.LSAME( TRANS, 'C' ) ) THENINFO = -2ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THENINFO = -3ELSE IF( N.LT.0 ) THENINFO = -4ELSE IF( NRHS.LT.0 ) THENINFO = -5ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -7ELSE IF( LDB.LT.MAX( 1, N ) ) THENINFO = -9END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRTRS', -INFO )RETURNEND IF** Quick return if possible*IF( N.EQ.0 )$ RETURN** Check for singularity.*IF( NOUNIT ) THENDO 10 INFO = 1, NIF( A( INFO, INFO ).EQ.ZERO )$ RETURN10 CONTINUEEND IFINFO = 0** Solve A * x = b or A**T * x = b.*CALL DTRSM( 'Left', UPLO, TRANS, DIAG, N, NRHS, ONE, A, LDA, B,$ LDB )*RETURN** End of DTRTRS*END*> \brief \b DTRTTF copies a triangular matrix from the standard full format (TR) to the rectangular full packed format (TF).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRTTF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrttf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrttf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrttf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRTTF( TRANSR, UPLO, N, A, LDA, ARF, INFO )** .. Scalar Arguments ..* CHARACTER TRANSR, UPLO* INTEGER INFO, N, LDA* ..* .. Array Arguments ..* DOUBLE PRECISION A( 0: LDA-1, 0: * ), ARF( 0: * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRTTF copies a triangular matrix A from standard full format (TR)*> to rectangular full packed format (TF) .*> \endverbatim** Arguments:* ==========**> \param[in] TRANSR*> \verbatim*> TRANSR is CHARACTER*1*> = 'N': ARF in Normal form is wanted;*> = 'T': ARF in Transpose form is wanted.*> \endverbatim*>*> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': Upper triangle of A is stored;*> = 'L': Lower triangle of A is stored.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrix A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N).*> On entry, the triangular matrix A. If UPLO = 'U', the*> leading N-by-N upper triangular part of the array A contains*> the upper triangular matrix, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of the array A contains*> the lower triangular matrix, and the strictly upper*> triangular part of A is not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the matrix A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] ARF*> \verbatim*> ARF is DOUBLE PRECISION array, dimension (NT).*> NT=N*(N+1)/2. On exit, the triangular matrix A in RFP format.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> We first consider Rectangular Full Packed (RFP) Format when N is*> even. We give an example where N = 6.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 05 00*> 11 12 13 14 15 10 11*> 22 23 24 25 20 21 22*> 33 34 35 30 31 32 33*> 44 45 40 41 42 43 44*> 55 50 51 52 53 54 55*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last*> three columns of AP upper. The lower triangle A(4:6,0:2) consists of*> the transpose of the first three columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:2,0:2) consists of*> the transpose of the last three columns of AP lower.*> This covers the case N even and TRANSR = 'N'.*>*> RFP A RFP A*>*> 03 04 05 33 43 53*> 13 14 15 00 44 54*> 23 24 25 10 11 55*> 33 34 35 20 21 22*> 00 44 45 30 31 32*> 01 11 55 40 41 42*> 02 12 22 50 51 52*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*>*> RFP A RFP A*>*> 03 13 23 33 00 01 02 33 00 10 20 30 40 50*> 04 14 24 34 44 11 12 43 44 11 21 31 41 51*> 05 15 25 35 45 55 22 53 54 55 22 32 42 52*>*>*> We then consider Rectangular Full Packed (RFP) Format when N is*> odd. We give an example where N = 5.*>*> AP is Upper AP is Lower*>*> 00 01 02 03 04 00*> 11 12 13 14 10 11*> 22 23 24 20 21 22*> 33 34 30 31 32 33*> 44 40 41 42 43 44*>*>*> Let TRANSR = 'N'. RFP holds AP as follows:*> For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last*> three columns of AP upper. The lower triangle A(3:4,0:1) consists of*> the transpose of the first two columns of AP upper.*> For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first*> three columns of AP lower. The upper triangle A(0:1,1:2) consists of*> the transpose of the last two columns of AP lower.*> This covers the case N odd and TRANSR = 'N'.*>*> RFP A RFP A*>*> 02 03 04 00 33 43*> 12 13 14 10 11 44*> 22 23 24 20 21 22*> 00 33 34 30 31 32*> 01 11 44 40 41 42*>*> Now let TRANSR = 'T'. RFP A in both UPLO cases is just the*> transpose of RFP A above. One therefore gets:*>*> RFP A RFP A*>*> 02 12 22 00 01 00 10 20 30 40 50*> 03 13 23 33 11 33 11 21 31 41 51*> 04 14 24 34 44 43 44 22 32 42 52*> \endverbatim** =====================================================================SUBROUTINE DTRTTF( TRANSR, UPLO, N, A, LDA, ARF, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANSR, UPLOINTEGER INFO, N, LDA* ..* .. Array Arguments ..DOUBLE PRECISION A( 0: LDA-1, 0: * ), ARF( 0: * )* ..** =====================================================================** ..* .. Local Scalars ..LOGICAL LOWER, NISODD, NORMALTRANSRINTEGER I, IJ, J, K, L, N1, N2, NT, NX2, NP1X2* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Intrinsic Functions ..INTRINSIC MAX, MOD* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0NORMALTRANSR = LSAME( TRANSR, 'N' )LOWER = LSAME( UPLO, 'L' )IF( .NOT.NORMALTRANSR .AND. .NOT.LSAME( TRANSR, 'T' ) ) THENINFO = -1ELSE IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -2ELSE IF( N.LT.0 ) THENINFO = -3ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -5END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRTTF', -INFO )RETURNEND IF** Quick return if possible*IF( N.LE.1 ) THENIF( N.EQ.1 ) THENARF( 0 ) = A( 0, 0 )END IFRETURNEND IF** Size of array ARF(0:nt-1)*NT = N*( N+1 ) / 2** Set N1 and N2 depending on LOWER: for N even N1=N2=K*IF( LOWER ) THENN2 = N / 2N1 = N - N2ELSEN1 = N / 2N2 = N - N1END IF** If N is odd, set NISODD = .TRUE., LDA=N+1 and A is (N+1)--by--K2.* If N is even, set K = N/2 and NISODD = .FALSE., LDA=N and A is* N--by--(N+1)/2.*IF( MOD( N, 2 ).EQ.0 ) THENK = N / 2NISODD = .FALSE.IF( .NOT.LOWER )$ NP1X2 = N + N + 2ELSENISODD = .TRUE.IF( .NOT.LOWER )$ NX2 = N + NEND IF*IF( NISODD ) THEN** N is odd*IF( NORMALTRANSR ) THEN** N is odd and TRANSR = 'N'*IF( LOWER ) THEN** N is odd, TRANSR = 'N', and UPLO = 'L'*IJ = 0DO J = 0, N2DO I = N1, N2 + JARF( IJ ) = A( N2+J, I )IJ = IJ + 1END DODO I = J, N - 1ARF( IJ ) = A( I, J )IJ = IJ + 1END DOEND DO*ELSE** N is odd, TRANSR = 'N', and UPLO = 'U'*IJ = NT - NDO J = N - 1, N1, -1DO I = 0, JARF( IJ ) = A( I, J )IJ = IJ + 1END DODO L = J - N1, N1 - 1ARF( IJ ) = A( J-N1, L )IJ = IJ + 1END DOIJ = IJ - NX2END DO*END IF*ELSE** N is odd and TRANSR = 'T'*IF( LOWER ) THEN** N is odd, TRANSR = 'T', and UPLO = 'L'*IJ = 0DO J = 0, N2 - 1DO I = 0, JARF( IJ ) = A( J, I )IJ = IJ + 1END DODO I = N1 + J, N - 1ARF( IJ ) = A( I, N1+J )IJ = IJ + 1END DOEND DODO J = N2, N - 1DO I = 0, N1 - 1ARF( IJ ) = A( J, I )IJ = IJ + 1END DOEND DO*ELSE** N is odd, TRANSR = 'T', and UPLO = 'U'*IJ = 0DO J = 0, N1DO I = N1, N - 1ARF( IJ ) = A( J, I )IJ = IJ + 1END DOEND DODO J = 0, N1 - 1DO I = 0, JARF( IJ ) = A( I, J )IJ = IJ + 1END DODO L = N2 + J, N - 1ARF( IJ ) = A( N2+J, L )IJ = IJ + 1END DOEND DO*END IF*END IF*ELSE** N is even*IF( NORMALTRANSR ) THEN** N is even and TRANSR = 'N'*IF( LOWER ) THEN** N is even, TRANSR = 'N', and UPLO = 'L'*IJ = 0DO J = 0, K - 1DO I = K, K + JARF( IJ ) = A( K+J, I )IJ = IJ + 1END DODO I = J, N - 1ARF( IJ ) = A( I, J )IJ = IJ + 1END DOEND DO*ELSE** N is even, TRANSR = 'N', and UPLO = 'U'*IJ = NT - N - 1DO J = N - 1, K, -1DO I = 0, JARF( IJ ) = A( I, J )IJ = IJ + 1END DODO L = J - K, K - 1ARF( IJ ) = A( J-K, L )IJ = IJ + 1END DOIJ = IJ - NP1X2END DO*END IF*ELSE** N is even and TRANSR = 'T'*IF( LOWER ) THEN** N is even, TRANSR = 'T', and UPLO = 'L'*IJ = 0J = KDO I = K, N - 1ARF( IJ ) = A( I, J )IJ = IJ + 1END DODO J = 0, K - 2DO I = 0, JARF( IJ ) = A( J, I )IJ = IJ + 1END DODO I = K + 1 + J, N - 1ARF( IJ ) = A( I, K+1+J )IJ = IJ + 1END DOEND DODO J = K - 1, N - 1DO I = 0, K - 1ARF( IJ ) = A( J, I )IJ = IJ + 1END DOEND DO*ELSE** N is even, TRANSR = 'T', and UPLO = 'U'*IJ = 0DO J = 0, KDO I = K, N - 1ARF( IJ ) = A( J, I )IJ = IJ + 1END DOEND DODO J = 0, K - 2DO I = 0, JARF( IJ ) = A( I, J )IJ = IJ + 1END DODO L = K + 1 + J, N - 1ARF( IJ ) = A( K+1+J, L )IJ = IJ + 1END DOEND DO* Note that here, on exit of the loop, J = K-1DO I = 0, JARF( IJ ) = A( I, J )IJ = IJ + 1END DO*END IF*END IF*END IF*RETURN** End of DTRTTF*END*> \brief \b DTRTTP copies a triangular matrix from the standard full format (TR) to the standard packed format (TP).** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTRTTP + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtrttp.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtrttp.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtrttp.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTRTTP( UPLO, N, A, LDA, AP, INFO )** .. Scalar Arguments ..* CHARACTER UPLO* INTEGER INFO, N, LDA* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), AP( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTRTTP copies a triangular matrix A from full format (TR) to standard*> packed format (TP).*> \endverbatim** Arguments:* ==========**> \param[in] UPLO*> \verbatim*> UPLO is CHARACTER*1*> = 'U': A is upper triangular.*> = 'L': A is lower triangular.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The order of the matrices AP and A. N >= 0.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On exit, the triangular matrix A. If UPLO = 'U', the leading*> N-by-N upper triangular part of A contains the upper*> triangular part of the matrix A, and the strictly lower*> triangular part of A is not referenced. If UPLO = 'L', the*> leading N-by-N lower triangular part of A contains the lower*> triangular part of the matrix A, and the strictly upper*> triangular part of A is not referenced.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,N).*> \endverbatim*>*> \param[out] AP*> \verbatim*> AP is DOUBLE PRECISION array, dimension (N*(N+1)/2)*> On exit, the upper or lower triangular matrix A, packed*> columnwise in a linear array. The j-th column of A is stored*> in the array AP as follows:*> if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;*> if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup doubleOTHERcomputational** =====================================================================SUBROUTINE DTRTTP( UPLO, N, A, LDA, AP, INFO )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..CHARACTER UPLOINTEGER INFO, N, LDA* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), AP( * )* ..** =====================================================================** .. Parameters ..* ..* .. Local Scalars ..LOGICAL LOWERINTEGER I, J, K* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. External Subroutines ..EXTERNAL XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0LOWER = LSAME( UPLO, 'L' )IF( .NOT.LOWER .AND. .NOT.LSAME( UPLO, 'U' ) ) THENINFO = -1ELSE IF( N.LT.0 ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, N ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTRTTP', -INFO )RETURNEND IF*IF( LOWER ) THENK = 0DO J = 1, NDO I = J, NK = K + 1AP( K ) = A( I, J )END DOEND DOELSEK = 0DO J = 1, NDO I = 1, JK = K + 1AP( K ) = A( I, J )END DOEND DOEND IF**RETURN** End of DTRTTP*END*> \brief \b DTZRQF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTZRQF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtzrqf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtzrqf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtzrqf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTZRQF( M, N, A, LDA, TAU, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> This routine is deprecated and has been replaced by routine DTZRZF.*>*> DTZRQF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A*> to upper triangular form by means of orthogonal transformations.*>*> The upper trapezoidal matrix A is factored as*>*> A = ( R 0 ) * Z,*>*> where Z is an N-by-N orthogonal matrix and R is an M-by-M upper*> triangular matrix.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= M.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the leading M-by-N upper trapezoidal part of the*> array A must contain the matrix to be factorized.*> On exit, the leading M-by-M upper triangular part of A*> contains the upper triangular matrix R, and elements M+1 to*> N of the first M rows of A, with the array TAU, represent the*> orthogonal matrix Z as a product of M elementary reflectors.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (M)*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup doubleOTHERcomputational**> \par Further Details:* =====================*>*> \verbatim*>*> The factorization is obtained by Householder's method. The kth*> transformation matrix, Z( k ), which is used to introduce zeros into*> the ( m - k + 1 )th row of A, is given in the form*>*> Z( k ) = ( I 0 ),*> ( 0 T( k ) )*>*> where*>*> T( k ) = I - tau*u( k )*u( k )**T, u( k ) = ( 1 ),*> ( 0 )*> ( z( k ) )*>*> tau is a scalar and z( k ) is an ( n - m ) element vector.*> tau and z( k ) are chosen to annihilate the elements of the kth row*> of X.*>*> The scalar tau is returned in the kth element of TAU and the vector*> u( k ) in the kth row of A, such that the elements of z( k ) are*> in a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in*> the upper triangular part of A.*>*> Z is given by*>*> Z = Z( 1 ) * Z( 2 ) * ... * Z( m ).*> \endverbatim*>* =====================================================================SUBROUTINE DTZRQF( M, N, A, LDA, TAU, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER INFO, LDA, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ONE, ZEROPARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, K, M1* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Subroutines ..EXTERNAL DAXPY, DCOPY, DGEMV, DGER, DLARFG, XERBLA* ..* .. Executable Statements ..** Test the input parameters.*INFO = 0IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IFIF( INFO.NE.0 ) THENCALL XERBLA( 'DTZRQF', -INFO )RETURNEND IF** Perform the factorization.*IF( M.EQ.0 )$ RETURNIF( M.EQ.N ) THENDO 10 I = 1, NTAU( I ) = ZERO10 CONTINUEELSEM1 = MIN( M+1, N )DO 20 K = M, 1, -1** Use a Householder reflection to zero the kth row of A.* First set up the reflection.*CALL DLARFG( N-M+1, A( K, K ), A( K, M1 ), LDA, TAU( K ) )*IF( ( TAU( K ).NE.ZERO ) .AND. ( K.GT.1 ) ) THEN** We now perform the operation A := A*P( k ).** Use the first ( k - 1 ) elements of TAU to store a( k ),* where a( k ) consists of the first ( k - 1 ) elements of* the kth column of A. Also let B denote the first* ( k - 1 ) rows of the last ( n - m ) columns of A.*CALL DCOPY( K-1, A( 1, K ), 1, TAU, 1 )** Form w = a( k ) + B*z( k ) in TAU.*CALL DGEMV( 'No transpose', K-1, N-M, ONE, A( 1, M1 ),$ LDA, A( K, M1 ), LDA, ONE, TAU, 1 )** Now form a( k ) := a( k ) - tau*w* and B := B - tau*w*z( k )**T.*CALL DAXPY( K-1, -TAU( K ), TAU, 1, A( 1, K ), 1 )CALL DGER( K-1, N-M, -TAU( K ), TAU, 1, A( K, M1 ), LDA,$ A( 1, M1 ), LDA )END IF20 CONTINUEEND IF*RETURN** End of DTZRQF*END*> \brief \b DTZRZF** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download DTZRZF + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtzrzf.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtzrzf.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtzrzf.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** SUBROUTINE DTZRZF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** .. Scalar Arguments ..* INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> DTZRZF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A*> to upper triangular form by means of orthogonal transformations.*>*> The upper trapezoidal matrix A is factored as*>*> A = ( R 0 ) * Z,*>*> where Z is an N-by-N orthogonal matrix and R is an M-by-M upper*> triangular matrix.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A. M >= 0.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A. N >= M.*> \endverbatim*>*> \param[in,out] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> On entry, the leading M-by-N upper trapezoidal part of the*> array A must contain the matrix to be factorized.*> On exit, the leading M-by-M upper triangular part of A*> contains the upper triangular matrix R, and elements M+1 to*> N of the first M rows of A, with the array TAU, represent the*> orthogonal matrix Z as a product of M elementary reflectors.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim*>*> \param[out] TAU*> \verbatim*> TAU is DOUBLE PRECISION array, dimension (M)*> The scalar factors of the elementary reflectors.*> \endverbatim*>*> \param[out] WORK*> \verbatim*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The dimension of the array WORK. LWORK >= max(1,M).*> For optimum performance LWORK >= M*NB, where NB is*> the optimal blocksize.*>*> If LWORK = -1, then a workspace query is assumed; the routine*> only calculates the optimal size of the WORK array, returns*> this value as the first entry of the WORK array, and no error*> message related to LWORK is issued by XERBLA.*> \endverbatim*>*> \param[out] INFO*> \verbatim*> INFO is INTEGER*> = 0: successful exit*> < 0: if INFO = -i, the i-th argument had an illegal value*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date April 2012**> \ingroup doubleOTHERcomputational**> \par Contributors:* ==================*>*> A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA**> \par Further Details:* =====================*>*> \verbatim*>*> The N-by-N matrix Z can be computed by*>*> Z = Z(1)*Z(2)* ... *Z(M)*>*> where each N-by-N Z(k) is given by*>*> Z(k) = I - tau(k)*v(k)*v(k)**T*>*> with v(k) is the kth row vector of the M-by-N matrix*>*> V = ( I A(:,M+1:N) )*>*> I is the M-by-M identity matrix, A(:,M+1:N)*> is the output stored in A on exit from DTZRZF,*> and tau(k) is the kth element of the array TAU.*>*> \endverbatim*>* =====================================================================SUBROUTINE DTZRZF( M, N, A, LDA, TAU, WORK, LWORK, INFO )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* April 2012** .. Scalar Arguments ..INTEGER INFO, LDA, LWORK, M, N* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * ), TAU( * ), WORK( * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..LOGICAL LQUERYINTEGER I, IB, IWS, KI, KK, LDWORK, LWKMIN, LWKOPT,$ M1, MU, NB, NBMIN, NX* ..* .. External Subroutines ..EXTERNAL XERBLA, DLARZB, DLARZT, DLATRZ* ..* .. Intrinsic Functions ..INTRINSIC MAX, MIN* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Test the input arguments*INFO = 0LQUERY = ( LWORK.EQ.-1 )IF( M.LT.0 ) THENINFO = -1ELSE IF( N.LT.M ) THENINFO = -2ELSE IF( LDA.LT.MAX( 1, M ) ) THENINFO = -4END IF*IF( INFO.EQ.0 ) THENIF( M.EQ.0 .OR. M.EQ.N ) THENLWKOPT = 1LWKMIN = 1ELSE** Determine the block size.*NB = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )LWKOPT = M*NBLWKMIN = MAX( 1, M )END IFWORK( 1 ) = LWKOPT*IF( LWORK.LT.LWKMIN .AND. .NOT.LQUERY ) THENINFO = -7END IFEND IF*IF( INFO.NE.0 ) THENCALL XERBLA( 'DTZRZF', -INFO )RETURNELSE IF( LQUERY ) THENRETURNEND IF** Quick return if possible*IF( M.EQ.0 ) THENRETURNELSE IF( M.EQ.N ) THENDO 10 I = 1, NTAU( I ) = ZERO10 CONTINUERETURNEND IF*NBMIN = 2NX = 1IWS = MIF( NB.GT.1 .AND. NB.LT.M ) THEN** Determine when to cross over from blocked to unblocked code.*NX = MAX( 0, ILAENV( 3, 'DGERQF', ' ', M, N, -1, -1 ) )IF( NX.LT.M ) THEN** Determine if workspace is large enough for blocked code.*LDWORK = MIWS = LDWORK*NBIF( LWORK.LT.IWS ) THEN** Not enough workspace to use optimal NB: reduce NB and* determine the minimum value of NB.*NB = LWORK / LDWORKNBMIN = MAX( 2, ILAENV( 2, 'DGERQF', ' ', M, N, -1,$ -1 ) )END IFEND IFEND IF*IF( NB.GE.NBMIN .AND. NB.LT.M .AND. NX.LT.M ) THEN** Use blocked code initially.* The last kk rows are handled by the block method.*M1 = MIN( M+1, N )KI = ( ( M-NX-1 ) / NB )*NBKK = MIN( M, KI+NB )*DO 20 I = M - KK + KI + 1, M - KK + 1, -NBIB = MIN( M-I+1, NB )** Compute the TZ factorization of the current block* A(i:i+ib-1,i:n)*CALL DLATRZ( IB, N-I+1, N-M, A( I, I ), LDA, TAU( I ),$ WORK )IF( I.GT.1 ) THEN** Form the triangular factor of the block reflector* H = H(i+ib-1) . . . H(i+1) H(i)*CALL DLARZT( 'Backward', 'Rowwise', N-M, IB, A( I, M1 ),$ LDA, TAU( I ), WORK, LDWORK )** Apply H to A(1:i-1,i:n) from the right*CALL DLARZB( 'Right', 'No transpose', 'Backward',$ 'Rowwise', I-1, N-I+1, IB, N-M, A( I, M1 ),$ LDA, WORK, LDWORK, A( 1, I ), LDA,$ WORK( IB+1 ), LDWORK )END IF20 CONTINUEMU = I + NB - 1ELSEMU = MEND IF** Use unblocked code to factor the last or only block*IF( MU.GT.0 )$ CALL DLATRZ( MU, N, N-M, A, LDA, TAU, WORK )*WORK( 1 ) = LWKOPT*RETURN** End of DTZRZF*END*> \brief \b IEEECK** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download IEEECK + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ieeeck.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ieeeck.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ieeeck.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE )** .. Scalar Arguments ..* INTEGER ISPEC* REAL ONE, ZERO* ..***> \par Purpose:* =============*>*> \verbatim*>*> IEEECK is called from the ILAENV to verify that Infinity and*> possibly NaN arithmetic is safe (i.e. will not trap).*> \endverbatim** Arguments:* ==========**> \param[in] ISPEC*> \verbatim*> ISPEC is INTEGER*> Specifies whether to test just for inifinity arithmetic*> or whether to test for infinity and NaN arithmetic.*> = 0: Verify infinity arithmetic only.*> = 1: Verify infinity and NaN arithmetic.*> \endverbatim*>*> \param[in] ZERO*> \verbatim*> ZERO is REAL*> Must contain the value 0.0*> This is passed to prevent the compiler from optimizing*> away this code.*> \endverbatim*>*> \param[in] ONE*> \verbatim*> ONE is REAL*> Must contain the value 1.0*> This is passed to prevent the compiler from optimizing*> away this code.*>*> RETURN VALUE: INTEGER*> = 0: Arithmetic failed to produce the correct answers*> = 1: Arithmetic produced the correct answers*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER ISPECREAL ONE, ZERO* ..** =====================================================================** .. Local Scalars ..REAL NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF,$ NEGZRO, NEWZRO, POSINF* ..* .. Executable Statements ..IEEECK = 1*POSINF = ONE / ZEROIF( POSINF.LE.ONE ) THENIEEECK = 0RETURNEND IF*NEGINF = -ONE / ZEROIF( NEGINF.GE.ZERO ) THENIEEECK = 0RETURNEND IF*NEGZRO = ONE / ( NEGINF+ONE )IF( NEGZRO.NE.ZERO ) THENIEEECK = 0RETURNEND IF*NEGINF = ONE / NEGZROIF( NEGINF.GE.ZERO ) THENIEEECK = 0RETURNEND IF*NEWZRO = NEGZRO + ZEROIF( NEWZRO.NE.ZERO ) THENIEEECK = 0RETURNEND IF*POSINF = ONE / NEWZROIF( POSINF.LE.ONE ) THENIEEECK = 0RETURNEND IF*NEGINF = NEGINF*POSINFIF( NEGINF.GE.ZERO ) THENIEEECK = 0RETURNEND IF*POSINF = POSINF*POSINFIF( POSINF.LE.ONE ) THENIEEECK = 0RETURNEND IF***** Return if we were only asked to check infinity arithmetic*IF( ISPEC.EQ.0 )$ RETURN*NAN1 = POSINF + NEGINF*NAN2 = POSINF / NEGINF*NAN3 = POSINF / POSINF*NAN4 = POSINF*ZERO*NAN5 = NEGINF*NEGZRO*NAN6 = NAN5*ZERO*IF( NAN1.EQ.NAN1 ) THENIEEECK = 0RETURNEND IF*IF( NAN2.EQ.NAN2 ) THENIEEECK = 0RETURNEND IF*IF( NAN3.EQ.NAN3 ) THENIEEECK = 0RETURNEND IF*IF( NAN4.EQ.NAN4 ) THENIEEECK = 0RETURNEND IF*IF( NAN5.EQ.NAN5 ) THENIEEECK = 0RETURNEND IF*IF( NAN6.EQ.NAN6 ) THENIEEECK = 0RETURNEND IF*RETURNEND*> \brief \b ILADLC scans a matrix for its last non-zero column.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download ILADLC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iladlc.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iladlc.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iladlc.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION ILADLC( M, N, A, LDA )** .. Scalar Arguments ..* INTEGER M, N, LDA* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> ILADLC scans A for its last non-zero column.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The m by n matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================INTEGER FUNCTION ILADLC( M, N, A, LDA )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER M, N, LDA* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I* ..* .. Executable Statements ..** Quick test for the common case where one corner is non-zero.IF( N.EQ.0 ) THENILADLC = NELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THENILADLC = NELSE* Now scan each column from the end, returning with the first non-zero.DO ILADLC = N, 1, -1DO I = 1, MIF( A(I, ILADLC).NE.ZERO ) RETURNEND DOEND DOEND IFRETURNEND*> \brief \b ILADLR scans a matrix for its last non-zero row.** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download ILADLR + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iladlr.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iladlr.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iladlr.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION ILADLR( M, N, A, LDA )** .. Scalar Arguments ..* INTEGER M, N, LDA* ..* .. Array Arguments ..* DOUBLE PRECISION A( LDA, * )* ..***> \par Purpose:* =============*>*> \verbatim*>*> ILADLR scans A for its last non-zero row.*> \endverbatim** Arguments:* ==========**> \param[in] M*> \verbatim*> M is INTEGER*> The number of rows of the matrix A.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> The number of columns of the matrix A.*> \endverbatim*>*> \param[in] A*> \verbatim*> A is DOUBLE PRECISION array, dimension (LDA,N)*> The m by n matrix A.*> \endverbatim*>*> \param[in] LDA*> \verbatim*> LDA is INTEGER*> The leading dimension of the array A. LDA >= max(1,M).*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup OTHERauxiliary** =====================================================================INTEGER FUNCTION ILADLR( M, N, A, LDA )** -- LAPACK auxiliary routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..INTEGER M, N, LDA* ..* .. Array Arguments ..DOUBLE PRECISION A( LDA, * )* ..** =====================================================================** .. Parameters ..DOUBLE PRECISION ZEROPARAMETER ( ZERO = 0.0D+0 )* ..* .. Local Scalars ..INTEGER I, J* ..* .. Executable Statements ..** Quick test for the common case where one corner is non-zero.IF( M.EQ.0 ) THENILADLR = MELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THENILADLR = MELSE* Scan up each column tracking the last zero row seen.ILADLR = 0DO J = 1, NI=MDO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))I=I-1ENDDOILADLR = MAX( ILADLR, I )END DOEND IFRETURNEND*> \brief \b ILAENV** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download ILAENV + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaenv.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaenv.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaenv.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 )** .. Scalar Arguments ..* CHARACTER*( * ) NAME, OPTS* INTEGER ISPEC, N1, N2, N3, N4* ..***> \par Purpose:* =============*>*> \verbatim*>*> ILAENV is called from the LAPACK routines to choose problem-dependent*> parameters for the local environment. See ISPEC for a description of*> the parameters.*>*> ILAENV returns an INTEGER*> if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC*> if ILAENV < 0: if ILAENV = -k, the k-th argument had an illegal value.*>*> This version provides a set of parameters which should give good,*> but not optimal, performance on many of the currently available*> computers. Users are encouraged to modify this subroutine to set*> the tuning parameters for their particular machine using the option*> and problem size information in the arguments.*>*> This routine will not function correctly if it is converted to all*> lower case. Converting it to all upper case is allowed.*> \endverbatim** Arguments:* ==========**> \param[in] ISPEC*> \verbatim*> ISPEC is INTEGER*> Specifies the parameter to be returned as the value of*> ILAENV.*> = 1: the optimal blocksize; if this value is 1, an unblocked*> algorithm will give the best performance.*> = 2: the minimum block size for which the block routine*> should be used; if the usable block size is less than*> this value, an unblocked routine should be used.*> = 3: the crossover point (in a block routine, for N less*> than this value, an unblocked routine should be used)*> = 4: the number of shifts, used in the nonsymmetric*> eigenvalue routines (DEPRECATED)*> = 5: the minimum column dimension for blocking to be used;*> rectangular blocks must have dimension at least k by m,*> where k is given by ILAENV(2,...) and m by ILAENV(5,...)*> = 6: the crossover point for the SVD (when reducing an m by n*> matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds*> this value, a QR factorization is used first to reduce*> the matrix to a triangular form.)*> = 7: the number of processors*> = 8: the crossover point for the multishift QR method*> for nonsymmetric eigenvalue problems (DEPRECATED)*> = 9: maximum size of the subproblems at the bottom of the*> computation tree in the divide-and-conquer algorithm*> (used by xGELSD and xGESDD)*> =10: ieee NaN arithmetic can be trusted not to trap*> =11: infinity arithmetic can be trusted not to trap*> 12 <= ISPEC <= 16:*> xHSEQR or related subroutines,*> see IPARMQ for detailed explanation*> \endverbatim*>*> \param[in] NAME*> \verbatim*> NAME is CHARACTER*(*)*> The name of the calling subroutine, in either upper case or*> lower case.*> \endverbatim*>*> \param[in] OPTS*> \verbatim*> OPTS is CHARACTER*(*)*> The character options to the subroutine NAME, concatenated*> into a single character string. For example, UPLO = 'U',*> TRANS = 'T', and DIAG = 'N' for a triangular routine would*> be specified as OPTS = 'UTN'.*> \endverbatim*>*> \param[in] N1*> \verbatim*> N1 is INTEGER*> \endverbatim*>*> \param[in] N2*> \verbatim*> N2 is INTEGER*> \endverbatim*>*> \param[in] N3*> \verbatim*> N3 is INTEGER*> \endverbatim*>*> \param[in] N4*> \verbatim*> N4 is INTEGER*> Problem dimensions for the subroutine NAME; these may not all*> be required.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date November 2017**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> The following conventions have been used when calling ILAENV from the*> LAPACK routines:*> 1) OPTS is a concatenation of all of the character options to*> subroutine NAME, in the same order that they appear in the*> argument list for NAME, even if they are not used in determining*> the value of the parameter specified by ISPEC.*> 2) The problem dimensions N1, N2, N3, N4 are specified in the order*> that they appear in the argument list for NAME. N1 is used*> first, N2 second, and so on, and unused problem dimensions are*> passed a value of -1.*> 3) The parameter value returned by ILAENV is checked for validity in*> the calling subroutine. For example, ILAENV is used to retrieve*> the optimal blocksize for STRTRI as follows:*>*> NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )*> IF( NB.LE.1 ) NB = MAX( 1, N )*> \endverbatim*>* =====================================================================INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 )** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* November 2017** .. Scalar Arguments ..CHARACTER*( * ) NAME, OPTSINTEGER ISPEC, N1, N2, N3, N4* ..** =====================================================================** .. Local Scalars ..INTEGER I, IC, IZ, NB, NBMIN, NXLOGICAL CNAME, SNAME, TWOSTAGECHARACTER C1*1, C2*2, C4*2, C3*3, SUBNAM*16* ..* .. Intrinsic Functions ..INTRINSIC CHAR, ICHAR, INT, MIN, REAL* ..* .. External Functions ..INTEGER IEEECK, IPARMQ, IPARAM2STAGEEXTERNAL IEEECK, IPARMQ, IPARAM2STAGE* ..* .. Executable Statements ..*GO TO ( 10, 10, 10, 80, 90, 100, 110, 120,$ 130, 140, 150, 160, 160, 160, 160, 160)ISPEC** Invalid value for ISPEC*ILAENV = -1RETURN*10 CONTINUE** Convert NAME to upper case if the first character is lower case.*ILAENV = 1SUBNAM = NAMEIC = ICHAR( SUBNAM( 1: 1 ) )IZ = ICHAR( 'Z' )IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN** ASCII character set*IF( IC.GE.97 .AND. IC.LE.122 ) THENSUBNAM( 1: 1 ) = CHAR( IC-32 )DO 20 I = 2, 6IC = ICHAR( SUBNAM( I: I ) )IF( IC.GE.97 .AND. IC.LE.122 )$ SUBNAM( I: I ) = CHAR( IC-32 )20 CONTINUEEND IF*ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN** EBCDIC character set*IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) ) THENSUBNAM( 1: 1 ) = CHAR( IC+64 )DO 30 I = 2, 6IC = ICHAR( SUBNAM( I: I ) )IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I:$ I ) = CHAR( IC+64 )30 CONTINUEEND IF*ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN** Prime machines: ASCII+128*IF( IC.GE.225 .AND. IC.LE.250 ) THENSUBNAM( 1: 1 ) = CHAR( IC-32 )DO 40 I = 2, 6IC = ICHAR( SUBNAM( I: I ) )IF( IC.GE.225 .AND. IC.LE.250 )$ SUBNAM( I: I ) = CHAR( IC-32 )40 CONTINUEEND IFEND IF*C1 = SUBNAM( 1: 1 )SNAME = C1.EQ.'S' .OR. C1.EQ.'D'CNAME = C1.EQ.'C' .OR. C1.EQ.'Z'IF( .NOT.( CNAME .OR. SNAME ) )$ RETURNC2 = SUBNAM( 2: 3 )C3 = SUBNAM( 4: 6 )C4 = C3( 2: 3 )TWOSTAGE = LEN( SUBNAM ).GE.11$ .AND. SUBNAM( 11: 11 ).EQ.'2'*GO TO ( 50, 60, 70 )ISPEC*50 CONTINUE** ISPEC = 1: block size** In these examples, separate code is provided for setting NB for* real and complex. We assume that NB will take the same value in* single or double precision.*NB = 1*IF( C2.EQ.'GE' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.$ C3.EQ.'QLF' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFELSE IF( C3.EQ.'QR ') THENIF( N3 .EQ. 1) THENIF( SNAME ) THEN* M*NIF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THENNB = N1ELSENB = 32768/N2END IFELSEIF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THENNB = N1ELSENB = 32768/N2END IFEND IFELSEIF( SNAME ) THENNB = 1ELSENB = 1END IFEND IFELSE IF( C3.EQ.'LQ ') THENIF( N3 .EQ. 2) THENIF( SNAME ) THEN* M*NIF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THENNB = N1ELSENB = 32768/N2END IFELSEIF ((N1*N2.LE.131072).OR.(N1.LE.8192)) THENNB = N1ELSENB = 32768/N2END IFEND IFELSEIF( SNAME ) THENNB = 1ELSENB = 1END IFEND IFELSE IF( C3.EQ.'HRD' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFELSE IF( C3.EQ.'BRD' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFELSE IF( C3.EQ.'TRI' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( C2.EQ.'PO' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( C2.EQ.'SY' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENIF( TWOSTAGE ) THENNB = 192ELSENB = 64END IFELSEIF( TWOSTAGE ) THENNB = 192ELSENB = 64END IFEND IFELSE IF( SNAME .AND. C3.EQ.'TRD' ) THENNB = 32ELSE IF( SNAME .AND. C3.EQ.'GST' ) THENNB = 64END IFELSE IF( CNAME .AND. C2.EQ.'HE' ) THENIF( C3.EQ.'TRF' ) THENIF( TWOSTAGE ) THENNB = 192ELSENB = 64END IFELSE IF( C3.EQ.'TRD' ) THENNB = 32ELSE IF( C3.EQ.'GST' ) THENNB = 64END IFELSE IF( SNAME .AND. C2.EQ.'OR' ) THENIF( C3( 1: 1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNB = 32END IFELSE IF( C3( 1: 1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNB = 32END IFEND IFELSE IF( CNAME .AND. C2.EQ.'UN' ) THENIF( C3( 1: 1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNB = 32END IFELSE IF( C3( 1: 1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNB = 32END IFEND IFELSE IF( C2.EQ.'GB' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENIF( N4.LE.64 ) THENNB = 1ELSENB = 32END IFELSEIF( N4.LE.64 ) THENNB = 1ELSENB = 32END IFEND IFEND IFELSE IF( C2.EQ.'PB' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENIF( N2.LE.64 ) THENNB = 1ELSENB = 32END IFELSEIF( N2.LE.64 ) THENNB = 1ELSENB = 32END IFEND IFEND IFELSE IF( C2.EQ.'TR' ) THENIF( C3.EQ.'TRI' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFELSE IF ( C3.EQ.'EVC' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( C2.EQ.'LA' ) THENIF( C3.EQ.'UUM' ) THENIF( SNAME ) THENNB = 64ELSENB = 64END IFEND IFELSE IF( SNAME .AND. C2.EQ.'ST' ) THENIF( C3.EQ.'EBZ' ) THENNB = 1END IFELSE IF( C2.EQ.'GG' ) THENNB = 32IF( C3.EQ.'HD3' ) THENIF( SNAME ) THENNB = 32ELSENB = 32END IFEND IFEND IFILAENV = NBRETURN*60 CONTINUE** ISPEC = 2: minimum block size*NBMIN = 2IF( C2.EQ.'GE' ) THENIF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.$ 'QLF' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFELSE IF( C3.EQ.'HRD' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFELSE IF( C3.EQ.'BRD' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFELSE IF( C3.EQ.'TRI' ) THENIF( SNAME ) THENNBMIN = 2ELSENBMIN = 2END IFEND IFELSE IF( C2.EQ.'SY' ) THENIF( C3.EQ.'TRF' ) THENIF( SNAME ) THENNBMIN = 8ELSENBMIN = 8END IFELSE IF( SNAME .AND. C3.EQ.'TRD' ) THENNBMIN = 2END IFELSE IF( CNAME .AND. C2.EQ.'HE' ) THENIF( C3.EQ.'TRD' ) THENNBMIN = 2END IFELSE IF( SNAME .AND. C2.EQ.'OR' ) THENIF( C3( 1: 1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNBMIN = 2END IFELSE IF( C3( 1: 1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNBMIN = 2END IFEND IFELSE IF( CNAME .AND. C2.EQ.'UN' ) THENIF( C3( 1: 1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNBMIN = 2END IFELSE IF( C3( 1: 1 ).EQ.'M' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNBMIN = 2END IFEND IFELSE IF( C2.EQ.'GG' ) THENNBMIN = 2IF( C3.EQ.'HD3' ) THENNBMIN = 2END IFEND IFILAENV = NBMINRETURN*70 CONTINUE** ISPEC = 3: crossover point*NX = 0IF( C2.EQ.'GE' ) THENIF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.$ 'QLF' ) THENIF( SNAME ) THENNX = 128ELSENX = 128END IFELSE IF( C3.EQ.'HRD' ) THENIF( SNAME ) THENNX = 128ELSENX = 128END IFELSE IF( C3.EQ.'BRD' ) THENIF( SNAME ) THENNX = 128ELSENX = 128END IFEND IFELSE IF( C2.EQ.'SY' ) THENIF( SNAME .AND. C3.EQ.'TRD' ) THENNX = 32END IFELSE IF( CNAME .AND. C2.EQ.'HE' ) THENIF( C3.EQ.'TRD' ) THENNX = 32END IFELSE IF( SNAME .AND. C2.EQ.'OR' ) THENIF( C3( 1: 1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNX = 128END IFEND IFELSE IF( CNAME .AND. C2.EQ.'UN' ) THENIF( C3( 1: 1 ).EQ.'G' ) THENIF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.$ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )$ THENNX = 128END IFEND IFELSE IF( C2.EQ.'GG' ) THENNX = 128IF( C3.EQ.'HD3' ) THENNX = 128END IFEND IFILAENV = NXRETURN*80 CONTINUE** ISPEC = 4: number of shifts (used by xHSEQR)*ILAENV = 6RETURN*90 CONTINUE** ISPEC = 5: minimum column dimension (not used)*ILAENV = 2RETURN*100 CONTINUE** ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD)*ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 )RETURN*110 CONTINUE** ISPEC = 7: number of processors (not used)*ILAENV = 1RETURN*120 CONTINUE** ISPEC = 8: crossover point for multishift (used by xHSEQR)*ILAENV = 50RETURN*130 CONTINUE** ISPEC = 9: maximum size of the subproblems at the bottom of the* computation tree in the divide-and-conquer algorithm* (used by xGELSD and xGESDD)*ILAENV = 25RETURN*140 CONTINUE** ISPEC = 10: ieee NaN arithmetic can be trusted not to trap** ILAENV = 0ILAENV = 1IF( ILAENV.EQ.1 ) THENILAENV = IEEECK( 1, 0.0, 1.0 )END IFRETURN*150 CONTINUE** ISPEC = 11: infinity arithmetic can be trusted not to trap** ILAENV = 0ILAENV = 1IF( ILAENV.EQ.1 ) THENILAENV = IEEECK( 0, 0.0, 1.0 )END IFRETURN*160 CONTINUE** 12 <= ISPEC <= 16: xHSEQR or related subroutines.*ILAENV = IPARMQ( ISPEC, NAME, OPTS, N1, N2, N3, N4 )RETURN** End of ILAENV*END*> \brief \b ILAPREC** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download ILAPREC + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaprec.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaprec.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaprec.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION ILAPREC( PREC )** .. Scalar Arguments ..* CHARACTER PREC* ..***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine translated from a character string specifying an*> intermediate precision to the relevant BLAST-specified integer*> constant.*>*> ILAPREC returns an INTEGER. If ILAPREC < 0, then the input is not a*> character indicating a supported intermediate precision. Otherwise*> ILAPREC returns the constant value corresponding to PREC.*> \endverbatim** Arguments:* ==========*** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================INTEGER FUNCTION ILAPREC( PREC )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER PREC* ..** =====================================================================** .. Parameters ..INTEGER BLAS_PREC_SINGLE, BLAS_PREC_DOUBLE, BLAS_PREC_INDIGENOUS,$ BLAS_PREC_EXTRAPARAMETER ( BLAS_PREC_SINGLE = 211, BLAS_PREC_DOUBLE = 212,$ BLAS_PREC_INDIGENOUS = 213, BLAS_PREC_EXTRA = 214 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..IF( LSAME( PREC, 'S' ) ) THENILAPREC = BLAS_PREC_SINGLEELSE IF( LSAME( PREC, 'D' ) ) THENILAPREC = BLAS_PREC_DOUBLEELSE IF( LSAME( PREC, 'I' ) ) THENILAPREC = BLAS_PREC_INDIGENOUSELSE IF( LSAME( PREC, 'X' ) .OR. LSAME( PREC, 'E' ) ) THENILAPREC = BLAS_PREC_EXTRAELSEILAPREC = -1END IFRETURN** End of ILAPREC*END*> \brief \b ILATRANS** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download ILATRANS + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilatrans.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilatrans.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilatrans.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION ILATRANS( TRANS )** .. Scalar Arguments ..* CHARACTER TRANS* ..***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine translates from a character string specifying a*> transposition operation to the relevant BLAST-specified integer*> constant.*>*> ILATRANS returns an INTEGER. If ILATRANS < 0, then the input is not*> a character indicating a transposition operator. Otherwise ILATRANS*> returns the constant value corresponding to TRANS.*> \endverbatim** Arguments:* ==========*** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date December 2016**> \ingroup auxOTHERcomputational** =====================================================================INTEGER FUNCTION ILATRANS( TRANS )** -- LAPACK computational routine (version 3.7.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* December 2016** .. Scalar Arguments ..CHARACTER TRANS* ..** =====================================================================** .. Parameters ..INTEGER BLAS_NO_TRANS, BLAS_TRANS, BLAS_CONJ_TRANSPARAMETER ( BLAS_NO_TRANS = 111, BLAS_TRANS = 112,$ BLAS_CONJ_TRANS = 113 )* ..* .. External Functions ..LOGICAL LSAMEEXTERNAL LSAME* ..* .. Executable Statements ..IF( LSAME( TRANS, 'N' ) ) THENILATRANS = BLAS_NO_TRANSELSE IF( LSAME( TRANS, 'T' ) ) THENILATRANS = BLAS_TRANSELSE IF( LSAME( TRANS, 'C' ) ) THENILATRANS = BLAS_CONJ_TRANSELSEILATRANS = -1END IFRETURN** End of ILATRANS*END*> \brief \b ILAVER returns the LAPACK version.*** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/** Definition:* ===========** SUBROUTINE ILAVER( VERS_MAJOR, VERS_MINOR, VERS_PATCH )** INTEGER VERS_MAJOR, VERS_MINOR, VERS_PATCH***> \par Purpose:* =============*>*> \verbatim*>*> This subroutine returns the LAPACK version.*> \endverbatim** Arguments:* ==========**> \param[out] VERS_MAJOR*> return the lapack major version*>*> \param[out] VERS_MINOR*> return the lapack minor version from the major version*>*> \param[out] VERS_PATCH*> return the lapack patch version from the minor version** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup auxOTHERauxiliary** =====================================================================SUBROUTINE ILAVER( VERS_MAJOR, VERS_MINOR, VERS_PATCH )** -- LAPACK computational routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** =====================================================================*INTEGER VERS_MAJOR, VERS_MINOR, VERS_PATCH* =====================================================================VERS_MAJOR = 3VERS_MINOR = 8VERS_PATCH = 0* =====================================================================*RETURNEND# 1 "SRC/iparam2stage.F"# 1 "<built-in>" 1# 1 "<built-in>" 3# 330 "<built-in>" 3# 1 "<command line>" 1# 1 "<built-in>" 2# 1 "SRC/iparam2stage.F" 2*> \brief \b IPARAM2STAGE** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download IPARAM2STAGE + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iparam2stage.F">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iparam2stage.F">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iparam2stage.F">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION IPARAM2STAGE( ISPEC, NAME, OPTS,* NI, NBI, IBI, NXI )* #if defined(_OPENMP)* use omp_lib* #endif* IMPLICIT NONE** .. Scalar Arguments ..* CHARACTER*( * ) NAME, OPTS* INTEGER ISPEC, NI, NBI, IBI, NXI**> \par Purpose:* =============*>*> \verbatim*>*> This program sets problem and machine dependent parameters*> useful for xHETRD_2STAGE, xHETRD_H@2HB, xHETRD_HB2ST,*> xGEBRD_2STAGE, xGEBRD_GE2GB, xGEBRD_GB2BD*> and related subroutines for eigenvalue problems.*> It is called whenever ILAENV is called with 17 <= ISPEC <= 21.*> It is called whenever ILAENV2STAGE is called with 1 <= ISPEC <= 5*> with a direct conversion ISPEC + 16.*> \endverbatim** Arguments:* ==========**> \param[in] ISPEC*> \verbatim*> ISPEC is integer scalar*> ISPEC specifies which tunable parameter IPARAM2STAGE should*> return.*>*> ISPEC=17: the optimal blocksize nb for the reduction to* BAND*>*> ISPEC=18: the optimal blocksize ib for the eigenvectors*> singular vectors update routine*>*> ISPEC=19: The length of the array that store the Housholder*> representation for the second stage*> Band to Tridiagonal or Bidiagonal*>*> ISPEC=20: The workspace needed for the routine in input.*>*> ISPEC=21: For future release.*> \endverbatim*>*> \param[in] NAME*> \verbatim*> NAME is character string*> Name of the calling subroutine*> \endverbatim*>*> \param[in] OPTS*> \verbatim*> OPTS is CHARACTER*(*)*> The character options to the subroutine NAME, concatenated*> into a single character string. For example, UPLO = 'U',*> TRANS = 'T', and DIAG = 'N' for a triangular routine would*> be specified as OPTS = 'UTN'.*> \endverbatim*>*> \param[in] NI*> \verbatim*> NI is INTEGER which is the size of the matrix*> \endverbatim*>*> \param[in] NBI*> \verbatim*> NBI is INTEGER which is the used in the reduciton,* (e.g., the size of the band), needed to compute workspace* and LHOUS2.*> \endverbatim*>*> \param[in] IBI*> \verbatim*> IBI is INTEGER which represent the IB of the reduciton,* needed to compute workspace and LHOUS2.*> \endverbatim*>*> \param[in] NXI*> \verbatim*> NXI is INTEGER needed in the future release.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2016**> \ingroup auxOTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Implemented by Azzam Haidar.*>*> All detail are available on technical report, SC11, SC13 papers.*>*> Azzam Haidar, Hatem Ltaief, and Jack Dongarra.*> Parallel reduction to condensed forms for symmetric eigenvalue problems*> using aggregated fine-grained and memory-aware kernels. In Proceedings*> of 2011 International Conference for High Performance Computing,*> Networking, Storage and Analysis (SC '11), New York, NY, USA,*> Article 8 , 11 pages.*> http://doi.acm.org/10.1145/2063384.2063394*>*> A. Haidar, J. Kurzak, P. Luszczek, 2013.*> An improved parallel singular value algorithm and its implementation*> for multicore hardware, In Proceedings of 2013 International Conference*> for High Performance Computing, Networking, Storage and Analysis (SC '13).*> Denver, Colorado, USA, 2013.*> Article 90, 12 pages.*> http://doi.acm.org/10.1145/2503210.2503292*>*> A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.*> A novel hybrid CPU-GPU generalized eigensolver for electronic structure*> calculations based on fine-grained memory aware tasks.*> International Journal of High Performance Computing Applications.*> Volume 28 Issue 2, Pages 196-209, May 2014.*> http://hpc.sagepub.com/content/28/2/196*>*> \endverbatim*>* =====================================================================INTEGER FUNCTION IPARAM2STAGE( ISPEC, NAME, OPTS,$ NI, NBI, IBI, NXI )IMPLICIT NONE** -- LAPACK auxiliary routine (version 3.8.0) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2016** .. Scalar Arguments ..CHARACTER*( * ) NAME, OPTSINTEGER ISPEC, NI, NBI, IBI, NXI** ================================================================* ..* .. Local Scalars ..INTEGER I, IC, IZ, KD, IB, LHOUS, LWORK, NTHREADS,$ FACTOPTNB, QROPTNB, LQOPTNBLOGICAL RPREC, CPRECCHARACTER PREC*1, ALGO*3, STAG*5, SUBNAM*12, VECT*1* ..* .. Intrinsic Functions ..INTRINSIC CHAR, ICHAR, MAX* ..* .. External Functions ..INTEGER ILAENVEXTERNAL ILAENV* ..* .. Executable Statements ..** Invalid value for ISPEC*IF( (ISPEC.LT.17).OR.(ISPEC.GT.21) ) THENIPARAM2STAGE = -1RETURNENDIF** Get the number of threads*NTHREADS = 1* WRITE(*,*) 'IPARAM VOICI NTHREADS ISPEC ',NTHREADS, ISPEC*IF( ISPEC .NE. 19 ) THEN** Convert NAME to upper case if the first character is lower case.*IPARAM2STAGE = -1SUBNAM = NAMEIC = ICHAR( SUBNAM( 1: 1 ) )IZ = ICHAR( 'Z' )IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN** ASCII character set*IF( IC.GE.97 .AND. IC.LE.122 ) THENSUBNAM( 1: 1 ) = CHAR( IC-32 )DO 100 I = 2, 12IC = ICHAR( SUBNAM( I: I ) )IF( IC.GE.97 .AND. IC.LE.122 )$ SUBNAM( I: I ) = CHAR( IC-32 )100 CONTINUEEND IF*ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN** EBCDIC character set*IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) ) THENSUBNAM( 1: 1 ) = CHAR( IC+64 )DO 110 I = 2, 12IC = ICHAR( SUBNAM( I: I ) )IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I:$ I ) = CHAR( IC+64 )110 CONTINUEEND IF*ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN** Prime machines: ASCII+128*IF( IC.GE.225 .AND. IC.LE.250 ) THENSUBNAM( 1: 1 ) = CHAR( IC-32 )DO 120 I = 2, 12IC = ICHAR( SUBNAM( I: I ) )IF( IC.GE.225 .AND. IC.LE.250 )$ SUBNAM( I: I ) = CHAR( IC-32 )120 CONTINUEEND IFEND IF*PREC = SUBNAM( 1: 1 )ALGO = SUBNAM( 4: 6 )STAG = SUBNAM( 8:12 )RPREC = PREC.EQ.'S' .OR. PREC.EQ.'D'CPREC = PREC.EQ.'C' .OR. PREC.EQ.'Z'** Invalid value for PRECISION*IF( .NOT.( RPREC .OR. CPREC ) ) THENIPARAM2STAGE = -1RETURNENDIFENDIF* WRITE(*,*),'RPREC,CPREC ',RPREC,CPREC,* $ ' ALGO ',ALGO,' STAGE ',STAG**IF (( ISPEC .EQ. 17 ) .OR. ( ISPEC .EQ. 18 )) THEN** ISPEC = 17, 18: block size KD, IB* Could be also dependent from N but for now it* depend only on sequential or parallel*IF( NTHREADS.GT.4 ) THENIF( CPREC ) THENKD = 128IB = 32ELSEKD = 160IB = 40ENDIFELSE IF( NTHREADS.GT.1 ) THENIF( CPREC ) THENKD = 64IB = 32ELSEKD = 64IB = 32ENDIFELSEIF( CPREC ) THENKD = 16IB = 16ELSEKD = 32IB = 16ENDIFENDIFIF( ISPEC.EQ.17 ) IPARAM2STAGE = KDIF( ISPEC.EQ.18 ) IPARAM2STAGE = IB*ELSE IF ( ISPEC .EQ. 19 ) THEN** ISPEC = 19:* LHOUS length of the Houselholder representation* matrix (V,T) of the second stage. should be >= 1.** Will add the VECT OPTION HERE next releaseVECT = OPTS(1:1)IF( VECT.EQ.'N' ) THENLHOUS = MAX( 1, 4*NI )ELSE* This is not correct, it need to call the ALGO and the stage2LHOUS = MAX( 1, 4*NI ) + IBIENDIFIF( LHOUS.GE.0 ) THENIPARAM2STAGE = LHOUSELSEIPARAM2STAGE = -1ENDIF*ELSE IF ( ISPEC .EQ. 20 ) THEN** ISPEC = 20: (21 for future use)* LWORK length of the workspace for* either or both stages for TRD and BRD. should be >= 1.* TRD:* TRD_stage 1: = LT + LW + LS1 + LS2* = LDT*KD + N*KD + N*MAX(KD,FACTOPTNB) + LDS2*KD* where LDT=LDS2=KD* = N*KD + N*max(KD,FACTOPTNB) + 2*KD*KD* TRD_stage 2: = (2NB+1)*N + KD*NTHREADS* TRD_both : = max(stage1,stage2) + AB ( AB=(KD+1)*N )* = N*KD + N*max(KD+1,FACTOPTNB)* + max(2*KD*KD, KD*NTHREADS)* + (KD+1)*NLWORK = -1SUBNAM(1:1) = PRECSUBNAM(2:6) = 'GEQRF'QROPTNB = ILAENV( 1, SUBNAM, ' ', NI, NBI, -1, -1 )SUBNAM(2:6) = 'GELQF'LQOPTNB = ILAENV( 1, SUBNAM, ' ', NBI, NI, -1, -1 )* Could be QR or LQ for TRD and the max for BRDFACTOPTNB = MAX(QROPTNB, LQOPTNB)IF( ALGO.EQ.'TRD' ) THENIF( STAG.EQ.'2STAG' ) THENLWORK = NI*NBI + NI*MAX(NBI+1,FACTOPTNB)$ + MAX(2*NBI*NBI, NBI*NTHREADS)$ + (NBI+1)*NIELSE IF( (STAG.EQ.'HE2HB').OR.(STAG.EQ.'SY2SB') ) THENLWORK = NI*NBI + NI*MAX(NBI,FACTOPTNB) + 2*NBI*NBIELSE IF( (STAG.EQ.'HB2ST').OR.(STAG.EQ.'SB2ST') ) THENLWORK = (2*NBI+1)*NI + NBI*NTHREADSENDIFELSE IF( ALGO.EQ.'BRD' ) THENIF( STAG.EQ.'2STAG' ) THENLWORK = 2*NI*NBI + NI*MAX(NBI+1,FACTOPTNB)$ + MAX(2*NBI*NBI, NBI*NTHREADS)$ + (NBI+1)*NIELSE IF( STAG.EQ.'GE2GB' ) THENLWORK = NI*NBI + NI*MAX(NBI,FACTOPTNB) + 2*NBI*NBIELSE IF( STAG.EQ.'GB2BD' ) THENLWORK = (3*NBI+1)*NI + NBI*NTHREADSENDIFENDIFLWORK = MAX ( 1, LWORK )IF( LWORK.GT.0 ) THENIPARAM2STAGE = LWORKELSEIPARAM2STAGE = -1ENDIF*ELSE IF ( ISPEC .EQ. 21 ) THEN** ISPEC = 21 for future useIPARAM2STAGE = NXIENDIF** ==== End of IPARAM2STAGE ====*END*> \brief \b IPARMQ** =========== DOCUMENTATION ===========** Online html documentation available at* http://www.netlib.org/lapack/explore-html/**> \htmlonly*> Download IPARMQ + dependencies*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iparmq.f">*> [TGZ]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iparmq.f">*> [ZIP]</a>*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iparmq.f">*> [TXT]</a>*> \endhtmlonly** Definition:* ===========** INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK )** .. Scalar Arguments ..* INTEGER IHI, ILO, ISPEC, LWORK, N* CHARACTER NAME*( * ), OPTS*( * )***> \par Purpose:* =============*>*> \verbatim*>*> This program sets problem and machine dependent parameters*> useful for xHSEQR and related subroutines for eigenvalue*> problems. It is called whenever*> IPARMQ is called with 12 <= ISPEC <= 16*> \endverbatim** Arguments:* ==========**> \param[in] ISPEC*> \verbatim*> ISPEC is INTEGER*> ISPEC specifies which tunable parameter IPARMQ should*> return.*>*> ISPEC=12: (INMIN) Matrices of order nmin or less*> are sent directly to xLAHQR, the implicit*> double shift QR algorithm. NMIN must be*> at least 11.*>*> ISPEC=13: (INWIN) Size of the deflation window.*> This is best set greater than or equal to*> the number of simultaneous shifts NS.*> Larger matrices benefit from larger deflation*> windows.*>*> ISPEC=14: (INIBL) Determines when to stop nibbling and*> invest in an (expensive) multi-shift QR sweep.*> If the aggressive early deflation subroutine*> finds LD converged eigenvalues from an order*> NW deflation window and LD.GT.(NW*NIBBLE)/100,*> then the next QR sweep is skipped and early*> deflation is applied immediately to the*> remaining active diagonal block. Setting*> IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a*> multi-shift QR sweep whenever early deflation*> finds a converged eigenvalue. Setting*> IPARMQ(ISPEC=14) greater than or equal to 100*> prevents TTQRE from skipping a multi-shift*> QR sweep.*>*> ISPEC=15: (NSHFTS) The number of simultaneous shifts in*> a multi-shift QR iteration.*>*> ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the*> following meanings.*> 0: During the multi-shift QR/QZ sweep,*> blocked eigenvalue reordering, blocked*> Hessenberg-triangular reduction,*> reflections and/or rotations are not*> accumulated when updating the*> far-from-diagonal matrix entries.*> 1: During the multi-shift QR/QZ sweep,*> blocked eigenvalue reordering, blocked*> Hessenberg-triangular reduction,*> reflections and/or rotations are*> accumulated, and matrix-matrix*> multiplication is used to update the*> far-from-diagonal matrix entries.*> 2: During the multi-shift QR/QZ sweep,*> blocked eigenvalue reordering, blocked*> Hessenberg-triangular reduction,*> reflections and/or rotations are*> accumulated, and 2-by-2 block structure*> is exploited during matrix-matrix*> multiplies.*> (If xTRMM is slower than xGEMM, then*> IPARMQ(ISPEC=16)=1 may be more efficient than*> IPARMQ(ISPEC=16)=2 despite the greater level of*> arithmetic work implied by the latter choice.)*> \endverbatim*>*> \param[in] NAME*> \verbatim*> NAME is character string*> Name of the calling subroutine*> \endverbatim*>*> \param[in] OPTS*> \verbatim*> OPTS is character string*> This is a concatenation of the string arguments to*> TTQRE.*> \endverbatim*>*> \param[in] N*> \verbatim*> N is INTEGER*> N is the order of the Hessenberg matrix H.*> \endverbatim*>*> \param[in] ILO*> \verbatim*> ILO is INTEGER*> \endverbatim*>*> \param[in] IHI*> \verbatim*> IHI is INTEGER*> It is assumed that H is already upper triangular*> in rows and columns 1:ILO-1 and IHI+1:N.*> \endverbatim*>*> \param[in] LWORK*> \verbatim*> LWORK is INTEGER*> The amount of workspace available.*> \endverbatim** Authors:* ========**> \author Univ. of Tennessee*> \author Univ. of California Berkeley*> \author Univ. of Colorado Denver*> \author NAG Ltd.**> \date June 2017**> \ingroup OTHERauxiliary**> \par Further Details:* =====================*>*> \verbatim*>*> Little is known about how best to choose these parameters.*> It is possible to use different values of the parameters*> for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR.*>*> It is probably best to choose different parameters for*> different matrices and different parameters at different*> times during the iteration, but this has not been*> implemented --- yet.*>*>*> The best choices of most of the parameters depend*> in an ill-understood way on the relative execution*> rate of xLAQR3 and xLAQR5 and on the nature of each*> particular eigenvalue problem. Experiment may be the*> only practical way to determine which choices are most*> effective.*>*> Following is a list of default values supplied by IPARMQ.*> These defaults may be adjusted in order to attain better*> performance in any particular computational environment.*>*> IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point.*> Default: 75. (Must be at least 11.)*>*> IPARMQ(ISPEC=13) Recommended deflation window size.*> This depends on ILO, IHI and NS, the*> number of simultaneous shifts returned*> by IPARMQ(ISPEC=15). The default for*> (IHI-ILO+1).LE.500 is NS. The default*> for (IHI-ILO+1).GT.500 is 3*NS/2.*>*> IPARMQ(ISPEC=14) Nibble crossover point. Default: 14.*>*> IPARMQ(ISPEC=15) Number of simultaneous shifts, NS.*> a multi-shift QR iteration.*>*> If IHI-ILO+1 is ...*>*> greater than ...but less ... the*> or equal to ... than default is*>*> 0 30 NS = 2+*> 30 60 NS = 4+*> 60 150 NS = 10*> 150 590 NS = ***> 590 3000 NS = 64*> 3000 6000 NS = 128*> 6000 infinity NS = 256*>*> (+) By default matrices of this order are*> passed to the implicit double shift routine*> xLAHQR. See IPARMQ(ISPEC=12) above. These*> values of NS are used only in case of a rare*> xLAHQR failure.*>*> (**) The asterisks (**) indicate an ad-hoc*> function increasing from 10 to 64.*>*> IPARMQ(ISPEC=16) Select structured matrix multiply.*> (See ISPEC=16 above for details.)*> Default: 3.*> \endverbatim*>* =====================================================================INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK )** -- LAPACK auxiliary routine (version 3.7.1) --* -- LAPACK is a software package provided by Univ. of Tennessee, --* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--* June 2017** .. Scalar Arguments ..INTEGER IHI, ILO, ISPEC, LWORK, NCHARACTER NAME*( * ), OPTS*( * )** ================================================================* .. Parameters ..INTEGER INMIN, INWIN, INIBL, ISHFTS, IACC22PARAMETER ( INMIN = 12, INWIN = 13, INIBL = 14,$ ISHFTS = 15, IACC22 = 16 )INTEGER NMIN, K22MIN, KACMIN, NIBBLE, KNWSWPPARAMETER ( NMIN = 75, K22MIN = 14, KACMIN = 14,$ NIBBLE = 14, KNWSWP = 500 )REAL TWOPARAMETER ( TWO = 2.0 )* ..* .. Local Scalars ..INTEGER NH, NSINTEGER I, IC, IZCHARACTER SUBNAM*6* ..* .. Intrinsic Functions ..INTRINSIC LOG, MAX, MOD, NINT, REAL* ..* .. Executable Statements ..IF( ( ISPEC.EQ.ISHFTS ) .OR. ( ISPEC.EQ.INWIN ) .OR.$ ( ISPEC.EQ.IACC22 ) ) THEN** ==== Set the number simultaneous shifts ====*NH = IHI - ILO + 1NS = 2IF( NH.GE.30 )$ NS = 4IF( NH.GE.60 )$ NS = 10IF( NH.GE.150 )$ NS = MAX( 10, NH / NINT( LOG( REAL( NH ) ) / LOG( TWO ) ) )IF( NH.GE.590 )$ NS = 64IF( NH.GE.3000 )$ NS = 128IF( NH.GE.6000 )$ NS = 256NS = MAX( 2, NS-MOD( NS, 2 ) )END IF*IF( ISPEC.EQ.INMIN ) THEN*** ===== Matrices of order smaller than NMIN get sent* . to xLAHQR, the classic double shift algorithm.* . This must be at least 11. ====*IPARMQ = NMIN*ELSE IF( ISPEC.EQ.INIBL ) THEN** ==== INIBL: skip a multi-shift qr iteration and* . whenever aggressive early deflation finds* . at least (NIBBLE*(window size)/100) deflations. ====*IPARMQ = NIBBLE*ELSE IF( ISPEC.EQ.ISHFTS ) THEN** ==== NSHFTS: The number of simultaneous shifts =====*IPARMQ = NS*ELSE IF( ISPEC.EQ.INWIN ) THEN** ==== NW: deflation window size. ====*IF( NH.LE.KNWSWP ) THENIPARMQ = NSELSEIPARMQ = 3*NS / 2END IF*ELSE IF( ISPEC.EQ.IACC22 ) THEN** ==== IACC22: Whether to accumulate reflections* . before updating the far-from-diagonal elements* . and whether to use 2-by-2 block structure while* . doing it. A small amount of work could be saved* . by making this choice dependent also upon the* . NH=IHI-ILO+1.*** Convert NAME to upper case if the first character is lower case.*IPARMQ = 0SUBNAM = NAMEIC = ICHAR( SUBNAM( 1: 1 ) )IZ = ICHAR( 'Z' )IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN** ASCII character set*IF( IC.GE.97 .AND. IC.LE.122 ) THENSUBNAM( 1: 1 ) = CHAR( IC-32 )DO I = 2, 6IC = ICHAR( SUBNAM( I: I ) )IF( IC.GE.97 .AND. IC.LE.122 )$ SUBNAM( I: I ) = CHAR( IC-32 )END DOEND IF*ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN** EBCDIC character set*IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) ) THENSUBNAM( 1: 1 ) = CHAR( IC+64 )DO I = 2, 6IC = ICHAR( SUBNAM( I: I ) )IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.$ ( IC.GE.145 .AND. IC.LE.153 ) .OR.$ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I:$ I ) = CHAR( IC+64 )END DOEND IF*ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN** Prime machines: ASCII+128*IF( IC.GE.225 .AND. IC.LE.250 ) THENSUBNAM( 1: 1 ) = CHAR( IC-32 )DO I = 2, 6IC = ICHAR( SUBNAM( I: I ) )IF( IC.GE.225 .AND. IC.LE.250 )$ SUBNAM( I: I ) = CHAR( IC-32 )END DOEND IFEND IF*IF( SUBNAM( 2:6 ).EQ.'GGHRD' .OR.$ SUBNAM( 2:6 ).EQ.'GGHD3' ) THENIPARMQ = 1IF( NH.GE.K22MIN )$ IPARMQ = 2ELSE IF ( SUBNAM( 4:6 ).EQ.'EXC' ) THENIF( NH.GE.KACMIN )$ IPARMQ = 1IF( NH.GE.K22MIN )$ IPARMQ = 2ELSE IF ( SUBNAM( 2:6 ).EQ.'HSEQR' .OR.$ SUBNAM( 2:5 ).EQ.'LAQR' ) THENIF( NS.GE.KACMIN )$ IPARMQ = 1IF( NS.GE.K22MIN )$ IPARMQ = 2END IF*ELSE* ===== invalid value of ispec =====IPARMQ = -1*END IF** ==== End of IPARMQ ====*END