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