gesvdq#
Functions
-
void sgesvdq(const char *joba, const char *jobp, const char *jobr, const char *jobu, const char *jobv, const INT m, const INT n, f32 *restrict A, const INT lda, f32 *restrict S, f32 *restrict U, const INT ldu, f32 *restrict V, const INT ldv, INT *numrank, INT *restrict iwork, const INT liwork, f32 *restrict work, const INT lwork, f32 *restrict rwork, const INT lrwork, INT *info)#
SGESVDQ computes the singular value decomposition (SVD) of a real M-by-N matrix A, where M >= N.
The SVD of A is written as
A = U * SIGMA * V**T
where SIGMA is an N-by-N diagonal matrix, U is an M-by-N orthonormal matrix, and V is an N-by-N orthogonal matrix. SGESVDQ computes the singular value decomposition (SVD) of a real
m-by-nmatrixA, wherem>=n. The SVD ofAis written aswhere SIGMA is an[++] [xx] [x0] [xx] A = U * SIGMA * V^*, [++] = [xx] * [ox] * [xx] [++] [xx]n-by-ndiagonal matrix, U is anm-by-northonormal matrix, and V is ann-by-northogonal matrix. The diagonal elements of SIGMA are the singular values ofA. The columns of U and V are the left and the right singular vectors ofA, respectively.- Further Details:
1. The data movement (matrix transpose) is coded using simple nested DO-loops because BLAS and LAPACK do not provide corresponding subroutines. Those DO-loops are easily identified in this source code - by the CONTINUE statements labeled with 11**. In an optimized version of this code, the nested DO loops should be replaced with calls to an optimized subroutine.
2. This code scales A by 1/SQRT(M) if the largest ABS(A(i,j)) could cause column norm overflow. This is the minimal precaution and it is left to the SVD routine (SGESVD) to do its own preemptive scaling if potential over- or underflows are detected. To avoid repeated scanning of the array A, an optimal implementation would do all necessary scaling before calling SGESVD and the scaling in SGESVD can be switched off.
3. Other comments related to code optimization are given in comments in the code, enclosed in [[double brackets]].
- Bugs, examples and comments:
Please report all bugs and send interesting examples and/or comments to drmac@math.hr. Thank you.
- References:
[1] Zlatko Drmac, Algorithm 977: A QR-Preconditioned QR SVD Method for Computing the SVD with High Accuracy. ACM Trans. Math. Softw. 44(1): 11:1-11:30 (2017)
SIGMA library, xGESVDQ section updated February 2016. Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
- Contributors:
Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
Parameters
injobaSpecifies the level of accuracy in the computed SVD.
joba='A': The requested accuracy corresponds to having the backward error bounded by|| delta A ||_F <= f(m,n)*EPS*|| A ||_F, whereEPS = slamch("Epsilon"). This authorises SGESVDQ to truncate the computed triangular factor in a rank revealing QR factorization whenever the truncated part is below the threshold of the order ofEPS * ||A||_F. This is aggressive truncation level.joba='M': Similarly as with'A', but the truncation is more gentle: it is allowed only when there is a drop on the diagonal of the triangular factor in the QR factorization. This is medium truncation level.joba='H': High accuracy requested. No numerical rank determination based on the rank revealing QR factorization is attempted.joba='E': Same as'H', and in addition the condition number of column scaledAis estimated and returned inrwork[0].N^(-1/4)*rwork[0] <= ||pinv(A_scaled)||_2 <= N^(1/4)*rwork[0].injobpjobp='P': The rows ofAare ordered in decreasing order with respect to||A(i,:)||_\infty. This enhances numerical accuracy at the cost of extra data movement. Recommended for numerical robustness.jobp='N': No row pivoting.injobrjobr='T': After the initial pivoted QR factorization, SGESVD is applied to the transposedR**Tof the computed triangular factor R. This involves some extra data movement (matrix transpositions). Useful for experiments, research and development.jobr='N': The triangular factor R is given as input to SGESVD. This may be preferred as it involves less data movement.injobujobu='A': Allmleft singular vectors are computed and returned in the matrixU. See the description ofU.jobu='S'orjobu='U':n = min(m,n)left singular vectors are computed and returned in the matrixU. See the description ofU.jobu='R': Numerical ranknumrankis determined and onlynumrankleft singular vectors are computed and returned in the matrixU.jobu='F': Thenleft singular vectors are returned in factored form as the product of the Q factor from the initial QR factorization and thenleft singular vectors of(R**T, 0)**T. If row pivoting is used, then the necessary information on the row pivoting is stored iniwork[n:n+m-2].jobu='N': The left singular vectors are not computed.injobvjobv='A'orjobv='V': Allnright singular vectors are computed and returned in the matrixV.jobv='R': Numerical ranknumrankis determined and onlynumrankright singular vectors are computed and returned in the matrixV. This option is allowed only ifjobu='R'orjobu='N'; otherwise it is illegal.jobv='N': The right singular vectors are not computed.inmThe number of rows of the input matrix
A.m>=0.innThe number of columns of the input matrix
A.m>=n>=0.inoutAArray of dimensions
ldaxn. On entry, the input matrixA. On exit, ifjobu!='N'orjobv!='N', the lower triangle ofAcontains the Householder vectors as stored by SGEQP3. Ifjobu='F', these Householder vectors together withwork[0:n-1]can be used to restore the Q factors from the initial pivoted QR factorization ofA. See the description ofU.inldaThe leading dimension of the array
A.lda>=max(1,m).outSArray of dimension
n. The singular values ofA, ordered so thatS[i]>=S[i+1].outUArray of dimension
lduxmifjobu='A'; see the description ofldu. In this case, on exit,Ucontains themleft singular vectors.lduxnifjobu='S','U','R'; see the description ofldu. In this case,Ucontains the leadingnor the leadingnumrankleft singular vectors.lduxnifjobu='F'; see the description ofldu. In this caseUcontainsnxnorthogonal matrix that can be used to form the left singular vectors. Ifjobu='N',Uis not referenced.inlduThe leading dimension of the array
U. Ifjobu='A','S','U','R',ldu>=max(1,m). Ifjobu='F',ldu>=max(1,n). Otherwise,ldu>=1.outVArray of dimension
ldvxnifjobv='A','V','R'or ifjoba='E'. Ifjobv='A'or'V',Vcontains then-by-northogonal matrixV**T; Ifjobv='R',Vcontains the firstnumrankrows ofV**T(the right singular vectors, stored rowwise, of thenumranklargest singular values). Ifjobv='N'andjoba='E',Vis used as a workspace. Ifjobv='N'andjoba!='E',Vis not referenced.inldvThe leading dimension of the array
V. Ifjobv='A','V','R', orjoba='E',ldv>=max(1,n). Otherwise,ldv>=1.outnumranknumrankis the numerical rank first determined after the rank revealing QR factorization, following the strategy specified by the value ofjoba. Ifjobv='R'andjobu='R', onlynumrankleading singular values and vectors are then requested in the call of SGESVD. The final value ofnumrankmight be further reduced if some singular values are computed as zeros.outiworkInteger array of dimension (
max(1,liwork)). On exit,iwork[0:n-1]contains column pivoting permutation of the rank revealing QR factorization. Ifjobp='P',iwork[n:n+m-2]contains the indices of the sequence of row swaps used in row pivoting. These can be used to restore the left singular vectors in the casejobu='F'. Ifliwork,lwork, orlrwork = -1, then on exit, ifinfo=0,iwork[0]returns the minimalliwork.inliworkThe dimension of the array
iwork.liwork >= n+m-1, ifjobp='P'andjoba!='E';liwork >= n, ifjobp='N'andjoba!='E';liwork >= n+m-1+n, ifjobp='P'andjoba='E';liwork >= n+n, ifjobp='N'andjoba='E'. Ifliwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thework,iwork, andrworkarrays, and no error message related tolworkis issued by XERBLA.outworkArray of dimension (
max(2,lwork)), used as a workspace. On exit, if, on entry,lwork!=-1,work[0:n-1]contains parameters needed to recover the Q factor from the QR factorization computed by SGEQP3. Ifliwork,lwork, orlrwork = -1, then on exit, ifinfo=0,work[0]returns the optimallwork, andwork[1]returns the minimallwork.inoutlworkThe dimension of the array
work. It is determined as follows:Finally,Let LWQP3 = 3*N+1, LWCON = 3*N, and let LWORQ = { MAX( N, 1 ), if JOBU = 'R', 'S', or 'U' { MAX( M, 1 ), if JOBU = 'A' LWSVD = MAX( 5*N, 1 ) LWLQF = MAX( N/2, 1 ), LWSVD2 = MAX( 5*(N/2), 1 ), LWORLQ = MAX( N, 1 ), LWQRF = MAX( N/2, 1 ), LWORQ2 = MAX( N, 1 ) Then the minimal value of LWORK is: = MAX( N + LWQP3, LWSVD ) if only the singular values are needed; = MAX( N + LWQP3, LWCON, LWSVD ) if only the singular values are needed, and a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWORQ ) if the singular values and the left singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD, LWORQ ) if the singular values and the left singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD ) if the singular values and the right singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD ) if the singular values and the right singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWORQ ) if the full SVD is requested with JOBV = 'R'; independent of JOBR; = N + MAX( LWQP3, LWCON, LWSVD, LWORQ ) if the full SVD is requested, JOBV = 'R' and, also a scaled condition estimate requested; independent of JOBR; = MAX( N + MAX( LWQP3, LWSVD, LWORQ ), N + MAX( LWQP3, N/2+LWLQF, N/2+LWSVD2, N/2+LWORLQ, LWORQ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWORQ ), N + MAX( LWQP3, LWCON, N/2+LWLQF, N/2+LWSVD2, N/2+LWORLQ, LWORQ ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N', and also a scaled condition number estimate requested. = MAX( N + MAX( LWQP3, LWSVD, LWORQ ), N + MAX( LWQP3, N/2+LWQRF, N/2+LWSVD2, N/2+LWORQ2, LWORQ ) ) if the full SVD is requested with JOBV = 'A', 'V', and JOBR ='T' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWORQ ), N + MAX( LWQP3, LWCON, N/2+LWQRF, N/2+LWSVD2, N/2+LWORQ2, LWORQ ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='T', and also a scaled condition number estimate requested.lworkmust be at least two:lwork = max(2,lwork). Iflwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thework,iwork, andrworkarrays, and no error message related tolworkis issued by XERBLA.outrworkArray of dimension (
max(1,lrwork)). On exit,If
joba='E',rwork[0]contains an estimate of the condition number of column scaledA. IfA = C * Dwhere D is diagonal and C has unit columns in the Euclidean norm, then, assuming full column rank,N^(-1/4) * rwork[0] <= ||pinv(C)||_2 <= N^(1/4) * rwork[0]. Otherwise,rwork[0] = -1.rwork[1]contains the number of singular values computed as exact zeros in SGESVD applied to the upper triangular or trapezoidal R (from the initial QR factorization). In case of early exit (no call to SGESVD, such as in the case of zero matrix)rwork[1] = -1. Ifliwork,lwork, orlrwork = -1, then on exit, ifinfo=0,rwork[0]returns the minimallrwork.
inlrworkThe dimension of the array
rwork. Ifjobp='P', thenlrwork >= max(2,m). Otherwise,lrwork >= 2. Iflrwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thework,iwork, andrworkarrays, and no error message related tolworkis issued by XERBLA.outinfoinfo=0: successful exit.info<0: ifinfo=-i, the i-th argument had an illegal value.info>0: if SBDSQR did not converge,infospecifies how many superdiagonals of an intermediate bidiagonal form B (computed in SGESVD) did not converge to zero.
void sgesvdq(
const char* joba,
const char* jobp,
const char* jobr,
const char* jobu,
const char* jobv,
const INT m,
const INT n,
f32* restrict A,
const INT lda,
f32* restrict S,
f32* restrict U,
const INT ldu,
f32* restrict V,
const INT ldv,
INT* numrank,
INT* restrict iwork,
const INT liwork,
f32* restrict work,
const INT lwork,
f32* restrict rwork,
const INT lrwork,
INT* info
);
Functions
-
void dgesvdq(const char *joba, const char *jobp, const char *jobr, const char *jobu, const char *jobv, const INT m, const INT n, f64 *restrict A, const INT lda, f64 *restrict S, f64 *restrict U, const INT ldu, f64 *restrict V, const INT ldv, INT *numrank, INT *restrict iwork, const INT liwork, f64 *restrict work, const INT lwork, f64 *restrict rwork, const INT lrwork, INT *info)#
DGESVDQ computes the singular value decomposition (SVD) of a real M-by-N matrix A, where M >= N.
The SVD of A is written as
A = U * SIGMA * V**T
where SIGMA is an N-by-N diagonal matrix, U is an M-by-N orthonormal matrix, and V is an N-by-N orthogonal matrix. DGESVDQ computes the singular value decomposition (SVD) of a real
m-by-nmatrixA, wherem>=n. The SVD ofAis written aswhere SIGMA is an[++] [xx] [x0] [xx] A = U * SIGMA * V^*, [++] = [xx] * [ox] * [xx] [++] [xx]n-by-ndiagonal matrix, U is anm-by-northonormal matrix, and V is ann-by-northogonal matrix. The diagonal elements of SIGMA are the singular values ofA. The columns of U and V are the left and the right singular vectors ofA, respectively.- Further Details:
1. The data movement (matrix transpose) is coded using simple nested DO-loops because BLAS and LAPACK do not provide corresponding subroutines. Those DO-loops are easily identified in this source code - by the CONTINUE statements labeled with 11**. In an optimized version of this code, the nested DO loops should be replaced with calls to an optimized subroutine.
2. This code scales A by 1/SQRT(M) if the largest ABS(A(i,j)) could cause column norm overflow. This is the minimal precaution and it is left to the SVD routine (DGESVD) to do its own preemptive scaling if potential over- or underflows are detected. To avoid repeated scanning of the array A, an optimal implementation would do all necessary scaling before calling DGESVD and the scaling in DGESVD can be switched off.
3. Other comments related to code optimization are given in comments in the code, enclosed in [[double brackets]].
- Bugs, examples and comments:
Please report all bugs and send interesting examples and/or comments to drmac@math.hr. Thank you.
- References:
[1] Zlatko Drmac, Algorithm 977: A QR-Preconditioned QR SVD Method for Computing the SVD with High Accuracy. ACM Trans. Math. Softw. 44(1): 11:1-11:30 (2017)
SIGMA library, xGESVDQ section updated February 2016. Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
- Contributors:
Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
Parameters
injobaSpecifies the level of accuracy in the computed SVD.
joba='A': The requested accuracy corresponds to having the backward error bounded by|| delta A ||_F <= f(m,n)*EPS*|| A ||_F, whereEPS = dlamch("Epsilon"). This authorises DGESVDQ to truncate the computed triangular factor in a rank revealing QR factorization whenever the truncated part is below the threshold of the order ofEPS * ||A||_F. This is aggressive truncation level.joba='M': Similarly as with'A', but the truncation is more gentle: it is allowed only when there is a drop on the diagonal of the triangular factor in the QR factorization. This is medium truncation level.joba='H': High accuracy requested. No numerical rank determination based on the rank revealing QR factorization is attempted.joba='E': Same as'H', and in addition the condition number of column scaledAis estimated and returned inrwork[0].N^(-1/4)*rwork[0] <= ||pinv(A_scaled)||_2 <= N^(1/4)*rwork[0].injobpjobp='P': The rows ofAare ordered in decreasing order with respect to||A(i,:)||_\infty. This enhances numerical accuracy at the cost of extra data movement. Recommended for numerical robustness.jobp='N': No row pivoting.injobrjobr='T': After the initial pivoted QR factorization, DGESVD is applied to the transposedR**Tof the computed triangular factor R. This involves some extra data movement (matrix transpositions). Useful for experiments, research and development.jobr='N': The triangular factor R is given as input to DGESVD. This may be preferred as it involves less data movement.injobujobu='A': Allmleft singular vectors are computed and returned in the matrixU. See the description ofU.jobu='S'orjobu='U':n = min(m,n)left singular vectors are computed and returned in the matrixU. See the description ofU.jobu='R': Numerical ranknumrankis determined and onlynumrankleft singular vectors are computed and returned in the matrixU.jobu='F': Thenleft singular vectors are returned in factored form as the product of the Q factor from the initial QR factorization and thenleft singular vectors of(R**T, 0)**T. If row pivoting is used, then the necessary information on the row pivoting is stored iniwork[n:n+m-2].jobu='N': The left singular vectors are not computed.injobvjobv='A'orjobv='V': Allnright singular vectors are computed and returned in the matrixV.jobv='R': Numerical ranknumrankis determined and onlynumrankright singular vectors are computed and returned in the matrixV. This option is allowed only ifjobu='R'orjobu='N'; otherwise it is illegal.jobv='N': The right singular vectors are not computed.inmThe number of rows of the input matrix
A.m>=0.innThe number of columns of the input matrix
A.m>=n>=0.inoutAArray of dimensions
ldaxn. On entry, the input matrixA. On exit, ifjobu!='N'orjobv!='N', the lower triangle ofAcontains the Householder vectors as stored by DGEQP3. Ifjobu='F', these Householder vectors together withwork[0:n-1]can be used to restore the Q factors from the initial pivoted QR factorization ofA. See the description ofU.inldaThe leading dimension of the array
A.lda>=max(1,m).outSArray of dimension
n. The singular values ofA, ordered so thatS[i]>=S[i+1].outUArray of dimension
lduxmifjobu='A'; see the description ofldu. In this case, on exit,Ucontains themleft singular vectors.lduxnifjobu='S','U','R'; see the description ofldu. In this case,Ucontains the leadingnor the leadingnumrankleft singular vectors.lduxnifjobu='F'; see the description ofldu. In this caseUcontainsnxnorthogonal matrix that can be used to form the left singular vectors. Ifjobu='N',Uis not referenced.inlduThe leading dimension of the array
U. Ifjobu='A','S','U','R',ldu>=max(1,m). Ifjobu='F',ldu>=max(1,n). Otherwise,ldu>=1.outVArray of dimension
ldvxnifjobv='A','V','R'or ifjoba='E'. Ifjobv='A'or'V',Vcontains then-by-northogonal matrixV**T; Ifjobv='R',Vcontains the firstnumrankrows ofV**T(the right singular vectors, stored rowwise, of thenumranklargest singular values). Ifjobv='N'andjoba='E',Vis used as a workspace. Ifjobv='N'andjoba!='E',Vis not referenced.inldvThe leading dimension of the array
V. Ifjobv='A','V','R', orjoba='E',ldv>=max(1,n). Otherwise,ldv>=1.outnumranknumrankis the numerical rank first determined after the rank revealing QR factorization, following the strategy specified by the value ofjoba. Ifjobv='R'andjobu='R', onlynumrankleading singular values and vectors are then requested in the call of DGESVD. The final value ofnumrankmight be further reduced if some singular values are computed as zeros.outiworkInteger array of dimension (
max(1,liwork)). On exit,iwork[0:n-1]contains column pivoting permutation of the rank revealing QR factorization. Ifjobp='P',iwork[n:n+m-2]contains the indices of the sequence of row swaps used in row pivoting. These can be used to restore the left singular vectors in the casejobu='F'. Ifliwork,lwork, orlrwork = -1, then on exit, ifinfo=0,iwork[0]returns the minimalliwork.inliworkThe dimension of the array
iwork.liwork >= n+m-1, ifjobp='P'andjoba!='E';liwork >= n, ifjobp='N'andjoba!='E';liwork >= n+m-1+n, ifjobp='P'andjoba='E';liwork >= n+n, ifjobp='N'andjoba='E'. Ifliwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thework,iwork, andrworkarrays, and no error message related tolworkis issued by XERBLA.outworkArray of dimension (
max(2,lwork)), used as a workspace. On exit, if, on entry,lwork!=-1,work[0:n-1]contains parameters needed to recover the Q factor from the QR factorization computed by DGEQP3. Ifliwork,lwork, orlrwork = -1, then on exit, ifinfo=0,work[0]returns the optimallwork, andwork[1]returns the minimallwork.inoutlworkThe dimension of the array
work. It is determined as follows:Finally,Let LWQP3 = 3*N+1, LWCON = 3*N, and let LWORQ = { MAX( N, 1 ), if JOBU = 'R', 'S', or 'U' { MAX( M, 1 ), if JOBU = 'A' LWSVD = MAX( 5*N, 1 ) LWLQF = MAX( N/2, 1 ), LWSVD2 = MAX( 5*(N/2), 1 ), LWORLQ = MAX( N, 1 ), LWQRF = MAX( N/2, 1 ), LWORQ2 = MAX( N, 1 ) Then the minimal value of LWORK is: = MAX( N + LWQP3, LWSVD ) if only the singular values are needed; = MAX( N + LWQP3, LWCON, LWSVD ) if only the singular values are needed, and a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWORQ ) if the singular values and the left singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD, LWORQ ) if the singular values and the left singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD ) if the singular values and the right singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD ) if the singular values and the right singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWORQ ) if the full SVD is requested with JOBV = 'R'; independent of JOBR; = N + MAX( LWQP3, LWCON, LWSVD, LWORQ ) if the full SVD is requested, JOBV = 'R' and, also a scaled condition estimate requested; independent of JOBR; = MAX( N + MAX( LWQP3, LWSVD, LWORQ ), N + MAX( LWQP3, N/2+LWLQF, N/2+LWSVD2, N/2+LWORLQ, LWORQ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWORQ ), N + MAX( LWQP3, LWCON, N/2+LWLQF, N/2+LWSVD2, N/2+LWORLQ, LWORQ ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N', and also a scaled condition number estimate requested. = MAX( N + MAX( LWQP3, LWSVD, LWORQ ), N + MAX( LWQP3, N/2+LWQRF, N/2+LWSVD2, N/2+LWORQ2, LWORQ ) ) if the full SVD is requested with JOBV = 'A', 'V', and JOBR ='T' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWORQ ), N + MAX( LWQP3, LWCON, N/2+LWQRF, N/2+LWSVD2, N/2+LWORQ2, LWORQ ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='T', and also a scaled condition number estimate requested.lworkmust be at least two:lwork = max(2,lwork). Iflwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thework,iwork, andrworkarrays, and no error message related tolworkis issued by XERBLA.outrworkArray of dimension (
max(1,lrwork)). On exit,If
joba='E',rwork[0]contains an estimate of the condition number of column scaledA. IfA = C * Dwhere D is diagonal and C has unit columns in the Euclidean norm, then, assuming full column rank,N^(-1/4) * rwork[0] <= ||pinv(C)||_2 <= N^(1/4) * rwork[0]. Otherwise,rwork[0] = -1.rwork[1]contains the number of singular values computed as exact zeros in DGESVD applied to the upper triangular or trapezoidal R (from the initial QR factorization). In case of early exit (no call to DGESVD, such as in the case of zero matrix)rwork[1] = -1. Ifliwork,lwork, orlrwork = -1, then on exit, ifinfo=0,rwork[0]returns the minimallrwork.
inlrworkThe dimension of the array
rwork. Ifjobp='P', thenlrwork >= max(2,m). Otherwise,lrwork >= 2. Iflrwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thework,iwork, andrworkarrays, and no error message related tolworkis issued by XERBLA.outinfoinfo=0: successful exit.info<0: ifinfo=-i, the i-th argument had an illegal value.info>0: if DBDSQR did not converge,infospecifies how many superdiagonals of an intermediate bidiagonal form B (computed in DGESVD) did not converge to zero.
void dgesvdq(
const char* joba,
const char* jobp,
const char* jobr,
const char* jobu,
const char* jobv,
const INT m,
const INT n,
f64* restrict A,
const INT lda,
f64* restrict S,
f64* restrict U,
const INT ldu,
f64* restrict V,
const INT ldv,
INT* numrank,
INT* restrict iwork,
const INT liwork,
f64* restrict work,
const INT lwork,
f64* restrict rwork,
const INT lrwork,
INT* info
);
Functions
-
void cgesvdq(const char *joba, const char *jobp, const char *jobr, const char *jobu, const char *jobv, const INT m, const INT n, c64 *restrict A, const INT lda, f32 *restrict S, c64 *restrict U, const INT ldu, c64 *restrict V, const INT ldv, INT *numrank, INT *restrict iwork, const INT liwork, c64 *restrict cwork, const INT lcwork, f32 *restrict rwork, const INT lrwork, INT *info)#
CGESVDQ computes the singular value decomposition (SVD) of a complex M-by-N matrix A, where M >= N.
The SVD of A is written as
A = U * SIGMA * V^*
where SIGMA is an N-by-N diagonal matrix, U is an M-by-N orthonormal matrix, and V is an N-by-N unitary matrix. CGESVDQ computes the singular value decomposition (SVD) of a complex
m-by-nmatrixA, wherem>=n. The SVD ofAis written aswhere SIGMA is an[++] [xx] [x0] [xx] A = U * SIGMA * V^*, [++] = [xx] * [ox] * [xx] [++] [xx]n-by-ndiagonal matrix, U is anm-by-northonormal matrix, and V is ann-by-nunitary matrix. The diagonal elements of SIGMA are the singular values ofA. The columns of U and V are the left and the right singular vectors ofA, respectively.- Further Details:
1. The data movement (matrix transpose) is coded using simple nested DO-loops because BLAS and LAPACK do not provide corresponding subroutines. Those DO-loops are easily identified in this source code - by the CONTINUE statements labeled with 11**. In an optimized version of this code, the nested DO loops should be replaced with calls to an optimized subroutine.
2. This code scales A by 1/SQRT(M) if the largest ABS(A(i,j)) could cause column norm overflow. This is the minimal precaution and it is left to the SVD routine (CGESVD) to do its own preemptive scaling if potential over- or underflows are detected. To avoid repeated scanning of the array A, an optimal implementation would do all necessary scaling before calling CGESVD and the scaling in CGESVD can be switched off.
3. Other comments related to code optimization are given in comments in the code, enclosed in [[double brackets]].
- Bugs, examples and comments:
Please report all bugs and send interesting examples and/or comments to drmac@math.hr. Thank you.
- References:
[1] Zlatko Drmac, Algorithm 977: A QR-Preconditioned QR SVD Method for Computing the SVD with High Accuracy. ACM Trans. Math. Softw. 44(1): 11:1-11:30 (2017)
SIGMA library, xGESVDQ section updated February 2016. Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
- Contributors:
Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
Parameters
injobaSpecifies the level of accuracy in the computed SVD.
joba='A': The requested accuracy corresponds to having the backward error bounded by|| delta A ||_F <= f(m,n)*EPS*|| A ||_F, whereEPS = clamch("Epsilon"). This authorises CGESVDQ to truncate the computed triangular factor in a rank revealing QR factorization whenever the truncated part is below the threshold of the order ofEPS * ||A||_F. This is aggressive truncation level.joba='M': Similarly as with'A', but the truncation is more gentle: it is allowed only when there is a drop on the diagonal of the triangular factor in the QR factorization. This is medium truncation level.joba='H': High accuracy requested. No numerical rank determination based on the rank revealing QR factorization is attempted.joba='E': Same as'H', and in addition the condition number of column scaledAis estimated and returned inrwork[0].N^(-1/4)*rwork[0] <= ||pinv(A_scaled)||_2 <= N^(1/4)*rwork[0].injobpjobp='P': The rows ofAare ordered in decreasing order with respect to||A(i,:)||_\infty. This enhances numerical accuracy at the cost of extra data movement. Recommended for numerical robustness.jobp='N': No row pivoting.injobrjobr='T': After the initial pivoted QR factorization, CGESVD is applied to the transposedR**Hof the computed triangular factor R. This involves some extra data movement (matrix transpositions). Useful for experiments, research and development.jobr='N': The triangular factor R is given as input to CGESVD. This may be preferred as it involves less data movement.injobujobu='A': Allmleft singular vectors are computed and returned in the matrixU. See the description ofU.jobu='S'orjobu='U':n = min(m,n)left singular vectors are computed and returned in the matrixU. See the description ofU.jobu='R': Numerical ranknumrankis determined and onlynumrankleft singular vectors are computed and returned in the matrixU.jobu='F': Thenleft singular vectors are returned in factored form as the product of the Q factor from the initial QR factorization and thenleft singular vectors of(R**H, 0)**H. If row pivoting is used, then the necessary information on the row pivoting is stored iniwork[n:n+m-2].jobu='N': The left singular vectors are not computed.injobvjobv='A'orjobv='V': Allnright singular vectors are computed and returned in the matrixV.jobv='R': Numerical ranknumrankis determined and onlynumrankright singular vectors are computed and returned in the matrixV. This option is allowed only ifjobu='R'orjobu='N'; otherwise it is illegal.jobv='N': The right singular vectors are not computed.inmThe number of rows of the input matrix
A.m>=0.innThe number of columns of the input matrix
A.m>=n>=0.inoutAArray of dimensions
ldaxn. On entry, the input matrixA. On exit, ifjobu!='N'orjobv!='N', the lower triangle ofAcontains the Householder vectors as stored by CGEQP3. Ifjobu='F', these Householder vectors together withcwork[0:n-1]can be used to restore the Q factors from the initial pivoted QR factorization ofA. See the description ofU.inldaThe leading dimension of the array
A.lda>=max(1,m).outSArray of dimension
n. The singular values ofA, ordered so thatS[i]>=S[i+1].outUArray of dimension
lduxmifjobu='A'; see the description ofldu. In this case, on exit,Ucontains themleft singular vectors.lduxnifjobu='S','U','R'; see the description ofldu. In this case,Ucontains the leadingnor the leadingnumrankleft singular vectors.lduxnifjobu='F'; see the description ofldu. In this caseUcontainsnxnunitary matrix that can be used to form the left singular vectors. Ifjobu='N',Uis not referenced.inlduThe leading dimension of the array
U. Ifjobu='A','S','U','R',ldu>=max(1,m). Ifjobu='F',ldu>=max(1,n). Otherwise,ldu>=1.outVArray of dimension
ldvxnifjobv='A','V','R'or ifjoba='E'. Ifjobv='A'or'V',Vcontains then-by-nunitary matrixV**H; Ifjobv='R',Vcontains the firstnumrankrows ofV**H(the right singular vectors, stored rowwise, of thenumranklargest singular values). Ifjobv='N'andjoba='E',Vis used as a workspace. Ifjobv='N'andjoba!='E',Vis not referenced.inldvThe leading dimension of the array
V. Ifjobv='A','V','R', orjoba='E',ldv>=max(1,n). Otherwise,ldv>=1.outnumranknumrankis the numerical rank first determined after the rank revealing QR factorization, following the strategy specified by the value ofjoba. Ifjobv='R'andjobu='R', onlynumrankleading singular values and vectors are then requested in the call of CGESVD. The final value ofnumrankmight be further reduced if some singular values are computed as zeros.outiworkInteger array of dimension (
max(1,liwork)). On exit,iwork[0:n-1]contains column pivoting permutation of the rank revealing QR factorization. Ifjobp='P',iwork[n:n+m-2]contains the indices of the sequence of row swaps used in row pivoting. These can be used to restore the left singular vectors in the casejobu='F'. Ifliwork,lcwork, orlrwork = -1, then on exit, ifinfo=0,iwork[0]returns the minimalliwork.inliworkThe dimension of the array
iwork.liwork >= n+m-1, ifjobp='P'andjoba!='E';liwork >= n, ifjobp='N'andjoba!='E';liwork >= n+m-1+n, ifjobp='P'andjoba='E';liwork >= n+n, ifjobp='N'andjoba='E'. Ifliwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thecwork,iwork, andrworkarrays, and no error message related tolcworkis issued by XERBLA.outcworkArray of dimension (
max(2,lcwork)), used as a workspace. On exit, if, on entry,lcwork!=-1,cwork[0:n-1]contains parameters needed to recover the Q factor from the QR factorization computed by CGEQP3. Ifliwork,lcwork, orlrwork = -1, then on exit, ifinfo=0,cwork[0]returns the optimallcwork, andcwork[1]returns the minimallcwork.inoutlcworkThe dimension of the array
cwork. It is determined as follows:Finally,Let LWQP3 = N+1, LWCON = 2*N, and let LWUNQ = { MAX( N, 1 ), if JOBU = 'R', 'S', or 'U' { MAX( M, 1 ), if JOBU = 'A' LWSVD = MAX( 3*N, 1 ) LWLQF = MAX( N/2, 1 ), LWSVD2 = MAX( 3*(N/2), 1 ), LWUNLQ = MAX( N, 1 ), LWQRF = MAX( N/2, 1 ), LWUNQ2 = MAX( N, 1 ) Then the minimal value of LCWORK is: = MAX( N + LWQP3, LWSVD ) if only the singular values are needed; = MAX( N + LWQP3, LWCON, LWSVD ) if only the singular values are needed, and a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWUNQ ) if the singular values and the left singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ) if the singular values and the left singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD ) if the singular values and the right singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD ) if the singular values and the right singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWUNQ ) if the full SVD is requested with JOBV = 'R'; independent of JOBR; = N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ) if the full SVD is requested, JOBV = 'R' and, also a scaled condition estimate requested; independent of JOBR; = MAX( N + MAX( LWQP3, LWSVD, LWUNQ ), N + MAX( LWQP3, N/2+LWLQF, N/2+LWSVD2, N/2+LWUNLQ, LWUNQ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ), N + MAX( LWQP3, LWCON, N/2+LWLQF, N/2+LWSVD2, N/2+LWUNLQ, LWUNQ ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N', and also a scaled condition number estimate requested. = MAX( N + MAX( LWQP3, LWSVD, LWUNQ ), N + MAX( LWQP3, N/2+LWQRF, N/2+LWSVD2, N/2+LWUNQ2, LWUNQ ) ) if the full SVD is requested with JOBV = 'A', 'V', and JOBR ='T' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ), N + MAX( LWQP3, LWCON, N/2+LWQRF, N/2+LWSVD2, N/2+LWUNQ2, LWUNQ ) ) if the full SVD is requested with JOBV = 'A', 'V' and JOBR ='T', and also a scaled condition number estimate requested.lcworkmust be at least two:lcwork = max(2,lcwork). Iflcwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thecwork,iwork, andrworkarrays, and no error message related tolcworkis issued by XERBLA.outrworkArray of dimension (
max(1,lrwork)). On exit,If
joba='E',rwork[0]contains an estimate of the condition number of column scaledA. IfA = C * Dwhere D is diagonal and C has unit columns in the Euclidean norm, then, assuming full column rank,N^(-1/4) * rwork[0] <= ||pinv(C)||_2 <= N^(1/4) * rwork[0]. Otherwise,rwork[0] = -1.rwork[1]contains the number of singular values computed as exact zeros in CGESVD applied to the upper triangular or trapezoidal R (from the initial QR factorization). In case of early exit (no call to CGESVD, such as in the case of zero matrix)rwork[1] = -1. Ifliwork,lcwork, orlrwork = -1, then on exit, ifinfo=0,rwork[0]returns the minimallrwork.
inlrworkThe dimension of the array
rwork. Ifjobp='P', thenlrwork >= max(2,m). Otherwise,lrwork >= 2. Iflrwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thecwork,iwork, andrworkarrays, and no error message related tolcworkis issued by XERBLA.outinfoinfo=0: successful exit.info<0: ifinfo=-i, the i-th argument had an illegal value.info>0: if CBDSQR did not converge,infospecifies how many superdiagonals of an intermediate bidiagonal form B (computed in CGESVD) did not converge to zero.
void cgesvdq(
const char* joba,
const char* jobp,
const char* jobr,
const char* jobu,
const char* jobv,
const INT m,
const INT n,
c64* restrict A,
const INT lda,
f32* restrict S,
c64* restrict U,
const INT ldu,
c64* restrict V,
const INT ldv,
INT* numrank,
INT* restrict iwork,
const INT liwork,
c64* restrict cwork,
const INT lcwork,
f32* restrict rwork,
const INT lrwork,
INT* info
);
Functions
-
void zgesvdq(const char *joba, const char *jobp, const char *jobr, const char *jobu, const char *jobv, const INT m, const INT n, c128 *restrict A, const INT lda, f64 *restrict S, c128 *restrict U, const INT ldu, c128 *restrict V, const INT ldv, INT *numrank, INT *restrict iwork, const INT liwork, c128 *restrict cwork, const INT lcwork, f64 *restrict rwork, const INT lrwork, INT *info)#
ZGESVDQ computes the singular value decomposition (SVD) of a complex M-by-N matrix A, where M >= N.
The SVD of A is written as
A = U * SIGMA * V^*
where SIGMA is an N-by-N diagonal matrix, U is an M-by-N orthonormal matrix, and V is an N-by-N unitary matrix. ZGESVDQ computes the singular value decomposition (SVD) of a complex
m-by-nmatrixA, wherem>=n. The SVD ofAis written aswhere SIGMA is an[++] [xx] [x0] [xx] A = U * SIGMA * V^*, [++] = [xx] * [ox] * [xx] [++] [xx]n-by-ndiagonal matrix, U is anm-by-northonormal matrix, and V is ann-by-nunitary matrix. The diagonal elements of SIGMA are the singular values ofA. The columns of U and V are the left and the right singular vectors ofA, respectively.- Further Details:
1. The data movement (matrix transpose) is coded using simple nested DO-loops because BLAS and LAPACK do not provide corresponding subroutines. Those DO-loops are easily identified in this source code - by the CONTINUE statements labeled with 11**. In an optimized version of this code, the nested DO loops should be replaced with calls to an optimized subroutine.
2. This code scales A by 1/SQRT(M) if the largest ABS(A(i,j)) could cause column norm overflow. This is the minimal precaution and it is left to the SVD routine (ZGESVD) to do its own preemptive scaling if potential over- or underflows are detected. To avoid repeated scanning of the array A, an optimal implementation would do all necessary scaling before calling ZGESVD and the scaling in ZGESVD can be switched off.
3. Other comments related to code optimization are given in comments in the code, enclosed in [[double brackets]].
- Bugs, examples and comments:
Please report all bugs and send interesting examples and/or comments to drmac@math.hr. Thank you.
- References:
[1] Zlatko Drmac, Algorithm 977: A QR-Preconditioned QR SVD Method for Computing the SVD with High Accuracy. ACM Trans. Math. Softw. 44(1): 11:1-11:30 (2017)
SIGMA library, xGESVDQ section updated February 2016. Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
- Contributors:
Developed and coded by Zlatko Drmac, Department of Mathematics University of Zagreb, Croatia, drmac@math.hr
Parameters
injobaSpecifies the level of accuracy in the computed SVD.
joba='A': The requested accuracy corresponds to having the backward error bounded by|| delta A ||_F <= f(m,n)*EPS*|| A ||_F, whereEPS = zlamch("Epsilon"). This authorises ZGESVDQ to truncate the computed triangular factor in a rank revealing QR factorization whenever the truncated part is below the threshold of the order ofEPS * ||A||_F. This is aggressive truncation level.joba='M': Similarly as with'A', but the truncation is more gentle: it is allowed only when there is a drop on the diagonal of the triangular factor in the QR factorization. This is medium truncation level.joba='H': High accuracy requested. No numerical rank determination based on the rank revealing QR factorization is attempted.joba='E': Same as'H', and in addition the condition number of column scaledAis estimated and returned inrwork[0].N^(-1/4)*rwork[0] <= ||pinv(A_scaled)||_2 <= N^(1/4)*rwork[0].injobpjobp='P': The rows ofAare ordered in decreasing order with respect to||A(i,:)||_\infty. This enhances numerical accuracy at the cost of extra data movement. Recommended for numerical robustness.jobp='N': No row pivoting.injobrjobr='T': After the initial pivoted QR factorization, ZGESVD is applied to the transposedR**Hof the computed triangular factor R. This involves some extra data movement (matrix transpositions). Useful for experiments, research and development.jobr='N': The triangular factor R is given as input to ZGESVD. This may be preferred as it involves less data movement.injobujobu='A': Allmleft singular vectors are computed and returned in the matrixU. See the description ofU.jobu='S'orjobu='U':n = min(m,n)left singular vectors are computed and returned in the matrixU. See the description ofU.jobu='R': Numerical ranknumrankis determined and onlynumrankleft singular vectors are computed and returned in the matrixU.jobu='F': Thenleft singular vectors are returned in factored form as the product of the Q factor from the initial QR factorization and thenleft singular vectors of(R**H, 0)**H. If row pivoting is used, then the necessary information on the row pivoting is stored iniwork[n:n+m-2].jobu='N': The left singular vectors are not computed.injobvjobv='A'orjobv='V': Allnright singular vectors are computed and returned in the matrixV.jobv='R': Numerical ranknumrankis determined and onlynumrankright singular vectors are computed and returned in the matrixV. This option is allowed only ifjobu='R'orjobu='N'; otherwise it is illegal.jobv='N': The right singular vectors are not computed.inmThe number of rows of the input matrix
A.m>=0.innThe number of columns of the input matrix
A.m>=n>=0.inoutAArray of dimensions
ldaxn. On entry, the input matrixA. On exit, ifjobu!='N'orjobv!='N', the lower triangle ofAcontains the Householder vectors as stored by ZGEQP3. Ifjobu='F', these Householder vectors together withcwork[0:n-1]can be used to restore the Q factors from the initial pivoted QR factorization ofA. See the description ofU.inldaThe leading dimension of the array
A.lda>=max(1,m).outSArray of dimension
n. The singular values ofA, ordered so thatS[i]>=S[i+1].outUArray of dimension
lduxmifjobu='A'; see the description ofldu. In this case, on exit,Ucontains themleft singular vectors.lduxnifjobu='S','U','R'; see the description ofldu. In this case,Ucontains the leadingnor the leadingnumrankleft singular vectors.lduxnifjobu='F'; see the description ofldu. In this caseUcontainsnxnunitary matrix that can be used to form the left singular vectors. Ifjobu='N',Uis not referenced.inlduThe leading dimension of the array
U. Ifjobu='A','S','U','R',ldu>=max(1,m). Ifjobu='F',ldu>=max(1,n). Otherwise,ldu>=1.outVArray of dimension
ldvxnifjobv='A','V','R'or ifjoba='E'. Ifjobv='A'or'V',Vcontains then-by-nunitary matrixV**H; Ifjobv='R',Vcontains the firstnumrankrows ofV**H(the right singular vectors, stored rowwise, of thenumranklargest singular values). Ifjobv='N'andjoba='E',Vis used as a workspace. Ifjobv='N'andjoba!='E',Vis not referenced.inldvThe leading dimension of the array
V. Ifjobv='A','V','R', orjoba='E',ldv>=max(1,n). Otherwise,ldv>=1.outnumranknumrankis the numerical rank first determined after the rank revealing QR factorization, following the strategy specified by the value ofjoba. Ifjobv='R'andjobu='R', onlynumrankleading singular values and vectors are then requested in the call of ZGESVD. The final value ofnumrankmight be further reduced if some singular values are computed as zeros.outiworkInteger array of dimension (
max(1,liwork)). On exit,iwork[0:n-1]contains column pivoting permutation of the rank revealing QR factorization. Ifjobp='P',iwork[n:n+m-2]contains the indices of the sequence of row swaps used in row pivoting. These can be used to restore the left singular vectors in the casejobu='F'. Ifliwork,lcwork, orlrwork = -1, then on exit, ifinfo=0,iwork[0]returns the minimalliwork.inliworkThe dimension of the array
iwork.liwork >= n+m-1, ifjobp='P'andjoba!='E';liwork >= n, ifjobp='N'andjoba!='E';liwork >= n+m-1+n, ifjobp='P'andjoba='E';liwork >= n+n, ifjobp='N'andjoba='E'. Ifliwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thecwork,iwork, andrworkarrays, and no error message related tolcworkis issued by XERBLA.outcworkArray of dimension (
max(2,lcwork)), used as a workspace. On exit, if, on entry,lcwork!=-1,cwork[0:n-1]contains parameters needed to recover the Q factor from the QR factorization computed by ZGEQP3. Ifliwork,lcwork, orlrwork = -1, then on exit, ifinfo=0,cwork[0]returns the optimallcwork, andcwork[1]returns the minimallcwork.inoutlcworkThe dimension of the array
cwork. It is determined as follows:Finally,Let LWQP3 = N+1, LWCON = 2*N, and let LWUNQ = { MAX( N, 1 ), if JOBU = 'R', 'S', or 'U' { MAX( M, 1 ), if JOBU = 'A' LWSVD = MAX( 3*N, 1 ) LWLQF = MAX( N/2, 1 ), LWSVD2 = MAX( 3*(N/2), 1 ), LWUNLQ = MAX( N, 1 ), LWQRF = MAX( N/2, 1 ), LWUNQ2 = MAX( N, 1 ) Then the minimal value of LCWORK is: = MAX( N + LWQP3, LWSVD ) if only the singular values are needed; = MAX( N + LWQP3, LWCON, LWSVD ) if only the singular values are needed, and a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWUNQ ) if the singular values and the left singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ) if the singular values and the left singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD ) if the singular values and the right singular vectors are requested; = N + MAX( LWQP3, LWCON, LWSVD ) if the singular values and the right singular vectors are requested, and also a scaled condition estimate requested; = N + MAX( LWQP3, LWSVD, LWUNQ ) if the full SVD is requested with JOBV = 'R'; independent of JOBR; = N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ) if the full SVD is requested, JOBV = 'R' and, also a scaled condition estimate requested; independent of JOBR; = MAX( N + MAX( LWQP3, LWSVD, LWUNQ ), N + MAX( LWQP3, N/2+LWLQF, N/2+LWSVD2, N/2+LWUNLQ, LWUNQ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ), N + MAX( LWQP3, LWCON, N/2+LWLQF, N/2+LWSVD2, N/2+LWUNLQ, LWUNQ ) ) if the full SVD is requested with JOBV = 'A' or 'V', and JOBR ='N', and also a scaled condition number estimate requested. = MAX( N + MAX( LWQP3, LWSVD, LWUNQ ), N + MAX( LWQP3, N/2+LWQRF, N/2+LWSVD2, N/2+LWUNQ2, LWUNQ ) ) if the full SVD is requested with JOBV = 'A', 'V', and JOBR ='T' = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ), N + MAX( LWQP3, LWCON, N/2+LWQRF, N/2+LWSVD2, N/2+LWUNQ2, LWUNQ ) ) if the full SVD is requested with JOBV = 'A', 'V' and JOBR ='T', and also a scaled condition number estimate requested.lcworkmust be at least two:lcwork = max(2,lcwork). Iflcwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thecwork,iwork, andrworkarrays, and no error message related tolcworkis issued by XERBLA.outrworkArray of dimension (
max(1,lrwork)). On exit,If
joba='E',rwork[0]contains an estimate of the condition number of column scaledA. IfA = C * Dwhere D is diagonal and C has unit columns in the Euclidean norm, then, assuming full column rank,N^(-1/4) * rwork[0] <= ||pinv(C)||_2 <= N^(1/4) * rwork[0]. Otherwise,rwork[0] = -1.rwork[1]contains the number of singular values computed as exact zeros in ZGESVD applied to the upper triangular or trapezoidal R (from the initial QR factorization). In case of early exit (no call to ZGESVD, such as in the case of zero matrix)rwork[1] = -1. Ifliwork,lcwork, orlrwork = -1, then on exit, ifinfo=0,rwork[0]returns the minimallrwork.
inlrworkThe dimension of the array
rwork. Ifjobp='P', thenlrwork >= max(2,m). Otherwise,lrwork >= 2. Iflrwork=-1, then a workspace query is assumed; the routine only calculates and returns the optimal and minimal sizes for thecwork,iwork, andrworkarrays, and no error message related tolcworkis issued by XERBLA.outinfoinfo=0: successful exit.info<0: ifinfo=-i, the i-th argument had an illegal value.info>0: if ZBDSQR did not converge,infospecifies how many superdiagonals of an intermediate bidiagonal form B (computed in ZGESVD) did not converge to zero.
void zgesvdq(
const char* joba,
const char* jobp,
const char* jobr,
const char* jobu,
const char* jobv,
const INT m,
const INT n,
c128* restrict A,
const INT lda,
f64* restrict S,
c128* restrict U,
const INT ldu,
c128* restrict V,
const INT ldv,
INT* numrank,
INT* restrict iwork,
const INT liwork,
c128* restrict cwork,
const INT lcwork,
f64* restrict rwork,
const INT lrwork,
INT* info
);