LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dsytrf_rk.f
Go to the documentation of this file.
1*> \brief \b DSYTRF_RK computes the factorization of a real symmetric indefinite matrix using the bounded Bunch-Kaufman (rook) diagonal pivoting method (BLAS3 blocked algorithm).
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSYTRF_RK + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsytrf_rk.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsytrf_rk.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsytrf_rk.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSYTRF_RK( UPLO, N, A, LDA, E, IPIV, WORK, LWORK,
20* INFO )
21*
22* .. Scalar Arguments ..
23* CHARACTER UPLO
24* INTEGER INFO, LDA, LWORK, N
25* ..
26* .. Array Arguments ..
27* INTEGER IPIV( * )
28* DOUBLE PRECISION A( LDA, * ), E ( * ), WORK( * )
29* ..
30*
31*
32*> \par Purpose:
33* =============
34*>
35*> \verbatim
36*> DSYTRF_RK computes the factorization of a real symmetric matrix A
37*> using the bounded Bunch-Kaufman (rook) diagonal pivoting method:
38*>
39*> A = P*U*D*(U**T)*(P**T) or A = P*L*D*(L**T)*(P**T),
40*>
41*> where U (or L) is unit upper (or lower) triangular matrix,
42*> U**T (or L**T) is the transpose of U (or L), P is a permutation
43*> matrix, P**T is the transpose of P, and D is symmetric and block
44*> diagonal with 1-by-1 and 2-by-2 diagonal blocks.
45*>
46*> This is the blocked version of the algorithm, calling Level 3 BLAS.
47*> For more information see Further Details section.
48*> \endverbatim
49*
50* Arguments:
51* ==========
52*
53*> \param[in] UPLO
54*> \verbatim
55*> UPLO is CHARACTER*1
56*> Specifies whether the upper or lower triangular part of the
57*> symmetric matrix A is stored:
58*> = 'U': Upper triangular
59*> = 'L': Lower triangular
60*> \endverbatim
61*>
62*> \param[in] N
63*> \verbatim
64*> N is INTEGER
65*> The order of the matrix A. N >= 0.
66*> \endverbatim
67*>
68*> \param[in,out] A
69*> \verbatim
70*> A is DOUBLE PRECISION array, dimension (LDA,N)
71*> On entry, the symmetric matrix A.
72*> If UPLO = 'U': the leading N-by-N upper triangular part
73*> of A contains the upper triangular part of the matrix A,
74*> and the strictly lower triangular part of A is not
75*> referenced.
76*>
77*> If UPLO = 'L': the leading N-by-N lower triangular part
78*> of A contains the lower triangular part of the matrix A,
79*> and the strictly upper triangular part of A is not
80*> referenced.
81*>
82*> On exit, contains:
83*> a) ONLY diagonal elements of the symmetric block diagonal
84*> matrix D on the diagonal of A, i.e. D(k,k) = A(k,k);
85*> (superdiagonal (or subdiagonal) elements of D
86*> are stored on exit in array E), and
87*> b) If UPLO = 'U': factor U in the superdiagonal part of A.
88*> If UPLO = 'L': factor L in the subdiagonal part of A.
89*> \endverbatim
90*>
91*> \param[in] LDA
92*> \verbatim
93*> LDA is INTEGER
94*> The leading dimension of the array A. LDA >= max(1,N).
95*> \endverbatim
96*>
97*> \param[out] E
98*> \verbatim
99*> E is DOUBLE PRECISION array, dimension (N)
100*> On exit, contains the superdiagonal (or subdiagonal)
101*> elements of the symmetric block diagonal matrix D
102*> with 1-by-1 or 2-by-2 diagonal blocks, where
103*> If UPLO = 'U': E(i) = D(i-1,i), i=2:N, E(1) is set to 0;
104*> If UPLO = 'L': E(i) = D(i+1,i), i=1:N-1, E(N) is set to 0.
105*>
106*> NOTE: For 1-by-1 diagonal block D(k), where
107*> 1 <= k <= N, the element E(k) is set to 0 in both
108*> UPLO = 'U' or UPLO = 'L' cases.
109*> \endverbatim
110*>
111*> \param[out] IPIV
112*> \verbatim
113*> IPIV is INTEGER array, dimension (N)
114*> IPIV describes the permutation matrix P in the factorization
115*> of matrix A as follows. The absolute value of IPIV(k)
116*> represents the index of row and column that were
117*> interchanged with the k-th row and column. The value of UPLO
118*> describes the order in which the interchanges were applied.
119*> Also, the sign of IPIV represents the block structure of
120*> the symmetric block diagonal matrix D with 1-by-1 or 2-by-2
121*> diagonal blocks which correspond to 1 or 2 interchanges
122*> at each factorization step. For more info see Further
123*> Details section.
124*>
125*> If UPLO = 'U',
126*> ( in factorization order, k decreases from N to 1 ):
127*> a) A single positive entry IPIV(k) > 0 means:
128*> D(k,k) is a 1-by-1 diagonal block.
129*> If IPIV(k) != k, rows and columns k and IPIV(k) were
130*> interchanged in the matrix A(1:N,1:N);
131*> If IPIV(k) = k, no interchange occurred.
132*>
133*> b) A pair of consecutive negative entries
134*> IPIV(k) < 0 and IPIV(k-1) < 0 means:
135*> D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
136*> (NOTE: negative entries in IPIV appear ONLY in pairs).
137*> 1) If -IPIV(k) != k, rows and columns
138*> k and -IPIV(k) were interchanged
139*> in the matrix A(1:N,1:N).
140*> If -IPIV(k) = k, no interchange occurred.
141*> 2) If -IPIV(k-1) != k-1, rows and columns
142*> k-1 and -IPIV(k-1) were interchanged
143*> in the matrix A(1:N,1:N).
144*> If -IPIV(k-1) = k-1, no interchange occurred.
145*>
146*> c) In both cases a) and b), always ABS( IPIV(k) ) <= k.
147*>
148*> d) NOTE: Any entry IPIV(k) is always NONZERO on output.
149*>
150*> If UPLO = 'L',
151*> ( in factorization order, k increases from 1 to N ):
152*> a) A single positive entry IPIV(k) > 0 means:
153*> D(k,k) is a 1-by-1 diagonal block.
154*> If IPIV(k) != k, rows and columns k and IPIV(k) were
155*> interchanged in the matrix A(1:N,1:N).
156*> If IPIV(k) = k, no interchange occurred.
157*>
158*> b) A pair of consecutive negative entries
159*> IPIV(k) < 0 and IPIV(k+1) < 0 means:
160*> D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
161*> (NOTE: negative entries in IPIV appear ONLY in pairs).
162*> 1) If -IPIV(k) != k, rows and columns
163*> k and -IPIV(k) were interchanged
164*> in the matrix A(1:N,1:N).
165*> If -IPIV(k) = k, no interchange occurred.
166*> 2) If -IPIV(k+1) != k+1, rows and columns
167*> k-1 and -IPIV(k-1) were interchanged
168*> in the matrix A(1:N,1:N).
169*> If -IPIV(k+1) = k+1, no interchange occurred.
170*>
171*> c) In both cases a) and b), always ABS( IPIV(k) ) >= k.
172*>
173*> d) NOTE: Any entry IPIV(k) is always NONZERO on output.
174*> \endverbatim
175*>
176*> \param[out] WORK
177*> \verbatim
178*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)).
179*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
180*> \endverbatim
181*>
182*> \param[in] LWORK
183*> \verbatim
184*> LWORK is INTEGER
185*> The length of WORK. LWORK >= 1. For best performance
186*> LWORK >= N*NB, where NB is the block size returned
187*> by ILAENV.
188*>
189*> If LWORK = -1, then a workspace query is assumed;
190*> the routine only calculates the optimal size of the WORK
191*> array, returns this value as the first entry of the WORK
192*> array, and no error message related to LWORK is issued
193*> by XERBLA.
194*> \endverbatim
195*>
196*> \param[out] INFO
197*> \verbatim
198*> INFO is INTEGER
199*> = 0: successful exit
200*>
201*> < 0: If INFO = -k, the k-th argument had an illegal value
202*>
203*> > 0: If INFO = k, the matrix A is singular, because:
204*> If UPLO = 'U': column k in the upper
205*> triangular part of A contains all zeros.
206*> If UPLO = 'L': column k in the lower
207*> triangular part of A contains all zeros.
208*>
209*> Therefore D(k,k) is exactly zero, and superdiagonal
210*> elements of column k of U (or subdiagonal elements of
211*> column k of L ) are all zeros. The factorization has
212*> been completed, but the block diagonal matrix D is
213*> exactly singular, and division by zero will occur if
214*> it is used to solve a system of equations.
215*>
216*> NOTE: INFO only stores the first occurrence of
217*> a singularity, any subsequent occurrence of singularity
218*> is not stored in INFO even though the factorization
219*> always completes.
220*> \endverbatim
221*
222* Authors:
223* ========
224*
225*> \author Univ. of Tennessee
226*> \author Univ. of California Berkeley
227*> \author Univ. of Colorado Denver
228*> \author NAG Ltd.
229*
230*> \ingroup hetrf_rk
231*
232*> \par Further Details:
233* =====================
234*>
235*> \verbatim
236*> TODO: put correct description
237*> \endverbatim
238*
239*> \par Contributors:
240* ==================
241*>
242*> \verbatim
243*>
244*> December 2016, Igor Kozachenko,
245*> Computer Science Division,
246*> University of California, Berkeley
247*>
248*> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
249*> School of Mathematics,
250*> University of Manchester
251*>
252*> \endverbatim
253*
254* =====================================================================
255 SUBROUTINE dsytrf_rk( UPLO, N, A, LDA, E, IPIV, WORK, LWORK,
256 $ INFO )
257*
258* -- LAPACK computational routine --
259* -- LAPACK is a software package provided by Univ. of Tennessee, --
260* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
261*
262* .. Scalar Arguments ..
263 CHARACTER UPLO
264 INTEGER INFO, LDA, LWORK, N
265* ..
266* .. Array Arguments ..
267 INTEGER IPIV( * )
268 DOUBLE PRECISION A( LDA, * ), E( * ), WORK( * )
269* ..
270*
271* =====================================================================
272*
273* .. Local Scalars ..
274 LOGICAL LQUERY, UPPER
275 INTEGER I, IINFO, IP, IWS, K, KB, LDWORK, LWKOPT,
276 $ nb, nbmin
277* ..
278* .. External Functions ..
279 LOGICAL LSAME
280 INTEGER ILAENV
281 EXTERNAL lsame, ilaenv
282* ..
283* .. External Subroutines ..
284 EXTERNAL dlasyf_rk, dsytf2_rk, dswap, xerbla
285* ..
286* .. Intrinsic Functions ..
287 INTRINSIC abs, max
288* ..
289* .. Executable Statements ..
290*
291* Test the input parameters.
292*
293 info = 0
294 upper = lsame( uplo, 'U' )
295 lquery = ( lwork.EQ.-1 )
296 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
297 info = -1
298 ELSE IF( n.LT.0 ) THEN
299 info = -2
300 ELSE IF( lda.LT.max( 1, n ) ) THEN
301 info = -4
302 ELSE IF( lwork.LT.1 .AND. .NOT.lquery ) THEN
303 info = -8
304 END IF
305*
306 IF( info.EQ.0 ) THEN
307*
308* Determine the block size
309*
310 nb = ilaenv( 1, 'DSYTRF_RK', uplo, n, -1, -1, -1 )
311 lwkopt = max( 1, n*nb )
312 work( 1 ) = lwkopt
313 END IF
314*
315 IF( info.NE.0 ) THEN
316 CALL xerbla( 'DSYTRF_RK', -info )
317 RETURN
318 ELSE IF( lquery ) THEN
319 RETURN
320 END IF
321*
322 nbmin = 2
323 ldwork = n
324 IF( nb.GT.1 .AND. nb.LT.n ) THEN
325 iws = ldwork*nb
326 IF( lwork.LT.iws ) THEN
327 nb = max( lwork / ldwork, 1 )
328 nbmin = max( 2, ilaenv( 2, 'DSYTRF_RK',
329 $ uplo, n, -1, -1, -1 ) )
330 END IF
331 ELSE
332 iws = 1
333 END IF
334 IF( nb.LT.nbmin )
335 $ nb = n
336*
337 IF( upper ) THEN
338*
339* Factorize A as U*D*U**T using the upper triangle of A
340*
341* K is the main loop index, decreasing from N to 1 in steps of
342* KB, where KB is the number of columns factorized by DLASYF_RK;
343* KB is either NB or NB-1, or K for the last block
344*
345 k = n
346 10 CONTINUE
347*
348* If K < 1, exit from loop
349*
350 IF( k.LT.1 )
351 $ GO TO 15
352*
353 IF( k.GT.nb ) THEN
354*
355* Factorize columns k-kb+1:k of A and use blocked code to
356* update columns 1:k-kb
357*
358 CALL dlasyf_rk( uplo, k, nb, kb, a, lda, e,
359 $ ipiv, work, ldwork, iinfo )
360 ELSE
361*
362* Use unblocked code to factorize columns 1:k of A
363*
364 CALL dsytf2_rk( uplo, k, a, lda, e, ipiv, iinfo )
365 kb = k
366 END IF
367*
368* Set INFO on the first occurrence of a zero pivot
369*
370 IF( info.EQ.0 .AND. iinfo.GT.0 )
371 $ info = iinfo
372*
373* No need to adjust IPIV
374*
375*
376* Apply permutations to the leading panel 1:k-1
377*
378* Read IPIV from the last block factored, i.e.
379* indices k-kb+1:k and apply row permutations to the
380* last k+1 colunms k+1:N after that block
381* (We can do the simple loop over IPIV with decrement -1,
382* since the ABS value of IPIV( I ) represents the row index
383* of the interchange with row i in both 1x1 and 2x2 pivot cases)
384*
385 IF( k.LT.n ) THEN
386 DO i = k, ( k - kb + 1 ), -1
387 ip = abs( ipiv( i ) )
388 IF( ip.NE.i ) THEN
389 CALL dswap( n-k, a( i, k+1 ), lda,
390 $ a( ip, k+1 ), lda )
391 END IF
392 END DO
393 END IF
394*
395* Decrease K and return to the start of the main loop
396*
397 k = k - kb
398 GO TO 10
399*
400* This label is the exit from main loop over K decreasing
401* from N to 1 in steps of KB
402*
403 15 CONTINUE
404*
405 ELSE
406*
407* Factorize A as L*D*L**T using the lower triangle of A
408*
409* K is the main loop index, increasing from 1 to N in steps of
410* KB, where KB is the number of columns factorized by DLASYF_RK;
411* KB is either NB or NB-1, or N-K+1 for the last block
412*
413 k = 1
414 20 CONTINUE
415*
416* If K > N, exit from loop
417*
418 IF( k.GT.n )
419 $ GO TO 35
420*
421 IF( k.LE.n-nb ) THEN
422*
423* Factorize columns k:k+kb-1 of A and use blocked code to
424* update columns k+kb:n
425*
426 CALL dlasyf_rk( uplo, n-k+1, nb, kb, a( k, k ), lda,
427 $ e( k ),
428 $ ipiv( k ), work, ldwork, iinfo )
429
430
431 ELSE
432*
433* Use unblocked code to factorize columns k:n of A
434*
435 CALL dsytf2_rk( uplo, n-k+1, a( k, k ), lda, e( k ),
436 $ ipiv( k ), iinfo )
437 kb = n - k + 1
438*
439 END IF
440*
441* Set INFO on the first occurrence of a zero pivot
442*
443 IF( info.EQ.0 .AND. iinfo.GT.0 )
444 $ info = iinfo + k - 1
445*
446* Adjust IPIV
447*
448 DO i = k, k + kb - 1
449 IF( ipiv( i ).GT.0 ) THEN
450 ipiv( i ) = ipiv( i ) + k - 1
451 ELSE
452 ipiv( i ) = ipiv( i ) - k + 1
453 END IF
454 END DO
455*
456* Apply permutations to the leading panel 1:k-1
457*
458* Read IPIV from the last block factored, i.e.
459* indices k:k+kb-1 and apply row permutations to the
460* first k-1 colunms 1:k-1 before that block
461* (We can do the simple loop over IPIV with increment 1,
462* since the ABS value of IPIV( I ) represents the row index
463* of the interchange with row i in both 1x1 and 2x2 pivot cases)
464*
465 IF( k.GT.1 ) THEN
466 DO i = k, ( k + kb - 1 ), 1
467 ip = abs( ipiv( i ) )
468 IF( ip.NE.i ) THEN
469 CALL dswap( k-1, a( i, 1 ), lda,
470 $ a( ip, 1 ), lda )
471 END IF
472 END DO
473 END IF
474*
475* Increase K and return to the start of the main loop
476*
477 k = k + kb
478 GO TO 20
479*
480* This label is the exit from main loop over K increasing
481* from 1 to N in steps of KB
482*
483 35 CONTINUE
484*
485* End Lower
486*
487 END IF
488*
489 work( 1 ) = lwkopt
490 RETURN
491*
492* End of DSYTRF_RK
493*
494 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dsytf2_rk(uplo, n, a, lda, e, ipiv, info)
DSYTF2_RK computes the factorization of a real symmetric indefinite matrix using the bounded Bunch-Ka...
Definition dsytf2_rk.f:239
subroutine dsytrf_rk(uplo, n, a, lda, e, ipiv, work, lwork, info)
DSYTRF_RK computes the factorization of a real symmetric indefinite matrix using the bounded Bunch-Ka...
Definition dsytrf_rk.f:257
subroutine dlasyf_rk(uplo, n, nb, kb, a, lda, e, ipiv, w, ldw, info)
DLASYF_RK computes a partial factorization of a real symmetric indefinite matrix using bounded Bunch-...
Definition dlasyf_rk.f:260
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82