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