dgeqpf.c
Go to the documentation of this file.
00001 /* dgeqpf.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__1 = 1;
00019 
00020 /* Subroutine */ int dgeqpf_(integer *m, integer *n, doublereal *a, integer *
00021         lda, integer *jpvt, doublereal *tau, doublereal *work, integer *info)
00022 {
00023     /* System generated locals */
00024     integer a_dim1, a_offset, i__1, i__2, i__3;
00025     doublereal d__1, d__2;
00026 
00027     /* Builtin functions */
00028     double sqrt(doublereal);
00029 
00030     /* Local variables */
00031     integer i__, j, ma, mn;
00032     doublereal aii;
00033     integer pvt;
00034     doublereal temp;
00035     extern doublereal dnrm2_(integer *, doublereal *, integer *);
00036     doublereal temp2, tol3z;
00037     extern /* Subroutine */ int dlarf_(char *, integer *, integer *, 
00038             doublereal *, integer *, doublereal *, doublereal *, integer *, 
00039             doublereal *);
00040     integer itemp;
00041     extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *, 
00042             doublereal *, integer *), dgeqr2_(integer *, integer *, 
00043             doublereal *, integer *, doublereal *, doublereal *, integer *), 
00044             dorm2r_(char *, char *, integer *, integer *, integer *, 
00045             doublereal *, integer *, doublereal *, doublereal *, integer *, 
00046             doublereal *, integer *);
00047     extern doublereal dlamch_(char *);
00048     extern integer idamax_(integer *, doublereal *, integer *);
00049     extern /* Subroutine */ int dlarfp_(integer *, doublereal *, doublereal *, 
00050              integer *, doublereal *), xerbla_(char *, integer *);
00051 
00052 
00053 /*  -- LAPACK deprecated driver routine (version 3.2) -- */
00054 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00055 /*     November 2006 */
00056 
00057 /*     .. Scalar Arguments .. */
00058 /*     .. */
00059 /*     .. Array Arguments .. */
00060 /*     .. */
00061 
00062 /*  Purpose */
00063 /*  ======= */
00064 
00065 /*  This routine is deprecated and has been replaced by routine DGEQP3. */
00066 
00067 /*  DGEQPF computes a QR factorization with column pivoting of a */
00068 /*  real M-by-N matrix A: A*P = Q*R. */
00069 
00070 /*  Arguments */
00071 /*  ========= */
00072 
00073 /*  M       (input) INTEGER */
00074 /*          The number of rows of the matrix A. M >= 0. */
00075 
00076 /*  N       (input) INTEGER */
00077 /*          The number of columns of the matrix A. N >= 0 */
00078 
00079 /*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
00080 /*          On entry, the M-by-N matrix A. */
00081 /*          On exit, the upper triangle of the array contains the */
00082 /*          min(M,N)-by-N upper triangular matrix R; the elements */
00083 /*          below the diagonal, together with the array TAU, */
00084 /*          represent the orthogonal matrix Q as a product of */
00085 /*          min(m,n) elementary reflectors. */
00086 
00087 /*  LDA     (input) INTEGER */
00088 /*          The leading dimension of the array A. LDA >= max(1,M). */
00089 
00090 /*  JPVT    (input/output) INTEGER array, dimension (N) */
00091 /*          On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted */
00092 /*          to the front of A*P (a leading column); if JPVT(i) = 0, */
00093 /*          the i-th column of A is a free column. */
00094 /*          On exit, if JPVT(i) = k, then the i-th column of A*P */
00095 /*          was the k-th column of A. */
00096 
00097 /*  TAU     (output) DOUBLE PRECISION array, dimension (min(M,N)) */
00098 /*          The scalar factors of the elementary reflectors. */
00099 
00100 /*  WORK    (workspace) DOUBLE PRECISION array, dimension (3*N) */
00101 
00102 /*  INFO    (output) INTEGER */
00103 /*          = 0:  successful exit */
00104 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00105 
00106 /*  Further Details */
00107 /*  =============== */
00108 
00109 /*  The matrix Q is represented as a product of elementary reflectors */
00110 
00111 /*     Q = H(1) H(2) . . . H(n) */
00112 
00113 /*  Each H(i) has the form */
00114 
00115 /*     H = I - tau * v * v' */
00116 
00117 /*  where tau is a real scalar, and v is a real vector with */
00118 /*  v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in A(i+1:m,i). */
00119 
00120 /*  The matrix P is represented in jpvt as follows: If */
00121 /*     jpvt(j) = i */
00122 /*  then the jth column of P is the ith canonical unit vector. */
00123 
00124 /*  Partial column norm updating strategy modified by */
00125 /*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics, */
00126 /*    University of Zagreb, Croatia. */
00127 /*    June 2006. */
00128 /*  For more details see LAPACK Working Note 176. */
00129 
00130 /*  ===================================================================== */
00131 
00132 /*     .. Parameters .. */
00133 /*     .. */
00134 /*     .. Local Scalars .. */
00135 /*     .. */
00136 /*     .. External Subroutines .. */
00137 /*     .. */
00138 /*     .. Intrinsic Functions .. */
00139 /*     .. */
00140 /*     .. External Functions .. */
00141 /*     .. */
00142 /*     .. Executable Statements .. */
00143 
00144 /*     Test the input arguments */
00145 
00146     /* Parameter adjustments */
00147     a_dim1 = *lda;
00148     a_offset = 1 + a_dim1;
00149     a -= a_offset;
00150     --jpvt;
00151     --tau;
00152     --work;
00153 
00154     /* Function Body */
00155     *info = 0;
00156     if (*m < 0) {
00157         *info = -1;
00158     } else if (*n < 0) {
00159         *info = -2;
00160     } else if (*lda < max(1,*m)) {
00161         *info = -4;
00162     }
00163     if (*info != 0) {
00164         i__1 = -(*info);
00165         xerbla_("DGEQPF", &i__1);
00166         return 0;
00167     }
00168 
00169     mn = min(*m,*n);
00170     tol3z = sqrt(dlamch_("Epsilon"));
00171 
00172 /*     Move initial columns up front */
00173 
00174     itemp = 1;
00175     i__1 = *n;
00176     for (i__ = 1; i__ <= i__1; ++i__) {
00177         if (jpvt[i__] != 0) {
00178             if (i__ != itemp) {
00179                 dswap_(m, &a[i__ * a_dim1 + 1], &c__1, &a[itemp * a_dim1 + 1], 
00180                          &c__1);
00181                 jpvt[i__] = jpvt[itemp];
00182                 jpvt[itemp] = i__;
00183             } else {
00184                 jpvt[i__] = i__;
00185             }
00186             ++itemp;
00187         } else {
00188             jpvt[i__] = i__;
00189         }
00190 /* L10: */
00191     }
00192     --itemp;
00193 
00194 /*     Compute the QR factorization and update remaining columns */
00195 
00196     if (itemp > 0) {
00197         ma = min(itemp,*m);
00198         dgeqr2_(m, &ma, &a[a_offset], lda, &tau[1], &work[1], info);
00199         if (ma < *n) {
00200             i__1 = *n - ma;
00201             dorm2r_("Left", "Transpose", m, &i__1, &ma, &a[a_offset], lda, &
00202                     tau[1], &a[(ma + 1) * a_dim1 + 1], lda, &work[1], info);
00203         }
00204     }
00205 
00206     if (itemp < mn) {
00207 
00208 /*        Initialize partial column norms. The first n elements of */
00209 /*        work store the exact column norms. */
00210 
00211         i__1 = *n;
00212         for (i__ = itemp + 1; i__ <= i__1; ++i__) {
00213             i__2 = *m - itemp;
00214             work[i__] = dnrm2_(&i__2, &a[itemp + 1 + i__ * a_dim1], &c__1);
00215             work[*n + i__] = work[i__];
00216 /* L20: */
00217         }
00218 
00219 /*        Compute factorization */
00220 
00221         i__1 = mn;
00222         for (i__ = itemp + 1; i__ <= i__1; ++i__) {
00223 
00224 /*           Determine ith pivot column and swap if necessary */
00225 
00226             i__2 = *n - i__ + 1;
00227             pvt = i__ - 1 + idamax_(&i__2, &work[i__], &c__1);
00228 
00229             if (pvt != i__) {
00230                 dswap_(m, &a[pvt * a_dim1 + 1], &c__1, &a[i__ * a_dim1 + 1], &
00231                         c__1);
00232                 itemp = jpvt[pvt];
00233                 jpvt[pvt] = jpvt[i__];
00234                 jpvt[i__] = itemp;
00235                 work[pvt] = work[i__];
00236                 work[*n + pvt] = work[*n + i__];
00237             }
00238 
00239 /*           Generate elementary reflector H(i) */
00240 
00241             if (i__ < *m) {
00242                 i__2 = *m - i__ + 1;
00243                 dlarfp_(&i__2, &a[i__ + i__ * a_dim1], &a[i__ + 1 + i__ * 
00244                         a_dim1], &c__1, &tau[i__]);
00245             } else {
00246                 dlarfp_(&c__1, &a[*m + *m * a_dim1], &a[*m + *m * a_dim1], &
00247                         c__1, &tau[*m]);
00248             }
00249 
00250             if (i__ < *n) {
00251 
00252 /*              Apply H(i) to A(i:m,i+1:n) from the left */
00253 
00254                 aii = a[i__ + i__ * a_dim1];
00255                 a[i__ + i__ * a_dim1] = 1.;
00256                 i__2 = *m - i__ + 1;
00257                 i__3 = *n - i__;
00258                 dlarf_("LEFT", &i__2, &i__3, &a[i__ + i__ * a_dim1], &c__1, &
00259                         tau[i__], &a[i__ + (i__ + 1) * a_dim1], lda, &work[(*
00260                         n << 1) + 1]);
00261                 a[i__ + i__ * a_dim1] = aii;
00262             }
00263 
00264 /*           Update partial column norms */
00265 
00266             i__2 = *n;
00267             for (j = i__ + 1; j <= i__2; ++j) {
00268                 if (work[j] != 0.) {
00269 
00270 /*                 NOTE: The following 4 lines follow from the analysis in */
00271 /*                 Lapack Working Note 176. */
00272 
00273                     temp = (d__1 = a[i__ + j * a_dim1], abs(d__1)) / work[j];
00274 /* Computing MAX */
00275                     d__1 = 0., d__2 = (temp + 1.) * (1. - temp);
00276                     temp = max(d__1,d__2);
00277 /* Computing 2nd power */
00278                     d__1 = work[j] / work[*n + j];
00279                     temp2 = temp * (d__1 * d__1);
00280                     if (temp2 <= tol3z) {
00281                         if (*m - i__ > 0) {
00282                             i__3 = *m - i__;
00283                             work[j] = dnrm2_(&i__3, &a[i__ + 1 + j * a_dim1], 
00284                                     &c__1);
00285                             work[*n + j] = work[j];
00286                         } else {
00287                             work[j] = 0.;
00288                             work[*n + j] = 0.;
00289                         }
00290                     } else {
00291                         work[j] *= sqrt(temp);
00292                     }
00293                 }
00294 /* L30: */
00295             }
00296 
00297 /* L40: */
00298         }
00299     }
00300     return 0;
00301 
00302 /*     End of DGEQPF */
00303 
00304 } /* dgeqpf_ */


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