Annotation of rpl/lapack/lapack/dlarfb.f, revision 1.8
1.1 bertrand 1: SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,
2: $ T, LDT, C, LDC, WORK, LDWORK )
3: IMPLICIT NONE
4: *
1.8 ! bertrand 5: * -- LAPACK auxiliary routine (version 3.3.1) --
1.1 bertrand 6: * -- LAPACK is a software package provided by Univ. of Tennessee, --
7: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
1.8 ! bertrand 8: * -- April 2011 --
1.1 bertrand 9: *
10: * .. Scalar Arguments ..
11: CHARACTER DIRECT, SIDE, STOREV, TRANS
12: INTEGER K, LDC, LDT, LDV, LDWORK, M, N
13: * ..
14: * .. Array Arguments ..
15: DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),
16: $ WORK( LDWORK, * )
17: * ..
18: *
19: * Purpose
20: * =======
21: *
1.8 ! bertrand 22: * DLARFB applies a real block reflector H or its transpose H**T to a
1.1 bertrand 23: * real m by n matrix C, from either the left or the right.
24: *
25: * Arguments
26: * =========
27: *
28: * SIDE (input) CHARACTER*1
1.8 ! bertrand 29: * = 'L': apply H or H**T from the Left
! 30: * = 'R': apply H or H**T from the Right
1.1 bertrand 31: *
32: * TRANS (input) CHARACTER*1
33: * = 'N': apply H (No transpose)
1.8 ! bertrand 34: * = 'T': apply H**T (Transpose)
1.1 bertrand 35: *
36: * DIRECT (input) CHARACTER*1
37: * Indicates how H is formed from a product of elementary
38: * reflectors
39: * = 'F': H = H(1) H(2) . . . H(k) (Forward)
40: * = 'B': H = H(k) . . . H(2) H(1) (Backward)
41: *
42: * STOREV (input) CHARACTER*1
43: * Indicates how the vectors which define the elementary
44: * reflectors are stored:
45: * = 'C': Columnwise
46: * = 'R': Rowwise
47: *
48: * M (input) INTEGER
49: * The number of rows of the matrix C.
50: *
51: * N (input) INTEGER
52: * The number of columns of the matrix C.
53: *
54: * K (input) INTEGER
55: * The order of the matrix T (= the number of elementary
56: * reflectors whose product defines the block reflector).
57: *
58: * V (input) DOUBLE PRECISION array, dimension
59: * (LDV,K) if STOREV = 'C'
60: * (LDV,M) if STOREV = 'R' and SIDE = 'L'
61: * (LDV,N) if STOREV = 'R' and SIDE = 'R'
1.8 ! bertrand 62: * The matrix V. See Further Details.
1.1 bertrand 63: *
64: * LDV (input) INTEGER
65: * The leading dimension of the array V.
66: * If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);
67: * if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);
68: * if STOREV = 'R', LDV >= K.
69: *
70: * T (input) DOUBLE PRECISION array, dimension (LDT,K)
71: * The triangular k by k matrix T in the representation of the
72: * block reflector.
73: *
74: * LDT (input) INTEGER
75: * The leading dimension of the array T. LDT >= K.
76: *
77: * C (input/output) DOUBLE PRECISION array, dimension (LDC,N)
78: * On entry, the m by n matrix C.
1.8 ! bertrand 79: * On exit, C is overwritten by H*C or H**T*C or C*H or C*H**T.
1.1 bertrand 80: *
81: * LDC (input) INTEGER
1.8 ! bertrand 82: * The leading dimension of the array C. LDC >= max(1,M).
1.1 bertrand 83: *
84: * WORK (workspace) DOUBLE PRECISION array, dimension (LDWORK,K)
85: *
86: * LDWORK (input) INTEGER
87: * The leading dimension of the array WORK.
88: * If SIDE = 'L', LDWORK >= max(1,N);
89: * if SIDE = 'R', LDWORK >= max(1,M).
90: *
1.8 ! bertrand 91: * Further Details
! 92: * ===============
! 93: *
! 94: * The shape of the matrix V and the storage of the vectors which define
! 95: * the H(i) is best illustrated by the following example with n = 5 and
! 96: * k = 3. The elements equal to 1 are not stored; the corresponding
! 97: * array elements are modified but restored on exit. The rest of the
! 98: * array is not used.
! 99: *
! 100: * DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':
! 101: *
! 102: * V = ( 1 ) V = ( 1 v1 v1 v1 v1 )
! 103: * ( v1 1 ) ( 1 v2 v2 v2 )
! 104: * ( v1 v2 1 ) ( 1 v3 v3 )
! 105: * ( v1 v2 v3 )
! 106: * ( v1 v2 v3 )
! 107: *
! 108: * DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':
! 109: *
! 110: * V = ( v1 v2 v3 ) V = ( v1 v1 1 )
! 111: * ( v1 v2 v3 ) ( v2 v2 v2 1 )
! 112: * ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )
! 113: * ( 1 v3 )
! 114: * ( 1 )
! 115: *
1.1 bertrand 116: * =====================================================================
117: *
118: * .. Parameters ..
119: DOUBLE PRECISION ONE
120: PARAMETER ( ONE = 1.0D+0 )
121: * ..
122: * .. Local Scalars ..
123: CHARACTER TRANST
124: INTEGER I, J, LASTV, LASTC
125: * ..
126: * .. External Functions ..
127: LOGICAL LSAME
128: INTEGER ILADLR, ILADLC
129: EXTERNAL LSAME, ILADLR, ILADLC
130: * ..
131: * .. External Subroutines ..
132: EXTERNAL DCOPY, DGEMM, DTRMM
133: * ..
134: * .. Executable Statements ..
135: *
136: * Quick return if possible
137: *
138: IF( M.LE.0 .OR. N.LE.0 )
139: $ RETURN
140: *
141: IF( LSAME( TRANS, 'N' ) ) THEN
142: TRANST = 'T'
143: ELSE
144: TRANST = 'N'
145: END IF
146: *
147: IF( LSAME( STOREV, 'C' ) ) THEN
148: *
149: IF( LSAME( DIRECT, 'F' ) ) THEN
150: *
151: * Let V = ( V1 ) (first K rows)
152: * ( V2 )
153: * where V1 is unit lower triangular.
154: *
155: IF( LSAME( SIDE, 'L' ) ) THEN
156: *
1.8 ! bertrand 157: * Form H * C or H**T * C where C = ( C1 )
! 158: * ( C2 )
1.1 bertrand 159: *
160: LASTV = MAX( K, ILADLR( M, K, V, LDV ) )
161: LASTC = ILADLC( LASTV, N, C, LDC )
162: *
1.8 ! bertrand 163: * W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)
1.1 bertrand 164: *
1.8 ! bertrand 165: * W := C1**T
1.1 bertrand 166: *
167: DO 10 J = 1, K
168: CALL DCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )
169: 10 CONTINUE
170: *
171: * W := W * V1
172: *
173: CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',
174: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
175: IF( LASTV.GT.K ) THEN
176: *
1.8 ! bertrand 177: * W := W + C2**T *V2
1.1 bertrand 178: *
179: CALL DGEMM( 'Transpose', 'No transpose',
180: $ LASTC, K, LASTV-K,
181: $ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,
182: $ ONE, WORK, LDWORK )
183: END IF
184: *
1.8 ! bertrand 185: * W := W * T**T or W * T
1.1 bertrand 186: *
187: CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit',
188: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
189: *
1.8 ! bertrand 190: * C := C - V * W**T
1.1 bertrand 191: *
192: IF( LASTV.GT.K ) THEN
193: *
1.8 ! bertrand 194: * C2 := C2 - V2 * W**T
1.1 bertrand 195: *
196: CALL DGEMM( 'No transpose', 'Transpose',
197: $ LASTV-K, LASTC, K,
198: $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,
199: $ C( K+1, 1 ), LDC )
200: END IF
201: *
1.8 ! bertrand 202: * W := W * V1**T
1.1 bertrand 203: *
204: CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',
205: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
206: *
1.8 ! bertrand 207: * C1 := C1 - W**T
1.1 bertrand 208: *
209: DO 30 J = 1, K
210: DO 20 I = 1, LASTC
211: C( J, I ) = C( J, I ) - WORK( I, J )
212: 20 CONTINUE
213: 30 CONTINUE
214: *
215: ELSE IF( LSAME( SIDE, 'R' ) ) THEN
216: *
1.8 ! bertrand 217: * Form C * H or C * H**T where C = ( C1 C2 )
1.1 bertrand 218: *
219: LASTV = MAX( K, ILADLR( N, K, V, LDV ) )
220: LASTC = ILADLR( M, LASTV, C, LDC )
221: *
222: * W := C * V = (C1*V1 + C2*V2) (stored in WORK)
223: *
224: * W := C1
225: *
226: DO 40 J = 1, K
227: CALL DCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )
228: 40 CONTINUE
229: *
230: * W := W * V1
231: *
232: CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',
233: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
234: IF( LASTV.GT.K ) THEN
235: *
236: * W := W + C2 * V2
237: *
238: CALL DGEMM( 'No transpose', 'No transpose',
239: $ LASTC, K, LASTV-K,
240: $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,
241: $ ONE, WORK, LDWORK )
242: END IF
243: *
1.8 ! bertrand 244: * W := W * T or W * T**T
1.1 bertrand 245: *
246: CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit',
247: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
248: *
1.8 ! bertrand 249: * C := C - W * V**T
1.1 bertrand 250: *
251: IF( LASTV.GT.K ) THEN
252: *
1.8 ! bertrand 253: * C2 := C2 - W * V2**T
1.1 bertrand 254: *
255: CALL DGEMM( 'No transpose', 'Transpose',
256: $ LASTC, LASTV-K, K,
257: $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,
258: $ C( 1, K+1 ), LDC )
259: END IF
260: *
1.8 ! bertrand 261: * W := W * V1**T
1.1 bertrand 262: *
263: CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',
264: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
265: *
266: * C1 := C1 - W
267: *
268: DO 60 J = 1, K
269: DO 50 I = 1, LASTC
270: C( I, J ) = C( I, J ) - WORK( I, J )
271: 50 CONTINUE
272: 60 CONTINUE
273: END IF
274: *
275: ELSE
276: *
277: * Let V = ( V1 )
278: * ( V2 ) (last K rows)
279: * where V2 is unit upper triangular.
280: *
281: IF( LSAME( SIDE, 'L' ) ) THEN
282: *
1.8 ! bertrand 283: * Form H * C or H**T * C where C = ( C1 )
! 284: * ( C2 )
1.1 bertrand 285: *
286: LASTV = MAX( K, ILADLR( M, K, V, LDV ) )
287: LASTC = ILADLC( LASTV, N, C, LDC )
288: *
1.8 ! bertrand 289: * W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)
1.1 bertrand 290: *
1.8 ! bertrand 291: * W := C2**T
1.1 bertrand 292: *
293: DO 70 J = 1, K
294: CALL DCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,
295: $ WORK( 1, J ), 1 )
296: 70 CONTINUE
297: *
298: * W := W * V2
299: *
300: CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',
301: $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,
302: $ WORK, LDWORK )
303: IF( LASTV.GT.K ) THEN
304: *
1.8 ! bertrand 305: * W := W + C1**T*V1
1.1 bertrand 306: *
307: CALL DGEMM( 'Transpose', 'No transpose',
308: $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,
309: $ ONE, WORK, LDWORK )
310: END IF
311: *
1.8 ! bertrand 312: * W := W * T**T or W * T
1.1 bertrand 313: *
314: CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit',
315: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
316: *
1.8 ! bertrand 317: * C := C - V * W**T
1.1 bertrand 318: *
319: IF( LASTV.GT.K ) THEN
320: *
1.8 ! bertrand 321: * C1 := C1 - V1 * W**T
1.1 bertrand 322: *
323: CALL DGEMM( 'No transpose', 'Transpose',
324: $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,
325: $ ONE, C, LDC )
326: END IF
327: *
1.8 ! bertrand 328: * W := W * V2**T
1.1 bertrand 329: *
330: CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',
331: $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,
332: $ WORK, LDWORK )
333: *
1.8 ! bertrand 334: * C2 := C2 - W**T
1.1 bertrand 335: *
336: DO 90 J = 1, K
337: DO 80 I = 1, LASTC
338: C( LASTV-K+J, I ) = C( LASTV-K+J, I ) - WORK(I, J)
339: 80 CONTINUE
340: 90 CONTINUE
341: *
342: ELSE IF( LSAME( SIDE, 'R' ) ) THEN
343: *
1.8 ! bertrand 344: * Form C * H or C * H**T where C = ( C1 C2 )
1.1 bertrand 345: *
346: LASTV = MAX( K, ILADLR( N, K, V, LDV ) )
347: LASTC = ILADLR( M, LASTV, C, LDC )
348: *
349: * W := C * V = (C1*V1 + C2*V2) (stored in WORK)
350: *
351: * W := C2
352: *
353: DO 100 J = 1, K
354: CALL DCOPY( LASTC, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )
355: 100 CONTINUE
356: *
357: * W := W * V2
358: *
359: CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',
360: $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,
361: $ WORK, LDWORK )
362: IF( LASTV.GT.K ) THEN
363: *
364: * W := W + C1 * V1
365: *
366: CALL DGEMM( 'No transpose', 'No transpose',
367: $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,
368: $ ONE, WORK, LDWORK )
369: END IF
370: *
1.8 ! bertrand 371: * W := W * T or W * T**T
1.1 bertrand 372: *
373: CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit',
374: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
375: *
1.8 ! bertrand 376: * C := C - W * V**T
1.1 bertrand 377: *
378: IF( LASTV.GT.K ) THEN
379: *
1.8 ! bertrand 380: * C1 := C1 - W * V1**T
1.1 bertrand 381: *
382: CALL DGEMM( 'No transpose', 'Transpose',
383: $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,
384: $ ONE, C, LDC )
385: END IF
386: *
1.8 ! bertrand 387: * W := W * V2**T
1.1 bertrand 388: *
389: CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',
390: $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,
391: $ WORK, LDWORK )
392: *
393: * C2 := C2 - W
394: *
395: DO 120 J = 1, K
396: DO 110 I = 1, LASTC
397: C( I, LASTV-K+J ) = C( I, LASTV-K+J ) - WORK(I, J)
398: 110 CONTINUE
399: 120 CONTINUE
400: END IF
401: END IF
402: *
403: ELSE IF( LSAME( STOREV, 'R' ) ) THEN
404: *
405: IF( LSAME( DIRECT, 'F' ) ) THEN
406: *
407: * Let V = ( V1 V2 ) (V1: first K columns)
408: * where V1 is unit upper triangular.
409: *
410: IF( LSAME( SIDE, 'L' ) ) THEN
411: *
1.8 ! bertrand 412: * Form H * C or H**T * C where C = ( C1 )
! 413: * ( C2 )
1.1 bertrand 414: *
415: LASTV = MAX( K, ILADLC( K, M, V, LDV ) )
416: LASTC = ILADLC( LASTV, N, C, LDC )
417: *
1.8 ! bertrand 418: * W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)
1.1 bertrand 419: *
1.8 ! bertrand 420: * W := C1**T
1.1 bertrand 421: *
422: DO 130 J = 1, K
423: CALL DCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )
424: 130 CONTINUE
425: *
1.8 ! bertrand 426: * W := W * V1**T
1.1 bertrand 427: *
428: CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',
429: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
430: IF( LASTV.GT.K ) THEN
431: *
1.8 ! bertrand 432: * W := W + C2**T*V2**T
1.1 bertrand 433: *
434: CALL DGEMM( 'Transpose', 'Transpose',
435: $ LASTC, K, LASTV-K,
436: $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV,
437: $ ONE, WORK, LDWORK )
438: END IF
439: *
1.8 ! bertrand 440: * W := W * T**T or W * T
1.1 bertrand 441: *
442: CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit',
443: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
444: *
1.8 ! bertrand 445: * C := C - V**T * W**T
1.1 bertrand 446: *
447: IF( LASTV.GT.K ) THEN
448: *
1.8 ! bertrand 449: * C2 := C2 - V2**T * W**T
1.1 bertrand 450: *
451: CALL DGEMM( 'Transpose', 'Transpose',
452: $ LASTV-K, LASTC, K,
453: $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK,
454: $ ONE, C( K+1, 1 ), LDC )
455: END IF
456: *
457: * W := W * V1
458: *
459: CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',
460: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
461: *
1.8 ! bertrand 462: * C1 := C1 - W**T
1.1 bertrand 463: *
464: DO 150 J = 1, K
465: DO 140 I = 1, LASTC
466: C( J, I ) = C( J, I ) - WORK( I, J )
467: 140 CONTINUE
468: 150 CONTINUE
469: *
470: ELSE IF( LSAME( SIDE, 'R' ) ) THEN
471: *
1.8 ! bertrand 472: * Form C * H or C * H**T where C = ( C1 C2 )
1.1 bertrand 473: *
474: LASTV = MAX( K, ILADLC( K, N, V, LDV ) )
475: LASTC = ILADLR( M, LASTV, C, LDC )
476: *
1.8 ! bertrand 477: * W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)
1.1 bertrand 478: *
479: * W := C1
480: *
481: DO 160 J = 1, K
482: CALL DCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )
483: 160 CONTINUE
484: *
1.8 ! bertrand 485: * W := W * V1**T
1.1 bertrand 486: *
487: CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',
488: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
489: IF( LASTV.GT.K ) THEN
490: *
1.8 ! bertrand 491: * W := W + C2 * V2**T
1.1 bertrand 492: *
493: CALL DGEMM( 'No transpose', 'Transpose',
494: $ LASTC, K, LASTV-K,
495: $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,
496: $ ONE, WORK, LDWORK )
497: END IF
498: *
1.8 ! bertrand 499: * W := W * T or W * T**T
1.1 bertrand 500: *
501: CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit',
502: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
503: *
504: * C := C - W * V
505: *
506: IF( LASTV.GT.K ) THEN
507: *
508: * C2 := C2 - W * V2
509: *
510: CALL DGEMM( 'No transpose', 'No transpose',
511: $ LASTC, LASTV-K, K,
512: $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV,
513: $ ONE, C( 1, K+1 ), LDC )
514: END IF
515: *
516: * W := W * V1
517: *
518: CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',
519: $ LASTC, K, ONE, V, LDV, WORK, LDWORK )
520: *
521: * C1 := C1 - W
522: *
523: DO 180 J = 1, K
524: DO 170 I = 1, LASTC
525: C( I, J ) = C( I, J ) - WORK( I, J )
526: 170 CONTINUE
527: 180 CONTINUE
528: *
529: END IF
530: *
531: ELSE
532: *
533: * Let V = ( V1 V2 ) (V2: last K columns)
534: * where V2 is unit lower triangular.
535: *
536: IF( LSAME( SIDE, 'L' ) ) THEN
537: *
1.8 ! bertrand 538: * Form H * C or H**T * C where C = ( C1 )
! 539: * ( C2 )
1.1 bertrand 540: *
541: LASTV = MAX( K, ILADLC( K, M, V, LDV ) )
542: LASTC = ILADLC( LASTV, N, C, LDC )
543: *
1.8 ! bertrand 544: * W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)
1.1 bertrand 545: *
1.8 ! bertrand 546: * W := C2**T
1.1 bertrand 547: *
548: DO 190 J = 1, K
549: CALL DCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,
550: $ WORK( 1, J ), 1 )
551: 190 CONTINUE
552: *
1.8 ! bertrand 553: * W := W * V2**T
1.1 bertrand 554: *
555: CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',
556: $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,
557: $ WORK, LDWORK )
558: IF( LASTV.GT.K ) THEN
559: *
1.8 ! bertrand 560: * W := W + C1**T * V1**T
1.1 bertrand 561: *
562: CALL DGEMM( 'Transpose', 'Transpose',
563: $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,
564: $ ONE, WORK, LDWORK )
565: END IF
566: *
1.8 ! bertrand 567: * W := W * T**T or W * T
1.1 bertrand 568: *
569: CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit',
570: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
571: *
1.8 ! bertrand 572: * C := C - V**T * W**T
1.1 bertrand 573: *
574: IF( LASTV.GT.K ) THEN
575: *
1.8 ! bertrand 576: * C1 := C1 - V1**T * W**T
1.1 bertrand 577: *
578: CALL DGEMM( 'Transpose', 'Transpose',
579: $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,
580: $ ONE, C, LDC )
581: END IF
582: *
583: * W := W * V2
584: *
585: CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',
586: $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,
587: $ WORK, LDWORK )
588: *
1.8 ! bertrand 589: * C2 := C2 - W**T
1.1 bertrand 590: *
591: DO 210 J = 1, K
592: DO 200 I = 1, LASTC
593: C( LASTV-K+J, I ) = C( LASTV-K+J, I ) - WORK(I, J)
594: 200 CONTINUE
595: 210 CONTINUE
596: *
597: ELSE IF( LSAME( SIDE, 'R' ) ) THEN
598: *
1.8 ! bertrand 599: * Form C * H or C * H**T where C = ( C1 C2 )
1.1 bertrand 600: *
601: LASTV = MAX( K, ILADLC( K, N, V, LDV ) )
602: LASTC = ILADLR( M, LASTV, C, LDC )
603: *
1.8 ! bertrand 604: * W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)
1.1 bertrand 605: *
606: * W := C2
607: *
608: DO 220 J = 1, K
609: CALL DCOPY( LASTC, C( 1, LASTV-K+J ), 1,
610: $ WORK( 1, J ), 1 )
611: 220 CONTINUE
612: *
1.8 ! bertrand 613: * W := W * V2**T
1.1 bertrand 614: *
615: CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',
616: $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,
617: $ WORK, LDWORK )
618: IF( LASTV.GT.K ) THEN
619: *
1.8 ! bertrand 620: * W := W + C1 * V1**T
1.1 bertrand 621: *
622: CALL DGEMM( 'No transpose', 'Transpose',
623: $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,
624: $ ONE, WORK, LDWORK )
625: END IF
626: *
1.8 ! bertrand 627: * W := W * T or W * T**T
1.1 bertrand 628: *
629: CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit',
630: $ LASTC, K, ONE, T, LDT, WORK, LDWORK )
631: *
632: * C := C - W * V
633: *
634: IF( LASTV.GT.K ) THEN
635: *
636: * C1 := C1 - W * V1
637: *
638: CALL DGEMM( 'No transpose', 'No transpose',
639: $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,
640: $ ONE, C, LDC )
641: END IF
642: *
643: * W := W * V2
644: *
645: CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',
646: $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,
647: $ WORK, LDWORK )
648: *
649: * C1 := C1 - W
650: *
651: DO 240 J = 1, K
652: DO 230 I = 1, LASTC
653: C( I, LASTV-K+J ) = C( I, LASTV-K+J ) - WORK(I, J)
654: 230 CONTINUE
655: 240 CONTINUE
656: *
657: END IF
658: *
659: END IF
660: END IF
661: *
662: RETURN
663: *
664: * End of DLARFB
665: *
666: END
CVSweb interface <joel.bertrand@systella.fr>