-
template<typename T>
void gesdd(char *jobz, integer *m, integer *n, T *a, integer *lda, T *s, T *u, integer *ldu, T *vt, integer *ldvt, T *work, integer *lwork, integer *iwork, integer *info)# General matrix singular value decomposition (divide-and-conquer)
Purpose:
Computation of singular value decomposition (SVD) of a real m-by-n matrix a, optionally computing the left and right singular vectors. If singular vectors are desired, it uses a divide-and-conquer algorithm. The SVD is written A = U * SIGMA * transpose(V) where SIGMA is an m-by-n matrix which is zero except for its min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and V is an n-by-n orthogonal matrix. The diagonal elements of SIGMA are the singular values of A; they are real and non-negative, and are returned in descending order. The first min(m,n) columns of U and V are the left and right singular vectors of A. Note that the routine returns vt = V**T, not V. 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:
jobz – [in]
jobz is char*
Specifies options for computing all or part of the matrix U:
= ‘A’: all M columns of U and all N rows of V**T are returned in the arrays U and vt;
= ‘S’: the first min(m,n) columns of U and the first min(m,n) rows of V**T are returned in the arrays U and vt;
= ‘O’: If m >= n, the first N columns of U are overwritten on the array a and all rows of V**T are returned in the array vt;
otherwise, all columns of U are returned in the array U and the first M rows of V**T are overwritten in the array a;
= ‘N’: no columns of U or rows of V**T are computed.m – [in]
m is integer*
The number of rows of the input matrix a. m >= 0.
n – [in]
n is integer*
The number of columns of the input matrix a. n >= 0.
a – [inout]
a is float/double array, dimension (lda,n)
On entry, the m-by-n matrix a.
On exit,
if jobz = ‘O’, A is overwritten with the first N columns of U (the left singular vectors, stored columnwise) if m >= n; A is overwritten with the first M rows of V**T (the right singular vectors, stored rowwise) otherwise.
if jobz .ne. ‘O’, the contents of A are destroyed.lda – [in]
lda is integer*
The leading dimension of the array a. lda >= fla_max(1,m).
s – [out]
s is float/double array, dimension (min(m,n))
The singular values of A, sorted so that S(i) >= S(i+1).
u – [out]
U is float/double array, dimension (ldu,UCOL)
UCOL = m if jobz = ‘A’ or jobz = ‘O’ and M < N;
UCOL = min(m,n) if jobz = ‘S’.
If jobz = ‘A’ or jobz = ‘O’ and m < m, U contains the m-by-m orthogonal matrix U;
if jobz = ‘S’, U contains the first min(m,n) columns of U (the left singular vectors, stored columnwise);
if jobz = ‘O’ and m >= n, or jobz = ‘N’, U is not referenced.
ldu – [in]
ldu is integer*
The leading dimension of the array U. ldu >= 1; if jobz = ‘S’ or ‘A’ or jobz = ‘O’ and m < n, ldu >= m.
vt – [out]
vt is float/double array, dimension (ldvt,n)
If jobz = ‘A’ or jobz = ‘O’ and m >= n, vt contains the n-by-n orthogonal matrix V**T;
if jobz = ‘S’, vt contains the first min(m,n) rows of V**T (the right singular vectors, stored rowwise);
if jobz = ‘O’ and M < N, or jobz = ‘N’, vt is not referenced.
ldvt – [in]
ldvt is integer*
The leading dimension of the array vt. ldvt >= 1;
if jobz = ‘A’ or jobz = ‘O’ and m >= n, ldvt >= n;
if jobz = ‘S’, ldvt >= min(m,n).
WORK – [out]
WORK is COMPLEX array, dimension (MAX(1,LWORK))
On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
LWORK – [in]
LWORK is INTEGER
The dimension of the array WORK. LWORK >= 1.
If LWORK = -1, a workspace query is assumed. The optimal size for the WORK array is calculated and stored in WORK(1), and no other work except argument checking is performed.
Let mx = fla_max(M,N) and mn = min(M,N).
If JOBZ = ‘N’, LWORK >= 2*mn + mx.
If JOBZ = ‘O’, LWORK >= 2*mn*mn + 2*mn + mx.
If JOBZ = ‘S’, LWORK >= mn*mn + 3*mn.
If JOBZ = ‘A’, LWORK >= mn*mn + 2*mn + mx.
These are not tight minimums in all cases; see comments inside code. For good performance, LWORK should generally be larger; a query is recommended.RWORK – [out]
RWORK is REAL array, dimension (MAX(1,LRWORK))
Let mx = fla_max(M,N) and mn = min(M,N).
If JOBZ = ‘N’, LRWORK >= 5*mn (LAPACK <= 3.6 needs 7*mn);
else if mx >> mn, LRWORK >= 5*mn*mn + 5*mn;
else LRWORK >= fla_max( 5*mn*mn + 5*mn, 2*mx*mn + 2*mn*mn + mn ).IWORK – [out] IWORK is INTEGER array, dimension (8*min(M,N))
INFO – [out]
INFO is INTEGER
= 0: successful exit.
< 0: if INFO = -i, the i-th argument had an illegal value.
> 0: The updating process of SBDSDC did not converge.