188 SUBROUTINE sgeev( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL,
190 $ LDVR, WORK, LWORK, INFO )
198 CHARACTER JOBVL, JOBVR
199 INTEGER INFO, LDA, LDVL, LDVR, LWORK, N
202 REAL A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
203 $ WI( * ), WORK( * ), WR( * )
210 PARAMETER ( ZERO = 0.0e0, one = 1.0e0 )
213 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR
215 INTEGER HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
216 $ lwork_trevc, maxwrk, minwrk, nout
217 REAL ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
232 INTEGER ISAMAX, ILAENV
233 REAL SLAMCH, SLANGE, SLAPY2, SNRM2,
235 EXTERNAL lsame, isamax, ilaenv,
236 $ slamch, slange, slapy2,
247 lquery = ( lwork.EQ.-1 )
248 wantvl = lsame( jobvl,
'V' )
249 wantvr = lsame( jobvr,
'V' )
250 IF( ( .NOT.wantvl ) .AND. ( .NOT.lsame( jobvl,
'N' ) ) )
THEN
252 ELSE IF( ( .NOT.wantvr ) .AND.
253 $ ( .NOT.lsame( jobvr,
'N' ) ) )
THEN
255 ELSE IF( n.LT.0 )
THEN
257 ELSE IF( lda.LT.max( 1, n ) )
THEN
259 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN
261 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN
280 maxwrk = 2*n + n*ilaenv( 1,
'SGEHRD',
' ', n, 1, n, 0 )
283 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
284 $
'SORGHR',
' ', n, 1, n, -1 ) )
285 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vl,
288 hswork = int( work(1) )
289 maxwrk = max( maxwrk, n + 1, n + hswork )
290 CALL strevc3(
'L',
'B',
SELECT, n, a, lda,
291 $ vl, ldvl, vr, ldvr, n, nout,
293 lwork_trevc = int( work(1) )
294 maxwrk = max( maxwrk, n + lwork_trevc )
295 maxwrk = max( maxwrk, 4*n )
296 ELSE IF( wantvr )
THEN
298 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
299 $
'SORGHR',
' ', n, 1, n, -1 ) )
300 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vr,
303 hswork = int( work(1) )
304 maxwrk = max( maxwrk, n + 1, n + hswork )
305 CALL strevc3(
'R',
'B',
SELECT, n, a, lda,
306 $ vl, ldvl, vr, ldvr, n, nout,
308 lwork_trevc = int( work(1) )
309 maxwrk = max( maxwrk, n + lwork_trevc )
310 maxwrk = max( maxwrk, 4*n )
313 CALL shseqr(
'E',
'N', n, 1, n, a, lda, wr, wi, vr,
316 hswork = int( work(1) )
317 maxwrk = max( maxwrk, n + 1, n + hswork )
319 maxwrk = max( maxwrk, minwrk )
323 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
329 CALL xerbla(
'SGEEV ', -info )
331 ELSE IF( lquery )
THEN
343 smlnum = slamch(
'S' )
344 bignum = one / smlnum
345 smlnum = sqrt( smlnum ) / eps
346 bignum = one / smlnum
350 anrm = slange(
'M', n, n, a, lda, dum )
352 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
355 ELSE IF( anrm.GT.bignum )
THEN
360 $
CALL slascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
366 CALL sgebal(
'B', n, a, lda, ilo, ihi, work( ibal ), ierr )
373 CALL sgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
374 $ lwork-iwrk+1, ierr )
382 CALL slacpy(
'L', n, n, a, lda, vl, ldvl )
387 CALL sorghr( n, ilo, ihi, vl, ldvl, work( itau ),
389 $ lwork-iwrk+1, ierr )
395 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vl,
397 $ work( iwrk ), lwork-iwrk+1, info )
405 CALL slacpy(
'F', n, n, vl, ldvl, vr, ldvr )
408 ELSE IF( wantvr )
THEN
414 CALL slacpy(
'L', n, n, a, lda, vr, ldvr )
419 CALL sorghr( n, ilo, ihi, vr, ldvr, work( itau ),
421 $ lwork-iwrk+1, ierr )
427 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vr,
429 $ work( iwrk ), lwork-iwrk+1, info )
437 CALL shseqr(
'E',
'N', n, ilo, ihi, a, lda, wr, wi, vr,
439 $ work( iwrk ), lwork-iwrk+1, info )
447 IF( wantvl .OR. wantvr )
THEN
452 CALL strevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr,
454 $ n, nout, work( iwrk ), lwork-iwrk+1, ierr )
462 CALL sgebak(
'B',
'L', n, ilo, ihi, work( ibal ), n, vl,
469 IF( wi( i ).EQ.zero )
THEN
470 scl = one / snrm2( n, vl( 1, i ), 1 )
471 CALL sscal( n, scl, vl( 1, i ), 1 )
472 ELSE IF( wi( i ).GT.zero )
THEN
473 scl = one / slapy2( snrm2( n, vl( 1, i ), 1 ),
474 $ snrm2( n, vl( 1, i+1 ), 1 ) )
475 CALL sscal( n, scl, vl( 1, i ), 1 )
476 CALL sscal( n, scl, vl( 1, i+1 ), 1 )
478 work( iwrk+k-1 ) = vl( k, i )**2 + vl( k, i+1 )**2
480 k = isamax( n, work( iwrk ), 1 )
481 CALL slartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
482 CALL srot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
493 CALL sgebak(
'B',
'R', n, ilo, ihi, work( ibal ), n, vr,
500 IF( wi( i ).EQ.zero )
THEN
501 scl = one / snrm2( n, vr( 1, i ), 1 )
502 CALL sscal( n, scl, vr( 1, i ), 1 )
503 ELSE IF( wi( i ).GT.zero )
THEN
504 scl = one / slapy2( snrm2( n, vr( 1, i ), 1 ),
505 $ snrm2( n, vr( 1, i+1 ), 1 ) )
506 CALL sscal( n, scl, vr( 1, i ), 1 )
507 CALL sscal( n, scl, vr( 1, i+1 ), 1 )
509 work( iwrk+k-1 ) = vr( k, i )**2 + vr( k, i+1 )**2
511 k = isamax( n, work( iwrk ), 1 )
512 CALL slartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
513 CALL srot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
523 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1,
525 $ max( n-info, 1 ), ierr )
526 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1,
528 $ max( n-info, 1 ), ierr )
530 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
532 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,