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
00021 int zpstf2_(char *uplo, integer *n, doublecomplex *a,
00022 integer *lda, integer *piv, integer *rank, doublereal *tol,
00023 doublereal *work, integer *info)
00024 {
00025
00026 integer a_dim1, a_offset, i__1, i__2, i__3;
00027 doublereal d__1;
00028 doublecomplex z__1, z__2;
00029
00030
00031 void d_cnjg(doublecomplex *, doublecomplex *);
00032 double sqrt(doublereal);
00033
00034
00035 integer i__, j, maxlocval;
00036 doublereal ajj;
00037 integer pvt;
00038 extern logical lsame_(char *, char *);
00039 doublereal dtemp;
00040 integer itemp;
00041 extern int zgemv_(char *, integer *, integer *,
00042 doublecomplex *, doublecomplex *, integer *, doublecomplex *,
00043 integer *, doublecomplex *, doublecomplex *, integer *);
00044 doublereal dstop;
00045 logical upper;
00046 doublecomplex ztemp;
00047 extern int zswap_(integer *, doublecomplex *, integer *,
00048 doublecomplex *, integer *);
00049 extern doublereal dlamch_(char *);
00050 extern logical disnan_(doublereal *);
00051 extern int xerbla_(char *, integer *), zdscal_(
00052 integer *, doublereal *, doublecomplex *, integer *), zlacgv_(
00053 integer *, doublecomplex *, integer *);
00054 extern integer dmaxloc_(doublereal *, integer *);
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
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 --work;
00148 --piv;
00149 a_dim1 = *lda;
00150 a_offset = 1 + a_dim1;
00151 a -= a_offset;
00152
00153
00154 *info = 0;
00155 upper = lsame_(uplo, "U");
00156 if (! upper && ! lsame_(uplo, "L")) {
00157 *info = -1;
00158 } else if (*n < 0) {
00159 *info = -2;
00160 } else if (*lda < max(1,*n)) {
00161 *info = -4;
00162 }
00163 if (*info != 0) {
00164 i__1 = -(*info);
00165 xerbla_("ZPSTF2", &i__1);
00166 return 0;
00167 }
00168
00169
00170
00171 if (*n == 0) {
00172 return 0;
00173 }
00174
00175
00176
00177 i__1 = *n;
00178 for (i__ = 1; i__ <= i__1; ++i__) {
00179 piv[i__] = i__;
00180
00181 }
00182
00183
00184
00185 i__1 = *n;
00186 for (i__ = 1; i__ <= i__1; ++i__) {
00187 i__2 = i__ + i__ * a_dim1;
00188 work[i__] = a[i__2].r;
00189
00190 }
00191 pvt = dmaxloc_(&work[1], n);
00192 i__1 = pvt + pvt * a_dim1;
00193 ajj = a[i__1].r;
00194 if (ajj == 0. || disnan_(&ajj)) {
00195 *rank = 0;
00196 *info = 1;
00197 goto L200;
00198 }
00199
00200
00201
00202 if (*tol < 0.) {
00203 dstop = *n * dlamch_("Epsilon") * ajj;
00204 } else {
00205 dstop = *tol;
00206 }
00207
00208
00209
00210 i__1 = *n;
00211 for (i__ = 1; i__ <= i__1; ++i__) {
00212 work[i__] = 0.;
00213
00214 }
00215
00216 if (upper) {
00217
00218
00219
00220 i__1 = *n;
00221 for (j = 1; j <= i__1; ++j) {
00222
00223
00224
00225
00226
00227 i__2 = *n;
00228 for (i__ = j; i__ <= i__2; ++i__) {
00229
00230 if (j > 1) {
00231 d_cnjg(&z__2, &a[j - 1 + i__ * a_dim1]);
00232 i__3 = j - 1 + i__ * a_dim1;
00233 z__1.r = z__2.r * a[i__3].r - z__2.i * a[i__3].i, z__1.i =
00234 z__2.r * a[i__3].i + z__2.i * a[i__3].r;
00235 work[i__] += z__1.r;
00236 }
00237 i__3 = i__ + i__ * a_dim1;
00238 work[*n + i__] = a[i__3].r - work[i__];
00239
00240
00241 }
00242
00243 if (j > 1) {
00244 maxlocval = (*n << 1) - (*n + j) + 1;
00245 itemp = dmaxloc_(&work[*n + j], &maxlocval);
00246 pvt = itemp + j - 1;
00247 ajj = work[*n + pvt];
00248 if (ajj <= dstop || disnan_(&ajj)) {
00249 i__2 = j + j * a_dim1;
00250 a[i__2].r = ajj, a[i__2].i = 0.;
00251 goto L190;
00252 }
00253 }
00254
00255 if (j != pvt) {
00256
00257
00258
00259 i__2 = pvt + pvt * a_dim1;
00260 i__3 = j + j * a_dim1;
00261 a[i__2].r = a[i__3].r, a[i__2].i = a[i__3].i;
00262 i__2 = j - 1;
00263 zswap_(&i__2, &a[j * a_dim1 + 1], &c__1, &a[pvt * a_dim1 + 1],
00264 &c__1);
00265 if (pvt < *n) {
00266 i__2 = *n - pvt;
00267 zswap_(&i__2, &a[j + (pvt + 1) * a_dim1], lda, &a[pvt + (
00268 pvt + 1) * a_dim1], lda);
00269 }
00270 i__2 = pvt - 1;
00271 for (i__ = j + 1; i__ <= i__2; ++i__) {
00272 d_cnjg(&z__1, &a[j + i__ * a_dim1]);
00273 ztemp.r = z__1.r, ztemp.i = z__1.i;
00274 i__3 = j + i__ * a_dim1;
00275 d_cnjg(&z__1, &a[i__ + pvt * a_dim1]);
00276 a[i__3].r = z__1.r, a[i__3].i = z__1.i;
00277 i__3 = i__ + pvt * a_dim1;
00278 a[i__3].r = ztemp.r, a[i__3].i = ztemp.i;
00279
00280 }
00281 i__2 = j + pvt * a_dim1;
00282 d_cnjg(&z__1, &a[j + pvt * a_dim1]);
00283 a[i__2].r = z__1.r, a[i__2].i = z__1.i;
00284
00285
00286
00287 dtemp = work[j];
00288 work[j] = work[pvt];
00289 work[pvt] = dtemp;
00290 itemp = piv[pvt];
00291 piv[pvt] = piv[j];
00292 piv[j] = itemp;
00293 }
00294
00295 ajj = sqrt(ajj);
00296 i__2 = j + j * a_dim1;
00297 a[i__2].r = ajj, a[i__2].i = 0.;
00298
00299
00300
00301 if (j < *n) {
00302 i__2 = j - 1;
00303 zlacgv_(&i__2, &a[j * a_dim1 + 1], &c__1);
00304 i__2 = j - 1;
00305 i__3 = *n - j;
00306 z__1.r = -1., z__1.i = -0.;
00307 zgemv_("Trans", &i__2, &i__3, &z__1, &a[(j + 1) * a_dim1 + 1],
00308 lda, &a[j * a_dim1 + 1], &c__1, &c_b1, &a[j + (j + 1)
00309 * a_dim1], lda);
00310 i__2 = j - 1;
00311 zlacgv_(&i__2, &a[j * a_dim1 + 1], &c__1);
00312 i__2 = *n - j;
00313 d__1 = 1. / ajj;
00314 zdscal_(&i__2, &d__1, &a[j + (j + 1) * a_dim1], lda);
00315 }
00316
00317
00318 }
00319
00320 } else {
00321
00322
00323
00324 i__1 = *n;
00325 for (j = 1; j <= i__1; ++j) {
00326
00327
00328
00329
00330
00331 i__2 = *n;
00332 for (i__ = j; i__ <= i__2; ++i__) {
00333
00334 if (j > 1) {
00335 d_cnjg(&z__2, &a[i__ + (j - 1) * a_dim1]);
00336 i__3 = i__ + (j - 1) * a_dim1;
00337 z__1.r = z__2.r * a[i__3].r - z__2.i * a[i__3].i, z__1.i =
00338 z__2.r * a[i__3].i + z__2.i * a[i__3].r;
00339 work[i__] += z__1.r;
00340 }
00341 i__3 = i__ + i__ * a_dim1;
00342 work[*n + i__] = a[i__3].r - work[i__];
00343
00344
00345 }
00346
00347 if (j > 1) {
00348 maxlocval = (*n << 1) - (*n + j) + 1;
00349 itemp = dmaxloc_(&work[*n + j], &maxlocval);
00350 pvt = itemp + j - 1;
00351 ajj = work[*n + pvt];
00352 if (ajj <= dstop || disnan_(&ajj)) {
00353 i__2 = j + j * a_dim1;
00354 a[i__2].r = ajj, a[i__2].i = 0.;
00355 goto L190;
00356 }
00357 }
00358
00359 if (j != pvt) {
00360
00361
00362
00363 i__2 = pvt + pvt * a_dim1;
00364 i__3 = j + j * a_dim1;
00365 a[i__2].r = a[i__3].r, a[i__2].i = a[i__3].i;
00366 i__2 = j - 1;
00367 zswap_(&i__2, &a[j + a_dim1], lda, &a[pvt + a_dim1], lda);
00368 if (pvt < *n) {
00369 i__2 = *n - pvt;
00370 zswap_(&i__2, &a[pvt + 1 + j * a_dim1], &c__1, &a[pvt + 1
00371 + pvt * a_dim1], &c__1);
00372 }
00373 i__2 = pvt - 1;
00374 for (i__ = j + 1; i__ <= i__2; ++i__) {
00375 d_cnjg(&z__1, &a[i__ + j * a_dim1]);
00376 ztemp.r = z__1.r, ztemp.i = z__1.i;
00377 i__3 = i__ + j * a_dim1;
00378 d_cnjg(&z__1, &a[pvt + i__ * a_dim1]);
00379 a[i__3].r = z__1.r, a[i__3].i = z__1.i;
00380 i__3 = pvt + i__ * a_dim1;
00381 a[i__3].r = ztemp.r, a[i__3].i = ztemp.i;
00382
00383 }
00384 i__2 = pvt + j * a_dim1;
00385 d_cnjg(&z__1, &a[pvt + j * a_dim1]);
00386 a[i__2].r = z__1.r, a[i__2].i = z__1.i;
00387
00388
00389
00390 dtemp = work[j];
00391 work[j] = work[pvt];
00392 work[pvt] = dtemp;
00393 itemp = piv[pvt];
00394 piv[pvt] = piv[j];
00395 piv[j] = itemp;
00396 }
00397
00398 ajj = sqrt(ajj);
00399 i__2 = j + j * a_dim1;
00400 a[i__2].r = ajj, a[i__2].i = 0.;
00401
00402
00403
00404 if (j < *n) {
00405 i__2 = j - 1;
00406 zlacgv_(&i__2, &a[j + a_dim1], lda);
00407 i__2 = *n - j;
00408 i__3 = j - 1;
00409 z__1.r = -1., z__1.i = -0.;
00410 zgemv_("No Trans", &i__2, &i__3, &z__1, &a[j + 1 + a_dim1],
00411 lda, &a[j + a_dim1], lda, &c_b1, &a[j + 1 + j *
00412 a_dim1], &c__1);
00413 i__2 = j - 1;
00414 zlacgv_(&i__2, &a[j + a_dim1], lda);
00415 i__2 = *n - j;
00416 d__1 = 1. / ajj;
00417 zdscal_(&i__2, &d__1, &a[j + 1 + j * a_dim1], &c__1);
00418 }
00419
00420
00421 }
00422
00423 }
00424
00425
00426
00427 *rank = *n;
00428
00429 goto L200;
00430 L190:
00431
00432
00433
00434
00435 *rank = j - 1;
00436 *info = 1;
00437
00438 L200:
00439 return 0;
00440
00441
00442
00443 }