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