SRC/dlarfb_gett.f(3)
β¨ NAME β¨
okay so this is SRC/dlarfb_gett.f(3) from the Library Functions Manual β bestie, we are officially in Fortran linear-algebra territory and it's giving iconic π
π SYNOPSIS π
- Functions/Subroutines
subroutine dlarfb_gett (ident, m, n, k, t, ldt, a, lda, b, ldb, work, ldwork)DLARFB_GETT
subroutine dlarfb_gett (ident, m, n, k, t, ldt, a, lda, b, ldb, work,
ldwork)
DLARFB_GETT
π οΈ Function/Subroutine Documentation π οΈ
subroutine dlarfb_gett (character ident, integer m, integer n, integer k,
double precision, dimension( ldt, * ) t, integer ldt, double precision,
dimension( lda, * ) a, integer lda, double precision, dimension( ldb, *
) b, integer ldb, double precision, dimension( ldwork, * ) work, integer
ldwork)
DLARFB_GETT
π― Purpose π―
Okay so DLARFB_GETT applies a real Householder block reflector H from the left to a real (K+M)-by-N matrix. That matrix is made of two block matrices: an upper trapezoidal K-by-N matrix A stored in the array A, and a rectangular M-by-(N-K) matrix B stored in the array B. The block reflector H is stored in a compact WY-representation, where the elementary reflectors live in the arrays A, B, and T. See the Further Details section for the juicy continuation π
π§ Parameters π§
IDENT
IDENT is CHARACTER*1
- If
IDENT = not 'I', or not 'i', thenV1is unit lower-triangular and stored in the leftK-by-Kblock of the input matrixA. - If
IDENT = 'I' or 'i', thenV1is an identity matrix and not stored.
See the Further Details section π«Ά
M
M is INTEGER
The number of rows of the matrix B. M >= 0.
N
N is INTEGER
The number of columns of the matrices A and B. N >= 0.
K
K is INTEGER
The number or rows of the matrix A β yes, βorβ, we're keeping the original typo energy π«Ά β and K is also the order of the matrix T, i.e. the number of elementary reflectors whose product defines the block reflector. 0 <= K <= N.
T
T is DOUBLE PRECISION array, dimension (LDT,K)
The upper-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.
A
A is DOUBLE PRECISION array, dimension (LDA,N)
On entry:
- a) In the
K-by-Nupper-trapezoidal partA: input matrixA. - b) In the columns below the diagonal: columns of
V1(ones are not stored on the diagonal).
On exit:
Ais overwritten by rectangularK-by-NproductH*A.
See the Further Details section π
LDA
LDA is INTEGER
(and yes, the source text labels this line LDB β iconic typo moment π β but the leading dimension is for the array A) The leading dimension of the array A. LDA >= max(1,K).
B
B is DOUBLE PRECISION array, dimension (LDB,N)
On entry:
- a) In the
M-by-(N-K)right block: input matrixB. - b) In the
M-by-Nleft block: columns ofV2.
On exit:
Bis overwritten by rectangularM-by-NproductH*B.
See the Further Details section πΈ
LDB
LDB is INTEGER
The leading dimension of the array B. LDB >= max(1,M).
WORK
WORK is DOUBLE PRECISION array, dimension (LDWORK,max(K,N-K))
LDWORK
LDWORK is INTEGER
The leading dimension of the array WORK. LDWORK>=max(1,K).
π 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
π Further Details π
okay so we're picking up mid-function-docs, bestie β this is where the math gets its full main-character moment π
π (1) Description of the Algebraic Operation π
So A is a K-by-N matrix made of two column-block matrices: A1, which is K-by-K, and A2, which is K-by-(N-K). And B is an M-by-N matrix made of two column-block matrices: B1, which is M-by-K, and B2, which is M-by-(N-K):
A = ( A1, A2 ).
B = ( B1, B2 ).
Here's the operation, no cap:
( A_out ) := H * ( A_in ) = ( I - V * T * V**T ) * ( A_in ) =
( B_out ) ( B_in ) ( B_in )
= ( I - ( V1 ) * T * ( V1**T, V2**T ) ) * ( A_in )
( V2 ) ( B_in )
On input, ( A_in ) over ( B_in ) consists of two block columns:
( A_in ) = (( A1_in ) ( A2_in )) = (( A1_in ) ( A2_in ))
( B_in ) (( B1_in ) ( B2_in )) (( 0 ) ( B2_in )),
and the column blocks are:
A1_inis aK-by-Kupper-triangular matrix stored in the upper triangular part of the arrayA(1:K,1:K).B1_inis anM-by-Krectangular ZERO matrix and not stored.A2_inis aK-by-(N-K) rectangular matrix stored in the arrayA(1:K,K+1:N).B2_inis anM-by-(N-K) rectangular matrix stored in the arrayB(1:M,K+1:N).
Then for V:
V = ( V1 )
( V2 )
where:
- if
IDENT == 'I',V1is aK-by-Kidentity matrix, not stored; - if
IDENT != 'I',V1is aK-by-Kunit lower-triangular matrix, stored in the lower-triangular part of the arrayA(1:K,1:K)(ones are not stored),
and V2 is an M-by-K rectangular stored the array B(1:M,1:K), (because on input B1_in is a rectangular zero matrix that is not stored and the space is used to store V2).
And T is a K-by-K upper-triangular matrix stored in the array T(1:K,1:K).
On output, ( A_out ) over ( B_out ) consists of two block columns:
( A_out ) = (( A1_out ) ( A2_out ))
( B_out ) (( B1_out ) ( B2_out )),
and the column blocks are:
A1_outis aK-by-Ksquare matrix, or aK-by-Kupper-triangular matrix, ifV1is an identity matrix.AiOutis stored in the arrayA(1:K,1:K).B1_outis anM-by-Krectangular matrix stored in the arrayB(1:M,K:N).A2_outis aK-by-(N-K) rectangular matrix stored in the arrayA(1:K,K+1:N).B2_outis anM-by-(N-K) rectangular matrix stored in the arrayB(1:M,K+1:N).
The operation above can be represented as the same operation on each block column:
( A1_out ) := H * ( A1_in ) = ( I - V * T * V**T ) * ( A1_in )
( B1_out ) ( 0 ) ( 0 )
( A2_out ) := H * ( A2_in ) = ( I - V * T * V**T ) * ( A2_in )
( B2_out ) ( B2_in ) ( B2_in )
If IDENT != 'I', the computation for column block 1 is:
A1_out: = A1_in - V1*T*(V1**T)*A1_in
B1_out: = - V2*T*(V1**T)*A1_in
and the computation for column block 2, which exists if N > K, is:
A2_out: = A2_in - V1*T*( (V1**T)*A2_in + (V2**T)*B2_in )
B2_out: = B2_in - V2*T*( (V1**T)*A2_in + (V2**T)*B2_in )
If IDENT == 'I', the operation for column block 1 is:
A1_out: = A1_in - V1*T**A1_in
B1_out: = - V2*T**A1_in
and the computation for column block 2, which exists if N > K, is:
A2_out: = A2_in - T*( A2_in + (V2**T)*B2_in )
B2_out: = B2_in - V2*T*( A2_in + (V2**T)*B2_in )
π§ (2) Description of the Algorithmic Computation π§
In the first step, we compute column block 2, i.e. A2 and B2. Here, we need to use the K-by-(N-K) rectangular workspace matrix W2 that is of the same size as the matrix A2. W2 is stored in the array WORK(1:K,1:(N-K)).
In the second step, we compute column block 1, i.e. A1 and B1. Here, we need to use the K-by-K square workspace matrix W1 that is of the same size as the as the matrix A1. W1 is stored in the array WORK(1:K,1:K).
NOTE: hence, in this routine, we need the workspace arrayWORKonly of sizeWORK(1:K,1:max(K,N-K))so it can hold bothW2from the first step andW1from the second step.
π€ Case (A): V1 is unit lower-triangular, i.e. IDENT != 'I'
This case has more computations than in Case (B).
if( IDENT != 'I' ) then
if ( N > K ) then
(First Step - column block 2)
col2_(1) W2: = A2
col2_(2) W2: = (V1**T) * W2 = (unit_lower_tr_of_(A1)**T) * W2
col2_(3) W2: = W2 + (V2**T) * B2 = W2 + (B1**T) * B2
col2_(4) W2: = T * W2
col2_(5) B2: = B2 - V2 * W2 = B2 - B1 * W2
col2_(6) W2: = V1 * W2 = unit_lower_tr_of_(A1) * W2
col2_(7) A2: = A2 - W2
else
(Second Step - column block 1)
col1_(1) W1: = A1
col1_(2) W1: = (V1**T) * W1 = (unit_lower_tr_of_(A1)**T) * W1
col1_(3) W1: = T * W1
col1_(4) B1: = - V2 * W1 = - B1 * W1
col1_(5) square W1: = V1 * W1 = unit_lower_tr_of_(A1) * W1
col1_(6) square A1: = A1 - W1
end if
end if
πΈ Case (B): V1 is an identity matrix, i.e. IDENT == 'I'
This case has less computations than in Case (A).
if( IDENT == 'I' ) then
if ( N > K ) then
(First Step - column block 2)
col2_(1) W2: = A2
col2_(3) W2: = W2 + (V2**T) * B2 = W2 + (B1**T) * B2
col2_(4) W2: = T * W2
col2_(5) B2: = B2 - V2 * W2 = B2 - B1 * W2
col2_(7) A2: = A2 - W2
else
(Second Step - column block 1)
col1_(1) W1: = A1
col1_(3) W1: = T * W1
col1_(4) B1: = - V2 * W1 = - B1 * W1
col1_(6) upper-triangular_of_(A1): = A1 - W1
end if
end if
π Combined Algorithm
Combine these cases (A) and (B) together, this is the resulting algorithm:
if ( N > K ) then
(First Step - column block 2)
col2_(1) W2: = A2
if( IDENT != 'I' ) then
col2_(2) W2: = (V1**T) * W2
= (unit_lower_tr_of_(A1)**T) * W2
end if
col2_(3) W2: = W2 + (V2**T) * B2 = W2 + (B1**T) * B2]
col2_(4) W2: = T * W2
col2_(5) B2: = B2 - V2 * W2 = B2 - B1 * W2
if( IDENT != 'I' ) then
col2_(6) W2: = V1 * W2 = unit_lower_tr_of_(A1) * W2
end if
col2_(7) A2: = A2 - W2
else
(Second Step - column block 1)
col1_(1) W1: = A1
if( IDENT != 'I' ) then
col1_(2) W1: = (V1**T) * W1
= (unit_lower_tr_of_(A1)**T) * W1
end if
col1_(3) W1: = T * W1
col1_(4) B1: = - V2 * W1 = - B1 * W1
if( IDENT != 'I' ) then
col1_(5) square W1: = V1 * W1 = unit_lower_tr_of_(A1) * W1
col1_(6_a) below_diag_of_(A1): = - below_diag_of_(W1)
end if
col1_(6_b) up_tr_of_(A1): = up_tr_of_(A1) - up_tr_of_(W1)
end if
π Definition π
Definition at line 390 of file dlarfb_gett.f.
π«Ά Author π«Ά
Generated automatically by Doxygen for LAPACK from the source code.
this cutie is LAPACK Version 3.12.0, source file SRC/dlarfb_gett.f(3) β and the footer's date slot is blank, so no date to report, bestie π
π¦ where this page comes from
- arch rolling: lapack-doc 3.12.1-2 Β· custom
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms