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