00001 /* dlaqp2.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 dlaqp2_(integer *m, integer *n, integer *offset, 00021 doublereal *a, integer *lda, integer *jpvt, doublereal *tau, 00022 doublereal *vn1, doublereal *vn2, doublereal *work) 00023 { 00024 /* System generated locals */ 00025 integer a_dim1, a_offset, i__1, i__2, i__3; 00026 doublereal d__1, d__2; 00027 00028 /* Builtin functions */ 00029 double sqrt(doublereal); 00030 00031 /* Local variables */ 00032 integer i__, j, mn; 00033 doublereal aii; 00034 integer pvt; 00035 doublereal temp; 00036 extern doublereal dnrm2_(integer *, doublereal *, integer *); 00037 doublereal temp2, tol3z; 00038 extern /* Subroutine */ int dlarf_(char *, integer *, integer *, 00039 doublereal *, integer *, doublereal *, doublereal *, integer *, 00040 doublereal *); 00041 integer offpi, itemp; 00042 extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *, 00043 doublereal *, integer *); 00044 extern doublereal dlamch_(char *); 00045 extern integer idamax_(integer *, doublereal *, integer *); 00046 extern /* Subroutine */ int dlarfp_(integer *, doublereal *, doublereal *, 00047 integer *, doublereal *); 00048 00049 00050 /* -- LAPACK auxiliary routine (version 3.2) -- */ 00051 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00052 /* November 2006 */ 00053 00054 /* .. Scalar Arguments .. */ 00055 /* .. */ 00056 /* .. Array Arguments .. */ 00057 /* .. */ 00058 00059 /* Purpose */ 00060 /* ======= */ 00061 00062 /* DLAQP2 computes a QR factorization with column pivoting of */ 00063 /* the block A(OFFSET+1:M,1:N). */ 00064 /* The block A(1:OFFSET,1:N) is accordingly pivoted, but not factorized. */ 00065 00066 /* Arguments */ 00067 /* ========= */ 00068 00069 /* M (input) INTEGER */ 00070 /* The number of rows of the matrix A. M >= 0. */ 00071 00072 /* N (input) INTEGER */ 00073 /* The number of columns of the matrix A. N >= 0. */ 00074 00075 /* OFFSET (input) INTEGER */ 00076 /* The number of rows of the matrix A that must be pivoted */ 00077 /* but no factorized. OFFSET >= 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 block A(OFFSET+1:M,1:N) is */ 00082 /* the triangular factor obtained; the elements in block */ 00083 /* A(OFFSET+1:M,1:N) below the diagonal, together with the */ 00084 /* array TAU, represent the orthogonal matrix Q as a product of */ 00085 /* elementary reflectors. Block A(1:OFFSET,1:N) has been */ 00086 /* accordingly pivoted, but no factorized. */ 00087 00088 /* LDA (input) INTEGER */ 00089 /* The leading dimension of the array A. LDA >= max(1,M). */ 00090 00091 /* JPVT (input/output) INTEGER array, dimension (N) */ 00092 /* On entry, if JPVT(i) .ne. 0, the i-th column of A is permuted */ 00093 /* to the front of A*P (a leading column); if JPVT(i) = 0, */ 00094 /* the i-th column of A is a free column. */ 00095 /* On exit, if JPVT(i) = k, then the i-th column of A*P */ 00096 /* was the k-th column of A. */ 00097 00098 /* TAU (output) DOUBLE PRECISION array, dimension (min(M,N)) */ 00099 /* The scalar factors of the elementary reflectors. */ 00100 00101 /* VN1 (input/output) DOUBLE PRECISION array, dimension (N) */ 00102 /* The vector with the partial column norms. */ 00103 00104 /* VN2 (input/output) DOUBLE PRECISION array, dimension (N) */ 00105 /* The vector with the exact column norms. */ 00106 00107 /* WORK (workspace) DOUBLE PRECISION array, dimension (N) */ 00108 00109 /* Further Details */ 00110 /* =============== */ 00111 00112 /* Based on contributions by */ 00113 /* G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain */ 00114 /* X. Sun, Computer Science Dept., Duke University, USA */ 00115 00116 /* Partial column norm updating strategy modified by */ 00117 /* Z. Drmac and Z. Bujanovic, Dept. of Mathematics, */ 00118 /* University of Zagreb, Croatia. */ 00119 /* June 2006. */ 00120 /* For more details see LAPACK Working Note 176. */ 00121 /* ===================================================================== */ 00122 00123 /* .. Parameters .. */ 00124 /* .. */ 00125 /* .. Local Scalars .. */ 00126 /* .. */ 00127 /* .. External Subroutines .. */ 00128 /* .. */ 00129 /* .. Intrinsic Functions .. */ 00130 /* .. */ 00131 /* .. External Functions .. */ 00132 /* .. */ 00133 /* .. Executable Statements .. */ 00134 00135 /* Parameter adjustments */ 00136 a_dim1 = *lda; 00137 a_offset = 1 + a_dim1; 00138 a -= a_offset; 00139 --jpvt; 00140 --tau; 00141 --vn1; 00142 --vn2; 00143 --work; 00144 00145 /* Function Body */ 00146 /* Computing MIN */ 00147 i__1 = *m - *offset; 00148 mn = min(i__1,*n); 00149 tol3z = sqrt(dlamch_("Epsilon")); 00150 00151 /* Compute factorization. */ 00152 00153 i__1 = mn; 00154 for (i__ = 1; i__ <= i__1; ++i__) { 00155 00156 offpi = *offset + i__; 00157 00158 /* Determine ith pivot column and swap if necessary. */ 00159 00160 i__2 = *n - i__ + 1; 00161 pvt = i__ - 1 + idamax_(&i__2, &vn1[i__], &c__1); 00162 00163 if (pvt != i__) { 00164 dswap_(m, &a[pvt * a_dim1 + 1], &c__1, &a[i__ * a_dim1 + 1], & 00165 c__1); 00166 itemp = jpvt[pvt]; 00167 jpvt[pvt] = jpvt[i__]; 00168 jpvt[i__] = itemp; 00169 vn1[pvt] = vn1[i__]; 00170 vn2[pvt] = vn2[i__]; 00171 } 00172 00173 /* Generate elementary reflector H(i). */ 00174 00175 if (offpi < *m) { 00176 i__2 = *m - offpi + 1; 00177 dlarfp_(&i__2, &a[offpi + i__ * a_dim1], &a[offpi + 1 + i__ * 00178 a_dim1], &c__1, &tau[i__]); 00179 } else { 00180 dlarfp_(&c__1, &a[*m + i__ * a_dim1], &a[*m + i__ * a_dim1], & 00181 c__1, &tau[i__]); 00182 } 00183 00184 if (i__ <= *n) { 00185 00186 /* Apply H(i)' to A(offset+i:m,i+1:n) from the left. */ 00187 00188 aii = a[offpi + i__ * a_dim1]; 00189 a[offpi + i__ * a_dim1] = 1.; 00190 i__2 = *m - offpi + 1; 00191 i__3 = *n - i__; 00192 dlarf_("Left", &i__2, &i__3, &a[offpi + i__ * a_dim1], &c__1, & 00193 tau[i__], &a[offpi + (i__ + 1) * a_dim1], lda, &work[1]); 00194 a[offpi + i__ * a_dim1] = aii; 00195 } 00196 00197 /* Update partial column norms. */ 00198 00199 i__2 = *n; 00200 for (j = i__ + 1; j <= i__2; ++j) { 00201 if (vn1[j] != 0.) { 00202 00203 /* NOTE: The following 4 lines follow from the analysis in */ 00204 /* Lapack Working Note 176. */ 00205 00206 /* Computing 2nd power */ 00207 d__2 = (d__1 = a[offpi + j * a_dim1], abs(d__1)) / vn1[j]; 00208 temp = 1. - d__2 * d__2; 00209 temp = max(temp,0.); 00210 /* Computing 2nd power */ 00211 d__1 = vn1[j] / vn2[j]; 00212 temp2 = temp * (d__1 * d__1); 00213 if (temp2 <= tol3z) { 00214 if (offpi < *m) { 00215 i__3 = *m - offpi; 00216 vn1[j] = dnrm2_(&i__3, &a[offpi + 1 + j * a_dim1], & 00217 c__1); 00218 vn2[j] = vn1[j]; 00219 } else { 00220 vn1[j] = 0.; 00221 vn2[j] = 0.; 00222 } 00223 } else { 00224 vn1[j] *= sqrt(temp); 00225 } 00226 } 00227 /* L10: */ 00228 } 00229 00230 /* L20: */ 00231 } 00232 00233 return 0; 00234 00235 /* End of DLAQP2 */ 00236 00237 } /* dlaqp2_ */