LAPACK 3.12.0
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 140 of file spstrf.f.

141*
142* -- LAPACK computational routine --
143* -- LAPACK is a software package provided by Univ. of Tennessee, --
144* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
145*
146* .. Scalar Arguments ..
147 REAL TOL
148 INTEGER INFO, LDA, N, RANK
149 CHARACTER UPLO
150* ..
151* .. Array Arguments ..
152 REAL A( LDA, * ), WORK( 2*N )
153 INTEGER PIV( N )
154* ..
155*
156* =====================================================================
157*
158* .. Parameters ..
159 REAL ONE, ZERO
160 parameter( one = 1.0e+0, zero = 0.0e+0 )
161* ..
162* .. Local Scalars ..
163 REAL AJJ, SSTOP, STEMP
164 INTEGER I, ITEMP, J, JB, K, NB, PVT
165 LOGICAL UPPER
166* ..
167* .. External Functions ..
168 REAL SLAMCH
169 INTEGER ILAENV
170 LOGICAL LSAME, SISNAN
171 EXTERNAL slamch, ilaenv, lsame, sisnan
172* ..
173* .. External Subroutines ..
174 EXTERNAL sgemv, spstf2, sscal, sswap, ssyrk, 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 = 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, j+1 ),
317 $ lda, a( k, j ), 1, one, a( j, j+1 ),
318 $ lda )
319 CALL sscal( n-j, one / ajj, a( j, j+1 ), lda )
320 END IF
321*
322 130 CONTINUE
323*
324* Update trailing matrix, J already incremented
325*
326 IF( k+jb.LE.n ) THEN
327 CALL ssyrk( 'Upper', 'Trans', n-j+1, jb, -one,
328 $ a( k, j ), lda, one, a( j, j ), lda )
329 END IF
330*
331 140 CONTINUE
332*
333 ELSE
334*
335* Compute the Cholesky factorization P**T * A * P = L * L**T
336*
337 DO 180 k = 1, n, nb
338*
339* Account for last block not being NB wide
340*
341 jb = min( nb, n-k+1 )
342*
343* Set relevant part of first half of WORK to zero,
344* holds dot products
345*
346 DO 150 i = k, n
347 work( i ) = 0
348 150 CONTINUE
349*
350 DO 170 j = k, k + jb - 1
351*
352* Find pivot, test for exit, else swap rows and columns
353* Update dot products, compute possible pivots which are
354* stored in the second half of WORK
355*
356 DO 160 i = j, n
357*
358 IF( j.GT.k ) THEN
359 work( i ) = work( i ) + a( i, j-1 )**2
360 END IF
361 work( n+i ) = a( i, i ) - work( i )
362*
363 160 CONTINUE
364*
365 IF( j.GT.1 ) THEN
366 itemp = maxloc( work( (n+j):(2*n) ), 1 )
367 pvt = itemp + j - 1
368 ajj = work( n+pvt )
369 IF( ajj.LE.sstop.OR.sisnan( ajj ) ) THEN
370 a( j, j ) = ajj
371 GO TO 190
372 END IF
373 END IF
374*
375 IF( j.NE.pvt ) THEN
376*
377* Pivot OK, so can now swap pivot rows and columns
378*
379 a( pvt, pvt ) = a( j, j )
380 CALL sswap( j-1, a( j, 1 ), lda, a( pvt, 1 ), lda )
381 IF( pvt.LT.n )
382 $ CALL sswap( n-pvt, a( pvt+1, j ), 1,
383 $ a( pvt+1, pvt ), 1 )
384 CALL sswap( pvt-j-1, a( j+1, j ), 1, a( pvt, j+1 ),
385 $ lda )
386*
387* Swap dot products and PIV
388*
389 stemp = work( j )
390 work( j ) = work( pvt )
391 work( pvt ) = stemp
392 itemp = piv( pvt )
393 piv( pvt ) = piv( j )
394 piv( j ) = itemp
395 END IF
396*
397 ajj = sqrt( ajj )
398 a( j, j ) = ajj
399*
400* Compute elements J+1:N of column J.
401*
402 IF( j.LT.n ) THEN
403 CALL sgemv( 'No Trans', n-j, j-k, -one,
404 $ a( j+1, k ), lda, a( j, k ), lda, one,
405 $ a( j+1, j ), 1 )
406 CALL sscal( n-j, one / ajj, a( j+1, j ), 1 )
407 END IF
408*
409 170 CONTINUE
410*
411* Update trailing matrix, J already incremented
412*
413 IF( k+jb.LE.n ) THEN
414 CALL ssyrk( 'Lower', 'No Trans', n-j+1, jb, -one,
415 $ a( j, k ), lda, one, a( j, j ), lda )
416 END IF
417*
418 180 CONTINUE
419*
420 END IF
421 END IF
422*
423* Ran to completion, A has full rank
424*
425 rank = n
426*
427 GO TO 200
428 190 CONTINUE
429*
430* Rank is the number of steps completed. Set INFO = 1 to signal
431* that the factorization cannot be used to solve a system.
432*
433 rank = j - 1
434 info = 1
435*
436 200 CONTINUE
437 RETURN
438*
439* End of SPSTRF
440*
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:162
logical function sisnan(sin)
SISNAN tests input for NaN.
Definition sisnan.f:59
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:141
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: