---
title: ?bdsdc
description: "计算N*N的上/下双对角矩阵B的奇异值分解，使用分治算法。"
url: https://www.hikunpeng.com/document/detail/zh/hpchistory/hpckit/develop2400/kunpengaccel_kml_0712.html
sourcePath: /source/zh/hpchistory/hpckit/develop2400/kunpengaccel_kml_0712.html
indexId: a386441de1ac95f77511ebd94a171af72cadab765cfd16e2de4ff458dc11d67f67
---
# ?bdsdc

计算N*N的上/下双对角矩阵B的奇异值分解，使用分治算法。

#### 接口定义

C Interface：

void sbdsdc_(const char *uplo, const char *compq, const int *n, float *d, float *e, float *u, const int *ldu, float *vt, const int *ldvt, float *q, int *iq,

float *work, int *iwork, int *info);

void dbdsdc_(const char *uplo, const char *compq, const int *n, double *d, double *e, double *u, const int *ldu, double *vt, const int *ldvt, double *q,

int *iq, double *work, int *iwork, int *info);

Fortran Interface：

SBDSDC(UPLO, COMPQ, N, D, E, U, LDU, VT, Q, IQ, WORK, IWORK, INFO)

DBDSDC(UPLO, COMPQ, N, D, E, U, LDU, VT, Q, IQ, WORK, IWORK, INFO)


#### 参数

| 参数 | 类型 | 说明 | 输入/输出 |
| --- | --- | --- | --- |
| uplo | 字符型 | ='U'，B为上双对角矩阵 ='L'，B为下双对角矩阵 | 输入 |
| compq | 字符型 | ='N'，只计算奇异值； ='P'，计算奇异值，并且以紧凑的形式计算奇异向量 ='I'，计算奇异值和奇异向量 | 输入 |
| n | 整数型 | 矩阵B的阶数 | 输入 |
| d | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 输入时，存放B的对角元素。 输出时，存放B的奇异值。 | 输入，输出 |
| e | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 输入，存放B的非对角元素。 输出时，E被销毁。 | 输入，输出 |
| u | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 维度是LDU\*N。 如果COMPQ='I'，退出时，U包括左奇异向量。 如果COMPQ为其他值，U无意义。 | 输出 |
| ldu | 整数型 | U的前导维度，LDU>=1。 如果需要奇异向量，LDU>=max(1,N)。 | 输入 |
| vt | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 维度ldvt\*n。 如果COMPQ='I'，退出时，vt包括右奇异向量。 如果COMPQ为其他值，vt无意义。 | 输出 |
| ldvt | 整数型 | vt的前导维度，ldvt>=1。 如果需要奇异向量，ldvt>=max(1,N)。 | 输入 |
| q | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 如果COMPQ='P'，Q和IQ存放左右特征向量，以紧凑的形式，仅需要NlogN的空间而不是2N^2。 如果COMPQ为其它值，Q无意义。 | 输出 |
| iq | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 如果COMPQ='P'，Q和IQ存放左右特征向量，以紧凑的形式，仅需要NlogN的空间而不是2N^2。 如果COMPQ为其它值，IQ无意义。 | 输出 |
| work | sbdsdc中为单精度实数数组 dbdsdc中为双精度实数数组 | 维度：MAX(1,LWORK) 如果COMPQ ='N'，则LWORK>=(4\*N)。 如果COMPQ ='P'，则LWORK>=(6\*N)。 如果COMPQ ='I'，则LWORK>=(3\*N\*\*2+4\*N)。 | 输出 |
| lwork | 整型数组 | 大小为（8\*N）。 | 输出 |
| info | 整数型 | 等于0：表示成功。 小于0：info=\-i，表示第i个参数非法。 大于0：计算出错。 | 输出 |


#### 依赖

#include "klapack.h"


#### 示例

C Interface

```
const char uplo = 'l';
const char compq = 'i';
const int n = 5;
const int ldu = 5;
const int ldvt = 5;

double d[] = {-151.409804,-96.158378,30.604367,-49.958984,-65.000480};
double e[] = {187.838419,-61.829661,47.241856,4.133032};
double *u = (double*)malloc(ldu * n * sizeof(double));
double *vt = (double*)malloc(ldvt * n * sizeof(double));
double *q = (double*)malloc(sizeof(double));
int *iq = (int*)malloc(sizeof(int));
double *work = (double*)malloc(4 * n * sizeof(double));
double *iwork = (double*)malloc(8 * n * sizeof(double));

int info = 0;

dbdsdc_(&uplo, &compq, &n, d, e, u, &ldu, vt, &ldvt, q, iq, work, iwork, &info);
if (info != 0) {
    printf("Error, info = %d\n", info);
    return info;
}

* output:
* d:
* 254.071515      87.547400       67.835074       64.370735       14.897476
* e:
* 0.000000        0.000000        0.000000        0.000000
* u:
* 0.562230        -0.822915       -0.081874       -0.001979       0.000007        0.504441        0.270668        0.734742        0.363253        -0.021916       * -0.297298       -0.191539       -0.135822       0.802484       -0.460975       -0.148954       -0.098365       -0.044364       0.423397        0.887076        * -0.564680       -0.450761       0.658054        -0.211655       -0.010871
* vt:
* -0.943444       -0.291675       0.133196        0.063327        0.055560        0.331373        -0.816196       0.395311        0.189552        0.178367        * -0.010230       0.452864        0.497591        0.289640        0.680678        0.000389        -0.208325       -0.619098       -0.271648       0.706772        * -0.000002       0.016272        0.441712        -0.895754       0.047431
```

Fortran Interface

```
CHARACTER :: uplo = "L"
CHARACTER :: compq = "i"
PARAMETER (n = 5)
PARAMETER (ldu = 5)
PARAMETER (ldvt = 5)
INTEGER :: info = 0
REAL(8) :: d(n)
REAL(8) :: e(n-1)
REAL(8) :: u(ldu, n)
REAL(8) :: vt(ldvt, n)
REAL(8) :: iwork(8, m)
REAL(8), ALLOCATABLE :: q(:)
INTEGER, ALLOCATABLE :: iq(:)
REAL(8) :: work(4*n)
REAL(8) :: iwork(8*n)
DATA d / -151.409804,-96.158378,30.604367,-49.958984,-65.000480 /
DATA e / 187.838419,-61.829661,47.241856,4.133032 /
EXTERNAL DBDSDC
CALL DBDSDC(uplo, compq, n, d, e, u, ldu, vt, ldvt, q, iq, work, iwork, info);
* output:
* d:
* 254.071515      87.547400       67.835074       64.370735       14.897476
* e:
* 0.000000        0.000000        0.000000        0.000000
* u:
* 0.562230        -0.822915       -0.081874       -0.001979       0.000007        0.504441        0.270668        0.734742        0.363253        -0.021916       * -0.297298       -0.191539       -0.135822       0.802484       -0.460975       -0.148954       -0.098365       -0.044364       0.423397        0.887076        * -0.564680       -0.450761       0.658054        -0.211655       -0.010871
* vt:
* -0.943444       -0.291675       0.133196        0.063327        0.055560        0.331373        -0.816196       0.395311        0.189552        0.178367        * -0.010230       0.452864        0.497591        0.289640        0.680678        0.000389        -0.208325       -0.619098       -0.271648       0.706772        * -0.000002       0.016272        0.441712        -0.895754       0.047431
```
