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