00001 SUBROUTINE SGEES( JOBVS, SORT, SELECT, N, A, LDA, SDIM, WR, WI,
00002 $ VS, LDVS, WORK, LWORK, BWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER JOBVS, SORT
00011 INTEGER INFO, LDA, LDVS, LWORK, N, SDIM
00012
00013
00014 LOGICAL BWORK( * )
00015 REAL A( LDA, * ), VS( LDVS, * ), WI( * ), WORK( * ),
00016 $ WR( * )
00017
00018
00019 LOGICAL SELECT
00020 EXTERNAL SELECT
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 REAL ZERO, ONE
00142 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
00143
00144
00145 LOGICAL CURSL, LASTSL, LQUERY, LST2SL, SCALEA, WANTST,
00146 $ WANTVS
00147 INTEGER HSWORK, I, I1, I2, IBAL, ICOND, IERR, IEVAL,
00148 $ IHI, ILO, INXT, IP, ITAU, IWRK, MAXWRK, MINWRK
00149 REAL ANRM, BIGNUM, CSCALE, EPS, S, SEP, SMLNUM
00150
00151
00152 INTEGER IDUM( 1 )
00153 REAL DUM( 1 )
00154
00155
00156 EXTERNAL SCOPY, SGEBAK, SGEBAL, SGEHRD, SHSEQR, SLABAD,
00157 $ SLACPY, SLASCL, SORGHR, SSWAP, STRSEN, XERBLA
00158
00159
00160 LOGICAL LSAME
00161 INTEGER ILAENV
00162 REAL SLAMCH, SLANGE
00163 EXTERNAL LSAME, ILAENV, SLAMCH, SLANGE
00164
00165
00166 INTRINSIC MAX, SQRT
00167
00168
00169
00170
00171
00172 INFO = 0
00173 LQUERY = ( LWORK.EQ.-1 )
00174 WANTVS = LSAME( JOBVS, 'V' )
00175 WANTST = LSAME( SORT, 'S' )
00176 IF( ( .NOT.WANTVS ) .AND. ( .NOT.LSAME( JOBVS, 'N' ) ) ) THEN
00177 INFO = -1
00178 ELSE IF( ( .NOT.WANTST ) .AND. ( .NOT.LSAME( SORT, 'N' ) ) ) THEN
00179 INFO = -2
00180 ELSE IF( N.LT.0 ) THEN
00181 INFO = -4
00182 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00183 INFO = -6
00184 ELSE IF( LDVS.LT.1 .OR. ( WANTVS .AND. LDVS.LT.N ) ) THEN
00185 INFO = -11
00186 END IF
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 IF( INFO.EQ.0 ) THEN
00199 IF( N.EQ.0 ) THEN
00200 MINWRK = 1
00201 MAXWRK = 1
00202 ELSE
00203 MAXWRK = 2*N + N*ILAENV( 1, 'SGEHRD', ' ', N, 1, N, 0 )
00204 MINWRK = 3*N
00205
00206 CALL SHSEQR( 'S', JOBVS, N, 1, N, A, LDA, WR, WI, VS, LDVS,
00207 $ WORK, -1, IEVAL )
00208 HSWORK = WORK( 1 )
00209
00210 IF( .NOT.WANTVS ) THEN
00211 MAXWRK = MAX( MAXWRK, N + HSWORK )
00212 ELSE
00213 MAXWRK = MAX( MAXWRK, 2*N + ( N - 1 )*ILAENV( 1,
00214 $ 'SORGHR', ' ', N, 1, N, -1 ) )
00215 MAXWRK = MAX( MAXWRK, N + HSWORK )
00216 END IF
00217 END IF
00218 WORK( 1 ) = MAXWRK
00219
00220 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
00221 INFO = -13
00222 END IF
00223 END IF
00224
00225 IF( INFO.NE.0 ) THEN
00226 CALL XERBLA( 'SGEES ', -INFO )
00227 RETURN
00228 ELSE IF( LQUERY ) THEN
00229 RETURN
00230 END IF
00231
00232
00233
00234 IF( N.EQ.0 ) THEN
00235 SDIM = 0
00236 RETURN
00237 END IF
00238
00239
00240
00241 EPS = SLAMCH( 'P' )
00242 SMLNUM = SLAMCH( 'S' )
00243 BIGNUM = ONE / SMLNUM
00244 CALL SLABAD( SMLNUM, BIGNUM )
00245 SMLNUM = SQRT( SMLNUM ) / EPS
00246 BIGNUM = ONE / SMLNUM
00247
00248
00249
00250 ANRM = SLANGE( 'M', N, N, A, LDA, DUM )
00251 SCALEA = .FALSE.
00252 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00253 SCALEA = .TRUE.
00254 CSCALE = SMLNUM
00255 ELSE IF( ANRM.GT.BIGNUM ) THEN
00256 SCALEA = .TRUE.
00257 CSCALE = BIGNUM
00258 END IF
00259 IF( SCALEA )
00260 $ CALL SLASCL( 'G', 0, 0, ANRM, CSCALE, N, N, A, LDA, IERR )
00261
00262
00263
00264
00265 IBAL = 1
00266 CALL SGEBAL( 'P', N, A, LDA, ILO, IHI, WORK( IBAL ), IERR )
00267
00268
00269
00270
00271 ITAU = N + IBAL
00272 IWRK = N + ITAU
00273 CALL SGEHRD( N, ILO, IHI, A, LDA, WORK( ITAU ), WORK( IWRK ),
00274 $ LWORK-IWRK+1, IERR )
00275
00276 IF( WANTVS ) THEN
00277
00278
00279
00280 CALL SLACPY( 'L', N, N, A, LDA, VS, LDVS )
00281
00282
00283
00284
00285 CALL SORGHR( N, ILO, IHI, VS, LDVS, WORK( ITAU ), WORK( IWRK ),
00286 $ LWORK-IWRK+1, IERR )
00287 END IF
00288
00289 SDIM = 0
00290
00291
00292
00293
00294 IWRK = ITAU
00295 CALL SHSEQR( 'S', JOBVS, N, ILO, IHI, A, LDA, WR, WI, VS, LDVS,
00296 $ WORK( IWRK ), LWORK-IWRK+1, IEVAL )
00297 IF( IEVAL.GT.0 )
00298 $ INFO = IEVAL
00299
00300
00301
00302 IF( WANTST .AND. INFO.EQ.0 ) THEN
00303 IF( SCALEA ) THEN
00304 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WR, N, IERR )
00305 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N, 1, WI, N, IERR )
00306 END IF
00307 DO 10 I = 1, N
00308 BWORK( I ) = SELECT( WR( I ), WI( I ) )
00309 10 CONTINUE
00310
00311
00312
00313
00314 CALL STRSEN( 'N', JOBVS, BWORK, N, A, LDA, VS, LDVS, WR, WI,
00315 $ SDIM, S, SEP, WORK( IWRK ), LWORK-IWRK+1, IDUM, 1,
00316 $ ICOND )
00317 IF( ICOND.GT.0 )
00318 $ INFO = N + ICOND
00319 END IF
00320
00321 IF( WANTVS ) THEN
00322
00323
00324
00325
00326 CALL SGEBAK( 'P', 'R', N, ILO, IHI, WORK( IBAL ), N, VS, LDVS,
00327 $ IERR )
00328 END IF
00329
00330 IF( SCALEA ) THEN
00331
00332
00333
00334 CALL SLASCL( 'H', 0, 0, CSCALE, ANRM, N, N, A, LDA, IERR )
00335 CALL SCOPY( N, A, LDA+1, WR, 1 )
00336 IF( CSCALE.EQ.SMLNUM ) THEN
00337
00338
00339
00340
00341
00342 IF( IEVAL.GT.0 ) THEN
00343 I1 = IEVAL + 1
00344 I2 = IHI - 1
00345 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, ILO-1, 1, WI,
00346 $ MAX( ILO-1, 1 ), IERR )
00347 ELSE IF( WANTST ) THEN
00348 I1 = 1
00349 I2 = N - 1
00350 ELSE
00351 I1 = ILO
00352 I2 = IHI - 1
00353 END IF
00354 INXT = I1 - 1
00355 DO 20 I = I1, I2
00356 IF( I.LT.INXT )
00357 $ GO TO 20
00358 IF( WI( I ).EQ.ZERO ) THEN
00359 INXT = I + 1
00360 ELSE
00361 IF( A( I+1, I ).EQ.ZERO ) THEN
00362 WI( I ) = ZERO
00363 WI( I+1 ) = ZERO
00364 ELSE IF( A( I+1, I ).NE.ZERO .AND. A( I, I+1 ).EQ.
00365 $ ZERO ) THEN
00366 WI( I ) = ZERO
00367 WI( I+1 ) = ZERO
00368 IF( I.GT.1 )
00369 $ CALL SSWAP( I-1, A( 1, I ), 1, A( 1, I+1 ), 1 )
00370 IF( N.GT.I+1 )
00371 $ CALL SSWAP( N-I-1, A( I, I+2 ), LDA,
00372 $ A( I+1, I+2 ), LDA )
00373 IF( WANTVS ) THEN
00374 CALL SSWAP( N, VS( 1, I ), 1, VS( 1, I+1 ), 1 )
00375 END IF
00376 A( I, I+1 ) = A( I+1, I )
00377 A( I+1, I ) = ZERO
00378 END IF
00379 INXT = I + 2
00380 END IF
00381 20 CONTINUE
00382 END IF
00383
00384
00385
00386 CALL SLASCL( 'G', 0, 0, CSCALE, ANRM, N-IEVAL, 1,
00387 $ WI( IEVAL+1 ), MAX( N-IEVAL, 1 ), IERR )
00388 END IF
00389
00390 IF( WANTST .AND. INFO.EQ.0 ) THEN
00391
00392
00393
00394 LASTSL = .TRUE.
00395 LST2SL = .TRUE.
00396 SDIM = 0
00397 IP = 0
00398 DO 30 I = 1, N
00399 CURSL = SELECT( WR( I ), WI( I ) )
00400 IF( WI( I ).EQ.ZERO ) THEN
00401 IF( CURSL )
00402 $ SDIM = SDIM + 1
00403 IP = 0
00404 IF( CURSL .AND. .NOT.LASTSL )
00405 $ INFO = N + 2
00406 ELSE
00407 IF( IP.EQ.1 ) THEN
00408
00409
00410
00411 CURSL = CURSL .OR. LASTSL
00412 LASTSL = CURSL
00413 IF( CURSL )
00414 $ SDIM = SDIM + 2
00415 IP = -1
00416 IF( CURSL .AND. .NOT.LST2SL )
00417 $ INFO = N + 2
00418 ELSE
00419
00420
00421
00422 IP = 1
00423 END IF
00424 END IF
00425 LST2SL = LASTSL
00426 LASTSL = CURSL
00427 30 CONTINUE
00428 END IF
00429
00430 WORK( 1 ) = MAXWRK
00431 RETURN
00432
00433
00434
00435 END