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 = {1.,0.};
00019 static doublecomplex c_b2 = {0.,0.};
00020 static integer c__1 = 1;
00021
00022 int zsptri_(char *uplo, integer *n, doublecomplex *ap,
00023 integer *ipiv, doublecomplex *work, integer *info)
00024 {
00025
00026 integer i__1, i__2, i__3;
00027 doublecomplex z__1, z__2, z__3;
00028
00029
00030 void z_div(doublecomplex *, doublecomplex *, doublecomplex *);
00031
00032
00033 doublecomplex d__;
00034 integer j, k;
00035 doublecomplex t, ak;
00036 integer kc, kp, kx, kpc, npp;
00037 doublecomplex akp1, temp, akkp1;
00038 extern logical lsame_(char *, char *);
00039 integer kstep;
00040 logical upper;
00041 extern int zcopy_(integer *, doublecomplex *, integer *,
00042 doublecomplex *, integer *);
00043 extern VOID zdotu_(doublecomplex *, integer *,
00044 doublecomplex *, integer *, doublecomplex *, integer *);
00045 extern int zswap_(integer *, doublecomplex *, integer *,
00046 doublecomplex *, integer *), zspmv_(char *, integer *,
00047 doublecomplex *, doublecomplex *, doublecomplex *, integer *,
00048 doublecomplex *, doublecomplex *, integer *), xerbla_(
00049 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_("ZSPTRI", &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. && ap[i__1].i == 0.)) {
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. && ap[i__2].i == 0.)) {
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 z_div(&z__1, &c_b1, &ap[kc + k - 1]);
00204 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00205
00206
00207
00208 if (k > 1) {
00209 i__1 = k - 1;
00210 zcopy_(&i__1, &ap[kc], &c__1, &work[1], &c__1);
00211 i__1 = k - 1;
00212 z__1.r = -1., z__1.i = -0.;
00213 zspmv_(uplo, &i__1, &z__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 zdotu_(&z__2, &i__3, &work[1], &c__1, &ap[kc], &c__1);
00219 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00220 ap[i__1].r = z__1.r, ap[i__1].i = z__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 z_div(&z__1, &ap[kc + k - 1], &t);
00232 ak.r = z__1.r, ak.i = z__1.i;
00233 z_div(&z__1, &ap[kcnext + k], &t);
00234 akp1.r = z__1.r, akp1.i = z__1.i;
00235 z_div(&z__1, &ap[kcnext + k - 1], &t);
00236 akkp1.r = z__1.r, akkp1.i = z__1.i;
00237 z__3.r = ak.r * akp1.r - ak.i * akp1.i, z__3.i = ak.r * akp1.i +
00238 ak.i * akp1.r;
00239 z__2.r = z__3.r - 1., z__2.i = z__3.i - 0.;
00240 z__1.r = t.r * z__2.r - t.i * z__2.i, z__1.i = t.r * z__2.i + t.i
00241 * z__2.r;
00242 d__.r = z__1.r, d__.i = z__1.i;
00243 i__1 = kc + k - 1;
00244 z_div(&z__1, &akp1, &d__);
00245 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00246 i__1 = kcnext + k;
00247 z_div(&z__1, &ak, &d__);
00248 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00249 i__1 = kcnext + k - 1;
00250 z__2.r = -akkp1.r, z__2.i = -akkp1.i;
00251 z_div(&z__1, &z__2, &d__);
00252 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00253
00254
00255
00256 if (k > 1) {
00257 i__1 = k - 1;
00258 zcopy_(&i__1, &ap[kc], &c__1, &work[1], &c__1);
00259 i__1 = k - 1;
00260 z__1.r = -1., z__1.i = -0.;
00261 zspmv_(uplo, &i__1, &z__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 zdotu_(&z__2, &i__3, &work[1], &c__1, &ap[kc], &c__1);
00267 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00268 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00269 i__1 = kcnext + k - 1;
00270 i__2 = kcnext + k - 1;
00271 i__3 = k - 1;
00272 zdotu_(&z__2, &i__3, &ap[kc], &c__1, &ap[kcnext], &c__1);
00273 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00274 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00275 i__1 = k - 1;
00276 zcopy_(&i__1, &ap[kcnext], &c__1, &work[1], &c__1);
00277 i__1 = k - 1;
00278 z__1.r = -1., z__1.i = -0.;
00279 zspmv_(uplo, &i__1, &z__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 zdotu_(&z__2, &i__3, &work[1], &c__1, &ap[kcnext], &c__1);
00285 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00286 ap[i__1].r = z__1.r, ap[i__1].i = z__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 zswap_(&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 z_div(&z__1, &c_b1, &ap[kc]);
00365 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00366
00367
00368
00369 if (k < *n) {
00370 i__1 = *n - k;
00371 zcopy_(&i__1, &ap[kc + 1], &c__1, &work[1], &c__1);
00372 i__1 = *n - k;
00373 z__1.r = -1., z__1.i = -0.;
00374 zspmv_(uplo, &i__1, &z__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 zdotu_(&z__2, &i__3, &work[1], &c__1, &ap[kc + 1], &c__1);
00380 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00381 ap[i__1].r = z__1.r, ap[i__1].i = z__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 z_div(&z__1, &ap[kcnext], &t);
00393 ak.r = z__1.r, ak.i = z__1.i;
00394 z_div(&z__1, &ap[kc], &t);
00395 akp1.r = z__1.r, akp1.i = z__1.i;
00396 z_div(&z__1, &ap[kcnext + 1], &t);
00397 akkp1.r = z__1.r, akkp1.i = z__1.i;
00398 z__3.r = ak.r * akp1.r - ak.i * akp1.i, z__3.i = ak.r * akp1.i +
00399 ak.i * akp1.r;
00400 z__2.r = z__3.r - 1., z__2.i = z__3.i - 0.;
00401 z__1.r = t.r * z__2.r - t.i * z__2.i, z__1.i = t.r * z__2.i + t.i
00402 * z__2.r;
00403 d__.r = z__1.r, d__.i = z__1.i;
00404 i__1 = kcnext;
00405 z_div(&z__1, &akp1, &d__);
00406 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00407 i__1 = kc;
00408 z_div(&z__1, &ak, &d__);
00409 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00410 i__1 = kcnext + 1;
00411 z__2.r = -akkp1.r, z__2.i = -akkp1.i;
00412 z_div(&z__1, &z__2, &d__);
00413 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00414
00415
00416
00417 if (k < *n) {
00418 i__1 = *n - k;
00419 zcopy_(&i__1, &ap[kc + 1], &c__1, &work[1], &c__1);
00420 i__1 = *n - k;
00421 z__1.r = -1., z__1.i = -0.;
00422 zspmv_(uplo, &i__1, &z__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 zdotu_(&z__2, &i__3, &work[1], &c__1, &ap[kc + 1], &c__1);
00428 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00429 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00430 i__1 = kcnext + 1;
00431 i__2 = kcnext + 1;
00432 i__3 = *n - k;
00433 zdotu_(&z__2, &i__3, &ap[kc + 1], &c__1, &ap[kcnext + 2], &
00434 c__1);
00435 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00436 ap[i__1].r = z__1.r, ap[i__1].i = z__1.i;
00437 i__1 = *n - k;
00438 zcopy_(&i__1, &ap[kcnext + 2], &c__1, &work[1], &c__1);
00439 i__1 = *n - k;
00440 z__1.r = -1., z__1.i = -0.;
00441 zspmv_(uplo, &i__1, &z__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 zdotu_(&z__2, &i__3, &work[1], &c__1, &ap[kcnext + 2], &c__1);
00447 z__1.r = ap[i__2].r - z__2.r, z__1.i = ap[i__2].i - z__2.i;
00448 ap[i__1].r = z__1.r, ap[i__1].i = z__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 zswap_(&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 }