PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
clatrs.f
Go to the documentation of this file.
1  SUBROUTINE clatrs( UPLO, TRANS, DIAG, NORMIN, N, A, LDA, X, SCALE,
2  $ cnorm, info )
3 *
4 * -- LAPACK auxiliary routine (version 3.2) --
5 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
6 * November 2006
7 *
8 * .. Scalar Arguments ..
9  CHARACTER diag, normin, trans, uplo
10  INTEGER info, lda, n
11  REAL scale
12 * ..
13 * .. Array Arguments ..
14  REAL cnorm( * )
15  COMPLEX a( lda, * ), x( * )
16 * ..
17 *
18 * Purpose
19 * =======
20 *
21 * CLATRS solves one of the triangular systems
22 *
23 * A * x = s*b, A**T * x = s*b, or A**H * x = s*b,
24 *
25 * with scaling to prevent overflow. Here A is an upper or lower
26 * triangular matrix, A**T denotes the transpose of A, A**H denotes the
27 * conjugate transpose of A, x and b are n-element vectors, and s is a
28 * scaling factor, usually less than or equal to 1, chosen so that the
29 * components of x will be less than the overflow threshold. If the
30 * unscaled problem will not cause overflow, the Level 2 BLAS routine
31 * CTRSV is called. If the matrix A is singular (A(j,j) = 0 for some j),
32 * then s is set to 0 and a non-trivial solution to A*x = 0 is returned.
33 *
34 * Arguments
35 * =========
36 *
37 * UPLO (input) CHARACTER*1
38 * Specifies whether the matrix A is upper or lower triangular.
39 * = 'U': Upper triangular
40 * = 'L': Lower triangular
41 *
42 * TRANS (input) CHARACTER*1
43 * Specifies the operation applied to A.
44 * = 'N': Solve A * x = s*b (No transpose)
45 * = 'T': Solve A**T * x = s*b (Transpose)
46 * = 'C': Solve A**H * x = s*b (Conjugate transpose)
47 *
48 * DIAG (input) CHARACTER*1
49 * Specifies whether or not the matrix A is unit triangular.
50 * = 'N': Non-unit triangular
51 * = 'U': Unit triangular
52 *
53 * NORMIN (input) CHARACTER*1
54 * Specifies whether CNORM has been set or not.
55 * = 'Y': CNORM contains the column norms on entry
56 * = 'N': CNORM is not set on entry. On exit, the norms will
57 * be computed and stored in CNORM.
58 *
59 * N (input) INTEGER
60 * The order of the matrix A. N >= 0.
61 *
62 * A (input) COMPLEX array, dimension (LDA,N)
63 * The triangular matrix A. If UPLO = 'U', the leading n by n
64 * upper triangular part of the array A contains the upper
65 * triangular matrix, and the strictly lower triangular part of
66 * A is not referenced. If UPLO = 'L', the leading n by n lower
67 * triangular part of the array A contains the lower triangular
68 * matrix, and the strictly upper triangular part of A is not
69 * referenced. If DIAG = 'U', the diagonal elements of A are
70 * also not referenced and are assumed to be 1.
71 *
72 * LDA (input) INTEGER
73 * The leading dimension of the array A. LDA >= max (1,N).
74 *
75 * X (input/output) COMPLEX array, dimension (N)
76 * On entry, the right hand side b of the triangular system.
77 * On exit, X is overwritten by the solution vector x.
78 *
79 * SCALE (output) REAL
80 * The scaling factor s for the triangular system
81 * A * x = s*b, A**T * x = s*b, or A**H * x = s*b.
82 * If SCALE = 0, the matrix A is singular or badly scaled, and
83 * the vector x is an exact or approximate solution to A*x = 0.
84 *
85 * CNORM (input or output) REAL array, dimension (N)
86 *
87 * If NORMIN = 'Y', CNORM is an input argument and CNORM(j)
88 * contains the norm of the off-diagonal part of the j-th column
89 * of A. If TRANS = 'N', CNORM(j) must be greater than or equal
90 * to the infinity-norm, and if TRANS = 'T' or 'C', CNORM(j)
91 * must be greater than or equal to the 1-norm.
92 *
93 * If NORMIN = 'N', CNORM is an output argument and CNORM(j)
94 * returns the 1-norm of the offdiagonal part of the j-th column
95 * of A.
96 *
97 * INFO (output) INTEGER
98 * = 0: successful exit
99 * < 0: if INFO = -k, the k-th argument had an illegal value
100 *
101 * Further Details
102 * ======= =======
103 *
104 * A rough bound on x is computed; if that is less than overflow, CTRSV
105 * is called, otherwise, specific code is used which checks for possible
106 * overflow or divide-by-zero at every operation.
107 *
108 * A columnwise scheme is used for solving A*x = b. The basic algorithm
109 * if A is lower triangular is
110 *
111 * x[1:n] := b[1:n]
112 * for j = 1, ..., n
113 * x(j) := x(j) / A(j,j)
114 * x[j+1:n] := x[j+1:n] - x(j) * A[j+1:n,j]
115 * end
116 *
117 * Define bounds on the components of x after j iterations of the loop:
118 * M(j) = bound on x[1:j]
119 * G(j) = bound on x[j+1:n]
120 * Initially, let M(0) = 0 and G(0) = max{x(i), i=1,...,n}.
121 *
122 * Then for iteration j+1 we have
123 * M(j+1) <= G(j) / | A(j+1,j+1) |
124 * G(j+1) <= G(j) + M(j+1) * | A[j+2:n,j+1] |
125 * <= G(j) ( 1 + CNORM(j+1) / | A(j+1,j+1) | )
126 *
127 * where CNORM(j+1) is greater than or equal to the infinity-norm of
128 * column j+1 of A, not counting the diagonal. Hence
129 *
130 * G(j) <= G(0) product ( 1 + CNORM(i) / | A(i,i) | )
131 * 1<=i<=j
132 * and
133 *
134 * |x(j)| <= ( G(0) / |A(j,j)| ) product ( 1 + CNORM(i) / |A(i,i)| )
135 * 1<=i< j
136 *
137 * Since |x(j)| <= M(j), we use the Level 2 BLAS routine CTRSV if the
138 * reciprocal of the largest M(j), j=1,..,n, is larger than
139 * max(underflow, 1/overflow).
140 *
141 * The bound on x(j) is also used to determine when a step in the
142 * columnwise method can be performed without fear of overflow. If
143 * the computed bound is greater than a large constant, x is scaled to
144 * prevent overflow, but if the bound overflows, x is set to 0, x(j) to
145 * 1, and scale to 0, and a non-trivial solution to A*x = 0 is found.
146 *
147 * Similarly, a row-wise scheme is used to solve A**T *x = b or
148 * A**H *x = b. The basic algorithm for A upper triangular is
149 *
150 * for j = 1, ..., n
151 * x(j) := ( b(j) - A[1:j-1,j]' * x[1:j-1] ) / A(j,j)
152 * end
153 *
154 * We simultaneously compute two bounds
155 * G(j) = bound on ( b(i) - A[1:i-1,i]' * x[1:i-1] ), 1<=i<=j
156 * M(j) = bound on x(i), 1<=i<=j
157 *
158 * The initial values are G(0) = 0, M(0) = max{b(i), i=1,..,n}, and we
159 * add the constraint G(j) >= G(j-1) and M(j) >= M(j-1) for j >= 1.
160 * Then the bound on x(j) is
161 *
162 * M(j) <= M(j-1) * ( 1 + CNORM(j) ) / | A(j,j) |
163 *
164 * <= M(0) * product ( ( 1 + CNORM(i) ) / |A(i,i)| )
165 * 1<=i<=j
166 *
167 * and we can safely call CTRSV if 1/M(n) and 1/G(n) are both greater
168 * than max(underflow, 1/overflow).
169 *
170 * =====================================================================
171 *
172 * .. Parameters ..
173  REAL zero, half, one, two
174  parameter( zero = 0.0e+0, half = 0.5e+0, one = 1.0e+0,
175  $ two = 2.0e+0 )
176 * ..
177 * .. Local Scalars ..
178  LOGICAL notran, nounit, upper
179  INTEGER i, imax, j, jfirst, jinc, jlast
180  REAL bignum, grow, rec, smlnum, tjj, tmax, tscal,
181  $ xbnd, xj, xmax
182  COMPLEX csumj, tjjs, uscal, zdum
183 * ..
184 * .. External Functions ..
185  LOGICAL lsame
186  INTEGER icamax, isamax
187  REAL scasum, slamch
188  COMPLEX cdotc, cdotu, cladiv
189  EXTERNAL lsame, icamax, isamax, scasum, slamch, cdotc,
190  $ cdotu, cladiv
191 * ..
192 * .. External Subroutines ..
193  EXTERNAL caxpy, csscal, ctrsv, slabad, sscal, xerbla
194 * ..
195 * .. Intrinsic Functions ..
196  INTRINSIC abs, aimag, cmplx, conjg, max, min, real
197 * ..
198 * .. Statement Functions ..
199  REAL cabs1, cabs2
200 * ..
201 * .. Statement Function definitions ..
202  cabs1( zdum ) = abs( REAL( ZDUM ) ) + abs( aimag( zdum ) )
203  cabs2( zdum ) = abs( REAL( ZDUM ) / 2. ) +
204  $ abs( aimag( zdum ) / 2. )
205 * ..
206 * .. Executable Statements ..
207 *
208  info = 0
209  upper = lsame( uplo, 'U' )
210  notran = lsame( trans, 'N' )
211  nounit = lsame( diag, 'N' )
212 *
213 * Test the input parameters.
214 *
215  IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
216  info = -1
217  ELSE IF( .NOT.notran .AND. .NOT.lsame( trans, 'T' ) .AND. .NOT.
218  $ lsame( trans, 'C' ) ) THEN
219  info = -2
220  ELSE IF( .NOT.nounit .AND. .NOT.lsame( diag, 'U' ) ) THEN
221  info = -3
222  ELSE IF( .NOT.lsame( normin, 'Y' ) .AND. .NOT.
223  $ lsame( normin, 'N' ) ) THEN
224  info = -4
225  ELSE IF( n.LT.0 ) THEN
226  info = -5
227  ELSE IF( lda.LT.max( 1, n ) ) THEN
228  info = -7
229  END IF
230  IF( info.NE.0 ) THEN
231  CALL xerbla( 'CLATRS', -info )
232  return
233  END IF
234 *
235 * Quick return if possible
236 *
237  IF( n.EQ.0 )
238  $ return
239 *
240 * Determine machine dependent parameters to control overflow.
241 *
242  smlnum = slamch( 'Safe minimum' )
243  bignum = one / smlnum
244  CALL slabad( smlnum, bignum )
245  smlnum = smlnum / slamch( 'Precision' )
246  bignum = one / smlnum
247  scale = one
248 *
249  IF( lsame( normin, 'N' ) ) THEN
250 *
251 * Compute the 1-norm of each column, not including the diagonal.
252 *
253  IF( upper ) THEN
254 *
255 * A is upper triangular.
256 *
257  DO 10 j = 1, n
258  cnorm( j ) = scasum( j-1, a( 1, j ), 1 )
259  10 continue
260  ELSE
261 *
262 * A is lower triangular.
263 *
264  DO 20 j = 1, n - 1
265  cnorm( j ) = scasum( n-j, a( j+1, j ), 1 )
266  20 continue
267  cnorm( n ) = zero
268  END IF
269  END IF
270 *
271 * Scale the column norms by TSCAL if the maximum element in CNORM is
272 * greater than BIGNUM/2.
273 *
274  imax = isamax( n, cnorm, 1 )
275  tmax = cnorm( imax )
276  IF( tmax.LE.bignum*half ) THEN
277  tscal = one
278  ELSE
279  tscal = half / ( smlnum*tmax )
280  CALL sscal( n, tscal, cnorm, 1 )
281  END IF
282 *
283 * Compute a bound on the computed solution vector to see if the
284 * Level 2 BLAS routine CTRSV can be used.
285 *
286  xmax = zero
287  DO 30 j = 1, n
288  xmax = max( xmax, cabs2( x( j ) ) )
289  30 continue
290  xbnd = xmax
291 *
292  IF( notran ) THEN
293 *
294 * Compute the growth in A * x = b.
295 *
296  IF( upper ) THEN
297  jfirst = n
298  jlast = 1
299  jinc = -1
300  ELSE
301  jfirst = 1
302  jlast = n
303  jinc = 1
304  END IF
305 *
306  IF( tscal.NE.one ) THEN
307  grow = zero
308  go to 60
309  END IF
310 *
311  IF( nounit ) THEN
312 *
313 * A is non-unit triangular.
314 *
315 * Compute GROW = 1/G(j) and XBND = 1/M(j).
316 * Initially, G(0) = max{x(i), i=1,...,n}.
317 *
318  grow = half / max( xbnd, smlnum )
319  xbnd = grow
320  DO 40 j = jfirst, jlast, jinc
321 *
322 * Exit the loop if the growth factor is too small.
323 *
324  IF( grow.LE.smlnum )
325  $ go to 60
326 *
327  tjjs = a( j, j )
328  tjj = cabs1( tjjs )
329 *
330  IF( tjj.GE.smlnum ) THEN
331 *
332 * M(j) = G(j-1) / abs(A(j,j))
333 *
334  xbnd = min( xbnd, min( one, tjj )*grow )
335  ELSE
336 *
337 * M(j) could overflow, set XBND to 0.
338 *
339  xbnd = zero
340  END IF
341 *
342  IF( tjj+cnorm( j ).GE.smlnum ) THEN
343 *
344 * G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) )
345 *
346  grow = grow*( tjj / ( tjj+cnorm( j ) ) )
347  ELSE
348 *
349 * G(j) could overflow, set GROW to 0.
350 *
351  grow = zero
352  END IF
353  40 continue
354  grow = xbnd
355  ELSE
356 *
357 * A is unit triangular.
358 *
359 * Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
360 *
361  grow = min( one, half / max( xbnd, smlnum ) )
362  DO 50 j = jfirst, jlast, jinc
363 *
364 * Exit the loop if the growth factor is too small.
365 *
366  IF( grow.LE.smlnum )
367  $ go to 60
368 *
369 * G(j) = G(j-1)*( 1 + CNORM(j) )
370 *
371  grow = grow*( one / ( one+cnorm( j ) ) )
372  50 continue
373  END IF
374  60 continue
375 *
376  ELSE
377 *
378 * Compute the growth in A**T * x = b or A**H * x = b.
379 *
380  IF( upper ) THEN
381  jfirst = 1
382  jlast = n
383  jinc = 1
384  ELSE
385  jfirst = n
386  jlast = 1
387  jinc = -1
388  END IF
389 *
390  IF( tscal.NE.one ) THEN
391  grow = zero
392  go to 90
393  END IF
394 *
395  IF( nounit ) THEN
396 *
397 * A is non-unit triangular.
398 *
399 * Compute GROW = 1/G(j) and XBND = 1/M(j).
400 * Initially, M(0) = max{x(i), i=1,...,n}.
401 *
402  grow = half / max( xbnd, smlnum )
403  xbnd = grow
404  DO 70 j = jfirst, jlast, jinc
405 *
406 * Exit the loop if the growth factor is too small.
407 *
408  IF( grow.LE.smlnum )
409  $ go to 90
410 *
411 * G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
412 *
413  xj = one + cnorm( j )
414  grow = min( grow, xbnd / xj )
415 *
416  tjjs = a( j, j )
417  tjj = cabs1( tjjs )
418 *
419  IF( tjj.GE.smlnum ) THEN
420 *
421 * M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
422 *
423  IF( xj.GT.tjj )
424  $ xbnd = xbnd*( tjj / xj )
425  ELSE
426 *
427 * M(j) could overflow, set XBND to 0.
428 *
429  xbnd = zero
430  END IF
431  70 continue
432  grow = min( grow, xbnd )
433  ELSE
434 *
435 * A is unit triangular.
436 *
437 * Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
438 *
439  grow = min( one, half / max( xbnd, smlnum ) )
440  DO 80 j = jfirst, jlast, jinc
441 *
442 * Exit the loop if the growth factor is too small.
443 *
444  IF( grow.LE.smlnum )
445  $ go to 90
446 *
447 * G(j) = ( 1 + CNORM(j) )*G(j-1)
448 *
449  xj = one + cnorm( j )
450  grow = grow / xj
451  80 continue
452  END IF
453  90 continue
454  END IF
455 *
456  IF( ( grow*tscal ).GT.smlnum ) THEN
457 *
458 * Use the Level 2 BLAS solve if the reciprocal of the bound on
459 * elements of X is not too small.
460 *
461  CALL ctrsv( uplo, trans, diag, n, a, lda, x, 1 )
462  ELSE
463 *
464 * Use a Level 1 BLAS solve, scaling intermediate results.
465 *
466  IF( xmax.GT.bignum*half ) THEN
467 *
468 * Scale X so that its components are less than or equal to
469 * BIGNUM in absolute value.
470 *
471  scale = ( bignum*half ) / xmax
472  CALL csscal( n, scale, x, 1 )
473  xmax = bignum
474  ELSE
475  xmax = xmax*two
476  END IF
477 *
478  IF( notran ) THEN
479 *
480 * Solve A * x = b
481 *
482  DO 110 j = jfirst, jlast, jinc
483 *
484 * Compute x(j) = b(j) / A(j,j), scaling x if necessary.
485 *
486  xj = cabs1( x( j ) )
487  IF( nounit ) THEN
488  tjjs = a( j, j )*tscal
489  ELSE
490  tjjs = tscal
491  IF( tscal.EQ.one )
492  $ go to 105
493  END IF
494  tjj = cabs1( tjjs )
495  IF( tjj.GT.smlnum ) THEN
496 *
497 * abs(A(j,j)) > SMLNUM:
498 *
499  IF( tjj.LT.one ) THEN
500  IF( xj.GT.tjj*bignum ) THEN
501 *
502 * Scale x by 1/b(j).
503 *
504  rec = one / xj
505  CALL csscal( n, rec, x, 1 )
506  scale = scale*rec
507  xmax = xmax*rec
508  END IF
509  END IF
510  x( j ) = cladiv( x( j ), tjjs )
511  xj = cabs1( x( j ) )
512  ELSE IF( tjj.GT.zero ) THEN
513 *
514 * 0 < abs(A(j,j)) <= SMLNUM:
515 *
516  IF( xj.GT.tjj*bignum ) THEN
517 *
518 * Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
519 * to avoid overflow when dividing by A(j,j).
520 *
521  rec = ( tjj*bignum ) / xj
522  IF( cnorm( j ).GT.one ) THEN
523 *
524 * Scale by 1/CNORM(j) to avoid overflow when
525 * multiplying x(j) times column j.
526 *
527  rec = rec / cnorm( j )
528  END IF
529  CALL csscal( n, rec, x, 1 )
530  scale = scale*rec
531  xmax = xmax*rec
532  END IF
533  x( j ) = cladiv( x( j ), tjjs )
534  xj = cabs1( x( j ) )
535  ELSE
536 *
537 * A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
538 * scale = 0, and compute a solution to A*x = 0.
539 *
540  DO 100 i = 1, n
541  x( i ) = zero
542  100 continue
543  x( j ) = one
544  xj = one
545  scale = zero
546  xmax = zero
547  END IF
548  105 continue
549 *
550 * Scale x if necessary to avoid overflow when adding a
551 * multiple of column j of A.
552 *
553  IF( xj.GT.one ) THEN
554  rec = one / xj
555  IF( cnorm( j ).GT.( bignum-xmax )*rec ) THEN
556 *
557 * Scale x by 1/(2*abs(x(j))).
558 *
559  rec = rec*half
560  CALL csscal( n, rec, x, 1 )
561  scale = scale*rec
562  END IF
563  ELSE IF( xj*cnorm( j ).GT.( bignum-xmax ) ) THEN
564 *
565 * Scale x by 1/2.
566 *
567  CALL csscal( n, half, x, 1 )
568  scale = scale*half
569  END IF
570 *
571  IF( upper ) THEN
572  IF( j.GT.1 ) THEN
573 *
574 * Compute the update
575 * x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j)
576 *
577  CALL caxpy( j-1, -x( j )*tscal, a( 1, j ), 1, x,
578  $ 1 )
579  i = icamax( j-1, x, 1 )
580  xmax = cabs1( x( i ) )
581  END IF
582  ELSE
583  IF( j.LT.n ) THEN
584 *
585 * Compute the update
586 * x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j)
587 *
588  CALL caxpy( n-j, -x( j )*tscal, a( j+1, j ), 1,
589  $ x( j+1 ), 1 )
590  i = j + icamax( n-j, x( j+1 ), 1 )
591  xmax = cabs1( x( i ) )
592  END IF
593  END IF
594  110 continue
595 *
596  ELSE IF( lsame( trans, 'T' ) ) THEN
597 *
598 * Solve A**T * x = b
599 *
600  DO 150 j = jfirst, jlast, jinc
601 *
602 * Compute x(j) = b(j) - sum A(k,j)*x(k).
603 * k<>j
604 *
605  xj = cabs1( x( j ) )
606  uscal = tscal
607  rec = one / max( xmax, one )
608  IF( cnorm( j ).GT.( bignum-xj )*rec ) THEN
609 *
610 * If x(j) could overflow, scale x by 1/(2*XMAX).
611 *
612  rec = rec*half
613  IF( nounit ) THEN
614  tjjs = a( j, j )*tscal
615  ELSE
616  tjjs = tscal
617  END IF
618  tjj = cabs1( tjjs )
619  IF( tjj.GT.one ) THEN
620 *
621 * Divide by A(j,j) when scaling x if A(j,j) > 1.
622 *
623  rec = min( one, rec*tjj )
624  uscal = cladiv( uscal, tjjs )
625  END IF
626  IF( rec.LT.one ) THEN
627  CALL csscal( n, rec, x, 1 )
628  scale = scale*rec
629  xmax = xmax*rec
630  END IF
631  END IF
632 *
633  csumj = zero
634  IF( uscal.EQ.cmplx( one ) ) THEN
635 *
636 * If the scaling needed for A in the dot product is 1,
637 * call CDOTU to perform the dot product.
638 *
639  IF( upper ) THEN
640  csumj = cdotu( j-1, a( 1, j ), 1, x, 1 )
641  ELSE IF( j.LT.n ) THEN
642  csumj = cdotu( n-j, a( j+1, j ), 1, x( j+1 ), 1 )
643  END IF
644  ELSE
645 *
646 * Otherwise, use in-line code for the dot product.
647 *
648  IF( upper ) THEN
649  DO 120 i = 1, j - 1
650  csumj = csumj + ( a( i, j )*uscal )*x( i )
651  120 continue
652  ELSE IF( j.LT.n ) THEN
653  DO 130 i = j + 1, n
654  csumj = csumj + ( a( i, j )*uscal )*x( i )
655  130 continue
656  END IF
657  END IF
658 *
659  IF( uscal.EQ.cmplx( tscal ) ) THEN
660 *
661 * Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
662 * was not used to scale the dotproduct.
663 *
664  x( j ) = x( j ) - csumj
665  xj = cabs1( x( j ) )
666  IF( nounit ) THEN
667  tjjs = a( j, j )*tscal
668  ELSE
669  tjjs = tscal
670  IF( tscal.EQ.one )
671  $ go to 145
672  END IF
673 *
674 * Compute x(j) = x(j) / A(j,j), scaling if necessary.
675 *
676  tjj = cabs1( tjjs )
677  IF( tjj.GT.smlnum ) THEN
678 *
679 * abs(A(j,j)) > SMLNUM:
680 *
681  IF( tjj.LT.one ) THEN
682  IF( xj.GT.tjj*bignum ) THEN
683 *
684 * Scale X by 1/abs(x(j)).
685 *
686  rec = one / xj
687  CALL csscal( n, rec, x, 1 )
688  scale = scale*rec
689  xmax = xmax*rec
690  END IF
691  END IF
692  x( j ) = cladiv( x( j ), tjjs )
693  ELSE IF( tjj.GT.zero ) THEN
694 *
695 * 0 < abs(A(j,j)) <= SMLNUM:
696 *
697  IF( xj.GT.tjj*bignum ) THEN
698 *
699 * Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
700 *
701  rec = ( tjj*bignum ) / xj
702  CALL csscal( n, rec, x, 1 )
703  scale = scale*rec
704  xmax = xmax*rec
705  END IF
706  x( j ) = cladiv( x( j ), tjjs )
707  ELSE
708 *
709 * A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
710 * scale = 0 and compute a solution to A**T *x = 0.
711 *
712  DO 140 i = 1, n
713  x( i ) = zero
714  140 continue
715  x( j ) = one
716  scale = zero
717  xmax = zero
718  END IF
719  145 continue
720  ELSE
721 *
722 * Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
723 * product has already been divided by 1/A(j,j).
724 *
725  x( j ) = cladiv( x( j ), tjjs ) - csumj
726  END IF
727  xmax = max( xmax, cabs1( x( j ) ) )
728  150 continue
729 *
730  ELSE
731 *
732 * Solve A**H * x = b
733 *
734  DO 190 j = jfirst, jlast, jinc
735 *
736 * Compute x(j) = b(j) - sum A(k,j)*x(k).
737 * k<>j
738 *
739  xj = cabs1( x( j ) )
740  uscal = tscal
741  rec = one / max( xmax, one )
742  IF( cnorm( j ).GT.( bignum-xj )*rec ) THEN
743 *
744 * If x(j) could overflow, scale x by 1/(2*XMAX).
745 *
746  rec = rec*half
747  IF( nounit ) THEN
748  tjjs = conjg( a( j, j ) )*tscal
749  ELSE
750  tjjs = tscal
751  END IF
752  tjj = cabs1( tjjs )
753  IF( tjj.GT.one ) THEN
754 *
755 * Divide by A(j,j) when scaling x if A(j,j) > 1.
756 *
757  rec = min( one, rec*tjj )
758  uscal = cladiv( uscal, tjjs )
759  END IF
760  IF( rec.LT.one ) THEN
761  CALL csscal( n, rec, x, 1 )
762  scale = scale*rec
763  xmax = xmax*rec
764  END IF
765  END IF
766 *
767  csumj = zero
768  IF( uscal.EQ.cmplx( one ) ) THEN
769 *
770 * If the scaling needed for A in the dot product is 1,
771 * call CDOTC to perform the dot product.
772 *
773  IF( upper ) THEN
774  csumj = cdotc( j-1, a( 1, j ), 1, x, 1 )
775  ELSE IF( j.LT.n ) THEN
776  csumj = cdotc( n-j, a( j+1, j ), 1, x( j+1 ), 1 )
777  END IF
778  ELSE
779 *
780 * Otherwise, use in-line code for the dot product.
781 *
782  IF( upper ) THEN
783  DO 160 i = 1, j - 1
784  csumj = csumj + ( conjg( a( i, j ) )*uscal )*
785  $ x( i )
786  160 continue
787  ELSE IF( j.LT.n ) THEN
788  DO 170 i = j + 1, n
789  csumj = csumj + ( conjg( a( i, j ) )*uscal )*
790  $ x( i )
791  170 continue
792  END IF
793  END IF
794 *
795  IF( uscal.EQ.cmplx( tscal ) ) THEN
796 *
797 * Compute x(j) := ( x(j) - CSUMJ ) / A(j,j) if 1/A(j,j)
798 * was not used to scale the dotproduct.
799 *
800  x( j ) = x( j ) - csumj
801  xj = cabs1( x( j ) )
802  IF( nounit ) THEN
803  tjjs = conjg( a( j, j ) )*tscal
804  ELSE
805  tjjs = tscal
806  IF( tscal.EQ.one )
807  $ go to 185
808  END IF
809 *
810 * Compute x(j) = x(j) / A(j,j), scaling if necessary.
811 *
812  tjj = cabs1( tjjs )
813  IF( tjj.GT.smlnum ) THEN
814 *
815 * abs(A(j,j)) > SMLNUM:
816 *
817  IF( tjj.LT.one ) THEN
818  IF( xj.GT.tjj*bignum ) THEN
819 *
820 * Scale X by 1/abs(x(j)).
821 *
822  rec = one / xj
823  CALL csscal( n, rec, x, 1 )
824  scale = scale*rec
825  xmax = xmax*rec
826  END IF
827  END IF
828  x( j ) = cladiv( x( j ), tjjs )
829  ELSE IF( tjj.GT.zero ) THEN
830 *
831 * 0 < abs(A(j,j)) <= SMLNUM:
832 *
833  IF( xj.GT.tjj*bignum ) THEN
834 *
835 * Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM.
836 *
837  rec = ( tjj*bignum ) / xj
838  CALL csscal( n, rec, x, 1 )
839  scale = scale*rec
840  xmax = xmax*rec
841  END IF
842  x( j ) = cladiv( x( j ), tjjs )
843  ELSE
844 *
845 * A(j,j) = 0: Set x(1:n) = 0, x(j) = 1, and
846 * scale = 0 and compute a solution to A**H *x = 0.
847 *
848  DO 180 i = 1, n
849  x( i ) = zero
850  180 continue
851  x( j ) = one
852  scale = zero
853  xmax = zero
854  END IF
855  185 continue
856  ELSE
857 *
858 * Compute x(j) := x(j) / A(j,j) - CSUMJ if the dot
859 * product has already been divided by 1/A(j,j).
860 *
861  x( j ) = cladiv( x( j ), tjjs ) - csumj
862  END IF
863  xmax = max( xmax, cabs1( x( j ) ) )
864  190 continue
865  END IF
866  scale = scale / tscal
867  END IF
868 *
869 * Scale the column norms by 1/TSCAL for return.
870 *
871  IF( tscal.NE.one ) THEN
872  CALL sscal( n, one / tscal, cnorm, 1 )
873  END IF
874 *
875  return
876 *
877 * End of CLATRS
878 *
879  END