dgelsx.c
Go to the documentation of this file.
00001 /* dgelsx.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
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 /* Subroutine */ 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     /* System generated locals */
00030     integer a_dim1, a_offset, b_dim1, b_offset, i__1, i__2;
00031     doublereal d__1;
00032 
00033     /* Local variables */
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 /* Subroutine */ 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 /* Subroutine */ 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 /* Subroutine */ int dlatzm_(char *, integer *, integer *, 
00058             doublereal *, integer *, doublereal *, doublereal *, doublereal *, 
00059              integer *, doublereal *);
00060     doublereal sminpr, smaxpr, smlnum;
00061     extern /* Subroutine */ int dtzrqf_(integer *, integer *, doublereal *, 
00062             integer *, doublereal *, integer *);
00063 
00064 
00065 /*  -- LAPACK driver routine (version 3.2) -- */
00066 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00067 /*     November 2006 */
00068 
00069 /*     .. Scalar Arguments .. */
00070 /*     .. */
00071 /*     .. Array Arguments .. */
00072 /*     .. */
00073 
00074 /*  Purpose */
00075 /*  ======= */
00076 
00077 /*  This routine is deprecated and has been replaced by routine DGELSY. */
00078 
00079 /*  DGELSX computes the minimum-norm solution to a real linear least */
00080 /*  squares problem: */
00081 /*      minimize || A * X - B || */
00082 /*  using a complete orthogonal factorization of A.  A is an M-by-N */
00083 /*  matrix which may be rank-deficient. */
00084 
00085 /*  Several right hand side vectors b and solution vectors x can be */
00086 /*  handled in a single call; they are stored as the columns of the */
00087 /*  M-by-NRHS right hand side matrix B and the N-by-NRHS solution */
00088 /*  matrix X. */
00089 
00090 /*  The routine first computes a QR factorization with column pivoting: */
00091 /*      A * P = Q * [ R11 R12 ] */
00092 /*                  [  0  R22 ] */
00093 /*  with R11 defined as the largest leading submatrix whose estimated */
00094 /*  condition number is less than 1/RCOND.  The order of R11, RANK, */
00095 /*  is the effective rank of A. */
00096 
00097 /*  Then, R22 is considered to be negligible, and R12 is annihilated */
00098 /*  by orthogonal transformations from the right, arriving at the */
00099 /*  complete orthogonal factorization: */
00100 /*     A * P = Q * [ T11 0 ] * Z */
00101 /*                 [  0  0 ] */
00102 /*  The minimum-norm solution is then */
00103 /*     X = P * Z' [ inv(T11)*Q1'*B ] */
00104 /*                [        0       ] */
00105 /*  where Q1 consists of the first RANK columns of Q. */
00106 
00107 /*  Arguments */
00108 /*  ========= */
00109 
00110 /*  M       (input) INTEGER */
00111 /*          The number of rows of the matrix A.  M >= 0. */
00112 
00113 /*  N       (input) INTEGER */
00114 /*          The number of columns of the matrix A.  N >= 0. */
00115 
00116 /*  NRHS    (input) INTEGER */
00117 /*          The number of right hand sides, i.e., the number of */
00118 /*          columns of matrices B and X. NRHS >= 0. */
00119 
00120 /*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
00121 /*          On entry, the M-by-N matrix A. */
00122 /*          On exit, A has been overwritten by details of its */
00123 /*          complete orthogonal factorization. */
00124 
00125 /*  LDA     (input) INTEGER */
00126 /*          The leading dimension of the array A.  LDA >= max(1,M). */
00127 
00128 /*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */
00129 /*          On entry, the M-by-NRHS right hand side matrix B. */
00130 /*          On exit, the N-by-NRHS solution matrix X. */
00131 /*          If m >= n and RANK = n, the residual sum-of-squares for */
00132 /*          the solution in the i-th column is given by the sum of */
00133 /*          squares of elements N+1:M in that column. */
00134 
00135 /*  LDB     (input) INTEGER */
00136 /*          The leading dimension of the array B. LDB >= max(1,M,N). */
00137 
00138 /*  JPVT    (input/output) INTEGER array, dimension (N) */
00139 /*          On entry, if JPVT(i) .ne. 0, the i-th column of A is an */
00140 /*          initial column, otherwise it is a free column.  Before */
00141 /*          the QR factorization of A, all initial columns are */
00142 /*          permuted to the leading positions; only the remaining */
00143 /*          free columns are moved as a result of column pivoting */
00144 /*          during the factorization. */
00145 /*          On exit, if JPVT(i) = k, then the i-th column of A*P */
00146 /*          was the k-th column of A. */
00147 
00148 /*  RCOND   (input) DOUBLE PRECISION */
00149 /*          RCOND is used to determine the effective rank of A, which */
00150 /*          is defined as the order of the largest leading triangular */
00151 /*          submatrix R11 in the QR factorization with pivoting of A, */
00152 /*          whose estimated condition number < 1/RCOND. */
00153 
00154 /*  RANK    (output) INTEGER */
00155 /*          The effective rank of A, i.e., the order of the submatrix */
00156 /*          R11.  This is the same as the order of the submatrix T11 */
00157 /*          in the complete orthogonal factorization of A. */
00158 
00159 /*  WORK    (workspace) DOUBLE PRECISION array, dimension */
00160 /*                      (max( min(M,N)+3*N, 2*min(M,N)+NRHS )), */
00161 
00162 /*  INFO    (output) INTEGER */
00163 /*          = 0:  successful exit */
00164 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00165 
00166 /*  ===================================================================== */
00167 
00168 /*     .. Parameters .. */
00169 /*     .. */
00170 /*     .. Local Scalars .. */
00171 /*     .. */
00172 /*     .. External Functions .. */
00173 /*     .. */
00174 /*     .. External Subroutines .. */
00175 /*     .. */
00176 /*     .. Intrinsic Functions .. */
00177 /*     .. */
00178 /*     .. Executable Statements .. */
00179 
00180     /* Parameter adjustments */
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     /* Function Body */
00191     mn = min(*m,*n);
00192     ismin = mn + 1;
00193     ismax = (mn << 1) + 1;
00194 
00195 /*     Test the input arguments. */
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 /* if(complicated condition) */ {
00207 /* Computing MAX */
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 /*     Quick return if possible */
00221 
00222 /* Computing MIN */
00223     i__1 = min(*m,*n);
00224     if (min(i__1,*nrhs) == 0) {
00225         *rank = 0;
00226         return 0;
00227     }
00228 
00229 /*     Get machine parameters */
00230 
00231     smlnum = dlamch_("S") / dlamch_("P");
00232     bignum = 1. / smlnum;
00233     dlabad_(&smlnum, &bignum);
00234 
00235 /*     Scale A, B if max elements outside range [SMLNUM,BIGNUM] */
00236 
00237     anrm = dlange_("M", m, n, &a[a_offset], lda, &work[1]);
00238     iascl = 0;
00239     if (anrm > 0. && anrm < smlnum) {
00240 
00241 /*        Scale matrix norm up to SMLNUM */
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 /*        Scale matrix norm down to BIGNUM */
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 /*        Matrix all zero. Return zero solution. */
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 /*        Scale matrix norm up to SMLNUM */
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 /*        Scale matrix norm down to BIGNUM */
00275 
00276         dlascl_("G", &c__0, &c__0, &bnrm, &bignum, m, nrhs, &b[b_offset], ldb, 
00277                  info);
00278         ibscl = 2;
00279     }
00280 
00281 /*     Compute QR factorization with column pivoting of A: */
00282 /*        A * P = Q * R */
00283 
00284     dgeqpf_(m, n, &a[a_offset], lda, &jpvt[1], &work[1], &work[mn + 1], info);
00285 
00286 /*     workspace 3*N. Details of Householder rotations stored */
00287 /*     in WORK(1:MN). */
00288 
00289 /*     Determine RANK using incremental condition estimation */
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 /* L20: */
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 /*     Logically partition R = [ R11 R12 ] */
00329 /*                             [  0  R22 ] */
00330 /*     where R11 = R(1:RANK,1:RANK) */
00331 
00332 /*     [R11,R12] = [ T11, 0 ] * Y */
00333 
00334     if (*rank < *n) {
00335         dtzrqf_(rank, n, &a[a_offset], lda, &work[mn + 1], info);
00336     }
00337 
00338 /*     Details of Householder rotations stored in WORK(MN+1:2*MN) */
00339 
00340 /*     B(1:M,1:NRHS) := Q' * B(1:M,1:NRHS) */
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 /*     workspace NRHS */
00346 
00347 /*     B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS) */
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 /* L30: */
00358         }
00359 /* L40: */
00360     }
00361 
00362 /*     B(1:N,1:NRHS) := Y' * B(1:N,1:NRHS) */
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 /* L50: */
00372         }
00373     }
00374 
00375 /*     workspace NRHS */
00376 
00377 /*     B(1:N,1:NRHS) := P * B(1:N,1:NRHS) */
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 /* L60: */
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 /* L80: */
00407         }
00408 /* L90: */
00409     }
00410 
00411 /*     Undo scaling */
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 /*     End of DGELSX */
00437 
00438 } /* dgelsx_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:44