 LAPACK  3.10.0 LAPACK: Linear Algebra PACKage

◆ zhpevd()

 subroutine zhpevd ( character JOBZ, character UPLO, integer N, complex*16, dimension( * ) AP, double precision, dimension( * ) W, complex*16, dimension( ldz, * ) Z, integer LDZ, complex*16, dimension( * ) WORK, integer LWORK, double precision, dimension( * ) RWORK, integer LRWORK, integer, dimension( * ) IWORK, integer LIWORK, integer INFO )

ZHPEVD computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices

Purpose:
ZHPEVD computes all the eigenvalues and, optionally, eigenvectors of
a complex Hermitian matrix A in packed storage.  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] AP AP is COMPLEX*16 array, dimension (N*(N+1)/2) On entry, the upper or lower triangle of the Hermitian matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows: if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j; if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n. On exit, AP is overwritten by values generated during the reduction to tridiagonal form. If UPLO = 'U', the diagonal and first superdiagonal of the tridiagonal matrix T overwrite the corresponding elements of A, and if UPLO = 'L', the diagonal and first subdiagonal of T overwrite the corresponding elements of A. [out] W W is DOUBLE PRECISION array, dimension (N) If INFO = 0, the eigenvalues in ascending order. [out] Z Z is COMPLEX*16 array, dimension (LDZ, N) If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal eigenvectors of the matrix A, with the i-th column of Z holding the eigenvector associated with W(i). If JOBZ = 'N', then Z is not referenced. [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 required LWORK. [in] LWORK LWORK is INTEGER The dimension of array WORK. If N <= 1, LWORK must be at least 1. If JOBZ = 'N' and N > 1, LWORK must be at least N. If JOBZ = 'V' and N > 1, LWORK must be at least 2*N. If LWORK = -1, then a workspace query is assumed; the routine only calculates the required 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 required LRWORK. [in] LRWORK LRWORK is INTEGER The dimension of 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 required 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 required LIWORK. [in] LIWORK LIWORK is INTEGER The dimension of array IWORK. If JOBZ = 'N' or 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 required 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, the algorithm failed to converge; i off-diagonal elements of an intermediate tridiagonal form did not converge to zero.

Definition at line 198 of file zhpevd.f.

200 *
201 * -- LAPACK driver routine --
202 * -- LAPACK is a software package provided by Univ. of Tennessee, --
203 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
204 *
205 * .. Scalar Arguments ..
206  CHARACTER JOBZ, UPLO
207  INTEGER INFO, LDZ, LIWORK, LRWORK, LWORK, N
208 * ..
209 * .. Array Arguments ..
210  INTEGER IWORK( * )
211  DOUBLE PRECISION RWORK( * ), W( * )
212  COMPLEX*16 AP( * ), WORK( * ), Z( LDZ, * )
213 * ..
214 *
215 * =====================================================================
216 *
217 * .. Parameters ..
218  DOUBLE PRECISION ZERO, ONE
219  parameter( zero = 0.0d+0, one = 1.0d+0 )
220  COMPLEX*16 CONE
221  parameter( cone = ( 1.0d+0, 0.0d+0 ) )
222 * ..
223 * .. Local Scalars ..
224  LOGICAL LQUERY, WANTZ
225  INTEGER IINFO, IMAX, INDE, INDRWK, INDTAU, INDWRK,
226  \$ ISCALE, LIWMIN, LLRWK, LLWRK, LRWMIN, LWMIN
227  DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
228  \$ SMLNUM
229 * ..
230 * .. External Functions ..
231  LOGICAL LSAME
232  DOUBLE PRECISION DLAMCH, ZLANHP
233  EXTERNAL lsame, dlamch, zlanhp
234 * ..
235 * .. External Subroutines ..
236  EXTERNAL dscal, dsterf, xerbla, zdscal, zhptrd, zstedc,
237  \$ zupmtr
238 * ..
239 * .. Intrinsic Functions ..
240  INTRINSIC sqrt
241 * ..
242 * .. Executable Statements ..
243 *
244 * Test the input parameters.
245 *
246  wantz = lsame( jobz, 'V' )
247  lquery = ( lwork.EQ.-1 .OR. lrwork.EQ.-1 .OR. liwork.EQ.-1 )
248 *
249  info = 0
250  IF( .NOT.( wantz .OR. lsame( jobz, 'N' ) ) ) THEN
251  info = -1
252  ELSE IF( .NOT.( lsame( uplo, 'L' ) .OR. lsame( uplo, 'U' ) ) )
253  \$ THEN
254  info = -2
255  ELSE IF( n.LT.0 ) THEN
256  info = -3
257  ELSE IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
258  info = -7
259  END IF
260 *
261  IF( info.EQ.0 ) THEN
262  IF( n.LE.1 ) THEN
263  lwmin = 1
264  liwmin = 1
265  lrwmin = 1
266  ELSE
267  IF( wantz ) THEN
268  lwmin = 2*n
269  lrwmin = 1 + 5*n + 2*n**2
270  liwmin = 3 + 5*n
271  ELSE
272  lwmin = n
273  lrwmin = n
274  liwmin = 1
275  END IF
276  END IF
277  work( 1 ) = lwmin
278  rwork( 1 ) = lrwmin
279  iwork( 1 ) = liwmin
280 *
281  IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
282  info = -9
283  ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
284  info = -11
285  ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
286  info = -13
287  END IF
288  END IF
289 *
290  IF( info.NE.0 ) THEN
291  CALL xerbla( 'ZHPEVD', -info )
292  RETURN
293  ELSE IF( lquery ) THEN
294  RETURN
295  END IF
296 *
297 * Quick return if possible
298 *
299  IF( n.EQ.0 )
300  \$ RETURN
301 *
302  IF( n.EQ.1 ) THEN
303  w( 1 ) = dble( ap( 1 ) )
304  IF( wantz )
305  \$ z( 1, 1 ) = cone
306  RETURN
307  END IF
308 *
309 * Get machine constants.
310 *
311  safmin = dlamch( 'Safe minimum' )
312  eps = dlamch( 'Precision' )
313  smlnum = safmin / eps
314  bignum = one / smlnum
315  rmin = sqrt( smlnum )
316  rmax = sqrt( bignum )
317 *
318 * Scale matrix to allowable range, if necessary.
319 *
320  anrm = zlanhp( 'M', uplo, n, ap, rwork )
321  iscale = 0
322  IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
323  iscale = 1
324  sigma = rmin / anrm
325  ELSE IF( anrm.GT.rmax ) THEN
326  iscale = 1
327  sigma = rmax / anrm
328  END IF
329  IF( iscale.EQ.1 ) THEN
330  CALL zdscal( ( n*( n+1 ) ) / 2, sigma, ap, 1 )
331  END IF
332 *
333 * Call ZHPTRD to reduce Hermitian packed matrix to tridiagonal form.
334 *
335  inde = 1
336  indtau = 1
337  indrwk = inde + n
338  indwrk = indtau + n
339  llwrk = lwork - indwrk + 1
340  llrwk = lrwork - indrwk + 1
341  CALL zhptrd( uplo, n, ap, w, rwork( inde ), work( indtau ),
342  \$ iinfo )
343 *
344 * For eigenvalues only, call DSTERF. For eigenvectors, first call
345 * ZUPGTR to generate the orthogonal matrix, then call ZSTEDC.
346 *
347  IF( .NOT.wantz ) THEN
348  CALL dsterf( n, w, rwork( inde ), info )
349  ELSE
350  CALL zstedc( 'I', n, w, rwork( inde ), z, ldz, work( indwrk ),
351  \$ llwrk, rwork( indrwk ), llrwk, iwork, liwork,
352  \$ info )
353  CALL zupmtr( 'L', uplo, 'N', n, n, ap, work( indtau ), z, ldz,
354  \$ work( indwrk ), iinfo )
355  END IF
356 *
357 * If matrix was scaled, then rescale eigenvalues appropriately.
358 *
359  IF( iscale.EQ.1 ) THEN
360  IF( info.EQ.0 ) THEN
361  imax = n
362  ELSE
363  imax = info - 1
364  END IF
365  CALL dscal( imax, one / sigma, w, 1 )
366  END IF
367 *
368  work( 1 ) = lwmin
369  rwork( 1 ) = lrwmin
370  iwork( 1 ) = liwmin
371  RETURN
372 *
373 * End of ZHPEVD
374 *
double precision function dlamch(CMACH)
DLAMCH
Definition: dlamch.f:69
subroutine xerbla(SRNAME, INFO)
XERBLA
Definition: xerbla.f:60
logical function lsame(CA, CB)
LSAME
Definition: lsame.f:53
subroutine dsterf(N, D, E, INFO)
DSTERF
Definition: dsterf.f:86
subroutine zdscal(N, DA, ZX, INCX)
ZDSCAL
Definition: zdscal.f:78
double precision function zlanhp(NORM, UPLO, N, AP, WORK)
ZLANHP returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition: zlanhp.f:117
subroutine zupmtr(SIDE, UPLO, TRANS, M, N, AP, TAU, C, LDC, WORK, INFO)
ZUPMTR
Definition: zupmtr.f:150
subroutine zhptrd(UPLO, N, AP, D, E, TAU, INFO)
ZHPTRD
Definition: zhptrd.f:151
subroutine zstedc(COMPZ, N, D, E, Z, LDZ, WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO)
ZSTEDC
Definition: zstedc.f:212
subroutine dscal(N, DA, DX, INCX)
DSCAL
Definition: dscal.f:79
Here is the call graph for this function:
Here is the caller graph for this function: