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

◆ clasyf_rook()

subroutine clasyf_rook ( character uplo,
integer n,
integer nb,
integer kb,
complex, dimension( lda, * ) a,
integer lda,
integer, dimension( * ) ipiv,
complex, dimension( ldw, * ) w,
integer ldw,
integer info )

CLASYF_ROOK computes a partial factorization of a complex symmetric matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method.

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

Purpose:
!>
!> CLASYF_ROOK computes a partial factorization of a complex symmetric
!> matrix A using the bounded Bunch-Kaufman () diagonal
!> pivoting method. The partial factorization has the form:
!>
!> A  =  ( I  U12 ) ( A11  0  ) (  I       0    )  if UPLO = 'U', or:
!>       ( 0  U22 ) (  0   D  ) ( U12**T U22**T )
!>
!> A  =  ( L11  0 ) (  D   0  ) ( L11**T L21**T )  if UPLO = 'L'
!>       ( L21  I ) (  0  A22 ) (  0       I    )
!>
!> where the order of D is at most NB. The actual order is returned in
!> the argument KB, and is either NB or NB-1, or N if N <= NB.
!>
!> CLASYF_ROOK is an auxiliary routine called by CSYTRF_ROOK. It uses
!> blocked code (calling Level 3 BLAS) to update the submatrix
!> A11 (if UPLO = 'U') or A22 (if UPLO = 'L').
!> 
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]NB
!>          NB is INTEGER
!>          The maximum number of columns of the matrix A that should be
!>          factored.  NB should be at least 2 to allow for 2-by-2 pivot
!>          blocks.
!> 
[out]KB
!>          KB is INTEGER
!>          The number of columns of A that were actually factored.
!>          KB is either NB-1 or NB, or N if N <= NB.
!> 
[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, A contains details of the partial factorization.
!> 
[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':
!>             Only the last KB elements of IPIV are set.
!>
!>             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) < 0 and IPIV(k-1) < 0, then rows and
!>             columns k and -IPIV(k) were interchanged and rows and
!>             columns k-1 and -IPIV(k-1) were inerchaged,
!>             D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
!>
!>          If UPLO = 'L':
!>             Only the first KB elements of IPIV are set.
!>
!>             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) < 0 and IPIV(k+1) < 0, then rows and
!>             columns k and -IPIV(k) were interchanged and rows and
!>             columns k+1 and -IPIV(k+1) were inerchaged,
!>             D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
!> 
[out]W
!>          W is COMPLEX array, dimension (LDW,NB)
!> 
[in]LDW
!>          LDW is INTEGER
!>          The leading dimension of the array W.  LDW >= max(1,N).
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0: successful exit
!>          > 0: if INFO = k, D(k,k) is exactly zero.  The factorization
!>               has been completed, but the block diagonal matrix D is
!>               exactly singular.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
!>
!>  November 2013,     Igor Kozachenko,
!>                  Computer Science Division,
!>                  University of California, Berkeley
!>
!>  September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
!>                  School of Mathematics,
!>                  University of Manchester
!>
!> 

Definition at line 180 of file clasyf_rook.f.

182*
183* -- LAPACK computational routine --
184* -- LAPACK is a software package provided by Univ. of Tennessee, --
185* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
186*
187* .. Scalar Arguments ..
188 CHARACTER UPLO
189 INTEGER INFO, KB, LDA, LDW, N, NB
190* ..
191* .. Array Arguments ..
192 INTEGER IPIV( * )
193 COMPLEX A( LDA, * ), W( LDW, * )
194* ..
195*
196* =====================================================================
197*
198* .. Parameters ..
199 REAL ZERO, ONE
200 parameter( zero = 0.0e+0, one = 1.0e+0 )
201 REAL EIGHT, SEVTEN
202 parameter( eight = 8.0e+0, sevten = 17.0e+0 )
203 COMPLEX CONE, CZERO
204 parameter( cone = ( 1.0e+0, 0.0e+0 ),
205 $ czero = ( 0.0e+0, 0.0e+0 ) )
206* ..
207* .. Local Scalars ..
208 LOGICAL DONE
209 INTEGER IMAX, ITEMP, J, JJ, JMAX, JP1, JP2, K, KK,
210 $ KW, KKW, KP, KSTEP, P, II
211 REAL ABSAKK, ALPHA, COLMAX, ROWMAX, STEMP, SFMIN
212 COMPLEX D11, D12, D21, D22, R1, T, Z
213* ..
214* .. External Functions ..
215 LOGICAL LSAME
216 INTEGER ICAMAX
217 REAL SLAMCH
218 EXTERNAL lsame, icamax, slamch
219* ..
220* .. External Subroutines ..
221 EXTERNAL ccopy, cgemmtr, cgemv, cscal, cswap
222* ..
223* .. Intrinsic Functions ..
224 INTRINSIC abs, max, min, sqrt, aimag, real
225* ..
226* .. Statement Functions ..
227 REAL CABS1
228* ..
229* .. Statement Function definitions ..
230 cabs1( z ) = abs( real( z ) ) + abs( aimag( z ) )
231* ..
232* .. Executable Statements ..
233*
234 info = 0
235*
236* Initialize ALPHA for use in choosing pivot block size.
237*
238 alpha = ( one+sqrt( sevten ) ) / eight
239*
240* Compute machine safe minimum
241*
242 sfmin = slamch( 'S' )
243*
244 IF( lsame( uplo, 'U' ) ) THEN
245*
246* Factorize the trailing columns of A using the upper triangle
247* of A and working backwards, and compute the matrix W = U12*D
248* for use in updating A11
249*
250* K is the main loop index, decreasing from N in steps of 1 or 2
251*
252 k = n
253 10 CONTINUE
254*
255* KW is the column of W which corresponds to column K of A
256*
257 kw = nb + k - n
258*
259* Exit from loop
260*
261 IF( ( k.LE.n-nb+1 .AND. nb.LT.n ) .OR. k.LT.1 )
262 $ GO TO 30
263*
264 kstep = 1
265 p = k
266*
267* Copy column K of A to column KW of W and update it
268*
269 CALL ccopy( k, a( 1, k ), 1, w( 1, kw ), 1 )
270 IF( k.LT.n )
271 $ CALL cgemv( 'No transpose', k, n-k, -cone, a( 1, k+1 ),
272 $ lda, w( k, kw+1 ), ldw, cone, w( 1, kw ), 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( w( k, kw ) )
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, w( 1, kw ), 1 )
285 colmax = cabs1( w( imax, kw ) )
286 ELSE
287 colmax = zero
288 END IF
289*
290 IF( max( absakk, colmax ).EQ.zero ) THEN
291*
292* Column K is zero or underflow: set INFO and continue
293*
294 IF( info.EQ.0 )
295 $ info = k
296 kp = k
297 CALL ccopy( k, w( 1, kw ), 1, a( 1, k ), 1 )
298 ELSE
299*
300* ============================================================
301*
302* Test for interchange
303*
304* Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX
305* (used to handle NaN and Inf)
306*
307 IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
308*
309* no interchange, use 1-by-1 pivot block
310*
311 kp = k
312*
313 ELSE
314*
315 done = .false.
316*
317* Loop until pivot found
318*
319 12 CONTINUE
320*
321* Begin pivot search loop body
322*
323*
324* Copy column IMAX to column KW-1 of W and update it
325*
326 CALL ccopy( imax, a( 1, imax ), 1, w( 1, kw-1 ),
327 $ 1 )
328 CALL ccopy( k-imax, a( imax, imax+1 ), lda,
329 $ w( imax+1, kw-1 ), 1 )
330*
331 IF( k.LT.n )
332 $ CALL cgemv( 'No transpose', k, n-k, -cone,
333 $ a( 1, k+1 ), lda, w( imax, kw+1 ), ldw,
334 $ cone, w( 1, kw-1 ), 1 )
335*
336* JMAX is the column-index of the largest off-diagonal
337* element in row IMAX, and ROWMAX is its absolute value.
338* Determine both ROWMAX and JMAX.
339*
340 IF( imax.NE.k ) THEN
341 jmax = imax + icamax( k-imax, w( imax+1, kw-1 ),
342 $ 1 )
343 rowmax = cabs1( w( jmax, kw-1 ) )
344 ELSE
345 rowmax = zero
346 END IF
347*
348 IF( imax.GT.1 ) THEN
349 itemp = icamax( imax-1, w( 1, kw-1 ), 1 )
350 stemp = cabs1( w( itemp, kw-1 ) )
351 IF( stemp.GT.rowmax ) THEN
352 rowmax = stemp
353 jmax = itemp
354 END IF
355 END IF
356*
357* Equivalent to testing for
358* CABS1( W( IMAX, KW-1 ) ).GE.ALPHA*ROWMAX
359* (used to handle NaN and Inf)
360*
361 IF( .NOT.(cabs1( w( imax, kw-1 ) ).LT.alpha*rowmax ) )
362 $ THEN
363*
364* interchange rows and columns K and IMAX,
365* use 1-by-1 pivot block
366*
367 kp = imax
368*
369* copy column KW-1 of W to column KW of W
370*
371 CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
372*
373 done = .true.
374*
375* Equivalent to testing for ROWMAX.EQ.COLMAX,
376* (used to handle NaN and Inf)
377*
378 ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
379 $ THEN
380*
381* interchange rows and columns K-1 and IMAX,
382* use 2-by-2 pivot block
383*
384 kp = imax
385 kstep = 2
386 done = .true.
387 ELSE
388*
389* Pivot not found: set params and repeat
390*
391 p = imax
392 colmax = rowmax
393 imax = jmax
394*
395* Copy updated JMAXth (next IMAXth) column to Kth of W
396*
397 CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
398*
399 END IF
400*
401* End pivot search loop body
402*
403 IF( .NOT. done ) GOTO 12
404*
405 END IF
406*
407* ============================================================
408*
409 kk = k - kstep + 1
410*
411* KKW is the column of W which corresponds to column KK of A
412*
413 kkw = nb + kk - n
414*
415 IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
416*
417* Copy non-updated column K to column P
418*
419 CALL ccopy( k-p, a( p+1, k ), 1, a( p, p+1 ), lda )
420 CALL ccopy( p, a( 1, k ), 1, a( 1, p ), 1 )
421*
422* Interchange rows K and P in last N-K+1 columns of A
423* and last N-K+2 columns of W
424*
425 CALL cswap( n-k+1, a( k, k ), lda, a( p, k ), lda )
426 CALL cswap( n-kk+1, w( k, kkw ), ldw, w( p, kkw ),
427 $ ldw )
428 END IF
429*
430* Updated column KP is already stored in column KKW of W
431*
432 IF( kp.NE.kk ) THEN
433*
434* Copy non-updated column KK to column KP
435*
436 a( kp, k ) = a( kk, k )
437 CALL ccopy( k-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
438 $ lda )
439 CALL ccopy( kp, a( 1, kk ), 1, a( 1, kp ), 1 )
440*
441* Interchange rows KK and KP in last N-KK+1 columns
442* of A and W
443*
444 CALL cswap( n-kk+1, a( kk, kk ), lda, a( kp, kk ),
445 $ lda )
446 CALL cswap( n-kk+1, w( kk, kkw ), ldw, w( kp, kkw ),
447 $ ldw )
448 END IF
449*
450 IF( kstep.EQ.1 ) THEN
451*
452* 1-by-1 pivot block D(k): column KW of W now holds
453*
454* W(k) = U(k)*D(k)
455*
456* where U(k) is the k-th column of U
457*
458* Store U(k) in column k of A
459*
460 CALL ccopy( k, w( 1, kw ), 1, a( 1, k ), 1 )
461 IF( k.GT.1 ) THEN
462 IF( cabs1( a( k, k ) ).GE.sfmin ) THEN
463 r1 = cone / a( k, k )
464 CALL cscal( k-1, r1, a( 1, k ), 1 )
465 ELSE IF( a( k, k ).NE.czero ) THEN
466 DO 14 ii = 1, k - 1
467 a( ii, k ) = a( ii, k ) / a( k, k )
468 14 CONTINUE
469 END IF
470 END IF
471*
472 ELSE
473*
474* 2-by-2 pivot block D(k): columns KW and KW-1 of W now
475* hold
476*
477* ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)
478*
479* where U(k) and U(k-1) are the k-th and (k-1)-th columns
480* of U
481*
482 IF( k.GT.2 ) THEN
483*
484* Store U(k) and U(k-1) in columns k and k-1 of A
485*
486 d12 = w( k-1, kw )
487 d11 = w( k, kw ) / d12
488 d22 = w( k-1, kw-1 ) / d12
489 t = cone / ( d11*d22-cone )
490 DO 20 j = 1, k - 2
491 a( j, k-1 ) = t*( (d11*w( j, kw-1 )-w( j, kw ) ) /
492 $ d12 )
493 a( j, k ) = t*( ( d22*w( j, kw )-w( j, kw-1 ) ) /
494 $ d12 )
495 20 CONTINUE
496 END IF
497*
498* Copy D(k) to A
499*
500 a( k-1, k-1 ) = w( k-1, kw-1 )
501 a( k-1, k ) = w( k-1, kw )
502 a( k, k ) = w( k, kw )
503 END IF
504 END IF
505*
506* Store details of the interchanges in IPIV
507*
508 IF( kstep.EQ.1 ) THEN
509 ipiv( k ) = kp
510 ELSE
511 ipiv( k ) = -p
512 ipiv( k-1 ) = -kp
513 END IF
514*
515* Decrease K and return to the start of the main loop
516*
517 k = k - kstep
518 GO TO 10
519*
520 30 CONTINUE
521*
522* Update the upper triangle of A11 (= A(1:k,1:k)) as
523*
524* A11 := A11 - U12*D*U12**T = A11 - U12*W**T
525*
526* (note that conjg(W) is actually stored)
527*
528 CALL cgemmtr( 'Upper', 'No transpose', 'Transpose', k, n-k,
529 $ -cone, a( 1, k+1 ), lda, w( 1, kw+1 ), ldw,
530 $ cone, a( 1, 1 ), lda )
531*
532* Put U12 in standard form by partially undoing the interchanges
533* in columns k+1:n
534*
535 j = k + 1
536 60 CONTINUE
537*
538 kstep = 1
539 jp1 = 1
540 jj = j
541 jp2 = ipiv( j )
542 IF( jp2.LT.0 ) THEN
543 jp2 = -jp2
544 j = j + 1
545 jp1 = -ipiv( j )
546 kstep = 2
547 END IF
548*
549 j = j + 1
550 IF( jp2.NE.jj .AND. j.LE.n )
551 $ CALL cswap( n-j+1, a( jp2, j ), lda, a( jj, j ), lda )
552 jj = j - 1
553 IF( jp1.NE.jj .AND. kstep.EQ.2 )
554 $ CALL cswap( n-j+1, a( jp1, j ), lda, a( jj, j ), lda )
555 IF( j.LE.n )
556 $ GO TO 60
557*
558* Set KB to the number of columns factorized
559*
560 kb = n - k
561*
562 ELSE
563*
564* Factorize the leading columns of A using the lower triangle
565* of A and working forwards, and compute the matrix W = L21*D
566* for use in updating A22
567*
568* K is the main loop index, increasing from 1 in steps of 1 or 2
569*
570 k = 1
571 70 CONTINUE
572*
573* Exit from loop
574*
575 IF( ( k.GE.nb .AND. nb.LT.n ) .OR. k.GT.n )
576 $ GO TO 90
577*
578 kstep = 1
579 p = k
580*
581* Copy column K of A to column K of W and update it
582*
583 CALL ccopy( n-k+1, a( k, k ), 1, w( k, k ), 1 )
584 IF( k.GT.1 )
585 $ CALL cgemv( 'No transpose', n-k+1, k-1, -cone, a( k, 1 ),
586 $ lda, w( k, 1 ), ldw, cone, w( k, k ), 1 )
587*
588* Determine rows and columns to be interchanged and whether
589* a 1-by-1 or 2-by-2 pivot block will be used
590*
591 absakk = cabs1( w( k, k ) )
592*
593* IMAX is the row-index of the largest off-diagonal element in
594* column K, and COLMAX is its absolute value.
595* Determine both COLMAX and IMAX.
596*
597 IF( k.LT.n ) THEN
598 imax = k + icamax( n-k, w( k+1, k ), 1 )
599 colmax = cabs1( w( imax, k ) )
600 ELSE
601 colmax = zero
602 END IF
603*
604 IF( max( absakk, colmax ).EQ.zero ) THEN
605*
606* Column K is zero or underflow: set INFO and continue
607*
608 IF( info.EQ.0 )
609 $ info = k
610 kp = k
611 CALL ccopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
612 ELSE
613*
614* ============================================================
615*
616* Test for interchange
617*
618* Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX
619* (used to handle NaN and Inf)
620*
621 IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
622*
623* no interchange, use 1-by-1 pivot block
624*
625 kp = k
626*
627 ELSE
628*
629 done = .false.
630*
631* Loop until pivot found
632*
633 72 CONTINUE
634*
635* Begin pivot search loop body
636*
637*
638* Copy column IMAX to column K+1 of W and update it
639*
640 CALL ccopy( imax-k, a( imax, k ), lda, w( k, k+1 ),
641 $ 1)
642 CALL ccopy( n-imax+1, a( imax, imax ), 1,
643 $ w( imax, k+1 ), 1 )
644 IF( k.GT.1 )
645 $ CALL cgemv( 'No transpose', n-k+1, k-1, -cone,
646 $ a( k, 1 ), lda, w( imax, 1 ), ldw,
647 $ cone, w( k, k+1 ), 1 )
648*
649* JMAX is the column-index of the largest off-diagonal
650* element in row IMAX, and ROWMAX is its absolute value.
651* Determine both ROWMAX and JMAX.
652*
653 IF( imax.NE.k ) THEN
654 jmax = k - 1 + icamax( imax-k, w( k, k+1 ), 1 )
655 rowmax = cabs1( w( jmax, k+1 ) )
656 ELSE
657 rowmax = zero
658 END IF
659*
660 IF( imax.LT.n ) THEN
661 itemp = imax + icamax( n-imax, w( imax+1, k+1 ),
662 $ 1)
663 stemp = cabs1( w( itemp, k+1 ) )
664 IF( stemp.GT.rowmax ) THEN
665 rowmax = stemp
666 jmax = itemp
667 END IF
668 END IF
669*
670* Equivalent to testing for
671* CABS1( W( IMAX, K+1 ) ).GE.ALPHA*ROWMAX
672* (used to handle NaN and Inf)
673*
674 IF( .NOT.( cabs1( w( imax, k+1 ) ).LT.alpha*rowmax ) )
675 $ THEN
676*
677* interchange rows and columns K and IMAX,
678* use 1-by-1 pivot block
679*
680 kp = imax
681*
682* copy column K+1 of W to column K of W
683*
684 CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ),
685 $ 1 )
686*
687 done = .true.
688*
689* Equivalent to testing for ROWMAX.EQ.COLMAX,
690* (used to handle NaN and Inf)
691*
692 ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
693 $ THEN
694*
695* interchange rows and columns K+1 and IMAX,
696* use 2-by-2 pivot block
697*
698 kp = imax
699 kstep = 2
700 done = .true.
701 ELSE
702*
703* Pivot not found: set params and repeat
704*
705 p = imax
706 colmax = rowmax
707 imax = jmax
708*
709* Copy updated JMAXth (next IMAXth) column to Kth of W
710*
711 CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ),
712 $ 1 )
713*
714 END IF
715*
716* End pivot search loop body
717*
718 IF( .NOT. done ) GOTO 72
719*
720 END IF
721*
722* ============================================================
723*
724 kk = k + kstep - 1
725*
726 IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
727*
728* Copy non-updated column K to column P
729*
730 CALL ccopy( p-k, a( k, k ), 1, a( p, k ), lda )
731 CALL ccopy( n-p+1, a( p, k ), 1, a( p, p ), 1 )
732*
733* Interchange rows K and P in first K columns of A
734* and first K+1 columns of W
735*
736 CALL cswap( k, a( k, 1 ), lda, a( p, 1 ), lda )
737 CALL cswap( kk, w( k, 1 ), ldw, w( p, 1 ), ldw )
738 END IF
739*
740* Updated column KP is already stored in column KK of W
741*
742 IF( kp.NE.kk ) THEN
743*
744* Copy non-updated column KK to column KP
745*
746 a( kp, k ) = a( kk, k )
747 CALL ccopy( kp-k-1, a( k+1, kk ), 1, a( kp, k+1 ),
748 $ lda )
749 CALL ccopy( n-kp+1, a( kp, kk ), 1, a( kp, kp ), 1 )
750*
751* Interchange rows KK and KP in first KK columns of A and W
752*
753 CALL cswap( kk, a( kk, 1 ), lda, a( kp, 1 ), lda )
754 CALL cswap( kk, w( kk, 1 ), ldw, w( kp, 1 ), ldw )
755 END IF
756*
757 IF( kstep.EQ.1 ) THEN
758*
759* 1-by-1 pivot block D(k): column k of W now holds
760*
761* W(k) = L(k)*D(k)
762*
763* where L(k) is the k-th column of L
764*
765* Store L(k) in column k of A
766*
767 CALL ccopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
768 IF( k.LT.n ) THEN
769 IF( cabs1( a( k, k ) ).GE.sfmin ) THEN
770 r1 = cone / a( k, k )
771 CALL cscal( n-k, r1, a( k+1, k ), 1 )
772 ELSE IF( a( k, k ).NE.czero ) THEN
773 DO 74 ii = k + 1, n
774 a( ii, k ) = a( ii, k ) / a( k, k )
775 74 CONTINUE
776 END IF
777 END IF
778*
779 ELSE
780*
781* 2-by-2 pivot block D(k): columns k and k+1 of W now hold
782*
783* ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k)
784*
785* where L(k) and L(k+1) are the k-th and (k+1)-th columns
786* of L
787*
788 IF( k.LT.n-1 ) THEN
789*
790* Store L(k) and L(k+1) in columns k and k+1 of A
791*
792 d21 = w( k+1, k )
793 d11 = w( k+1, k+1 ) / d21
794 d22 = w( k, k ) / d21
795 t = cone / ( d11*d22-cone )
796 DO 80 j = k + 2, n
797 a( j, k ) = t*( ( d11*w( j, k )-w( j, k+1 ) ) /
798 $ d21 )
799 a( j, k+1 ) = t*( ( d22*w( j, k+1 )-w( j, k ) ) /
800 $ d21 )
801 80 CONTINUE
802 END IF
803*
804* Copy D(k) to A
805*
806 a( k, k ) = w( k, k )
807 a( k+1, k ) = w( k+1, k )
808 a( k+1, k+1 ) = w( k+1, k+1 )
809 END IF
810 END IF
811*
812* Store details of the interchanges in IPIV
813*
814 IF( kstep.EQ.1 ) THEN
815 ipiv( k ) = kp
816 ELSE
817 ipiv( k ) = -p
818 ipiv( k+1 ) = -kp
819 END IF
820*
821* Increase K and return to the start of the main loop
822*
823 k = k + kstep
824 GO TO 70
825*
826 90 CONTINUE
827*
828* Update the lower triangle of A22 (= A(k:n,k:n)) as
829*
830* A22 := A22 - L21*D*L21**T = A22 - L21*W**T
831*
832* (note that conjg(W) is actually stored)
833*
834 CALL cgemmtr( 'Lower', 'No transpose', 'Transpose', n-k+1,
835 $ k-1, -cone, a( k, 1 ), lda, w( k, 1 ), ldw,
836 $ cone, a( k, k ), lda )
837*
838* Put L21 in standard form by partially undoing the interchanges
839* in columns 1:k-1
840*
841 j = k - 1
842 120 CONTINUE
843*
844 kstep = 1
845 jp1 = 1
846 jj = j
847 jp2 = ipiv( j )
848 IF( jp2.LT.0 ) THEN
849 jp2 = -jp2
850 j = j - 1
851 jp1 = -ipiv( j )
852 kstep = 2
853 END IF
854*
855 j = j - 1
856 IF( jp2.NE.jj .AND. j.GE.1 )
857 $ CALL cswap( j, a( jp2, 1 ), lda, a( jj, 1 ), lda )
858 jj = j + 1
859 IF( jp1.NE.jj .AND. kstep.EQ.2 )
860 $ CALL cswap( j, a( jp1, 1 ), lda, a( jj, 1 ), lda )
861 IF( j.GE.1 )
862 $ GO TO 120
863*
864* Set KB to the number of columns factorized
865*
866 kb = k - 1
867*
868 END IF
869 RETURN
870*
871* End of CLASYF_ROOK
872*
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
Definition ccopy.f:81
subroutine cgemmtr(uplo, transa, transb, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMMTR
Definition cgemmtr.f:191
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
Definition cgemv.f:160
integer function icamax(n, cx, incx)
ICAMAX
Definition icamax.f:71
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
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: