doubleOTHERcomputational(3)

📦
version 3.11.0 · 2 versions
, in debian bookworm

💖 doubleOTHERcomputational(3) 💖

LAPACK manual, bestie. This is part 1 of 58, so we're just getting started. No cap.


✨ NAME ✨

doubleOTHERcomputational — double 🦋

That's the whole vibe for this section: it's literally double. More parts are on the way, so stay tuned. 💅

✨ SYNOPSIS ✨

🫶 Functions 🫶

okay so here's the tea bestie: this is the full function roster and I am not skipping a single one of them. every signature is here, verbatim, in its little code block, with me hyping it up underneath. no cuts, no "and so on", no "etc." — we're doing all of it. 💅


  • ctplqt — CTPLQT
subroutine ctplqt (M, N, L, MB, A, LDA, B, LDB, T, LDT, WORK, INFO)

that's the whole entry, bestie. no description, no notes, just a signature and a name. iconic behaviour honestly. ✨

  • ctplqt2 — CTPLQT2
subroutine ctplqt2 (M, N, L, A, LDA, B, LDB, T, LDT, INFO)

again, just the signature. the 2 at the end is doing all the heavy lifting. 🎀

  • ctpmlqt — CTPMLQT
subroutine ctpmlqt (SIDE, TRANS, M, N, K, L, MB, V, LDV, T, LDT, A, LDA, B, LDB, WORK, INFO)

look at that arg list. SIDE, TRANS, MB, LDV, LDT — she's highkey the busiest of the CTP trio and I respect it. 👑

  • dbbcsd — DBBCSD
subroutine dbbcsd (JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q, THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E, B22D, B22E, WORK, LWORK, INFO)

the way this one just keeps going — THETA, PHI, and then B11D, B11E, B12D, B12E, B21D, B21E, B22D, B22E. a whole grid of B's. the naming scheme ate, fr fr. 🌈

  • dgetsqrhrt — DGETSQRHRT
subroutine dgetsqrhrt (M, N, MB1, NB1, NB2, A, LDA, T, LDT, WORK, LWORK, INFO)

say DGETSQRHRT five times fast, I dare you, you can't. 🦋

  • dgghd3 — DGGHD3
subroutine dgghd3 (COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, WORK, LWORK, INFO)

COMPQ, COMPZ, ILO, IHI — the whole squad is here and they're all sitting down. 😌

  • dgghrd — DGGHRD
subroutine dgghrd (COMPQ, COMPZ, N, ILO, IHI, A, LDA, B, LDB, Q, LDQ, Z, LDZ, INFO)

same energy as the one above, just without the trailing WORK, LWORK. the no-work era of DGGHRD. 💖

  • dggqrf — DGGQRF
subroutine dggqrf (N, M, P, A, LDA, TAUA, B, LDB, TAUB, WORK, LWORK, INFO)

note that it's N, M, P in that exact order — write that down, don't trust your memory. 📝

  • dggrqf — DGGRQF
subroutine dggrqf (M, P, N, A, LDA, TAUA, B, LDB, TAUB, WORK, LWORK, INFO)

and THIS one is M, P, N. yes they're genuinely different. yes it's a lot. yes I'm fine. 💀

  • dggsvp3 — DGGSVP3
subroutine dggsvp3 (JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB, TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ, IWORK, TAU, WORK, LWORK, INFO)

TOLA, TOLB, IWORK, TAU — she brought everything to the function. thorough queen behaviour. 🎀

  • dgsvj0 — DGSVJ0
subroutine dgsvj0 (JOBV, M, N, A, LDA, D, SVA, MV, V, LDV, EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO)

DGSVJ0 is the pre-processor for the routine dgesvj. opening act that absolutely ate, no skips. 🫶

  • dgsvj1 — DGSVJ1
subroutine dgsvj1 (JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV, EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO)

DGSVJ1 is also a pre-processor for the routine dgesvj — except it applies Jacobi rotations targeting only particular pivots. selective? we love that for her. ✨

  • dhsein — DHSEIN
subroutine dhsein (SIDE, EIGSRC, INITV, SELECT, N, H, LDH, WR, WI, VL, LDVL, VR, LDVR, MM, M, WORK, IFAILL, IFAILR, INFO)

WR, WI, VL, VR, IFAILL, IFAILR — left AND right, she said why not both. 👑🌈

  • dhseqr — DHSEQR
subroutine dhseqr (JOB, COMPZ, N, ILO, IHI, H, LDH, WR, WI, Z, LDZ, WORK, LWORK, INFO)

JOB, COMPZ, ILO, IHI — the classic lineup. no notes. 💅

  • dla_lin_berr — DLA_LIN_BERR
subroutine dla_lin_berr (N, NZ, NRHS, RES, AYB, BERR)

DLA_LIN_BERR computes a component-wise relative backward error. tiny arg list, huge responsibility. 🍓

  • dla_wwaddw — DLA_WWADDW
subroutine dla_wwaddw (N, X, Y, W)

DLA_WWADDW adds a vector into a doubled-single vector. four args, zero drama. that's the dream honestly. 🧚

  • dlals0 — DLALS0
subroutine dlals0 (ICOMPQ, NL, NR, SQRE, NRHS, B, LDB, BX, LDBX, PERM, GIVPTR, GIVCOL, LDGCOL, GIVNUM, LDGNUM, POLES, DIFL, DIFR, Z, K, C, S, WORK, INFO)

DLALS0 applies back multiplying factors in solving the least squares problem using the divide and conquer SVD approach. It's used by sgelsd. and yes, there really are that many arguments. count them. I'll wait. 😭

  • dlalsa — DLALSA
subroutine dlalsa (ICOMPQ, SMLSIZ, N, NRHS, B, LDB, BX, LDBX, U, LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK, IWORK, INFO)

DLALSA computes the SVD of the coefficient matrix in compact form, and it's used by sgelsd. GIVPTR, GIVCOL, GIVNUM — the givens family reunion. 🎀

  • dlalsd — DLALSD
subroutine dlalsd (UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND, RANK, WORK, IWORK, INFO)

DLALSD uses the singular value decomposition of A to solve the least squares problem. D and E and RCOND and RANK — the whole least-squares storyline in one call. 🔥

  • dlansf — DLANSF (a double precision function, not a subroutine — respect the difference bestie)
double precision function dlansf (NORM, TRANSR, UPLO, N, A, WORK)

DLANSF returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a symmetric matrix in RFP format. four norms, one function. she contains multitudes. ✨

  • dlarscl2 — DLARSCL2
subroutine dlarscl2 (M, N, D, X, LDX)

DLARSCL2 performs reciprocal diagonal scaling on a matrix. reciprocal, meaning the flip side. don't mix it up with her sister below. 🦋

  • dlarz — DLARZ
subroutine dlarz (SIDE, M, N, L, V, INCV, TAU, C, LDC, WORK)

DLARZ applies an elementary reflector (as returned by stzrzf) to a general matrix. note the INCV in there, she's fancy like that. 💅

  • dlarzb — DLARZB
subroutine dlarzb (SIDE, TRANS, DIRECT, STOREV, M, N, K, L, V, LDV, T, LDT, C, LDC, WORK, LDWORK)

DLARZB applies a block reflector or its transpose to a general matrix. the b stands for block, and also for baddie. 🌈

  • dlarzt — DLARZT
subroutine dlarzt (DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT)

DLARZT forms the triangular factor T of a block reflector H = I - vtvH. yes that's the formula, exactly as written, don't come for me. 💜

  • dlascl2 — DLASCL2
subroutine dlascl2 (M, N, D, X, LDX)

DLASCL2 performs diagonal scaling on a matrix. regular scaling, not reciprocal. the distinction matters, bestie. 🎀

  • dlatrz — DLATRZ
subroutine dlatrz (M, N, L, A, LDA, TAU, WORK)

DLATRZ factors an upper trapezoidal matrix by means of orthogonal transformations. upper trapezoidal — she's shaped like a little bucket and she knows it. 🍓

  • dopgtr — DOPGTR
subroutine dopgtr (UPLO, N, AP, TAU, Q, LDQ, WORK, INFO)

just the signature, no description. silent but powerful. 😌

  • dopmtr — DOPMTR
subroutine dopmtr (SIDE, UPLO, TRANS, M, N, AP, TAU, C, LDC, WORK, INFO)

same deal — name and args only. the strong silent type. 🔥

  • dorbdb — DORBDB
subroutine dorbdb (TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, X21, LDX21, X22, LDX22, THETA, PHI, TAUP1, TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO)

X11, X12, X21, X22 — she's a whole four-quadrant situation. and THETA and PHI are here too of course. 👑

  • dorbdb1 — DORBDB1
subroutine dorbdb1 (M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)

the 1 variant, half the quadrants, all the attitude. ✨

  • dorbdb2 — DORBDB2
subroutine dorbdb2 (M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)

identical signature to DORBDB1, different name. don't ask, just vibe. 💅

  • dorbdb3 — DORBDB3
subroutine dorbdb3 (M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, WORK, LWORK, INFO)

yep, same signature again. the DORBDB girls are matching, it's a coordinated outfit. 🎀

  • dorbdb4 — DORBDB4
subroutine dorbdb4 (M, P, Q, X11, LDX11, X21, LDX21, THETA, PHI, TAUP1, TAUP2, TAUQ1, PHANTOM, WORK, LWORK, INFO)

WAIT. there's an extra argument called PHANTOM. phantom. like a ghost. in a linear algebra routine. I'm obsessed and I need everyone to know. 👻💜

  • dorbdb5 — DORBDB5
subroutine dorbdb5 (M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, LDQ2, WORK, LWORK, INFO)

different shape entirely — M1, M2, INCX1, INCX2, LDQ1, LDQ2. she's the cousin who moved away. 🦋

  • dorbdb6 — DORBDB6
subroutine dorbdb6 (M1, M2, N, X1, INCX1, X2, INCX2, Q1, LDQ1, Q2, LDQ2, WORK, LWORK, INFO)

same signature as DORBDB5. matching sets, we love to see it. ✨

  • dorcsd — DORCSD
recursive subroutine dorcsd (JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, X21, LDX21, X22, LDX22, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, V2T, LDV2T, WORK, LWORK, IWORK, INFO)

it's a recursive subroutine — she calls herself. self-love, literally. and yes, that arg list is as long as it looks. 😭

  • dorcsd2by1 — DORCSD2BY1
subroutine dorcsd2by1 (JOBU1, JOBU2, JOBV1T, M, P, Q, X11, LDX11, X21, LDX21, THETA, U1, LDU1, U2, LDU2, V1T, LDV1T, WORK, LWORK, IWORK, INFO)

the "2 by 1" version. compact, focused, still brings IWORK to the party. 💅

  • dorg2l — DORG2L
subroutine dorg2l (M, N, K, A, LDA, TAU, WORK, INFO)

DORG2L generates all or part of the orthogonal matrix Q from a QL factorization determined by sgeqlf (unblocked algorithm). note: QL, and note: unblocked. two very important details. 🎀

  • dorg2r — DORG2R
subroutine dorg2r (M, N, K, A, LDA, TAU, WORK, INFO)

DORG2R generates all or part of the orthogonal matrix Q from a QR factorization determined by sgeqrf (unblocked algorithm). QR this time, not QL. don't get it twisted. 🔥

  • dorghr — DORGHR
subroutine dorghr (N, ILO, IHI, A, LDA, TAU, WORK, LWORK, INFO)

signature only. ILO and IHI are back, they never really left. 😌

  • dorgl2 — DORGL2
subroutine dorgl2 (M, N, K, A, LDA, TAU, WORK, INFO)

name and args, nothing else. the minimalist. 🧚

  • dorglq — DORGLQ
subroutine dorglq (M, N, K, A, LDA, TAU, WORK, LWORK, INFO)

the LQ sibling with a LWORK glow-up. ✨

  • dorgql — DORGQL
subroutine dorgql (M, N, K, A, LDA, TAU, WORK, LWORK, INFO)

QL this time. the letters matter bestie, always check the letters. 💅

  • dorgqr — DORGQR
subroutine dorgqr (M, N, K, A, LDA, TAU, WORK, LWORK, INFO)

QR. the one everyone's heard of. she's famous, she's fine, she's booked. 👑

  • dorgr2 — DORGR2
subroutine dorgr2 (M, N, K, A, LDA, TAU, WORK, INFO)

DORGR2 generates all or part of the orthogonal matrix Q from an RQ factorization determined by sgerqf (unblocked algorithm). RQ, reversed Q R, yes that's real, yes I checked. 🎀

  • dorgrq — DORGRQ
subroutine dorgrq (M, N, K, A, LDA, TAU, WORK, LWORK, INFO)

the blocked RQ girl. she brought LWORK. 🦋

  • dorgtr — DORGTR
subroutine dorgtr (UPLO, N, A, LDA, TAU, WORK, LWORK, INFO)

UPLO and N and TAU — short, punchy, gets the job done. 💜

  • dorgtsqr — DORGTSQR
subroutine dorgtsqr (M, N, MB, NB, A, LDA, T, LDT, WORK, LWORK, INFO)

MB AND NB. two block sizes. she's thorough like that. 🔥

  • dorgtsqr_row — DORGTSQR_ROW
subroutine dorgtsqr_row (M, N, MB, NB, A, LDA, T, LDT, WORK, LWORK, INFO)

the _row variant — same signature as DORGTSQR, different name. the underscore is doing a LOT of work here. 😭

  • dorhr_col — DORHR_COL
subroutine dorhr_col (M, N, NB, A, LDA, T, LDT, D, INFO)

_col this time, and there's a lone D hanging out at the end. mysterious. I respect it. ✨

  • dorm2l — DORM2L
subroutine dorm2l (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, INFO)

DORM2L multiplies a general matrix by the orthogonal matrix from a QL factorization determined by sgeqlf (unblocked algorithm). it's a multiply, not a generate. whole different verb. 🎀

  • dorm2r — DORM2R
subroutine dorm2r (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, INFO)

DORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sgeqrf (unblocked algorithm). QR, unblocked, C instead of A for the target. noted. 🔥

  • dormbr — DORMBR
subroutine dormbr (VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

she's got a VECT argument, which is lowkey a flex. 💅

  • dormhr — DORMHR
subroutine dormhr (SIDE, TRANS, M, N, ILO, IHI, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

ILO and IHI made it into this one too. they're everywhere, they're booked and busy. 😌

  • dorml2 — DORML2
subroutine dorml2 (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, INFO)

DORML2 multiplies a general matrix by the orthogonal matrix from a LQ factorization determined by sgelqf (unblocked algorithm). LQ! say it with me. L. Q. 🦋

  • dormlq — DORMLQ
subroutine dormlq (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

the blocked LQ girl, LWORK included, no notes. ✨

  • dormql — DORMQL
subroutine dormql (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

QL. she and DORMLQ are mirror images and honestly that's the plot twist. 💜

  • dormqr — DORMQR
subroutine dormqr (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

the most popular girl in school. everyone's called her at least once. 👑

  • dormr2 — DORMR2
subroutine dormr2 (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, INFO)

DORMR2 multiplies a general matrix by the orthogonal matrix from a RQ factorization determined by sgerqf (unblocked algorithm). RQ again, unblocked again, iconic again. 🎀

  • dormr3 — DORMR3
subroutine dormr3 (SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC, WORK, INFO)

DORMR3 multiplies a general matrix by the orthogonal matrix from a RZ factorization determined by stzrzf (unblocked algorithm). RZ! not RQ, not QR. RZ. and there's an extra L in the args too. she's built different. 🔥

  • dormrq — DORMRQ
subroutine dormrq (SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

RQ, blocked, LWORK, done. 💅

  • dormrz — DORMRZ
subroutine dormrz (SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

the RZ queen, blocked version, extra L included. she and DORMR3 are a set. ✨

  • dormtr — DORMTR
subroutine dormtr (SIDE, UPLO, TRANS, M, N, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)

SIDE, UPLO, TRANS — the holy trinity of control flags. 🫶

  • dpbcon — DPBCON
subroutine dpbcon (UPLO, N, KD, AB, LDAB, ANORM, RCOND, WORK, IWORK, INFO)

the band-matrix crew starts here. KD, AB, LDAB — band life. 🎸

  • dpbequ — DPBEQU
subroutine dpbequ (UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, INFO)

S, SCOND, AMAX — she's all about the equilibration glow-up. ✨

  • dpbrfs — DPBRFS
subroutine dpbrfs (UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO)

FERR AND BERR. two error vectors. she's thorough, she's checking everything, she's that girl. 🔥

  • dpbstf — DPBSTF
subroutine dpbstf (UPLO, N, KD, AB, LDAB, INFO)

short and sweet. six args and she's out. 💅

  • dpbtf2 — DPBTF2
subroutine dpbtf2 (UPLO, N, KD, AB, LDAB, INFO)

DPBTF2 computes the Cholesky factorization of a symmetric/Hermitian positive definite band matrix (unblocked algorithm). unblocked! the 2 is the tell, always check the 2. 🎀

  • dpbtrf — DPBTRF
subroutine dpbtrf (UPLO, N, KD, AB, LDAB, INFO)

the blocked Cholesky-in-bands. no 2, so she's the full version. 😌

  • dpbtrs — DPBTRS
subroutine dpbtrs (UPLO, N, KD, NRHS, AB, LDAB, B, LDB, INFO)

the s means solve, and she's here to solve. 🦋

  • dpftrf — DPFTRF
subroutine dpftrf (TRANSR, UPLO, N, A, INFO)

TRANSR and UPLO — RFP format enters the chat. ✨

  • dpftri — DPFTRI
subroutine dpftri (TRANSR, UPLO, N, A, INFO)

same signature, i for inverse. the vibe is: undo it. 💜

  • dpftrs — DPFTRS
subroutine dpftrs (TRANSR, UPLO, N, NRHS, A, B, LDB, INFO)

NRHS joins, B shows up, we're solving now. 🔥

  • dppcon — DPPCON
subroutine dppcon (UPLO, N, AP, ANORM, RCOND, WORK, IWORK, INFO)

packed storage era begins. AP not AB, don't confuse them. 📝

  • dppequ — DPPEQU
subroutine dppequ (UPLO, N, AP, S, SCOND, AMAX, INFO)

equilibration, packed style. S, SCOND, AMAX back on their bullshit. ✨

  • dpprfs — DPPRFS
subroutine dpprfs (UPLO, N, NRHS, AP, AFP, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO)

AP AND AFP — the original and the factorization, side by side. it's giving before and after. 🎀

  • dpptrf — DPPTRF
subroutine dpptrf (UPLO, N, AP, INFO)

four args. that's it. that's the whole girl. 💅

  • dpptri — DPPTRI
subroutine dpptri (UPLO, N, AP, INFO)

same four args, inverse flavour. 🦋

  • dpptrs — DPPTRS
subroutine dpptrs (UPLO, N, NRHS, AP, B, LDB, INFO)

solve, packed, NRHS present, B present, we're good. 💜

  • dpstf2 — DPSTF2
subroutine dpstf2 (UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO)

DPSTF2 computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix. semidefinite! pivoting! RANK and TOL and PIV! she's advanced. 👑

  • dpstrf — DPSTRF
subroutine dpstrf (UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO)

DPSTRF computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix. identical description, identical signature, no 2 in the name. blocked edition. 🔥

  • dsbgst — DSBGST
subroutine dsbgst (VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X, LDX, WORK, INFO)

KA and KB — two bandwidths, two matrices, one very busy subroutine. 💅

  • dsbtrd — DSBTRD
subroutine dsbtrd (VECT, UPLO, N, KD, AB, LDAB, D, E, Q, LDQ, WORK, INFO)

D, E, Q — tridiagonal reduction, the whole trilogy. 🎀

  • dsfrk — DSFRK
subroutine dsfrk (TRANSR, UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, C)

DSFRK performs a symmetric rank-k operation for matrix in RFP format. ALPHA and BETA both showed up, so you know it's a rank-k update. and there's no INFO at the end — she doesn't report back, she just does it. 😭✨

okay bestie the roster keeps going, grab a snack 🍓 — these are all the double-precision "other computational" girlies:

  • subroutine dspcon (UPLO, N, AP, IPIV, ANORM, RCOND, WORK, IWORK, INFO) — DSPCON
  • subroutine dspgst (ITYPE, UPLO, N, AP, BP, INFO) — DSPGST
  • subroutine dsprfs (UPLO, N, NRHS, AP, AFP, IPIV, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO) — DSPRFS
  • subroutine dsptrd (UPLO, N, AP, D, E, TAU, INFO) — DSPTRD
  • subroutine dsptrf (UPLO, N, AP, IPIV, INFO) — DSPTRF
  • subroutine dsptri (UPLO, N, AP, IPIV, WORK, INFO) — DSPTRI
  • subroutine dsptrs (UPLO, N, NRHS, AP, IPIV, B, LDB, INFO) — DSPTRS
  • subroutine dstegr (JOBZ, RANGE, N, D, E, VL, VU, IL, IU, ABSTOL, M, W, Z, LDZ, ISUPPZ, WORK, LWORK, IWORK, LIWORK, INFO) — DSTEGR
  • subroutine dstein (N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK, IWORK, IFAIL, INFO) — DSTEIN
  • subroutine dstemr (JOBZ, RANGE, N, D, E, VL, VU, IL, IU, M, W, Z, LDZ, NZC, ISUPPZ, TRYRAC, WORK, LWORK, IWORK, LIWORK, INFO) — DSTEMR
  • subroutine dtbcon (NORM, UPLO, DIAG, N, KD, AB, LDAB, RCOND, WORK, IWORK, INFO) — DTBCON
  • subroutine dtbrfs (UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO) — DTBRFS
  • subroutine dtbtrs (UPLO, TRANS, DIAG, N, KD, NRHS, AB, LDAB, B, LDB, INFO) — DTBTRS
  • subroutine dtfsm (TRANSR, SIDE, UPLO, TRANS, DIAG, M, N, ALPHA, A, B, LDB) — DTFSM solves a matrix equation (one operand is a triangular matrix in RFP format). 💅
  • subroutine dtftri (TRANSR, UPLO, DIAG, N, A, INFO) — DTFTRI
  • subroutine dtfttp (TRANSR, UPLO, N, ARF, AP, INFO) — DTFTTP copies a triangular matrix from the rectangular full packed format (TF) to the standard packed format (TP).
  • subroutine dtfttr (TRANSR, UPLO, N, ARF, A, LDA, INFO) — DTFTTR copies a triangular matrix from the rectangular full packed format (TF) to the standard full format (TR).
  • subroutine dtgsen (IJOB, WANTQ, WANTZ, SELECT, N, A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, Q, LDQ, Z, LDZ, M, PL, PR, DIF, WORK, LWORK, IWORK, LIWORK, INFO) — DTGSEN
  • subroutine dtgsja (JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B, LDB, TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV, Q, LDQ, WORK, NCYCLE, INFO) — DTGSJA
  • subroutine dtgsna (JOB, HOWMNY, SELECT, N, A, LDA, B, LDB, VL, LDVL, VR, LDVR, S, DIF, MM, M, WORK, LWORK, IWORK, INFO) — DTGSNA
  • subroutine dtpcon (NORM, UPLO, DIAG, N, AP, RCOND, WORK, IWORK, INFO) — DTPCON
  • subroutine dtplqt (M, N, L, MB, A, LDA, B, LDB, T, LDT, WORK, INFO) — DTPLQT
  • subroutine dtplqt2 (M, N, L, A, LDA, B, LDB, T, LDT, INFO) — DTPLQT2 computes a LQ factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.
  • subroutine dtpmlqt (SIDE, TRANS, M, N, K, L, MB, V, LDV, T, LDT, A, LDA, B, LDB, WORK, INFO) — DTPMLQT
  • subroutine dtpmqrt (SIDE, TRANS, M, N, K, L, NB, V, LDV, T, LDT, A, LDA, B, LDB, WORK, INFO) — DTPMQRT
  • subroutine dtpqrt (M, N, L, NB, A, LDA, B, LDB, T, LDT, WORK, INFO) — DTPQRT
  • subroutine dtpqrt2 (M, N, L, A, LDA, B, LDB, T, LDT, INFO) — DTPQRT2 computes a QR factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.
  • subroutine dtprfs (UPLO, TRANS, DIAG, N, NRHS, AP, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO) — DTPRFS
  • subroutine dtptri (UPLO, DIAG, N, AP, INFO) — DTPTRI
  • subroutine dtptrs (UPLO, TRANS, DIAG, N, NRHS, AP, B, LDB, INFO) — DTPTRS
  • subroutine dtpttf (TRANSR, UPLO, N, AP, ARF, INFO) — DTPTTF copies a triangular matrix from the standard packed format (TP) to the rectangular full packed format (TF).
  • subroutine dtpttr (UPLO, N, AP, A, LDA, INFO) — DTPTTR copies a triangular matrix from the standard packed format (TP) to the standard full format (TR).
  • subroutine dtrcon (NORM, UPLO, DIAG, N, A, LDA, RCOND, WORK, IWORK, INFO) — DTRCON
  • subroutine dtrevc (SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, INFO) — DTREVC
  • subroutine dtrevc3 (SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, MM, M, WORK, LWORK, INFO) — DTREVC3
  • subroutine dtrexc (COMPQ, N, T, LDT, Q, LDQ, IFST, ILST, WORK, INFO) — DTREXC
  • subroutine dtrrfs (UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB, X, LDX, FERR, BERR, WORK, IWORK, INFO) — DTRRFS
  • subroutine dtrsen (JOB, COMPQ, SELECT, N, T, LDT, Q, LDQ, WR, WI, M, S, SEP, WORK, LWORK, IWORK, LIWORK, INFO) — DTRSEN
  • subroutine dtrsna (JOB, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR, LDVR, S, SEP, MM, M, WORK, LDWORK, IWORK, INFO) — DTRSNA
  • subroutine dtrti2 (UPLO, DIAG, N, A, LDA, INFO) — DTRTI2 computes the inverse of a triangular matrix (unblocked algorithm).
  • subroutine dtrtri (UPLO, DIAG, N, A, LDA, INFO) — DTRTRI
  • subroutine dtrtrs (UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB, INFO) — DTRTRS
  • subroutine dtrttf (TRANSR, UPLO, N, A, LDA, ARF, INFO) — DTRTTF copies a triangular matrix from the standard full format (TR) to the rectangular full packed format (TF).
  • subroutine dtrttp (UPLO, N, A, LDA, AP, INFO) — DTRTTP copies a triangular matrix from the standard full format (TR) to the standard packed format (TP).
  • subroutine dtzrzf (M, N, A, LDA, TAU, WORK, LWORK, INFO) — DTZRZF
  • subroutine stplqt (M, N, L, MB, A, LDA, B, LDB, T, LDT, WORK, INFO) — STPLQT
  • subroutine stplqt2 (M, N, L, A, LDA, B, LDB, T, LDT, INFO) — STPLQT2 computes a LQ factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.
  • subroutine stpmlqt (SIDE, TRANS, M, N, K, L, MB, V, LDV, T, LDT, A, LDA, B, LDB, WORK, INFO) — STPMLQT
  • subroutine ztplqt (M, N, L, MB, A, LDA, B, LDB, T, LDT, WORK, INFO) — ZTPLQT
  • subroutine ztplqt2 (M, N, L, A, LDA, B, LDB, T, LDT, INFO) — ZTPLQT2 computes a LQ factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.
  • subroutine ztpmlqt (SIDE, TRANS, M, N, K, L, MB, V, LDV, T, LDT, A, LDA, B, LDB, WORK, INFO) — ZTPMLQT

✨ Detailed Description ✨

okay so, no cap, this is the group of double other Computational routines. that's the whole vibe. 💖


💫 Function Documentation 💫

ctplqt — the main character of this section 👑

subroutine ctplqt (integer M, integer N, integer L, integer MB, complex,
    dimension( lda, * ) A, integer LDA, complex, dimension( ldb, * ) B,
    integer LDB, complex, dimension( ldt, * ) T, integer LDT, complex,
    dimension( * ) WORK, integer INFO)

CTPLQT


Purpose 🎯

CTPLQT computes a blocked LQ factorization of a complex 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. she's giving structured, she's giving organized, she ate. 💅✨


Parameters 🌸

  • M

M is INTEGER. The number of rows of the matrix B, and the order of the triangular matrix A. M >= 0.

  • N

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

  • L

L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details.

  • MB

MB is INTEGER. The block size to be used in the blocked QR. M >= MB >= 1.

  • A

A is COMPLEX array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L.

  • LDA

LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).

  • B

B is COMPLEX array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details.

  • LDB

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

  • T

T is COMPLEX array, dimension (LDT,N). The lower triangular block reflectors stored in compact form as a sequence of upper triangular blocks. See Further Details.

  • LDT

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

  • WORK

WORK is COMPLEX array, dimension (MB*M).

  • INFO

INFO is INTEGER.

  • = 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.


Further Details: 🧚

The input matrix C is a M-by-(M+N) matrix

             C = [ A ] [ B ]

where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal matrix consisting of a M-by-(N-L) rectangular matrix B1 on left of a M-by-L upper trapezoidal matrix B2:

        [ B ] = [ B1 ] [ B2 ]
                 [ B1 ]  <- M-by-(N-L) rectangular
                 [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a M-by-M lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular.

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

           [ C ] = [ A ] [ B ]
                  [ A ]  <- lower triangular M-by-M
                  [ B ]  <- M-by-N pentagonal

so that W can be represented as

           [ W ] = [ I ] [ V ]
                  [ I ]  <- identity, M-by-M
                  [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

           [ V ] = [ V1 ] [ V2 ]
                  [ V1 ] <- M-by-(N-L) rectangular
                  [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s. 🦋

okay so the number of blocks is B = ceiling(M/MB), where each block is of order MB except for the last block, which is of order IB = M - (M-1)*MB. For each of the B blocks, an upper triangular block reflector factor gets computed: T1, T2, ..., TB. The MB-by-MB (and IB-by-IB for the last block) T's are stored in the MB-by-N matrix T as

T = [T1 T2 ... TB].

🎀 subroutine ctplqt2 🎀

subroutine ctplqt2 (integer M, integer N, integer L, complex, dimension( lda, * ) A, integer LDA, complex, dimension( ldb, * ) B, integer LDB, complex, dimension( ldt, * ) T, integer LDT, integer INFO)

💖 CTPLQT2

✨ Purpose

CTPLQT2 computes a LQ factorization of a complex 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. bestie it literally eats 💅

🌸 Parameters

  • M — M is INTEGER. The total number of rows of the matrix B. Constraint: M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B, and the order of the triangular matrix A. Constraint: N >= 0.
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. Constraint: MIN(M,N) >= L >= 0. See Further Details, iykyk.
  • A — A is COMPLEX array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L. 👀
  • LDA — LDA is INTEGER. The leading dimension of the array A. Constraint: LDA >= max(1,M).
  • B — B is COMPLEX array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details.
  • LDB — LDB is INTEGER. The leading dimension of the array B. Constraint: LDB >= max(1,M).
  • T — T is COMPLEX array, dimension (LDT,M). The N-by-N upper triangular factor T of the block reflector. See Further Details.
  • LDT — LDT is INTEGER. The leading dimension of the array T. Constraint: LDT >= max(1,M).
  • INFO — INFO is INTEGER. Exit status, and it is giving receipts: = 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.

🦋 Further Details

The input matrix C is a M-by-(M+N) matrix

             C = [ A ][ B ]

where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal matrix consisting of a M-by-(N-L) rectangular matrix B1 left of a M-by-L upper trapezoidal matrix B2:

             B = [ B1 ][ B2 ]
                 [ B1 ]  <-     M-by-(N-L) rectangular
                 [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a N-by-N lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular.

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

             C = [ A ][ B ]
                 [ A ]  <- lower triangular M-by-M
                 [ B ]  <- M-by-N pentagonal

so that W can be represented as

             W = [ I ][ V ]
                 [ I ]  <- identity, M-by-M
                 [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

             W = [ V1 ][ V2 ]
                 [ V1 ] <-     M-by-(N-L) rectangular
                 [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s. The (M+N)-by-(M+N) block reflector H is then given by

             H = I - W**T * T * W

where W^H is the conjugate transpose of W and T is the upper triangular factor of the block reflector. no cap that's the whole vibe of the thing ✨


🎀 subroutine ctpmlqt 🎀

subroutine ctpmlqt (character SIDE, character TRANS, integer M, integer N, integer K, integer L, integer MB, complex, dimension( ldv, * ) V, integer LDV, complex, dimension( ldt, * ) T, integer LDT, complex, dimension( lda, * ) A, integer LDA, complex, dimension( ldb, * ) B, integer LDB, complex, dimension( * ) WORK, integer INFO)

💖 CTPMLQT

✨ Purpose

CTPMLQT applies a complex unitary matrix Q obtained from a 'triangular-pentagonal' complex block reflector H to a general complex matrix C, which consists of two blocks A and B. 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.
  • TRANS — TRANS is CHARACTER*1. = 'N': No transpose, apply Q; = 'C': Conjugate transpose, apply Q**H.
  • M — M is INTEGER. The number of rows of the matrix B. Constraint: M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B. Constraint: N >= 0.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q.
  • L — L is INTEGER. The order of the trapezoidal part of V. Constraint: K >= L >= 0. See Further Details.
  • MB — MB is INTEGER. The block size used for the storage of T. Constraint: K >= MB >= 1.
not me reminding you that this must be the same value of MB used to generate T in CTPLQT. if you get that wrong the whole thing falls apart bestie 😭
  • V — V is COMPLEX array, dimension (LDV,K). The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by CTPLQT in B. See Further Details.
  • LDV — LDV is INTEGER. The leading dimension of the array V. Constraint: LDV >= K.
  • T — T is COMPLEX array, dimension (LDT,K). The upper triangular factors of the block reflectors as returned by CTPLQT, stored as a MB-by-K matrix.
  • LDT — LDT is INTEGER. The leading dimension of the array T. Constraint: LDT >= MB.
  • A — A is COMPLEX 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.
  • LDA — LDA is INTEGER. The leading dimension of the array A. If SIDE = 'L', LDA >= max(1,K); If SIDE = 'R', LDA >= max(1,M).
  • B — B is COMPLEX 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.
  • LDB — LDB is INTEGER. The leading dimension of the array B. Constraint: LDB >= max(1,M).
  • WORK — WORK is COMPLEX array. The dimension of WORK is N*MB if SIDE = 'L', or M*MB if SIDE = 'R'.
  • INFO — INFO is INTEGER. Exit status: = 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.

🦋 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 lower trapezoidal, consisting of the first L rows of a K-by-K upper triangular matrix. If L=K, V2 is lower 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 K-by-M.

                         [B]

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

The complex unitary 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.

🎀 subroutine dbbcsd 🎀

subroutine dbbcsd (character JOBU1, character JOBU2, character JOBV1T, character JOBV2T, character TRANS, integer M, integer P, integer Q, double precision, dimension( * ) THETA, double precision, dimension( * ) PHI, double precision, dimension( ldu1, * ) U1, integer LDU1, double precision, dimension( ldu2, * ) U2, integer LDU2, double precision, dimension( ldv1t, * ) V1T, integer LDV1T, double precision, dimension( ldv2t, * ) V2T, integer LDV2T, double precision, dimension( * ) B11D, double precision, dimension( * ) B11E, double precision, dimension( * ) B12D, double precision, dimension( * ) B12E, double precision, dimension( * ) B21D, double precision, dimension( * ) B21E, double precision, dimension( * ) B22D, double precision, dimension( * ) B22E, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

💖 DBBCSD

✨ Purpose

DBBCSD computes the CS decomposition of an orthogonal matrix in bidiagonal-block form,

    [ B11 | B12 0  0 ]
    [  0  |  0 -I  0 ]
X = [----------------]
    [ B21 | B22 0  0 ]
    [  0  |  0  0  I ]

                                      [  C | -S  0  0 ]
                          [ U1 |    ] [  0 |  0 -I  0 ] [ V1 |    ]**T
                        = [---------] [---------------] [---------]   .
                          [    | U2 ] [  S |  C  0  0 ] [    | V2 ]
                                      [  0 |  0  0  I ]

iconic. the decomposition itself is the main character here 💅🌈

X is M-by-M, its top-left block is P-by-Q, and Q must be no larger than P, M-P, or M-Q. (If Q is not the smallest index, then X must be transposed and/or permuted. This can be done in constant time using the TRANS and SIGNS options. See DORCSD for details.)

The bidiagonal matrices B11, B12, B21, and B22 are represented implicitly by angles THETA(1:Q) and PHI(1:Q-1).

The orthogonal matrices U1, U2, V1T, and V2T are input/output. The input matrices are pre- or post-multiplied by the appropriate singular vector matrices.


Parameters 💖

  • JOBU1 — JOBU1 is CHARACTER
    • = 'Y': U1 is updated;
    • otherwise: U1 is not updated.
  • JOBU2 — JOBU2 is CHARACTER
    • = 'Y': U2 is updated;
    • otherwise: U2 is not updated.
  • JOBV1T — JOBV1T is CHARACTER
    • = 'Y': V1T is updated;
    • otherwise: V1T is not updated.
  • JOBV2T — JOBV2T is CHARACTER
    • = 'Y': V2T is updated;
    • otherwise: V2T is not updated.
  • TRANS — TRANS is CHARACTER
    • = 'T': X, U1, U2, V1T, and V2T are stored in row-major order;
    • otherwise: X, U1, U2, V1T, and V2T are stored in column-major order.
  • M — M is INTEGER. The number of rows and columns in X, the orthogonal matrix in bidiagonal-block form. she's a square, bestie 💅
  • P — P is INTEGER. The number of rows in the top-left block of X. 0 <= P <= M.
  • Q — Q is INTEGER. The number of columns in the top-left block of X. 0 <= Q <= MIN(P,M-P,M-Q).
  • THETA — THETA is DOUBLE PRECISION array, dimension (Q). On entry, the angles THETA(1),...,THETA(Q) that, along with PHI(1), ...,PHI(Q-1), define the matrix in bidiagonal-block form. On exit, the angles whose cosines and sines define the diagonal blocks in the CS decomposition.
  • PHI — PHI is DOUBLE PRECISION array, dimension (Q-1). The angles PHI(1),...,PHI(Q-1) that, along with THETA(1),...,THETA(Q), define the matrix in bidiagonal-block form.
  • U1 — U1 is DOUBLE PRECISION array, dimension (LDU1,P). On entry, a P-by-P matrix. On exit, U1 is postmultiplied by the left singular vector matrix common to [ B11 ; 0 ] and [ B12 0 0 ; 0 -I 0 0 ].
  • LDU1 — LDU1 is INTEGER. The leading dimension of the array U1, LDU1 >= MAX(1,P).
  • U2 — U2 is DOUBLE PRECISION array, dimension (LDU2,M-P). On entry, an (M-P)-by-(M-P) matrix. On exit, U2 is postmultiplied by the left singular vector matrix common to [ B21 ; 0 ] and [ B22 0 0 ; 0 0 I ].
  • LDU2 — LDU2 is INTEGER. The leading dimension of the array U2, LDU2 >= MAX(1,M-P).
  • V1T — V1T is DOUBLE PRECISION array, dimension (LDV1T,Q). On entry, a Q-by-Q matrix. On exit, V1T is premultiplied by the transpose of the right singular vector matrix common to [ B11 ; 0 ] and [ B21 ; 0 ].
  • LDV1T — LDV1T is INTEGER. The leading dimension of the array V1T, LDV1T >= MAX(1,Q).
  • V2T — V2T is DOUBLE PRECISION array, dimension (LDV2T,M-Q). On entry, an (M-Q)-by-(M-Q) matrix. On exit, V2T is premultiplied by the transpose of the right singular vector matrix common to [ B12 0 0 ; 0 -I 0 ] and [ B22 0 0 ; 0 0 I ].
  • LDV2T — LDV2T is INTEGER. The leading dimension of the array V2T, LDV2T >= MAX(1,M-Q).
  • B11D — B11D is DOUBLE PRECISION array, dimension (Q). When DBBCSD converges, B11D contains the cosines of THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then B11D contains the diagonal of the partially reduced top-left block.
  • B11E — B11E is DOUBLE PRECISION array, dimension (Q-1). When DBBCSD converges, B11E contains zeros. If DBBCSD fails to converge, then B11E contains the superdiagonal of the partially reduced top-left block.
  • B12D — B12D is DOUBLE PRECISION array, dimension (Q). When DBBCSD converges, B12D contains the negative sines of THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then B12D contains the diagonal of the partially reduced top-right block.
  • B12E — B12E is DOUBLE PRECISION array, dimension (Q-1). When DBBCSD converges, B12E contains zeros. If DBBCSD fails to converge, then B12E contains the subdiagonal of the partially reduced top-right block.
  • B21D — B21D is DOUBLE PRECISION array, dimension (Q). When DBBCSD converges, B21D contains the negative sines of THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then B21D contains the diagonal of the partially reduced bottom-left block.
  • B21E — B21E is DOUBLE PRECISION array, dimension (Q-1). When DBBCSD converges, B21E contains zeros. If DBBCSD fails to converge, then B21E contains the subdiagonal of the partially reduced bottom-left block.
  • B22D — B22D is DOUBLE PRECISION array, dimension (Q). When DBBCSD converges, B22D contains the negative sines of THETA(1), ..., THETA(Q). If DBBCSD fails to converge, then B22D contains the diagonal of the partially reduced bottom-right block.
  • B22E — B22E is DOUBLE PRECISION array, dimension (Q-1). When DBBCSD converges, B22E contains zeros. If DBBCSD fails to converge, then B22E contains the subdiagonal of the partially reduced bottom-right block.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= MAX(1,8*Q).

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the work array, and no error message related to LWORK is issued by XERBLA.

  • INFO — INFO is INTEGER
    • = 0: successful exit.
    • < 0: if INFO = -i, the i-th argument had an illegal value.
    • > 0: if DBBCSD did not converge, INFO specifies the number of nonzero entries in PHI, and B11D, B11E, etc., contain the partially reduced matrix.

Internal Parameters: 🔧✨

  • TOLMUL — DOUBLE PRECISION, default = MAX(10,MIN(100,EPS**(-1/8)))

TOLMUL controls the convergence criterion of the QR loop. Angles THETA(i), PHI(i) are rounded to 0 or PI/2 when they are within TOLMUL*EPS of either bound.


References: 📚

  1. [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.

Author 💖

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


subroutine dgetsqrhrt — DGETSQRHRT 🦋

subroutine dgetsqrhrt (integer M, integer N, integer MB1, integer NB1, integer NB2, double precision, dimension( lda, * ) A, integer LDA, double precision, dimension( ldt, * ) T, integer LDT, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

Purpose: 🎯

DGETSQRHRT computes a NB2-sized column blocked QR-factorization of a real M-by-N matrix A with M >= N,

A = Q * R.

The routine uses internally a NB1-sized column blocked and MB1-sized row blocked TSQR-factorization and perfors the reconstruction of the Householder vectors from the TSQR output. The routine also converts the R_tsqr factor from the TSQR-factorization output into the R factor that corresponds to the Householder QR-factorization,

A = Q_tsqr * R_tsqr = Q * R.

The output Q and R factors are stored in the same format as in DGEQRT (Q is in blocked compact WY-representation). See the documentation of DGEQRT for more details on the format.

Parameters 🌸

  • M — M is INTEGER. The number of rows of the matrix A. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix A. M >= N >= 0.
  • MB1 — MB1 is INTEGER. The row block size to be used in the blocked TSQR. MB1 > N.
  • NB1 — NB1 is INTEGER. The column block size to be used in the blocked TSQR. N >= NB1 >= 1.
  • NB2 — NB2 is INTEGER. The block size to be used in the blocked QR that is output. NB2 >= 1.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N)

On entry: an M-by-N matrix A.

On exit:

  1. the elements on and above the diagonal of the array contain the N-by-N upper-triangular matrix R corresponding to the Householder QR;
  2. the elements below the diagonal represent Q by the columns of blocked V (compact WY-representation).
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • T — T is DOUBLE PRECISION array, dimension (LDT,N)). The upper triangular block reflectors stored in compact form as a sequence of upper triangular blocks.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= NB2.
  • WORK — (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK —

Okay so the dimension of the array WORK? It's giving math homework but make it cute. Here's the exact tea:

LWORK >= MAX( LWT + LW1, MAX( LWT+N*N+LW2, LWT+N*N+N ) ),
where
   NUM_ALL_ROW_BLOCKS = CEIL((M-N)/(MB1-N)),
   NB1LOCAL = MIN(NB1,N).
   LWT = NUM_ALL_ROW_BLOCKS * N * NB1LOCAL,
   LW1 = NB1LOCAL * N,
   LW2 = NB1LOCAL * MAX( NB1LOCAL, ( N - NB1LOCAL ) ),

If LWORK = -1, then a workspace query is assumed. The routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.

  • INFO — INFO is INTEGER
    • = 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.

Contributors:

  • November 2020, Igor Kozachenko, Computer Science Division, University of California, Berkeley

✨ DGGHD3 ✨

subroutine dgghd3 (character COMPQ, character COMPZ, integer N, integer ILO,
    integer IHI, double precision, dimension( lda, * ) A, integer LDA,
    double precision, dimension( ldb, * ) B, integer LDB, double precision,
    dimension( ldq, * ) Q, integer LDQ, double precision, dimension( ldz, *
    ) Z, integer LDZ, double precision, dimension( * ) WORK, integer LWORK,
    integer INFO)

🎯 Purpose 🎯

DGGHD3 reduces a pair of real matrices (A,B) to generalized upper Hessenberg form using orthogonal transformations, where A is a general matrix and B is upper triangular. The form of the generalized eigenvalue problem is

A*x = lambda*B*x,

and B is typically made upper triangular by computing its QR factorization and moving the orthogonal matrix Q to the left side of the equation.

This subroutine simultaneously reduces A to a Hessenberg matrix H:

Q**T*A*Z = H

and transforms B to another upper triangular matrix T:

Q**T*B*Z = T

in order to reduce the problem to its standard form

H*y = lambda*T*y

where y = Z**T*x.

The orthogonal matrices Q and Z are determined as products of Givens rotations. They may either be formed explicitly, or they may be postmultiplied into input matrices Q1 and Z1, so that

Q1 * A * Z1**T = (Q1*Q) * H * (Z1*Z)**T

Q1 * B * Z1**T = (Q1*Q) * T * (Z1*Z)**T

If Q1 is the orthogonal matrix from the QR factorization of B in the original equation A*x = lambda*B*x, then DGGHD3 reduces the original problem to generalized Hessenberg form.

This is a blocked variant of DGGHRD, using matrix-matrix multiplications for parts of the computation to enhance performance.

📋 Parameters 📋

  • COMPQ — COMPQ is CHARACTER*1
    • = 'N': do not compute Q;
    • = 'I': Q is initialized to the unit matrix, and the orthogonal matrix Q is returned;
    • = 'V': Q must contain an orthogonal matrix Q1 on entry, and the product Q1*Q is returned.
  • COMPZ — COMPZ is CHARACTER*1
    • = 'N': do not compute Z;
    • = 'I': Z is initialized to the unit matrix, and the orthogonal matrix Z is returned;
    • = 'V': Z must contain an orthogonal matrix Z1 on entry, and the product Z1*Z is returned.
  • N — N is INTEGER. The order of the matrices A and B. N >= 0.
  • ILO — ILO is INTEGER
  • IHI — IHI is INTEGER
    • ILO and IHI mark the rows and columns of A which are to be reduced. It is assumed that A is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to DGGBAL; otherwise they should be set to 1 and N respectively. 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
  • A — A is DOUBLE PRECISION array, dimension (LDA, N). On entry, the N-by-N general matrix to be reduced. On exit, the upper triangle and the first subdiagonal of A are overwritten with the upper Hessenberg matrix H, and the rest is set to zero.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B — B is DOUBLE PRECISION array, dimension (LDB, N). On entry, the N-by-N upper triangular matrix B. On exit, the upper triangular matrix T = Q**T B Z. The elements below the diagonal are set to zero.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • Q — Q is DOUBLE PRECISION array, dimension (LDQ, N). On entry, if COMPQ = 'V', the orthogonal matrix Q1, typically from the QR factorization of B. On exit, if COMPQ='I', the orthogonal matrix Q, and if COMPQ = 'V', the product Q1*Q. Not referenced if COMPQ='N'.
  • LDQ — LDQ is INTEGER. The leading dimension of the array Q. LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise.
  • Z — Z is DOUBLE PRECISION array, dimension (LDZ, N). On entry, if COMPZ = 'V', the orthogonal matrix Z1. On exit, if COMPZ='I', the orthogonal matrix Z, and if COMPZ = 'V', the product Z1*Z. Not referenced if COMPZ='N'.
  • LDZ — LDZ is INTEGER. The leading dimension of the array Z. LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise.
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The length of the array WORK. LWORK >= 1. For optimum performance LWORK >= 6*N*NB, where NB is the optimal blocksize.
    • If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
  • INFO — INFO is INTEGER
    • = 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.

🔍 Further Details 🔍

This routine reduces A to Hessenberg form and maintains B in triangular form using a blocked variant of Moler and Stewart's original algorithm, as described by Kagstrom, Kressner, Quintana-Orti, and Quintana-Orti (BIT 2008).


🌸 DGGHRD 🌸

subroutine dgghrd (character COMPQ, character COMPZ, integer N, integer ILO,
    integer IHI, double precision, dimension( lda, * ) A, integer LDA,
    double precision, dimension( ldb, * ) B, integer LDB, double precision,
    dimension( ldq, * ) Q, integer LDQ, double precision, dimension( ldz, *
    ) Z, integer LDZ, integer INFO)

🎯 Purpose 🎯

DGGHRD reduces a pair of real matrices (A,B) to generalized upper Hessenberg form using orthogonal transformations, where A is a general matrix and B is upper triangular. The form of the generalized eigenvalue problem is

A*x = lambda*B*x,

and B is typically made upper triangular by computing its QR factorization and moving the orthogonal matrix Q to the left side of the equation.

This subroutine simultaneously reduces A to a Hessenberg matrix H:

Q**T*A*Z = H

and transforms B to another upper triangular matrix T:

Q**T*B*Z = T

in order to reduce the problem to its standard form

H*y = lambda*T*y

where y = Z**T*x.

The orthogonal matrices Q and Z are determined as products of Givens rotations. They may either be formed explicitly, or they may be postmultiplied into input matrices Q1 and Z1, so that

Q1 * A * Z1**T = (Q1*Q) * H * (Z1*Z)**T

Q1 * B * Z1**T = (Q1*Q) * T * (Z1*Z)**T

If Q1 is the orthogonal matrix from the QR factorization of B in the original equation A*x = lambda*B*x, then DGGHRD reduces the original problem to generalized Hessenberg form.

📋 Parameters 📋

  • COMPQ — COMPQ is CHARACTER*1
    • = 'N': do not compute Q;
    • = 'I': Q is initialized to the unit matrix, and the orthogonal matrix Q is returned;
    • = 'V': Q must contain an orthogonal matrix Q1 on entry, and the product Q1*Q is returned.
  • COMPZ — COMPZ is CHARACTER*1
    • = 'N': do not compute Z;
    • = 'I': Z is initialized to the unit matrix, and the orthogonal matrix Z is returned;
    • = 'V': Z must contain an orthogonal matrix Z1 on entry, and the product Z1*Z is returned.
  • N — N is INTEGER. The order of the matrices A and B. N >= 0.
  • ILO — ILO is INTEGER
  • IHI — IHI is INTEGER
    • ILO and IHI mark the rows and columns of A which are to be reduced. It is assumed that A is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to DGGBAL; otherwise they should be set to 1 and N respectively. 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
  • A — A is DOUBLE PRECISION array, dimension (LDA, N). On entry, the N-by-N general matrix to be reduced. On exit, the upper triangle and the first subdiagonal of A are overwritten with the upper Hessenberg matrix H, and the rest is set to zero.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B —
  • B — DOUBLE PRECISION array, dimension (LDB, N) On entry, the N-by-N upper triangular matrix B. On exit, the upper triangular matrix T = Q**T B Z. The elements below the diagonal are set to zero. 🫶
  • LDB — INTEGER The leading dimension of the array B. LDB >= max(1,N). ✨
  • Q — DOUBLE PRECISION array, dimension (LDQ, N) On entry, if COMPQ = 'V', the orthogonal matrix Q1, typically from the QR factorization of B. On exit, if COMPQ='I', the orthogonal matrix Q, and if COMPQ = 'V', the product Q1*Q. Not referenced if COMPQ='N'. 👑
  • LDQ — INTEGER The leading dimension of the array Q. LDQ >= N if COMPQ='V' or 'I'; LDQ >= 1 otherwise. 💅
  • Z — DOUBLE PRECISION array, dimension (LDZ, N) On entry, if COMPZ = 'V', the orthogonal matrix Z1. On exit, if COMPZ='I', the orthogonal matrix Z, and if COMPZ = 'V', the product Z1*Z. Not referenced if COMPZ='N'. 🌸
  • LDZ — INTEGER The leading dimension of the array Z. LDZ >= N if COMPZ='V' or 'I'; LDZ >= 1 otherwise. 🦋
  • INFO — INTEGER
= 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.

🌈 Further Details

This routine reduces A to Hessenberg and B to triangular form by an unblocked reduction, as described in Matrix Computations, by Golub and Van Loan (Johns Hopkins Press.) 📚


subroutine dggqrf (integer N, integer M, integer P, double precision, dimension( lda, * ) A, integer LDA, double precision, dimension( * ) TAUA, double precision, dimension( ldb, * ) B, integer LDB, double precision, dimension( * ) TAUB, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DGGQRF

✨ Purpose

Bestie, DGGQRF computes a generalized QR factorization of an N-by-M matrix A and an N-by-P matrix B:

A = Q*R,        B = Q*T*Z,

where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal matrix, and R and T assume one of the forms:

if N >= M,  R = ( R11 ) M  ,   or if N < M,  R = ( R11  R12 ) N,
                (  0  ) N-M                         N   M-N
                   M

where R11 is upper triangular, and

if N <= P,  T = ( 0  T12 ) N,   or if N > P,  T = ( T11 ) N-P,
                 P-N  N                           ( T21 ) P
                                                     P

where T12 or T21 is upper triangular.

In particular, if B is square and nonsingular, the GQR factorization of A and B implicitly gives the QR factorization of inv(B)*A:

inv(B)*A = Z**T*(inv(T)*R)

where inv(B) denotes the inverse of the matrix B, and Z**T denotes the transpose of the matrix Z. No cap, that's the whole plot. 🔥

🎀 Parameters

  • N — INTEGER The number of rows of the matrices A and B. N >= 0. ⭐
  • M — INTEGER The number of columns of the matrix A. M >= 0. ⭐
  • P — INTEGER The number of columns of the matrix B. P >= 0. ⭐
  • A — DOUBLE PRECISION array, dimension (LDA,M) On entry, the N-by-M matrix A. On exit, the elements on and above the diagonal of the array contain the min(N,M)-by-M upper trapezoidal matrix R (R is upper triangular if N >= M); the elements below the diagonal, with the array TAUA, represent the orthogonal matrix Q as a product of min(N,M) elementary reflectors (see Further Details). 🫶
  • LDA — INTEGER The leading dimension of the array A. LDA >= max(1,N). ✨
  • TAUA — DOUBLE PRECISION array, dimension (min(N,M)) The scalar factors of the elementary reflectors which represent the orthogonal matrix Q (see Further Details). 💅
  • B — DOUBLE PRECISION array, dimension (LDB,P) On entry, the N-by-P matrix B. On exit, if N <= P, the upper triangle of the subarray B(1:N,P-N+1:P) contains the N-by-N upper triangular matrix T; if N > P, the elements on and above the (N-P)-th subdiagonal contain the N-by-P upper trapezoidal matrix T; the remaining elements, with the array TAUB, represent the orthogonal matrix Z as a product of elementary reflectors (see Further Details). 🦋
  • LDB — INTEGER The leading dimension of the array B. LDB >= max(1,N). 🌸
  • TAUB — DOUBLE PRECISION array, dimension (min(N,P)) The scalar factors of the elementary reflectors which represent the orthogonal matrix Z (see Further Details). 🌈
  • WORK — DOUBLE PRECISION array, dimension (MAX(1,LWORK)) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 👑
  • LWORK — INTEGER The dimension of the array WORK. LWORK >= max(1,N,M,P). For optimum performance LWORK >= max(N,M,P)*max(NB1,NB2,NB3), where NB1 is the optimal blocksize for the QR factorization of an N-by-M matrix, NB2 is the optimal blocksize for the RQ factorization of an N-by-P matrix, and NB3 is the optimal blocksize for a call of DORMQR.

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. 💀

  • INFO — INTEGER
= 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.

🌈 Further Details

The matrix Q is represented as a product of elementary reflectors

   Q = H(1) H(2) . . . H(k), where k = min(n,m).

Each H(i) has the form

   H(i) = I - taua * v * v**T

where taua is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:n) is stored on exit in A(i+1:n,i), and taua in TAUA(i). To form Q explicitly, use LAPACK subroutine DORGQR. To use Q to update another matrix, use LAPACK subroutine DORMQR. 🧚

The matrix Z is represented as a product of elementary reflectors

   Z = H(1) H(2) . . . H(k), where k = min(n,p).

Each H(i) has the form

   H(i) = I - taub * v * v**T

where taub is a real scalar, and v is a real vector with v(p-k+i+1:p) = 0 and v(p-k+i) = 1; v(1:p-k+i-1) is stored on exit in B(n-k+i,1:p-k+i-1), and taub in TAUB(i). To form Z explicitly, use LAPACK subroutine DORGRQ. To use Z to update another matrix, use LAPACK subroutine DORMRQ. 💜


subroutine dggrqf (integer M, integer P, integer N, double precision, dimension( lda, * ) A, integer LDA, double precision, dimension( * ) TAUA, double precision, dimension( ldb, * ) B, integer LDB, double precision, dimension( * ) TAUB, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DGGRQF

✨ Purpose

DGGRQF computes a generalized RQ factorization of an M-by-N matrix A and a P-by-N matrix B:

A = R*Q,        B = Z*T*Q,

where Q is an N-by-N orthogonal matrix, Z is a P-by-P orthogonal matrix, and R and T assume one of the forms:

if M <= N,  R = ( 0  R12 ) M,   or if M > N,  R = ( R11 ) M-N,
                 N-M  M                           ( R21 ) N
                                                     N

where R12 or R21 is upper triangular, and

if P >= N,  T = ( T11 ) N  ,   or if P < N,  T = ( T11  T12 ) P,
                (  0  ) P-N                         P   N-P
                   N

where T11 is upper triangular.

In particular, if B is square and nonsingular, the GRQ factorization of A and B implicitly gives the RQ factorization of A*inv(B):

A*inv(B) = (R*inv(T))*Z**T

where inv(B) denotes the inverse of the matrix B, and Z**T denotes the transpose of the matrix Z. Main character behavior fr fr. 🔥

🎀 Parameters

  • M — INTEGER The number of rows of the matrix A. M >= 0. ⭐
  • P — INTEGER The number of rows of the matrix B. P >= 0. ⭐
  • N — INTEGER The number of columns of the matrices A and B. N >= 0. ⭐
  • A — DOUBLE PRECISION array, dimension (LDA,N) On entry, the M-by-N matrix A. On exit, if M <= N, the upper triangle of the subarray A(1:M,N-M+1:N) contains the M-by-M upper triangular matrix R; if M > N, the elements on and above the (M-N)-th subdiagonal contain the M-by-N upper trapezoidal matrix R; the remaining elements, with the array TAUA, represent the orthogonal matrix Q as a product of elementary reflectors (see Further Details). 🫶
  • LDA — INTEGER The leading dimension of the array A. LDA >= max(1,M). ✨
  • TAUA — DOUBLE PRECISION array, dimension (min(M,N)) The scalar factors of the elementary reflectors which represent the orthogonal matrix Q (see Further Details). 💅
  • B — DOUBLE PRECISION array, dimension (LDB,N) On entry, the P-by-N matrix B. On exit, the elements on and above the diagonal of the array contain the min(P,N)-by-N upper trapezoidal matrix T (T is upper triangular if P >= N); the elements below the diagonal, with the array TAUB, represent the orthogonal matrix Z as a product of elementary reflectors (see Further Details). 🌸
  • LDB — INTEGER The leading dimension of the array B. LDB >= max(1,P). 🦋
  • TAUB
  • TAU — DOUBLE PRECISION array, dimension (min(P,N)). These are the scalar factors of the elementary reflectors that represent the orthogonal matrix Z — peep Further Details down below for the full tea, bestie. 💅
  • WORK — DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, then WORK(1) returns the optimal LWORK. She's a little self-reporting queen like that. ✨
  • LWORK — INTEGER. It's the dimension of the array WORK, and honestly the bar is:
LWORK >= max(1,N,M,P).

For optimum performance you want:

LWORK >= max(N,M,P)*max(NB1,NB2,NB3),

where NB1 is the optimal blocksize for the RQ factorization of an M-by-N matrix, NB2 is the optimal blocksize for the QR factorization of a P-by-N matrix, and NB3 is the optimal blocksize for a call of DORMRQ. Three block sizes, three whole moods. 🫶

And now the fun part: if LWORK = -1, then a workspace query is assumed. The routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. It's giving "just checking the size, no notes." 😌

  • INFO — INTEGER, the vibe report:
= 0:  successful exit
< 0:  if INF0= -i, the i-th argument had an illegal value.
ngl bestie if INFO comes back negative it's because the i-th argument had an illegal value. Somebody passed something cursed and it got caught. 🚨

👑 Author 👑

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

🔍 Further Details: 🔍

Okay so the matrix Q is represented as a product of elementary reflectors:

   Q = H(1) H(2) . . . H(k), where k = min(m,n).

Each H(i) has the form:

   H(i) = I - taua * v * v**T

where taua is a real scalar, and v is a real vector with v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit in A(m-k+i,1:n-k+i-1), and taua in TAUA(i). 🌸

To form Q explicitly, use LAPACK subroutine DORGRQ. To use Q to update another matrix, use LAPACK subroutine DORMRQ. iykyk. 💖

And the matrix Z is represented as a product of elementary reflectors:

   Z = H(1) H(2) . . . H(k), where k = min(p,n).

Each H(i) has the form:

   H(i) = I - taub * v * v**T

where taub is a real scalar, and v is a real vector with v(1:i-1) = 0 and v(i) = 1; v(i+1:p) is stored on exit in B(i+1:p,i), and taub in TAUB(i). 🦋

To form Z explicitly, use LAPACK subroutine DORGQR. To use Z to update another matrix, use LAPACK subroutine DORMQR. Two matrices, two reflector families, zero chill. ✨


🎀 subroutine dggsvp3 🎀

The whole signature, verbatim, because we do NOT paraphrase signatures in this house:

subroutine dggsvp3 (character JOBU, character JOBV, character JOBQ, integer
    M, integer P, integer N, double precision, dimension( lda, * ) A,
    integer LDA, double precision, dimension( ldb, * ) B, integer LDB,
    double precision TOLA, double precision TOLB, integer K, integer L,
    double precision, dimension( ldu, * ) U, integer LDU, double precision,
    dimension( ldv, * ) V, integer LDV, double precision, dimension( ldq, *
    ) Q, integer LDQ, integer, dimension( * ) IWORK, double precision,
    dimension( * ) TAU, double precision, dimension( * ) WORK, integer
    LWORK, integer INFO)

DGGSVP3 — say it with your chest. 👑

✨ Purpose ✨

DGGSVP3 computes orthogonal matrices U, V and Q such that:

                   N-K-L  K    L
 U**T*A*Q =     K ( 0    A12  A13 )  if M-K-L >= 0;
                L ( 0     0   A23 )
            M-K-L ( 0     0    0  )

                 N-K-L  K    L
        =     K ( 0    A12  A13 )  if M-K-L < 0;
            M-K ( 0     0   A23 )

                 N-K-L  K    L
 V**T*B*Q =   L ( 0     0   B13 )
            P-L ( 0     0    0  )

where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0, otherwise A23 is (M-K)-by-L upper trapezoidal. And K+L = the effective numerical rank of the (M+P)-by-N matrix (A**T,B**T)**T. 🔥

This decomposition is the preprocessing step for computing the Generalized Singular Value Decomposition (GSVD), see subroutine DGGSVD3. It's the opening act, and it ate. 💅

🌈 Parameters 🌈

  • JOBU — CHARACTER*1. Pick your fighter:
    • 'U': Orthogonal matrix U is computed;
    • 'N': U is not computed.
  • JOBV — CHARACTER*1. Round two:
    • 'V': Orthogonal matrix V is computed;
    • 'N': V is not computed.
  • JOBQ — CHARACTER*1. And the third one:
    • 'Q': Orthogonal matrix Q is computed;
    • 'N': Q is not computed.
  • M — INTEGER. The number of rows of the matrix A. M >= 0. Non-negotiable. ✋
  • P — INTEGER. The number of rows of the matrix B. P >= 0.
  • N — INTEGER. The number of columns of the matrices A and B. N >= 0.
  • A — DOUBLE PRECISION array, dimension (LDA,N). On entry, the M-by-N matrix A. On exit, A contains the triangular (or trapezoidal) matrix described in the Purpose section. She transforms. 🦋
  • LDA — INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • B — DOUBLE PRECISION array, dimension (LDB,N). On entry, the P-by-N matrix B. On exit, B contains the triangular matrix described in the Purpose section.
  • LDB — INTEGER. The leading dimension of the array B. LDB >= max(1,P).
  • TOLA — DOUBLE PRECISION.
  • TOLB — DOUBLE PRECISION.

TOLA and TOLB are the thresholds to determine the effective numerical rank of matrix B and a subblock of A. Generally, they are set to:

TOLA = MAX(M,N)*norm(A)*MACHEPS,
TOLB = MAX(P,N)*norm(B)*MACHEPS.

The size of TOLA and TOLB may affect the size of backward errors of the decomposition. So like… choose wisely bestie, these numbers have consequences. 😭

  • K — INTEGER.
  • L — INTEGER.

On exit, K and L specify the dimension of the subblocks described in the Purpose section. And K + L = effective numerical rank of (A**T,B**T)**T. They come as a pair, always. 🫶

  • U — DOUBLE PRECISION array, dimension (LDU,M). If JOBU = 'U', U contains the orthogonal matrix U. If JOBU = 'N', U is not referenced. She doesn't even get looked at, and honestly same. 💀
  • LDU — INTEGER. The leading dimension of the array U. LDU >= max(1,M) if JOBU = 'U'; LDU >= 1 otherwise.
  • V — DOUBLE PRECISION array, dimension (LDV,P). If JOBV = 'V', V contains the orthogonal matrix V. If JOBV = 'N', V is not referenced.
  • LDV — INTEGER. The leading dimension of the array V. LDV >= max(1,P) if JOBV = 'V'; LDV >= 1 otherwise.
  • Q — DOUBLE PRECISION array, dimension (LDQ,N). If JOBQ = 'Q', Q contains the orthogonal matrix Q. If JOBQ = 'N', Q is not referenced.
  • LDQ — INTEGER. The leading dimension of the array Q. LDQ >= max(1,N) if JOBQ = 'Q'; LDQ >= 1 otherwise.
  • IWORK — INTEGER array, dimension (N).
  • TAU — DOUBLE PRECISION array, dimension (N).
  • WORK — DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. Classic.
  • LWORK — INTEGER. The dimension of the array WORK.

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. Same energy as before, she's just peeking at the size. 👀

  • INFO — INTEGER:
= 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.

🔍 Further Details: 🔍

The subroutine uses LAPACK subroutine DGEQP3 for the QR factorization with column pivoting to detect the effective numerical rank of the a matrix. It may be replaced by a better rank determination strategy — so like, glow-up permitted. ✨

DGGSVP3 replaces the deprecated subroutine DGGSVP. > Deprecated means please stop calling it, bestie, it's retired. She handed over the crown. 👑


🌸 subroutine dgsvj0 🌸

subroutine dgsvj0 (character*1 JOBV, integer M, integer N, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( n ) D,
    double precision, dimension( n ) SVA, integer MV, double precision,
    dimension( ldv, * ) V, integer LDV, double precision EPS, double
    precision SFMIN, double precision TOL, integer NSWEEP, double precision,
    dimension( lwork ) WORK, integer LWORK, integer INFO)

DGSVJ0 pre-processor for the routine dgesvj. She's the opening number, the pre-game playlist. 🎀

✨ Purpose ✨

DGSVJ0 is called from DGESVJ as a pre-processor and that is its main purpose. It applies Jacobi rotations in the same way as DGESVJ does, but it does not check convergence (stopping criterion). Few tuning parameters (marked by [TP]) are available for the implementer. It's giving "I do the work, you handle the vibes." 💅

🌈 Parameters 🌈

  • JOBV — CHARACTER*1. Specifies whether the output from this procedure is used to compute the matrix V:
    • 'V': the product of the Jacobi rotations is accumulated by postmulyiplying the N-by-N array V. (See the description of V.)
    • 'A': the product of the Jacobi rotations is accumulated by postmulyiplying the MV-by-N array V. (See the descriptions of MV and V.)
    • 'N': the Jacobi rotations are not accumulated.
  • M — INTEGER. The number of rows of the input matrix A. M >= 0.
  • N — INTEGER. The number of columns of the input matrix A. M >= N >= 0. Both constraints, both honored. 🫶
  • A — DOUBLE PRECISION array, dimension (LDA,N).

On entry, M-by-N matrix A, such that A*diag(D) represents the input matrix.

On exit, A_onexit * D_onexit represents the input matrix A*diag(D) post-multiplied by a sequence of Jacobi rotations, where the rotation threshold and the total number of sweeps are given in TOL and NSWEEP, respectively. (See the descriptions of D, TOL and NSWEEP.)

She goes in one way and comes out another way. Main character transformation arc. 🦋

  • LDA — …
  • LDA — it's an INTEGER. The leading dimension of the array A, and LDA >= max(1,M). no wiggle room bestie 💅
  • D — DOUBLE PRECISION array, dimension (N). This one is lowkey doing the most: it accumulates the scaling factors from the fast scaled Jacobi rotations.

On entry, A*diag(D) represents the input matrix.

On exit, A_onexit*diag(D_onexit) represents the input matrix post-multiplied by a sequence of Jacobi rotations, where the rotation threshold and the total number of sweeps are given in TOL and NSWEEP, respectively.

(See the descriptions of A, TOL and NSWEEP.) 🦋

  • SVA — DOUBLE PRECISION array, dimension (N).

On entry, SVA contains the Euclidean norms of the columns of the matrix A*diag(D).

On exit, SVA contains the Euclidean norms of the columns of the matrix onexit*diag(D_onexit). ✨

  • MV — INTEGER.
    • If JOBV = 'A', then MV rows of V are post-multipled by a sequence of Jacobi rotations.
    • If JOBV = 'N', then MV is not referenced.
  • V — DOUBLE PRECISION array, dimension (LDV,N).
    • If JOBV = 'V' then N rows of V are post-multipled by a sequence of Jacobi rotations.
    • If JOBV = 'A' then MV rows of V are post-multipled by a sequence of Jacobi rotations.
    • If JOBV = 'N', then V is not referenced.
  • LDV — INTEGER. The leading dimension of the array V, and LDV >= 1.
    • If JOBV = 'V', then LDV >= N.
    • If JOBV = 'A', then LDV >= MV.
  • EPS — DOUBLE PRECISION. and it literally just is EPS = DLAMCH('Epsilon'). iconic, no notes 🎀
  • SFMIN — DOUBLE PRECISION. same energy: SFMIN = DLAMCH('Safe Minimum'). 💖
  • TOL — DOUBLE PRECISION. This is the threshold for Jacobi rotations, bestie. For a pair A(:,p), A(:,q) of pivot columns, the Jacobi rotation is applied only if DABS(COS(angle(A(:,p),A(:,q)))) > TOL. if it doesn't clear the bar, it doesn't get the rotation, periodt. 👑
  • NSWEEP — INTEGER. The number of sweeps of Jacobi rotations to be performed. that's the whole job description fr fr.
  • WORK — DOUBLE PRECISION array, dimension (LWORK). just the workspace, living its life.
  • LWORK — INTEGER. The dimension of WORK, and LWORK >= M. don't skimp.
  • INFO — INTEGER.
    • = 0: successful exit. we love to see it 🌈
    • < 0: if INFO = -i, then the i-th argument had an illegal value. 💀 yeah somebody passed something cursed.

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

🫶 Further Details:

DGSVJ0 is used just to enable DGESVJ to call a simplified version of itself to work on a submatrix of the original matrix.

💜 Contributors:

Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)

😭 Bugs, Examples and Comments:

Please report all bugs and send interesting test examples and comments to drmac@math.hr. Thank you.


🌸 subroutine dgsvj1

subroutine dgsvj1 (character*1 JOBV, integer M, integer N, integer N1,
    double precision, dimension( lda, * ) A, integer LDA, double precision,
    dimension( n ) D, double precision, dimension( n ) SVA, integer MV,
    double precision, dimension( ldv, * ) V, integer LDV, double precision
    EPS, double precision SFMIN, double precision TOL, integer NSWEEP,
    double precision, dimension( lwork ) WORK, integer LWORK, integer INFO)

DGSVJ1 pre-processor for the routine dgesvj, applies Jacobi rotations targeting only particular pivots.

Purpose:

DGSVJ1 is called from DGESVJ as a pre-processor and that is its main purpose. It applies Jacobi rotations in the same way as DGESVJ does, but it targets only particular pivots and it does not check convergence (stopping criterion). Few tuning parameters (marked by [TP]) are available for the implementer.

Further Details 🫶

DGSVJ1 applies few sweeps of Jacobi rotations in the column space of the input M-by-N matrix A. The pivot pairs are taken from the (1,2) off-diagonal block in the corresponding N-by-N Gram matrix A^T * A. The block-entries (tiles) of the (1,2) off-diagonal block are marked by the [x]'s in the following scheme:

   | *  *  * [x] [x] [x]|
   | *  *  * [x] [x] [x]|    Row-cycling in the nblr-by-nblc [x] blocks.
   | *  *  * [x] [x] [x]|    Row-cyclic pivoting inside each [x] block.
   |[x] [x] [x] *  *  * |
   |[x] [x] [x] *  *  * |
   |[x] [x] [x] *  *  * |

In terms of the columns of A, the first N1 columns are rotated 'against' the remaining N-N1 columns, trying to increase the angle between the corresponding subspaces. The off-diagonal block is N1-by-(N-N1) and it is tiled using quadratic tiles of side KBL. Here, KBL is a tuning parameter. The number of sweeps is given in NSWEEP and the orthogonality threshold is given in TOL. ✨

Parameters 💅

  • JOBV — CHARACTER*1. Specifies whether the output from this procedure is used to compute the matrix V:
    • = 'V': the product of the Jacobi rotations is accumulated by postmulyiplying the N-by-N array V. (See the description of V.)
    • = 'A': the product of the Jacobi rotations is accumulated by postmulyiplying the MV-by-N array V. (See the descriptions of MV and V.)
    • = 'N': the Jacobi rotations are not accumulated.
  • M — INTEGER. The number of rows of the input matrix A. M >= 0.
  • N — INTEGER. The number of columns of the input matrix A. M >= N >= 0.
  • N1 — INTEGER. N1 specifies the 2 x 2 block partition, the first N1 columns are rotated 'against' the remaining N-N1 columns of A. 🦋
  • A — DOUBLE PRECISION array, dimension (LDA,N).

On entry, M-by-N matrix A, such that A*diag(D) represents the input matrix.

On exit, A_onexit * D_onexit represents the input matrix A*diag(D) post-multiplied by a sequence of Jacobi rotations, where the rotation threshold and the total number of sweeps are given in TOL and NSWEEP, respectively.

(See the descriptions of N1, D, TOL and NSWEEP.)

  • LDA — INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • D — DOUBLE PRECISION array, dimension (N). The array D accumulates the scaling factors from the fast scaled Jacobi rotations.

On entry, A*diag(D) represents the input matrix.

On exit, A_onexit*diag(D_onexit) represents the input matrix post-multiplied by a sequence of Jacobi rotations, where the rotation threshold and the total number of sweeps are given in TOL and NSWEEP, respectively.

(See the descriptions of N1, A, TOL and NSWEEP.)

  • SVA — DOUBLE PRECISION array, dimension (N).

On entry, SVA contains the Euclidean norms of the columns of the matrix A*diag(D).

On exit, SVA contains the Euclidean norms of the columns of the matrix onexit*diag(D_onexit). 💖

  • MV — INTEGER.
    • If JOBV = 'A', then MV rows of V are post-multipled by a sequence of Jacobi rotations.
    • If JOBV = 'N', then MV is not referenced.
  • V — DOUBLE PRECISION array, dimension (LDV,N).
    • If JOBV = 'V', then N rows of V are post-multipled by a sequence of Jacobi rotations.
    • If JOBV = 'A', then MV rows of V are post-multipled by a sequence of Jacobi rotations.
    • If JOBV = 'N', then V is not referenced.
  • LDV — INTEGER. The leading dimension of the array V, LDV >= 1.
    • If JOBV = 'V', LDV >= N.
    • If JOBV = 'A', LDV >= MV.
  • EPS — DOUBLE PRECISION. EPS = DLAMCH('Epsilon').
  • SFMIN — DOUBLE PRECISION. SFMIN = DLAMCH('Safe Minimum').
  • TOL — DOUBLE PRECISION. TOL is the threshold for Jacobi rotations. For a pair A(:,p), A(:,q) of pivot columns, the Jacobi rotation is applied only if DABS(COS(angle(A(:,p),A(:,q)))) > TOL.
  • NSWEEP — INTEGER. NSWEEP is the number of sweeps of Jacobi rotations to be performed.
  • WORK — DOUBLE PRECISION array, dimension (LWORK).
  • LWORK — INTEGER. LWORK is the dimension of WORK. LWORK >= M.
  • INFO — INTEGER.
    • = 0: successful exit. 🌈
    • < 0: if INFO = -i, then the i-th argument had an illegal value. 💀

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

💜 Contributors:

Zlatko Drmac (Zagreb, Croatia) and Kresimir Veselic (Hagen, Germany)


🦋 subroutine dhsein

subroutine dhsein (character SIDE, character EIGSRC, character INITV,
    logical, dimension( * ) SELECT, integer N, double precision, dimension(
    ldh, * ) H, integer LDH, double precision, dimension( * ) WR, double
    precision, dimension( * ) WI, double precision, dimension( ldvl, * ) VL,
    integer LDVL, double precision, dimension( ldvr, * ) VR, integer LDVR,
    integer MM, integer M, double precision, dimension( * ) WORK, integer,
    dimension( * ) IFAILL, integer, dimension( * ) IFAILR, integer INFO)

DHSEIN

Purpose:

DHSEIN uses inverse iteration to find specified right and/or left eigenvectors of a real upper Hessenberg matrix H. 🎀

The right eigenvector x and the left eigenvector y of the matrix H corresponding to an eigenvalue w are defined by:

             H * x = w * x,     y**h * H = w * y**h

where y**h denotes the conjugate transpose of the vector y. ✨

Parameters 👑

  • SIDE
  • SIDE is CHARACTER*1 — bestie, this one decides which eigenvectors we're even pulling up:
    • = 'R': right eigenvectors only, no lefties invited;
    • = 'L': left eigenvectors only, right side stays unbothered;
    • = 'B': both right AND left, we're doing the most 💅.
  • EIGSRC is CHARACTER*1 — it tells us where the eigenvalues in (WR,WI) came from, and honestly the vibe depends on it:
    • = 'Q': the eigenvalues were found using DHSEQR; so like, if H has zero subdiagonal elements and is therefore block-triangular, then the j-th eigenvalue can be assumed to be an eigenvalue of the block containing the j-th row/column. This lil property is what lets DHSEIN do inverse iteration on just one diagonal block. iconic shortcut ✨
    • = 'N': no assumptions, periodt — no correspondence between eigenvalues and diagonal blocks is assumed. In this case DHSEIN has to always do inverse iteration using the whole matrix H. no skipping, bestie 😭
  • INITV is CHARACTER*1:
    • = 'N': no initial vectors are supplied, we start fresh;
    • = 'U': user-supplied initial vectors are stored in the arrays VL and/or VR (your starter pack, your choice 🎀).
  • SELECT is a LOGICAL array, dimension (N) — this is the guest list, it specifies the eigenvectors to be computed. To select the real eigenvector corresponding to a real eigenvalue WR(j), SELECT(j) must be set to .TRUE.. To select the complex eigenvector corresponding to a complex eigenvalue (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)), either SELECT(j) or SELECT(j+1) or both must be set to .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is .FALSE.. yeah it edits your list, that's just how it is 💅
  • N is INTEGER — the order of the matrix H. N >= 0.
  • H is a DOUBLE PRECISION array, dimension (LDH,N) — the upper Hessenberg matrix H. And heads up bestie: if a NaN is detected in H, the routine will return with INFO=-6. 💀
  • LDH is INTEGER — the leading dimension of the array H. LDH >= max(1,N).
  • WR is a DOUBLE PRECISION array, dimension (N).
  • WI is a DOUBLE PRECISION array, dimension (N).

On entry, the real and imaginary parts of the eigenvalues of H; a complex conjugate pair of eigenvalues must be stored in consecutive elements of WR and WI.

On exit, WR may have been altered, since close eigenvalues are perturbed slightly in searching for independent eigenvectors. not me gaslighting your eigenvalues 🫶

  • VL is a DOUBLE PRECISION array, dimension (LDVL,MM).

On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must contain starting vectors for the inverse iteration for the left eigenvectors; the starting vector for each eigenvector must be in the same column(s) in which the eigenvector will be stored.

On exit, if SIDE = 'L' or 'B', the left eigenvectors specified by SELECT will be stored consecutively in the columns of VL, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part.

If SIDE = 'R', VL is not referenced. (not me, not today 🙈)

  • LDVL is INTEGER — the leading dimension of the array VL. LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise.
  • VR is a DOUBLE PRECISION array, dimension (LDVR,MM).

On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must contain starting vectors for the inverse iteration for the right eigenvectors; the starting vector for each eigenvector must be in the same column(s) in which the eigenvector will be stored.

On exit, if SIDE = 'R' or 'B', the right eigenvectors specified by SELECT will be stored consecutively in the columns of VR, in the same order as their eigenvalues. A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part.

If SIDE = 'L', VR is not referenced.

  • LDVR is INTEGER — the leading dimension of the array VR. LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise.
  • MM is INTEGER — the number of columns in the arrays VL and/or VR. MM >= M.
  • M is INTEGER — the number of columns in the arrays VL and/or VR required to store the eigenvectors; each selected real eigenvector occupies one column and each selected complex eigenvector occupies two columns. simple math, bestie 🧮
  • WORK is a DOUBLE PRECISION array, dimension ((N+2)*N).
  • IFAILL is an INTEGER array, dimension (MM).

If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left eigenvector in the i-th column of VL (corresponding to the eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the eigenvector converged satisfactorily. If the i-th and (i+1)th columns of VL hold a complex eigenvector, then IFAILL(i) and IFAILL(i+1) are set to the same value. matching besties fr fr 👯

If SIDE = 'R', IFAILL is not referenced.

  • IFAILR is an INTEGER array, dimension (MM).

If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right eigenvector in the i-th column of VR (corresponding to the eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the eigenvector converged satisfactorily. If the i-th and (i+1)th columns of VR hold a complex eigenvector, then IFAILR(i) and IFAILR(i+1) are set to the same value.

If SIDE = 'L', IFAILR is not referenced.

  • INFO is INTEGER:
    • = 0: successful exit, we ate 🔥
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, i is the number of eigenvectors which failed to converge; see IFAILL and IFAILR for further details.

👑 Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🌸 Further Details 🌸

Each eigenvector is normalized so that the element of largest
magnitude has magnitude 1; here the magnitude of a complex number
(x,y) is taken to be |x|+|y|.

okay so that's the normalization lore, no cap 💖


✨ subroutine dhseqr ✨

subroutine dhseqr (character JOB, character COMPZ, integer N, integer ILO,
    integer IHI, double precision, dimension( ldh, * ) H, integer LDH,
    double precision, dimension( * ) WR, double precision, dimension( * )
    WI, double precision, dimension( ldz, * ) Z, integer LDZ, double
    precision, dimension( * ) WORK, integer LWORK, integer INFO)

💫 DHSEQR 💫

🎀 Purpose 🎀

DHSEQR computes the eigenvalues of a Hessenberg matrix H and, optionally, the matrices T and Z from the Schur decomposition

H = Z T Z**T,

where T is an upper quasi-triangular matrix (the Schur form), and Z is the orthogonal matrix of Schur vectors. like, it's giving decomposition moment ✨

Optionally Z may be postmultiplied into an input orthogonal matrix Q so that this routine can give the Schur factorization of a matrix A which has been reduced to the Hessenberg form H by the orthogonal matrix Q:

A = Q*H*Q**T = (QZ)*T*(QZ)**T.

bestie it's just remixing Q into the mix 💅


🌈 Parameters 🌈

  • JOB is CHARACTER*1:
    • = 'E': compute eigenvalues only;
    • = 'S': compute eigenvalues and the Schur form T.
  • COMPZ is CHARACTER*1:
    • = 'N': no Schur vectors are computed, we're keeping it minimal;
    • = 'I': Z is initialized to the unit matrix and the matrix Z of Schur vectors of H is returned;
    • = 'V': Z must contain an orthogonal matrix Q on entry, and the product Q*Z is returned.
  • N is INTEGER — the order of the matrix H. N >= 0.
  • ILO is INTEGER.
  • IHI is INTEGER.

It is assumed that H is already upper triangular in rows and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally set by a previous call to DGEBAL, and then passed to ZGEHRD when the matrix output by DGEBAL is reduced to Hessenberg form. Otherwise ILO and IHI should be set to 1 and N respectively. If N > 0, then 1 <= ILO <= IHI <= N. If N = 0, then ILO = 1 and IHI = 0. the pipeline is real y'all 🫶

  • H is a DOUBLE PRECISION array, dimension (LDH,N).

On entry, the upper Hessenberg matrix H.

On exit, if INFO = 0 and JOB = 'S', then H contains the upper quasi-triangular matrix T from the Schur decomposition (the Schur form); 2-by-2 diagonal blocks (corresponding to complex conjugate pairs of eigenvalues) are returned in standard form, with H(i,i) = H(i+1,i+1) and H(i+1,i)*H(i,i+1) < 0. If INFO = 0 and JOB = 'E', the contents of H are unspecified on exit. (The output value of H when INFO > 0 is given under the description of INFO below.) so like, don't come for H if you asked for 'E', it's allowed to be a mystery 🙈

Unlike earlier versions of DHSEQR, this subroutine may explicitly H(i,j) = 0 for i > j and j = 1, 2, ... ILO-1 or j = IHI+1, IHI+2, ... N. glow up behavior, honestly 💅

  • LDH is INTEGER — the leading dimension of the array H. LDH >= max(1,N).
  • WR is a DOUBLE PRECISION array, dimension (N).
  • WI is a DOUBLE PRECISION array, dimension (N).

okay so bestie, WR and WI are the real and imaginary parts, respectively, of the computed eigenvalues. If two eigenvalues are computed as a complex conjugate pair, they are stored in consecutive elements of WR and WI, say the i-th and (i+1)th, with WI(i) > 0 and WI(i+1) < 0. If JOB = 'S', the eigenvalues are stored in the same order as on the diagonal of the Schur form returned in H, with WR(i) = H(i,i) and, if H(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) = sqrt(-H(i+1,i)*H(i,i+1)) and WI(i+1) = -WI(i). 💅 no cap.

  • Z — Z is DOUBLE PRECISION array, dimension (LDZ,N). If COMPZ = 'N', Z is not referenced. If COMPZ = 'I', on entry Z need not be set and on exit, if INFO = 0, Z contains the orthogonal matrix Z of the Schur vectors of H. If COMPZ = 'V', on entry Z must contain an N-by-N matrix Q, which is assumed to be equal to the unit matrix except for the submatrix Z(ILO:IHI,ILO:IHI). On exit, if INFO = 0, Z contains Q*Z. Normally Q is the orthogonal matrix generated by DORGHR after the call to DGEHRD which formed the Hessenberg matrix H. (The output value of Z when INFO > 0 is given under the description of INFO below.) 💖
  • LDZ — LDZ is INTEGER. The leading dimension of the array Z. If COMPZ = 'I' or COMPZ = 'V', then LDZ >= MAX(1,N). Otherwise, LDZ >= 1. ✨
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). On exit, if INFO = 0, WORK(1) returns an estimate of the optimal value for LWORK. 🌸
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,N) is sufficient and delivers very good and sometimes optimal performance. However, LWORK as large as 11*N may be required for optimal performance. A workspace query is recommended to determine the optimal workspace size.

If LWORK = -1, then DHSEQR does a workspace query. In this case, DHSEQR checks the input parameters and estimates the optimal workspace size for the given values of N, ILO and IHI. The estimate is returned in WORK(1). No error message related to LWORK is issued by XERBLA. Neither H nor Z are accessed. 💅

  • INFO — INFO is INTEGER
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, DHSEQR failed to compute all of the eigenvalues. Elements 1:ilo-1 and i+1:n of WR and WI contain those eigenvalues which have been successfully computed. (Failures are rare.)

If INFO > 0 and JOB = 'E', then on exit, the remaining unconverged eigenvalues are the eigenvalues of the upper Hessenberg matrix rows and columns ILO through INFO of the final, output value of H.

If INFO > 0 and JOB = 'S', then on exit

(*)  (initial value of H)*U  = U*(final value of H)

where U is an orthogonal matrix. The final value of H is upper Hessenberg and quasi-triangular in rows and columns INFO+1 through IHI.

If INFO > 0 and COMPZ = 'V', then on exit

(final value of Z)  =  (initial value of Z)*U

where U is the orthogonal matrix in (*) (regardless of the value of JOB.)

If INFO > 0 and COMPZ = 'I', then on exit

(final value of Z)  = U

where U is the orthogonal matrix in (*) (regardless of the value of JOB.)

If INFO > 0 and COMPZ = 'N', then Z is not accessed. 😭


👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

💖 Contributors:

Karen Braman and Ralph Byers, Department of Mathematics, University of Kansas, USA

🔥 Further Details:

Default values supplied by ILAENV(ISPEC,'DHSEQR',JOB(:1)//COMPZ(:1),N,ILO,IHI,LWORK). It is suggested that these defaults be adjusted in order to attain best performance in each particular computational environment.

  • ISPEC=12: The DLAHQR vs DLAQR0 crossover point. Default: 75. (Must be at least 11.) periodt.
  • ISPEC=13: Recommended deflation window size. This depends on ILO, IHI and NS. NS is the number of simultaneous shifts returned by ILAENV(ISPEC=15). (See ISPEC=15 below.) The default for (IHI-ILO+1) <= 500 is NS. The default for (IHI-ILO+1) > 500 is 3*NS/2.
  • ISPEC=14: Nibble crossover point. (See IPARMQ for details.) Default: 14% of deflation window size.
  • ISPEC=15: Number of simultaneous shifts in a multishift QR iteration.

If IHI-ILO+1 is ...

greater than      ...but less    ... the
or equal to ...      than        default is

     1               30          NS =   2(+)
    30               60          NS =   4(+)
    60              150          NS =  10(+)
   150              590          NS =  **
   590             3000          NS =  64
  3000             6000          NS = 128
  6000             infinity      NS = 256

(+) By default some or all matrices of this order are passed to the implicit double shift routine DLAHQR and this parameter is ignored. See ISPEC=12 above and comments in IPARMQ for details.

(**) The asterisks (**) indicate an ad-hoc function of N increasing from 10 to 64.

  • ISPEC=16: Select structured matrix multiply. If the number of simultaneous shifts (specified by ISPEC=15) is less than 14, then the default for ISPEC=16 is 0. Otherwise the default for ISPEC=16 is 2. 🌈

📚 References:

K. Braman, R. Byers and R. Mathias, The Multi-Shift QR Algorithm Part I: Maintaining Well Focused Shifts, and Level 3 Performance, SIAM Journal of Matrix Analysis, volume 23, pages 929--947, 2002.

K. Braman, R. Byers and R. Mathias, The Multi-Shift QR Algorithm Part II: Aggressive Early Deflation, SIAM Journal of Matrix Analysis, volume 23, pages 948--973, 2002.


🦋 subroutine dla_lin_berr (integer N, integer NZ, integer NRHS, double precision, dimension( n, nrhs ) RES, double precision, dimension( n, nrhs ) AYB, double precision, dimension( nrhs ) BERR)

DLA_LIN_BERR computes a component-wise relative backward error.

✨ Purpose:

DLA_LIN_BERR computes component-wise relative backward error from the formula

max(i) ( abs(R(i)) / ( abs(op(A_s))*abs(Y) + abs(B_s) )(i) )

where abs(Z) is the component-wise absolute value of the matrix or vector Z.

🎀 Parameters

  • N — N is INTEGER. The number of linear equations, i.e., the order of the matrix A. N >= 0.
  • NZ — NZ is INTEGER. We add (NZ+1)*SLAMCH( 'Safe minimum' ) to R(i) in the numerator to guard against spuriously zero residuals. Default value is N.
  • NRHS — NRHS is INTEGER. The number of right hand sides, i.e., the number of columns of the matrices AYB, RES, and BERR. NRHS >= 0.
  • RES — RES is DOUBLE PRECISION array, dimension (N,NRHS). The residual matrix, i.e., the matrix R in the relative backward error formula above.
  • AYB — AYB is DOUBLE PRECISION array, dimension (N, NRHS). The denominator in the relative backward error formula above, i.e., the matrix abs(op(A_s))*abs(Y) + abs(B_s). The matrices A, Y, and B are from iterative refinement (see dla_gerfsx_extended.f).
  • BERR — BERR is DOUBLE PRECISION array, dimension (NRHS). The component-wise relative backward error from the formula above.

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🧚 subroutine dla_wwaddw (integer N, double precision, dimension( * ) X, double precision, dimension( * ) Y, double precision, dimension( * ) W)

DLA_WWADDW adds a vector into a doubled-single vector.

✨ Purpose:

DLA_WWADDW adds a vector W into a doubled-single vector (X, Y).

This works for all extant IBM's hex and binary floating point arithmetic, but not for decimal.

🎀 Parameters

  • N — N is INTEGER. The length of vectors X, Y, and W.
  • X — X is DOUBLE PRECISION array, dimension (N). The first part of the doubled-single accumulation vector.
  • Y — Y is DOUBLE PRECISION array, dimension (N). The second part of the doubled-single accumulation vector.
  • W — W is DOUBLE PRECISION array, dimension (N). The vector to be added.

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

   subroutine dlals0 (integer ICOMPQ, integer NL, integer NR, integer SQRE,
       integer NRHS, double precision, dimension( ldb, * ) B, integer LDB,
       double precision, dimension( ldbx, * ) BX, integer LDBX, integer,
       dimension( * ) PERM, integer GIVPTR, integer, dimension( ldgcol, * )
       GIVCOL, integer LDGCOL, double precision, dimension( ldgnum, * ) GIVNUM,
       integer LDGNUM, double precision, dimension( ldgnum, * ) POLES, double
       precision, dimension( * ) DIFL, double precision, dimension( ldgnum, * )
       DIFR, double precision, dimension( * ) Z, integer K, double precision C,
       double precision S, double precision, dimension( * ) WORK, integer INFO)

okay bestie, meet DLALS0 💖 — the girl who does the back-multiplying. Not the forward one. The back one. There's a difference and she takes it very personally.

DLALS0 applies back multiplying factors in solving the least squares problem using divide and conquer SVD approach. Used by sgelsd. 🫶


🌸 Purpose 🌸

DLALS0 applies back the multiplying factors of either the left or the right singular vector matrix of a diagonal matrix appended by a row to the right hand side matrix B in solving the least squares problem using the divide-and-conquer SVD approach. 🦋

For the left singular vector matrix, three types of orthogonal matrices are involved:

  1. (1L) Givens rotations: the number of such rotations is GIVPTR; the pairs of columns/rows they were applied to are stored in GIVCOL; and the C- and S-values of these rotations are stored in GIVNUM.
  2. (2L) Permutation. The (NL+1)-st row of B is to be moved to the first row, and for J=2:N, PERM(J)-th row of B is to be moved to the J-th row.
  3. (3L) The left singular vector matrix of the remaining matrix.

For the right singular vector matrix, four types of orthogonal matrices are involved:

  1. (1R) The right singular vector matrix of the remaining matrix.
  2. (2R) If SQRE = 1, one extra Givens rotation to generate the right null space.
  3. (3R) The inverse transformation of (2L).
  4. (4R) The inverse transformation of (1L).

✨ Parameters ✨

ICOMPQ

ICOMPQ is INTEGER. Specifies whether singular vectors are to be computed in factored form:

  • = 0: Left singular vector matrix.
  • = 1: Right singular vector matrix.

NL

NL is INTEGER. The row dimension of the upper block. NL >= 1. 💜

NR

NR is INTEGER. The row dimension of the lower block. NR >= 1.

SQRE

SQRE is INTEGER.

  • = 0: the lower block is an NR-by-NR square matrix.
  • = 1: the lower block is an NR-by-(NR+1) rectangular matrix.

The bidiagonal matrix has row dimension N = NL + NR + 1, and column dimension M = N + SQRE. 🎀

NRHS

NRHS is INTEGER. The number of columns of B and BX. NRHS must be at least 1.

B

B is DOUBLE PRECISION array, dimension ( LDB, NRHS ).

On input, B contains the right hand sides of the least squares problem in rows 1 through M. On output, B contains the solution X in rows 1 through N. 🫶

LDB

LDB is INTEGER. The leading dimension of B. LDB must be at least max(1,MAX( M, N )).

BX

BX is DOUBLE PRECISION array, dimension ( LDBX, NRHS ).

LDBX

LDBX is INTEGER. The leading dimension of BX.

PERM

PERM is INTEGER array, dimension ( N ). The permutations (from deflation and sorting) applied to the two blocks.

GIVPTR

GIVPTR is INTEGER. The number of Givens rotations which took place in this subproblem.

GIVCOL

GIVCOL is INTEGER array, dimension ( LDGCOL, 2 ). Each pair of numbers indicates a pair of rows/columns involved in a Givens rotation.

LDGCOL

LDGCOL is INTEGER. The leading dimension of GIVCOL, must be at least N.

GIVNUM

GIVNUM is DOUBLE PRECISION array, dimension ( LDGNUM, 2 ). Each number indicates the C or S value used in the corresponding Givens rotation.

LDGNUM

LDGNUM is INTEGER. The leading dimension of arrays DIFR, POLES and GIVNUM, must be at least K.

POLES

POLES is DOUBLE PRECISION array, dimension ( LDGNUM, 2 ). On entry, POLES(1:K, 1) contains the new singular values obtained from solving the secular equation, and POLES(1:K, 2) is an array containing the poles in the secular equation.

DIFL

DIFL is DOUBLE PRECISION array, dimension ( K ). On entry, DIFL(I) is the distance between I-th updated (undeflated) singular value and the I-th (undeflated) old singular value.

DIFR

DIFR is DOUBLE PRECISION array, dimension ( LDGNUM, 2 ). On entry, DIFR(I, 1) contains the distances between I-th updated (undeflated) singular value and the I+1-th (undeflated) old singular value. And DIFR(I, 2) is the normalizing factor for the I-th right singular vector.

Z

Z is DOUBLE PRECISION array, dimension ( K ). Contain the components of the deflation-adjusted updating row vector. 🌈

K

K is INTEGER. Contains the dimension of the non-deflated matrix. This is the order of the related secular equation. 1 <= K <= N. 👑

C

C is DOUBLE PRECISION. C contains garbage if SQRE = 0 and the C-value of a Givens rotation related to the right null space if SQRE = 1.

not me reading "garbage" in a manpage 💀 yeah bestie it literally says garbage. Do not trust it. Do not look at it.

S

S is DOUBLE PRECISION. S contains garbage if SQRE = 0 and the S-value of a Givens rotation related to the right null space if SQRE = 1.

WORK

WORK is DOUBLE PRECISION array, dimension ( K ).

INFO

INFO is INTEGER.

  • = 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.

🧚 Contributors 🧚

  • Ming Gu and Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA
  • Osni Marques, LBNL/NERSC, USA

ok and now her bestie enters the chat 💅

   subroutine dlalsa (integer ICOMPQ, integer SMLSIZ, integer N, integer NRHS,
       double precision, dimension( ldb, * ) B, integer LDB, double precision,
       dimension( ldbx, * ) BX, integer LDBX, double precision, dimension( ldu,
       * ) U, integer LDU, double precision, dimension( ldu, * ) VT, integer,
       dimension( * ) K, double precision, dimension( ldu, * ) DIFL, double
       precision, dimension( ldu, * ) DIFR, double precision, dimension( ldu, *
       ) Z, double precision, dimension( ldu, * ) POLES, integer, dimension( *
       ) GIVPTR, integer, dimension( ldgcol, * ) GIVCOL, integer LDGCOL,
       integer, dimension( ldgcol, * ) PERM, double precision, dimension( ldu,
       * ) GIVNUM, double precision, dimension( * ) C, double precision,
       dimension( * ) S, double precision, dimension( * ) WORK, integer,
       dimension( * ) IWORK, integer INFO)

DLALSA computes the SVD of the coefficient matrix in compact form. Used by sgelsd. 💖

🌸 Purpose 🌸

DLALSA is an intermediate step in solving the least squares problem by computing the SVD of the coefficient matrix in compact form (The singular vectors are computed as products of simple orthorgonal matrices.).

If ICOMPQ = 0, DLALSA applies the inverse of the left singular vector matrix of an upper bidiagonal matrix to the right hand side; and if ICOMPQ = 1, DLALSA applies the right singular vector matrix to the right hand side. The singular vector matrices were generated in compact form by DLALSA. 🦋


✨ Parameters ✨

ICOMPQ

ICOMPQ is INTEGER. Specifies whether the left or the right singular vector matrix is involved.

  • = 0: Left singular vector matrix
  • = 1: Right singular vector matrix

SMLSIZ

SMLSIZ is INTEGER. The maximum size of the subproblems at the bottom of the computation tree. 🌳

N

N is INTEGER. The row and column dimensions of the upper bidiagonal matrix.

NRHS

NRHS is INTEGER. The number of columns of B and BX. NRHS must be at least 1.

B

B is DOUBLE PRECISION array, dimension ( LDB, NRHS ).

On input, B contains the right hand sides of the least squares problem in rows 1 through M. On output, B contains the solution X in rows 1 through N. 🫶

LDB

LDB is INTEGER. The leading dimension of B in the calling subprogram. LDB must be at least max(1,MAX( M, N )).

BX

BX is DOUBLE PRECISION array, dimension ( LDBX, NRHS ). On exit, the result of applying the left or right singular vector matrix to B. ✨

LDBX

LDBX is INTEGER. The leading dimension of BX.

U

U is DOUBLE PRECISION array, dimension ( LDU, SMLSIZ ). On entry, U contains the left singular vector matrices of all subproblems at the bottom level.

LDU

LDU is INTEGER, LDU = > N. The leading dimension of arrays U, VT, DIFL, DIFR, POLES, GIVNUM, and Z.

VT

VT is DOUBLE PRECISION array, dimension ( LDU, SMLSIZ+1 ). On entry, VT**T contains the right singular vector matrices of all subproblems at the bottom level.

K

K is INTEGER array, dimension ( N ).

DIFL

DIFL is DOUBLE PRECISION array, dimension ( LDU, NLVL ), where NLVL = INT(log_2 (N/(SMLSIZ+1))) + 1. 💜

DIFR

DIFR is DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ). On entry, DIFL(*, I) and DIFR(*, 2 * I -1) record distances between singular values on the I-th level and singular values on the (I -1)-th level, and DIFR(*, 2 * I) record the normalizing factors of the right singular vectors matrices of subproblems on I-th level.

Z

  • Z — DOUBLE PRECISION array, dimension ( LDU, NLVL ). On entry, Z(1, I) contains the components of the deflation-adjusted updating row vector for subproblems on the I-th level. ✨
  • POLES — DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ). On entry, POLES(*, 2 * I -1: 2 * I) contains the new and old singular values involved in the secular equations on the I-th level. 💅
  • GIVPTR — INTEGER array, dimension ( N ). On entry, GIVPTR( I ) records the number of Givens rotations performed on the I-th problem on the computation tree. 🌀
  • GIVCOL — INTEGER array, dimension ( LDGCOL, 2 * NLVL ). On entry, for each I, GIVCOL(*, 2 * I - 1: 2 * I) records the locations of Givens rotations performed on the I-th level on the computation tree. 🌸
  • LDGCOL — INTEGER, LDGCOL = > N. The leading dimension of arrays GIVCOL and PERM. (yes bestie, it literally says = > N in the source, we don't make the rules 💀)
  • PERM — INTEGER array, dimension ( LDGCOL, NLVL ). On entry, PERM(*, I) records permutations done on the I-th level of the computation tree. 🎀
  • GIVNUM — DOUBLE PRECISION array, dimension ( LDU, 2 * NLVL ). On entry, GIVNUM(*, 2 *I -1 : 2 * I) records the C- and S-values of Givens rotations performed on the I-th level on the computation tree. ✨
  • C — DOUBLE PRECISION array, dimension ( N ). On entry, if the I-th subproblem is not square, C( I ) contains the C-value of a Givens rotation related to the right null space of the I-th subproblem. 💖
  • S — DOUBLE PRECISION array, dimension ( N ). On entry, if the I-th subproblem is not square, S( I ) contains the S-value of a Givens rotation related to the right null space of the I-th subproblem. 🦋
  • WORK — DOUBLE PRECISION array, dimension (N). 🛠️
  • IWORK — INTEGER array, dimension (3*N). 🧮
  • INFO — INTEGER. = 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.

Contributors:

Ming Gu and Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA

Osni Marques, LBNL/NERSC, USA


subroutine dlalsd

subroutine dlalsd (character UPLO, integer SMLSIZ, integer N, integer NRHS,
    double precision, dimension( * ) D, double precision, dimension( * ) E,
    double precision, dimension( ldb, * ) B, integer LDB, double precision
    RCOND, integer RANK, double precision, dimension( * ) WORK, integer,
    dimension( * ) IWORK, integer INFO)

DLALSD uses the singular value decomposition of A to solve the least squares problem. ✨

Purpose:

DLALSD uses the singular value decomposition of A to solve the least squares problem of finding X to minimize the Euclidean norm of each column of A*X-B, where A is N-by-N upper bidiagonal, and X and B are N-by-NRHS. The solution X overwrites B. 💅

The singular values of A smaller than RCOND times the largest singular value are treated as zero in solving the least squares problem; in this case a minimum norm solution is returned. The actual singular values are returned in D in ascending order. 📈

This code makes very mild assumptions about floating point arithmetic. It will work on machines with a guard digit in add/subtract, or on those binary machines without guard digits which subtract like the Cray XMP, Cray YMP, Cray C 90, or Cray 2. It could conceivably fail on hexadecimal or decimal machines without guard digits, but we know of none. 🧮

Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': D and E define an upper bidiagonal matrix.
    • = 'L': D and E define a lower bidiagonal matrix. (yes, two spaces, we keep it 💀)
  • SMLSIZ — SMLSIZ is INTEGER. The maximum size of the subproblems at the bottom of the computation tree. 🌳
  • N — N is INTEGER. The dimension of the bidiagonal matrix. N >= 0. 📏
  • NRHS — NRHS is INTEGER. The number of columns of B. NRHS must be at least 1. 🗂️
  • D — D is DOUBLE PRECISION array, dimension (N). On entry D contains the main diagonal of the bidiagonal matrix. On exit, if INFO = 0, D contains its singular values. 💎
  • E — E is DOUBLE PRECISION array, dimension (N-1). Contains the super-diagonal entries of the bidiagonal matrix. On exit, E has been destroyed. 💥
  • B — B is DOUBLE PRECISION array, dimension (LDB,NRHS). On input, B contains the right hand sides of the least squares problem. On output, B contains the solution X. 🎯
  • LDB — LDB is INTEGER. The leading dimension of B in the calling subprogram. LDB must be at least max(1,N). 📐
  • RCOND — RCOND is DOUBLE PRECISION. The singular values of A less than or equal to RCOND times the largest singular value are treated as zero in solving the least squares problem. If RCOND is negative, machine precision is used instead. For example, if diag(S)*X=B were the least squares problem, where diag(S) is a diagonal matrix of singular values, the solution would be X(i) = B(i) / S(i) if S(i) is greater than RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to RCOND*max(S). ⚖️
  • RANK — RANK is INTEGER. The number of singular values of A greater than RCOND times the largest singular value. 🏆
  • WORK — WORK is DOUBLE PRECISION array, dimension at least (9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2), where NLVL = max(0, INT(log_2 (N/(SMLSIZ+1))) + 1). 🛠️
  • IWORK — IWORK is INTEGER array, dimension at least (3*N*NLVL + 11*N). 🧮
  • INFO — INFO is INTEGER
    • = 0: successful exit.
    • < 0: if INFO = -i, the i-th argument had an illegal value.
    • > 0: The algorithm failed to compute a singular value while working on the submatrix lying in rows and columns INFO/(N+1) through MOD(INFO,N+1). 🚨

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Contributors:

Ming Gu and Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA

Osni Marques, LBNL/NERSC, USA


double precision function dlansf

double precision function dlansf (character NORM, character TRANSR,
    character UPLO, integer N, double precision, dimension( 0: * ) A, double
    precision, dimension( 0: * ) WORK)

DLANSF returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a symmetric matrix in RFP format. 🌈

Purpose:

DLANSF returns the value of the one norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric matrix A in RFP format. 💫

Returns

DLANSF

DLANSF = ( max(abs(A(i,j))), NORM = 'M' or 'm'
         (
         ( norm1(A),         NORM = '1', 'O' or 'o'
         (
         ( normI(A),         NORM = 'I' or 'i'
         (
         ( normF(A),         NORM = 'F', 'f', 'E' or 'e'

where norm1 denotes the one norm of a matrix (maximum column sum), normI denotes the infinity norm of a matrix (maximum row sum) and normF denotes the Frobenius norm of a matrix (square root of sum of squares). Note that max(abs(A(i,j))) is not a matrix norm. 🧠

Parameters

  • NORM — NORM is CHARACTER*1. Specifies the value to be returned in DLANSF as described above. 🎚️
  • TRANSR — TRANSR is CHARACTER*1. Specifies whether the RFP format of A is normal or transposed format.
    • = 'N': RFP format is Normal;
    • = 'T': RFP format is Transpose. 🔄
  • UPLO — UPLO is CHARACTER*1. On entry, UPLO specifies whether the RFP matrix A came from an upper or lower triangular matrix as follows:
    • = 'U': RFP A came from an upper triangular matrix;
    • = 'L': RFP A came from a lower triangular matrix. ⬆️⬇️
  • N — N is INTEGER. The order of the matrix A. N >= 0. When N = 0, DLANSF is set to zero. 0️⃣
  • A — A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ); On entry, the upper (if UPLO = 'U') or lower (if UPLO = 'L') part of the symmetric matrix A stored in RFP format. See the 'Notes' below for more details. Unchanged on exit. 📦
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)), where LWORK >= N when NORM = 'I' or '1' or 'O'; otherwise, WORK is not referenced. 🛠️

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details:

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6. 🔢

                 AP is Upper             AP is Lower

              00 01 02 03 04 05       00
                 11 12 13 14 15       10 11
                    22 23 24 25       20 21 22
                       33 34 35       30 31 32 33
                          44 45       40 41 42 43 44
                             55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows:

For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper.

For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower.

This covers the case N even and TRANSR = 'N'. ✨

       RFP A                   RFP A

      03 04 05                33 43 53
      13 14 15                00 44 54
      23 24 25                10 11 55
      33 34 35                20 21 22
      00 44 45                30 31 32
      01 11 55                40 41 42
      02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

        RFP A                   RFP A

   03 13 23 33 00 01 02    33 00 10 20 30 40 50
   04 14 24 34 44 11 12    43 44 11 21 31 41 51
   05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. We give an example where N = 5.

   AP is Upper                 AP is Lower

  00 01 02 03 04              00
     11 12 13 14              10 11
        22 23 24              20 21 22
           33 34              30 31 32 33
              44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows:

For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper.

For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower.

This covers the case N odd and TRANSR = 'N'. 🦋

       RFP A                   RFP A

      02 03 04                00 33 43
      12 13 14                10 11 44
      22 23 24                20 21 22
      00 33 34                30 31 32
      01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

        RFP A                   RFP A

   02 12 22 00 01             00 10 20 30 40 50
   03 13 23 33 11             33 11 21 31 41 51
   04 14 24 34 44             43 44 22 32 42 52

🌸 subroutine dlarscl2 🌸

subroutine dlarscl2 (integer M, integer N, double precision, dimension( * )
    D, double precision, dimension( ldx, * ) X, integer LDX)

DLARSCL2 performs reciprocal diagonal scaling on a matrix. slay

Purpose:

DLARSCL2 performs a reciprocal diagonal scaling on a matrix:

  x <-- inv(D) * x

where the diagonal matrix D is stored as a vector.

Eventually to be replaced by BLAS_dge_diag_scale in the new BLAS standard. 👀

Parameters

  • M — M is INTEGER. The number of rows of D and X. M >= 0.
  • N — N is INTEGER. The number of columns of X. N >= 0.
  • D — D is DOUBLE PRECISION array, dimension (M). Diagonal matrix D, stored as a vector of length M.
  • X — X is DOUBLE PRECISION array, dimension (LDX,N). On entry, the matrix X to be scaled by D. On exit, the scaled matrix. glow up ✨
  • LDX — LDX is INTEGER. The leading dimension of the matrix X. LDX >= M.

Author

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

💜 subroutine dlarz 💜

subroutine dlarz (character SIDE, integer M, integer N, integer L, double
    precision, dimension( * ) V, integer INCV, double precision TAU, double
    precision, dimension( ldc, * ) C, integer LDC, double precision,
    dimension( * ) WORK)

DLARZ applies an elementary reflector (as returned by stzrzf) to a general matrix. periodt.

Purpose:

DLARZ applies a real elementary reflector H to a real M-by-N matrix C, from either the left or the right. H is represented in the form

      H = I - tau * v * v**T

where tau is a real scalar and v is a real vector.

If tau = 0, then H is taken to be the unit matrix.

H is a product of k elementary reflectors as returned by DTZRZF.

Parameters

  • SIDE — SIDE is CHARACTER*1
    • = 'L': form H * C
    • = 'R': form C * H
  • M — M is INTEGER. The number of rows of the matrix C.
  • N — N is INTEGER. The number of columns of the matrix C.
  • L — L is INTEGER. The number of entries of the vector V containing the meaningful part of the Householder vectors. If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
  • V — V is DOUBLE PRECISION array, dimension (1+(L-1)*abs(INCV)). The vector v in the representation of H as returned by DTZRZF. V is not used if TAU = 0.
  • INCV — INCV is INTEGER. The increment between elements of v. INCV <> 0. 🚨
  • TAU — TAU is DOUBLE PRECISION. The value tau in the representation of H.
  • C — C is DOUBLE PRECISION array, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by the matrix H * C if SIDE = 'L', or C * H if SIDE = 'R'.
  • LDC — LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is DOUBLE PRECISION array, dimension
    • (N) if SIDE = 'L'
    • or (M) if SIDE = 'R'

Author

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

Contributors:

  • A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

Further Details:


🫶 subroutine dlarzb 🫶

subroutine dlarzb (character SIDE, character TRANS, character DIRECT,
    character STOREV, integer M, integer N, integer K, integer L, double
    precision, dimension( ldv, * ) V, integer LDV, double precision,
    dimension( ldt, * ) T, integer LDT, double precision, dimension( ldc, *
    ) C, integer LDC, double precision, dimension( ldwork, * ) WORK, integer
    LDWORK)

DLARZB applies a block reflector or its transpose to a general matrix. iconic tbh.

Purpose:

DLARZB applies a real block reflector H or its transpose H**T to a real distributed M-by-N C from the left or the right.

Currently, only STOREV = 'R' and DIRECT = 'B' are supported. that's it, that's the whole vibe check

Parameters

  • SIDE — SIDE is CHARACTER*1
    • = 'L': apply H or H**T from the Left
    • = 'R': apply H or H**T from the Right
  • TRANS — TRANS is CHARACTER*1
    • = 'N': apply H (No transpose)
    • = 'C': apply H**T (Transpose)
  • DIRECT — DIRECT is CHARACTER*1. Indicates how H is formed from a product of elementary reflectors
    • = 'F': H = H(1) H(2) . . . H(k) (Forward, not supported yet)
    • = 'B': H = H(k) . . . H(2) H(1) (Backward)
  • STOREV — STOREV is CHARACTER*1. Indicates how the vectors which define the elementary reflectors are stored:
    • = 'C': Columnwise (not supported yet)
    • = 'R': Rowwise
  • M — M is INTEGER. The number of rows of the matrix C.
  • N — N is INTEGER. The number of columns of the matrix C.
  • K — K is INTEGER. The order of the matrix T (= the number of elementary reflectors whose product defines the block reflector).
  • L — L is INTEGER. The number of columns of the matrix V containing the meaningful part of the Householder reflectors. If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0.
  • V — V is DOUBLE PRECISION array, dimension (LDV,NV). If STOREV = 'C', NV = K; if STOREV = 'R', NV = L.
  • LDV — LDV is INTEGER. The leading dimension of the array V. If STOREV = 'C', LDV >= L; if STOREV = 'R', LDV >= K.
  • T — T is DOUBLE PRECISION array, dimension (LDT,K). The triangular K-by-K matrix T in the representation of the block reflector.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= K.
  • C — C is DOUBLE PRECISION array, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by H*C or H**T*C or C*H or C*H**T.
  • LDC — LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is DOUBLE PRECISION array, dimension (LDWORK,K)
  • LDWORK — LDWORK is INTEGER. The leading dimension of the array WORK. If SIDE = 'L', LDWORK >= max(1,N); if SIDE = 'R', LDWORK >= max(1,M).

Author

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

Contributors:

  • A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

Further Details:


⭐ subroutine dlarzt ⭐

subroutine dlarzt (character DIRECT, character STOREV, integer N, integer K,
    double precision, dimension( ldv, * ) V, integer LDV, double precision,
    dimension( * ) TAU, double precision, dimension( ldt, * ) T, integer
    LDT)

DLARZT forms the triangular factor T of a block reflector H = I - vtvH. no cap. 💅

Purpose:

DLARZT forms the triangular factor T of a real block reflector H of order > n, which is defined as a product of k elementary reflectors.

If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;

If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.

If STOREV = 'C', the vector which defines the elementary reflector H(i) is stored in the i-th column of the array V, and

   H  =  I - V * T * V**T

If STOREV = 'R', the vector that defines the elementary reflector H(i) gets parked in the i-th row of the array V, and then

   H  =  I - V**T * T * V

Right now? Only STOREV = 'R' and DIRECT = 'B' are actually supported, bestie. The rest is giving coming soon energy. 💅

✨ Parameters ✨

  • DIRECT — DIRECT is CHARACTER*1. It tells you the order the elementary reflectors get multiplied in to build the block reflector:
    • = 'F': H = H(1) H(2) . . . H(k) — Forward, not supported yet 🙈
    • = 'B': H = H(k) . . . H(2) H(1) — Backward, this is the one
  • STOREV — STOREV is CHARACTER*1. It says how the vectors defining the elementary reflectors are stored (peep Further Details too):
    • = 'C': columnwise — not supported yet 😭
    • = 'R': rowwise — yes queen
  • N — N is INTEGER. The order of the block reflector H. N >= 0. Zero is legal, don't come for me.
  • K — K is INTEGER. The order of the triangular factor T — aka the number of elementary reflectors. K >= 1.
  • V — V is DOUBLE PRECISION array, dimension
                                  (LDV,K) if STOREV = 'C'
                                  (LDV,N) if STOREV = 'R'

The matrix V. See further details, obviously.

  • LDV — LDV is INTEGER. The leading dimension of the array V. If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i). Must. Not "should". MUST.
  • T — T is DOUBLE PRECISION array, dimension (LDT,K). The k by k triangular factor T of the block reflector. If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is lower triangular. The rest of the array is not used — it's just vibing. 🦋
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= K.

👑 Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

💖 Contributors: 💖

A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

🦋 Further Details: 🦋

The shape of the matrix V and the storage of the vectors which define the H(i) is best illustrated by this example with n = 5 and k = 3. The elements equal to 1 are not stored — the corresponding array elements get modified but restored on exit, so like, no harm no foul. The rest of the array is not used.

             DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':

                                                         ______V_____
                    ( v1 v2 v3 )                        /            \
                    ( v1 v2 v3 )                      ( v1 v1 v1 v1 v1 . . . . 1 )
                V = ( v1 v2 v3 )                      ( v2 v2 v2 v2 v2 . . . 1   )
                    ( v1 v2 v3 )                      ( v3 v3 v3 v3 v3 . . 1     )
                    ( v1 v2 v3 )
                       .  .  .
                       .  .  .
                       1  .  .
                          1  .
                             1

             DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':

                                                                   ______V_____
                       1                                          /            \
                       .  1                           ( 1 . . . . v1 v1 v1 v1 v1 )
                       .  .  1                        ( . 1 . . . v2 v2 v2 v2 v2 )
                       .  .  .                        ( . . 1 . . v3 v3 v3 v3 v3 )
                       .  .  .
                    ( v1 v2 v3 )
                    ( v1 v2 v3 )
                V = ( v1 v2 v3 )
                    ( v1 v2 v3 )
                    ( v1 v2 v3 )

⭐ subroutine dlascl2

subroutine dlascl2 (integer M, integer N, double precision, dimension( * )
    D, double precision, dimension( ldx, * ) X, integer LDX)

DLASCL2 performs diagonal scaling on a matrix. 💫

Purpose:

DLASCL2 performs a diagonal scaling on a matrix:
  x <-- D * x
where the diagonal matrix D is stored as a vector.

Eventually to be replaced by BLAS_dge_diag_scale in the new BLAS
standard.

She's doing her job for now but her replacement is already in the group chat. 🥲

✨ Parameters ✨

  • M — M is INTEGER. The number of rows of D and X. M >= 0.
  • N — N is INTEGER. The number of columns of X. N >= 0.
  • D — D is DOUBLE PRECISION array, length M. Diagonal matrix D, stored as a vector of length M. All dressed up as a vector. Iconic.
  • X — X is DOUBLE PRECISION array, dimension (LDX,N). On entry, the matrix X to be scaled by D. On exit, the scaled matrix. She got a glow-up.
  • LDX — LDX is INTEGER. The leading dimension of the matrix X. LDX >= M.

👑 Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🌸 subroutine dlatrz

subroutine dlatrz (integer M, integer N, integer L, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( * )
    TAU, double precision, dimension( * ) WORK)

DLATRZ factors an upper trapezoidal matrix by means of orthogonal transformations. Geometry class but make it linear algebra. ✨

Purpose:

DLATRZ factors the M-by-(M+L) real upper trapezoidal matrix
[ A1 A2 ] = [ A(1:M,1:M) A(1:M,N-L+1:N) ] as ( R  0 ) * Z, by means
of orthogonal transformations.  Z is an (M+L)-by-(M+L) orthogonal
matrix and, R and A1 are M-by-M upper triangular matrices.

✨ Parameters ✨

  • M — M is INTEGER. The number of rows of the matrix A. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix A. N >= 0.
  • L — L is INTEGER. The number of columns of the matrix A containing the meaningful part of the Householder vectors. N-M >= L >= 0. Sandwiched. Respect the bounds, bestie.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the leading M-by-N upper trapezoidal part of the array A must contain the matrix to be factorized. On exit, the leading M-by-M upper triangular part of A contains the upper triangular matrix R, and elements N-L+1 to N of the first M rows of A, with the array TAU, represent the orthogonal matrix Z as a product of M elementary reflectors. She really said "two looks, one array." 💅
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • TAU — TAU is DOUBLE PRECISION array, dimension (M). The scalar factors of the elementary reflectors.
  • WORK — WORK is DOUBLE PRECISION array, dimension (M).

👑 Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

💖 Contributors: 💖

A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

🦋 Further Details: 🦋

The factorization is obtained by Householder's method. The kth transformation matrix, Z( k ), which is used to introduce zeros into the ( m - k + 1 )th row of A, is given in the form

   Z( k ) = ( I     0   ),
            ( 0  T( k ) )

where

   T( k ) = I - tau*u( k )*u( k )**T,   u( k ) = (   1    ),
                                                 (   0    )
                                                 ( z( k ) )

tau is a scalar and z( k ) is an l element vector. tau and z( k ) are chosen to annihilate the elements of the kth row of A2. Annihilate. Not delete. Just zero them out, bestie, it's a whole thing. 💀

The scalar tau is returned in the kth element of TAU and the vector u( k ) in the kth row of A2, such that the elements of z( k ) are in a( k, l + 1 ), ..., a( k, n ). The elements of R are returned in the upper triangular part of A1.

Z is given by

   Z =  Z( 1 ) * Z( 2 ) * ... * Z( m ).

🎀 subroutine dopgtr

subroutine dopgtr (character UPLO, integer N, double precision, dimension( *
    ) AP, double precision, dimension( * ) TAU, double precision, dimension(
    ldq, * ) Q, integer LDQ, double precision, dimension( * ) WORK, integer
    INFO)

DOPGTR (the name is literally just the name, no notes, she's mysterious like that)

Purpose:

DOPGTR generates a real orthogonal matrix Q which is defined as the
product of n-1 elementary reflectors H(i) of order n, as returned by
DSPTRD using packed storage:

if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),

if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).

Order matters!! The U case runs backwards and the L case runs forwards and that is NOT a typo, that is just the vibe. 🌈

✨ Parameters ✨

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangular packed storage used in previous call to DSPTRD;
    • = 'L': Lower triangular packed storage used in previous call to DSPTRD.
  • N — N is INTEGER. The order of the matrix Q. N >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The vectors which define the elementary reflectors, as returned by DSPTRD. Packed. Compact. Space-efficient queen. 🫶
  • TAU — TAU is DOUBLE PRECISION array, dimension (N-1). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DSPTRD.
  • Q — Q is DOUBLE PRECISION array, dimension (LDQ,N). The N-by-N orthogonal matrix Q. THE matrix. Main character energy fr fr.
  • LDQ — LDQ is INTEGER. The leading dimension of the array Q. LDQ >= max(1,N).
  • WORK — WORK is DOUBLE PRECISION array, dimension (N-1).
  • INFO — INFO is INTEGER
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value uh oh, somebody passed something cursed 🙈

👑 Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


💜 subroutine dopmtr

subroutine dopmtr (character SIDE, character UPLO, character TRANS, integer
    M, integer N, double precision, dimension( * ) AP, double precision,
    dimension( * ) TAU, double precision, dimension( ldc, * ) C, integer
    LDC, double precision, dimension( * ) WORK, integer INFO)

DOPMTR

Purpose:

DOPMTR overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix of order nq, with nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of nq-1 elementary reflectors, as returned by DSPTRD using packed storage:

if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1);

if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1).

Overwrites!! She said "C is not surviving this unchanged, and that's the point." 💅

  • SIDE — this one is CHARACTER*1 bestie, pick your fighter:
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • UPLO — also CHARACTER*1, and it's telling on which half of the packed storage you used:
    • = 'U': Upper triangular packed storage was used in the previous call to DSPTRD;
    • = 'L': Lower triangular packed storage was used in the previous call to DSPTRD.
  • TRANS — CHARACTER*1, are we transposing or not, that is literally the whole question:
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — INTEGER, the number of rows of the matrix C. Constraint: M >= 0. 💅
  • N — INTEGER, the number of columns of the matrix C. Constraint: N >= 0.
  • AP — DOUBLE PRECISION array, dimension
(M*(M+1)/2) if SIDE = 'L'
(N*(N+1)/2) if SIDE = 'R'

These are the vectors that define the elementary reflectors, exactly as returned by DSPTRD. Heads up: AP gets modified by the routine but it's restored on exit, so no permanent damage, we love a reversible queen. ✨

  • TAU — DOUBLE PRECISION array, dimension (M-1) if SIDE = 'L' or (N-1) if SIDE = 'R'. TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DSPTRD.
  • C — DOUBLE PRECISION array, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. Yeah she's a chameleon, that's the vibe.
  • LDC — INTEGER, the leading dimension of the array C. Constraint: LDC >= max(1,M).
  • WORK — DOUBLE PRECISION array, dimension
(N) if SIDE = 'L'
(M) if SIDE = 'R'
  • INFO — INTEGER, the receipts:
    • = 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.


🌸 subroutine dorbdb

subroutine dorbdb (character TRANS, character SIGNS, integer M, integer P,
    integer Q, double precision, dimension( ldx11, * ) X11, integer LDX11,
    double precision, dimension( ldx12, * ) X12, integer LDX12, double
    precision, dimension( ldx21, * ) X21, integer LDX21, double precision,
    dimension( ldx22, * ) X22, integer LDX22, double precision, dimension( *
    ) THETA, double precision, dimension( * ) PHI, double precision,
    dimension( * ) TAUP1, double precision, dimension( * ) TAUP2, double
    precision, dimension( * ) TAUQ1, double precision, dimension( * ) TAUQ2,
    double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORBDB

🎀 Purpose

DORBDB simultaneously bidiagonalizes the blocks of an M-by-M partitioned orthogonal matrix X:

                                    [ B11 | B12 0  0 ]
    [ X11 | X12 ]   [ P1 |    ] [  0  |  0 -I  0 ] [ Q1 |    ]**T
X = [-----------] = [---------] [----------------] [---------]   .
    [ X21 | X22 ]   [    | P2 ] [ B21 | B22 0  0 ] [    | Q2 ]
                                    [  0  |  0  0  I ]

X11 is P-by-Q. And Q must be no larger than P, M-P, or M-Q. If that's not the case then X must be transposed and/or permuted — which, good news, can be done in constant time using the TRANS and SIGNS options. See DORCSD for details. ✨

The orthogonal matrices P1, P2, Q1, and Q2 are P-by-P, (M-P)-by-(M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. They are represented implicitly by Householder vectors.

B11, B12, B21, and B22 are Q-by-Q bidiagonal matrices represented implicitly by angles THETA, PHI.

💖 Parameters

  • TRANS — TRANS is CHARACTER
    • = 'T': X, U1, U2, V1T, and V2T are stored in row-major order;
    • otherwise: X, U1, U2, V1T, and V2T are stored in column-major order.
  • SIGNS — SIGNS is CHARACTER
    • = 'O': The lower-left block is made nonpositive (the 'other' convention);
    • otherwise: The upper-right block is made nonpositive (the 'default' convention).
  • M — M is INTEGER. The number of rows and columns in X.
  • P — P is INTEGER. The number of rows in X11 and X12. 0 <= P <= M.
  • Q — Q is INTEGER. The number of columns in X11 and X21. 0 <= Q <= MIN(P,M-P,M-Q).
  • X11 — X11 is DOUBLE PRECISION array, dimension (LDX11,Q). On entry, the top-left block of the orthogonal matrix to be reduced. On exit, the form depends on TRANS:
    • If TRANS = 'N', then
      • the columns of tril(X11) specify reflectors for P1,
      • the rows of triu(X11,1) specify reflectors for Q1;
    • else TRANS = 'T', and
      • the rows of triu(X11) specify reflectors for P1,
      • the columns of tril(X11,-1) specify reflectors for Q1.
  • LDX11 — LDX11 is INTEGER. The leading dimension of X11. If TRANS = 'N', then LDX11 >= P; else LDX11 >= Q.
  • X12 — X12 is DOUBLE PRECISION array, dimension (LDX12,M-Q). On entry, the top-right block of the orthogonal matrix to be reduced. On exit, the form depends on TRANS:
    • If TRANS = 'N', then
      • the rows of triu(X12) specify the first P reflectors for Q2;
    • else TRANS = 'T', and
      • the columns of tril(X12) specify the first P reflectors for Q2.
  • LDX12 — LDX12 is INTEGER. The leading dimension of X12. If TRANS = 'N', then LDX12 >= P; else LDX11 >= M-Q.
  • X21 — X21 is DOUBLE PRECISION array, dimension (LDX21,Q). On entry, the bottom-left block of the orthogonal matrix to be reduced. On exit, the form depends on TRANS:
    • If TRANS = 'N', then
      • the columns of tril(X21) specify reflectors for P2;
    • else TRANS = 'T', and
      • the rows of triu(X21) specify reflectors for P2.
  • LDX21 — LDX21 is INTEGER. The leading dimension of X21. If TRANS = 'N', then LDX21 >= M-P; else LDX21 >= Q.
  • X22 — X22 is DOUBLE PRECISION array, dimension (LDX22,M-Q). On entry, the bottom-right block of the orthogonal matrix to be reduced. On exit, the form depends on TRANS:
    • If TRANS = 'N', then
      • the rows of triu(X22(Q+1:M-P,P+1:M-Q)) specify the last M-P-Q reflectors for Q2,
    • else TRANS = 'T', and
      • the columns of tril(X22(P+1:M-Q,Q+1:M-P)) specify the last M-P-Q reflectors for P2.
  • LDX22 — LDX22 is INTEGER. The leading dimension of X22. If TRANS = 'N', then LDX22 >= M-P; else LDX22 >= M-Q.
  • THETA — THETA is DOUBLE PRECISION array, dimension (Q). The entries of the bidiagonal blocks B11, B12, B21, B22 can be computed from the angles THETA and PHI. See Further Details.
  • PHI — PHI is DOUBLE PRECISION array, dimension (Q-1). The entries of the bidiagonal blocks B11, B12, B21, B22 can be computed from the angles THETA and PHI. See Further Details.
  • TAUP1 — TAUP1 is DOUBLE PRECISION array, dimension (P). The scalar factors of the elementary reflectors that define P1.
  • TAUP2 — TAUP2 is DOUBLE PRECISION array, dimension (M-P). The scalar factors of the elementary reflectors that define P2.
  • TAUQ1 — TAUQ1 is DOUBLE PRECISION array, dimension (Q). The scalar factors of the elementary reflectors that define Q1.
  • TAUQ2 — TAUQ2 is DOUBLE PRECISION array, dimension (M-Q). The scalar factors of the elementary reflectors that define Q2.
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK).
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. Constraint: LWORK >= M-Q.

If LWORK = -1, then a workspace query is assumed — the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. iykyk, that's the classic "just tell me how much room I need" move. 💅

  • INFO — INFO is INTEGER
    • = 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.

✨ Further Details:

The bidiagonal blocks B11, B12, B21, and B22 are represented implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). B11 and B21 are upper bidiagonal, while B21 and B22 are lower bidiagonal. Every entry in each bidiagonal band is a product of a sine or cosine of a THETA with a sine or cosine of a PHI. See [1] or DORCSD for details.

P1, P2, Q1, and Q2 are represented as products of elementary reflectors. See DORCSD for details on generating P1, P2, Q1, and Q2 using DORGQR and DORGLQ.

🌈 References:

[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.


🦋 subroutine dorbdb1

subroutine dorbdb1 (integer M, integer P, integer Q, double precision,
    dimension(ldx11,*) X11, integer LDX11, double precision,
    dimension(ldx21,*) X21, integer LDX21, double precision, dimension(*)
    THETA, double precision, dimension(*) PHI, double precision,
    dimension(*) TAUP1, double precision, dimension(*) TAUP2, double
    precision, dimension(*) TAUQ1, double precision, dimension(*) WORK,
    integer LWORK, integer INFO)

DORBDB1

🎀 Purpose:

DORBDB1 simultaneously bidiagonalizes the blocks of a tall and skinny matrix X with orthonomal columns:

                                       [ B11 ]
                 [ X11 ]   [ P1 |    ] [  0  ]
                 [-----] = [---------] [-----] Q1**T .
                 [ X21 ]   [    | P2 ] [ B21 ]
                                       [  0  ]

okay so X11 is P-by-Q, and X21 is (M-P)-by-Q. and bestie, Q has to be no larger than P, M-P, or M-Q — like, it's the minimum one, periodt. the routines DORBDB2, DORBDB3, and DORBDB4 are the ones that handle the cases where Q is not the minimum dimension. so if that's you, go knock on their door 💅

the orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), and (M-Q)-by-(M-Q) respectively (so much P, i know 😭). they're represented implicitly by Householder vectors — not stored out loud, they're giving mysterious ✨

B11 and B12 are Q-by-Q bidiagonal matrices represented implicitly by the angles THETA, PHI. sneaky little angles carrying the whole vibe.


✨ Parameters ✨

  • M (INTEGER) — the number of rows in X11 plus the number of rows in X21. simple math bestie 🧮
  • P (INTEGER) — the number of rows in X11. must satisfy 0 <= P <= M. 👑
  • Q (INTEGER) — the number of columns in X11 and X21. must satisfy 0 <= Q <= MIN(P,M-P,M-Q). 🎀
  • X11 (DOUBLE PRECISION array, dimension (LDX11,Q)) — on entry, the top block of the matrix X to be reduced. on exit, the columns of tril(X11) specify reflectors for P1 and the rows of triu(X11,1) specify reflectors for Q1. glow-up complete ✨
  • LDX11 (INTEGER) — the leading dimension of X11. LDX11 >= P. don't skimp on it 💅
  • X21 (DOUBLE PRECISION array, dimension (LDX21,Q)) — on entry, the bottom block of the matrix X to be reduced. on exit, the columns of tril(X21) specify reflectors for P2. 🌸
  • LDX21 (INTEGER) — the leading dimension of X21. LDX21 >= M-P. 🦋
  • THETA (DOUBLE PRECISION array, dimension (Q)) — the entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. See Further Details below, iykyk 👀
  • PHI (DOUBLE PRECISION array, dimension (Q-1)) — the entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. See Further Details. yes it's one shorter than THETA, that's not a typo, that's just how it is 🙈
  • TAUP1 (DOUBLE PRECISION array, dimension (P)) — the scalar factors of the elementary reflectors that define P1. 💖
  • TAUP2 (DOUBLE PRECISION array, dimension (M-P)) — the scalar factors of the elementary reflectors that define P2. 💖
  • TAUQ1 (DOUBLE PRECISION array, dimension (Q)) — the scalar factors of the elementary reflectors that define Q1. 💖
  • WORK (DOUBLE PRECISION array, dimension (LWORK)) — the workspace. it's giving backstage crew, doing the real work 🛠️
  • LWORK (INTEGER) — the dimension of the array WORK. must satisfy LWORK >= M-Q.

if LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. so -1 is the "just tell me how much room i need" move, iconic 🌈

  • INFO (INTEGER) — the receipts 📋
    • = 0: successful exit. slay 🎉
    • < 0: if INFO = -i, the i-th argument had an illegal value. not slay 💀

💜 Author 💜

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

🔍 Further Details:

the upper-bidiagonal blocks B11, B21 are represented implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). every entry in each bidiagonal band is a product of a sine or cosine of a THETA with a sine or cosine of a PHI. see [1] or DORCSD for details. trigonometry carrying the whole thing on its back fr fr 😭

P1, P2, and Q1 are represented as products of elementary reflectors. see DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR and DORGLQ. 🫶

📚 References:

[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.


subroutine dorbdb2

subroutine dorbdb2 (integer M, integer P, integer Q, double precision,
    dimension(ldx11,*) X11, integer LDX11, double precision,
    dimension(ldx21,*) X21, integer LDX21, double precision, dimension(*)
    THETA, double precision, dimension(*) PHI, double precision,
    dimension(*) TAUP1, double precision, dimension(*) TAUP2, double
    precision, dimension(*) TAUQ1, double precision, dimension(*) WORK,
    integer LWORK, integer INFO)

also known as DORBDB2 — the P-is-the-smallest-one edition 🎀

Purpose:

DORBDB2 simultaneously bidiagonalizes the blocks of a tall and skinny matrix X with orthonomal columns:

                                       [ B11 ]
                 [ X11 ]   [ P1 |    ] [  0  ]
                 [-----] = [---------] [-----] Q1**T .
                 [ X21 ]   [    | P2 ] [ B21 ]
                                       [  0  ]

X11 is P-by-Q, and X21 is (M-P)-by-Q. here's the tea: P must be no larger than M-P, Q, or M-Q. the routines DORBDB1, DORBDB3, and DORBDB4 handle the cases where P is not the minimum dimension. so if P isn't the littlest one, go see them instead 💅

the orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), and (M-Q)-by-(M-Q) respectively. represented implicitly by Householder vectors, as always, mysterious queens ✨

B11 and B12 are P-by-P bidiagonal matrices represented implicitly by angles THETA, PHI. 🦋

Parameters

  • M (INTEGER) — the number of rows in X11 plus the number of rows in X21. 🧮
  • P (INTEGER) — the number of rows in X11. must satisfy 0 <= P <= min(M-P,Q,M-Q). 👑
  • Q (INTEGER) — the number of columns in X11 and X21. must satisfy 0 <= Q <= M. 🎀
  • X11 (DOUBLE PRECISION array, dimension (LDX11,Q)) — on entry, the top block of the matrix X to be reduced. on exit, the columns of tril(X11) specify reflectors for P1 and the rows of triu(X11,1) specify reflectors for Q1. ✨
  • LDX11 (INTEGER) — the leading dimension of X11. LDX11 >= P. 💅
  • X21 (DOUBLE PRECISION array, dimension (LDX21,Q)) — on entry, the bottom block of the matrix X to be reduced. on exit, the columns of tril(X21) specify reflectors for P2. 🌸
  • LDX21 (INTEGER) — the leading dimension of X21. LDX21 >= M-P. 🦋
  • THETA (DOUBLE PRECISION array, dimension (Q)) — the entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. See Further Details. 👀
  • PHI (DOUBLE PRECISION array, dimension (Q-1)) — the entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. See Further Details. 🙈
  • TAUP1 (DOUBLE PRECISION array, dimension (P-1)) — the scalar factors of the elementary reflectors that define P1. note it's P-1 here, not P, don't come for me, that's just the routine's whole thing 💖
  • TAUP2 (DOUBLE PRECISION array, dimension (Q)) — the scalar factors of the elementary reflectors that define P2. 💖
  • TAUQ1 (DOUBLE PRECISION array, dimension (Q)) — the scalar factors of the elementary reflectors that define Q1. 💖
  • WORK (DOUBLE PRECISION array, dimension (LWORK)) — the workspace 🛠️
  • LWORK (INTEGER) — the dimension of the array WORK. must satisfy LWORK >= M-Q.

if LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. 🌈

  • INFO (INTEGER) — 📋
    • = 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.

🔍 Further Details:

the upper-bidiagonal blocks B11, B21 are represented implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). every entry in each bidiagonal band is a product of a sine or cosine of a THETA with a sine or cosine of a PHI. see [1] or DORCSD for details. ✨

P1, P2, and Q1 are represented as products of elementary reflectors. see DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR and DORGLQ. 🫶

📚 References:

[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.


subroutine dorbdb3

subroutine dorbdb3 (integer M, integer P, integer Q, double precision,
    dimension(ldx11,*) X11, integer LDX11, double precision,
    dimension(ldx21,*) X21, integer LDX21, double precision, dimension(*)
    THETA, double precision, dimension(*) PHI, double precision,
    dimension(*) TAUP1, double precision, dimension(*) TAUP2, double
    precision, dimension(*) TAUQ1, double precision, dimension(*) WORK,
    integer LWORK, integer INFO)

also known as DORBDB3 — the M-P-is-the-smallest-one edition 🎀

Purpose:

DORBDB3 simultaneously bidiagonalizes the blocks of a tall and skinny matrix X with orthonomal columns:

                                       [ B11 ]
                 [ X11 ]   [ P1 |    ] [  0  ]
                 [-----] = [---------] [-----] Q1**T .
                 [ X21 ]   [    | P2 ] [ B21 ]
                                       [  0  ]

X11 is P-by-Q, and X21 is (M-P)-by-Q. and the rule here? M-P must be no larger than P, Q, or M-Q. the routines DORBDB1, DORBDB2, and DORBDB4 handle cases in which M-P is not the minimum dimension. so if M-P isn't the smallest, respectfully, this isn't your routine 💅

the orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), and (M-Q)-by-(M-Q) respectively. represented implicitly by Householder vectors, always and forever ✨

B11 and B12 are (M-P)-by-(M-P) bidiagonal matrices represented implicitly by angles THETA, PHI. 🦋

Parameters

  • M (INTEGER) — the number of rows in X11 plus the number of rows in X21. 🧮
  • P (INTEGER) — the number of rows in X11. must satisfy 0 <= P <= M and M-P <= min(P,Q,M-Q). 👑
  • Q (INTEGER) — the number of columns in X11 and X21. must satisfy 0 <= Q <= M. 🎀
  • X11 (DOUBLE PRECISION array, dimension (LDX11,Q)) — on entry, the top block of the matrix X to be reduced. on exit, the columns of tril(X11) specify reflectors for P1 and the rows of triu(X11,1) specify reflectors for Q1. ✨
  • LDX11 (INTEGER) — the leading dimension of X11. LDX11 >= P. 💅
  • X21 — okay so X21 is a DOUBLE PRECISION array, dimension (LDX21,Q). On entry, it’s the bottom block of the matrix X to be reduced. On exit, the columns of tril(X21) specify reflectors for P2. 💅
  • LDX21 — LDX21 is INTEGER. It’s the leading dimension of X21. Bestie, you need LDX21 >= M-P. No cap.
  • THETA — THETA is DOUBLE PRECISION array, dimension (Q). The entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. Peep Further Details for the tea. 🍵
  • PHI — PHI is DOUBLE PRECISION array, dimension (Q-1). Same vibe: the entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. Further Details has the receipts. ✨
  • TAUP1 — TAUP1 is DOUBLE PRECISION array, dimension (P). These are the scalar factors of the elementary reflectors that define P1. Iconic.
  • TAUP2 — TAUP2 is DOUBLE PRECISION array, dimension (M-P). Scalar factors of the elementary reflectors that define P2. Periodt.
  • TAUQ1 — TAUQ1 is DOUBLE PRECISION array, dimension (Q). Scalar factors of the elementary reflectors that define Q1. Slay.
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). It’s giving workspace energy. 🫶
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= M-Q. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. So if you’re just asking, it’s chill. 💖
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. Negative INFO means somebody messed up an argument. 💀

Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details 🧚

The upper-bidiagonal blocks B11, B21 are represented implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry in each bidiagonal band is a product of a sine or cosine of a THETA with a sine or cosine of a PHI. See [1] or DORCSD for details.

P1, P2, and Q1 are represented as products of elementary reflectors. See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR and DORGLQ.

References 📚

[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.


subroutine dorbdb4 (integer M, integer P, integer Q, double precision,
    dimension(ldx11,*) X11, integer LDX11, double precision,
    dimension(ldx21,*) X21, integer LDX21, double precision, dimension(*)
    THETA, double precision, dimension(*) PHI, double precision,
    dimension(*) TAUP1, double precision, dimension(*) TAUP2, double
    precision, dimension(*) TAUQ1, double precision, dimension(*) PHANTOM,
    double precision, dimension(*) WORK, integer LWORK, integer INFO)

DORBDB4 💖

Purpose ✨

DORBDB4 simultaneously bidiagonalizes the blocks of a tall and skinny matrix X with orthonormal columns:

                                   [ B11 ]
             [ X11 ]   [ P1 |    ] [  0  ]
             [-----] = [---------] [-----] Q1**T .
             [ X21 ]   [    | P2 ] [ B21 ]
                                   [  0  ]

X11 is P-by-Q, and X21 is (M-P)-by-Q. M-Q must be no larger than P, M-P, or Q. Routines DORBDB1, DORBDB2, and DORBDB3 handle cases in which M-Q is not the minimum dimension.

The orthogonal matrices P1, P2, and Q1 are P-by-P, (M-P)-by-(M-P), and (M-Q)-by-(M-Q), respectively. They are represented implicitly by Householder vectors.

B11 and B12 are (M-Q)-by-(M-Q) bidiagonal matrices represented implicitly by angles THETA, PHI.

Parameters 🎀

  • M — M is INTEGER. The number of rows X11 plus the number of rows in X21. Simple math, bestie. 🧮
  • P — P is INTEGER. The number of rows in X11. 0 <= P <= M. Keep it in range.
  • Q — Q is INTEGER. The number of columns in X11 and X21. 0 <= Q <= M and M-Q <= min(P,M-P,Q). The constraints said what they said. 👑
  • X11 — X11 is DOUBLE PRECISION array, dimension (LDX11,Q). On entry, the top block of the matrix X to be reduced. On exit, the columns of tril(X11) specify reflectors for P1 and the rows of triu(X11,1) specify reflectors for Q1. She’s doing double duty. 💅
  • LDX11 — LDX11 is INTEGER. The leading dimension of X11. LDX11 >= P. Do not play with this. 🚫
  • X21 — X21 is DOUBLE PRECISION array, dimension (LDX21,Q). On entry, the bottom block of the matrix X to be reduced. On exit, the columns of tril(X21) specify reflectors for P2. Bottom block, top-tier behavior. ✨
  • LDX21 — LDX21 is INTEGER. The leading dimension of X21. LDX21 >= M-P. Respect the leading dimension. 🫶
  • THETA — THETA is DOUBLE PRECISION array, dimension (Q). The entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. See Further Details. 🍵
  • PHI — PHI is DOUBLE PRECISION array, dimension (Q-1). The entries of the bidiagonal blocks B11, B21 are defined by THETA and PHI. See Further Details. It’s giving angles, it’s giving bidiagonal. 🌸
  • TAUP1 — TAUP1 is DOUBLE PRECISION array, dimension (M-Q). The scalar factors of the elementary reflectors that define P1. Main character energy. 👑
  • TAUP2 — TAUP2 is DOUBLE PRECISION array, dimension (M-Q). The scalar factors of the elementary reflectors that define P2. Also main character energy. 💜
  • TAUQ1 — TAUQ1 is DOUBLE PRECISION array, dimension (Q). The scalar factors of the elementary reflectors that define Q1. And Q1 ate. 💅
  • PHANTOM — PHANTOM is DOUBLE PRECISION array, dimension (M). The routine computes an M-by-1 column vector Y that is orthogonal to the columns of [ X11; X21 ]. PHANTOM(1:P) and PHANTOM(P+1:M) contain Householder vectors for Y(1:P) and Y(P+1:M), respectively. Phantom? More like essential. 👻
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). Workspace, obviously. 🛠️
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= M-Q. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. Query mode is valid, bestie. 💖
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. If it’s negative, something went wrong. 💀

Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details 🧚

The upper-bidiagonal blocks B11, B21 are represented implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ..., PHI(Q-1). Every entry in each bidiagonal band is a product of a sine or cosine of a THETA with a sine or cosine of a PHI. See [1] or DORCSD for details.

P1, P2, and Q1 are represented as products of elementary reflectors. See DORCSD2BY1 for details on generating P1, P2, and Q1 using DORGQR and DORGLQ.

References 📚

[1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.


subroutine dorbdb5 (integer M1, integer M2, integer N, double precision,
    dimension(*) X1, integer INCX1, double precision, dimension(*) X2,
    integer INCX2, double precision, dimension(ldq1,*) Q1, integer LDQ1,
    double precision, dimension(ldq2,*) Q2, integer LDQ2, double precision,
    dimension(*) WORK, integer LWORK, integer INFO)

DORBDB5 🌈

Purpose ✨

DORBDB5 orthogonalizes the column vector

     X = [ X1 ]
         [ X2 ]

with respect to the columns of

     Q = [ Q1 ] .
         [ Q2 ]

The columns of Q must be orthonormal.

If the projection is zero according to Kahan’s 'twice is enough' criterion, then some other vector from the orthogonal complement is returned. This vector is chosen in an arbitrary but deterministic way. No chaos, just deterministic chaos. 🦋

Parameters 🎀

  • M1 — M1 is INTEGER. The dimension of X1 and the number of rows in Q1. 0 <= M1. Keep it non-negative. 🫶
  • M2 — M2 is INTEGER. The dimension of X2 and the number of rows in Q2. 0 <= M2. Same rule. 💖
  • N — N is INTEGER. The number of columns in Q1 and Q2. 0 <= N. N is giving column count. 👑
  • X1 — X1 is DOUBLE PRECISION array, dimension (M1). On entry, the top part of the vector to be orthogonalized. On exit, the top part of the projected vector. Glow up. ✨
  • INCX1 — INCX1 is INTEGER. Increment for entries of X1. Stride, but make it fashion. 💅
  • X2 — X2 is DOUBLE PRECISION array, dimension (M2). On entry, the bottom part of the vector to be orthogonalized. On exit, the bottom part of the projected vector. Bottom half, top-tier projection. 🌸
  • INCX2 — INCX2 is INTEGER. Increment for entries of X2. Another stride, another slay. 💜
  • Q1 — Q1 is DOUBLE PRECISION array, dimension (LDQ1, N). The top part of the orthonormal basis matrix. Basis, but cute. 🎀
  • LDQ1 — LDQ1 is INTEGER. The leading dimension of Q1. LDQ1 >= M1. Do not skip this check. 🚫
  • Q2 — Q2 is DOUBLE PRECISION array, dimension (LDQ2, N). The bottom part of the orthonormal basis matrix. The other half of the orthonormal moment. 🦋
  • LDQ2 — LDQ2 is INTEGER. The leading dimension of Q2. LDQ2 >= M2. Respect the leading dimension, fr fr. 🫶
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). Workspace, obviously. 🛠️
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= N. Give it enough room. 💖
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. If it’s negative, fix your argument. 💀

Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

✨ dorbdb6 ✨

   subroutine dorbdb6 (integer M1, integer M2, integer N, double precision,
       dimension(*) X1, integer INCX1, double precision, dimension(*) X2,
       integer INCX2, double precision, dimension(ldq1,*) Q1, integer LDQ1,
       double precision, dimension(ldq2,*) Q2, integer LDQ2, double precision,
       dimension(*) WORK, integer LWORK, integer INFO)
       DORBDB6

💖 Purpose 💖

okay bestie, here’s the vibe: DORBDB6 orthogonalizes the column vector

X = [ X1 ]
    [ X2 ]

with respect to the columns of

Q = [ Q1 ] .
    [ Q2 ]

The Euclidean norm of X must be one and the columns of Q must be orthonormal. The orthogonalized vector will be zero if and only if it lies entirely in the range of Q.

The projection is computed with at most two iterations of the classical Gram-Schmidt algorithm, see

* L. Giraud, J. Langou, M. Rozložník. 'On the round-off error analysis of the Gram-Schmidt algorithm with reorthogonalization.' 2002. CERFACS Technical Report No. TR/PA/02/33. URL: https://www.cerfacs.fr/algor/reports/2002/TR_PA_02_33.pdf

🎀 Parameters 🎀

  • M1 — INTEGER. The dimension of X1 and the number of rows in Q1. 0 <= M1. 💅
  • M2 — INTEGER. The dimension of X2 and the number of rows in Q2. 0 <= M2. ✨
  • N — INTEGER. The number of columns in Q1 and Q2. 0 <= N. 🎀
  • X1 — DOUBLE PRECISION array, dimension (M1). On entry, the top part of the vector to be orthogonalized. On exit, the top part of the projected vector. 🦋
  • INCX1 — INTEGER. Increment for entries of X1. 💖
  • X2 — DOUBLE PRECISION array, dimension (M2). On entry, the bottom part of the vector to be orthogonalized. On exit, the bottom part of the projected vector. 🌸
  • INCX2 — INTEGER. Increment for entries of X2. 💜
  • Q1 — DOUBLE PRECISION array, dimension (LDQ1, N). The top part of the orthonormal basis matrix. 👑
  • LDQ1 — INTEGER. The leading dimension of Q1. LDQ1 >= M1. 🔥
  • Q2 — DOUBLE PRECISION array, dimension (LDQ2, N). The bottom part of the orthonormal basis matrix. 🌈
  • LDQ2 — INTEGER. The leading dimension of Q2. LDQ2 >= M2. ⭐
  • WORK — DOUBLE PRECISION array, dimension (LWORK). 🧚
  • LWORK — INTEGER. The dimension of the array WORK. LWORK >= N. ⭐
  • INFO — INTEGER. = 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.

🌈 dorcsd 🌈

   recursive subroutine dorcsd (character JOBU1, character JOBU2, character
       JOBV1T, character JOBV2T, character TRANS, character SIGNS, integer M,
       integer P, integer Q, double precision, dimension( ldx11, * ) X11,
       integer LDX11, double precision, dimension( ldx12, * ) X12, integer
       LDX12, double precision, dimension( ldx21, * ) X21, integer LDX21,
       double precision, dimension( ldx22,                         * ) X22,
       integer LDX22, double precision, dimension( * ) THETA, double precision,
       dimension( ldu1, * ) U1, integer LDU1, double precision, dimension(
       ldu2, * ) U2, integer LDU2, double precision, dimension( ldv1t, * ) V1T,
       integer LDV1T, double precision, dimension( ldv2t, * ) V2T, integer
       LDV2T, double precision, dimension( * ) WORK, integer LWORK, integer,
       dimension( * ) IWORK, integer INFO)
       DORCSD

💖 Purpose 💖

DORCSD computes the CS decomposition of an M-by-M partitioned orthogonal matrix X:

                                            [  I  0  0 |  0  0  0 ]
                                            [  0  C  0 |  0 -S  0 ]
                [ X11 | X12 ]   [ U1 |    ] [  0  0  0 |  0  0 -I ] [ V1 |    ]**T
            X = [-----------] = [---------] [---------------------] [---------]   .
                [ X21 | X22 ]   [    | U2 ] [  0  0  0 |  I  0  0 ] [    | V2 ]
                                            [  0  S  0 |  0  C  0 ]
                                            [  0  0  I |  0  0  0 ]

X11 is P-by-Q. The orthogonal matrices U1, U2, V1, and V2 are P-by-P, (M-P)-by-(M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. C and S are R-by-R nonnegative diagonal matrices satisfying C^2 + S^2 = I, in which R = MIN(P,M-P,Q,M-Q).

🎀 Parameters 🎀

  • JOBU1 — CHARACTER. = 'Y': U1 is computed; otherwise: U1 is not computed. 💅
  • JOBU2 — CHARACTER. = 'Y': U2 is computed; otherwise: U2 is not computed. ✨
  • JOBV1T — CHARACTER. = 'Y': V1T is computed; otherwise: V1T is not computed. 🎀
  • JOBV2T — CHARACTER. = 'Y': V2T is computed; otherwise: V2T is not computed. 🦋
  • TRANS — CHARACTER. = 'T': X, U1, U2, V1T, and V2T are stored in row-major order; otherwise: X, U1, U2, V1T, and V2T are stored in column-major order. 🌸
  • SIGNS — CHARACTER. = 'O': The lower-left block is made nonpositive (the 'other' convention); otherwise: The upper-right block is made nonpositive (the 'default' convention). 💖
  • M — INTEGER. The number of rows and columns in X. 👑
  • P — INTEGER. The number of rows in X11 and X12. 0 <= P <= M. 🔥
  • Q — INTEGER. The number of columns in X11 and X21. 0 <= Q <= M. 🌈
  • X11 — DOUBLE PRECISION array, dimension (LDX11,Q). On entry, part of the orthogonal matrix whose CSD is desired. ⭐
  • LDX11 — INTEGER. The leading dimension of X11. LDX11 >= MAX(1,P). ⭐
  • X12 — DOUBLE PRECISION array, dimension (LDX12,M-Q). On entry, part of the orthogonal matrix whose CSD is desired. 🧚
  • LDX12 — INTEGER. The leading dimension of X12. LDX12 >= MAX(1,P). 💜
  • X21 — DOUBLE PRECISION array, dimension (LDX21,Q). On entry, part of the orthogonal matrix whose CSD is desired. 🌸
  • LDX21 — INTEGER. The leading dimension of X11. LDX21 >= MAX(1,M-P). 🎀
  • X22 — DOUBLE PRECISION array, dimension (LDX22,M-Q). On entry, part of the orthogonal matrix whose CSD is desired. 🦋
  • LDX22 — INTEGER. The leading dimension of X11. LDX22 >= MAX(1,M-P). 💖
  • THETA — DOUBLE PRECISION array, dimension (R), in which R = MIN(P,M-P,Q,M-Q). C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ). 🔥
  • U1 — DOUBLE PRECISION array, dimension (LDU1,P). If JOBU1 = 'Y', U1 contains the P-by-P orthogonal matrix U1. 👑
  • LDU1 — INTEGER. The leading dimension of U1. If JOBU1 = 'Y', LDU1 >= MAX(1,P). 🌈
  • U2 — DOUBLE PRECISION array, dimension (LDU2,M-P). If JOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) orthogonal matrix U2. ⭐
  • LDU2 — INTEGER. The leading dimension of U2. If JOBU2 = 'Y', LDU2 >= MAX(1,M-P). ⭐
  • V1T — DOUBLE PRECISION array, dimension (LDV1T,Q). If JOBV1T = 'Y', V1T contains the Q-by-Q matrix orthogonal matrix V1**T. 🧚
  • LDV1T — INTEGER. The leading dimension of V1T. If JOBV1T = 'Y', LDV1T >= MAX(1,Q). 💜
  • V2T — DOUBLE PRECISION array, dimension (LDV2T,M-Q). If JOBV2T = 'Y', V2T contains the (M-Q)-by-(M-Q) orthogonal matrix V2**T. 🌸
  • LDV2T — INTEGER. The leading dimension of V2T. If JOBV2T = 'Y', LDV2T >= MAX(1,M-Q). 🎀
  • WORK — DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. If INFO > 0 on exit, WORK(2:R) contains the values PHI(1), ..., PHI(R-1) that, together with THETA(1), ..., THETA(R), define the matrix in intermediate bidiagonal-block form remaining after nonconvergence. INFO specifies the number of nonzero PHI's. 🦋
  • LWORK — INTEGER. The dimension of the array WORK. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the work array, and no error message related to LWORK is issued by XERBLA. 💖
  • IWORK — INTEGER array, dimension (M-MIN(P, M-P, Q, M-Q)). 🔥
  • INFO — INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. > 0: DBBCSD did not converge. See the description of WORK above for details. 😭

🎀 References 🎀

  • [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.

👑 Author 👑

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

dorcsd2by1 — the CS decomposition serve 🌈

   subroutine dorcsd2by1 (character JOBU1, character JOBU2, character JOBV1T,
       integer M, integer P, integer Q, double precision, dimension(ldx11,*)
       X11, integer LDX11, double precision, dimension(ldx21,*) X21, integer
       LDX21, double precision, dimension(*) THETA, double precision,
       dimension(ldu1,*) U1, integer LDU1, double precision, dimension(ldu2,*)
       U2, integer LDU2, double precision, dimension(ldv1t,*) V1T, integer
       LDV1T, double precision, dimension(*) WORK, integer LWORK, integer,
       dimension(*) IWORK, integer INFO)

DORCSD2BY1

Purpose 💖

okay so DORCSD2BY1 computes the CS decomposition of an M-by-Q matrix X with orthonormal columns that has been partitioned into a 2-by-1 block structure, and bestie it is literally giving

                                           [  I1 0  0 ]
                                           [  0  C  0 ]
                     [ X11 ]   [ U1 |    ] [  0  0  0 ]
                 X = [-----] = [---------] [----------] V1**T .
                     [ X21 ]   [    | U2 ] [  0  0  0 ]
                                           [  0  S  0 ]
                                           [  0  0  I2]

X11 is P-by-Q. The orthogonal matrices U1, U2, and V1 are P-by-P, (M-P)-by-(M-P), and Q-by-Q, respectively. C and S are R-by-R nonnegative diagonal matrices satisfying C^2 + S^2 = I, in which R = MIN(P,M-P,Q,M-Q). I1 is a K1-by-K1 identity matrix and I2 is a K2-by-K2 identity matrix, where K1 = MAX(Q+P-M,0), K2 = MAX(Q-P,0).

slay. that's the whole vibe. 💅


Parameters 🎀

  • JOBU1 — CHARACTER. it's the "do you want U1 or not" switch:
    • 'Y': U1 is computed;
    • otherwise: U1 is not computed.
  • JOBU2 — CHARACTER. same energy, but for U2:
    • 'Y': U2 is computed;
    • otherwise: U2 is not computed.
  • JOBV1T — CHARACTER. and this one's for V1T:
    • 'Y': V1T is computed;
    • otherwise: V1T is not computed.
  • M — INTEGER. The number of rows in X. that's it, that's the whole job.
  • P — INTEGER. The number of rows in X11. constraint check bestie: 0 <= P <= M.
  • Q — INTEGER. The number of columns in X11 and X21. also 0 <= Q <= M.
  • X11 — DOUBLE PRECISION array, dimension (LDX11,Q). On entry, part of the orthogonal matrix whose CSD is desired. so like, bring the tea, we'll decompose it.
  • LDX11 — INTEGER. The leading dimension of X11. LDX11 >= MAX(1,P).
  • X21 — DOUBLE PRECISION array, dimension (LDX21,Q). On entry, part of the orthogonal matrix whose CSD is desired. same deal, different block.
  • LDX21 — INTEGER. The leading dimension of X21. LDX21 >= MAX(1,M-P).
  • THETA — DOUBLE PRECISION array, dimension (R), in which R = MIN(P,M-P,Q,M-Q).
    • C = DIAG( COS(THETA(1)), ... , COS(THETA(R)) ) and
    • S = DIAG( SIN(THETA(1)), ... , SIN(THETA(R)) ).
  • U1 — DOUBLE PRECISION array, dimension (P). If JOBU1 = 'Y', U1 contains the P-by-P orthogonal matrix U1. iconic.
  • LDU1 — INTEGER. The leading dimension of U1. If JOBU1 = 'Y', LDU1 >= MAX(1,P).
  • U2 — DOUBLE PRECISION array, dimension (M-P). If JOBU2 = 'Y', U2 contains the (M-P)-by-(M-P) orthogonal matrix U2.
  • LDU2 — INTEGER. The leading dimension of U2. If JOBU2 = 'Y', LDU2 >= MAX(1,M-P).
  • V1T — DOUBLE PRECISION array, dimension (Q). If JOBV1T = 'Y', V1T contains the Q-by-Q matrix orthogonal matrix V1**T. yes the transpose is already in the name, we don't make the rules.
  • LDV1T — INTEGER. The leading dimension of V1T. If JOBV1T = 'Y', LDV1T >= MAX(1,Q).
  • WORK — DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. If INFO > 0 on exit, WORK(2:R) contains the values PHI(1), ..., PHI(R-1) that, together with THETA(1), ..., THETA(R), define the matrix in intermediate bidiagonal-block form remaining after nonconvergence. INFO specifies the number of nonzero PHI's. so if it didn't converge, the leftovers are just... sitting there in WORK. rude but informative. 🙈
  • LWORK — INTEGER. The dimension of the array WORK.
If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the work array, and no error message related to LWORK is issued by XERBLA.
  • IWORK — INTEGER array, dimension (M-MIN(P,M-P,Q,M-Q)). that's the whole description bestie, no notes.
  • INFO — INTEGER. the receipts:
    • = 0: successful exit.
    • < 0: if INFO = -i, the i-th argument had an illegal value.
    • > 0: DBBCSD did not converge. See the description of WORK above for details.

References 📚

  • [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. Algorithms, 50(1):33-65, 2009.

Author ✨

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

dorg2l — generate Q from a QL factorization 🦋

   subroutine dorg2l (integer M, integer N, integer K, double precision,
       dimension( lda, * ) A, integer LDA, double precision, dimension( * )
       TAU, double precision, dimension( * ) WORK, integer INFO)

DORG2L generates all or part of the orthogonal matrix Q from a QL factorization determined by sgeqlf (unblocked algorithm). unblocked!! the little one!! 🥺

Purpose 💜

DORG2L generates an m by n real matrix Q with orthonormal columns, which is defined as the last n columns of a product of k elementary reflectors of order m

      Q  =  H(k) . . . H(2) H(1)

as returned by DGEQLF. note the order — H(k) comes FIRST, it's going backwards, and that's on purpose. periodt.

Parameters 🎀

  • M — INTEGER. The number of rows of the matrix Q. M >= 0.
  • N — INTEGER. The number of columns of the matrix Q. M >= N >= 0.
  • K — INTEGER. The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0.
  • A — DOUBLE PRECISION array, dimension (LDA,N).
    • On entry, the (n-k+i)-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQLF in the last k columns of its array argument A.
    • On exit, the m by n matrix Q. glow up. 💅
  • LDA — INTEGER. The first dimension of the array A. LDA >= max(1,M).
  • TAU — DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQLF.
  • WORK — DOUBLE PRECISION array, dimension (N). no further comment, it just works here.
  • INFO — INTEGER.
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument has an illegal value

Author ✨

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

dorg2r — generate Q from a QR factorization 🌸

   subroutine dorg2r (integer M, integer N, integer K, double precision,
       dimension( lda, * ) A, integer LDA, double precision, dimension( * )
       TAU, double precision, dimension( * ) WORK, integer INFO)

DORG2R generates all or part of the orthogonal matrix Q from a QR factorization determined by sgeqrf (unblocked algorithm). yes bestie it's the sibling of dorg2l, they're twins but one goes left and one goes right. 🫶

Purpose 💖

DORG2R generates an m by n real matrix Q with orthonormal columns, which is defined as the first n columns of a product of k elementary reflectors of order m

      Q  =  H(1) H(2) . . . H(k)

as returned by DGEQRF. see how it's H(1) first here? forward order, main character energy, exactly the opposite of her sister. ✨

Parameters 🎀

  • M — INTEGER. The number of rows of the matrix Q. M >= 0.
  • N — INTEGER. The number of columns of the matrix Q. M >= N >= 0.
  • K — INTEGER. The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0.
  • A — DOUBLE PRECISION array, dimension (LDA,N).
    • On entry, the i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A.
    • On exit, the m-by-n matrix Q.
  • LDA — INTEGER. The first dimension of the array A. LDA >= max(1,M).
  • TAU — DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF.
  • WORK — DOUBLE PRECISION array, dimension (N).
  • INFO — INTEGER.
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument has an illegal value

Author ✨

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

dorghr — assemble Q from the Hessenberg reduction 🌈

   subroutine dorghr (integer N, integer ILO, integer IHI, double precision,
       dimension( lda, * ) A, integer LDA, double precision, dimension( * )
       TAU, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGHR

Purpose 💜

DORGHR generates a real orthogonal matrix Q which is defined as the product of IHI-ILO elementary reflectors of order N, as returned by DGEHRD:

      Q = H(ilo) H(ilo+1) . . . H(ihi-1).

Parameters 🎀

  • N — INTEGER. The order of the matrix Q. N >= 0.
  • ILO — INTEGER.
  • IHI — INTEGER.
    • ILO and IHI must have the same values as in the previous call of DGEHRD. Q is equal to the unit matrix except in the submatrix Q(ilo+1:ihi,ilo+1:ihi).
    • 1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.
  • A — DOUBLE PRECISION array, dimension (LDA,N).
    • On entry, the vectors which define the elementary reflectors, as returned by DGEHRD.
    • On exit, the N-by-N orthogonal matrix Q.
  • LDA — INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • TAU — …and that is exactly where this chunk runs out bestie 😭 the TAU tea is literally mid-sentence, catch it in the next part 💅
  • TAU — TAU is DOUBLE PRECISION array, dimension (N-1). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEHRD. 💫
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. yes bestie it's doing double duty, it's a whole multitasker 💅
  • LWORK — LWORK is INTEGER. It's the dimension of the array WORK, and LWORK >= IHI-ILO. For optimum performance, LWORK >= (IHI-ILO)*NB, where NB is the optimal blocksize. 🧚

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. iykyk, it's a lil sneak peek of how much space you'd need 🌸

  • INFO — INFO is INTEGER.
    • = 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.

🌈 subroutine dorgl2 — the DORGL2 era begins

subroutine dorgl2 (integer M, integer N, integer K, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( * )
    TAU, double precision, dimension( * ) WORK, integer INFO)

DORGL2

✨ Purpose ✨

DORGL2 generates an m by n real matrix Q with orthonormal rows, which is defined as the first m rows of a product of k elementary reflectors of order n

Q  =  H(k) . . . H(2) H(1)

as returned by DGELQF. 🫶

Parameters

  • M — M is INTEGER. It's the number of rows of the matrix Q. M >= 0. 👑
  • N — N is INTEGER. It's the number of columns of the matrix Q. N >= M. 🦋
  • K — K is INTEGER. It's the number of elementary reflectors whose product defines the matrix Q. M >= K >= 0. ✨
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGELQF in the first k rows of its array argument A. On exit, the m-by-n matrix Q. 🎀
  • LDA — LDA is INTEGER. The first dimension of the array A. LDA >= max(1,M). 💅
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGELQF. 💖
  • WORK — WORK is DOUBLE PRECISION array, dimension (M). 🌸
  • INFO — INFO is INTEGER.
    • = 0: successful exit ✅
    • < 0: if INFO = -i, the i-th argument has an illegal value 😭

Author

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

🌈 subroutine dorglq

subroutine dorglq (integer M, integer N, integer K, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( * )
    TAU, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGLQ

✨ Purpose ✨

DORGLQ generates an M-by-N real matrix Q with orthonormal rows, which is defined as the first M rows of a product of K elementary reflectors of order N

Q  =  H(k) . . . H(2) H(1)

as returned by DGELQF. 🫶

Parameters

  • M — M is INTEGER. The number of rows of the matrix Q. M >= 0. 👑
  • N — N is INTEGER. The number of columns of the matrix Q. N >= M. 🦋
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. M >= K >= 0. ✨
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGELQF in the first k rows of its array argument A. On exit, the M-by-N matrix Q. 🎀
  • LDA — LDA is INTEGER. The first dimension of the array A. LDA >= max(1,M). 💅
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGELQF. 💖
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 🌸
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,M). For optimum performance LWORK >= M*NB, where NB is the optimal blocksize. 🧚

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. ⭐

  • INFO — INFO is INTEGER.
    • = 0: successful exit ✅
    • < 0: if INFO = -i, the i-th argument has an illegal value 💀

Author

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

🌈 subroutine dorgql

subroutine dorgql (integer M, integer N, integer K, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( * )
    TAU, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGQL

✨ Purpose ✨

DORGQL generates an M-by-N real matrix Q with orthonormal columns, which is defined as the last N columns of a product of K elementary reflectors of order M

Q  =  H(k) . . . H(2) H(1)

as returned by DGEQLF. 🫶

Parameters

  • M — M is INTEGER. The number of rows of the matrix Q. M >= 0. 👑
  • N — N is INTEGER. The number of columns of the matrix Q. M >= N >= 0. 🦋
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. ✨
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the (n-k+i)-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQLF in the last k columns of its array argument A. On exit, the M-by-N matrix Q. 🎀
  • LDA — LDA is INTEGER. The first dimension of the array A. LDA >= max(1,M). 💅
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQLF. 💖
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 🌸
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,N). For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. 🧚

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. ⭐

  • INFO — INFO is INTEGER.
    • = 0: successful exit ✅
    • < 0: if INFO = -i, the i-th argument has an illegal value 💀

Author

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

🌈 subroutine dorgqr

subroutine dorgqr (integer M, integer N, integer K, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( * )
    TAU, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGQR

✨ Purpose ✨

DORGQR generates an M-by-N real matrix Q with orthonormal columns, which is defined as the first N columns of a product of K elementary reflectors of order M

Q  =  H(1) H(2) . . . H(k)

as returned by DGEQRF. 🫶

bestie notice the order flipped on this one — it's H(1) H(2) . . . H(k), not the other way around. the way that matters 😭

Parameters

  • M — M is INTEGER. The number of rows of the matrix Q. M >= 0. 👑
  • N — N is INTEGER. The number of columns of the matrix Q. M >= N >= 0. 🦋
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. N >= K >= 0. ✨
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. On exit, the M-by-N matrix Q. 🎀
  • LDA — LDA is INTEGER. The first dimension of the array A. LDA >= max(1,M). 💅
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF. 💖
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 🌸
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,N). For optimum performance LWORK >= N*NB, where NB is the optimal blocksize. 🧚

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. ⭐

  • INFO — INFO is INTEGER.
    • = 0: successful exit ✅
    • < 0: if INFO = -i, the i-th argument has an illegal value 💀

Author

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

🌈 subroutine dorgr2

subroutine dorgr2 (integer M, integer N, integer K, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( * )
    TAU, double precision, dimension( * ) WORK, integer INFO)

DORGR2 generates all or part of the orthogonal matrix Q from an RQ factorization determined by sgerqf (unblocked algorithm). 🔥

wait hold on, bestie — yes, sgerqf, that's what it says, that's not me typoing, that's literally the text. single precision sibling energy in a double precision page, it's giving crossover episode 🫠 (staying faithful to the source, no cap)

Purpose ✨

Okay bestie, DORGR2 generates an m by n real matrix Q with orthonormal rows, which is defined as the last m rows of a product of k elementary reflectors of order n

Q  =  H(1) H(2) . . . H(k)

as returned by DGERQF. No cap, that's the whole vibe. 💅

Parameters 🎀

  • M — M is INTEGER. The number of rows of the matrix Q. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix Q. N >= M.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. M >= K >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the (m-k+i)-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGERQF in the last k rows of its array argument A. On exit, the m by n matrix Q.
  • LDA — LDA is INTEGER. The first dimension of the array A. LDA >= max(1,M).
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGERQF.
  • WORK — WORK is DOUBLE PRECISION array, dimension (M).
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument has an illegal value.

Author 💖

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.
subroutine dorgrq (integer M, integer N, integer K, double precision, dimension( lda, * ) A, integer LDA, double precision, dimension( * ) TAU, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGRQ 🦋

Purpose ✨

DORGRQ generates an M-by-N real matrix Q with orthonormal rows, which is defined as the last M rows of a product of K elementary reflectors of order N

Q  =  H(1) H(2) . . . H(k)

as returned by DGERQF. (Yes, same reflector bestie, just different letters. Slay. 💅)

Parameters 🎀

  • M — M is INTEGER. The number of rows of the matrix Q. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix Q. N >= M.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. M >= K >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the (m-k+i)-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGERQF in the last k rows of its array argument A. On exit, the M-by-N matrix Q.
  • LDA — LDA is INTEGER. The first dimension of the array A. LDA >= max(1,M).
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGERQF.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,M). For optimum performance LWORK >= M*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument has an illegal value.

Author 💖

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.
subroutine dorgtr (character UPLO, integer N, double precision, dimension( lda, * ) A, integer LDA, double precision, dimension( * ) TAU, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGTR 🌸

Purpose ✨

DORGTR generates a real orthogonal matrix Q which is defined as the product of n-1 elementary reflectors of order N, as returned by DSYTRD:

if UPLO = 'U', Q = H(n-1) . . . H(2) H(1),

if UPLO = 'L', Q = H(1) H(2) . . . H(n-1).

Parameters 🎀

  • UPLO — UPLO is CHARACTER*1. = 'U': Upper triangle of A contains elementary reflectors from DSYTRD; = 'L': Lower triangle of A contains elementary reflectors from DSYTRD.
  • N — N is INTEGER. The order of the matrix Q. N >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the vectors which define the elementary reflectors, as returned by DSYTRD. On exit, the N-by-N orthogonal matrix Q.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • TAU — TAU is DOUBLE PRECISION array, dimension (N-1). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DSYTRD.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,N-1). For optimum performance LWORK >= (N-1)*NB, where NB is the optimal blocksize. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
  • INFO — INFO is INTEGER. = 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.
subroutine dorgtsqr (integer M, integer N, integer MB, integer NB, double precision, dimension( lda, * ) A, integer LDA, double precision, dimension( ldt, * ) T, integer LDT, double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DORGTSQR 👑

Purpose ✨

DORGTSQR generates an M-by-N real matrix Q_out with orthonormal columns, which are the first N columns of a product of real orthogonal matrices of order M which are returned by DLATSQR

Q_out = first_N_columns_of( Q(1)_in * Q(2)_in * ... * Q(k)_in ).

See the documentation for DLATSQR. (iykyk, go read that one too. 💅)

Parameters 🎀

  • M — M is INTEGER. The number of rows of the matrix A. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix A. M >= N >= 0.
  • MB — MB is INTEGER. The row block size used by DLATSQR to return arrays A and T. MB > N. (Note that if MB > M, then M is used instead of MB as the row block size).
  • NB — NB is INTEGER. The column block size used by DLATSQR to return arrays A and T. NB >= 1. (Note that if NB > N, then N is used instead of NB as the column block size).
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry: The elements on and above the diagonal are not accessed. The elements below the diagonal represent the unit lower-trapezoidal blocked matrix V computed by DLATSQR that defines the input matrices Q_in(k) (ones on the diagonal are not stored) (same format as the output A below the diagonal in DLATSQR). On exit: The array A contains an M-by-N orthonormal matrix Q_out, i.e the columns of A are orthogonal unit vectors.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • T — T is DOUBLE PRECISION array, dimension (LDT, N * NIRB) where NIRB = Number_of_input_row_blocks = MAX( 1, CEIL((M-N)/(MB-N)) ) Let NICB = Number_of_input_col_blocks = CEIL(N/NB). The upper-triangular block reflectors used to define the input matrices Q_in(k), k=(1:NIRB*NICB). The block reflectors are stored in compact form in NIRB block reflector sequences. Each of NIRB block reflector sequences is stored in a larger NB-by-N column block of T and consists of NICB smaller NB-by-NB upper-triangular column blocks. (same format as the output T in DLATSQR).
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,min(NB1,N)).
  • WORK — WORK is (workspace) DOUBLE PRECISION array, dimension (MAX(2,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= (M+NB)*N. If LWORK = -1, then a workspace query is assumed. The routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
  • INFO — INFO is INTEGER. = 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.

Contributors 🌈

November 2019, Igor Kozachenko, Computer Science Division, University of California, Berkeley

  • A — ok bestie this is a DOUBLE PRECISION array, dimension (LDA,N), and it's doing the whole glow-up arc ✨

On entry: everything on and above the diagonal is just vibing, not used as input 🙈. What does matter is everything below the diagonal — that's the unit lower-trapezoidal blocked matrix V computed by DLATSQR that defines the input matrices Q_in(k) (and heads up: the ones sitting on the diagonal are not stored, they're implied). Wanna know more? Go read the DLATSQR docs, iykyk 💅

On exit: the array A now holds an M-by-N orthonormal matrix Q_out, meaning the columns of A are orthogonal unit vectors. She's serving orthonormal, periodt 👑

  • LDA — INTEGER, the leading dimension of the array A. Gotta be LDA >= max(1,M). No exceptions, fr fr.
  • T — DOUBLE PRECISION array, dimension (LDT, N * NIRB), where:
NIRB = Number_of_input_row_blocks
     = MAX( 1, CEIL((M-N)/(MB-N)) )

and also let's define, while we're here:

NICB = Number_of_input_col_blocks
     = CEIL(N/NB)

This array holds the upper-triangular block reflectors used to define the input matrices Q_in(k), for k=(1:NIRB*NICB). The block reflectors are stored in compact form in NIRB block reflector sequences 🌸. Each of those NIRB block reflector sequences lives inside a larger NB-by-N column block of T, and is made up of NICB smaller NB-by-NB upper-triangular column blocks. Again, DLATSQR has the full tea on the format of T ☕

  • LDT — INTEGER, the leading dimension of the array T. Must satisfy LDT >= max(1,min(NB,N)). Iconic constraint, love that for her.
  • WORK — (workspace) DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, then WORK(1) returns the optimal LWORK 🎀 (she's generous like that).
  • LWORK — INTEGER, the dimension of the array WORK. The requirement is:
LWORK >= NBLOCAL * MAX(NBLOCAL,(N-NBLOCAL))

where NBLOCAL=MIN(NB,N).

If LWORK = -1, then a workspace query is assumed 🕵️‍♀️. The routine only calculates the optimal size of the WORK array, hands it back as the first entry of WORK, and XERBLA will not throw any error message about LWORK. It's a vibe check, not an error, bestie.
  • INFO — INTEGER, the receipts 📋:
    • = 0: successful exit, we ate 🍽️✨
    • < 0: if INFO = -i, then the i-th argument had an illegal value 💀

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

💜 Contributors

November 2020, Igor Kozachenko, Computer Science Division, University of California, Berkeley


🦋 dorhr_col

subroutine dorhr_col (integer M, integer N, integer NB, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( ldt, *
    ) T, integer LDT, double precision, dimension( * ) D, integer INFO)

DORHR_COL

Purpose

DORHR_COL takes an M-by-N real matrix Q_in with orthonormal columns as input, stored in A, and performs Householder Reconstruction (HR) 🧚✨ — which is a fancy way of saying it reconstructs Householder vectors V(i) that implicitly represent another M-by-N matrix Q_out, with the property that:

Q_in = Q_out*S

where S is an N-by-N diagonal matrix whose diagonal entries are equal to +1 or -1 🎀. The Householder vectors (the columns V(i) of V) get stored in A on output, and the diagonal entries of S get stored in D. Block reflectors are also returned in T (same output format as DGEQRT). It's giving transformation, it's giving reconstruction 💅

Parameters

  • M — INTEGER. The number of rows of the matrix A. M >= 0.
  • N — INTEGER. The number of columns of the matrix A. M >= N >= 0.
  • NB — INTEGER. The column block size to be used in the reconstruction of Householder column vector blocks in the array A and the corresponding block reflectors in the array T. NB >= 1. (And note: if NB > N, then N is used instead of NB as the column block size — she adapts, she's flexible 💁‍♀️)
  • A — DOUBLE PRECISION array, dimension (LDA,N).

On entry: the array A contains an M-by-N orthonormal matrix Q_in, i.e. the columns of A are orthogonal unit vectors ✨

On exit: the elements below the diagonal of A represent the unit lower-trapezoidal matrix V of Householder column vectors V(i). The unit diagonal entries of V are not stored (same format as the output below the diagonal in A from DGEQRT). The matrix T and the matrix V stored on output in A implicitly define Q_out 🔮

The elements above the diagonal contain the factor U of the 'modified' LU-decomposition:

   Q_in - ( S ) = V * U
          ( 0 )

where 0 is a (M-N)-by-(M-N) zero matrix.

  • LDA — INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • T — DOUBLE PRECISION array, dimension (LDT, N).

Let's define, real quick:

NOCB = Number_of_output_col_blocks
     = CEIL(N/NB)

On exit, T(1:NB, 1:N) contains NOCB upper-triangular block reflectors used to define Q_out, stored in compact form as a sequence of upper-triangular NB-by-NB column blocks (same format as the output T in DGEQRT). The matrix T and the matrix V stored on output in A implicitly define Q_out.

NOTE: the lower triangles below the upper-triangular blocks will be filled with zeros. See Further Details for the full lore 📖
  • LDT — INTEGER. The leading dimension of the array T. LDT >= max(1,min(NB,N)).
  • D — DOUBLE PRECISION array, dimension min(M,N). The elements can only be plus or minus one 👯‍♀️

D(i) is constructed as D(i) = -SIGN(Q_in_i(i,i)), where 1 <= i <= min(M,N), and Q_in_i is Q_in after performing i-1 steps of “modified” Gaussian elimination. See Further Details below, bestie 🫶

  • INFO — INTEGER, the receipts:
    • = 0: successful exit 🎉
    • < 0: if INFO = -i, then the i-th argument had an illegal value 💀

Further Details

The computed M-by-M orthogonal factor Q_out is defined implicitly as a product of orthogonal matrices Q_out(i). Each Q_out(i) is stored in the compact WY-representation format in the corresponding blocks of matrices V (stored in A) and T 🌈

The M-by-N unit lower-trapezoidal matrix V stored in the M-by-N matrix A contains the column vectors V(i) in NB-size column blocks VB(j). For example, VB(1) contains the columns V(1), V(2), ... V(NB).

NOTE: the unit entries on the diagonal of Y are not stored in A 🙈

The number of column blocks is:

NOCB = Number_of_output_col_blocks = CEIL(N/NB)

where each block is of order NB except for the last block, which is of order LAST_NB = N - (NOCB-1)*NB 🌸

For example, if M=6, N=5 and NB=2, the matrix V is:

V = (    VB(1),   VB(2), VB(3) ) =

  = (   1                      )
    ( v21    1                 )
    ( v31  v32    1            )
    ( v41  v42  v43   1        )
    ( v51  v52  v53  v54    1  )
    ( v61  v62  v63  v54   v65 )

For each of the column blocks VB(i), an upper-triangular block reflector TB(i) is computed. These blocks are stored as a sequence of upper-triangular column blocks in the NB-by-N matrix T. The size of each TB(i) block is NB-by-NB, except for the last block, whose size is LAST_NB-by-LAST_NB ✨

For example, if M=6, N=5 and NB=2, the matrix T is:

T  = (    TB(1),    TB(2), TB(3) ) =

   = ( t11  t12  t13  t14   t15  )
     (      t22       t24        )

The M-by-M factor Q_out is given as a product of NOCB orthogonal M-by-M matrices Q_out(i):

Q_out = Q_out(1) * Q_out(2) * ... * Q_out(NOCB),

where each matrix Q_out(i) is given by the WY-representation using corresponding blocks from the matrices V and T:

Q_out(i) = I - VB(i) * TB(i) * (VB(i))**T,

where I is the identity matrix. Here is the formula with matrix dimensions:

Q(i){M-by-M} = I{M-by-M} - VB(i){M-by-INB} * TB(i){INB-by-INB} * (VB(i))**T {INB-by-M},

okay so that's the actual math for the block, bestie 💅 — where INB = NB, except for that very last block NOCB, where INB=LAST_NB. Yes queen, the last block is always the special one, main character behavior fr fr.

            =====
            NOTE:
            =====
NOTE TIME, pay attention bestie 💖

If Q_in is literally the result of doing a QR factorization like

            B = Q_in * R_in, then:

            B = (Q_out*S) * R_in = Q_out * (S * R_in) = Q_out * R_out.

So if you wanna interpret Q_out as the actual result of the QR factorization of B (the way that you would, lowkey), then the corresponding R_out should equal R_out = S * R_in — meaning some rows of R_in get multiplied by -1. Not me giving you a whole sign flip situation 🙈 but that's just how it is.

For all the nitty gritty details of the algorithm, go read [1]. It's giving ✨academic✨.

            [1] 'Reconstructing Householder vectors from tall-skinny QR',
                G. Ballard, J. Demmel, L. Grigori, M. Jacquelin, H.D. Nguyen,
                E. Solomonik, J. Parallel Distrib. Comput.,
                vol. 85, pp. 3-31, 2015.

Author 👑

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

Contributors: 🫶

  • November 2019, Igor Kozachenko, Computer Science Division, University of California, Berkeley

subroutine dorm2l 🌈

   subroutine dorm2l (character SIDE, character TRANS, integer M, integer N,
       integer K, double precision, dimension( lda, * ) A, integer LDA, double
       precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
       integer LDC, double precision, dimension( * ) WORK, integer INFO)

OK so DORM2L multiplies a general matrix by the orthogonal matrix from a QL factorization determined by sgeqlf — and yes bestie, it's the unblocked algorithm, the little one 🥺.

Purpose:

DORM2L overwrites the general real m by n matrix C with

                  Q * C  if SIDE = 'L' and TRANS = 'N', or

                  Q**T * C  if SIDE = 'L' and TRANS = 'T', or

                  C * Q  if SIDE = 'R' and TRANS = 'N', or

                  C * Q**T if SIDE = 'R' and TRANS = 'T',

where Q is a real orthogonal matrix defined as the product of k elementary reflectors, iykyk:

                  Q = H(k) . . . H(2) H(1)

as returned by DGEQLF. And Q is of order m if SIDE = 'L' and of order n if SIDE = 'R'. Slay 💅

Parameters

  • SIDE — it's a CHARACTER*1, okay? And it means:
    • = 'L': apply Q or Q**T from the Left
    • = 'R': apply Q or Q**T from the Right
  • TRANS — also CHARACTER*1, the moment of truth:
    • = 'N': apply Q (No transpose)
    • = 'T': apply Q**T (Transpose)
  • M — INTEGER, the number of rows of the matrix C. M >= 0.
  • N — INTEGER, the number of columns of the matrix C. N >= 0.
  • K — INTEGER, the number of elementary reflectors whose product defines the matrix Q.
    • If SIDE = 'L', M >= K >= 0;
    • if SIDE = 'R', N >= K >= 0.
  • A — DOUBLE PRECISION array, dimension (LDA,K). The i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQLF in the last k columns of its array argument A. A is modified by the routine but restored on exit. So she's messy for a sec but she cleans up after herself, periodt 💖
  • LDA — INTEGER, the leading dimension of the array A.
    • If SIDE = 'L', LDA >= max(1,M);
    • if SIDE = 'R', LDA >= max(1,N).
  • TAU — DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQLF.
  • C — DOUBLE PRECISION array, dimension (LDC,N).
    • On entry, the m by n matrix C.
    • On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. Byeee original C 😭
  • LDC — INTEGER, the leading dimension of the array C. LDC >= max(1,M).
  • WORK — DOUBLE PRECISION array, dimension
    • (N) if SIDE = 'L',
    • (M) if SIDE = 'R'
  • INFO — INTEGER, the vibe check:
    • = 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.

subroutine dorm2r 🌈

   subroutine dorm2r (character SIDE, character TRANS, integer M, integer N,
       integer K, double precision, dimension( lda, * ) A, integer LDA, double
       precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
       integer LDC, double precision, dimension( * ) WORK, integer INFO)

DORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sgeqrf — unblocked algorithm again, we love a small-and-mighty routine 🦋.

Purpose:

DORM2R overwrites the general real m by n matrix C with

                  Q * C  if SIDE = 'L' and TRANS = 'N', or

                  Q**T* C  if SIDE = 'L' and TRANS = 'T', or

                  C * Q  if SIDE = 'R' and TRANS = 'N', or

                  C * Q**T if SIDE = 'R' and TRANS = 'T',

where Q is a real orthogonal matrix defined as the product of k elementary reflectors, bestie:

                  Q = H(1) H(2) . . . H(k)

as returned by DGEQRF. Q is of order m if SIDE = 'L' and of order n if SIDE = 'R'. Same energy, different factorization 🔥

Parameters

  • SIDE — CHARACTER*1:
    • = 'L': apply Q or Q**T from the Left
    • = 'R': apply Q or Q**T from the Right
  • TRANS — CHARACTER*1:
    • = 'N': apply Q (No transpose)
    • = 'T': apply Q**T (Transpose)
  • M — INTEGER, the number of rows of the matrix C. M >= 0.
  • N — INTEGER, the number of columns of the matrix C. N >= 0.
  • K — INTEGER, the number of elementary reflectors whose product defines the matrix Q.
    • If SIDE = 'L', M >= K >= 0;
    • if SIDE = 'R', N >= K >= 0.
  • A — DOUBLE PRECISION array, dimension (LDA,K). The i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. A is modified by the routine but restored on exit. Again — temporary chaos, then fully restored, no cap 💅
  • LDA — INTEGER, the leading dimension of the array A.
    • If SIDE = 'L', LDA >= max(1,M);
    • if SIDE = 'R', LDA >= max(1,N).
  • TAU — DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF.
  • C — DOUBLE PRECISION array, dimension (LDC,N).
    • On entry, the m by n matrix C.
    • On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. Gone, reduced to atoms 🙈
  • LDC — INTEGER, the leading dimension of the array C. LDC >= max(1,M).
  • WORK — DOUBLE PRECISION array, dimension
    • (N) if SIDE = 'L',
    • (M) if SIDE = 'R'
  • INFO — INTEGER:
    • = 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.

subroutine dormbr 🌈

   subroutine dormbr (character VECT, character SIDE, character TRANS, integer
       M, integer N, integer K, double precision, dimension( lda, * ) A,
       integer LDA, double precision, dimension( * ) TAU, double precision,
       dimension( ldc, * ) C, integer LDC, double precision, dimension( * )
       WORK, integer LWORK, integer INFO)

DORMBR — that's it, that's the whole one-liner, iconic brevity honestly 👑

Purpose:

If VECT = 'Q', DORMBR overwrites the general real M-by-N matrix C with

                            SIDE = 'L'     SIDE = 'R'
            TRANS = 'N':      Q * C          C * Q
            TRANS = 'T':      Q**T * C       C * Q**T

If VECT = 'P', DORMBR overwrites the general real M-by-N matrix C with

                            SIDE = 'L'     SIDE = 'R'
            TRANS = 'N':      P * C          C * P
            TRANS = 'T':      P**T * C       C * P**T

Here Q and P**T are the orthogonal matrices determined by DGEBRD when reducing a real matrix A to bidiagonal form: A = Q * B * P**T. And Q and P**T are defined as products of elementary reflectors H(i) and G(i) respectively. Two reflectors, two icons, we stan a duo 🫶

Let nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. So nq is the order of the orthogonal matrix Q or P**T that is being applied. Math stays mathing ✨

If VECT = 'Q', A is assumed to have been an NQ-by-K matrix:

            if nq >= k, Q = H(1) H(2) . . . H(k);
            if nq < k, Q = H(1) H(2) . . . H(nq-1).

If VECT = 'P', A is assumed to have been a K-by-NQ matrix:

            if k < nq, P = G(1) G(2) . . . G(k);
            if k >= nq, P = G(1) G(2) . . . G(nq-1).

Notice the inequalities flip-flop between the two cases, bestie — read them slow, they WILL catch you slipping 😭

Parameters

  • VECT — CHARACTER*1:
    • = 'Q': apply Q or Q**T;
    • = 'P': apply P or P**T.
  • SIDE — CHARACTER*1:
    • = 'L': apply Q, Q**T, P or P**T from the Left;
    • = 'R': apply Q, Q**T, P or P**T from the Right.
  • TRANS — CHARACTER*1:
    • = 'N': No transpose, apply Q or P;
    • = 'T': Transpose, apply Q**T or P**T.
  • M — INTEGER, the number of rows of the matrix C. M >= 0.
  • N — INTEGER, the number of columns of the matrix C. N >= 0.
  • K — INTEGER.
    • If VECT = 'Q', the number of columns in the original matrix reduced by DGEBRD.
    • If VECT = 'P', the number of rows in the original matrix reduced by DGEBRD.
    • K >= 0.
  • A — DOUBLE PRECISION array, dimension
    • (LDA,min(nq,K)) if VECT = 'Q'
    • (LDA,nq) if VECT = 'P'

The vectors which define the elementary reflectors H(i) and G(i), whose products determine the matrices Q and P, as returned by DGEBRD.

  • LDA — INTEGER, the leading dimension of the array A.
    • If VECT = 'Q', LDA >= max(1,nq);
    • if VECT = 'P', LDA >= max(1,min(nq,K)).
  • TAU —
  • TAU — TAU is a DOUBLE PRECISION array, dimension (min(nq,K)). Every TAU(i) has to hold the scalar factor of the elementary reflector H(i) or G(i) — whichever one is out here defining Q or P — exactly as DGEBRD handed it over in the array argument TAUQ or TAUP. ✨
  • C — C is a DOUBLE PRECISION array, dimension (LDC,N). On entry it's the M-by-N matrix C, and on exit C gets overwritten by Q*C or Q**T*C or C*Q**T or C*Q or P*C or P**T*C or C*P or C*P**T. She's replaced, she's transformed, she's not coming back bestie 💅
  • LDC — LDC is INTEGER. It's the leading dimension of the array C. Rule of the land: LDC >= max(1,M). 🫶
  • WORK — WORK is a DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, then WORK(1) returns the optimal LWORK. Iconic little peek-behind-the-curtain moment 👑
  • LWORK — LWORK is INTEGER, the dimension of the array WORK. So: if SIDE = 'L', then LWORK >= max(1,N); if SIDE = 'R', then LWORK >= max(1,M). And for optimum performance you want LWORK >= N*NB if SIDE = 'L', and LWORK >= M*NB if SIDE = 'R', where NB is the optimal blocksize. Optimum performance is a vibe, not a requirement 🌈

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. It's giving "just asking, not committing" 🧚

  • INFO — INFO is INTEGER. = 0: successful exit, we ate 🍓. < 0: if INFO = -i, the i-th argument had an illegal value — so go count your arguments, bestie 🙈

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


subroutine dormhr

subroutine dormhr (character SIDE, character TRANS, integer M, integer N,
    integer ILO, integer IHI, double precision, dimension( lda, * ) A,
    integer LDA, double precision, dimension( * ) TAU, double precision,
    dimension( ldc, * ) C, integer LDC, double precision, dimension( * )
    WORK, integer LWORK, integer INFO)

DORMHR 🌸

Purpose:

DORMHR overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix of order nq, with nq = m if
SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of
IHI-ILO elementary reflectors, as returned by DGEHRD:

Q = H(ilo) H(ilo+1) . . . H(ihi-1).

So Q is built from IHI-ILO elementary reflectors, stacked in that order, and it comes straight out of DGEHRD. Main character energy, honestly 👑

Parameters

  • SIDE — SIDE is CHARACTER*1. = 'L': apply Q or Q**T from the Left; = 'R': apply Q or Q**T from the Right. Pick a side, any side 💅
  • TRANS — TRANS is CHARACTER*1. = 'N': No transpose, apply Q; = 'T': Transpose, apply Q**T.
  • M — M is INTEGER. The number of rows of the matrix C. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix C. N >= 0.
  • ILO — ILO is INTEGER.
  • IHI — IHI is INTEGER.

ILO and IHI must have the same values as in the previous call of DGEHRD. Q is equal to the unit matrix except in the submatrix Q(ilo+1:ihi,ilo+1:ihi). If SIDE = 'L', then 1 <= ILO <= IHI <= M, if M > 0, and ILO = 1 and IHI = 0, if M = 0; if SIDE = 'R', then 1 <= ILO <= IHI <= N, if N > 0, and ILO = 1 and IHI = 0, if N = 0. Same values as last time, no improvising ⭐

  • A — A is a DOUBLE PRECISION array, dimension (LDA,M) if SIDE = 'L', (LDA,N) if SIDE = 'R'. It holds the vectors which define the elementary reflectors, as returned by DGEHRD.
  • LDA — LDA is INTEGER, the leading dimension of the array A. LDA >= max(1,M) if SIDE = 'L'; LDA >= max(1,N) if SIDE = 'R'.
  • TAU — TAU is a DOUBLE PRECISION array, dimension (M-1) if SIDE = 'L', (N-1) if SIDE = 'R'. TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEHRD.
  • C — C is a DOUBLE PRECISION array, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. Bye bye original C 🦋
  • LDC — LDC is INTEGER, the leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is a DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. ✨
  • LWORK — LWORK is INTEGER, the dimension of the array WORK. If SIDE = 'L', LWORK >= max(1,N); if SIDE = 'R', LWORK >= max(1,M). For optimum performance LWORK >= N*NB if SIDE = 'L', and LWORK >= M*NB if SIDE = 'R', where NB is the optimal blocksize.

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. 🌈

  • INFO — INFO is INTEGER. = 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.


subroutine dorml2

subroutine dorml2 (character SIDE, character TRANS, integer M, integer N,
    integer K, double precision, dimension( lda, * ) A, integer LDA, double
    precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
    integer LDC, double precision, dimension( * ) WORK, integer INFO)

DORML2 multiplies a general matrix by the orthogonal matrix from a LQ factorization determined by sgelqf (unblocked algorithm). 🎀

Purpose:

DORML2 overwrites the general real m by n matrix C with

      Q * C  if SIDE = 'L' and TRANS = 'N', or

      Q**T* C  if SIDE = 'L' and TRANS = 'T', or

      C * Q  if SIDE = 'R' and TRANS = 'N', or

      C * Q**T if SIDE = 'R' and TRANS = 'T',

where Q is a real orthogonal matrix defined as the product of k
elementary reflectors

      Q = H(k) . . . H(2) H(1)

as returned by DGELQF. Q is of order m if SIDE = 'L' and of order n
if SIDE = 'R'.

Note the order, bestie: Q = H(k) . . . H(2) H(1) — counting down, not up. DGELQF said so, so we do it 💜

Parameters

  • SIDE — SIDE is CHARACTER*1. = 'L': apply Q or Q**T from the Left; = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1. = 'N': apply Q (No transpose); = 'T': apply Q**T (Transpose).
  • M — M is INTEGER. The number of rows of the matrix C. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix C. N >= 0.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0.
  • A — A is a DOUBLE PRECISION array, dimension (LDA,M) if SIDE = 'L', (LDA,N) if SIDE = 'R'. The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGELQF in the first k rows of its array argument A. Important: A is modified by the routine but restored on exit. She goes out, she comes back, no harm done 🧚
  • LDA — LDA is INTEGER, the leading dimension of the array A. LDA >= max(1,K).
  • TAU — TAU is a DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGELQF.
  • C — C is a DOUBLE PRECISION array, dimension (LDC,N). On entry, the m by n matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. 💅
  • LDC — LDC is INTEGER, the leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is a DOUBLE PRECISION array, dimension (N) if SIDE = 'L', (M) if SIDE = 'R'. Yes bestie, no LWORK here — this one's the unblocked version, she keeps it simple 🌸
  • INFO — INFO is INTEGER. = 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.


subroutine dormlq

subroutine dormlq (character SIDE, character TRANS, integer M, integer N,
    integer K, double precision, dimension( lda, * ) A, integer LDA, double
    precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
    integer LDC, double precision, dimension( * ) WORK, integer LWORK,
    integer INFO)

DORMLQ 🔥

Purpose:

DORMLQ overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix defined as the product of k
elementary reflectors

      Q = H(k) . . . H(2) H(1)

as returned by DGELQF. Q is of order M if SIDE = 'L' and of order N
if SIDE = 'R'.

Same reflector stack, same DGELQF origin, but this is the blocked one — so hello again, LWORK 🫶

Parameters

  • SIDE — SIDE is CHARACTER*1. = 'L': apply Q or Q**T from the Left; = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1. = 'N': No transpose, apply Q; = 'T': Transpose, apply Q**T.
  • M — M is INTEGER. The number of rows of the matrix C. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix C. N >= 0.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0.
  • A
  • A — A is DOUBLE PRECISION array, dimension
    • (LDA,M) if SIDE = 'L',
    • (LDA,N) if SIDE = 'R'

bestie the i-th row has GOT to hold the vector that defines the elementary reflector H(i), for i = 1,2,...,k, exactly as DGELQF handed it back in the first k rows of its array argument A. 💅

  • LDA — LDA is INTEGER — it's the leading dimension of the array A, and the rule is LDA >= max(1,K). no cap. ✨
  • TAU — TAU is DOUBLE PRECISION array, dimension (K) — TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGELQF. 🎀
  • C — C is DOUBLE PRECISION array, dimension (LDC,N) — on entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. it literally gets replaced, so don't come crying if your original matrix is gone 😭
  • LDC — LDC is INTEGER — the leading dimension of the array C, and LDC >= max(1,M). 🫶
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) — on exit, if INFO = 0, then WORK(1) returns the optimal LWORK. 🦋
  • LWORK — LWORK is INTEGER — the dimension of the array WORK.
    • If SIDE = 'L', LWORK >= max(1,N);
    • if SIDE = 'R', LWORK >= max(1,M).
    • For good performance, LWORK should generally be larger. (like, treat the minimum as a floor, not a flex ✨)
If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. it's giving "just asking, not telling" 💅
  • INFO — INFO is INTEGER
    • = 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.


subroutine dormql 💜

subroutine dormql (character SIDE, character TRANS, integer M, integer N,
    integer K, double precision, dimension( lda, * ) A, integer LDA, double
    precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
    integer LDC, double precision, dimension( * ) WORK, integer LWORK,
    integer INFO)

DORMQL

Purpose 🎯

DORMQL overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix defined as the product of k elementary reflectors

      Q = H(k) . . . H(2) H(1)

as returned by DGEQLF. Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'. it's the reverse-order one, keep that in mind bestie 👑

Parameters ✨

  • SIDE — SIDE is CHARACTER*1
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — M is INTEGER — the number of rows of the matrix C. M >= 0.
  • N — N is INTEGER — the number of columns of the matrix C. N >= 0.
  • K — K is INTEGER — the number of elementary reflectors whose product defines the matrix Q.
    • If SIDE = 'L', M >= K >= 0;
    • if SIDE = 'R', N >= K >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,K) — the i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQLF in the last k columns of its array argument A. (last, not first — don't mix her up with the others 🙈)
  • LDA — LDA is INTEGER — the leading dimension of the array A.
    • If SIDE = 'L', LDA >= max(1,M);
    • if SIDE = 'R', LDA >= max(1,N).
  • TAU — TAU is DOUBLE PRECISION array, dimension (K) — TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQLF. 🎀
  • C — C is DOUBLE PRECISION array, dimension (LDC,N) — on entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
  • LDC — LDC is INTEGER — the leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) — on exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER — the dimension of the array WORK.
    • If SIDE = 'L', LWORK >= max(1,N);
    • if SIDE = 'R', LWORK >= max(1,M).
    • For good performance, LWORK should generally be larger.
If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. ✨
  • INFO — INFO is INTEGER
    • = 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.


subroutine dormqr 🌸

subroutine dormqr (character SIDE, character TRANS, integer M, integer N,
    integer K, double precision, dimension( lda, * ) A, integer LDA, double
    precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
    integer LDC, double precision, dimension( * ) WORK, integer LWORK,
    integer INFO)

DORMQR

Purpose 🎯

DORMQR overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix defined as the product of k elementary reflectors

      Q = H(1) H(2) . . . H(k)

as returned by DGEQRF. Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'. the classic, the blueprint, the moment 💅

Parameters ✨

  • SIDE — SIDE is CHARACTER*1
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — M is INTEGER — the number of rows of the matrix C. M >= 0.
  • N — N is INTEGER — the number of columns of the matrix C. N >= 0.
  • K — K is INTEGER — the number of elementary reflectors whose product defines the matrix Q.
    • If SIDE = 'L', M >= K >= 0;
    • if SIDE = 'R', N >= K >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,K) — the i-th column must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGEQRF in the first k columns of its array argument A. 🦋
  • LDA — LDA is INTEGER — the leading dimension of the array A.
    • If SIDE = 'L', LDA >= max(1,M);
    • if SIDE = 'R', LDA >= max(1,N).
  • TAU — TAU is DOUBLE PRECISION array, dimension (K) — TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGEQRF. 🎀
  • C — C is DOUBLE PRECISION array, dimension (LDC,N) — on entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q.
  • LDC — LDC is INTEGER — the leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) — on exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER — the dimension of the array WORK.
    • If SIDE = 'L', LWORK >= max(1,N);
    • if SIDE = 'R', LWORK >= max(1,M).
    • For good performance, LWORK should generally be larger.
If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. 💜
  • INFO — INFO is INTEGER
    • = 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.


subroutine dormr2 🍓

subroutine dormr2 (character SIDE, character TRANS, integer M, integer N,
    integer K, double precision, dimension( lda, * ) A, integer LDA, double
    precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
    integer LDC, double precision, dimension( * ) WORK, integer INFO)

DORMR2 multiplies a general matrix by the orthogonal matrix from a RQ factorization determined by sgerqf (unblocked algorithm). the little unblocked one, doing her best, and honestly? slaying 🌈

Purpose 🎯

DORMR2 overwrites the general real m by n matrix C with

      Q * C  if SIDE = 'L' and TRANS = 'N', or

      Q**T* C  if SIDE = 'L' and TRANS = 'T', or

      C * Q  if SIDE = 'R' and TRANS = 'N', or

      C * Q**T if SIDE = 'R' and TRANS = 'T',

where Q is a real orthogonal matrix defined as the product of k elementary reflectors

      Q = H(1) H(2) . . . H(k)

as returned by DGERQF. Q is of order m if SIDE = 'L' and of order n if SIDE = 'R'. 🧚

Parameters ✨

  • SIDE — SIDE is CHARACTER*1
    • = 'L': apply Q or Q**T from the Left
    • = 'R': apply Q or Q**T from the Right
  • TRANS — TRANS is CHARACTER*1
    • = 'N': apply Q (No transpose)
    • = 'T': apply Q' (Transpose)
  • M — M is INTEGER — the number of rows of the matrix C. M >= 0.
  • N — N is INTEGER — the number of columns of the matrix C. N >= 0.
  • K — K is INTEGER — the number of elementary reflectors whose product defines the matrix Q.
    • If SIDE = 'L', M >= K >= 0;
    • if SIDE = 'R', N >= K >= 0.
  • A —

A is DOUBLE PRECISION array, dimension

(LDA,M) if SIDE = 'L',
(LDA,N) if SIDE = 'R'

The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGERQF in the last k rows of its array argument A. A is modified by the routine but restored on exit. So like, it goes in for a glow-up and comes back exactly how it left. Iconic behaviour honestly. 💅

  • LDA — LDA is INTEGER. It's the leading dimension of the array A. So LDA >= max(1,K). Keep it big enough bestie, that's the whole vibe. ✨
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGERQF. It's the lil scalar sidekick, you don't build it yourself, DGERQF hands it to you. 🎀
  • C — C is DOUBLE PRECISION array, dimension (LDC,N). On entry, the m by n matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. Yeah she gets fully overwritten, so if you needed the original you should've saved a copy, no cap. 😭
  • LDC — LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is DOUBLE PRECISION array, dimension
(N) if SIDE = 'L',
(M) if SIDE = 'R'
  • INFO — INFO is INTEGER
    • = 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.

Contributors:

A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

Further Details:


subroutine dormrq

subroutine dormrq (character SIDE, character TRANS, integer M, integer N,
    integer K, double precision, dimension( lda, * ) A, integer LDA, double
    precision, dimension( * ) TAU, double precision, dimension( ldc, * ) C,
    integer LDC, double precision, dimension( * ) WORK, integer LWORK,
    integer INFO)

DORMRQ bestie it's literally just the name, that's the whole title ✨

Purpose:

DORMRQ overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix defined as the product of k elementary reflectors

Q = H(1) H(2) . . . H(k)

as returned by DGERQF. Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'. So depending on which side you're applying from, the size of Q switches up — main character energy, she adapts. 👑

Parameters

  • SIDE — SIDE is CHARACTER*1
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — M is INTEGER. The number of rows of the matrix C. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix C. N >= 0.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0.
  • A — A is DOUBLE PRECISION array, dimension
(LDA,M) if SIDE = 'L',
(LDA,N) if SIDE = 'R'

The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DGERQF in the last k rows of its array argument A. Note: no "restored on exit" here, so don't assume it's untouched, k? 🙈

  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,K).
  • TAU — TAU is DOUBLE PRECISION array, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DGERQF.
  • C — C is DOUBLE PRECISION array, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. Again bestie, overwritten. Gone. Poof. 🦋
  • LDC — LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. Ooh she's reporting back, love that for her. 💜
  • LWORK — LWORK is INTEGER. The dimension of the array WORK.
    • If SIDE = 'L', LWORK >= max(1,N);
    • if SIDE = 'R', LWORK >= max(1,M).
    • For good performance, LWORK should generally be larger. Like, bigger is better here, it's giving "treat yourself to some extra workspace". ✨

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. So -1 is the sneaky "just tell me how much room I need" mode, no yelling involved. 🤫

  • INFO — INFO is INTEGER
    • = 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.


subroutine dormrz

subroutine dormrz (character SIDE, character TRANS, integer M, integer N,
    integer K, integer L, double precision, dimension( lda, * ) A, integer
    LDA, double precision, dimension( * ) TAU, double precision, dimension(
    ldc, * ) C, integer LDC, double precision, dimension( * ) WORK, integer
    LWORK, integer INFO)

DORMRZ ✨

Purpose:

DORMRZ overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix defined as the product of k elementary reflectors

Q = H(1) H(2) . . . H(k)

as returned by DTZRZF. Q is of order M if SIDE = 'L' and of order N if SIDE = 'R'. Same energy as before, different factorization bestie — this one's repping DTZRZF. 🎀

Parameters

  • SIDE — SIDE is CHARACTER*1
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — M is INTEGER. The number of rows of the matrix C. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix C. N >= 0.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. If SIDE = 'L', M >= K >= 0; if SIDE = 'R', N >= K >= 0.
  • L — L is INTEGER. The number of columns of the matrix A containing the meaningful part of the Householder reflectors. If SIDE = 'L', M >= L >= 0, if SIDE = 'R', N >= L >= 0. This is the "how much of this even matters" count, lowkey important. 👀
  • A —
  • A — DOUBLE PRECISION array</p>, dimension (LDA,M) if SIDE = 'L', and (LDA,N) if SIDE = 'R'. Row i has to hold the vector that defines the elementary reflector H(i), for i = 1,2,...,k, exactly as DTZRZF hands it back in the last k rows of its array argument A. 💅 Fun lil fact: A gets modified by the routine but restored on exit — she leaves no trace, iconic behavior fr fr.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,K).
  • TAU — DOUBLE PRECISION array</p>, dimension (K). TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DTZRZF. 🎀
  • C — DOUBLE PRECISION array</p>, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**H*C or C*Q**H or C*Q. She said "new matrix, who dis" ✨
  • LDC — LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
  • WORK — DOUBLE PRECISION array</p>, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 🫶
  • LWORK — LWORK is INTEGER. The dimension of the array WORK.
    • If SIDE = 'L', LWORK >= max(1,N);
    • if SIDE = 'R', LWORK >= max(1,M).
    • For good performance, LWORK should generally be larger. bigger workspace = better vibes, lowkey

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. 💀

  • INFO — INFO is INTEGER.
    • = 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.


Contributors: 💖

A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA


Further Details: 🦋

okay bestie this section is literally empty in the original. nothing here. a beautiful void. the girls are resting. 😌✨

subroutine dormtr 💫

subroutine dormtr (character SIDE, character UPLO, character TRANS, integer
    M, integer N, double precision, dimension( lda, * ) A, integer LDA,
    double precision, dimension( * ) TAU, double precision, dimension( ldc,
    * ) C, integer LDC, double precision, dimension( * ) WORK, integer
    LWORK, integer INFO)

DORMTR 👑

Purpose:

DORMTR overwrites the general real M-by-N matrix C with

                SIDE = 'L'     SIDE = 'R'
TRANS = 'N':      Q * C          C * Q
TRANS = 'T':      Q**T * C       C * Q**T

where Q is a real orthogonal matrix of order nq, with nq = m if SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of nq-1 elementary reflectors, as returned by DSYTRD:

  • if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1);
  • if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1).

the way she builds Q out of reflectors one by one… main character energy, no cap 💅

Parameters

  • SIDE — SIDE is CHARACTER*1.
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • UPLO — UPLO is CHARACTER*1.
    • = 'U': Upper triangle of A contains elementary reflectors from DSYTRD;
    • = 'L': Lower triangle of A contains elementary reflectors from DSYTRD.
  • TRANS — TRANS is CHARACTER*1.
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — M is INTEGER. The number of rows of the matrix C. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix C. N >= 0.
  • A — DOUBLE PRECISION array</p>, dimension (LDA,M) if SIDE = 'L', (LDA,N) if SIDE = 'R'. The vectors which define the elementary reflectors, as returned by DSYTRD. 🎀
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M) if SIDE = 'L'; LDA >= max(1,N) if SIDE = 'R'.
  • TAU — DOUBLE PRECISION array</p>, dimension (M-1) if SIDE = 'L', (N-1) if SIDE = 'R'. TAU(i) must contain the scalar factor of the elementary reflector H(i), as returned by DSYTRD.
  • C — DOUBLE PRECISION array</p>, dimension (LDC,N). On entry, the M-by-N matrix C. On exit, C is overwritten by Q*C or Q**T*C or C*Q**T or C*Q. ✨
  • LDC — LDC is INTEGER. The leading dimension of the array C. LDC >= max(1,M).
  • WORK — DOUBLE PRECISION array</p>, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK.
    • If SIDE = 'L', LWORK >= max(1,N);
    • if SIDE = 'R', LWORK >= max(1,M).
    • For optimum performance LWORK >= N*NB if SIDE = 'L', and LWORK >= M*NB if SIDE = 'R', where NB is the optimal blocksize. the bigger the better, bestie, she loves a fat workspace

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.

  • INFO — INFO is INTEGER.
    • = 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.


subroutine dpbcon 🦋

subroutine dpbcon (character UPLO, integer N, integer KD, double precision,
    dimension( ldab, * ) AB, integer LDAB, double precision ANORM, double
    precision RCOND, double precision, dimension( * ) WORK, integer,
    dimension( * ) IWORK, integer INFO)

DPBCON

Purpose:

DPBCON estimates the reciprocal of the condition number (in the 1-norm) of a real symmetric positive definite band matrix using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPBTRF.

An estimate is obtained for norm(inv(A)), and the reciprocal of the condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). she's literally just doing division but make it dramatic 💅

Parameters

  • UPLO — UPLO is CHARACTER*1.
    • = 'U': Upper triangular factor stored in AB;
    • = 'L': Lower triangular factor stored in AB.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • KD — KD is INTEGER. The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  • AB — DOUBLE PRECISION array</p>, dimension (LDAB,N). The triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the band matrix A, stored in the first KD+1 rows of the array. The j-th column of U or L is stored in the j-th column of the array AB as follows:
    • if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO ='L', AB(1+i-j,j) = L(i,j) for j<=i<=min(n,j+kd).
ngl the index math here is giving "iykyk" — copy it exactly, don't freestyle it 🫶
  • LDAB — LDAB is INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • ANORM — ANORM is DOUBLE PRECISION. The 1-norm (or infinity-norm) of the symmetric band matrix A.
  • RCOND — RCOND is DOUBLE PRECISION. The reciprocal of the condition number of the matrix A, computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an estimate of the 1-norm of inv(A) computed in this routine.
  • WORK — DOUBLE PRECISION array</p>, dimension (3*N)
  • IWORK — INTEGER array</p>, dimension (N)
  • INFO — INFO is INTEGER.
    • = 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.


subroutine dpbequ 🌸

subroutine dpbequ (character UPLO, integer N, integer KD, double precision,
    dimension( ldab, * ) AB, integer LDAB, double precision, dimension( * )
    S, double precision SCOND, double precision AMAX, integer INFO)

DPBEQU

Purpose:

DPBEQU computes row and column scalings intended to equilibrate a symmetric positive definite band matrix A and reduce its condition number (with respect to the two-norm). S contains the scale factors, S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This choice of S puts the condition number of B within a factor N of the smallest possible condition number over all possible diagonal scalings. she's out here making the diagonal all ones like a little glow-up montage ✨👑

Parameters

  • UPLO — UPLO is CHARACTER*1.
    • = 'U': Upper triangular of A is stored;
    • = 'L': Lower triangular of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • KD — KD is INTEGER. The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  • AB — DOUBLE PRECISION array</p>, dimension (LDAB,N). The upper or lower triangle of the symmetric band matrix A, stored in the first KD+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows:
    • if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).
  • LDAB — LDAB is INTEGER. The leading dimension of the array A. LDAB >= KD+1.
  • S — DOUBLE PRECISION array</p>, dimension (N). If INFO = 0, S contains the scale factors for A.
  • SCOND — SCOND is DOUBLE PRECISION. If INFO = 0, S contains the ratio of the smallest S(i) to the largest S(i). If SCOND >= 0.1 and AMAX is neither too large nor too small, it is not worth scaling by S. 💀 so don't bother, bestie, save yourself the work
  • AMAX —
  • AMAX — AMAX is DOUBLE PRECISION ✨ it's the absolute value of the biggest matrix element, bestie. And listen: if AMAX is very close to overflowing or very close to underflowing, the matrix should be scaled. no cap, that's a real vibe check 🫶
  • INFO — INFO is INTEGER and it's literally the receipts:
    • = 0: successful exit 🎉
    • < 0: if INFO = -i, the i-th argument had an illegal value 🙈
    • > 0: if INFO = i, the i-th diagonal element is nonpositive 💀

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🦋 dpbrfs 🦋

subroutine dpbrfs (character UPLO, integer N, integer KD, integer NRHS,
    double precision, dimension( ldab, * ) AB, integer LDAB, double
    precision, dimension( ldafb, * ) AFB, integer LDAFB, double precision,
    dimension( ldb, * ) B, integer LDB, double precision, dimension( ldx, *
    ) X, integer LDX, double precision, dimension( * ) FERR, double
    precision, dimension( * ) BERR, double precision, dimension( * ) WORK,
    integer, dimension( * ) IWORK, integer INFO)
    DPBRFS

Purpose

okay so DPBRFS improves the computed solution to a system of linear equations when the coefficient matrix is symmetric positive definite and banded, and it hands you error bounds plus backward error estimates for the solution. it's giving glow-up for your answer 💅✨

Parameters

  • UPLO

UPLO is CHARACTER*1

  • = 'U': Upper triangle of A is stored;
  • = 'L': Lower triangle of A is stored.
  • N

N is INTEGER The order of the matrix A. N >= 0.

  • KD

KD is INTEGER The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.

  • NRHS

NRHS is INTEGER The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0.

  • AB

AB is DOUBLE PRECISION array, dimension (LDAB,N) The upper or lower triangle of the symmetric band matrix A, stored in the first KD+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows: if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

  • LDAB

LDAB is INTEGER The leading dimension of the array AB. LDAB >= KD+1.

  • AFB

AFB is DOUBLE PRECISION array, dimension (LDAFB,N) The triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the band matrix A as computed by DPBTRF, in the same storage format as A (see AB).

  • LDAFB

LDAFB is INTEGER The leading dimension of the array AFB. LDAFB >= KD+1.

  • B

B is DOUBLE PRECISION array, dimension (LDB,NRHS) The right hand side matrix B.

  • LDB

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

  • X

X is DOUBLE PRECISION array, dimension (LDX,NRHS) On entry, the solution matrix X, as computed by DPBTRS. On exit, the improved solution matrix X. main character arc fr 🦋

  • LDX

LDX is INTEGER The leading dimension of the array X. LDX >= max(1,N).

  • FERR

FERR is DOUBLE PRECISION array, dimension (NRHS) The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error. lowkey it's a lil dramatic but in a safe way 🎀

  • BERR

BERR is DOUBLE PRECISION array, dimension (NRHS) The componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution).

  • WORK

WORK is DOUBLE PRECISION array, dimension (3*N)

  • IWORK

IWORK is INTEGER array, dimension (N)

  • INFO

INFO is INTEGER

  • = 0: successful exit
  • < 0: if INFO = -i, the i-th argument had an illegal value

Internal Parameters

ITMAX is the maximum number of steps of iterative refinement. ✨

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🌸 dpbstf 🌸

subroutine dpbstf (character UPLO, integer N, integer KD, double precision,
    dimension( ldab, * ) AB, integer LDAB, integer INFO)
    DPBSTF

Purpose

DPBSTF computes a split Cholesky factorization of a real symmetric positive definite band matrix A. it's the split girlie of the Cholesky world 💅

This routine is designed to be used in conjunction with DSBGST. they're a package deal, iykyk 🫶

The factorization has the form A = S**T*S where S is a band matrix of the same bandwidth as A and the following structure:

  S = ( U    )
      ( M  L )

where U is upper triangular of order m = (n+kd)/2, and L is lower triangular of order n-m. the way that math just... slices 🎀

Parameters

  • UPLO

UPLO is CHARACTER*1

  • = 'U': Upper triangle of A is stored;
  • = 'L': Lower triangle of A is stored.
  • N

N is INTEGER The order of the matrix A. N >= 0.

  • KD

KD is INTEGER The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.

  • AB

AB is DOUBLE PRECISION array, dimension (LDAB,N) On entry, the upper or lower triangle of the symmetric band matrix A, stored in the first kd+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows: if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

On exit, if INFO = 0, the factor S from the split Cholesky factorization A = S**T*S. See Further Details. ✨

  • LDAB

LDAB is INTEGER The leading dimension of the array AB. LDAB >= KD+1.

  • INFO

INFO is INTEGER

  • = 0: successful exit
  • < 0: if INFO = -i, the i-th argument had an illegal value
  • > 0: if INFO = i, the factorization could not be completed, because the updated element a(i,i) was negative; the matrix A is not positive definite. 🫠 so close bestie, but no.

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details

The band storage scheme is illustrated by the following example, when N = 7, KD = 2:

 S = ( s11  s12  s13                     )
     (      s22  s23  s24                )
     (           s33  s34                )
     (                s44                )
     (           s53  s54  s55           )
     (                s64  s65  s66      )
     (                     s75  s76  s77 )

If UPLO = 'U', the array AB holds:

 on entry:                          on exit:

  *    *   a13  a24  a35  a46  a57   *    *   s13  s24  s53  s64  s75
  *   a12  a23  a34  a45  a56  a67   *   s12  s23  s34  s54  s65  s76
 a11  a22  a33  a44  a55  a66  a77  s11  s22  s33  s44  s55  s66  s77

If UPLO = 'L', the array AB holds:

 on entry:                          on exit:

 a11  a22  a33  a44  a55  a66  a77  s11  s22  s33  s44  s55  s66  s77
 a21  a32  a43  a54  a65  a76   *   s12  s23  s34  s54  s65  s76   *
 a31  a42  a53  a64  a64   *    *   s13  s24  s53  s64  s75   *    *

Array elements marked * are not used by the routine. they're just there, decorative, unbothered 💅


🎀 dpbtf2 🎀

subroutine dpbtf2 (character UPLO, integer N, integer KD, double precision,
    dimension( ldab, * ) AB, integer LDAB, integer INFO)
    DPBTF2

DPBTF2 computes the Cholesky factorization of a symmetric/Hermitian positive definite band matrix (unblocked algorithm). the unblocked version — the OG, the blueprint, the pre-glow-up era 🌸

Purpose

DPBTF2 computes the Cholesky factorization of a real symmetric positive definite band matrix A. ✨

The factorization has the form

   A = U**T * U ,  if UPLO = 'U', or
   A = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix, U**T is the transpose of U, and L is lower triangular.

This is the unblocked version of the algorithm, calling Level 2 BLAS. it's giving "doing it the long way but make it iconic" 👑

Parameters

  • UPLO

UPLO is CHARACTER*1 Specifies whether the upper or lower triangular part of the symmetric matrix A is stored:

  • = 'U': Upper triangular
  • = 'L': Lower triangular
  • N

N is INTEGER The order of the matrix A. N >= 0.

  • KD

KD is INTEGER The number of super-diagonals of the matrix A if UPLO = 'U', or the number of sub-diagonals if UPLO = 'L'. KD >= 0.

  • AB

AB is DOUBLE PRECISION array, dimension (LDAB,N) On entry, the upper or lower triangle of the symmetric band matrix A, stored in the first KD+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows: if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

On exit, if INFO = 0, the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the band matrix A, in the same storage format as A. 🦋

  • LDAB

LDAB is INTEGER The leading dimension of the array AB. LDAB >= KD+1.

  • INFO

INFO is INTEGER

  • = 0: successful exit
  • < 0: if INFO = -k, the k-th argument had an illegal value
  • > 0: if INFO = k, the leading minor of order k is not positive definite, and the factorization could not be completed. 💀 the minor said "not today"

Author

Univ. of Tennessee

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

Further Details 💅

The band storage scheme is illustrated by the following example, when N = 6, KD = 2, and UPLO = 'U':

On entry:                       On exit:

    *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
    *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
   a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66

Similarly, if UPLO = 'L' the format of A is as follows:

On entry:                       On exit:

   a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
   a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
   a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *

Array elements marked * are not used by the routine.


subroutine dpbtrf

subroutine dpbtrf (character UPLO, integer N, integer KD, double precision,
    dimension( ldab, * ) AB, integer LDAB, integer INFO)

DPBTRF 👑

Purpose

DPBTRF computes the Cholesky factorization of a real symmetric positive definite band matrix A.

The factorization has the form

A = U**T * U,  if UPLO = 'U', or
A = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is lower triangular.

Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • KD — KD is INTEGER. The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  • AB — AB is DOUBLE PRECISION array, dimension (LDAB,N). On entry, the upper or lower triangle of the symmetric band matrix A, stored in the first KD+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows:
    • if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

On exit, if INFO = 0, the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the band matrix A, in the same storage format as A.

  • LDAB — LDAB is INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • INFO — INFO is INTEGER.
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the leading minor of order i is not positive definite, and the factorization could not be completed.

Author

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

Further Details 💖

The band storage scheme is illustrated by the following example, when N = 6, KD = 2, and UPLO = 'U':

On entry:                       On exit:

    *    *   a13  a24  a35  a46      *    *   u13  u24  u35  u46
    *   a12  a23  a34  a45  a56      *   u12  u23  u34  u45  u56
   a11  a22  a33  a44  a55  a66     u11  u22  u33  u44  u55  u66

Similarly, if UPLO = 'L' the format of A is as follows:

On entry:                       On exit:

   a11  a22  a33  a44  a55  a66     l11  l22  l33  l44  l55  l66
   a21  a32  a43  a54  a65   *      l21  l32  l43  l54  l65   *
   a31  a42  a53  a64   *    *      l31  l42  l53  l64   *    *

Array elements marked * are not used by the routine.

Contributors

Peter Mayes and Giuseppe Radicati, IBM ECSEC, Rome, March 23, 1989


subroutine dpbtrs

subroutine dpbtrs (character UPLO, integer N, integer KD, integer NRHS,
    double precision, dimension( ldab, * ) AB, integer LDAB, double
    precision, dimension( ldb, * ) B, integer LDB, integer INFO)

DPBTRS ✨

Purpose

DPBTRS solves a system of linear equations A*X = B with a symmetric positive definite band matrix A using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPBTRF.

Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangular factor stored in AB;
    • = 'L': Lower triangular factor stored in AB.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • KD — KD is INTEGER. The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  • NRHS — NRHS is INTEGER. The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.
  • AB — AB is DOUBLE PRECISION array, dimension (LDAB,N). The triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T of the band matrix A, stored in the first KD+1 rows of the array. The j-th column of U or L is stored in the j-th column of the array AB as follows:
    • if UPLO ='U', AB(kd+1+i-j,j) = U(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO ='L', AB(1+i-j,j) = L(i,j) for j<=i<=min(n,j+kd).
  • LDAB — LDAB is INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • B — B is DOUBLE PRECISION array, dimension (LDB,NRHS). On entry, the right hand side matrix B. On exit, the solution matrix X.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • INFO — INFO is INTEGER.
    • = 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.

subroutine dpftrf

subroutine dpftrf (character TRANSR, character UPLO, integer N, double
    precision, dimension( 0: * ) A, integer INFO)

DPFTRF 🌈

Purpose

DPFTRF computes the Cholesky factorization of a real symmetric positive definite matrix A.

The factorization has the form

A = U**T * U,  if UPLO = 'U', or
A = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is lower triangular.

This is the block version of the algorithm, calling Level 3 BLAS.

Parameters

  • TRANSR — TRANSR is CHARACTER*1
    • = 'N': The Normal TRANSR of RFP A is stored;
    • = 'T': The Transpose TRANSR of RFP A is stored.
  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of RFP A is stored;
    • = 'L': Lower triangle of RFP A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • A — A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ). On entry, the symmetric matrix A in RFP format. RFP format is described by TRANSR, UPLO, and N as follows: If TRANSR = 'N' then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is the transpose of RFP A as defined when TRANSR = 'N'. The contents of RFP A are defined by UPLO as follows: If UPLO = 'U' the RFP A contains the NT elements of upper packed A. If UPLO = 'L' the RFP A contains the elements of lower packed A. The LDA of RFP A is (N+1)/2 when TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and N is odd. See the Note below for more details.

On exit, if INFO = 0, the factor U or L from the Cholesky factorization RFP A = U**T*U or RFP A = L*L**T.

  • INFO — INFO is INTEGER.
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the leading minor of order i is not positive definite, and the factorization could not be completed.

Author

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

Further Details 🦋

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6.

    AP is Upper             AP is Lower

  00 01 02 03 04 05       00
     11 12 13 14 15       10 11
        22 23 24 25       20 21 22
           33 34 35       30 31 32 33
              44 45       40 41 42 43 44
                 55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows: For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper. For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower. This covers the case N even and TRANSR = 'N'.

        RFP A                   RFP A

       03 04 05                33 43 53
       13 14 15                00 44 54
       23 24 25                10 11 55
       33 34 35                20 21 22
       00 44 45                30 31 32
       01 11 55                40 41 42
       02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

         RFP A                   RFP A

   03 13 23 33 00 01 02    33 00 10 20 30 40 50
   04 14 24 34 44 11 12    43 44 11 21 31 41 51
   05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. We give an example where N = 5.

   AP is Upper                 AP is Lower

  00 01 02 03 04              00
     11 12 13 14              10 11
        22 23 24              20 21 22
           33 34              30 31 32 33
              44              40 41 42 43 44

okay so bestie, we're still deep in the RFP lore 💅 — let TRANSR = 'N'. RFP holds AP like this: For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper. For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower. This covers the case N odd and TRANSR = 'N'. No cap. 🦋

                    RFP A                   RFP A

                   02 03 04                00 33 43
                   12 13 14                10 11 44
                   22 23 24                20 21 22
                   00 33 34                30 31 32
                   01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                02 12 22 00 01             00 10 20 30 40 50
                03 13 23 33 11             33 11 21 31 41 51
                04 14 24 34 44             43 44 22 32 42 52

✨ subroutine dpftri (character TRANSR, character UPLO, integer N, double precision, dimension( 0: * ) A, integer INFO) — DPFTRI

subroutine dpftri (character TRANSR, character UPLO, integer N, double
    precision, dimension( 0: * ) A, integer INFO)

DPFTRI

🎯 Purpose

DPFTRI computes the inverse of a (real) symmetric positive definite matrix A using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPFTRF. It's giving matrix inverse realness, periodt. 💖

🔧 Parameters

  • TRANSR — TRANSR is CHARACTER*1
    • = 'N': The Normal TRANSR of RFP A is stored;
    • = 'T': The Transpose TRANSR of RFP A is stored.
  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER The order of the matrix A. N >= 0. Slay.
  • A — A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ) On entry, the symmetric matrix A in RFP format. RFP format is described by TRANSR, UPLO, and N as follows: If TRANSR = 'N' then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is the transpose of RFP A as defined when TRANSR = 'N'. The contents of RFP A are defined by UPLO as follows: If UPLO = 'U' the RFP A contains the nt elements of upper packed A. If UPLO = 'L' the RFP A contains the elements of lower packed A. The LDA of RFP A is (N+1)/2 when TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and N is odd. See the Note below for more details.

On exit, the symmetric inverse of the original matrix, in the same storage format. Obsessed. 💅

  • INFO — INFO is INTEGER
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the (i,i) element of the factor U or L is zero, and the inverse could not be computed.

✍️ Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

🔍 Further Details

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6.

             AP is Upper             AP is Lower

          00 01 02 03 04 05       00
             11 12 13 14 15       10 11
                22 23 24 25       20 21 22
                   33 34 35       30 31 32 33
                      44 45       40 41 42 43 44
                         55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows: For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper. For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower. This covers the case N even and TRANSR = 'N'.

                    RFP A                   RFP A

                   03 04 05                33 43 53
                   13 14 15                00 44 54
                   23 24 25                10 11 55
                   33 34 35                20 21 22
                   00 44 45                30 31 32
                   01 11 55                40 41 42
                   02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                03 13 23 33 00 01 02    33 00 10 20 30 40 50
                04 14 24 34 44 11 12    43 44 11 21 31 41 51
                05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. We give an example where N = 5.

                AP is Upper                 AP is Lower

              00 01 02 03 04              00
                 11 12 13 14              10 11
                    22 23 24              20 21 22
                       33 34              30 31 32 33
                          44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows: For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper. For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower. This covers the case N odd and TRANSR = 'N'.

                    RFP A                   RFP A

                   02 03 04                00 33 43
                   12 13 14                10 11 44
                   22 23 24                20 21 22
                   00 33 34                30 31 32
                   01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                02 12 22 00 01             00 10 20 30 40 50
                03 13 23 33 11             33 11 21 31 41 51
                04 14 24 34 44             43 44 22 32 42 52

💖 subroutine dpftrs (character TRANSR, character UPLO, integer N, integer NRHS, double precision, dimension( 0: * ) A, double precision, dimension( ldb, * ) B, integer LDB, integer INFO) — DPFTRS

subroutine dpftrs (character TRANSR, character UPLO, integer N, integer
    NRHS, double precision, dimension( 0: * ) A, double precision,
    dimension( ldb, * ) B, integer LDB, integer INFO)

DPFTRS

🎯 Purpose

DPFTRS solves a system of linear equations A*X = B with a symmetric positive definite matrix A using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPFTRF. It's giving solve-the-system energy, fr fr. 🔥

🔧 Parameters

  • TRANSR — TRANSR is CHARACTER*1
    • = 'N': The Normal TRANSR of RFP A is stored;
    • = 'T': The Transpose TRANSR of RFP A is stored.
  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of RFP A is stored;
    • = 'L': Lower triangle of RFP A is stored.
  • N — N is INTEGER The order of the matrix A. N >= 0.
  • NRHS — NRHS is INTEGER The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.
  • A — A is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ). The triangular factor U or L from the Cholesky factorization of RFP A = U**T*U or RFP A = L*L**T, as computed by DPFTRF. See note below for more details about RFP A.
  • B — B is DOUBLE PRECISION array, dimension (LDB,NRHS) On entry, the right hand side matrix B. On exit, the solution matrix X.
  • LDB — LDB is INTEGER The leading dimension of the array B. LDB >= max(1,N).
  • INFO — INFO is INTEGER
    • = 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.

🔍 Further Details

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6.

             AP is Upper             AP is Lower

          00 01 02 03 04 05       00
             11 12 13 14 15       10 11
                22 23 24 25       20 21 22
                   33 34 35       30 31 32 33
                      44 45       40 41 42 43 44
                         55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows: For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper. For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower. This covers the case N even and TRANSR = 'N'.

                    RFP A                   RFP A

                   03 04 05                33 43 53
                   13 14 15                00 44 54
                   23 24 25                10 11 55
                   33 34 35                20 21 22
                   00 44 45                30 31 32
                   01 11 55                40 41 42
                   02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                03 13 23 33 00 01 02    33 00 10 20 30 40 50
                04 14 24 34 44 11 12    43 44 11 21 31 41 51
                05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. We give an example where N = 5.

                AP is Upper                 AP is Lower

              00 01 02 03 04              00
                 11 12 13 14              10 11
                    22 23 24              20 21 22
                       33 34              30 31 32 33
                          44              40 41 42 43 44
Let TRANSR = 'N'. RFP holds AP as follows:
For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last
three columns of AP upper. The lower triangle A(3:4,0:1) consists of
the transpose of the first two columns of AP upper.
For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first
three columns of AP lower. The upper triangle A(0:1,1:2) consists of
the transpose of the last two columns of AP lower.
This covers the case N odd and TRANSR = 'N'.

ok bestie so that's the N is odd, TRANSR = 'N' era 💅 and here's what RFP A is actually giving:

       RFP A                   RFP A

      02 03 04                00 33 43
      12 13 14                10 11 44
      22 23 24                20 21 22
      00 33 34                30 31 32
      01 11 44                40 41 42

and NOW ✨ let TRANSR = 'T'. bestie listen — RFP A in both UPLO cases is literally just the transpose of RFP A up there. so you get:

         RFP A                   RFP A

   02 12 22 00 01             00 10 20 30 40 50
   03 13 23 33 11             33 11 21 31 41 51
   04 14 24 34 44             43 44 22 32 42 52

it's giving transpose. iconic behavior honestly 🦋


🌸 subroutine dppcon 🌸

subroutine dppcon (character UPLO, integer N, double precision, dimension( *
    ) AP, double precision ANORM, double precision RCOND, double precision,
    dimension( * ) WORK, integer, dimension( * ) IWORK, integer INFO)

DPPCON

💖 Purpose:

DPPCON estimates the reciprocal of the condition number (in the 1-norm) of a real symmetric positive definite packed matrix using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPPTRF. no cap 🔥

An estimate is obtained for norm(inv(A)), and the reciprocal of the condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))). the way that math just math-ed 💅

🎀 Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T, packed columnwise in a linear array. The j-th column of U or L is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n.
  • ANORM — ANORM is DOUBLE PRECISION. The 1-norm (or infinity-norm) of the symmetric matrix A.
  • RCOND — RCOND is DOUBLE PRECISION. The reciprocal of the condition number of the matrix A, computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an estimate of the 1-norm of inv(A) computed in this routine.
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N)
  • IWORK — IWORK is INTEGER array, dimension (N)
  • INFO — INFO is INTEGER
    • = 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.


🌈 subroutine dppequ 🌈

subroutine dppequ (character UPLO, integer N, double precision, dimension( *
    ) AP, double precision, dimension( * ) S, double precision SCOND, double
    precision AMAX, integer INFO)

DPPEQU

💜 Purpose:

DPPEQU computes row and column scalings intended to equilibrate a symmetric positive definite matrix A in packed storage and reduce its condition number (with respect to the two-norm). S contains the scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal. This choice of S puts the condition number of B within a factor N of the smallest possible condition number over all possible diagonal scalings. balance queen behavior ⚖️✨

🍓 Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  • S — S is DOUBLE PRECISION array, dimension (N). If INFO = 0, S contains the scale factors for A.
  • SCOND — SCOND is DOUBLE PRECISION. If INFO = 0, S contains the ratio of the smallest S(i) to the largest S(i). If SCOND >= 0.1 and AMAX is neither too large nor too small, it is not worth scaling by S.
  • AMAX — AMAX is DOUBLE PRECISION. Absolute value of largest matrix element. If AMAX is very close to overflow or very close to underflow, the matrix should be scaled.
  • INFO — INFO is INTEGER
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the i-th diagonal element is nonpositive.

🫶 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


💫 subroutine dpprfs 💫

subroutine dpprfs (character UPLO, integer N, integer NRHS, double
    precision, dimension( * ) AP, double precision, dimension( * ) AFP,
    double precision, dimension( ldb, * ) B, integer LDB, double precision,
    dimension( ldx, * ) X, integer LDX, double precision, dimension( * )
    FERR, double precision, dimension( * ) BERR, double precision,
    dimension( * ) WORK, integer, dimension( * ) IWORK, integer INFO)

DPPRFS

✨ Purpose:

DPPRFS improves the computed solution to a system of linear equations when the coefficient matrix is symmetric positive definite and packed, and provides error bounds and backward error estimates for the solution. glow-up for your answer matrix, fr fr 💖

🌸 Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • NRHS — NRHS is INTEGER. The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  • AFP — AFP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T, as computed by DPPTRF/ZPPTRF, packed columnwise in a linear array in the same format as A (see AP).
  • B — B is DOUBLE PRECISION array, dimension (LDB,NRHS). The right hand side matrix B.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • X — X is DOUBLE PRECISION array, dimension (LDX,NRHS). On entry, the solution matrix X, as computed by DPPTRS. On exit, the improved solution matrix X.
  • LDX — LDX is INTEGER. The leading dimension of the array X. LDX >= max(1,N).
  • FERR — FERR is DOUBLE PRECISION array, dimension (NRHS). The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error.
  • BERR — BERR is DOUBLE PRECISION array, dimension (NRHS). The componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution).
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N)
  • IWORK — IWORK is INTEGER array, dimension (N)
  • INFO — INFO is INTEGER
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value

🧚 Internal Parameters:

ITMAX is the maximum number of steps of iterative refinement.

🌟 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🎀 subroutine dpptrf 🎀

subroutine dpptrf (character UPLO, integer N, double precision, dimension( *
    ) AP, integer INFO)

DPPTRF

💅 Purpose:

DPPTRF computes the Cholesky factorization of a real symmetric positive definite matrix A stored in packed format. the moment we've all been waiting for 🎉

The factorization has the form

   A = U**T * U,  if UPLO = 'U', or
   A = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is lower triangular. iconic 💜

🦋 Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). On entry, the upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.

See below for further details.

On exit, if INFO = 0, the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T is sitting right there, in the exact same storage format as A. Same layout, no reshuffling, no drama. 💖

  • INFO — is INTEGER, and bestie, listen, it's the receipts:
    • = 0: successful exit 🎉
    • < 0: if INFO = -i, the i-th argument had an illegal value (rude of you, honestly)
    • > 0: if INFO = i, the leading minor of order i is not positive definite, and the factorization could not be completed. So close, and yet. 😭

🎀 Author

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

✨ Further Details ✨

The packed storage scheme is illustrated by the following example when N = 4, UPLO = 'U':

Two-dimensional storage of the symmetric matrix A:

   a11 a12 a13 a14
       a22 a23 a24
           a33 a34     (aij = aji)
               a44

Packed storage of the upper triangle of A:

AP = [ a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 ]

See? Everything crammed into one lil linear array, no wasted zeros, no empty seats. The way it just fits. 🦋


dpptri 💅

subroutine dpptri (character UPLO, integer N, double precision, dimension( * ) AP, integer INFO)

DPPTRI. Okay so what's the vibe? It computes the inverse of a real symmetric positive definite matrix A, using the Cholesky factorization A = U**T*U or A = L*L**T that DPPTRF already computed for you. Like, DPPTRF did the hard part, and this one just finishes the job. Teamwork, honestly. 🫶

🌸 Purpose

DPPTRI computes the inverse of a real symmetric positive definite matrix A using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPPTRF.

🎀 Parameters

  • UPLO — is CHARACTER*1, and it picks which triangle we're working with:
    • = 'U': Upper triangular factor is stored in AP;
    • = 'L': Lower triangular factor is stored in AP.
  • N — is INTEGER. The order of the matrix A. N >= 0. (Yes, zero counts, we don't gatekeep.)
  • AP — is DOUBLE PRECISION array, dimension (N*(N+1)/2).
    • On entry: the triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T, packed columnwise as a linear array. The j-th column of U or L is stored in the array AP as follows:
      • if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j;
      • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n.
    • On exit: the upper or lower triangle of the (symmetric) inverse of A, overwriting the input factor U or L. Yeah bestie, your input is gone, it got replaced. That's not a bug, that's the whole point. 💀
  • INFO — is INTEGER:
    • = 0: successful exit ⭐
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the (i,i) element of the factor U or L is zero, and the inverse could not be computed.

🎀 Author

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

dpptrs 🔥

subroutine dpptrs (character UPLO, integer N, integer NRHS, double precision, dimension( * ) AP, double precision, dimension( ldb, * ) B, integer LDB, integer INFO)

DPPTRS, the solver girlie. 🧚

🌸 Purpose

DPPTRS solves a system of linear equations A*X = B with a symmetric positive definite matrix A in packed storage, using the Cholesky factorization A = U**T*U or A = L*L**T computed by DPPTRF.

🎀 Parameters

  • UPLO — is CHARACTER*1:
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — is INTEGER. The order of the matrix A. N >= 0.
  • NRHS — is INTEGER. The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.
  • AP — is DOUBLE PRECISION array, dimension (N*(N+1)/2). The triangular factor U or L from the Cholesky factorization A = U**T*U or A = L*L**T, packed columnwise in a linear array. The j-th column of U or L is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = U(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = L(i,j) for j<=i<=n.
  • B — is DOUBLE PRECISION array, dimension (LDB,NRHS).
    • On entry: the right hand side matrix B.
    • On exit: the solution matrix X. Glow up moment. ✨
  • LDB — is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • INFO — is INTEGER:
    • = 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.

dpstf2 🌈

subroutine dpstf2 (character UPLO, integer N, double precision, dimension( lda, * ) A, integer LDA, integer, dimension( n ) PIV, integer RANK, double precision TOL, double precision, dimension( 2*n ) WORK, integer INFO)

DPSTF2 computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix.

🌸 Purpose

DPSTF2 computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix A.

The factorization has the form

   P**T * A * P = U**T * U ,  if UPLO = 'U',
   P**T * A * P = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is lower triangular, and P is stored as vector PIV.

Heads up bestie: this algorithm does not attempt to check that A is positive semidefinite. It just trusts you. This version of the algorithm calls level 2 BLAS. 👑

🎀 Parameters

  • UPLO — is CHARACTER*1. Specifies whether the upper or lower triangular part of the symmetric matrix A is stored.
    • = 'U': Upper triangular
    • = 'L': Lower triangular
  • N — is INTEGER. The order of the matrix A. N >= 0.
  • A — is DOUBLE PRECISION array, dimension (LDA,N).
    • On entry: the symmetric matrix A. If UPLO = 'U', the leading n by n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n by n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced.
    • On exit: if INFO = 0, the factor U or L from the Cholesky factorization as above.
  • PIV — is INTEGER array, dimension (N). PIV is such that the nonzero entries are P( PIV(K), K ) = 1.
  • RANK — is INTEGER. The rank of A given by the number of steps the algorithm completed. It literally counted how far it got. 🫡
  • TOL — is DOUBLE PRECISION. User defined tolerance. If TOL < 0, then N*U*MAX( A( K,K ) ) will be used. The algorithm terminates at the (K-1)st step if the pivot <= TOL.
  • LDA — is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • WORK — is DOUBLE PRECISION array, dimension (2*N). Work space. (Just vibing in the background, holding the math.)
  • INFO — is INTEGER:
    • < 0: If INFO = -K, the K-th argument had an illegal value,
    • = 0: algorithm completed successfully, and
    • > 0: the matrix A is either rank deficient with computed rank as returned in RANK, or is not positive semidefinite. See Section 7 of LAPACK Working Note #161 for further information.

🎀 Author

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

dpstrf 👑

subroutine dpstrf (character UPLO, integer N, double precision, dimension( lda, * ) A, integer LDA, integer, dimension( n ) PIV, integer RANK, double precision TOL, double precision, dimension( 2*n ) WORK, integer INFO)

DPSTRF computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix.

Basically dpstf2's main character sibling. Same job, bigger flex. 💅

🌸 Purpose

DPSTRF computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix A.

The factorization has the form

   P**T * A * P = U**T * U ,  if UPLO = 'U',
   P**T * A * P = L  * L**T,  if UPLO = 'L',

where U is an upper triangular matrix and L is lower triangular, and P is stored as vector PIV.

Same warning, same energy: this algorithm does not attempt to check that A is positive semidefinite. This version of the algorithm calls level 3 BLAS — that's the difference, bestie. 🦋

🎀 Parameters

  • UPLO — is CHARACTER*1. Specifies whether the upper or lower triangular part of the symmetric matrix A is stored.
    • = 'U': Upper triangular
    • = 'L': Lower triangular
  • N — is INTEGER. The order of the matrix A. N >= 0.
  • A — is DOUBLE PRECISION array, dimension (LDA,N).
    • On entry: the symmetric matrix A. If UPLO = 'U', the leading n by n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n by n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced.
    • On exit: if INFO = 0, the factor U or L from the Cholesky factorization as above.
  • LDA — is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • PIV — is INTEGER array, dimension (N). PIV is such that the nonzero entries are P( PIV(K), K ) = 1.
  • RANK — is INTEGER. The rank of A given by the number of steps the algorithm completed.
  • TOL — is DOUBLE PRECISION. User defined tolerance. If TOL < 0, then N*U*MAX( A(K,K) ) will be used. The algorithm terminates at the (K-1)st step if the pivot <= TOL.
  • WORK — is DOUBLE PRECISION array, dimension (2*N). Work space.
  • INFO

INFO is INTEGER

  • < 0: if INFO = -K, then the K-th argument was straight-up illegal, like it did NOT pass the vibe check.
  • = 0: algorithm finished successfully, ate and left no crumbs. ✨
  • > 0: the matrix A is either rank deficient — with the computed rank handed back to you in RANK — or it's just not positive semidefinite. Not the moment. See Section 7 of LAPACK Working Note #161 if you want the full lore.

👑 Author

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

🦋 subroutine dsbgst

subroutine dsbgst (character VECT, character UPLO, integer N, integer KA,
    integer KB, double precision, dimension( ldab, * ) AB, integer LDAB,
    double precision, dimension( ldbb, * ) BB, integer LDBB, double
    precision, dimension( ldx, * ) X, integer LDX, double precision,
    dimension( * ) WORK, integer INFO)

DSBGST — say hi to the glow-up routine 💅

Purpose:

DSBGST reduces a real symmetric-definite banded generalized eigenproblem

A*x = lambda*B*x

to standard form

C*y = lambda*y

in such a way that C has the same bandwidth as A. Iconic behavior honestly.

B must have been previously factorized as S**T*S by DPBSTF, using a split Cholesky factorization. Then A gets overwritten by C = X**T*A*X, where X = S**(-1)*Q and Q is an orthogonal matrix chosen specifically to preserve the bandwidth of A. Bestie is protecting the bandwidth with her life. 🫶

Parameters

  • VECT — VECT is CHARACTER*1.
    • = 'N': do not form the transformation matrix X;
    • = 'V': form X.
  • UPLO — UPLO is CHARACTER*1.
    • = 'U': upper triangle of A is stored;
    • = 'L': lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrices A and B. N >= 0.
  • KA — KA is INTEGER. The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KA >= 0.
  • KB — KB is INTEGER. The number of superdiagonals of the matrix B if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KA >= KB >= 0.
  • AB — AB is DOUBLE PRECISION array, dimension (LDAB,N).

On entry, the upper or lower triangle of the symmetric band matrix A, stored in the first ka+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows:

  • if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
  • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+ka).

On exit, the transformed matrix X**T*A*X, stored in the same format as A. She changed, but the format stayed the same. Growth. 🌱

  • LDAB — LDAB is INTEGER. The leading dimension of the array AB. LDAB >= KA+1.
  • BB — BB is DOUBLE PRECISION array, dimension (LDBB,N). The banded factor S from the split Cholesky factorization of B, as returned by DPBSTF, stored in the first KB+1 rows of the array.
  • LDBB — LDBB is INTEGER. The leading dimension of the array BB. LDBB >= KB+1.
  • X — X is DOUBLE PRECISION array, dimension (LDX,N).
    • If VECT = 'V', the n-by-n matrix X.
    • If VECT = 'N', the array X is not referenced. She's literally not even invited to the function. 💀
  • LDX — LDX is INTEGER. The leading dimension of the array X. LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.
  • WORK — WORK is DOUBLE PRECISION array, dimension (2*N).
  • INFO — INFO is INTEGER.
    • = 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.

🎀 subroutine dsbtrd

subroutine dsbtrd (character VECT, character UPLO, integer N, integer KD,
    double precision, dimension( ldab, * ) AB, integer LDAB, double
    precision, dimension( * ) D, double precision, dimension( * ) E, double
    precision, dimension( ldq, * ) Q, integer LDQ, double precision,
    dimension( * ) WORK, integer INFO)

DSBTRD — tridiagonal-ify that band matrix, no cap ✨

Purpose:

DSBTRD reduces a real symmetric band matrix A to symmetric tridiagonal form T by an orthogonal similarity transformation:

Q**T * A * Q = T.

She's taking that wide band and squeezing it down to three little diagonals. Minimalism era. 🦋

Parameters

  • VECT — VECT is CHARACTER*1.
    • = 'N': do not form Q;
    • = 'V': form Q;
    • = 'U': update a matrix X, by forming X*Q.
  • UPLO — UPLO is CHARACTER*1.
    • = 'U': upper triangle of A is stored;
    • = 'L': lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • KD — KD is INTEGER. The number of superdiagonals of the matrix A if UPLO = 'U', or the number of subdiagonals if UPLO = 'L'. KD >= 0.
  • AB — AB is DOUBLE PRECISION array, dimension (LDAB,N).

On entry, the upper or lower triangle of the symmetric band matrix A, stored in the first KD+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows:

  • if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
  • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

On exit, the diagonal elements of AB are overwritten by the diagonal elements of the tridiagonal matrix T. If KD > 0, the elements on the first superdiagonal (if UPLO = 'U') or the first subdiagonal (if UPLO = 'L') are overwritten by the off-diagonal elements of T. And the rest of AB? Overwritten by values generated during the reduction. She cleared the whole closet and restocked it, fr fr. 💅

  • LDAB — LDAB is INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • D — D is DOUBLE PRECISION array, dimension (N). The diagonal elements of the tridiagonal matrix T.
  • E — E is DOUBLE PRECISION array, dimension (N-1). The off-diagonal elements of the tridiagonal matrix T:
    • E(i) = T(i,i+1) if UPLO = 'U';
    • E(i) = T(i+1,i) if UPLO = 'L'.
  • Q — Q is DOUBLE PRECISION array, dimension (LDQ,N).

On entry, if VECT = 'U', then Q must contain an N-by-N matrix X; if VECT = 'N' or 'V', then Q need not be set. No pressure bestie, it's optional.

On exit:

  • if VECT = 'V', Q contains the N-by-N orthogonal matrix Q;
  • if VECT = 'U', Q contains the product X*Q;
  • if VECT = 'N', the array Q is not referenced.
  • LDQ — LDQ is INTEGER. The leading dimension of the array Q. LDQ >= 1, and LDQ >= N if VECT = 'V' or 'U'.
  • WORK — WORK is DOUBLE PRECISION array, dimension (N).
  • INFO — INFO is INTEGER.
    • = 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.

💜 Further Details:

Modified by Linda Kaufman, Bell Labs. Shoutout to Linda, an absolute queen. 👑


⭐ subroutine dsfrk

subroutine dsfrk (character TRANSR, character UPLO, character TRANS, integer
    N, integer K, double precision ALPHA, double precision, dimension( lda,
    * ) A, integer LDA, double precision BETA, double precision, dimension(
    * ) C)

DSFRK performs a symmetric rank-k operation for matrix in RFP format. It's giving Level 3 BLAS energy but make it RFP. 🔥

Purpose:

Level 3 BLAS like routine for C in RFP Format.

DSFRK performs one of the symmetric rank--k operations

C := alpha*A*A**T + beta*C,

or

C := alpha*A**T*A + beta*C,

where alpha and beta are real scalars, C is an n--by--n symmetric matrix and A is an n--by--k matrix in the first case and a k--by--n matrix in the second case. Pick your fighter. 🥊

Parameters

  • TRANSR — TRANSR is CHARACTER*1.
    • = 'N': The Normal Form of RFP A is stored;
    • = 'T': The Transpose Form of RFP A is stored.
  • UPLO — UPLO is CHARACTER*1.

On entry, UPLO specifies whether the upper or lower triangular part of the array C is to be referenced as follows:

  • UPLO = 'U' or 'u': Only the upper triangular part of C is to be referenced.
  • UPLO = 'L' or 'l': Only the lower triangular part of C is to be referenced.

Unchanged on exit. She's not touching it, just looking. 👀

  • TRANS — TRANS is CHARACTER*1.

On entry, TRANS specifies the operation to be performed as follows:

  • TRANS = 'N' or 'n': C := alpha*A*A**T + beta*C.
  • TRANS = 'T' or 't': C := alpha*A**T*A + beta*C.

Unchanged on exit.

  • N — N is INTEGER.

On entry, N specifies the order of the matrix C. N must be at least zero.

Unchanged on exit.

  • K — K is INTEGER.

On entry with TRANS = 'N' or 'n', K specifies the number of columns of the matrix A, and on entry with TRANS = 'T' or 't', K specifies the number of rows of the matrix A. K must be at least zero.

Unchanged on exit.

  • ALPHA — ALPHA is DOUBLE PRECISION.

On entry, ALPHA specifies the scalar alpha.

Unchanged on exit.

  • A — A is DOUBLE PRECISION array, dimension (LDA,ka) where KA is K when TRANS = 'N' or 'n', and is N otherwise.

Before entry with TRANS = 'N' or 'n', the leading N--by--K part of the array A must contain the matrix A, otherwise the leading K--by--N part of the array A must contain the matrix A.

Unchanged on exit.

  • LDA — LDA is INTEGER.

On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When TRANS = 'N' or 'n' then LDA must be at least max( 1, n ), otherwise LDA must be at least max( 1, k ).

Unchanged on exit.

  • BETA — BETA is DOUBLE PRECISION.

On entry, BETA specifies the scalar beta.

Unchanged on exit.

  • C
  • C — a DOUBLE PRECISION array, dimension (NT), where NT = N*(N+1)/2. On entry this is the symmetric matrix C, vibing in RFP Format, and RFP Format itself is described by TRANSR, UPLO and N. 🎀

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


subroutine dspcon 💅

subroutine dspcon (character UPLO, integer N, double precision, dimension( * ) AP, integer, dimension( * ) IPIV, double precision ANORM, double precision RCOND, double precision, dimension( * ) WORK, integer, dimension( * ) IWORK, integer INFO)

Purpose

ok bestie so DSPCON estimates the reciprocal of the condition number (in the 1-norm, periodt) of a real symmetric packed matrix A, using the factorization

A = U*D*U**T or A = L*D*L**T

that was computed by DSPTRF. 💖

It gets an estimate for norm(inv(A)), and then the reciprocal of the condition number comes out as

RCOND = 1 / (ANORM * norm(inv(A)))

Parameters

  • UPLO — CHARACTER*1. Tells us whether the deets of the factorization are stored as an upper or lower triangular matrix. = 'U': Upper triangular, form is A = U*D*U**T; = 'L': Lower triangular, form is A = L*D*L**T. 🦋
  • N — INTEGER. The order of the matrix A. N >= 0. ✨
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2). This holds the block diagonal matrix D plus the multipliers used to get the factor U or L, exactly as computed by DSPTRF, stored as a packed triangular matrix. 🔥
  • IPIV — INTEGER array, dimension (N). The details of the interchanges and the block structure of D, as determined by DSPTRF. 👑
  • ANORM — DOUBLE PRECISION. The 1-norm of the original matrix A. 💜
  • RCOND — DOUBLE PRECISION. The reciprocal of the condition number of the matrix A, computed as RCOND = 1/(ANORM * AINVNM), where AINVNM is an estimate of the 1-norm of inv(A) computed in this routine. 🌸
  • WORK — DOUBLE PRECISION array, dimension (2*N). 🫶
  • IWORK — INTEGER array, dimension (N). 🫶
  • INFO — INTEGER. = 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.


subroutine dspgst 🌈

subroutine dspgst (integer ITYPE, character UPLO, integer N, double precision, dimension( * ) AP, double precision, dimension( * ) BP, integer INFO)

Purpose

DSPGST reduces a real symmetric-definite generalized eigenproblem to standard form, using packed storage. lowkey iconic 💅

  • If ITYPE = 1, the problem is A*x = lambda*B*x, and A is overwritten by inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T).
  • If ITYPE = 2 or 3, the problem is A*B*x = lambda*x or B*A*x = lambda*x, and A is overwritten by U*A*U**T or L**T*A*L.
Heads up bestie: B must have been previously factorized as U**T*U or L*L**T by DPPTRF. No skipping that step. 🙈

Parameters

  • ITYPE — INTEGER. = 1: compute inv(U**T)*A*inv(U) or inv(L)*A*inv(L**T); = 2 or 3: compute U*A*U**T or L**T*A*L. ✨
  • UPLO — CHARACTER*1. = 'U': Upper triangle of A is stored and B is factored as U**T*U; = 'L': Lower triangle of A is stored and B is factored as L*L**T. 🦋
  • N — INTEGER. The order of the matrices A and B. N >= 0. 💖
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2). On entry, the upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.

On exit, if INFO = 0, the transformed matrix, stored in the same format as A. 🔥

  • BP — DOUBLE PRECISION array, dimension (N*(N+1)/2). The triangular factor from the Cholesky factorization of B, stored in the same format as A, as returned by DPPTRF. 👑
  • INFO — INTEGER. = 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.


subroutine dsprfs 🎀

subroutine dsprfs (character UPLO, integer N, integer NRHS, double precision, dimension( * ) AP, double precision, dimension( * ) AFP, integer, dimension( * ) IPIV, double precision, dimension( ldb, * ) B, integer LDB, double precision, dimension( ldx, * ) X, integer LDX, double precision, dimension( * ) FERR, double precision, dimension( * ) BERR, double precision, dimension( * ) WORK, integer, dimension( * ) IWORK, integer INFO)

Purpose

DSPRFS improves the computed solution to a system of linear equations when the coefficient matrix is symmetric indefinite and packed, and it hands you error bounds plus backward error estimates for the solution. it's giving accuracy ✨

Parameters

  • UPLO — CHARACTER*1. = 'U': Upper triangle of A is stored; = 'L': Lower triangle of A is stored. 🦋
  • N — INTEGER. The order of the matrix A. N >= 0. 💖
  • NRHS — INTEGER. The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0. 🌸
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2). The upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.

🔥

  • AFP — DOUBLE PRECISION array, dimension (N*(N+1)/2). The factored form of the matrix A. AFP contains the block diagonal matrix D and the multipliers used to obtain the factor U or L from the factorization A = U*D*U**T or A = L*D*L**T as computed by DSPTRF, stored as a packed triangular matrix. 👑
  • IPIV — INTEGER array, dimension (N). Details of the interchanges and the block structure of D as determined by DSPTRF. 💜
  • B — DOUBLE PRECISION array, dimension (LDB,NRHS). The right hand side matrix B. 🫶
  • LDB — INTEGER. The leading dimension of the array B. LDB >= max(1,N). ⭐
  • X — DOUBLE PRECISION array, dimension (LDX,NRHS). On entry, the solution matrix X, as computed by DSPTRS. On exit, the improved solution matrix X. 💅
  • LDX — INTEGER. The leading dimension of the array X. LDX >= max(1,N). ⭐
  • FERR — DOUBLE PRECISION array, dimension (NRHS). The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error. 😭
  • BERR — DOUBLE PRECISION array, dimension (NRHS). The componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution). 🌈
  • WORK — DOUBLE PRECISION array, dimension (3*N). 🫶
  • IWORK — INTEGER array, dimension (N). 🫶
  • INFO — INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. 💀

Internal Parameters

ITMAX is the maximum number of steps of iterative refinement.

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


subroutine dsptrd 🦋

subroutine dsptrd (character UPLO, integer N, double precision, dimension( * ) AP, double precision, dimension( * ) D, double precision, dimension( * ) E, double precision, dimension( * ) TAU, integer INFO)

Purpose

DSPTRD reduces a real symmetric matrix A stored in packed form to symmetric tridiagonal form T by an orthogonal similarity transformation:

Q**T * A * Q = T

main character energy, honestly 👑✨

Parameters

  • UPLO — CHARACTER*1. = 'U': Upper triangle of A is stored; = 'L': Lower triangle of A is stored. 💖
  • N — INTEGER. The order of the matrix A. N >= 0. 🌸
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2). On entry, the upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.

On exit, if UPLO = 'U', the diagonal and first superdiagonal of A are overwritten by the corresponding elements of the tridiagonal matrix T, and the elements above the first superdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors; if UPLO = 'L', the diagonal and first subdiagonal of A are over-written by the corresponding elements of the tridiagonal matrix T, and the elements below the first subdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. 🔥

  • D
  • D — DOUBLE PRECISION array, dimension (N) 🌸 these are the diagonal girlies of the tridiagonal matrix T, where D(i) = A(i,i). no cap, just the main diagonal doing its thing.
  • E — DOUBLE PRECISION array, dimension (N-1) 🦋 the off-diagonal elements of that same tridiagonal matrix T: E(i) = A(i,i+1) if UPLO = 'U', and E(i) = A(i+1,i) if UPLO = 'L'. it's giving "depends on which triangle you picked" energy.
  • TAU — DOUBLE PRECISION array, dimension (N-1) ✨ the scalar factors of the elementary reflectors (peep Further Details below, bestie, it's all explained there).
  • INFO — INTEGER 💅 the receipts:
    • = 0: successful exit, we ate. 👑
    • < 0: if INFO = -i, the i-th argument had an illegal value. 😭 somebody passed something cursed.

✍️ Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

🔍 Further Details:

If UPLO = 'U', the matrix Q is represented as a product of elementary reflectors

Q = H(n-1) . . . H(2) H(1).

Each H(i) has the form

H(i) = I - tau * v * v**T

where tau is a real scalar, and v is a real vector with v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in AP, overwriting A(1:i-1,i+1), and tau is stored in TAU(i).

If UPLO = 'L', the matrix Q is represented as a product of elementary reflectors

Q = H(1) H(2) . . . H(n-1).

Each H(i) has the form

H(i) = I - tau * v * v**T

where tau is a real scalar, and v is a real vector with v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in AP, overwriting A(i+2:n,i), and tau is stored in TAU(i).


🎀 subroutine dsptrf

subroutine dsptrf (character UPLO, integer N, double precision, dimension( * ) AP, integer, dimension( * ) IPIV, integer INFO)

DSPTRF 🌈

💡 Purpose:

DSPTRF computes the factorization of a real symmetric matrix A stored in packed format using the Bunch-Kaufman diagonal pivoting method:

A = U*D*U**T  or  A = L*D*L**T

where U (or L) is a product of permutation and unit upper (lower) triangular matrices, and D is symmetric and block diagonal with 1-by-1 and 2-by-2 diagonal blocks. literally iconic behaviour. 👑

🧚 Parameters

  • UPLO — CHARACTER*1 🦋 which triangle of A we're vibing with:
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — INTEGER 💖 the order of the matrix A. N >= 0. (zero is allowed, don't come for her.)
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2) ✨ on entry, the upper or lower triangle of the symmetric matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.

On exit, the block diagonal matrix D and the multipliers used to obtain the factor U or L, stored as a packed triangular matrix overwriting A (see below for further details). she transforms 💅

  • IPIV — INTEGER array, dimension (N) 🍓 the details of the interchanges and the block structure of D:
    • If IPIV(k) > 0, then rows and columns k and IPIV(k) were interchanged and D(k,k) is a 1-by-1 diagonal block.
    • If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
    • If UPLO = 'L' and IPIV(k) = IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
  • INFO — INTEGER 🙈 the whole plot:
    • = 0: successful exit, we're so back. 🫶
    • < 0: if INFO = -i, the i-th argument had an illegal value. 😭
    • > 0: if INFO = i, D(i,i) is exactly zero. The factorization has been completed, but the block diagonal matrix D is exactly singular, and division by zero will occur if it is used to solve a system of equations. bestie. RUN. 💀

✍️ Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

🔍 Further Details:

If UPLO = 'U', then A = U*D*U**T, where

U = P(n)*U(n)* ... *P(k)U(k)* ...,

i.e., U is a product of terms P(k)*U(k), where k decreases from n to 1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as defined by IPIV(k), and U(k) is a unit upper triangular matrix, such that if the diagonal block D(k) is of order s (s = 1 or 2), then

         (   I    v    0   )   k-s
 U(k) =  (   0    I    0   )   s
         (   0    0    I   )   n-k
            k-s   s   n-k

If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).

If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), and A(k,k), and v overwrites A(1:k-2,k-1:k).

If UPLO = 'L', then A = L*D*L**T, where

L = P(1)*L(1)* ... *P(k)*L(k)* ...,

i.e., L is a product of terms P(k)*L(k), where k increases from 1 to n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks D(k). P(k) is a permutation matrix as defined by IPIV(k), and L(k) is a unit lower triangular matrix, such that if the diagonal block D(k) is of order s (s = 1 or 2), then

         (   I    0     0   )  k-1
 L(k) =  (   0    I     0   )  s
         (   0    v     I   )  n-k-s+1
            k-1   s  n-k-s+1

If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).

If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).

🌟 Contributors:

J. Lewis, Boeing Computer Services Company


🦋 subroutine dsptri

subroutine dsptri (character UPLO, integer N, double precision, dimension( * ) AP, integer, dimension( * ) IPIV, double precision, dimension( * ) WORK, integer INFO)

DSPTRI 💜

💡 Purpose:

DSPTRI computes the inverse of a real symmetric indefinite matrix A in packed storage using the factorization A = U*D*U**T or A = L*D*L**T computed by DSPTRF. she's doing the reverse thing, and she's doing it flawlessly. 💅

🧚 Parameters

  • UPLO — CHARACTER*1 🌸 specifies whether the details of the factorization are stored as an upper or lower triangular matrix:
    • = 'U': Upper triangular, form is A = U*D*U**T;
    • = 'L': Lower triangular, form is A = L*D*L**T.
  • N — INTEGER 💖 the order of the matrix A. N >= 0.
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2) ✨ on entry, the block diagonal matrix D and the multipliers used to obtain the factor U or L as computed by DSPTRF, stored as a packed triangular matrix.

On exit, if INFO = 0, the (symmetric) inverse of the original matrix, stored as a packed triangular matrix. The j-th column of inv(A) is stored in the array AP as follows:

  • if UPLO = 'U', AP(i + (j-1)*j/2) = inv(A)(i,j) for 1<=i<=j;
  • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = inv(A)(i,j) for j<=i<=n.
  • IPIV — INTEGER array, dimension (N) 🍓 details of the interchanges and the block structure of D as determined by DSPTRF.
  • WORK — DOUBLE PRECISION array, dimension (N) 🎀
  • INFO — INTEGER 🙈
    • = 0: successful exit 🫶
    • < 0: if INFO = -i, the i-th argument had an illegal value 😭
    • > 0: if INFO = i, D(i,i) = 0; the matrix is singular and its inverse could not be computed. she said no. 💀

✍️ Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🧚 subroutine dsptrs

subroutine dsptrs (character UPLO, integer N, integer NRHS, double precision, dimension( * ) AP, integer, dimension( * ) IPIV, double precision, dimension( ldb, * ) B, integer LDB, integer INFO)

DSPTRS ⭐

💡 Purpose:

DSPTRS solves a system of linear equations A*X = B with a real symmetric matrix A stored in packed format using the factorization A = U*D*U**T or A = L*D*L**T computed by DSPTRF. solving for X, as she should. 👑

🧚 Parameters

  • UPLO — CHARACTER*1 🌸 specifies whether the details of the factorization are stored as an upper or lower triangular matrix:
    • = 'U': Upper triangular, form is A = U*D*U**T;
    • = 'L': Lower triangular, form is A = L*D*L**T.
  • N — INTEGER 💖 the order of the matrix A. N >= 0.
  • NRHS — INTEGER 🦋 the number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2) ✨ the block diagonal matrix D and the multipliers used to obtain the factor U or L as computed by DSPTRF, stored as a packed triangular matrix.
  • IPIV — INTEGER array, dimension (N) 🍓 details of the interchanges and the block structure of D as determined by DSPTRF.
  • B — DOUBLE PRECISION array, dimension (LDB,NRHS) 🎀 on entry, the right hand side matrix B. On exit, the solution matrix X. glow up moment. 🌈
  • LDB — INTEGER 💅 the leading dimension of the array B. LDB >= max(1,N).
  • INFO — INTEGER 🙈
    • = 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.


🌈 subroutine dstegr

subroutine dstegr (character JOBZ, character RANGE, integer N, double precision, dimension( * ) D, double precision, dimension( * ) E, double precision VL, double precision VU, integer IL, integer IU, double precision ABSTOL, integer M, double precision, dimension( * ) W, double precision, dimension( ldz, * ) Z, integer LDZ, integer, dimension( * ) ISUPPZ, double precision, dimension( * ) WORK, integer LWORK, integer, dimension( * ) IWORK, integer LIWORK, integer INFO)

DSTEGR 💖✨

💡 Purpose:

DSTEGR computes selected eigenvalues and, optionally, eigenvectors of a real symmetric tridiagonal matrix T. Any such unreduced matrix has a well defined set of pairwise different real eigenvalues, and the corresponding real eigenvectors are pairwise orthogonal. It's giving spectral theory baddie, no cap. 💅

The spectrum may be computed either completely or partially by specifying either an interval (VL,VU] or a range of indices IL:IU for the desired eigenvalues.

DSTEGR is a compatibility wrapper around the improved DSTEMR routine. See DSTEMR for further details. One important change is that the ABSTOL parameter no longer provides any benefit and hence is no longer used. Not me still passing ABSTOL in 2024... 🙈

Note: DSTEGR and DSTEMR work only on machines which follow IEEE-754 floating-point standard in their handling of infinities and NaNs. Normal execution may create these exceptiona values and hence may abort due to a floating point exception in environments which do not conform to the IEEE-754 standard. 💀

✨ Parameters ✨

  • JOBZ — JOBZ is CHARACTER*1
    • = 'N': Compute eigenvalues only;
    • = 'V': Compute eigenvalues and eigenvectors.
  • RANGE — RANGE is CHARACTER*1
    • = 'A': all eigenvalues will be found.
    • = 'V': all eigenvalues in the half-open interval (VL,VU] will be found.
    • = 'I': the IL-th through IU-th eigenvalues will be found.
  • N — N is INTEGER. The order of the matrix. N >= 0. ✨
  • D — D is DOUBLE PRECISION array, dimension (N). On entry, the N diagonal elements of the tridiagonal matrix T. On exit, D is overwritten.
  • E — E is DOUBLE PRECISION array, dimension (N). On entry, the (N-1) subdiagonal elements of the tridiagonal matrix T in elements 1 to N-1 of E. E(N) need not be set on input, but is used internally as workspace. On exit, E is overwritten.
  • VL — VL is DOUBLE PRECISION. If RANGE='V', the lower bound of the interval to be searched for eigenvalues. VL < VU. Not referenced if RANGE = 'A' or 'I'.
  • VU — VU is DOUBLE PRECISION. If RANGE='V', the upper bound of the interval to be searched for eigenvalues. VL < VU. Not referenced if RANGE = 'A' or 'I'.
  • IL — IL is INTEGER. If RANGE='I', the index of the smallest eigenvalue to be returned. 1 <= IL <= IU <= N, if N > 0. Not referenced if RANGE = 'A' or 'V'.
  • IU — IU is INTEGER. If RANGE='I', the index of the largest eigenvalue to be returned. 1 <= IL <= IU <= N, if N > 0. Not referenced if RANGE = 'A' or 'V'.
  • ABSTOL — ABSTOL is DOUBLE PRECISION. Unused. Was the absolute error tolerance for the eigenvalues/eigenvectors in previous versions.
  • M — M is INTEGER. The total number of eigenvalues found. 0 <= M <= N. If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
  • W — W is DOUBLE PRECISION array, dimension (N). The first M elements contain the selected eigenvalues in ascending order.
  • Z — Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) ). If JOBZ = 'V', and if INFO = 0, then the first M columns of Z contain the orthonormal eigenvectors of the matrix T corresponding to the selected eigenvalues, with the i-th column of Z holding the eigenvector associated with W(i). If JOBZ = 'N', then Z is not referenced. Note: the user must ensure that at least max(1,M) columns are supplied in the array Z; if RANGE = 'V', the exact value of M is not known in advance and an upper bound must be used. Supplying N columns is always safe.
  • LDZ — LDZ is INTEGER. The leading dimension of the array Z. LDZ >= 1, and if JOBZ = 'V', then LDZ >= max(1,N).
  • ISUPPZ — ISUPPZ is INTEGER array, dimension ( 2*max(1,M) ). The support of the eigenvectors in Z, i.e., the indices indicating the nonzero elements in Z. The i-th computed eigenvector is nonzero only in elements ISUPPZ( 2*i-1 ) through ISUPPZ( 2*i ). This is relevant in the case when the matrix is split. ISUPPZ is only accessed when JOBZ is 'V' and N > 0.
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). On exit, if INFO = 0, WORK(1) returns the optimal (and minimal) LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,18*N) if JOBZ = 'V', and LWORK >= max(1,12*N) if JOBZ = 'N'. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
  • IWORK — IWORK is INTEGER array, dimension (LIWORK). On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK.
  • LIWORK — LIWORK is INTEGER. The dimension of the array IWORK. LIWORK >= max(1,10*N) if the eigenvectors are desired, and LIWORK >= max(1,8*N) if only the eigenvalues are to be computed. If LIWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the IWORK array, returns this value as the first entry of the IWORK array, and no error message related to LIWORK is issued by XERBLA.
  • INFO — INFO is INTEGER. On exit, INFO
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = 1X, internal error in DLARRE, if INFO = 2X, internal error in DLARRV. Here, the digit X = ABS( IINFO ) < 10, where IINFO is the nonzero error code returned by DLARRE or DLARRV, respectively.

✨ Author ✨

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

🫶 Contributors: 🫶

  • Inderjit Dhillon, IBM Almaden, USA
  • Osni Marques, LBNL/NERSC, USA
  • Christof Voemel, LBNL/NERSC, USA

subroutine dstein

subroutine dstein (integer N, double precision, dimension( * ) D, double precision, dimension( * ) E, integer M, double precision, dimension( * ) W, integer, dimension( * ) IBLOCK, integer, dimension( * ) ISPLIT, double precision, dimension( ldz, * ) Z, integer LDZ, double precision, dimension( * ) WORK, integer, dimension( * ) IWORK, integer, dimension( * ) IFAIL, integer INFO)

DSTEIN

Purpose:

DSTEIN computes the eigenvectors of a real symmetric tridiagonal matrix T corresponding to specified eigenvalues, using inverse iteration. The maximum number of iterations allowed for each eigenvector is specified by an internal parameter MAXITS (currently set to 5).

Parameters

  • N — N is INTEGER. The order of the matrix. N >= 0.
  • D — D is DOUBLE PRECISION array, dimension (N). The n diagonal elements of the tridiagonal matrix T.
  • E — E is DOUBLE PRECISION array, dimension (N-1). The (n-1) subdiagonal elements of the tridiagonal matrix T, in elements 1 to N-1.
  • M — M is INTEGER. The number of eigenvectors to be found. 0 <= M <= N.
  • W — W is DOUBLE PRECISION array, dimension (N). The first M elements of W contain the eigenvalues for which eigenvectors are to be computed. The eigenvalues should be grouped by split-off block and ordered from smallest to largest within the block. ( The output array W from DSTEBZ with ORDER = 'B' is expected here. )
  • IBLOCK — IBLOCK is INTEGER array, dimension (N). The submatrix indices associated with the corresponding eigenvalues in W; IBLOCK(i)=1 if eigenvalue W(i) belongs to the first submatrix from the top, =2 if W(i) belongs to the second submatrix, etc. ( The output array IBLOCK from DSTEBZ is expected here. )
  • ISPLIT — ISPLIT is INTEGER array, dimension (N). The splitting points, at which T breaks up into submatrices. The first submatrix consists of rows/columns 1 to ISPLIT( 1 ), the second of rows/columns ISPLIT( 1 )+1 through ISPLIT( 2 ), etc. ( The output array ISPLIT from DSTEBZ is expected here. )
  • Z — Z is DOUBLE PRECISION array, dimension (LDZ, M). The computed eigenvectors. The eigenvector associated with the eigenvalue W(i) is stored in the i-th column of Z. Any vector which fails to converge is set to its current iterate after MAXITS iterations.
  • LDZ — LDZ is INTEGER. The leading dimension of the array Z. LDZ >= max(1,N).
  • WORK — WORK is DOUBLE PRECISION array, dimension (5*N)
  • IWORK — IWORK is INTEGER array, dimension (N)
  • IFAIL — IFAIL is INTEGER array, dimension (M). On normal exit, all elements of IFAIL are zero. If one or more eigenvectors fail to converge after MAXITS iterations, then their indices are stored in array IFAIL.
  • INFO — INFO is INTEGER
    • = 0: successful exit.
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, then i eigenvectors failed to converge in MAXITS iterations. Their indices are stored in array IFAIL.

Internal Parameters:

  • MAXITS — INTEGER, default = 5. The maximum number of iterations performed.
  • EXTRA — INTEGER, default = 2. The number of iterations performed after norm growth criterion is satisfied, should be at least 1.

Author

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

subroutine dstemr (...)

subroutine dstemr (character JOBZ, character RANGE, integer N, double
    precision, dimension( * ) D, double precision, dimension( * ) E, double
    precision VL, double precision VU, integer IL, integer IU, integer M,
    double precision, dimension( * ) W, double precision, dimension( ldz, *
    ) Z, integer LDZ, integer NZC, integer, dimension( * ) ISUPPZ, logical
    TRYRAC, double precision, dimension( * ) WORK, integer LWORK, integer,
    dimension( * ) IWORK, integer LIWORK, integer INFO)

DSTEMR 💅

Purpose:

okay so DSTEMR? She computes selected eigenvalues and, optionally, eigenvectors of a real symmetric tridiagonal matrix T. Any such unreduced matrix has a well defined set of pairwise different real eigenvalues, the corresponding real eigenvectors are pairwise orthogonal. no cap.

The spectrum may be computed either completely or partially by specifying either an interval (VL,VU] or a range of indices IL:IU for the desired eigenvalues.

Depending on the number of desired eigenvalues, these are computed either by bisection or the dqds algorithm. Numerically orthogonal eigenvectors are computed by the use of various suitable L D L^T factorizations near clusters of close eigenvalues (referred to as RRRs, Relatively Robust Representations). An informal sketch of the algorithm follows.

For each unreduced block (submatrix) of T,

  • (a) Compute T - sigma I = L D L^T, so that L and D define all the wanted eigenvalues to high relative accuracy. This means that small relative changes in the entries of D and L cause only small relative changes in the eigenvalues and eigenvectors. The standard (unfactored) representation of the tridiagonal matrix T does not have this property in general.
  • (b) Compute the eigenvalues to suitable accuracy. If the eigenvectors are desired, the algorithm attains full accuracy of the computed eigenvalues only right before the corresponding vectors have to be computed, see steps c) and d).
  • (c) For each cluster of close eigenvalues, select a new shift close to the cluster, find a new factorization, and refine the shifted eigenvalues to suitable accuracy.
  • (d) For each eigenvalue with a large enough relative separation compute the corresponding eigenvector by forming a rank revealing twisted factorization. Go back to (c) for any clusters that remain.

For more details, see:

  • Inderjit S. Dhillon and Beresford N. Parlett: 'Multiple representations to compute orthogonal eigenvectors of symmetric tridiagonal matrices,' Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
  • Inderjit Dhillon and Beresford Parlett: 'Orthogonal Eigenvectors and Relative Gaps,' SIAM Journal on Matrix Analysis and Applications, Vol. 25, 2004. Also LAPACK Working Note 154.
  • Inderjit Dhillon: 'A new O(n^2) algorithm for the symmetric tridiagonal eigenvalue/eigenvector problem', Computer Science Division Technical Report No. UCB/CSD-97-971, UC Berkeley, May 1997.

Further Details

  1. DSTEMR works only on machines which follow IEEE-754 floating-point standard in their handling of infinities and NaNs. This permits the use of efficient inner loops avoiding a check for zero divisors.

Parameters

  • JOBZ — okay so JOBZ is CHARACTER*1. = 'N': Compute eigenvalues only; = 'V': Compute eigenvalues and eigenvectors. pick your fighter 💅
  • RANGE — RANGE is CHARACTER*1. = 'A': all eigenvalues will be found. = 'V': all eigenvalues in the half-open interval (VL,VU] will be found. = 'I': the IL-th through IU-th eigenvalues will be found. choose your range, bestie
  • N — N is INTEGER. The order of the matrix. N >= 0. she's the size, no cap
  • D — D is DOUBLE PRECISION array, dimension (N). On entry, the N diagonal elements of the tridiagonal matrix T. On exit, D is overwritten. she gets replaced, periodt
  • E — E is DOUBLE PRECISION array, dimension (N). On entry, the (N-1) subdiagonal elements of the tridiagonal matrix T in elements 1 to N-1 of E. E(N) need not be set on input, but is used internally as workspace. On exit, E is overwritten. workspace queen 🎀
  • VL — VL is DOUBLE PRECISION. If RANGE='V', the lower bound of the interval to be searched for eigenvalues. VL < VU. Not referenced if RANGE = 'A' or 'I'. only if you picked the V range, iykyk
  • VU — VU is DOUBLE PRECISION. If RANGE='V', the upper bound of the interval to be searched for eigenvalues. VL < VU. Not referenced if RANGE = 'A' or 'I'. upper bound bestie ✨
  • IL — IL is INTEGER. If RANGE='I', the index of the smallest eigenvalue to be returned. 1 <= IL <= IU <= N, if N > 0. Not referenced if RANGE = 'A' or 'V'. index vibes
  • IU — IU is INTEGER. If RANGE='I', the index of the largest eigenvalue to be returned. 1 <= IL <= IU <= N, if N > 0. Not referenced if RANGE = 'A' or 'V'. the other index 🦋
  • M — M is INTEGER. The total number of eigenvalues found. 0 <= M <= N. If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1. the count, slay
  • W — W is DOUBLE PRECISION array, dimension (N). The first M elements contain the selected eigenvalues in ascending order. sorted, periodt 🌸
  • Z — Z is DOUBLE PRECISION array, dimension (LDZ, max(1,M) ). If JOBZ = 'V', and if INFO = 0, then the first M columns of Z contain the orthonormal eigenvectors of the matrix T corresponding to the selected eigenvalues, with the i-th column of Z holding the eigenvector associated with W(i). If JOBZ = 'N', then Z is not referenced. Note: the user must ensure that at least max(1,M) columns are supplied in the array Z; if RANGE = 'V', the exact value of M is not known in advance and can be computed with a workspace query by setting NZC = -1, see below. eigenvector central 👑
  • LDZ — LDZ is INTEGER. The leading dimension of the array Z. LDZ >= 1, and if JOBZ = 'V', then LDZ >= max(1,N). leading dimension realness
  • NZC — NZC is INTEGER. The number of eigenvectors to be held in the array Z. If RANGE = 'A', then NZC >= max(1,N). If RANGE = 'V', then NZC >= the number of eigenvalues in (VL,VU]. If RANGE = 'I', then NZC >= IU-IL+1. If NZC = -1, then a workspace query is assumed; the routine calculates the number of columns of the array Z that are needed to hold the eigenvectors. This value is returned as the first entry of the Z array, and no error message related to NZC is issued by XERBLA. query mode, iykyk 💜
  • ISUPPZ — ISUPPZ is INTEGER array, dimension ( 2*max(1,M) ). The support of the eigenvectors in Z, i.e., the indices indicating the nonzero elements in Z. The i-th computed eigenvector is nonzero only in elements ISUPPZ( 2*i-1 ) through ISUPPZ( 2*i ). This is relevant in the case when the matrix is split. ISUPPZ is only accessed when JOBZ is 'V' and N > 0. support system, literally 🫶
  • TRYRAC — TRYRAC is LOGICAL. If TRYRAC = .TRUE., indicates that the code should check whether the tridiagonal matrix defines its eigenvalues to high relative accuracy. If so, the code uses relative-accuracy preserving algorithms that might be (a bit) slower depending on the matrix. If the matrix does not define its eigenvalues to high relative accuracy, the code can use possibly faster algorithms. If TRYRAC = .FALSE., the code is not required to guarantee relatively accurate eigenvalues and can use the fastest possible techniques. On exit, a .TRUE. TRYRAC will be set to .FALSE. if the matrix does not define its eigenvalues to high relative accuracy. accuracy check, bestie 😭
  • WORK — WORK is DOUBLE PRECISION array, dimension (LWORK). On exit, if INFO = 0, WORK(1) returns the optimal (and minimal) LWORK. workspace tea 🔥
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,18*N) if JOBZ = 'V', and LWORK >= max(1,12*N) if JOBZ = 'N'. If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. size matters, periodt ⭐
  • IWORK — IWORK is INTEGER array, dimension (LIWORK). On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK. integer workspace icon
  • LIWORK — LIWORK is INTEGER. The dimension of the array IWORK. LIWORK >= max(1,10*N) if the eigenvectors are desired, and LIWORK >= max(1,8*N) if only the eigenvalues are to be computed. If LIWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the IWORK array, returns this value as the first entry of the IWORK array, and no error message related to LIWORK is issued by XERBLA. more workspace realness 🌈
  • INFO — INFO is INTEGER. On exit, INFO = 0: successful exit; < 0: if INFO = -i, the i-th argument had an illegal value; > 0: if INFO = 1X, internal error in DLARRE, if INFO = 2X, internal error in DLARRV. Here, the digit X = ABS( IINFO ) < 10, where IINFO is the nonzero error code returned by DLARRE or DLARRV, respectively. exit status tea 💀

Author

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

Contributors 🫶

  • Beresford Parlett, University of California, Berkeley, USA
  • Jim Demmel, University of California, Berkeley, USA
  • Inderjit Dhillon, University of Texas, Austin, USA
  • Osni Marques, LBNL/NERSC, USA
  • Christof Voemel, University of California, Berkeley, USA

DTBCON 💅

subroutine dtbcon (character NORM, character UPLO, character DIAG, integer
    N, integer KD, double precision, dimension( ldab, * ) AB, integer LDAB,
    double precision RCOND, double precision, dimension( * ) WORK, integer,
    dimension( * ) IWORK, integer INFO)

Purpose ✨

Okay bestie, DTBCON estimates the reciprocal of the condition number of a triangular band matrix A, and it can do it in either the 1-norm or the infinity-norm, your choice, no cap.

The way it works: it computes the norm of A, then gets an estimate for norm(inv(A)), and then the reciprocal of the condition number comes out as

RCOND = 1 / ( norm(A) * norm(inv(A)) ).

Parameters 🎀

  • NORM — CHARACTER*1. Tells it whether you want the 1-norm condition number or the infinity-norm condition number:
    • = '1' or 'O': 1-norm;
    • = 'I': Infinity-norm.
  • UPLO — CHARACTER*1.
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • DIAG — CHARACTER*1.
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — INTEGER. The order of the matrix A. N >= 0.
  • KD — INTEGER. The number of superdiagonals or subdiagonals of the triangular band matrix A. KD >= 0.
  • AB — DOUBLE PRECISION array, dimension (LDAB,N). The upper or lower triangular band matrix A, stored in the first kd+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows:
    • if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

If DIAG = 'U', the diagonal elements of A are not referenced and are assumed to be 1. 💫

  • LDAB — INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • RCOND — DOUBLE PRECISION. The reciprocal of the condition number of the matrix A, computed as RCOND = 1/(norm(A) * norm(inv(A))).
  • WORK — DOUBLE PRECISION array, dimension (3*N).
  • IWORK — INTEGER array, dimension (N).
  • INFO — INTEGER.
    • = 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.


DTBRFS 🦋

subroutine dtbrfs (character UPLO, character TRANS, character DIAG, integer
    N, integer KD, integer NRHS, double precision, dimension( ldab, * ) AB,
    integer LDAB, double precision, dimension( ldb, * ) B, integer LDB,
    double precision, dimension( ldx, * ) X, integer LDX, double precision,
    dimension( * ) FERR, double precision, dimension( * ) BERR, double
    precision, dimension( * ) WORK, integer, dimension( * ) IWORK, integer
    INFO)

Purpose 💖

DTBRFS hands you error bounds and backward error estimates for the solution to a system of linear equations with a triangular band coefficient matrix. It's giving quality assurance energy fr fr.

Heads up bestie: the solution matrix X must be computed by DTBTRS or some other means before entering this routine.

And no, DTBRFS does not do iterative refinement — because doing so cannot improve the backward error. So don't ask. Periodt. 💅

Parameters 🌸

  • UPLO — CHARACTER*1.
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • TRANS — CHARACTER*1. Specifies the form of the system of equations:
    • = 'N': A * X = B (No transpose)
    • = 'T': A**T * X = B (Transpose)
    • = 'C': A**H * X = B (Conjugate transpose = Transpose)
  • DIAG — CHARACTER*1.
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — INTEGER. The order of the matrix A. N >= 0.
  • KD — INTEGER. The number of superdiagonals or subdiagonals of the triangular band matrix A. KD >= 0.
  • NRHS — INTEGER. The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0.
  • AB — DOUBLE PRECISION array, dimension (LDAB,N). The upper or lower triangular band matrix A, stored in the first kd+1 rows of the array. The j-th column of A is stored in the j-th column of the array AB as follows:
    • if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

If DIAG = 'U', the diagonal elements of A are not referenced and are assumed to be 1.

  • LDAB — INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • B — DOUBLE PRECISION array, dimension (LDB,NRHS). The right hand side matrix B.
  • LDB — INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • X — DOUBLE PRECISION array, dimension (LDX,NRHS). The solution matrix X.
  • LDX — INTEGER. The leading dimension of the array X. LDX >= max(1,N).
  • FERR — DOUBLE PRECISION array, dimension (NRHS). The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error. So like, it's a little dramatic but in a safe direction, iykyk. 🙈
  • BERR — DOUBLE PRECISION array, dimension (NRHS). The componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution).
  • WORK — DOUBLE PRECISION array, dimension (3*N).
  • IWORK — INTEGER array, dimension (N).
  • INFO — INTEGER.
    • = 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.


DTBTRS 🔥

subroutine dtbtrs (character UPLO, character TRANS, character DIAG, integer
    N, integer KD, integer NRHS, double precision, dimension( ldab, * ) AB,
    integer LDAB, double precision, dimension( ldb, * ) B, integer LDB,
    integer INFO)

Purpose 👑

DTBTRS solves a triangular system of the form

A * X = B  or  A**T * X = B,

where A is a triangular band matrix of order N, and B is an N-by NRHS matrix. And bestie, it does a check to verify that A is nonsingular. Safety first. 💅

Parameters 🌈

  • UPLO — CHARACTER*1.
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • TRANS — CHARACTER*1. Specifies the form the system of equations:
    • = 'N': A * X = B (No transpose)
    • = 'T': A**T * X = B (Transpose)
    • = 'C': A**H * X = B (Conjugate transpose = Transpose)
  • DIAG — CHARACTER*1.
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — INTEGER. The order of the matrix A. N >= 0.
  • KD — INTEGER. The number of superdiagonals or subdiagonals of the triangular band matrix A. KD >= 0.
  • NRHS — INTEGER. The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.
  • AB — DOUBLE PRECISION array, dimension (LDAB,N). The upper or lower triangular band matrix A, stored in the first kd+1 rows of AB. The j-th column of A is stored in the j-th column of the array AB as follows:
    • if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
    • if UPLO = 'L', AB(1+i-j,j) = A(i,j) for j<=i<=min(n,j+kd).

If DIAG = 'U', the diagonal elements of A are not referenced and are assumed to be 1.

  • LDAB — INTEGER. The leading dimension of the array AB. LDAB >= KD+1.
  • B — DOUBLE PRECISION array, dimension (LDB,NRHS). On entry, the right hand side matrix B. On exit, if INFO = 0, the solution matrix X. Glow-up moment honestly ✨
  • LDB — INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • INFO — INTEGER.
    • = 0: successful exit ✨
    • < 0: if INFO = -i, the i-th argument had an illegal value 😭
    • > 0: if INFO = i, the i-th diagonal element of A is zero, indicating that the matrix is singular and the solutions X have not been computed. 💀

Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


DTFSM 🧚

subroutine dtfsm (character TRANSR, character SIDE, character UPLO,
    character TRANS, character DIAG, integer M, integer N, double precision
    ALPHA, double precision, dimension( 0: * ) A, double precision,
    dimension( 0: ldb-1, 0: * ) B, integer LDB)

DTFSM solves a matrix equation (one operand is a triangular matrix in RFP format).

Purpose 💜

Level 3 BLAS like routine for A in RFP Format.

   op( A )*X = alpha*B  or  X*op( A ) = alpha*B

where alpha is a scalar, X and B are m by n matrices, A is a unit, or non-unit, upper or lower triangular matrix and op( A ) is one of

   op( A ) = A   or   op( A ) = A**T.

A is in Rectangular Full Packed (RFP) Format.

And bestie, listen — the matrix X gets overwritten on B. It's giving "no takebacks" energy. 💅


Parameters 💖

  • TRANSR — CHARACTER*1
    • = 'N': the Normal Form of RFP A is stored;
    • = 'T': the Transpose Form of RFP A is stored.
  • SIDE — CHARACTER*1. On entry, SIDE tells us whether op( A ) is chillin' on the left or the right of X, like so:
    • SIDE = 'L' or 'l' → op( A )*X = alpha*B.
    • SIDE = 'R' or 'r' → X*op( A ) = alpha*B.

Unchanged on exit. 🫶

  • UPLO — CHARACTER*1. On entry, UPLO says whether the RFP matrix A came from an upper or lower triangular matrix:
    • UPLO = 'U' or 'u' → RFP A came from an upper triangular matrix
    • UPLO = 'L' or 'l' → RFP A came from a lower triangular matrix

Unchanged on exit. ✨

  • TRANS — CHARACTER*1. On entry, TRANS specifies the form of op( A ) used in the matrix multiplication:
    • TRANS = 'N' or 'n' → op( A ) = A.
    • TRANS = 'T' or 't' → op( A ) = A'.

Unchanged on exit. 🎀

  • DIAG — CHARACTER*1. On entry, DIAG says whether or not RFP A is unit triangular:
    • DIAG = 'U' or 'u' → A is assumed to be unit triangular.
    • DIAG = 'N' or 'n' → A is not assumed to be unit triangular.

Unchanged on exit. 🦋

  • M — INTEGER. On entry, M is the number of rows of B. M must be at least zero. Unchanged on exit.
  • N — INTEGER. On entry, N is the number of columns of B. N must be at least zero. Unchanged on exit.
  • ALPHA — DOUBLE PRECISION. On entry, ALPHA is the scalar alpha. When alpha is zero then A is not referenced and B need not be set before entry. Unchanged on exit.
  • A — DOUBLE PRECISION array, dimension (NT), with NT = N*(N+1)/2. On entry, this is the matrix A in RFP Format.

RFP Format is described by TRANSR, UPLO and N as follows:

  • If TRANSR='N' then RFP A is (0:N,0:K-1) when N is even; K=N/2. RFP A is (0:N-1,0:K) when N is odd; K=N/2.
  • If TRANSR = 'T' then RFP is the transpose of RFP A as defined when TRANSR = 'N'.
  • The contents of RFP A are defined by UPLO as follows: if UPLO = 'U' the RFP A contains the NT elements of upper packed A either in normal or transpose Format. If UPLO = 'L' the RFP A contains the NT elements of lower packed A either in normal or transpose Format.
  • The LDA of RFP A is (N+1)/2 when TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and is N when it's odd.

See the Note below for more details. Unchanged on exit. 🌸

  • B — DOUBLE PRECISION array, dimension (LDB,N). Before entry, the leading m by n part of the array B must contain the right-hand side matrix B, and on exit it is overwritten by the solution matrix X. 😭 (girl, save a copy if you need the original, fr fr)
  • LDB — INTEGER. On entry, LDB is the first dimension of B as declared in the calling (sub) program. LDB must be at least max( 1, m ). Unchanged on exit.

Author 👑

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

Further Details 💅

Okay so first up, let's do Rectangular Full Packed (RFP) Format when N is even. Example time: N = 6.

                 AP is Upper             AP is Lower

              00 01 02 03 04 05       00
                 11 12 13 14 15       10 11
                    22 23 24 25       20 21 22
                       33 34 35       30 31 32 33
                          44 45       40 41 42 43 44
                             55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP like this:

  • For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper.
  • For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower.

That covers the case N even and TRANSR = 'N'.

                    RFP A                   RFP A

                   03 04 05                33 43 53
                   13 14 15                00 44 54
                   23 24 25                10 11 55
                   33 34 35                20 21 22
                   00 44 45                30 31 32
                   01 11 55                40 41 42
                   02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. So you get:

                      RFP A                   RFP A

                03 13 23 33 00 01 02    33 00 10 20 30 40 50
                04 14 24 34 44 11 12    43 44 11 21 31 41 51
                05 15 25 35 45 55 22    53 54 55 22 32 42 52

Next up: RFP Format when N is odd. Example where N = 5.

                AP is Upper                 AP is Lower

              00 01 02 03 04              00
                 11 12 13 14              10 11
                    22 23 24              20 21 22
                       33 34              30 31 32 33
                          44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows:

  • For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper.
  • For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower.

That covers the case N odd and TRANSR = 'N'.

                    RFP A                   RFP A

                   02 03 04                00 33 43
                   12 13 14                10 11 44
                   22 23 24                20 21 22
                   00 33 34                30 31 32
                   01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                02 12 22 00 01             00 10 20 30 40 50
                03 13 23 33 11             33 11 21 31 41 51
                04 14 24 34 44             43 44 22 32 42 52

subroutine dtftri

subroutine dtftri (character TRANSR, character UPLO, character DIAG, integer
    N, double precision, dimension( 0: * ) A, integer INFO)

DTFTRI 🧚

Purpose:

DTFTRI computes the inverse of a triangular matrix A stored in RFP format.

This is a Level 3 BLAS version of the algorithm. She's built different. 🔥

Parameters

  • TRANSR — CHARACTER*1
    • = 'N': the Normal TRANSR of RFP A is stored;
    • = 'T': the Transpose TRANSR of RFP A is stored.
  • UPLO — CHARACTER*1
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • DIAG — CHARACTER*1
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — INTEGER. The order of the matrix A. N >= 0.
  • A — DOUBLE PRECISION array, dimension (0:nt-1), where nt=N*(N+1)/2. On entry, the triangular factor of a Hermitian Positive Definite matrix A in RFP format.

RFP format is described by TRANSR, UPLO, and N as follows:

  • If TRANSR = 'N' then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is (0:N-1,0:k) when N is odd; k=N/2.
  • If TRANSR = 'T' then RFP is the transpose of RFP A as defined when TRANSR = 'N'.
  • The contents of RFP A are defined by UPLO as follows: if UPLO = 'U' the RFP A contains the nt elements of upper packed A; if UPLO = 'L' the RFP A contains the nt elements of lower packed A.
  • The LDA of RFP A is (N+1)/2 when TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and N when N is odd.

See the Note below for more details.

On exit, the (triangular) inverse of the original matrix, in the same storage format. 💜

  • INFO — INTEGER
    • = 0: successful exit ✨
    • < 0: if INFO = -i, the i-th argument had an illegal value 🙈
    • > 0: if INFO = i, A(i,i) is exactly zero. The triangular matrix is singular and its inverse can not be computed. 💀

Author 👑

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

Further Details 🦋

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6.

                 AP is Upper             AP is Lower

              00 01 02 03 04 05       00
                 11 12 13 14 15       10 11
                    22 23 24 25       20 21 22
                       33 34 35       30 31 32 33
                          44 45       40 41 42 43 44
                             55       50 51 52 53 54 55

Okay bestie, we're deep in the RFP lore now — the N even case, N odd case, and the exact index gymnastics. Buckle up, this is the good stuff 💖


Let TRANSR = 'N'. RFP holds AP like this:

  • For UPLO = 'U' the upper trapezoid <code>A(0:5,0:2)</code> is made of the last three columns of AP upper. The lower triangle <code>A(4:6,0:2)</code> is the transpose of the first three columns of AP upper.
  • For UPLO = 'L' the lower trapezoid <code>A(1:6,0:2)</code> is made of the first three columns of AP lower. The upper triangle <code>A(0:2,0:2)</code> is the transpose of the last three columns of AP lower.

This covers the case N even and TRANSR = 'N'.

                    RFP A                   RFP A

                   03 04 05                33 43 53
                   13 14 15                00 44 54
                   23 24 25                10 11 55
                   33 34 35                20 21 22
                   00 44 45                30 31 32
                   01 11 55                40 41 42
                   02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. So one therefore gets:

                      RFP A                   RFP A

                03 13 23 33 00 01 02    33 00 10 20 30 40 50
                04 14 24 34 44 11 12    43 44 11 21 31 41 51
                05 15 25 35 45 55 22    53 54 55 22 32 42 52

Now we consider Rectangular Full Packed (RFP) Format when N is odd. Example where N = 5:

                AP is Upper                 AP is Lower

              00 01 02 03 04              00
                 11 12 13 14              10 11
                    22 23 24              20 21 22
                       33 34              30 31 32 33
                          44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows:

  • For UPLO = 'U' the upper trapezoid <code>A(0:4,0:2)</code> is the last three columns of AP upper. The lower triangle <code>A(3:4,0:1)</code> is the transpose of the first two columns of AP upper.
  • For UPLO = 'L' the lower trapezoid <code>A(0:4,0:2)</code> is the first three columns of AP lower. The upper triangle <code>A(0:1,1:2)</code> is the transpose of the last two columns of AP lower.

This covers the case N odd and TRANSR = 'N'.

                    RFP A                   RFP A

                   02 03 04                00 33 43
                   12 13 14                10 11 44
                   22 23 24                20 21 22
                   00 33 34                30 31 32
                   01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                02 12 22 00 01             00 10 20 30 40 50
                03 13 23 33 11             33 11 21 31 41 51
                04 14 24 34 44             43 44 22 32 42 52

🌸 subroutine dtfttp 🌸

   subroutine dtfttp (character TRANSR, character UPLO, integer N, double
       precision, dimension( 0: * ) ARF, double precision, dimension( 0: * )
       AP, integer INFO)

DTFTTP copies a triangular matrix from the rectangular full packed format (TF) to the standard packed format (TP). Obsessed with the glow-up honestly 💅

✨ Purpose ✨

DTFTTP copies a triangular matrix A from rectangular full packed format (TF) to standard packed format (TP).

🎀 Parameters 🎀

  • TRANSR — is CHARACTER*1
    • = 'N': ARF is in Normal format;
    • = 'T': ARF is in Transpose format;
  • UPLO — is CHARACTER*1
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • N — is INTEGER. The order of the matrix A. N >= 0.
  • ARF — is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ). On entry, the upper or lower triangular matrix A stored in RFP format. For a further discussion see Notes below.
  • AP — is DOUBLE PRECISION array, dimension ( N*(N+1)/2 ). On exit, the upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  • INFO — is INTEGER
    • = 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.

🌈 Further Details 🌈

We first consider Rectangular Full Packed (RFP) Format when N is even. Example where N = 6.

                 AP is Upper             AP is Lower

              00 01 02 03 04 05       00
                 11 12 13 14 15       10 11
                    22 23 24 25       20 21 22
                       33 34 35       30 31 32 33
                          44 45       40 41 42 43 44
                             55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows:

  • For UPLO = 'U' the upper trapezoid <code>A(0:5,0:2)</code> is the last three columns of AP upper. The lower triangle <code>A(4:6,0:2)</code> is the transpose of the first three columns of AP upper.
  • For UPLO = 'L' the lower trapezoid <code>A(1:6,0:2)</code> is the first three columns of AP lower. The upper triangle <code>A(0:2,0:2)</code> is the transpose of the last three columns of AP lower.

This covers the case N even and TRANSR = 'N'.

                    RFP A                   RFP A

                   03 04 05                33 43 53
                   13 14 15                00 44 54
                   23 24 25                10 11 55
                   33 34 35                20 21 22
                   00 44 45                30 31 32
                   01 11 55                40 41 42
                   02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                03 13 23 33 00 01 02    33 00 10 20 30 40 50
                04 14 24 34 44 11 12    43 44 11 21 31 41 51
                05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. Example where N = 5.

                AP is Upper                 AP is Lower

              00 01 02 03 04              00
                 11 12 13 14              10 11
                    22 23 24              20 21 22
                       33 34              30 31 32 33
                          44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows:

  • For UPLO = 'U' the upper trapezoid <code>A(0:4,0:2)</code> is the last three columns of AP upper. The lower triangle <code>A(3:4,0:1)</code> is the transpose of the first two columns of AP upper.
  • For UPLO = 'L' the lower trapezoid <code>A(0:4,0:2)</code> is the first three columns of AP lower. The upper triangle <code>A(0:1,1:2)</code> is the transpose of the last two columns of AP lower.

This covers the case N odd and TRANSR = 'N'.

                    RFP A                   RFP A

                   02 03 04                00 33 43
                   12 13 14                10 11 44
                   22 23 24                20 21 22
                   00 33 34                30 31 32
                   01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                02 12 22 00 01             00 10 20 30 40 50
                03 13 23 33 11             33 11 21 31 41 51
                04 14 24 34 44             43 44 22 32 42 52

🦋 subroutine dtfttr 🦋

   subroutine dtfttr (character TRANSR, character UPLO, integer N, double
       precision, dimension( 0: * ) ARF, double precision, dimension( 0: lda-1,
       0: * ) A, integer LDA, integer INFO)

DTFTTR copies a triangular matrix from the rectangular full packed format (TF) to the standard full format (TR). The glow-up pipeline continues, no cap ✨

✨ Purpose ✨

DTFTTR copies a triangular matrix A from rectangular full packed format (TF) to standard full format (TR).

🎀 Parameters 🎀

  • TRANSR — is CHARACTER*1
    • = 'N': ARF is in Normal format;
    • = 'T': ARF is in Transpose format.
  • UPLO — is CHARACTER*1
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • N — is INTEGER. The order of the matrices ARF and A. N >= 0.
  • ARF — is DOUBLE PRECISION array, dimension (N*(N+1)/2). On entry, the upper (if UPLO = 'U') or lower (if UPLO = 'L') matrix A in RFP format. See the 'Notes' below for more details.
  • A — is DOUBLE PRECISION array, dimension (LDA,N). On exit, the triangular matrix A.
    • If UPLO = 'U', the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced.
    • If UPLO = 'L', the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced.
  • LDA — is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • INFO — is INTEGER
    • = 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.

🌈 Further Details 🌈

We first consider Rectangular Full Packed (RFP) Format when N is even. Example where N = 6.

                 AP is Upper             AP is Lower

              00 01 02 03 04 05       00
                 11 12 13 14 15       10 11
                    22 23 24 25       20 21 22
                       33 34 35       30 31 32 33
                          44 45       40 41 42 43 44
                             55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows:

  • For UPLO = 'U' the upper trapezoid <code>A(0:5,0:2)</code> is the last three columns of AP upper. The lower triangle <code>A(4:6,0:2)</code> is the transpose of the first three columns of AP upper.
  • For UPLO = 'L' the lower trapezoid <code>A(1:6,0:2)</code> is the first three columns of AP lower. The upper triangle <code>A(0:2,0:2)</code> is the transpose of the last three columns of AP lower.

This covers the case N even and TRANSR = 'N'.

                    RFP A                   RFP A
                   03 04 05                33 43 53
                   13 14 15                00 44 54
                   23 24 25                10 11 55
                   33 34 35                20 21 22
                   00 44 45                30 31 32
                   01 11 55                40 41 42
                   02 12 22                50 51 52

Okay so now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A up above, no extra lore. So you get:

                      RFP A                   RFP A

                03 13 23 33 00 01 02    33 00 10 20 30 40 50
                04 14 24 34 44 11 12    43 44 11 21 31 41 51
                05 15 25 35 45 55 22    53 54 55 22 32 42 52

And then we do Rectangular Full Packed (RFP) Format for when N is odd. Bestie, the example is N = 5, here we go:

                AP is Upper                 AP is Lower

              00 01 02 03 04              00
                 11 12 13 14              10 11
                    22 23 24              20 21 22
                       33 34              30 31 32 33
                          44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP like this, bestie, stay with me:

  • For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper.
  • For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower.

This covers the case N odd and TRANSR = 'N'. ✨

                    RFP A                   RFP A

                   02 03 04                00 33 43
                   12 13 14                10 11 44
                   22 23 24                20 21 22
                   00 33 34                30 31 32
                   01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

                      RFP A                   RFP A

                02 12 22 00 01             00 10 20 30 40 50
                03 13 23 33 11             33 11 21 31 41 51
                04 14 24 34 44             43 44 22 32 42 52

🫶 subroutine dtgsen 🫶

subroutine dtgsen (integer IJOB, logical WANTQ, logical WANTZ, logical,
    dimension( * ) SELECT, integer N, double precision, dimension( lda, * )
    A, integer LDA, double precision, dimension( ldb, * ) B, integer LDB,
    double precision, dimension( * ) ALPHAR, double precision, dimension( *
    ) ALPHAI, double precision, dimension( * ) BETA, double precision,
    dimension( ldq, * ) Q, integer LDQ, double precision, dimension( ldz, *
    ) Z, integer LDZ, integer M, double precision PL, double precision PR,
    double precision, dimension( * ) DIF, double precision, dimension( * )
    WORK, integer LWORK, integer, dimension( * ) IWORK, integer LIWORK,
    integer INFO)

👑 DTGSEN 👑

🌸 Purpose 🌸

DTGSEN reorders the generalized real Schur decomposition of a real matrix pair (A, B) — like, it does it in terms of an orthonormal equivalence transformation Q**T * (A, B) * Z — so that a selected cluster of eigenvalues shows up in the leading diagonal blocks of the upper quasi-triangular matrix A and the upper triangular B. The leading columns of Q and Z form orthonormal bases of the corresponding left and right eigenspaces (deflating subspaces). And bestie, (A, B) must already be in generalized real Schur canonical form (the kind DGGES hands you), meaning A is block upper triangular with 1-by-1 and 2-by-2 diagonal blocks. B is upper triangular. No cap. 💅

DTGSEN also computes the generalized eigenvalues

w(j) = (ALPHAR(j) + i*ALPHAI(j))/BETA(j)

of the reordered matrix pair (A, B).

Optionally, DTGSEN computes the estimates of reciprocal condition numbers for eigenvalues and eigenspaces. These are Difu[(A11,B11), (A22,B22)] and Difl[(A11,B11), (A22,B22)], i.e. the separation(s) between the matrix pairs (A11, B11) and (A22,B22) that correspond to the selected cluster and the eigenvalues outside the cluster, resp., and norms of 'projections' onto left and right eigenspaces w.r.t. the selected cluster in the (1,1)-block.


✨ Parameters ✨

  • IJOB — IJOB is INTEGER. It specifies whether condition numbers are required for the cluster of eigenvalues (PL and PR) or the deflating subspaces (Difu and Difl). Like, choose your fighter:
    • =0: Only reorder w.r.t. SELECT. No extras.
    • =1: Reciprocal of norms of 'projections' onto left and right eigenspaces w.r.t. the selected cluster (PL and PR).
    • =2: Upper bounds on Difu and Difl. F-norm-based estimate (DIF(1:2)).
    • =3: Estimate of Difu and Difl. 1-norm-based estimate (DIF(1:2)). About 5 times as expensive as IJOB = 2. 💀
    • =4: Compute PL, PR and DIF (i.e. 0, 1 and 2 above): Economic version to get it all.
    • =5: Compute PL, PR and DIF (i.e. 0, 1 and 3 above)
  • WANTQ — WANTQ is LOGICAL.
    • .TRUE. : update the left transformation matrix Q;
    • .FALSE.: do not update Q.
  • WANTZ — WANTZ is LOGICAL.
    • .TRUE. : update the right transformation matrix Z;
    • .FALSE.: do not update Z.
  • SELECT — SELECT is LOGICAL array, dimension (N). SELECT specifies the eigenvalues in the selected cluster. To select a real eigenvalue w(j), SELECT(j) must be set to .TRUE.. To select a complex conjugate pair of eigenvalues w(j) and w(j+1), corresponding to a 2-by-2 diagonal block, either SELECT(j) or SELECT(j+1) or both must be set to .TRUE.; a complex conjugate pair of eigenvalues must be either both included in the cluster or both excluded. That's the rule, periodt.
  • N — N is INTEGER. The order of the matrices A and B. N >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N).
    • On entry, the upper quasi-triangular matrix A, with (A, B) in generalized real Schur canonical form.
    • On exit, A is overwritten by the reordered matrix A.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B — B is DOUBLE PRECISION array, dimension (LDB,N).
    • On entry, the upper triangular matrix B, with (A, B) in generalized real Schur canonical form.
    • On exit, B is overwritten by the reordered matrix B.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • ALPHAR — ALPHAR is DOUBLE PRECISION array, dimension (N)
  • ALPHAI — ALPHAI is DOUBLE PRECISION array, dimension (N)
  • BETA — BETA is DOUBLE PRECISION array, dimension (N).

On exit, (ALPHAR(j) + ALPHAI(j)*i)/BETA(j), j=1,...,N, will be the generalized eigenvalues. ALPHAR(j) + ALPHAI(j)*i and BETA(j), j=1,...,N are the diagonals of the complex Schur form (S,T) that would result if the 2-by-2 diagonal blocks of the real generalized Schur form of (A,B) were further reduced to triangular form using complex unitary transformations. If ALPHAI(j) is zero, then the j-th eigenvalue is real; if positive, then the j-th and (j+1)-st eigenvalues are a complex conjugate pair, with ALPHAI(j+1) negative. 🦋

  • Q — Q is DOUBLE PRECISION array, dimension (LDQ,N).
    • On entry, if WANTQ = .TRUE., Q is an N-by-N matrix.
    • On exit, Q has been postmultiplied by the left orthogonal transformation matrix which reorder (A, B); The leading M columns of Q form orthonormal bases for the specified pair of left eigenspaces (deflating subspaces).
    • If WANTQ = .FALSE., Q is not referenced.
  • LDQ — LDQ is INTEGER. The leading dimension of the array Q. LDQ >= 1; and if WANTQ = .TRUE., LDQ >= N.
  • Z — Z is DOUBLE PRECISION array, dimension (LDZ,N).
    • On entry, if WANTZ = .TRUE., Z is an N-by-N matrix.
    • On exit, Z has been postmultiplied by the left orthogonal transformation matrix which reorder (A, B); The leading M columns of Z form orthonormal bases for the specified pair of left eigenspaces (deflating subspaces).
    • If WANTZ = .FALSE., Z is not referenced.
  • LDZ — LDZ is INTEGER. The leading dimension of the array Z. LDZ >= 1; If WANTZ = .TRUE., LDZ >= N.
  • M — M is INTEGER. The dimension of the specified pair of left and right eigenspaces (deflating subspaces). 0 <= M <= N.
  • PL — PL is DOUBLE PRECISION
  • PR — PR is DOUBLE PRECISION.

If IJOB = 1, 4 or 5, PL, PR are lower bounds on the reciprocal of the norm of 'projections' onto left and right eigenspaces with respect to the selected cluster. 0 < PL, PR <= 1. If M = 0 or M = N, PL = PR = 1. If IJOB = 0, 2 or 3, PL and PR are not referenced.

  • DIF — DIF is DOUBLE PRECISION array, dimension (2). If IJOB >= 2, DIF(1:2) store the estimates of Difu and Difl. If IJOB = 2 or 4, DIF(1:2) are F-norm-based upper bounds on Difu and Difl. If IJOB = 3 or 5, DIF(1:2) are 1-norm-based estimates of Difu and Difl. If M = 0 or N, DIF(1:2) = F-norm([A, B]). If IJOB = 0 or 1, DIF is not referenced.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= 4*N+16. If IJOB = 1, 2 or 4, LWORK >= MAX(4*N+16, 2*M*(N-M)). If IJOB = 3 or 5, LWORK >= MAX(4*N+16, 4*M*(N-M)).

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. i y k y k — it's the classic workspace-query move. 😌

  • IWORK

IWORK

IWORK is an INTEGER array, dimension (MAX(1,LIWORK)) 💖

So on the way out, if INFO = 0, then IWORK(1) hands you back the optimal LIWORK ✨ like a little gift.


LIWORK

LIWORK is INTEGER 🌸

  • It's the dimension of the IWORK array, and it has to be LIWORK >= 1 — non-negotiable bestie 💅
  • If IJOB = 1, 2 or 4, then LIWORK >= N+6
  • If IJOB = 3 or 5, then LIWORK >= MAX(2*M*(N-M), N+6)
And if LIWORK = -1?? 👀 That's the workspace-query mode, babes. The routine only calculates the optimal size of the IWORK array, returns that value as the first entry of the IWORK array, and no error message related to LIWORK is issued by XERBLA. So don't come for XERBLA, it's minding its business 🙈

INFO

INFO is INTEGER 🦋

  • =0: Successful exit. slay ✨
  • <0: If INFO = -i, the i-th argument had an illegal value 😭
  • =1: Reordering of (A, B) failed because the transformed matrix pair (A, B) would be too far from generalized Schur form — the problem is very ill-conditioned. (A, B) may have been partially reordered. And if requested, 0 is returned in DIF(*), PL and PR. 💀

Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


Further Details: 🧚

Okay so DTGSEN first collects the selected eigenvalues by computing orthogonal U and W that move them to the top left corner of (A, B). In other words, the selected eigenvalues are the eigenvalues of (A11, B11) in:

          U**T*(A, B)*W = (A11 A12) (B11 B12) n1
                          ( 0  A22),( 0  B22) n2
                            n1  n2    n1  n2

where N = n1+n2 and U**T means the transpose of U. The first n1 columns of U and W span the specified pair of left and right eigenspaces (deflating subspaces) of (A, B). 🎀

If (A, B) has been obtained from the generalized real Schur decomposition of a matrix pair (C, D) = Q*(A, B)*Z**T, then the reordered generalized real Schur form of (C, D) is given by

                   (C, D) = (Q*U)*(U**T*(A, B)*W)*(Z*W)**T,

and the first n1 columns of Q*U and Z*W span the corresponding deflating subspaces of (C, D) (Q and Z store Q*U and Z*W, resp.). ✨

Heads up bestie: if the selected eigenvalue is sufficiently ill-conditioned, then its value may differ significantly from its value before reordering. 😭 Not a vibe but it's the truth.

The reciprocal condition numbers of the left and right eigenspaces spanned by the first n1 columns of U and W (or Q*U and Z*W) may be returned in DIF(1:2), corresponding to Difu and Difl, resp.

The Difu and Difl are defined as:

     Difu[(A11, B11), (A22, B22)] = sigma-min( Zu )
and
     Difl[(A11, B11), (A22, B22)] = Difu[(A22, B22), (A11, B11)],

where sigma-min(Zu) is the smallest singular value of the (2*n1*n2)-by-(2*n1*n2) matrix

     Zu = [ kron(In2, A11)  -kron(A22**T, In1) ]
          [ kron(In2, B11)  -kron(B22**T, In1) ].

Here, Inx is the identity matrix of size nx and A22**T is the transpose of A22. kron(X, Y) is the Kronecker product between the matrices X and Y. 💖

When DIF(2) is small, small changes in (A, B) can cause large changes in the deflating subspace. An approximate (asymptotic) bound on the maximum angular error in the computed deflating subspaces is

     EPS * norm((A, B)) / DIF(2),

where EPS is the machine precision. 🌸

The reciprocal norm of the projectors on the left and right eigenspaces associated with (A11, B11) may be returned in PL and PR. They are computed as follows. First we compute L and R so that P*(A, B)*Q is block diagonal, where

     P = ( I -L ) n1           Q = ( I R ) n1
         ( 0  I ) n2    and        ( 0 I ) n2
           n1 n2                    n1 n2

and (L, R) is the solution to the generalized Sylvester equation

     A11*R - L*A22 = -A12
     B11*R - L*B22 = -B12

Then PL = (F-norm(L)**2+1)**(-1/2) and PR = (F-norm(R)**2+1)**(-1/2). An approximate (asymptotic) bound on the average absolute error of the selected eigenvalues is

     EPS * norm((A, B)) / PL.

There are also global error bounds which valid for perturbations up to a certain restriction: A lower bound (x) on the smallest F-norm(E,F) for which an eigenvalue of (A11, B11) may move and coalesce with an eigenvalue of (A22, B22) under perturbation (E,F), (i.e. (A + E, B + F), is

     x = min(Difu,Difl)/((1/(PL*PL)+1/(PR*PR))**(1/2)+2*max(1/PL,1/PR)).

An approximate bound on x can be computed from DIF(1:2), PL and PR. 🦋

If y = ( F-norm(E,F) / x) <= 1, the angles between the perturbed (L', R') and unperturbed (L, R) left and right deflating subspaces associated with the selected cluster in the (1,1)-blocks can be bounded as

     max-angle(L, L') <= arctan( y * PL / (1 - y * (1 - PL * PL)**(1/2))
     max-angle(R, R') <= arctan( y * PR / (1 - y * (1 - PR * PR)**(1/2))

See LAPACK User's Guide section 4.11 or the following references for more information. 📚

Note that if the default method for computing the Frobenius-norm-based estimate DIF is not wanted (see DLATDF), then the parameter IDIFJB (see below) should be changed from 3 to 4 (routine DLATDF (IJOB = 2 will be used)). See DTGSYL for more details. 👑


Contributors: 🫶

Bo Kagstrom and Peter Poromaa, Department of Computing Science, Umea University, S-901 87 Umea, Sweden.


References: 📖

  1. B. Kagstrom; A Direct Method for Reordering Eigenvalues in the Generalized Real Schur Form of a Regular Matrix Pair (A, B), in M.S. Moonen et al (eds), Linear Algebra for Large Scale and Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.
  2. B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified Eigenvalues of a Regular Matrix Pair (A, B) and Condition Estimation: Theory, Algorithms and Software, Report UMINF - 94.04, Department of Computing Science, Umea University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working Note 87. To appear in Numerical Algorithms, 1996.
  3. B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software for Solving the Generalized Sylvester Equation and Estimating the Separation between Regular Matrix Pairs, Report UMINF - 93.23, Department of Computing Science, Umea University, S-901 87 Umea, Sweden, December 1993, Revised April 1994, Also as LAPACK Working Note 75. To appear in ACM Trans. on Math. Software, Vol 22, No 1, 1996.

DTGSJA ✨

subroutine dtgsja (character JOBU, character JOBV, character JOBQ, integer
    M, integer P, integer N, integer K, integer L, double precision,
    dimension( lda, * ) A, integer LDA, double precision, dimension( ldb, *
    ) B, integer LDB, double precision TOLA, double precision TOLB, double
    precision, dimension( * ) ALPHA, double precision, dimension( * ) BETA,
    double precision, dimension( ldu, * ) U, integer LDU, double precision,
    dimension( ldv, * ) V, integer LDV, double precision, dimension( ldq, *
    ) Q, integer LDQ, double precision, dimension( * ) WORK, integer NCYCLE,
    integer INFO)

DTGSJA 💅


Purpose: 💜

DTGSJA computes the generalized singular value decomposition (GSVD) of two real upper triangular (or trapezoidal) matrices A and B. 🔥

On entry, it is assumed that matrices A and B have the following forms, which may be obtained by the preprocessing subroutine DGGSVP from a general M-by-N matrix A and P-by-N matrix B:

              N-K-L  K    L
    A =    K ( 0    A12  A13 ) if M-K-L >= 0;
           L ( 0     0   A23 )
       M-K-L ( 0     0    0  )

        N-K-L  K    L
    A =  K ( 0    A12  A13 ) if M-K-L < 0;
       M-K ( 0     0   A23 )

        N-K-L  K    L
    B =  L ( 0     0   B13 )
       P-L ( 0     0    0  )

where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0, otherwise A23 is (M-K)-by-L upper trapezoidal. 🌈

On exit,

        U**T *A*Q = D1*( 0 R ),    V**T *B*Q = D2*( 0 R ),

where U, V and Q are orthogonal matrices. R is a nonsingular upper triangular matrix, and D1 and D2 are ``diagonal'' matrices, which are of the following structures: ⭐

If M-K-L >= 0,

                     K  L
        D1 =     K ( I  0 )
                 L ( 0  C )
             M-K-L ( 0  0 )

                   K  L
        D2 = L   ( 0  S )
             P-L ( 0  0 )

                N-K-L  K    L
   ( 0 R ) = K (  0   R11  R12 ) K
             L (  0    0   R22 ) L

where

   C = diag( ALPHA(K+1), ... , ALPHA(K+L) ),
   S = diag( BETA(K+1),  ... , BETA(K+L) ),
   C**2 + S**2 = I.

   R is stored in A(1:K+L,N-K-L+1:N) on exit.

If M-K-L < 0,

                K M-K K+L-M
     D1 =   K ( I  0    0   )
          M-K ( 0  C    0   )

                  K M-K K+L-M
     D2 =   M-K ( 0  S    0   )
          K+L-M ( 0  0    I   )
            P-L ( 0  0    0   )

                N-K-L  K   M-K  K+L-M
 ( 0 R ) =    K ( 0    R11  R12  R13  )
           M-K ( 0     0   R22  R23  )
         K+L-M ( 0     0    0   R33  )

where

 C = diag( ALPHA(K+1), ... , ALPHA(M) ),
 S = diag( BETA(K+1),  ... , BETA(M) ),
 C**2 + S**2 = I.

 R = ( R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N) and R33 is stored
     (  0  R22 R23 )
 in B(M-K+1:L,N+M-K-L+1:N) on exit.

The computation of the orthogonal transformation matrices U, V or Q is optional. These matrices may either be formed explicitly, or they may be postmultiplied into input matrices U1, V1, or Q1. 🎀


Parameters

JOBU

JOBU is CHARACTER*1 🦋

  • = 'U': U must contain an orthogonal matrix U1 on entry, and the product U1*U is returned;
  • = 'I': U is initialized to the unit matrix, and the orthogonal matrix U is returned;
  • = 'N': U is not computed.

JOBV

JOBV is CHARACTER*1 💖

  • = 'V': V must contain an orthogonal matrix V1 on entry, and the product V1*V is returned;
  • = 'I': V is initialized to the unit matrix, and the orthogonal matrix V is returned;
  • = 'N': V is not computed.
  • JOBV — bestie this one is CHARACTER*1 and it's the whole vibe check for V:
    • 'V': V has to already be holding an orthogonal matrix V1 when you walk in, and then the product V1*V is what gets returned 💫
    • 'I': V gets initialized to the unit matrix, and the orthogonal matrix V is what you get back
    • 'N': V is literally not computed. we're not doing it. periodt.
  • JOBQ — also CHARACTER*1, same energy but for Q:
    • 'Q': Q must contain an orthogonal matrix Q1 on entry, and the product Q1*Q is returned
    • 'I': Q is initialized to the unit matrix, and the orthogonal matrix Q is returned
    • 'N': Q is not computed
  • M — INTEGER. the number of rows of the matrix A. M >= 0.
  • P — INTEGER. the number of rows of the matrix B. P >= 0.
  • N — INTEGER. the number of columns of the matrices A and B. N >= 0.
  • K — INTEGER
  • L — INTEGER

K and L specify the subblocks in the input matrices A and B: A23 = A(K+1:MIN(K+L,M),N-L+1:N) and B13 = B(1:L,N-L+1:N) of A and B, whose GSVD is going to be computed by DTGSJA. See Further Details. 👀

  • A — DOUBLE PRECISION array, dimension (LDA,N). On entry, the M-by-N matrix A. On exit, A(N-K+1:N,1:MIN(K+L,M) ) contains the triangular matrix R or part of R. See Purpose for details.
  • LDA — INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • B — DOUBLE PRECISION array, dimension (LDB,N). On entry, the P-by-N matrix B. On exit, if necessary, B(M-K+1:L,N+M-K-L+1:N) contains a part of R. See Purpose for details.
  • LDB — INTEGER. The leading dimension of the array B. LDB >= max(1,P).
  • TOLA — DOUBLE PRECISION
  • TOLB — DOUBLE PRECISION

TOLA and TOLB are the convergence criteria for the Jacobi-Kogbetliantz iteration procedure. Generally, they are the same as used in the preprocessing step, say

TOLA = max(M,N)*norm(A)*MAZHEPS,
TOLB = max(P,N)*norm(B)*MAZHEPS.
  • ALPHA — DOUBLE PRECISION array, dimension (N)
  • BETA — DOUBLE PRECISION array, dimension (N)

On exit, ALPHA and BETA contain the generalized singular value pairs of A and B;

ALPHA(1:K) = 1,
BETA(1:K)  = 0,

and if M-K-L >= 0,

ALPHA(K+1:K+L) = diag(C),
BETA(K+1:K+L)  = diag(S),

or if M-K-L < 0,

ALPHA(K+1:M)= C, ALPHA(M+1:K+L)= 0
BETA(K+1:M) = S, BETA(M+1:K+L) = 1.

Furthermore, if K+L < N,

ALPHA(K+L+1:N) = 0 and
BETA(K+L+1:N)  = 0.
  • U — DOUBLE PRECISION array, dimension (LDU,M). On entry, if JOBU = 'U', U must contain a matrix U1 (usually the orthogonal matrix returned by DGGSVP). On exit, if JOBU = 'I', U contains the orthogonal matrix U; if JOBU = 'U', U contains the product U1*U. If JOBU = 'N', U is not referenced. 🚫
  • LDU — INTEGER. The leading dimension of the array U. LDU >= max(1,M) if JOBU = 'U'; LDU >= 1 otherwise.
  • V — DOUBLE PRECISION array, dimension (LDV,P). On entry, if JOBV = 'V', V must contain a matrix V1 (usually the orthogonal matrix returned by DGGSVP). On exit, if JOBV = 'I', V contains the orthogonal matrix V; if JOBV = 'V', V contains the product V1*V. If JOBV = 'N', V is not referenced.
  • LDV — INTEGER. The leading dimension of the array V. LDV >= max(1,P) if JOBV = 'V'; LDV >= 1 otherwise.
  • Q — DOUBLE PRECISION array, dimension (LDQ,N). On entry, if JOBQ = 'Q', Q must contain a matrix Q1 (usually the orthogonal matrix returned by DGGSVP). On exit, if JOBQ = 'I', Q contains the orthogonal matrix Q; if JOBQ = 'Q', Q contains the product Q1*Q. If JOBQ = 'N', Q is not referenced.
  • LDQ — INTEGER. The leading dimension of the array Q. LDQ >= max(1,N) if JOBQ = 'Q'; LDQ >= 1 otherwise.
  • WORK — DOUBLE PRECISION array, dimension (2*N)
  • NCYCLE — INTEGER. The number of cycles required for convergence. 🔁
  • INFO — INTEGER
    • = 0: successful exit 🎉
    • < 0: if INFO = -i, the i-th argument had an illegal value. 💀
    • = 1: the procedure does not converge after MAXIT cycles.

🔧 Internal Parameters 🔧

MAXIT INTEGER

MAXIT specifies the total loops that the iterative procedure may take. If after MAXIT cycles, the routine fails to converge, we return INFO = 1.


👑 Author 👑

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🌈 Further Details: 🌈

DTGSJA essentially uses a variant of Kogbetliantz algorithm to reduce min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L matrix B13 to the form:

         U1**T *A13*Q1 = C1*R1; V1**T *B13*Q1 = S1*R1,

where U1, V1 and Q1 are orthogonal matrix, and Z**T is the transpose of Z. C1 and S1 are diagonal matrices satisfying

      C1**2 + S1**2 = I,

and R1 is an L-by-L nonsingular upper triangular matrix. ✨


🦋 subroutine dtgsna 🦋

subroutine dtgsna (character JOB, character HOWMNY, logical, dimension( * )
SELECT, integer N, double precision, dimension( lda, * ) A, integer LDA,
double precision, dimension( ldb, * ) B, integer LDB, double precision,
dimension( ldvl, * ) VL, integer LDVL, double precision, dimension(
ldvr, * ) VR, integer LDVR, double precision, dimension( * ) S, double
precision, dimension( * ) DIF, integer MM, integer M, double precision,
dimension( * ) WORK, integer LWORK, integer, dimension( * ) IWORK,
integer INFO)

DTGSNA

✨ Purpose ✨

DTGSNA estimates reciprocal condition numbers for specified eigenvalues and/or eigenvectors of a matrix pair (A, B) in generalized real Schur canonical form (or of any matrix pair (Q*A*Z**T, Q*B*Z**T) with orthogonal matrices Q and Z, where Z**T denotes the transpose of Z.

(A, B) must be in generalized real Schur form (as returned by DGGES), i.e. A is block upper triangular with 1-by-1 and 2-by-2 diagonal blocks. B is upper triangular. 🧠

💅 Parameters 💅

  • JOB — CHARACTER*1. Specifies whether condition numbers are required for eigenvalues (S) or eigenvectors (DIF):
    • 'E': for eigenvalues only (S);
    • 'V': for eigenvectors only (DIF);
    • 'B': for both eigenvalues and eigenvectors (S and DIF).
  • HOWMNY — CHARACTER*1
    • 'A': compute condition numbers for all eigenpairs;
    • 'S': compute condition numbers for selected eigenpairs specified by the array SELECT.
  • SELECT — LOGICAL array, dimension (N). If HOWMNY = 'S', SELECT specifies the eigenpairs for which condition numbers are required. To select condition numbers for the eigenpair corresponding to a real eigenvalue w(j), SELECT(j) must be set to .TRUE.. To select condition numbers corresponding to a complex conjugate pair of eigenvalues w(j) and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be set to .TRUE.. If HOWMNY = 'A', SELECT is not referenced.
  • N — INTEGER. The order of the square matrix pair (A, B). N >= 0.
  • A — DOUBLE PRECISION array, dimension (LDA,N). The upper quasi-triangular matrix A in the pair (A,B).
  • LDA — INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B — DOUBLE PRECISION array, dimension (LDB,N). The upper triangular matrix B in the pair (A,B).
  • LDB — INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • VL — DOUBLE PRECISION array, dimension (LDVL,M). If JOB = 'E' or 'B', VL must contain left eigenvectors of (A, B), corresponding to the eigenpairs specified by HOWMNY and SELECT. The eigenvectors must be stored in consecutive columns of VL, as returned by DTGEVC. If JOB = 'V', VL is not referenced.
  • LDVL — INTEGER. The leading dimension of the array VL. LDVL >= 1. If JOB = 'E' or 'B', LDVL >= N.
  • VR — DOUBLE PRECISION array, dimension (LDVR,M). If JOB = 'E' or 'B', VR must contain right eigenvectors of (A, B), corresponding to the eigenpairs specified by HOWMNY and SELECT. The eigenvectors must be stored in consecutive columns ov VR, as returned by DTGEVC. If JOB = 'V', VR is not referenced.
  • LDVR — INTEGER. The leading dimension of the array VR. LDVR >= 1. If JOB = 'E' or 'B', LDVR >= N.
  • S —

S

S is a DOUBLE PRECISION array, dimension (MM).

If JOB = 'E' or 'B', the reciprocal condition numbers of the selected eigenvalues, stored in consecutive elements of the array. For a complex conjugate pair of eigenvalues two consecutive elements of S are set to the same value. Thus S(j), DIF(j), and the j-th columns of VL and VR all correspond to the same eigenpair (but not in general the j-th eigenpair, unless all eigenpairs are selected). If JOB = 'V', S is not referenced. 💅

DIF

DIF is a DOUBLE PRECISION array, dimension (MM).

If JOB = 'V' or 'B', the estimated reciprocal condition numbers of the selected eigenvectors, stored in consecutive elements of the array. For a complex eigenvector two consecutive elements of DIF are set to the same value. If the eigenvalues cannot be reordered to compute DIF(j), DIF(j) is set to 0; this can only occur when the true value would be very small anyway. If JOB = 'E', DIF is not referenced. ✨

MM

MM is INTEGER.

The number of elements in the arrays S and DIF. MM >= M.

M

M is INTEGER.

The number of elements of the arrays S and DIF used to store the specified condition numbers; for each selected real eigenvalue one element is used, and for each selected complex conjugate pair of eigenvalues, two elements are used. If HOWMNY = 'A', M is set to N.

WORK

WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)).

On exit, if INFO = 0, WORK(1) returns the optimal LWORK.

LWORK

LWORK is INTEGER.

The dimension of the array WORK. LWORK >= max(1,N). If JOB = 'V' or 'B' LWORK >= 2*N*(N+2)+16.

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.

IWORK

IWORK is INTEGER array, dimension (N + 6).

If JOB = 'E', IWORK is not referenced.

INFO

INFO is INTEGER.

  • =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.

Further Details:

Okay bestie, let's get into the math because it's giving academic baddie energy. 📚✨ The reciprocal of the condition number of a generalized eigenvalue w = (a, b) is defined as

                  S(w) = (|u**TAv|**2 + |u**TBv|**2)**(1/2) / (norm(u)*norm(v))

where u and v are the left and right eigenvectors of (A, B) corresponding to w; |z| denotes the absolute value of the complex number, and norm(u) denotes the 2-norm of the vector u. The pair (a, b) corresponds to an eigenvalue w = a/b (= u**TAv/u**TBv) of the matrix pair (A, B). If both a and b equal zero, then (A B) is singular and S(I) = -1 is returned.

An approximate error bound on the chordal distance between the i-th computed generalized eigenvalue w and the corresponding exact eigenvalue lambda is

                  chord(w, lambda) <= EPS * norm(A, B) / S(I)

where EPS is the machine precision.

The reciprocal of the condition number DIF(i) of right eigenvector u and left eigenvector v corresponding to the generalized eigenvalue w is defined as follows:

a) If the i-th eigenvalue w = (a,b) is real

Suppose U and V are orthogonal transformations such that

                         U**T*(A, B)*V  = (S, T) = ( a   *  ) ( b  *  )  1
                                                   ( 0  S22 ),( 0 T22 )  n-1
                                                     1  n-1     1 n-1

Then the reciprocal condition number DIF(i) is

                           Difl((a, b), (S22, T22)) = sigma-min( Zl ),

where sigma-min(Zl) denotes the smallest singular value of the 2(n-1)-by-2(n-1) matrix

                    Zl = [ kron(a, In-1)  -kron(1, S22) ]
                         [ kron(b, In-1)  -kron(1, T22) ] .

Here In-1 is the identity matrix of size n-1. kron(X, Y) is the Kronecker product between the matrices X and Y.

Note that if the default method for computing DIF(i) is wanted (see DLATDF), then the parameter DIFDRI (see below) should be changed from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). See DTGSYL for more details.

b) If the i-th and (i+1)-th eigenvalues are complex conjugate pair,

Suppose U and V are orthogonal transformations such that

                         U**T*(A, B)*V = (S, T) = ( S11  *   ) ( T11  *  )  2
                                                  ( 0    S22 ),( 0    T22) n-2
                                                    2    n-2     2    n-2

and (S11, T11) corresponds to the complex conjugate eigenvalue pair (w, conjg(w)). There exist unitary matrices U1 and V1 such that

                  U1**T*S11*V1 = ( s11 s12 ) and U1**T*T11*V1 = ( t11 t12 )
                                 (  0  s22 )                    (  0  t22 )

where the generalized eigenvalues w = s11/t11 and conjg(w) = s22/t22.

Then the reciprocal condition number DIF(i) is bounded by

                    min( d1, max( 1, |real(s11)/real(s22)| )*d2 )

where, d1 = Difl((s11, t11), (s22, t22)) = sigma-min(Z1), where Z1 is the complex 2-by-2 matrix

                         Z1 =  [ s11  -s22 ]
                               [ t11  -t22 ],

This is done by computing (using real arithmetic) the roots of the characteristical polynomial det(Z1**T * Z1 - lambda I), where Z1**T denotes the transpose of Z1 and det(X) denotes the determinant of X.

and d2 is an upper bound on Difl((S11, T11), (S22, T22)), i.e. an upper bound on sigma-min(Z2), where Z2 is (2n-2)-by-(2n-2)

                         Z2 = [ kron(S11**T, In-2)  -kron(I2, S22) ]
                              [ kron(T11**T, In-2)  -kron(I2, T22) ]

Note that if the default method for computing DIF is wanted (see DLATDF), then the parameter DIFDRI (see below) should be changed from 3 to 4 (routine DLATDF(IJOB = 2 will be used)). See DTGSYL for more details.

For each eigenvalue/vector specified by SELECT, DIF stores a Frobenius norm-based estimate of Difl.

An approximate error bound for the i-th computed eigenvector VL(i) or VR(i) is given by

                        EPS * norm(A, B) / DIF(i).

See ref. [2-3] for more details and further references.

Contributors:

Bo Kagstrom and Peter Poromaa, Department of Computing Science, Umea University, S-901 87 Umea, Sweden.

References:

  • [1] B. Kagstrom; A Direct Method for Reordering Eigenvalues in the Generalized Real Schur Form of a Regular Matrix Pair (A, B), in M.S. Moonen et al (eds), Linear Algebra for Large Scale and Real-Time Applications, Kluwer Academic Publ. 1993, pp 195-218.
  • [2] B. Kagstrom and P. Poromaa; Computing Eigenspaces with Specified Eigenvalues of a Regular Matrix Pair (A, B) and Condition Estimation: Theory, Algorithms and Software, Report UMINF - 94.04, Department of Computing Science, Umea University, S-901 87 Umea, Sweden, 1994. Also as LAPACK Working Note 87. To appear in Numerical Algorithms, 1996.
  • [3] B. Kagstrom and P. Poromaa, LAPACK-Style Algorithms and Software for Solving the Generalized Sylvester Equation and Estimating the Separation between Regular Matrix Pairs, Report UMINF - 93.23, Department of Computing Science, Umea University, S-901 87 Umea, Sweden, December 1993, Revised April 1994, Also as LAPACK Working Note 75. To appear in ACM Trans. on Math. Software, Vol 22, No 1, 1996.

subroutine dtpcon (character NORM, character UPLO, character DIAG, integer N, double precision, dimension( * ) AP, double precision RCOND, double precision, dimension( * ) WORK, integer, dimension( * ) IWORK, integer INFO)

   subroutine dtpcon (character NORM, character UPLO, character DIAG, integer
       N, double precision, dimension( * ) AP, double precision RCOND, double
       precision, dimension( * ) WORK, integer, dimension( * ) IWORK, integer
       INFO)

DTPCON

Purpose:

DTPCON estimates the reciprocal of the condition number of a packed triangular matrix A, in either the 1-norm or the infinity-norm.

The norm of A is computed and an estimate is obtained for norm(inv(A)), then the reciprocal of the condition number is computed as

               RCOND = 1 / ( norm(A) * norm(inv(A)) ).

Parameters

  • NORM — NORM is CHARACTER*1. Specifies whether the 1-norm condition number or the infinity-norm condition number is required:
    • = '1' or 'O': 1-norm;
    • = 'I': Infinity-norm.
  • UPLO — UPLO is CHARACTER*1.
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • DIAG — DIAG is CHARACTER*1.
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n. If DIAG = 'U', the diagonal elements of A are not referenced and are assumed to be 1.
  • RCOND — RCOND is DOUBLE PRECISION. The reciprocal of the condition number of the matrix A, computed as RCOND = 1/(norm(A) * norm(inv(A))).
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N).
  • IWORK — IWORK is INTEGER array, dimension (N).
  • INFO — INFO is INTEGER.
    • = 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.

🌸 dtplqt 🌸

   subroutine dtplqt (integer M, integer N, integer L, integer MB, double
       precision, dimension( lda, * ) A, integer LDA, double precision,
       dimension( ldb, * ) B, integer LDB, double precision, dimension( ldt, *
       ) T, integer LDT, double precision, dimension( * ) WORK, integer INFO)
       DTPLQT

Purpose — okay so bestie, DTPLQT computes a blocked LQ factorization of a real 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. It's giving very structured, very ✨ deliberate ✨.

Parameters

  • M — M is INTEGER. The number of rows of the matrix B, and the order of the triangular matrix A. M >= 0. 💅
  • N — N is INTEGER. The number of columns of the matrix B. N >= 0.
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details. 👀
  • MB — MB is INTEGER. The block size to be used in the blocked QR. M >= MB >= 1.
  • A — A is DOUBLE PRECISION array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L. 🦋
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • B — B is DOUBLE PRECISION array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M).
  • T — T is DOUBLE PRECISION array, dimension (LDT,N). The lower triangular block reflectors stored in compact form as a sequence of upper triangular blocks. See Further Details. 🎀
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= MB.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MB*M).
  • INFO — INFO is INTEGER.
    • = 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. iconic lineage fr fr

Further Details

The input matrix C is a M-by-(M+N) matrix

                  C = [ A ] [ B ]

where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal matrix consisting of a M-by-(N-L) rectangular matrix B1 on left of a M-by-L upper trapezoidal matrix B2:

             [ B ] = [ B1 ] [ B2 ]
                      [ B1 ]  <- M-by-(N-L) rectangular
                      [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a M-by-M lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular. ✨

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

           [ C ] = [ A ] [ B ]
                  [ A ]  <- lower triangular M-by-M
                  [ B ]  <- M-by-N pentagonal

so that W can be represented as

           [ W ] = [ I ] [ V ]
                  [ I ]  <- identity, M-by-M
                  [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

           [ V ] = [ V1 ] [ V2 ]
                  [ V1 ] <- M-by-(N-L) rectangular
                  [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s.

The number of blocks is B = ceiling(M/MB), where each block is of order MB except for the last block, which is of order IB = M - (M-1)*MB. For each of the B blocks, a upper triangular block reflector factor is computed: T1, T2, ..., TB. The MB-by-MB (and IB-by-IB for the last block) T's are stored in the MB-by-N matrix T as

              T = [T1 T2 ... TB].

🫶 dtplqt2 🫶

   subroutine dtplqt2 (integer M, integer N, integer L, double precision,
       dimension( lda, * ) A, integer LDA, double precision, dimension( ldb, *
       ) B, integer LDB, double precision, dimension( ldt, * ) T, integer LDT,
       integer INFO)

DTPLQT2 computes a LQ factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q. lowkey the unblocked little sibling, and we love her.

Purpose — DTPLQT2 computes a LQ a factorization of a real 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. 🧚

Parameters

  • M — M is INTEGER. The total number of rows of the matrix B. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B, and the order of the triangular matrix A. N >= 0.
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details.
  • A — A is DOUBLE PRECISION array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L. 💖
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • B — B is DOUBLE PRECISION array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M).
  • T — T is DOUBLE PRECISION array, dimension (LDT,M). The N-by-N upper triangular factor T of the block reflector. See Further Details. 🌸
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,M).
  • INFO — INFO is INTEGER.
    • = 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.

Further Details

The input matrix C is a M-by-(M+N) matrix

                  C = [ A ][ B ]

where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal matrix consisting of a M-by-(N-L) rectangular matrix B1 left of a M-by-L upper trapezoidal matrix B2:

                  B = [ B1 ][ B2 ]
                      [ B1 ]  <-     M-by-(N-L) rectangular
                      [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a N-by-N lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular.

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

                  C = [ A ][ B ]
                      [ A ]  <- lower triangular M-by-M
                      [ B ]  <- M-by-N pentagonal

so that W can be represented as

                  W = [ I ][ V ]
                      [ I ]  <- identity, M-by-M
                      [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

                  W = [ V1 ][ V2 ]
                      [ V1 ] <-     M-by-(N-L) rectangular
                      [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s. The (M+N)-by-(M+N) block reflector H is then given by

                  H = I - W**T * T * W

where W^H is the conjugate transpose of W and T is the upper triangular factor of the block reflector. 🔥


👑 dtpmlqt 👑

   subroutine dtpmlqt (character SIDE, character TRANS, integer M, integer N,
       integer K, integer L, integer MB, 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)
       DTPMLQT

Purpose — DTPMQRT applies a real orthogonal matrix Q obtained from a 'triangular-pentagonal' real block reflector H to a general real matrix C, which consists of two blocks A and B. she's the applier, the main character of "now do something with that reflector".

Parameters

  • SIDE — SIDE is CHARACTER*1.
    • = 'L': apply Q or Q**T from the Left;
    • = 'R': apply Q or Q**T from the Right.
  • TRANS — TRANS is CHARACTER*1.
    • = 'N': No transpose, apply Q;
    • = 'T': Transpose, apply Q**T.
  • M — M is INTEGER. The number of rows of the matrix B. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B. N >= 0.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q.
  • L — L is INTEGER. The order of the trapezoidal part of V. K >= L >= 0. See Further Details.
  • MB — MB is INTEGER. The block size used for the storage of T. K >= MB >= 1. This must be the same value of MB used to generate T in DTPLQT. ⚠️ like, do not mix and match here bestie.
  • V — V is DOUBLE PRECISION array, dimension (LDV,K). The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by DTPLQT in B. See Further Details. 🌈
  • LDV

LDV

LDV is an INTEGER, bestie. It's the leading dimension of the array V. You need LDV >= K. 💅

T

T is a DOUBLE PRECISION array, dimension (LDT,K). These are the upper triangular factors of the block reflectors, as returned by DTPLQT, stored as a MB-by-K matrix. 🎀

LDT

LDT is an INTEGER. It's the leading dimension of the array T. You need LDT >= MB. ✨

A

A is a DOUBLE PRECISION array, dimension (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**T*C or C*Q or C*Q**T. See Further Details. 👑

LDA

LDA is an INTEGER. It's the leading dimension of the array A. If SIDE = 'L', LDA >= max(1,K); if SIDE = 'R', LDA >= max(1,M). 💖

B

B is a DOUBLE PRECISION array, dimension (LDB,N). On entry, it's the M-by-N matrix B. On exit, B gets 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 an INTEGER. It's the leading dimension of the array B. You need LDB >= max(1,M). 🦋

WORK

WORK is a DOUBLE PRECISION array. Its dimension is N*MB if SIDE = 'L', or M*MB if SIDE = 'R'. ✨

INFO

INFO is an INTEGER.

  • = 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.

💖 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 lower trapezoidal, consisting of the first L rows of a K-by-K upper triangular matrix. If L=K, V2 is lower 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 K-by-M.
    [B]

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

The real 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='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. 🎀

   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 'triangular-pentagonal' real block reflector H to a general real matrix C, which consists of two blocks A and B. 🦋

✨ Parameters ✨

SIDE

SIDE is CHARACTER*1.

  • = 'L': apply Q or Q**T from the Left; 👈
  • = 'R': apply Q or Q**T from the Right. 👉

TRANS

TRANS is CHARACTER*1.

  • = 'N': No transpose, apply Q; ✨
  • = 'T': Transpose, apply Q**T. 🔥

M

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

N

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

K

K is an INTEGER. The number of elementary reflectors whose product defines the matrix Q. 👑

L

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

NB

NB is an 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. 💅

V

V is a 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 an 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 a 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. 🎀

LDT

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

A

A is a 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 an INTEGER. The leading dimension of the array A. If SIDE = 'L', LDC >= max(1,K); if SIDE = 'R', LDC >= max(1,M). 💀

B

B is a 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 an INTEGER. The leading dimension of the array B. LDB >= max(1,M). ✨

WORK

WORK is a DOUBLE PRECISION array. The dimension of WORK is N*NB if SIDE = 'L', or M*NB if SIDE = 'R'. 🎀

INFO

INFO is an INTEGER.

  • = 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.

💖 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 real 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='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. 🎀

   subroutine dtpqrt (integer M, integer N, integer L, integer NB, double
       precision, dimension( lda, * ) A, integer LDA, double precision,
       dimension( ldb, * ) B, integer LDB, double precision, dimension( ldt, *
       ) T, integer LDT, double precision, dimension( * ) WORK, integer INFO)
       DTPQRT

🌟 Purpose 🌟

DTPQRT computes a blocked QR factorization of a real 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. 🦋

✨ Parameters ✨

M

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

N

N is an INTEGER. The number of columns of the matrix B, and the order of the triangular matrix A. N >= 0. 🌸

L

L is an INTEGER. The number of rows of the upper trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details. 🎀

NB

NB is an INTEGER. The block size to be used in the blocked QR. N >= NB >= 1. 💅

A

A is a DOUBLE PRECISION array, dimension (LDA,N). On entry, the upper triangular N-by-N matrix A. On exit, the elements on and above the diagonal of the array contain the upper triangular matrix R. 👑

LDA

LDA is an INTEGER. The leading dimension of the array A. LDA >= max(1,N). ✨

B

B is a DOUBLE PRECISION array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first M-L rows are rectangular, and the last L rows are upper trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details. 🦋

LDB

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

T

T is a DOUBLE PRECISION array, dimension (LDT,N). The upper triangular block reflectors stored in compact form as a sequence of upper triangular blocks. See Further Details. 🌸

LDT

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

WORK

WORK is a DOUBLE PRECISION array, dimension (NB*N). 💅

INFO

INFO is an INTEGER.

  • = 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.

💖 Further Details 💖

The input matrix C is a (N+M)-by-N matrix

             C = [ A ]
                 [ B ]

where A is an upper triangular N-by-N matrix, and B is M-by-N pentagonal matrix consisting of a (M-L)-by-N rectangular matrix B1 on top of a L-by-N upper trapezoidal matrix B2:

okay bestie, we're picking right back up in the middle of it, no re-intros, let's GO 💅


The upper trapezoidal matrix B2 is literally just the first L rows of an N-by-N upper triangular matrix, where 0 <= L <= MIN(M,N). So if L=0, then B is rectangular M-by-N; and if M=L=N, B is upper triangular. slay.

The matrix W stores the elementary reflectors H(i) in the i-th column below the diagonal (of A) inside the (N+M)-by-N input matrix C, like this:

                          C = [ A ]  <- upper triangular N-by-N
                              [ B ]  <- M-by-N pentagonal

so that W can be represented as

                          W = [ I ]  <- identity, N-by-N
                              [ V ]  <- M-by-N, same form as B.

So yeah — literally all the info you need for W is sitting on exit in B, which we're calling V up there. And note that V has the same form as B, bestie, which is to say:

                          V = [ V1 ] <- (M-L)-by-N rectangular
                              [ V2 ] <-     L-by-N upper trapezoidal.

The columns of V represent the vectors which define the H(i)'s. iconic tbh

The number of blocks is B = ceiling(N/NB), where each block is of order NB except for the last block, which is of order IB = N - (B-1)*NB. For each of the B blocks, a upper triangular block reflector factor is computed: T1, T2, ..., TB. The NB-by-NB (and IB-by-IB for the last block) T's are stored in the NB-by-N matrix T as

                          T = [T1 T2 ... TB].

✨ subroutine dtpqrt2 ✨

   subroutine dtpqrt2 (integer M, integer N, integer L, double precision,
       dimension( lda, * ) A, integer LDA, double precision, dimension( ldb, *
       ) B, integer LDB, double precision, dimension( ldt, * ) T, integer LDT,
       integer INFO)

DTPQRT2 computes a QR factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.

💖 Purpose 💖

DTPQRT2 computes a QR factorization of a real 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q.

🎀 Parameters 🎀

  • M — M is INTEGER. The total number of rows of the matrix B. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B, and the order of the triangular matrix A. N >= 0.
  • L — L is INTEGER. The number of rows of the upper trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details, bestie.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the upper triangular N-by-N matrix A. On exit, the elements on and above the diagonal of the array contain the upper triangular matrix R.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B — B is DOUBLE PRECISION array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first M-L rows are rectangular, and the last L rows are upper trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M).
  • T — T is DOUBLE PRECISION array, dimension (LDT,N). The N-by-N upper triangular factor T of the block reflector. See Further Details.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,N)
  • INFO — INFO is INTEGER.
    • = 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.

🌈 Further Details 🌈

The input matrix C is a (N+M)-by-N matrix

                          C = [ A ]
                              [ B ]

where A is an upper triangular N-by-N matrix, and B is M-by-N pentagonal matrix consisting of a (M-L)-by-N rectangular matrix B1 on top of a L-by-N upper trapezoidal matrix B2:

                          B = [ B1 ]  <- (M-L)-by-N rectangular
                              [ B2 ]  <-     L-by-N upper trapezoidal.

The upper trapezoidal matrix B2 consists of the first L rows of a N-by-N upper triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is upper triangular.

The matrix W stores the elementary reflectors H(i) in the i-th column below the diagonal (of A) in the (N+M)-by-N input matrix C

                          C = [ A ]  <- upper triangular N-by-N
                              [ B ]  <- M-by-N pentagonal

so that W can be represented as

                          W = [ I ]  <- identity, N-by-N
                              [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

                          V = [ V1 ] <- (M-L)-by-N rectangular
                              [ V2 ] <-     L-by-N upper trapezoidal.

The columns of V represent the vectors which define the H(i)'s. The (M+N)-by-(M+N) block reflector H is then given by

                          H = I - W * T * W**T

where W^H is the conjugate transpose of W and T is the upper triangular factor of the block reflector. no cap, that's the whole vibe of it ✨


💜 subroutine dtprfs 💜

   subroutine dtprfs (character UPLO, character TRANS, character DIAG, integer
       N, integer NRHS, double precision, dimension( * ) AP, double precision,
       dimension( ldb, * ) B, integer LDB, double precision, dimension( ldx, *
       ) X, integer LDX, double precision, dimension( * ) FERR, double
       precision, dimension( * ) BERR, double precision, dimension( * ) WORK,
       integer, dimension( * ) IWORK, integer INFO)

DTPRFS — that's the name, that's the whole title, she's lowkey mysterious like that.

🌸 Purpose 🌸

DTPRFS provides error bounds and backward error estimates for the solution to a system of linear equations with a triangular packed coefficient matrix.

The solution matrix X must be computed by DTPTRS or some other means before entering this routine. And listen — DTPRFS does not do iterative refinement, because doing so cannot improve the backward error. So don't come in here asking for a glow-up that isn't happening, bestie. 💀

🦋 Parameters 🦋

  • UPLO — UPLO is CHARACTER*1.
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • TRANS — TRANS is CHARACTER*1. Specifies the form of the system of equations:
    • = 'N': A * X = B (No transpose)
    • = 'T': A**T * X = B (Transpose)
    • = 'C': A**H * X = B (Conjugate transpose = Transpose)
  • DIAG — DIAG is CHARACTER*1.
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • NRHS — NRHS is INTEGER. The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0.
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). The upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.

If DIAG = 'U', the diagonal elements of A are not referenced and are assumed to be 1.

  • B — B is DOUBLE PRECISION array, dimension (LDB,NRHS). The right hand side matrix B.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • X — X is DOUBLE PRECISION array, dimension (LDX,NRHS). The solution matrix X.
  • LDX — LDX is INTEGER. The leading dimension of the array X. LDX >= max(1,N).
  • FERR — FERR is DOUBLE PRECISION array, dimension (NRHS). The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error. she's a little dramatic, she overshoots, we love her anyway
  • BERR — BERR is DOUBLE PRECISION array, dimension (NRHS). The componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution).
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N)
  • IWORK — IWORK is INTEGER array, dimension (N)
  • INFO — INFO is INTEGER.
    • = 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.


⭐ subroutine dtptri ⭐

   subroutine dtptri (character UPLO, character DIAG, integer N, double
       precision, dimension( * ) AP, integer INFO)

DTPTRI — she's here, she's serving, she inverts things.

🌟 Purpose 🌟

DTPTRI computes the inverse of a real upper or lower triangular matrix A stored in packed format.

💅 Parameters 💅

  • UPLO — UPLO is CHARACTER*1.
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • DIAG — DIAG is CHARACTER*1.
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • AP
  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2) 💜

On entry, this is your upper-or-lower triangular matrix A, bestie, stored columnwise in a linear array. The j-th column of A lives in AP like this:

  • if UPLO = 'U': AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  • if UPLO = 'L': AP(i + (j-1)*((2*n-j)/2) = A(i,j) for j<=i<=n.

Scroll down for further details, iykyk. 👀

On exit? It's the (triangular) inverse of the original matrix, in the same packed storage format. Iconic, she stayed in format. ✨

  • INFO — INTEGER 🌸
    • = 0: successful exit, we ate 💅
    • < 0: if INFO = -i, the i-th argument had an illegal value 😭
    • > 0: if INFO = i, A(i,i) is exactly zero. The triangular matrix is singular and its inverse can not be computed. No cap, that's just over. 💀

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🔎 Further Details:

A triangular matrix A can be transferred to packed storage using one of the following program segments:

UPLO = 'U':                      UPLO = 'L':

      JC = 1                           JC = 1
      DO 2 J = 1, N                    DO 2 J = 1, N
         DO 1 I = 1, J                    DO 1 I = J, N
            AP(JC+I-1) = A(I,J)              AP(JC+I-J) = A(I,J)
    1    CONTINUE                    1    CONTINUE
         JC = JC + J                      JC = JC + N - J + 1
    2 CONTINUE                       2 CONTINUE

🦋 subroutine dtptrs (character UPLO, character TRANS, character DIAG, integer N, integer NRHS, double precision, dimension( * ) AP, double precision, dimension( ldb, * ) B, integer LDB, integer INFO)

DTPTRS

Purpose:

DTPTRS solves a triangular system of the form

A * X = B  or  A**T * X = B,

where A is a triangular matrix of order N stored in packed format, and B is an N-by-NRHS matrix. A check is made to verify that A is nonsingular. She does a vibe check first, periodt. 🫶

Parameters

  • UPLO — CHARACTER*1
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • TRANS — CHARACTER*1

Specifies the form of the system of equations:

  • = 'N': A * X = B (No transpose)
  • = 'T': A**T * X = B (Transpose)
  • = 'C': A**H * X = B (Conjugate transpose = Transpose)
  • DIAG — CHARACTER*1
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — INTEGER

The order of the matrix A. N >= 0.

  • NRHS — INTEGER

The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0.

  • AP — DOUBLE PRECISION array, dimension (N*(N+1)/2) 🌸

The upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:

  • if UPLO = 'U': AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  • if UPLO = 'L': AP(i + (j-1)*(2*n-j)/2) = A(i,j) for j<=i<=n.
  • B — DOUBLE PRECISION array, dimension (LDB,NRHS) 💖

On entry, the right hand side matrix B.

On exit, if INFO = 0, the solution matrix X. The glow-up is real. ✨

  • LDB — INTEGER

The leading dimension of the array B. LDB >= max(1,N).

  • INFO — INTEGER
    • = 0: successful exit 🎀
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the i-th diagonal element of A is zero, indicating that the matrix is singular and the solutions X have not been computed. 💀

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🧚 subroutine dtpttf (character TRANSR, character UPLO, integer N, double precision, dimension( 0: * ) AP, double precision, dimension( 0: * ) ARF, integer INFO)

DTPTTF copies a triangular matrix from the standard packed format (TP) to the rectangular full packed format (TF). A whole format glow-up. 🔥

Purpose:

DTPTTF copies a triangular matrix A from standard packed format (TP) to rectangular full packed format (TF).

Parameters

  • TRANSR — CHARACTER*1
    • = 'N': ARF in Normal format is wanted;
    • = 'T': ARF in Conjugate-transpose format is wanted.
  • UPLO — CHARACTER*1
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • N — INTEGER

The order of the matrix A. N >= 0.

  • AP — DOUBLE PRECISION array, dimension ( N*(N+1)/2 ), 🌸

On entry, the upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:

  • if UPLO = 'U': AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  • if UPLO = 'L': AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  • ARF — DOUBLE PRECISION array, dimension ( N*(N+1)/2 ), 💜

On exit, the upper or lower triangular matrix A stored in RFP format. For a further discussion see Notes below. 👀

  • INFO — INTEGER
    • = 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.


Further Details:

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6.

    AP is Upper             AP is Lower

  00 01 02 03 04 05       00
     11 12 13 14 15       10 11
        22 23 24 25       20 21 22
           33 34 35       30 31 32 33
              44 45       40 41 42 43 44
                 55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows:

For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper.

For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower.

This covers the case N even and TRANSR = 'N'.

       RFP A                   RFP A

      03 04 05                33 43 53
      13 14 15                00 44 54
      23 24 25                10 11 55
      33 34 35                20 21 22
      00 44 45                30 31 32
      01 11 55                40 41 42
      02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

         RFP A                   RFP A

   03 13 23 33 00 01 02    33 00 10 20 30 40 50
   04 14 24 34 44 11 12    43 44 11 21 31 41 51
   05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. We give an example where N = 5.

   AP is Upper                 AP is Lower

 00 01 02 03 04              00
    11 12 13 14              10 11
       22 23 24              20 21 22
          33 34              30 31 32 33
             44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows:

For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper.

For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower.

This covers the case N odd and TRANSR = 'N'.

       RFP A                   RFP A

      02 03 04                00 33 43
      12 13 14                10 11 44
      22 23 24                20 21 22
      00 33 34                30 31 32
      01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

         RFP A                   RFP A

   02 12 22 00 01             00 10 20 30 40 50
   03 13 23 33 11             33 11 21 31 41 51
   04 14 24 34 44             43 44 22 32 42 52

🎀 subroutine dtpttr (character UPLO, integer N, double precision, dimension( * ) AP, double precision, dimension( lda, * ) A, integer LDA, integer INFO)

DTPTTR copies a triangular matrix from the standard packed format (TP) to the standard full format (TR). She's unpacking, bestie, and she looks amazing. 💅

Purpose:

DTPTTR copies a triangular matrix A from standard packed format (TP) to standard full format (TR).

Parameters

  • UPLO — CHARACTER*1
    • = 'U': A is upper triangular.
    • = 'L': A is lower triangular.
  • N — INTEGER

The order of the matrix A. N >= 0.

  • AP — DOUBLE PRECISION array, dimension ( N*(N+1)/2 ), 🌸

On entry, the upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:

  • if UPLO = 'U': AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
  • if UPLO = 'L': AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  • A — DOUBLE PRECISION array, dimension ( LDA, N ) 💜

On exit, the triangular matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced.

  • LDA
  • LDA — INTEGER bestie, this is the leading dimension of the array A. The vibe check here is LDA >= max(1,N), and she does not negotiate 💅
  • INFO — INTEGER, the final report card:
    • = 0: successful exit, we ate, no notes ✨
    • < 0: if INFO = -i, then the i-th argument had an illegal value — somebody showed up in the wrong outfit and we are naming names 💀

Author 🌸

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

🦋 dtrcon 🦋

subroutine dtrcon (character NORM, character UPLO, character DIAG, integer
    N, double precision, dimension( lda, * ) A, integer LDA, double
    precision RCOND, double precision, dimension( * ) WORK, integer,
    dimension( * ) IWORK, integer INFO)

DTRCON

Purpose ✨

okay so DTRCON estimates the reciprocal of the condition number of a triangular matrix A, and you get to choose whether it's the 1-norm or the infinity-norm. main character energy, pick your fighter 💜

Here's the tea: it computes the norm of A, gets itself an estimate for norm(inv(A)), and then the reciprocal of the condition number is just

RCOND = 1 / ( norm(A) * norm(inv(A)) ).

periodt. that's the whole recipe 🎀

Parameters 💅

  • NORM — NORM is CHARACTER*1. Tells us whether you want the 1-norm condition number or the infinity-norm condition number, bestie:
    • = '1' or 'O': 1-norm;
    • = 'I': Infinity-norm.
  • UPLO — UPLO is CHARACTER*1:
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • DIAG — DIAG is CHARACTER*1:
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. Rule of thumb: N >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). It's the triangular matrix A itself. So listen: if UPLO = 'U', then the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced — she's simply not invited 🚫. If UPLO = 'L', then the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced either. And if DIAG = 'U', the diagonal elements of A are also not referenced, because they're just assumed to be 1. iconic behaviour honestly 👑
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N), always.
  • RCOND — RCOND is DOUBLE PRECISION. The reciprocal of the condition number of the matrix A, computed as RCOND = 1/(norm(A) * norm(inv(A))). yes she's literally the formula, that's the whole personality 🌈
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N).
  • IWORK — IWORK is INTEGER array, dimension (N).
  • INFO — INFO is INTEGER:
    • = 0: successful exit, slay 🎉
    • < 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.

🧚 dtrevc 🧚

subroutine dtrevc (character SIDE, character HOWMNY, logical, dimension( * )
    SELECT, integer N, double precision, dimension( ldt, * ) T, integer LDT,
    double precision, dimension( ldvl, * ) VL, integer LDVL, double
    precision, dimension( ldvr, * ) VR, integer LDVR, integer MM, integer M,
    double precision, dimension( * ) WORK, integer INFO)

DTREVC

Purpose ✨

DTREVC computes some or all of the right and/or left eigenvectors of a real upper quasi-triangular matrix T. Matrices like this get produced by the Schur factorization of a real general matrix, like:

A = Q*T*Q**T, as computed by DHSEQR.

The right eigenvector x and the left eigenvector y of T that correspond to an eigenvalue w are defined by:

T*x = w*x,     (y**H)*T = w*(y**H)

where y**H means the conjugate transpose of y. And no, the eigenvalues are not an input to this routine — she reads them directly from the diagonal blocks of T, she doesn't need you to hand her anything 💅

This routine hands back the matrices X and/or Y of right and left eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an input matrix. And if Q is the orthogonal factor that reduces a matrix A to Schur form T, then Q*X and Q*Y are the matrices of right and left eigenvectors of A. so many matrices bestie, but we're keeping up 🫶

Parameters 💅

  • SIDE — SIDE is CHARACTER*1:
    • = 'R': compute right eigenvectors only;
    • = 'L': compute left eigenvectors only;
    • = 'B': compute both right and left eigenvectors.
  • HOWMNY — HOWMNY is CHARACTER*1:
    • = 'A': compute all right and/or left eigenvectors;
    • = 'B': compute all right and/or left eigenvectors, backtransformed by the matrices in VR and/or VL;
    • = 'S': compute selected right and/or left eigenvectors, as indicated by the logical array SELECT.
  • SELECT — SELECT is LOGICAL array, dimension (N). If HOWMNY = 'S', then SELECT specifies the eigenvectors to be computed. If w(j) is a real eigenvalue, the corresponding real eigenvector gets computed if SELECT(j) is .TRUE.. If w(j) and w(j+1) are the real and imaginary parts of a complex eigenvalue, the corresponding complex eigenvector gets computed if either SELECT(j) or SELECT(j+1) is .TRUE., and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to .FALSE.. Not referenced if HOWMNY = 'A' or 'B' — she's off duty then 🙈
  • N — N is INTEGER. The order of the matrix T. N >= 0.
  • T — T is DOUBLE PRECISION array, dimension (LDT,N). The upper quasi-triangular matrix T in Schur canonical form. fancy ✨
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,N).
  • VL — VL is DOUBLE PRECISION array, dimension (LDVL,MM). On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', then VL must contain an N-by-N matrix Q (usually the orthogonal matrix Q of Schur vectors returned by DHSEQR). On exit, if SIDE = 'L' or 'B', VL contains:
    • if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
    • if HOWMNY = 'B', the matrix Q*Y;
    • if HOWMNY = 'S', the left eigenvectors of T specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues.

A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns — the first holding the real part, and the second the imaginary part. Not referenced if SIDE = 'R'.

  • LDVL — LDVL is INTEGER. The leading dimension of the array VL. LDVL >= 1, and if SIDE = 'L' or 'B', then LDVL >= N.
  • VR — VR is DOUBLE PRECISION array, dimension (LDVR,MM). On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', then VR must contain an N-by-N matrix Q (usually the orthogonal matrix Q of Schur vectors returned by DHSEQR). On exit, if SIDE = 'R' or 'B', VR contains:
    • if HOWMNY = 'A', the matrix X of right eigenvectors of T;
    • if HOWMNY = 'B', the matrix Q*X;
    • if HOWMNY = 'S', the right eigenvectors of T specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues.

A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns — the first holding the real part and the second the imaginary part. Not referenced if SIDE = 'L'.

  • LDVR — LDVR is INTEGER. The leading dimension of the array VR. LDVR >= 1, and if SIDE = 'R' or 'B', then LDVR >= N.
  • MM — MM is INTEGER. The number of columns in the arrays VL and/or VR. MM >= M.
  • M — M is INTEGER. The number of columns in the arrays VL and/or VR that are actually used to store the eigenvectors. If HOWMNY = 'A' or 'B', then M is set to N. Each selected real eigenvector occupies one column, and each selected complex eigenvector occupies two columns. math is math 📐
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N).
  • INFO — INFO is INTEGER:
    • = 0: successful exit, we love to see it 🎉
    • < 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.

Further Details 🔥

The algorithm used in this program is basically backward (forward) substitution, with scaling to make the code robust against possible overflow. (yes bestie, the scaling is the whole point, she's built different 💪)

Each eigenvector is normalized so that the element of largest magnitude has magnitude 1. And here, the magnitude of a complex number (x,y) is taken to be |x| + |y|. that's the rule, no cap 🧮


🎀 dtrevc3 🎀

subroutine dtrevc3 (character SIDE, character HOWMNY, logical, dimension( *
    ) SELECT, integer N, double precision, dimension( ldt, * ) T, integer
    LDT, double precision, dimension( ldvl, * ) VL, integer LDVL, double
    precision, dimension( ldvr, * ) VR, integer LDVR, integer MM, integer M,
    double precision, dimension( * ) WORK, integer LWORK, integer INFO)

DTREVC3

Purpose ✨

DTREVC3 computes some or all of the right and/or left eigenvectors of a real upper quasi-triangular matrix T. Matrices of this type are produced by the Schur factorization of a real general matrix, like:

A = Q*T*Q**T, as computed by DHSEQR.

The right eigenvector x and the left eigenvector y of T corresponding to an eigenvalue w are defined by:

T*x = w*x,     (y**T)*T = w*(y**T)

where y**T denotes the transpose of the vector y. And once again, the eigenvalues are not input to this routine — she reads them directly from the diagonal blocks of T. she's independent, she's self-sufficient 💅

This routine returns the matrices X and/or Y of right and left eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an input matrix. If Q is the orthogonal factor that reduces a matrix A to Schur form T, then Q*X and Q*Y are the matrices of right and left eigenvectors of A.

This uses a Level 3 BLAS version of the back transformation. level 3 BLAS bestie, she's fast, she's fancy, she's the upgrade 💖

✨ Parameters ✨

  • SIDE — SIDE is CHARACTER*1, and it's literally just "which side, bestie?"
    • = 'R': compute right eigenvectors only;
    • = 'L': compute left eigenvectors only;
    • = 'B': compute both right and left eigenvectors. both sides, greedy icon behavior 💅
  • HOWMNY — HOWMNY is CHARACTER*1, aka "how many / which ones tho"
    • = 'A': compute all right and/or left eigenvectors;
    • = 'B': compute all right and/or left eigenvectors, backtransformed by the matrices in VR and/or VL;
    • = 'S': compute selected right and/or left eigenvectors, as indicated by the logical array SELECT.
  • SELECT — SELECT is LOGICAL array, dimension (N). no cap, this one's the picker 🎀
    • If HOWMNY = 'S', SELECT specifies the eigenvectors to be computed.
    • If w(j) is a real eigenvalue, the corresponding real eigenvector is computed if SELECT(j) is .TRUE..
    • If w(j) and w(j+1) are the real and imaginary parts of a complex eigenvalue, the corresponding complex eigenvector is computed if either SELECT(j) or SELECT(j+1) is .TRUE., and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is set to .FALSE..
    • Not referenced if HOWMNY = 'A' or 'B'.
  • N — N is INTEGER. The order of the matrix T. N >= 0.
  • T — T is DOUBLE PRECISION array, dimension (LDT,N). The upper quasi-triangular matrix T in Schur canonical form.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,N).
  • VL — VL is DOUBLE PRECISION array, dimension (LDVL,MM). bestie this one has layers 💖
    • On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must contain an N-by-N matrix Q (usually the orthogonal matrix Q of Schur vectors returned by DHSEQR).
    • On exit, if SIDE = 'L' or 'B', VL contains:
      • if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
      • if HOWMNY = 'B', the matrix Q*Y;
      • if HOWMNY = 'S', the left eigenvectors of T specified by SELECT, stored consecutively in the columns of VL, in the same order as their eigenvalues.
    • A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part, and the second the imaginary part.
    • Not referenced if SIDE = 'R'.
  • LDVL — LDVL is INTEGER. The leading dimension of the array VL. LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.
  • VR — VR is DOUBLE PRECISION array, dimension (LDVR,MM). the right-side twin, matching energy ✨
    • On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must contain an N-by-N matrix Q (usually the orthogonal matrix Q of Schur vectors returned by DHSEQR).
    • On exit, if SIDE = 'R' or 'B', VR contains:
      • if HOWMNY = 'A', the matrix X of right eigenvectors of T;
      • if HOWMNY = 'B', the matrix Q*X;
      • if HOWMNY = 'S', the right eigenvectors of T specified by SELECT, stored consecutively in the columns of VR, in the same order as their eigenvalues.
    • A complex eigenvector corresponding to a complex eigenvalue is stored in two consecutive columns, the first holding the real part and the second the imaginary part.
    • Not referenced if SIDE = 'L'.
  • LDVR — LDVR is INTEGER. The leading dimension of the array VR. LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
  • MM — MM is INTEGER. The number of columns in the arrays VL and/or VR. MM >= M.
  • M — M is INTEGER. The number of columns in the arrays VL and/or VR actually used to store the eigenvectors.
    • If HOWMNY = 'A' or 'B', M is set to N.
    • Each selected real eigenvector occupies one column and each selected complex eigenvector occupies two columns.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)).
  • LWORK — LWORK is INTEGER. The dimension of array WORK. LWORK >= max(1,3*N).
    • For optimum performance, LWORK >= N + 2*N*NB, where NB is the optimal blocksize.
    • If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
  • INFO — INFO is INTEGER
    • = 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.

🔥 Further Details:

The algorithm used in this program is basically backward (forward) substitution, with scaling to make the the code robust against possible overflow. (yes. "the the". we love a typo moment, we respect the typo, the typo stays 💅)

Each eigenvector is normalized so that the element of largest magnitude has magnitude 1; here the magnitude of a complex number (x,y) is taken to be |x| + |y|.


🦋 subroutine dtrexc 🦋

subroutine dtrexc (character COMPQ, integer N, double precision, dimension(
    ldt, * ) T, integer LDT, double precision, dimension( ldq, * ) Q,
    integer LDQ, integer IFST, integer ILST, double precision, dimension( *
    ) WORK, integer INFO)

✨ DTREXC ✨

🎀 Purpose:

DTREXC reorders the real Schur factorization of a real matrix A = Q*T*Q**T, so that the diagonal block of T with row index IFST is moved to row ILST.

The real Schur form T is reordered by an orthogonal similarity transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors is updated by postmultiplying it with Z.

T must be in Schur canonical form (as returned by DHSEQR), that is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block has its diagonal elements equal and its off-diagonal elements of opposite sign. no exceptions bestie, that's the shape or it's nothing

✨ Parameters ✨

  • COMPQ — COMPQ is CHARACTER*1
    • = 'V': update the matrix Q of Schur vectors;
    • = 'N': do not update Q.
  • N — N is INTEGER. The order of the matrix T. N >= 0.
    • If N == 0 arguments ILST and IFST may be any value. fr fr, anything goes, nobody's checking
  • T — T is DOUBLE PRECISION array, dimension (LDT,N)
    • On entry, the upper quasi-triangular matrix T, in Schur Schur canonical form. (another "Schur Schur". the double-tap is intentional at this point, I don't make the rules 🫶)
    • On exit, the reordered upper quasi-triangular matrix, again in Schur canonical form.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,N).
  • Q — Q is DOUBLE PRECISION array, dimension (LDQ,N)
    • On entry, if COMPQ = 'V', the matrix Q of Schur vectors.
    • On exit, if COMPQ = 'V', Q has been postmultiplied by the orthogonal transformation matrix Z which reorders T.
    • If COMPQ = 'N', Q is not referenced. ignored, ghosted, not even looked at
  • LDQ — LDQ is INTEGER. The leading dimension of the array Q. LDQ >= 1, and if COMPQ = 'V', LDQ >= max(1,N).
  • IFST — IFST is INTEGER
  • ILST — ILST is INTEGER
    • Specify the reordering of the diagonal blocks of T. The block with row index IFST is moved to row ILST, by a sequence of transpositions between adjacent blocks.
    • On exit, if IFST pointed on entry to the second row of a 2-by-2 block, it is changed to point to the first row; ILST always points to the first row of the block in its final position (which may differ from its input value by +1 or -1). 1 <= IFST <= N; 1 <= ILST <= N.
  • WORK — WORK is DOUBLE PRECISION array, dimension (N)
  • INFO — INFO is INTEGER
    • = 0: successful exit 🌸
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • = 1: two adjacent blocks were too close to swap (the problem is very ill-conditioned); T may have been partially reordered, and ILST points to the first row of the current position of the block being moved.
Heads up bestie: INFO = 1 means the problem is very ill-conditioned. T may have been partially reordered, and ILST points to the first row of the current position of the block being moved. So like… it tried. 😭

👑 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.


🦋 subroutine dtrrfs 🦋

subroutine dtrrfs (character UPLO, character TRANS, character DIAG, integer
    N, integer NRHS, double precision, dimension( lda, * ) A, integer LDA,
    double precision, dimension( ldb, * ) B, integer LDB, double precision,
    dimension( ldx, * ) X, integer LDX, double precision, dimension( * )
    FERR, double precision, dimension( * ) BERR, double precision,
    dimension( * ) WORK, integer, dimension( * ) IWORK, integer INFO)

✨ DTRRFS ✨

🎀 Purpose:

DTRRFS provides error bounds and backward error estimates for the solution to a system of linear equations with a triangular coefficient matrix.

The solution matrix X must be computed by DTRTRS or some other means before entering this routine. DTRRFS does not do iterative refinement because doing so cannot improve the backward error. it's giving "don't bother, it wouldn't help anyway"

✨ Parameters ✨

  • UPLO — UPLO is CHARACTER*1
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • TRANS — TRANS is CHARACTER*1. Specifies the form of the system of equations:
    • = 'N': A * X = B (No transpose)
    • = 'T': A**T * X = B (Transpose)
    • = 'C': A**H * X = B (Conjugate transpose = Transpose)
  • DIAG — DIAG is CHARACTER*1
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • NRHS — NRHS is INTEGER. The number of right hand sides, i.e., the number of columns of the matrices B and X. NRHS >= 0.
  • A — A
  • A — it's a DOUBLE PRECISION array, dimension (LDA,N), and it's the triangular matrix itself 💜 If UPLO = 'U', the leading N-by-N upper triangular chunk of A holds the upper triangular matrix, and the strictly lower triangular part of A is not referenced (it's just vibing, nobody's looking at it). If UPLO = 'L', the leading N-by-N lower triangular part of A holds the lower triangular matrix, and the strictly upper triangular part of A is not referenced. And if DIAG = 'U', the diagonal elements of A are also not referenced and are assumed to be 1. bestie they are simply not perceived 💅
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B — B is DOUBLE PRECISION array, dimension (LDB,NRHS). The right hand side matrix B. 🫶
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • X — X is DOUBLE PRECISION array, dimension (LDX,NRHS). The solution matrix X. ✨
  • LDX — LDX is INTEGER. The leading dimension of the array X. LDX >= max(1,N).
  • FERR — FERR is DOUBLE PRECISION array, dimension (NRHS). The estimated forward error bound for each solution vector X(j) (the j-th column of the solution matrix X). If XTRUE is the true solution corresponding to X(j), FERR(j) is an estimated upper bound for the magnitude of the largest element in (X(j) - XTRUE) divided by the magnitude of the largest element in X(j). The estimate is as reliable as the estimate for RCOND, and is almost always a slight overestimate of the true error. so it's like, an overthinker, but a useful one 🌸
  • BERR — BERR is DOUBLE PRECISION array, dimension (NRHS). The componentwise relative backward error of each solution vector X(j) (i.e., the smallest relative change in any element of A or B that makes X(j) an exact solution). iconic question honestly: how much do we gotta nudge the problem so this answer becomes perfect 🎀
  • WORK — WORK is DOUBLE PRECISION array, dimension (3*N).
  • IWORK — IWORK is INTEGER array, dimension (N).
  • INFO — INFO is INTEGER, and here's the vibe check:
= 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.


👑 subroutine dtrsen

subroutine dtrsen (character JOB, character COMPQ, logical, dimension( * )
    SELECT, integer N, double precision, dimension( ldt, * ) T, integer LDT,
    double precision, dimension( ldq, * ) Q, integer LDQ, double precision,
    dimension( * ) WR, double precision, dimension( * ) WI, integer M,
    double precision S, double precision SEP, double precision, dimension( *
    ) WORK, integer LWORK, integer, dimension( * ) IWORK, integer LIWORK,
    integer INFO)

DTRSEN — say it with me, D-T-R-S-E-N 🌈

🌟 Purpose:

DTRSEN reorders the real Schur factorization of a real matrix A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in the leading diagonal blocks of the upper quasi-triangular matrix T, and the leading columns of Q form an orthonormal basis of the corresponding right invariant subspace. it's literally rearranging the group chat so the important people are at the top 💅

Optionally the routine computes the reciprocal condition numbers of the cluster of eigenvalues and/or the invariant subspace. optional, like a good skincare step ✨

T must be in Schur canonical form (as returned by DHSEQR), that is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block has its diagonal elements equal and its off-diagonal elements of opposite sign. 🦋

🎀 Parameters

  • JOB — JOB is CHARACTER*1. Specifies whether condition numbers are required for the cluster of eigenvalues (S) or the invariant subspace (SEP):
= 'N': none;
= 'E': for eigenvalues only (S);
= 'V': for invariant subspace only (SEP);
= 'B': for both eigenvalues and invariant subspace (S and
       SEP).
  • COMPQ — COMPQ is CHARACTER*1:
= 'V': update the matrix Q of Schur vectors;
= 'N': do not update Q.
  • SELECT — SELECT is LOGICAL array, dimension (N). SELECT specifies the eigenvalues in the selected cluster. To select a real eigenvalue w(j), SELECT(j) must be set to .TRUE.. To select a complex conjugate pair of eigenvalues w(j) and w(j+1), corresponding to a 2-by-2 diagonal block, either SELECT(j) or SELECT(j+1) or both must be set to .TRUE.; a complex conjugate pair of eigenvalues must be either both included in the cluster or both excluded. no splitting up the couple, they come as a pair or not at all 💖
  • N — N is INTEGER. The order of the matrix T. N >= 0.
  • T — T is DOUBLE PRECISION array, dimension (LDT,N). On entry, the upper quasi-triangular matrix T, in Schur canonical form. On exit, T is overwritten by the reordered matrix T, again in Schur canonical form, with the selected eigenvalues in the leading diagonal blocks. 🌸
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,N).
  • Q — Q is DOUBLE PRECISION array, dimension (LDQ,N). On entry, if COMPQ = 'V', the matrix Q of Schur vectors. On exit, if COMPQ = 'V', Q has been postmultiplied by the orthogonal transformation matrix which reorders T; the leading M columns of Q form an orthonormal basis for the specified invariant subspace. If COMPQ = 'N', Q is not referenced. if you said 'N' it's not even in the room 🙈
  • LDQ — LDQ is INTEGER. The leading dimension of the array Q. LDQ >= 1; and if COMPQ = 'V', LDQ >= N.
  • WR — WR is DOUBLE PRECISION array, dimension (N).
  • WI — WI is DOUBLE PRECISION array, dimension (N). The real and imaginary parts, respectively, of the reordered eigenvalues of T. The eigenvalues are stored in the same order as on the diagonal of T, with WR(i) = T(i,i) and, if T(i:i+1,i:i+1) is a 2-by-2 diagonal block, WI(i) > 0 and WI(i+1) = -WI(i). Note that if a complex eigenvalue is sufficiently ill-conditioned, then its value may differ significantly from its value before reordering. fr fr, messy eigenvalues can come out looking different than they went in 💀
  • M — M is INTEGER. The dimension of the specified invariant subspace. 0 < = M <= N.
  • S — S is DOUBLE PRECISION. If JOB = 'E' or 'B', S is a lower bound on the reciprocal condition number for the selected cluster of eigenvalues. S cannot underestimate the true reciprocal condition number by more than a factor of sqrt(N). If M = 0 or N, S = 1. If JOB = 'N' or 'V', S is not referenced. ⭐
  • SEP — SEP is DOUBLE PRECISION. If JOB = 'V' or 'B', SEP is the estimated reciprocal condition number of the specified invariant subspace. If M = 0 or N, SEP = norm(T). If JOB = 'N' or 'E', SEP is not referenced. 🌈
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK. 🎀
  • LWORK — LWORK is INTEGER. The dimension of the array WORK.
If JOB = 'N', LWORK >= max(1,N);
if JOB = 'E', LWORK >= max(1,M*(N-M));
if JOB = 'V' or 'B', LWORK >= max(1,2*M*(N-M)).

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. the -1 thing is the "just tell me how much room I need" move, no notes ✨

  • IWORK — IWORK is INTEGER array, dimension (MAX(1,LIWORK)). On exit, if INFO = 0, IWORK(1) returns the optimal LIWORK. 🦋
  • LIWORK — LIWORK is INTEGER. The dimension of the array IWORK.
If JOB = 'N' or 'E', LIWORK >= 1;
if JOB = 'V' or 'B', LIWORK >= max(1,M*(N-M)).

If LIWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the IWORK array, returns this value as the first entry of the IWORK array, and no error message related to LIWORK is issued by XERBLA. 💜

  • INFO — INFO is INTEGER:
= 0: successful exit
< 0: if INFO = -i, the i-th argument had an illegal value
= 1: reordering of T failed because some eigenvalues are too
     close to separate (the problem is very ill-conditioned);
     T may have been partially reordered, and WR and WI
     contain the eigenvalues in the same order as in T; S and
     SEP (if requested) are set to zero.
okay the INFO = 1 case is the dramatic one: the eigenvalues were too close to tell apart, the problem is very ill-conditioned, T may have been partially reordered, and WR/WI carry the eigenvalues in the same order as in T; S and SEP (if you asked for them) get set to zero. not a full slay, more of a partial slay 😭

🫶 Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

💅 Further Details:

DTRSEN first collects the selected eigenvalues by computing an orthogonal transformation Z to move them to the top left corner of T. In other words, the selected eigenvalues are the eigenvalues of T11 in:

Z**T * T * Z = ( T11 T12 ) n1
               (  0  T22 ) n2
                  n1  n2

where N = n1+n2 and Z**T means the transpose of Z. The first n1 columns of Z span the specified invariant subspace of T. 🌸

If T has been obtained from the real Schur factorization of a matrix A = Q*T*Q**T, then the reordered real Schur factorization of A is given by A = (Q*Z)*(Z**T*T*Z)*(Q*Z)**T, and the first n1 columns of Q*Z span the corresponding invariant subspace of A. the transformation is a whole group-chat migration and it comes with you 👑

The reciprocal condition number of the average of the eigenvalues of T11 may be returned in S. S lies between 0 (very badly conditioned) and 1 (very well conditioned). It is computed as follows. First we compute R so that

                     P = ( I  R ) n1
                         ( 0  0 ) n2
                           n1 n2

okay so P is literally the projector onto the invariant subspace that vibes with T11, and R is the solution of the Sylvester equation:

T11*R - R*T22 = T12.

Let F-norm(M) be the Frobenius-norm of M and 2-norm(M) be the two-norm of M. Then S gets computed as this lower bound

(1 + F-norm(R)**2)**(-1/2)

on the reciprocal of 2-norm(P) — that's the true reciprocal condition number, bestie. And S cannot underestimate 1 / 2-norm(P) by more than a factor of sqrt(N). slay, bounded error 💅

An approximate error bound for the computed average of the eigenvalues of T11 is

EPS * norm(T) / S

where EPS is the machine precision. cute.

The reciprocal condition number of the right invariant subspace spanned by the first n1 columns of Z (or of Q*Z) comes back in SEP. And SEP is defined as the separation of T11 and T22:

sep( T11, T22 ) = sigma-min( C )

where sigma-min(C) is the smallest singular value of the n1*n2-by-n1*n2 matrix

C  = kprod( I(n2), T11 ) - kprod( transpose(T22), I(n1) )

I(m) is an m by m identity matrix, and kprod is the Kronecker product (iykyk). We estimate sigma-min(C) by the reciprocal of an estimate of the 1-norm of inverse(C). The true reciprocal 1-norm of inverse(C) cannot differ from sigma-min(C) by more than a factor of sqrt(n1*n2). fr fr, it's giving "we're approximating but we have receipts".

when SEP is small, small changes in T can cause large changes in the invariant subspace. not a drill, bestie. An approximate bound on the maximum angular error in the computed right invariant subspace is
EPS * norm(T) / SEP

🦋 dtrsna 🦋

subroutine dtrsna (character JOB, character HOWMNY, logical, dimension( * )
    SELECT, integer N, double precision, dimension( ldt, * ) T, integer LDT,
    double precision, dimension( ldvl, * ) VL, integer LDVL, double
    precision, dimension( ldvr, * ) VR, integer LDVR, double precision,
    dimension( * ) S, double precision, dimension( * ) SEP, integer MM,
    integer M, double precision, dimension( ldwork, * ) WORK, integer
    LDWORK, integer, dimension( * ) IWORK, integer INFO)

✨ Purpose ✨

DTRSNA estimates reciprocal condition numbers for specified eigenvalues and/or right eigenvectors of a real upper quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q orthogonal). 👑

T must be in Schur canonical form (as returned by DHSEQR), that is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block has its diagonal elements equal and its off-diagonal elements of opposite sign. no cap, that's the shape.

🎀 Parameters 🎀

  • JOB — JOB is CHARACTER*1. Specifies whether condition numbers are required for eigenvalues (S) or eigenvectors (SEP):
    • = 'E': for eigenvalues only (S);
    • = 'V': for eigenvectors only (SEP);
    • = 'B': for both eigenvalues and eigenvectors (S and SEP).
  • HOWMNY — HOWMNY is CHARACTER*1:
    • = 'A': compute condition numbers for all eigenpairs;
    • = 'S': compute condition numbers for selected eigenpairs specified by the array SELECT.
  • SELECT — SELECT is LOGICAL array, dimension (N). If HOWMNY = 'S', SELECT specifies the eigenpairs for which condition numbers are required. To select condition numbers for the eigenpair corresponding to a real eigenvalue w(j), SELECT(j) must be set to .TRUE.. To select condition numbers corresponding to a complex conjugate pair of eigenvalues w(j) and w(j+1), either SELECT(j) or SELECT(j+1) or both, must be set to .TRUE.. If HOWMNY = 'A', SELECT is not referenced. 🙈
  • N — N is INTEGER. The order of the matrix T. N >= 0.
  • T — T is DOUBLE PRECISION array, dimension (LDT,N). The upper quasi-triangular matrix T, in Schur canonical form.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,N).
  • VL — VL is DOUBLE PRECISION array, dimension (LDVL,M). If JOB = 'E' or 'B', VL must contain left eigenvectors of T (or of any Q*T*Q**T with Q orthogonal), corresponding to the eigenpairs specified by HOWMNY and SELECT. The eigenvectors must be stored in consecutive columns of VL, as returned by DHSEIN or DTREVC. If JOB = 'V', VL is not referenced.
  • LDVL — LDVL is INTEGER. The leading dimension of the array VL. LDVL >= 1; and if JOB = 'E' or 'B', LDVL >= N.
  • VR — VR is DOUBLE PRECISION array, dimension (LDVR,M). If JOB = 'E' or 'B', VR must contain right eigenvectors of T (or of any Q*T*Q**T with Q orthogonal), corresponding to the eigenpairs specified by HOWMNY and SELECT. The eigenvectors must be stored in consecutive columns of VR, as returned by DHSEIN or DTREVC. If JOB = 'V', VR is not referenced.
  • LDVR — LDVR is INTEGER. The leading dimension of the array VR. LDVR >= 1; and if JOB = 'E' or 'B', LDVR >= N.
  • S — S is DOUBLE PRECISION array, dimension (MM). If JOB = 'E' or 'B', the reciprocal condition numbers of the selected eigenvalues, stored in consecutive elements of the array. For a complex conjugate pair of eigenvalues two consecutive elements of S are set to the same value. Thus S(j), SEP(j), and the j-th columns of VL and VR all correspond to the same eigenpair (but not in general the j-th eigenpair, unless all eigenpairs are selected). If JOB = 'V', S is not referenced.
  • SEP — SEP is DOUBLE PRECISION array, dimension (MM). If JOB = 'V' or 'B', the estimated reciprocal condition numbers of the selected eigenvectors, stored in consecutive elements of the array. For a complex eigenvector two consecutive elements of SEP are set to the same value. If the eigenvalues cannot be reordered to compute SEP(j), SEP(j) is set to 0; this can only occur when the true value would be very small anyway. If JOB = 'E', SEP is not referenced.
  • MM — MM is INTEGER. The number of elements in the arrays S (if JOB = 'E' or 'B') and/or SEP (if JOB = 'V' or 'B'). MM >= M.
  • M — M is INTEGER. The number of elements of the arrays S and/or SEP actually used to store the estimated condition numbers. If HOWMNY = 'A', M is set to N.
  • WORK — WORK is DOUBLE PRECISION array, dimension (LDWORK,N+6). If JOB = 'E', WORK is not referenced.
  • LDWORK — LDWORK is INTEGER. The leading dimension of the array WORK. LDWORK >= 1; and if JOB = 'V' or 'B', LDWORK >= N.
  • IWORK — IWORK is INTEGER array, dimension (2*(N-1)). If JOB = 'E', IWORK is not referenced.
  • INFO — INFO is INTEGER:
    • = 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.

💜 Further Details 💜

The reciprocal of the condition number of an eigenvalue lambda is defined as

S(lambda) = |v**T*u| / (norm(u)*norm(v))

where u and v are the right and left eigenvectors of T corresponding to lambda; v**T denotes the transpose of v, and norm(u) denotes the Euclidean norm. These reciprocal condition numbers always lie between zero (very badly conditioned) and one (very well conditioned). If n = 1, S(lambda) is defined to be 1.

An approximate error bound for a computed eigenvalue W(i) is given by

EPS * norm(T) / S(i)

where EPS is the machine precision.

The reciprocal of the condition number of the right eigenvector u corresponding to lambda is defined as follows. Suppose

T = ( lambda  c  )
    (   0    T22 )

Then the reciprocal condition number is

SEP( lambda, T22 ) = sigma-min( T22 - lambda*I )

where sigma-min denotes the smallest singular value. We approximate the smallest singular value by the reciprocal of an estimate of the one-norm of the inverse of T22 - lambda*I. If n = 1, SEP(1) is defined to be abs(T(1,1)).

An approximate error bound for a computed right eigenvector VR(i) is given by

EPS * norm(T) / SEP(i)

🌈 dtrti2 🌈

subroutine dtrti2 (character UPLO, character DIAG, integer N, double
    precision, dimension( lda, * ) A, integer LDA, integer INFO)

DTRTI2 computes the inverse of a triangular matrix (unblocked algorithm). 💅

✨ Purpose ✨

DTRTI2 computes the inverse of a real upper or lower triangular matrix.

This is the Level 2 BLAS version of the algorithm. iconic.

🎀 Parameters 🎀

  • UPLO — UPLO is CHARACTER*1. Specifies whether the matrix A is upper or lower triangular.
    • = 'U': Upper triangular
    • = 'L': Lower triangular
  • DIAG — DIAG is CHARACTER*1. Specifies whether or not the matrix A is unit triangular.
    • = 'N': Non-unit triangular
    • = 'U': Unit triangular
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the triangular matrix A. If UPLO = 'U', the leading n by n upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n by n lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. If DIAG = 'U', the diagonal elements of A are also not referenced and are assumed to be 1.
  • A — so on exit? Yeah bestie, this array gets overwritten with the (triangular) inverse of the original matrix, sitting in the same storage format. No cap, it's giving glow-up. 💅
  • LDA — LDA is INTEGER. It's the leading dimension of the array A, and the rule is LDA >= max(1,N). Respect the dimension, she's the main character. 👑
  • INFO — INFO is INTEGER, and here's the vibe check:
    • = 0: successful exit, we ate. ✨
    • < 0: if INFO = -k, then the k-th argument had an illegal value. Not the move. 💀

📜 Author 📜

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

🦋 dtrtri 🦋

subroutine dtrtri (character UPLO, character DIAG, integer N, double
    precision, dimension( lda, * ) A, integer LDA, integer INFO)

Purpose:

DTRTRI computes the inverse of a real upper or lower triangular matrix A. 🎀

Fun fact: this is the Level 3 BLAS version of the algorithm. She's upgraded, she's efficient, she's iconic. 🔥

Parameters

  • UPLO — UPLO is CHARACTER*1, the orientation check:
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • DIAG — DIAG is CHARACTER*1, the diagonal situation:
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. And N >= 0, periodt.
  • A — A is a DOUBLE PRECISION array, dimension (LDA,N). So on entry, this is your triangular matrix A. If UPLO = 'U', then the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced (she's not even looking at it, lowkey ignoring it 💅). If UPLO = 'L', then the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. And if DIAG = 'U', the diagonal elements of A are also not referenced and are just assumed to be 1.

On exit, the (triangular) inverse of the original matrix, in the same storage format. The transformation is real, bestie. 🦋

  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • INFO — INFO is INTEGER:
    • = 0: successful exit ✨
    • < 0: if INFO = -i, the i-th argument had an illegal value 🙈
    • > 0: if INFO = i, then A(i,i) is exactly zero. The triangular matrix is singular and its inverse can not be computed. That's the plot twist nobody wanted. 😭

Author

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

🌈 dtrtrs 🌈

subroutine dtrtrs (character UPLO, character TRANS, character DIAG, integer
    N, integer NRHS, double precision, dimension( lda, * ) A, integer LDA,
    double precision, dimension( ldb, * ) B, integer LDB, integer INFO)

Purpose:

DTRTRS solves a triangular system of the form

   A * X = B  or  A**T * X = B,

where A is a triangular matrix of order N, and B is an N-by-NRHS matrix. And yes, a check is made to verify that A is nonsingular — she does her homework before answering, fr fr. 📝

Parameters

  • UPLO — UPLO is CHARACTER*1:
    • = 'U': A is upper triangular;
    • = 'L': A is lower triangular.
  • TRANS — TRANS is CHARACTER*1. Specifies the form of the system of equations:
    • = 'N': A * X = B (No transpose)
    • = 'T': A**T * X = B (Transpose)
    • = 'C': A**H * X = B (Conjugate transpose = Transpose)
  • DIAG — DIAG is CHARACTER*1:
    • = 'N': A is non-unit triangular;
    • = 'U': A is unit triangular.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • NRHS — NRHS is INTEGER. The number of right hand sides, i.e., the number of columns of the matrix B. NRHS >= 0. So many right-hand sides, so many vibes. 🎀
  • A — A is a DOUBLE PRECISION array, dimension (LDA,N). The triangular matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced. And if DIAG = 'U', the diagonal elements of A are also not referenced and are assumed to be 1. ✨
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • B — B is a DOUBLE PRECISION array, dimension (LDB,NRHS).
    • On entry, the right hand side matrix B.
    • On exit, if INFO = 0, the solution matrix X. She solved it, she's the moment. 💅
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,N).
  • INFO — INFO is INTEGER:
    • = 0: successful exit
    • < 0: if INFO = -i, the i-th argument had an illegal value
    • > 0: if INFO = i, the i-th diagonal element of A is zero, indicating that the matrix is singular and the solutions X have not been computed. Empty handed, bestie. 😭

Author

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

🧚 dtrttf 🧚

subroutine dtrttf (character TRANSR, character UPLO, integer N, double
    precision, dimension( 0: lda-1, 0: * ) A, integer LDA, double precision,
    dimension( 0: * ) ARF, integer INFO)

DTRTTF copies a triangular matrix from the standard full format (TR) to the rectangular full packed format (TF). It's a whole repackage-and-slay situation. 🎁

Purpose:

DTRTTF copies a triangular matrix A from standard full format (TR) to rectangular full packed format (TF). Periodt. ✨

Parameters

  • TRANSR — TRANSR is CHARACTER*1:
    • = 'N': ARF in Normal form is wanted;
    • = 'T': ARF in Transpose form is wanted.
  • UPLO — UPLO is CHARACTER*1:
    • = 'U': Upper triangle of A is stored;
    • = 'L': Lower triangle of A is stored.
  • N — N is INTEGER. The order of the matrix A. N >= 0.
  • A — A is a DOUBLE PRECISION array, dimension (LDA,N). On entry, the triangular matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of the array A contains the upper triangular matrix, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of the array A contains the lower triangular matrix, and the strictly upper triangular part of A is not referenced.
  • LDA — LDA is INTEGER. The leading dimension of the matrix A. LDA >= max(1,N).
  • ARF — ARF is a DOUBLE PRECISION array, dimension (NT). Here NT=N*(N+1)/2. On exit, the triangular matrix A in RFP format. She's packed, she's rectangular, she's ready. 🦋
  • INFO — INFO is INTEGER:
    • = 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.

🔍 Further Details: 🔍

Okay bestie, sit down, this is the part where we actually explain the format. 🍓

We first consider Rectangular Full Packed (RFP) Format when N is even. We give an example where N = 6.

    AP is Upper             AP is Lower

  00 01 02 03 04 05       00
     11 12 13 14 15       10 11
        22 23 24 25       20 21 22
           33 34 35       30 31 32 33
              44 45       40 41 42 43 44
                 55       50 51 52 53 54 55

Let TRANSR = 'N'. RFP holds AP as follows: For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last three columns of AP upper. The lower triangle A(4:6,0:2) consists of the transpose of the first three columns of AP upper. For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first three columns of AP lower. The upper triangle A(0:2,0:2) consists of the transpose of the last three columns of AP lower. This covers the case N even and TRANSR = 'N'.

       RFP A                   RFP A

      03 04 05                33 43 53
      13 14 15                00 44 54
      23 24 25                10 11 55
      33 34 35                20 21 22
      00 44 45                30 31 32
      01 11 55                40 41 42
      02 12 22                50 51 52

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

         RFP A                   RFP A

   03 13 23 33 00 01 02    33 00 10 20 30 40 50
   04 14 24 34 44 11 12    43 44 11 21 31 41 51
   05 15 25 35 45 55 22    53 54 55 22 32 42 52

We then consider Rectangular Full Packed (RFP) Format when N is odd. We give an example where N = 5.

   AP is Upper                 AP is Lower

 00 01 02 03 04              00
    11 12 13 14              10 11
       22 23 24              20 21 22
          33 34              30 31 32 33
             44              40 41 42 43 44

Let TRANSR = 'N'. RFP holds AP as follows: For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last three columns of AP upper. The lower triangle A(3:4,0:1) consists of the transpose of the first two columns of AP upper. For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first three columns of AP lower. The upper triangle A(0:1,1:2) consists of the transpose of the last two columns of AP lower. This covers the case N odd and TRANSR = 'N'.

       RFP A                   RFP A

      02 03 04                00 33 43
      12 13 14                10 11 44
      22 23 24                20 21 22
      00 33 34                30 31 32
      01 11 44                40 41 42

Now let TRANSR = 'T'. RFP A in both UPLO cases is just the transpose of RFP A above. One therefore gets:

         RFP A                   RFP A

   02 12 22 00 01             00 10 20 30 40 50
   03 13 23 33 11             33 11 21 31 41 51
   04 14 24 34 44             43 44 22 32 42 52

And that's the whole packed-format saga, bestie. No cap, it's a lot, but you got this. 💜

🦋 dtrttp — TR ➡️ TP, the glow-up 💅

subroutine dtrttp (character UPLO, integer N, double precision, dimension(
    lda, * ) A, integer LDA, double precision, dimension( * ) AP, integer
    INFO)

DTRTTP copies a triangular matrix from the standard full format (TR) to the standard packed format (TP). no cap, that's literally the whole job 🫶

Purpose:

DTRTTP copies a triangular matrix A from full format (TR) to standard packed format (TP).

Parameters

  • UPLO — UPLO is CHARACTER*1
    • = 'U': A is upper triangular.
    • = 'L': A is lower triangular.
  • N — N is INTEGER. The order of the matrices AP and A. N >= 0.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On exit, the triangular matrix A. If UPLO = 'U', the leading N-by-N upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading N-by-N lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. (so like, half of A is just vibing, untouched, main character of its own lane 🌸)
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,N).
  • AP — AP is DOUBLE PRECISION array, dimension (N*(N+1)/2). On exit, the upper or lower triangular matrix A, packed columnwise in a linear array. The j-th column of A is stored in the array AP as follows:
    • if UPLO = 'U', AP(i + (j-1)*j/2) = A(i,j) for 1<=i<=j;
    • if UPLO = 'L', AP(i + (j-1)*(2n-j)/2) = A(i,j) for j<=i<=n.
  • INFO — INFO is INTEGER
    • = 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.

🔥 dtzrzf — upper trapezoidal ➡️ upper triangular, the transformation arc

subroutine dtzrzf (integer M, integer N, double precision, dimension( lda, *
    ) A, integer LDA, double precision, dimension( * ) TAU, double
    precision, dimension( * ) WORK, integer LWORK, integer INFO)

DTZRZF (that's the whole NAME, bestie, it said everything it needed to say 😌)

Purpose:

DTZRZF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A to upper triangular form by means of orthogonal transformations.

The upper trapezoidal matrix A is factored as

A = ( R  0 ) * Z,

where Z is an N-by-N orthogonal matrix and R is an M-by-M upper triangular matrix.

Parameters

  • M — M is INTEGER. The number of rows of the matrix A. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix A. N >= M.
  • A — A is DOUBLE PRECISION array, dimension (LDA,N). On entry, the leading M-by-N upper trapezoidal part of the array A must contain the matrix to be factorized. On exit, the leading M-by-M upper triangular part of A contains the upper triangular matrix R, and elements M+1 to N of the first M rows of A, with the array TAU, represent the orthogonal matrix Z as a product of M elementary reflectors. it's giving before-and-after pic 📸
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • TAU — TAU is DOUBLE PRECISION array, dimension (M). The scalar factors of the elementary reflectors.
  • WORK — WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)). On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
  • LWORK — LWORK is INTEGER. The dimension of the array WORK. LWORK >= max(1,M). For optimum performance LWORK >= M*NB, where NB is the optimal blocksize.

If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA. (yes queen, ask for the size, no drama, no yelling 🔇)

  • INFO — INFO is INTEGER
    • = 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.

Contributors:

  • A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

Further Details:

The N-by-N matrix Z can be computed by

   Z =  Z(1)*Z(2)* ... *Z(M)

where each N-by-N Z(k) is given by

   Z(k) = I - tau(k)*v(k)*v(k)**T

with v(k) is the kth row vector of the M-by-N matrix

   V = ( I   A(:,M+1:N) )

I is the M-by-M identity matrix, A(:,M+1:N) is the output stored in A on exit from DTZRZF, and tau(k) is the kth element of the array TAU.


🌈 stplqt — blocked LQ of a triangular-pentagonal situation ✨

subroutine stplqt (integer M, integer N, integer L, integer MB, real,
    dimension( lda, * ) A, integer LDA, real, dimension( ldb, * ) B, integer
    LDB, real, dimension( ldt, * ) T, integer LDT, real, dimension( * )
    WORK, integer INFO)

STPLQT

Purpose:

STPLQT computes a blocked LQ factorization of a real 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q.

Parameters

  • M — M is INTEGER. The number of rows of the matrix B, and the order of the triangular matrix A. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B. N >= 0.
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details.
  • MB — MB is INTEGER. The block size to be used in the blocked QR. M >= MB >= 1.
  • A — A is REAL array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M).
  • B — B is REAL array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M).
  • T — T is REAL array, dimension (LDT,N). The lower triangular block reflectors stored in compact form as a sequence of upper triangular blocks. See Further Details.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= MB.
  • WORK — WORK is REAL array, dimension (MB*M)
  • INFO — INFO is INTEGER
    • = 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.

Further Details:

     The input matrix C is a M-by-(M+N) matrix

                  C = [ A ] [ B ]

     where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal
     matrix consisting of a M-by-(N-L) rectangular matrix B1 on left of a M-by-L
     upper trapezoidal matrix B2:
             [ B ] = [ B1 ] [ B2 ]
                      [ B1 ]  <- M-by-(N-L) rectangular
                      [ B2 ]  <-     M-by-L lower trapezoidal.

     The lower trapezoidal matrix B2 consists of the first L columns of a
     M-by-M lower triangular matrix, where 0 <= L <= MIN(M,N).  If L=0,
     B is rectangular M-by-N; if M=L=N, B is lower triangular.

     The matrix W stores the elementary reflectors H(i) in the i-th row
     above the diagonal (of A) in the M-by-(M+N) input matrix C
               [ C ] = [ A ] [ B ]
                      [ A ]  <- lower triangular M-by-M
                      [ B ]  <- M-by-N pentagonal

     so that W can be represented as
               [ W ] = [ I ] [ V ]
                      [ I ]  <- identity, M-by-M
                      [ V ]  <- M-by-N, same form as B.

     Thus, all of information needed for W is contained on exit in B, which
     we call V above.  Note that V has the same form as B; that is,
               [ V ] = [ V1 ] [ V2 ]
                      [ V1 ] <- M-by-(N-L) rectangular
                      [ V2 ] <-     M-by-L lower trapezoidal.

     The rows of V represent the vectors which define the H(i)'s.

     The number of blocks is B = ceiling(M/MB), where each
     block is of order MB except for the last block, which is of order
     IB = M - (M-1)*MB.  For each of the B blocks, a upper triangular block
     reflector factor is computed: T1, T2, ..., TB.  The MB-by-MB (and IB-by-IB
     for the last block) T's are stored in the MB-by-N matrix T as

                  T = [T1 T2 ... TB].

🎀 stplqt2 — unblocked, still iconic

subroutine stplqt2 (integer M, integer N, integer L, real, dimension( lda, *
    ) A, integer LDA, real, dimension( ldb, * ) B, integer LDB, real,
    dimension( ldt, * ) T, integer LDT, integer INFO)

STPLQT2 computes a LQ factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q.

Purpose:

STPLQT2 computes a LQ a factorization of a real 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q.

Parameters

  • M — M is INTEGER. The total number of rows of the matrix B. M >= 0.
  • N — N is INTEGER. The number of columns of the matrix B, and the order of the triangular matrix A. N >= 0.
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details.
  • A —

okay so picking up right in the middle of the parameter tea for this routine, no cap:

  • A — bestie, listen A is a REAL array, dimension (LDA,M). On entry, it's the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L. slay.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M). periodt.
  • B — B is REAL array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details. iykyk.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M). no cap.
  • T — T is REAL array, dimension (LDT,M). The N-by-N upper triangular factor T of the block reflector. See Further Details. it's giving factor realness.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,M) (yes, no semicolon there, we don't make the rules).
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. so if it's negative, something went wrong, bestie.

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details:

okay this is the math tea, stay with me 💅

The input matrix C is a M-by-(M+N) matrix

C = [ A ][ B ]

where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal matrix consisting of a M-by-(N-L) rectangular matrix B1 left of a M-by-L upper trapezoidal matrix B2:

B = [ B1 ][ B2 ]
    [ B1 ]  <-     M-by-(N-L) rectangular
    [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a N-by-N lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular.

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

C = [ A ][ B ]
    [ A ]  <- lower triangular M-by-M
    [ B ]  <- M-by-N pentagonal

so that W can be represented as

W = [ I ][ V ]
    [ I ]  <- identity, M-by-M
    [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

W = [ V1 ][ V2 ]
    [ V1 ] <-     M-by-(N-L) rectangular
    [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s. The (M+N)-by-(M+N) block reflector H is then given by

H = I - W**T * T * W

where W^H is the conjugate transpose of W and T is the upper triangular factor of the block reflector. whew, math ate.


STPMLQT

okay next up, STPMLQT, let's gooo 💖

subroutine stpmlqt (character SIDE, character TRANS, integer M, integer N,
    integer K, integer L, integer MB, real, dimension( ldv, * ) V, integer
    LDV, real, dimension( ldt, * ) T, integer LDT, real, dimension( lda, * )
    A, integer LDA, real, dimension( ldb, * ) B, integer LDB, real,
    dimension( * ) WORK, integer INFO)

Purpose

STPMLQT applies a real orthogonal matrix Q obtained from a 'triangular-pentagonal' real block reflector H to a general real matrix C, which consists of two blocks A and B. so it's doing the apply thing.

Parameters

  • SIDE — SIDE is CHARACTER*1. = 'L': apply Q or Q**T from the Left; = 'R': apply Q or Q**T from the Right. pick a side, bestie.
  • TRANS — TRANS is CHARACTER*1. = 'N': No transpose, apply Q; = 'T': Transpose, apply Q**T. transpose tea.
  • M — M is INTEGER. The number of rows of the matrix B. M >= 0. no negatives allowed.
  • N — N is INTEGER. The number of columns of the matrix B. N >= 0. same.
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. so K of them.
  • L — L is INTEGER. The order of the trapezoidal part of V. K >= L >= 0. See Further Details. trapezoid vibes.
  • MB — MB is INTEGER. The block size used for the storage of T. K >= MB >= 1. This must be the same value of MB used to generate T in STPLQT. so don't mix up your MB, fr fr.
  • V — V is REAL array, dimension (LDV,K). The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by STPLQT in B. See Further Details. rows of reflectors, iconic.
  • LDV — LDV is INTEGER. The leading dimension of the array V. LDV >= K. check.
  • T — T is REAL array, dimension (LDT,K). The upper triangular factors of the block reflectors as returned by STPLQT, stored as a MB-by-K matrix. upper triangular, periodt.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= MB. yes.
  • A — A is REAL 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. overwritten, so don't need the old A.
  • LDA — LDA is INTEGER. The leading dimension of the array A. If SIDE = 'L', LDA >= max(1,K); If SIDE = 'R', LDA >= max(1,M). depends on side.
  • B — B is REAL 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. same overwrite energy.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M). check.
  • WORK — WORK is REAL array. The dimension of WORK is N*MB if SIDE = 'L', or M*MB if SIDE = 'R'. workspace, do not skip.
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. negative INFO means bad news.

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details:

okay more details, let's get into it 🦋

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 lower trapezoidal, consisting of the first L rows of a K-by-K upper triangular matrix. If L=K, V2 is lower 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 K-by-M.

[B]

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

The real 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='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.


ZTPLQT

and finally ZTPLQT, the complex cousin 💜

subroutine ztplqt (integer M, integer N, integer L, integer MB, complex*16,
    dimension( lda, * ) A, integer LDA, complex*16, dimension( ldb, * ) B,
    integer LDB, complex*16, dimension( ldt, * ) T, integer LDT, complex*16,
    dimension( * ) WORK, integer INFO)

Purpose

ZTPLQT computes a blocked LQ factorization of a complex 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. complex, so fancy.

Parameters

  • M — M is INTEGER. The number of rows of the matrix B, and the order of the triangular matrix A. M >= 0. order of A, periodt.
  • N — N is INTEGER. The number of columns of the matrix B. N >= 0. check.
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details. trapezoid again.
  • MB — MB is INTEGER. The block size to be used in the blocked QR. M >= MB >= 1. block size, don't skip.
  • A — A is COMPLEX*16 array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L. lower triangular realness.
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M). check.
  • B — B is COMPLEX*16 array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details. same pentagonal energy.
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M). check.
  • T — T is COMPLEX*16 array, dimension (LDT,N). The lower triangular block reflectors stored in compact form as a sequence of upper triangular blocks. See Further Details. compact form, cute.
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= MB. check.
  • WORK — WORK is COMPLEX*16 array, dimension (MB*M). workspace.
  • INFO — INFO is INTEGER. = 0: successful exit. < 0: if INFO = -i, the i-th argument had an illegal value. negative means bad.

Author

Univ. of Tennessee

Univ. of California Berkeley

Univ. of Colorado Denver

NAG Ltd.

Further Details:

okay final further details for this part 🌈

The input matrix C is a M-by-(M+N) matrix

C = [ A ] [ B ]

so A is a lower triangular M-by-M matrix, and B is an M-by-N pentagonal matrix made of an M-by-(N-L) rectangular matrix B1 on the left of an M-by-L upper trapezoidal matrix B2:

                     [ B ] = [ B1 ] [ B2 ]
                              [ B1 ]  <- M-by-(N-L) rectangular
                              [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a M-by-M lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular. 💅

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

                       [ C ] = [ A ] [ B ]
                              [ A ]  <- lower triangular M-by-M
                              [ B ]  <- M-by-N pentagonal

so that W can be represented as

                       [ W ] = [ I ] [ V ]
                              [ I ]  <- identity, M-by-M
                              [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

                       [ V ] = [ V1 ] [ V2 ]
                              [ V1 ] <- M-by-(N-L) rectangular
                              [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s. ✨

The number of blocks is B = ceiling(M/MB), where each block is of order MB except for the last block, which is of order IB = M - (M-1)*MB. For each of the B blocks, a upper triangular block reflector factor is computed: T1, T2, ..., TB. The MB-by-MB (and IB-by-IB for the last block) T's are stored in the MB-by-N matrix T as

                          T = [T1 T2 ... TB].

✨ subroutine ztplqt2 ✨

subroutine ztplqt2 (integer M, integer N, integer L, complex*16, dimension(
    lda, * ) A, integer LDA, complex*16, dimension( ldb, * ) B, integer LDB,
    complex*16, dimension( ldt, * ) T, integer LDT, integer INFO)

ZTPLQT2 computes a LQ factorization of a real or complex 'triangular-pentagonal' matrix, which is composed of a triangular block and a pentagonal block, using the compact WY representation for Q. 🎀

Purpose

okay so ZTPLQT2 computes an LQ factorization of a complex 'triangular-pentagonal' matrix C, which is composed of a triangular block A and pentagonal block B, using the compact WY representation for Q. it's giving math but make it fashion. 🦋

Parameters

  • M — M is INTEGER. The total number of rows of the matrix B. M >= 0. 💖
  • N — N is INTEGER. The number of columns of the matrix B, and the order of the triangular matrix A. N >= 0. ✨
  • L — L is INTEGER. The number of rows of the lower trapezoidal part of B. MIN(M,N) >= L >= 0. See Further Details. 🎀
  • A — A is COMPLEX*16 array, dimension (LDA,M). On entry, the lower triangular M-by-M matrix A. On exit, the elements on and below the diagonal of the array contain the lower triangular matrix L. 🦋
  • LDA — LDA is INTEGER. The leading dimension of the array A. LDA >= max(1,M). 🌸
  • B — B is COMPLEX*16 array, dimension (LDB,N). On entry, the pentagonal M-by-N matrix B. The first N-L columns are rectangular, and the last L columns are lower trapezoidal. On exit, B contains the pentagonal matrix V. See Further Details. 💅
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M). 🫶
  • T — T is COMPLEX*16 array, dimension (LDT,M). The N-by-N upper triangular factor T of the block reflector. See Further Details. 😭
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= max(1,M). 🔥
  • INFO — INFO is INTEGER. = 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.

Further Details

The input matrix C is a M-by-(M+N) matrix

                          C = [ A ][ B ]

where A is an lower triangular M-by-M matrix, and B is M-by-N pentagonal matrix consisting of a M-by-(N-L) rectangular matrix B1 left of a M-by-L upper trapezoidal matrix B2:

                          B = [ B1 ][ B2 ]
                              [ B1 ]  <-     M-by-(N-L) rectangular
                              [ B2 ]  <-     M-by-L lower trapezoidal.

The lower trapezoidal matrix B2 consists of the first L columns of a N-by-N lower triangular matrix, where 0 <= L <= MIN(M,N). If L=0, B is rectangular M-by-N; if M=L=N, B is lower triangular. 🌈

The matrix W stores the elementary reflectors H(i) in the i-th row above the diagonal (of A) in the M-by-(M+N) input matrix C

                          C = [ A ][ B ]
                              [ A ]  <- lower triangular M-by-M
                              [ B ]  <- M-by-N pentagonal

so that W can be represented as

                          W = [ I ][ V ]
                              [ I ]  <- identity, M-by-M
                              [ V ]  <- M-by-N, same form as B.

Thus, all of information needed for W is contained on exit in B, which we call V above. Note that V has the same form as B; that is,

                          W = [ V1 ][ V2 ]
                              [ V1 ] <-     M-by-(N-L) rectangular
                              [ V2 ] <-     M-by-L lower trapezoidal.

The rows of V represent the vectors which define the H(i)'s. The (M+N)-by-(M+N) block reflector H is then given by

                          H = I - W**T * T * W

where W^H is the conjugate transpose of W and T is the upper triangular factor of the block reflector. 💜


✨ subroutine ztpmlqt ✨

subroutine ztpmlqt (character SIDE, character TRANS, integer M, integer N,
    integer K, integer L, integer MB, 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)

ZTPMLQT 🔥

Purpose

ZTPMLQT applies a complex unitary matrix Q obtained from a 'triangular-pentagonal' complex block reflector H to a general complex matrix C, which consists of two blocks A and B. periodt. 💅

Parameters

  • SIDE — SIDE is CHARACTER*1. = 'L': apply Q or Q**H from the Left; = 'R': apply Q or Q**H from the Right. 💖
  • TRANS — TRANS is CHARACTER*1. = 'N': No transpose, apply Q; = 'C': Conjugate transpose, apply Q**H. ✨
  • M — M is INTEGER. The number of rows of the matrix B. M >= 0. 🎀
  • N — N is INTEGER. The number of columns of the matrix B. N >= 0. 🦋
  • K — K is INTEGER. The number of elementary reflectors whose product defines the matrix Q. 🌸
  • L — L is INTEGER. The order of the trapezoidal part of V. K >= L >= 0. See Further Details. 💅
  • MB — MB is INTEGER. The block size used for the storage of T. K >= MB >= 1. This must be the same value of MB used to generate T in ZTPLQT. 🔥
  • V — V is COMPLEX*16 array, dimension (LDV,K). The i-th row must contain the vector which defines the elementary reflector H(i), for i = 1,2,...,k, as returned by ZTPLQT in B. See Further Details. 😭
  • LDV — LDV is INTEGER. The leading dimension of the array V. LDV >= K. 🫶
  • T — T is COMPLEX*16 array, dimension (LDT,K). The upper triangular factors of the block reflectors as returned by ZTPLQT, stored as a MB-by-K matrix. 👑
  • LDT — LDT is INTEGER. The leading dimension of the array T. LDT >= MB. ⭐
  • 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. 💜
  • LDA — LDA is INTEGER. The leading dimension of the array A. If SIDE = 'L', LDA >= max(1,K); If SIDE = 'R', LDA >= max(1,M). 🌈
  • 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. 🍓
  • LDB — LDB is INTEGER. The leading dimension of the array B. LDB >= max(1,M). 🧚
  • WORK — WORK is COMPLEX*16 array. The dimension of WORK is N*MB if SIDE = 'L', or M*MB if SIDE = 'R'. 💀
  • INFO — INFO is INTEGER. = 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.

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 lower trapezoidal, consisting of the first L rows of a K-by-K upper triangular matrix. If L=K, V2 is lower 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 K-by-M.

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

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

The complex unitary 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. 💖

✨ AUTHOR ✨

This whole page? Not written by a human hand, bestie. It was Generated automatically by Doxygen for LAPACK from the source code. 🤖💖

Like, Doxygen literally read the source and spat this out. No author sat down and typed it. It's giving machine-made, still iconic. 🎀


And that's a wrap on part 58 of 58, which means you have officially read the entire page, and honestly? 👑

This was LAPACK, version 3.11.0, dated Sun Nov 27 2022, and the page you just finished is doubleOTHERcomputational(3). 🦋✨

Go forth and slay your linear algebra, bestie. No cap. 💅🌸🫶

📦 where this page comes from