SRC/ztpmqrt.f(3)

πŸ’œ SRC/ztpmqrt.f πŸ’œ

okay so bestie, welcome to the ztpmqrt glow-up ✨ this is a page from the Library Functions Manual and it's giving very serious linear algebra main character energy. it's a Fortran subroutine page, so grab a snack πŸ“, we're doing this.


🌸 NAME 🌸

SRC/ztpmqrt.f β€” literally the file itself, that's the name, we love a self-titled icon πŸ‘‘


✨ SYNOPSIS ✨

Functions/Subroutines

  • subroutine ztpmqrt (side, trans, m, n, k, l, nb, v, ldv, t, ldt, a, lda, b, ldb, work, info) β€” the one, the only, ZTPMQRT πŸ’…

πŸ¦‹ Function/Subroutine Documentation πŸ¦‹

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

ZTPMQRT 🫢 that's the whole signature, no cap.


πŸŽ€ Purpose πŸŽ€

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

so basically: Q shows up, Q is derived from a complex block reflector H, and the job is to slap that Q onto a general complex matrix C β€” and C is split into two blocks, A and B. two blocks, one vibe check. slay πŸ’–


πŸ‘‘ Parameters πŸ‘‘

SIDE

!> SIDE is CHARACTER*1 !> = 'L': apply Q or Q**H from the Left; !> = 'R': apply Q or Q**H from the Right. !>

which side are we attacking from, bestie β€” 'L' for Left, 'R' for Right. pick a lane ✨

TRANS

!> TRANS is CHARACTER*1 !> = 'N': No transpose, apply Q; !> = 'C': Conjugate transpose, apply Q**H. !>

'N' = no transpose, you get plain Q. 'C' = conjugate transpose, you get Q**H. chose your fighter πŸ₯Š

M

!> M is INTEGER !> The number of rows of the matrix B. M >= 0. !>

the row count of B. M >= 0, keep it non-negative pls πŸ™

N

!> N is INTEGER !> The number of columns of the matrix B. N >= 0. !>

the column count of B. N >= 0, same energy πŸ’«

K

!> K is INTEGER !> The number of elementary reflectors whose product defines !> the matrix Q. !>

K = how many elementary reflectors you're multiplying together to build Q. it's the reflector headcount 🧚

L

!> L is INTEGER !> The order of the trapezoidal part of V. !> K >= L >= 0. See Further Details. !>

order of the trapezoidal part of V. constraint check: K >= L >= 0 ⭐ (peep Further Details below for the whole trapezoid lore)

NB

!> NB is INTEGER !> The block size used for the storage of T. K >= NB >= 1. !> This must be the same value of NB used to generate T !> in CTPQRT. !>

the block size used when storing T. K >= NB >= 1.

⚠️ and it must be the same NB value you used to generate T back in CTPQRT. mismatch and it's over, no cap 😭

V

!> V is COMPLEX*16 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. !>

COMPLEX*16 array, dimension (LDV,K). column i holds the vector defining elementary reflector H(i) for i = 1,2,...,k, exactly as CTPQRT handed it back in B. Further Details has the whole story πŸ“–

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). !>

leading dimension of V, and it depends on your side choice:

  • SIDE = 'L' β†’ LDV >= max(1,M)
  • SIDE = 'R' β†’ LDV >= max(1,N)

T

!> T is COMPLEX*16 array, dimension (LDT,K) !> The upper triangular factors of the block reflectors !> as returned by CTPQRT, stored as a NB-by-K matrix. !>

COMPLEX*16 array, dimension (LDT,K). these are the upper triangular factors of the block reflectors, as returned by CTPQRT, living as an NB-by-K matrix πŸ’

LDT

!> LDT is INTEGER !> The leading dimension of the array T. LDT >= NB. !>

leading dimension of T. LDT >= NB. that's it, that's the rule.

A

!> A is COMPLEX*16 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**H*C or C*Q or C*Q**H. See Further Details. !>

COMPLEX*16 array. dimension is (LDA,N) if SIDE = 'L', or (LDA,K) if SIDE = 'R'. on entry it's the K-by-N or M-by-K matrix A. on exit, A gets overwritten by the corresponding block of Q*C or Q**H*C or C*Q or C*Q**H πŸ”₯ (Further Details, bestie, go look)

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). !>

leading dimension of the array A:

  • SIDE = 'L' β†’ LDC >= max(1,K)
  • SIDE = 'R' β†’ LDC >= max(1,M)
πŸ’€ okay listen β€” yes, it literally says LDC here in the source even though we're talking about LDA. we are reporting, not editing. the original said it, we're saying it. take it up with the source, i don't make the rules πŸ™ˆ

B

!> B is COMPLEX*16 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**H*C or C*Q or C*Q**H. See Further Details. !>

COMPLEX*16 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**H*C or C*Q or C*Q**H. iconic behaviour honestly ✨

LDB

!> LDB is INTEGER !> The leading dimension of the array B. !> LDB >= max(1,M). !>

leading dimension of B. LDB >= max(1,M). simple, clean, slaying.

WORK

!> WORK is COMPLEX*16 array. The dimension of WORK is !> N*NB if SIDE = 'L', or M*NB if SIDE = 'R'. !>

COMPLEX*16 array, and the size depends on side:

  • N*NB if SIDE = 'L'
  • M*NB if SIDE = 'R'

INFO

!> INFO is INTEGER !> = 0: successful exit !> < 0: if INFO = -i, the i-th argument had an illegal value !>

the receipts πŸ“‹

  • = 0 β†’ successful exit, we ate πŸŽ‰
  • < 0 β†’ INFO = -i means the i-th argument had an illegal value, someone's getting cancelled (lovingly) 🫢

πŸ’– Author πŸ’–

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

the whole squad, we stan our institutions πŸ›οΈ


🌈 Further Details: 🌈

!> !> 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]. !> !> 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. !> !> If SIDE = 'L': C = [A] where A is K-by-N, B is M-by-N and V is M-by-K. !> [B] !> !> If SIDE = 'R': C = [A B] where A is M-by-K, B is M-by-N and V is N-by-K. !> !> The complex orthogonal matrix Q is formed from V and T. !> !> If TRANS='N' and SIDE='L', C is on exit replaced with Q * C. !> !> If TRANS='C' and SIDE='L', C is on exit replaced with Q**H * C. !> !> If TRANS='N' and SIDE='R', C is on exit replaced with C * Q. !> !> If TRANS='C' and SIDE='R', C is on exit replaced with C * Q**H. !>

so like, let's break it down because this is the good part πŸ“

the columns of the pentagonal matrix V hold the elementary reflectors H(1), H(2), ..., H(K). V is built from two blocks β€” a rectangular block V1 and a trapezoidal block V2:

V = [V1]
    [V2].

the size of the trapezoidal block V2 is decided by the parameter L, where 0 <= L <= K. V2 is upper trapezoidal, made of the first L rows of a K-by-K upper triangular matrix. if L=K, V2 is upper triangular; if L=0, there's no trapezoidal block at all, so V = V1 and it's rectangular. shape-shifting queen πŸ¦‹

if SIDE = 'L': C looks like this, where A is K-by-N, B is M-by-N and V is M-by-K:

C = [A]
    [B]

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

the complex orthogonal matrix Q is formed from V and T. πŸ’«

and the exit plot twists:

  • TRANS='N' and SIDE='L' β†’ C is on exit replaced with Q * C
  • TRANS='C' and SIDE='L' β†’ C is on exit replaced with Q**H * C
  • TRANS='N' and SIDE='R' β†’ C is on exit replaced with C * Q
  • TRANS='C' and SIDE='R' β†’ C is on exit replaced with C * Q**H

that's the whole chart, memorize it, it's on the test πŸŽ€


⭐ Definition at line 214 of file ztpmqrt.f ⭐

yep, that's where it lives. line 214 of ztpmqrt.f. mark it πŸ“


🧚 Author 🧚

Generated automatically by Doxygen for LAPACK from the source code. (not a human, a little documentation goblin did this one for us, and honestly? it ate πŸ€–βœ¨)


and that's the page, bestie!! πŸ«ΆπŸ’– this was LAPACK, Version 3.12.0, serving you SRC/ztpmqrt.f(3) realness from the manual. go forth and apply your Q in the correct direction, ily, bye πŸ‘‘πŸŒˆπŸ’…

πŸ“¦ where this page comes from