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_b2 = {0.f,0.f};
00019 static integer c__1 = 1;
00020
00021 int chptri_(char *uplo, integer *n, complex *ap, integer *
00022 ipiv, complex *work, integer *info)
00023 {
00024
00025 integer i__1, i__2, i__3;
00026 real r__1;
00027 complex q__1, q__2;
00028
00029
00030 double c_abs(complex *);
00031 void r_cnjg(complex *, complex *);
00032
00033
00034 real d__;
00035 integer j, k;
00036 real t, ak;
00037 integer kc, kp, kx, kpc, npp;
00038 real akp1;
00039 complex temp, akkp1;
00040 extern VOID cdotc_(complex *, integer *, complex *, integer
00041 *, complex *, integer *);
00042 extern logical lsame_(char *, char *);
00043 extern int ccopy_(integer *, complex *, integer *,
00044 complex *, integer *), chpmv_(char *, integer *, complex *,
00045 complex *, complex *, integer *, complex *, complex *, integer *), cswap_(integer *, complex *, integer *, complex *,
00046 integer *);
00047 integer kstep;
00048 logical upper;
00049 extern int xerbla_(char *, integer *);
00050 integer kcnext;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
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 --work;
00123 --ipiv;
00124 --ap;
00125
00126
00127 *info = 0;
00128 upper = lsame_(uplo, "U");
00129 if (! upper && ! lsame_(uplo, "L")) {
00130 *info = -1;
00131 } else if (*n < 0) {
00132 *info = -2;
00133 }
00134 if (*info != 0) {
00135 i__1 = -(*info);
00136 xerbla_("CHPTRI", &i__1);
00137 return 0;
00138 }
00139
00140
00141
00142 if (*n == 0) {
00143 return 0;
00144 }
00145
00146
00147
00148 if (upper) {
00149
00150
00151
00152 kp = *n * (*n + 1) / 2;
00153 for (*info = *n; *info >= 1; --(*info)) {
00154 i__1 = kp;
00155 if (ipiv[*info] > 0 && (ap[i__1].r == 0.f && ap[i__1].i == 0.f)) {
00156 return 0;
00157 }
00158 kp -= *info;
00159
00160 }
00161 } else {
00162
00163
00164
00165 kp = 1;
00166 i__1 = *n;
00167 for (*info = 1; *info <= i__1; ++(*info)) {
00168 i__2 = kp;
00169 if (ipiv[*info] > 0 && (ap[i__2].r == 0.f && ap[i__2].i == 0.f)) {
00170 return 0;
00171 }
00172 kp = kp + *n - *info + 1;
00173
00174 }
00175 }
00176 *info = 0;
00177
00178 if (upper) {
00179
00180
00181
00182
00183
00184
00185 k = 1;
00186 kc = 1;
00187 L30:
00188
00189
00190
00191 if (k > *n) {
00192 goto L50;
00193 }
00194
00195 kcnext = kc + k;
00196 if (ipiv[k] > 0) {
00197
00198
00199
00200
00201
00202 i__1 = kc + k - 1;
00203 i__2 = kc + k - 1;
00204 r__1 = 1.f / ap[i__2].r;
00205 ap[i__1].r = r__1, ap[i__1].i = 0.f;
00206
00207
00208
00209 if (k > 1) {
00210 i__1 = k - 1;
00211 ccopy_(&i__1, &ap[kc], &c__1, &work[1], &c__1);
00212 i__1 = k - 1;
00213 q__1.r = -1.f, q__1.i = -0.f;
00214 chpmv_(uplo, &i__1, &q__1, &ap[1], &work[1], &c__1, &c_b2, &
00215 ap[kc], &c__1);
00216 i__1 = kc + k - 1;
00217 i__2 = kc + k - 1;
00218 i__3 = k - 1;
00219 cdotc_(&q__2, &i__3, &work[1], &c__1, &ap[kc], &c__1);
00220 r__1 = q__2.r;
00221 q__1.r = ap[i__2].r - r__1, q__1.i = ap[i__2].i;
00222 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00223 }
00224 kstep = 1;
00225 } else {
00226
00227
00228
00229
00230
00231 t = c_abs(&ap[kcnext + k - 1]);
00232 i__1 = kc + k - 1;
00233 ak = ap[i__1].r / t;
00234 i__1 = kcnext + k;
00235 akp1 = ap[i__1].r / t;
00236 i__1 = kcnext + k - 1;
00237 q__1.r = ap[i__1].r / t, q__1.i = ap[i__1].i / t;
00238 akkp1.r = q__1.r, akkp1.i = q__1.i;
00239 d__ = t * (ak * akp1 - 1.f);
00240 i__1 = kc + k - 1;
00241 r__1 = akp1 / d__;
00242 ap[i__1].r = r__1, ap[i__1].i = 0.f;
00243 i__1 = kcnext + k;
00244 r__1 = ak / d__;
00245 ap[i__1].r = r__1, ap[i__1].i = 0.f;
00246 i__1 = kcnext + k - 1;
00247 q__2.r = -akkp1.r, q__2.i = -akkp1.i;
00248 q__1.r = q__2.r / d__, q__1.i = q__2.i / d__;
00249 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00250
00251
00252
00253 if (k > 1) {
00254 i__1 = k - 1;
00255 ccopy_(&i__1, &ap[kc], &c__1, &work[1], &c__1);
00256 i__1 = k - 1;
00257 q__1.r = -1.f, q__1.i = -0.f;
00258 chpmv_(uplo, &i__1, &q__1, &ap[1], &work[1], &c__1, &c_b2, &
00259 ap[kc], &c__1);
00260 i__1 = kc + k - 1;
00261 i__2 = kc + k - 1;
00262 i__3 = k - 1;
00263 cdotc_(&q__2, &i__3, &work[1], &c__1, &ap[kc], &c__1);
00264 r__1 = q__2.r;
00265 q__1.r = ap[i__2].r - r__1, q__1.i = ap[i__2].i;
00266 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00267 i__1 = kcnext + k - 1;
00268 i__2 = kcnext + k - 1;
00269 i__3 = k - 1;
00270 cdotc_(&q__2, &i__3, &ap[kc], &c__1, &ap[kcnext], &c__1);
00271 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00272 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00273 i__1 = k - 1;
00274 ccopy_(&i__1, &ap[kcnext], &c__1, &work[1], &c__1);
00275 i__1 = k - 1;
00276 q__1.r = -1.f, q__1.i = -0.f;
00277 chpmv_(uplo, &i__1, &q__1, &ap[1], &work[1], &c__1, &c_b2, &
00278 ap[kcnext], &c__1);
00279 i__1 = kcnext + k;
00280 i__2 = kcnext + k;
00281 i__3 = k - 1;
00282 cdotc_(&q__2, &i__3, &work[1], &c__1, &ap[kcnext], &c__1);
00283 r__1 = q__2.r;
00284 q__1.r = ap[i__2].r - r__1, q__1.i = ap[i__2].i;
00285 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00286 }
00287 kstep = 2;
00288 kcnext = kcnext + k + 1;
00289 }
00290
00291 kp = (i__1 = ipiv[k], abs(i__1));
00292 if (kp != k) {
00293
00294
00295
00296
00297 kpc = (kp - 1) * kp / 2 + 1;
00298 i__1 = kp - 1;
00299 cswap_(&i__1, &ap[kc], &c__1, &ap[kpc], &c__1);
00300 kx = kpc + kp - 1;
00301 i__1 = k - 1;
00302 for (j = kp + 1; j <= i__1; ++j) {
00303 kx = kx + j - 1;
00304 r_cnjg(&q__1, &ap[kc + j - 1]);
00305 temp.r = q__1.r, temp.i = q__1.i;
00306 i__2 = kc + j - 1;
00307 r_cnjg(&q__1, &ap[kx]);
00308 ap[i__2].r = q__1.r, ap[i__2].i = q__1.i;
00309 i__2 = kx;
00310 ap[i__2].r = temp.r, ap[i__2].i = temp.i;
00311
00312 }
00313 i__1 = kc + kp - 1;
00314 r_cnjg(&q__1, &ap[kc + kp - 1]);
00315 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00316 i__1 = kc + k - 1;
00317 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00318 i__1 = kc + k - 1;
00319 i__2 = kpc + kp - 1;
00320 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00321 i__1 = kpc + kp - 1;
00322 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00323 if (kstep == 2) {
00324 i__1 = kc + k + k - 1;
00325 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00326 i__1 = kc + k + k - 1;
00327 i__2 = kc + k + kp - 1;
00328 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00329 i__1 = kc + k + kp - 1;
00330 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00331 }
00332 }
00333
00334 k += kstep;
00335 kc = kcnext;
00336 goto L30;
00337 L50:
00338
00339 ;
00340 } else {
00341
00342
00343
00344
00345
00346
00347 npp = *n * (*n + 1) / 2;
00348 k = *n;
00349 kc = npp;
00350 L60:
00351
00352
00353
00354 if (k < 1) {
00355 goto L80;
00356 }
00357
00358 kcnext = kc - (*n - k + 2);
00359 if (ipiv[k] > 0) {
00360
00361
00362
00363
00364
00365 i__1 = kc;
00366 i__2 = kc;
00367 r__1 = 1.f / ap[i__2].r;
00368 ap[i__1].r = r__1, ap[i__1].i = 0.f;
00369
00370
00371
00372 if (k < *n) {
00373 i__1 = *n - k;
00374 ccopy_(&i__1, &ap[kc + 1], &c__1, &work[1], &c__1);
00375 i__1 = *n - k;
00376 q__1.r = -1.f, q__1.i = -0.f;
00377 chpmv_(uplo, &i__1, &q__1, &ap[kc + *n - k + 1], &work[1], &
00378 c__1, &c_b2, &ap[kc + 1], &c__1);
00379 i__1 = kc;
00380 i__2 = kc;
00381 i__3 = *n - k;
00382 cdotc_(&q__2, &i__3, &work[1], &c__1, &ap[kc + 1], &c__1);
00383 r__1 = q__2.r;
00384 q__1.r = ap[i__2].r - r__1, q__1.i = ap[i__2].i;
00385 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00386 }
00387 kstep = 1;
00388 } else {
00389
00390
00391
00392
00393
00394 t = c_abs(&ap[kcnext + 1]);
00395 i__1 = kcnext;
00396 ak = ap[i__1].r / t;
00397 i__1 = kc;
00398 akp1 = ap[i__1].r / t;
00399 i__1 = kcnext + 1;
00400 q__1.r = ap[i__1].r / t, q__1.i = ap[i__1].i / t;
00401 akkp1.r = q__1.r, akkp1.i = q__1.i;
00402 d__ = t * (ak * akp1 - 1.f);
00403 i__1 = kcnext;
00404 r__1 = akp1 / d__;
00405 ap[i__1].r = r__1, ap[i__1].i = 0.f;
00406 i__1 = kc;
00407 r__1 = ak / d__;
00408 ap[i__1].r = r__1, ap[i__1].i = 0.f;
00409 i__1 = kcnext + 1;
00410 q__2.r = -akkp1.r, q__2.i = -akkp1.i;
00411 q__1.r = q__2.r / d__, q__1.i = q__2.i / d__;
00412 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00413
00414
00415
00416 if (k < *n) {
00417 i__1 = *n - k;
00418 ccopy_(&i__1, &ap[kc + 1], &c__1, &work[1], &c__1);
00419 i__1 = *n - k;
00420 q__1.r = -1.f, q__1.i = -0.f;
00421 chpmv_(uplo, &i__1, &q__1, &ap[kc + (*n - k + 1)], &work[1], &
00422 c__1, &c_b2, &ap[kc + 1], &c__1);
00423 i__1 = kc;
00424 i__2 = kc;
00425 i__3 = *n - k;
00426 cdotc_(&q__2, &i__3, &work[1], &c__1, &ap[kc + 1], &c__1);
00427 r__1 = q__2.r;
00428 q__1.r = ap[i__2].r - r__1, q__1.i = ap[i__2].i;
00429 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00430 i__1 = kcnext + 1;
00431 i__2 = kcnext + 1;
00432 i__3 = *n - k;
00433 cdotc_(&q__2, &i__3, &ap[kc + 1], &c__1, &ap[kcnext + 2], &
00434 c__1);
00435 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00436 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00437 i__1 = *n - k;
00438 ccopy_(&i__1, &ap[kcnext + 2], &c__1, &work[1], &c__1);
00439 i__1 = *n - k;
00440 q__1.r = -1.f, q__1.i = -0.f;
00441 chpmv_(uplo, &i__1, &q__1, &ap[kc + (*n - k + 1)], &work[1], &
00442 c__1, &c_b2, &ap[kcnext + 2], &c__1);
00443 i__1 = kcnext;
00444 i__2 = kcnext;
00445 i__3 = *n - k;
00446 cdotc_(&q__2, &i__3, &work[1], &c__1, &ap[kcnext + 2], &c__1);
00447 r__1 = q__2.r;
00448 q__1.r = ap[i__2].r - r__1, q__1.i = ap[i__2].i;
00449 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00450 }
00451 kstep = 2;
00452 kcnext -= *n - k + 3;
00453 }
00454
00455 kp = (i__1 = ipiv[k], abs(i__1));
00456 if (kp != k) {
00457
00458
00459
00460
00461 kpc = npp - (*n - kp + 1) * (*n - kp + 2) / 2 + 1;
00462 if (kp < *n) {
00463 i__1 = *n - kp;
00464 cswap_(&i__1, &ap[kc + kp - k + 1], &c__1, &ap[kpc + 1], &
00465 c__1);
00466 }
00467 kx = kc + kp - k;
00468 i__1 = kp - 1;
00469 for (j = k + 1; j <= i__1; ++j) {
00470 kx = kx + *n - j + 1;
00471 r_cnjg(&q__1, &ap[kc + j - k]);
00472 temp.r = q__1.r, temp.i = q__1.i;
00473 i__2 = kc + j - k;
00474 r_cnjg(&q__1, &ap[kx]);
00475 ap[i__2].r = q__1.r, ap[i__2].i = q__1.i;
00476 i__2 = kx;
00477 ap[i__2].r = temp.r, ap[i__2].i = temp.i;
00478
00479 }
00480 i__1 = kc + kp - k;
00481 r_cnjg(&q__1, &ap[kc + kp - k]);
00482 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00483 i__1 = kc;
00484 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00485 i__1 = kc;
00486 i__2 = kpc;
00487 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00488 i__1 = kpc;
00489 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00490 if (kstep == 2) {
00491 i__1 = kc - *n + k - 1;
00492 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00493 i__1 = kc - *n + k - 1;
00494 i__2 = kc - *n + kp - 1;
00495 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00496 i__1 = kc - *n + kp - 1;
00497 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00498 }
00499 }
00500
00501 k -= kstep;
00502 kc = kcnext;
00503 goto L60;
00504 L80:
00505 ;
00506 }
00507
00508 return 0;
00509
00510
00511
00512 }