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 = {1.f,0.f};
00019 static complex c_b2 = {0.f,0.f};
00020 static integer c__1 = 1;
00021
00022 int csptri_(char *uplo, integer *n, complex *ap, integer *
00023 ipiv, complex *work, integer *info)
00024 {
00025
00026 integer i__1, i__2, i__3;
00027 complex q__1, q__2, q__3;
00028
00029
00030 void c_div(complex *, complex *, complex *);
00031
00032
00033 complex d__;
00034 integer j, k;
00035 complex t, ak;
00036 integer kc, kp, kx, kpc, npp;
00037 complex akp1, temp, akkp1;
00038 extern logical lsame_(char *, char *);
00039 extern int ccopy_(integer *, complex *, integer *,
00040 complex *, integer *);
00041 extern VOID cdotu_(complex *, integer *, complex *, integer
00042 *, complex *, integer *);
00043 extern int cswap_(integer *, complex *, integer *,
00044 complex *, integer *);
00045 integer kstep;
00046 extern int cspmv_(char *, integer *, complex *, complex *
00047 , complex *, integer *, complex *, complex *, integer *);
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_("CSPTRI", &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 c_div(&q__1, &c_b1, &ap[kc + k - 1]);
00204 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00205
00206
00207
00208 if (k > 1) {
00209 i__1 = k - 1;
00210 ccopy_(&i__1, &ap[kc], &c__1, &work[1], &c__1);
00211 i__1 = k - 1;
00212 q__1.r = -1.f, q__1.i = -0.f;
00213 cspmv_(uplo, &i__1, &q__1, &ap[1], &work[1], &c__1, &c_b2, &
00214 ap[kc], &c__1);
00215 i__1 = kc + k - 1;
00216 i__2 = kc + k - 1;
00217 i__3 = k - 1;
00218 cdotu_(&q__2, &i__3, &work[1], &c__1, &ap[kc], &c__1);
00219 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00220 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00221 }
00222 kstep = 1;
00223 } else {
00224
00225
00226
00227
00228
00229 i__1 = kcnext + k - 1;
00230 t.r = ap[i__1].r, t.i = ap[i__1].i;
00231 c_div(&q__1, &ap[kc + k - 1], &t);
00232 ak.r = q__1.r, ak.i = q__1.i;
00233 c_div(&q__1, &ap[kcnext + k], &t);
00234 akp1.r = q__1.r, akp1.i = q__1.i;
00235 c_div(&q__1, &ap[kcnext + k - 1], &t);
00236 akkp1.r = q__1.r, akkp1.i = q__1.i;
00237 q__3.r = ak.r * akp1.r - ak.i * akp1.i, q__3.i = ak.r * akp1.i +
00238 ak.i * akp1.r;
00239 q__2.r = q__3.r - 1.f, q__2.i = q__3.i - 0.f;
00240 q__1.r = t.r * q__2.r - t.i * q__2.i, q__1.i = t.r * q__2.i + t.i
00241 * q__2.r;
00242 d__.r = q__1.r, d__.i = q__1.i;
00243 i__1 = kc + k - 1;
00244 c_div(&q__1, &akp1, &d__);
00245 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00246 i__1 = kcnext + k;
00247 c_div(&q__1, &ak, &d__);
00248 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00249 i__1 = kcnext + k - 1;
00250 q__2.r = -akkp1.r, q__2.i = -akkp1.i;
00251 c_div(&q__1, &q__2, &d__);
00252 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00253
00254
00255
00256 if (k > 1) {
00257 i__1 = k - 1;
00258 ccopy_(&i__1, &ap[kc], &c__1, &work[1], &c__1);
00259 i__1 = k - 1;
00260 q__1.r = -1.f, q__1.i = -0.f;
00261 cspmv_(uplo, &i__1, &q__1, &ap[1], &work[1], &c__1, &c_b2, &
00262 ap[kc], &c__1);
00263 i__1 = kc + k - 1;
00264 i__2 = kc + k - 1;
00265 i__3 = k - 1;
00266 cdotu_(&q__2, &i__3, &work[1], &c__1, &ap[kc], &c__1);
00267 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00268 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00269 i__1 = kcnext + k - 1;
00270 i__2 = kcnext + k - 1;
00271 i__3 = k - 1;
00272 cdotu_(&q__2, &i__3, &ap[kc], &c__1, &ap[kcnext], &c__1);
00273 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00274 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00275 i__1 = k - 1;
00276 ccopy_(&i__1, &ap[kcnext], &c__1, &work[1], &c__1);
00277 i__1 = k - 1;
00278 q__1.r = -1.f, q__1.i = -0.f;
00279 cspmv_(uplo, &i__1, &q__1, &ap[1], &work[1], &c__1, &c_b2, &
00280 ap[kcnext], &c__1);
00281 i__1 = kcnext + k;
00282 i__2 = kcnext + k;
00283 i__3 = k - 1;
00284 cdotu_(&q__2, &i__3, &work[1], &c__1, &ap[kcnext], &c__1);
00285 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00286 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00287 }
00288 kstep = 2;
00289 kcnext = kcnext + k + 1;
00290 }
00291
00292 kp = (i__1 = ipiv[k], abs(i__1));
00293 if (kp != k) {
00294
00295
00296
00297
00298 kpc = (kp - 1) * kp / 2 + 1;
00299 i__1 = kp - 1;
00300 cswap_(&i__1, &ap[kc], &c__1, &ap[kpc], &c__1);
00301 kx = kpc + kp - 1;
00302 i__1 = k - 1;
00303 for (j = kp + 1; j <= i__1; ++j) {
00304 kx = kx + j - 1;
00305 i__2 = kc + j - 1;
00306 temp.r = ap[i__2].r, temp.i = ap[i__2].i;
00307 i__2 = kc + j - 1;
00308 i__3 = kx;
00309 ap[i__2].r = ap[i__3].r, ap[i__2].i = ap[i__3].i;
00310 i__2 = kx;
00311 ap[i__2].r = temp.r, ap[i__2].i = temp.i;
00312
00313 }
00314 i__1 = kc + k - 1;
00315 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00316 i__1 = kc + k - 1;
00317 i__2 = kpc + kp - 1;
00318 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00319 i__1 = kpc + kp - 1;
00320 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00321 if (kstep == 2) {
00322 i__1 = kc + k + k - 1;
00323 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00324 i__1 = kc + k + k - 1;
00325 i__2 = kc + k + kp - 1;
00326 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00327 i__1 = kc + k + kp - 1;
00328 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00329 }
00330 }
00331
00332 k += kstep;
00333 kc = kcnext;
00334 goto L30;
00335 L50:
00336
00337 ;
00338 } else {
00339
00340
00341
00342
00343
00344
00345 npp = *n * (*n + 1) / 2;
00346 k = *n;
00347 kc = npp;
00348 L60:
00349
00350
00351
00352 if (k < 1) {
00353 goto L80;
00354 }
00355
00356 kcnext = kc - (*n - k + 2);
00357 if (ipiv[k] > 0) {
00358
00359
00360
00361
00362
00363 i__1 = kc;
00364 c_div(&q__1, &c_b1, &ap[kc]);
00365 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00366
00367
00368
00369 if (k < *n) {
00370 i__1 = *n - k;
00371 ccopy_(&i__1, &ap[kc + 1], &c__1, &work[1], &c__1);
00372 i__1 = *n - k;
00373 q__1.r = -1.f, q__1.i = -0.f;
00374 cspmv_(uplo, &i__1, &q__1, &ap[kc + *n - k + 1], &work[1], &
00375 c__1, &c_b2, &ap[kc + 1], &c__1);
00376 i__1 = kc;
00377 i__2 = kc;
00378 i__3 = *n - k;
00379 cdotu_(&q__2, &i__3, &work[1], &c__1, &ap[kc + 1], &c__1);
00380 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00381 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00382 }
00383 kstep = 1;
00384 } else {
00385
00386
00387
00388
00389
00390 i__1 = kcnext + 1;
00391 t.r = ap[i__1].r, t.i = ap[i__1].i;
00392 c_div(&q__1, &ap[kcnext], &t);
00393 ak.r = q__1.r, ak.i = q__1.i;
00394 c_div(&q__1, &ap[kc], &t);
00395 akp1.r = q__1.r, akp1.i = q__1.i;
00396 c_div(&q__1, &ap[kcnext + 1], &t);
00397 akkp1.r = q__1.r, akkp1.i = q__1.i;
00398 q__3.r = ak.r * akp1.r - ak.i * akp1.i, q__3.i = ak.r * akp1.i +
00399 ak.i * akp1.r;
00400 q__2.r = q__3.r - 1.f, q__2.i = q__3.i - 0.f;
00401 q__1.r = t.r * q__2.r - t.i * q__2.i, q__1.i = t.r * q__2.i + t.i
00402 * q__2.r;
00403 d__.r = q__1.r, d__.i = q__1.i;
00404 i__1 = kcnext;
00405 c_div(&q__1, &akp1, &d__);
00406 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00407 i__1 = kc;
00408 c_div(&q__1, &ak, &d__);
00409 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00410 i__1 = kcnext + 1;
00411 q__2.r = -akkp1.r, q__2.i = -akkp1.i;
00412 c_div(&q__1, &q__2, &d__);
00413 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00414
00415
00416
00417 if (k < *n) {
00418 i__1 = *n - k;
00419 ccopy_(&i__1, &ap[kc + 1], &c__1, &work[1], &c__1);
00420 i__1 = *n - k;
00421 q__1.r = -1.f, q__1.i = -0.f;
00422 cspmv_(uplo, &i__1, &q__1, &ap[kc + (*n - k + 1)], &work[1], &
00423 c__1, &c_b2, &ap[kc + 1], &c__1);
00424 i__1 = kc;
00425 i__2 = kc;
00426 i__3 = *n - k;
00427 cdotu_(&q__2, &i__3, &work[1], &c__1, &ap[kc + 1], &c__1);
00428 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__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 cdotu_(&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 cspmv_(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 cdotu_(&q__2, &i__3, &work[1], &c__1, &ap[kcnext + 2], &c__1);
00447 q__1.r = ap[i__2].r - q__2.r, q__1.i = ap[i__2].i - q__2.i;
00448 ap[i__1].r = q__1.r, ap[i__1].i = q__1.i;
00449 }
00450 kstep = 2;
00451 kcnext -= *n - k + 3;
00452 }
00453
00454 kp = (i__1 = ipiv[k], abs(i__1));
00455 if (kp != k) {
00456
00457
00458
00459
00460 kpc = npp - (*n - kp + 1) * (*n - kp + 2) / 2 + 1;
00461 if (kp < *n) {
00462 i__1 = *n - kp;
00463 cswap_(&i__1, &ap[kc + kp - k + 1], &c__1, &ap[kpc + 1], &
00464 c__1);
00465 }
00466 kx = kc + kp - k;
00467 i__1 = kp - 1;
00468 for (j = k + 1; j <= i__1; ++j) {
00469 kx = kx + *n - j + 1;
00470 i__2 = kc + j - k;
00471 temp.r = ap[i__2].r, temp.i = ap[i__2].i;
00472 i__2 = kc + j - k;
00473 i__3 = kx;
00474 ap[i__2].r = ap[i__3].r, ap[i__2].i = ap[i__3].i;
00475 i__2 = kx;
00476 ap[i__2].r = temp.r, ap[i__2].i = temp.i;
00477
00478 }
00479 i__1 = kc;
00480 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00481 i__1 = kc;
00482 i__2 = kpc;
00483 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00484 i__1 = kpc;
00485 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00486 if (kstep == 2) {
00487 i__1 = kc - *n + k - 1;
00488 temp.r = ap[i__1].r, temp.i = ap[i__1].i;
00489 i__1 = kc - *n + k - 1;
00490 i__2 = kc - *n + kp - 1;
00491 ap[i__1].r = ap[i__2].r, ap[i__1].i = ap[i__2].i;
00492 i__1 = kc - *n + kp - 1;
00493 ap[i__1].r = temp.r, ap[i__1].i = temp.i;
00494 }
00495 }
00496
00497 k -= kstep;
00498 kc = kcnext;
00499 goto L60;
00500 L80:
00501 ;
00502 }
00503
00504 return 0;
00505
00506
00507
00508 }