?sy(he)evd
Compute all the eigenvalues and (optional) eigenvectors of a symmetric (Hermitian) matrix. The eigenvectors are calculated by using a divide and conquer algorithm.
That is, matrix A is factorized into
, where
is a diagonal matrix, the diagonal element
is an eigenvalue, Z is an orthogonal matrix, and each column vector
of Z is a corresponding eigenvector. That is,
, where
.
Interface Definition
C interface:
void dsyevd_(const char *jobz, const char *uplo, const int *n, double *a, const int *lda, double *w, double *work, const int *lwork, int *iwork, const int *liwork, int *info);
void ssyevd_(const char *jobz, const char *uplo, const int *n, float *a, const int *lda, float *w, float *work, const int *lwork, int *iwork, const int *liwork, int *info);
void cheevd_(const char *jobz, const char *uplo, const int *n, float _Complex *a, const int *lda, float *w, float _Complex *work, const int *lwork, float *rwork, const int *lrwork, int *iwork, const int *liwork, int *info);
void zheevd_(const char *jobz, const char *uplo, const int *n, double _Complex *a, const int *lda, double *w, double _Complex *work, const int *lwork, double *rwork, const int *lrwork, int *iwork, const int *liwork, int *info);
Fortran interface:
DSYEVD(JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK, LIWORK, INFO);
SSYEVD(JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, IWORK, LIWORK, INFO);
CHEEVD(JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO);
ZHEEVD(JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, RWORK, LRWORK, IWORK, LIWORK, INFO);
Parameters
|
Parameter |
Type |
Description |
Input/Output |
|---|---|---|---|
|
jobz |
Character |
|
Input |
|
uplo |
Character |
|
Input |
|
n |
Integer |
Number of rows or columns in the symmetric matrix A. |
Input |
|
a |
|
|
Input/Output |
|
lda |
Integer |
Leading dimension of matrix A. lda ≥ max(1, n). |
Input |
|
w |
|
Eigenvalues in ascending order. The length is n. |
Output |
|
work |
|
Workspace array. After this function is called, work[0] returns the optimal lwork value. |
Output |
|
lwork |
Integer |
Length of the work array. If lwork = -1, the optimal work size is queried and the result is saved in work[0]. If lwork ≠ -1:
|
Input |
|
rwork (only for complex types) |
|
Workspace array. After this function is called, work[0] returns the optimal lwork value. |
Output |
|
lrwork (only for the complex type) |
|
Length of the rwork array. If lrwork = -1, the optimal work size is queried and the result is saved in rwork[0]. If lrwork ≠ -1:
|
Input |
|
iwork |
Integer array |
Temporary storage space. After this interface is called with lwork = -1, iwork[0] is the optimal liwork value. |
Output |
|
liwork |
Integer |
Length of the iwork array. If liwork=-1, the optimal iwork size is queried and the result is saved in iwork[0]. Otherwise:
|
Input |
|
info |
Integer |
Execution result:
|
Output |
Dependencies
#include "klapack.h"
Examples
C interface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
char jobz = 'V'; char uplo = 'L'; int n = 5; int lda = 5; int info = 0; double w[5]; double *work = NULL; double qwork; int lwork = -1; int *iwork = NULL; int qiwork; int liwork = -1; /* * Symmetric A (stored in column-major): * 7.027 8.710 1.015 6.929 7.584 * 8.710 0.839 2.469 3.850 0.559 * 1.015 2.469 1.930 6.761 7.207 * 6.929 3.850 6.761 4.344 4.804 * 7.584 0.559 7.207 4.804 6.177 */ double a[] = {7.027, 8.710, 1.015, 6.929, 7.584, 8.710, 0.839, 2.469, 3.850, 0.559, 1.015, 2.469, 1.930, 6.761, 7.207, 6.929, 3.850, 6.761, 4.344, 4.804, 7.584, 0.559, 7.207, 4.804, 6.177}; /* Query optimal work size */ dsyevd_(&jobz, &uplo, &n, a, &lda, w, &qwork, &lwork, &qiwork, &liwork, &info); if (info != 0) { return ERROR; } lwork = (int)qwork; work = (double *)malloc(sizeof(double) * lwork); liwork = (int)qiwork; iwork = (int *)malloc(sizeof(int) * liwork); /* Calculate eigenvalues and eigenvectors */ dsyevd_(&jobz, &uplo, &n, a, &lda, w, work, &lwork, iwork, &liwork, &info); free(work); free(iwork); /* * Output: * Eigenvalues (in w) * -8.8422 -3.3411 1.1888 6.2050 25.1065 * Eigenvectors (in a, stored in column-major) * 0.5405 -0.1616 -0.3059 -0.5235 -0.5604 * -0.4913 0.5975 0.2432 -0.4882 -0.3228 * 0.4886 0.4989 0.3454 0.5213 -0.3482 * -0.2410 -0.6062 0.5831 0.1038 -0.4729 * -0.4120 0.0219 -0.6228 0.4528 -0.4867 */ |
Fortran interface:
CHARACTER :: jobz = "V"
CHARACTER :: uplo = "L"
PARAMETER (n = 5)
PARAMETER (lda = 5)
INTEGER :: info = 0
REAL(8) :: w(5);
REAL(8) :: qwork(1)
REAL(8), ALLOCATABLE :: work(:)
INTEGER :: lwork = -1
INTEGER :: qiwork(1)
REAL(8), ALLOCATABLE :: iwork(:)
INTEGER :: liwork = -1
* Symmetric A (stored in column-major):
* 7.027 8.710 1.015 6.929 7.584
* 8.710 0.839 2.469 3.850 0.559
* 1.015 2.469 1.930 6.761 7.207
* 6.929 3.850 6.761 4.344 4.804
* 7.584 0.559 7.207 4.804 6.177
REAL(8) :: a(n, n)
DATA a / 7.027, 8.710, 1.015, 6.929, 7.584,
$ 8.710, 0.839, 2.469, 3.850, 0.559,
$ 1.015, 2.469, 1.930, 6.761, 7.207,
$ 6.929, 3.850, 6.761, 4.344, 4.804,
$ 7.584, 0.559, 7.207, 4.804, 6.177 /
* Query optimal work size
EXTERNAL DSYEVD
CALL DSYEVD(jobz, uplo, n, a, lda, w, qwork, lwork, qiwork,
$ liwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
lwork = INT(qwork(1))
liwork = INT(qiwork(1))
ALLOCATE(work(lwork), iwork(liwork))
* Calculate eigenvalues and eigenvectors
CALL DSYEVD(jobz, uplo, n, a, lda, w, work, lwork, iwork,
$ liwork, info)
DEALLOCATE(work, iwork);
* Output:
* Eigenvalues (in w)
* -8.8422 -3.3411 1.1888 6.2050 25.1065
* Eigenvectors (in a, stored in column-major)
* 0.5405 -0.1616 -0.3059 -0.5235 -0.5604
* -0.4913 0.5975 0.2432 -0.4882 -0.3228
* 0.4886 0.4989 0.3454 0.5213 -0.3482
* -0.2410 -0.6062 0.5831 0.1038 -0.4729
* -0.4120 0.0219 -0.6228 0.4528 -0.4867