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
00022 int zhpt21_(integer *itype, char *uplo, integer *n, integer *
00023 kband, doublecomplex *ap, doublereal *d__, doublereal *e,
00024 doublecomplex *u, integer *ldu, doublecomplex *vp, doublecomplex *tau,
00025 doublecomplex *work, doublereal *rwork, doublereal *result)
00026 {
00027
00028 integer u_dim1, u_offset, i__1, i__2, i__3, i__4, i__5, i__6;
00029 doublereal d__1, d__2;
00030 doublecomplex z__1, z__2, z__3;
00031
00032
00033 integer j, jp, jr, jp1, lap;
00034 doublereal ulp, unfl;
00035 doublecomplex temp;
00036 extern int zhpr_(char *, integer *, doublereal *,
00037 doublecomplex *, integer *, doublecomplex *), zhpr2_(char
00038 *, integer *, doublecomplex *, doublecomplex *, integer *,
00039 doublecomplex *, integer *, doublecomplex *);
00040 extern logical lsame_(char *, char *);
00041 integer iinfo;
00042 doublereal anorm;
00043 extern int zgemm_(char *, char *, integer *, integer *,
00044 integer *, doublecomplex *, doublecomplex *, integer *,
00045 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00046 integer *);
00047 char cuplo[1];
00048 doublecomplex vsave;
00049 extern VOID zdotc_(doublecomplex *, integer *,
00050 doublecomplex *, integer *, doublecomplex *, integer *);
00051 logical lower;
00052 doublereal wnorm;
00053 extern int zcopy_(integer *, doublecomplex *, integer *,
00054 doublecomplex *, integer *), zhpmv_(char *, integer *,
00055 doublecomplex *, doublecomplex *, doublecomplex *, integer *,
00056 doublecomplex *, doublecomplex *, integer *), zaxpy_(
00057 integer *, doublecomplex *, doublecomplex *, integer *,
00058 doublecomplex *, integer *);
00059 extern doublereal dlamch_(char *), zlange_(char *, integer *,
00060 integer *, doublecomplex *, integer *, doublereal *),
00061 zlanhp_(char *, char *, integer *, doublecomplex *, doublereal *);
00062 extern int zlacpy_(char *, integer *, integer *,
00063 doublecomplex *, integer *, doublecomplex *, integer *),
00064 zlaset_(char *, integer *, integer *, doublecomplex *,
00065 doublecomplex *, doublecomplex *, integer *), zupmtr_(
00066 char *, char *, char *, integer *, integer *, doublecomplex *,
00067 doublecomplex *, doublecomplex *, integer *, doublecomplex *,
00068 integer *);
00069
00070
00071
00072
00073
00074
00075
00076
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 --ap;
00243 --d__;
00244 --e;
00245 u_dim1 = *ldu;
00246 u_offset = 1 + u_dim1;
00247 u -= u_offset;
00248 --vp;
00249 --tau;
00250 --work;
00251 --rwork;
00252 --result;
00253
00254
00255 result[1] = 0.;
00256 if (*itype == 1) {
00257 result[2] = 0.;
00258 }
00259 if (*n <= 0) {
00260 return 0;
00261 }
00262
00263 lap = *n * (*n + 1) / 2;
00264
00265 if (lsame_(uplo, "U")) {
00266 lower = FALSE_;
00267 *(unsigned char *)cuplo = 'U';
00268 } else {
00269 lower = TRUE_;
00270 *(unsigned char *)cuplo = 'L';
00271 }
00272
00273 unfl = dlamch_("Safe minimum");
00274 ulp = dlamch_("Epsilon") * dlamch_("Base");
00275
00276
00277
00278 if (*itype < 1 || *itype > 3) {
00279 result[1] = 10. / ulp;
00280 return 0;
00281 }
00282
00283
00284
00285
00286
00287 if (*itype == 3) {
00288 anorm = 1.;
00289 } else {
00290
00291 d__1 = zlanhp_("1", cuplo, n, &ap[1], &rwork[1])
00292 ;
00293 anorm = max(d__1,unfl);
00294 }
00295
00296
00297
00298 if (*itype == 1) {
00299
00300
00301
00302 zlaset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00303 zcopy_(&lap, &ap[1], &c__1, &work[1], &c__1);
00304
00305 i__1 = *n;
00306 for (j = 1; j <= i__1; ++j) {
00307 d__1 = -d__[j];
00308 zhpr_(cuplo, n, &d__1, &u[j * u_dim1 + 1], &c__1, &work[1]);
00309
00310 }
00311
00312 if (*n > 1 && *kband == 1) {
00313 i__1 = *n - 1;
00314 for (j = 1; j <= i__1; ++j) {
00315 i__2 = j;
00316 z__2.r = e[i__2], z__2.i = 0.;
00317 z__1.r = -z__2.r, z__1.i = -z__2.i;
00318 zhpr2_(cuplo, n, &z__1, &u[j * u_dim1 + 1], &c__1, &u[(j - 1)
00319 * u_dim1 + 1], &c__1, &work[1]);
00320
00321 }
00322 }
00323 wnorm = zlanhp_("1", cuplo, n, &work[1], &rwork[1]);
00324
00325 } else if (*itype == 2) {
00326
00327
00328
00329 zlaset_("Full", n, n, &c_b1, &c_b1, &work[1], n);
00330
00331 if (lower) {
00332 i__1 = lap;
00333 i__2 = *n;
00334 work[i__1].r = d__[i__2], work[i__1].i = 0.;
00335 for (j = *n - 1; j >= 1; --j) {
00336 jp = ((*n << 1) - j) * (j - 1) / 2;
00337 jp1 = jp + *n - j;
00338 if (*kband == 1) {
00339 i__1 = jp + j + 1;
00340 i__2 = j;
00341 z__2.r = 1. - tau[i__2].r, z__2.i = 0. - tau[i__2].i;
00342 i__3 = j;
00343 z__1.r = e[i__3] * z__2.r, z__1.i = e[i__3] * z__2.i;
00344 work[i__1].r = z__1.r, work[i__1].i = z__1.i;
00345 i__1 = *n;
00346 for (jr = j + 2; jr <= i__1; ++jr) {
00347 i__2 = jp + jr;
00348 i__3 = j;
00349 z__3.r = -tau[i__3].r, z__3.i = -tau[i__3].i;
00350 i__4 = j;
00351 z__2.r = e[i__4] * z__3.r, z__2.i = e[i__4] * z__3.i;
00352 i__5 = jp + jr;
00353 z__1.r = z__2.r * vp[i__5].r - z__2.i * vp[i__5].i,
00354 z__1.i = z__2.r * vp[i__5].i + z__2.i * vp[
00355 i__5].r;
00356 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00357
00358 }
00359 }
00360
00361 i__1 = j;
00362 if (tau[i__1].r != 0. || tau[i__1].i != 0.) {
00363 i__1 = jp + j + 1;
00364 vsave.r = vp[i__1].r, vsave.i = vp[i__1].i;
00365 i__1 = jp + j + 1;
00366 vp[i__1].r = 1., vp[i__1].i = 0.;
00367 i__1 = *n - j;
00368 zhpmv_("L", &i__1, &c_b2, &work[jp1 + j + 1], &vp[jp + j
00369 + 1], &c__1, &c_b1, &work[lap + 1], &c__1);
00370 i__1 = j;
00371 z__2.r = tau[i__1].r * -.5, z__2.i = tau[i__1].i * -.5;
00372 i__2 = *n - j;
00373 zdotc_(&z__3, &i__2, &work[lap + 1], &c__1, &vp[jp + j +
00374 1], &c__1);
00375 z__1.r = z__2.r * z__3.r - z__2.i * z__3.i, z__1.i =
00376 z__2.r * z__3.i + z__2.i * z__3.r;
00377 temp.r = z__1.r, temp.i = z__1.i;
00378 i__1 = *n - j;
00379 zaxpy_(&i__1, &temp, &vp[jp + j + 1], &c__1, &work[lap +
00380 1], &c__1);
00381 i__1 = *n - j;
00382 i__2 = j;
00383 z__1.r = -tau[i__2].r, z__1.i = -tau[i__2].i;
00384 zhpr2_("L", &i__1, &z__1, &vp[jp + j + 1], &c__1, &work[
00385 lap + 1], &c__1, &work[jp1 + j + 1]);
00386
00387 i__1 = jp + j + 1;
00388 vp[i__1].r = vsave.r, vp[i__1].i = vsave.i;
00389 }
00390 i__1 = jp + j;
00391 i__2 = j;
00392 work[i__1].r = d__[i__2], work[i__1].i = 0.;
00393
00394 }
00395 } else {
00396 work[1].r = d__[1], work[1].i = 0.;
00397 i__1 = *n - 1;
00398 for (j = 1; j <= i__1; ++j) {
00399 jp = j * (j - 1) / 2;
00400 jp1 = jp + j;
00401 if (*kband == 1) {
00402 i__2 = jp1 + j;
00403 i__3 = j;
00404 z__2.r = 1. - tau[i__3].r, z__2.i = 0. - tau[i__3].i;
00405 i__4 = j;
00406 z__1.r = e[i__4] * z__2.r, z__1.i = e[i__4] * z__2.i;
00407 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00408 i__2 = j - 1;
00409 for (jr = 1; jr <= i__2; ++jr) {
00410 i__3 = jp1 + jr;
00411 i__4 = j;
00412 z__3.r = -tau[i__4].r, z__3.i = -tau[i__4].i;
00413 i__5 = j;
00414 z__2.r = e[i__5] * z__3.r, z__2.i = e[i__5] * z__3.i;
00415 i__6 = jp1 + jr;
00416 z__1.r = z__2.r * vp[i__6].r - z__2.i * vp[i__6].i,
00417 z__1.i = z__2.r * vp[i__6].i + z__2.i * vp[
00418 i__6].r;
00419 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00420
00421 }
00422 }
00423
00424 i__2 = j;
00425 if (tau[i__2].r != 0. || tau[i__2].i != 0.) {
00426 i__2 = jp1 + j;
00427 vsave.r = vp[i__2].r, vsave.i = vp[i__2].i;
00428 i__2 = jp1 + j;
00429 vp[i__2].r = 1., vp[i__2].i = 0.;
00430 zhpmv_("U", &j, &c_b2, &work[1], &vp[jp1 + 1], &c__1, &
00431 c_b1, &work[lap + 1], &c__1);
00432 i__2 = j;
00433 z__2.r = tau[i__2].r * -.5, z__2.i = tau[i__2].i * -.5;
00434 zdotc_(&z__3, &j, &work[lap + 1], &c__1, &vp[jp1 + 1], &
00435 c__1);
00436 z__1.r = z__2.r * z__3.r - z__2.i * z__3.i, z__1.i =
00437 z__2.r * z__3.i + z__2.i * z__3.r;
00438 temp.r = z__1.r, temp.i = z__1.i;
00439 zaxpy_(&j, &temp, &vp[jp1 + 1], &c__1, &work[lap + 1], &
00440 c__1);
00441 i__2 = j;
00442 z__1.r = -tau[i__2].r, z__1.i = -tau[i__2].i;
00443 zhpr2_("U", &j, &z__1, &vp[jp1 + 1], &c__1, &work[lap + 1]
00444 , &c__1, &work[1]);
00445 i__2 = jp1 + j;
00446 vp[i__2].r = vsave.r, vp[i__2].i = vsave.i;
00447 }
00448 i__2 = jp1 + j + 1;
00449 i__3 = j + 1;
00450 work[i__2].r = d__[i__3], work[i__2].i = 0.;
00451
00452 }
00453 }
00454
00455 i__1 = lap;
00456 for (j = 1; j <= i__1; ++j) {
00457 i__2 = j;
00458 i__3 = j;
00459 i__4 = j;
00460 z__1.r = work[i__3].r - ap[i__4].r, z__1.i = work[i__3].i - ap[
00461 i__4].i;
00462 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00463
00464 }
00465 wnorm = zlanhp_("1", cuplo, n, &work[1], &rwork[1]);
00466
00467 } else if (*itype == 3) {
00468
00469
00470
00471 if (*n < 2) {
00472 return 0;
00473 }
00474 zlacpy_(" ", n, n, &u[u_offset], ldu, &work[1], n);
00475
00476 i__1 = *n;
00477 zupmtr_("R", cuplo, "C", n, n, &vp[1], &tau[1], &work[1], n, &work[
00478 i__1 * i__1 + 1], &iinfo);
00479 if (iinfo != 0) {
00480 result[1] = 10. / ulp;
00481 return 0;
00482 }
00483
00484 i__1 = *n;
00485 for (j = 1; j <= i__1; ++j) {
00486 i__2 = (*n + 1) * (j - 1) + 1;
00487 i__3 = (*n + 1) * (j - 1) + 1;
00488 z__1.r = work[i__3].r - 1., z__1.i = work[i__3].i - 0.;
00489 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00490
00491 }
00492
00493 wnorm = zlange_("1", n, n, &work[1], n, &rwork[1]);
00494 }
00495
00496 if (anorm > wnorm) {
00497 result[1] = wnorm / anorm / (*n * ulp);
00498 } else {
00499 if (anorm < 1.) {
00500
00501 d__1 = wnorm, d__2 = *n * anorm;
00502 result[1] = min(d__1,d__2) / anorm / (*n * ulp);
00503 } else {
00504
00505 d__1 = wnorm / anorm, d__2 = (doublereal) (*n);
00506 result[1] = min(d__1,d__2) / (*n * ulp);
00507 }
00508 }
00509
00510
00511
00512
00513
00514 if (*itype == 1) {
00515 zgemm_("N", "C", n, n, n, &c_b2, &u[u_offset], ldu, &u[u_offset], ldu,
00516 &c_b1, &work[1], n);
00517
00518 i__1 = *n;
00519 for (j = 1; j <= i__1; ++j) {
00520 i__2 = (*n + 1) * (j - 1) + 1;
00521 i__3 = (*n + 1) * (j - 1) + 1;
00522 z__1.r = work[i__3].r - 1., z__1.i = work[i__3].i - 0.;
00523 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00524
00525 }
00526
00527
00528 d__1 = zlange_("1", n, n, &work[1], n, &rwork[1]), d__2 = (
00529 doublereal) (*n);
00530 result[2] = min(d__1,d__2) / (*n * ulp);
00531 }
00532
00533 return 0;
00534
00535
00536
00537 }