?gesvd
Compute the SVD of a general matrix.
Interface Definition
C interface:
sgesvd_(const char *jobu, const char *jobvt, const int *m, const int *n, float *a, const int *lda, float *s, float *u, const int *ldu, float *vt,
const int *ldvt, float *work, const int *lwork, int *info);
dgesvd_(const char *jobu, const char *jobvt, const int *m, const int *n, double *a, const int *lda, double *s, double *u, const int *ldu, double *vt,
const int *ldvt, double *work, const int *lwork, int *info);
cgesvd_(const char *jobu, const char *jobvt, const int *m, const int *n, float _Complex *a, const int *lda, float *s, float _Complex *u, const int *ldu, float _Complex *vt,
const int *ldvt, float _Complex *work, const int *lwork, float *rwork, int *info);
zgesvd_(const char *jobu, const char *jobvt, const int *m, const int *n, double _Complex *a, const int *lda, double *s, double _Complex *u, const int *ldu, double _Complex *vt,
const int *ldvt, double _Complex *work, const int *lwork, double *rwork, int *info);
Fortran interface:
SGESVD(JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO);
DGESVD(JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO);
CGESVD(JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, INFO);
ZGESVD(JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, INFO);
Parameters
Parameter |
Type |
Description |
Input/Output |
|---|---|---|---|
jobu |
Character |
|
Input |
jobvt |
Character |
|
Input |
m |
Integer |
Number of rows in matrix a. m ≥ 0. |
Input |
n |
Integer |
Number of columns in matrix a. n ≥ 0. |
Input |
a |
|
Array with a size of lda*n. On entry: Matrix a is an m x n matrix. On exit
|
Input/Output |
lda |
|
Leading dimension of matrix a. lda ≥ max(1, m). |
Input |
s |
|
Array with a size of min(m, n). On exit, it contains the singular values of matrix a sorted such that s(i) ≥ s(i+1). |
Output |
u |
|
Array with a size of ldu*ucol, where ucol = m if jobu = 'A' or ucol = min(m, n) if jobu = 'S'. If jobu = 'A', it is an m x m unitary matrix u. If jobu = 'S', it contains the first min(m, n) columns of matrix U (left singular vectors, column-major order). If jobu = 'N' or 'O', it is not used. |
Output |
ldu |
Integer |
Leading dimension of matrix u. ldu ≥ 1. If jobu = 'S' or 'A', ldu ≥ m. |
Input |
vt |
|
Array with a size of ldvt*n. If jobvt = 'A', it is an n x n unitary matrix v**H. If jobvt = 'S', it contains the first min(m, n) rows of matrix v**H (right singular vectors, row-major order). If jobvt = 'N' or 'O', it is not used. |
Output |
ldvt |
Integer |
Leading dimension of matrix vt. ldvt ≥ 1. If jobvt = 'A', ldvt ≥ n. If jobvt = 'S', ldvt ≥ min(m, n). |
Input |
work |
|
Array with a size of max(1, lwork). On exit: If info = 0, work(1) returns the optimal lwork size. |
Output |
lwork |
Integer |
Size of the work array. lwork ≥ max(1, 2*min(m, n) + max(m, n)). If lwork = -1, the function only computes the optimal size of the work array. |
Input |
rwork (only for complex types) |
|
Array with a size of 5*min(m,n). If info > 0 upon exit, rwork(1:min(m,n)-1) contains the unconverged superdiagonal elements of an upper bidiagonal matrix B whose diagonal elements are stored in s. |
Output |
info |
Integer |
|
Output |
Dependencies
#include "klapack.h"
Examples
C interface:
const char jobu = 'A';
const char jobvt = 'A';
const int m = 5;
const int n = 5;
const int lda = 5;
const int ldu = 5;
const int ldvt = 5;
double a[] = {72.1673, 66.1857, 64.7644, 28.0199, 91.4151,
6.5180, 62.8483, 72.4323, 46.5760, 8.6928,
28.9821, 42.1828, 18.6437, 99.8612, 35.6972,
67.9812, 5.0880, 85.5035, 79.2945, 54.5920,
28.6869, 49.7512, 7.5186, 28.6929, 84.6041};
double *s = (double*)malloc(m * sizeof(double));
double *u = (double*)malloc(ldu*m * sizeof(double));
double *vt = (double*)malloc(ldvt*n * sizeof(double));
double qwork;
int lwork = -1;
int info = 0;
dgesvd_(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &qwork, &lwork, &info);
if (info != 0) {
printf("Error, info = %d\n", info);
return info;
}
lwork = (int)qwork;
double *work = (double*)malloc(lwork * sizeof(double));
dgesvd_(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, &info);
if (info != 0) {
printf("Error, info = %d\n", info);
return info;
}
/* output */
* s
* 254.071516 87.547400 67.835073 64.370735 14.897476
* u
* -0.395825 -0.377874 -0.458327 -0.488090 -0.502234 -0.155273 -0.217110 0.348128 0.628260 -0.642534 * -0.312281 0.362918 -0.694714 0.528618 0.093312 -0.399962 0.761762 0.321232 -0.289476 -0.269743
* -0.749482 -0.313183 0.287969 0.061841 0.503430
* vt
* -0.562230 -0.504441 -0.297298 0.148954 -0.564680 -0.340949 0.391046 -0.060652 0.818829 0.238069 * -0.403926 0.372759 0.728616 -0.186514 -0.363629 -0.527964 0.375181 -0.468379 -0.520847 0.299721 * -0.354610 -0.559386 0.397083 -0.035531 0.634351
Fortran interface:
CHARACTER :: jobu = "A"
CHARACTER :: jobvt = "A"
PARAMETER (m = 5)
PARAMETER (n = 5)
PARAMETER (lda = 5)
PARAMETER (ldu = 5)
PARAMETER (ldvt = 5)
INTEGER :: info = 0
REAL(8) :: a(lad, n)
REAL(8) :: s(m)
REAL(8) :: u(ldu, m)
REAL(8) :: vt(ldvt, n)
REAL(8), ALLOCATABLE :: work(:)
INTEGER :: lwork = -1
REAL(8) :: qwork
DATA a / 72.1673, 66.1857, 64.7644, 28.0199, 91.4151,
6.5180, 62.8483, 72.4323, 46.5760, 8.6928,
28.9821, 42.1828, 18.6437, 99.8612, 35.6972,
67.9812, 5.0880, 85.5035, 79.2945, 54.5920,
28.6869, 49.7512, 7.5186, 28.6929, 84.6041/
EXTERNAL DGESVD
CALL DGESVD(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, qwork, lwork, info);
lwork = (int)qwork;
work = (double *)malloc(sizeof(double) * lwork);
CALL DGESVD(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, info);
*
* Output:
* s
* 254.071516 87.547400 67.835073 64.370735 14.897476
* u
* -0.395825 -0.377874 -0.458327 -0.488090 -0.502234 -0.155273 -0.217110 0.348128 0.628260 -0.642534 * -0.312281 0.362918 -0.694714 0.528618 0.093312 -0.399962 0.761762 0.321232 -0.289476 -0.269743
* -0.749482 -0.313183 0.287969 0.061841 0.503430
* vt
* -0.562230 -0.504441 -0.297298 0.148954 -0.564680 -0.340949 0.391046 -0.060652 0.818829 0.238069 * -0.403926 0.372759 0.728616 -0.186514 -0.363629 -0.527964 0.375181 -0.468379 -0.520847 0.299721 * -0.354610 -0.559386 0.397083 -0.035531 0.634351