?(or,un)mbr
Compute Q*C, QT*C, C*Q, C*QT, P*C, PT*C, C*P, or C*PT, where Q and PT are orthogonal matrices computed by a call to GEBRD, that is, A=Q*B*PT.
Interface Definition
C interface:
sormbr_(const char *vect, const char *side, const char *trans, const int *m, const int *n, const int *k, const float *a, const int *lda, const float *tau, float *c, const int *ldc, float *work, const int *lwork, int *info);
dormbr_(const char *vect, const char *side, const char *trans, const int *m, const int *n, const int *k, const double *a, const int *lda, const double *tau, double *c, const int *ldc, double *work, const int *lwork, int *info);
cunmbr_(const char *vect, const char *side, const char *trans, const int *m, const int *n, const int *k, const float _Complex *a, const int *lda, const float _Complex *tau, float _Complex *c, const int *ldc, float _Complex *work, const int *lwork, int *info);
zunmbr_(const char *vect, const char *side, const char *trans, const int *m, const int *n, const int *k, const double _Complex *a, const int *lda, const double _Complex *tau, double _Complex *c, const int *ldc, double _Complex *work, const int *lwork, int *info);
Fortran interface:
SORMBR(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO);
DORMBR(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO);
CUNMBR(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO);
ZUNMBR(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO);
Parameters
Parameter |
Type |
Description |
Input/Output |
|---|---|---|---|
vect |
Character |
|
Input |
side |
Character |
|
Input |
trans |
Character |
|
Input |
m |
Integer |
Number of rows in matrix C. m ≥ 0. |
Input |
n |
Integer |
Number of columns in matrix C, n ≥ 0. |
Input |
k |
Integer |
Number of columns in Q or number of rows in P, k ≥ 0. |
Input |
a |
|
This array represents reflectors H and G, and Q and P can be calculated by multiplying the two reflectors. |
Input |
lda |
Integer |
Leading dimension of matrix A.
|
Input |
tau |
|
Array with a size of min(nq, k). This array represents the scalar factors of H and G. |
Input |
c |
|
Array with a size of ldc*n.
|
Input/Output |
ldc |
Integer |
Leading dimension of matrix C. ldc≥max(1, m). |
Input |
work |
|
Work array, with a size of max(1, lwork). If info=0, work(0) returns the optimal lwork size. |
Output |
lwork |
Integer |
Size of work.
|
Input |
Info |
Integer |
|
Output |
Dependency
#include "klapack.h"
Examples
C interface:
const char vect = 'Q';
const char side = 'L';
const char trans = 'N';
const int n = 4;
const int m = 4;
const int k = 4;
const int lda = n;
const int ldc = m;
int info = 0;
double *work = NULL;
double qwork;
int lwork = -1;
double *d = (double*)malloc(n * sizeof(double));
double *e = (double*)malloc((n - 1) * sizeof(double));
double *tauq = (double*)malloc(n * sizeof(double));
double *taup = (double*)malloc(n * sizeof(double));
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};
double c[] = {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 */
dgebrd_(&m, &n, a, &lda, d, e, tauq, taup, &qwork, &lwork, &info);
if (info != 0) {
printf("ERROR, info = %d\n", info);
return info;
}
lwork = (int)qwork;
work = (double *)malloc(sizeof(double) * lwork);
/* Calculate Q */
dgebrd_(&m, &n, a, &lda, d, e, tauq, taup, work, &lwork, &info);
if (info != 0) {
printf("ERROR, info = %d\n", info);
return info;
}
dormbr_(&vect, &side, &trans, &m, &n, &k, a, &lda, tauq, c, &ldc, work, &lwork, &info);
if (info != 0) {
printf("ERROR, info = %d\n", info);
return info;
}
/* output */
* a
* -13.201670 13.064517 0.286648 0.441152
* 0.430577 -8.159976 2.308820 -0.069390
* 0.050176 -0.414492 5.045717 -1.018082
* 0.342534 -0.018475 0.799162 -3.517170
Fortran interface:
CHARACTER :: vect = "Q"
CHARACTER :: side = "L"
CHARACTER :: tarns = "N"
PARAMETER (n = 4)
PARAMETER (m = 4)
PARAMETER (lda = 4)
PARAMETER (ldc = 4)
PARAMETER (k = 4)
INTEGER :: info = 0
REAL(8) :: a(lda, n)
REAL(8) :: c(ldc, n)
REAL(8) :: d(n)
REAL(8) :: e(n-1)
REAL(8) :: tauq(n)
REAL(8) :: taup(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 c / 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 /
EXTERNAL DGEBRD,DORMBR
CALL DGEBRD(m, n, a, lda, d, e, tauq, taup, qwork, lwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
lwork = INT(qwork(1))
ALLOCATE(work(lwork))
CALL DGEBRD(m, n, a, lda, d, e, tauq, taup, qwork, lwork, info)
IF (info.NE.0) THEN
CALL EXIT(1)
END IF
CALL DORMBR(vect, side, trans, m, n, k, a, lda, tauq, c, ldc, work, lwork, info)
DEALLOCATE(work);
*
* Output:
* a
* -13.201670 13.064517 0.286648 0.441152
* 0.430577 -8.159976 2.308820 -0.069390
* 0.050176 -0.414492 5.045717 -1.018082
* 0.342534 -0.018475 0.799162 -3.517170