00001 SUBROUTINE DSPT21( ITYPE, UPLO, N, KBAND, AP, D, E, U, LDU, VP,
00002 $ TAU, WORK, RESULT )
00003
00004
00005
00006
00007
00008
00009 CHARACTER UPLO
00010 INTEGER ITYPE, KBAND, LDU, N
00011
00012
00013 DOUBLE PRECISION AP( * ), D( * ), E( * ), RESULT( 2 ), TAU( * ),
00014 $ U( LDU, * ), VP( * ), WORK( * )
00015
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
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 DOUBLE PRECISION ZERO, ONE, TEN
00163 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TEN = 10.0D0 )
00164 DOUBLE PRECISION HALF
00165 PARAMETER ( HALF = 1.0D+0 / 2.0D+0 )
00166
00167
00168 LOGICAL LOWER
00169 CHARACTER CUPLO
00170 INTEGER IINFO, J, JP, JP1, JR, LAP
00171 DOUBLE PRECISION ANORM, TEMP, ULP, UNFL, VSAVE, WNORM
00172
00173
00174 LOGICAL LSAME
00175 DOUBLE PRECISION DDOT, DLAMCH, DLANGE, DLANSP
00176 EXTERNAL LSAME, DDOT, DLAMCH, DLANGE, DLANSP
00177
00178
00179 EXTERNAL DAXPY, DCOPY, DGEMM, DLACPY, DLASET, DOPMTR,
00180 $ DSPMV, DSPR, DSPR2
00181
00182
00183 INTRINSIC DBLE, MAX, MIN
00184
00185
00186
00187
00188
00189 RESULT( 1 ) = ZERO
00190 IF( ITYPE.EQ.1 )
00191 $ RESULT( 2 ) = ZERO
00192 IF( N.LE.0 )
00193 $ RETURN
00194
00195 LAP = ( N*( N+1 ) ) / 2
00196
00197 IF( LSAME( UPLO, 'U' ) ) THEN
00198 LOWER = .FALSE.
00199 CUPLO = 'U'
00200 ELSE
00201 LOWER = .TRUE.
00202 CUPLO = 'L'
00203 END IF
00204
00205 UNFL = DLAMCH( 'Safe minimum' )
00206 ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
00207
00208
00209
00210 IF( ITYPE.LT.1 .OR. ITYPE.GT.3 ) THEN
00211 RESULT( 1 ) = TEN / ULP
00212 RETURN
00213 END IF
00214
00215
00216
00217
00218
00219 IF( ITYPE.EQ.3 ) THEN
00220 ANORM = ONE
00221 ELSE
00222 ANORM = MAX( DLANSP( '1', CUPLO, N, AP, WORK ), UNFL )
00223 END IF
00224
00225
00226
00227 IF( ITYPE.EQ.1 ) THEN
00228
00229
00230
00231 CALL DLASET( 'Full', N, N, ZERO, ZERO, WORK, N )
00232 CALL DCOPY( LAP, AP, 1, WORK, 1 )
00233
00234 DO 10 J = 1, N
00235 CALL DSPR( CUPLO, N, -D( J ), U( 1, J ), 1, WORK )
00236 10 CONTINUE
00237
00238 IF( N.GT.1 .AND. KBAND.EQ.1 ) THEN
00239 DO 20 J = 1, N - 1
00240 CALL DSPR2( CUPLO, N, -E( J ), U( 1, J ), 1, U( 1, J+1 ),
00241 $ 1, WORK )
00242 20 CONTINUE
00243 END IF
00244 WNORM = DLANSP( '1', CUPLO, N, WORK, WORK( N**2+1 ) )
00245
00246 ELSE IF( ITYPE.EQ.2 ) THEN
00247
00248
00249
00250 CALL DLASET( 'Full', N, N, ZERO, ZERO, WORK, N )
00251
00252 IF( LOWER ) THEN
00253 WORK( LAP ) = D( N )
00254 DO 40 J = N - 1, 1, -1
00255 JP = ( ( 2*N-J )*( J-1 ) ) / 2
00256 JP1 = JP + N - J
00257 IF( KBAND.EQ.1 ) THEN
00258 WORK( JP+J+1 ) = ( ONE-TAU( J ) )*E( J )
00259 DO 30 JR = J + 2, N
00260 WORK( JP+JR ) = -TAU( J )*E( J )*VP( JP+JR )
00261 30 CONTINUE
00262 END IF
00263
00264 IF( TAU( J ).NE.ZERO ) THEN
00265 VSAVE = VP( JP+J+1 )
00266 VP( JP+J+1 ) = ONE
00267 CALL DSPMV( 'L', N-J, ONE, WORK( JP1+J+1 ),
00268 $ VP( JP+J+1 ), 1, ZERO, WORK( LAP+1 ), 1 )
00269 TEMP = -HALF*TAU( J )*DDOT( N-J, WORK( LAP+1 ), 1,
00270 $ VP( JP+J+1 ), 1 )
00271 CALL DAXPY( N-J, TEMP, VP( JP+J+1 ), 1, WORK( LAP+1 ),
00272 $ 1 )
00273 CALL DSPR2( 'L', N-J, -TAU( J ), VP( JP+J+1 ), 1,
00274 $ WORK( LAP+1 ), 1, WORK( JP1+J+1 ) )
00275 VP( JP+J+1 ) = VSAVE
00276 END IF
00277 WORK( JP+J ) = D( J )
00278 40 CONTINUE
00279 ELSE
00280 WORK( 1 ) = D( 1 )
00281 DO 60 J = 1, N - 1
00282 JP = ( J*( J-1 ) ) / 2
00283 JP1 = JP + J
00284 IF( KBAND.EQ.1 ) THEN
00285 WORK( JP1+J ) = ( ONE-TAU( J ) )*E( J )
00286 DO 50 JR = 1, J - 1
00287 WORK( JP1+JR ) = -TAU( J )*E( J )*VP( JP1+JR )
00288 50 CONTINUE
00289 END IF
00290
00291 IF( TAU( J ).NE.ZERO ) THEN
00292 VSAVE = VP( JP1+J )
00293 VP( JP1+J ) = ONE
00294 CALL DSPMV( 'U', J, ONE, WORK, VP( JP1+1 ), 1, ZERO,
00295 $ WORK( LAP+1 ), 1 )
00296 TEMP = -HALF*TAU( J )*DDOT( J, WORK( LAP+1 ), 1,
00297 $ VP( JP1+1 ), 1 )
00298 CALL DAXPY( J, TEMP, VP( JP1+1 ), 1, WORK( LAP+1 ),
00299 $ 1 )
00300 CALL DSPR2( 'U', J, -TAU( J ), VP( JP1+1 ), 1,
00301 $ WORK( LAP+1 ), 1, WORK )
00302 VP( JP1+J ) = VSAVE
00303 END IF
00304 WORK( JP1+J+1 ) = D( J+1 )
00305 60 CONTINUE
00306 END IF
00307
00308 DO 70 J = 1, LAP
00309 WORK( J ) = WORK( J ) - AP( J )
00310 70 CONTINUE
00311 WNORM = DLANSP( '1', CUPLO, N, WORK, WORK( LAP+1 ) )
00312
00313 ELSE IF( ITYPE.EQ.3 ) THEN
00314
00315
00316
00317 IF( N.LT.2 )
00318 $ RETURN
00319 CALL DLACPY( ' ', N, N, U, LDU, WORK, N )
00320 CALL DOPMTR( 'R', CUPLO, 'T', N, N, VP, TAU, WORK, N,
00321 $ WORK( N**2+1 ), IINFO )
00322 IF( IINFO.NE.0 ) THEN
00323 RESULT( 1 ) = TEN / ULP
00324 RETURN
00325 END IF
00326
00327 DO 80 J = 1, N
00328 WORK( ( N+1 )*( J-1 )+1 ) = WORK( ( N+1 )*( J-1 )+1 ) - ONE
00329 80 CONTINUE
00330
00331 WNORM = DLANGE( '1', N, N, WORK, N, WORK( N**2+1 ) )
00332 END IF
00333
00334 IF( ANORM.GT.WNORM ) THEN
00335 RESULT( 1 ) = ( WNORM / ANORM ) / ( N*ULP )
00336 ELSE
00337 IF( ANORM.LT.ONE ) THEN
00338 RESULT( 1 ) = ( MIN( WNORM, N*ANORM ) / ANORM ) / ( N*ULP )
00339 ELSE
00340 RESULT( 1 ) = MIN( WNORM / ANORM, DBLE( N ) ) / ( N*ULP )
00341 END IF
00342 END IF
00343
00344
00345
00346
00347
00348 IF( ITYPE.EQ.1 ) THEN
00349 CALL DGEMM( 'N', 'C', N, N, N, ONE, U, LDU, U, LDU, ZERO, WORK,
00350 $ N )
00351
00352 DO 90 J = 1, N
00353 WORK( ( N+1 )*( J-1 )+1 ) = WORK( ( N+1 )*( J-1 )+1 ) - ONE
00354 90 CONTINUE
00355
00356 RESULT( 2 ) = MIN( DLANGE( '1', N, N, WORK, N,
00357 $ WORK( N**2+1 ) ), DBLE( N ) ) / ( N*ULP )
00358 END IF
00359
00360 RETURN
00361
00362
00363
00364 END