203 SUBROUTINE zheevd( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK,
204 $ LRWORK, IWORK, LIWORK, INFO )
212 INTEGER INFO, LDA, LIWORK, LRWORK, LWORK, N
216 DOUBLE PRECISION RWORK( * ), W( * )
217 COMPLEX*16 A( LDA, * ), WORK( * )
223 DOUBLE PRECISION ZERO, ONE
224 parameter( zero = 0.0d0, one = 1.0d0 )
226 parameter( cone = ( 1.0d0, 0.0d0 ) )
229 LOGICAL LOWER, LQUERY, WANTZ
230 INTEGER IINFO, IMAX, INDE, INDRWK, INDTAU, INDWK2,
231 $ indwrk, iscale, liopt, liwmin, llrwk, llwork,
232 $ llwrk2, lopt, lropt, lrwmin, lwmin
233 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
239 DOUBLE PRECISION DLAMCH, ZLANHE
240 EXTERNAL lsame, ilaenv, dlamch, zlanhe
253 wantz = lsame( jobz,
'V' )
254 lower = lsame( uplo,
'L' )
255 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
258 IF( .NOT.( wantz .OR. lsame( jobz,
'N' ) ) )
THEN
260 ELSE IF( .NOT.( lower .OR. lsame( uplo,
'U' ) ) )
THEN
262 ELSE IF( n.LT.0 )
THEN
264 ELSE IF( lda.LT.max( 1, n ) )
THEN
279 lrwmin = 1 + 5*n + 2*n**2
286 lopt = max( lwmin, n +
287 $ ilaenv( 1,
'ZHETRD', uplo, n, -1, -1, -1 ) )
295 IF( lwork.LT.lwmin .AND. .NOT.lquery )
THEN
297 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery )
THEN
299 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery )
THEN
305 CALL xerbla(
'ZHEEVD', -info )
307 ELSE IF( lquery )
THEN
317 w( 1 ) = dble( a( 1, 1 ) )
325 safmin = dlamch(
'Safe minimum' )
326 eps = dlamch(
'Precision' )
327 smlnum = safmin / eps
328 bignum = one / smlnum
329 rmin = sqrt( smlnum )
330 rmax = sqrt( bignum )
334 anrm = zlanhe(
'M', uplo, n, a, lda, rwork )
336 IF( anrm.GT.zero .AND. anrm.LT.rmin )
THEN
339 ELSE IF( anrm.GT.rmax )
THEN
344 $
CALL zlascl( uplo, 0, 0, one, sigma, n, n, a, lda, info )
352 indwk2 = indwrk + n*n
353 llwork = lwork - indwrk + 1
354 llwrk2 = lwork - indwk2 + 1
355 llrwk = lrwork - indrwk + 1
356 CALL zhetrd( uplo, n, a, lda, w, rwork( inde ), work( indtau ),
357 $ work( indwrk ), llwork, iinfo )
365 IF( .NOT.wantz )
THEN
366 CALL dsterf( n, w, rwork( inde ), info )
368 CALL zstedc(
'I', n, w, rwork( inde ), work( indwrk ), n,
369 $ work( indwk2 ), llwrk2, rwork( indrwk ), llrwk,
370 $ iwork, liwork, info )
371 CALL zunmtr(
'L', uplo,
'N', n, n, a, lda, work( indtau ),
372 $ work( indwrk ), n, work( indwk2 ), llwrk2, iinfo )
373 CALL zlacpy(
'A', n, n, work( indwrk ), n, a, lda )
378 IF( iscale.EQ.1 )
THEN
384 CALL dscal( imax, one / sigma, w, 1 )
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dsterf(N, D, E, INFO)
DSTERF
subroutine zhetrd(UPLO, N, A, LDA, D, E, TAU, WORK, LWORK, INFO)
ZHETRD
subroutine zheevd(JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO)
ZHEEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zunmtr(SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMTR
subroutine zstedc(COMPZ, N, D, E, Z, LDZ, WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO)
ZSTEDC
subroutine dscal(N, DA, DX, INCX)
DSCAL