00001 SUBROUTINE DTGEXC( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00002 $ LDZ, IFST, ILST, WORK, LWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 LOGICAL WANTQ, WANTZ
00011 INTEGER IFST, ILST, INFO, LDA, LDB, LDQ, LDZ, LWORK, N
00012
00013
00014 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
00015 $ WORK( * ), Z( LDZ, * )
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
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 DOUBLE PRECISION ZERO
00138 PARAMETER ( ZERO = 0.0D+0 )
00139
00140
00141 LOGICAL LQUERY
00142 INTEGER HERE, LWMIN, NBF, NBL, NBNEXT
00143
00144
00145 EXTERNAL DTGEX2, XERBLA
00146
00147
00148 INTRINSIC MAX
00149
00150
00151
00152
00153
00154 INFO = 0
00155 LQUERY = ( LWORK.EQ.-1 )
00156 IF( N.LT.0 ) THEN
00157 INFO = -3
00158 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00159 INFO = -5
00160 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00161 INFO = -7
00162 ELSE IF( LDQ.LT.1 .OR. WANTQ .AND. ( LDQ.LT.MAX( 1, N ) ) ) THEN
00163 INFO = -9
00164 ELSE IF( LDZ.LT.1 .OR. WANTZ .AND. ( LDZ.LT.MAX( 1, N ) ) ) THEN
00165 INFO = -11
00166 ELSE IF( IFST.LT.1 .OR. IFST.GT.N ) THEN
00167 INFO = -12
00168 ELSE IF( ILST.LT.1 .OR. ILST.GT.N ) THEN
00169 INFO = -13
00170 END IF
00171
00172 IF( INFO.EQ.0 ) THEN
00173 IF( N.LE.1 ) THEN
00174 LWMIN = 1
00175 ELSE
00176 LWMIN = 4*N + 16
00177 END IF
00178 WORK(1) = LWMIN
00179
00180 IF (LWORK.LT.LWMIN .AND. .NOT.LQUERY) THEN
00181 INFO = -15
00182 END IF
00183 END IF
00184
00185 IF( INFO.NE.0 ) THEN
00186 CALL XERBLA( 'DTGEXC', -INFO )
00187 RETURN
00188 ELSE IF( LQUERY ) THEN
00189 RETURN
00190 END IF
00191
00192
00193
00194 IF( N.LE.1 )
00195 $ RETURN
00196
00197
00198
00199
00200 IF( IFST.GT.1 ) THEN
00201 IF( A( IFST, IFST-1 ).NE.ZERO )
00202 $ IFST = IFST - 1
00203 END IF
00204 NBF = 1
00205 IF( IFST.LT.N ) THEN
00206 IF( A( IFST+1, IFST ).NE.ZERO )
00207 $ NBF = 2
00208 END IF
00209
00210
00211
00212
00213 IF( ILST.GT.1 ) THEN
00214 IF( A( ILST, ILST-1 ).NE.ZERO )
00215 $ ILST = ILST - 1
00216 END IF
00217 NBL = 1
00218 IF( ILST.LT.N ) THEN
00219 IF( A( ILST+1, ILST ).NE.ZERO )
00220 $ NBL = 2
00221 END IF
00222 IF( IFST.EQ.ILST )
00223 $ RETURN
00224
00225 IF( IFST.LT.ILST ) THEN
00226
00227
00228
00229 IF( NBF.EQ.2 .AND. NBL.EQ.1 )
00230 $ ILST = ILST - 1
00231 IF( NBF.EQ.1 .AND. NBL.EQ.2 )
00232 $ ILST = ILST + 1
00233
00234 HERE = IFST
00235
00236 10 CONTINUE
00237
00238
00239
00240 IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN
00241
00242
00243
00244 NBNEXT = 1
00245 IF( HERE+NBF+1.LE.N ) THEN
00246 IF( A( HERE+NBF+1, HERE+NBF ).NE.ZERO )
00247 $ NBNEXT = 2
00248 END IF
00249 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00250 $ LDZ, HERE, NBF, NBNEXT, WORK, LWORK, INFO )
00251 IF( INFO.NE.0 ) THEN
00252 ILST = HERE
00253 RETURN
00254 END IF
00255 HERE = HERE + NBNEXT
00256
00257
00258
00259 IF( NBF.EQ.2 ) THEN
00260 IF( A( HERE+1, HERE ).EQ.ZERO )
00261 $ NBF = 3
00262 END IF
00263
00264 ELSE
00265
00266
00267
00268
00269 NBNEXT = 1
00270 IF( HERE+3.LE.N ) THEN
00271 IF( A( HERE+3, HERE+2 ).NE.ZERO )
00272 $ NBNEXT = 2
00273 END IF
00274 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00275 $ LDZ, HERE+1, 1, NBNEXT, WORK, LWORK, INFO )
00276 IF( INFO.NE.0 ) THEN
00277 ILST = HERE
00278 RETURN
00279 END IF
00280 IF( NBNEXT.EQ.1 ) THEN
00281
00282
00283
00284 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00285 $ LDZ, HERE, 1, 1, WORK, LWORK, INFO )
00286 IF( INFO.NE.0 ) THEN
00287 ILST = HERE
00288 RETURN
00289 END IF
00290 HERE = HERE + 1
00291
00292 ELSE
00293
00294
00295
00296 IF( A( HERE+2, HERE+1 ).EQ.ZERO )
00297 $ NBNEXT = 1
00298 IF( NBNEXT.EQ.2 ) THEN
00299
00300
00301
00302 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,
00303 $ Z, LDZ, HERE, 1, NBNEXT, WORK, LWORK,
00304 $ INFO )
00305 IF( INFO.NE.0 ) THEN
00306 ILST = HERE
00307 RETURN
00308 END IF
00309 HERE = HERE + 2
00310 ELSE
00311
00312
00313
00314 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,
00315 $ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )
00316 IF( INFO.NE.0 ) THEN
00317 ILST = HERE
00318 RETURN
00319 END IF
00320 HERE = HERE + 1
00321 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,
00322 $ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )
00323 IF( INFO.NE.0 ) THEN
00324 ILST = HERE
00325 RETURN
00326 END IF
00327 HERE = HERE + 1
00328 END IF
00329
00330 END IF
00331 END IF
00332 IF( HERE.LT.ILST )
00333 $ GO TO 10
00334 ELSE
00335 HERE = IFST
00336
00337 20 CONTINUE
00338
00339
00340
00341 IF( NBF.EQ.1 .OR. NBF.EQ.2 ) THEN
00342
00343
00344
00345 NBNEXT = 1
00346 IF( HERE.GE.3 ) THEN
00347 IF( A( HERE-1, HERE-2 ).NE.ZERO )
00348 $ NBNEXT = 2
00349 END IF
00350 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00351 $ LDZ, HERE-NBNEXT, NBNEXT, NBF, WORK, LWORK,
00352 $ INFO )
00353 IF( INFO.NE.0 ) THEN
00354 ILST = HERE
00355 RETURN
00356 END IF
00357 HERE = HERE - NBNEXT
00358
00359
00360
00361 IF( NBF.EQ.2 ) THEN
00362 IF( A( HERE+1, HERE ).EQ.ZERO )
00363 $ NBF = 3
00364 END IF
00365
00366 ELSE
00367
00368
00369
00370
00371 NBNEXT = 1
00372 IF( HERE.GE.3 ) THEN
00373 IF( A( HERE-1, HERE-2 ).NE.ZERO )
00374 $ NBNEXT = 2
00375 END IF
00376 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00377 $ LDZ, HERE-NBNEXT, NBNEXT, 1, WORK, LWORK,
00378 $ INFO )
00379 IF( INFO.NE.0 ) THEN
00380 ILST = HERE
00381 RETURN
00382 END IF
00383 IF( NBNEXT.EQ.1 ) THEN
00384
00385
00386
00387 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ, Z,
00388 $ LDZ, HERE, NBNEXT, 1, WORK, LWORK, INFO )
00389 IF( INFO.NE.0 ) THEN
00390 ILST = HERE
00391 RETURN
00392 END IF
00393 HERE = HERE - 1
00394 ELSE
00395
00396
00397
00398 IF( A( HERE, HERE-1 ).EQ.ZERO )
00399 $ NBNEXT = 1
00400 IF( NBNEXT.EQ.2 ) THEN
00401
00402
00403
00404 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,
00405 $ Z, LDZ, HERE-1, 2, 1, WORK, LWORK, INFO )
00406 IF( INFO.NE.0 ) THEN
00407 ILST = HERE
00408 RETURN
00409 END IF
00410 HERE = HERE - 2
00411 ELSE
00412
00413
00414
00415 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,
00416 $ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )
00417 IF( INFO.NE.0 ) THEN
00418 ILST = HERE
00419 RETURN
00420 END IF
00421 HERE = HERE - 1
00422 CALL DTGEX2( WANTQ, WANTZ, N, A, LDA, B, LDB, Q, LDQ,
00423 $ Z, LDZ, HERE, 1, 1, WORK, LWORK, INFO )
00424 IF( INFO.NE.0 ) THEN
00425 ILST = HERE
00426 RETURN
00427 END IF
00428 HERE = HERE - 1
00429 END IF
00430 END IF
00431 END IF
00432 IF( HERE.GT.ILST )
00433 $ GO TO 20
00434 END IF
00435 ILST = HERE
00436 WORK( 1 ) = LWMIN
00437 RETURN
00438
00439
00440
00441 END