LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ spstrf()

subroutine spstrf ( character uplo,
integer n,
real, dimension( lda, * ) a,
integer lda,
integer, dimension( n ) piv,
integer rank,
real tol,
real, dimension( 2*n ) work,
integer info )

SPSTRF computes the Cholesky factorization with complete pivoting of a real symmetric positive semidefinite matrix.

Download SPSTRF + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SPSTRF computes the Cholesky factorization with complete
!> pivoting of a real symmetric positive semidefinite matrix A.
!>
!> The factorization has the form
!>    P**T * A * P = U**T * U ,  if UPLO = 'U',
!>    P**T * A * P = L  * L**T,  if UPLO = 'L',
!> where U is an upper triangular matrix and L is lower triangular, and
!> P is stored as vector PIV.
!>
!> This algorithm does not attempt to check that A is positive
!> semidefinite. This version of the algorithm calls level 3 BLAS.
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>          Specifies whether the upper or lower triangular part of the
!>          symmetric matrix A is stored.
!>          = 'U':  Upper triangular
!>          = 'L':  Lower triangular
!> 
[in]N
!>          N is INTEGER
!>          The order of the matrix A.  N >= 0.
!> 
[in,out]A
!>          A is REAL array, dimension (LDA,N)
!>          On entry, the symmetric matrix A.  If UPLO = 'U', the leading
!>          n by n upper triangular part of A contains the upper
!>          triangular part of the matrix A, and the strictly lower
!>          triangular part of A is not referenced.  If UPLO = 'L', the
!>          leading n by n lower triangular part of A contains the lower
!>          triangular part of the matrix A, and the strictly upper
!>          triangular part of A is not referenced.
!>
!>          On exit, if INFO = 0, the factor U or L from the Cholesky
!>          factorization as above.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]PIV
!>          PIV is INTEGER array, dimension (N)
!>          PIV is such that the nonzero entries are P( PIV(K), K ) = 1.
!> 
[out]RANK
!>          RANK is INTEGER
!>          The rank of A given by the number of steps the algorithm
!>          completed.
!> 
[in]TOL
!>          TOL is REAL
!>          User defined tolerance. If TOL < 0, then N*U*MAX( A(K,K) )
!>          will be used. The algorithm terminates at the (K-1)st step
!>          if the pivot <= TOL.
!> 
[out]WORK
!>          WORK is REAL array, dimension (2*N)
!>          Work space.
!> 
[out]INFO
!>          INFO is INTEGER
!>          < 0: If INFO = -K, the K-th argument had an illegal value,
!>          = 0: algorithm completed successfully, and
!>          > 0: the matrix A is either rank deficient with computed rank
!>               as returned in RANK, or is not positive semidefinite. See
!>               Section 7 of LAPACK Working Note #161 for further
!>               information.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 138 of file spstrf.f.

140*
141* -- LAPACK computational routine --
142* -- LAPACK is a software package provided by Univ. of Tennessee, --
143* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
144*
145* .. Scalar Arguments ..
146 REAL TOL
147 INTEGER INFO, LDA, N, RANK
148 CHARACTER UPLO
149* ..
150* .. Array Arguments ..
151 REAL A( LDA, * ), WORK( 2*N )
152 INTEGER PIV( N )
153* ..
154*
155* =====================================================================
156*
157* .. Parameters ..
158 REAL ONE, ZERO
159 parameter( one = 1.0e+0, zero = 0.0e+0 )
160* ..
161* .. Local Scalars ..
162 REAL AJJ, SSTOP, STEMP
163 INTEGER I, ITEMP, J, JB, K, NB, PVT
164 LOGICAL UPPER
165* ..
166* .. External Functions ..
167 REAL SLAMCH
168 INTEGER ILAENV
169 LOGICAL LSAME, SISNAN
170 EXTERNAL slamch, ilaenv, lsame, sisnan
171* ..
172* .. External Subroutines ..
173 EXTERNAL sgemv, spstf2, sscal, sswap, ssyrk,
174 $ xerbla
175* ..
176* .. Intrinsic Functions ..
177 INTRINSIC max, min, sqrt, maxloc
178* ..
179* .. Executable Statements ..
180*
181* Test the input parameters.
182*
183 info = 0
184 upper = lsame( uplo, 'U' )
185 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
186 info = -1
187 ELSE IF( n.LT.0 ) THEN
188 info = -2
189 ELSE IF( lda.LT.max( 1, n ) ) THEN
190 info = -4
191 END IF
192 IF( info.NE.0 ) THEN
193 CALL xerbla( 'SPSTRF', -info )
194 RETURN
195 END IF
196*
197* Quick return if possible
198*
199 IF( n.EQ.0 )
200 $ RETURN
201*
202* Get block size
203*
204 nb = ilaenv( 1, 'SPOTRF', uplo, n, -1, -1, -1 )
205 IF( nb.LE.1 .OR. nb.GE.n ) THEN
206*
207* Use unblocked code
208*
209 CALL spstf2( uplo, n, a( 1, 1 ), lda, piv, rank, tol, work,
210 $ info )
211 GO TO 200
212*
213 ELSE
214*
215* Initialize PIV
216*
217 DO 100 i = 1, n
218 piv( i ) = i
219 100 CONTINUE
220*
221* Compute stopping value
222*
223 pvt = 1
224 ajj = a( pvt, pvt )
225 DO i = 2, n
226 IF( a( i, i ).GT.ajj ) THEN
227 pvt = i
228 ajj = a( pvt, pvt )
229 END IF
230 END DO
231 IF( ajj.LE.zero.OR.sisnan( ajj ) ) THEN
232 rank = 0
233 info = 1
234 GO TO 200
235 END IF
236*
237* Compute stopping value if not supplied
238*
239 IF( tol.LT.zero ) THEN
240 sstop = real( n ) * slamch( 'Epsilon' ) * ajj
241 ELSE
242 sstop = tol
243 END IF
244*
245*
246 IF( upper ) THEN
247*
248* Compute the Cholesky factorization P**T * A * P = U**T * U
249*
250 DO 140 k = 1, n, nb
251*
252* Account for last block not being NB wide
253*
254 jb = min( nb, n-k+1 )
255*
256* Set relevant part of first half of WORK to zero,
257* holds dot products
258*
259 DO 110 i = k, n
260 work( i ) = 0
261 110 CONTINUE
262*
263 DO 130 j = k, k + jb - 1
264*
265* Find pivot, test for exit, else swap rows and columns
266* Update dot products, compute possible pivots which are
267* stored in the second half of WORK
268*
269 DO 120 i = j, n
270*
271 IF( j.GT.k ) THEN
272 work( i ) = work( i ) + a( j-1, i )**2
273 END IF
274 work( n+i ) = a( i, i ) - work( i )
275*
276 120 CONTINUE
277*
278 IF( j.GT.1 ) THEN
279 itemp = maxloc( work( (n+j):(2*n) ), 1 )
280 pvt = itemp + j - 1
281 ajj = work( n+pvt )
282 IF( ajj.LE.sstop.OR.sisnan( ajj ) ) THEN
283 a( j, j ) = ajj
284 GO TO 190
285 END IF
286 END IF
287*
288 IF( j.NE.pvt ) THEN
289*
290* Pivot OK, so can now swap pivot rows and columns
291*
292 a( pvt, pvt ) = a( j, j )
293 CALL sswap( j-1, a( 1, j ), 1, a( 1, pvt ), 1 )
294 IF( pvt.LT.n )
295 $ CALL sswap( n-pvt, a( j, pvt+1 ), lda,
296 $ a( pvt, pvt+1 ), lda )
297 CALL sswap( pvt-j-1, a( j, j+1 ), lda,
298 $ a( j+1, pvt ), 1 )
299*
300* Swap dot products and PIV
301*
302 stemp = work( j )
303 work( j ) = work( pvt )
304 work( pvt ) = stemp
305 itemp = piv( pvt )
306 piv( pvt ) = piv( j )
307 piv( j ) = itemp
308 END IF
309*
310 ajj = sqrt( ajj )
311 a( j, j ) = ajj
312*
313* Compute elements J+1:N of row J.
314*
315 IF( j.LT.n ) THEN
316 CALL sgemv( 'Trans', j-k, n-j, -one, a( k,
317 $ j+1 ),
318 $ lda, a( k, j ), 1, one, a( j, j+1 ),
319 $ lda )
320 CALL sscal( n-j, one / ajj, a( j, j+1 ), lda )
321 END IF
322*
323 130 CONTINUE
324*
325* Update trailing matrix, J already incremented
326*
327 IF( k+jb.LE.n ) THEN
328 CALL ssyrk( 'Upper', 'Trans', n-j+1, jb, -one,
329 $ a( k, j ), lda, one, a( j, j ), lda )
330 END IF
331*
332 140 CONTINUE
333*
334 ELSE
335*
336* Compute the Cholesky factorization P**T * A * P = L * L**T
337*
338 DO 180 k = 1, n, nb
339*
340* Account for last block not being NB wide
341*
342 jb = min( nb, n-k+1 )
343*
344* Set relevant part of first half of WORK to zero,
345* holds dot products
346*
347 DO 150 i = k, n
348 work( i ) = 0
349 150 CONTINUE
350*
351 DO 170 j = k, k + jb - 1
352*
353* Find pivot, test for exit, else swap rows and columns
354* Update dot products, compute possible pivots which are
355* stored in the second half of WORK
356*
357 DO 160 i = j, n
358*
359 IF( j.GT.k ) THEN
360 work( i ) = work( i ) + a( i, j-1 )**2
361 END IF
362 work( n+i ) = a( i, i ) - work( i )
363*
364 160 CONTINUE
365*
366 IF( j.GT.1 ) THEN
367 itemp = maxloc( work( (n+j):(2*n) ), 1 )
368 pvt = itemp + j - 1
369 ajj = work( n+pvt )
370 IF( ajj.LE.sstop.OR.sisnan( ajj ) ) THEN
371 a( j, j ) = ajj
372 GO TO 190
373 END IF
374 END IF
375*
376 IF( j.NE.pvt ) THEN
377*
378* Pivot OK, so can now swap pivot rows and columns
379*
380 a( pvt, pvt ) = a( j, j )
381 CALL sswap( j-1, a( j, 1 ), lda, a( pvt, 1 ),
382 $ lda )
383 IF( pvt.LT.n )
384 $ CALL sswap( n-pvt, a( pvt+1, j ), 1,
385 $ a( pvt+1, pvt ), 1 )
386 CALL sswap( pvt-j-1, a( j+1, j ), 1, a( pvt,
387 $ j+1 ),
388 $ lda )
389*
390* Swap dot products and PIV
391*
392 stemp = work( j )
393 work( j ) = work( pvt )
394 work( pvt ) = stemp
395 itemp = piv( pvt )
396 piv( pvt ) = piv( j )
397 piv( j ) = itemp
398 END IF
399*
400 ajj = sqrt( ajj )
401 a( j, j ) = ajj
402*
403* Compute elements J+1:N of column J.
404*
405 IF( j.LT.n ) THEN
406 CALL sgemv( 'No Trans', n-j, j-k, -one,
407 $ a( j+1, k ), lda, a( j, k ), lda, one,
408 $ a( j+1, j ), 1 )
409 CALL sscal( n-j, one / ajj, a( j+1, j ), 1 )
410 END IF
411*
412 170 CONTINUE
413*
414* Update trailing matrix, J already incremented
415*
416 IF( k+jb.LE.n ) THEN
417 CALL ssyrk( 'Lower', 'No Trans', n-j+1, jb, -one,
418 $ a( j, k ), lda, one, a( j, j ), lda )
419 END IF
420*
421 180 CONTINUE
422*
423 END IF
424 END IF
425*
426* Ran to completion, A has full rank
427*
428 rank = n
429*
430 GO TO 200
431 190 CONTINUE
432*
433* Rank is the number of steps completed. Set INFO = 1 to signal
434* that the factorization cannot be used to solve a system.
435*
436 rank = j - 1
437 info = 1
438*
439 200 CONTINUE
440 RETURN
441*
442* End of SPSTRF
443*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine sgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
SGEMV
Definition sgemv.f:158
subroutine ssyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
SSYRK
Definition ssyrk.f:169
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
logical function sisnan(sin)
SISNAN tests input for NaN.
Definition sisnan.f:57
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine spstf2(uplo, n, a, lda, piv, rank, tol, work, info)
SPSTF2 computes the Cholesky factorization with complete pivoting of a real symmetric positive semide...
Definition spstf2.f:140
subroutine sscal(n, sa, sx, incx)
SSCAL
Definition sscal.f:79
subroutine sswap(n, sx, incx, sy, incy)
SSWAP
Definition sswap.f:82
Here is the call graph for this function:
Here is the caller graph for this function: