00001 /* stzrzf.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 integer c_n1 = -1; 00020 static integer c__3 = 3; 00021 static integer c__2 = 2; 00022 00023 /* Subroutine */ int stzrzf_(integer *m, integer *n, real *a, integer *lda, 00024 real *tau, real *work, integer *lwork, integer *info) 00025 { 00026 /* System generated locals */ 00027 integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5; 00028 00029 /* Local variables */ 00030 integer i__, m1, ib, nb, ki, kk, mu, nx, iws, nbmin; 00031 extern /* Subroutine */ int xerbla_(char *, integer *); 00032 extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 00033 integer *, integer *); 00034 extern /* Subroutine */ int slarzb_(char *, char *, char *, char *, 00035 integer *, integer *, integer *, integer *, real *, integer *, 00036 real *, integer *, real *, integer *, real *, integer *); 00037 integer ldwork; 00038 extern /* Subroutine */ int slarzt_(char *, char *, integer *, integer *, 00039 real *, integer *, real *, real *, integer *); 00040 integer lwkopt; 00041 logical lquery; 00042 extern /* Subroutine */ int slatrz_(integer *, integer *, integer *, real 00043 *, integer *, real *, real *); 00044 00045 00046 /* -- LAPACK routine (version 3.2) -- */ 00047 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00048 /* November 2006 */ 00049 00050 /* .. Scalar Arguments .. */ 00051 /* .. */ 00052 /* .. Array Arguments .. */ 00053 /* .. */ 00054 00055 /* Purpose */ 00056 /* ======= */ 00057 00058 /* STZRZF reduces the M-by-N ( M<=N ) real upper trapezoidal matrix A */ 00059 /* to upper triangular form by means of orthogonal transformations. */ 00060 00061 /* The upper trapezoidal matrix A is factored as */ 00062 00063 /* A = ( R 0 ) * Z, */ 00064 00065 /* where Z is an N-by-N orthogonal matrix and R is an M-by-M upper */ 00066 /* triangular matrix. */ 00067 00068 /* Arguments */ 00069 /* ========= */ 00070 00071 /* M (input) INTEGER */ 00072 /* The number of rows of the matrix A. M >= 0. */ 00073 00074 /* N (input) INTEGER */ 00075 /* The number of columns of the matrix A. N >= M. */ 00076 00077 /* A (input/output) REAL array, dimension (LDA,N) */ 00078 /* On entry, the leading M-by-N upper trapezoidal part of the */ 00079 /* array A must contain the matrix to be factorized. */ 00080 /* On exit, the leading M-by-M upper triangular part of A */ 00081 /* contains the upper triangular matrix R, and elements M+1 to */ 00082 /* N of the first M rows of A, with the array TAU, represent the */ 00083 /* orthogonal matrix Z as a product of M elementary reflectors. */ 00084 00085 /* LDA (input) INTEGER */ 00086 /* The leading dimension of the array A. LDA >= max(1,M). */ 00087 00088 /* TAU (output) REAL array, dimension (M) */ 00089 /* The scalar factors of the elementary reflectors. */ 00090 00091 /* WORK (workspace/output) REAL array, dimension (MAX(1,LWORK)) */ 00092 /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */ 00093 00094 /* LWORK (input) INTEGER */ 00095 /* The dimension of the array WORK. LWORK >= max(1,M). */ 00096 /* For optimum performance LWORK >= M*NB, where NB is */ 00097 /* the optimal blocksize. */ 00098 00099 /* If LWORK = -1, then a workspace query is assumed; the routine */ 00100 /* only calculates the optimal size of the WORK array, returns */ 00101 /* this value as the first entry of the WORK array, and no error */ 00102 /* message related to LWORK is issued by XERBLA. */ 00103 00104 /* INFO (output) INTEGER */ 00105 /* = 0: successful exit */ 00106 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00107 00108 /* Further Details */ 00109 /* =============== */ 00110 00111 /* Based on contributions by */ 00112 /* A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA */ 00113 00114 /* The factorization is obtained by Householder's method. The kth */ 00115 /* transformation matrix, Z( k ), which is used to introduce zeros into */ 00116 /* the ( m - k + 1 )th row of A, is given in the form */ 00117 00118 /* Z( k ) = ( I 0 ), */ 00119 /* ( 0 T( k ) ) */ 00120 00121 /* where */ 00122 00123 /* T( k ) = I - tau*u( k )*u( k )', u( k ) = ( 1 ), */ 00124 /* ( 0 ) */ 00125 /* ( z( k ) ) */ 00126 00127 /* tau is a scalar and z( k ) is an ( n - m ) element vector. */ 00128 /* tau and z( k ) are chosen to annihilate the elements of the kth row */ 00129 /* of X. */ 00130 00131 /* The scalar tau is returned in the kth element of TAU and the vector */ 00132 /* u( k ) in the kth row of A, such that the elements of z( k ) are */ 00133 /* in a( k, m + 1 ), ..., a( k, n ). The elements of R are returned in */ 00134 /* the upper triangular part of A. */ 00135 00136 /* Z is given by */ 00137 00138 /* Z = Z( 1 ) * Z( 2 ) * ... * Z( m ). */ 00139 00140 /* ===================================================================== */ 00141 00142 /* .. Parameters .. */ 00143 /* .. */ 00144 /* .. Local Scalars .. */ 00145 /* .. */ 00146 /* .. External Subroutines .. */ 00147 /* .. */ 00148 /* .. Intrinsic Functions .. */ 00149 /* .. */ 00150 /* .. External Functions .. */ 00151 /* .. */ 00152 /* .. Executable Statements .. */ 00153 00154 /* Test the input arguments */ 00155 00156 /* Parameter adjustments */ 00157 a_dim1 = *lda; 00158 a_offset = 1 + a_dim1; 00159 a -= a_offset; 00160 --tau; 00161 --work; 00162 00163 /* Function Body */ 00164 *info = 0; 00165 lquery = *lwork == -1; 00166 if (*m < 0) { 00167 *info = -1; 00168 } else if (*n < *m) { 00169 *info = -2; 00170 } else if (*lda < max(1,*m)) { 00171 *info = -4; 00172 } 00173 00174 if (*info == 0) { 00175 if (*m == 0 || *m == *n) { 00176 lwkopt = 1; 00177 } else { 00178 00179 /* Determine the block size. */ 00180 00181 nb = ilaenv_(&c__1, "SGERQF", " ", m, n, &c_n1, &c_n1); 00182 lwkopt = *m * nb; 00183 } 00184 work[1] = (real) lwkopt; 00185 00186 if (*lwork < max(1,*m) && ! lquery) { 00187 *info = -7; 00188 } 00189 } 00190 00191 if (*info != 0) { 00192 i__1 = -(*info); 00193 xerbla_("STZRZF", &i__1); 00194 return 0; 00195 } else if (lquery) { 00196 return 0; 00197 } 00198 00199 /* Quick return if possible */ 00200 00201 if (*m == 0) { 00202 return 0; 00203 } else if (*m == *n) { 00204 i__1 = *n; 00205 for (i__ = 1; i__ <= i__1; ++i__) { 00206 tau[i__] = 0.f; 00207 /* L10: */ 00208 } 00209 return 0; 00210 } 00211 00212 nbmin = 2; 00213 nx = 1; 00214 iws = *m; 00215 if (nb > 1 && nb < *m) { 00216 00217 /* Determine when to cross over from blocked to unblocked code. */ 00218 00219 /* Computing MAX */ 00220 i__1 = 0, i__2 = ilaenv_(&c__3, "SGERQF", " ", m, n, &c_n1, &c_n1); 00221 nx = max(i__1,i__2); 00222 if (nx < *m) { 00223 00224 /* Determine if workspace is large enough for blocked code. */ 00225 00226 ldwork = *m; 00227 iws = ldwork * nb; 00228 if (*lwork < iws) { 00229 00230 /* Not enough workspace to use optimal NB: reduce NB and */ 00231 /* determine the minimum value of NB. */ 00232 00233 nb = *lwork / ldwork; 00234 /* Computing MAX */ 00235 i__1 = 2, i__2 = ilaenv_(&c__2, "SGERQF", " ", m, n, &c_n1, & 00236 c_n1); 00237 nbmin = max(i__1,i__2); 00238 } 00239 } 00240 } 00241 00242 if (nb >= nbmin && nb < *m && nx < *m) { 00243 00244 /* Use blocked code initially. */ 00245 /* The last kk rows are handled by the block method. */ 00246 00247 /* Computing MIN */ 00248 i__1 = *m + 1; 00249 m1 = min(i__1,*n); 00250 ki = (*m - nx - 1) / nb * nb; 00251 /* Computing MIN */ 00252 i__1 = *m, i__2 = ki + nb; 00253 kk = min(i__1,i__2); 00254 00255 i__1 = *m - kk + 1; 00256 i__2 = -nb; 00257 for (i__ = *m - kk + ki + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; 00258 i__ += i__2) { 00259 /* Computing MIN */ 00260 i__3 = *m - i__ + 1; 00261 ib = min(i__3,nb); 00262 00263 /* Compute the TZ factorization of the current block */ 00264 /* A(i:i+ib-1,i:n) */ 00265 00266 i__3 = *n - i__ + 1; 00267 i__4 = *n - *m; 00268 slatrz_(&ib, &i__3, &i__4, &a[i__ + i__ * a_dim1], lda, &tau[i__], 00269 &work[1]); 00270 if (i__ > 1) { 00271 00272 /* Form the triangular factor of the block reflector */ 00273 /* H = H(i+ib-1) . . . H(i+1) H(i) */ 00274 00275 i__3 = *n - *m; 00276 slarzt_("Backward", "Rowwise", &i__3, &ib, &a[i__ + m1 * 00277 a_dim1], lda, &tau[i__], &work[1], &ldwork); 00278 00279 /* Apply H to A(1:i-1,i:n) from the right */ 00280 00281 i__3 = i__ - 1; 00282 i__4 = *n - i__ + 1; 00283 i__5 = *n - *m; 00284 slarzb_("Right", "No transpose", "Backward", "Rowwise", &i__3, 00285 &i__4, &ib, &i__5, &a[i__ + m1 * a_dim1], lda, &work[ 00286 1], &ldwork, &a[i__ * a_dim1 + 1], lda, &work[ib + 1], 00287 &ldwork) 00288 ; 00289 } 00290 /* L20: */ 00291 } 00292 mu = i__ + nb - 1; 00293 } else { 00294 mu = *m; 00295 } 00296 00297 /* Use unblocked code to factor the last or only block */ 00298 00299 if (mu > 0) { 00300 i__2 = *n - *m; 00301 slatrz_(&mu, n, &i__2, &a[a_offset], lda, &tau[1], &work[1]); 00302 } 00303 00304 work[1] = (real) lwkopt; 00305 00306 return 0; 00307 00308 /* End of STZRZF */ 00309 00310 } /* stzrzf_ */