00001 SUBROUTINE DLAG2( A, LDA, B, LDB, SAFMIN, SCALE1, SCALE2, WR1,
00002 $ WR2, WI )
00003
00004
00005
00006
00007
00008
00009
00010 INTEGER LDA, LDB
00011 DOUBLE PRECISION SAFMIN, SCALE1, SCALE2, WI, WR1, WR2
00012
00013
00014 DOUBLE PRECISION A( LDA, * ), B( LDB, * )
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 DOUBLE PRECISION ZERO, ONE, TWO
00098 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0 )
00099 DOUBLE PRECISION HALF
00100 PARAMETER ( HALF = ONE / TWO )
00101 DOUBLE PRECISION FUZZY1
00102 PARAMETER ( FUZZY1 = ONE+1.0D-5 )
00103
00104
00105 DOUBLE PRECISION A11, A12, A21, A22, ABI22, ANORM, AS11, AS12,
00106 $ AS22, ASCALE, B11, B12, B22, BINV11, BINV22,
00107 $ BMIN, BNORM, BSCALE, BSIZE, C1, C2, C3, C4, C5,
00108 $ DIFF, DISCR, PP, QQ, R, RTMAX, RTMIN, S1, S2,
00109 $ SAFMAX, SHIFT, SS, SUM, WABS, WBIG, WDET,
00110 $ WSCALE, WSIZE, WSMALL
00111
00112
00113 INTRINSIC ABS, MAX, MIN, SIGN, SQRT
00114
00115
00116
00117 RTMIN = SQRT( SAFMIN )
00118 RTMAX = ONE / RTMIN
00119 SAFMAX = ONE / SAFMIN
00120
00121
00122
00123 ANORM = MAX( ABS( A( 1, 1 ) )+ABS( A( 2, 1 ) ),
00124 $ ABS( A( 1, 2 ) )+ABS( A( 2, 2 ) ), SAFMIN )
00125 ASCALE = ONE / ANORM
00126 A11 = ASCALE*A( 1, 1 )
00127 A21 = ASCALE*A( 2, 1 )
00128 A12 = ASCALE*A( 1, 2 )
00129 A22 = ASCALE*A( 2, 2 )
00130
00131
00132
00133 B11 = B( 1, 1 )
00134 B12 = B( 1, 2 )
00135 B22 = B( 2, 2 )
00136 BMIN = RTMIN*MAX( ABS( B11 ), ABS( B12 ), ABS( B22 ), RTMIN )
00137 IF( ABS( B11 ).LT.BMIN )
00138 $ B11 = SIGN( BMIN, B11 )
00139 IF( ABS( B22 ).LT.BMIN )
00140 $ B22 = SIGN( BMIN, B22 )
00141
00142
00143
00144 BNORM = MAX( ABS( B11 ), ABS( B12 )+ABS( B22 ), SAFMIN )
00145 BSIZE = MAX( ABS( B11 ), ABS( B22 ) )
00146 BSCALE = ONE / BSIZE
00147 B11 = B11*BSCALE
00148 B12 = B12*BSCALE
00149 B22 = B22*BSCALE
00150
00151
00152
00153
00154
00155 BINV11 = ONE / B11
00156 BINV22 = ONE / B22
00157 S1 = A11*BINV11
00158 S2 = A22*BINV22
00159 IF( ABS( S1 ).LE.ABS( S2 ) ) THEN
00160 AS12 = A12 - S1*B12
00161 AS22 = A22 - S1*B22
00162 SS = A21*( BINV11*BINV22 )
00163 ABI22 = AS22*BINV22 - SS*B12
00164 PP = HALF*ABI22
00165 SHIFT = S1
00166 ELSE
00167 AS12 = A12 - S2*B12
00168 AS11 = A11 - S2*B11
00169 SS = A21*( BINV11*BINV22 )
00170 ABI22 = -SS*B12
00171 PP = HALF*( AS11*BINV11+ABI22 )
00172 SHIFT = S2
00173 END IF
00174 QQ = SS*AS12
00175 IF( ABS( PP*RTMIN ).GE.ONE ) THEN
00176 DISCR = ( RTMIN*PP )**2 + QQ*SAFMIN
00177 R = SQRT( ABS( DISCR ) )*RTMAX
00178 ELSE
00179 IF( PP**2+ABS( QQ ).LE.SAFMIN ) THEN
00180 DISCR = ( RTMAX*PP )**2 + QQ*SAFMAX
00181 R = SQRT( ABS( DISCR ) )*RTMIN
00182 ELSE
00183 DISCR = PP**2 + QQ
00184 R = SQRT( ABS( DISCR ) )
00185 END IF
00186 END IF
00187
00188
00189
00190
00191
00192
00193
00194 IF( DISCR.GE.ZERO .OR. R.EQ.ZERO ) THEN
00195 SUM = PP + SIGN( R, PP )
00196 DIFF = PP - SIGN( R, PP )
00197 WBIG = SHIFT + SUM
00198
00199
00200
00201 WSMALL = SHIFT + DIFF
00202 IF( HALF*ABS( WBIG ).GT.MAX( ABS( WSMALL ), SAFMIN ) ) THEN
00203 WDET = ( A11*A22-A12*A21 )*( BINV11*BINV22 )
00204 WSMALL = WDET / WBIG
00205 END IF
00206
00207
00208
00209
00210 IF( PP.GT.ABI22 ) THEN
00211 WR1 = MIN( WBIG, WSMALL )
00212 WR2 = MAX( WBIG, WSMALL )
00213 ELSE
00214 WR1 = MAX( WBIG, WSMALL )
00215 WR2 = MIN( WBIG, WSMALL )
00216 END IF
00217 WI = ZERO
00218 ELSE
00219
00220
00221
00222 WR1 = SHIFT + PP
00223 WR2 = WR1
00224 WI = R
00225 END IF
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 C1 = BSIZE*( SAFMIN*MAX( ONE, ASCALE ) )
00240 C2 = SAFMIN*MAX( ONE, BNORM )
00241 C3 = BSIZE*SAFMIN
00242 IF( ASCALE.LE.ONE .AND. BSIZE.LE.ONE ) THEN
00243 C4 = MIN( ONE, ( ASCALE / SAFMIN )*BSIZE )
00244 ELSE
00245 C4 = ONE
00246 END IF
00247 IF( ASCALE.LE.ONE .OR. BSIZE.LE.ONE ) THEN
00248 C5 = MIN( ONE, ASCALE*BSIZE )
00249 ELSE
00250 C5 = ONE
00251 END IF
00252
00253
00254
00255 WABS = ABS( WR1 ) + ABS( WI )
00256 WSIZE = MAX( SAFMIN, C1, FUZZY1*( WABS*C2+C3 ),
00257 $ MIN( C4, HALF*MAX( WABS, C5 ) ) )
00258 IF( WSIZE.NE.ONE ) THEN
00259 WSCALE = ONE / WSIZE
00260 IF( WSIZE.GT.ONE ) THEN
00261 SCALE1 = ( MAX( ASCALE, BSIZE )*WSCALE )*
00262 $ MIN( ASCALE, BSIZE )
00263 ELSE
00264 SCALE1 = ( MIN( ASCALE, BSIZE )*WSCALE )*
00265 $ MAX( ASCALE, BSIZE )
00266 END IF
00267 WR1 = WR1*WSCALE
00268 IF( WI.NE.ZERO ) THEN
00269 WI = WI*WSCALE
00270 WR2 = WR1
00271 SCALE2 = SCALE1
00272 END IF
00273 ELSE
00274 SCALE1 = ASCALE*BSIZE
00275 SCALE2 = SCALE1
00276 END IF
00277
00278
00279
00280 IF( WI.EQ.ZERO ) THEN
00281 WSIZE = MAX( SAFMIN, C1, FUZZY1*( ABS( WR2 )*C2+C3 ),
00282 $ MIN( C4, HALF*MAX( ABS( WR2 ), C5 ) ) )
00283 IF( WSIZE.NE.ONE ) THEN
00284 WSCALE = ONE / WSIZE
00285 IF( WSIZE.GT.ONE ) THEN
00286 SCALE2 = ( MAX( ASCALE, BSIZE )*WSCALE )*
00287 $ MIN( ASCALE, BSIZE )
00288 ELSE
00289 SCALE2 = ( MIN( ASCALE, BSIZE )*WSCALE )*
00290 $ MAX( ASCALE, BSIZE )
00291 END IF
00292 WR2 = WR2*WSCALE
00293 ELSE
00294 SCALE2 = ASCALE*BSIZE
00295 END IF
00296 END IF
00297
00298
00299
00300 RETURN
00301 END