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