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__0 = 0;
00019 static doublereal c_b13 = 0.;
00020 static integer c__2 = 2;
00021 static integer c__1 = 1;
00022 static doublereal c_b36 = 1.;
00023
00024 int dgelsx_(integer *m, integer *n, integer *nrhs,
00025 doublereal *a, integer *lda, doublereal *b, integer *ldb, integer *
00026 jpvt, doublereal *rcond, integer *rank, doublereal *work, integer *
00027 info)
00028 {
00029
00030 integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2;
00031 doublereal d__1;
00032
00033
00034 integer i__, j, k;
00035 doublereal c1, c2, s1, s2, t1, t2;
00036 integer mn;
00037 doublereal anrm, bnrm, smin, smax;
00038 integer iascl, ibscl, ismin, ismax;
00039 extern int dtrsm_(char *, char *, char *, char *,
00040 integer *, integer *, doublereal *, doublereal *, integer *,
00041 doublereal *, integer *), dlaic1_(
00042 integer *, integer *, doublereal *, doublereal *, doublereal *,
00043 doublereal *, doublereal *, doublereal *, doublereal *), dorm2r_(
00044 char *, char *, integer *, integer *, integer *, doublereal *,
00045 integer *, doublereal *, doublereal *, integer *, doublereal *,
00046 integer *), dlabad_(doublereal *, doublereal *);
00047 extern doublereal dlamch_(char *), dlange_(char *, integer *,
00048 integer *, doublereal *, integer *, doublereal *);
00049 extern int dlascl_(char *, integer *, integer *,
00050 doublereal *, doublereal *, integer *, integer *, doublereal *,
00051 integer *, integer *), dgeqpf_(integer *, integer *,
00052 doublereal *, integer *, integer *, doublereal *, doublereal *,
00053 integer *), dlaset_(char *, integer *, integer *, doublereal *,
00054 doublereal *, doublereal *, integer *), xerbla_(char *,
00055 integer *);
00056 doublereal bignum;
00057 extern int dlatzm_(char *, integer *, integer *,
00058 doublereal *, integer *, doublereal *, doublereal *, doublereal *,
00059 integer *, doublereal *);
00060 doublereal sminpr, smaxpr, smlnum;
00061 extern int dtzrqf_(integer *, integer *, doublereal *,
00062 integer *, doublereal *, 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
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 a_dim1 = *lda;
00182 a_offset = 1 + a_dim1;
00183 a -= a_offset;
00184 b_dim1 = *ldb;
00185 b_offset = 1 + b_dim1;
00186 b -= b_offset;
00187 --jpvt;
00188 --work;
00189
00190
00191 mn = min(*m,*n);
00192 ismin = mn + 1;
00193 ismax = (mn << 1) + 1;
00194
00195
00196
00197 *info = 0;
00198 if (*m < 0) {
00199 *info = -1;
00200 } else if (*n < 0) {
00201 *info = -2;
00202 } else if (*nrhs < 0) {
00203 *info = -3;
00204 } else if (*lda < max(1,*m)) {
00205 *info = -5;
00206 } else {
00207
00208 i__1 = max(1,*m);
00209 if (*ldb < max(i__1,*n)) {
00210 *info = -7;
00211 }
00212 }
00213
00214 if (*info != 0) {
00215 i__1 = -(*info);
00216 xerbla_("DGELSX", &i__1);
00217 return 0;
00218 }
00219
00220
00221
00222
00223 i__1 = min(*m,*n);
00224 if (min(i__1,*nrhs) == 0) {
00225 *rank = 0;
00226 return 0;
00227 }
00228
00229
00230
00231 smlnum = dlamch_("S") / dlamch_("P");
00232 bignum = 1. / smlnum;
00233 dlabad_(&smlnum, &bignum);
00234
00235
00236
00237 anrm = dlange_("M", m, n, &a[a_offset], lda, &work[1]);
00238 iascl = 0;
00239 if (anrm > 0. && anrm < smlnum) {
00240
00241
00242
00243 dlascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda,
00244 info);
00245 iascl = 1;
00246 } else if (anrm > bignum) {
00247
00248
00249
00250 dlascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda,
00251 info);
00252 iascl = 2;
00253 } else if (anrm == 0.) {
00254
00255
00256
00257 i__1 = max(*m,*n);
00258 dlaset_("F", &i__1, nrhs, &c_b13, &c_b13, &b[b_offset], ldb);
00259 *rank = 0;
00260 goto L100;
00261 }
00262
00263 bnrm = dlange_("M", m, nrhs, &b[b_offset], ldb, &work[1]);
00264 ibscl = 0;
00265 if (bnrm > 0. && bnrm < smlnum) {
00266
00267
00268
00269 dlascl_("G", &c__0, &c__0, &bnrm, &smlnum, m, nrhs, &b[b_offset], ldb,
00270 info);
00271 ibscl = 1;
00272 } else if (bnrm > bignum) {
00273
00274
00275
00276 dlascl_("G", &c__0, &c__0, &bnrm, &bignum, m, nrhs, &b[b_offset], ldb,
00277 info);
00278 ibscl = 2;
00279 }
00280
00281
00282
00283
00284 dgeqpf_(m, n, &a[a_offset], lda, &jpvt[1], &work[1], &work[mn + 1], info);
00285
00286
00287
00288
00289
00290
00291 work[ismin] = 1.;
00292 work[ismax] = 1.;
00293 smax = (d__1 = a[a_dim1 + 1], abs(d__1));
00294 smin = smax;
00295 if ((d__1 = a[a_dim1 + 1], abs(d__1)) == 0.) {
00296 *rank = 0;
00297 i__1 = max(*m,*n);
00298 dlaset_("F", &i__1, nrhs, &c_b13, &c_b13, &b[b_offset], ldb);
00299 goto L100;
00300 } else {
00301 *rank = 1;
00302 }
00303
00304 L10:
00305 if (*rank < mn) {
00306 i__ = *rank + 1;
00307 dlaic1_(&c__2, rank, &work[ismin], &smin, &a[i__ * a_dim1 + 1], &a[
00308 i__ + i__ * a_dim1], &sminpr, &s1, &c1);
00309 dlaic1_(&c__1, rank, &work[ismax], &smax, &a[i__ * a_dim1 + 1], &a[
00310 i__ + i__ * a_dim1], &smaxpr, &s2, &c2);
00311
00312 if (smaxpr * *rcond <= sminpr) {
00313 i__1 = *rank;
00314 for (i__ = 1; i__ <= i__1; ++i__) {
00315 work[ismin + i__ - 1] = s1 * work[ismin + i__ - 1];
00316 work[ismax + i__ - 1] = s2 * work[ismax + i__ - 1];
00317
00318 }
00319 work[ismin + *rank] = c1;
00320 work[ismax + *rank] = c2;
00321 smin = sminpr;
00322 smax = smaxpr;
00323 ++(*rank);
00324 goto L10;
00325 }
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 if (*rank < *n) {
00335 dtzrqf_(rank, n, &a[a_offset], lda, &work[mn + 1], info);
00336 }
00337
00338
00339
00340
00341
00342 dorm2r_("Left", "Transpose", m, nrhs, &mn, &a[a_offset], lda, &work[1], &
00343 b[b_offset], ldb, &work[(mn << 1) + 1], info);
00344
00345
00346
00347
00348
00349 dtrsm_("Left", "Upper", "No transpose", "Non-unit", rank, nrhs, &c_b36, &
00350 a[a_offset], lda, &b[b_offset], ldb);
00351
00352 i__1 = *n;
00353 for (i__ = *rank + 1; i__ <= i__1; ++i__) {
00354 i__2 = *nrhs;
00355 for (j = 1; j <= i__2; ++j) {
00356 b[i__ + j * b_dim1] = 0.;
00357
00358 }
00359
00360 }
00361
00362
00363
00364 if (*rank < *n) {
00365 i__1 = *rank;
00366 for (i__ = 1; i__ <= i__1; ++i__) {
00367 i__2 = *n - *rank + 1;
00368 dlatzm_("Left", &i__2, nrhs, &a[i__ + (*rank + 1) * a_dim1], lda,
00369 &work[mn + i__], &b[i__ + b_dim1], &b[*rank + 1 + b_dim1],
00370 ldb, &work[(mn << 1) + 1]);
00371
00372 }
00373 }
00374
00375
00376
00377
00378
00379 i__1 = *nrhs;
00380 for (j = 1; j <= i__1; ++j) {
00381 i__2 = *n;
00382 for (i__ = 1; i__ <= i__2; ++i__) {
00383 work[(mn << 1) + i__] = 1.;
00384
00385 }
00386 i__2 = *n;
00387 for (i__ = 1; i__ <= i__2; ++i__) {
00388 if (work[(mn << 1) + i__] == 1.) {
00389 if (jpvt[i__] != i__) {
00390 k = i__;
00391 t1 = b[k + j * b_dim1];
00392 t2 = b[jpvt[k] + j * b_dim1];
00393 L70:
00394 b[jpvt[k] + j * b_dim1] = t1;
00395 work[(mn << 1) + k] = 0.;
00396 t1 = t2;
00397 k = jpvt[k];
00398 t2 = b[jpvt[k] + j * b_dim1];
00399 if (jpvt[k] != i__) {
00400 goto L70;
00401 }
00402 b[i__ + j * b_dim1] = t1;
00403 work[(mn << 1) + k] = 0.;
00404 }
00405 }
00406
00407 }
00408
00409 }
00410
00411
00412
00413 if (iascl == 1) {
00414 dlascl_("G", &c__0, &c__0, &anrm, &smlnum, n, nrhs, &b[b_offset], ldb,
00415 info);
00416 dlascl_("U", &c__0, &c__0, &smlnum, &anrm, rank, rank, &a[a_offset],
00417 lda, info);
00418 } else if (iascl == 2) {
00419 dlascl_("G", &c__0, &c__0, &anrm, &bignum, n, nrhs, &b[b_offset], ldb,
00420 info);
00421 dlascl_("U", &c__0, &c__0, &bignum, &anrm, rank, rank, &a[a_offset],
00422 lda, info);
00423 }
00424 if (ibscl == 1) {
00425 dlascl_("G", &c__0, &c__0, &smlnum, &bnrm, n, nrhs, &b[b_offset], ldb,
00426 info);
00427 } else if (ibscl == 2) {
00428 dlascl_("G", &c__0, &c__0, &bignum, &bnrm, n, nrhs, &b[b_offset], ldb,
00429 info);
00430 }
00431
00432 L100:
00433
00434 return 0;
00435
00436
00437
00438 }