1 *> \brief \b DLALN2 solves a 1-by-1 or 2-by-2 linear system of equations of the specified form.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DLALN2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlaln2.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlaln2.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlaln2.f">
21 * SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,
22 * LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )
24 * .. Scalar Arguments ..
26 * INTEGER INFO, LDA, LDB, LDX, NA, NW
27 * DOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM
29 * .. Array Arguments ..
30 * DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * )
39 *> DLALN2 solves a system of the form (ca A - w D ) X = s B
40 *> or (ca A**T - w D) X = s B with possible scaling ("s") and
41 *> perturbation of A. (A**T means A-transpose.)
43 *> A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
44 *> real diagonal matrix, w is a real or complex value, and X and B are
45 *> NA x 1 matrices -- real if w is real, complex if w is complex. NA
48 *> If w is complex, X and B are represented as NA x 2 matrices,
49 *> the first column of each being the real part and the second
50 *> being the imaginary part.
52 *> "s" is a scaling factor (.LE. 1), computed by DLALN2, which is
53 *> so chosen that X can be computed without overflow. X is further
54 *> scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
57 *> If both singular values of (ca A - w D) are less than SMIN,
58 *> SMIN*identity will be used instead of (ca A - w D). If only one
59 *> singular value is less than SMIN, one element of (ca A - w D) will be
60 *> perturbed enough to make the smallest singular value roughly SMIN.
61 *> If both singular values are at least SMIN, (ca A - w D) will not be
62 *> perturbed. In any case, the perturbation will be at most some small
63 *> multiple of max( SMIN, ulp*norm(ca A - w D) ). The singular values
64 *> are computed by infinity-norm approximations, and thus will only be
65 *> correct to a factor of 2 or so.
67 *> Note: all input quantities are assumed to be smaller than overflow
68 *> by a reasonable factor. (See BIGNUM.)
77 *> =.TRUE.: A-transpose will be used.
78 *> =.FALSE.: A will be used (not transposed.)
84 *> The size of the matrix A. It may (only) be 1 or 2.
90 *> 1 if "w" is real, 2 if "w" is complex. It may only be 1
96 *> SMIN is DOUBLE PRECISION
97 *> The desired lower bound on the singular values of A. This
98 *> should be a safe distance away from underflow or overflow,
99 *> say, between (underflow/machine precision) and (machine
100 *> precision * overflow ). (See BIGNUM and ULP.)
105 *> CA is DOUBLE PRECISION
106 *> The coefficient c, which A is multiplied by.
111 *> A is DOUBLE PRECISION array, dimension (LDA,NA)
112 *> The NA x NA matrix A.
118 *> The leading dimension of A. It must be at least NA.
123 *> D1 is DOUBLE PRECISION
124 *> The 1,1 element in the diagonal matrix D.
129 *> D2 is DOUBLE PRECISION
130 *> The 2,2 element in the diagonal matrix D. Not used if NA=1.
135 *> B is DOUBLE PRECISION array, dimension (LDB,NW)
136 *> The NA x NW matrix B (right-hand side). If NW=2 ("w" is
137 *> complex), column 1 contains the real part of B and column 2
138 *> contains the imaginary part.
144 *> The leading dimension of B. It must be at least NA.
149 *> WR is DOUBLE PRECISION
150 *> The real part of the scalar "w".
155 *> WI is DOUBLE PRECISION
156 *> The imaginary part of the scalar "w". Not used if NW=1.
161 *> X is DOUBLE PRECISION array, dimension (LDX,NW)
162 *> The NA x NW matrix X (unknowns), as computed by DLALN2.
163 *> If NW=2 ("w" is complex), on exit, column 1 will contain
164 *> the real part of X and column 2 will contain the imaginary
171 *> The leading dimension of X. It must be at least NA.
176 *> SCALE is DOUBLE PRECISION
177 *> The scale factor that B must be multiplied by to insure
178 *> that overflow does not occur when computing X. Thus,
179 *> (ca A - w D) X will be SCALE*B, not B (ignoring
180 *> perturbations of A.) It will be at most 1.
185 *> XNORM is DOUBLE PRECISION
186 *> The infinity-norm of X, when X is regarded as an NA x NW
193 *> An error flag. It will be set to zero if no error occurs,
194 *> a negative number if an argument is in error, or a positive
195 *> number if ca A - w D had to be perturbed.
196 *> The possible values are:
197 *> = 0: No error occurred, and (ca A - w D) did not have to be
199 *> = 1: (ca A - w D) had to be perturbed to make its smallest
200 *> (or only) singular value greater than SMIN.
201 *> NOTE: In the interests of speed, this routine does not
202 *> check the inputs for errors.
208 *> \author Univ. of Tennessee
209 *> \author Univ. of California Berkeley
210 *> \author Univ. of Colorado Denver
213 *> \date September 2012
215 *> \ingroup doubleOTHERauxiliary
217 * =====================================================================
218 SUBROUTINE DLALN2( LTRANS, NA, NW, SMIN, CA, A, LDA, D1, D2, B,
219 $ LDB, WR, WI, X, LDX, SCALE, XNORM, INFO )
221 * -- LAPACK auxiliary routine (version 3.4.2) --
222 * -- LAPACK is a software package provided by Univ. of Tennessee, --
223 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
226 * .. Scalar Arguments ..
228 INTEGER INFO, LDA, LDB, LDX, NA, NW
229 DOUBLE PRECISION CA, D1, D2, SCALE, SMIN, WI, WR, XNORM
231 * .. Array Arguments ..
232 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), X( LDX, * )
235 * =====================================================================
238 DOUBLE PRECISION ZERO, ONE
239 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
241 PARAMETER ( TWO = 2.0D0 )
243 * .. Local Scalars ..
245 DOUBLE PRECISION BBND, BI1, BI2, BIGNUM, BNORM, BR1, BR2, CI21,
246 $ CI22, CMAX, CNORM, CR21, CR22, CSI, CSR, LI21,
247 $ LR21, SMINI, SMLNUM, TEMP, U22ABS, UI11, UI11R,
248 $ UI12, UI12S, UI22, UR11, UR11R, UR12, UR12S,
249 $ UR22, XI1, XI2, XR1, XR2
252 LOGICAL RSWAP( 4 ), ZSWAP( 4 )
253 INTEGER IPIVOT( 4, 4 )
254 DOUBLE PRECISION CI( 2, 2 ), CIV( 4 ), CR( 2, 2 ), CRV( 4 )
256 * .. External Functions ..
257 DOUBLE PRECISION DLAMCH
260 * .. External Subroutines ..
263 * .. Intrinsic Functions ..
267 EQUIVALENCE ( CI( 1, 1 ), CIV( 1 ) ),
268 $ ( CR( 1, 1 ), CRV( 1 ) )
270 * .. Data statements ..
271 DATA ZSWAP / .FALSE., .FALSE., .TRUE., .TRUE. /
272 DATA RSWAP / .FALSE., .TRUE., .FALSE., .TRUE. /
273 DATA IPIVOT / 1, 2, 3, 4, 2, 1, 4, 3, 3, 4, 1, 2, 4,
276 * .. Executable Statements ..
280 SMLNUM = TWO*DLAMCH( 'Safe minimum' )
281 BIGNUM = ONE / SMLNUM
282 SMINI = MAX( SMIN, SMLNUM )
284 * Don't check for input errors
288 * Standard Initializations
294 * 1 x 1 (i.e., scalar) system C X = B
302 CSR = CA*A( 1, 1 ) - WR*D1
305 * If | C | < SMINI, use C = SMINI
307 IF( CNORM.LT.SMINI ) THEN
313 * Check scaling for X = B / C
315 BNORM = ABS( B( 1, 1 ) )
316 IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
317 IF( BNORM.GT.BIGNUM*CNORM )
318 $ SCALE = ONE / BNORM
323 X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / CSR
324 XNORM = ABS( X( 1, 1 ) )
327 * Complex 1x1 system (w is complex)
331 CSR = CA*A( 1, 1 ) - WR*D1
333 CNORM = ABS( CSR ) + ABS( CSI )
335 * If | C | < SMINI, use C = SMINI
337 IF( CNORM.LT.SMINI ) THEN
344 * Check scaling for X = B / C
346 BNORM = ABS( B( 1, 1 ) ) + ABS( B( 1, 2 ) )
347 IF( CNORM.LT.ONE .AND. BNORM.GT.ONE ) THEN
348 IF( BNORM.GT.BIGNUM*CNORM )
349 $ SCALE = ONE / BNORM
354 CALL DLADIV( SCALE*B( 1, 1 ), SCALE*B( 1, 2 ), CSR, CSI,
355 $ X( 1, 1 ), X( 1, 2 ) )
356 XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
363 * Compute the real part of C = ca A - w D (or ca A**T - w D )
365 CR( 1, 1 ) = CA*A( 1, 1 ) - WR*D1
366 CR( 2, 2 ) = CA*A( 2, 2 ) - WR*D2
368 CR( 1, 2 ) = CA*A( 2, 1 )
369 CR( 2, 1 ) = CA*A( 1, 2 )
371 CR( 2, 1 ) = CA*A( 2, 1 )
372 CR( 1, 2 ) = CA*A( 1, 2 )
377 * Real 2x2 system (w is real)
379 * Find the largest element in C
385 IF( ABS( CRV( J ) ).GT.CMAX ) THEN
386 CMAX = ABS( CRV( J ) )
391 * If norm(C) < SMINI, use SMINI*identity.
393 IF( CMAX.LT.SMINI ) THEN
394 BNORM = MAX( ABS( B( 1, 1 ) ), ABS( B( 2, 1 ) ) )
395 IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
396 IF( BNORM.GT.BIGNUM*SMINI )
397 $ SCALE = ONE / BNORM
400 X( 1, 1 ) = TEMP*B( 1, 1 )
401 X( 2, 1 ) = TEMP*B( 2, 1 )
407 * Gaussian elimination with complete pivoting.
410 CR21 = CRV( IPIVOT( 2, ICMAX ) )
411 UR12 = CRV( IPIVOT( 3, ICMAX ) )
412 CR22 = CRV( IPIVOT( 4, ICMAX ) )
415 UR22 = CR22 - UR12*LR21
417 * If smaller pivot < SMINI, use SMINI
419 IF( ABS( UR22 ).LT.SMINI ) THEN
423 IF( RSWAP( ICMAX ) ) THEN
431 BBND = MAX( ABS( BR1*( UR22*UR11R ) ), ABS( BR2 ) )
432 IF( BBND.GT.ONE .AND. ABS( UR22 ).LT.ONE ) THEN
433 IF( BBND.GE.BIGNUM*ABS( UR22 ) )
437 XR2 = ( BR2*SCALE ) / UR22
438 XR1 = ( SCALE*BR1 )*UR11R - XR2*( UR11R*UR12 )
439 IF( ZSWAP( ICMAX ) ) THEN
446 XNORM = MAX( ABS( XR1 ), ABS( XR2 ) )
448 * Further scaling if norm(A) norm(X) > overflow
450 IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
451 IF( XNORM.GT.BIGNUM / CMAX ) THEN
453 X( 1, 1 ) = TEMP*X( 1, 1 )
454 X( 2, 1 ) = TEMP*X( 2, 1 )
461 * Complex 2x2 system (w is complex)
463 * Find the largest element in C
473 IF( ABS( CRV( J ) )+ABS( CIV( J ) ).GT.CMAX ) THEN
474 CMAX = ABS( CRV( J ) ) + ABS( CIV( J ) )
479 * If norm(C) < SMINI, use SMINI*identity.
481 IF( CMAX.LT.SMINI ) THEN
482 BNORM = MAX( ABS( B( 1, 1 ) )+ABS( B( 1, 2 ) ),
483 $ ABS( B( 2, 1 ) )+ABS( B( 2, 2 ) ) )
484 IF( SMINI.LT.ONE .AND. BNORM.GT.ONE ) THEN
485 IF( BNORM.GT.BIGNUM*SMINI )
486 $ SCALE = ONE / BNORM
489 X( 1, 1 ) = TEMP*B( 1, 1 )
490 X( 2, 1 ) = TEMP*B( 2, 1 )
491 X( 1, 2 ) = TEMP*B( 1, 2 )
492 X( 2, 2 ) = TEMP*B( 2, 2 )
498 * Gaussian elimination with complete pivoting.
502 CR21 = CRV( IPIVOT( 2, ICMAX ) )
503 CI21 = CIV( IPIVOT( 2, ICMAX ) )
504 UR12 = CRV( IPIVOT( 3, ICMAX ) )
505 UI12 = CIV( IPIVOT( 3, ICMAX ) )
506 CR22 = CRV( IPIVOT( 4, ICMAX ) )
507 CI22 = CIV( IPIVOT( 4, ICMAX ) )
508 IF( ICMAX.EQ.1 .OR. ICMAX.EQ.4 ) THEN
510 * Code when off-diagonals of pivoted C are real
512 IF( ABS( UR11 ).GT.ABS( UI11 ) ) THEN
514 UR11R = ONE / ( UR11*( ONE+TEMP**2 ) )
518 UI11R = -ONE / ( UI11*( ONE+TEMP**2 ) )
525 UR22 = CR22 - UR12*LR21
526 UI22 = CI22 - UR12*LI21
529 * Code when diagonals of pivoted C are real
537 UR22 = CR22 - UR12*LR21 + UI12*LI21
538 UI22 = -UR12*LI21 - UI12*LR21
540 U22ABS = ABS( UR22 ) + ABS( UI22 )
542 * If smaller pivot < SMINI, use SMINI
544 IF( U22ABS.LT.SMINI ) THEN
549 IF( RSWAP( ICMAX ) ) THEN
560 BR2 = BR2 - LR21*BR1 + LI21*BI1
561 BI2 = BI2 - LI21*BR1 - LR21*BI1
562 BBND = MAX( ( ABS( BR1 )+ABS( BI1 ) )*
563 $ ( U22ABS*( ABS( UR11R )+ABS( UI11R ) ) ),
564 $ ABS( BR2 )+ABS( BI2 ) )
565 IF( BBND.GT.ONE .AND. U22ABS.LT.ONE ) THEN
566 IF( BBND.GE.BIGNUM*U22ABS ) THEN
575 CALL DLADIV( BR2, BI2, UR22, UI22, XR2, XI2 )
576 XR1 = UR11R*BR1 - UI11R*BI1 - UR12S*XR2 + UI12S*XI2
577 XI1 = UI11R*BR1 + UR11R*BI1 - UI12S*XR2 - UR12S*XI2
578 IF( ZSWAP( ICMAX ) ) THEN
589 XNORM = MAX( ABS( XR1 )+ABS( XI1 ), ABS( XR2 )+ABS( XI2 ) )
591 * Further scaling if norm(A) norm(X) > overflow
593 IF( XNORM.GT.ONE .AND. CMAX.GT.ONE ) THEN
594 IF( XNORM.GT.BIGNUM / CMAX ) THEN
596 X( 1, 1 ) = TEMP*X( 1, 1 )
597 X( 2, 1 ) = TEMP*X( 2, 1 )
598 X( 1, 2 ) = TEMP*X( 1, 2 )
599 X( 2, 2 ) = TEMP*X( 2, 2 )