00001 SUBROUTINE SLASY2( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,
00002 $ LDTR, B, LDB, SCALE, X, LDX, XNORM, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 LOGICAL LTRANL, LTRANR
00011 INTEGER INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2
00012 REAL SCALE, XNORM
00013
00014
00015 REAL B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),
00016 $ X( LDX, * )
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 REAL ZERO, ONE
00098 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
00099 REAL TWO, HALF, EIGHT
00100 PARAMETER ( TWO = 2.0E+0, HALF = 0.5E+0, EIGHT = 8.0E+0 )
00101
00102
00103 LOGICAL BSWAP, XSWAP
00104 INTEGER I, IP, IPIV, IPSV, J, JP, JPSV, K
00105 REAL BET, EPS, GAM, L21, SGN, SMIN, SMLNUM, TAU1,
00106 $ TEMP, U11, U12, U22, XMAX
00107
00108
00109 LOGICAL BSWPIV( 4 ), XSWPIV( 4 )
00110 INTEGER JPIV( 4 ), LOCL21( 4 ), LOCU12( 4 ),
00111 $ LOCU22( 4 )
00112 REAL BTMP( 4 ), T16( 4, 4 ), TMP( 4 ), X2( 2 )
00113
00114
00115 INTEGER ISAMAX
00116 REAL SLAMCH
00117 EXTERNAL ISAMAX, SLAMCH
00118
00119
00120 EXTERNAL SCOPY, SSWAP
00121
00122
00123 INTRINSIC ABS, MAX
00124
00125
00126 DATA LOCU12 / 3, 4, 1, 2 / , LOCL21 / 2, 1, 4, 3 / ,
00127 $ LOCU22 / 4, 3, 2, 1 /
00128 DATA XSWPIV / .FALSE., .FALSE., .TRUE., .TRUE. /
00129 DATA BSWPIV / .FALSE., .TRUE., .FALSE., .TRUE. /
00130
00131
00132
00133
00134
00135 INFO = 0
00136
00137
00138
00139 IF( N1.EQ.0 .OR. N2.EQ.0 )
00140 $ RETURN
00141
00142
00143
00144 EPS = SLAMCH( 'P' )
00145 SMLNUM = SLAMCH( 'S' ) / EPS
00146 SGN = ISGN
00147
00148 K = N1 + N1 + N2 - 2
00149 GO TO ( 10, 20, 30, 50 )K
00150
00151
00152
00153 10 CONTINUE
00154 TAU1 = TL( 1, 1 ) + SGN*TR( 1, 1 )
00155 BET = ABS( TAU1 )
00156 IF( BET.LE.SMLNUM ) THEN
00157 TAU1 = SMLNUM
00158 BET = SMLNUM
00159 INFO = 1
00160 END IF
00161
00162 SCALE = ONE
00163 GAM = ABS( B( 1, 1 ) )
00164 IF( SMLNUM*GAM.GT.BET )
00165 $ SCALE = ONE / GAM
00166
00167 X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / TAU1
00168 XNORM = ABS( X( 1, 1 ) )
00169 RETURN
00170
00171
00172
00173
00174
00175 20 CONTINUE
00176
00177 SMIN = MAX( EPS*MAX( ABS( TL( 1, 1 ) ), ABS( TR( 1, 1 ) ),
00178 $ ABS( TR( 1, 2 ) ), ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) ),
00179 $ SMLNUM )
00180 TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
00181 TMP( 4 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )
00182 IF( LTRANR ) THEN
00183 TMP( 2 ) = SGN*TR( 2, 1 )
00184 TMP( 3 ) = SGN*TR( 1, 2 )
00185 ELSE
00186 TMP( 2 ) = SGN*TR( 1, 2 )
00187 TMP( 3 ) = SGN*TR( 2, 1 )
00188 END IF
00189 BTMP( 1 ) = B( 1, 1 )
00190 BTMP( 2 ) = B( 1, 2 )
00191 GO TO 40
00192
00193
00194
00195
00196
00197 30 CONTINUE
00198 SMIN = MAX( EPS*MAX( ABS( TR( 1, 1 ) ), ABS( TL( 1, 1 ) ),
00199 $ ABS( TL( 1, 2 ) ), ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) ),
00200 $ SMLNUM )
00201 TMP( 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
00202 TMP( 4 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )
00203 IF( LTRANL ) THEN
00204 TMP( 2 ) = TL( 1, 2 )
00205 TMP( 3 ) = TL( 2, 1 )
00206 ELSE
00207 TMP( 2 ) = TL( 2, 1 )
00208 TMP( 3 ) = TL( 1, 2 )
00209 END IF
00210 BTMP( 1 ) = B( 1, 1 )
00211 BTMP( 2 ) = B( 2, 1 )
00212 40 CONTINUE
00213
00214
00215
00216
00217 IPIV = ISAMAX( 4, TMP, 1 )
00218 U11 = TMP( IPIV )
00219 IF( ABS( U11 ).LE.SMIN ) THEN
00220 INFO = 1
00221 U11 = SMIN
00222 END IF
00223 U12 = TMP( LOCU12( IPIV ) )
00224 L21 = TMP( LOCL21( IPIV ) ) / U11
00225 U22 = TMP( LOCU22( IPIV ) ) - U12*L21
00226 XSWAP = XSWPIV( IPIV )
00227 BSWAP = BSWPIV( IPIV )
00228 IF( ABS( U22 ).LE.SMIN ) THEN
00229 INFO = 1
00230 U22 = SMIN
00231 END IF
00232 IF( BSWAP ) THEN
00233 TEMP = BTMP( 2 )
00234 BTMP( 2 ) = BTMP( 1 ) - L21*TEMP
00235 BTMP( 1 ) = TEMP
00236 ELSE
00237 BTMP( 2 ) = BTMP( 2 ) - L21*BTMP( 1 )
00238 END IF
00239 SCALE = ONE
00240 IF( ( TWO*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( U22 ) .OR.
00241 $ ( TWO*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( U11 ) ) THEN
00242 SCALE = HALF / MAX( ABS( BTMP( 1 ) ), ABS( BTMP( 2 ) ) )
00243 BTMP( 1 ) = BTMP( 1 )*SCALE
00244 BTMP( 2 ) = BTMP( 2 )*SCALE
00245 END IF
00246 X2( 2 ) = BTMP( 2 ) / U22
00247 X2( 1 ) = BTMP( 1 ) / U11 - ( U12 / U11 )*X2( 2 )
00248 IF( XSWAP ) THEN
00249 TEMP = X2( 2 )
00250 X2( 2 ) = X2( 1 )
00251 X2( 1 ) = TEMP
00252 END IF
00253 X( 1, 1 ) = X2( 1 )
00254 IF( N1.EQ.1 ) THEN
00255 X( 1, 2 ) = X2( 2 )
00256 XNORM = ABS( X( 1, 1 ) ) + ABS( X( 1, 2 ) )
00257 ELSE
00258 X( 2, 1 ) = X2( 2 )
00259 XNORM = MAX( ABS( X( 1, 1 ) ), ABS( X( 2, 1 ) ) )
00260 END IF
00261 RETURN
00262
00263
00264
00265
00266
00267
00268
00269
00270 50 CONTINUE
00271 SMIN = MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),
00272 $ ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )
00273 SMIN = MAX( SMIN, ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),
00274 $ ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )
00275 SMIN = MAX( EPS*SMIN, SMLNUM )
00276 BTMP( 1 ) = ZERO
00277 CALL SCOPY( 16, BTMP, 0, T16, 1 )
00278 T16( 1, 1 ) = TL( 1, 1 ) + SGN*TR( 1, 1 )
00279 T16( 2, 2 ) = TL( 2, 2 ) + SGN*TR( 1, 1 )
00280 T16( 3, 3 ) = TL( 1, 1 ) + SGN*TR( 2, 2 )
00281 T16( 4, 4 ) = TL( 2, 2 ) + SGN*TR( 2, 2 )
00282 IF( LTRANL ) THEN
00283 T16( 1, 2 ) = TL( 2, 1 )
00284 T16( 2, 1 ) = TL( 1, 2 )
00285 T16( 3, 4 ) = TL( 2, 1 )
00286 T16( 4, 3 ) = TL( 1, 2 )
00287 ELSE
00288 T16( 1, 2 ) = TL( 1, 2 )
00289 T16( 2, 1 ) = TL( 2, 1 )
00290 T16( 3, 4 ) = TL( 1, 2 )
00291 T16( 4, 3 ) = TL( 2, 1 )
00292 END IF
00293 IF( LTRANR ) THEN
00294 T16( 1, 3 ) = SGN*TR( 1, 2 )
00295 T16( 2, 4 ) = SGN*TR( 1, 2 )
00296 T16( 3, 1 ) = SGN*TR( 2, 1 )
00297 T16( 4, 2 ) = SGN*TR( 2, 1 )
00298 ELSE
00299 T16( 1, 3 ) = SGN*TR( 2, 1 )
00300 T16( 2, 4 ) = SGN*TR( 2, 1 )
00301 T16( 3, 1 ) = SGN*TR( 1, 2 )
00302 T16( 4, 2 ) = SGN*TR( 1, 2 )
00303 END IF
00304 BTMP( 1 ) = B( 1, 1 )
00305 BTMP( 2 ) = B( 2, 1 )
00306 BTMP( 3 ) = B( 1, 2 )
00307 BTMP( 4 ) = B( 2, 2 )
00308
00309
00310
00311 DO 100 I = 1, 3
00312 XMAX = ZERO
00313 DO 70 IP = I, 4
00314 DO 60 JP = I, 4
00315 IF( ABS( T16( IP, JP ) ).GE.XMAX ) THEN
00316 XMAX = ABS( T16( IP, JP ) )
00317 IPSV = IP
00318 JPSV = JP
00319 END IF
00320 60 CONTINUE
00321 70 CONTINUE
00322 IF( IPSV.NE.I ) THEN
00323 CALL SSWAP( 4, T16( IPSV, 1 ), 4, T16( I, 1 ), 4 )
00324 TEMP = BTMP( I )
00325 BTMP( I ) = BTMP( IPSV )
00326 BTMP( IPSV ) = TEMP
00327 END IF
00328 IF( JPSV.NE.I )
00329 $ CALL SSWAP( 4, T16( 1, JPSV ), 1, T16( 1, I ), 1 )
00330 JPIV( I ) = JPSV
00331 IF( ABS( T16( I, I ) ).LT.SMIN ) THEN
00332 INFO = 1
00333 T16( I, I ) = SMIN
00334 END IF
00335 DO 90 J = I + 1, 4
00336 T16( J, I ) = T16( J, I ) / T16( I, I )
00337 BTMP( J ) = BTMP( J ) - T16( J, I )*BTMP( I )
00338 DO 80 K = I + 1, 4
00339 T16( J, K ) = T16( J, K ) - T16( J, I )*T16( I, K )
00340 80 CONTINUE
00341 90 CONTINUE
00342 100 CONTINUE
00343 IF( ABS( T16( 4, 4 ) ).LT.SMIN )
00344 $ T16( 4, 4 ) = SMIN
00345 SCALE = ONE
00346 IF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.
00347 $ ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.
00348 $ ( EIGHT*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T16( 3, 3 ) ) .OR.
00349 $ ( EIGHT*SMLNUM )*ABS( BTMP( 4 ) ).GT.ABS( T16( 4, 4 ) ) ) THEN
00350 SCALE = ( ONE / EIGHT ) / MAX( ABS( BTMP( 1 ) ),
00351 $ ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ), ABS( BTMP( 4 ) ) )
00352 BTMP( 1 ) = BTMP( 1 )*SCALE
00353 BTMP( 2 ) = BTMP( 2 )*SCALE
00354 BTMP( 3 ) = BTMP( 3 )*SCALE
00355 BTMP( 4 ) = BTMP( 4 )*SCALE
00356 END IF
00357 DO 120 I = 1, 4
00358 K = 5 - I
00359 TEMP = ONE / T16( K, K )
00360 TMP( K ) = BTMP( K )*TEMP
00361 DO 110 J = K + 1, 4
00362 TMP( K ) = TMP( K ) - ( TEMP*T16( K, J ) )*TMP( J )
00363 110 CONTINUE
00364 120 CONTINUE
00365 DO 130 I = 1, 3
00366 IF( JPIV( 4-I ).NE.4-I ) THEN
00367 TEMP = TMP( 4-I )
00368 TMP( 4-I ) = TMP( JPIV( 4-I ) )
00369 TMP( JPIV( 4-I ) ) = TEMP
00370 END IF
00371 130 CONTINUE
00372 X( 1, 1 ) = TMP( 1 )
00373 X( 2, 1 ) = TMP( 2 )
00374 X( 1, 2 ) = TMP( 3 )
00375 X( 2, 2 ) = TMP( 4 )
00376 XNORM = MAX( ABS( TMP( 1 ) )+ABS( TMP( 3 ) ),
00377 $ ABS( TMP( 2 ) )+ABS( TMP( 4 ) ) )
00378 RETURN
00379
00380
00381
00382 END