---
title: ?(or,un)gtr
description: "通过反射因子生成正交矩阵Q，其中反射因子由SYTRD计算得来。"
url: https://www.hikunpeng.com/document/detail/zh/kunpenghpcs/hpckit/devg/kunpengaccel_kml_0784.html
sourcePath: /source/zh/kunpenghpcs/hpckit/devg/kunpengaccel_kml_0784.html
indexId: afae8abfd0689e315cda9da75c1eadb71d1f668a6fe94b7356ccc73b9aa1ab7361
---
# ?(or,un)gtr

通过反射因子生成正交矩阵Q，其中反射因子由SYTRD计算得来。

#### 接口定义

C Interface：

sorgtr_(const char *uplo, const int *n, float *a, const int *lda, const float *tau, float *work, const int *lwork, int *info);

dorgtr_(const char *uplo, const int *n, double *a, const int *lda, const double *tau, double *work, const int *lwork, int *info);

cungtr_(const char *uplo, const int *n, float _Complex *a, const int *lda, const float _Complex *tau, float _Complex *work, const int *lwork, int *info);

zungtr_(const char *uplo, const int *n, double _Complex *a, const int *lda, const double _Complex *tau, double _Complex *work, const int *lwork, int *info);

Fortran Interface：

SORGTR(UPLO, N, A, LDA, TAU, WORK, LWORK, INFO);

DORGTR(UPLO, N, A, LDA, TAU, WORK, LWORK, INFO);

CUNGTR(UPLO, N, A, LDA, TAU, WORK, LWORK, INFO);

ZUNGTR(UPLO, N, A, LDA, TAU, WORK, LWORK, INFO);


#### 参数

| 参数 | 类型 | 说明 | 输入/输出 |
| --- | --- | --- | --- |
| uplo | 字符型 | 'U'：存放A的上三角部分。 'L'：存放A的下三角部分。 | 输入 |
| n | 整数型 | 矩阵A的维度， n≥0。 | 输入 |
| a | 在sorgtr中为单精度浮点型数组。 在dorgtr中为双精度浮点型数组。 在cungtr中为单精度复数型数组。 在zungtr中为双精度复数型数组。 | 大小为lda\*n。 进入时：表示反射器。 退出时：n\*n的正交矩阵Q。 | 输入，输出 |
| lda | 整数型 | 矩阵A的主维，lda≥max(1, n)。 | 输入 |
| tau | 在sorgtr中为单精度浮点型数组。 在dorgtr中为双精度浮点型数组。 在cungtr中为单精度复数型数组。 在zungtr中为双精度复数型数组。 | 大小为n\-1。 该数组表示H的标量因子。 | 输入 |
| work | 在sorgtr中为单精度浮点型数组。 在dorgtr中为双精度浮点型数组。 在cungtr中为单精度复数型数组。 在zungtr中为双精度复数型数组。 | 工作数组，大小为max(1, lwork)。 info=0时，work(0)返回最优lwork大小。 | 输出 |
| lwork | 整数型 | work的大小。 若lwork≥n \- 1，为获取最优性能lwork≥(n\-1)\*nb，nb为最优分块大小。 若lwork=\-1，work返回最优大小。 | 输入 |
| Info | 整数型 | 等于0：表示成功。 小于0：info=\-i，表示第i个参数非法。 | 输出 |


#### 依赖

#include "klapack.h"


#### 示例

C Interface：

```
char uplo = 'L';
int n = 4;
int lda = n;
int info = 0;
double tau[4] = {1.003949, 1.125229, 1.978923, 0.000000};
double *work = NULL;
double qwork;
int lwork = -1;
double *d = (double*)malloc(n * sizeof(double));
double *e = (double*)malloc((n - 1) * sizeof(double));
/*
* tau:
*   1.003949  1.125229  1.978923  0.000000
* A (4x4, stored in column-major):
*   7.027  8.710  1.015  6.929
*   8.710  0.839  2.469  3.850
*   1.015  2.469  1.930  6.761
*   6.929  3.850  6.761  4.344
*
*/
double a[] = {7.027, 8.710, 1.015, 6.929,
8.710, 0.839, 2.469, 3.850,
1.015, 2.469, 1.930, 6.761,
6.929, 3.850, 6.761, 4.344};
/* Query optimal work size */
dsytrd_(&uplo, &n, a, &lda, d, e, tau, &qwork, &lwork, &info);
if (info != 0) {
printf("ERROR, info = %d\n", info);
return 1;
}
lwork = (int)qwork;
work = (double *)malloc(sizeof(double) * lwork);
/* Calculate Q */
dsytrd_(&uplo, &n, a, &lda, d, e, tau, work, &lwork, &info);
dorgtr_(&uplo, &n, a, &lda, tau, work, &lwork, &info);
/* output */
* a
* 1.000000        0.000000        0.000000        0.000000
* 0.000000        -0.779341       0.346782        -0.521890
* 0.000000        -0.090819       -0.886612       -0.453510
* 0.000000        -0.619983       -0.306042       0.722467
```

Fortran Interface：

```
CHARACTER :: uplo = "L"
PARAMETER (n = 4)
PARAMETER (lda = 4)
INTEGER :: info = 0
REAL(8) :: a(lda, n)
REAL(8) :: d(n)
REAL(8) :: e(n-1)
REAL(8) :: tau(n)
REAL(8), ALLOCATABLE :: work(:)
REAL(8) :: qwork(1)
INTEGER :: lwork = -1
DATA a / 7.027, 8.710, 1.015, 6.929,
&        8.710, 0.839, 2.469, 3.850,
&        1.015, 2.469, 1.930, 6.761,
&        6.929, 3.850, 6.761, 4.344 /
DATA tau / 1.003949, 1.125229, 1.978923, 0.000000 /
EXTERNAL DSYTRD,DORGTR
CALL DSYTRD(uplo, n, a, lda, d, e, tau, qwork, lwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
lwork = INT(qwork(1))
ALLOCATE(work(lwork))
CALL DSYTRD(uplo, n, a, lda, d, e, tau, qwork, lwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
CALL DORGTR(uplo, n, a, lda, tau, work, lwork, info)
DEALLOCATE(work);
*
* Output:
* a
*
1.000000        0.000000        0.000000        0.000000
* 0.000000        -0.779341       0.346782        -0.521890
* 0.000000        -0.090819       -0.886612       -0.453510
* 0.000000        -0.619983       -0.306042       0.722467
```
