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