Rate This Document
Findability
Accuracy
Completeness
Readability

?(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

  • 'Q': Q is used for computation.
  • 'P': P is used for computation.

Input

side

Character

  • 'L': Q and P are applied to C from the left.
  • 'R': Q and P are applied to C from the right.

Input

trans

Character

  • 'N': Q and P are not transposed.
  • 'T': Q and P are transposed.

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

  • A single-precision floating-point array for sormbr
  • A double-precision floating-point array for dormbr
  • A single-precision complex array for cunmbr
  • A double-precision complex array for zunmbr
  • If vect='Q', the size is lda*min(nq, k).
  • If vect='P', the size is lda*nq.

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.

  • If vect='Q', lda≥max(1, nq).
  • If vect='P', lda≥(1, min(nq, k)).

Input

tau

  • A single-precision floating-point array for sormbr
  • A double-precision floating-point array for dormbr
  • A single-precision complex array for cunmbr
  • A double-precision complex array for zunmbr

Array with a size of min(nq, k).

This array represents the scalar factors of H and G.

Input

c

  • A single-precision floating-point array for sormbr
  • A double-precision floating-point array for dormbr
  • A single-precision complex array for cunmbr
  • A double-precision complex array for zunmbr

Array with a size of ldc*n.

  • On entry: an m*n matrix.
  • On exit: Q*C, QH*C, C*QH, C*Q, P*C, PH*C, C*P, or C*PH.

Input/Output

ldc

Integer

Leading dimension of matrix C. ldc≥max(1, m).

Input

work

  • A single-precision floating-point array for sormbr
  • A double-precision floating-point array for dormbr
  • A single-precision complex array for cunmbr
  • A double-precision complex array for zunmbr

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.

  • If side='L', lwork≥max(1, n).
  • If side='R', lwork≥max(1, m).
  • If lwork=-1, the optimal size is returned.

Input

Info

Integer

  • 0: The execution is successful.
  • Smaller than 0: If info = -i, the i-th parameter has an illegal value.

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