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 complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__1 = 1;
00021 static integer c_n1 = -1;
00022 static logical c_true = TRUE_;
00023 static integer c__12 = 12;
00024
00025 int claqr3_(logical *wantt, logical *wantz, integer *n,
00026 integer *ktop, integer *kbot, integer *nw, complex *h__, integer *ldh,
00027 integer *iloz, integer *ihiz, complex *z__, integer *ldz, integer *
00028 ns, integer *nd, complex *sh, complex *v, integer *ldv, integer *nh,
00029 complex *t, integer *ldt, integer *nv, complex *wv, integer *ldwv,
00030 complex *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 complex q__1, q__2;
00037
00038
00039 double r_imag(complex *);
00040 void r_cnjg(complex *, complex *);
00041
00042
00043 integer i__, j;
00044 complex s;
00045 integer jw;
00046 real foo;
00047 integer kln;
00048 complex tau;
00049 integer knt;
00050 real ulp;
00051 integer lwk1, lwk2, lwk3;
00052 complex beta;
00053 integer kcol, info, nmin, ifst, ilst, ltop, krow;
00054 extern int clarf_(char *, integer *, integer *, complex *
00055 , integer *, complex *, complex *, integer *, complex *),
00056 cgemm_(char *, char *, integer *, integer *, integer *, complex *,
00057 complex *, integer *, complex *, integer *, complex *, complex *,
00058 integer *), ccopy_(integer *, complex *, integer
00059 *, complex *, integer *);
00060 integer infqr, kwtop;
00061 extern int claqr4_(logical *, logical *, integer *,
00062 integer *, integer *, complex *, integer *, complex *, integer *,
00063 integer *, complex *, integer *, complex *, integer *, integer *),
00064 slabad_(real *, real *), cgehrd_(integer *, integer *, integer *,
00065 complex *, integer *, complex *, complex *, integer *, integer *)
00066 , clarfg_(integer *, complex *, complex *, integer *, complex *);
00067 extern doublereal slamch_(char *);
00068 extern int clahqr_(logical *, logical *, integer *,
00069 integer *, integer *, complex *, integer *, complex *, integer *,
00070 integer *, complex *, integer *, integer *), clacpy_(char *,
00071 integer *, integer *, complex *, integer *, complex *, integer *), claset_(char *, integer *, integer *, complex *, complex
00072 *, complex *, integer *);
00073 real safmin;
00074 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00075 integer *, integer *);
00076 real safmax;
00077 extern int ctrexc_(char *, integer *, complex *, integer
00078 *, complex *, integer *, integer *, integer *, integer *),
00079 cunmhr_(char *, char *, integer *, integer *, integer *, integer
00080 *, complex *, integer *, complex *, complex *, integer *, complex
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 --sh;
00254 v_dim1 = *ldv;
00255 v_offset = 1 + v_dim1;
00256 v -= v_offset;
00257 t_dim1 = *ldt;
00258 t_offset = 1 + t_dim1;
00259 t -= t_offset;
00260 wv_dim1 = *ldwv;
00261 wv_offset = 1 + wv_dim1;
00262 wv -= wv_offset;
00263 --work;
00264
00265
00266
00267 i__1 = *nw, i__2 = *kbot - *ktop + 1;
00268 jw = min(i__1,i__2);
00269 if (jw <= 2) {
00270 lwkopt = 1;
00271 } else {
00272
00273
00274
00275 i__1 = jw - 1;
00276 cgehrd_(&jw, &c__1, &i__1, &t[t_offset], ldt, &work[1], &work[1], &
00277 c_n1, &info);
00278 lwk1 = (integer) work[1].r;
00279
00280
00281
00282 i__1 = jw - 1;
00283 cunmhr_("R", "N", &jw, &jw, &c__1, &i__1, &t[t_offset], ldt, &work[1],
00284 &v[v_offset], ldv, &work[1], &c_n1, &info);
00285 lwk2 = (integer) work[1].r;
00286
00287
00288
00289 claqr4_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sh[1],
00290 &c__1, &jw, &v[v_offset], ldv, &work[1], &c_n1, &infqr);
00291 lwk3 = (integer) work[1].r;
00292
00293
00294
00295
00296 i__1 = jw + max(lwk1,lwk2);
00297 lwkopt = max(i__1,lwk3);
00298 }
00299
00300
00301
00302 if (*lwork == -1) {
00303 r__1 = (real) lwkopt;
00304 q__1.r = r__1, q__1.i = 0.f;
00305 work[1].r = q__1.r, work[1].i = q__1.i;
00306 return 0;
00307 }
00308
00309
00310
00311 *ns = 0;
00312 *nd = 0;
00313 work[1].r = 1.f, work[1].i = 0.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.r = 0.f, s.i = 0.f;
00338 } else {
00339 i__1 = kwtop + (kwtop - 1) * h_dim1;
00340 s.r = h__[i__1].r, s.i = h__[i__1].i;
00341 }
00342
00343 if (*kbot == kwtop) {
00344
00345
00346
00347 i__1 = kwtop;
00348 i__2 = kwtop + kwtop * h_dim1;
00349 sh[i__1].r = h__[i__2].r, sh[i__1].i = h__[i__2].i;
00350 *ns = 1;
00351 *nd = 0;
00352
00353 i__1 = kwtop + kwtop * h_dim1;
00354 r__5 = smlnum, r__6 = ulp * ((r__1 = h__[i__1].r, dabs(r__1)) + (r__2
00355 = r_imag(&h__[kwtop + kwtop * h_dim1]), dabs(r__2)));
00356 if ((r__3 = s.r, dabs(r__3)) + (r__4 = r_imag(&s), dabs(r__4)) <=
00357 dmax(r__5,r__6)) {
00358 *ns = 0;
00359 *nd = 1;
00360 if (kwtop > *ktop) {
00361 i__1 = kwtop + (kwtop - 1) * h_dim1;
00362 h__[i__1].r = 0.f, h__[i__1].i = 0.f;
00363 }
00364 }
00365 work[1].r = 1.f, work[1].i = 0.f;
00366 return 0;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375 clacpy_("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 ccopy_(&i__1, &h__[kwtop + 1 + kwtop * h_dim1], &i__2, &t[t_dim1 + 2], &
00381 i__3);
00382
00383 claset_("A", &jw, &jw, &c_b1, &c_b2, &v[v_offset], ldv);
00384 nmin = ilaenv_(&c__12, "CLAQR3", "SV", &jw, &c__1, &jw, lwork);
00385 if (jw > nmin) {
00386 claqr4_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sh[
00387 kwtop], &c__1, &jw, &v[v_offset], ldv, &work[1], lwork, &
00388 infqr);
00389 } else {
00390 clahqr_(&c_true, &c_true, &jw, &c__1, &jw, &t[t_offset], ldt, &sh[
00391 kwtop], &c__1, &jw, &v[v_offset], ldv, &infqr);
00392 }
00393
00394
00395
00396 *ns = jw;
00397 ilst = infqr + 1;
00398 i__1 = jw;
00399 for (knt = infqr + 1; knt <= i__1; ++knt) {
00400
00401
00402
00403 i__2 = *ns + *ns * t_dim1;
00404 foo = (r__1 = t[i__2].r, dabs(r__1)) + (r__2 = r_imag(&t[*ns + *ns *
00405 t_dim1]), dabs(r__2));
00406 if (foo == 0.f) {
00407 foo = (r__1 = s.r, dabs(r__1)) + (r__2 = r_imag(&s), dabs(r__2));
00408 }
00409 i__2 = *ns * v_dim1 + 1;
00410
00411 r__5 = smlnum, r__6 = ulp * foo;
00412 if (((r__1 = s.r, dabs(r__1)) + (r__2 = r_imag(&s), dabs(r__2))) * ((
00413 r__3 = v[i__2].r, dabs(r__3)) + (r__4 = r_imag(&v[*ns *
00414 v_dim1 + 1]), dabs(r__4))) <= dmax(r__5,r__6)) {
00415
00416
00417
00418 --(*ns);
00419 } else {
00420
00421
00422
00423
00424 ifst = *ns;
00425 ctrexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst, &
00426 ilst, &info);
00427 ++ilst;
00428 }
00429
00430 }
00431
00432
00433
00434 if (*ns == 0) {
00435 s.r = 0.f, s.i = 0.f;
00436 }
00437
00438 if (*ns < jw) {
00439
00440
00441
00442
00443 i__1 = *ns;
00444 for (i__ = infqr + 1; i__ <= i__1; ++i__) {
00445 ifst = i__;
00446 i__2 = *ns;
00447 for (j = i__ + 1; j <= i__2; ++j) {
00448 i__3 = j + j * t_dim1;
00449 i__4 = ifst + ifst * t_dim1;
00450 if ((r__1 = t[i__3].r, dabs(r__1)) + (r__2 = r_imag(&t[j + j *
00451 t_dim1]), dabs(r__2)) > (r__3 = t[i__4].r, dabs(r__3)
00452 ) + (r__4 = r_imag(&t[ifst + ifst * t_dim1]), dabs(
00453 r__4))) {
00454 ifst = j;
00455 }
00456
00457 }
00458 ilst = i__;
00459 if (ifst != ilst) {
00460 ctrexc_("V", &jw, &t[t_offset], ldt, &v[v_offset], ldv, &ifst,
00461 &ilst, &info);
00462 }
00463
00464 }
00465 }
00466
00467
00468
00469 i__1 = jw;
00470 for (i__ = infqr + 1; i__ <= i__1; ++i__) {
00471 i__2 = kwtop + i__ - 1;
00472 i__3 = i__ + i__ * t_dim1;
00473 sh[i__2].r = t[i__3].r, sh[i__2].i = t[i__3].i;
00474
00475 }
00476
00477
00478 if (*ns < jw || s.r == 0.f && s.i == 0.f) {
00479 if (*ns > 1 && (s.r != 0.f || s.i != 0.f)) {
00480
00481
00482
00483 ccopy_(ns, &v[v_offset], ldv, &work[1], &c__1);
00484 i__1 = *ns;
00485 for (i__ = 1; i__ <= i__1; ++i__) {
00486 i__2 = i__;
00487 r_cnjg(&q__1, &work[i__]);
00488 work[i__2].r = q__1.r, work[i__2].i = q__1.i;
00489
00490 }
00491 beta.r = work[1].r, beta.i = work[1].i;
00492 clarfg_(ns, &beta, &work[2], &c__1, &tau);
00493 work[1].r = 1.f, work[1].i = 0.f;
00494
00495 i__1 = jw - 2;
00496 i__2 = jw - 2;
00497 claset_("L", &i__1, &i__2, &c_b1, &c_b1, &t[t_dim1 + 3], ldt);
00498
00499 r_cnjg(&q__1, &tau);
00500 clarf_("L", ns, &jw, &work[1], &c__1, &q__1, &t[t_offset], ldt, &
00501 work[jw + 1]);
00502 clarf_("R", ns, ns, &work[1], &c__1, &tau, &t[t_offset], ldt, &
00503 work[jw + 1]);
00504 clarf_("R", &jw, ns, &work[1], &c__1, &tau, &v[v_offset], ldv, &
00505 work[jw + 1]);
00506
00507 i__1 = *lwork - jw;
00508 cgehrd_(&jw, &c__1, ns, &t[t_offset], ldt, &work[1], &work[jw + 1]
00509 , &i__1, &info);
00510 }
00511
00512
00513
00514 if (kwtop > 1) {
00515 i__1 = kwtop + (kwtop - 1) * h_dim1;
00516 r_cnjg(&q__2, &v[v_dim1 + 1]);
00517 q__1.r = s.r * q__2.r - s.i * q__2.i, q__1.i = s.r * q__2.i + s.i
00518 * q__2.r;
00519 h__[i__1].r = q__1.r, h__[i__1].i = q__1.i;
00520 }
00521 clacpy_("U", &jw, &jw, &t[t_offset], ldt, &h__[kwtop + kwtop * h_dim1]
00522 , ldh);
00523 i__1 = jw - 1;
00524 i__2 = *ldt + 1;
00525 i__3 = *ldh + 1;
00526 ccopy_(&i__1, &t[t_dim1 + 2], &i__2, &h__[kwtop + 1 + kwtop * h_dim1],
00527 &i__3);
00528
00529
00530
00531
00532 if (*ns > 1 && (s.r != 0.f || s.i != 0.f)) {
00533 i__1 = *lwork - jw;
00534 cunmhr_("R", "N", &jw, ns, &c__1, ns, &t[t_offset], ldt, &work[1],
00535 &v[v_offset], ldv, &work[jw + 1], &i__1, &info);
00536 }
00537
00538
00539
00540 if (*wantt) {
00541 ltop = 1;
00542 } else {
00543 ltop = *ktop;
00544 }
00545 i__1 = kwtop - 1;
00546 i__2 = *nv;
00547 for (krow = ltop; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00548 i__2) {
00549
00550 i__3 = *nv, i__4 = kwtop - krow;
00551 kln = min(i__3,i__4);
00552 cgemm_("N", "N", &kln, &jw, &jw, &c_b2, &h__[krow + kwtop *
00553 h_dim1], ldh, &v[v_offset], ldv, &c_b1, &wv[wv_offset],
00554 ldwv);
00555 clacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &h__[krow + kwtop *
00556 h_dim1], ldh);
00557
00558 }
00559
00560
00561
00562 if (*wantt) {
00563 i__2 = *n;
00564 i__1 = *nh;
00565 for (kcol = *kbot + 1; i__1 < 0 ? kcol >= i__2 : kcol <= i__2;
00566 kcol += i__1) {
00567
00568 i__3 = *nh, i__4 = *n - kcol + 1;
00569 kln = min(i__3,i__4);
00570 cgemm_("C", "N", &jw, &kln, &jw, &c_b2, &v[v_offset], ldv, &
00571 h__[kwtop + kcol * h_dim1], ldh, &c_b1, &t[t_offset],
00572 ldt);
00573 clacpy_("A", &jw, &kln, &t[t_offset], ldt, &h__[kwtop + kcol *
00574 h_dim1], ldh);
00575
00576 }
00577 }
00578
00579
00580
00581 if (*wantz) {
00582 i__1 = *ihiz;
00583 i__2 = *nv;
00584 for (krow = *iloz; i__2 < 0 ? krow >= i__1 : krow <= i__1; krow +=
00585 i__2) {
00586
00587 i__3 = *nv, i__4 = *ihiz - krow + 1;
00588 kln = min(i__3,i__4);
00589 cgemm_("N", "N", &kln, &jw, &jw, &c_b2, &z__[krow + kwtop *
00590 z_dim1], ldz, &v[v_offset], ldv, &c_b1, &wv[wv_offset]
00591 , ldwv);
00592 clacpy_("A", &kln, &jw, &wv[wv_offset], ldwv, &z__[krow +
00593 kwtop * z_dim1], ldz);
00594
00595 }
00596 }
00597 }
00598
00599
00600
00601 *nd = jw - *ns;
00602
00603
00604
00605
00606
00607
00608
00609 *ns -= infqr;
00610
00611
00612
00613 r__1 = (real) lwkopt;
00614 q__1.r = r__1, q__1.i = 0.f;
00615 work[1].r = q__1.r, work[1].i = q__1.i;
00616
00617
00618
00619 return 0;
00620 }