OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches

Functions

subroutine zheev (jobz, uplo, n, a, lda, w, work, lwork, rwork, info)
  ZHEEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zheev_2stage (jobz, uplo, n, a, lda, w, work, lwork, rwork, info)
  ZHEEV_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
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 zheevd_2stage (jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork, iwork, liwork, info)
  ZHEEVD_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zheevr (jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, rwork, lrwork, iwork, liwork, info)
  ZHEEVR computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zheevr_2stage (jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, rwork, lrwork, iwork, liwork, info)
  ZHEEVR_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zheevx (jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, rwork, iwork, ifail, info)
  ZHEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zheevx_2stage (jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, rwork, iwork, ifail, info)
  ZHEEVX_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
subroutine zhegv (itype, jobz, uplo, n, a, lda, b, ldb, w, work, lwork, rwork, info)
 ZHEGV
subroutine zhegv_2stage (itype, jobz, uplo, n, a, lda, b, ldb, w, work, lwork, rwork, info)
 ZHEGV_2STAGE
subroutine zhegvd (itype, jobz, uplo, n, a, lda, b, ldb, w, work, lwork, rwork, lrwork, iwork, liwork, info)
 ZHEGVD
subroutine zhegvx (itype, jobz, range, uplo, n, a, lda, b, ldb, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, rwork, iwork, ifail, info)
 ZHEGVX

Detailed Description

This is the group of complex16 eigenvalue driver functions for HE matrices

Function Documentation

◆ zheev()

subroutine zheev ( character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer info )

ZHEEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEV computes all eigenvalues and, optionally, eigenvectors of a
!> complex Hermitian matrix A.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          orthonormal eigenvectors of the matrix A.
!>          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
!>          or the upper triangle (if UPLO='U') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.  LWORK >= max(1,2*N-1).
!>          For optimal efficiency, LWORK >= (NB+1)*N,
!>          where NB is the blocksize for ZHETRD returned by ILAENV.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (max(1, 3*N-2))
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO = i, the algorithm failed to converge; i
!>                off-diagonal elements of an intermediate tridiagonal
!>                form did not converge to zero.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 138 of file zheev.f.

140*
141* -- LAPACK driver routine --
142* -- LAPACK is a software package provided by Univ. of Tennessee, --
143* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
144*
145* .. Scalar Arguments ..
146 CHARACTER JOBZ, UPLO
147 INTEGER INFO, LDA, LWORK, N
148* ..
149* .. Array Arguments ..
150 DOUBLE PRECISION RWORK( * ), W( * )
151 COMPLEX*16 A( LDA, * ), WORK( * )
152* ..
153*
154* =====================================================================
155*
156* .. Parameters ..
157 DOUBLE PRECISION ZERO, ONE
158 parameter( zero = 0.0d0, one = 1.0d0 )
159 COMPLEX*16 CONE
160 parameter( cone = ( 1.0d0, 0.0d0 ) )
161* ..
162* .. Local Scalars ..
163 LOGICAL LOWER, LQUERY, WANTZ
164 INTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
165 $ LLWORK, LWKOPT, NB
166 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
167 $ SMLNUM
168* ..
169* .. External Functions ..
170 LOGICAL LSAME
171 INTEGER ILAENV
172 DOUBLE PRECISION DLAMCH, ZLANHE
173 EXTERNAL lsame, ilaenv, dlamch, zlanhe
174* ..
175* .. External Subroutines ..
176 EXTERNAL dscal, dsterf, xerbla, zhetrd, zlascl, zsteqr,
177 $ zungtr
178* ..
179* .. Intrinsic Functions ..
180 INTRINSIC max, sqrt
181* ..
182* .. Executable Statements ..
183*
184* Test the input parameters.
185*
186 wantz = lsame( jobz, 'V' )
187 lower = lsame( uplo, 'L' )
188 lquery = ( lwork.EQ.-1 )
189*
190 info = 0
191 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
192 info = -1
193 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
194 info = -2
195 ELSE IF( n.LT.0 ) THEN
196 info = -3
197 ELSE IF( lda.LT.max( 1, n ) ) THEN
198 info = -5
199 END IF
200*
201 IF( info.EQ.0 ) THEN
202 nb = ilaenv( 1, 'ZHETRD', uplo, n, -1, -1, -1 )
203 lwkopt = max( 1, ( nb+1 )*n )
204 work( 1 ) = lwkopt
205*
206 IF( lwork.LT.max( 1, 2*n-1 ) .AND. .NOT.lquery )
207 $ info = -8
208 END IF
209*
210 IF( info.NE.0 ) THEN
211 CALL xerbla( 'ZHEEV ', -info )
212 RETURN
213 ELSE IF( lquery ) THEN
214 RETURN
215 END IF
216*
217* Quick return if possible
218*
219 IF( n.EQ.0 ) THEN
220 RETURN
221 END IF
222*
223 IF( n.EQ.1 ) THEN
224 w( 1 ) = dble( a( 1, 1 ) )
225 work( 1 ) = 1
226 IF( wantz )
227 $ a( 1, 1 ) = cone
228 RETURN
229 END IF
230*
231* Get machine constants.
232*
233 safmin = dlamch( 'Safe minimum' )
234 eps = dlamch( 'Precision' )
235 smlnum = safmin / eps
236 bignum = one / smlnum
237 rmin = sqrt( smlnum )
238 rmax = sqrt( bignum )
239*
240* Scale matrix to allowable range, if necessary.
241*
242 anrm = zlanhe( 'M', uplo, n, a, lda, rwork )
243 iscale = 0
244 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
245 iscale = 1
246 sigma = rmin / anrm
247 ELSE IF( anrm.GT.rmax ) THEN
248 iscale = 1
249 sigma = rmax / anrm
250 END IF
251 IF( iscale.EQ.1 )
252 $ CALL zlascl( uplo, 0, 0, one, sigma, n, n, a, lda, info )
253*
254* Call ZHETRD to reduce Hermitian matrix to tridiagonal form.
255*
256 inde = 1
257 indtau = 1
258 indwrk = indtau + n
259 llwork = lwork - indwrk + 1
260 CALL zhetrd( uplo, n, a, lda, w, rwork( inde ), work( indtau ),
261 $ work( indwrk ), llwork, iinfo )
262*
263* For eigenvalues only, call DSTERF. For eigenvectors, first call
264* ZUNGTR to generate the unitary matrix, then call ZSTEQR.
265*
266 IF( .NOT.wantz ) THEN
267 CALL dsterf( n, w, rwork( inde ), info )
268 ELSE
269 CALL zungtr( uplo, n, a, lda, work( indtau ), work( indwrk ),
270 $ llwork, iinfo )
271 indwrk = inde + n
272 CALL zsteqr( jobz, n, w, rwork( inde ), a, lda,
273 $ rwork( indwrk ), info )
274 END IF
275*
276* If matrix was scaled, then rescale eigenvalues appropriately.
277*
278 IF( iscale.EQ.1 ) THEN
279 IF( info.EQ.0 ) THEN
280 imax = n
281 ELSE
282 imax = info - 1
283 END IF
284 CALL dscal( imax, one / sigma, w, 1 )
285 END IF
286*
287* Set WORK(1) to optimal complex workspace size.
288*
289 work( 1 ) = lwkopt
290*
291 RETURN
292*
293* End of ZHEEV
294*
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:162
subroutine dsterf(n, d, e, info)
DSTERF
Definition dsterf.f:86
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
logical function lsame(ca, cb)
LSAME
Definition lsame.f:53
double precision function zlanhe(norm, uplo, n, a, lda, work)
ZLANHE returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition zlanhe.f:124
subroutine zhetrd(uplo, n, a, lda, d, e, tau, work, lwork, info)
ZHETRD
Definition zhetrd.f:192
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.
Definition zlascl.f:143
subroutine zsteqr(compz, n, d, e, z, ldz, work, info)
ZSTEQR
Definition zsteqr.f:132
subroutine zungtr(uplo, n, a, lda, tau, work, lwork, info)
ZUNGTR
Definition zungtr.f:123
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
#define max(a, b)
Definition macros.h:21

◆ zheev_2stage()

subroutine zheev_2stage ( character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer info )

ZHEEV_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEV_2STAGE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEV_2STAGE computes all eigenvalues and, optionally, eigenvectors of a
!> complex Hermitian matrix A using the 2stage technique for
!> the reduction to tridiagonal.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!>                  Not available in this release.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          orthonormal eigenvectors of the matrix A.
!>          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
!>          or the upper triangle (if UPLO='U') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK. LWORK >= 1, when N <= 1;
!>          otherwise  
!>          If JOBZ = 'N' and N > 1, LWORK must be queried.
!>                                   LWORK = MAX(1, dimension) where
!>                                   dimension = max(stage1,stage2) + (KD+1)*N + N
!>                                             = N*KD + N*max(KD+1,FACTOPTNB) 
!>                                               + max(2*KD*KD, KD*NTHREADS) 
!>                                               + (KD+1)*N + N
!>                                   where KD is the blocking size of the reduction,
!>                                   FACTOPTNB is the blocking used by the QR or LQ
!>                                   algorithm, usually FACTOPTNB=128 is a good choice
!>                                   NTHREADS is the number of threads used when
!>                                   openMP compilation is enabled, otherwise =1.
!>          If JOBZ = 'V' and N > 1, LWORK must be queried. Not yet available
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (max(1, 3*N-2))
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO = i, the algorithm failed to converge; i
!>                off-diagonal elements of an intermediate tridiagonal
!>                form did not converge to zero.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  All details about the 2stage techniques are available in:
!>
!>  Azzam Haidar, Hatem Ltaief, and Jack Dongarra.
!>  Parallel reduction to condensed forms for symmetric eigenvalue problems
!>  using aggregated fine-grained and memory-aware kernels. In Proceedings
!>  of 2011 International Conference for High Performance Computing,
!>  Networking, Storage and Analysis (SC '11), New York, NY, USA,
!>  Article 8 , 11 pages.
!>  http://doi.acm.org/10.1145/2063384.2063394
!>
!>  A. Haidar, J. Kurzak, P. Luszczek, 2013.
!>  An improved parallel singular value algorithm and its implementation 
!>  for multicore hardware, In Proceedings of 2013 International Conference
!>  for High Performance Computing, Networking, Storage and Analysis (SC '13).
!>  Denver, Colorado, USA, 2013.
!>  Article 90, 12 pages.
!>  http://doi.acm.org/10.1145/2503210.2503292
!>
!>  A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.
!>  A novel hybrid CPU-GPU generalized eigensolver for electronic structure 
!>  calculations based on fine-grained memory aware tasks.
!>  International Journal of High Performance Computing Applications.
!>  Volume 28 Issue 2, Pages 196-209, May 2014.
!>  http://hpc.sagepub.com/content/28/2/196 
!>
!> 

Definition at line 187 of file zheev_2stage.f.

189*
190 IMPLICIT NONE
191*
192* -- LAPACK driver routine --
193* -- LAPACK is a software package provided by Univ. of Tennessee, --
194* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
195*
196* .. Scalar Arguments ..
197 CHARACTER JOBZ, UPLO
198 INTEGER INFO, LDA, LWORK, N
199* ..
200* .. Array Arguments ..
201 DOUBLE PRECISION RWORK( * ), W( * )
202 COMPLEX*16 A( LDA, * ), WORK( * )
203* ..
204*
205* =====================================================================
206*
207* .. Parameters ..
208 DOUBLE PRECISION ZERO, ONE
209 parameter( zero = 0.0d0, one = 1.0d0 )
210 COMPLEX*16 CONE
211 parameter( cone = ( 1.0d0, 0.0d0 ) )
212* ..
213* .. Local Scalars ..
214 LOGICAL LOWER, LQUERY, WANTZ
215 INTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
216 $ LLWORK, LWMIN, LHTRD, LWTRD, KD, IB, INDHOUS
217 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
218 $ SMLNUM
219* ..
220* .. External Functions ..
221 LOGICAL LSAME
222 INTEGER ILAENV2STAGE
223 DOUBLE PRECISION DLAMCH, ZLANHE
224 EXTERNAL lsame, dlamch, zlanhe, ilaenv2stage
225* ..
226* .. External Subroutines ..
227 EXTERNAL dscal, dsterf, xerbla, zlascl, zsteqr,
229* ..
230* .. Intrinsic Functions ..
231 INTRINSIC dble, max, sqrt
232* ..
233* .. Executable Statements ..
234*
235* Test the input parameters.
236*
237 wantz = lsame( jobz, 'V' )
238 lower = lsame( uplo, 'L' )
239 lquery = ( lwork.EQ.-1 )
240*
241 info = 0
242 IF( .NOT.( lsame( jobz, 'N' ) ) ) THEN
243 info = -1
244 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
245 info = -2
246 ELSE IF( n.LT.0 ) THEN
247 info = -3
248 ELSE IF( lda.LT.max( 1, n ) ) THEN
249 info = -5
250 END IF
251*
252 IF( info.EQ.0 ) THEN
253 kd = ilaenv2stage( 1, 'ZHETRD_2STAGE', jobz, n, -1, -1, -1 )
254 ib = ilaenv2stage( 2, 'ZHETRD_2STAGE', jobz, n, kd, -1, -1 )
255 lhtrd = ilaenv2stage( 3, 'ZHETRD_2STAGE', jobz, n, kd, ib, -1 )
256 lwtrd = ilaenv2stage( 4, 'ZHETRD_2STAGE', jobz, n, kd, ib, -1 )
257 lwmin = n + lhtrd + lwtrd
258 work( 1 ) = lwmin
259*
260 IF( lwork.LT.lwmin .AND. .NOT.lquery )
261 $ info = -8
262 END IF
263*
264 IF( info.NE.0 ) THEN
265 CALL xerbla( 'ZHEEV_2STAGE ', -info )
266 RETURN
267 ELSE IF( lquery ) THEN
268 RETURN
269 END IF
270*
271* Quick return if possible
272*
273 IF( n.EQ.0 ) THEN
274 RETURN
275 END IF
276*
277 IF( n.EQ.1 ) THEN
278 w( 1 ) = dble( a( 1, 1 ) )
279 work( 1 ) = 1
280 IF( wantz )
281 $ a( 1, 1 ) = cone
282 RETURN
283 END IF
284*
285* Get machine constants.
286*
287 safmin = dlamch( 'Safe minimum' )
288 eps = dlamch( 'Precision' )
289 smlnum = safmin / eps
290 bignum = one / smlnum
291 rmin = sqrt( smlnum )
292 rmax = sqrt( bignum )
293*
294* Scale matrix to allowable range, if necessary.
295*
296 anrm = zlanhe( 'M', uplo, n, a, lda, rwork )
297 iscale = 0
298 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
299 iscale = 1
300 sigma = rmin / anrm
301 ELSE IF( anrm.GT.rmax ) THEN
302 iscale = 1
303 sigma = rmax / anrm
304 END IF
305 IF( iscale.EQ.1 )
306 $ CALL zlascl( uplo, 0, 0, one, sigma, n, n, a, lda, info )
307*
308* Call ZHETRD_2STAGE to reduce Hermitian matrix to tridiagonal form.
309*
310 inde = 1
311 indtau = 1
312 indhous = indtau + n
313 indwrk = indhous + lhtrd
314 llwork = lwork - indwrk + 1
315*
316 CALL zhetrd_2stage( jobz, uplo, n, a, lda, w, rwork( inde ),
317 $ work( indtau ), work( indhous ), lhtrd,
318 $ work( indwrk ), llwork, iinfo )
319*
320* For eigenvalues only, call DSTERF. For eigenvectors, first call
321* ZUNGTR to generate the unitary matrix, then call ZSTEQR.
322*
323 IF( .NOT.wantz ) THEN
324 CALL dsterf( n, w, rwork( inde ), info )
325 ELSE
326 CALL zungtr( uplo, n, a, lda, work( indtau ), work( indwrk ),
327 $ llwork, iinfo )
328 indwrk = inde + n
329 CALL zsteqr( jobz, n, w, rwork( inde ), a, lda,
330 $ rwork( indwrk ), info )
331 END IF
332*
333* If matrix was scaled, then rescale eigenvalues appropriately.
334*
335 IF( iscale.EQ.1 ) THEN
336 IF( info.EQ.0 ) THEN
337 imax = n
338 ELSE
339 imax = info - 1
340 END IF
341 CALL dscal( imax, one / sigma, w, 1 )
342 END IF
343*
344* Set WORK(1) to optimal complex workspace size.
345*
346 work( 1 ) = lwmin
347*
348 RETURN
349*
350* End of ZHEEV_2STAGE
351*
integer function ilaenv2stage(ispec, name, opts, n1, n2, n3, n4)
ILAENV2STAGE
subroutine zhetrd_2stage(vect, uplo, n, a, lda, d, e, tau, hous2, lhous2, work, lwork, info)
ZHETRD_2STAGE

◆ zheevd()

subroutine zheevd ( character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer lrwork,
integer, dimension( * ) iwork,
integer liwork,
integer info )

ZHEEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEVD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEVD computes all eigenvalues and, optionally, eigenvectors of a
!> complex Hermitian matrix A.  If eigenvectors are desired, it uses a
!> divide and conquer algorithm.
!>
!> The divide and conquer algorithm makes very mild assumptions about
!> floating point arithmetic. It will work on machines with a guard
!> digit in add/subtract, or on those binary machines without guard
!> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
!> Cray-2. It could conceivably fail on hexadecimal or decimal machines
!> without guard digits, but we know of none.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          orthonormal eigenvectors of the matrix A.
!>          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
!>          or the upper triangle (if UPLO='U') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.
!>          If N <= 1,                LWORK must be at least 1.
!>          If JOBZ  = 'N' and N > 1, LWORK must be at least N + 1.
!>          If JOBZ  = 'V' and N > 1, LWORK must be at least 2*N + N**2.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal sizes of the WORK, RWORK and
!>          IWORK arrays, returns these values as the first entries of
!>          the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array,
!>                                         dimension (LRWORK)
!>          On exit, if INFO = 0, RWORK(1) returns the optimal LRWORK.
!> 
[in]LRWORK
!>          LRWORK is INTEGER
!>          The dimension of the array RWORK.
!>          If N <= 1,                LRWORK must be at least 1.
!>          If JOBZ  = 'N' and N > 1, LRWORK must be at least N.
!>          If JOBZ  = 'V' and N > 1, LRWORK must be at least
!>                         1 + 5*N + 2*N**2.
!>
!>          If LRWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
!>          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
!> 
[in]LIWORK
!>          LIWORK is INTEGER
!>          The dimension of the array IWORK.
!>          If N <= 1,                LIWORK must be at least 1.
!>          If JOBZ  = 'N' and N > 1, LIWORK must be at least 1.
!>          If JOBZ  = 'V' and N > 1, LIWORK must be at least 3 + 5*N.
!>
!>          If LIWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO = i and JOBZ = 'N', then the algorithm failed
!>                to converge; i off-diagonal elements of an intermediate
!>                tridiagonal form did not converge to zero;
!>                if INFO = i and JOBZ = 'V', then the algorithm failed
!>                to compute an eigenvalue while working on the submatrix
!>                lying in rows and columns INFO/(N+1) through
!>                mod(INFO,N+1).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
Modified description of INFO. Sven, 16 Feb 05.
Contributors:
Jeff Rutter, Computer Science Division, University of California at Berkeley, USA

Definition at line 203 of file zheevd.f.

205*
206* -- LAPACK driver routine --
207* -- LAPACK is a software package provided by Univ. of Tennessee, --
208* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
209*
210* .. Scalar Arguments ..
211 CHARACTER JOBZ, UPLO
212 INTEGER INFO, LDA, LIWORK, LRWORK, LWORK, N
213* ..
214* .. Array Arguments ..
215 INTEGER IWORK( * )
216 DOUBLE PRECISION RWORK( * ), W( * )
217 COMPLEX*16 A( LDA, * ), WORK( * )
218* ..
219*
220* =====================================================================
221*
222* .. Parameters ..
223 DOUBLE PRECISION ZERO, ONE
224 parameter( zero = 0.0d0, one = 1.0d0 )
225 COMPLEX*16 CONE
226 parameter( cone = ( 1.0d0, 0.0d0 ) )
227* ..
228* .. Local Scalars ..
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,
234 $ SMLNUM
235* ..
236* .. External Functions ..
237 LOGICAL LSAME
238 INTEGER ILAENV
239 DOUBLE PRECISION DLAMCH, ZLANHE
240 EXTERNAL lsame, ilaenv, dlamch, zlanhe
241* ..
242* .. External Subroutines ..
243 EXTERNAL dscal, dsterf, xerbla, zhetrd, zlacpy, zlascl,
244 $ zstedc, zunmtr
245* ..
246* .. Intrinsic Functions ..
247 INTRINSIC max, sqrt
248* ..
249* .. Executable Statements ..
250*
251* Test the input parameters.
252*
253 wantz = lsame( jobz, 'V' )
254 lower = lsame( uplo, 'L' )
255 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
256*
257 info = 0
258 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
259 info = -1
260 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
261 info = -2
262 ELSE IF( n.LT.0 ) THEN
263 info = -3
264 ELSE IF( lda.LT.max( 1, n ) ) THEN
265 info = -5
266 END IF
267*
268 IF( info.EQ.0 ) THEN
269 IF( n.LE.1 ) THEN
270 lwmin = 1
271 lrwmin = 1
272 liwmin = 1
273 lopt = lwmin
274 lropt = lrwmin
275 liopt = liwmin
276 ELSE
277 IF( wantz ) THEN
278 lwmin = 2*n + n*n
279 lrwmin = 1 + 5*n + 2*n**2
280 liwmin = 3 + 5*n
281 ELSE
282 lwmin = n + 1
283 lrwmin = n
284 liwmin = 1
285 END IF
286 lopt = max( lwmin, n +
287 $ ilaenv( 1, 'ZHETRD', uplo, n, -1, -1, -1 ) )
288 lropt = lrwmin
289 liopt = liwmin
290 END IF
291 work( 1 ) = lopt
292 rwork( 1 ) = lropt
293 iwork( 1 ) = liopt
294*
295 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
296 info = -8
297 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
298 info = -10
299 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
300 info = -12
301 END IF
302 END IF
303*
304 IF( info.NE.0 ) THEN
305 CALL xerbla( 'ZHEEVD', -info )
306 RETURN
307 ELSE IF( lquery ) THEN
308 RETURN
309 END IF
310*
311* Quick return if possible
312*
313 IF( n.EQ.0 )
314 $ RETURN
315*
316 IF( n.EQ.1 ) THEN
317 w( 1 ) = dble( a( 1, 1 ) )
318 IF( wantz )
319 $ a( 1, 1 ) = cone
320 RETURN
321 END IF
322*
323* Get machine constants.
324*
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 )
331*
332* Scale matrix to allowable range, if necessary.
333*
334 anrm = zlanhe( 'M', uplo, n, a, lda, rwork )
335 iscale = 0
336 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
337 iscale = 1
338 sigma = rmin / anrm
339 ELSE IF( anrm.GT.rmax ) THEN
340 iscale = 1
341 sigma = rmax / anrm
342 END IF
343 IF( iscale.EQ.1 )
344 $ CALL zlascl( uplo, 0, 0, one, sigma, n, n, a, lda, info )
345*
346* Call ZHETRD to reduce Hermitian matrix to tridiagonal form.
347*
348 inde = 1
349 indtau = 1
350 indwrk = indtau + n
351 indrwk = inde + n
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 )
358*
359* For eigenvalues only, call DSTERF. For eigenvectors, first call
360* ZSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the
361* tridiagonal matrix, then call ZUNMTR to multiply it to the
362* Householder transformations represented as Householder vectors in
363* A.
364*
365 IF( .NOT.wantz ) THEN
366 CALL dsterf( n, w, rwork( inde ), info )
367 ELSE
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 )
374 END IF
375*
376* If matrix was scaled, then rescale eigenvalues appropriately.
377*
378 IF( iscale.EQ.1 ) THEN
379 IF( info.EQ.0 ) THEN
380 imax = n
381 ELSE
382 imax = info - 1
383 END IF
384 CALL dscal( imax, one / sigma, w, 1 )
385 END IF
386*
387 work( 1 ) = lopt
388 rwork( 1 ) = lropt
389 iwork( 1 ) = liopt
390*
391 RETURN
392*
393* End of ZHEEVD
394*
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
Definition zlacpy.f:103
subroutine zunmtr(side, uplo, trans, m, n, a, lda, tau, c, ldc, work, lwork, info)
ZUNMTR
Definition zunmtr.f:171
subroutine zstedc(compz, n, d, e, z, ldz, work, lwork, rwork, lrwork, iwork, liwork, info)
ZSTEDC
Definition zstedc.f:212

◆ zheevd_2stage()

subroutine zheevd_2stage ( character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer lrwork,
integer, dimension( * ) iwork,
integer liwork,
integer info )

ZHEEVD_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEVD_2STAGE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEVD_2STAGE computes all eigenvalues and, optionally, eigenvectors of a
!> complex Hermitian matrix A using the 2stage technique for
!> the reduction to tridiagonal.  If eigenvectors are desired, it uses a
!> divide and conquer algorithm.
!>
!> The divide and conquer algorithm makes very mild assumptions about
!> floating point arithmetic. It will work on machines with a guard
!> digit in add/subtract, or on those binary machines without guard
!> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
!> Cray-2. It could conceivably fail on hexadecimal or decimal machines
!> without guard digits, but we know of none.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!>                  Not available in this release.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          orthonormal eigenvectors of the matrix A.
!>          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
!>          or the upper triangle (if UPLO='U') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.
!>          If N <= 1,               LWORK must be at least 1.
!>          If JOBZ = 'N' and N > 1, LWORK must be queried.
!>                                   LWORK = MAX(1, dimension) where
!>                                   dimension = max(stage1,stage2) + (KD+1)*N + N+1
!>                                             = N*KD + N*max(KD+1,FACTOPTNB) 
!>                                               + max(2*KD*KD, KD*NTHREADS) 
!>                                               + (KD+1)*N + N+1
!>                                   where KD is the blocking size of the reduction,
!>                                   FACTOPTNB is the blocking used by the QR or LQ
!>                                   algorithm, usually FACTOPTNB=128 is a good choice
!>                                   NTHREADS is the number of threads used when
!>                                   openMP compilation is enabled, otherwise =1.
!>          If JOBZ = 'V' and N > 1, LWORK must be at least 2*N + N**2
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal sizes of the WORK, RWORK and
!>          IWORK arrays, returns these values as the first entries of
!>          the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array,
!>                                         dimension (LRWORK)
!>          On exit, if INFO = 0, RWORK(1) returns the optimal LRWORK.
!> 
[in]LRWORK
!>          LRWORK is INTEGER
!>          The dimension of the array RWORK.
!>          If N <= 1,                LRWORK must be at least 1.
!>          If JOBZ  = 'N' and N > 1, LRWORK must be at least N.
!>          If JOBZ  = 'V' and N > 1, LRWORK must be at least
!>                         1 + 5*N + 2*N**2.
!>
!>          If LRWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
!>          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
!> 
[in]LIWORK
!>          LIWORK is INTEGER
!>          The dimension of the array IWORK.
!>          If N <= 1,                LIWORK must be at least 1.
!>          If JOBZ  = 'N' and N > 1, LIWORK must be at least 1.
!>          If JOBZ  = 'V' and N > 1, LIWORK must be at least 3 + 5*N.
!>
!>          If LIWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO = i and JOBZ = 'N', then the algorithm failed
!>                to converge; i off-diagonal elements of an intermediate
!>                tridiagonal form did not converge to zero;
!>                if INFO = i and JOBZ = 'V', then the algorithm failed
!>                to compute an eigenvalue while working on the submatrix
!>                lying in rows and columns INFO/(N+1) through
!>                mod(INFO,N+1).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
Modified description of INFO. Sven, 16 Feb 05.
Contributors:
Jeff Rutter, Computer Science Division, University of California at Berkeley, USA
Further Details:
!>
!>  All details about the 2stage techniques are available in:
!>
!>  Azzam Haidar, Hatem Ltaief, and Jack Dongarra.
!>  Parallel reduction to condensed forms for symmetric eigenvalue problems
!>  using aggregated fine-grained and memory-aware kernels. In Proceedings
!>  of 2011 International Conference for High Performance Computing,
!>  Networking, Storage and Analysis (SC '11), New York, NY, USA,
!>  Article 8 , 11 pages.
!>  http://doi.acm.org/10.1145/2063384.2063394
!>
!>  A. Haidar, J. Kurzak, P. Luszczek, 2013.
!>  An improved parallel singular value algorithm and its implementation 
!>  for multicore hardware, In Proceedings of 2013 International Conference
!>  for High Performance Computing, Networking, Storage and Analysis (SC '13).
!>  Denver, Colorado, USA, 2013.
!>  Article 90, 12 pages.
!>  http://doi.acm.org/10.1145/2503210.2503292
!>
!>  A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.
!>  A novel hybrid CPU-GPU generalized eigensolver for electronic structure 
!>  calculations based on fine-grained memory aware tasks.
!>  International Journal of High Performance Computing Applications.
!>  Volume 28 Issue 2, Pages 196-209, May 2014.
!>  http://hpc.sagepub.com/content/28/2/196 
!>
!> 

Definition at line 251 of file zheevd_2stage.f.

253*
254 IMPLICIT NONE
255*
256* -- LAPACK driver routine --
257* -- LAPACK is a software package provided by Univ. of Tennessee, --
258* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
259*
260* .. Scalar Arguments ..
261 CHARACTER JOBZ, UPLO
262 INTEGER INFO, LDA, LIWORK, LRWORK, LWORK, N
263* ..
264* .. Array Arguments ..
265 INTEGER IWORK( * )
266 DOUBLE PRECISION RWORK( * ), W( * )
267 COMPLEX*16 A( LDA, * ), WORK( * )
268* ..
269*
270* =====================================================================
271*
272* .. Parameters ..
273 DOUBLE PRECISION ZERO, ONE
274 parameter( zero = 0.0d0, one = 1.0d0 )
275 COMPLEX*16 CONE
276 parameter( cone = ( 1.0d0, 0.0d0 ) )
277* ..
278* .. Local Scalars ..
279 LOGICAL LOWER, LQUERY, WANTZ
280 INTEGER IINFO, IMAX, INDE, INDRWK, INDTAU, INDWK2,
281 $ INDWRK, ISCALE, LIWMIN, LLRWK, LLWORK,
282 $ LLWRK2, LRWMIN, LWMIN,
283 $ LHTRD, LWTRD, KD, IB, INDHOUS
284
285
286 DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
287 $ SMLNUM
288* ..
289* .. External Functions ..
290 LOGICAL LSAME
291 INTEGER ILAENV2STAGE
292 DOUBLE PRECISION DLAMCH, ZLANHE
293 EXTERNAL lsame, dlamch, zlanhe, ilaenv2stage
294* ..
295* .. External Subroutines ..
296 EXTERNAL dscal, dsterf, xerbla, zlacpy, zlascl,
298* ..
299* .. Intrinsic Functions ..
300 INTRINSIC dble, max, sqrt
301* ..
302* .. Executable Statements ..
303*
304* Test the input parameters.
305*
306 wantz = lsame( jobz, 'V' )
307 lower = lsame( uplo, 'L' )
308 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
309*
310 info = 0
311 IF( .NOT.( lsame( jobz, 'N' ) ) ) THEN
312 info = -1
313 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
314 info = -2
315 ELSE IF( n.LT.0 ) THEN
316 info = -3
317 ELSE IF( lda.LT.max( 1, n ) ) THEN
318 info = -5
319 END IF
320*
321 IF( info.EQ.0 ) THEN
322 IF( n.LE.1 ) THEN
323 lwmin = 1
324 lrwmin = 1
325 liwmin = 1
326 ELSE
327 kd = ilaenv2stage( 1, 'ZHETRD_2STAGE', jobz,
328 $ n, -1, -1, -1 )
329 ib = ilaenv2stage( 2, 'ZHETRD_2STAGE', jobz,
330 $ n, kd, -1, -1 )
331 lhtrd = ilaenv2stage( 3, 'ZHETRD_2STAGE', jobz,
332 $ n, kd, ib, -1 )
333 lwtrd = ilaenv2stage( 4, 'ZHETRD_2STAGE', jobz,
334 $ n, kd, ib, -1 )
335 IF( wantz ) THEN
336 lwmin = 2*n + n*n
337 lrwmin = 1 + 5*n + 2*n**2
338 liwmin = 3 + 5*n
339 ELSE
340 lwmin = n + 1 + lhtrd + lwtrd
341 lrwmin = n
342 liwmin = 1
343 END IF
344 END IF
345 work( 1 ) = lwmin
346 rwork( 1 ) = lrwmin
347 iwork( 1 ) = liwmin
348*
349 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
350 info = -8
351 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
352 info = -10
353 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
354 info = -12
355 END IF
356 END IF
357*
358 IF( info.NE.0 ) THEN
359 CALL xerbla( 'ZHEEVD_2STAGE', -info )
360 RETURN
361 ELSE IF( lquery ) THEN
362 RETURN
363 END IF
364*
365* Quick return if possible
366*
367 IF( n.EQ.0 )
368 $ RETURN
369*
370 IF( n.EQ.1 ) THEN
371 w( 1 ) = dble( a( 1, 1 ) )
372 IF( wantz )
373 $ a( 1, 1 ) = cone
374 RETURN
375 END IF
376*
377* Get machine constants.
378*
379 safmin = dlamch( 'Safe minimum' )
380 eps = dlamch( 'Precision' )
381 smlnum = safmin / eps
382 bignum = one / smlnum
383 rmin = sqrt( smlnum )
384 rmax = sqrt( bignum )
385*
386* Scale matrix to allowable range, if necessary.
387*
388 anrm = zlanhe( 'M', uplo, n, a, lda, rwork )
389 iscale = 0
390 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
391 iscale = 1
392 sigma = rmin / anrm
393 ELSE IF( anrm.GT.rmax ) THEN
394 iscale = 1
395 sigma = rmax / anrm
396 END IF
397 IF( iscale.EQ.1 )
398 $ CALL zlascl( uplo, 0, 0, one, sigma, n, n, a, lda, info )
399*
400* Call ZHETRD_2STAGE to reduce Hermitian matrix to tridiagonal form.
401*
402 inde = 1
403 indrwk = inde + n
404 llrwk = lrwork - indrwk + 1
405 indtau = 1
406 indhous = indtau + n
407 indwrk = indhous + lhtrd
408 llwork = lwork - indwrk + 1
409 indwk2 = indwrk + n*n
410 llwrk2 = lwork - indwk2 + 1
411*
412 CALL zhetrd_2stage( jobz, uplo, n, a, lda, w, rwork( inde ),
413 $ work( indtau ), work( indhous ), lhtrd,
414 $ work( indwrk ), llwork, iinfo )
415*
416* For eigenvalues only, call DSTERF. For eigenvectors, first call
417* ZSTEDC to generate the eigenvector matrix, WORK(INDWRK), of the
418* tridiagonal matrix, then call ZUNMTR to multiply it to the
419* Householder transformations represented as Householder vectors in
420* A.
421*
422 IF( .NOT.wantz ) THEN
423 CALL dsterf( n, w, rwork( inde ), info )
424 ELSE
425 CALL zstedc( 'I', n, w, rwork( inde ), work( indwrk ), n,
426 $ work( indwk2 ), llwrk2, rwork( indrwk ), llrwk,
427 $ iwork, liwork, info )
428 CALL zunmtr( 'L', uplo, 'N', n, n, a, lda, work( indtau ),
429 $ work( indwrk ), n, work( indwk2 ), llwrk2, iinfo )
430 CALL zlacpy( 'A', n, n, work( indwrk ), n, a, lda )
431 END IF
432*
433* If matrix was scaled, then rescale eigenvalues appropriately.
434*
435 IF( iscale.EQ.1 ) THEN
436 IF( info.EQ.0 ) THEN
437 imax = n
438 ELSE
439 imax = info - 1
440 END IF
441 CALL dscal( imax, one / sigma, w, 1 )
442 END IF
443*
444 work( 1 ) = lwmin
445 rwork( 1 ) = lrwmin
446 iwork( 1 ) = liwmin
447*
448 RETURN
449*
450* End of ZHEEVD_2STAGE
451*

◆ zheevr()

subroutine zheevr ( character jobz,
character range,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision abstol,
integer m,
double precision, dimension( * ) w,
complex*16, dimension( ldz, * ) z,
integer ldz,
integer, dimension( * ) isuppz,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer lrwork,
integer, dimension( * ) iwork,
integer liwork,
integer info )

ZHEEVR computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEVR + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEVR computes selected eigenvalues and, optionally, eigenvectors
!> of a complex Hermitian matrix A.  Eigenvalues and eigenvectors can
!> be selected by specifying either a range of values or a range of
!> indices for the desired eigenvalues.
!>
!> ZHEEVR first reduces the matrix A to tridiagonal form T with a call
!> to ZHETRD.  Then, whenever possible, ZHEEVR calls ZSTEMR to compute
!> eigenspectrum using Relatively Robust Representations.  ZSTEMR
!> computes eigenvalues by the dqds algorithm, while orthogonal
!> eigenvectors are computed from various  L D L^T representations
!> (also known as Relatively Robust Representations). Gram-Schmidt
!> orthogonalization is avoided as far as possible. More specifically,
!> the various steps of the algorithm are as follows.
!>
!> For each unreduced block (submatrix) of T,
!>    (a) Compute T - sigma I  = L D L^T, so that L and D
!>        define all the wanted eigenvalues to high relative accuracy.
!>        This means that small relative changes in the entries of D and L
!>        cause only small relative changes in the eigenvalues and
!>        eigenvectors. The standard (unfactored) representation of the
!>        tridiagonal matrix T does not have this property in general.
!>    (b) Compute the eigenvalues to suitable accuracy.
!>        If the eigenvectors are desired, the algorithm attains full
!>        accuracy of the computed eigenvalues only right before
!>        the corresponding vectors have to be computed, see steps c) and d).
!>    (c) For each cluster of close eigenvalues, select a new
!>        shift close to the cluster, find a new factorization, and refine
!>        the shifted eigenvalues to suitable accuracy.
!>    (d) For each eigenvalue with a large enough relative separation compute
!>        the corresponding eigenvector by forming a rank revealing twisted
!>        factorization. Go back to (c) for any clusters that remain.
!>
!> The desired accuracy of the output can be specified by the input
!> parameter ABSTOL.
!>
!> For more details, see ZSTEMR's documentation and:
!> - Inderjit S. Dhillon and Beresford N. Parlett: 
!>   Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
!> - Inderjit Dhillon and Beresford Parlett:  SIAM Journal on Matrix Analysis and Applications, Vol. 25,
!>   2004.  Also LAPACK Working Note 154.
!> - Inderjit Dhillon: ,
!>   Computer Science Division Technical Report No. UCB/CSD-97-971,
!>   UC Berkeley, May 1997.
!>
!>
!> Note 1 : ZHEEVR calls ZSTEMR when the full spectrum is requested
!> on machines which conform to the ieee-754 floating point standard.
!> ZHEEVR calls DSTEBZ and ZSTEIN on non-ieee machines and
!> when partial spectrum requests are made.
!>
!> Normal execution of ZSTEMR may create NaNs and infinities and
!> hence may abort due to a floating point exception in environments
!> which do not handle NaNs and infinities in the ieee standard default
!> manner.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': all eigenvalues will be found.
!>          = 'V': all eigenvalues in the half-open interval (VL,VU]
!>                 will be found.
!>          = 'I': the IL-th through IU-th eigenvalues will be found.
!>          For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and
!>          ZSTEIN are called
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, the lower triangle (if UPLO='L') or the upper
!>          triangle (if UPLO='U') of A, including the diagonal, is
!>          destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The absolute error tolerance for the eigenvalues.
!>          An approximate eigenvalue is accepted as converged
!>          when it is determined to lie in an interval [a,b]
!>          of width less than or equal to
!>
!>                  ABSTOL + EPS *   max( |a|,|b| ) ,
!>
!>          where EPS is the machine precision.  If ABSTOL is less than
!>          or equal to zero, then  EPS*|T|  will be used in its place,
!>          where |T| is the 1-norm of the tridiagonal matrix obtained
!>          by reducing A to tridiagonal form.
!>
!>          See  by Demmel and
!>          Kahan, LAPACK Working Note #3.
!>
!>          If high relative accuracy is important, set ABSTOL to
!>          DLAMCH( 'Safe minimum' ).  Doing so will guarantee that
!>          eigenvalues are computed to high relative accuracy when
!>          possible in future releases.  The current code does not
!>          make any guarantees about high relative accuracy, but
!>          future releases will. See J. Barlow and J. Demmel,
!>          , LAPACK Working Note #7, for a discussion
!>          of which matrices define their eigenvalues to high relative
!>          accuracy.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues found.  0 <= M <= N.
!>          If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          The first M elements contain the selected eigenvalues in
!>          ascending order.
!> 
[out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
!>          If JOBZ = 'V', then if INFO = 0, the first M columns of Z
!>          contain the orthonormal eigenvectors of the matrix A
!>          corresponding to the selected eigenvalues, with the i-th
!>          column of Z holding the eigenvector associated with W(i).
!>          If JOBZ = 'N', then Z is not referenced.
!>          Note: the user must ensure that at least max(1,M) columns are
!>          supplied in the array Z; if RANGE = 'V', the exact value of M
!>          is not known in advance and an upper bound must be used.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.  LDZ >= 1, and if
!>          JOBZ = 'V', LDZ >= max(1,N).
!> 
[out]ISUPPZ
!>          ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )
!>          The support of the eigenvectors in Z, i.e., the indices
!>          indicating the nonzero elements in Z. The i-th eigenvector
!>          is nonzero only in elements ISUPPZ( 2*i-1 ) through
!>          ISUPPZ( 2*i ). This is an output of ZSTEMR (tridiagonal
!>          matrix). The support of the eigenvectors of A is typically
!>          1:N because of the unitary transformations applied by ZUNMTR.
!>          Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.  LWORK >= max(1,2*N).
!>          For optimal efficiency, LWORK >= (NB+1)*N,
!>          where NB is the max of the blocksize for ZHETRD and for
!>          ZUNMTR as returned by ILAENV.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal sizes of the WORK, RWORK and
!>          IWORK arrays, returns these values as the first entries of
!>          the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
!>          On exit, if INFO = 0, RWORK(1) returns the optimal
!>          (and minimal) LRWORK.
!> 
[in]LRWORK
!>          LRWORK is INTEGER
!>          The length of the array RWORK.  LRWORK >= max(1,24*N).
!>
!>          If LRWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
!>          On exit, if INFO = 0, IWORK(1) returns the optimal
!>          (and minimal) LIWORK.
!> 
[in]LIWORK
!>          LIWORK is INTEGER
!>          The dimension of the array IWORK.  LIWORK >= max(1,10*N).
!>
!>          If LIWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  Internal error
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Inderjit Dhillon, IBM Almaden, USA
Osni Marques, LBNL/NERSC, USA
Ken Stanley, Computer Science Division, University of California at Berkeley, USA
Jason Riedy, Computer Science Division, University of California at Berkeley, USA

Definition at line 354 of file zheevr.f.

357*
358* -- LAPACK driver routine --
359* -- LAPACK is a software package provided by Univ. of Tennessee, --
360* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
361*
362* .. Scalar Arguments ..
363 CHARACTER JOBZ, RANGE, UPLO
364 INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LRWORK, LWORK,
365 $ M, N
366 DOUBLE PRECISION ABSTOL, VL, VU
367* ..
368* .. Array Arguments ..
369 INTEGER ISUPPZ( * ), IWORK( * )
370 DOUBLE PRECISION RWORK( * ), W( * )
371 COMPLEX*16 A( LDA, * ), WORK( * ), Z( LDZ, * )
372* ..
373*
374* =====================================================================
375*
376* .. Parameters ..
377 DOUBLE PRECISION ZERO, ONE, TWO
378 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
379* ..
380* .. Local Scalars ..
381 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
382 $ WANTZ, TRYRAC
383 CHARACTER ORDER
384 INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP,
385 $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK,
386 $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ,
387 $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN,
388 $ LWKOPT, LWMIN, NB, NSPLIT
389 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
390 $ SIGMA, SMLNUM, TMP1, VLL, VUU
391* ..
392* .. External Functions ..
393 LOGICAL LSAME
394 INTEGER ILAENV
395 DOUBLE PRECISION DLAMCH, ZLANSY
396 EXTERNAL lsame, ilaenv, dlamch, zlansy
397* ..
398* .. External Subroutines ..
399 EXTERNAL dcopy, dscal, dstebz, dsterf, xerbla, zdscal,
401* ..
402* .. Intrinsic Functions ..
403 INTRINSIC dble, max, min, sqrt
404* ..
405* .. Executable Statements ..
406*
407* Test the input parameters.
408*
409 ieeeok = ilaenv( 10, 'ZHEEVR', 'N', 1, 2, 3, 4 )
410*
411 lower = lsame( uplo, 'L' )
412 wantz = lsame( jobz, 'V' )
413 alleig = lsame( range, 'A' )
414 valeig = lsame( range, 'V' )
415 indeig = lsame( range, 'I' )
416*
417 lquery = ( ( lwork.EQ.-1 ) .OR. ( lrwork.EQ.-1 ) .OR.
418 $ ( liwork.EQ.-1 ) )
419*
420 lrwmin = max( 1, 24*n )
421 liwmin = max( 1, 10*n )
422 lwmin = max( 1, 2*n )
423*
424 info = 0
425 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
426 info = -1
427 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
428 info = -2
429 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
430 info = -3
431 ELSE IF( n.LT.0 ) THEN
432 info = -4
433 ELSE IF( lda.LT.max( 1, n ) ) THEN
434 info = -6
435 ELSE
436 IF( valeig ) THEN
437 IF( n.GT.0 .AND. vu.LE.vl )
438 $ info = -8
439 ELSE IF( indeig ) THEN
440 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
441 info = -9
442 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
443 info = -10
444 END IF
445 END IF
446 END IF
447 IF( info.EQ.0 ) THEN
448 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
449 info = -15
450 END IF
451 END IF
452*
453 IF( info.EQ.0 ) THEN
454 nb = ilaenv( 1, 'ZHETRD', uplo, n, -1, -1, -1 )
455 nb = max( nb, ilaenv( 1, 'ZUNMTR', uplo, n, -1, -1, -1 ) )
456 lwkopt = max( ( nb+1 )*n, lwmin )
457 work( 1 ) = lwkopt
458 rwork( 1 ) = lrwmin
459 iwork( 1 ) = liwmin
460*
461 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
462 info = -18
463 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
464 info = -20
465 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
466 info = -22
467 END IF
468 END IF
469*
470 IF( info.NE.0 ) THEN
471 CALL xerbla( 'ZHEEVR', -info )
472 RETURN
473 ELSE IF( lquery ) THEN
474 RETURN
475 END IF
476*
477* Quick return if possible
478*
479 m = 0
480 IF( n.EQ.0 ) THEN
481 work( 1 ) = 1
482 RETURN
483 END IF
484*
485 IF( n.EQ.1 ) THEN
486 work( 1 ) = 2
487 IF( alleig .OR. indeig ) THEN
488 m = 1
489 w( 1 ) = dble( a( 1, 1 ) )
490 ELSE
491 IF( vl.LT.dble( a( 1, 1 ) ) .AND. vu.GE.dble( a( 1, 1 ) ) )
492 $ THEN
493 m = 1
494 w( 1 ) = dble( a( 1, 1 ) )
495 END IF
496 END IF
497 IF( wantz ) THEN
498 z( 1, 1 ) = one
499 isuppz( 1 ) = 1
500 isuppz( 2 ) = 1
501 END IF
502 RETURN
503 END IF
504*
505* Get machine constants.
506*
507 safmin = dlamch( 'Safe minimum' )
508 eps = dlamch( 'Precision' )
509 smlnum = safmin / eps
510 bignum = one / smlnum
511 rmin = sqrt( smlnum )
512 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
513*
514* Scale matrix to allowable range, if necessary.
515*
516 iscale = 0
517 abstll = abstol
518 IF (valeig) THEN
519 vll = vl
520 vuu = vu
521 END IF
522 anrm = zlansy( 'M', uplo, n, a, lda, rwork )
523 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
524 iscale = 1
525 sigma = rmin / anrm
526 ELSE IF( anrm.GT.rmax ) THEN
527 iscale = 1
528 sigma = rmax / anrm
529 END IF
530 IF( iscale.EQ.1 ) THEN
531 IF( lower ) THEN
532 DO 10 j = 1, n
533 CALL zdscal( n-j+1, sigma, a( j, j ), 1 )
534 10 CONTINUE
535 ELSE
536 DO 20 j = 1, n
537 CALL zdscal( j, sigma, a( 1, j ), 1 )
538 20 CONTINUE
539 END IF
540 IF( abstol.GT.0 )
541 $ abstll = abstol*sigma
542 IF( valeig ) THEN
543 vll = vl*sigma
544 vuu = vu*sigma
545 END IF
546 END IF
547
548* Initialize indices into workspaces. Note: The IWORK indices are
549* used only if DSTERF or ZSTEMR fail.
550
551* WORK(INDTAU:INDTAU+N-1) stores the complex scalar factors of the
552* elementary reflectors used in ZHETRD.
553 indtau = 1
554* INDWK is the starting offset of the remaining complex workspace,
555* and LLWORK is the remaining complex workspace size.
556 indwk = indtau + n
557 llwork = lwork - indwk + 1
558
559* RWORK(INDRD:INDRD+N-1) stores the real tridiagonal's diagonal
560* entries.
561 indrd = 1
562* RWORK(INDRE:INDRE+N-1) stores the off-diagonal entries of the
563* tridiagonal matrix from ZHETRD.
564 indre = indrd + n
565* RWORK(INDRDD:INDRDD+N-1) is a copy of the diagonal entries over
566* -written by ZSTEMR (the DSTERF path copies the diagonal to W).
567 indrdd = indre + n
568* RWORK(INDREE:INDREE+N-1) is a copy of the off-diagonal entries over
569* -written while computing the eigenvalues in DSTERF and ZSTEMR.
570 indree = indrdd + n
571* INDRWK is the starting offset of the left-over real workspace, and
572* LLRWORK is the remaining workspace size.
573 indrwk = indree + n
574 llrwork = lrwork - indrwk + 1
575
576* IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and
577* stores the block indices of each of the M<=N eigenvalues.
578 indibl = 1
579* IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and
580* stores the starting and finishing indices of each block.
581 indisp = indibl + n
582* IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors
583* that corresponding to eigenvectors that fail to converge in
584* DSTEIN. This information is discarded; if any fail, the driver
585* returns INFO > 0.
586 indifl = indisp + n
587* INDIWO is the offset of the remaining integer workspace.
588 indiwo = indifl + n
589
590*
591* Call ZHETRD to reduce Hermitian matrix to tridiagonal form.
592*
593 CALL zhetrd( uplo, n, a, lda, rwork( indrd ), rwork( indre ),
594 $ work( indtau ), work( indwk ), llwork, iinfo )
595*
596* If all eigenvalues are desired
597* then call DSTERF or ZSTEMR and ZUNMTR.
598*
599 test = .false.
600 IF( indeig ) THEN
601 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
602 test = .true.
603 END IF
604 END IF
605 IF( ( alleig.OR.test ) .AND. ( ieeeok.EQ.1 ) ) THEN
606 IF( .NOT.wantz ) THEN
607 CALL dcopy( n, rwork( indrd ), 1, w, 1 )
608 CALL dcopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
609 CALL dsterf( n, w, rwork( indree ), info )
610 ELSE
611 CALL dcopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
612 CALL dcopy( n, rwork( indrd ), 1, rwork( indrdd ), 1 )
613*
614 IF (abstol .LE. two*n*eps) THEN
615 tryrac = .true.
616 ELSE
617 tryrac = .false.
618 END IF
619 CALL zstemr( jobz, 'A', n, rwork( indrdd ),
620 $ rwork( indree ), vl, vu, il, iu, m, w,
621 $ z, ldz, n, isuppz, tryrac,
622 $ rwork( indrwk ), llrwork,
623 $ iwork, liwork, info )
624*
625* Apply unitary matrix used in reduction to tridiagonal
626* form to eigenvectors returned by ZSTEMR.
627*
628 IF( wantz .AND. info.EQ.0 ) THEN
629 indwkn = indwk
630 llwrkn = lwork - indwkn + 1
631 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda,
632 $ work( indtau ), z, ldz, work( indwkn ),
633 $ llwrkn, iinfo )
634 END IF
635 END IF
636*
637*
638 IF( info.EQ.0 ) THEN
639 m = n
640 GO TO 30
641 END IF
642 info = 0
643 END IF
644*
645* Otherwise, call DSTEBZ and, if eigenvectors are desired, ZSTEIN.
646* Also call DSTEBZ and ZSTEIN if ZSTEMR fails.
647*
648 IF( wantz ) THEN
649 order = 'B'
650 ELSE
651 order = 'E'
652 END IF
653
654 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
655 $ rwork( indrd ), rwork( indre ), m, nsplit, w,
656 $ iwork( indibl ), iwork( indisp ), rwork( indrwk ),
657 $ iwork( indiwo ), info )
658*
659 IF( wantz ) THEN
660 CALL zstein( n, rwork( indrd ), rwork( indre ), m, w,
661 $ iwork( indibl ), iwork( indisp ), z, ldz,
662 $ rwork( indrwk ), iwork( indiwo ), iwork( indifl ),
663 $ info )
664*
665* Apply unitary matrix used in reduction to tridiagonal
666* form to eigenvectors returned by ZSTEIN.
667*
668 indwkn = indwk
669 llwrkn = lwork - indwkn + 1
670 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda, work( indtau ), z,
671 $ ldz, work( indwkn ), llwrkn, iinfo )
672 END IF
673*
674* If matrix was scaled, then rescale eigenvalues appropriately.
675*
676 30 CONTINUE
677 IF( iscale.EQ.1 ) THEN
678 IF( info.EQ.0 ) THEN
679 imax = m
680 ELSE
681 imax = info - 1
682 END IF
683 CALL dscal( imax, one / sigma, w, 1 )
684 END IF
685*
686* If eigenvalues are not in order, then sort them, along with
687* eigenvectors.
688*
689 IF( wantz ) THEN
690 DO 50 j = 1, m - 1
691 i = 0
692 tmp1 = w( j )
693 DO 40 jj = j + 1, m
694 IF( w( jj ).LT.tmp1 ) THEN
695 i = jj
696 tmp1 = w( jj )
697 END IF
698 40 CONTINUE
699*
700 IF( i.NE.0 ) THEN
701 itmp1 = iwork( indibl+i-1 )
702 w( i ) = w( j )
703 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
704 w( j ) = tmp1
705 iwork( indibl+j-1 ) = itmp1
706 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
707 END IF
708 50 CONTINUE
709 END IF
710*
711* Set WORK(1) to optimal workspace size.
712*
713 work( 1 ) = lwkopt
714 rwork( 1 ) = lrwmin
715 iwork( 1 ) = liwmin
716*
717 RETURN
718*
719* End of ZHEEVR
720*
subroutine dstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
DSTEBZ
Definition dstebz.f:273
subroutine zstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
ZSTEIN
Definition zstein.f:182
subroutine zstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
ZSTEMR
Definition zstemr.f:338
double precision function zlansy(norm, uplo, n, a, lda, work)
ZLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition zlansy.f:123
subroutine zdscal(n, da, zx, incx)
ZDSCAL
Definition zdscal.f:78
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
#define min(a, b)
Definition macros.h:20

◆ zheevr_2stage()

subroutine zheevr_2stage ( character jobz,
character range,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision abstol,
integer m,
double precision, dimension( * ) w,
complex*16, dimension( ldz, * ) z,
integer ldz,
integer, dimension( * ) isuppz,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer lrwork,
integer, dimension( * ) iwork,
integer liwork,
integer info )

ZHEEVR_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEVR_2STAGE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEVR_2STAGE computes selected eigenvalues and, optionally, eigenvectors
!> of a complex Hermitian matrix A using the 2stage technique for
!> the reduction to tridiagonal.  Eigenvalues and eigenvectors can
!> be selected by specifying either a range of values or a range of
!> indices for the desired eigenvalues.
!>
!> ZHEEVR_2STAGE first reduces the matrix A to tridiagonal form T with a call
!> to ZHETRD.  Then, whenever possible, ZHEEVR_2STAGE calls ZSTEMR to compute
!> eigenspectrum using Relatively Robust Representations.  ZSTEMR
!> computes eigenvalues by the dqds algorithm, while orthogonal
!> eigenvectors are computed from various  L D L^T representations
!> (also known as Relatively Robust Representations). Gram-Schmidt
!> orthogonalization is avoided as far as possible. More specifically,
!> the various steps of the algorithm are as follows.
!>
!> For each unreduced block (submatrix) of T,
!>    (a) Compute T - sigma I  = L D L^T, so that L and D
!>        define all the wanted eigenvalues to high relative accuracy.
!>        This means that small relative changes in the entries of D and L
!>        cause only small relative changes in the eigenvalues and
!>        eigenvectors. The standard (unfactored) representation of the
!>        tridiagonal matrix T does not have this property in general.
!>    (b) Compute the eigenvalues to suitable accuracy.
!>        If the eigenvectors are desired, the algorithm attains full
!>        accuracy of the computed eigenvalues only right before
!>        the corresponding vectors have to be computed, see steps c) and d).
!>    (c) For each cluster of close eigenvalues, select a new
!>        shift close to the cluster, find a new factorization, and refine
!>        the shifted eigenvalues to suitable accuracy.
!>    (d) For each eigenvalue with a large enough relative separation compute
!>        the corresponding eigenvector by forming a rank revealing twisted
!>        factorization. Go back to (c) for any clusters that remain.
!>
!> The desired accuracy of the output can be specified by the input
!> parameter ABSTOL.
!>
!> For more details, see ZSTEMR's documentation and:
!> - Inderjit S. Dhillon and Beresford N. Parlett: 
!>   Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
!> - Inderjit Dhillon and Beresford Parlett:  SIAM Journal on Matrix Analysis and Applications, Vol. 25,
!>   2004.  Also LAPACK Working Note 154.
!> - Inderjit Dhillon: ,
!>   Computer Science Division Technical Report No. UCB/CSD-97-971,
!>   UC Berkeley, May 1997.
!>
!>
!> Note 1 : ZHEEVR_2STAGE calls ZSTEMR when the full spectrum is requested
!> on machines which conform to the ieee-754 floating point standard.
!> ZHEEVR_2STAGE calls DSTEBZ and ZSTEIN on non-ieee machines and
!> when partial spectrum requests are made.
!>
!> Normal execution of ZSTEMR may create NaNs and infinities and
!> hence may abort due to a floating point exception in environments
!> which do not handle NaNs and infinities in the ieee standard default
!> manner.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!>                  Not available in this release.
!> 
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': all eigenvalues will be found.
!>          = 'V': all eigenvalues in the half-open interval (VL,VU]
!>                 will be found.
!>          = 'I': the IL-th through IU-th eigenvalues will be found.
!>          For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and
!>          ZSTEIN are called
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, the lower triangle (if UPLO='L') or the upper
!>          triangle (if UPLO='U') of A, including the diagonal, is
!>          destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The absolute error tolerance for the eigenvalues.
!>          An approximate eigenvalue is accepted as converged
!>          when it is determined to lie in an interval [a,b]
!>          of width less than or equal to
!>
!>                  ABSTOL + EPS *   max( |a|,|b| ) ,
!>
!>          where EPS is the machine precision.  If ABSTOL is less than
!>          or equal to zero, then  EPS*|T|  will be used in its place,
!>          where |T| is the 1-norm of the tridiagonal matrix obtained
!>          by reducing A to tridiagonal form.
!>
!>          See  by Demmel and
!>          Kahan, LAPACK Working Note #3.
!>
!>          If high relative accuracy is important, set ABSTOL to
!>          DLAMCH( 'Safe minimum' ).  Doing so will guarantee that
!>          eigenvalues are computed to high relative accuracy when
!>          possible in future releases.  The current code does not
!>          make any guarantees about high relative accuracy, but
!>          future releases will. See J. Barlow and J. Demmel,
!>          , LAPACK Working Note #7, for a discussion
!>          of which matrices define their eigenvalues to high relative
!>          accuracy.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues found.  0 <= M <= N.
!>          If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          The first M elements contain the selected eigenvalues in
!>          ascending order.
!> 
[out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
!>          If JOBZ = 'V', then if INFO = 0, the first M columns of Z
!>          contain the orthonormal eigenvectors of the matrix A
!>          corresponding to the selected eigenvalues, with the i-th
!>          column of Z holding the eigenvector associated with W(i).
!>          If JOBZ = 'N', then Z is not referenced.
!>          Note: the user must ensure that at least max(1,M) columns are
!>          supplied in the array Z; if RANGE = 'V', the exact value of M
!>          is not known in advance and an upper bound must be used.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.  LDZ >= 1, and if
!>          JOBZ = 'V', LDZ >= max(1,N).
!> 
[out]ISUPPZ
!>          ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )
!>          The support of the eigenvectors in Z, i.e., the indices
!>          indicating the nonzero elements in Z. The i-th eigenvector
!>          is nonzero only in elements ISUPPZ( 2*i-1 ) through
!>          ISUPPZ( 2*i ). This is an output of ZSTEMR (tridiagonal
!>          matrix). The support of the eigenvectors of A is typically 
!>          1:N because of the unitary transformations applied by ZUNMTR.
!>          Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.  
!>          If JOBZ = 'N' and N > 1, LWORK must be queried.
!>                                   LWORK = MAX(1, 26*N, dimension) where
!>                                   dimension = max(stage1,stage2) + (KD+1)*N + N
!>                                             = N*KD + N*max(KD+1,FACTOPTNB) 
!>                                               + max(2*KD*KD, KD*NTHREADS) 
!>                                               + (KD+1)*N + N
!>                                   where KD is the blocking size of the reduction,
!>                                   FACTOPTNB is the blocking used by the QR or LQ
!>                                   algorithm, usually FACTOPTNB=128 is a good choice
!>                                   NTHREADS is the number of threads used when
!>                                   openMP compilation is enabled, otherwise =1.
!>          If JOBZ = 'V' and N > 1, LWORK must be queried. Not yet available
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal sizes of the WORK, RWORK and
!>          IWORK arrays, returns these values as the first entries of
!>          the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
!>          On exit, if INFO = 0, RWORK(1) returns the optimal
!>          (and minimal) LRWORK.
!> 
[in]LRWORK
!>          LRWORK is INTEGER
!>          The length of the array RWORK.  LRWORK >= max(1,24*N).
!>
!>          If LRWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
!>          On exit, if INFO = 0, IWORK(1) returns the optimal
!>          (and minimal) LIWORK.
!> 
[in]LIWORK
!>          LIWORK is INTEGER
!>          The dimension of the array IWORK.  LIWORK >= max(1,10*N).
!>
!>          If LIWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  Internal error
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Inderjit Dhillon, IBM Almaden, USA
Osni Marques, LBNL/NERSC, USA
Ken Stanley, Computer Science Division, University of California at Berkeley, USA
Jason Riedy, Computer Science Division, University of California at Berkeley, USA
Further Details:
!>
!>  All details about the 2stage techniques are available in:
!>
!>  Azzam Haidar, Hatem Ltaief, and Jack Dongarra.
!>  Parallel reduction to condensed forms for symmetric eigenvalue problems
!>  using aggregated fine-grained and memory-aware kernels. In Proceedings
!>  of 2011 International Conference for High Performance Computing,
!>  Networking, Storage and Analysis (SC '11), New York, NY, USA,
!>  Article 8 , 11 pages.
!>  http://doi.acm.org/10.1145/2063384.2063394
!>
!>  A. Haidar, J. Kurzak, P. Luszczek, 2013.
!>  An improved parallel singular value algorithm and its implementation 
!>  for multicore hardware, In Proceedings of 2013 International Conference
!>  for High Performance Computing, Networking, Storage and Analysis (SC '13).
!>  Denver, Colorado, USA, 2013.
!>  Article 90, 12 pages.
!>  http://doi.acm.org/10.1145/2503210.2503292
!>
!>  A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.
!>  A novel hybrid CPU-GPU generalized eigensolver for electronic structure 
!>  calculations based on fine-grained memory aware tasks.
!>  International Journal of High Performance Computing Applications.
!>  Volume 28 Issue 2, Pages 196-209, May 2014.
!>  http://hpc.sagepub.com/content/28/2/196 
!>
!> 

Definition at line 402 of file zheevr_2stage.f.

406*
407 IMPLICIT NONE
408*
409* -- LAPACK driver routine --
410* -- LAPACK is a software package provided by Univ. of Tennessee, --
411* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
412*
413* .. Scalar Arguments ..
414 CHARACTER JOBZ, RANGE, UPLO
415 INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LRWORK, LWORK,
416 $ M, N
417 DOUBLE PRECISION ABSTOL, VL, VU
418* ..
419* .. Array Arguments ..
420 INTEGER ISUPPZ( * ), IWORK( * )
421 DOUBLE PRECISION RWORK( * ), W( * )
422 COMPLEX*16 A( LDA, * ), WORK( * ), Z( LDZ, * )
423* ..
424*
425* =====================================================================
426*
427* .. Parameters ..
428 DOUBLE PRECISION ZERO, ONE, TWO
429 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
430* ..
431* .. Local Scalars ..
432 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
433 $ WANTZ, TRYRAC
434 CHARACTER ORDER
435 INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP,
436 $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK,
437 $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ,
438 $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN,
439 $ LWMIN, NSPLIT, LHTRD, LWTRD, KD, IB, INDHOUS
440 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
441 $ SIGMA, SMLNUM, TMP1, VLL, VUU
442* ..
443* .. External Functions ..
444 LOGICAL LSAME
445 INTEGER ILAENV, ILAENV2STAGE
446 DOUBLE PRECISION DLAMCH, ZLANSY
448* ..
449* .. External Subroutines ..
450 EXTERNAL dcopy, dscal, dstebz, dsterf, xerbla, zdscal,
452* ..
453* .. Intrinsic Functions ..
454 INTRINSIC dble, max, min, sqrt
455* ..
456* .. Executable Statements ..
457*
458* Test the input parameters.
459*
460 ieeeok = ilaenv( 10, 'ZHEEVR', 'N', 1, 2, 3, 4 )
461*
462 lower = lsame( uplo, 'L' )
463 wantz = lsame( jobz, 'V' )
464 alleig = lsame( range, 'A' )
465 valeig = lsame( range, 'V' )
466 indeig = lsame( range, 'I' )
467*
468 lquery = ( ( lwork.EQ.-1 ) .OR. ( lrwork.EQ.-1 ) .OR.
469 $ ( liwork.EQ.-1 ) )
470*
471 kd = ilaenv2stage( 1, 'ZHETRD_2STAGE', jobz, n, -1, -1, -1 )
472 ib = ilaenv2stage( 2, 'ZHETRD_2STAGE', jobz, n, kd, -1, -1 )
473 lhtrd = ilaenv2stage( 3, 'ZHETRD_2STAGE', jobz, n, kd, ib, -1 )
474 lwtrd = ilaenv2stage( 4, 'ZHETRD_2STAGE', jobz, n, kd, ib, -1 )
475 lwmin = n + lhtrd + lwtrd
476 lrwmin = max( 1, 24*n )
477 liwmin = max( 1, 10*n )
478*
479 info = 0
480 IF( .NOT.( lsame( jobz, 'N' ) ) ) THEN
481 info = -1
482 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
483 info = -2
484 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
485 info = -3
486 ELSE IF( n.LT.0 ) THEN
487 info = -4
488 ELSE IF( lda.LT.max( 1, n ) ) THEN
489 info = -6
490 ELSE
491 IF( valeig ) THEN
492 IF( n.GT.0 .AND. vu.LE.vl )
493 $ info = -8
494 ELSE IF( indeig ) THEN
495 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
496 info = -9
497 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
498 info = -10
499 END IF
500 END IF
501 END IF
502 IF( info.EQ.0 ) THEN
503 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
504 info = -15
505 END IF
506 END IF
507*
508 IF( info.EQ.0 ) THEN
509 work( 1 ) = lwmin
510 rwork( 1 ) = lrwmin
511 iwork( 1 ) = liwmin
512*
513 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
514 info = -18
515 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
516 info = -20
517 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
518 info = -22
519 END IF
520 END IF
521*
522 IF( info.NE.0 ) THEN
523 CALL xerbla( 'ZHEEVR_2STAGE', -info )
524 RETURN
525 ELSE IF( lquery ) THEN
526 RETURN
527 END IF
528*
529* Quick return if possible
530*
531 m = 0
532 IF( n.EQ.0 ) THEN
533 work( 1 ) = 1
534 RETURN
535 END IF
536*
537 IF( n.EQ.1 ) THEN
538 work( 1 ) = 2
539 IF( alleig .OR. indeig ) THEN
540 m = 1
541 w( 1 ) = dble( a( 1, 1 ) )
542 ELSE
543 IF( vl.LT.dble( a( 1, 1 ) ) .AND. vu.GE.dble( a( 1, 1 ) ) )
544 $ THEN
545 m = 1
546 w( 1 ) = dble( a( 1, 1 ) )
547 END IF
548 END IF
549 IF( wantz ) THEN
550 z( 1, 1 ) = one
551 isuppz( 1 ) = 1
552 isuppz( 2 ) = 1
553 END IF
554 RETURN
555 END IF
556*
557* Get machine constants.
558*
559 safmin = dlamch( 'Safe minimum' )
560 eps = dlamch( 'Precision' )
561 smlnum = safmin / eps
562 bignum = one / smlnum
563 rmin = sqrt( smlnum )
564 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
565*
566* Scale matrix to allowable range, if necessary.
567*
568 iscale = 0
569 abstll = abstol
570 IF (valeig) THEN
571 vll = vl
572 vuu = vu
573 END IF
574 anrm = zlansy( 'M', uplo, n, a, lda, rwork )
575 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
576 iscale = 1
577 sigma = rmin / anrm
578 ELSE IF( anrm.GT.rmax ) THEN
579 iscale = 1
580 sigma = rmax / anrm
581 END IF
582 IF( iscale.EQ.1 ) THEN
583 IF( lower ) THEN
584 DO 10 j = 1, n
585 CALL zdscal( n-j+1, sigma, a( j, j ), 1 )
586 10 CONTINUE
587 ELSE
588 DO 20 j = 1, n
589 CALL zdscal( j, sigma, a( 1, j ), 1 )
590 20 CONTINUE
591 END IF
592 IF( abstol.GT.0 )
593 $ abstll = abstol*sigma
594 IF( valeig ) THEN
595 vll = vl*sigma
596 vuu = vu*sigma
597 END IF
598 END IF
599
600* Initialize indices into workspaces. Note: The IWORK indices are
601* used only if DSTERF or ZSTEMR fail.
602
603* WORK(INDTAU:INDTAU+N-1) stores the complex scalar factors of the
604* elementary reflectors used in ZHETRD.
605 indtau = 1
606* INDWK is the starting offset of the remaining complex workspace,
607* and LLWORK is the remaining complex workspace size.
608 indhous = indtau + n
609 indwk = indhous + lhtrd
610 llwork = lwork - indwk + 1
611
612* RWORK(INDRD:INDRD+N-1) stores the real tridiagonal's diagonal
613* entries.
614 indrd = 1
615* RWORK(INDRE:INDRE+N-1) stores the off-diagonal entries of the
616* tridiagonal matrix from ZHETRD.
617 indre = indrd + n
618* RWORK(INDRDD:INDRDD+N-1) is a copy of the diagonal entries over
619* -written by ZSTEMR (the DSTERF path copies the diagonal to W).
620 indrdd = indre + n
621* RWORK(INDREE:INDREE+N-1) is a copy of the off-diagonal entries over
622* -written while computing the eigenvalues in DSTERF and ZSTEMR.
623 indree = indrdd + n
624* INDRWK is the starting offset of the left-over real workspace, and
625* LLRWORK is the remaining workspace size.
626 indrwk = indree + n
627 llrwork = lrwork - indrwk + 1
628
629* IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and
630* stores the block indices of each of the M<=N eigenvalues.
631 indibl = 1
632* IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and
633* stores the starting and finishing indices of each block.
634 indisp = indibl + n
635* IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors
636* that corresponding to eigenvectors that fail to converge in
637* ZSTEIN. This information is discarded; if any fail, the driver
638* returns INFO > 0.
639 indifl = indisp + n
640* INDIWO is the offset of the remaining integer workspace.
641 indiwo = indifl + n
642
643*
644* Call ZHETRD_2STAGE to reduce Hermitian matrix to tridiagonal form.
645*
646 CALL zhetrd_2stage( jobz, uplo, n, a, lda, rwork( indrd ),
647 $ rwork( indre ), work( indtau ),
648 $ work( indhous ), lhtrd,
649 $ work( indwk ), llwork, iinfo )
650*
651* If all eigenvalues are desired
652* then call DSTERF or ZSTEMR and ZUNMTR.
653*
654 test = .false.
655 IF( indeig ) THEN
656 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
657 test = .true.
658 END IF
659 END IF
660 IF( ( alleig.OR.test ) .AND. ( ieeeok.EQ.1 ) ) THEN
661 IF( .NOT.wantz ) THEN
662 CALL dcopy( n, rwork( indrd ), 1, w, 1 )
663 CALL dcopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
664 CALL dsterf( n, w, rwork( indree ), info )
665 ELSE
666 CALL dcopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
667 CALL dcopy( n, rwork( indrd ), 1, rwork( indrdd ), 1 )
668*
669 IF (abstol .LE. two*n*eps) THEN
670 tryrac = .true.
671 ELSE
672 tryrac = .false.
673 END IF
674 CALL zstemr( jobz, 'A', n, rwork( indrdd ),
675 $ rwork( indree ), vl, vu, il, iu, m, w,
676 $ z, ldz, n, isuppz, tryrac,
677 $ rwork( indrwk ), llrwork,
678 $ iwork, liwork, info )
679*
680* Apply unitary matrix used in reduction to tridiagonal
681* form to eigenvectors returned by ZSTEMR.
682*
683 IF( wantz .AND. info.EQ.0 ) THEN
684 indwkn = indwk
685 llwrkn = lwork - indwkn + 1
686 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda,
687 $ work( indtau ), z, ldz, work( indwkn ),
688 $ llwrkn, iinfo )
689 END IF
690 END IF
691*
692*
693 IF( info.EQ.0 ) THEN
694 m = n
695 GO TO 30
696 END IF
697 info = 0
698 END IF
699*
700* Otherwise, call DSTEBZ and, if eigenvectors are desired, ZSTEIN.
701* Also call DSTEBZ and ZSTEIN if ZSTEMR fails.
702*
703 IF( wantz ) THEN
704 order = 'B'
705 ELSE
706 order = 'E'
707 END IF
708
709 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
710 $ rwork( indrd ), rwork( indre ), m, nsplit, w,
711 $ iwork( indibl ), iwork( indisp ), rwork( indrwk ),
712 $ iwork( indiwo ), info )
713*
714 IF( wantz ) THEN
715 CALL zstein( n, rwork( indrd ), rwork( indre ), m, w,
716 $ iwork( indibl ), iwork( indisp ), z, ldz,
717 $ rwork( indrwk ), iwork( indiwo ), iwork( indifl ),
718 $ info )
719*
720* Apply unitary matrix used in reduction to tridiagonal
721* form to eigenvectors returned by ZSTEIN.
722*
723 indwkn = indwk
724 llwrkn = lwork - indwkn + 1
725 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda, work( indtau ), z,
726 $ ldz, work( indwkn ), llwrkn, iinfo )
727 END IF
728*
729* If matrix was scaled, then rescale eigenvalues appropriately.
730*
731 30 CONTINUE
732 IF( iscale.EQ.1 ) THEN
733 IF( info.EQ.0 ) THEN
734 imax = m
735 ELSE
736 imax = info - 1
737 END IF
738 CALL dscal( imax, one / sigma, w, 1 )
739 END IF
740*
741* If eigenvalues are not in order, then sort them, along with
742* eigenvectors.
743*
744 IF( wantz ) THEN
745 DO 50 j = 1, m - 1
746 i = 0
747 tmp1 = w( j )
748 DO 40 jj = j + 1, m
749 IF( w( jj ).LT.tmp1 ) THEN
750 i = jj
751 tmp1 = w( jj )
752 END IF
753 40 CONTINUE
754*
755 IF( i.NE.0 ) THEN
756 itmp1 = iwork( indibl+i-1 )
757 w( i ) = w( j )
758 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
759 w( j ) = tmp1
760 iwork( indibl+j-1 ) = itmp1
761 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
762 END IF
763 50 CONTINUE
764 END IF
765*
766* Set WORK(1) to optimal workspace size.
767*
768 work( 1 ) = lwmin
769 rwork( 1 ) = lrwmin
770 iwork( 1 ) = liwmin
771*
772 RETURN
773*
774* End of ZHEEVR_2STAGE
775*

◆ zheevx()

subroutine zheevx ( character jobz,
character range,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision abstol,
integer m,
double precision, dimension( * ) w,
complex*16, dimension( ldz, * ) z,
integer ldz,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer, dimension( * ) iwork,
integer, dimension( * ) ifail,
integer info )

ZHEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEVX + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEVX computes selected eigenvalues and, optionally, eigenvectors
!> of a complex Hermitian matrix A.  Eigenvalues and eigenvectors can
!> be selected by specifying either a range of values or a range of
!> indices for the desired eigenvalues.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': all eigenvalues will be found.
!>          = 'V': all eigenvalues in the half-open interval (VL,VU]
!>                 will be found.
!>          = 'I': the IL-th through IU-th eigenvalues will be found.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, the lower triangle (if UPLO='L') or the upper
!>          triangle (if UPLO='U') of A, including the diagonal, is
!>          destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The absolute error tolerance for the eigenvalues.
!>          An approximate eigenvalue is accepted as converged
!>          when it is determined to lie in an interval [a,b]
!>          of width less than or equal to
!>
!>                  ABSTOL + EPS *   max( |a|,|b| ) ,
!>
!>          where EPS is the machine precision.  If ABSTOL is less than
!>          or equal to zero, then  EPS*|T|  will be used in its place,
!>          where |T| is the 1-norm of the tridiagonal matrix obtained
!>          by reducing A to tridiagonal form.
!>
!>          Eigenvalues will be computed most accurately when ABSTOL is
!>          set to twice the underflow threshold 2*DLAMCH('S'), not zero.
!>          If this routine returns with INFO>0, indicating that some
!>          eigenvectors did not converge, try setting ABSTOL to
!>          2*DLAMCH('S').
!>
!>          See  by Demmel and
!>          Kahan, LAPACK Working Note #3.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues found.  0 <= M <= N.
!>          If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          On normal exit, the first M elements contain the selected
!>          eigenvalues in ascending order.
!> 
[out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
!>          If JOBZ = 'V', then if INFO = 0, the first M columns of Z
!>          contain the orthonormal eigenvectors of the matrix A
!>          corresponding to the selected eigenvalues, with the i-th
!>          column of Z holding the eigenvector associated with W(i).
!>          If an eigenvector fails to converge, then that column of Z
!>          contains the latest approximation to the eigenvector, and the
!>          index of the eigenvector is returned in IFAIL.
!>          If JOBZ = 'N', then Z is not referenced.
!>          Note: the user must ensure that at least max(1,M) columns are
!>          supplied in the array Z; if RANGE = 'V', the exact value of M
!>          is not known in advance and an upper bound must be used.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.  LDZ >= 1, and if
!>          JOBZ = 'V', LDZ >= max(1,N).
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.  LWORK >= 1, when N <= 1;
!>          otherwise 2*N.
!>          For optimal efficiency, LWORK >= (NB+1)*N,
!>          where NB is the max of the blocksize for ZHETRD and for
!>          ZUNMTR as returned by ILAENV.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (7*N)
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (5*N)
!> 
[out]IFAIL
!>          IFAIL is INTEGER array, dimension (N)
!>          If JOBZ = 'V', then if INFO = 0, the first M elements of
!>          IFAIL are zero.  If INFO > 0, then IFAIL contains the
!>          indices of the eigenvectors that failed to converge.
!>          If JOBZ = 'N', then IFAIL is not referenced.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO = i, then i eigenvectors failed to converge.
!>                Their indices are stored in array IFAIL.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 256 of file zheevx.f.

259*
260* -- LAPACK driver routine --
261* -- LAPACK is a software package provided by Univ. of Tennessee, --
262* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
263*
264* .. Scalar Arguments ..
265 CHARACTER JOBZ, RANGE, UPLO
266 INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N
267 DOUBLE PRECISION ABSTOL, VL, VU
268* ..
269* .. Array Arguments ..
270 INTEGER IFAIL( * ), IWORK( * )
271 DOUBLE PRECISION RWORK( * ), W( * )
272 COMPLEX*16 A( LDA, * ), WORK( * ), Z( LDZ, * )
273* ..
274*
275* =====================================================================
276*
277* .. Parameters ..
278 DOUBLE PRECISION ZERO, ONE
279 parameter( zero = 0.0d+0, one = 1.0d+0 )
280 COMPLEX*16 CONE
281 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
282* ..
283* .. Local Scalars ..
284 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
285 $ WANTZ
286 CHARACTER ORDER
287 INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
288 $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE,
289 $ ITMP1, J, JJ, LLWORK, LWKMIN, LWKOPT, NB,
290 $ NSPLIT
291 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
292 $ SIGMA, SMLNUM, TMP1, VLL, VUU
293* ..
294* .. External Functions ..
295 LOGICAL LSAME
296 INTEGER ILAENV
297 DOUBLE PRECISION DLAMCH, ZLANHE
298 EXTERNAL lsame, ilaenv, dlamch, zlanhe
299* ..
300* .. External Subroutines ..
301 EXTERNAL dcopy, dscal, dstebz, dsterf, xerbla, zdscal,
303 $ zunmtr
304* ..
305* .. Intrinsic Functions ..
306 INTRINSIC dble, max, min, sqrt
307* ..
308* .. Executable Statements ..
309*
310* Test the input parameters.
311*
312 lower = lsame( uplo, 'L' )
313 wantz = lsame( jobz, 'V' )
314 alleig = lsame( range, 'A' )
315 valeig = lsame( range, 'V' )
316 indeig = lsame( range, 'I' )
317 lquery = ( lwork.EQ.-1 )
318*
319 info = 0
320 IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
321 info = -1
322 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
323 info = -2
324 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
325 info = -3
326 ELSE IF( n.LT.0 ) THEN
327 info = -4
328 ELSE IF( lda.LT.max( 1, n ) ) THEN
329 info = -6
330 ELSE
331 IF( valeig ) THEN
332 IF( n.GT.0 .AND. vu.LE.vl )
333 $ info = -8
334 ELSE IF( indeig ) THEN
335 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
336 info = -9
337 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
338 info = -10
339 END IF
340 END IF
341 END IF
342 IF( info.EQ.0 ) THEN
343 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
344 info = -15
345 END IF
346 END IF
347*
348 IF( info.EQ.0 ) THEN
349 IF( n.LE.1 ) THEN
350 lwkmin = 1
351 work( 1 ) = lwkmin
352 ELSE
353 lwkmin = 2*n
354 nb = ilaenv( 1, 'ZHETRD', uplo, n, -1, -1, -1 )
355 nb = max( nb, ilaenv( 1, 'ZUNMTR', uplo, n, -1, -1, -1 ) )
356 lwkopt = max( 1, ( nb + 1 )*n )
357 work( 1 ) = lwkopt
358 END IF
359*
360 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
361 $ info = -17
362 END IF
363*
364 IF( info.NE.0 ) THEN
365 CALL xerbla( 'ZHEEVX', -info )
366 RETURN
367 ELSE IF( lquery ) THEN
368 RETURN
369 END IF
370*
371* Quick return if possible
372*
373 m = 0
374 IF( n.EQ.0 ) THEN
375 RETURN
376 END IF
377*
378 IF( n.EQ.1 ) THEN
379 IF( alleig .OR. indeig ) THEN
380 m = 1
381 w( 1 ) = dble( a( 1, 1 ) )
382 ELSE IF( valeig ) THEN
383 IF( vl.LT.dble( a( 1, 1 ) ) .AND. vu.GE.dble( a( 1, 1 ) ) )
384 $ THEN
385 m = 1
386 w( 1 ) = dble( a( 1, 1 ) )
387 END IF
388 END IF
389 IF( wantz )
390 $ z( 1, 1 ) = cone
391 RETURN
392 END IF
393*
394* Get machine constants.
395*
396 safmin = dlamch( 'Safe minimum' )
397 eps = dlamch( 'Precision' )
398 smlnum = safmin / eps
399 bignum = one / smlnum
400 rmin = sqrt( smlnum )
401 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
402*
403* Scale matrix to allowable range, if necessary.
404*
405 iscale = 0
406 abstll = abstol
407 IF( valeig ) THEN
408 vll = vl
409 vuu = vu
410 END IF
411 anrm = zlanhe( 'M', uplo, n, a, lda, rwork )
412 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
413 iscale = 1
414 sigma = rmin / anrm
415 ELSE IF( anrm.GT.rmax ) THEN
416 iscale = 1
417 sigma = rmax / anrm
418 END IF
419 IF( iscale.EQ.1 ) THEN
420 IF( lower ) THEN
421 DO 10 j = 1, n
422 CALL zdscal( n-j+1, sigma, a( j, j ), 1 )
423 10 CONTINUE
424 ELSE
425 DO 20 j = 1, n
426 CALL zdscal( j, sigma, a( 1, j ), 1 )
427 20 CONTINUE
428 END IF
429 IF( abstol.GT.0 )
430 $ abstll = abstol*sigma
431 IF( valeig ) THEN
432 vll = vl*sigma
433 vuu = vu*sigma
434 END IF
435 END IF
436*
437* Call ZHETRD to reduce Hermitian matrix to tridiagonal form.
438*
439 indd = 1
440 inde = indd + n
441 indrwk = inde + n
442 indtau = 1
443 indwrk = indtau + n
444 llwork = lwork - indwrk + 1
445 CALL zhetrd( uplo, n, a, lda, rwork( indd ), rwork( inde ),
446 $ work( indtau ), work( indwrk ), llwork, iinfo )
447*
448* If all eigenvalues are desired and ABSTOL is less than or equal to
449* zero, then call DSTERF or ZUNGTR and ZSTEQR. If this fails for
450* some eigenvalue, then try DSTEBZ.
451*
452 test = .false.
453 IF( indeig ) THEN
454 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
455 test = .true.
456 END IF
457 END IF
458 IF( ( alleig .OR. test ) .AND. ( abstol.LE.zero ) ) THEN
459 CALL dcopy( n, rwork( indd ), 1, w, 1 )
460 indee = indrwk + 2*n
461 IF( .NOT.wantz ) THEN
462 CALL dcopy( n-1, rwork( inde ), 1, rwork( indee ), 1 )
463 CALL dsterf( n, w, rwork( indee ), info )
464 ELSE
465 CALL zlacpy( 'A', n, n, a, lda, z, ldz )
466 CALL zungtr( uplo, n, z, ldz, work( indtau ),
467 $ work( indwrk ), llwork, iinfo )
468 CALL dcopy( n-1, rwork( inde ), 1, rwork( indee ), 1 )
469 CALL zsteqr( jobz, n, w, rwork( indee ), z, ldz,
470 $ rwork( indrwk ), info )
471 IF( info.EQ.0 ) THEN
472 DO 30 i = 1, n
473 ifail( i ) = 0
474 30 CONTINUE
475 END IF
476 END IF
477 IF( info.EQ.0 ) THEN
478 m = n
479 GO TO 40
480 END IF
481 info = 0
482 END IF
483*
484* Otherwise, call DSTEBZ and, if eigenvectors are desired, ZSTEIN.
485*
486 IF( wantz ) THEN
487 order = 'B'
488 ELSE
489 order = 'E'
490 END IF
491 indibl = 1
492 indisp = indibl + n
493 indiwk = indisp + n
494 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
495 $ rwork( indd ), rwork( inde ), m, nsplit, w,
496 $ iwork( indibl ), iwork( indisp ), rwork( indrwk ),
497 $ iwork( indiwk ), info )
498*
499 IF( wantz ) THEN
500 CALL zstein( n, rwork( indd ), rwork( inde ), m, w,
501 $ iwork( indibl ), iwork( indisp ), z, ldz,
502 $ rwork( indrwk ), iwork( indiwk ), ifail, info )
503*
504* Apply unitary matrix used in reduction to tridiagonal
505* form to eigenvectors returned by ZSTEIN.
506*
507 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda, work( indtau ), z,
508 $ ldz, work( indwrk ), llwork, iinfo )
509 END IF
510*
511* If matrix was scaled, then rescale eigenvalues appropriately.
512*
513 40 CONTINUE
514 IF( iscale.EQ.1 ) THEN
515 IF( info.EQ.0 ) THEN
516 imax = m
517 ELSE
518 imax = info - 1
519 END IF
520 CALL dscal( imax, one / sigma, w, 1 )
521 END IF
522*
523* If eigenvalues are not in order, then sort them, along with
524* eigenvectors.
525*
526 IF( wantz ) THEN
527 DO 60 j = 1, m - 1
528 i = 0
529 tmp1 = w( j )
530 DO 50 jj = j + 1, m
531 IF( w( jj ).LT.tmp1 ) THEN
532 i = jj
533 tmp1 = w( jj )
534 END IF
535 50 CONTINUE
536*
537 IF( i.NE.0 ) THEN
538 itmp1 = iwork( indibl+i-1 )
539 w( i ) = w( j )
540 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
541 w( j ) = tmp1
542 iwork( indibl+j-1 ) = itmp1
543 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
544 IF( info.NE.0 ) THEN
545 itmp1 = ifail( i )
546 ifail( i ) = ifail( j )
547 ifail( j ) = itmp1
548 END IF
549 END IF
550 60 CONTINUE
551 END IF
552*
553* Set WORK(1) to optimal complex workspace size.
554*
555 work( 1 ) = lwkopt
556*
557 RETURN
558*
559* End of ZHEEVX
560*

◆ zheevx_2stage()

subroutine zheevx_2stage ( character jobz,
character range,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision abstol,
integer m,
double precision, dimension( * ) w,
complex*16, dimension( ldz, * ) z,
integer ldz,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer, dimension( * ) iwork,
integer, dimension( * ) ifail,
integer info )

ZHEEVX_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

Download ZHEEVX_2STAGE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEEVX_2STAGE computes selected eigenvalues and, optionally, eigenvectors
!> of a complex Hermitian matrix A using the 2stage technique for
!> the reduction to tridiagonal.  Eigenvalues and eigenvectors can
!> be selected by specifying either a range of values or a range of
!> indices for the desired eigenvalues.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!>                  Not available in this release.
!> 
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': all eigenvalues will be found.
!>          = 'V': all eigenvalues in the half-open interval (VL,VU]
!>                 will be found.
!>          = 'I': the IL-th through IU-th eigenvalues will be found.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, the lower triangle (if UPLO='L') or the upper
!>          triangle (if UPLO='U') of A, including the diagonal, is
!>          destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The absolute error tolerance for the eigenvalues.
!>          An approximate eigenvalue is accepted as converged
!>          when it is determined to lie in an interval [a,b]
!>          of width less than or equal to
!>
!>                  ABSTOL + EPS *   max( |a|,|b| ) ,
!>
!>          where EPS is the machine precision.  If ABSTOL is less than
!>          or equal to zero, then  EPS*|T|  will be used in its place,
!>          where |T| is the 1-norm of the tridiagonal matrix obtained
!>          by reducing A to tridiagonal form.
!>
!>          Eigenvalues will be computed most accurately when ABSTOL is
!>          set to twice the underflow threshold 2*DLAMCH('S'), not zero.
!>          If this routine returns with INFO>0, indicating that some
!>          eigenvectors did not converge, try setting ABSTOL to
!>          2*DLAMCH('S').
!>
!>          See  by Demmel and
!>          Kahan, LAPACK Working Note #3.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues found.  0 <= M <= N.
!>          If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          On normal exit, the first M elements contain the selected
!>          eigenvalues in ascending order.
!> 
[out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
!>          If JOBZ = 'V', then if INFO = 0, the first M columns of Z
!>          contain the orthonormal eigenvectors of the matrix A
!>          corresponding to the selected eigenvalues, with the i-th
!>          column of Z holding the eigenvector associated with W(i).
!>          If an eigenvector fails to converge, then that column of Z
!>          contains the latest approximation to the eigenvector, and the
!>          index of the eigenvector is returned in IFAIL.
!>          If JOBZ = 'N', then Z is not referenced.
!>          Note: the user must ensure that at least max(1,M) columns are
!>          supplied in the array Z; if RANGE = 'V', the exact value of M
!>          is not known in advance and an upper bound must be used.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.  LDZ >= 1, and if
!>          JOBZ = 'V', LDZ >= max(1,N).
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK. LWORK >= 1, when N <= 1;
!>          otherwise  
!>          If JOBZ = 'N' and N > 1, LWORK must be queried.
!>                                   LWORK = MAX(1, 8*N, dimension) where
!>                                   dimension = max(stage1,stage2) + (KD+1)*N + N
!>                                             = N*KD + N*max(KD+1,FACTOPTNB) 
!>                                               + max(2*KD*KD, KD*NTHREADS) 
!>                                               + (KD+1)*N + N
!>                                   where KD is the blocking size of the reduction,
!>                                   FACTOPTNB is the blocking used by the QR or LQ
!>                                   algorithm, usually FACTOPTNB=128 is a good choice
!>                                   NTHREADS is the number of threads used when
!>                                   openMP compilation is enabled, otherwise =1.
!>          If JOBZ = 'V' and N > 1, LWORK must be queried. Not yet available
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (7*N)
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (5*N)
!> 
[out]IFAIL
!>          IFAIL is INTEGER array, dimension (N)
!>          If JOBZ = 'V', then if INFO = 0, the first M elements of
!>          IFAIL are zero.  If INFO > 0, then IFAIL contains the
!>          indices of the eigenvectors that failed to converge.
!>          If JOBZ = 'N', then IFAIL is not referenced.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO = i, then i eigenvectors failed to converge.
!>                Their indices are stored in array IFAIL.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  All details about the 2stage techniques are available in:
!>
!>  Azzam Haidar, Hatem Ltaief, and Jack Dongarra.
!>  Parallel reduction to condensed forms for symmetric eigenvalue problems
!>  using aggregated fine-grained and memory-aware kernels. In Proceedings
!>  of 2011 International Conference for High Performance Computing,
!>  Networking, Storage and Analysis (SC '11), New York, NY, USA,
!>  Article 8 , 11 pages.
!>  http://doi.acm.org/10.1145/2063384.2063394
!>
!>  A. Haidar, J. Kurzak, P. Luszczek, 2013.
!>  An improved parallel singular value algorithm and its implementation 
!>  for multicore hardware, In Proceedings of 2013 International Conference
!>  for High Performance Computing, Networking, Storage and Analysis (SC '13).
!>  Denver, Colorado, USA, 2013.
!>  Article 90, 12 pages.
!>  http://doi.acm.org/10.1145/2503210.2503292
!>
!>  A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.
!>  A novel hybrid CPU-GPU generalized eigensolver for electronic structure 
!>  calculations based on fine-grained memory aware tasks.
!>  International Journal of High Performance Computing Applications.
!>  Volume 28 Issue 2, Pages 196-209, May 2014.
!>  http://hpc.sagepub.com/content/28/2/196 
!>
!> 

Definition at line 303 of file zheevx_2stage.f.

306*
307 IMPLICIT NONE
308*
309* -- LAPACK driver routine --
310* -- LAPACK is a software package provided by Univ. of Tennessee, --
311* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
312*
313* .. Scalar Arguments ..
314 CHARACTER JOBZ, RANGE, UPLO
315 INTEGER IL, INFO, IU, LDA, LDZ, LWORK, M, N
316 DOUBLE PRECISION ABSTOL, VL, VU
317* ..
318* .. Array Arguments ..
319 INTEGER IFAIL( * ), IWORK( * )
320 DOUBLE PRECISION RWORK( * ), W( * )
321 COMPLEX*16 A( LDA, * ), WORK( * ), Z( LDZ, * )
322* ..
323*
324* =====================================================================
325*
326* .. Parameters ..
327 DOUBLE PRECISION ZERO, ONE
328 parameter( zero = 0.0d+0, one = 1.0d+0 )
329 COMPLEX*16 CONE
330 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
331* ..
332* .. Local Scalars ..
333 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
334 $ WANTZ
335 CHARACTER ORDER
336 INTEGER I, IINFO, IMAX, INDD, INDE, INDEE, INDIBL,
337 $ INDISP, INDIWK, INDRWK, INDTAU, INDWRK, ISCALE,
338 $ ITMP1, J, JJ, LLWORK,
339 $ NSPLIT, LWMIN, LHTRD, LWTRD, KD, IB, INDHOUS
340 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
341 $ SIGMA, SMLNUM, TMP1, VLL, VUU
342* ..
343* .. External Functions ..
344 LOGICAL LSAME
345 INTEGER ILAENV2STAGE
346 DOUBLE PRECISION DLAMCH, ZLANHE
347 EXTERNAL lsame, dlamch, zlanhe, ilaenv2stage
348* ..
349* .. External Subroutines ..
350 EXTERNAL dcopy, dscal, dstebz, dsterf, xerbla, zdscal,
353* ..
354* .. Intrinsic Functions ..
355 INTRINSIC dble, max, min, sqrt
356* ..
357* .. Executable Statements ..
358*
359* Test the input parameters.
360*
361 lower = lsame( uplo, 'L' )
362 wantz = lsame( jobz, 'V' )
363 alleig = lsame( range, 'A' )
364 valeig = lsame( range, 'V' )
365 indeig = lsame( range, 'I' )
366 lquery = ( lwork.EQ.-1 )
367*
368 info = 0
369 IF( .NOT.( lsame( jobz, 'N' ) ) ) THEN
370 info = -1
371 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
372 info = -2
373 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
374 info = -3
375 ELSE IF( n.LT.0 ) THEN
376 info = -4
377 ELSE IF( lda.LT.max( 1, n ) ) THEN
378 info = -6
379 ELSE
380 IF( valeig ) THEN
381 IF( n.GT.0 .AND. vu.LE.vl )
382 $ info = -8
383 ELSE IF( indeig ) THEN
384 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
385 info = -9
386 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
387 info = -10
388 END IF
389 END IF
390 END IF
391 IF( info.EQ.0 ) THEN
392 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
393 info = -15
394 END IF
395 END IF
396*
397 IF( info.EQ.0 ) THEN
398 IF( n.LE.1 ) THEN
399 lwmin = 1
400 work( 1 ) = lwmin
401 ELSE
402 kd = ilaenv2stage( 1, 'ZHETRD_2STAGE', jobz,
403 $ n, -1, -1, -1 )
404 ib = ilaenv2stage( 2, 'ZHETRD_2STAGE', jobz,
405 $ n, kd, -1, -1 )
406 lhtrd = ilaenv2stage( 3, 'ZHETRD_2STAGE', jobz,
407 $ n, kd, ib, -1 )
408 lwtrd = ilaenv2stage( 4, 'ZHETRD_2STAGE', jobz,
409 $ n, kd, ib, -1 )
410 lwmin = n + lhtrd + lwtrd
411 work( 1 ) = lwmin
412 END IF
413*
414 IF( lwork.LT.lwmin .AND. .NOT.lquery )
415 $ info = -17
416 END IF
417*
418 IF( info.NE.0 ) THEN
419 CALL xerbla( 'ZHEEVX_2STAGE', -info )
420 RETURN
421 ELSE IF( lquery ) THEN
422 RETURN
423 END IF
424*
425* Quick return if possible
426*
427 m = 0
428 IF( n.EQ.0 ) THEN
429 RETURN
430 END IF
431*
432 IF( n.EQ.1 ) THEN
433 IF( alleig .OR. indeig ) THEN
434 m = 1
435 w( 1 ) = dble( a( 1, 1 ) )
436 ELSE IF( valeig ) THEN
437 IF( vl.LT.dble( a( 1, 1 ) ) .AND. vu.GE.dble( a( 1, 1 ) ) )
438 $ THEN
439 m = 1
440 w( 1 ) = dble( a( 1, 1 ) )
441 END IF
442 END IF
443 IF( wantz )
444 $ z( 1, 1 ) = cone
445 RETURN
446 END IF
447*
448* Get machine constants.
449*
450 safmin = dlamch( 'Safe minimum' )
451 eps = dlamch( 'Precision' )
452 smlnum = safmin / eps
453 bignum = one / smlnum
454 rmin = sqrt( smlnum )
455 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
456*
457* Scale matrix to allowable range, if necessary.
458*
459 iscale = 0
460 abstll = abstol
461 IF( valeig ) THEN
462 vll = vl
463 vuu = vu
464 END IF
465 anrm = zlanhe( 'M', uplo, n, a, lda, rwork )
466 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
467 iscale = 1
468 sigma = rmin / anrm
469 ELSE IF( anrm.GT.rmax ) THEN
470 iscale = 1
471 sigma = rmax / anrm
472 END IF
473 IF( iscale.EQ.1 ) THEN
474 IF( lower ) THEN
475 DO 10 j = 1, n
476 CALL zdscal( n-j+1, sigma, a( j, j ), 1 )
477 10 CONTINUE
478 ELSE
479 DO 20 j = 1, n
480 CALL zdscal( j, sigma, a( 1, j ), 1 )
481 20 CONTINUE
482 END IF
483 IF( abstol.GT.0 )
484 $ abstll = abstol*sigma
485 IF( valeig ) THEN
486 vll = vl*sigma
487 vuu = vu*sigma
488 END IF
489 END IF
490*
491* Call ZHETRD_2STAGE to reduce Hermitian matrix to tridiagonal form.
492*
493 indd = 1
494 inde = indd + n
495 indrwk = inde + n
496 indtau = 1
497 indhous = indtau + n
498 indwrk = indhous + lhtrd
499 llwork = lwork - indwrk + 1
500*
501 CALL zhetrd_2stage( jobz, uplo, n, a, lda, rwork( indd ),
502 $ rwork( inde ), work( indtau ),
503 $ work( indhous ), lhtrd, work( indwrk ),
504 $ llwork, iinfo )
505*
506* If all eigenvalues are desired and ABSTOL is less than or equal to
507* zero, then call DSTERF or ZUNGTR and ZSTEQR. If this fails for
508* some eigenvalue, then try DSTEBZ.
509*
510 test = .false.
511 IF( indeig ) THEN
512 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
513 test = .true.
514 END IF
515 END IF
516 IF( ( alleig .OR. test ) .AND. ( abstol.LE.zero ) ) THEN
517 CALL dcopy( n, rwork( indd ), 1, w, 1 )
518 indee = indrwk + 2*n
519 IF( .NOT.wantz ) THEN
520 CALL dcopy( n-1, rwork( inde ), 1, rwork( indee ), 1 )
521 CALL dsterf( n, w, rwork( indee ), info )
522 ELSE
523 CALL zlacpy( 'A', n, n, a, lda, z, ldz )
524 CALL zungtr( uplo, n, z, ldz, work( indtau ),
525 $ work( indwrk ), llwork, iinfo )
526 CALL dcopy( n-1, rwork( inde ), 1, rwork( indee ), 1 )
527 CALL zsteqr( jobz, n, w, rwork( indee ), z, ldz,
528 $ rwork( indrwk ), info )
529 IF( info.EQ.0 ) THEN
530 DO 30 i = 1, n
531 ifail( i ) = 0
532 30 CONTINUE
533 END IF
534 END IF
535 IF( info.EQ.0 ) THEN
536 m = n
537 GO TO 40
538 END IF
539 info = 0
540 END IF
541*
542* Otherwise, call DSTEBZ and, if eigenvectors are desired, ZSTEIN.
543*
544 IF( wantz ) THEN
545 order = 'B'
546 ELSE
547 order = 'E'
548 END IF
549 indibl = 1
550 indisp = indibl + n
551 indiwk = indisp + n
552 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
553 $ rwork( indd ), rwork( inde ), m, nsplit, w,
554 $ iwork( indibl ), iwork( indisp ), rwork( indrwk ),
555 $ iwork( indiwk ), info )
556*
557 IF( wantz ) THEN
558 CALL zstein( n, rwork( indd ), rwork( inde ), m, w,
559 $ iwork( indibl ), iwork( indisp ), z, ldz,
560 $ rwork( indrwk ), iwork( indiwk ), ifail, info )
561*
562* Apply unitary matrix used in reduction to tridiagonal
563* form to eigenvectors returned by ZSTEIN.
564*
565 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda, work( indtau ), z,
566 $ ldz, work( indwrk ), llwork, iinfo )
567 END IF
568*
569* If matrix was scaled, then rescale eigenvalues appropriately.
570*
571 40 CONTINUE
572 IF( iscale.EQ.1 ) THEN
573 IF( info.EQ.0 ) THEN
574 imax = m
575 ELSE
576 imax = info - 1
577 END IF
578 CALL dscal( imax, one / sigma, w, 1 )
579 END IF
580*
581* If eigenvalues are not in order, then sort them, along with
582* eigenvectors.
583*
584 IF( wantz ) THEN
585 DO 60 j = 1, m - 1
586 i = 0
587 tmp1 = w( j )
588 DO 50 jj = j + 1, m
589 IF( w( jj ).LT.tmp1 ) THEN
590 i = jj
591 tmp1 = w( jj )
592 END IF
593 50 CONTINUE
594*
595 IF( i.NE.0 ) THEN
596 itmp1 = iwork( indibl+i-1 )
597 w( i ) = w( j )
598 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
599 w( j ) = tmp1
600 iwork( indibl+j-1 ) = itmp1
601 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
602 IF( info.NE.0 ) THEN
603 itmp1 = ifail( i )
604 ifail( i ) = ifail( j )
605 ifail( j ) = itmp1
606 END IF
607 END IF
608 60 CONTINUE
609 END IF
610*
611* Set WORK(1) to optimal complex workspace size.
612*
613 work( 1 ) = lwmin
614*
615 RETURN
616*
617* End of ZHEEVX_2STAGE
618*

◆ zhegv()

subroutine zhegv ( integer itype,
character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
complex*16, dimension( ldb, * ) b,
integer ldb,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer info )

ZHEGV

Download ZHEGV + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEGV computes all the eigenvalues, and optionally, the eigenvectors
!> of a complex generalized Hermitian-definite eigenproblem, of the form
!> A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.
!> Here A and B are assumed to be Hermitian and B is also
!> positive definite.
!> 
Parameters
[in]ITYPE
!>          ITYPE is INTEGER
!>          Specifies the problem type to be solved:
!>          = 1:  A*x = (lambda)*B*x
!>          = 2:  A*B*x = (lambda)*x
!>          = 3:  B*A*x = (lambda)*x
!> 
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangles of A and B are stored;
!>          = 'L':  Lower triangles of A and B are stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A and B.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          matrix Z of eigenvectors.  The eigenvectors are normalized
!>          as follows:
!>          if ITYPE = 1 or 2, Z**H*B*Z = I;
!>          if ITYPE = 3, Z**H*inv(B)*Z = I.
!>          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
!>          or the lower triangle (if UPLO='L') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in,out]B
!>          B is COMPLEX*16 array, dimension (LDB, N)
!>          On entry, the Hermitian positive definite matrix B.
!>          If UPLO = 'U', the leading N-by-N upper triangular part of B
!>          contains the upper triangular part of the matrix B.
!>          If UPLO = 'L', the leading N-by-N lower triangular part of B
!>          contains the lower triangular part of the matrix B.
!>
!>          On exit, if INFO <= N, the part of B containing the matrix is
!>          overwritten by the triangular factor U or L from the Cholesky
!>          factorization B = U**H*U or B = L*L**H.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.  LWORK >= max(1,2*N-1).
!>          For optimal efficiency, LWORK >= (NB+1)*N,
!>          where NB is the blocksize for ZHETRD returned by ILAENV.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (max(1, 3*N-2))
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  ZPOTRF or ZHEEV returned an error code:
!>             <= N:  if INFO = i, ZHEEV failed to converge;
!>                    i off-diagonal elements of an intermediate
!>                    tridiagonal form did not converge to zero;
!>             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
!>                    minor of order i of B is not positive definite.
!>                    The factorization of B could not be completed and
!>                    no eigenvalues or eigenvectors were computed.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 179 of file zhegv.f.

181*
182* -- LAPACK driver routine --
183* -- LAPACK is a software package provided by Univ. of Tennessee, --
184* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
185*
186* .. Scalar Arguments ..
187 CHARACTER JOBZ, UPLO
188 INTEGER INFO, ITYPE, LDA, LDB, LWORK, N
189* ..
190* .. Array Arguments ..
191 DOUBLE PRECISION RWORK( * ), W( * )
192 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * )
193* ..
194*
195* =====================================================================
196*
197* .. Parameters ..
198 COMPLEX*16 ONE
199 parameter( one = ( 1.0d+0, 0.0d+0 ) )
200* ..
201* .. Local Scalars ..
202 LOGICAL LQUERY, UPPER, WANTZ
203 CHARACTER TRANS
204 INTEGER LWKOPT, NB, NEIG
205* ..
206* .. External Functions ..
207 LOGICAL LSAME
208 INTEGER ILAENV
209 EXTERNAL lsame, ilaenv
210* ..
211* .. External Subroutines ..
212 EXTERNAL xerbla, zheev, zhegst, zpotrf, ztrmm, ztrsm
213* ..
214* .. Intrinsic Functions ..
215 INTRINSIC max
216* ..
217* .. Executable Statements ..
218*
219* Test the input parameters.
220*
221 wantz = lsame( jobz, 'V' )
222 upper = lsame( uplo, 'U' )
223 lquery = ( lwork.EQ.-1 )
224*
225 info = 0
226 IF( itype.LT.1 .OR. itype.GT.3 ) THEN
227 info = -1
228 ELSE IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
229 info = -2
230 ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
231 info = -3
232 ELSE IF( n.LT.0 ) THEN
233 info = -4
234 ELSE IF( lda.LT.max( 1, n ) ) THEN
235 info = -6
236 ELSE IF( ldb.LT.max( 1, n ) ) THEN
237 info = -8
238 END IF
239*
240 IF( info.EQ.0 ) THEN
241 nb = ilaenv( 1, 'ZHETRD', uplo, n, -1, -1, -1 )
242 lwkopt = max( 1, ( nb + 1 )*n )
243 work( 1 ) = lwkopt
244*
245 IF( lwork.LT.max( 1, 2*n - 1 ) .AND. .NOT.lquery ) THEN
246 info = -11
247 END IF
248 END IF
249*
250 IF( info.NE.0 ) THEN
251 CALL xerbla( 'ZHEGV ', -info )
252 RETURN
253 ELSE IF( lquery ) THEN
254 RETURN
255 END IF
256*
257* Quick return if possible
258*
259 IF( n.EQ.0 )
260 $ RETURN
261*
262* Form a Cholesky factorization of B.
263*
264 CALL zpotrf( uplo, n, b, ldb, info )
265 IF( info.NE.0 ) THEN
266 info = n + info
267 RETURN
268 END IF
269*
270* Transform problem to standard eigenvalue problem and solve.
271*
272 CALL zhegst( itype, uplo, n, a, lda, b, ldb, info )
273 CALL zheev( jobz, uplo, n, a, lda, w, work, lwork, rwork, info )
274*
275 IF( wantz ) THEN
276*
277* Backtransform eigenvectors to the original problem.
278*
279 neig = n
280 IF( info.GT.0 )
281 $ neig = info - 1
282 IF( itype.EQ.1 .OR. itype.EQ.2 ) THEN
283*
284* For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
285* backtransform eigenvectors: x = inv(L)**H *y or inv(U)*y
286*
287 IF( upper ) THEN
288 trans = 'N'
289 ELSE
290 trans = 'C'
291 END IF
292*
293 CALL ztrsm( 'Left', uplo, trans, 'Non-unit', n, neig, one,
294 $ b, ldb, a, lda )
295*
296 ELSE IF( itype.EQ.3 ) THEN
297*
298* For B*A*x=(lambda)*x;
299* backtransform eigenvectors: x = L*y or U**H *y
300*
301 IF( upper ) THEN
302 trans = 'C'
303 ELSE
304 trans = 'N'
305 END IF
306*
307 CALL ztrmm( 'Left', uplo, trans, 'Non-unit', n, neig, one,
308 $ b, ldb, a, lda )
309 END IF
310 END IF
311*
312 work( 1 ) = lwkopt
313*
314 RETURN
315*
316* End of ZHEGV
317*
subroutine zhegst(itype, uplo, n, a, lda, b, ldb, info)
ZHEGST
Definition zhegst.f:128
subroutine zheev(jobz, uplo, n, a, lda, w, work, lwork, rwork, info)
ZHEEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
Definition zheev.f:140
subroutine ztrmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
ZTRMM
Definition ztrmm.f:177
subroutine ztrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
ZTRSM
Definition ztrsm.f:180
subroutine zpotrf(uplo, n, a, lda, info)
ZPOTRF VARIANT: right looking block version of the algorithm, calling Level 3 BLAS.
Definition zpotrf.f:102

◆ zhegv_2stage()

subroutine zhegv_2stage ( integer itype,
character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
complex*16, dimension( ldb, * ) b,
integer ldb,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer info )

ZHEGV_2STAGE

Download ZHEGV_2STAGE + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEGV_2STAGE computes all the eigenvalues, and optionally, the eigenvectors
!> of a complex generalized Hermitian-definite eigenproblem, of the form
!> A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.
!> Here A and B are assumed to be Hermitian and B is also
!> positive definite.
!> This routine use the 2stage technique for the reduction to tridiagonal
!> which showed higher performance on recent architecture and for large
!> sizes N>2000.
!> 
Parameters
[in]ITYPE
!>          ITYPE is INTEGER
!>          Specifies the problem type to be solved:
!>          = 1:  A*x = (lambda)*B*x
!>          = 2:  A*B*x = (lambda)*x
!>          = 3:  B*A*x = (lambda)*x
!> 
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!>                  Not available in this release.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangles of A and B are stored;
!>          = 'L':  Lower triangles of A and B are stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A and B.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          matrix Z of eigenvectors.  The eigenvectors are normalized
!>          as follows:
!>          if ITYPE = 1 or 2, Z**H*B*Z = I;
!>          if ITYPE = 3, Z**H*inv(B)*Z = I.
!>          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
!>          or the lower triangle (if UPLO='L') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in,out]B
!>          B is COMPLEX*16 array, dimension (LDB, N)
!>          On entry, the Hermitian positive definite matrix B.
!>          If UPLO = 'U', the leading N-by-N upper triangular part of B
!>          contains the upper triangular part of the matrix B.
!>          If UPLO = 'L', the leading N-by-N lower triangular part of B
!>          contains the lower triangular part of the matrix B.
!>
!>          On exit, if INFO <= N, the part of B containing the matrix is
!>          overwritten by the triangular factor U or L from the Cholesky
!>          factorization B = U**H*U or B = L*L**H.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK. LWORK >= 1, when N <= 1;
!>          otherwise  
!>          If JOBZ = 'N' and N > 1, LWORK must be queried.
!>                                   LWORK = MAX(1, dimension) where
!>                                   dimension = max(stage1,stage2) + (KD+1)*N + N
!>                                             = N*KD + N*max(KD+1,FACTOPTNB) 
!>                                               + max(2*KD*KD, KD*NTHREADS) 
!>                                               + (KD+1)*N + N
!>                                   where KD is the blocking size of the reduction,
!>                                   FACTOPTNB is the blocking used by the QR or LQ
!>                                   algorithm, usually FACTOPTNB=128 is a good choice
!>                                   NTHREADS is the number of threads used when
!>                                   openMP compilation is enabled, otherwise =1.
!>          If JOBZ = 'V' and N > 1, LWORK must be queried. Not yet available
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (max(1, 3*N-2))
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  ZPOTRF or ZHEEV returned an error code:
!>             <= N:  if INFO = i, ZHEEV failed to converge;
!>                    i off-diagonal elements of an intermediate
!>                    tridiagonal form did not converge to zero;
!>             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
!>                    minor of order i of B is not positive definite.
!>                    The factorization of B could not be completed and
!>                    no eigenvalues or eigenvectors were computed.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  All details about the 2stage techniques are available in:
!>
!>  Azzam Haidar, Hatem Ltaief, and Jack Dongarra.
!>  Parallel reduction to condensed forms for symmetric eigenvalue problems
!>  using aggregated fine-grained and memory-aware kernels. In Proceedings
!>  of 2011 International Conference for High Performance Computing,
!>  Networking, Storage and Analysis (SC '11), New York, NY, USA,
!>  Article 8 , 11 pages.
!>  http://doi.acm.org/10.1145/2063384.2063394
!>
!>  A. Haidar, J. Kurzak, P. Luszczek, 2013.
!>  An improved parallel singular value algorithm and its implementation 
!>  for multicore hardware, In Proceedings of 2013 International Conference
!>  for High Performance Computing, Networking, Storage and Analysis (SC '13).
!>  Denver, Colorado, USA, 2013.
!>  Article 90, 12 pages.
!>  http://doi.acm.org/10.1145/2503210.2503292
!>
!>  A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.
!>  A novel hybrid CPU-GPU generalized eigensolver for electronic structure 
!>  calculations based on fine-grained memory aware tasks.
!>  International Journal of High Performance Computing Applications.
!>  Volume 28 Issue 2, Pages 196-209, May 2014.
!>  http://hpc.sagepub.com/content/28/2/196 
!>
!> 

Definition at line 230 of file zhegv_2stage.f.

232*
233 IMPLICIT NONE
234*
235* -- LAPACK driver routine --
236* -- LAPACK is a software package provided by Univ. of Tennessee, --
237* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
238*
239* .. Scalar Arguments ..
240 CHARACTER JOBZ, UPLO
241 INTEGER INFO, ITYPE, LDA, LDB, LWORK, N
242* ..
243* .. Array Arguments ..
244 DOUBLE PRECISION RWORK( * ), W( * )
245 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * )
246* ..
247*
248* =====================================================================
249*
250* .. Parameters ..
251 COMPLEX*16 ONE
252 parameter( one = ( 1.0d+0, 0.0d+0 ) )
253* ..
254* .. Local Scalars ..
255 LOGICAL LQUERY, UPPER, WANTZ
256 CHARACTER TRANS
257 INTEGER NEIG, LWMIN, LHTRD, LWTRD, KD, IB
258* ..
259* .. External Functions ..
260 LOGICAL LSAME
261 INTEGER ILAENV2STAGE
262 EXTERNAL lsame, ilaenv2stage
263* ..
264* .. External Subroutines ..
265 EXTERNAL xerbla, zhegst, zpotrf, ztrmm, ztrsm,
267* ..
268* .. Intrinsic Functions ..
269 INTRINSIC max
270* ..
271* .. Executable Statements ..
272*
273* Test the input parameters.
274*
275 wantz = lsame( jobz, 'V' )
276 upper = lsame( uplo, 'U' )
277 lquery = ( lwork.EQ.-1 )
278*
279 info = 0
280 IF( itype.LT.1 .OR. itype.GT.3 ) THEN
281 info = -1
282 ELSE IF( .NOT.( lsame( jobz, 'N' ) ) ) THEN
283 info = -2
284 ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
285 info = -3
286 ELSE IF( n.LT.0 ) THEN
287 info = -4
288 ELSE IF( lda.LT.max( 1, n ) ) THEN
289 info = -6
290 ELSE IF( ldb.LT.max( 1, n ) ) THEN
291 info = -8
292 END IF
293*
294 IF( info.EQ.0 ) THEN
295 kd = ilaenv2stage( 1, 'ZHETRD_2STAGE', jobz, n, -1, -1, -1 )
296 ib = ilaenv2stage( 2, 'ZHETRD_2STAGE', jobz, n, kd, -1, -1 )
297 lhtrd = ilaenv2stage( 3, 'ZHETRD_2STAGE', jobz, n, kd, ib, -1 )
298 lwtrd = ilaenv2stage( 4, 'ZHETRD_2STAGE', jobz, n, kd, ib, -1 )
299 lwmin = n + lhtrd + lwtrd
300 work( 1 ) = lwmin
301*
302 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
303 info = -11
304 END IF
305 END IF
306*
307 IF( info.NE.0 ) THEN
308 CALL xerbla( 'ZHEGV_2STAGE ', -info )
309 RETURN
310 ELSE IF( lquery ) THEN
311 RETURN
312 END IF
313*
314* Quick return if possible
315*
316 IF( n.EQ.0 )
317 $ RETURN
318*
319* Form a Cholesky factorization of B.
320*
321 CALL zpotrf( uplo, n, b, ldb, info )
322 IF( info.NE.0 ) THEN
323 info = n + info
324 RETURN
325 END IF
326*
327* Transform problem to standard eigenvalue problem and solve.
328*
329 CALL zhegst( itype, uplo, n, a, lda, b, ldb, info )
330 CALL zheev_2stage( jobz, uplo, n, a, lda, w,
331 $ work, lwork, rwork, info )
332*
333 IF( wantz ) THEN
334*
335* Backtransform eigenvectors to the original problem.
336*
337 neig = n
338 IF( info.GT.0 )
339 $ neig = info - 1
340 IF( itype.EQ.1 .OR. itype.EQ.2 ) THEN
341*
342* For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
343* backtransform eigenvectors: x = inv(L)**H *y or inv(U)*y
344*
345 IF( upper ) THEN
346 trans = 'N'
347 ELSE
348 trans = 'C'
349 END IF
350*
351 CALL ztrsm( 'Left', uplo, trans, 'Non-unit', n, neig, one,
352 $ b, ldb, a, lda )
353*
354 ELSE IF( itype.EQ.3 ) THEN
355*
356* For B*A*x=(lambda)*x;
357* backtransform eigenvectors: x = L*y or U**H *y
358*
359 IF( upper ) THEN
360 trans = 'C'
361 ELSE
362 trans = 'N'
363 END IF
364*
365 CALL ztrmm( 'Left', uplo, trans, 'Non-unit', n, neig, one,
366 $ b, ldb, a, lda )
367 END IF
368 END IF
369*
370 work( 1 ) = lwmin
371*
372 RETURN
373*
374* End of ZHEGV_2STAGE
375*
subroutine zheev_2stage(jobz, uplo, n, a, lda, w, work, lwork, rwork, info)
ZHEEV_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matr...

◆ zhegvd()

subroutine zhegvd ( integer itype,
character jobz,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
complex*16, dimension( ldb, * ) b,
integer ldb,
double precision, dimension( * ) w,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer lrwork,
integer, dimension( * ) iwork,
integer liwork,
integer info )

ZHEGVD

Download ZHEGVD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEGVD computes all the eigenvalues, and optionally, the eigenvectors
!> of a complex generalized Hermitian-definite eigenproblem, of the form
!> A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.  Here A and
!> B are assumed to be Hermitian and B is also positive definite.
!> If eigenvectors are desired, it uses a divide and conquer algorithm.
!>
!> The divide and conquer algorithm makes very mild assumptions about
!> floating point arithmetic. It will work on machines with a guard
!> digit in add/subtract, or on those binary machines without guard
!> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
!> Cray-2. It could conceivably fail on hexadecimal or decimal machines
!> without guard digits, but we know of none.
!> 
Parameters
[in]ITYPE
!>          ITYPE is INTEGER
!>          Specifies the problem type to be solved:
!>          = 1:  A*x = (lambda)*B*x
!>          = 2:  A*B*x = (lambda)*x
!>          = 3:  B*A*x = (lambda)*x
!> 
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangles of A and B are stored;
!>          = 'L':  Lower triangles of A and B are stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A and B.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>
!>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
!>          matrix Z of eigenvectors.  The eigenvectors are normalized
!>          as follows:
!>          if ITYPE = 1 or 2, Z**H*B*Z = I;
!>          if ITYPE = 3, Z**H*inv(B)*Z = I.
!>          If JOBZ = 'N', then on exit the upper triangle (if UPLO='U')
!>          or the lower triangle (if UPLO='L') of A, including the
!>          diagonal, is destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in,out]B
!>          B is COMPLEX*16 array, dimension (LDB, N)
!>          On entry, the Hermitian matrix B.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of B contains the
!>          upper triangular part of the matrix B.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of B contains
!>          the lower triangular part of the matrix B.
!>
!>          On exit, if INFO <= N, the part of B containing the matrix is
!>          overwritten by the triangular factor U or L from the Cholesky
!>          factorization B = U**H*U or B = L*L**H.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,N).
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          If INFO = 0, the eigenvalues in ascending order.
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.
!>          If N <= 1,                LWORK >= 1.
!>          If JOBZ  = 'N' and N > 1, LWORK >= N + 1.
!>          If JOBZ  = 'V' and N > 1, LWORK >= 2*N + N**2.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal sizes of the WORK, RWORK and
!>          IWORK arrays, returns these values as the first entries of
!>          the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
!>          On exit, if INFO = 0, RWORK(1) returns the optimal LRWORK.
!> 
[in]LRWORK
!>          LRWORK is INTEGER
!>          The dimension of the array RWORK.
!>          If N <= 1,                LRWORK >= 1.
!>          If JOBZ  = 'N' and N > 1, LRWORK >= N.
!>          If JOBZ  = 'V' and N > 1, LRWORK >= 1 + 5*N + 2*N**2.
!>
!>          If LRWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
!>          On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
!> 
[in]LIWORK
!>          LIWORK is INTEGER
!>          The dimension of the array IWORK.
!>          If N <= 1,                LIWORK >= 1.
!>          If JOBZ  = 'N' and N > 1, LIWORK >= 1.
!>          If JOBZ  = 'V' and N > 1, LIWORK >= 3 + 5*N.
!>
!>          If LIWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  ZPOTRF or ZHEEVD returned an error code:
!>             <= N:  if INFO = i and JOBZ = 'N', then the algorithm
!>                    failed to converge; i off-diagonal elements of an
!>                    intermediate tridiagonal form did not converge to
!>                    zero;
!>                    if INFO = i and JOBZ = 'V', then the algorithm
!>                    failed to compute an eigenvalue while working on
!>                    the submatrix lying in rows and columns INFO/(N+1)
!>                    through mod(INFO,N+1);
!>             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
!>                    minor of order i of B is not positive definite.
!>                    The factorization of B could not be completed and
!>                    no eigenvalues or eigenvectors were computed.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  Modified so that no backsubstitution is performed if ZHEEVD fails to
!>  converge (NEIG in old code could be greater than N causing out of
!>  bounds reference to A - reported by Ralf Meyer).  Also corrected the
!>  description of INFO and the test on ITYPE. Sven, 16 Feb 05.
!> 
Contributors:
Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA

Definition at line 247 of file zhegvd.f.

249*
250* -- LAPACK driver routine --
251* -- LAPACK is a software package provided by Univ. of Tennessee, --
252* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
253*
254* .. Scalar Arguments ..
255 CHARACTER JOBZ, UPLO
256 INTEGER INFO, ITYPE, LDA, LDB, LIWORK, LRWORK, LWORK, N
257* ..
258* .. Array Arguments ..
259 INTEGER IWORK( * )
260 DOUBLE PRECISION RWORK( * ), W( * )
261 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * )
262* ..
263*
264* =====================================================================
265*
266* .. Parameters ..
267 COMPLEX*16 CONE
268 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
269* ..
270* .. Local Scalars ..
271 LOGICAL LQUERY, UPPER, WANTZ
272 CHARACTER TRANS
273 INTEGER LIOPT, LIWMIN, LOPT, LROPT, LRWMIN, LWMIN
274* ..
275* .. External Functions ..
276 LOGICAL LSAME
277 EXTERNAL lsame
278* ..
279* .. External Subroutines ..
280 EXTERNAL xerbla, zheevd, zhegst, zpotrf, ztrmm, ztrsm
281* ..
282* .. Intrinsic Functions ..
283 INTRINSIC dble, max
284* ..
285* .. Executable Statements ..
286*
287* Test the input parameters.
288*
289 wantz = lsame( jobz, 'V' )
290 upper = lsame( uplo, 'U' )
291 lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
292*
293 info = 0
294 IF( n.LE.1 ) THEN
295 lwmin = 1
296 lrwmin = 1
297 liwmin = 1
298 ELSE IF( wantz ) THEN
299 lwmin = 2*n + n*n
300 lrwmin = 1 + 5*n + 2*n*n
301 liwmin = 3 + 5*n
302 ELSE
303 lwmin = n + 1
304 lrwmin = n
305 liwmin = 1
306 END IF
307 lopt = lwmin
308 lropt = lrwmin
309 liopt = liwmin
310 IF( itype.LT.1 .OR. itype.GT.3 ) THEN
311 info = -1
312 ELSE IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
313 info = -2
314 ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
315 info = -3
316 ELSE IF( n.LT.0 ) THEN
317 info = -4
318 ELSE IF( lda.LT.max( 1, n ) ) THEN
319 info = -6
320 ELSE IF( ldb.LT.max( 1, n ) ) THEN
321 info = -8
322 END IF
323*
324 IF( info.EQ.0 ) THEN
325 work( 1 ) = lopt
326 rwork( 1 ) = lropt
327 iwork( 1 ) = liopt
328*
329 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
330 info = -11
331 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
332 info = -13
333 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
334 info = -15
335 END IF
336 END IF
337*
338 IF( info.NE.0 ) THEN
339 CALL xerbla( 'ZHEGVD', -info )
340 RETURN
341 ELSE IF( lquery ) THEN
342 RETURN
343 END IF
344*
345* Quick return if possible
346*
347 IF( n.EQ.0 )
348 $ RETURN
349*
350* Form a Cholesky factorization of B.
351*
352 CALL zpotrf( uplo, n, b, ldb, info )
353 IF( info.NE.0 ) THEN
354 info = n + info
355 RETURN
356 END IF
357*
358* Transform problem to standard eigenvalue problem and solve.
359*
360 CALL zhegst( itype, uplo, n, a, lda, b, ldb, info )
361 CALL zheevd( jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork,
362 $ iwork, liwork, info )
363 lopt = max( dble( lopt ), dble( work( 1 ) ) )
364 lropt = max( dble( lropt ), dble( rwork( 1 ) ) )
365 liopt = max( dble( liopt ), dble( iwork( 1 ) ) )
366*
367 IF( wantz .AND. info.EQ.0 ) THEN
368*
369* Backtransform eigenvectors to the original problem.
370*
371 IF( itype.EQ.1 .OR. itype.EQ.2 ) THEN
372*
373* For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
374* backtransform eigenvectors: x = inv(L)**H *y or inv(U)*y
375*
376 IF( upper ) THEN
377 trans = 'N'
378 ELSE
379 trans = 'C'
380 END IF
381*
382 CALL ztrsm( 'Left', uplo, trans, 'Non-unit', n, n, cone,
383 $ b, ldb, a, lda )
384*
385 ELSE IF( itype.EQ.3 ) THEN
386*
387* For B*A*x=(lambda)*x;
388* backtransform eigenvectors: x = L*y or U**H *y
389*
390 IF( upper ) THEN
391 trans = 'C'
392 ELSE
393 trans = 'N'
394 END IF
395*
396 CALL ztrmm( 'Left', uplo, trans, 'Non-unit', n, n, cone,
397 $ b, ldb, a, lda )
398 END IF
399 END IF
400*
401 work( 1 ) = lopt
402 rwork( 1 ) = lropt
403 iwork( 1 ) = liopt
404*
405 RETURN
406*
407* End of ZHEGVD
408*
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
Definition zheevd.f:205

◆ zhegvx()

subroutine zhegvx ( integer itype,
character jobz,
character range,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
complex*16, dimension( ldb, * ) b,
integer ldb,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision abstol,
integer m,
double precision, dimension( * ) w,
complex*16, dimension( ldz, * ) z,
integer ldz,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer, dimension( * ) iwork,
integer, dimension( * ) ifail,
integer info )

ZHEGVX

Download ZHEGVX + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> ZHEGVX computes selected eigenvalues, and optionally, eigenvectors
!> of a complex generalized Hermitian-definite eigenproblem, of the form
!> A*x=(lambda)*B*x,  A*Bx=(lambda)*x,  or B*A*x=(lambda)*x.  Here A and
!> B are assumed to be Hermitian and B is also positive definite.
!> Eigenvalues and eigenvectors can be selected by specifying either a
!> range of values or a range of indices for the desired eigenvalues.
!> 
Parameters
[in]ITYPE
!>          ITYPE is INTEGER
!>          Specifies the problem type to be solved:
!>          = 1:  A*x = (lambda)*B*x
!>          = 2:  A*B*x = (lambda)*x
!>          = 3:  B*A*x = (lambda)*x
!> 
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!> 
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': all eigenvalues will be found.
!>          = 'V': all eigenvalues in the half-open interval (VL,VU]
!>                 will be found.
!>          = 'I': the IL-th through IU-th eigenvalues will be found.
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangles of A and B are stored;
!>          = 'L':  Lower triangles of A and B are stored.
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrices A and B.  N >= 0.
!> 
[in,out]A
!>          A is COMPLEX*16 array, dimension (LDA, N)
!>          On entry, the Hermitian matrix A.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of A contains the
!>          upper triangular part of the matrix A.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>
!>          On exit,  the lower triangle (if UPLO='L') or the upper
!>          triangle (if UPLO='U') of A, including the diagonal, is
!>          destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in,out]B
!>          B is COMPLEX*16 array, dimension (LDB, N)
!>          On entry, the Hermitian matrix B.  If UPLO = 'U', the
!>          leading N-by-N upper triangular part of B contains the
!>          upper triangular part of the matrix B.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of B contains
!>          the lower triangular part of the matrix B.
!>
!>          On exit, if INFO <= N, the part of B containing the matrix is
!>          overwritten by the triangular factor U or L from the Cholesky
!>          factorization B = U**H*U or B = L*L**H.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B.  LDB >= max(1,N).
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The absolute error tolerance for the eigenvalues.
!>          An approximate eigenvalue is accepted as converged
!>          when it is determined to lie in an interval [a,b]
!>          of width less than or equal to
!>
!>                  ABSTOL + EPS *   max( |a|,|b| ) ,
!>
!>          where EPS is the machine precision.  If ABSTOL is less than
!>          or equal to zero, then  EPS*|T|  will be used in its place,
!>          where |T| is the 1-norm of the tridiagonal matrix obtained
!>          by reducing C to tridiagonal form, where C is the symmetric
!>          matrix of the standard symmetric problem to which the
!>          generalized problem is transformed.
!>
!>          Eigenvalues will be computed most accurately when ABSTOL is
!>          set to twice the underflow threshold 2*DLAMCH('S'), not zero.
!>          If this routine returns with INFO>0, indicating that some
!>          eigenvectors did not converge, try setting ABSTOL to
!>          2*DLAMCH('S').
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues found.  0 <= M <= N.
!>          If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          The first M elements contain the selected
!>          eigenvalues in ascending order.
!> 
[out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
!>          If JOBZ = 'N', then Z is not referenced.
!>          If JOBZ = 'V', then if INFO = 0, the first M columns of Z
!>          contain the orthonormal eigenvectors of the matrix A
!>          corresponding to the selected eigenvalues, with the i-th
!>          column of Z holding the eigenvector associated with W(i).
!>          The eigenvectors are normalized as follows:
!>          if ITYPE = 1 or 2, Z**T*B*Z = I;
!>          if ITYPE = 3, Z**T*inv(B)*Z = I.
!>
!>          If an eigenvector fails to converge, then that column of Z
!>          contains the latest approximation to the eigenvector, and the
!>          index of the eigenvector is returned in IFAIL.
!>          Note: the user must ensure that at least max(1,M) columns are
!>          supplied in the array Z; if RANGE = 'V', the exact value of M
!>          is not known in advance and an upper bound must be used.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.  LDZ >= 1, and if
!>          JOBZ = 'V', LDZ >= max(1,N).
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The length of the array WORK.  LWORK >= max(1,2*N).
!>          For optimal efficiency, LWORK >= (NB+1)*N,
!>          where NB is the blocksize for ZHETRD returned by ILAENV.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (7*N)
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (5*N)
!> 
[out]IFAIL
!>          IFAIL is INTEGER array, dimension (N)
!>          If JOBZ = 'V', then if INFO = 0, the first M elements of
!>          IFAIL are zero.  If INFO > 0, then IFAIL contains the
!>          indices of the eigenvectors that failed to converge.
!>          If JOBZ = 'N', then IFAIL is not referenced.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  ZPOTRF or ZHEEVX returned an error code:
!>             <= N:  if INFO = i, ZHEEVX failed to converge;
!>                    i eigenvectors failed to converge.  Their indices
!>                    are stored in array IFAIL.
!>             > N:   if INFO = N + i, for 1 <= i <= N, then the leading
!>                    minor of order i of B is not positive definite.
!>                    The factorization of B could not be completed and
!>                    no eigenvalues or eigenvectors were computed.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Mark Fahey, Department of Mathematics, Univ. of Kentucky, USA

Definition at line 304 of file zhegvx.f.

307*
308* -- LAPACK driver routine --
309* -- LAPACK is a software package provided by Univ. of Tennessee, --
310* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
311*
312* .. Scalar Arguments ..
313 CHARACTER JOBZ, RANGE, UPLO
314 INTEGER IL, INFO, ITYPE, IU, LDA, LDB, LDZ, LWORK, M, N
315 DOUBLE PRECISION ABSTOL, VL, VU
316* ..
317* .. Array Arguments ..
318 INTEGER IFAIL( * ), IWORK( * )
319 DOUBLE PRECISION RWORK( * ), W( * )
320 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * ),
321 $ Z( LDZ, * )
322* ..
323*
324* =====================================================================
325*
326* .. Parameters ..
327 COMPLEX*16 CONE
328 parameter( cone = ( 1.0d+0, 0.0d+0 ) )
329* ..
330* .. Local Scalars ..
331 LOGICAL ALLEIG, INDEIG, LQUERY, UPPER, VALEIG, WANTZ
332 CHARACTER TRANS
333 INTEGER LWKOPT, NB
334* ..
335* .. External Functions ..
336 LOGICAL LSAME
337 INTEGER ILAENV
338 EXTERNAL lsame, ilaenv
339* ..
340* .. External Subroutines ..
341 EXTERNAL xerbla, zheevx, zhegst, zpotrf, ztrmm, ztrsm
342* ..
343* .. Intrinsic Functions ..
344 INTRINSIC max, min
345* ..
346* .. Executable Statements ..
347*
348* Test the input parameters.
349*
350 wantz = lsame( jobz, 'V' )
351 upper = lsame( uplo, 'U' )
352 alleig = lsame( range, 'A' )
353 valeig = lsame( range, 'V' )
354 indeig = lsame( range, 'I' )
355 lquery = ( lwork.EQ.-1 )
356*
357 info = 0
358 IF( itype.LT.1 .OR. itype.GT.3 ) THEN
359 info = -1
360 ELSE IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
361 info = -2
362 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
363 info = -3
364 ELSE IF( .NOT.( upper .OR. lsame( uplo, 'L' ) ) ) THEN
365 info = -4
366 ELSE IF( n.LT.0 ) THEN
367 info = -5
368 ELSE IF( lda.LT.max( 1, n ) ) THEN
369 info = -7
370 ELSE IF( ldb.LT.max( 1, n ) ) THEN
371 info = -9
372 ELSE
373 IF( valeig ) THEN
374 IF( n.GT.0 .AND. vu.LE.vl )
375 $ info = -11
376 ELSE IF( indeig ) THEN
377 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
378 info = -12
379 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
380 info = -13
381 END IF
382 END IF
383 END IF
384 IF (info.EQ.0) THEN
385 IF (ldz.LT.1 .OR. (wantz .AND. ldz.LT.n)) THEN
386 info = -18
387 END IF
388 END IF
389*
390 IF( info.EQ.0 ) THEN
391 nb = ilaenv( 1, 'ZHETRD', uplo, n, -1, -1, -1 )
392 lwkopt = max( 1, ( nb + 1 )*n )
393 work( 1 ) = lwkopt
394*
395 IF( lwork.LT.max( 1, 2*n ) .AND. .NOT.lquery ) THEN
396 info = -20
397 END IF
398 END IF
399*
400 IF( info.NE.0 ) THEN
401 CALL xerbla( 'ZHEGVX', -info )
402 RETURN
403 ELSE IF( lquery ) THEN
404 RETURN
405 END IF
406*
407* Quick return if possible
408*
409 m = 0
410 IF( n.EQ.0 ) THEN
411 RETURN
412 END IF
413*
414* Form a Cholesky factorization of B.
415*
416 CALL zpotrf( uplo, n, b, ldb, info )
417 IF( info.NE.0 ) THEN
418 info = n + info
419 RETURN
420 END IF
421*
422* Transform problem to standard eigenvalue problem and solve.
423*
424 CALL zhegst( itype, uplo, n, a, lda, b, ldb, info )
425 CALL zheevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,
426 $ m, w, z, ldz, work, lwork, rwork, iwork, ifail,
427 $ info )
428*
429 IF( wantz ) THEN
430*
431* Backtransform eigenvectors to the original problem.
432*
433 IF( info.GT.0 )
434 $ m = info - 1
435 IF( itype.EQ.1 .OR. itype.EQ.2 ) THEN
436*
437* For A*x=(lambda)*B*x and A*B*x=(lambda)*x;
438* backtransform eigenvectors: x = inv(L)**H *y or inv(U)*y
439*
440 IF( upper ) THEN
441 trans = 'N'
442 ELSE
443 trans = 'C'
444 END IF
445*
446 CALL ztrsm( 'Left', uplo, trans, 'Non-unit', n, m, cone, b,
447 $ ldb, z, ldz )
448*
449 ELSE IF( itype.EQ.3 ) THEN
450*
451* For B*A*x=(lambda)*x;
452* backtransform eigenvectors: x = L*y or U**H *y
453*
454 IF( upper ) THEN
455 trans = 'C'
456 ELSE
457 trans = 'N'
458 END IF
459*
460 CALL ztrmm( 'Left', uplo, trans, 'Non-unit', n, m, cone, b,
461 $ ldb, z, ldz )
462 END IF
463 END IF
464*
465* Set WORK(1) to optimal complex workspace size.
466*
467 work( 1 ) = lwkopt
468*
469 RETURN
470*
471* End of ZHEGVX
472*
subroutine zheevx(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, work, lwork, rwork, iwork, ifail, info)
ZHEEVX computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices
Definition zheevx.f:259