PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
clarft.f
Go to the documentation of this file.
1  SUBROUTINE clarft( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
2 *
3 * -- LAPACK auxiliary routine (version 3.2) --
4 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
5 * November 2006
6 *
7 * .. Scalar Arguments ..
8  CHARACTER direct, storev
9  INTEGER k, ldt, ldv, n
10 * ..
11 * .. Array Arguments ..
12  COMPLEX t( ldt, * ), tau( * ), v( ldv, * )
13 * ..
14 *
15 * Purpose
16 * =======
17 *
18 * CLARFT forms the triangular factor T of a complex block reflector H
19 * of order n, which is defined as a product of k elementary reflectors.
20 *
21 * If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
22 *
23 * If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
24 *
25 * If STOREV = 'C', the vector which defines the elementary reflector
26 * H(i) is stored in the i-th column of the array V, and
27 *
28 * H = I - V * T * V'
29 *
30 * If STOREV = 'R', the vector which defines the elementary reflector
31 * H(i) is stored in the i-th row of the array V, and
32 *
33 * H = I - V' * T * V
34 *
35 * Arguments
36 * =========
37 *
38 * DIRECT (input) CHARACTER*1
39 * Specifies the order in which the elementary reflectors are
40 * multiplied to form the block reflector:
41 * = 'F': H = H(1) H(2) . . . H(k) (Forward)
42 * = 'B': H = H(k) . . . H(2) H(1) (Backward)
43 *
44 * STOREV (input) CHARACTER*1
45 * Specifies how the vectors which define the elementary
46 * reflectors are stored (see also Further Details):
47 * = 'C': columnwise
48 * = 'R': rowwise
49 *
50 * N (input) INTEGER
51 * The order of the block reflector H. N >= 0.
52 *
53 * K (input) INTEGER
54 * The order of the triangular factor T (= the number of
55 * elementary reflectors). K >= 1.
56 *
57 * V (input/output) COMPLEX array, dimension
58 * (LDV,K) if STOREV = 'C'
59 * (LDV,N) if STOREV = 'R'
60 * The matrix V. See further details.
61 *
62 * LDV (input) INTEGER
63 * The leading dimension of the array V.
64 * If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
65 *
66 * TAU (input) COMPLEX array, dimension (K)
67 * TAU(i) must contain the scalar factor of the elementary
68 * reflector H(i).
69 *
70 * T (output) COMPLEX array, dimension (LDT,K)
71 * The k by k triangular factor T of the block reflector.
72 * If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
73 * lower triangular. The rest of the array is not used.
74 *
75 * LDT (input) INTEGER
76 * The leading dimension of the array T. LDT >= K.
77 *
78 * Further Details
79 * ===============
80 *
81 * The shape of the matrix V and the storage of the vectors which define
82 * the H(i) is best illustrated by the following example with n = 5 and
83 * k = 3. The elements equal to 1 are not stored; the corresponding
84 * array elements are modified but restored on exit. The rest of the
85 * array is not used.
86 *
87 * DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':
88 *
89 * V = ( 1 ) V = ( 1 v1 v1 v1 v1 )
90 * ( v1 1 ) ( 1 v2 v2 v2 )
91 * ( v1 v2 1 ) ( 1 v3 v3 )
92 * ( v1 v2 v3 )
93 * ( v1 v2 v3 )
94 *
95 * DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':
96 *
97 * V = ( v1 v2 v3 ) V = ( v1 v1 1 )
98 * ( v1 v2 v3 ) ( v2 v2 v2 1 )
99 * ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )
100 * ( 1 v3 )
101 * ( 1 )
102 *
103 * =====================================================================
104 *
105 * .. Parameters ..
106  COMPLEX one, zero
107  parameter( one = ( 1.0e+0, 0.0e+0 ),
108  $ zero = ( 0.0e+0, 0.0e+0 ) )
109 * ..
110 * .. Local Scalars ..
111  INTEGER i, j, prevlastv, lastv
112  COMPLEX vii
113 * ..
114 * .. External Subroutines ..
115  EXTERNAL cgemv, clacgv, ctrmv
116 * ..
117 * .. External Functions ..
118  LOGICAL lsame
119  EXTERNAL lsame
120 * ..
121 * .. Executable Statements ..
122 *
123 * Quick return if possible
124 *
125  IF( n.EQ.0 )
126  $ return
127 *
128  IF( lsame( direct, 'F' ) ) THEN
129  prevlastv = n
130  DO 20 i = 1, k
131  prevlastv = max( prevlastv, i )
132  IF( tau( i ).EQ.zero ) THEN
133 *
134 * H(i) = I
135 *
136  DO 10 j = 1, i
137  t( j, i ) = zero
138  10 continue
139  ELSE
140 *
141 * general case
142 *
143  vii = v( i, i )
144  v( i, i ) = one
145  IF( lsame( storev, 'C' ) ) THEN
146 ! Skip any trailing zeros.
147  DO lastv = n, i+1, -1
148  IF( v( lastv, i ).NE.zero ) goto 55
149  END DO
150  55 continue
151  j = min( lastv, prevlastv )
152 *
153 * T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)' * V(i:j,i)
154 *
155  CALL cgemv( 'Conjugate transpose', j-i+1, i-1,
156  $ -tau( i ), v( i, 1 ), ldv, v( i, i ), 1,
157  $ zero, t( 1, i ), 1 )
158  ELSE
159 ! Skip any trailing zeros.
160  DO lastv = n, i+1, -1
161  IF( v( i, lastv ).NE.zero ) goto 65
162  END DO
163  65 continue
164  j = min( lastv, prevlastv )
165 *
166 * T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)'
167 *
168  IF( i.LT.j )
169  $ CALL clacgv( j-i, v( i, i+1 ), ldv )
170  CALL cgemv( 'No transpose', i-1, j-i+1, -tau( i ),
171  $ v( 1, i ), ldv, v( i, i ), ldv, zero,
172  $ t( 1, i ), 1 )
173  IF( i.LT.j )
174  $ CALL clacgv( j-i, v( i, i+1 ), ldv )
175  END IF
176  v( i, i ) = vii
177 *
178 * T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)
179 *
180  CALL ctrmv( 'Upper', 'No transpose', 'Non-unit', i-1, t,
181  $ ldt, t( 1, i ), 1 )
182  t( i, i ) = tau( i )
183  IF( i.GT.1 ) THEN
184  prevlastv = max( prevlastv, lastv )
185  ELSE
186  prevlastv = lastv
187  END IF
188  END IF
189  20 continue
190  ELSE
191  prevlastv = 1
192  DO 40 i = k, 1, -1
193  IF( tau( i ).EQ.zero ) THEN
194 *
195 * H(i) = I
196 *
197  DO 30 j = i, k
198  t( j, i ) = zero
199  30 continue
200  ELSE
201 *
202 * general case
203 *
204  IF( i.LT.k ) THEN
205  IF( lsame( storev, 'C' ) ) THEN
206  vii = v( n-k+i, i )
207  v( n-k+i, i ) = one
208 ! Skip any leading zeros.
209  DO lastv = 1, i-1
210  IF( v( lastv, i ).NE.zero ) goto 75
211  END DO
212  75 continue
213  j = max( lastv, prevlastv )
214 *
215 * T(i+1:k,i) :=
216 * - tau(i) * V(j:n-k+i,i+1:k)' * V(j:n-k+i,i)
217 *
218  CALL cgemv( 'Conjugate transpose', n-k+i-j+1, k-i,
219  $ -tau( i ), v( j, i+1 ), ldv, v( j, i ),
220  $ 1, zero, t( i+1, i ), 1 )
221  v( n-k+i, i ) = vii
222  ELSE
223  vii = v( i, n-k+i )
224  v( i, n-k+i ) = one
225 ! Skip any leading zeros.
226  DO lastv = 1, i-1
227  IF( v( i, lastv ).NE.zero ) goto 85
228  END DO
229  85 continue
230  j = max( lastv, prevlastv )
231 *
232 * T(i+1:k,i) :=
233 * - tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)'
234 *
235  CALL clacgv( n-k+i-1-j+1, v( i, j ), ldv )
236  CALL cgemv( 'No transpose', k-i, n-k+i-j+1,
237  $ -tau( i ), v( i+1, j ), ldv, v( i, j ), ldv,
238  $ zero, t( i+1, i ), 1 )
239  CALL clacgv( n-k+i-1-j+1, v( i, j ), ldv )
240  v( i, n-k+i ) = vii
241  END IF
242 *
243 * T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
244 *
245  CALL ctrmv( 'Lower', 'No transpose', 'Non-unit', k-i,
246  $ t( i+1, i+1 ), ldt, t( i+1, i ), 1 )
247  IF( i.GT.1 ) THEN
248  prevlastv = min( prevlastv, lastv )
249  ELSE
250  prevlastv = lastv
251  END IF
252  END IF
253  t( i, i ) = tau( i )
254  END IF
255  40 continue
256  END IF
257  return
258 *
259 * End of CLARFT
260 *
261  END