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 integer c__1 = 1;
00020 static integer c_n1 = -1;
00021 static doublereal c_b29 = -1.;
00022 static doublereal c_b30 = 1.;
00023
00024 int zpstrf_(char *uplo, integer *n, doublecomplex *a,
00025 integer *lda, integer *piv, integer *rank, doublereal *tol,
00026 doublereal *work, integer *info)
00027 {
00028
00029 integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5;
00030 doublereal d__1;
00031 doublecomplex z__1, z__2;
00032
00033
00034 void d_cnjg(doublecomplex *, doublecomplex *);
00035 double sqrt(doublereal);
00036
00037
00038 integer i__, j, k, maxlocval, jb, nb;
00039 doublereal ajj;
00040 integer pvt;
00041 extern logical lsame_(char *, char *);
00042 doublereal dtemp;
00043 integer itemp;
00044 extern int zherk_(char *, char *, integer *, integer *,
00045 doublereal *, doublecomplex *, integer *, doublereal *,
00046 doublecomplex *, integer *), zgemv_(char *,
00047 integer *, integer *, doublecomplex *, doublecomplex *, integer *,
00048 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00049 integer *);
00050 doublereal dstop;
00051 logical upper;
00052 doublecomplex ztemp;
00053 extern int zswap_(integer *, doublecomplex *, integer *,
00054 doublecomplex *, integer *);
00055 extern doublereal dlamch_(char *);
00056 extern int zpstf2_(char *, integer *, doublecomplex *,
00057 integer *, integer *, integer *, doublereal *, doublereal *,
00058 integer *);
00059 extern logical disnan_(doublereal *);
00060 extern int xerbla_(char *, integer *);
00061 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00062 integer *, integer *);
00063 extern int zdscal_(integer *, doublereal *,
00064 doublecomplex *, integer *), zlacgv_(integer *, doublecomplex *,
00065 integer *);
00066 extern integer dmaxloc_(doublereal *, integer *);
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
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 --work;
00163 --piv;
00164 a_dim1 = *lda;
00165 a_offset = 1 + a_dim1;
00166 a -= a_offset;
00167
00168
00169 *info = 0;
00170 upper = lsame_(uplo, "U");
00171 if (! upper && ! lsame_(uplo, "L")) {
00172 *info = -1;
00173 } else if (*n < 0) {
00174 *info = -2;
00175 } else if (*lda < max(1,*n)) {
00176 *info = -4;
00177 }
00178 if (*info != 0) {
00179 i__1 = -(*info);
00180 xerbla_("ZPSTRF", &i__1);
00181 return 0;
00182 }
00183
00184
00185
00186 if (*n == 0) {
00187 return 0;
00188 }
00189
00190
00191
00192 nb = ilaenv_(&c__1, "ZPOTRF", uplo, n, &c_n1, &c_n1, &c_n1);
00193 if (nb <= 1 || nb >= *n) {
00194
00195
00196
00197 zpstf2_(uplo, n, &a[a_dim1 + 1], lda, &piv[1], rank, tol, &work[1],
00198 info);
00199 goto L230;
00200
00201 } else {
00202
00203
00204
00205 i__1 = *n;
00206 for (i__ = 1; i__ <= i__1; ++i__) {
00207 piv[i__] = i__;
00208
00209 }
00210
00211
00212
00213 i__1 = *n;
00214 for (i__ = 1; i__ <= i__1; ++i__) {
00215 i__2 = i__ + i__ * a_dim1;
00216 work[i__] = a[i__2].r;
00217
00218 }
00219 pvt = dmaxloc_(&work[1], n);
00220 i__1 = pvt + pvt * a_dim1;
00221 ajj = a[i__1].r;
00222 if (ajj == 0. || disnan_(&ajj)) {
00223 *rank = 0;
00224 *info = 1;
00225 goto L230;
00226 }
00227
00228
00229
00230 if (*tol < 0.) {
00231 dstop = *n * dlamch_("Epsilon") * ajj;
00232 } else {
00233 dstop = *tol;
00234 }
00235
00236
00237 if (upper) {
00238
00239
00240
00241 i__1 = *n;
00242 i__2 = nb;
00243 for (k = 1; i__2 < 0 ? k >= i__1 : k <= i__1; k += i__2) {
00244
00245
00246
00247
00248 i__3 = nb, i__4 = *n - k + 1;
00249 jb = min(i__3,i__4);
00250
00251
00252
00253
00254 i__3 = *n;
00255 for (i__ = k; i__ <= i__3; ++i__) {
00256 work[i__] = 0.;
00257
00258 }
00259
00260 i__3 = k + jb - 1;
00261 for (j = k; j <= i__3; ++j) {
00262
00263
00264
00265
00266
00267 i__4 = *n;
00268 for (i__ = j; i__ <= i__4; ++i__) {
00269
00270 if (j > k) {
00271 d_cnjg(&z__2, &a[j - 1 + i__ * a_dim1]);
00272 i__5 = j - 1 + i__ * a_dim1;
00273 z__1.r = z__2.r * a[i__5].r - z__2.i * a[i__5].i,
00274 z__1.i = z__2.r * a[i__5].i + z__2.i * a[
00275 i__5].r;
00276 work[i__] += z__1.r;
00277 }
00278 i__5 = i__ + i__ * a_dim1;
00279 work[*n + i__] = a[i__5].r - work[i__];
00280
00281
00282 }
00283
00284 if (j > 1) {
00285 maxlocval = (*n << 1) - (*n + j) + 1;
00286 itemp = dmaxloc_(&work[*n + j], &maxlocval);
00287 pvt = itemp + j - 1;
00288 ajj = work[*n + pvt];
00289 if (ajj <= dstop || disnan_(&ajj)) {
00290 i__4 = j + j * a_dim1;
00291 a[i__4].r = ajj, a[i__4].i = 0.;
00292 goto L220;
00293 }
00294 }
00295
00296 if (j != pvt) {
00297
00298
00299
00300 i__4 = pvt + pvt * a_dim1;
00301 i__5 = j + j * a_dim1;
00302 a[i__4].r = a[i__5].r, a[i__4].i = a[i__5].i;
00303 i__4 = j - 1;
00304 zswap_(&i__4, &a[j * a_dim1 + 1], &c__1, &a[pvt *
00305 a_dim1 + 1], &c__1);
00306 if (pvt < *n) {
00307 i__4 = *n - pvt;
00308 zswap_(&i__4, &a[j + (pvt + 1) * a_dim1], lda, &a[
00309 pvt + (pvt + 1) * a_dim1], lda);
00310 }
00311 i__4 = pvt - 1;
00312 for (i__ = j + 1; i__ <= i__4; ++i__) {
00313 d_cnjg(&z__1, &a[j + i__ * a_dim1]);
00314 ztemp.r = z__1.r, ztemp.i = z__1.i;
00315 i__5 = j + i__ * a_dim1;
00316 d_cnjg(&z__1, &a[i__ + pvt * a_dim1]);
00317 a[i__5].r = z__1.r, a[i__5].i = z__1.i;
00318 i__5 = i__ + pvt * a_dim1;
00319 a[i__5].r = ztemp.r, a[i__5].i = ztemp.i;
00320
00321 }
00322 i__4 = j + pvt * a_dim1;
00323 d_cnjg(&z__1, &a[j + pvt * a_dim1]);
00324 a[i__4].r = z__1.r, a[i__4].i = z__1.i;
00325
00326
00327
00328 dtemp = work[j];
00329 work[j] = work[pvt];
00330 work[pvt] = dtemp;
00331 itemp = piv[pvt];
00332 piv[pvt] = piv[j];
00333 piv[j] = itemp;
00334 }
00335
00336 ajj = sqrt(ajj);
00337 i__4 = j + j * a_dim1;
00338 a[i__4].r = ajj, a[i__4].i = 0.;
00339
00340
00341
00342 if (j < *n) {
00343 i__4 = j - 1;
00344 zlacgv_(&i__4, &a[j * a_dim1 + 1], &c__1);
00345 i__4 = j - k;
00346 i__5 = *n - j;
00347 z__1.r = -1., z__1.i = -0.;
00348 zgemv_("Trans", &i__4, &i__5, &z__1, &a[k + (j + 1) *
00349 a_dim1], lda, &a[k + j * a_dim1], &c__1, &
00350 c_b1, &a[j + (j + 1) * a_dim1], lda);
00351 i__4 = j - 1;
00352 zlacgv_(&i__4, &a[j * a_dim1 + 1], &c__1);
00353 i__4 = *n - j;
00354 d__1 = 1. / ajj;
00355 zdscal_(&i__4, &d__1, &a[j + (j + 1) * a_dim1], lda);
00356 }
00357
00358
00359 }
00360
00361
00362
00363 if (k + jb <= *n) {
00364 i__3 = *n - j + 1;
00365 zherk_("Upper", "Conj Trans", &i__3, &jb, &c_b29, &a[k +
00366 j * a_dim1], lda, &c_b30, &a[j + j * a_dim1], lda);
00367 }
00368
00369
00370 }
00371
00372 } else {
00373
00374
00375
00376 i__2 = *n;
00377 i__1 = nb;
00378 for (k = 1; i__1 < 0 ? k >= i__2 : k <= i__2; k += i__1) {
00379
00380
00381
00382
00383 i__3 = nb, i__4 = *n - k + 1;
00384 jb = min(i__3,i__4);
00385
00386
00387
00388
00389 i__3 = *n;
00390 for (i__ = k; i__ <= i__3; ++i__) {
00391 work[i__] = 0.;
00392
00393 }
00394
00395 i__3 = k + jb - 1;
00396 for (j = k; j <= i__3; ++j) {
00397
00398
00399
00400
00401
00402 i__4 = *n;
00403 for (i__ = j; i__ <= i__4; ++i__) {
00404
00405 if (j > k) {
00406 d_cnjg(&z__2, &a[i__ + (j - 1) * a_dim1]);
00407 i__5 = i__ + (j - 1) * a_dim1;
00408 z__1.r = z__2.r * a[i__5].r - z__2.i * a[i__5].i,
00409 z__1.i = z__2.r * a[i__5].i + z__2.i * a[
00410 i__5].r;
00411 work[i__] += z__1.r;
00412 }
00413 i__5 = i__ + i__ * a_dim1;
00414 work[*n + i__] = a[i__5].r - work[i__];
00415
00416
00417 }
00418
00419 if (j > 1) {
00420 maxlocval = (*n << 1) - (*n + j) + 1;
00421 itemp = dmaxloc_(&work[*n + j], &maxlocval);
00422 pvt = itemp + j - 1;
00423 ajj = work[*n + pvt];
00424 if (ajj <= dstop || disnan_(&ajj)) {
00425 i__4 = j + j * a_dim1;
00426 a[i__4].r = ajj, a[i__4].i = 0.;
00427 goto L220;
00428 }
00429 }
00430
00431 if (j != pvt) {
00432
00433
00434
00435 i__4 = pvt + pvt * a_dim1;
00436 i__5 = j + j * a_dim1;
00437 a[i__4].r = a[i__5].r, a[i__4].i = a[i__5].i;
00438 i__4 = j - 1;
00439 zswap_(&i__4, &a[j + a_dim1], lda, &a[pvt + a_dim1],
00440 lda);
00441 if (pvt < *n) {
00442 i__4 = *n - pvt;
00443 zswap_(&i__4, &a[pvt + 1 + j * a_dim1], &c__1, &a[
00444 pvt + 1 + pvt * a_dim1], &c__1);
00445 }
00446 i__4 = pvt - 1;
00447 for (i__ = j + 1; i__ <= i__4; ++i__) {
00448 d_cnjg(&z__1, &a[i__ + j * a_dim1]);
00449 ztemp.r = z__1.r, ztemp.i = z__1.i;
00450 i__5 = i__ + j * a_dim1;
00451 d_cnjg(&z__1, &a[pvt + i__ * a_dim1]);
00452 a[i__5].r = z__1.r, a[i__5].i = z__1.i;
00453 i__5 = pvt + i__ * a_dim1;
00454 a[i__5].r = ztemp.r, a[i__5].i = ztemp.i;
00455
00456 }
00457 i__4 = pvt + j * a_dim1;
00458 d_cnjg(&z__1, &a[pvt + j * a_dim1]);
00459 a[i__4].r = z__1.r, a[i__4].i = z__1.i;
00460
00461
00462
00463
00464 dtemp = work[j];
00465 work[j] = work[pvt];
00466 work[pvt] = dtemp;
00467 itemp = piv[pvt];
00468 piv[pvt] = piv[j];
00469 piv[j] = itemp;
00470 }
00471
00472 ajj = sqrt(ajj);
00473 i__4 = j + j * a_dim1;
00474 a[i__4].r = ajj, a[i__4].i = 0.;
00475
00476
00477
00478 if (j < *n) {
00479 i__4 = j - 1;
00480 zlacgv_(&i__4, &a[j + a_dim1], lda);
00481 i__4 = *n - j;
00482 i__5 = j - k;
00483 z__1.r = -1., z__1.i = -0.;
00484 zgemv_("No Trans", &i__4, &i__5, &z__1, &a[j + 1 + k *
00485 a_dim1], lda, &a[j + k * a_dim1], lda, &c_b1,
00486 &a[j + 1 + j * a_dim1], &c__1);
00487 i__4 = j - 1;
00488 zlacgv_(&i__4, &a[j + a_dim1], lda);
00489 i__4 = *n - j;
00490 d__1 = 1. / ajj;
00491 zdscal_(&i__4, &d__1, &a[j + 1 + j * a_dim1], &c__1);
00492 }
00493
00494
00495 }
00496
00497
00498
00499 if (k + jb <= *n) {
00500 i__3 = *n - j + 1;
00501 zherk_("Lower", "No Trans", &i__3, &jb, &c_b29, &a[j + k *
00502 a_dim1], lda, &c_b30, &a[j + j * a_dim1], lda);
00503 }
00504
00505
00506 }
00507
00508 }
00509 }
00510
00511
00512
00513 *rank = *n;
00514
00515 goto L230;
00516 L220:
00517
00518
00519
00520
00521 *rank = j - 1;
00522 *info = 1;
00523
00524 L230:
00525 return 0;
00526
00527
00528
00529 }