/home/abui.../dtpmqrt.f(3)

πŸ“¦ version 3.12.0, in opensuse-leap 16.0

πŸ¦‹ DTPMQRT β€” the trap-and-triangular reflector glow-up (LAPACK, dtpmqrt.f)

okay so bestie, this is a page from the Library Functions Manual for /home/abui.../dtpmqrt.f, and honestly? It's giving main-character Fortran. Buckle up, we're reading a manpage together and it's gonna slay πŸ’…


✨ NAME ✨

/home/abuild/rpmbuild/BUILD/lapack-static-3.12.0-build/lapack-3.12.0/SRC/dtpmqrt.f

like, that's the whole name. it's a path. it's that girl who introduces herself with her full legal name πŸŽ€


✨ SYNOPSIS ✨

Functions/Subroutines

subroutine DTPMQRT (side, trans, m, n, k, l, nb, v, ldv, t, ldt, a, lda,
    b, ldb, work, info)

DTPMQRT β€” yes that's the whole description, she said "my name is enough" πŸ‘‘


✨ Function/Subroutine Documentation ✨

subroutine DTPMQRT (character side, character trans, integer m, integer n,
    integer k, integer l, integer nb, double precision, dimension( ldv, * )
    v, integer ldv, double precision, dimension( ldt, * ) t, integer ldt,
    double precision, dimension( lda, * ) a, integer lda, double precision,
    dimension( ldb, * ) b, integer ldb, double precision, dimension( * )
    work, integer info)

DTPMQRT 🫢

πŸ’– Purpose πŸ’–

!>
!> DTPMQRT applies a real orthogonal matrix Q obtained from a
!>  real block reflector H to a general
!> real matrix C, which consists of two blocks A and B.
!>

Translation for the girlies who don't dream in Fortran: it takes a real orthogonal matrix Q (built from a real block reflector H) and applies it to a general real matrix C, and C is literally split into two blocks, A and B. that's it. that's the vibe. no cap ✨


🌸 Parameters 🌸 (the whole roster, no skips)

  • SIDE β€” SIDE is CHARACTER*1, and it picks a side like it's picking a fight:
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • TRANS β€” TRANS is CHARACTER*1, the "are we transposing or not" switch:
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M β€” M is INTEGER. It's the number of rows of the matrix B. M >= 0, always, don't be weird about it.
  • N β€” N is INTEGER. The number of columns of the matrix B. N >= 0 too. we stay positive πŸ’–
  • K β€” K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. (yes, product. they're multiplying. iconic.)
  • L β€” L is INTEGER. The order of the trapezoidal part of V. K >= L >= 0. See Further Details, bestie, there's a whole section πŸ‘€
  • NB β€” NB is INTEGER. The block size used for the storage of T. K >= NB >= 1. lowkey important: This must be the same value of NB used to generate T in CTPQRT. mismatch it and you're on your own πŸ™ˆ
  • V β€” V is DOUBLE PRECISION array, dimension (LDV,K). The i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by CTPQRT in B. See Further Details.
  • LDV β€” LDV is INTEGER. The leading dimension of the array V.
    • If SIDE = 'L', LDV >= max(1,M);
    • if SIDE = 'R', LDV >= max(1,N).
  • T β€” T is DOUBLE PRECISION array, dimension (LDT,K). The upper triangular factors of the block reflectors as returned by CTPQRT, stored as a NB-by-K matrix. (stored as, exactly that.)
  • LDT β€” LDT is INTEGER. The leading dimension of the array T. LDT >= NB.
  • A β€” A is DOUBLE PRECISION array, dimension
(LDA,N) if SIDE = 'L' or
(LDA,K) if SIDE = 'R'

On entry, the K-by-N or M-by-K matrix A. On exit, A is overwritten by the corresponding block of Q*C or Q**T*C or C*Q or C*Q**T. See Further Details.

  • LDA β€” LDA is INTEGER. The leading dimension of the array A.
    • If SIDE = 'L', LDC >= max(1,K);
    • If SIDE = 'R', LDC >= max(1,M).
okay ngl, the original literally says LDC here even though this is LDA's description β€” I'm not fixing it, I'm just saying it out loud, that's the tea 🍡 (typo and all, we report faithfully πŸ’€)
  • B β€” B is DOUBLE PRECISION array, dimension (LDB,N). On entry, the M-by-N matrix B. On exit, B is overwritten by the corresponding block of Q*C or Q**T*C or C*Q or C*Q**T. See Further Details.
  • LDB β€” LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M).
  • WORK β€” WORK is DOUBLE PRECISION array. The dimension of WORK is N*NB if SIDE = 'L', or M*NB if SIDE = 'R'. size it right or perish 🫢
  • INFO β€” INFO is INTEGER, the little status report we all deserve:
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value

πŸ‘‘ Author πŸ‘‘

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

the whole collab. a group project that actually worked, we love to see it 🌈


🧚 Further Details: 🧚 (the part where V gets geometry)

!>
!>  The columns of the pentagonal matrix V contain the elementary reflectors
!>  H(1), H(2), ..., H(K); V is composed of a rectangular block V1 and a
!>  trapezoidal block V2:
!>
!>        V = [V1]
!>            [V2].
!>

so V is pentagonal (pentagonal!! she's shaped 😭) and it's stacked like:

V = [V1]
    [V2].
!>
!>  The size of the trapezoidal block V2 is determined by the parameter L,
!>  where 0 <= L <= K; V2 is upper trapezoidal, consisting of the first L
!>  rows of a K-by-K upper triangular matrix.  If L=K, V2 is upper triangular;
!>  if L=0, there is no trapezoidal block, hence V = V1 is rectangular.
!>

breaking it down, fr fr:

  • V2's size is decided by L, where 0 <= L <= K.
  • V2 is upper trapezoidal β€” literally the first L rows of a K-by-K upper triangular matrix.
  • If L=K, V2 is upper triangular.
  • if L=0, there is no trapezoidal block, hence V = V1 is rectangular. gone. reduced to atoms πŸ’€
!>
!>  If SIDE = 'L':  C = [A]  where A is K-by-N,  B is M-by-N and V is M-by-K.
!>                      [B]
!>

so with SIDE = 'L', the whole C is a stack:

C = [A]
    [B]

with A being K-by-N, B being M-by-N, and V being M-by-K. (the original draws that [B] floating underneath, and honestly? same energy πŸŽ€)

!>
!>  If SIDE = 'R':  C = [A B]  where A is M-by-K, B is M-by-N and V is N-by-K.
!>

and with SIDE = 'R', C is side-by-side instead: C = [A B], where A is M-by-K, B is M-by-N, and V is N-by-K.

!>
!>  The real orthogonal matrix Q is formed from V and T.
!>

Q comes from V and T. the duo. the collab we needed 🀝

and now the four endings, the multiverse of outcomes:

!>
!>  If TRANS='N' and SIDE='L', C is on exit replaced with Q * C.
!>
!>  If TRANS='T' and SIDE='L', C is on exit replaced with Q**T * C.
!>
!>  If TRANS='N' and SIDE='R', C is on exit replaced with C * Q.
!>
!>  If TRANS='T' and SIDE='R', C is on exit replaced with C * Q**T.
!>
  • TRANS='N' + SIDE='L' β†’ C becomes Q * C
  • TRANS='T' + SIDE='L' β†’ C becomes Q**T * C
  • TRANS='N' + SIDE='R' β†’ C becomes C * Q
  • TRANS='T' + SIDE='R' β†’ C becomes C * Q**T

every combination accounted for, no crumbs left, ate and left no evidence πŸ”₯

Definition at line 214 of file dtpmqrt.f. (line 214 specifically, in case you were wondering, and yes you can go look, she's right there πŸ¦‹)

🌟 Author (the meta one) 🌟

Generated automatically by Doxygen for LAPACK from the source code. (it wasn't even written by a human, it was birthed by a doc generator and still turned out iconic)


and that's the whole page, bestie πŸ’œ LAPACK, Version 3.12.0, dated at the top as /home/abui.../dtpmqrt.f(3) β€” go forth and apply your block reflectors correctly, mwah 🫢✨

πŸ“¦ where this page comes from