?gesdd
计算矩形矩阵的奇异值分解,可以用来计算左和右奇异向量,使用分治算法。
接口定义
C Interface:
void sgesdd_(const char *jobz, 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 *iwork, int *info);
void dgesdd_(const char *jobz, 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 *iwork, int *info);
void cgesdd_(const char *jobz, 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 *iwork, int *info);
void zgesdd_(const char *jobz, 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 *iwork, int *info);
Fortran Interface:
SGESDD(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
DGESDD(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, IWORK, INFO)
CGESDD(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, IWORK, INFO)
ZGESDD(JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, IWORK, INFO)
参数
参数 |
类型 |
说明 |
输入/输出 |
---|---|---|---|
jobz |
字符型 |
|
输入 |
m |
整数型 |
矩阵的维度,m≥0。 |
输入 |
n |
整数型 |
矩阵的维度,m≥0。 |
输入 |
a |
|
大小为M*N |
输入,输出 |
lda |
整数型 |
矩阵A的前导维度,lda>=max(1,M)。 |
输入 |
s |
|
|
输出 |
u |
|
|
输出 |
ldu |
整数型 |
|
输入 |
vt |
|
|
输出 |
ldvt |
整数型 |
|
输入 |
work |
|
|
输出 |
lwork |
整数型 |
矩阵work的维度,lwork>=1。如果lwork=1,默认为查询状态,在work第一个元素中返回合适的大小,并且不检查其它work的参数。
|
输入 |
iwork |
整数型数组 |
数组维度为8*min(M,N)。 |
输出 |
info |
整数型 |
|
输出 |
依赖
#include "klapack.h"
示例
C Interface:
const char jobz = '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 *iwork = (double*)malloc(8 * m * sizeof(double)); double qwork; int lwork = -1; int info = 0; dgesdd_(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, &qwork, &lwork, iwork, &info); if (info != 0) { printf("Error, info = %d\n", info); return info; } lwork = (int)qwork; double *work = (double*)malloc(lwork * sizeof(double)); dgesdd_(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, iwork, &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 :: jobz = "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) :: iwork(8, m) 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 DGESDD CALL DGESDD(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, qwork, lwork, iwork, info); lwork = (int)qwork; work = (double *)malloc(sizeof(double) * lwork); CALL DGESDD(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, iwork, 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