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_n1 = -1;
00020 static logical c_true = TRUE_;
00021 static real c_b17 = 0.f;
00022 static real c_b18 = 1.f;
00023 static integer c__12 = 12;
00024
00025 int slaqr3_(logical *wantt, logical *wantz, integer *n,
00026 integer *ktop, integer *kbot, integer *nw, real *h__, integer *ldh,
00027 integer *iloz, integer *ihiz, real *z__, integer *ldz, integer *ns,
00028 integer *nd, real *sr, real *si, real *v, integer *ldv, integer *nh,
00029 real *t, integer *ldt, integer *nv, real *wv, integer *ldwv, real *
00030 work, integer *lwork)
00031 {
00032
00033 integer h_dim1, h_offset, t_dim1, t_offset, v_dim1, v_offset, wv_dim1,
00034 wv_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4;
00035 real r__1, r__2, r__3, r__4, r__5, r__6;
00036
00037
00038 double sqrt(doublereal);
00039
00040
00041 integer i__, j, k;
00042 real s, aa, bb, cc, dd, cs, sn;
00043 integer jw;
00044 real evi, evk, foo;
00045 integer kln;
00046 real tau, ulp;
00047 integer lwk1, lwk2, lwk3;
00048 real beta;
00049 integer kend, kcol, info, nmin, ifst, ilst, ltop, krow;
00050 logical bulge;
00051 extern int slarf_(char *, integer *, integer *, real *,
00052 integer *, real *, real *, integer *, real *), sgemm_(
00053 char *, char *, integer *, integer *, integer *, real *, real *,
00054 integer *, real *, integer *, real *, real *, integer *);
00055 integer infqr;
00056 extern int scopy_(integer *, real *, integer *, real *,
00057 integer *);
00058 integer kwtop;
00059 extern int slanv2_(real *, real *, real *, real *, real *
00060 , real *, real *, real *, real *, real *), slaqr4_(logical *,
00061 logical *, integer *, integer *, integer *, real *, integer *,
00062 real *, real *, integer *, integer *, real *, integer *, real *,
00063 integer *, integer *), slabad_(real *, real *);
00064 extern doublereal slamch_(char *);
00065 extern int sgehrd_(integer *, integer *, integer *, real
00066 *, integer *, real *, real *, integer *, integer *);
00067 real safmin;
00068 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00069 integer *, integer *);
00070 real safmax;
00071 extern int slarfg_(integer *, real *, real *, integer *,
00072 real *), slahqr_(logical *, logical *, integer *, integer *,
00073 integer *, real *, integer *, real *, real *, integer *, integer *
00074 , real *, integer *, integer *), slacpy_(char *, integer *,
00075 integer *, real *, integer *, real *, integer *), slaset_(
00076 char *, integer *, integer *, real *, real *, real *, integer *);
00077 logical sorted;
00078 extern int strexc_(char *, integer *, real *, integer *,
00079 real *, integer *, integer *, integer *, real *, integer *), sormhr_(char *, char *, integer *, integer *, integer *,
00080 integer *, real *, integer *, real *, real *, integer *, real *,
00081 integer *, integer *);
00082 real smlnum;
00083 integer lwkopt;
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
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 h_dim1 = *ldh;
00248 h_offset = 1 + h_dim1;
00249 h__ -= h_offset;
00250 z_dim1 = *ldz;
00251 z_offset = 1 + z_dim1;
00252 z__ -= z_offset;
00253 --sr;
00254 --si;
00255 v_dim1 = *ldv;
00256 v_offset = 1 + v_dim1;
00257 v -= v_offset;
00258 t_dim1 = *ldt;
00259 t_offset = 1 + t_dim1;
00260 t -= t_offset;
00261 wv_dim1 = *ldwv;
00262 wv_offset = 1 + wv_dim1;
00263 wv -= wv_offset;
00264 --work;
00265
00266
00267
00268 i__1 = *nw, i__2 = *kbot - *ktop + 1;
00269 jw = min(i__1,i__2);
00270 if (jw <= 2) {
00271 lwkopt = 1;
00272 } else {
00273
00274
00275
00276 i__1 = jw - 1;
00277 sgehrd_(&jw, &c__1, &i__1, &t[t_offset], ldt, &work[1], &work[1], &
00278 c_n1, &info);
00279 lwk1 = (integer) work[1];
00280
00281
00282
00283 i__1 = jw - 1;
00284 sormhr_("R", "N", &jw, &jw, &c__1, &i__1, &t[t_offset], ldt, &work[1],
00285 &v[v_offset], ldv, &work[1], &c_n1, &info);
00286 lwk2 = (integer) work[1];
00287
00288
00289
00290 slaqr4_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sr[1],
00291 &si[1], &c__1, &jw, &v[v_offset], ldv, &work[1], &c_n1, &
00292 infqr);
00293 lwk3 = (integer) work[1];
00294
00295
00296
00297
00298 i__1 = jw + max(lwk1,lwk2);
00299 lwkopt = max(i__1,lwk3);
00300 }
00301
00302
00303
00304 if (*lwork == -1) {
00305 work[1] = (real) lwkopt;
00306 return 0;
00307 }
00308
00309
00310
00311 *ns = 0;
00312 *nd = 0;
00313 work[1] = 1.f;
00314 if (*ktop > *kbot) {
00315 return 0;
00316 }
00317
00318 if (*nw < 1) {
00319 return 0;
00320 }
00321
00322
00323
00324 safmin = slamch_("SAFE MINIMUM");
00325 safmax = 1.f / safmin;
00326 slabad_(&safmin, &safmax);
00327 ulp = slamch_("PRECISION");
00328 smlnum = safmin * ((real) (*n) / ulp);
00329
00330
00331
00332
00333 i__1 = *nw, i__2 = *kbot - *ktop + 1;
00334 jw = min(i__1,i__2);
00335 kwtop = *kbot - jw + 1;
00336 if (kwtop == *ktop) {
00337 s = 0.f;
00338 } else {
00339 s = h__[kwtop + (kwtop - 1) * h_dim1];
00340 }
00341
00342 if (*kbot == kwtop) {
00343
00344
00345
00346 sr[kwtop] = h__[kwtop + kwtop * h_dim1];
00347 si[kwtop] = 0.f;
00348 *ns = 1;
00349 *nd = 0;
00350
00351 r__2 = smlnum, r__3 = ulp * (r__1 = h__[kwtop + kwtop * h_dim1], dabs(
00352 r__1));
00353 if (dabs(s) <= dmax(r__2,r__3)) {
00354 *ns = 0;
00355 *nd = 1;
00356 if (kwtop > *ktop) {
00357 h__[kwtop + (kwtop - 1) * h_dim1] = 0.f;
00358 }
00359 }
00360 work[1] = 1.f;
00361 return 0;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370 slacpy_("U", &jw, &jw, &h__[kwtop + kwtop * h_dim1], ldh, &t[t_offset],
00371 ldt);
00372 i__1 = jw - 1;
00373 i__2 = *ldh + 1;
00374 i__3 = *ldt + 1;
00375 scopy_(&i__1, &h__[kwtop + 1 + kwtop * h_dim1], &i__2, &t[t_dim1 + 2], &
00376 i__3);
00377
00378 slaset_("A", &jw, &jw, &c_b17, &c_b18, &v[v_offset], ldv);
00379 nmin = ilaenv_(&c__12, "SLAQR3", "SV", &jw, &c__1, &jw, lwork);
00380 if (jw > nmin) {
00381 slaqr4_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sr[
00382 kwtop], &si[kwtop], &c__1, &jw, &v[v_offset], ldv, &work[1],
00383 lwork, &infqr);
00384 } else {
00385 slahqr_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sr[
00386 kwtop], &si[kwtop], &c__1, &jw, &v[v_offset], ldv, &infqr);
00387 }
00388
00389
00390
00391 i__1 = jw - 3;
00392 for (j = 1; j <= i__1; ++j) {
00393 t[j + 2 + j * t_dim1] = 0.f;
00394 t[j + 3 + j * t_dim1] = 0.f;
00395
00396 }
00397 if (jw > 2) {
00398 t[jw + (jw - 2) * t_dim1] = 0.f;
00399 }
00400
00401
00402
00403 *ns = jw;
00404 ilst = infqr + 1;
00405 L20:
00406 if (ilst <= *ns) {
00407 if (*ns == 1) {
00408 bulge = FALSE_;
00409 } else {
00410 bulge = t[*ns + (*ns - 1) * t_dim1] != 0.f;
00411 }
00412
00413
00414
00415 if (! bulge) {
00416
00417
00418
00419 foo = (r__1 = t[*ns + *ns * t_dim1], dabs(r__1));
00420 if (foo == 0.f) {
00421 foo = dabs(s);
00422 }
00423
00424 r__2 = smlnum, r__3 = ulp * foo;
00425 if ((r__1 = s * v[*ns * v_dim1 + 1], dabs(r__1)) <= dmax(r__2,
00426 r__3)) {
00427
00428
00429
00430 --(*ns);
00431 } else {
00432
00433
00434
00435
00436 ifst = *ns;
00437 strexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00438 &ilst, &work[1], &info);
00439 ++ilst;
00440 }
00441 } else {
00442
00443
00444
00445 foo = (r__3 = t[*ns + *ns * t_dim1], dabs(r__3)) + sqrt((r__1 = t[
00446 *ns + (*ns - 1) * t_dim1], dabs(r__1))) * sqrt((r__2 = t[*
00447 ns - 1 + *ns * t_dim1], dabs(r__2)));
00448 if (foo == 0.f) {
00449 foo = dabs(s);
00450 }
00451
00452 r__3 = (r__1 = s * v[*ns * v_dim1 + 1], dabs(r__1)), r__4 = (r__2
00453 = s * v[(*ns - 1) * v_dim1 + 1], dabs(r__2));
00454
00455 r__5 = smlnum, r__6 = ulp * foo;
00456 if (dmax(r__3,r__4) <= dmax(r__5,r__6)) {
00457
00458
00459
00460 *ns += -2;
00461 } else {
00462
00463
00464
00465
00466
00467 ifst = *ns;
00468 strexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00469 &ilst, &work[1], &info);
00470 ilst += 2;
00471 }
00472 }
00473
00474
00475
00476 goto L20;
00477 }
00478
00479
00480
00481 if (*ns == 0) {
00482 s = 0.f;
00483 }
00484
00485 if (*ns < jw) {
00486
00487
00488
00489
00490
00491 sorted = FALSE_;
00492 i__ = *ns + 1;
00493 L30:
00494 if (sorted) {
00495 goto L50;
00496 }
00497 sorted = TRUE_;
00498
00499 kend = i__ - 1;
00500 i__ = infqr + 1;
00501 if (i__ == *ns) {
00502 k = i__ + 1;
00503 } else if (t[i__ + 1 + i__ * t_dim1] == 0.f) {
00504 k = i__ + 1;
00505 } else {
00506 k = i__ + 2;
00507 }
00508 L40:
00509 if (k <= kend) {
00510 if (k == i__ + 1) {
00511 evi = (r__1 = t[i__ + i__ * t_dim1], dabs(r__1));
00512 } else {
00513 evi = (r__3 = t[i__ + i__ * t_dim1], dabs(r__3)) + sqrt((r__1
00514 = t[i__ + 1 + i__ * t_dim1], dabs(r__1))) * sqrt((
00515 r__2 = t[i__ + (i__ + 1) * t_dim1], dabs(r__2)));
00516 }
00517
00518 if (k == kend) {
00519 evk = (r__1 = t[k + k * t_dim1], dabs(r__1));
00520 } else if (t[k + 1 + k * t_dim1] == 0.f) {
00521 evk = (r__1 = t[k + k * t_dim1], dabs(r__1));
00522 } else {
00523 evk = (r__3 = t[k + k * t_dim1], dabs(r__3)) + sqrt((r__1 = t[
00524 k + 1 + k * t_dim1], dabs(r__1))) * sqrt((r__2 = t[k
00525 + (k + 1) * t_dim1], dabs(r__2)));
00526 }
00527
00528 if (evi >= evk) {
00529 i__ = k;
00530 } else {
00531 sorted = FALSE_;
00532 ifst = i__;
00533 ilst = k;
00534 strexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00535 &ilst, &work[1], &info);
00536 if (info == 0) {
00537 i__ = ilst;
00538 } else {
00539 i__ = k;
00540 }
00541 }
00542 if (i__ == kend) {
00543 k = i__ + 1;
00544 } else if (t[i__ + 1 + i__ * t_dim1] == 0.f) {
00545 k = i__ + 1;
00546 } else {
00547 k = i__ + 2;
00548 }
00549 goto L40;
00550 }
00551 goto L30;
00552 L50:
00553 ;
00554 }
00555
00556
00557
00558 i__ = jw;
00559 L60:
00560 if (i__ >= infqr + 1) {
00561 if (i__ == infqr + 1) {
00562 sr[kwtop + i__ - 1] = t[i__ + i__ * t_dim1];
00563 si[kwtop + i__ - 1] = 0.f;
00564 --i__;
00565 } else if (t[i__ + (i__ - 1) * t_dim1] == 0.f) {
00566 sr[kwtop + i__ - 1] = t[i__ + i__ * t_dim1];
00567 si[kwtop + i__ - 1] = 0.f;
00568 --i__;
00569 } else {
00570 aa = t[i__ - 1 + (i__ - 1) * t_dim1];
00571 cc = t[i__ + (i__ - 1) * t_dim1];
00572 bb = t[i__ - 1 + i__ * t_dim1];
00573 dd = t[i__ + i__ * t_dim1];
00574 slanv2_(&aa, &bb, &cc, &dd, &sr[kwtop + i__ - 2], &si[kwtop + i__
00575 - 2], &sr[kwtop + i__ - 1], &si[kwtop + i__ - 1], &cs, &
00576 sn);
00577 i__ += -2;
00578 }
00579 goto L60;
00580 }
00581
00582 if (*ns < jw || s == 0.f) {
00583 if (*ns > 1 && s != 0.f) {
00584
00585
00586
00587 scopy_(ns, &v[v_offset], ldv, &work[1], &c__1);
00588 beta = work[1];
00589 slarfg_(ns, &beta, &work[2], &c__1, &tau);
00590 work[1] = 1.f;
00591
00592 i__1 = jw - 2;
00593 i__2 = jw - 2;
00594 slaset_("L", &i__1, &i__2, &c_b17, &c_b17, &t[t_dim1 + 3], ldt);
00595
00596 slarf_("L", ns, &jw, &work[1], &c__1, &tau, &t[t_offset], ldt, &
00597 work[jw + 1]);
00598 slarf_("R", ns, ns, &work[1], &c__1, &tau, &t[t_offset], ldt, &
00599 work[jw + 1]);
00600 slarf_("R", &jw, ns, &work[1], &c__1, &tau, &v[v_offset], ldv, &
00601 work[jw + 1]);
00602
00603 i__1 = *lwork - jw;
00604 sgehrd_(&jw, &c__1, ns, &t[t_offset], ldt, &work[1], &work[jw + 1]
00605 , &i__1, &info);
00606 }
00607
00608
00609
00610 if (kwtop > 1) {
00611 h__[kwtop + (kwtop - 1) * h_dim1] = s * v[v_dim1 + 1];
00612 }
00613 slacpy_("U", &jw, &jw, &t[t_offset], ldt, &h__[kwtop + kwtop * h_dim1]
00614 , ldh);
00615 i__1 = jw - 1;
00616 i__2 = *ldt + 1;
00617 i__3 = *ldh + 1;
00618 scopy_(&i__1, &t[t_dim1 + 2], &i__2, &h__[kwtop + 1 + kwtop * h_dim1],
00619 &i__3);
00620
00621
00622
00623
00624 if (*ns > 1 && s != 0.f) {
00625 i__1 = *lwork - jw;
00626 sormhr_("R", "N", &jw, ns, &c__1, ns, &t[t_offset], ldt, &work[1],
00627 &v[v_offset], ldv, &work[jw + 1], &i__1, &info);
00628 }
00629
00630
00631
00632 if (*wantt) {
00633 ltop = 1;
00634 } else {
00635 ltop = *ktop;
00636 }
00637 i__1 = kwtop - 1;
00638 i__2 = *nv;
00639 for (krow = ltop; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00640 i__2) {
00641
00642 i__3 = *nv, i__4 = kwtop - krow;
00643 kln = min(i__3,i__4);
00644 sgemm_("N", "N", &kln, &jw, &jw, &c_b18, &h__[krow + kwtop *
00645 h_dim1], ldh, &v[v_offset], ldv, &c_b17, &wv[wv_offset],
00646 ldwv);
00647 slacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &h__[krow + kwtop *
00648 h_dim1], ldh);
00649
00650 }
00651
00652
00653
00654 if (*wantt) {
00655 i__2 = *n;
00656 i__1 = *nh;
00657 for (kcol = *kbot + 1; i__1 < 0 ? kcol >= i__2 : kcol <= i__2;
00658 kcol += i__1) {
00659
00660 i__3 = *nh, i__4 = *n - kcol + 1;
00661 kln = min(i__3,i__4);
00662 sgemm_("C", "N", &jw, &kln, &jw, &c_b18, &v[v_offset], ldv, &
00663 h__[kwtop + kcol * h_dim1], ldh, &c_b17, &t[t_offset],
00664 ldt);
00665 slacpy_("A", &jw, &kln, &t[t_offset], ldt, &h__[kwtop + kcol *
00666 h_dim1], ldh);
00667
00668 }
00669 }
00670
00671
00672
00673 if (*wantz) {
00674 i__1 = *ihiz;
00675 i__2 = *nv;
00676 for (krow = *iloz; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00677 i__2) {
00678
00679 i__3 = *nv, i__4 = *ihiz - krow + 1;
00680 kln = min(i__3,i__4);
00681 sgemm_("N", "N", &kln, &jw, &jw, &c_b18, &z__[krow + kwtop *
00682 z_dim1], ldz, &v[v_offset], ldv, &c_b17, &wv[
00683 wv_offset], ldwv);
00684 slacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &z__[krow +
00685 kwtop * z_dim1], ldz);
00686
00687 }
00688 }
00689 }
00690
00691
00692
00693 *nd = jw - *ns;
00694
00695
00696
00697
00698
00699
00700
00701 *ns -= infqr;
00702
00703
00704
00705 work[1] = (real) lwkopt;
00706
00707
00708
00709 return 0;
00710 }