1 *> \brief \b SLAQTR solves a real quasi-triangular system of equations, or a complex quasi-triangular system of special form, in real arithmetic.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SLAQTR + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slaqtr.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slaqtr.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slaqtr.f">
21 * SUBROUTINE SLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,
24 * .. Scalar Arguments ..
25 * LOGICAL LREAL, LTRAN
26 * INTEGER INFO, LDT, N
29 * .. Array Arguments ..
30 * REAL B( * ), T( LDT, * ), WORK( * ), X( * )
39 *> SLAQTR solves the real quasi-triangular system
41 *> op(T)*p = scale*c, if LREAL = .TRUE.
43 *> or the complex quasi-triangular systems
45 *> op(T + iB)*(p+iq) = scale*(c+id), if LREAL = .FALSE.
47 *> in real arithmetic, where T is upper quasi-triangular.
48 *> If LREAL = .FALSE., then the first diagonal block of T must be
49 *> 1 by 1, B is the specially structured matrix
51 *> B = [ b(1) b(2) ... b(n) ]
57 *> op(A) = A or A**T, A**T denotes the transpose of
60 *> On input, X = [ c ]. On output, X = [ p ].
63 *> This subroutine is designed for the condition number estimation
73 *> On entry, LTRAN specifies the option of conjugate transpose:
74 *> = .FALSE., op(T+i*B) = T+i*B,
75 *> = .TRUE., op(T+i*B) = (T+i*B)**T.
81 *> On entry, LREAL specifies the input matrix structure:
82 *> = .FALSE., the input is complex
83 *> = .TRUE., the input is real
89 *> On entry, N specifies the order of T+i*B. N >= 0.
94 *> T is REAL array, dimension (LDT,N)
95 *> On entry, T contains a matrix in Schur canonical form.
96 *> If LREAL = .FALSE., then the first diagonal block of T must
103 *> The leading dimension of the matrix T. LDT >= max(1,N).
108 *> B is REAL array, dimension (N)
109 *> On entry, B contains the elements to form the matrix
110 *> B as described above.
111 *> If LREAL = .TRUE., B is not referenced.
117 *> On entry, W is the diagonal element of the matrix B.
118 *> If LREAL = .TRUE., W is not referenced.
124 *> On exit, SCALE is the scale factor.
129 *> X is REAL array, dimension (2*N)
130 *> On entry, X contains the right hand side of the system.
131 *> On exit, X is overwritten by the solution.
136 *> WORK is REAL array, dimension (N)
142 *> On exit, INFO is set to
143 *> 0: successful exit.
144 *> 1: the some diagonal 1 by 1 block has been perturbed by
145 *> a small number SMIN to keep nonsingularity.
146 *> 2: the some diagonal 2 by 2 block has been perturbed by
147 *> a small number in SLALN2 to keep nonsingularity.
148 *> NOTE: In the interests of speed, this routine does not
149 *> check the inputs for errors.
155 *> \author Univ. of Tennessee
156 *> \author Univ. of California Berkeley
157 *> \author Univ. of Colorado Denver
160 *> \date September 2012
162 *> \ingroup realOTHERauxiliary
164 * =====================================================================
165 SUBROUTINE SLAQTR( LTRAN, LREAL, N, T, LDT, B, W, SCALE, X, WORK,
168 * -- LAPACK auxiliary routine (version 3.4.2) --
169 * -- LAPACK is a software package provided by Univ. of Tennessee, --
170 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
173 * .. Scalar Arguments ..
178 * .. Array Arguments ..
179 REAL B( * ), T( LDT, * ), WORK( * ), X( * )
182 * =====================================================================
186 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
188 * .. Local Scalars ..
190 INTEGER I, IERR, J, J1, J2, JNEXT, K, N1, N2
191 REAL BIGNUM, EPS, REC, SCALOC, SI, SMIN, SMINW,
192 $ SMLNUM, SR, TJJ, TMP, XJ, XMAX, XNORM, Z
195 REAL D( 2, 2 ), V( 2, 2 )
197 * .. External Functions ..
199 REAL SASUM, SDOT, SLAMCH, SLANGE
200 EXTERNAL ISAMAX, SASUM, SDOT, SLAMCH, SLANGE
202 * .. External Subroutines ..
203 EXTERNAL SAXPY, SLADIV, SLALN2, SSCAL
205 * .. Intrinsic Functions ..
208 * .. Executable Statements ..
210 * Do not test the input parameters for errors
215 * Quick return if possible
220 * Set constants to control overflow
223 SMLNUM = SLAMCH( 'S' ) / EPS
224 BIGNUM = ONE / SMLNUM
226 XNORM = SLANGE( 'M', N, N, T, LDT, D )
228 $ XNORM = MAX( XNORM, ABS( W ), SLANGE( 'M', N, 1, B, N, D ) )
229 SMIN = MAX( SMLNUM, EPS*XNORM )
231 * Compute 1-norm of each column of strictly upper triangular
232 * part of T to control overflow in triangular solver.
236 WORK( J ) = SASUM( J-1, T( 1, J ), 1 )
239 IF( .NOT.LREAL ) THEN
241 WORK( I ) = WORK( I ) + ABS( B( I ) )
249 K = ISAMAX( N1, X, 1 )
253 IF( XMAX.GT.BIGNUM ) THEN
254 SCALE = BIGNUM / XMAX
255 CALL SSCAL( N1, SCALE, X, 1 )
263 * Solve T*p = scale*c
273 IF( T( J, J-1 ).NE.ZERO ) THEN
281 * Meet 1 by 1 diagonal block
283 * Scale to avoid overflow when computing
287 TJJ = ABS( T( J1, J1 ) )
289 IF( TJJ.LT.SMIN ) THEN
298 IF( TJJ.LT.ONE ) THEN
299 IF( XJ.GT.BIGNUM*TJJ ) THEN
301 CALL SSCAL( N, REC, X, 1 )
306 X( J1 ) = X( J1 ) / TMP
309 * Scale x if necessary to avoid overflow when adding a
310 * multiple of column j1 of T.
314 IF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THEN
315 CALL SSCAL( N, REC, X, 1 )
320 CALL SAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
321 K = ISAMAX( J1-1, X, 1 )
327 * Meet 2 by 2 diagonal block
329 * Call 2 by 2 linear system solve, to take
330 * care of possible overflow by scaling factor.
334 CALL SLALN2( .FALSE., 2, 1, SMIN, ONE, T( J1, J1 ),
335 $ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,
336 $ SCALOC, XNORM, IERR )
340 IF( SCALOC.NE.ONE ) THEN
341 CALL SSCAL( N, SCALOC, X, 1 )
347 * Scale V(1,1) (= X(J1)) and/or V(2,1) (=X(J2))
348 * to avoid overflow in updating right-hand side.
350 XJ = MAX( ABS( V( 1, 1 ) ), ABS( V( 2, 1 ) ) )
353 IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
354 $ ( BIGNUM-XMAX )*REC ) THEN
355 CALL SSCAL( N, REC, X, 1 )
360 * Update right-hand side
363 CALL SAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
364 CALL SAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )
365 K = ISAMAX( J1-1, X, 1 )
375 * Solve T**T*p = scale*c
385 IF( T( J+1, J ).NE.ZERO ) THEN
393 * 1 by 1 diagonal block
395 * Scale if necessary to avoid overflow in forming the
396 * right-hand side element by inner product.
399 IF( XMAX.GT.ONE ) THEN
401 IF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THEN
402 CALL SSCAL( N, REC, X, 1 )
408 X( J1 ) = X( J1 ) - SDOT( J1-1, T( 1, J1 ), 1, X, 1 )
411 TJJ = ABS( T( J1, J1 ) )
413 IF( TJJ.LT.SMIN ) THEN
419 IF( TJJ.LT.ONE ) THEN
420 IF( XJ.GT.BIGNUM*TJJ ) THEN
422 CALL SSCAL( N, REC, X, 1 )
427 X( J1 ) = X( J1 ) / TMP
428 XMAX = MAX( XMAX, ABS( X( J1 ) ) )
432 * 2 by 2 diagonal block
434 * Scale if necessary to avoid overflow in forming the
435 * right-hand side elements by inner product.
437 XJ = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ) )
438 IF( XMAX.GT.ONE ) THEN
440 IF( MAX( WORK( J2 ), WORK( J1 ) ).GT.( BIGNUM-XJ )*
442 CALL SSCAL( N, REC, X, 1 )
448 D( 1, 1 ) = X( J1 ) - SDOT( J1-1, T( 1, J1 ), 1, X,
450 D( 2, 1 ) = X( J2 ) - SDOT( J1-1, T( 1, J2 ), 1, X,
453 CALL SLALN2( .TRUE., 2, 1, SMIN, ONE, T( J1, J1 ),
454 $ LDT, ONE, ONE, D, 2, ZERO, ZERO, V, 2,
455 $ SCALOC, XNORM, IERR )
459 IF( SCALOC.NE.ONE ) THEN
460 CALL SSCAL( N, SCALOC, X, 1 )
465 XMAX = MAX( ABS( X( J1 ) ), ABS( X( J2 ) ), XMAX )
473 SMINW = MAX( EPS*ABS( W ), SMIN )
476 * Solve (T + iB)*(p+iq) = c+id
486 IF( T( J, J-1 ).NE.ZERO ) THEN
494 * 1 by 1 diagonal block
496 * Scale if necessary to avoid overflow in division
501 XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )
502 TJJ = ABS( T( J1, J1 ) ) + ABS( Z )
504 IF( TJJ.LT.SMINW ) THEN
513 IF( TJJ.LT.ONE ) THEN
514 IF( XJ.GT.BIGNUM*TJJ ) THEN
516 CALL SSCAL( N2, REC, X, 1 )
521 CALL SLADIV( X( J1 ), X( N+J1 ), TMP, Z, SR, SI )
524 XJ = ABS( X( J1 ) ) + ABS( X( N+J1 ) )
526 * Scale x if necessary to avoid overflow when adding a
527 * multiple of column j1 of T.
531 IF( WORK( J1 ).GT.( BIGNUM-XMAX )*REC ) THEN
532 CALL SSCAL( N2, REC, X, 1 )
538 CALL SAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
539 CALL SAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,
542 X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 )
543 X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 )
547 XMAX = MAX( XMAX, ABS( X( K ) )+
554 * Meet 2 by 2 diagonal block
558 D( 1, 2 ) = X( N+J1 )
559 D( 2, 2 ) = X( N+J2 )
560 CALL SLALN2( .FALSE., 2, 2, SMINW, ONE, T( J1, J1 ),
561 $ LDT, ONE, ONE, D, 2, ZERO, -W, V, 2,
562 $ SCALOC, XNORM, IERR )
566 IF( SCALOC.NE.ONE ) THEN
567 CALL SSCAL( 2*N, SCALOC, X, 1 )
572 X( N+J1 ) = V( 1, 2 )
573 X( N+J2 ) = V( 2, 2 )
575 * Scale X(J1), .... to avoid overflow in
576 * updating right hand side.
578 XJ = MAX( ABS( V( 1, 1 ) )+ABS( V( 1, 2 ) ),
579 $ ABS( V( 2, 1 ) )+ABS( V( 2, 2 ) ) )
582 IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
583 $ ( BIGNUM-XMAX )*REC ) THEN
584 CALL SSCAL( N2, REC, X, 1 )
589 * Update the right-hand side.
592 CALL SAXPY( J1-1, -X( J1 ), T( 1, J1 ), 1, X, 1 )
593 CALL SAXPY( J1-1, -X( J2 ), T( 1, J2 ), 1, X, 1 )
595 CALL SAXPY( J1-1, -X( N+J1 ), T( 1, J1 ), 1,
597 CALL SAXPY( J1-1, -X( N+J2 ), T( 1, J2 ), 1,
600 X( 1 ) = X( 1 ) + B( J1 )*X( N+J1 ) +
602 X( N+1 ) = X( N+1 ) - B( J1 )*X( J1 ) -
607 XMAX = MAX( ABS( X( K ) )+ABS( X( K+N ) ),
617 * Solve (T + iB)**T*(p+iq) = c+id
627 IF( T( J+1, J ).NE.ZERO ) THEN
635 * 1 by 1 diagonal block
637 * Scale if necessary to avoid overflow in forming the
638 * right-hand side element by inner product.
640 XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )
641 IF( XMAX.GT.ONE ) THEN
643 IF( WORK( J1 ).GT.( BIGNUM-XJ )*REC ) THEN
644 CALL SSCAL( N2, REC, X, 1 )
650 X( J1 ) = X( J1 ) - SDOT( J1-1, T( 1, J1 ), 1, X, 1 )
651 X( N+J1 ) = X( N+J1 ) - SDOT( J1-1, T( 1, J1 ), 1,
654 X( J1 ) = X( J1 ) - B( J1 )*X( N+1 )
655 X( N+J1 ) = X( N+J1 ) + B( J1 )*X( 1 )
657 XJ = ABS( X( J1 ) ) + ABS( X( J1+N ) )
663 * Scale if necessary to avoid overflow in
666 TJJ = ABS( T( J1, J1 ) ) + ABS( Z )
668 IF( TJJ.LT.SMINW ) THEN
674 IF( TJJ.LT.ONE ) THEN
675 IF( XJ.GT.BIGNUM*TJJ ) THEN
677 CALL SSCAL( N2, REC, X, 1 )
682 CALL SLADIV( X( J1 ), X( N+J1 ), TMP, -Z, SR, SI )
685 XMAX = MAX( ABS( X( J1 ) )+ABS( X( J1+N ) ), XMAX )
689 * 2 by 2 diagonal block
691 * Scale if necessary to avoid overflow in forming the
692 * right-hand side element by inner product.
694 XJ = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),
695 $ ABS( X( J2 ) )+ABS( X( N+J2 ) ) )
696 IF( XMAX.GT.ONE ) THEN
698 IF( MAX( WORK( J1 ), WORK( J2 ) ).GT.
699 $ ( BIGNUM-XJ ) / XMAX ) THEN
700 CALL SSCAL( N2, REC, X, 1 )
706 D( 1, 1 ) = X( J1 ) - SDOT( J1-1, T( 1, J1 ), 1, X,
708 D( 2, 1 ) = X( J2 ) - SDOT( J1-1, T( 1, J2 ), 1, X,
710 D( 1, 2 ) = X( N+J1 ) - SDOT( J1-1, T( 1, J1 ), 1,
712 D( 2, 2 ) = X( N+J2 ) - SDOT( J1-1, T( 1, J2 ), 1,
714 D( 1, 1 ) = D( 1, 1 ) - B( J1 )*X( N+1 )
715 D( 2, 1 ) = D( 2, 1 ) - B( J2 )*X( N+1 )
716 D( 1, 2 ) = D( 1, 2 ) + B( J1 )*X( 1 )
717 D( 2, 2 ) = D( 2, 2 ) + B( J2 )*X( 1 )
719 CALL SLALN2( .TRUE., 2, 2, SMINW, ONE, T( J1, J1 ),
720 $ LDT, ONE, ONE, D, 2, ZERO, W, V, 2,
721 $ SCALOC, XNORM, IERR )
725 IF( SCALOC.NE.ONE ) THEN
726 CALL SSCAL( N2, SCALOC, X, 1 )
731 X( N+J1 ) = V( 1, 2 )
732 X( N+J2 ) = V( 2, 2 )
733 XMAX = MAX( ABS( X( J1 ) )+ABS( X( N+J1 ) ),
734 $ ABS( X( J2 ) )+ABS( X( N+J2 ) ), XMAX )