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

◆ csytf2()

subroutine csytf2 ( character uplo,
integer n,
complex, dimension( lda, * ) a,
integer lda,
integer, dimension( * ) ipiv,
integer info )

CSYTF2 computes the factorization of a real symmetric indefinite matrix, using the diagonal pivoting method (unblocked algorithm).

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

Purpose:
!>
!> CSYTF2 computes the factorization of a complex symmetric matrix A
!> using the Bunch-Kaufman diagonal pivoting method:
!>
!>    A = U*D*U**T  or  A = L*D*L**T
!>
!> where U (or L) is a product of permutation and unit upper (lower)
!> triangular matrices, U**T is the transpose of U, and D is symmetric and
!> block diagonal with 1-by-1 and 2-by-2 diagonal blocks.
!>
!> This is the unblocked version of the algorithm, calling Level 2 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 COMPLEX 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, the block diagonal matrix D and the multipliers used
!>          to obtain the factor U or L (see below for further details).
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[out]IPIV
!>          IPIV is INTEGER array, dimension (N)
!>          Details of the interchanges and the block structure of D.
!>
!>          If UPLO = 'U':
!>             If IPIV(k) > 0, then rows and columns k and IPIV(k) were
!>             interchanged and D(k,k) is a 1-by-1 diagonal block.
!>
!>             If IPIV(k) = IPIV(k-1) < 0, then rows and columns
!>             k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k)
!>             is a 2-by-2 diagonal block.
!>
!>          If UPLO = 'L':
!>             If IPIV(k) > 0, then rows and columns k and IPIV(k) were
!>             interchanged and D(k,k) is a 1-by-1 diagonal block.
!>
!>             If IPIV(k) = IPIV(k+1) < 0, then rows and columns
!>             k+1 and -IPIV(k) were interchanged and D(k:k+1,k:k+1)
!>             is a 2-by-2 diagonal block.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0: successful exit
!>          < 0: if INFO = -k, the k-th argument had an illegal value
!>          > 0: if INFO = k, D(k,k) is exactly zero.  The factorization
!>               has been completed, but the block diagonal matrix D is
!>               exactly singular, and division by zero will occur if it
!>               is used to solve a system of equations.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
!>
!>  If UPLO = 'U', then A = U*D*U**T, where
!>     U = P(n)*U(n)* ... *P(k)U(k)* ...,
!>  i.e., U is a product of terms P(k)*U(k), where k decreases from n to
!>  1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
!>  and 2-by-2 diagonal blocks D(k).  P(k) is a permutation matrix as
!>  defined by IPIV(k), and U(k) is a unit upper triangular matrix, such
!>  that if the diagonal block D(k) is of order s (s = 1 or 2), then
!>
!>             (   I    v    0   )   k-s
!>     U(k) =  (   0    I    0   )   s
!>             (   0    0    I   )   n-k
!>                k-s   s   n-k
!>
!>  If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).
!>  If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),
!>  and A(k,k), and v overwrites A(1:k-2,k-1:k).
!>
!>  If UPLO = 'L', then A = L*D*L**T, where
!>     L = P(1)*L(1)* ... *P(k)*L(k)* ...,
!>  i.e., L is a product of terms P(k)*L(k), where k increases from 1 to
!>  n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
!>  and 2-by-2 diagonal blocks D(k).  P(k) is a permutation matrix as
!>  defined by IPIV(k), and L(k) is a unit lower triangular matrix, such
!>  that if the diagonal block D(k) is of order s (s = 1 or 2), then
!>
!>             (   I    0     0   )  k-1
!>     L(k) =  (   0    I     0   )  s
!>             (   0    v     I   )  n-k-s+1
!>                k-1   s  n-k-s+1
!>
!>  If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).
!>  If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),
!>  and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).
!> 
Contributors:
!>
!>  09-29-06 - patch from
!>    Bobby Cheng, MathWorks
!>
!>    Replace l.209 and l.377
!>         IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN
!>    by
!>         IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. SISNAN(ABSAKK) ) THEN
!>
!>  1-96 - Based on modifications by J. Lewis, Boeing Computer Services
!>         Company
!> 

Definition at line 188 of file csytf2.f.

189*
190* -- LAPACK computational routine --
191* -- LAPACK is a software package provided by Univ. of Tennessee, --
192* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
193*
194* .. Scalar Arguments ..
195 CHARACTER UPLO
196 INTEGER INFO, LDA, N
197* ..
198* .. Array Arguments ..
199 INTEGER IPIV( * )
200 COMPLEX A( LDA, * )
201* ..
202*
203* =====================================================================
204*
205* .. Parameters ..
206 REAL ZERO, ONE
207 parameter( zero = 0.0e+0, one = 1.0e+0 )
208 REAL EIGHT, SEVTEN
209 parameter( eight = 8.0e+0, sevten = 17.0e+0 )
210 COMPLEX CONE
211 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
212* ..
213* .. Local Scalars ..
214 LOGICAL UPPER
215 INTEGER I, IMAX, J, JMAX, K, KK, KP, KSTEP
216 REAL ABSAKK, ALPHA, COLMAX, ROWMAX
217 COMPLEX D11, D12, D21, D22, R1, T, WK, WKM1, WKP1, Z
218* ..
219* .. External Functions ..
220 LOGICAL LSAME, SISNAN
221 INTEGER ICAMAX
222 EXTERNAL lsame, icamax, sisnan
223* ..
224* .. External Subroutines ..
225 EXTERNAL cscal, cswap, csyr, xerbla
226* ..
227* .. Intrinsic Functions ..
228 INTRINSIC abs, aimag, max, real, sqrt
229* ..
230* .. Statement Functions ..
231 REAL CABS1
232* ..
233* .. Statement Function definitions ..
234 cabs1( z ) = abs( real( z ) ) + abs( aimag( z ) )
235* ..
236* .. Executable Statements ..
237*
238* Test the input parameters.
239*
240 info = 0
241 upper = lsame( uplo, 'U' )
242 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
243 info = -1
244 ELSE IF( n.LT.0 ) THEN
245 info = -2
246 ELSE IF( lda.LT.max( 1, n ) ) THEN
247 info = -4
248 END IF
249 IF( info.NE.0 ) THEN
250 CALL xerbla( 'CSYTF2', -info )
251 RETURN
252 END IF
253*
254* Initialize ALPHA for use in choosing pivot block size.
255*
256 alpha = ( one+sqrt( sevten ) ) / eight
257*
258 IF( upper ) THEN
259*
260* Factorize A as U*D*U**T using the upper triangle of A
261*
262* K is the main loop index, decreasing from N to 1 in steps of
263* 1 or 2
264*
265 k = n
266 10 CONTINUE
267*
268* If K < 1, exit from loop
269*
270 IF( k.LT.1 )
271 $ GO TO 70
272 kstep = 1
273*
274* Determine rows and columns to be interchanged and whether
275* a 1-by-1 or 2-by-2 pivot block will be used
276*
277 absakk = cabs1( a( k, k ) )
278*
279* IMAX is the row-index of the largest off-diagonal element in
280* column K, and COLMAX is its absolute value.
281* Determine both COLMAX and IMAX.
282*
283 IF( k.GT.1 ) THEN
284 imax = icamax( k-1, a( 1, k ), 1 )
285 colmax = cabs1( a( imax, k ) )
286 ELSE
287 colmax = zero
288 END IF
289*
290 IF( max( absakk, colmax ).EQ.zero .OR. sisnan(absakk) ) THEN
291*
292* Column K is zero or underflow, or contains a NaN:
293* set INFO and continue
294*
295 IF( info.EQ.0 )
296 $ info = k
297 kp = k
298 ELSE
299 IF( absakk.GE.alpha*colmax ) THEN
300*
301* no interchange, use 1-by-1 pivot block
302*
303 kp = k
304 ELSE
305*
306* JMAX is the column-index of the largest off-diagonal
307* element in row IMAX, and ROWMAX is its absolute value
308*
309 jmax = imax + icamax( k-imax, a( imax, imax+1 ), lda )
310 rowmax = cabs1( a( imax, jmax ) )
311 IF( imax.GT.1 ) THEN
312 jmax = icamax( imax-1, a( 1, imax ), 1 )
313 rowmax = max( rowmax, cabs1( a( jmax, imax ) ) )
314 END IF
315*
316 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
317*
318* no interchange, use 1-by-1 pivot block
319*
320 kp = k
321 ELSE IF( cabs1( a( imax, imax ) ).GE.alpha*rowmax ) THEN
322*
323* interchange rows and columns K and IMAX, use 1-by-1
324* pivot block
325*
326 kp = imax
327 ELSE
328*
329* interchange rows and columns K-1 and IMAX, use 2-by-2
330* pivot block
331*
332 kp = imax
333 kstep = 2
334 END IF
335 END IF
336*
337 kk = k - kstep + 1
338 IF( kp.NE.kk ) THEN
339*
340* Interchange rows and columns KK and KP in the leading
341* submatrix A(1:k,1:k)
342*
343 CALL cswap( kp-1, a( 1, kk ), 1, a( 1, kp ), 1 )
344 CALL cswap( kk-kp-1, a( kp+1, kk ), 1, a( kp, kp+1 ),
345 $ lda )
346 t = a( kk, kk )
347 a( kk, kk ) = a( kp, kp )
348 a( kp, kp ) = t
349 IF( kstep.EQ.2 ) THEN
350 t = a( k-1, k )
351 a( k-1, k ) = a( kp, k )
352 a( kp, k ) = t
353 END IF
354 END IF
355*
356* Update the leading submatrix
357*
358 IF( kstep.EQ.1 ) THEN
359*
360* 1-by-1 pivot block D(k): column k now holds
361*
362* W(k) = U(k)*D(k)
363*
364* where U(k) is the k-th column of U
365*
366* Perform a rank-1 update of A(1:k-1,1:k-1) as
367*
368* A := A - U(k)*D(k)*U(k)**T = A - W(k)*1/D(k)*W(k)**T
369*
370 r1 = cone / a( k, k )
371 CALL csyr( uplo, k-1, -r1, a( 1, k ), 1, a, lda )
372*
373* Store U(k) in column k
374*
375 CALL cscal( k-1, r1, a( 1, k ), 1 )
376 ELSE
377*
378* 2-by-2 pivot block D(k): columns k and k-1 now hold
379*
380* ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)
381*
382* where U(k) and U(k-1) are the k-th and (k-1)-th columns
383* of U
384*
385* Perform a rank-2 update of A(1:k-2,1:k-2) as
386*
387* A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T
388* = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )**T
389*
390 IF( k.GT.2 ) THEN
391*
392 d12 = a( k-1, k )
393 d22 = a( k-1, k-1 ) / d12
394 d11 = a( k, k ) / d12
395 t = cone / ( d11*d22-cone )
396 d12 = t / d12
397*
398 DO 30 j = k - 2, 1, -1
399 wkm1 = d12*( d11*a( j, k-1 )-a( j, k ) )
400 wk = d12*( d22*a( j, k )-a( j, k-1 ) )
401 DO 20 i = j, 1, -1
402 a( i, j ) = a( i, j ) - a( i, k )*wk -
403 $ a( i, k-1 )*wkm1
404 20 CONTINUE
405 a( j, k ) = wk
406 a( j, k-1 ) = wkm1
407 30 CONTINUE
408*
409 END IF
410*
411 END IF
412 END IF
413*
414* Store details of the interchanges in IPIV
415*
416 IF( kstep.EQ.1 ) THEN
417 ipiv( k ) = kp
418 ELSE
419 ipiv( k ) = -kp
420 ipiv( k-1 ) = -kp
421 END IF
422*
423* Decrease K and return to the start of the main loop
424*
425 k = k - kstep
426 GO TO 10
427*
428 ELSE
429*
430* Factorize A as L*D*L**T using the lower triangle of A
431*
432* K is the main loop index, increasing from 1 to N in steps of
433* 1 or 2
434*
435 k = 1
436 40 CONTINUE
437*
438* If K > N, exit from loop
439*
440 IF( k.GT.n )
441 $ GO TO 70
442 kstep = 1
443*
444* Determine rows and columns to be interchanged and whether
445* a 1-by-1 or 2-by-2 pivot block will be used
446*
447 absakk = cabs1( a( k, k ) )
448*
449* IMAX is the row-index of the largest off-diagonal element in
450* column K, and COLMAX is its absolute value.
451* Determine both COLMAX and IMAX.
452*
453 IF( k.LT.n ) THEN
454 imax = k + icamax( n-k, a( k+1, k ), 1 )
455 colmax = cabs1( a( imax, k ) )
456 ELSE
457 colmax = zero
458 END IF
459*
460 IF( max( absakk, colmax ).EQ.zero .OR. sisnan(absakk) ) THEN
461*
462* Column K is zero or underflow, or contains a NaN:
463* set INFO and continue
464*
465 IF( info.EQ.0 )
466 $ info = k
467 kp = k
468 ELSE
469 IF( absakk.GE.alpha*colmax ) THEN
470*
471* no interchange, use 1-by-1 pivot block
472*
473 kp = k
474 ELSE
475*
476* JMAX is the column-index of the largest off-diagonal
477* element in row IMAX, and ROWMAX is its absolute value
478*
479 jmax = k - 1 + icamax( imax-k, a( imax, k ), lda )
480 rowmax = cabs1( a( imax, jmax ) )
481 IF( imax.LT.n ) THEN
482 jmax = imax + icamax( n-imax, a( imax+1, imax ),
483 $ 1 )
484 rowmax = max( rowmax, cabs1( a( jmax, imax ) ) )
485 END IF
486*
487 IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
488*
489* no interchange, use 1-by-1 pivot block
490*
491 kp = k
492 ELSE IF( cabs1( a( imax, imax ) ).GE.alpha*rowmax ) THEN
493*
494* interchange rows and columns K and IMAX, use 1-by-1
495* pivot block
496*
497 kp = imax
498 ELSE
499*
500* interchange rows and columns K+1 and IMAX, use 2-by-2
501* pivot block
502*
503 kp = imax
504 kstep = 2
505 END IF
506 END IF
507*
508 kk = k + kstep - 1
509 IF( kp.NE.kk ) THEN
510*
511* Interchange rows and columns KK and KP in the trailing
512* submatrix A(k:n,k:n)
513*
514 IF( kp.LT.n )
515 $ CALL cswap( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ),
516 $ 1 )
517 CALL cswap( kp-kk-1, a( kk+1, kk ), 1, a( kp, kk+1 ),
518 $ lda )
519 t = a( kk, kk )
520 a( kk, kk ) = a( kp, kp )
521 a( kp, kp ) = t
522 IF( kstep.EQ.2 ) THEN
523 t = a( k+1, k )
524 a( k+1, k ) = a( kp, k )
525 a( kp, k ) = t
526 END IF
527 END IF
528*
529* Update the trailing submatrix
530*
531 IF( kstep.EQ.1 ) THEN
532*
533* 1-by-1 pivot block D(k): column k now holds
534*
535* W(k) = L(k)*D(k)
536*
537* where L(k) is the k-th column of L
538*
539 IF( k.LT.n ) THEN
540*
541* Perform a rank-1 update of A(k+1:n,k+1:n) as
542*
543* A := A - L(k)*D(k)*L(k)**T = A - W(k)*(1/D(k))*W(k)**T
544*
545 r1 = cone / a( k, k )
546 CALL csyr( uplo, n-k, -r1, a( k+1, k ), 1,
547 $ a( k+1, k+1 ), lda )
548*
549* Store L(k) in column K
550*
551 CALL cscal( n-k, r1, a( k+1, k ), 1 )
552 END IF
553 ELSE
554*
555* 2-by-2 pivot block D(k)
556*
557 IF( k.LT.n-1 ) THEN
558*
559* Perform a rank-2 update of A(k+2:n,k+2:n) as
560*
561* A := A - ( L(k) L(k+1) )*D(k)*( L(k) L(k+1) )**T
562* = A - ( W(k) W(k+1) )*inv(D(k))*( W(k) W(k+1) )**T
563*
564* where L(k) and L(k+1) are the k-th and (k+1)-th
565* columns of L
566*
567 d21 = a( k+1, k )
568 d11 = a( k+1, k+1 ) / d21
569 d22 = a( k, k ) / d21
570 t = cone / ( d11*d22-cone )
571 d21 = t / d21
572*
573 DO 60 j = k + 2, n
574 wk = d21*( d11*a( j, k )-a( j, k+1 ) )
575 wkp1 = d21*( d22*a( j, k+1 )-a( j, k ) )
576 DO 50 i = j, n
577 a( i, j ) = a( i, j ) - a( i, k )*wk -
578 $ a( i, k+1 )*wkp1
579 50 CONTINUE
580 a( j, k ) = wk
581 a( j, k+1 ) = wkp1
582 60 CONTINUE
583 END IF
584 END IF
585 END IF
586*
587* Store details of the interchanges in IPIV
588*
589 IF( kstep.EQ.1 ) THEN
590 ipiv( k ) = kp
591 ELSE
592 ipiv( k ) = -kp
593 ipiv( k+1 ) = -kp
594 END IF
595*
596* Increase K and return to the start of the main loop
597*
598 k = k + kstep
599 GO TO 40
600*
601 END IF
602*
603 70 CONTINUE
604 RETURN
605*
606* End of CSYTF2
607*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine csyr(uplo, n, alpha, x, incx, a, lda)
CSYR performs the symmetric rank-1 update of a complex symmetric matrix.
Definition csyr.f:133
integer function icamax(n, cx, incx)
ICAMAX
Definition icamax.f:71
logical function sisnan(sin)
SISNAN tests input for NaN.
Definition sisnan.f:57
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine cscal(n, ca, cx, incx)
CSCAL
Definition cscal.f:78
subroutine cswap(n, cx, incx, cy, incy)
CSWAP
Definition cswap.f:81
Here is the call graph for this function:
Here is the caller graph for this function: