LAPACK  3.7.0
LAPACK: Linear Algebra PACKage
clahef_rk.f
Go to the documentation of this file.
1 *> \brief \b CLAHEF_RK computes a partial factorization of a complex Hermitian indefinite matrix using 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 *> \htmlonly
9 *> Download CLAHEF_RK + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clahef_rk.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clahef_rk.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clahef_rk.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE CLAHEF_RK( UPLO, N, NB, KB, A, LDA, E, IPIV, W, LDW,
22 * INFO )
23 *
24 * .. Scalar Arguments ..
25 * CHARACTER UPLO
26 * INTEGER INFO, KB, LDA, LDW, N, NB
27 * ..
28 * .. Array Arguments ..
29 * INTEGER IPIV( * )
30 * COMPLEX A( LDA, * ), E( * ), W( LDW, * )
31 * ..
32 *
33 *
34 *> \par Purpose:
35 * =============
36 *>
37 *> \verbatim
38 *> CLAHEF_RK computes a partial factorization of a complex Hermitian
39 *> matrix A using the bounded Bunch-Kaufman (rook) diagonal
40 *> pivoting method. The partial factorization has the form:
41 *>
42 *> A = ( I U12 ) ( A11 0 ) ( I 0 ) if UPLO = 'U', or:
43 *> ( 0 U22 ) ( 0 D ) ( U12**H U22**H )
44 *>
45 *> A = ( L11 0 ) ( D 0 ) ( L11**H L21**H ) if UPLO = 'L',
46 *> ( L21 I ) ( 0 A22 ) ( 0 I )
47 *>
48 *> where the order of D is at most NB. The actual order is returned in
49 *> the argument KB, and is either NB or NB-1, or N if N <= NB.
50 *>
51 *> CLAHEF_RK is an auxiliary routine called by CHETRF_RK. It uses
52 *> blocked code (calling Level 3 BLAS) to update the submatrix
53 *> A11 (if UPLO = 'U') or A22 (if UPLO = 'L').
54 *> \endverbatim
55 *
56 * Arguments:
57 * ==========
58 *
59 *> \param[in] UPLO
60 *> \verbatim
61 *> UPLO is CHARACTER*1
62 *> Specifies whether the upper or lower triangular part of the
63 *> Hermitian matrix A is stored:
64 *> = 'U': Upper triangular
65 *> = 'L': Lower triangular
66 *> \endverbatim
67 *>
68 *> \param[in] N
69 *> \verbatim
70 *> N is INTEGER
71 *> The order of the matrix A. N >= 0.
72 *> \endverbatim
73 *>
74 *> \param[in] NB
75 *> \verbatim
76 *> NB is INTEGER
77 *> The maximum number of columns of the matrix A that should be
78 *> factored. NB should be at least 2 to allow for 2-by-2 pivot
79 *> blocks.
80 *> \endverbatim
81 *>
82 *> \param[out] KB
83 *> \verbatim
84 *> KB is INTEGER
85 *> The number of columns of A that were actually factored.
86 *> KB is either NB-1 or NB, or N if N <= NB.
87 *> \endverbatim
88 *>
89 *> \param[in,out] A
90 *> \verbatim
91 *> A is COMPLEX array, dimension (LDA,N)
92 *> On entry, the Hermitian matrix A.
93 *> If UPLO = 'U': the leading N-by-N upper triangular part
94 *> of A contains the upper triangular part of the matrix A,
95 *> and the strictly lower triangular part of A is not
96 *> referenced.
97 *>
98 *> If UPLO = 'L': the leading N-by-N lower triangular part
99 *> of A contains the lower triangular part of the matrix A,
100 *> and the strictly upper triangular part of A is not
101 *> referenced.
102 *>
103 *> On exit, contains:
104 *> a) ONLY diagonal elements of the Hermitian block diagonal
105 *> matrix D on the diagonal of A, i.e. D(k,k) = A(k,k);
106 *> (superdiagonal (or subdiagonal) elements of D
107 *> are stored on exit in array E), and
108 *> b) If UPLO = 'U': factor U in the superdiagonal part of A.
109 *> If UPLO = 'L': factor L in the subdiagonal part of A.
110 *> \endverbatim
111 *>
112 *> \param[in] LDA
113 *> \verbatim
114 *> LDA is INTEGER
115 *> The leading dimension of the array A. LDA >= max(1,N).
116 *> \endverbatim
117 *>
118 *> \param[out] E
119 *> \verbatim
120 *> E is COMPLEX array, dimension (N)
121 *> On exit, contains the superdiagonal (or subdiagonal)
122 *> elements of the Hermitian block diagonal matrix D
123 *> with 1-by-1 or 2-by-2 diagonal blocks, where
124 *> If UPLO = 'U': E(i) = D(i-1,i), i=2:N, E(1) is set to 0;
125 *> If UPLO = 'L': E(i) = D(i+1,i), i=1:N-1, E(N) is set to 0.
126 *>
127 *> NOTE: For 1-by-1 diagonal block D(k), where
128 *> 1 <= k <= N, the element E(k) is set to 0 in both
129 *> UPLO = 'U' or UPLO = 'L' cases.
130 *> \endverbatim
131 *>
132 *> \param[out] IPIV
133 *> \verbatim
134 *> IPIV is INTEGER array, dimension (N)
135 *> IPIV describes the permutation matrix P in the factorization
136 *> of matrix A as follows. The absolute value of IPIV(k)
137 *> represents the index of row and column that were
138 *> interchanged with the k-th row and column. The value of UPLO
139 *> describes the order in which the interchanges were applied.
140 *> Also, the sign of IPIV represents the block structure of
141 *> the Hermitian block diagonal matrix D with 1-by-1 or 2-by-2
142 *> diagonal blocks which correspond to 1 or 2 interchanges
143 *> at each factorization step.
144 *>
145 *> If UPLO = 'U',
146 *> ( in factorization order, k decreases from N to 1 ):
147 *> a) A single positive entry IPIV(k) > 0 means:
148 *> D(k,k) is a 1-by-1 diagonal block.
149 *> If IPIV(k) != k, rows and columns k and IPIV(k) were
150 *> interchanged in the submatrix A(1:N,N-KB+1:N);
151 *> If IPIV(k) = k, no interchange occurred.
152 *>
153 *>
154 *> b) A pair of consecutive negative entries
155 *> IPIV(k) < 0 and IPIV(k-1) < 0 means:
156 *> D(k-1:k,k-1:k) is a 2-by-2 diagonal block.
157 *> (NOTE: negative entries in IPIV appear ONLY in pairs).
158 *> 1) If -IPIV(k) != k, rows and columns
159 *> k and -IPIV(k) were interchanged
160 *> in the matrix A(1:N,N-KB+1:N).
161 *> If -IPIV(k) = k, no interchange occurred.
162 *> 2) If -IPIV(k-1) != k-1, rows and columns
163 *> k-1 and -IPIV(k-1) were interchanged
164 *> in the submatrix A(1:N,N-KB+1:N).
165 *> If -IPIV(k-1) = k-1, no interchange occurred.
166 *>
167 *> c) In both cases a) and b) is always ABS( IPIV(k) ) <= k.
168 *>
169 *> d) NOTE: Any entry IPIV(k) is always NONZERO on output.
170 *>
171 *> If UPLO = 'L',
172 *> ( in factorization order, k increases from 1 to N ):
173 *> a) A single positive entry IPIV(k) > 0 means:
174 *> D(k,k) is a 1-by-1 diagonal block.
175 *> If IPIV(k) != k, rows and columns k and IPIV(k) were
176 *> interchanged in the submatrix A(1:N,1:KB).
177 *> If IPIV(k) = k, no interchange occurred.
178 *>
179 *> b) A pair of consecutive negative entries
180 *> IPIV(k) < 0 and IPIV(k+1) < 0 means:
181 *> D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
182 *> (NOTE: negative entries in IPIV appear ONLY in pairs).
183 *> 1) If -IPIV(k) != k, rows and columns
184 *> k and -IPIV(k) were interchanged
185 *> in the submatrix A(1:N,1:KB).
186 *> If -IPIV(k) = k, no interchange occurred.
187 *> 2) If -IPIV(k+1) != k+1, rows and columns
188 *> k-1 and -IPIV(k-1) were interchanged
189 *> in the submatrix A(1:N,1:KB).
190 *> If -IPIV(k+1) = k+1, no interchange occurred.
191 *>
192 *> c) In both cases a) and b) is always ABS( IPIV(k) ) >= k.
193 *>
194 *> d) NOTE: Any entry IPIV(k) is always NONZERO on output.
195 *> \endverbatim
196 *>
197 *> \param[out] W
198 *> \verbatim
199 *> W is COMPLEX array, dimension (LDW,NB)
200 *> \endverbatim
201 *>
202 *> \param[in] LDW
203 *> \verbatim
204 *> LDW is INTEGER
205 *> The leading dimension of the array W. LDW >= max(1,N).
206 *> \endverbatim
207 *>
208 *> \param[out] INFO
209 *> \verbatim
210 *> INFO is INTEGER
211 *> = 0: successful exit
212 *>
213 *> < 0: If INFO = -k, the k-th argument had an illegal value
214 *>
215 *> > 0: If INFO = k, the matrix A is singular, because:
216 *> If UPLO = 'U': column k in the upper
217 *> triangular part of A contains all zeros.
218 *> If UPLO = 'L': column k in the lower
219 *> triangular part of A contains all zeros.
220 *>
221 *> Therefore D(k,k) is exactly zero, and superdiagonal
222 *> elements of column k of U (or subdiagonal elements of
223 *> column k of L ) are all zeros. The factorization has
224 *> been completed, but the block diagonal matrix D is
225 *> exactly singular, and division by zero will occur if
226 *> it is used to solve a system of equations.
227 *>
228 *> NOTE: INFO only stores the first occurrence of
229 *> a singularity, any subsequent occurrence of singularity
230 *> is not stored in INFO even though the factorization
231 *> always completes.
232 *> \endverbatim
233 *
234 * Authors:
235 * ========
236 *
237 *> \author Univ. of Tennessee
238 *> \author Univ. of California Berkeley
239 *> \author Univ. of Colorado Denver
240 *> \author NAG Ltd.
241 *
242 *> \date December 2016
243 *
244 *> \ingroup complexHEcomputational
245 *
246 *> \par Contributors:
247 * ==================
248 *>
249 *> \verbatim
250 *>
251 *> December 2016, Igor Kozachenko,
252 *> Computer Science Division,
253 *> University of California, Berkeley
254 *>
255 *> September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
256 *> School of Mathematics,
257 *> University of Manchester
258 *>
259 *> \endverbatim
260 *
261 * =====================================================================
262  SUBROUTINE clahef_rk( UPLO, N, NB, KB, A, LDA, E, IPIV, W, LDW,
263  $ info )
264 *
265 * -- LAPACK computational routine (version 3.7.0) --
266 * -- LAPACK is a software package provided by Univ. of Tennessee, --
267 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
268 * December 2016
269 *
270 * .. Scalar Arguments ..
271  CHARACTER UPLO
272  INTEGER INFO, KB, LDA, LDW, N, NB
273 * ..
274 * .. Array Arguments ..
275  INTEGER IPIV( * )
276  COMPLEX A( lda, * ), W( ldw, * ), E( * )
277 * ..
278 *
279 * =====================================================================
280 *
281 * .. Parameters ..
282  REAL ZERO, ONE
283  parameter ( zero = 0.0e+0, one = 1.0e+0 )
284  REAL EIGHT, SEVTEN
285  parameter ( eight = 8.0e+0, sevten = 17.0e+0 )
286  COMPLEX CONE, CZERO
287  parameter ( cone = ( 1.0e+0, 0.0e+0 ),
288  $ czero = ( 0.0e+0, 0.0e+0 ) )
289 * ..
290 * .. Local Scalars ..
291  LOGICAL DONE
292  INTEGER IMAX, ITEMP, II, J, JB, JJ, JMAX, K, KK, KKW,
293  $ kp, kstep, kw, p
294  REAL ABSAKK, ALPHA, COLMAX, STEMP, R1, ROWMAX, T,
295  $ sfmin
296  COMPLEX D11, D21, D22, Z
297 * ..
298 * .. External Functions ..
299  LOGICAL LSAME
300  INTEGER ICAMAX
301  REAL SLAMCH
302  EXTERNAL lsame, icamax, slamch
303 * ..
304 * .. External Subroutines ..
305  EXTERNAL ccopy, csscal, cgemm, cgemv, clacgv, cswap
306 * ..
307 * .. Intrinsic Functions ..
308  INTRINSIC abs, conjg, aimag, max, min, REAL, SQRT
309 * ..
310 * .. Statement Functions ..
311  REAL CABS1
312 * ..
313 * .. Statement Function definitions ..
314  cabs1( z ) = abs( REAL( Z ) ) + abs( AIMAG( z ) )
315 * ..
316 * .. Executable Statements ..
317 *
318  info = 0
319 *
320 * Initialize ALPHA for use in choosing pivot block size.
321 *
322  alpha = ( one+sqrt( sevten ) ) / eight
323 *
324 * Compute machine safe minimum
325 *
326  sfmin = slamch( 'S' )
327 *
328  IF( lsame( uplo, 'U' ) ) THEN
329 *
330 * Factorize the trailing columns of A using the upper triangle
331 * of A and working backwards, and compute the matrix W = U12*D
332 * for use in updating A11 (note that conjg(W) is actually stored)
333 *
334 * Initilize the first entry of array E, where superdiagonal
335 * elements of D are stored
336 *
337  e( 1 ) = czero
338 *
339 * K is the main loop index, decreasing from N in steps of 1 or 2
340 *
341  k = n
342  10 CONTINUE
343 *
344 * KW is the column of W which corresponds to column K of A
345 *
346  kw = nb + k - n
347 *
348 * Exit from loop
349 *
350  IF( ( k.LE.n-nb+1 .AND. nb.LT.n ) .OR. k.LT.1 )
351  $ GO TO 30
352 *
353  kstep = 1
354  p = k
355 *
356 * Copy column K of A to column KW of W and update it
357 *
358  IF( k.GT.1 )
359  $ CALL ccopy( k-1, a( 1, k ), 1, w( 1, kw ), 1 )
360  w( k, kw ) = REAL( A( K, K ) )
361  IF( k.LT.n ) THEN
362  CALL cgemv( 'No transpose', k, n-k, -cone, a( 1, k+1 ), lda,
363  $ w( k, kw+1 ), ldw, cone, w( 1, kw ), 1 )
364  w( k, kw ) = REAL( W( K, KW ) )
365  END IF
366 *
367 * Determine rows and columns to be interchanged and whether
368 * a 1-by-1 or 2-by-2 pivot block will be used
369 *
370  absakk = abs( REAL( W( K, KW ) ) )
371 *
372 * IMAX is the row-index of the largest off-diagonal element in
373 * column K, and COLMAX is its absolute value.
374 * Determine both COLMAX and IMAX.
375 *
376  IF( k.GT.1 ) THEN
377  imax = icamax( k-1, w( 1, kw ), 1 )
378  colmax = cabs1( w( imax, kw ) )
379  ELSE
380  colmax = zero
381  END IF
382 *
383  IF( max( absakk, colmax ).EQ.zero ) THEN
384 *
385 * Column K is zero or underflow: set INFO and continue
386 *
387  IF( info.EQ.0 )
388  $ info = k
389  kp = k
390  a( k, k ) = REAL( W( K, KW ) )
391  IF( k.GT.1 )
392  $ CALL ccopy( k-1, w( 1, kw ), 1, a( 1, k ), 1 )
393 *
394 * Set E( K ) to zero
395 *
396  IF( k.GT.1 )
397  $ e( k ) = czero
398 *
399  ELSE
400 *
401 * ============================================================
402 *
403 * BEGIN pivot search
404 *
405 * Case(1)
406 * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX
407 * (used to handle NaN and Inf)
408  IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
409 *
410 * no interchange, use 1-by-1 pivot block
411 *
412  kp = k
413 *
414  ELSE
415 *
416 * Lop until pivot found
417 *
418  done = .false.
419 *
420  12 CONTINUE
421 *
422 * BEGIN pivot search loop body
423 *
424 *
425 * Copy column IMAX to column KW-1 of W and update it
426 *
427  IF( imax.GT.1 )
428  $ CALL ccopy( imax-1, a( 1, imax ), 1, w( 1, kw-1 ),
429  $ 1 )
430  w( imax, kw-1 ) = REAL( A( IMAX, IMAX ) )
431 *
432  CALL ccopy( k-imax, a( imax, imax+1 ), lda,
433  $ w( imax+1, kw-1 ), 1 )
434  CALL clacgv( k-imax, w( imax+1, kw-1 ), 1 )
435 *
436  IF( k.LT.n ) THEN
437  CALL cgemv( 'No transpose', k, n-k, -cone,
438  $ a( 1, k+1 ), lda, w( imax, kw+1 ), ldw,
439  $ cone, w( 1, kw-1 ), 1 )
440  w( imax, kw-1 ) = REAL( W( IMAX, KW-1 ) )
441  END IF
442 *
443 * JMAX is the column-index of the largest off-diagonal
444 * element in row IMAX, and ROWMAX is its absolute value.
445 * Determine both ROWMAX and JMAX.
446 *
447  IF( imax.NE.k ) THEN
448  jmax = imax + icamax( k-imax, w( imax+1, kw-1 ),
449  $ 1 )
450  rowmax = cabs1( w( jmax, kw-1 ) )
451  ELSE
452  rowmax = zero
453  END IF
454 *
455  IF( imax.GT.1 ) THEN
456  itemp = icamax( imax-1, w( 1, kw-1 ), 1 )
457  stemp = cabs1( w( itemp, kw-1 ) )
458  IF( stemp.GT.rowmax ) THEN
459  rowmax = stemp
460  jmax = itemp
461  END IF
462  END IF
463 *
464 * Case(2)
465 * Equivalent to testing for
466 * ABS( REAL( W( IMAX,KW-1 ) ) ).GE.ALPHA*ROWMAX
467 * (used to handle NaN and Inf)
468 *
469  IF( .NOT.( abs( REAL( W( IMAX,KW-1 ) ) )
470  $ .LT.alpha*rowmax ) ) THEN
471 *
472 * interchange rows and columns K and IMAX,
473 * use 1-by-1 pivot block
474 *
475  kp = imax
476 *
477 * copy column KW-1 of W to column KW of W
478 *
479  CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
480 *
481  done = .true.
482 *
483 * Case(3)
484 * Equivalent to testing for ROWMAX.EQ.COLMAX,
485 * (used to handle NaN and Inf)
486 *
487  ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
488  $ THEN
489 *
490 * interchange rows and columns K-1 and IMAX,
491 * use 2-by-2 pivot block
492 *
493  kp = imax
494  kstep = 2
495  done = .true.
496 *
497 * Case(4)
498  ELSE
499 *
500 * Pivot not found: set params and repeat
501 *
502  p = imax
503  colmax = rowmax
504  imax = jmax
505 *
506 * Copy updated JMAXth (next IMAXth) column to Kth of W
507 *
508  CALL ccopy( k, w( 1, kw-1 ), 1, w( 1, kw ), 1 )
509 *
510  END IF
511 *
512 *
513 * END pivot search loop body
514 *
515  IF( .NOT.done ) GOTO 12
516 *
517  END IF
518 *
519 * END pivot search
520 *
521 * ============================================================
522 *
523 * KK is the column of A where pivoting step stopped
524 *
525  kk = k - kstep + 1
526 *
527 * KKW is the column of W which corresponds to column KK of A
528 *
529  kkw = nb + kk - n
530 *
531 * Interchange rows and columns P and K.
532 * Updated column P is already stored in column KW of W.
533 *
534  IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
535 *
536 * Copy non-updated column K to column P of submatrix A
537 * at step K. No need to copy element into columns
538 * K and K-1 of A for 2-by-2 pivot, since these columns
539 * will be later overwritten.
540 *
541  a( p, p ) = REAL( A( K, K ) )
542  CALL ccopy( k-1-p, a( p+1, k ), 1, a( p, p+1 ),
543  $ lda )
544  CALL clacgv( k-1-p, a( p, p+1 ), lda )
545  IF( p.GT.1 )
546  $ CALL ccopy( p-1, a( 1, k ), 1, a( 1, p ), 1 )
547 *
548 * Interchange rows K and P in the last K+1 to N columns of A
549 * (columns K and K-1 of A for 2-by-2 pivot will be
550 * later overwritten). Interchange rows K and P
551 * in last KKW to NB columns of W.
552 *
553  IF( k.LT.n )
554  $ CALL cswap( n-k, a( k, k+1 ), lda, a( p, k+1 ),
555  $ lda )
556  CALL cswap( n-kk+1, w( k, kkw ), ldw, w( p, kkw ),
557  $ ldw )
558  END IF
559 *
560 * Interchange rows and columns KP and KK.
561 * Updated column KP is already stored in column KKW of W.
562 *
563  IF( kp.NE.kk ) THEN
564 *
565 * Copy non-updated column KK to column KP of submatrix A
566 * at step K. No need to copy element into column K
567 * (or K and K-1 for 2-by-2 pivot) of A, since these columns
568 * will be later overwritten.
569 *
570  a( kp, kp ) = REAL( A( KK, KK ) )
571  CALL ccopy( kk-1-kp, a( kp+1, kk ), 1, a( kp, kp+1 ),
572  $ lda )
573  CALL clacgv( kk-1-kp, a( kp, kp+1 ), lda )
574  IF( kp.GT.1 )
575  $ CALL ccopy( kp-1, a( 1, kk ), 1, a( 1, kp ), 1 )
576 *
577 * Interchange rows KK and KP in last K+1 to N columns of A
578 * (columns K (or K and K-1 for 2-by-2 pivot) of A will be
579 * later overwritten). Interchange rows KK and KP
580 * in last KKW to NB columns of W.
581 *
582  IF( k.LT.n )
583  $ CALL cswap( n-k, a( kk, k+1 ), lda, a( kp, k+1 ),
584  $ lda )
585  CALL cswap( n-kk+1, w( kk, kkw ), ldw, w( kp, kkw ),
586  $ ldw )
587  END IF
588 *
589  IF( kstep.EQ.1 ) THEN
590 *
591 * 1-by-1 pivot block D(k): column kw of W now holds
592 *
593 * W(kw) = U(k)*D(k),
594 *
595 * where U(k) is the k-th column of U
596 *
597 * (1) Store subdiag. elements of column U(k)
598 * and 1-by-1 block D(k) in column k of A.
599 * (NOTE: Diagonal element U(k,k) is a UNIT element
600 * and not stored)
601 * A(k,k) := D(k,k) = W(k,kw)
602 * A(1:k-1,k) := U(1:k-1,k) = W(1:k-1,kw)/D(k,k)
603 *
604 * (NOTE: No need to use for Hermitian matrix
605 * A( K, K ) = REAL( W( K, K) ) to separately copy diagonal
606 * element D(k,k) from W (potentially saves only one load))
607  CALL ccopy( k, w( 1, kw ), 1, a( 1, k ), 1 )
608  IF( k.GT.1 ) THEN
609 *
610 * (NOTE: No need to check if A(k,k) is NOT ZERO,
611 * since that was ensured earlier in pivot search:
612 * case A(k,k) = 0 falls into 2x2 pivot case(3))
613 *
614 * Handle division by a small number
615 *
616  t = REAL( A( K, K ) )
617  IF( abs( t ).GE.sfmin ) THEN
618  r1 = one / t
619  CALL csscal( k-1, r1, a( 1, k ), 1 )
620  ELSE
621  DO 14 ii = 1, k-1
622  a( ii, k ) = a( ii, k ) / t
623  14 CONTINUE
624  END IF
625 *
626 * (2) Conjugate column W(kw)
627 *
628  CALL clacgv( k-1, w( 1, kw ), 1 )
629 *
630 * Store the superdiagonal element of D in array E
631 *
632  e( k ) = czero
633 *
634  END IF
635 *
636  ELSE
637 *
638 * 2-by-2 pivot block D(k): columns kw and kw-1 of W now hold
639 *
640 * ( W(kw-1) W(kw) ) = ( U(k-1) U(k) )*D(k)
641 *
642 * where U(k) and U(k-1) are the k-th and (k-1)-th columns
643 * of U
644 *
645 * (1) Store U(1:k-2,k-1) and U(1:k-2,k) and 2-by-2
646 * block D(k-1:k,k-1:k) in columns k-1 and k of A.
647 * (NOTE: 2-by-2 diagonal block U(k-1:k,k-1:k) is a UNIT
648 * block and not stored)
649 * A(k-1:k,k-1:k) := D(k-1:k,k-1:k) = W(k-1:k,kw-1:kw)
650 * A(1:k-2,k-1:k) := U(1:k-2,k:k-1:k) =
651 * = W(1:k-2,kw-1:kw) * ( D(k-1:k,k-1:k)**(-1) )
652 *
653  IF( k.GT.2 ) THEN
654 *
655 * Factor out the columns of the inverse of 2-by-2 pivot
656 * block D, so that each column contains 1, to reduce the
657 * number of FLOPS when we multiply panel
658 * ( W(kw-1) W(kw) ) by this inverse, i.e. by D**(-1).
659 *
660 * D**(-1) = ( d11 cj(d21) )**(-1) =
661 * ( d21 d22 )
662 *
663 * = 1/(d11*d22-|d21|**2) * ( ( d22) (-cj(d21) ) ) =
664 * ( (-d21) ( d11 ) )
665 *
666 * = 1/(|d21|**2) * 1/((d11/cj(d21))*(d22/d21)-1) *
667 *
668 * * ( d21*( d22/d21 ) conj(d21)*( - 1 ) ) =
669 * ( ( -1 ) ( d11/conj(d21) ) )
670 *
671 * = 1/(|d21|**2) * 1/(D22*D11-1) *
672 *
673 * * ( d21*( D11 ) conj(d21)*( -1 ) ) =
674 * ( ( -1 ) ( D22 ) )
675 *
676 * = (1/|d21|**2) * T * ( d21*( D11 ) conj(d21)*( -1 ) ) =
677 * ( ( -1 ) ( D22 ) )
678 *
679 * = ( (T/conj(d21))*( D11 ) (T/d21)*( -1 ) ) =
680 * ( ( -1 ) ( D22 ) )
681 *
682 * Handle division by a small number. (NOTE: order of
683 * operations is important)
684 *
685 * = ( T*(( D11 )/conj(D21)) T*(( -1 )/D21 ) )
686 * ( (( -1 ) ) (( D22 ) ) ),
687 *
688 * where D11 = d22/d21,
689 * D22 = d11/conj(d21),
690 * D21 = d21,
691 * T = 1/(D22*D11-1).
692 *
693 * (NOTE: No need to check for division by ZERO,
694 * since that was ensured earlier in pivot search:
695 * (a) d21 != 0 in 2x2 pivot case(4),
696 * since |d21| should be larger than |d11| and |d22|;
697 * (b) (D22*D11 - 1) != 0, since from (a),
698 * both |D11| < 1, |D22| < 1, hence |D22*D11| << 1.)
699 *
700  d21 = w( k-1, kw )
701  d11 = w( k, kw ) / conjg( d21 )
702  d22 = w( k-1, kw-1 ) / d21
703  t = one / ( REAL( d11*d22 )-ONE )
704 *
705 * Update elements in columns A(k-1) and A(k) as
706 * dot products of rows of ( W(kw-1) W(kw) ) and columns
707 * of D**(-1)
708 *
709  DO 20 j = 1, k - 2
710  a( j, k-1 ) = t*( ( d11*w( j, kw-1 )-w( j, kw ) ) /
711  $ d21 )
712  a( j, k ) = t*( ( d22*w( j, kw )-w( j, kw-1 ) ) /
713  $ conjg( d21 ) )
714  20 CONTINUE
715  END IF
716 *
717 * Copy diagonal elements of D(K) to A,
718 * copy superdiagonal element of D(K) to E(K) and
719 * ZERO out superdiagonal entry of A
720 *
721  a( k-1, k-1 ) = w( k-1, kw-1 )
722  a( k-1, k ) = czero
723  a( k, k ) = w( k, kw )
724  e( k ) = w( k-1, kw )
725  e( k-1 ) = czero
726 *
727 * (2) Conjugate columns W(kw) and W(kw-1)
728 *
729  CALL clacgv( k-1, w( 1, kw ), 1 )
730  CALL clacgv( k-2, w( 1, kw-1 ), 1 )
731 *
732  END IF
733 *
734 * End column K is nonsingular
735 *
736  END IF
737 *
738 * Store details of the interchanges in IPIV
739 *
740  IF( kstep.EQ.1 ) THEN
741  ipiv( k ) = kp
742  ELSE
743  ipiv( k ) = -p
744  ipiv( k-1 ) = -kp
745  END IF
746 *
747 * Decrease K and return to the start of the main loop
748 *
749  k = k - kstep
750  GO TO 10
751 *
752  30 CONTINUE
753 *
754 * Update the upper triangle of A11 (= A(1:k,1:k)) as
755 *
756 * A11 := A11 - U12*D*U12**H = A11 - U12*W**H
757 *
758 * computing blocks of NB columns at a time (note that conjg(W) is
759 * actually stored)
760 *
761  DO 50 j = ( ( k-1 ) / nb )*nb + 1, 1, -nb
762  jb = min( nb, k-j+1 )
763 *
764 * Update the upper triangle of the diagonal block
765 *
766  DO 40 jj = j, j + jb - 1
767  a( jj, jj ) = REAL( A( JJ, JJ ) )
768  CALL cgemv( 'No transpose', jj-j+1, n-k, -cone,
769  $ a( j, k+1 ), lda, w( jj, kw+1 ), ldw, cone,
770  $ a( j, jj ), 1 )
771  a( jj, jj ) = REAL( A( JJ, JJ ) )
772  40 CONTINUE
773 *
774 * Update the rectangular superdiagonal block
775 *
776  IF( j.GE.2 )
777  $ CALL cgemm( 'No transpose', 'Transpose', j-1, jb, n-k,
778  $ -cone, a( 1, k+1 ), lda, w( j, kw+1 ), ldw,
779  $ cone, a( 1, j ), lda )
780  50 CONTINUE
781 *
782 * Set KB to the number of columns factorized
783 *
784  kb = n - k
785 *
786  ELSE
787 *
788 * Factorize the leading columns of A using the lower triangle
789 * of A and working forwards, and compute the matrix W = L21*D
790 * for use in updating A22 (note that conjg(W) is actually stored)
791 *
792 * Initilize the unused last entry of the subdiagonal array E.
793 *
794  e( n ) = czero
795 *
796 * K is the main loop index, increasing from 1 in steps of 1 or 2
797 *
798  k = 1
799  70 CONTINUE
800 *
801 * Exit from loop
802 *
803  IF( ( k.GE.nb .AND. nb.LT.n ) .OR. k.GT.n )
804  $ GO TO 90
805 *
806  kstep = 1
807  p = k
808 *
809 * Copy column K of A to column K of W and update column K of W
810 *
811  w( k, k ) = REAL( A( K, K ) )
812  IF( k.LT.n )
813  $ CALL ccopy( n-k, a( k+1, k ), 1, w( k+1, k ), 1 )
814  IF( k.GT.1 ) THEN
815  CALL cgemv( 'No transpose', n-k+1, k-1, -cone, a( k, 1 ),
816  $ lda, w( k, 1 ), ldw, cone, w( k, k ), 1 )
817  w( k, k ) = REAL( W( K, K ) )
818  END IF
819 *
820 * Determine rows and columns to be interchanged and whether
821 * a 1-by-1 or 2-by-2 pivot block will be used
822 *
823  absakk = abs( REAL( W( K, K ) ) )
824 *
825 * IMAX is the row-index of the largest off-diagonal element in
826 * column K, and COLMAX is its absolute value.
827 * Determine both COLMAX and IMAX.
828 *
829  IF( k.LT.n ) THEN
830  imax = k + icamax( n-k, w( k+1, k ), 1 )
831  colmax = cabs1( w( imax, k ) )
832  ELSE
833  colmax = zero
834  END IF
835 *
836  IF( max( absakk, colmax ).EQ.zero ) THEN
837 *
838 * Column K is zero or underflow: set INFO and continue
839 *
840  IF( info.EQ.0 )
841  $ info = k
842  kp = k
843  a( k, k ) = REAL( W( K, K ) )
844  IF( k.LT.n )
845  $ CALL ccopy( n-k, w( k+1, k ), 1, a( k+1, k ), 1 )
846 *
847 * Set E( K ) to zero
848 *
849  IF( k.LT.n )
850  $ e( k ) = czero
851 *
852  ELSE
853 *
854 * ============================================================
855 *
856 * BEGIN pivot search
857 *
858 * Case(1)
859 * Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX
860 * (used to handle NaN and Inf)
861 *
862  IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
863 *
864 * no interchange, use 1-by-1 pivot block
865 *
866  kp = k
867 *
868  ELSE
869 *
870  done = .false.
871 *
872 * Loop until pivot found
873 *
874  72 CONTINUE
875 *
876 * BEGIN pivot search loop body
877 *
878 *
879 * Copy column IMAX to column k+1 of W and update it
880 *
881  CALL ccopy( imax-k, a( imax, k ), lda, w( k, k+1 ), 1)
882  CALL clacgv( imax-k, w( k, k+1 ), 1 )
883  w( imax, k+1 ) = REAL( A( IMAX, IMAX ) )
884 *
885  IF( imax.LT.n )
886  $ CALL ccopy( n-imax, a( imax+1, imax ), 1,
887  $ w( imax+1, k+1 ), 1 )
888 *
889  IF( k.GT.1 ) THEN
890  CALL cgemv( 'No transpose', n-k+1, k-1, -cone,
891  $ a( k, 1 ), lda, w( imax, 1 ), ldw,
892  $ cone, w( k, k+1 ), 1 )
893  w( imax, k+1 ) = REAL( W( IMAX, K+1 ) )
894  END IF
895 *
896 * JMAX is the column-index of the largest off-diagonal
897 * element in row IMAX, and ROWMAX is its absolute value.
898 * Determine both ROWMAX and JMAX.
899 *
900  IF( imax.NE.k ) THEN
901  jmax = k - 1 + icamax( imax-k, w( k, k+1 ), 1 )
902  rowmax = cabs1( w( jmax, k+1 ) )
903  ELSE
904  rowmax = zero
905  END IF
906 *
907  IF( imax.LT.n ) THEN
908  itemp = imax + icamax( n-imax, w( imax+1, k+1 ), 1)
909  stemp = cabs1( w( itemp, k+1 ) )
910  IF( stemp.GT.rowmax ) THEN
911  rowmax = stemp
912  jmax = itemp
913  END IF
914  END IF
915 *
916 * Case(2)
917 * Equivalent to testing for
918 * ABS( REAL( W( IMAX,K+1 ) ) ).GE.ALPHA*ROWMAX
919 * (used to handle NaN and Inf)
920 *
921  IF( .NOT.( abs( REAL( W( IMAX,K+1 ) ) )
922  $ .LT.alpha*rowmax ) ) THEN
923 *
924 * interchange rows and columns K and IMAX,
925 * use 1-by-1 pivot block
926 *
927  kp = imax
928 *
929 * copy column K+1 of W to column K of W
930 *
931  CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ), 1 )
932 *
933  done = .true.
934 *
935 * Case(3)
936 * Equivalent to testing for ROWMAX.EQ.COLMAX,
937 * (used to handle NaN and Inf)
938 *
939  ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
940  $ THEN
941 *
942 * interchange rows and columns K+1 and IMAX,
943 * use 2-by-2 pivot block
944 *
945  kp = imax
946  kstep = 2
947  done = .true.
948 *
949 * Case(4)
950  ELSE
951 *
952 * Pivot not found: set params and repeat
953 *
954  p = imax
955  colmax = rowmax
956  imax = jmax
957 *
958 * Copy updated JMAXth (next IMAXth) column to Kth of W
959 *
960  CALL ccopy( n-k+1, w( k, k+1 ), 1, w( k, k ), 1 )
961 *
962  END IF
963 *
964 *
965 * End pivot search loop body
966 *
967  IF( .NOT.done ) GOTO 72
968 *
969  END IF
970 *
971 * END pivot search
972 *
973 * ============================================================
974 *
975 * KK is the column of A where pivoting step stopped
976 *
977  kk = k + kstep - 1
978 *
979 * Interchange rows and columns P and K (only for 2-by-2 pivot).
980 * Updated column P is already stored in column K of W.
981 *
982  IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
983 *
984 * Copy non-updated column KK-1 to column P of submatrix A
985 * at step K. No need to copy element into columns
986 * K and K+1 of A for 2-by-2 pivot, since these columns
987 * will be later overwritten.
988 *
989  a( p, p ) = REAL( A( K, K ) )
990  CALL ccopy( p-k-1, a( k+1, k ), 1, a( p, k+1 ), lda )
991  CALL clacgv( p-k-1, a( p, k+1 ), lda )
992  IF( p.LT.n )
993  $ CALL ccopy( n-p, a( p+1, k ), 1, a( p+1, p ), 1 )
994 *
995 * Interchange rows K and P in first K-1 columns of A
996 * (columns K and K+1 of A for 2-by-2 pivot will be
997 * later overwritten). Interchange rows K and P
998 * in first KK columns of W.
999 *
1000  IF( k.GT.1 )
1001  $ CALL cswap( k-1, a( k, 1 ), lda, a( p, 1 ), lda )
1002  CALL cswap( kk, w( k, 1 ), ldw, w( p, 1 ), ldw )
1003  END IF
1004 *
1005 * Interchange rows and columns KP and KK.
1006 * Updated column KP is already stored in column KK of W.
1007 *
1008  IF( kp.NE.kk ) THEN
1009 *
1010 * Copy non-updated column KK to column KP of submatrix A
1011 * at step K. No need to copy element into column K
1012 * (or K and K+1 for 2-by-2 pivot) of A, since these columns
1013 * will be later overwritten.
1014 *
1015  a( kp, kp ) = REAL( A( KK, KK ) )
1016  CALL ccopy( kp-kk-1, a( kk+1, kk ), 1, a( kp, kk+1 ),
1017  $ lda )
1018  CALL clacgv( kp-kk-1, a( kp, kk+1 ), lda )
1019  IF( kp.LT.n )
1020  $ CALL ccopy( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ), 1 )
1021 *
1022 * Interchange rows KK and KP in first K-1 columns of A
1023 * (column K (or K and K+1 for 2-by-2 pivot) of A will be
1024 * later overwritten). Interchange rows KK and KP
1025 * in first KK columns of W.
1026 *
1027  IF( k.GT.1 )
1028  $ CALL cswap( k-1, a( kk, 1 ), lda, a( kp, 1 ), lda )
1029  CALL cswap( kk, w( kk, 1 ), ldw, w( kp, 1 ), ldw )
1030  END IF
1031 *
1032  IF( kstep.EQ.1 ) THEN
1033 *
1034 * 1-by-1 pivot block D(k): column k of W now holds
1035 *
1036 * W(k) = L(k)*D(k),
1037 *
1038 * where L(k) is the k-th column of L
1039 *
1040 * (1) Store subdiag. elements of column L(k)
1041 * and 1-by-1 block D(k) in column k of A.
1042 * (NOTE: Diagonal element L(k,k) is a UNIT element
1043 * and not stored)
1044 * A(k,k) := D(k,k) = W(k,k)
1045 * A(k+1:N,k) := L(k+1:N,k) = W(k+1:N,k)/D(k,k)
1046 *
1047 * (NOTE: No need to use for Hermitian matrix
1048 * A( K, K ) = REAL( W( K, K) ) to separately copy diagonal
1049 * element D(k,k) from W (potentially saves only one load))
1050  CALL ccopy( n-k+1, w( k, k ), 1, a( k, k ), 1 )
1051  IF( k.LT.n ) THEN
1052 *
1053 * (NOTE: No need to check if A(k,k) is NOT ZERO,
1054 * since that was ensured earlier in pivot search:
1055 * case A(k,k) = 0 falls into 2x2 pivot case(3))
1056 *
1057 * Handle division by a small number
1058 *
1059  t = REAL( A( K, K ) )
1060  IF( abs( t ).GE.sfmin ) THEN
1061  r1 = one / t
1062  CALL csscal( n-k, r1, a( k+1, k ), 1 )
1063  ELSE
1064  DO 74 ii = k + 1, n
1065  a( ii, k ) = a( ii, k ) / t
1066  74 CONTINUE
1067  END IF
1068 *
1069 * (2) Conjugate column W(k)
1070 *
1071  CALL clacgv( n-k, w( k+1, k ), 1 )
1072 *
1073 * Store the subdiagonal element of D in array E
1074 *
1075  e( k ) = czero
1076 *
1077  END IF
1078 *
1079  ELSE
1080 *
1081 * 2-by-2 pivot block D(k): columns k and k+1 of W now hold
1082 *
1083 * ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k)
1084 *
1085 * where L(k) and L(k+1) are the k-th and (k+1)-th columns
1086 * of L
1087 *
1088 * (1) Store L(k+2:N,k) and L(k+2:N,k+1) and 2-by-2
1089 * block D(k:k+1,k:k+1) in columns k and k+1 of A.
1090 * NOTE: 2-by-2 diagonal block L(k:k+1,k:k+1) is a UNIT
1091 * block and not stored.
1092 * A(k:k+1,k:k+1) := D(k:k+1,k:k+1) = W(k:k+1,k:k+1)
1093 * A(k+2:N,k:k+1) := L(k+2:N,k:k+1) =
1094 * = W(k+2:N,k:k+1) * ( D(k:k+1,k:k+1)**(-1) )
1095 *
1096  IF( k.LT.n-1 ) THEN
1097 *
1098 * Factor out the columns of the inverse of 2-by-2 pivot
1099 * block D, so that each column contains 1, to reduce the
1100 * number of FLOPS when we multiply panel
1101 * ( W(kw-1) W(kw) ) by this inverse, i.e. by D**(-1).
1102 *
1103 * D**(-1) = ( d11 cj(d21) )**(-1) =
1104 * ( d21 d22 )
1105 *
1106 * = 1/(d11*d22-|d21|**2) * ( ( d22) (-cj(d21) ) ) =
1107 * ( (-d21) ( d11 ) )
1108 *
1109 * = 1/(|d21|**2) * 1/((d11/cj(d21))*(d22/d21)-1) *
1110 *
1111 * * ( d21*( d22/d21 ) conj(d21)*( - 1 ) ) =
1112 * ( ( -1 ) ( d11/conj(d21) ) )
1113 *
1114 * = 1/(|d21|**2) * 1/(D22*D11-1) *
1115 *
1116 * * ( d21*( D11 ) conj(d21)*( -1 ) ) =
1117 * ( ( -1 ) ( D22 ) )
1118 *
1119 * = (1/|d21|**2) * T * ( d21*( D11 ) conj(d21)*( -1 ) ) =
1120 * ( ( -1 ) ( D22 ) )
1121 *
1122 * = ( (T/conj(d21))*( D11 ) (T/d21)*( -1 ) ) =
1123 * ( ( -1 ) ( D22 ) )
1124 *
1125 * Handle division by a small number. (NOTE: order of
1126 * operations is important)
1127 *
1128 * = ( T*(( D11 )/conj(D21)) T*(( -1 )/D21 ) )
1129 * ( (( -1 ) ) (( D22 ) ) ),
1130 *
1131 * where D11 = d22/d21,
1132 * D22 = d11/conj(d21),
1133 * D21 = d21,
1134 * T = 1/(D22*D11-1).
1135 *
1136 * (NOTE: No need to check for division by ZERO,
1137 * since that was ensured earlier in pivot search:
1138 * (a) d21 != 0 in 2x2 pivot case(4),
1139 * since |d21| should be larger than |d11| and |d22|;
1140 * (b) (D22*D11 - 1) != 0, since from (a),
1141 * both |D11| < 1, |D22| < 1, hence |D22*D11| << 1.)
1142 *
1143  d21 = w( k+1, k )
1144  d11 = w( k+1, k+1 ) / d21
1145  d22 = w( k, k ) / conjg( d21 )
1146  t = one / ( REAL( d11*d22 )-ONE )
1147 *
1148 * Update elements in columns A(k) and A(k+1) as
1149 * dot products of rows of ( W(k) W(k+1) ) and columns
1150 * of D**(-1)
1151 *
1152  DO 80 j = k + 2, n
1153  a( j, k ) = t*( ( d11*w( j, k )-w( j, k+1 ) ) /
1154  $ conjg( d21 ) )
1155  a( j, k+1 ) = t*( ( d22*w( j, k+1 )-w( j, k ) ) /
1156  $ d21 )
1157  80 CONTINUE
1158  END IF
1159 *
1160 * Copy diagonal elements of D(K) to A,
1161 * copy subdiagonal element of D(K) to E(K) and
1162 * ZERO out subdiagonal entry of A
1163 *
1164  a( k, k ) = w( k, k )
1165  a( k+1, k ) = czero
1166  a( k+1, k+1 ) = w( k+1, k+1 )
1167  e( k ) = w( k+1, k )
1168  e( k+1 ) = czero
1169 *
1170 * (2) Conjugate columns W(k) and W(k+1)
1171 *
1172  CALL clacgv( n-k, w( k+1, k ), 1 )
1173  CALL clacgv( n-k-1, w( k+2, k+1 ), 1 )
1174 *
1175  END IF
1176 *
1177 * End column K is nonsingular
1178 *
1179  END IF
1180 *
1181 * Store details of the interchanges in IPIV
1182 *
1183  IF( kstep.EQ.1 ) THEN
1184  ipiv( k ) = kp
1185  ELSE
1186  ipiv( k ) = -p
1187  ipiv( k+1 ) = -kp
1188  END IF
1189 *
1190 * Increase K and return to the start of the main loop
1191 *
1192  k = k + kstep
1193  GO TO 70
1194 *
1195  90 CONTINUE
1196 *
1197 * Update the lower triangle of A22 (= A(k:n,k:n)) as
1198 *
1199 * A22 := A22 - L21*D*L21**H = A22 - L21*W**H
1200 *
1201 * computing blocks of NB columns at a time (note that conjg(W) is
1202 * actually stored)
1203 *
1204  DO 110 j = k, n, nb
1205  jb = min( nb, n-j+1 )
1206 *
1207 * Update the lower triangle of the diagonal block
1208 *
1209  DO 100 jj = j, j + jb - 1
1210  a( jj, jj ) = REAL( A( JJ, JJ ) )
1211  CALL cgemv( 'No transpose', j+jb-jj, k-1, -cone,
1212  $ a( jj, 1 ), lda, w( jj, 1 ), ldw, cone,
1213  $ a( jj, jj ), 1 )
1214  a( jj, jj ) = REAL( A( JJ, JJ ) )
1215  100 CONTINUE
1216 *
1217 * Update the rectangular subdiagonal block
1218 *
1219  IF( j+jb.LE.n )
1220  $ CALL cgemm( 'No transpose', 'Transpose', n-j-jb+1, jb,
1221  $ k-1, -cone, a( j+jb, 1 ), lda, w( j, 1 ),
1222  $ ldw, cone, a( j+jb, j ), lda )
1223  110 CONTINUE
1224 *
1225 * Set KB to the number of columns factorized
1226 *
1227  kb = k - 1
1228 *
1229  END IF
1230  RETURN
1231 *
1232 * End of CLAHEF_RK
1233 *
1234  END
subroutine clahef_rk(UPLO, N, NB, KB, A, LDA, E, IPIV, W, LDW, INFO)
CLAHEF_RK computes a partial factorization of a complex Hermitian indefinite matrix using bounded Bun...
Definition: clahef_rk.f:264
subroutine cgemv(TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY)
CGEMV
Definition: cgemv.f:160
subroutine clacgv(N, X, INCX)
CLACGV conjugates a complex vector.
Definition: clacgv.f:76
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
subroutine csscal(N, SA, CX, INCX)
CSSCAL
Definition: csscal.f:54