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 doublecomplex c_b1 = {0.,0.};
00019 static doublecomplex c_b2 = {1.,0.};
00020 static integer c__1 = 1;
00021 static integer c_n1 = -1;
00022 static logical c_true = TRUE_;
00023
00024 int zlaqr2_(logical *wantt, logical *wantz, integer *n,
00025 integer *ktop, integer *kbot, integer *nw, doublecomplex *h__,
00026 integer *ldh, integer *iloz, integer *ihiz, doublecomplex *z__,
00027 integer *ldz, integer *ns, integer *nd, doublecomplex *sh,
00028 doublecomplex *v, integer *ldv, integer *nh, doublecomplex *t,
00029 integer *ldt, integer *nv, doublecomplex *wv, integer *ldwv,
00030 doublecomplex *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 doublecomplex z__1, z__2;
00037
00038
00039 double d_imag(doublecomplex *);
00040 void d_cnjg(doublecomplex *, doublecomplex *);
00041
00042
00043 integer i__, j;
00044 doublecomplex s;
00045 integer jw;
00046 doublereal foo;
00047 integer kln;
00048 doublecomplex tau;
00049 integer knt;
00050 doublereal ulp;
00051 integer lwk1, lwk2;
00052 doublecomplex beta;
00053 integer kcol, info, ifst, ilst, ltop, krow;
00054 extern int zlarf_(char *, integer *, integer *,
00055 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00056 integer *, doublecomplex *);
00057 integer infqr;
00058 extern int zgemm_(char *, char *, integer *, integer *,
00059 integer *, doublecomplex *, doublecomplex *, integer *,
00060 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00061 integer *);
00062 integer kwtop;
00063 extern int zcopy_(integer *, doublecomplex *, integer *,
00064 doublecomplex *, integer *), dlabad_(doublereal *, doublereal *);
00065 extern doublereal dlamch_(char *);
00066 doublereal safmin, safmax;
00067 extern int zgehrd_(integer *, integer *, integer *,
00068 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00069 integer *, integer *), zlarfg_(integer *, doublecomplex *,
00070 doublecomplex *, integer *, doublecomplex *), zlahqr_(logical *,
00071 logical *, integer *, integer *, integer *, doublecomplex *,
00072 integer *, doublecomplex *, integer *, integer *, doublecomplex *,
00073 integer *, integer *), zlacpy_(char *, integer *, integer *,
00074 doublecomplex *, integer *, doublecomplex *, integer *),
00075 zlaset_(char *, integer *, integer *, doublecomplex *,
00076 doublecomplex *, doublecomplex *, integer *);
00077 doublereal smlnum;
00078 extern int ztrexc_(char *, integer *, doublecomplex *,
00079 integer *, doublecomplex *, integer *, integer *, integer *,
00080 integer *);
00081 integer lwkopt;
00082 extern int zunmhr_(char *, char *, integer *, integer *,
00083 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00084 doublecomplex *, integer *, doublecomplex *, integer *, integer *
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 h_dim1 = *ldh;
00254 h_offset = 1 + h_dim1;
00255 h__ -= h_offset;
00256 z_dim1 = *ldz;
00257 z_offset = 1 + z_dim1;
00258 z__ -= z_offset;
00259 --sh;
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 zgehrd_(&jw, &c__1, &i__1, &t[t_offset], ldt, &work[1], &work[1], &
00283 c_n1, &info);
00284 lwk1 = (integer) work[1].r;
00285
00286
00287
00288 i__1 = jw - 1;
00289 zunmhr_("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].r;
00292
00293
00294
00295 lwkopt = jw + max(lwk1,lwk2);
00296 }
00297
00298
00299
00300 if (*lwork == -1) {
00301 d__1 = (doublereal) lwkopt;
00302 z__1.r = d__1, z__1.i = 0.;
00303 work[1].r = z__1.r, work[1].i = z__1.i;
00304 return 0;
00305 }
00306
00307
00308
00309 *ns = 0;
00310 *nd = 0;
00311 work[1].r = 1., work[1].i = 0.;
00312 if (*ktop > *kbot) {
00313 return 0;
00314 }
00315
00316 if (*nw < 1) {
00317 return 0;
00318 }
00319
00320
00321
00322 safmin = dlamch_("SAFE MINIMUM");
00323 safmax = 1. / safmin;
00324 dlabad_(&safmin, &safmax);
00325 ulp = dlamch_("PRECISION");
00326 smlnum = safmin * ((doublereal) (*n) / ulp);
00327
00328
00329
00330
00331 i__1 = *nw, i__2 = *kbot - *ktop + 1;
00332 jw = min(i__1,i__2);
00333 kwtop = *kbot - jw + 1;
00334 if (kwtop == *ktop) {
00335 s.r = 0., s.i = 0.;
00336 } else {
00337 i__1 = kwtop + (kwtop - 1) * h_dim1;
00338 s.r = h__[i__1].r, s.i = h__[i__1].i;
00339 }
00340
00341 if (*kbot == kwtop) {
00342
00343
00344
00345 i__1 = kwtop;
00346 i__2 = kwtop + kwtop * h_dim1;
00347 sh[i__1].r = h__[i__2].r, sh[i__1].i = h__[i__2].i;
00348 *ns = 1;
00349 *nd = 0;
00350
00351 i__1 = kwtop + kwtop * h_dim1;
00352 d__5 = smlnum, d__6 = ulp * ((d__1 = h__[i__1].r, abs(d__1)) + (d__2 =
00353 d_imag(&h__[kwtop + kwtop * h_dim1]), abs(d__2)));
00354 if ((d__3 = s.r, abs(d__3)) + (d__4 = d_imag(&s), abs(d__4)) <= max(
00355 d__5,d__6)) {
00356 *ns = 0;
00357 *nd = 1;
00358 if (kwtop > *ktop) {
00359 i__1 = kwtop + (kwtop - 1) * h_dim1;
00360 h__[i__1].r = 0., h__[i__1].i = 0.;
00361 }
00362 }
00363 work[1].r = 1., work[1].i = 0.;
00364 return 0;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 zlacpy_("U", &jw, &jw, &h__[kwtop + kwtop * h_dim1], ldh, &t[t_offset],
00374 ldt);
00375 i__1 = jw - 1;
00376 i__2 = *ldh + 1;
00377 i__3 = *ldt + 1;
00378 zcopy_(&i__1, &h__[kwtop + 1 + kwtop * h_dim1], &i__2, &t[t_dim1 + 2], &
00379 i__3);
00380
00381 zlaset_("A", &jw, &jw, &c_b1, &c_b2, &v[v_offset], ldv);
00382 zlahqr_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sh[kwtop],
00383 &c__1, &jw, &v[v_offset], ldv, &infqr);
00384
00385
00386
00387 *ns = jw;
00388 ilst = infqr + 1;
00389 i__1 = jw;
00390 for (knt = infqr + 1; knt <= i__1; ++knt) {
00391
00392
00393
00394 i__2 = *ns + *ns * t_dim1;
00395 foo = (d__1 = t[i__2].r, abs(d__1)) + (d__2 = d_imag(&t[*ns + *ns *
00396 t_dim1]), abs(d__2));
00397 if (foo == 0.) {
00398 foo = (d__1 = s.r, abs(d__1)) + (d__2 = d_imag(&s), abs(d__2));
00399 }
00400 i__2 = *ns * v_dim1 + 1;
00401
00402 d__5 = smlnum, d__6 = ulp * foo;
00403 if (((d__1 = s.r, abs(d__1)) + (d__2 = d_imag(&s), abs(d__2))) * ((
00404 d__3 = v[i__2].r, abs(d__3)) + (d__4 = d_imag(&v[*ns * v_dim1
00405 + 1]), abs(d__4))) <= max(d__5,d__6)) {
00406
00407
00408
00409 --(*ns);
00410 } else {
00411
00412
00413
00414
00415 ifst = *ns;
00416 ztrexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst, &
00417 ilst, &info);
00418 ++ilst;
00419 }
00420
00421 }
00422
00423
00424
00425 if (*ns == 0) {
00426 s.r = 0., s.i = 0.;
00427 }
00428
00429 if (*ns < jw) {
00430
00431
00432
00433
00434 i__1 = *ns;
00435 for (i__ = infqr + 1; i__ <= i__1; ++i__) {
00436 ifst = i__;
00437 i__2 = *ns;
00438 for (j = i__ + 1; j <= i__2; ++j) {
00439 i__3 = j + j * t_dim1;
00440 i__4 = ifst + ifst * t_dim1;
00441 if ((d__1 = t[i__3].r, abs(d__1)) + (d__2 = d_imag(&t[j + j *
00442 t_dim1]), abs(d__2)) > (d__3 = t[i__4].r, abs(d__3))
00443 + (d__4 = d_imag(&t[ifst + ifst * t_dim1]), abs(d__4))
00444 ) {
00445 ifst = j;
00446 }
00447
00448 }
00449 ilst = i__;
00450 if (ifst != ilst) {
00451 ztrexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00452 &ilst, &info);
00453 }
00454
00455 }
00456 }
00457
00458
00459
00460 i__1 = jw;
00461 for (i__ = infqr + 1; i__ <= i__1; ++i__) {
00462 i__2 = kwtop + i__ - 1;
00463 i__3 = i__ + i__ * t_dim1;
00464 sh[i__2].r = t[i__3].r, sh[i__2].i = t[i__3].i;
00465
00466 }
00467
00468
00469 if (*ns < jw || s.r == 0. && s.i == 0.) {
00470 if (*ns > 1 && (s.r != 0. || s.i != 0.)) {
00471
00472
00473
00474 zcopy_(ns, &v[v_offset], ldv, &work[1], &c__1);
00475 i__1 = *ns;
00476 for (i__ = 1; i__ <= i__1; ++i__) {
00477 i__2 = i__;
00478 d_cnjg(&z__1, &work[i__]);
00479 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00480
00481 }
00482 beta.r = work[1].r, beta.i = work[1].i;
00483 zlarfg_(ns, &beta, &work[2], &c__1, &tau);
00484 work[1].r = 1., work[1].i = 0.;
00485
00486 i__1 = jw - 2;
00487 i__2 = jw - 2;
00488 zlaset_("L", &i__1, &i__2, &c_b1, &c_b1, &t[t_dim1 + 3], ldt);
00489
00490 d_cnjg(&z__1, &tau);
00491 zlarf_("L", ns, &jw, &work[1], &c__1, &z__1, &t[t_offset], ldt, &
00492 work[jw + 1]);
00493 zlarf_("R", ns, ns, &work[1], &c__1, &tau, &t[t_offset], ldt, &
00494 work[jw + 1]);
00495 zlarf_("R", &jw, ns, &work[1], &c__1, &tau, &v[v_offset], ldv, &
00496 work[jw + 1]);
00497
00498 i__1 = *lwork - jw;
00499 zgehrd_(&jw, &c__1, ns, &t[t_offset], ldt, &work[1], &work[jw + 1]
00500 , &i__1, &info);
00501 }
00502
00503
00504
00505 if (kwtop > 1) {
00506 i__1 = kwtop + (kwtop - 1) * h_dim1;
00507 d_cnjg(&z__2, &v[v_dim1 + 1]);
00508 z__1.r = s.r * z__2.r - s.i * z__2.i, z__1.i = s.r * z__2.i + s.i
00509 * z__2.r;
00510 h__[i__1].r = z__1.r, h__[i__1].i = z__1.i;
00511 }
00512 zlacpy_("U", &jw, &jw, &t[t_offset], ldt, &h__[kwtop + kwtop * h_dim1]
00513 , ldh);
00514 i__1 = jw - 1;
00515 i__2 = *ldt + 1;
00516 i__3 = *ldh + 1;
00517 zcopy_(&i__1, &t[t_dim1 + 2], &i__2, &h__[kwtop + 1 + kwtop * h_dim1],
00518 &i__3);
00519
00520
00521
00522
00523 if (*ns > 1 && (s.r != 0. || s.i != 0.)) {
00524 i__1 = *lwork - jw;
00525 zunmhr_("R", "N", &jw, ns, &c__1, ns, &t[t_offset], ldt, &work[1],
00526 &v[v_offset], ldv, &work[jw + 1], &i__1, &info);
00527 }
00528
00529
00530
00531 if (*wantt) {
00532 ltop = 1;
00533 } else {
00534 ltop = *ktop;
00535 }
00536 i__1 = kwtop - 1;
00537 i__2 = *nv;
00538 for (krow = ltop; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00539 i__2) {
00540
00541 i__3 = *nv, i__4 = kwtop - krow;
00542 kln = min(i__3,i__4);
00543 zgemm_("N", "N", &kln, &jw, &jw, &c_b2, &h__[krow + kwtop *
00544 h_dim1], ldh, &v[v_offset], ldv, &c_b1, &wv[wv_offset],
00545 ldwv);
00546 zlacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &h__[krow + kwtop *
00547 h_dim1], ldh);
00548
00549 }
00550
00551
00552
00553 if (*wantt) {
00554 i__2 = *n;
00555 i__1 = *nh;
00556 for (kcol = *kbot + 1; i__1 < 0 ? kcol >= i__2 : kcol <= i__2;
00557 kcol += i__1) {
00558
00559 i__3 = *nh, i__4 = *n - kcol + 1;
00560 kln = min(i__3,i__4);
00561 zgemm_("C", "N", &jw, &kln, &jw, &c_b2, &v[v_offset], ldv, &
00562 h__[kwtop + kcol * h_dim1], ldh, &c_b1, &t[t_offset],
00563 ldt);
00564 zlacpy_("A", &jw, &kln, &t[t_offset], ldt, &h__[kwtop + kcol *
00565 h_dim1], ldh);
00566
00567 }
00568 }
00569
00570
00571
00572 if (*wantz) {
00573 i__1 = *ihiz;
00574 i__2 = *nv;
00575 for (krow = *iloz; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00576 i__2) {
00577
00578 i__3 = *nv, i__4 = *ihiz - krow + 1;
00579 kln = min(i__3,i__4);
00580 zgemm_("N", "N", &kln, &jw, &jw, &c_b2, &z__[krow + kwtop *
00581 z_dim1], ldz, &v[v_offset], ldv, &c_b1, &wv[wv_offset]
00582 , ldwv);
00583 zlacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &z__[krow +
00584 kwtop * z_dim1], ldz);
00585
00586 }
00587 }
00588 }
00589
00590
00591
00592 *nd = jw - *ns;
00593
00594
00595
00596
00597
00598
00599
00600 *ns -= infqr;
00601
00602
00603
00604 d__1 = (doublereal) lwkopt;
00605 z__1.r = d__1, z__1.i = 0.;
00606 work[1].r = z__1.r, work[1].i = z__1.i;
00607
00608
00609
00610 return 0;
00611 }