---
title: ?gesvd
description: "一般矩阵SVD分解。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengboostkithistory/240RC2/accel/kunpengaccel_kml_17_0081.html
sourcePath: /source/zh/kunpengboostkithistory/240RC2/accel/kunpengaccel_kml_17_0081.html
indexId: e99d6ae85b8cd7d6a3027870c64cca71e5a829639c4a8846d9ac03854cd37ab076
---
# ?gesvd

一般矩阵SVD分解。

#### 接口定义

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, float *rwork, 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, double *rwork, 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, RWORK, INFO);

DGESVD(JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, 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);


#### 参数

| 参数 | 类型 | 说明 | 输入/输出 |
| --- | --- | --- | --- |
| jobu | 字符型 | 'A'：返回酉矩阵U(左奇异值向量)的所有列。 'S'：返回酉矩阵U(左奇异值向量)的前min(m,n)列。 'O'：返回酉矩阵U(左奇异值向量)的前min(m,n)列，并复写到矩阵a。 'N'：酉矩阵U(左奇异值向量)不被计算。 | 输入 |
| jobvt | 字符型 | 'A'：返回V\*\*H(右奇异值向量)的所有列，保存在矩阵vt中。 'S'：返回V\*\*H(右奇异值向量)的前min(m,n)列，保存在矩阵vt中。 'O'：返回V\*\*H(右奇异值向量)的前min(m,n)列，并复写到矩阵a。 'N'：V\*\*H(右奇异值向量)不被计算。 | 输入 |
| m | 整数型 | 矩阵a的行数，m≥0。 | 输入 |
| n | 整数型 | 矩阵a的列数，n≥0。 | 输入 |
| a | 在sgesvd中为单精度浮点型数组 在dgesvd中为双精度浮点型数组 在cgesvd中为单精度复数型数组 在zgesvd中为双精度复数型数组 | 大小为lda\*n。 输入时：矩阵a为m\*n的矩阵。 输出时： jobu='O': 矩阵a被酉矩阵U（左奇异值向量）的前min(m,n)列覆盖。 jobvt='O': 矩阵a被V\*\*H（右奇异值向量, 按行优先存储）的前min(m,n)列覆盖。 jobu !='O' 且 jobvt != 'O': 矩阵a的内容被销毁。 | 输入，输出 |
| lda | 整数型 | 矩阵a的主维，lda≥max(1,m)。 | 输入 |
| s | 在sgesvd中为单精度浮点型数组 在dgesvd中为双精度浮点型数组 在cgesvd中为单精度浮点型数组 在zgesvd中为双精度浮点型数组 | 大小为min(m, n)。 输出为矩阵a的奇异值，且按s(i)>=s(i+1)的规则排序。 | 输出 |
| u | 在sgesvd中为单精度浮点型数组 在dgesvd中为双精度浮点型数组 在cgesvd中为单精度复数型数组 在zgesvd中为双精度复数型数组 | 大小为ldu\*ucol，其中当jobu='A'时，ucol=m; jobu='S'时，ucol=min(m,n)。 若jobu='A': 其为m\*m的酉矩阵u。 若jobu='S': 其包含了U矩阵(左奇异值向量，列优先存储)的前min(m,n)列。 若jobu='N' 或 'O': 其不被使用。 | 输出 |
| ldu | 整数型 | 矩阵u的主维，ldu>=1; 当jobu='S'或'A'时， ldu>=m。 | 输入 |
| vt | 在sgesvd中为单精度浮点型数组 在dgesvd中为双精度浮点型数组 在cgesvd中为单精度复数型数组 在zgesvd中为双精度复数型数组 | 大小为ldvt\*n。 若jobvt='A': 其为n\*n的酉矩阵v\*\*H。 若jobvt='S': 其包含矩阵v\*\*H(右奇异值向量, 按行优先存储)的前min(m,n)行。 若jobvt='N'或'O': 其不被使用。 | 输出 |
| ldvt | 整数型 | 矩阵vt的主维，ldvt>=1; 若jobvt='A', 则ldvt>=n; 若jobvt='S'，则ldvt>=min(m,n)。 | 输入 |
| work | 在sgesvd中为单精度浮点型数组 在dgesvd中为双精度浮点型数组 在cgesvd中为单精度复数型数组 在zgesvd中为双精度复数型数组 | 大小为max(1, lwork)。 退出时，若info=0, work(1)返回最优lwork大小。 | 输出 |
| lwork | 整数型 | work数组的大小，lwork>=max(1, 2\*min(m,n)+max(m,n)) 若lwork=\-1, 则表明函数只计算最优的work大小 | 输入 |
| rwork | 在sgesvd中为单精度浮点型数组 在dgesvd中为双精度浮点型数组 在cgesvd中为单精度浮点型数组 在zgesvd中为双精度浮点型数组 | 大小为5\*min(m,n) 退出时，若info>0, rwork(1:min(m,n)\-1)包含了上双对角矩阵B的未收敛超对角线元素，而其对角线元素保存在s中 | 输出 |
| info | 整数型 | 等于0：表示成功 小于0：info=\-i，表示第i个参数非法 大于0：若ZBDSQR不收敛，info则表示中间形式的矩阵B中有多少个超对角线不收敛到零 | 输出 |


#### 依赖

#include "klapack.h"


#### 示例

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
```
