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