00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static integer c__1 = 1;
00019 static integer c__2 = 2;
00020
00021 int dtgexc_(logical *wantq, logical *wantz, integer *n,
00022 doublereal *a, integer *lda, doublereal *b, integer *ldb, doublereal *
00023 q, integer *ldq, doublereal *z__, integer *ldz, integer *ifst,
00024 integer *ilst, doublereal *work, integer *lwork, integer *info)
00025 {
00026
00027 integer a_dim1, a_offset, b_dim1, b_offset, q_dim1, q_offset, z_dim1,
00028 z_offset, i__1;
00029
00030
00031 integer nbf, nbl, here, lwmin;
00032 extern int dtgex2_(logical *, logical *, integer *,
00033 doublereal *, integer *, doublereal *, integer *, doublereal *,
00034 integer *, doublereal *, integer *, integer *, integer *, integer
00035 *, doublereal *, integer *, integer *), xerbla_(char *, integer *);
00036 integer nbnext;
00037 logical lquery;
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
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 a_dim1 = *lda;
00181 a_offset = 1 + a_dim1;
00182 a -= a_offset;
00183 b_dim1 = *ldb;
00184 b_offset = 1 + b_dim1;
00185 b -= b_offset;
00186 q_dim1 = *ldq;
00187 q_offset = 1 + q_dim1;
00188 q -= q_offset;
00189 z_dim1 = *ldz;
00190 z_offset = 1 + z_dim1;
00191 z__ -= z_offset;
00192 --work;
00193
00194
00195 *info = 0;
00196 lquery = *lwork == -1;
00197 if (*n < 0) {
00198 *info = -3;
00199 } else if (*lda < max(1,*n)) {
00200 *info = -5;
00201 } else if (*ldb < max(1,*n)) {
00202 *info = -7;
00203 } else if (*ldq < 1 || *wantq && *ldq < max(1,*n)) {
00204 *info = -9;
00205 } else if (*ldz < 1 || *wantz && *ldz < max(1,*n)) {
00206 *info = -11;
00207 } else if (*ifst < 1 || *ifst > *n) {
00208 *info = -12;
00209 } else if (*ilst < 1 || *ilst > *n) {
00210 *info = -13;
00211 }
00212
00213 if (*info == 0) {
00214 if (*n <= 1) {
00215 lwmin = 1;
00216 } else {
00217 lwmin = (*n << 2) + 16;
00218 }
00219 work[1] = (doublereal) lwmin;
00220
00221 if (*lwork < lwmin && ! lquery) {
00222 *info = -15;
00223 }
00224 }
00225
00226 if (*info != 0) {
00227 i__1 = -(*info);
00228 xerbla_("DTGEXC", &i__1);
00229 return 0;
00230 } else if (lquery) {
00231 return 0;
00232 }
00233
00234
00235
00236 if (*n <= 1) {
00237 return 0;
00238 }
00239
00240
00241
00242
00243 if (*ifst > 1) {
00244 if (a[*ifst + (*ifst - 1) * a_dim1] != 0.) {
00245 --(*ifst);
00246 }
00247 }
00248 nbf = 1;
00249 if (*ifst < *n) {
00250 if (a[*ifst + 1 + *ifst * a_dim1] != 0.) {
00251 nbf = 2;
00252 }
00253 }
00254
00255
00256
00257
00258 if (*ilst > 1) {
00259 if (a[*ilst + (*ilst - 1) * a_dim1] != 0.) {
00260 --(*ilst);
00261 }
00262 }
00263 nbl = 1;
00264 if (*ilst < *n) {
00265 if (a[*ilst + 1 + *ilst * a_dim1] != 0.) {
00266 nbl = 2;
00267 }
00268 }
00269 if (*ifst == *ilst) {
00270 return 0;
00271 }
00272
00273 if (*ifst < *ilst) {
00274
00275
00276
00277 if (nbf == 2 && nbl == 1) {
00278 --(*ilst);
00279 }
00280 if (nbf == 1 && nbl == 2) {
00281 ++(*ilst);
00282 }
00283
00284 here = *ifst;
00285
00286 L10:
00287
00288
00289
00290 if (nbf == 1 || nbf == 2) {
00291
00292
00293
00294 nbnext = 1;
00295 if (here + nbf + 1 <= *n) {
00296 if (a[here + nbf + 1 + (here + nbf) * a_dim1] != 0.) {
00297 nbnext = 2;
00298 }
00299 }
00300 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb, &q[
00301 q_offset], ldq, &z__[z_offset], ldz, &here, &nbf, &nbnext,
00302 &work[1], lwork, info);
00303 if (*info != 0) {
00304 *ilst = here;
00305 return 0;
00306 }
00307 here += nbnext;
00308
00309
00310
00311 if (nbf == 2) {
00312 if (a[here + 1 + here * a_dim1] == 0.) {
00313 nbf = 3;
00314 }
00315 }
00316
00317 } else {
00318
00319
00320
00321
00322 nbnext = 1;
00323 if (here + 3 <= *n) {
00324 if (a[here + 3 + (here + 2) * a_dim1] != 0.) {
00325 nbnext = 2;
00326 }
00327 }
00328 i__1 = here + 1;
00329 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb, &q[
00330 q_offset], ldq, &z__[z_offset], ldz, &i__1, &c__1, &
00331 nbnext, &work[1], lwork, info);
00332 if (*info != 0) {
00333 *ilst = here;
00334 return 0;
00335 }
00336 if (nbnext == 1) {
00337
00338
00339
00340 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb,
00341 &q[q_offset], ldq, &z__[z_offset], ldz, &here, &c__1,
00342 &c__1, &work[1], lwork, info);
00343 if (*info != 0) {
00344 *ilst = here;
00345 return 0;
00346 }
00347 ++here;
00348
00349 } else {
00350
00351
00352
00353 if (a[here + 2 + (here + 1) * a_dim1] == 0.) {
00354 nbnext = 1;
00355 }
00356 if (nbnext == 2) {
00357
00358
00359
00360 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset],
00361 ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &
00362 here, &c__1, &nbnext, &work[1], lwork, info);
00363 if (*info != 0) {
00364 *ilst = here;
00365 return 0;
00366 }
00367 here += 2;
00368 } else {
00369
00370
00371
00372 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset],
00373 ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &
00374 here, &c__1, &c__1, &work[1], lwork, info);
00375 if (*info != 0) {
00376 *ilst = here;
00377 return 0;
00378 }
00379 ++here;
00380 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset],
00381 ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &
00382 here, &c__1, &c__1, &work[1], lwork, info);
00383 if (*info != 0) {
00384 *ilst = here;
00385 return 0;
00386 }
00387 ++here;
00388 }
00389
00390 }
00391 }
00392 if (here < *ilst) {
00393 goto L10;
00394 }
00395 } else {
00396 here = *ifst;
00397
00398 L20:
00399
00400
00401
00402 if (nbf == 1 || nbf == 2) {
00403
00404
00405
00406 nbnext = 1;
00407 if (here >= 3) {
00408 if (a[here - 1 + (here - 2) * a_dim1] != 0.) {
00409 nbnext = 2;
00410 }
00411 }
00412 i__1 = here - nbnext;
00413 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb, &q[
00414 q_offset], ldq, &z__[z_offset], ldz, &i__1, &nbnext, &nbf,
00415 &work[1], lwork, info);
00416 if (*info != 0) {
00417 *ilst = here;
00418 return 0;
00419 }
00420 here -= nbnext;
00421
00422
00423
00424 if (nbf == 2) {
00425 if (a[here + 1 + here * a_dim1] == 0.) {
00426 nbf = 3;
00427 }
00428 }
00429
00430 } else {
00431
00432
00433
00434
00435 nbnext = 1;
00436 if (here >= 3) {
00437 if (a[here - 1 + (here - 2) * a_dim1] != 0.) {
00438 nbnext = 2;
00439 }
00440 }
00441 i__1 = here - nbnext;
00442 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb, &q[
00443 q_offset], ldq, &z__[z_offset], ldz, &i__1, &nbnext, &
00444 c__1, &work[1], lwork, info);
00445 if (*info != 0) {
00446 *ilst = here;
00447 return 0;
00448 }
00449 if (nbnext == 1) {
00450
00451
00452
00453 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset], ldb,
00454 &q[q_offset], ldq, &z__[z_offset], ldz, &here, &
00455 nbnext, &c__1, &work[1], lwork, info);
00456 if (*info != 0) {
00457 *ilst = here;
00458 return 0;
00459 }
00460 --here;
00461 } else {
00462
00463
00464
00465 if (a[here + (here - 1) * a_dim1] == 0.) {
00466 nbnext = 1;
00467 }
00468 if (nbnext == 2) {
00469
00470
00471
00472 i__1 = here - 1;
00473 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset],
00474 ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &
00475 i__1, &c__2, &c__1, &work[1], lwork, info);
00476 if (*info != 0) {
00477 *ilst = here;
00478 return 0;
00479 }
00480 here += -2;
00481 } else {
00482
00483
00484
00485 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset],
00486 ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &
00487 here, &c__1, &c__1, &work[1], lwork, info);
00488 if (*info != 0) {
00489 *ilst = here;
00490 return 0;
00491 }
00492 --here;
00493 dtgex2_(wantq, wantz, n, &a[a_offset], lda, &b[b_offset],
00494 ldb, &q[q_offset], ldq, &z__[z_offset], ldz, &
00495 here, &c__1, &c__1, &work[1], lwork, info);
00496 if (*info != 0) {
00497 *ilst = here;
00498 return 0;
00499 }
00500 --here;
00501 }
00502 }
00503 }
00504 if (here > *ilst) {
00505 goto L20;
00506 }
00507 }
00508 *ilst = here;
00509 work[1] = (doublereal) lwmin;
00510 return 0;
00511
00512
00513
00514 }