LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zlasyf_rook.f
Go to the documentation of this file.
1*> \brief \b ZLASYF_ROOK computes a partial factorization of a complex symmetric matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method.
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZLASYF_ROOK + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlasyf_rook.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlasyf_rook.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlasyf_rook.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZLASYF_ROOK( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW, INFO )
20*
21* .. Scalar Arguments ..
22* CHARACTER UPLO
23* INTEGER INFO, KB, LDA, LDW, N, NB
24* ..
25* .. Array Arguments ..
26* INTEGER IPIV( * )
27* COMPLEX*16 A( LDA, * ), W( LDW, * )
28* ..
29*
30*
31*> \par Purpose:
32* =============
33*>
34*> \verbatim
35*>
36*> ZLASYF_ROOK computes a partial factorization of a complex symmetric
37*> matrix A using the bounded Bunch-Kaufman ("rook") diagonal
38*> pivoting method. The partial factorization has the form:
39*>
40*> A = ( I U12 ) ( A11 0 ) ( I 0 ) if UPLO = 'U', or:
41*> ( 0 U22 ) ( 0 D ) ( U12**T U22**T )
42*>
43*> A = ( L11 0 ) ( D 0 ) ( L11**T L21**T ) if UPLO = 'L'
44*> ( L21 I ) ( 0 A22 ) ( 0 I )
45*>
46*> where the order of D is at most NB. The actual order is returned in
47*> the argument KB, and is either NB or NB-1, or N if N <= NB.
48*>
49*> ZLASYF_ROOK is an auxiliary routine called by ZSYTRF_ROOK. It uses
50*> blocked code (calling Level 3 BLAS) to update the submatrix
51*> A11 (if UPLO = 'U') or A22 (if UPLO = 'L').
52*> \endverbatim
53*
54* Arguments:
55* ==========
56*
57*> \param[in] UPLO
58*> \verbatim
59*> UPLO is CHARACTER*1
60*> Specifies whether the upper or lower triangular part of the
61*> symmetric matrix A is stored:
62*> = 'U': Upper triangular
63*> = 'L': Lower triangular
64*> \endverbatim
65*>
66*> \param[in] N
67*> \verbatim
68*> N is INTEGER
69*> The order of the matrix A. N >= 0.
70*> \endverbatim
71*>
72*> \param[in] NB
73*> \verbatim
74*> NB is INTEGER
75*> The maximum number of columns of the matrix A that should be
76*> factored. NB should be at least 2 to allow for 2-by-2 pivot
77*> blocks.
78*> \endverbatim
79*>
80*> \param[out] KB
81*> \verbatim
82*> KB is INTEGER
83*> The number of columns of A that were actually factored.
84*> KB is either NB-1 or NB, or N if N <= NB.
85*> \endverbatim
86*>
87*> \param[in,out] A
88*> \verbatim
89*> A is COMPLEX*16 array, dimension (LDA,N)
90*> On entry, the symmetric matrix A. If UPLO = 'U', the leading
91*> n-by-n upper triangular part of A contains the upper
92*> triangular part of the matrix A, and the strictly lower
93*> triangular part of A is not referenced. If UPLO = 'L', the
94*> leading n-by-n lower triangular part of A contains the lower
95*> triangular part of the matrix A, and the strictly upper
96*> triangular part of A is not referenced.
97*> On exit, A contains details of the partial factorization.
98*> \endverbatim
99*>
100*> \param[in] LDA
101*> \verbatim
102*> LDA is INTEGER
103*> The leading dimension of the array A. LDA >= max(1,N).
104*> \endverbatim
105*>
106*> \param[out] IPIV
107*> \verbatim
108*> IPIV is INTEGER array, dimension (N)
109*> Details of the interchanges and the block structure of D.
110*>
111*> If UPLO = 'U':
112*> Only the last KB elements of IPIV are set.
113*>
114*> If IPIV(k) > 0, then rows and columns k and IPIV(k) were
115*> interchanged and D(k,k) is a 1-by-1 diagonal block.
116*>
117*> If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and
118*> columns k and -IPIV(k) were interchanged and rows and
119*> columns k-1 and -IPIV(k-1) were inerchaged,
120*> D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
121*>
122*> If UPLO = 'L':
123*> Only the first KB elements of IPIV are set.
124*>
125*> If IPIV(k) > 0, then rows and columns k and IPIV(k)
126*> were interchanged and D(k,k) is a 1-by-1 diagonal block.
127*>
128*> If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and
129*> columns k and -IPIV(k) were interchanged and rows and
130*> columns k+1 and -IPIV(k+1) were inerchaged,
131*> D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
132*> \endverbatim
133*>
134*> \param[out] W
135*> \verbatim
136*> W is COMPLEX*16 array, dimension (LDW,NB)
137*> \endverbatim
138*>
139*> \param[in] LDW
140*> \verbatim
141*> LDW is INTEGER
142*> The leading dimension of the array W. LDW >= max(1,N).
143*> \endverbatim
144*>
145*> \param[out] INFO
146*> \verbatim
147*> INFO is INTEGER
148*> = 0: successful exit
149*> > 0: if INFO = k, D(k,k) is exactly zero. The factorization
150*> has been completed, but the block diagonal matrix D is
151*> exactly singular.
152*> \endverbatim
153*
154* Authors:
155* ========
156*
157*> \author Univ. of Tennessee
158*> \author Univ. of California Berkeley
159*> \author Univ. of Colorado Denver
160*> \author NAG Ltd.
161*
162*> \ingroup lahef_rook
163*
164*> \par Contributors:
165* ==================
166*>
167*> \verbatim
168*>
169*> November 2013, Igor Kozachenko,
170*> Computer Science Division,
171*> University of California, Berkeley
172*>
173*> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
174*> School of Mathematics,
175*> University of Manchester
176*>
177*> \endverbatim
178*
179* =====================================================================
180 SUBROUTINE zlasyf_rook( UPLO, N, NB, KB, A, LDA, IPIV, W, LDW,
181 $ INFO )
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*16 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 COMPLEX*16 CONE, CZERO
204 parameter( cone = ( 1.0d+0, 0.0d+0 ),
205 $ czero = ( 0.0d+0, 0.0d+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 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, ROWMAX, DTEMP, SFMIN
212 COMPLEX*16 D11, D12, D21, D22, R1, T, Z
213* ..
214* .. External Functions ..
215 LOGICAL LSAME
216 INTEGER IZAMAX
217 DOUBLE PRECISION DLAMCH
218 EXTERNAL lsame, izamax, dlamch
219* ..
220* .. External Subroutines ..
221 EXTERNAL zcopy, zgemmtr, zgemv, zscal, zswap
222* ..
223* .. Intrinsic Functions ..
224 INTRINSIC abs, max, min, sqrt, dimag, dble
225* ..
226* .. Statement Functions ..
227 DOUBLE PRECISION CABS1
228* ..
229* .. Statement Function definitions ..
230 cabs1( z ) = abs( dble( z ) ) + abs( dimag( 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 = dlamch( '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 zcopy( k, a( 1, k ), 1, w( 1, kw ), 1 )
270 IF( k.LT.n )
271 $ CALL zgemv( '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 = izamax( 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 zcopy( 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 zcopy( imax, a( 1, imax ), 1, w( 1, kw-1 ),
327 $ 1 )
328 CALL zcopy( k-imax, a( imax, imax+1 ), lda,
329 $ w( imax+1, kw-1 ), 1 )
330*
331 IF( k.LT.n )
332 $ CALL zgemv( '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 + izamax( 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 = izamax( imax-1, w( 1, kw-1 ), 1 )
350 dtemp = cabs1( w( itemp, kw-1 ) )
351 IF( dtemp.GT.rowmax ) THEN
352 rowmax = dtemp
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 zcopy( 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 zcopy( 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 zcopy( k-p, a( p+1, k ), 1, a( p, p+1 ), lda )
420 CALL zcopy( 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 zswap( n-k+1, a( k, k ), lda, a( p, k ), lda )
426 CALL zswap( 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 zcopy( k-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
438 $ lda )
439 CALL zcopy( 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 zswap( n-kk+1, a( kk, kk ), lda, a( kp, kk ),
445 $ lda )
446 CALL zswap( 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 zcopy( 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 zscal( 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 zgemmtr( '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 zswap( 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 zswap( 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 zcopy( n-k+1, a( k, k ), 1, w( k, k ), 1 )
584 IF( k.GT.1 )
585 $ CALL zgemv( '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 + izamax( 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 zcopy( 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 zcopy( imax-k, a( imax, k ), lda, w( k, k+1 ),
641 $ 1)
642 CALL zcopy( n-imax+1, a( imax, imax ), 1,
643 $ w( imax, k+1 ), 1 )
644 IF( k.GT.1 )
645 $ CALL zgemv( '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 + izamax( 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 + izamax( n-imax, w( imax+1, k+1 ),
662 $ 1)
663 dtemp = cabs1( w( itemp, k+1 ) )
664 IF( dtemp.GT.rowmax ) THEN
665 rowmax = dtemp
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 zcopy( 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 zcopy( 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 zcopy( p-k, a( k, k ), 1, a( p, k ), lda )
731 CALL zcopy( 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 zswap( k, a( k, 1 ), lda, a( p, 1 ), lda )
737 CALL zswap( 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 zcopy( kp-k-1, a( k+1, kk ), 1, a( kp, k+1 ),
748 $ lda )
749 CALL zcopy( 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 zswap( kk, a( kk, 1 ), lda, a( kp, 1 ), lda )
754 CALL zswap( 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 zcopy( 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 zscal( 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 zgemmtr( '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 zswap( j, a( jp2, 1 ), lda, a( jj, 1 ), lda )
858 jj = j + 1
859 IF( jp1.NE.jj .AND. kstep.EQ.2 )
860 $ CALL zswap( 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 ZLASYF_ROOK
872*
873 END
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
Definition zcopy.f:81
subroutine zgemmtr(uplo, transa, transb, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMMTR
Definition zgemmtr.f:191
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
Definition zgemv.f:160
subroutine zlasyf_rook(uplo, n, nb, kb, a, lda, ipiv, w, ldw, info)
ZLASYF_ROOK computes a partial factorization of a complex symmetric matrix using the bounded Bunch-Ka...
subroutine zscal(n, za, zx, incx)
ZSCAL
Definition zscal.f:78
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81