1 SUBROUTINE DLARFB
( SIDE
, TRANS
, DIRECT
, STOREV
, M
, N
, K
, V
, LDV
,
2 $ T
, LDT
, C
, LDC
, WORK
, LDWORK
)
4 * -- LAPACK auxiliary routine
(version
3.1) --
5 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
8 * .. Scalar Arguments
..
9 CHARACTER DIRECT
, SIDE
, STOREV
, TRANS
10 INTEGER K
, LDC
, LDT
, LDV
, LDWORK
, M
, N
12 * .. Array Arguments
..
13 DOUBLE PRECISION C
( LDC
, * ), T
( LDT
, * ), V
( LDV
, * ),
20 * DLARFB applies a
real block reflector H or its transpose H
' to a
21 * real m by n matrix C, from either the left or the right.
26 * SIDE (input) CHARACTER*1
27 * = 'L
': apply H or H' from the Left
28 * = 'R': apply H or H
' from the Right
30 * TRANS (input) CHARACTER*1
31 * = 'N
': apply H (No transpose)
32 * = 'T
': apply H' (Transpose
)
34 * DIRECT
(input
) CHARACTER*1
35 * Indicates how H is formed from a product of elementary
37 * = 'F': H
= H
(1) H
(2) . . . H
(k
) (Forward
)
38 * = 'B': H
= H
(k
) . . . H
(2) H
(1) (Backward
)
40 * STOREV
(input
) CHARACTER*1
41 * Indicates how the vectors which define the elementary
42 * reflectors are stored
:
47 * The number of rows of the matrix C
.
50 * The number of columns of the matrix C
.
53 * The order of the matrix T
(= the number of elementary
54 * reflectors whose product defines the block reflector
).
56 * V
(input
) DOUBLE PRECISION array
, dimension
57 * (LDV
,K
) if STOREV
= 'C'
58 * (LDV
,M
) if STOREV
= 'R' and SIDE
= 'L'
59 * (LDV
,N
) if STOREV
= 'R' and SIDE
= 'R'
60 * The matrix V
. See further details
.
63 * The leading
dimension of the array V
.
64 * If STOREV
= 'C' and SIDE
= 'L', LDV
>= max
(1,M
);
65 * if STOREV
= 'C' and SIDE
= 'R', LDV
>= max
(1,N
);
66 * if STOREV
= 'R', LDV
>= K
.
68 * T
(input
) DOUBLE PRECISION array
, dimension (LDT
,K
)
69 * The triangular k by k matrix T in the representation of the
73 * The leading
dimension of the array T
. LDT
>= K
.
75 * C
(input
/output
) DOUBLE PRECISION array
, dimension (LDC
,N
)
76 * On entry
, the m by n matrix C
.
77 * On exit
, C is overwritten by H*C or H
'*C or C*H or C*H'.
80 * The leading
dimension of the array C
. LDA
>= max
(1,M
).
82 * WORK
(workspace
) DOUBLE PRECISION array
, dimension (LDWORK
,K
)
84 * LDWORK
(input
) INTEGER
85 * The leading
dimension of the array WORK
.
86 * If SIDE
= 'L', LDWORK
>= max
(1,N
);
87 * if SIDE
= 'R', LDWORK
>= max
(1,M
).
89 * =====================================================================
93 PARAMETER ( ONE
= 1.0D
+0 )
99 * .. External Functions
..
103 * .. External Subroutines
..
104 EXTERNAL DCOPY
, DGEMM
, DTRMM
106 * .. Executable Statements
..
108 * Quick
return if possible
110 IF( M
.LE
.0 .OR
. N
.LE
.0 )
113 IF( LSAME
( TRANS
, 'N' ) ) THEN
119 IF( LSAME
( STOREV
, 'C' ) ) THEN
121 IF( LSAME
( DIRECT
, 'F' ) ) THEN
123 * Let V
= ( V1
) (first K rows
)
125 * where V1 is unit lower triangular
.
127 IF( LSAME
( SIDE
, 'L' ) ) THEN
129 * Form H
* C or H
' * C where C = ( C1 )
132 * W := C' * V
= (C1
'*V1 + C2'*V2
) (stored in WORK
)
137 CALL DCOPY( N, C( J, 1 ), LDC, WORK( 1, J ), 1 )
142 CALL DTRMM( 'Right
', 'Lower
', 'No transpose
', 'Unit
', N,
143 $ K, ONE, V, LDV, WORK, LDWORK )
148 CALL DGEMM
( 'Transpose', 'No transpose', N
, K
, M
-K
,
149 $ ONE
, C
( K
+1, 1 ), LDC
, V
( K
+1, 1 ), LDV
,
150 $ ONE
, WORK
, LDWORK
)
153 * W
:= W
* T
' or W * T
155 CALL DTRMM( 'Right
', 'Upper
', TRANST, 'Non
-unit
', N, K,
156 $ ONE, T, LDT, WORK, LDWORK )
164 CALL DGEMM( 'No transpose
', 'Transpose
', M-K, N, K,
165 $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,
171 CALL DTRMM
( 'Right', 'Lower', 'Transpose', 'Unit', N
, K
,
172 $ ONE
, V
, LDV
, WORK
, LDWORK
)
178 C( J, I ) = C( J, I ) - WORK( I, J )
182 ELSE IF( LSAME( SIDE, 'R
' ) ) THEN
184 * Form C * H or C * H' where C
= ( C1 C2
)
186 * W
:= C
* V
= (C1*V1
+ C2*V2
) (stored in WORK
)
191 CALL DCOPY
( M
, C
( 1, J
), 1, WORK
( 1, J
), 1 )
196 CALL DTRMM
( 'Right', 'Lower', 'No transpose', 'Unit', M
,
197 $ K
, ONE
, V
, LDV
, WORK
, LDWORK
)
202 CALL DGEMM
( 'No transpose', 'No transpose', M
, K
, N
-K
,
203 $ ONE
, C
( 1, K
+1 ), LDC
, V
( K
+1, 1 ), LDV
,
204 $ ONE
, WORK
, LDWORK
)
207 * W
:= W
* T or W
* T
'
209 CALL DTRMM( 'Right
', 'Upper
', TRANS, 'Non
-unit
', M, K,
210 $ ONE, T, LDT, WORK, LDWORK )
218 CALL DGEMM( 'No transpose
', 'Transpose
', M, N-K, K,
219 $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,
225 CALL DTRMM
( 'Right', 'Lower', 'Transpose', 'Unit', M
, K
,
226 $ ONE
, V
, LDV
, WORK
, LDWORK
)
232 C
( I
, J
) = C
( I
, J
) - WORK
( I
, J
)
240 * ( V2
) (last K rows
)
241 * where V2 is unit upper triangular
.
243 IF( LSAME
( SIDE
, 'L' ) ) THEN
245 * Form H
* C or H
' * C where C = ( C1 )
248 * W := C' * V
= (C1
'*V1 + C2'*V2
) (stored in WORK
)
253 CALL DCOPY( N, C( M-K+J, 1 ), LDC, WORK( 1, J ), 1 )
258 CALL DTRMM( 'Right
', 'Upper
', 'No transpose
', 'Unit
', N,
259 $ K, ONE, V( M-K+1, 1 ), LDV, WORK, LDWORK )
264 CALL DGEMM
( 'Transpose', 'No transpose', N
, K
, M
-K
,
265 $ ONE
, C
, LDC
, V
, LDV
, ONE
, WORK
, LDWORK
)
268 * W
:= W
* T
' or W * T
270 CALL DTRMM( 'Right
', 'Lower
', TRANST, 'Non
-unit
', N, K,
271 $ ONE, T, LDT, WORK, LDWORK )
279 CALL DGEMM( 'No transpose
', 'Transpose
', M-K, N, K,
280 $ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )
285 CALL DTRMM
( 'Right', 'Upper', 'Transpose', 'Unit', N
, K
,
286 $ ONE
, V
( M
-K
+1, 1 ), LDV
, WORK
, LDWORK
)
292 C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )
296 ELSE IF( LSAME( SIDE, 'R
' ) ) THEN
298 * Form C * H or C * H' where C
= ( C1 C2
)
300 * W
:= C
* V
= (C1*V1
+ C2*V2
) (stored in WORK
)
305 CALL DCOPY
( M
, C
( 1, N
-K
+J
), 1, WORK
( 1, J
), 1 )
310 CALL DTRMM
( 'Right', 'Upper', 'No transpose', 'Unit', M
,
311 $ K
, ONE
, V
( N
-K
+1, 1 ), LDV
, WORK
, LDWORK
)
316 CALL DGEMM
( 'No transpose', 'No transpose', M
, K
, N
-K
,
317 $ ONE
, C
, LDC
, V
, LDV
, ONE
, WORK
, LDWORK
)
320 * W
:= W
* T or W
* T
'
322 CALL DTRMM( 'Right
', 'Lower
', TRANS, 'Non
-unit
', M, K,
323 $ ONE, T, LDT, WORK, LDWORK )
331 CALL DGEMM( 'No transpose
', 'Transpose
', M, N-K, K,
332 $ -ONE, WORK, LDWORK, V, LDV, ONE, C, LDC )
337 CALL DTRMM
( 'Right', 'Upper', 'Transpose', 'Unit', M
, K
,
338 $ ONE
, V
( N
-K
+1, 1 ), LDV
, WORK
, LDWORK
)
344 C
( I
, N
-K
+J
) = C
( I
, N
-K
+J
) - WORK
( I
, J
)
350 ELSE IF( LSAME
( STOREV
, 'R' ) ) THEN
352 IF( LSAME
( DIRECT
, 'F' ) ) THEN
354 * Let V
= ( V1 V2
) (V1
: first K columns
)
355 * where V1 is unit upper triangular
.
357 IF( LSAME
( SIDE
, 'L' ) ) THEN
359 * Form H
* C or H
' * C where C = ( C1 )
362 * W := C' * V
' = (C1'*V1
' + C2'*V2
') (stored in WORK)
367 CALL DCOPY
( N
, C
( J
, 1 ), LDC
, WORK
( 1, J
), 1 )
372 CALL DTRMM( 'Right
', 'Upper
', 'Transpose
', 'Unit
', N, K,
373 $ ONE, V, LDV, WORK, LDWORK )
378 CALL DGEMM( 'Transpose
', 'Transpose
', N, K, M-K, ONE,
379 $ C( K+1, 1 ), LDC, V( 1, K+1 ), LDV, ONE,
383 * W := W * T' or W
* T
385 CALL DTRMM
( 'Right', 'Upper', TRANST
, 'Non-unit', N
, K
,
386 $ ONE
, T
, LDT
, WORK
, LDWORK
)
392 * C2
:= C2
- V2
' * W'
394 CALL DGEMM
( 'Transpose', 'Transpose', M
-K
, N
, K
, -ONE
,
395 $ V
( 1, K
+1 ), LDV
, WORK
, LDWORK
, ONE
,
401 CALL DTRMM
( 'Right', 'Upper', 'No transpose', 'Unit', N
,
402 $ K
, ONE
, V
, LDV
, WORK
, LDWORK
)
408 C( J, I ) = C( J, I ) - WORK( I, J )
412 ELSE IF( LSAME( SIDE, 'R
' ) ) THEN
414 * Form C * H or C * H' where C
= ( C1 C2
)
416 * W
:= C
* V
' = (C1*V1' + C2*V2
') (stored in WORK)
421 CALL DCOPY( M, C( 1, J ), 1, WORK( 1, J ), 1 )
426 CALL DTRMM
( 'Right', 'Upper', 'Transpose', 'Unit', M
, K
,
427 $ ONE
, V
, LDV
, WORK
, LDWORK
)
432 CALL DGEMM( 'No transpose
', 'Transpose
', M, K, N-K,
433 $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,
434 $ ONE, WORK, LDWORK )
437 * W := W * T or W * T'
439 CALL DTRMM
( 'Right', 'Upper', TRANS
, 'Non-unit', M
, K
,
440 $ ONE
, T
, LDT
, WORK
, LDWORK
)
448 CALL DGEMM
( 'No transpose', 'No transpose', M
, N
-K
, K
,
449 $
-ONE
, WORK
, LDWORK
, V
( 1, K
+1 ), LDV
, ONE
,
455 CALL DTRMM
( 'Right', 'Upper', 'No transpose', 'Unit', M
,
456 $ K
, ONE
, V
, LDV
, WORK
, LDWORK
)
462 C
( I
, J
) = C
( I
, J
) - WORK
( I
, J
)
470 * Let V
= ( V1 V2
) (V2
: last K columns
)
471 * where V2 is unit lower triangular
.
473 IF( LSAME
( SIDE
, 'L' ) ) THEN
475 * Form H
* C or H
' * C where C = ( C1 )
478 * W := C' * V
' = (C1'*V1
' + C2'*V2
') (stored in WORK)
483 CALL DCOPY
( N
, C
( M
-K
+J
, 1 ), LDC
, WORK
( 1, J
), 1 )
488 CALL DTRMM( 'Right
', 'Lower
', 'Transpose
', 'Unit
', N, K,
489 $ ONE, V( 1, M-K+1 ), LDV, WORK, LDWORK )
494 CALL DGEMM( 'Transpose
', 'Transpose
', N, K, M-K, ONE,
495 $ C, LDC, V, LDV, ONE, WORK, LDWORK )
498 * W := W * T' or W
* T
500 CALL DTRMM
( 'Right', 'Lower', TRANST
, 'Non-unit', N
, K
,
501 $ ONE
, T
, LDT
, WORK
, LDWORK
)
507 * C1
:= C1
- V1
' * W'
509 CALL DGEMM
( 'Transpose', 'Transpose', M
-K
, N
, K
, -ONE
,
510 $ V
, LDV
, WORK
, LDWORK
, ONE
, C
, LDC
)
515 CALL DTRMM
( 'Right', 'Lower', 'No transpose', 'Unit', N
,
516 $ K
, ONE
, V
( 1, M
-K
+1 ), LDV
, WORK
, LDWORK
)
522 C( M-K+J, I ) = C( M-K+J, I ) - WORK( I, J )
526 ELSE IF( LSAME( SIDE, 'R
' ) ) THEN
528 * Form C * H or C * H' where C
= ( C1 C2
)
530 * W
:= C
* V
' = (C1*V1' + C2*V2
') (stored in WORK)
535 CALL DCOPY( M, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
540 CALL DTRMM
( 'Right', 'Lower', 'Transpose', 'Unit', M
, K
,
541 $ ONE
, V
( 1, N
-K
+1 ), LDV
, WORK
, LDWORK
)
546 CALL DGEMM( 'No transpose
', 'Transpose
', M, K, N-K,
547 $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )
550 * W := W * T or W * T'
552 CALL DTRMM
( 'Right', 'Lower', TRANS
, 'Non-unit', M
, K
,
553 $ ONE
, T
, LDT
, WORK
, LDWORK
)
561 CALL DGEMM
( 'No transpose', 'No transpose', M
, N
-K
, K
,
562 $
-ONE
, WORK
, LDWORK
, V
, LDV
, ONE
, C
, LDC
)
567 CALL DTRMM
( 'Right', 'Lower', 'No transpose', 'Unit', M
,
568 $ K
, ONE
, V
( 1, N
-K
+1 ), LDV
, WORK
, LDWORK
)
574 C
( I
, N
-K
+J
) = C
( I
, N
-K
+J
) - WORK
( I
, J
)