00001 SUBROUTINE ZHET21( ITYPE, UPLO, N, KBAND, A, LDA, D, E, U, LDU, V,
00002 $ LDV, TAU, WORK, RWORK, RESULT )
00003
00004
00005
00006
00007
00008
00009 CHARACTER UPLO
00010 INTEGER ITYPE, KBAND, LDA, LDU, LDV, N
00011
00012
00013 DOUBLE PRECISION D( * ), E( * ), RESULT( 2 ), RWORK( * )
00014 COMPLEX*16 A( LDA, * ), TAU( * ), U( LDU, * ),
00015 $ V( LDV, * ), WORK( * )
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 DOUBLE PRECISION ZERO, ONE, TEN
00147 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TEN = 10.0D+0 )
00148 COMPLEX*16 CZERO, CONE
00149 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
00150 $ CONE = ( 1.0D+0, 0.0D+0 ) )
00151
00152
00153 LOGICAL LOWER
00154 CHARACTER CUPLO
00155 INTEGER IINFO, J, JCOL, JR, JROW
00156 DOUBLE PRECISION ANORM, ULP, UNFL, WNORM
00157 COMPLEX*16 VSAVE
00158
00159
00160 LOGICAL LSAME
00161 DOUBLE PRECISION DLAMCH, ZLANGE, ZLANHE
00162 EXTERNAL LSAME, DLAMCH, ZLANGE, ZLANHE
00163
00164
00165 EXTERNAL ZGEMM, ZHER, ZHER2, ZLACPY, ZLARFY, ZLASET,
00166 $ ZUNM2L, ZUNM2R
00167
00168
00169 INTRINSIC DBLE, DCMPLX, MAX, MIN
00170
00171
00172
00173 RESULT( 1 ) = ZERO
00174 IF( ITYPE.EQ.1 )
00175 $ RESULT( 2 ) = ZERO
00176 IF( N.LE.0 )
00177 $ RETURN
00178
00179 IF( LSAME( UPLO, 'U' ) ) THEN
00180 LOWER = .FALSE.
00181 CUPLO = 'U'
00182 ELSE
00183 LOWER = .TRUE.
00184 CUPLO = 'L'
00185 END IF
00186
00187 UNFL = DLAMCH( 'Safe minimum' )
00188 ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
00189
00190
00191
00192 IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
00193 RESULT( 1 ) = TEN / ULP
00194 RETURN
00195 END IF
00196
00197
00198
00199
00200
00201 IF( ITYPE.EQ.3 ) THEN
00202 ANORM = ONE
00203 ELSE
00204 ANORM = MAX( ZLANHE( '1', CUPLO, N, A, LDA, RWORK ), UNFL )
00205 END IF
00206
00207
00208
00209 IF( ITYPE.EQ.1 ) THEN
00210
00211
00212
00213 CALL ZLASET( 'Full', N, N, CZERO, CZERO, WORK, N )
00214 CALL ZLACPY( CUPLO, N, N, A, LDA, WORK, N )
00215
00216 DO 10 J = 1, N
00217 CALL ZHER( CUPLO, N, -D( J ), U( 1, J ), 1, WORK, N )
00218 10 CONTINUE
00219
00220 IF( N.GT.1 .AND. KBAND.EQ.1 ) THEN
00221 DO 20 J = 1, N - 1
00222 CALL ZHER2( CUPLO, N, -DCMPLX( E( J ) ), U( 1, J ), 1,
00223 $ U( 1, J-1 ), 1, WORK, N )
00224 20 CONTINUE
00225 END IF
00226 WNORM = ZLANHE( '1', CUPLO, N, WORK, N, RWORK )
00227
00228 ELSE IF( ITYPE.EQ.2 ) THEN
00229
00230
00231
00232 CALL ZLASET( 'Full', N, N, CZERO, CZERO, WORK, N )
00233
00234 IF( LOWER ) THEN
00235 WORK( N**2 ) = D( N )
00236 DO 40 J = N - 1, 1, -1
00237 IF( KBAND.EQ.1 ) THEN
00238 WORK( ( N+1 )*( J-1 )+2 ) = ( CONE-TAU( J ) )*E( J )
00239 DO 30 JR = J + 2, N
00240 WORK( ( J-1 )*N+JR ) = -TAU( J )*E( J )*V( JR, J )
00241 30 CONTINUE
00242 END IF
00243
00244 VSAVE = V( J+1, J )
00245 V( J+1, J ) = ONE
00246 CALL ZLARFY( 'L', N-J, V( J+1, J ), 1, TAU( J ),
00247 $ WORK( ( N+1 )*J+1 ), N, WORK( N**2+1 ) )
00248 V( J+1, J ) = VSAVE
00249 WORK( ( N+1 )*( J-1 )+1 ) = D( J )
00250 40 CONTINUE
00251 ELSE
00252 WORK( 1 ) = D( 1 )
00253 DO 60 J = 1, N - 1
00254 IF( KBAND.EQ.1 ) THEN
00255 WORK( ( N+1 )*J ) = ( CONE-TAU( J ) )*E( J )
00256 DO 50 JR = 1, J - 1
00257 WORK( J*N+JR ) = -TAU( J )*E( J )*V( JR, J+1 )
00258 50 CONTINUE
00259 END IF
00260
00261 VSAVE = V( J, J+1 )
00262 V( J, J+1 ) = ONE
00263 CALL ZLARFY( 'U', J, V( 1, J+1 ), 1, TAU( J ), WORK, N,
00264 $ WORK( N**2+1 ) )
00265 V( J, J+1 ) = VSAVE
00266 WORK( ( N+1 )*J+1 ) = D( J+1 )
00267 60 CONTINUE
00268 END IF
00269
00270 DO 90 JCOL = 1, N
00271 IF( LOWER ) THEN
00272 DO 70 JROW = JCOL, N
00273 WORK( JROW+N*( JCOL-1 ) ) = WORK( JROW+N*( JCOL-1 ) )
00274 $ - A( JROW, JCOL )
00275 70 CONTINUE
00276 ELSE
00277 DO 80 JROW = 1, JCOL
00278 WORK( JROW+N*( JCOL-1 ) ) = WORK( JROW+N*( JCOL-1 ) )
00279 $ - A( JROW, JCOL )
00280 80 CONTINUE
00281 END IF
00282 90 CONTINUE
00283 WNORM = ZLANHE( '1', CUPLO, N, WORK, N, RWORK )
00284
00285 ELSE IF( ITYPE.EQ.3 ) THEN
00286
00287
00288
00289 IF( N.LT.2 )
00290 $ RETURN
00291 CALL ZLACPY( ' ', N, N, U, LDU, WORK, N )
00292 IF( LOWER ) THEN
00293 CALL ZUNM2R( 'R', 'C', N, N-1, N-1, V( 2, 1 ), LDV, TAU,
00294 $ WORK( N+1 ), N, WORK( N**2+1 ), IINFO )
00295 ELSE
00296 CALL ZUNM2L( 'R', 'C', N, N-1, N-1, V( 1, 2 ), LDV, TAU,
00297 $ WORK, N, WORK( N**2+1 ), IINFO )
00298 END IF
00299 IF( IINFO.NE.0 ) THEN
00300 RESULT( 1 ) = TEN / ULP
00301 RETURN
00302 END IF
00303
00304 DO 100 J = 1, N
00305 WORK( ( N+1 )*( J-1 )+1 ) = WORK( ( N+1 )*( J-1 )+1 ) - CONE
00306 100 CONTINUE
00307
00308 WNORM = ZLANGE( '1', N, N, WORK, N, RWORK )
00309 END IF
00310
00311 IF( ANORM.GT.WNORM ) THEN
00312 RESULT( 1 ) = ( WNORM / ANORM ) / ( N*ULP )
00313 ELSE
00314 IF( ANORM.LT.ONE ) THEN
00315 RESULT( 1 ) = ( MIN( WNORM, N*ANORM ) / ANORM ) / ( N*ULP )
00316 ELSE
00317 RESULT( 1 ) = MIN( WNORM / ANORM, DBLE( N ) ) / ( N*ULP )
00318 END IF
00319 END IF
00320
00321
00322
00323
00324
00325 IF( ITYPE.EQ.1 ) THEN
00326 CALL ZGEMM( 'N', 'C', N, N, N, CONE, U, LDU, U, LDU, CZERO,
00327 $ WORK, N )
00328
00329 DO 110 J = 1, N
00330 WORK( ( N+1 )*( J-1 )+1 ) = WORK( ( N+1 )*( J-1 )+1 ) - CONE
00331 110 CONTINUE
00332
00333 RESULT( 2 ) = MIN( ZLANGE( '1', N, N, WORK, N, RWORK ),
00334 $ DBLE( N ) ) / ( N*ULP )
00335 END IF
00336
00337 RETURN
00338
00339
00340
00341 END