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