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 = {0.,0.};
00019 static doublecomplex c_b2 = {1.,0.};
00020 static integer c__0 = 0;
00021 static integer c__2 = 2;
00022 static integer c__1 = 1;
00023
00024 int zgelsx_(integer *m, integer *n, integer *nrhs,
00025 doublecomplex *a, integer *lda, doublecomplex *b, integer *ldb,
00026 integer *jpvt, doublereal *rcond, integer *rank, doublecomplex *work,
00027 doublereal *rwork, integer *info)
00028 {
00029
00030 integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
00031 doublecomplex z__1;
00032
00033
00034 double z_abs(doublecomplex *);
00035 void d_cnjg(doublecomplex *, doublecomplex *);
00036
00037
00038 integer i__, j, k;
00039 doublecomplex c1, c2, s1, s2, t1, t2;
00040 integer mn;
00041 doublereal anrm, bnrm, smin, smax;
00042 integer iascl, ibscl, ismin, ismax;
00043 extern int ztrsm_(char *, char *, char *, char *,
00044 integer *, integer *, doublecomplex *, doublecomplex *, integer *,
00045 doublecomplex *, integer *),
00046 zlaic1_(integer *, integer *, doublecomplex *, doublereal *,
00047 doublecomplex *, doublecomplex *, doublereal *, doublecomplex *,
00048 doublecomplex *), dlabad_(doublereal *, doublereal *);
00049 extern doublereal dlamch_(char *);
00050 extern int zunm2r_(char *, char *, integer *, integer *,
00051 integer *, doublecomplex *, integer *, doublecomplex *,
00052 doublecomplex *, integer *, doublecomplex *, integer *), xerbla_(char *, integer *);
00053 extern doublereal zlange_(char *, integer *, integer *, doublecomplex *,
00054 integer *, doublereal *);
00055 doublereal bignum;
00056 extern int zlascl_(char *, integer *, integer *,
00057 doublereal *, doublereal *, integer *, integer *, doublecomplex *,
00058 integer *, integer *), zgeqpf_(integer *, integer *,
00059 doublecomplex *, integer *, integer *, doublecomplex *,
00060 doublecomplex *, doublereal *, integer *), zlaset_(char *,
00061 integer *, integer *, doublecomplex *, doublecomplex *,
00062 doublecomplex *, integer *);
00063 doublereal sminpr, smaxpr, smlnum;
00064 extern int zlatzm_(char *, integer *, integer *,
00065 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00066 doublecomplex *, integer *, doublecomplex *), ztzrqf_(
00067 integer *, integer *, doublecomplex *, integer *, doublecomplex *,
00068 integer *);
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
00182
00183
00184
00185
00186
00187
00188
00189 a_dim1 = *lda;
00190 a_offset = 1 + a_dim1;
00191 a -= a_offset;
00192 b_dim1 = *ldb;
00193 b_offset = 1 + b_dim1;
00194 b -= b_offset;
00195 --jpvt;
00196 --work;
00197 --rwork;
00198
00199
00200 mn = min(*m,*n);
00201 ismin = mn + 1;
00202 ismax = (mn << 1) + 1;
00203
00204
00205
00206 *info = 0;
00207 if (*m < 0) {
00208 *info = -1;
00209 } else if (*n < 0) {
00210 *info = -2;
00211 } else if (*nrhs < 0) {
00212 *info = -3;
00213 } else if (*lda < max(1,*m)) {
00214 *info = -5;
00215 } else {
00216
00217 i__1 = max(1,*m);
00218 if (*ldb < max(i__1,*n)) {
00219 *info = -7;
00220 }
00221 }
00222
00223 if (*info != 0) {
00224 i__1 = -(*info);
00225 xerbla_("ZGELSX", &i__1);
00226 return 0;
00227 }
00228
00229
00230
00231
00232 i__1 = min(*m,*n);
00233 if (min(i__1,*nrhs) == 0) {
00234 *rank = 0;
00235 return 0;
00236 }
00237
00238
00239
00240 smlnum = dlamch_("S") / dlamch_("P");
00241 bignum = 1. / smlnum;
00242 dlabad_(&smlnum, &bignum);
00243
00244
00245
00246 anrm = zlange_("M", m, n, &a[a_offset], lda, &rwork[1]);
00247 iascl = 0;
00248 if (anrm > 0. && anrm < smlnum) {
00249
00250
00251
00252 zlascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda,
00253 info);
00254 iascl = 1;
00255 } else if (anrm > bignum) {
00256
00257
00258
00259 zlascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda,
00260 info);
00261 iascl = 2;
00262 } else if (anrm == 0.) {
00263
00264
00265
00266 i__1 = max(*m,*n);
00267 zlaset_("F", &i__1, nrhs, &c_b1, &c_b1, &b[b_offset], ldb);
00268 *rank = 0;
00269 goto L100;
00270 }
00271
00272 bnrm = zlange_("M", m, nrhs, &b[b_offset], ldb, &rwork[1]);
00273 ibscl = 0;
00274 if (bnrm > 0. && bnrm < smlnum) {
00275
00276
00277
00278 zlascl_("G", &c__0, &c__0, &bnrm, &smlnum, m, nrhs, &b[b_offset], ldb,
00279 info);
00280 ibscl = 1;
00281 } else if (bnrm > bignum) {
00282
00283
00284
00285 zlascl_("G", &c__0, &c__0, &bnrm, &bignum, m, nrhs, &b[b_offset], ldb,
00286 info);
00287 ibscl = 2;
00288 }
00289
00290
00291
00292
00293 zgeqpf_(m, n, &a[a_offset], lda, &jpvt[1], &work[1], &work[mn + 1], &
00294 rwork[1], info);
00295
00296
00297
00298
00299
00300
00301 i__1 = ismin;
00302 work[i__1].r = 1., work[i__1].i = 0.;
00303 i__1 = ismax;
00304 work[i__1].r = 1., work[i__1].i = 0.;
00305 smax = z_abs(&a[a_dim1 + 1]);
00306 smin = smax;
00307 if (z_abs(&a[a_dim1 + 1]) == 0.) {
00308 *rank = 0;
00309 i__1 = max(*m,*n);
00310 zlaset_("F", &i__1, nrhs, &c_b1, &c_b1, &b[b_offset], ldb);
00311 goto L100;
00312 } else {
00313 *rank = 1;
00314 }
00315
00316 L10:
00317 if (*rank < mn) {
00318 i__ = *rank + 1;
00319 zlaic1_(&c__2, rank, &work[ismin], &smin, &a[i__ * a_dim1 + 1], &a[
00320 i__ + i__ * a_dim1], &sminpr, &s1, &c1);
00321 zlaic1_(&c__1, rank, &work[ismax], &smax, &a[i__ * a_dim1 + 1], &a[
00322 i__ + i__ * a_dim1], &smaxpr, &s2, &c2);
00323
00324 if (smaxpr * *rcond <= sminpr) {
00325 i__1 = *rank;
00326 for (i__ = 1; i__ <= i__1; ++i__) {
00327 i__2 = ismin + i__ - 1;
00328 i__3 = ismin + i__ - 1;
00329 z__1.r = s1.r * work[i__3].r - s1.i * work[i__3].i, z__1.i =
00330 s1.r * work[i__3].i + s1.i * work[i__3].r;
00331 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00332 i__2 = ismax + i__ - 1;
00333 i__3 = ismax + i__ - 1;
00334 z__1.r = s2.r * work[i__3].r - s2.i * work[i__3].i, z__1.i =
00335 s2.r * work[i__3].i + s2.i * work[i__3].r;
00336 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00337
00338 }
00339 i__1 = ismin + *rank;
00340 work[i__1].r = c1.r, work[i__1].i = c1.i;
00341 i__1 = ismax + *rank;
00342 work[i__1].r = c2.r, work[i__1].i = c2.i;
00343 smin = sminpr;
00344 smax = smaxpr;
00345 ++(*rank);
00346 goto L10;
00347 }
00348 }
00349
00350
00351
00352
00353
00354
00355
00356 if (*rank < *n) {
00357 ztzrqf_(rank, n, &a[a_offset], lda, &work[mn + 1], info);
00358 }
00359
00360
00361
00362
00363
00364 zunm2r_("Left", "Conjugate transpose", m, nrhs, &mn, &a[a_offset], lda, &
00365 work[1], &b[b_offset], ldb, &work[(mn << 1) + 1], info);
00366
00367
00368
00369
00370
00371 ztrsm_("Left", "Upper", "No transpose", "Non-unit", rank, nrhs, &c_b2, &a[
00372 a_offset], lda, &b[b_offset], ldb);
00373
00374 i__1 = *n;
00375 for (i__ = *rank + 1; i__ <= i__1; ++i__) {
00376 i__2 = *nrhs;
00377 for (j = 1; j <= i__2; ++j) {
00378 i__3 = i__ + j * b_dim1;
00379 b[i__3].r = 0., b[i__3].i = 0.;
00380
00381 }
00382
00383 }
00384
00385
00386
00387 if (*rank < *n) {
00388 i__1 = *rank;
00389 for (i__ = 1; i__ <= i__1; ++i__) {
00390 i__2 = *n - *rank + 1;
00391 d_cnjg(&z__1, &work[mn + i__]);
00392 zlatzm_("Left", &i__2, nrhs, &a[i__ + (*rank + 1) * a_dim1], lda,
00393 &z__1, &b[i__ + b_dim1], &b[*rank + 1 + b_dim1], ldb, &
00394 work[(mn << 1) + 1]);
00395
00396 }
00397 }
00398
00399
00400
00401
00402
00403 i__1 = *nrhs;
00404 for (j = 1; j <= i__1; ++j) {
00405 i__2 = *n;
00406 for (i__ = 1; i__ <= i__2; ++i__) {
00407 i__3 = (mn << 1) + i__;
00408 work[i__3].r = 1., work[i__3].i = 0.;
00409
00410 }
00411 i__2 = *n;
00412 for (i__ = 1; i__ <= i__2; ++i__) {
00413 i__3 = (mn << 1) + i__;
00414 if (work[i__3].r == 1. && work[i__3].i == 0.) {
00415 if (jpvt[i__] != i__) {
00416 k = i__;
00417 i__3 = k + j * b_dim1;
00418 t1.r = b[i__3].r, t1.i = b[i__3].i;
00419 i__3 = jpvt[k] + j * b_dim1;
00420 t2.r = b[i__3].r, t2.i = b[i__3].i;
00421 L70:
00422 i__3 = jpvt[k] + j * b_dim1;
00423 b[i__3].r = t1.r, b[i__3].i = t1.i;
00424 i__3 = (mn << 1) + k;
00425 work[i__3].r = 0., work[i__3].i = 0.;
00426 t1.r = t2.r, t1.i = t2.i;
00427 k = jpvt[k];
00428 i__3 = jpvt[k] + j * b_dim1;
00429 t2.r = b[i__3].r, t2.i = b[i__3].i;
00430 if (jpvt[k] != i__) {
00431 goto L70;
00432 }
00433 i__3 = i__ + j * b_dim1;
00434 b[i__3].r = t1.r, b[i__3].i = t1.i;
00435 i__3 = (mn << 1) + k;
00436 work[i__3].r = 0., work[i__3].i = 0.;
00437 }
00438 }
00439
00440 }
00441
00442 }
00443
00444
00445
00446 if (iascl == 1) {
00447 zlascl_("G", &c__0, &c__0, &anrm, &smlnum, n, nrhs, &b[b_offset], ldb,
00448 info);
00449 zlascl_("U", &c__0, &c__0, &smlnum, &anrm, rank, rank, &a[a_offset],
00450 lda, info);
00451 } else if (iascl == 2) {
00452 zlascl_("G", &c__0, &c__0, &anrm, &bignum, n, nrhs, &b[b_offset], ldb,
00453 info);
00454 zlascl_("U", &c__0, &c__0, &bignum, &anrm, rank, rank, &a[a_offset],
00455 lda, info);
00456 }
00457 if (ibscl == 1) {
00458 zlascl_("G", &c__0, &c__0, &smlnum, &bnrm, n, nrhs, &b[b_offset], ldb,
00459 info);
00460 } else if (ibscl == 2) {
00461 zlascl_("G", &c__0, &c__0, &bignum, &bnrm, n, nrhs, &b[b_offset], ldb,
00462 info);
00463 }
00464
00465 L100:
00466
00467 return 0;
00468
00469
00470
00471 }