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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:06