1*> \brief \b ZSTT22 2* 3* =========== DOCUMENTATION =========== 4* 5* Online html documentation available at 6* http://www.netlib.org/lapack/explore-html/ 7* 8* Definition: 9* =========== 10* 11* SUBROUTINE ZSTT22( N, M, KBAND, AD, AE, SD, SE, U, LDU, WORK, 12* LDWORK, RWORK, RESULT ) 13* 14* .. Scalar Arguments .. 15* INTEGER KBAND, LDU, LDWORK, M, N 16* .. 17* .. Array Arguments .. 18* DOUBLE PRECISION AD( * ), AE( * ), RESULT( 2 ), RWORK( * ), 19* $ SD( * ), SE( * ) 20* COMPLEX*16 U( LDU, * ), WORK( LDWORK, * ) 21* .. 22* 23* 24*> \par Purpose: 25* ============= 26*> 27*> \verbatim 28*> 29*> ZSTT22 checks a set of M eigenvalues and eigenvectors, 30*> 31*> A U = U S 32*> 33*> where A is Hermitian tridiagonal, the columns of U are unitary, 34*> and S is diagonal (if KBAND=0) or Hermitian tridiagonal (if KBAND=1). 35*> Two tests are performed: 36*> 37*> RESULT(1) = | U* A U - S | / ( |A| m ulp ) 38*> 39*> RESULT(2) = | I - U*U | / ( m ulp ) 40*> \endverbatim 41* 42* Arguments: 43* ========== 44* 45*> \param[in] N 46*> \verbatim 47*> N is INTEGER 48*> The size of the matrix. If it is zero, ZSTT22 does nothing. 49*> It must be at least zero. 50*> \endverbatim 51*> 52*> \param[in] M 53*> \verbatim 54*> M is INTEGER 55*> The number of eigenpairs to check. If it is zero, ZSTT22 56*> does nothing. It must be at least zero. 57*> \endverbatim 58*> 59*> \param[in] KBAND 60*> \verbatim 61*> KBAND is INTEGER 62*> The bandwidth of the matrix S. It may only be zero or one. 63*> If zero, then S is diagonal, and SE is not referenced. If 64*> one, then S is Hermitian tri-diagonal. 65*> \endverbatim 66*> 67*> \param[in] AD 68*> \verbatim 69*> AD is DOUBLE PRECISION array, dimension (N) 70*> The diagonal of the original (unfactored) matrix A. A is 71*> assumed to be Hermitian tridiagonal. 72*> \endverbatim 73*> 74*> \param[in] AE 75*> \verbatim 76*> AE is DOUBLE PRECISION array, dimension (N) 77*> The off-diagonal of the original (unfactored) matrix A. A 78*> is assumed to be Hermitian tridiagonal. AE(1) is ignored, 79*> AE(2) is the (1,2) and (2,1) element, etc. 80*> \endverbatim 81*> 82*> \param[in] SD 83*> \verbatim 84*> SD is DOUBLE PRECISION array, dimension (N) 85*> The diagonal of the (Hermitian tri-) diagonal matrix S. 86*> \endverbatim 87*> 88*> \param[in] SE 89*> \verbatim 90*> SE is DOUBLE PRECISION array, dimension (N) 91*> The off-diagonal of the (Hermitian tri-) diagonal matrix S. 92*> Not referenced if KBSND=0. If KBAND=1, then AE(1) is 93*> ignored, SE(2) is the (1,2) and (2,1) element, etc. 94*> \endverbatim 95*> 96*> \param[in] U 97*> \verbatim 98*> U is DOUBLE PRECISION array, dimension (LDU, N) 99*> The unitary matrix in the decomposition. 100*> \endverbatim 101*> 102*> \param[in] LDU 103*> \verbatim 104*> LDU is INTEGER 105*> The leading dimension of U. LDU must be at least N. 106*> \endverbatim 107*> 108*> \param[out] WORK 109*> \verbatim 110*> WORK is COMPLEX*16 array, dimension (LDWORK, M+1) 111*> \endverbatim 112*> 113*> \param[in] LDWORK 114*> \verbatim 115*> LDWORK is INTEGER 116*> The leading dimension of WORK. LDWORK must be at least 117*> max(1,M). 118*> \endverbatim 119*> 120*> \param[out] RWORK 121*> \verbatim 122*> RWORK is DOUBLE PRECISION array, dimension (N) 123*> \endverbatim 124*> 125*> \param[out] RESULT 126*> \verbatim 127*> RESULT is DOUBLE PRECISION array, dimension (2) 128*> The values computed by the two tests described above. The 129*> values are currently limited to 1/ulp, to avoid overflow. 130*> \endverbatim 131* 132* Authors: 133* ======== 134* 135*> \author Univ. of Tennessee 136*> \author Univ. of California Berkeley 137*> \author Univ. of Colorado Denver 138*> \author NAG Ltd. 139* 140*> \ingroup complex16_eig 141* 142* ===================================================================== 143 SUBROUTINE ZSTT22( N, M, KBAND, AD, AE, SD, SE, U, LDU, WORK, 144 $ LDWORK, RWORK, RESULT ) 145* 146* -- LAPACK test routine -- 147* -- LAPACK is a software package provided by Univ. of Tennessee, -- 148* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 149* 150* .. Scalar Arguments .. 151 INTEGER KBAND, LDU, LDWORK, M, N 152* .. 153* .. Array Arguments .. 154 DOUBLE PRECISION AD( * ), AE( * ), RESULT( 2 ), RWORK( * ), 155 $ SD( * ), SE( * ) 156 COMPLEX*16 U( LDU, * ), WORK( LDWORK, * ) 157* .. 158* 159* ===================================================================== 160* 161* .. Parameters .. 162 DOUBLE PRECISION ZERO, ONE 163 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) 164 COMPLEX*16 CZERO, CONE 165 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ), 166 $ CONE = ( 1.0D+0, 0.0D+0 ) ) 167* .. 168* .. Local Scalars .. 169 INTEGER I, J, K 170 DOUBLE PRECISION ANORM, ULP, UNFL, WNORM 171 COMPLEX*16 AUKJ 172* .. 173* .. External Functions .. 174 DOUBLE PRECISION DLAMCH, ZLANGE, ZLANSY 175 EXTERNAL DLAMCH, ZLANGE, ZLANSY 176* .. 177* .. External Subroutines .. 178 EXTERNAL ZGEMM 179* .. 180* .. Intrinsic Functions .. 181 INTRINSIC ABS, DBLE, MAX, MIN 182* .. 183* .. Executable Statements .. 184* 185 RESULT( 1 ) = ZERO 186 RESULT( 2 ) = ZERO 187 IF( N.LE.0 .OR. M.LE.0 ) 188 $ RETURN 189* 190 UNFL = DLAMCH( 'Safe minimum' ) 191 ULP = DLAMCH( 'Epsilon' ) 192* 193* Do Test 1 194* 195* Compute the 1-norm of A. 196* 197 IF( N.GT.1 ) THEN 198 ANORM = ABS( AD( 1 ) ) + ABS( AE( 1 ) ) 199 DO 10 J = 2, N - 1 200 ANORM = MAX( ANORM, ABS( AD( J ) )+ABS( AE( J ) )+ 201 $ ABS( AE( J-1 ) ) ) 202 10 CONTINUE 203 ANORM = MAX( ANORM, ABS( AD( N ) )+ABS( AE( N-1 ) ) ) 204 ELSE 205 ANORM = ABS( AD( 1 ) ) 206 END IF 207 ANORM = MAX( ANORM, UNFL ) 208* 209* Norm of U*AU - S 210* 211 DO 40 I = 1, M 212 DO 30 J = 1, M 213 WORK( I, J ) = CZERO 214 DO 20 K = 1, N 215 AUKJ = AD( K )*U( K, J ) 216 IF( K.NE.N ) 217 $ AUKJ = AUKJ + AE( K )*U( K+1, J ) 218 IF( K.NE.1 ) 219 $ AUKJ = AUKJ + AE( K-1 )*U( K-1, J ) 220 WORK( I, J ) = WORK( I, J ) + U( K, I )*AUKJ 221 20 CONTINUE 222 30 CONTINUE 223 WORK( I, I ) = WORK( I, I ) - SD( I ) 224 IF( KBAND.EQ.1 ) THEN 225 IF( I.NE.1 ) 226 $ WORK( I, I-1 ) = WORK( I, I-1 ) - SE( I-1 ) 227 IF( I.NE.N ) 228 $ WORK( I, I+1 ) = WORK( I, I+1 ) - SE( I ) 229 END IF 230 40 CONTINUE 231* 232 WNORM = ZLANSY( '1', 'L', M, WORK, M, RWORK ) 233* 234 IF( ANORM.GT.WNORM ) THEN 235 RESULT( 1 ) = ( WNORM / ANORM ) / ( M*ULP ) 236 ELSE 237 IF( ANORM.LT.ONE ) THEN 238 RESULT( 1 ) = ( MIN( WNORM, M*ANORM ) / ANORM ) / ( M*ULP ) 239 ELSE 240 RESULT( 1 ) = MIN( WNORM / ANORM, DBLE( M ) ) / ( M*ULP ) 241 END IF 242 END IF 243* 244* Do Test 2 245* 246* Compute U*U - I 247* 248 CALL ZGEMM( 'T', 'N', M, M, N, CONE, U, LDU, U, LDU, CZERO, WORK, 249 $ M ) 250* 251 DO 50 J = 1, M 252 WORK( J, J ) = WORK( J, J ) - ONE 253 50 CONTINUE 254* 255 RESULT( 2 ) = MIN( DBLE( M ), ZLANGE( '1', M, M, WORK, M, 256 $ RWORK ) ) / ( M*ULP ) 257* 258 RETURN 259* 260* End of ZSTT22 261* 262 END 263