|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532 |
- *> \brief \b DLAQZ4
- *
- * =========== DOCUMENTATION ===========
- *
- * Online html documentation available at
- * http://www.netlib.org/lapack/explore-html/
- *
- *> \htmlonly
- *> Download DLAQZ4 + dependencies
- *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaqz4.f">
- *> [TGZ]</a>
- *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaqz4.f">
- *> [ZIP]</a>
- *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaqz4.f">
- *> [TXT]</a>
- *> \endhtmlonly
- *
- * Definition:
- * ===========
- *
- * SUBROUTINE DLAQZ4( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NSHIFTS,
- * $ NBLOCK_DESIRED, SR, SI, SS, A, LDA, B, LDB, Q, LDQ, Z, LDZ,
- * $ QC, LDQC, ZC, LDZC, WORK, LWORK, INFO )
- * IMPLICIT NONE
- *
- * Function arguments
- * LOGICAL, INTENT( IN ) :: ILSCHUR, ILQ, ILZ
- * INTEGER, INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
- * $ NSHIFTS, NBLOCK_DESIRED, LDQC, LDZC
- *
- * DOUBLE PRECISION, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ),
- * $ Q( LDQ, * ), Z( LDZ, * ), QC( LDQC, * ), ZC( LDZC, * ),
- * $ WORK( * ), SR( * ), SI( * ), SS( * )
- *
- * INTEGER, INTENT( OUT ) :: INFO
- * ..
- *
- *
- *> \par Purpose:
- * =============
- *>
- *> \verbatim
- *>
- *> DLAQZ4 Executes a single multishift QZ sweep
- *> \endverbatim
- *
- * Arguments:
- * ==========
- *
- *> \param[in] ILSCHUR
- *> \verbatim
- *> ILSCHUR is LOGICAL
- *> Determines whether or not to update the full Schur form
- *> \endverbatim
- *> \param[in] ILQ
- *> \verbatim
- *> ILQ is LOGICAL
- *> Determines whether or not to update the matrix Q
- *> \endverbatim
- *>
- *> \param[in] ILZ
- *> \verbatim
- *> ILZ is LOGICAL
- *> Determines whether or not to update the matrix Z
- *> \endverbatim
- *>
- *> \param[in] N
- *> \verbatim
- *> N is INTEGER
- *> The order of the matrices A, B, Q, and Z. N >= 0.
- *> \endverbatim
- *>
- *> \param[in] ILO
- *> \verbatim
- *> ILO is INTEGER
- *> \endverbatim
- *>
- *> \param[in] IHI
- *> \verbatim
- *> IHI is INTEGER
- *> \endverbatim
- *>
- *> \param[in] NSHIFTS
- *> \verbatim
- *> NSHIFTS is INTEGER
- *> The desired number of shifts to use
- *> \endverbatim
- *>
- *> \param[in] NBLOCK_DESIRED
- *> \verbatim
- *> NBLOCK_DESIRED is INTEGER
- *> The desired size of the computational windows
- *> \endverbatim
- *>
- *> \param[in] SR
- *> \verbatim
- *> SR is DOUBLE PRECISION array. SR contains
- *> the real parts of the shifts to use.
- *> \endverbatim
- *>
- *> \param[in] SI
- *> \verbatim
- *> SI is DOUBLE PRECISION array. SI contains
- *> the imaginary parts of the shifts to use.
- *> \endverbatim
- *>
- *> \param[in] SS
- *> \verbatim
- *> SS is DOUBLE PRECISION array. SS contains
- *> the scale of the shifts to use.
- *> \endverbatim
- *>
- *> \param[in,out] A
- *> \verbatim
- *> A is DOUBLE PRECISION array, dimension (LDA, N)
- *> \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)
- *> \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)
- *> \endverbatim
- *>
- *> \param[in] LDQ
- *> \verbatim
- *> LDQ is INTEGER
- *> \endverbatim
- *>
- *> \param[in,out] Z
- *> \verbatim
- *> Z is DOUBLE PRECISION array, dimension (LDZ, N)
- *> \endverbatim
- *>
- *> \param[in] LDZ
- *> \verbatim
- *> LDZ is INTEGER
- *> \endverbatim
- *>
- *> \param[in,out] QC
- *> \verbatim
- *> QC is DOUBLE PRECISION array, dimension (LDQC, NBLOCK_DESIRED)
- *> \endverbatim
- *>
- *> \param[in] LDQC
- *> \verbatim
- *> LDQC is INTEGER
- *> \endverbatim
- *>
- *> \param[in,out] ZC
- *> \verbatim
- *> ZC is DOUBLE PRECISION array, dimension (LDZC, NBLOCK_DESIRED)
- *> \endverbatim
- *>
- *> \param[in] LDZC
- *> \verbatim
- *> LDZ is INTEGER
- *> \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
- *> \endverbatim
- *
- * Authors:
- * ========
- *
- *> \author Thijs Steel, KU Leuven
- *
- *> \date May 2020
- *
- *> \ingroup doubleGEcomputational
- *>
- * =====================================================================
- SUBROUTINE DLAQZ4( ILSCHUR, ILQ, ILZ, N, ILO, IHI, NSHIFTS,
- $ NBLOCK_DESIRED, SR, SI, SS, A, LDA, B, LDB, Q,
- $ LDQ, Z, LDZ, QC, LDQC, ZC, LDZC, WORK, LWORK,
- $ INFO )
- IMPLICIT NONE
-
- * Function arguments
- LOGICAL, INTENT( IN ) :: ILSCHUR, ILQ, ILZ
- INTEGER, INTENT( IN ) :: N, ILO, IHI, LDA, LDB, LDQ, LDZ, LWORK,
- $ NSHIFTS, NBLOCK_DESIRED, LDQC, LDZC
-
- DOUBLE PRECISION, INTENT( INOUT ) :: A( LDA, * ), B( LDB, * ),
- $ Q( LDQ, * ), Z( LDZ, * ), QC( LDQC, * ),
- $ ZC( LDZC, * ), WORK( * ), SR( * ), SI( * ),
- $ SS( * )
-
- INTEGER, INTENT( OUT ) :: INFO
-
- * Parameters
- DOUBLE PRECISION :: ZERO, ONE, HALF
- PARAMETER( ZERO = 0.0D0, ONE = 1.0D0, HALF = 0.5D0 )
-
- * Local scalars
- INTEGER :: I, J, NS, ISTARTM, ISTOPM, SHEIGHT, SWIDTH, K, NP,
- $ ISTARTB, ISTOPB, ISHIFT, NBLOCK, NPOS
- DOUBLE PRECISION :: TEMP, V( 3 ), C1, S1, C2, S2, SWAP
- *
- * External functions
- EXTERNAL :: XERBLA, DGEMM, DLAQZ1, DLAQZ2, DLASET, DLARTG, DROT,
- $ DLACPY
-
- INFO = 0
- IF ( NBLOCK_DESIRED .LT. NSHIFTS+1 ) THEN
- INFO = -8
- END IF
- IF ( LWORK .EQ.-1 ) THEN
- * workspace query, quick return
- WORK( 1 ) = N*NBLOCK_DESIRED
- RETURN
- ELSE IF ( LWORK .LT. N*NBLOCK_DESIRED ) THEN
- INFO = -25
- END IF
-
- IF( INFO.NE.0 ) THEN
- CALL XERBLA( 'DLAQZ4', -INFO )
- RETURN
- END IF
-
- * Executable statements
-
- IF ( NSHIFTS .LT. 2 ) THEN
- RETURN
- END IF
-
- IF ( ILO .GE. IHI ) THEN
- RETURN
- END IF
-
- IF ( ILSCHUR ) THEN
- ISTARTM = 1
- ISTOPM = N
- ELSE
- ISTARTM = ILO
- ISTOPM = IHI
- END IF
-
- * Shuffle shifts into pairs of real shifts and pairs
- * of complex conjugate shifts assuming complex
- * conjugate shifts are already adjacent to one
- * another
-
- DO I = 1, NSHIFTS-2, 2
- IF( 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 ) = SWAP
-
- SWAP = SS( I )
- SS( I ) = SS( I+1 )
- SS( I+1 ) = SS( I+2 )
- SS( I+2 ) = SWAP
- END IF
- END DO
-
- * 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 = NSHIFTS-MOD( NSHIFTS, 2 )
- NPOS = MAX( NBLOCK_DESIRED-NS, 1 )
-
- * The following block introduces the shifts and chases
- * them down one by one just enough to make space for
- * the other shifts. The near-the-diagonal block is
- * of size (ns+1) x ns.
-
- CALL DLASET( 'FULL', NS+1, NS+1, ZERO, ONE, QC, LDQC )
- CALL DLASET( 'FULL', NS, NS, ZERO, ONE, ZC, LDZC )
-
- DO I = 1, NS, 2
- * Introduce the shift
- CALL DLAQZ1( A( ILO, ILO ), LDA, B( ILO, ILO ), LDB, SR( I ),
- $ SR( I+1 ), SI( I ), SS( I ), SS( I+1 ), V )
-
- TEMP = V( 2 )
- CALL DLARTG( TEMP, V( 3 ), C1, S1, V( 2 ) )
- CALL DLARTG( V( 1 ), V( 2 ), C2, S2, TEMP )
-
- CALL DROT( NS, A( ILO+1, ILO ), LDA, A( ILO+2, ILO ), LDA, C1,
- $ S1 )
- CALL DROT( NS, A( ILO, ILO ), LDA, A( ILO+1, ILO ), LDA, C2,
- $ S2 )
- CALL DROT( NS, B( ILO+1, ILO ), LDB, B( ILO+2, ILO ), LDB, C1,
- $ S1 )
- CALL DROT( NS, B( ILO, ILO ), LDB, B( ILO+1, ILO ), LDB, C2,
- $ S2 )
- CALL DROT( NS+1, QC( 1, 2 ), 1, QC( 1, 3 ), 1, C1, S1 )
- CALL DROT( NS+1, QC( 1, 1 ), 1, QC( 1, 2 ), 1, C2, S2 )
-
- * Chase the shift down
- DO J = 1, NS-1-I
-
- CALL DLAQZ2( .TRUE., .TRUE., J, 1, NS, IHI-ILO+1, A( ILO,
- $ ILO ), LDA, B( ILO, ILO ), LDB, NS+1, 1, QC,
- $ LDQC, NS, 1, ZC, LDZC )
-
- END DO
-
- END DO
-
- * Update the rest of the pencil
-
- * Update A(ilo:ilo+ns,ilo+ns:istopm) and B(ilo:ilo+ns,ilo+ns:istopm)
- * from the left with Qc(1:ns+1,1:ns+1)'
- SHEIGHT = NS+1
- SWIDTH = ISTOPM-( ILO+NS )+1
- IF ( SWIDTH > 0 ) THEN
- CALL DGEMM( 'T', 'N', SHEIGHT, SWIDTH, SHEIGHT, ONE, QC, LDQC,
- $ A( ILO, ILO+NS ), LDA, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, A( ILO,
- $ ILO+NS ), LDA )
- CALL DGEMM( 'T', 'N', SHEIGHT, SWIDTH, SHEIGHT, ONE, QC, LDQC,
- $ B( ILO, ILO+NS ), LDB, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, B( ILO,
- $ ILO+NS ), LDB )
- END IF
- IF ( ILQ ) THEN
- CALL DGEMM( 'N', 'N', N, SHEIGHT, SHEIGHT, ONE, Q( 1, ILO ),
- $ LDQ, QC, LDQC, ZERO, WORK, N )
- CALL DLACPY( 'ALL', N, SHEIGHT, WORK, N, Q( 1, ILO ), LDQ )
- END IF
-
- * Update A(istartm:ilo-1,ilo:ilo+ns-1) and B(istartm:ilo-1,ilo:ilo+ns-1)
- * from the right with Zc(1:ns,1:ns)
- SHEIGHT = ILO-1-ISTARTM+1
- SWIDTH = NS
- IF ( SHEIGHT > 0 ) THEN
- CALL DGEMM( 'N', 'N', SHEIGHT, SWIDTH, SWIDTH, ONE, A( ISTARTM,
- $ ILO ), LDA, ZC, LDZC, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, A( ISTARTM,
- $ ILO ), LDA )
- CALL DGEMM( 'N', 'N', SHEIGHT, SWIDTH, SWIDTH, ONE, B( ISTARTM,
- $ ILO ), LDB, ZC, LDZC, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, B( ISTARTM,
- $ ILO ), LDB )
- END IF
- IF ( ILZ ) THEN
- CALL DGEMM( 'N', 'N', N, SWIDTH, SWIDTH, ONE, Z( 1, ILO ), LDZ,
- $ ZC, LDZC, ZERO, WORK, N )
- CALL DLACPY( 'ALL', N, SWIDTH, WORK, N, Z( 1, ILO ), LDZ )
- END IF
-
- * The following block chases the shifts down to the bottom
- * right block. If possible, a shift is moved down npos
- * positions at a time
-
- K = ILO
- DO WHILE ( K < IHI-NS )
- NP = MIN( IHI-NS-K, NPOS )
- * Size of the near-the-diagonal block
- NBLOCK = NS+NP
- * istartb points to the first row we will be updating
- ISTARTB = K+1
- * istopb points to the last column we will be updating
- ISTOPB = K+NBLOCK-1
-
- CALL DLASET( 'FULL', NS+NP, NS+NP, ZERO, ONE, QC, LDQC )
- CALL DLASET( 'FULL', NS+NP, NS+NP, ZERO, ONE, ZC, LDZC )
-
- * Near the diagonal shift chase
- DO I = NS-1, 0, -2
- DO J = 0, NP-1
- * Move down the block with index k+i+j-1, updating
- * the (ns+np x ns+np) block:
- * (k:k+ns+np,k:k+ns+np-1)
- CALL DLAQZ2( .TRUE., .TRUE., K+I+J-1, ISTARTB, ISTOPB,
- $ IHI, A, LDA, B, LDB, NBLOCK, K+1, QC, LDQC,
- $ NBLOCK, K, ZC, LDZC )
- END DO
- END DO
-
- * Update rest of the pencil
-
- * Update A(k+1:k+ns+np, k+ns+np:istopm) and
- * B(k+1:k+ns+np, k+ns+np:istopm)
- * from the left with Qc(1:ns+np,1:ns+np)'
- SHEIGHT = NS+NP
- SWIDTH = ISTOPM-( K+NS+NP )+1
- IF ( SWIDTH > 0 ) THEN
- CALL DGEMM( 'T', 'N', SHEIGHT, SWIDTH, SHEIGHT, ONE, QC,
- $ LDQC, A( K+1, K+NS+NP ), LDA, ZERO, WORK,
- $ SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, A( K+1,
- $ K+NS+NP ), LDA )
- CALL DGEMM( 'T', 'N', SHEIGHT, SWIDTH, SHEIGHT, ONE, QC,
- $ LDQC, B( K+1, K+NS+NP ), LDB, ZERO, WORK,
- $ SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, B( K+1,
- $ K+NS+NP ), LDB )
- END IF
- IF ( ILQ ) THEN
- CALL DGEMM( 'N', 'N', N, NBLOCK, NBLOCK, ONE, Q( 1, K+1 ),
- $ LDQ, QC, LDQC, ZERO, WORK, N )
- CALL DLACPY( 'ALL', N, NBLOCK, WORK, N, Q( 1, K+1 ), LDQ )
- END IF
-
- * Update A(istartm:k,k:k+ns+npos-1) and B(istartm:k,k:k+ns+npos-1)
- * from the right with Zc(1:ns+np,1:ns+np)
- SHEIGHT = K-ISTARTM+1
- SWIDTH = NBLOCK
- IF ( SHEIGHT > 0 ) THEN
- CALL DGEMM( 'N', 'N', SHEIGHT, SWIDTH, SWIDTH, ONE,
- $ A( ISTARTM, K ), LDA, ZC, LDZC, ZERO, WORK,
- $ SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT,
- $ A( ISTARTM, K ), LDA )
- CALL DGEMM( 'N', 'N', SHEIGHT, SWIDTH, SWIDTH, ONE,
- $ B( ISTARTM, K ), LDB, ZC, LDZC, ZERO, WORK,
- $ SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT,
- $ B( ISTARTM, K ), LDB )
- END IF
- IF ( ILZ ) THEN
- CALL DGEMM( 'N', 'N', N, NBLOCK, NBLOCK, ONE, Z( 1, K ),
- $ LDZ, ZC, LDZC, ZERO, WORK, N )
- CALL DLACPY( 'ALL', N, NBLOCK, WORK, N, Z( 1, K ), LDZ )
- END IF
-
- K = K+NP
-
- END DO
-
- * The following block removes the shifts from the bottom right corner
- * one by one. Updates are initially applied to A(ihi-ns+1:ihi,ihi-ns:ihi).
-
- CALL DLASET( 'FULL', NS, NS, ZERO, ONE, QC, LDQC )
- CALL DLASET( 'FULL', NS+1, NS+1, ZERO, ONE, ZC, LDZC )
-
- * istartb points to the first row we will be updating
- ISTARTB = IHI-NS+1
- * istopb points to the last column we will be updating
- ISTOPB = IHI
-
- DO I = 1, NS, 2
- * Chase the shift down to the bottom right corner
- DO ISHIFT = IHI-I-1, IHI-2
- CALL DLAQZ2( .TRUE., .TRUE., ISHIFT, ISTARTB, ISTOPB, IHI,
- $ A, LDA, B, LDB, NS, IHI-NS+1, QC, LDQC, NS+1,
- $ IHI-NS, ZC, LDZC )
- END DO
-
- END DO
-
- * Update rest of the pencil
-
- * Update A(ihi-ns+1:ihi, ihi+1:istopm)
- * from the left with Qc(1:ns,1:ns)'
- SHEIGHT = NS
- SWIDTH = ISTOPM-( IHI+1 )+1
- IF ( SWIDTH > 0 ) THEN
- CALL DGEMM( 'T', 'N', SHEIGHT, SWIDTH, SHEIGHT, ONE, QC, LDQC,
- $ A( IHI-NS+1, IHI+1 ), LDA, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT,
- $ A( IHI-NS+1, IHI+1 ), LDA )
- CALL DGEMM( 'T', 'N', SHEIGHT, SWIDTH, SHEIGHT, ONE, QC, LDQC,
- $ B( IHI-NS+1, IHI+1 ), LDB, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT,
- $ B( IHI-NS+1, IHI+1 ), LDB )
- END IF
- IF ( ILQ ) THEN
- CALL DGEMM( 'N', 'N', N, NS, NS, ONE, Q( 1, IHI-NS+1 ), LDQ,
- $ QC, LDQC, ZERO, WORK, N )
- CALL DLACPY( 'ALL', N, NS, WORK, N, Q( 1, IHI-NS+1 ), LDQ )
- END IF
-
- * Update A(istartm:ihi-ns,ihi-ns:ihi)
- * from the right with Zc(1:ns+1,1:ns+1)
- SHEIGHT = IHI-NS-ISTARTM+1
- SWIDTH = NS+1
- IF ( SHEIGHT > 0 ) THEN
- CALL DGEMM( 'N', 'N', SHEIGHT, SWIDTH, SWIDTH, ONE, A( ISTARTM,
- $ IHI-NS ), LDA, ZC, LDZC, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, A( ISTARTM,
- $ IHI-NS ), LDA )
- CALL DGEMM( 'N', 'N', SHEIGHT, SWIDTH, SWIDTH, ONE, B( ISTARTM,
- $ IHI-NS ), LDB, ZC, LDZC, ZERO, WORK, SHEIGHT )
- CALL DLACPY( 'ALL', SHEIGHT, SWIDTH, WORK, SHEIGHT, B( ISTARTM,
- $ IHI-NS ), LDB )
- END IF
- IF ( ILZ ) THEN
- CALL DGEMM( 'N', 'N', N, NS+1, NS+1, ONE, Z( 1, IHI-NS ), LDZ,
- $ ZC, LDZC, ZERO, WORK, N )
- CALL DLACPY( 'ALL', N, NS+1, WORK, N, Z( 1, IHI-NS ), LDZ )
- END IF
-
- END SUBROUTINE
|