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

◆ dlasyf_rook()

subroutine dlasyf_rook ( character uplo,
integer n,
integer nb,
integer kb,
double precision, dimension( lda, * ) a,
integer lda,
integer, dimension( * ) ipiv,
double precision, dimension( ldw, * ) w,
integer ldw,
integer info )

DLASYF_ROOK *> DLASYF_ROOK computes a partial factorization of a real symmetric matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method.

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

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