dlaqps.c
Go to the documentation of this file.
00001 /* dlaqps.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 static doublereal c_b8 = -1.;
00020 static doublereal c_b9 = 1.;
00021 static doublereal c_b16 = 0.;
00022 
00023 /* Subroutine */ int dlaqps_(integer *m, integer *n, integer *offset, integer 
00024         *nb, integer *kb, doublereal *a, integer *lda, integer *jpvt, 
00025         doublereal *tau, doublereal *vn1, doublereal *vn2, doublereal *auxv, 
00026         doublereal *f, integer *ldf)
00027 {
00028     /* System generated locals */
00029     integer a_dim1, a_offset, f_dim1, f_offset, i__1, i__2;
00030     doublereal d__1, d__2;
00031 
00032     /* Builtin functions */
00033     double sqrt(doublereal);
00034     integer i_dnnt(doublereal *);
00035 
00036     /* Local variables */
00037     integer j, k, rk;
00038     doublereal akk;
00039     integer pvt;
00040     doublereal temp;
00041     extern doublereal dnrm2_(integer *, doublereal *, integer *);
00042     doublereal temp2, tol3z;
00043     extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *, 
00044             integer *, doublereal *, doublereal *, integer *, doublereal *, 
00045             integer *, doublereal *, doublereal *, integer *),
00046              dgemv_(char *, integer *, integer *, doublereal *, doublereal *, 
00047             integer *, doublereal *, integer *, doublereal *, doublereal *, 
00048             integer *);
00049     integer itemp;
00050     extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *, 
00051             doublereal *, integer *);
00052     extern doublereal dlamch_(char *);
00053     extern integer idamax_(integer *, doublereal *, integer *);
00054     extern /* Subroutine */ int dlarfp_(integer *, doublereal *, doublereal *, 
00055              integer *, doublereal *);
00056     integer lsticc, lastrk;
00057 
00058 
00059 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00060 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00061 /*     November 2006 */
00062 
00063 /*     .. Scalar Arguments .. */
00064 /*     .. */
00065 /*     .. Array Arguments .. */
00066 /*     .. */
00067 
00068 /*  Purpose */
00069 /*  ======= */
00070 
00071 /*  DLAQPS computes a step of QR factorization with column pivoting */
00072 /*  of a real M-by-N matrix A by using Blas-3.  It tries to factorize */
00073 /*  NB columns from A starting from the row OFFSET+1, and updates all */
00074 /*  of the matrix with Blas-3 xGEMM. */
00075 
00076 /*  In some cases, due to catastrophic cancellations, it cannot */
00077 /*  factorize NB columns.  Hence, the actual number of factorized */
00078 /*  columns is returned in KB. */
00079 
00080 /*  Block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized. */
00081 
00082 /*  Arguments */
00083 /*  ========= */
00084 
00085 /*  M       (input) INTEGER */
00086 /*          The number of rows of the matrix A. M >= 0. */
00087 
00088 /*  N       (input) INTEGER */
00089 /*          The number of columns of the matrix A. N >= 0 */
00090 
00091 /*  OFFSET  (input) INTEGER */
00092 /*          The number of rows of A that have been factorized in */
00093 /*          previous steps. */
00094 
00095 /*  NB      (input) INTEGER */
00096 /*          The number of columns to factorize. */
00097 
00098 /*  KB      (output) INTEGER */
00099 /*          The number of columns actually factorized. */
00100 
00101 /*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
00102 /*          On entry, the M-by-N matrix A. */
00103 /*          On exit, block A(OFFSET+1:M,1:KB) is the triangular */
00104 /*          factor obtained and block A(1:OFFSET,1:N) has been */
00105 /*          accordingly pivoted, but no factorized. */
00106 /*          The rest of the matrix, block A(OFFSET+1:M,KB+1:N) has */
00107 /*          been updated. */
00108 
00109 /*  LDA     (input) INTEGER */
00110 /*          The leading dimension of the array A. LDA >= max(1,M). */
00111 
00112 /*  JPVT    (input/output) INTEGER array, dimension (N) */
00113 /*          JPVT(I) = K <==> Column K of the full matrix A has been */
00114 /*          permuted into position I in AP. */
00115 
00116 /*  TAU     (output) DOUBLE PRECISION array, dimension (KB) */
00117 /*          The scalar factors of the elementary reflectors. */
00118 
00119 /*  VN1     (input/output) DOUBLE PRECISION array, dimension (N) */
00120 /*          The vector with the partial column norms. */
00121 
00122 /*  VN2     (input/output) DOUBLE PRECISION array, dimension (N) */
00123 /*          The vector with the exact column norms. */
00124 
00125 /*  AUXV    (input/output) DOUBLE PRECISION array, dimension (NB) */
00126 /*          Auxiliar vector. */
00127 
00128 /*  F       (input/output) DOUBLE PRECISION array, dimension (LDF,NB) */
00129 /*          Matrix F' = L*Y'*A. */
00130 
00131 /*  LDF     (input) INTEGER */
00132 /*          The leading dimension of the array F. LDF >= max(1,N). */
00133 
00134 /*  Further Details */
00135 /*  =============== */
00136 
00137 /*  Based on contributions by */
00138 /*    G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain */
00139 /*    X. Sun, Computer Science Dept., Duke University, USA */
00140 
00141 /*  Partial column norm updating strategy modified by */
00142 /*    Z. Drmac and Z. Bujanovic, Dept. of Mathematics, */
00143 /*    University of Zagreb, Croatia. */
00144 /*    June 2006. */
00145 /*  For more details see LAPACK Working Note 176. */
00146 /*  ===================================================================== */
00147 
00148 /*     .. Parameters .. */
00149 /*     .. */
00150 /*     .. Local Scalars .. */
00151 /*     .. */
00152 /*     .. External Subroutines .. */
00153 /*     .. */
00154 /*     .. Intrinsic Functions .. */
00155 /*     .. */
00156 /*     .. External Functions .. */
00157 /*     .. */
00158 /*     .. Executable Statements .. */
00159 
00160     /* Parameter adjustments */
00161     a_dim1 = *lda;
00162     a_offset = 1 + a_dim1;
00163     a -= a_offset;
00164     --jpvt;
00165     --tau;
00166     --vn1;
00167     --vn2;
00168     --auxv;
00169     f_dim1 = *ldf;
00170     f_offset = 1 + f_dim1;
00171     f -= f_offset;
00172 
00173     /* Function Body */
00174 /* Computing MIN */
00175     i__1 = *m, i__2 = *n + *offset;
00176     lastrk = min(i__1,i__2);
00177     lsticc = 0;
00178     k = 0;
00179     tol3z = sqrt(dlamch_("Epsilon"));
00180 
00181 /*     Beginning of while loop. */
00182 
00183 L10:
00184     if (k < *nb && lsticc == 0) {
00185         ++k;
00186         rk = *offset + k;
00187 
00188 /*        Determine ith pivot column and swap if necessary */
00189 
00190         i__1 = *n - k + 1;
00191         pvt = k - 1 + idamax_(&i__1, &vn1[k], &c__1);
00192         if (pvt != k) {
00193             dswap_(m, &a[pvt * a_dim1 + 1], &c__1, &a[k * a_dim1 + 1], &c__1);
00194             i__1 = k - 1;
00195             dswap_(&i__1, &f[pvt + f_dim1], ldf, &f[k + f_dim1], ldf);
00196             itemp = jpvt[pvt];
00197             jpvt[pvt] = jpvt[k];
00198             jpvt[k] = itemp;
00199             vn1[pvt] = vn1[k];
00200             vn2[pvt] = vn2[k];
00201         }
00202 
00203 /*        Apply previous Householder reflectors to column K: */
00204 /*        A(RK:M,K) := A(RK:M,K) - A(RK:M,1:K-1)*F(K,1:K-1)'. */
00205 
00206         if (k > 1) {
00207             i__1 = *m - rk + 1;
00208             i__2 = k - 1;
00209             dgemv_("No transpose", &i__1, &i__2, &c_b8, &a[rk + a_dim1], lda, 
00210                     &f[k + f_dim1], ldf, &c_b9, &a[rk + k * a_dim1], &c__1);
00211         }
00212 
00213 /*        Generate elementary reflector H(k). */
00214 
00215         if (rk < *m) {
00216             i__1 = *m - rk + 1;
00217             dlarfp_(&i__1, &a[rk + k * a_dim1], &a[rk + 1 + k * a_dim1], &
00218                     c__1, &tau[k]);
00219         } else {
00220             dlarfp_(&c__1, &a[rk + k * a_dim1], &a[rk + k * a_dim1], &c__1, &
00221                     tau[k]);
00222         }
00223 
00224         akk = a[rk + k * a_dim1];
00225         a[rk + k * a_dim1] = 1.;
00226 
00227 /*        Compute Kth column of F: */
00228 
00229 /*        Compute  F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)'*A(RK:M,K). */
00230 
00231         if (k < *n) {
00232             i__1 = *m - rk + 1;
00233             i__2 = *n - k;
00234             dgemv_("Transpose", &i__1, &i__2, &tau[k], &a[rk + (k + 1) * 
00235                     a_dim1], lda, &a[rk + k * a_dim1], &c__1, &c_b16, &f[k + 
00236                     1 + k * f_dim1], &c__1);
00237         }
00238 
00239 /*        Padding F(1:K,K) with zeros. */
00240 
00241         i__1 = k;
00242         for (j = 1; j <= i__1; ++j) {
00243             f[j + k * f_dim1] = 0.;
00244 /* L20: */
00245         }
00246 
00247 /*        Incremental updating of F: */
00248 /*        F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)' */
00249 /*                    *A(RK:M,K). */
00250 
00251         if (k > 1) {
00252             i__1 = *m - rk + 1;
00253             i__2 = k - 1;
00254             d__1 = -tau[k];
00255             dgemv_("Transpose", &i__1, &i__2, &d__1, &a[rk + a_dim1], lda, &a[
00256                     rk + k * a_dim1], &c__1, &c_b16, &auxv[1], &c__1);
00257 
00258             i__1 = k - 1;
00259             dgemv_("No transpose", n, &i__1, &c_b9, &f[f_dim1 + 1], ldf, &
00260                     auxv[1], &c__1, &c_b9, &f[k * f_dim1 + 1], &c__1);
00261         }
00262 
00263 /*        Update the current row of A: */
00264 /*        A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)'. */
00265 
00266         if (k < *n) {
00267             i__1 = *n - k;
00268             dgemv_("No transpose", &i__1, &k, &c_b8, &f[k + 1 + f_dim1], ldf, 
00269                     &a[rk + a_dim1], lda, &c_b9, &a[rk + (k + 1) * a_dim1], 
00270                     lda);
00271         }
00272 
00273 /*        Update partial column norms. */
00274 
00275         if (rk < lastrk) {
00276             i__1 = *n;
00277             for (j = k + 1; j <= i__1; ++j) {
00278                 if (vn1[j] != 0.) {
00279 
00280 /*                 NOTE: The following 4 lines follow from the analysis in */
00281 /*                 Lapack Working Note 176. */
00282 
00283                     temp = (d__1 = a[rk + j * a_dim1], abs(d__1)) / vn1[j];
00284 /* Computing MAX */
00285                     d__1 = 0., d__2 = (temp + 1.) * (1. - temp);
00286                     temp = max(d__1,d__2);
00287 /* Computing 2nd power */
00288                     d__1 = vn1[j] / vn2[j];
00289                     temp2 = temp * (d__1 * d__1);
00290                     if (temp2 <= tol3z) {
00291                         vn2[j] = (doublereal) lsticc;
00292                         lsticc = j;
00293                     } else {
00294                         vn1[j] *= sqrt(temp);
00295                     }
00296                 }
00297 /* L30: */
00298             }
00299         }
00300 
00301         a[rk + k * a_dim1] = akk;
00302 
00303 /*        End of while loop. */
00304 
00305         goto L10;
00306     }
00307     *kb = k;
00308     rk = *offset + *kb;
00309 
00310 /*     Apply the block reflector to the rest of the matrix: */
00311 /*     A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) - */
00312 /*                         A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)'. */
00313 
00314 /* Computing MIN */
00315     i__1 = *n, i__2 = *m - *offset;
00316     if (*kb < min(i__1,i__2)) {
00317         i__1 = *m - rk;
00318         i__2 = *n - *kb;
00319         dgemm_("No transpose", "Transpose", &i__1, &i__2, kb, &c_b8, &a[rk + 
00320                 1 + a_dim1], lda, &f[*kb + 1 + f_dim1], ldf, &c_b9, &a[rk + 1 
00321                 + (*kb + 1) * a_dim1], lda);
00322     }
00323 
00324 /*     Recomputation of difficult columns. */
00325 
00326 L40:
00327     if (lsticc > 0) {
00328         itemp = i_dnnt(&vn2[lsticc]);
00329         i__1 = *m - rk;
00330         vn1[lsticc] = dnrm2_(&i__1, &a[rk + 1 + lsticc * a_dim1], &c__1);
00331 
00332 /*        NOTE: The computation of VN1( LSTICC ) relies on the fact that */
00333 /*        SNRM2 does not fail on vectors with norm below the value of */
00334 /*        SQRT(DLAMCH('S')) */
00335 
00336         vn2[lsticc] = vn1[lsticc];
00337         lsticc = itemp;
00338         goto L40;
00339     }
00340 
00341     return 0;
00342 
00343 /*     End of DLAQPS */
00344 
00345 } /* dlaqps_ */


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