---
title: ?gelss
description: "使用SVD方法对线性最小二乘问题求解其最小范数解。"
url: https://www.hikunpeng.com/document/detail/zh/kunpengboostkithistory/240RC2/accel/kunpengaccel_kml_16_0704.html
sourcePath: /source/zh/kunpengboostkithistory/240RC2/accel/kunpengaccel_kml_16_0704.html
indexId: 2c270db335eae97108ddcffb471b17cf629ee9fc7a01628c596219993a58b2ba76
---
# ?gelss

使用SVD方法对线性最小二乘问题求解其最小范数解。

#### 接口定义

C Interface：

sgelss_(const int *m, const int *n, const int *nrhs, float *a, const int *lda, float *b, const int *ldb, float *s, const float *rcond, int *rank, float *work, const int *lwork, float *rwork, int *info);

dgelss_( const int *m, const int *n, const int *nrhs, double *a, const int *lda, double *b, const int *ldb, double *s, const double *rcond, int *rank, double *work, const int *lwork, double *rwork, int *info);

cgelss_(const int *m, const int *n, const int *nrhs, float _Complex *a, const int *lda, float _Complex *b, const int *ldb, float *s, const float *rcond, int *rank, float _Complex *work, const int *lwork, float *rwork, int *info);

zgelss_(const int *m, const int *n, const int *nrhs, double _Complex *a, const int *lda, double _Complex *b, const int *ldb, double *s, const double *rcond, int *rank, double _Complex *work, const int *lwork, double *rwork, int *info);

Fortran Interface：

SGELSS(M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, INFO)

DGELSS(M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, INFO)

CGELSS(M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, RWORK, INFO)

ZGELSS(M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, RWORK, INFO)


#### 参数

| 参数 | 类型 | 说明 | 输入/输出 |
| --- | --- | --- | --- |
| m | 整数型 | 矩阵A的行数，m≥0。 | 输入 |
| n | 整数型 | 矩阵A的列数，n≥0。 | 输入 |
| nrhs | 整数型 | 右端项列数，nrhs≥0。 | 输入 |
| a | 在sgelss中为单精度浮点型数组。 在dgelss中为双精度浮点型数组。 在cgelss中为单精度复数型数组。 在zgelss中为双精度复数型数组。 | 大小为lda\*n。 进入时：为m\*n的矩阵。 退出时，A的前min(m, n)行将被其右奇异向量覆盖，并按行存储。 | 输入，输出 |
| lda | 整数型 | 矩阵A的主维，lda≥max(1, m)。 | 输入 |
| b | 在sgelss中为单精度浮点型数组。 在dgelss中为双精度浮点型数组。 在cgelss中为单精度复数型数组。 在zgelss中为双精度复数型数组。 | 右端矩阵，大小为ldb\*nrhs。 进入时：m\*nrhs大小的右端项矩阵B。 退出时，B被N\*NRHS大小的解矩阵X覆盖。如果m≥n且RANK=n，则第i列中解的剩余平方和由该列中元素n+1:m的平方和给出。 | 输入，输出 |
| ldb | 整数型 | 矩阵b的主维。 | 输入 |
| s | 在sgelss中为单精度浮点型数组。 在dgelss中为双精度浮点型数组。 在cgelss中为单精度复数型数组。 在zgelss中为双精度复数型数组。 | A的奇异值按降序排列。 A的条件数二范数= S(1)/S(min(m,n))。 | 输出 |
| rcond | 在sgelss中为单精度浮点型数。 在dgelss中为双精度浮点型数。 在cgelss中为单精度浮点型数。 在zgelss中为双精度浮点型数。 | RCOND用于确定A的有效秩。 奇异值S(i)≤RCOND\*S(1)被视为零。如果RCOND<0，则使用机器精度。 | 输入 |
| rank | 整数型 | A的有效秩，即大于RCOND\*S(1)的奇异值的数量。 | 输出 |
| work | 在sgelss中为单精度浮点型数组。 在dgelss中为双精度浮点型数组。 在cgelss中为单精度复数型数组。 在zgelss中为双精度复数型数组。 | 退出时，如果INFO=0，则work(0)返回最佳lwork。 | 输出 |
| lwork | 整数型 | work的大小。 | 输入 |
| rwork（复数特有） | 在cgelss中为单精度浮点型数组。 在zgelss中为双精度浮点型数组。 | 大小至少为max(1, 5\*min(m, n))。 | 输出 |
| info | 整数型 | 等于0：表示成功。 小于0：info=\-i，表示第i个参数非法。 大于0：算法计算SVD时无法收敛，若info=i，则中间双对角线形式的i个对角线元素没有收敛到零。 | 输出 |


#### 依赖

#include "klapack.h"


#### 示例

C Interface：

```
const int m = 4;
const int n = 4;
const int nrhs = 2;
const int lda = 4;
const int ldb = 4;
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 b[] = {9.4532, 1.5204, 2.2127, 0.9891, 7.1778,
6.8955, 7.2465, 3.5019, 8.2268, 3.5287};
double *s = (double*)malloc(n * sizeof(double));
double rcond = -1.0;
int rank;
double qwork;
int lwork = -1;
int info = 0;
dgelss_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, &qwork, &lwork, &info);
if (info != 0) {
printf("Error, info = %d\n", info);
return info;
}
lwork = (int)qwork;
double *work = (double*)malloc(lwork * sizeof(double));
dgelss_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork, &info);
if (info != 0) {
printf("Error, info = %d\n", info);
return info;
}
/* output */
* a
* -0.552769       -0.578412       -0.312159       -0.512292
* -0.073442       0.602089        0.251939        -0.754070
* -0.827844       0.298713        0.251050        0.403012
* -0.061050       0.462277        -0.880941       0.080724
* b
* 0.153366        0.083995
* -0.538653       0.096517
* 1.080726        -0.174382
* -0.145340       0.022261
* rank
* 4
```

Fortran Interface：

```
CHARACTER :: tarns = "N"
PARAMETER (n = 4)
PARAMETER (m = 4)
PARAMETER (lda = 4)
PARAMETER (ldb = 4)
PARAMETER (nrhs = 2)
INTEGER :: info = 0
REAL(8) :: a(lda, n)
REAL(8) :: b(ldb, nrhs)
REAL(8) :: s(n)
REAL(8), ALLOCATABLE :: work(:)
REAL(8) :: rcond = -1.0
REAL(8) :: qwork(1)
INTEGER :: lwork = -1
INTEGER :: rank
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 /
DATA b / 9.4532, 1.5204, 2.2127, 0.9891, 7.1778,
&        6.8955, 7.2465, 3.5019, 8.2268, 3.5287 /
EXTERNAL DGELSS
CALL DGELSS(m, n, nrhs, a, lda, b, ldb, s, rcond, rank, qwork, lwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
lwork = INT(qwork(1))
ALLOCATE(work(lwork))
CALL DGELSS(m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
DEALLOCATE(work);
*
* Output:
* a
* -0.552769       -0.578412       -0.312159       -0.512292
* -0.073442       0.602089        0.251939        -0.754070
* -0.827844       0.298713        0.251050        0.403012
* -0.061050       0.462277        -0.880941       0.080724
* b
* 0.153366        0.083995
* -0.538653       0.096517
* 1.080726        -0.174382
* -0.145340       0.022261
* rank
* 4
```
