LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
claunhr_col_getrfnp2.f
Go to the documentation of this file.
1*> \brief \b CLAUNHR_COL_GETRFNP2
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download CLAUNHR_COL_GETRFNP2 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/claunhr_col_getrfnp2.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/claunhr_col_getrfnp2.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/claunhr_col_getrfnp2.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* RECURSIVE SUBROUTINE CLAUNHR_COL_GETRFNP2( M, N, A, LDA, D, INFO )
20*
21* .. Scalar Arguments ..
22* INTEGER INFO, LDA, M, N
23* ..
24* .. Array Arguments ..
25* COMPLEX A( LDA, * ), D( * )
26* ..
27*
28*
29*> \par Purpose:
30* =============
31*>
32*> \verbatim
33*>
34*> CLAUNHR_COL_GETRFNP2 computes the modified LU factorization without
35*> pivoting of a complex general M-by-N matrix A. The factorization has
36*> the form:
37*>
38*> A - S = L * U,
39*>
40*> where:
41*> S is a m-by-n diagonal sign matrix with the diagonal D, so that
42*> D(i) = S(i,i), 1 <= i <= min(M,N). The diagonal D is constructed
43*> as D(i)=-SIGN(A(i,i)), where A(i,i) is the value after performing
44*> i-1 steps of Gaussian elimination. This means that the diagonal
45*> element at each step of "modified" Gaussian elimination is at
46*> least one in absolute value (so that division-by-zero not
47*> possible during the division by the diagonal element);
48*>
49*> L is a M-by-N lower triangular matrix with unit diagonal elements
50*> (lower trapezoidal if M > N);
51*>
52*> and U is a M-by-N upper triangular matrix
53*> (upper trapezoidal if M < N).
54*>
55*> This routine is an auxiliary routine used in the Householder
56*> reconstruction routine CUNHR_COL. In CUNHR_COL, this routine is
57*> applied to an M-by-N matrix A with orthonormal columns, where each
58*> element is bounded by one in absolute value. With the choice of
59*> the matrix S above, one can show that the diagonal element at each
60*> step of Gaussian elimination is the largest (in absolute value) in
61*> the column on or below the diagonal, so that no pivoting is required
62*> for numerical stability [1].
63*>
64*> For more details on the Householder reconstruction algorithm,
65*> including the modified LU factorization, see [1].
66*>
67*> This is the recursive version of the LU factorization algorithm.
68*> Denote A - S by B. The algorithm divides the matrix B into four
69*> submatrices:
70*>
71*> [ B11 | B12 ] where B11 is n1 by n1,
72*> B = [ -----|----- ] B21 is (m-n1) by n1,
73*> [ B21 | B22 ] B12 is n1 by n2,
74*> B22 is (m-n1) by n2,
75*> with n1 = min(m,n)/2, n2 = n-n1.
76*>
77*>
78*> The subroutine calls itself to factor B11, solves for B21,
79*> solves for B12, updates B22, then calls itself to factor B22.
80*>
81*> For more details on the recursive LU algorithm, see [2].
82*>
83*> CLAUNHR_COL_GETRFNP2 is called to factorize a block by the blocked
84*> routine CLAUNHR_COL_GETRFNP, which uses blocked code calling
85*> Level 3 BLAS to update the submatrix. However, CLAUNHR_COL_GETRFNP2
86*> is self-sufficient and can be used without CLAUNHR_COL_GETRFNP.
87*>
88*> [1] "Reconstructing Householder vectors from tall-skinny QR",
89*> G. Ballard, J. Demmel, L. Grigori, M. Jacquelin, H.D. Nguyen,
90*> E. Solomonik, J. Parallel Distrib. Comput.,
91*> vol. 85, pp. 3-31, 2015.
92*>
93*> [2] "Recursion leads to automatic variable blocking for dense linear
94*> algebra algorithms", F. Gustavson, IBM J. of Res. and Dev.,
95*> vol. 41, no. 6, pp. 737-755, 1997.
96*> \endverbatim
97*
98* Arguments:
99* ==========
100*
101*> \param[in] M
102*> \verbatim
103*> M is INTEGER
104*> The number of rows of the matrix A. M >= 0.
105*> \endverbatim
106*>
107*> \param[in] N
108*> \verbatim
109*> N is INTEGER
110*> The number of columns of the matrix A. N >= 0.
111*> \endverbatim
112*>
113*> \param[in,out] A
114*> \verbatim
115*> A is COMPLEX array, dimension (LDA,N)
116*> On entry, the M-by-N matrix to be factored.
117*> On exit, the factors L and U from the factorization
118*> A-S=L*U; the unit diagonal elements of L are not stored.
119*> \endverbatim
120*>
121*> \param[in] LDA
122*> \verbatim
123*> LDA is INTEGER
124*> The leading dimension of the array A. LDA >= max(1,M).
125*> \endverbatim
126*>
127*> \param[out] D
128*> \verbatim
129*> D is COMPLEX array, dimension min(M,N)
130*> The diagonal elements of the diagonal M-by-N sign matrix S,
131*> D(i) = S(i,i), where 1 <= i <= min(M,N). The elements can be
132*> only ( +1.0, 0.0 ) or (-1.0, 0.0 ).
133*> \endverbatim
134*>
135*> \param[out] INFO
136*> \verbatim
137*> INFO is INTEGER
138*> = 0: successful exit
139*> < 0: if INFO = -i, the i-th argument had an illegal value
140*> \endverbatim
141*>
142* Authors:
143* ========
144*
145*> \author Univ. of Tennessee
146*> \author Univ. of California Berkeley
147*> \author Univ. of Colorado Denver
148*> \author NAG Ltd.
149*
150*> \ingroup launhr_col_getrfnp2
151*
152*> \par Contributors:
153* ==================
154*>
155*> \verbatim
156*>
157*> November 2019, Igor Kozachenko,
158*> Computer Science Division,
159*> University of California, Berkeley
160*>
161*> \endverbatim
162*
163* =====================================================================
164 RECURSIVE SUBROUTINE claunhr_col_getrfnp2( M, N, A, LDA, D,
165 $ INFO )
166 IMPLICIT NONE
167*
168* -- LAPACK computational routine --
169* -- LAPACK is a software package provided by Univ. of Tennessee, --
170* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
171*
172* .. Scalar Arguments ..
173 INTEGER info, lda, m, n
174* ..
175* .. Array Arguments ..
176 COMPLEX a( lda, * ), d( * )
177* ..
178*
179* =====================================================================
180*
181* .. Parameters ..
182 REAL one
183 parameter( one = 1.0e+0 )
184 COMPLEX cone
185 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
186* ..
187* .. Local Scalars ..
188 REAL sfmin
189 INTEGER i, iinfo, n1, n2
190 COMPLEX z
191* ..
192* .. External Functions ..
193 REAL slamch
194 EXTERNAL slamch
195* ..
196* .. External Subroutines ..
197 EXTERNAL cgemm, cscal, ctrsm, xerbla
198* ..
199* .. Intrinsic Functions ..
200 INTRINSIC abs, real, cmplx, aimag, sign, max, min
201* ..
202* .. Statement Functions ..
203 DOUBLE PRECISION cabs1
204* ..
205* .. Statement Function definitions ..
206 cabs1( z ) = abs( real( z ) ) + abs( aimag( z ) )
207* ..
208* .. Executable Statements ..
209*
210* Test the input parameters
211*
212 info = 0
213 IF( m.LT.0 ) THEN
214 info = -1
215 ELSE IF( n.LT.0 ) THEN
216 info = -2
217 ELSE IF( lda.LT.max( 1, m ) ) THEN
218 info = -4
219 END IF
220 IF( info.NE.0 ) THEN
221 CALL xerbla( 'CLAUNHR_COL_GETRFNP2', -info )
222 RETURN
223 END IF
224*
225* Quick return if possible
226*
227 IF( min( m, n ).EQ.0 )
228 $ RETURN
229
230 IF ( m.EQ.1 ) THEN
231*
232* One row case, (also recursion termination case),
233* use unblocked code
234*
235* Transfer the sign
236*
237 d( 1 ) = cmplx( -sign( one, real( a( 1, 1 ) ) ) )
238*
239* Construct the row of U
240*
241 a( 1, 1 ) = a( 1, 1 ) - d( 1 )
242*
243 ELSE IF( n.EQ.1 ) THEN
244*
245* One column case, (also recursion termination case),
246* use unblocked code
247*
248* Transfer the sign
249*
250 d( 1 ) = cmplx( -sign( one, real( a( 1, 1 ) ) ) )
251*
252* Construct the row of U
253*
254 a( 1, 1 ) = a( 1, 1 ) - d( 1 )
255*
256* Scale the elements 2:M of the column
257*
258* Determine machine safe minimum
259*
260 sfmin = slamch('S')
261*
262* Construct the subdiagonal elements of L
263*
264 IF( cabs1( a( 1, 1 ) ) .GE. sfmin ) THEN
265 CALL cscal( m-1, cone / a( 1, 1 ), a( 2, 1 ), 1 )
266 ELSE
267 DO i = 2, m
268 a( i, 1 ) = a( i, 1 ) / a( 1, 1 )
269 END DO
270 END IF
271*
272 ELSE
273*
274* Divide the matrix B into four submatrices
275*
276 n1 = min( m, n ) / 2
277 n2 = n-n1
278
279*
280* Factor B11, recursive call
281*
282 CALL claunhr_col_getrfnp2( n1, n1, a, lda, d, iinfo )
283*
284* Solve for B21
285*
286 CALL ctrsm( 'R', 'U', 'N', 'N', m-n1, n1, cone, a, lda,
287 $ a( n1+1, 1 ), lda )
288*
289* Solve for B12
290*
291 CALL ctrsm( 'L', 'L', 'N', 'U', n1, n2, cone, a, lda,
292 $ a( 1, n1+1 ), lda )
293*
294* Update B22, i.e. compute the Schur complement
295* B22 := B22 - B21*B12
296*
297 CALL cgemm( 'N', 'N', m-n1, n2, n1, -cone, a( n1+1, 1 ),
298 $ lda,
299 $ a( 1, n1+1 ), lda, cone, a( n1+1, n1+1 ), lda )
300*
301* Factor B22, recursive call
302*
303 CALL claunhr_col_getrfnp2( m-n1, n2, a( n1+1, n1+1 ), lda,
304 $ d( n1+1 ), iinfo )
305*
306 END IF
307 RETURN
308*
309* End of CLAUNHR_COL_GETRFNP2
310*
311 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
Definition cgemm.f:188
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
recursive subroutine claunhr_col_getrfnp2(m, n, a, lda, d, info)
CLAUNHR_COL_GETRFNP2
subroutine cscal(n, ca, cx, incx)
CSCAL
Definition cscal.f:78
subroutine ctrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
CTRSM
Definition ctrsm.f:180