xref: /aosp_15_r20/external/eigen/lapack/dlarft.f (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Li*> \brief \b DLARFT
2*bf2c3715SXin Li*
3*bf2c3715SXin Li*  =========== DOCUMENTATION ===========
4*bf2c3715SXin Li*
5*bf2c3715SXin Li* Online html documentation available at
6*bf2c3715SXin Li*            http://www.netlib.org/lapack/explore-html/
7*bf2c3715SXin Li*
8*bf2c3715SXin Li*> \htmlonly
9*bf2c3715SXin Li*> Download DLARFT + dependencies
10*bf2c3715SXin Li*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarft.f">
11*bf2c3715SXin Li*> [TGZ]</a>
12*bf2c3715SXin Li*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarft.f">
13*bf2c3715SXin Li*> [ZIP]</a>
14*bf2c3715SXin Li*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarft.f">
15*bf2c3715SXin Li*> [TXT]</a>
16*bf2c3715SXin Li*> \endhtmlonly
17*bf2c3715SXin Li*
18*bf2c3715SXin Li*  Definition:
19*bf2c3715SXin Li*  ===========
20*bf2c3715SXin Li*
21*bf2c3715SXin Li*       SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
22*bf2c3715SXin Li*
23*bf2c3715SXin Li*       .. Scalar Arguments ..
24*bf2c3715SXin Li*       CHARACTER          DIRECT, STOREV
25*bf2c3715SXin Li*       INTEGER            K, LDT, LDV, N
26*bf2c3715SXin Li*       ..
27*bf2c3715SXin Li*       .. Array Arguments ..
28*bf2c3715SXin Li*       DOUBLE PRECISION   T( LDT, * ), TAU( * ), V( LDV, * )
29*bf2c3715SXin Li*       ..
30*bf2c3715SXin Li*
31*bf2c3715SXin Li*
32*bf2c3715SXin Li*> \par Purpose:
33*bf2c3715SXin Li*  =============
34*bf2c3715SXin Li*>
35*bf2c3715SXin Li*> \verbatim
36*bf2c3715SXin Li*>
37*bf2c3715SXin Li*> DLARFT forms the triangular factor T of a real block reflector H
38*bf2c3715SXin Li*> of order n, which is defined as a product of k elementary reflectors.
39*bf2c3715SXin Li*>
40*bf2c3715SXin Li*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;
41*bf2c3715SXin Li*>
42*bf2c3715SXin Li*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.
43*bf2c3715SXin Li*>
44*bf2c3715SXin Li*> If STOREV = 'C', the vector which defines the elementary reflector
45*bf2c3715SXin Li*> H(i) is stored in the i-th column of the array V, and
46*bf2c3715SXin Li*>
47*bf2c3715SXin Li*>    H  =  I - V * T * V**T
48*bf2c3715SXin Li*>
49*bf2c3715SXin Li*> If STOREV = 'R', the vector which defines the elementary reflector
50*bf2c3715SXin Li*> H(i) is stored in the i-th row of the array V, and
51*bf2c3715SXin Li*>
52*bf2c3715SXin Li*>    H  =  I - V**T * T * V
53*bf2c3715SXin Li*> \endverbatim
54*bf2c3715SXin Li*
55*bf2c3715SXin Li*  Arguments:
56*bf2c3715SXin Li*  ==========
57*bf2c3715SXin Li*
58*bf2c3715SXin Li*> \param[in] DIRECT
59*bf2c3715SXin Li*> \verbatim
60*bf2c3715SXin Li*>          DIRECT is CHARACTER*1
61*bf2c3715SXin Li*>          Specifies the order in which the elementary reflectors are
62*bf2c3715SXin Li*>          multiplied to form the block reflector:
63*bf2c3715SXin Li*>          = 'F': H = H(1) H(2) . . . H(k) (Forward)
64*bf2c3715SXin Li*>          = 'B': H = H(k) . . . H(2) H(1) (Backward)
65*bf2c3715SXin Li*> \endverbatim
66*bf2c3715SXin Li*>
67*bf2c3715SXin Li*> \param[in] STOREV
68*bf2c3715SXin Li*> \verbatim
69*bf2c3715SXin Li*>          STOREV is CHARACTER*1
70*bf2c3715SXin Li*>          Specifies how the vectors which define the elementary
71*bf2c3715SXin Li*>          reflectors are stored (see also Further Details):
72*bf2c3715SXin Li*>          = 'C': columnwise
73*bf2c3715SXin Li*>          = 'R': rowwise
74*bf2c3715SXin Li*> \endverbatim
75*bf2c3715SXin Li*>
76*bf2c3715SXin Li*> \param[in] N
77*bf2c3715SXin Li*> \verbatim
78*bf2c3715SXin Li*>          N is INTEGER
79*bf2c3715SXin Li*>          The order of the block reflector H. N >= 0.
80*bf2c3715SXin Li*> \endverbatim
81*bf2c3715SXin Li*>
82*bf2c3715SXin Li*> \param[in] K
83*bf2c3715SXin Li*> \verbatim
84*bf2c3715SXin Li*>          K is INTEGER
85*bf2c3715SXin Li*>          The order of the triangular factor T (= the number of
86*bf2c3715SXin Li*>          elementary reflectors). K >= 1.
87*bf2c3715SXin Li*> \endverbatim
88*bf2c3715SXin Li*>
89*bf2c3715SXin Li*> \param[in] V
90*bf2c3715SXin Li*> \verbatim
91*bf2c3715SXin Li*>          V is DOUBLE PRECISION array, dimension
92*bf2c3715SXin Li*>                               (LDV,K) if STOREV = 'C'
93*bf2c3715SXin Li*>                               (LDV,N) if STOREV = 'R'
94*bf2c3715SXin Li*>          The matrix V. See further details.
95*bf2c3715SXin Li*> \endverbatim
96*bf2c3715SXin Li*>
97*bf2c3715SXin Li*> \param[in] LDV
98*bf2c3715SXin Li*> \verbatim
99*bf2c3715SXin Li*>          LDV is INTEGER
100*bf2c3715SXin Li*>          The leading dimension of the array V.
101*bf2c3715SXin Li*>          If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.
102*bf2c3715SXin Li*> \endverbatim
103*bf2c3715SXin Li*>
104*bf2c3715SXin Li*> \param[in] TAU
105*bf2c3715SXin Li*> \verbatim
106*bf2c3715SXin Li*>          TAU is DOUBLE PRECISION array, dimension (K)
107*bf2c3715SXin Li*>          TAU(i) must contain the scalar factor of the elementary
108*bf2c3715SXin Li*>          reflector H(i).
109*bf2c3715SXin Li*> \endverbatim
110*bf2c3715SXin Li*>
111*bf2c3715SXin Li*> \param[out] T
112*bf2c3715SXin Li*> \verbatim
113*bf2c3715SXin Li*>          T is DOUBLE PRECISION array, dimension (LDT,K)
114*bf2c3715SXin Li*>          The k by k triangular factor T of the block reflector.
115*bf2c3715SXin Li*>          If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is
116*bf2c3715SXin Li*>          lower triangular. The rest of the array is not used.
117*bf2c3715SXin Li*> \endverbatim
118*bf2c3715SXin Li*>
119*bf2c3715SXin Li*> \param[in] LDT
120*bf2c3715SXin Li*> \verbatim
121*bf2c3715SXin Li*>          LDT is INTEGER
122*bf2c3715SXin Li*>          The leading dimension of the array T. LDT >= K.
123*bf2c3715SXin Li*> \endverbatim
124*bf2c3715SXin Li*
125*bf2c3715SXin Li*  Authors:
126*bf2c3715SXin Li*  ========
127*bf2c3715SXin Li*
128*bf2c3715SXin Li*> \author Univ. of Tennessee
129*bf2c3715SXin Li*> \author Univ. of California Berkeley
130*bf2c3715SXin Li*> \author Univ. of Colorado Denver
131*bf2c3715SXin Li*> \author NAG Ltd.
132*bf2c3715SXin Li*
133*bf2c3715SXin Li*> \date April 2012
134*bf2c3715SXin Li*
135*bf2c3715SXin Li*> \ingroup doubleOTHERauxiliary
136*bf2c3715SXin Li*
137*bf2c3715SXin Li*> \par Further Details:
138*bf2c3715SXin Li*  =====================
139*bf2c3715SXin Li*>
140*bf2c3715SXin Li*> \verbatim
141*bf2c3715SXin Li*>
142*bf2c3715SXin Li*>  The shape of the matrix V and the storage of the vectors which define
143*bf2c3715SXin Li*>  the H(i) is best illustrated by the following example with n = 5 and
144*bf2c3715SXin Li*>  k = 3. The elements equal to 1 are not stored.
145*bf2c3715SXin Li*>
146*bf2c3715SXin Li*>  DIRECT = 'F' and STOREV = 'C':         DIRECT = 'F' and STOREV = 'R':
147*bf2c3715SXin Li*>
148*bf2c3715SXin Li*>               V = (  1       )                 V = (  1 v1 v1 v1 v1 )
149*bf2c3715SXin Li*>                   ( v1  1    )                     (     1 v2 v2 v2 )
150*bf2c3715SXin Li*>                   ( v1 v2  1 )                     (        1 v3 v3 )
151*bf2c3715SXin Li*>                   ( v1 v2 v3 )
152*bf2c3715SXin Li*>                   ( v1 v2 v3 )
153*bf2c3715SXin Li*>
154*bf2c3715SXin Li*>  DIRECT = 'B' and STOREV = 'C':         DIRECT = 'B' and STOREV = 'R':
155*bf2c3715SXin Li*>
156*bf2c3715SXin Li*>               V = ( v1 v2 v3 )                 V = ( v1 v1  1       )
157*bf2c3715SXin Li*>                   ( v1 v2 v3 )                     ( v2 v2 v2  1    )
158*bf2c3715SXin Li*>                   (  1 v2 v3 )                     ( v3 v3 v3 v3  1 )
159*bf2c3715SXin Li*>                   (     1 v3 )
160*bf2c3715SXin Li*>                   (        1 )
161*bf2c3715SXin Li*> \endverbatim
162*bf2c3715SXin Li*>
163*bf2c3715SXin Li*  =====================================================================
164*bf2c3715SXin Li      SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )
165*bf2c3715SXin Li*
166*bf2c3715SXin Li*  -- LAPACK auxiliary routine (version 3.4.1) --
167*bf2c3715SXin Li*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
168*bf2c3715SXin Li*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
169*bf2c3715SXin Li*     April 2012
170*bf2c3715SXin Li*
171*bf2c3715SXin Li*     .. Scalar Arguments ..
172*bf2c3715SXin Li      CHARACTER          DIRECT, STOREV
173*bf2c3715SXin Li      INTEGER            K, LDT, LDV, N
174*bf2c3715SXin Li*     ..
175*bf2c3715SXin Li*     .. Array Arguments ..
176*bf2c3715SXin Li      DOUBLE PRECISION   T( LDT, * ), TAU( * ), V( LDV, * )
177*bf2c3715SXin Li*     ..
178*bf2c3715SXin Li*
179*bf2c3715SXin Li*  =====================================================================
180*bf2c3715SXin Li*
181*bf2c3715SXin Li*     .. Parameters ..
182*bf2c3715SXin Li      DOUBLE PRECISION   ONE, ZERO
183*bf2c3715SXin Li      PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
184*bf2c3715SXin Li*     ..
185*bf2c3715SXin Li*     .. Local Scalars ..
186*bf2c3715SXin Li      INTEGER            I, J, PREVLASTV, LASTV
187*bf2c3715SXin Li*     ..
188*bf2c3715SXin Li*     .. External Subroutines ..
189*bf2c3715SXin Li      EXTERNAL           DGEMV, DTRMV
190*bf2c3715SXin Li*     ..
191*bf2c3715SXin Li*     .. External Functions ..
192*bf2c3715SXin Li      LOGICAL            LSAME
193*bf2c3715SXin Li      EXTERNAL           LSAME
194*bf2c3715SXin Li*     ..
195*bf2c3715SXin Li*     .. Executable Statements ..
196*bf2c3715SXin Li*
197*bf2c3715SXin Li*     Quick return if possible
198*bf2c3715SXin Li*
199*bf2c3715SXin Li      IF( N.EQ.0 )
200*bf2c3715SXin Li     $   RETURN
201*bf2c3715SXin Li*
202*bf2c3715SXin Li      IF( LSAME( DIRECT, 'F' ) ) THEN
203*bf2c3715SXin Li         PREVLASTV = N
204*bf2c3715SXin Li         DO I = 1, K
205*bf2c3715SXin Li            PREVLASTV = MAX( I, PREVLASTV )
206*bf2c3715SXin Li            IF( TAU( I ).EQ.ZERO ) THEN
207*bf2c3715SXin Li*
208*bf2c3715SXin Li*              H(i)  =  I
209*bf2c3715SXin Li*
210*bf2c3715SXin Li               DO J = 1, I
211*bf2c3715SXin Li                  T( J, I ) = ZERO
212*bf2c3715SXin Li               END DO
213*bf2c3715SXin Li            ELSE
214*bf2c3715SXin Li*
215*bf2c3715SXin Li*              general case
216*bf2c3715SXin Li*
217*bf2c3715SXin Li               IF( LSAME( STOREV, 'C' ) ) THEN
218*bf2c3715SXin Li*                 Skip any trailing zeros.
219*bf2c3715SXin Li                  DO LASTV = N, I+1, -1
220*bf2c3715SXin Li                     IF( V( LASTV, I ).NE.ZERO ) EXIT
221*bf2c3715SXin Li                  END DO
222*bf2c3715SXin Li                  DO J = 1, I-1
223*bf2c3715SXin Li                     T( J, I ) = -TAU( I ) * V( I , J )
224*bf2c3715SXin Li                  END DO
225*bf2c3715SXin Li                  J = MIN( LASTV, PREVLASTV )
226*bf2c3715SXin Li*
227*bf2c3715SXin Li*                 T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)**T * V(i:j,i)
228*bf2c3715SXin Li*
229*bf2c3715SXin Li                  CALL DGEMV( 'Transpose', J-I, I-1, -TAU( I ),
230*bf2c3715SXin Li     $                        V( I+1, 1 ), LDV, V( I+1, I ), 1, ONE,
231*bf2c3715SXin Li     $                        T( 1, I ), 1 )
232*bf2c3715SXin Li               ELSE
233*bf2c3715SXin Li*                 Skip any trailing zeros.
234*bf2c3715SXin Li                  DO LASTV = N, I+1, -1
235*bf2c3715SXin Li                     IF( V( I, LASTV ).NE.ZERO ) EXIT
236*bf2c3715SXin Li                  END DO
237*bf2c3715SXin Li                  DO J = 1, I-1
238*bf2c3715SXin Li                     T( J, I ) = -TAU( I ) * V( J , I )
239*bf2c3715SXin Li                  END DO
240*bf2c3715SXin Li                  J = MIN( LASTV, PREVLASTV )
241*bf2c3715SXin Li*
242*bf2c3715SXin Li*                 T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)**T
243*bf2c3715SXin Li*
244*bf2c3715SXin Li                  CALL DGEMV( 'No transpose', I-1, J-I, -TAU( I ),
245*bf2c3715SXin Li     $                        V( 1, I+1 ), LDV, V( I, I+1 ), LDV, ONE,
246*bf2c3715SXin Li     $                        T( 1, I ), 1 )
247*bf2c3715SXin Li               END IF
248*bf2c3715SXin Li*
249*bf2c3715SXin Li*              T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)
250*bf2c3715SXin Li*
251*bf2c3715SXin Li               CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,
252*bf2c3715SXin Li     $                     LDT, T( 1, I ), 1 )
253*bf2c3715SXin Li               T( I, I ) = TAU( I )
254*bf2c3715SXin Li               IF( I.GT.1 ) THEN
255*bf2c3715SXin Li                  PREVLASTV = MAX( PREVLASTV, LASTV )
256*bf2c3715SXin Li               ELSE
257*bf2c3715SXin Li                  PREVLASTV = LASTV
258*bf2c3715SXin Li               END IF
259*bf2c3715SXin Li            END IF
260*bf2c3715SXin Li         END DO
261*bf2c3715SXin Li      ELSE
262*bf2c3715SXin Li         PREVLASTV = 1
263*bf2c3715SXin Li         DO I = K, 1, -1
264*bf2c3715SXin Li            IF( TAU( I ).EQ.ZERO ) THEN
265*bf2c3715SXin Li*
266*bf2c3715SXin Li*              H(i)  =  I
267*bf2c3715SXin Li*
268*bf2c3715SXin Li               DO J = I, K
269*bf2c3715SXin Li                  T( J, I ) = ZERO
270*bf2c3715SXin Li               END DO
271*bf2c3715SXin Li            ELSE
272*bf2c3715SXin Li*
273*bf2c3715SXin Li*              general case
274*bf2c3715SXin Li*
275*bf2c3715SXin Li               IF( I.LT.K ) THEN
276*bf2c3715SXin Li                  IF( LSAME( STOREV, 'C' ) ) THEN
277*bf2c3715SXin Li*                    Skip any leading zeros.
278*bf2c3715SXin Li                     DO LASTV = 1, I-1
279*bf2c3715SXin Li                        IF( V( LASTV, I ).NE.ZERO ) EXIT
280*bf2c3715SXin Li                     END DO
281*bf2c3715SXin Li                     DO J = I+1, K
282*bf2c3715SXin Li                        T( J, I ) = -TAU( I ) * V( N-K+I , J )
283*bf2c3715SXin Li                     END DO
284*bf2c3715SXin Li                     J = MAX( LASTV, PREVLASTV )
285*bf2c3715SXin Li*
286*bf2c3715SXin Li*                    T(i+1:k,i) = -tau(i) * V(j:n-k+i,i+1:k)**T * V(j:n-k+i,i)
287*bf2c3715SXin Li*
288*bf2c3715SXin Li                     CALL DGEMV( 'Transpose', N-K+I-J, K-I, -TAU( I ),
289*bf2c3715SXin Li     $                           V( J, I+1 ), LDV, V( J, I ), 1, ONE,
290*bf2c3715SXin Li     $                           T( I+1, I ), 1 )
291*bf2c3715SXin Li                  ELSE
292*bf2c3715SXin Li*                    Skip any leading zeros.
293*bf2c3715SXin Li                     DO LASTV = 1, I-1
294*bf2c3715SXin Li                        IF( V( I, LASTV ).NE.ZERO ) EXIT
295*bf2c3715SXin Li                     END DO
296*bf2c3715SXin Li                     DO J = I+1, K
297*bf2c3715SXin Li                        T( J, I ) = -TAU( I ) * V( J, N-K+I )
298*bf2c3715SXin Li                     END DO
299*bf2c3715SXin Li                     J = MAX( LASTV, PREVLASTV )
300*bf2c3715SXin Li*
301*bf2c3715SXin Li*                    T(i+1:k,i) = -tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)**T
302*bf2c3715SXin Li*
303*bf2c3715SXin Li                     CALL DGEMV( 'No transpose', K-I, N-K+I-J,
304*bf2c3715SXin Li     $                    -TAU( I ), V( I+1, J ), LDV, V( I, J ), LDV,
305*bf2c3715SXin Li     $                    ONE, T( I+1, I ), 1 )
306*bf2c3715SXin Li                  END IF
307*bf2c3715SXin Li*
308*bf2c3715SXin Li*                 T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)
309*bf2c3715SXin Li*
310*bf2c3715SXin Li                  CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,
311*bf2c3715SXin Li     $                        T( I+1, I+1 ), LDT, T( I+1, I ), 1 )
312*bf2c3715SXin Li                  IF( I.GT.1 ) THEN
313*bf2c3715SXin Li                     PREVLASTV = MIN( PREVLASTV, LASTV )
314*bf2c3715SXin Li                  ELSE
315*bf2c3715SXin Li                     PREVLASTV = LASTV
316*bf2c3715SXin Li                  END IF
317*bf2c3715SXin Li               END IF
318*bf2c3715SXin Li               T( I, I ) = TAU( I )
319*bf2c3715SXin Li            END IF
320*bf2c3715SXin Li         END DO
321*bf2c3715SXin Li      END IF
322*bf2c3715SXin Li      RETURN
323*bf2c3715SXin Li*
324*bf2c3715SXin Li*     End of DLARFT
325*bf2c3715SXin Li*
326*bf2c3715SXin Li      END
327