190 SUBROUTINE sgeev( JOBVL, JOBVR, N, A, LDA, WR, WI, VL, LDVL, VR,
191 $ LDVR, WORK, LWORK, INFO )
199 CHARACTER JOBVL, JOBVR
200 INTEGER INFO, LDA, LDVL, LDVR, LWORK, N
203 REAL A( LDA, * ), VL( LDVL, * ), VR( LDVR, * ),
204 $ wi( * ), work( * ), wr( * )
211 parameter( zero = 0.0e0, one = 1.0e0 )
214 LOGICAL LQUERY, SCALEA, WANTVL, WANTVR
216 INTEGER HSWORK, I, IBAL, IERR, IHI, ILO, ITAU, IWRK, K,
217 $ lwork_trevc, maxwrk, minwrk, nout
218 REAL ANRM, BIGNUM, CS, CSCALE, EPS, R, SCL, SMLNUM,
231 INTEGER ISAMAX, ILAENV
232 REAL SLAMCH, SLANGE, SLAPY2, SNRM2, SROUNDUP_LWORK
233 EXTERNAL lsame, isamax, ilaenv, slamch, slange, slapy2,
234 $ snrm2, sroundup_lwork
244 lquery = ( lwork.EQ.-1 )
245 wantvl = lsame( jobvl,
'V' )
246 wantvr = lsame( jobvr,
'V' )
247 IF( ( .NOT.wantvl ) .AND. ( .NOT.lsame( jobvl,
'N' ) ) )
THEN
249 ELSE IF( ( .NOT.wantvr ) .AND. ( .NOT.lsame( jobvr,
'N' ) ) )
THEN
251 ELSE IF( n.LT.0 )
THEN
253 ELSE IF( lda.LT.max( 1, n ) )
THEN
255 ELSE IF( ldvl.LT.1 .OR. ( wantvl .AND. ldvl.LT.n ) )
THEN
257 ELSE IF( ldvr.LT.1 .OR. ( wantvr .AND. ldvr.LT.n ) )
THEN
276 maxwrk = 2*n + n*ilaenv( 1,
'SGEHRD',
' ', n, 1, n, 0 )
279 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
280 $
'SORGHR',
' ', n, 1, n, -1 ) )
281 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vl, ldvl,
283 hswork = int( work(1) )
284 maxwrk = max( maxwrk, n + 1, n + hswork )
285 CALL strevc3(
'L',
'B',
SELECT, n, a, lda,
286 $ vl, ldvl, vr, ldvr, n, nout,
288 lwork_trevc = int( work(1) )
289 maxwrk = max( maxwrk, n + lwork_trevc )
290 maxwrk = max( maxwrk, 4*n )
291 ELSE IF( wantvr )
THEN
293 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
294 $
'SORGHR',
' ', n, 1, n, -1 ) )
295 CALL shseqr(
'S',
'V', n, 1, n, a, lda, wr, wi, vr, ldvr,
297 hswork = int( work(1) )
298 maxwrk = max( maxwrk, n + 1, n + hswork )
299 CALL strevc3(
'R',
'B',
SELECT, n, a, lda,
300 $ vl, ldvl, vr, ldvr, n, nout,
302 lwork_trevc = int( work(1) )
303 maxwrk = max( maxwrk, n + lwork_trevc )
304 maxwrk = max( maxwrk, 4*n )
307 CALL shseqr(
'E',
'N', n, 1, n, a, lda, wr, wi, vr, ldvr,
309 hswork = int( work(1) )
310 maxwrk = max( maxwrk, n + 1, n + hswork )
312 maxwrk = max( maxwrk, minwrk )
314 work( 1 ) = sroundup_lwork(maxwrk)
316 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
322 CALL xerbla(
'SGEEV ', -info )
324 ELSE IF( lquery )
THEN
336 smlnum = slamch(
'S' )
337 bignum = one / smlnum
338 smlnum = sqrt( smlnum ) / eps
339 bignum = one / smlnum
343 anrm = slange(
'M', n, n, a, lda, dum )
345 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
348 ELSE IF( anrm.GT.bignum )
THEN
353 $
CALL slascl(
'G', 0, 0, anrm, cscale, n, n, a, lda, ierr )
359 CALL sgebal(
'B', n, a, lda, ilo, ihi, work( ibal ), ierr )
366 CALL sgehrd( n, ilo, ihi, a, lda, work( itau ), work( iwrk ),
367 $ lwork-iwrk+1, ierr )
375 CALL slacpy(
'L', n, n, a, lda, vl, ldvl )
380 CALL sorghr( n, ilo, ihi, vl, ldvl, work( itau ), work( iwrk ),
381 $ lwork-iwrk+1, ierr )
387 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vl, ldvl,
388 $ work( iwrk ), lwork-iwrk+1, info )
396 CALL slacpy(
'F', n, n, vl, ldvl, vr, ldvr )
399 ELSE IF( wantvr )
THEN
405 CALL slacpy(
'L', n, n, a, lda, vr, ldvr )
410 CALL sorghr( n, ilo, ihi, vr, ldvr, work( itau ), work( iwrk ),
411 $ lwork-iwrk+1, ierr )
417 CALL shseqr(
'S',
'V', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
418 $ work( iwrk ), lwork-iwrk+1, info )
426 CALL shseqr(
'E',
'N', n, ilo, ihi, a, lda, wr, wi, vr, ldvr,
427 $ work( iwrk ), lwork-iwrk+1, info )
435 IF( wantvl .OR. wantvr )
THEN
440 CALL strevc3( side,
'B',
SELECT, n, a, lda, vl, ldvl, vr, ldvr,
441 $ n, nout, work( iwrk ), lwork-iwrk+1, ierr )
449 CALL sgebak(
'B',
'L', n, ilo, ihi, work( ibal ), n, vl, ldvl,
455 IF( wi( i ).EQ.zero )
THEN
456 scl = one / snrm2( n, vl( 1, i ), 1 )
457 CALL sscal( n, scl, vl( 1, i ), 1 )
458 ELSE IF( wi( i ).GT.zero )
THEN
459 scl = one / slapy2( snrm2( n, vl( 1, i ), 1 ),
460 $ snrm2( n, vl( 1, i+1 ), 1 ) )
461 CALL sscal( n, scl, vl( 1, i ), 1 )
462 CALL sscal( n, scl, vl( 1, i+1 ), 1 )
464 work( iwrk+k-1 ) = vl( k, i )**2 + vl( k, i+1 )**2
466 k = isamax( n, work( iwrk ), 1 )
467 CALL slartg( vl( k, i ), vl( k, i+1 ), cs, sn, r )
468 CALL srot( n, vl( 1, i ), 1, vl( 1, i+1 ), 1, cs, sn )
479 CALL sgebak(
'B',
'R', n, ilo, ihi, work( ibal ), n, vr, ldvr,
485 IF( wi( i ).EQ.zero )
THEN
486 scl = one / snrm2( n, vr( 1, i ), 1 )
487 CALL sscal( n, scl, vr( 1, i ), 1 )
488 ELSE IF( wi( i ).GT.zero )
THEN
489 scl = one / slapy2( snrm2( n, vr( 1, i ), 1 ),
490 $ snrm2( n, vr( 1, i+1 ), 1 ) )
491 CALL sscal( n, scl, vr( 1, i ), 1 )
492 CALL sscal( n, scl, vr( 1, i+1 ), 1 )
494 work( iwrk+k-1 ) = vr( k, i )**2 + vr( k, i+1 )**2
496 k = isamax( n, work( iwrk ), 1 )
497 CALL slartg( vr( k, i ), vr( k, i+1 ), cs, sn, r )
498 CALL srot( n, vr( 1, i ), 1, vr( 1, i+1 ), 1, cs, sn )
508 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1, wr( info+1 ),
509 $ max( n-info, 1 ), ierr )
510 CALL slascl(
'G', 0, 0, cscale, anrm, n-info, 1, wi( info+1 ),
511 $ max( n-info, 1 ), ierr )
513 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wr, n,
515 CALL slascl(
'G', 0, 0, cscale, anrm, ilo-1, 1, wi, n,
520 work( 1 ) = sroundup_lwork(maxwrk)
subroutine xerbla(srname, info)
subroutine sgebak(job, side, n, ilo, ihi, scale, m, v, ldv, info)
SGEBAK
subroutine sgebal(job, n, a, lda, ilo, ihi, scale, info)
SGEBAL
subroutine sgeev(jobvl, jobvr, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork, info)
SGEEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for GE matrices
subroutine sgehrd(n, ilo, ihi, a, lda, tau, work, lwork, info)
SGEHRD
subroutine shseqr(job, compz, n, ilo, ihi, h, ldh, wr, wi, z, ldz, work, lwork, info)
SHSEQR
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine srot(n, sx, incx, sy, incy, c, s)
SROT
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine strevc3(side, howmny, select, n, t, ldt, vl, ldvl, vr, ldvr, mm, m, work, lwork, info)
STREVC3
subroutine sorghr(n, ilo, ihi, a, lda, tau, work, lwork, info)
SORGHR