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__13 = 13;
00019 static integer c__15 = 15;
00020 static integer c_n1 = -1;
00021 static integer c__12 = 12;
00022 static integer c__14 = 14;
00023 static integer c__16 = 16;
00024 static logical c_false = FALSE_;
00025 static integer c__1 = 1;
00026 static integer c__3 = 3;
00027
00028 int zlaqr4_(logical *wantt, logical *wantz, integer *n,
00029 integer *ilo, integer *ihi, doublecomplex *h__, integer *ldh,
00030 doublecomplex *w, integer *iloz, integer *ihiz, doublecomplex *z__,
00031 integer *ldz, doublecomplex *work, integer *lwork, integer *info)
00032 {
00033
00034 integer h_dim1, h_offset, z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5;
00035 doublereal d__1, d__2, d__3, d__4, d__5, d__6, d__7, d__8;
00036 doublecomplex z__1, z__2, z__3, z__4, z__5;
00037
00038
00039 double d_imag(doublecomplex *);
00040 void z_sqrt(doublecomplex *, doublecomplex *);
00041
00042
00043 integer i__, k;
00044 doublereal s;
00045 doublecomplex aa, bb, cc, dd;
00046 integer ld, nh, it, ks, kt, ku, kv, ls, ns, nw;
00047 doublecomplex tr2, det;
00048 integer inf, kdu, nho, nve, kwh, nsr, nwr, kwv, ndec, ndfl, kbot, nmin;
00049 doublecomplex swap;
00050 integer ktop;
00051 doublecomplex zdum[1] ;
00052 integer kacc22, itmax, nsmax, nwmax, kwtop;
00053 extern int zlaqr2_(logical *, logical *, integer *,
00054 integer *, integer *, integer *, doublecomplex *, integer *,
00055 integer *, integer *, doublecomplex *, integer *, integer *,
00056 integer *, doublecomplex *, doublecomplex *, integer *, integer *,
00057 doublecomplex *, integer *, integer *, doublecomplex *, integer *
00058 , doublecomplex *, integer *), zlaqr5_(logical *, logical *,
00059 integer *, integer *, integer *, integer *, integer *,
00060 doublecomplex *, doublecomplex *, integer *, integer *, integer *,
00061 doublecomplex *, integer *, doublecomplex *, integer *,
00062 doublecomplex *, integer *, integer *, doublecomplex *, integer *,
00063 integer *, doublecomplex *, integer *);
00064 integer nibble;
00065 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00066 integer *, integer *);
00067 char jbcmpz[2];
00068 doublecomplex rtdisc;
00069 integer nwupbd;
00070 logical sorted;
00071 extern int zlahqr_(logical *, logical *, integer *,
00072 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00073 integer *, integer *, doublecomplex *, integer *, integer *),
00074 zlacpy_(char *, integer *, integer *, doublecomplex *, integer *,
00075 doublecomplex *, integer *);
00076 integer lwkopt;
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
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
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 h_dim1 = *ldh;
00267 h_offset = 1 + h_dim1;
00268 h__ -= h_offset;
00269 --w;
00270 z_dim1 = *ldz;
00271 z_offset = 1 + z_dim1;
00272 z__ -= z_offset;
00273 --work;
00274
00275
00276 *info = 0;
00277
00278
00279
00280 if (*n == 0) {
00281 work[1].r = 1., work[1].i = 0.;
00282 return 0;
00283 }
00284
00285 if (*n <= 11) {
00286
00287
00288
00289 lwkopt = 1;
00290 if (*lwork != -1) {
00291 zlahqr_(wantt, wantz, n, ilo, ihi, &h__[h_offset], ldh, &w[1],
00292 iloz, ihiz, &z__[z_offset], ldz, info);
00293 }
00294 } else {
00295
00296
00297
00298
00299
00300
00301 *info = 0;
00302
00303
00304
00305 if (*wantt) {
00306 *(unsigned char *)jbcmpz = 'S';
00307 } else {
00308 *(unsigned char *)jbcmpz = 'E';
00309 }
00310 if (*wantz) {
00311 *(unsigned char *)&jbcmpz[1] = 'V';
00312 } else {
00313 *(unsigned char *)&jbcmpz[1] = 'N';
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 nwr = ilaenv_(&c__13, "ZLAQR4", jbcmpz, n, ilo, ihi, lwork);
00323 nwr = max(2,nwr);
00324
00325 i__1 = *ihi - *ilo + 1, i__2 = (*n - 1) / 3, i__1 = min(i__1,i__2);
00326 nwr = min(i__1,nwr);
00327
00328
00329
00330
00331
00332
00333 nsr = ilaenv_(&c__15, "ZLAQR4", jbcmpz, n, ilo, ihi, lwork);
00334
00335 i__1 = nsr, i__2 = (*n + 6) / 9, i__1 = min(i__1,i__2), i__2 = *ihi -
00336 *ilo;
00337 nsr = min(i__1,i__2);
00338
00339 i__1 = 2, i__2 = nsr - nsr % 2;
00340 nsr = max(i__1,i__2);
00341
00342
00343
00344
00345
00346 i__1 = nwr + 1;
00347 zlaqr2_(wantt, wantz, n, ilo, ihi, &i__1, &h__[h_offset], ldh, iloz,
00348 ihiz, &z__[z_offset], ldz, &ls, &ld, &w[1], &h__[h_offset],
00349 ldh, n, &h__[h_offset], ldh, n, &h__[h_offset], ldh, &work[1],
00350 &c_n1);
00351
00352
00353
00354
00355 i__1 = nsr * 3 / 2, i__2 = (integer) work[1].r;
00356 lwkopt = max(i__1,i__2);
00357
00358
00359
00360 if (*lwork == -1) {
00361 d__1 = (doublereal) lwkopt;
00362 z__1.r = d__1, z__1.i = 0.;
00363 work[1].r = z__1.r, work[1].i = z__1.i;
00364 return 0;
00365 }
00366
00367
00368
00369 nmin = ilaenv_(&c__12, "ZLAQR4", jbcmpz, n, ilo, ihi, lwork);
00370 nmin = max(11,nmin);
00371
00372
00373
00374 nibble = ilaenv_(&c__14, "ZLAQR4", jbcmpz, n, ilo, ihi, lwork);
00375 nibble = max(0,nibble);
00376
00377
00378
00379
00380 kacc22 = ilaenv_(&c__16, "ZLAQR4", jbcmpz, n, ilo, ihi, lwork);
00381 kacc22 = max(0,kacc22);
00382 kacc22 = min(2,kacc22);
00383
00384
00385
00386
00387
00388 i__1 = (*n - 1) / 3, i__2 = *lwork / 2;
00389 nwmax = min(i__1,i__2);
00390 nw = nwmax;
00391
00392
00393
00394
00395
00396 i__1 = (*n + 6) / 9, i__2 = (*lwork << 1) / 3;
00397 nsmax = min(i__1,i__2);
00398 nsmax -= nsmax % 2;
00399
00400
00401
00402 ndfl = 1;
00403
00404
00405
00406
00407 i__1 = 10, i__2 = *ihi - *ilo + 1;
00408 itmax = max(i__1,i__2) * 30;
00409
00410
00411
00412 kbot = *ihi;
00413
00414
00415
00416 i__1 = itmax;
00417 for (it = 1; it <= i__1; ++it) {
00418
00419
00420
00421 if (kbot < *ilo) {
00422 goto L80;
00423 }
00424
00425
00426
00427 i__2 = *ilo + 1;
00428 for (k = kbot; k >= i__2; --k) {
00429 i__3 = k + (k - 1) * h_dim1;
00430 if (h__[i__3].r == 0. && h__[i__3].i == 0.) {
00431 goto L20;
00432 }
00433
00434 }
00435 k = *ilo;
00436 L20:
00437 ktop = k;
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 nh = kbot - ktop + 1;
00456 nwupbd = min(nh,nwmax);
00457 if (ndfl < 5) {
00458 nw = min(nwupbd,nwr);
00459 } else {
00460
00461 i__2 = nwupbd, i__3 = nw << 1;
00462 nw = min(i__2,i__3);
00463 }
00464 if (nw < nwmax) {
00465 if (nw >= nh - 1) {
00466 nw = nh;
00467 } else {
00468 kwtop = kbot - nw + 1;
00469 i__2 = kwtop + (kwtop - 1) * h_dim1;
00470 i__3 = kwtop - 1 + (kwtop - 2) * h_dim1;
00471 if ((d__1 = h__[i__2].r, abs(d__1)) + (d__2 = d_imag(&h__[
00472 kwtop + (kwtop - 1) * h_dim1]), abs(d__2)) > (
00473 d__3 = h__[i__3].r, abs(d__3)) + (d__4 = d_imag(&
00474 h__[kwtop - 1 + (kwtop - 2) * h_dim1]), abs(d__4))
00475 ) {
00476 ++nw;
00477 }
00478 }
00479 }
00480 if (ndfl < 5) {
00481 ndec = -1;
00482 } else if (ndec >= 0 || nw >= nwupbd) {
00483 ++ndec;
00484 if (nw - ndec < 2) {
00485 ndec = 0;
00486 }
00487 nw -= ndec;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 kv = *n - nw + 1;
00502 kt = nw + 1;
00503 nho = *n - nw - 1 - kt + 1;
00504 kwv = nw + 2;
00505 nve = *n - nw - kwv + 1;
00506
00507
00508
00509 zlaqr2_(wantt, wantz, n, &ktop, &kbot, &nw, &h__[h_offset], ldh,
00510 iloz, ihiz, &z__[z_offset], ldz, &ls, &ld, &w[1], &h__[kv
00511 + h_dim1], ldh, &nho, &h__[kv + kt * h_dim1], ldh, &nve, &
00512 h__[kwv + h_dim1], ldh, &work[1], lwork);
00513
00514
00515
00516 kbot -= ld;
00517
00518
00519
00520 ks = kbot - ls + 1;
00521
00522
00523
00524
00525
00526
00527
00528 if (ld == 0 || ld * 100 <= nw * nibble && kbot - ktop + 1 > min(
00529 nmin,nwmax)) {
00530
00531
00532
00533
00534
00535
00536
00537 i__4 = 2, i__5 = kbot - ktop;
00538 i__2 = min(nsmax,nsr), i__3 = max(i__4,i__5);
00539 ns = min(i__2,i__3);
00540 ns -= ns % 2;
00541
00542
00543
00544
00545
00546
00547
00548
00549 if (ndfl % 6 == 0) {
00550 ks = kbot - ns + 1;
00551 i__2 = ks + 1;
00552 for (i__ = kbot; i__ >= i__2; i__ += -2) {
00553 i__3 = i__;
00554 i__4 = i__ + i__ * h_dim1;
00555 i__5 = i__ + (i__ - 1) * h_dim1;
00556 d__3 = ((d__1 = h__[i__5].r, abs(d__1)) + (d__2 =
00557 d_imag(&h__[i__ + (i__ - 1) * h_dim1]), abs(
00558 d__2))) * .75;
00559 z__1.r = h__[i__4].r + d__3, z__1.i = h__[i__4].i;
00560 w[i__3].r = z__1.r, w[i__3].i = z__1.i;
00561 i__3 = i__ - 1;
00562 i__4 = i__;
00563 w[i__3].r = w[i__4].r, w[i__3].i = w[i__4].i;
00564
00565 }
00566 } else {
00567
00568
00569
00570
00571
00572
00573
00574 if (kbot - ks + 1 <= ns / 2) {
00575 ks = kbot - ns + 1;
00576 kt = *n - ns + 1;
00577 zlacpy_("A", &ns, &ns, &h__[ks + ks * h_dim1], ldh, &
00578 h__[kt + h_dim1], ldh);
00579 zlahqr_(&c_false, &c_false, &ns, &c__1, &ns, &h__[kt
00580 + h_dim1], ldh, &w[ks], &c__1, &c__1, zdum, &
00581 c__1, &inf);
00582 ks += inf;
00583
00584
00585
00586
00587
00588
00589
00590
00591 if (ks >= kbot) {
00592 i__2 = kbot - 1 + (kbot - 1) * h_dim1;
00593 i__3 = kbot + (kbot - 1) * h_dim1;
00594 i__4 = kbot - 1 + kbot * h_dim1;
00595 i__5 = kbot + kbot * h_dim1;
00596 s = (d__1 = h__[i__2].r, abs(d__1)) + (d__2 =
00597 d_imag(&h__[kbot - 1 + (kbot - 1) *
00598 h_dim1]), abs(d__2)) + ((d__3 = h__[i__3]
00599 .r, abs(d__3)) + (d__4 = d_imag(&h__[kbot
00600 + (kbot - 1) * h_dim1]), abs(d__4))) + ((
00601 d__5 = h__[i__4].r, abs(d__5)) + (d__6 =
00602 d_imag(&h__[kbot - 1 + kbot * h_dim1]),
00603 abs(d__6))) + ((d__7 = h__[i__5].r, abs(
00604 d__7)) + (d__8 = d_imag(&h__[kbot + kbot *
00605 h_dim1]), abs(d__8)));
00606 i__2 = kbot - 1 + (kbot - 1) * h_dim1;
00607 z__1.r = h__[i__2].r / s, z__1.i = h__[i__2].i /
00608 s;
00609 aa.r = z__1.r, aa.i = z__1.i;
00610 i__2 = kbot + (kbot - 1) * h_dim1;
00611 z__1.r = h__[i__2].r / s, z__1.i = h__[i__2].i /
00612 s;
00613 cc.r = z__1.r, cc.i = z__1.i;
00614 i__2 = kbot - 1 + kbot * h_dim1;
00615 z__1.r = h__[i__2].r / s, z__1.i = h__[i__2].i /
00616 s;
00617 bb.r = z__1.r, bb.i = z__1.i;
00618 i__2 = kbot + kbot * h_dim1;
00619 z__1.r = h__[i__2].r / s, z__1.i = h__[i__2].i /
00620 s;
00621 dd.r = z__1.r, dd.i = z__1.i;
00622 z__2.r = aa.r + dd.r, z__2.i = aa.i + dd.i;
00623 z__1.r = z__2.r / 2., z__1.i = z__2.i / 2.;
00624 tr2.r = z__1.r, tr2.i = z__1.i;
00625 z__3.r = aa.r - tr2.r, z__3.i = aa.i - tr2.i;
00626 z__4.r = dd.r - tr2.r, z__4.i = dd.i - tr2.i;
00627 z__2.r = z__3.r * z__4.r - z__3.i * z__4.i,
00628 z__2.i = z__3.r * z__4.i + z__3.i *
00629 z__4.r;
00630 z__5.r = bb.r * cc.r - bb.i * cc.i, z__5.i = bb.r
00631 * cc.i + bb.i * cc.r;
00632 z__1.r = z__2.r - z__5.r, z__1.i = z__2.i -
00633 z__5.i;
00634 det.r = z__1.r, det.i = z__1.i;
00635 z__2.r = -det.r, z__2.i = -det.i;
00636 z_sqrt(&z__1, &z__2);
00637 rtdisc.r = z__1.r, rtdisc.i = z__1.i;
00638 i__2 = kbot - 1;
00639 z__2.r = tr2.r + rtdisc.r, z__2.i = tr2.i +
00640 rtdisc.i;
00641 z__1.r = s * z__2.r, z__1.i = s * z__2.i;
00642 w[i__2].r = z__1.r, w[i__2].i = z__1.i;
00643 i__2 = kbot;
00644 z__2.r = tr2.r - rtdisc.r, z__2.i = tr2.i -
00645 rtdisc.i;
00646 z__1.r = s * z__2.r, z__1.i = s * z__2.i;
00647 w[i__2].r = z__1.r, w[i__2].i = z__1.i;
00648
00649 ks = kbot - 1;
00650 }
00651 }
00652
00653 if (kbot - ks + 1 > ns) {
00654
00655
00656
00657 sorted = FALSE_;
00658 i__2 = ks + 1;
00659 for (k = kbot; k >= i__2; --k) {
00660 if (sorted) {
00661 goto L60;
00662 }
00663 sorted = TRUE_;
00664 i__3 = k - 1;
00665 for (i__ = ks; i__ <= i__3; ++i__) {
00666 i__4 = i__;
00667 i__5 = i__ + 1;
00668 if ((d__1 = w[i__4].r, abs(d__1)) + (d__2 =
00669 d_imag(&w[i__]), abs(d__2)) < (d__3 =
00670 w[i__5].r, abs(d__3)) + (d__4 =
00671 d_imag(&w[i__ + 1]), abs(d__4))) {
00672 sorted = FALSE_;
00673 i__4 = i__;
00674 swap.r = w[i__4].r, swap.i = w[i__4].i;
00675 i__4 = i__;
00676 i__5 = i__ + 1;
00677 w[i__4].r = w[i__5].r, w[i__4].i = w[i__5]
00678 .i;
00679 i__4 = i__ + 1;
00680 w[i__4].r = swap.r, w[i__4].i = swap.i;
00681 }
00682
00683 }
00684
00685 }
00686 L60:
00687 ;
00688 }
00689 }
00690
00691
00692
00693
00694 if (kbot - ks + 1 == 2) {
00695 i__2 = kbot;
00696 i__3 = kbot + kbot * h_dim1;
00697 z__2.r = w[i__2].r - h__[i__3].r, z__2.i = w[i__2].i -
00698 h__[i__3].i;
00699 z__1.r = z__2.r, z__1.i = z__2.i;
00700 i__4 = kbot - 1;
00701 i__5 = kbot + kbot * h_dim1;
00702 z__4.r = w[i__4].r - h__[i__5].r, z__4.i = w[i__4].i -
00703 h__[i__5].i;
00704 z__3.r = z__4.r, z__3.i = z__4.i;
00705 if ((d__1 = z__1.r, abs(d__1)) + (d__2 = d_imag(&z__1),
00706 abs(d__2)) < (d__3 = z__3.r, abs(d__3)) + (d__4 =
00707 d_imag(&z__3), abs(d__4))) {
00708 i__2 = kbot - 1;
00709 i__3 = kbot;
00710 w[i__2].r = w[i__3].r, w[i__2].i = w[i__3].i;
00711 } else {
00712 i__2 = kbot;
00713 i__3 = kbot - 1;
00714 w[i__2].r = w[i__3].r, w[i__2].i = w[i__3].i;
00715 }
00716 }
00717
00718
00719
00720
00721
00722
00723
00724 i__2 = ns, i__3 = kbot - ks + 1;
00725 ns = min(i__2,i__3);
00726 ns -= ns % 2;
00727 ks = kbot - ns + 1;
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 kdu = ns * 3 - 3;
00741 ku = *n - kdu + 1;
00742 kwh = kdu + 1;
00743 nho = *n - kdu - 3 - (kdu + 1) + 1;
00744 kwv = kdu + 4;
00745 nve = *n - kdu - kwv + 1;
00746
00747
00748
00749 zlaqr5_(wantt, wantz, &kacc22, n, &ktop, &kbot, &ns, &w[ks], &
00750 h__[h_offset], ldh, iloz, ihiz, &z__[z_offset], ldz, &
00751 work[1], &c__3, &h__[ku + h_dim1], ldh, &nve, &h__[
00752 kwv + h_dim1], ldh, &nho, &h__[ku + kwh * h_dim1],
00753 ldh);
00754 }
00755
00756
00757
00758 if (ld > 0) {
00759 ndfl = 1;
00760 } else {
00761 ++ndfl;
00762 }
00763
00764
00765
00766 }
00767
00768
00769
00770
00771 *info = kbot;
00772 L80:
00773 ;
00774 }
00775
00776
00777
00778 d__1 = (doublereal) lwkopt;
00779 z__1.r = d__1, z__1.i = 0.;
00780 work[1].r = z__1.r, work[1].i = z__1.i;
00781
00782
00783
00784 return 0;
00785 }