LAPACK  3.6.1
LAPACK: Linear Algebra PACKage
subroutine clasyf ( 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 computes a partial factorization of a complex symmetric matrix using the Bunch-Kaufman diagonal pivoting method.

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

Purpose:
 CLASYF computes a partial factorization of a complex symmetric matrix
 A using the 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.
 Note that U**T denotes the transpose of U.

 CLASYF is an auxiliary routine called by CSYTRF. 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) = 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':
             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) = 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]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.
Date
November 2013
Contributors:
  November 2013,  Igor Kozachenko,
                  Computer Science Division,
                  University of California, Berkeley

Definition at line 179 of file clasyf.f.

179 *
180 * -- LAPACK computational routine (version 3.5.0) --
181 * -- LAPACK is a software package provided by Univ. of Tennessee, --
182 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
183 * November 2013
184 *
185 * .. Scalar Arguments ..
186  CHARACTER uplo
187  INTEGER info, kb, lda, ldw, n, nb
188 * ..
189 * .. Array Arguments ..
190  INTEGER ipiv( * )
191  COMPLEX a( lda, * ), w( ldw, * )
192 * ..
193 *
194 * =====================================================================
195 *
196 * .. Parameters ..
197  REAL zero, one
198  parameter ( zero = 0.0e+0, one = 1.0e+0 )
199  REAL eight, sevten
200  parameter ( eight = 8.0e+0, sevten = 17.0e+0 )
201  COMPLEX cone
202  parameter ( cone = ( 1.0e+0, 0.0e+0 ) )
203 * ..
204 * .. Local Scalars ..
205  INTEGER imax, j, jb, jj, jmax, jp, k, kk, kkw, kp,
206  $ kstep, kw
207  REAL absakk, alpha, colmax, rowmax
208  COMPLEX d11, d21, d22, r1, t, z
209 * ..
210 * .. External Functions ..
211  LOGICAL lsame
212  INTEGER icamax
213  EXTERNAL lsame, icamax
214 * ..
215 * .. External Subroutines ..
216  EXTERNAL ccopy, cgemm, cgemv, cscal, cswap
217 * ..
218 * .. Intrinsic Functions ..
219  INTRINSIC abs, aimag, max, min, REAL, sqrt
220 * ..
221 * .. Statement Functions ..
222  REAL cabs1
223 * ..
224 * .. Statement Function definitions ..
225  cabs1( z ) = abs( REAL( Z ) ) + abs( aimag( z ) )
226 * ..
227 * .. Executable Statements ..
228 *
229  info = 0
230 *
231 * Initialize ALPHA for use in choosing pivot block size.
232 *
233  alpha = ( one+sqrt( sevten ) ) / eight
234 *
235  IF( lsame( uplo, 'U' ) ) THEN
236 *
237 * Factorize the trailing columns of A using the upper triangle
238 * of A and working backwards, and compute the matrix W = U12*D
239 * for use in updating A11
240 *
241 * K is the main loop index, decreasing from N in steps of 1 or 2
242 *
243 * KW is the column of W which corresponds to column K of A
244 *
245  k = n
246  10 CONTINUE
247  kw = nb + k - n
248 *
249 * Exit from loop
250 *
251  IF( ( k.LE.n-nb+1 .AND. nb.LT.n ) .OR. k.LT.1 )
252  $ GO TO 30
253 *
254 * Copy column K of A to column KW of W and update it
255 *
256  CALL ccopy( k, a( 1, k ), 1, w( 1, kw ), 1 )
257  IF( k.LT.n )
258  $ CALL cgemv( 'No transpose', k, n-k, -cone, a( 1, k+1 ), lda,
259  $ w( k, kw+1 ), ldw, cone, w( 1, kw ), 1 )
260 *
261  kstep = 1
262 *
263 * Determine rows and columns to be interchanged and whether
264 * a 1-by-1 or 2-by-2 pivot block will be used
265 *
266  absakk = cabs1( w( k, kw ) )
267 *
268 * IMAX is the row-index of the largest off-diagonal element in
269 * column K, and COLMAX is its absolute value.
270 * Determine both COLMAX and IMAX.
271 *
272  IF( k.GT.1 ) THEN
273  imax = icamax( k-1, w( 1, kw ), 1 )
274  colmax = cabs1( w( imax, kw ) )
275  ELSE
276  colmax = zero
277  END IF
278 *
279  IF( max( absakk, colmax ).EQ.zero ) THEN
280 *
281 * Column K is zero or underflow: set INFO and continue
282 *
283  IF( info.EQ.0 )
284  $ info = k
285  kp = k
286  ELSE
287  IF( absakk.GE.alpha*colmax ) THEN
288 *
289 * no interchange, use 1-by-1 pivot block
290 *
291  kp = k
292  ELSE
293 *
294 * Copy column IMAX to column KW-1 of W and update it
295 *
296  CALL ccopy( imax, a( 1, imax ), 1, w( 1, kw-1 ), 1 )
297  CALL ccopy( k-imax, a( imax, imax+1 ), lda,
298  $ w( imax+1, kw-1 ), 1 )
299  IF( k.LT.n )
300  $ CALL cgemv( 'No transpose', k, n-k, -cone,
301  $ a( 1, k+1 ), lda, w( imax, kw+1 ), ldw,
302  $ cone, w( 1, kw-1 ), 1 )
303 *
304 * JMAX is the column-index of the largest off-diagonal
305 * element in row IMAX, and ROWMAX is its absolute value
306 *
307  jmax = imax + icamax( k-imax, w( imax+1, kw-1 ), 1 )
308  rowmax = cabs1( w( jmax, kw-1 ) )
309  IF( imax.GT.1 ) THEN
310  jmax = icamax( imax-1, w( 1, kw-1 ), 1 )
311  rowmax = max( rowmax, cabs1( w( jmax, kw-1 ) ) )
312  END IF
313 *
314  IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
315 *
316 * no interchange, use 1-by-1 pivot block
317 *
318  kp = k
319  ELSE IF( cabs1( w( imax, kw-1 ) ).GE.alpha*rowmax ) THEN
320 *
321 * interchange rows and columns K and IMAX, use 1-by-1
322 * pivot block
323 *
324  kp = imax
325 *
326 * copy column KW-1 of W to column KW of W
327 *
328  CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
329  ELSE
330 *
331 * interchange rows and columns K-1 and IMAX, use 2-by-2
332 * pivot block
333 *
334  kp = imax
335  kstep = 2
336  END IF
337  END IF
338 *
339 * ============================================================
340 *
341 * KK is the column of A where pivoting step stopped
342 *
343  kk = k - kstep + 1
344 *
345 * KKW is the column of W which corresponds to column KK of A
346 *
347  kkw = nb + kk - n
348 *
349 * Interchange rows and columns KP and KK.
350 * Updated column KP is already stored in column KKW of W.
351 *
352  IF( kp.NE.kk ) THEN
353 *
354 * Copy non-updated column KK to column KP of submatrix A
355 * at step K. No need to copy element into column K
356 * (or K and K-1 for 2-by-2 pivot) of A, since these columns
357 * will be later overwritten.
358 *
359  a( kp, kp ) = a( kk, kk )
360  CALL ccopy( kk-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
361  $ lda )
362  IF( kp.GT.1 )
363  $ CALL ccopy( kp-1, a( 1, kk ), 1, a( 1, kp ), 1 )
364 *
365 * Interchange rows KK and KP in last K+1 to N columns of A
366 * (columns K (or K and K-1 for 2-by-2 pivot) of A will be
367 * later overwritten). Interchange rows KK and KP
368 * in last KKW to NB columns of W.
369 *
370  IF( k.LT.n )
371  $ CALL cswap( n-k, a( kk, k+1 ), lda, a( kp, k+1 ),
372  $ lda )
373  CALL cswap( n-kk+1, w( kk, kkw ), ldw, w( kp, kkw ),
374  $ ldw )
375  END IF
376 *
377  IF( kstep.EQ.1 ) THEN
378 *
379 * 1-by-1 pivot block D(k): column kw of W now holds
380 *
381 * W(kw) = U(k)*D(k),
382 *
383 * where U(k) is the k-th column of U
384 *
385 * Store subdiag. elements of column U(k)
386 * and 1-by-1 block D(k) in column k of A.
387 * NOTE: Diagonal element U(k,k) is a UNIT element
388 * and not stored.
389 * A(k,k) := D(k,k) = W(k,kw)
390 * A(1:k-1,k) := U(1:k-1,k) = W(1:k-1,kw)/D(k,k)
391 *
392  CALL ccopy( k, w( 1, kw ), 1, a( 1, k ), 1 )
393  r1 = cone / a( k, k )
394  CALL cscal( k-1, r1, a( 1, k ), 1 )
395 *
396  ELSE
397 *
398 * 2-by-2 pivot block D(k): columns kw and kw-1 of W now hold
399 *
400 * ( W(kw-1) W(kw) ) = ( U(k-1) U(k) )*D(k)
401 *
402 * where U(k) and U(k-1) are the k-th and (k-1)-th columns
403 * of U
404 *
405 * Store U(1:k-2,k-1) and U(1:k-2,k) and 2-by-2
406 * block D(k-1:k,k-1:k) in columns k-1 and k of A.
407 * NOTE: 2-by-2 diagonal block U(k-1:k,k-1:k) is a UNIT
408 * block and not stored.
409 * A(k-1:k,k-1:k) := D(k-1:k,k-1:k) = W(k-1:k,kw-1:kw)
410 * A(1:k-2,k-1:k) := U(1:k-2,k:k-1:k) =
411 * = W(1:k-2,kw-1:kw) * ( D(k-1:k,k-1:k)**(-1) )
412 *
413  IF( k.GT.2 ) THEN
414 *
415 * Compose the columns of the inverse of 2-by-2 pivot
416 * block D in the following way to reduce the number
417 * of FLOPS when we myltiply panel ( W(kw-1) W(kw) ) by
418 * this inverse
419 *
420 * D**(-1) = ( d11 d21 )**(-1) =
421 * ( d21 d22 )
422 *
423 * = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) =
424 * ( (-d21 ) ( d11 ) )
425 *
426 * = 1/d21 * 1/((d11/d21)*(d22/d21)-1) *
427 *
428 * * ( ( d22/d21 ) ( -1 ) ) =
429 * ( ( -1 ) ( d11/d21 ) )
430 *
431 * = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) =
432 * ( ( -1 ) ( D22 ) )
433 *
434 * = 1/d21 * T * ( ( D11 ) ( -1 ) )
435 * ( ( -1 ) ( D22 ) )
436 *
437 * = D21 * ( ( D11 ) ( -1 ) )
438 * ( ( -1 ) ( D22 ) )
439 *
440  d21 = w( k-1, kw )
441  d11 = w( k, kw ) / d21
442  d22 = w( k-1, kw-1 ) / d21
443  t = cone / ( d11*d22-cone )
444 *
445 * Update elements in columns A(k-1) and A(k) as
446 * dot products of rows of ( W(kw-1) W(kw) ) and columns
447 * of D**(-1)
448 *
449  d21 = t / d21
450  DO 20 j = 1, k - 2
451  a( j, k-1 ) = d21*( d11*w( j, kw-1 )-w( j, kw ) )
452  a( j, k ) = d21*( d22*w( j, kw )-w( j, kw-1 ) )
453  20 CONTINUE
454  END IF
455 *
456 * Copy D(k) to A
457 *
458  a( k-1, k-1 ) = w( k-1, kw-1 )
459  a( k-1, k ) = w( k-1, kw )
460  a( k, k ) = w( k, kw )
461 *
462  END IF
463 *
464  END IF
465 *
466 * Store details of the interchanges in IPIV
467 *
468  IF( kstep.EQ.1 ) THEN
469  ipiv( k ) = kp
470  ELSE
471  ipiv( k ) = -kp
472  ipiv( k-1 ) = -kp
473  END IF
474 *
475 * Decrease K and return to the start of the main loop
476 *
477  k = k - kstep
478  GO TO 10
479 *
480  30 CONTINUE
481 *
482 * Update the upper triangle of A11 (= A(1:k,1:k)) as
483 *
484 * A11 := A11 - U12*D*U12**T = A11 - U12*W**T
485 *
486 * computing blocks of NB columns at a time
487 *
488  DO 50 j = ( ( k-1 ) / nb )*nb + 1, 1, -nb
489  jb = min( nb, k-j+1 )
490 *
491 * Update the upper triangle of the diagonal block
492 *
493  DO 40 jj = j, j + jb - 1
494  CALL cgemv( 'No transpose', jj-j+1, n-k, -cone,
495  $ a( j, k+1 ), lda, w( jj, kw+1 ), ldw, cone,
496  $ a( j, jj ), 1 )
497  40 CONTINUE
498 *
499 * Update the rectangular superdiagonal block
500 *
501  CALL cgemm( 'No transpose', 'Transpose', j-1, jb, n-k,
502  $ -cone, a( 1, k+1 ), lda, w( j, kw+1 ), ldw,
503  $ cone, a( 1, j ), lda )
504  50 CONTINUE
505 *
506 * Put U12 in standard form by partially undoing the interchanges
507 * in columns k+1:n looping backwards from k+1 to n
508 *
509  j = k + 1
510  60 CONTINUE
511 *
512 * Undo the interchanges (if any) of rows JJ and JP at each
513 * step J
514 *
515 * (Here, J is a diagonal index)
516  jj = j
517  jp = ipiv( j )
518  IF( jp.LT.0 ) THEN
519  jp = -jp
520 * (Here, J is a diagonal index)
521  j = j + 1
522  END IF
523 * (NOTE: Here, J is used to determine row length. Length N-J+1
524 * of the rows to swap back doesn't include diagonal element)
525  j = j + 1
526  IF( jp.NE.jj .AND. j.LE.n )
527  $ CALL cswap( n-j+1, a( jp, j ), lda, a( jj, j ), lda )
528  IF( j.LT.n )
529  $ GO TO 60
530 *
531 * Set KB to the number of columns factorized
532 *
533  kb = n - k
534 *
535  ELSE
536 *
537 * Factorize the leading columns of A using the lower triangle
538 * of A and working forwards, and compute the matrix W = L21*D
539 * for use in updating A22
540 *
541 * K is the main loop index, increasing from 1 in steps of 1 or 2
542 *
543  k = 1
544  70 CONTINUE
545 *
546 * Exit from loop
547 *
548  IF( ( k.GE.nb .AND. nb.LT.n ) .OR. k.GT.n )
549  $ GO TO 90
550 *
551 * Copy column K of A to column K of W and update it
552 *
553  CALL ccopy( n-k+1, a( k, k ), 1, w( k, k ), 1 )
554  CALL cgemv( 'No transpose', n-k+1, k-1, -cone, a( k, 1 ), lda,
555  $ w( k, 1 ), ldw, cone, w( k, k ), 1 )
556 *
557  kstep = 1
558 *
559 * Determine rows and columns to be interchanged and whether
560 * a 1-by-1 or 2-by-2 pivot block will be used
561 *
562  absakk = cabs1( w( k, k ) )
563 *
564 * IMAX is the row-index of the largest off-diagonal element in
565 * column K, and COLMAX is its absolute value.
566 * Determine both COLMAX and IMAX.
567 *
568  IF( k.LT.n ) THEN
569  imax = k + icamax( n-k, w( k+1, k ), 1 )
570  colmax = cabs1( w( imax, k ) )
571  ELSE
572  colmax = zero
573  END IF
574 *
575  IF( max( absakk, colmax ).EQ.zero ) THEN
576 *
577 * Column K is zero or underflow: set INFO and continue
578 *
579  IF( info.EQ.0 )
580  $ info = k
581  kp = k
582  ELSE
583  IF( absakk.GE.alpha*colmax ) THEN
584 *
585 * no interchange, use 1-by-1 pivot block
586 *
587  kp = k
588  ELSE
589 *
590 * Copy column IMAX to column K+1 of W and update it
591 *
592  CALL ccopy( imax-k, a( imax, k ), lda, w( k, k+1 ), 1 )
593  CALL ccopy( n-imax+1, a( imax, imax ), 1, w( imax, k+1 ),
594  $ 1 )
595  CALL cgemv( 'No transpose', n-k+1, k-1, -cone, a( k, 1 ),
596  $ lda, w( imax, 1 ), ldw, cone, w( k, k+1 ),
597  $ 1 )
598 *
599 * JMAX is the column-index of the largest off-diagonal
600 * element in row IMAX, and ROWMAX is its absolute value
601 *
602  jmax = k - 1 + icamax( imax-k, w( k, k+1 ), 1 )
603  rowmax = cabs1( w( jmax, k+1 ) )
604  IF( imax.LT.n ) THEN
605  jmax = imax + icamax( n-imax, w( imax+1, k+1 ), 1 )
606  rowmax = max( rowmax, cabs1( w( jmax, k+1 ) ) )
607  END IF
608 *
609  IF( absakk.GE.alpha*colmax*( colmax / rowmax ) ) THEN
610 *
611 * no interchange, use 1-by-1 pivot block
612 *
613  kp = k
614  ELSE IF( cabs1( w( imax, k+1 ) ).GE.alpha*rowmax ) THEN
615 *
616 * interchange rows and columns K and IMAX, use 1-by-1
617 * pivot block
618 *
619  kp = imax
620 *
621 * copy column K+1 of W to column K of W
622 *
623  CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ), 1 )
624  ELSE
625 *
626 * interchange rows and columns K+1 and IMAX, use 2-by-2
627 * pivot block
628 *
629  kp = imax
630  kstep = 2
631  END IF
632  END IF
633 *
634 * ============================================================
635 *
636 * KK is the column of A where pivoting step stopped
637 *
638  kk = k + kstep - 1
639 *
640 * Interchange rows and columns KP and KK.
641 * Updated column KP is already stored in column KK of W.
642 *
643  IF( kp.NE.kk ) THEN
644 *
645 * Copy non-updated column KK to column KP of submatrix A
646 * at step K. No need to copy element into column K
647 * (or K and K+1 for 2-by-2 pivot) of A, since these columns
648 * will be later overwritten.
649 *
650  a( kp, kp ) = a( kk, kk )
651  CALL ccopy( kp-kk-1, a( kk+1, kk ), 1, a( kp, kk+1 ),
652  $ lda )
653  IF( kp.LT.n )
654  $ CALL ccopy( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ), 1 )
655 *
656 * Interchange rows KK and KP in first K-1 columns of A
657 * (columns K (or K and K+1 for 2-by-2 pivot) of A will be
658 * later overwritten). Interchange rows KK and KP
659 * in first KK columns of W.
660 *
661  IF( k.GT.1 )
662  $ CALL cswap( k-1, a( kk, 1 ), lda, a( kp, 1 ), lda )
663  CALL cswap( kk, w( kk, 1 ), ldw, w( kp, 1 ), ldw )
664  END IF
665 *
666  IF( kstep.EQ.1 ) THEN
667 *
668 * 1-by-1 pivot block D(k): column k of W now holds
669 *
670 * W(k) = L(k)*D(k),
671 *
672 * where L(k) is the k-th column of L
673 *
674 * Store subdiag. elements of column L(k)
675 * and 1-by-1 block D(k) in column k of A.
676 * (NOTE: Diagonal element L(k,k) is a UNIT element
677 * and not stored)
678 * A(k,k) := D(k,k) = W(k,k)
679 * A(k+1:N,k) := L(k+1:N,k) = W(k+1:N,k)/D(k,k)
680 *
681  CALL ccopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
682  IF( k.LT.n ) THEN
683  r1 = cone / a( k, k )
684  CALL cscal( n-k, r1, a( k+1, k ), 1 )
685  END IF
686 *
687  ELSE
688 *
689 * 2-by-2 pivot block D(k): columns k and k+1 of W now hold
690 *
691 * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k)
692 *
693 * where L(k) and L(k+1) are the k-th and (k+1)-th columns
694 * of L
695 *
696 * Store L(k+2:N,k) and L(k+2:N,k+1) and 2-by-2
697 * block D(k:k+1,k:k+1) in columns k and k+1 of A.
698 * (NOTE: 2-by-2 diagonal block L(k:k+1,k:k+1) is a UNIT
699 * block and not stored)
700 * A(k:k+1,k:k+1) := D(k:k+1,k:k+1) = W(k:k+1,k:k+1)
701 * A(k+2:N,k:k+1) := L(k+2:N,k:k+1) =
702 * = W(k+2:N,k:k+1) * ( D(k:k+1,k:k+1)**(-1) )
703 *
704  IF( k.LT.n-1 ) THEN
705 *
706 * Compose the columns of the inverse of 2-by-2 pivot
707 * block D in the following way to reduce the number
708 * of FLOPS when we myltiply panel ( W(k) W(k+1) ) by
709 * this inverse
710 *
711 * D**(-1) = ( d11 d21 )**(-1) =
712 * ( d21 d22 )
713 *
714 * = 1/(d11*d22-d21**2) * ( ( d22 ) (-d21 ) ) =
715 * ( (-d21 ) ( d11 ) )
716 *
717 * = 1/d21 * 1/((d11/d21)*(d22/d21)-1) *
718 *
719 * * ( ( d22/d21 ) ( -1 ) ) =
720 * ( ( -1 ) ( d11/d21 ) )
721 *
722 * = 1/d21 * 1/(D22*D11-1) * ( ( D11 ) ( -1 ) ) =
723 * ( ( -1 ) ( D22 ) )
724 *
725 * = 1/d21 * T * ( ( D11 ) ( -1 ) )
726 * ( ( -1 ) ( D22 ) )
727 *
728 * = D21 * ( ( D11 ) ( -1 ) )
729 * ( ( -1 ) ( D22 ) )
730 *
731  d21 = w( k+1, k )
732  d11 = w( k+1, k+1 ) / d21
733  d22 = w( k, k ) / d21
734  t = cone / ( d11*d22-cone )
735  d21 = t / d21
736 *
737 * Update elements in columns A(k) and A(k+1) as
738 * dot products of rows of ( W(k) W(k+1) ) and columns
739 * of D**(-1)
740 *
741  DO 80 j = k + 2, n
742  a( j, k ) = d21*( d11*w( j, k )-w( j, k+1 ) )
743  a( j, k+1 ) = d21*( d22*w( j, k+1 )-w( j, k ) )
744  80 CONTINUE
745  END IF
746 *
747 * Copy D(k) to A
748 *
749  a( k, k ) = w( k, k )
750  a( k+1, k ) = w( k+1, k )
751  a( k+1, k+1 ) = w( k+1, k+1 )
752 *
753  END IF
754 *
755  END IF
756 *
757 * Store details of the interchanges in IPIV
758 *
759  IF( kstep.EQ.1 ) THEN
760  ipiv( k ) = kp
761  ELSE
762  ipiv( k ) = -kp
763  ipiv( k+1 ) = -kp
764  END IF
765 *
766 * Increase K and return to the start of the main loop
767 *
768  k = k + kstep
769  GO TO 70
770 *
771  90 CONTINUE
772 *
773 * Update the lower triangle of A22 (= A(k:n,k:n)) as
774 *
775 * A22 := A22 - L21*D*L21**T = A22 - L21*W**T
776 *
777 * computing blocks of NB columns at a time
778 *
779  DO 110 j = k, n, nb
780  jb = min( nb, n-j+1 )
781 *
782 * Update the lower triangle of the diagonal block
783 *
784  DO 100 jj = j, j + jb - 1
785  CALL cgemv( 'No transpose', j+jb-jj, k-1, -cone,
786  $ a( jj, 1 ), lda, w( jj, 1 ), ldw, cone,
787  $ a( jj, jj ), 1 )
788  100 CONTINUE
789 *
790 * Update the rectangular subdiagonal block
791 *
792  IF( j+jb.LE.n )
793  $ CALL cgemm( 'No transpose', 'Transpose', n-j-jb+1, jb,
794  $ k-1, -cone, a( j+jb, 1 ), lda, w( j, 1 ),
795  $ ldw, cone, a( j+jb, j ), lda )
796  110 CONTINUE
797 *
798 * Put L21 in standard form by partially undoing the interchanges
799 * of rows in columns 1:k-1 looping backwards from k-1 to 1
800 *
801  j = k - 1
802  120 CONTINUE
803 *
804 * Undo the interchanges (if any) of rows JJ and JP at each
805 * step J
806 *
807 * (Here, J is a diagonal index)
808  jj = j
809  jp = ipiv( j )
810  IF( jp.LT.0 ) THEN
811  jp = -jp
812 * (Here, J is a diagonal index)
813  j = j - 1
814  END IF
815 * (NOTE: Here, J is used to determine row length. Length J
816 * of the rows to swap back doesn't include diagonal element)
817  j = j - 1
818  IF( jp.NE.jj .AND. j.GE.1 )
819  $ CALL cswap( j, a( jp, 1 ), lda, a( jj, 1 ), lda )
820  IF( j.GT.1 )
821  $ GO TO 120
822 *
823 * Set KB to the number of columns factorized
824 *
825  kb = k - 1
826 *
827  END IF
828  RETURN
829 *
830 * End of CLASYF
831 *
subroutine cscal(N, CA, CX, INCX)
CSCAL
Definition: cscal.f:54
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:53
subroutine ccopy(N, CX, INCX, CY, INCY)
CCOPY
Definition: ccopy.f:52
subroutine cswap(N, CX, INCX, CY, INCY)
CSWAP
Definition: cswap.f:52
subroutine cgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
CGEMM
Definition: cgemm.f:189
logical function lsame(CA, CB)
LSAME
Definition: lsame.f:55

Here is the call graph for this function:

Here is the caller graph for this function: