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