claqps.c
Go to the documentation of this file.
00001 /* claqps.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 complex c_b1 = {0.f,0.f};
00019 static complex c_b2 = {1.f,0.f};
00020 static integer c__1 = 1;
00021 
00022 /* Subroutine */ int claqps_(integer *m, integer *n, integer *offset, integer 
00023         *nb, integer *kb, complex *a, integer *lda, integer *jpvt, complex *
00024         tau, real *vn1, real *vn2, complex *auxv, complex *f, integer *ldf)
00025 {
00026     /* System generated locals */
00027     integer a_dim1, a_offset, f_dim1, f_offset, i__1, i__2, i__3;
00028     real r__1, r__2;
00029     complex q__1;
00030 
00031     /* Builtin functions */
00032     double sqrt(doublereal);
00033     void r_cnjg(complex *, complex *);
00034     double c_abs(complex *);
00035     integer i_nint(real *);
00036 
00037     /* Local variables */
00038     integer j, k, rk;
00039     complex akk;
00040     integer pvt;
00041     real temp, temp2, tol3z;
00042     extern /* Subroutine */ int cgemm_(char *, char *, integer *, integer *, 
00043             integer *, complex *, complex *, integer *, complex *, integer *, 
00044             complex *, complex *, integer *), cgemv_(char *, 
00045             integer *, integer *, complex *, complex *, integer *, complex *, 
00046             integer *, complex *, complex *, integer *), cswap_(
00047             integer *, complex *, integer *, complex *, integer *);
00048     integer itemp;
00049     extern doublereal scnrm2_(integer *, complex *, integer *);
00050     extern /* Subroutine */ int clarfp_(integer *, complex *, complex *, 
00051             integer *, complex *);
00052     extern doublereal slamch_(char *);
00053     integer lsticc;
00054     extern integer isamax_(integer *, real *, integer *);
00055     integer lastrk;
00056 
00057 
00058 /*  -- LAPACK auxiliary routine (version 3.2) -- */
00059 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
00060 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
00061 /*     November 2006 */
00062 
00063 /*     .. Scalar Arguments .. */
00064 /*     .. */
00065 /*     .. Array Arguments .. */
00066 /*     .. */
00067 
00068 /*  Purpose */
00069 /*  ======= */
00070 
00071 /*  CLAQPS computes a step of QR factorization with column pivoting */
00072 /*  of a complex 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) COMPLEX 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) COMPLEX array, dimension (KB) */
00117 /*          The scalar factors of the elementary reflectors. */
00118 
00119 /*  VN1     (input/output) REAL array, dimension (N) */
00120 /*          The vector with the partial column norms. */
00121 
00122 /*  VN2     (input/output) REAL array, dimension (N) */
00123 /*          The vector with the exact column norms. */
00124 
00125 /*  AUXV    (input/output) COMPLEX array, dimension (NB) */
00126 /*          Auxiliar vector. */
00127 
00128 /*  F       (input/output) COMPLEX 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(slamch_("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 + isamax_(&i__1, &vn1[k], &c__1);
00192         if (pvt != k) {
00193             cswap_(m, &a[pvt * a_dim1 + 1], &c__1, &a[k * a_dim1 + 1], &c__1);
00194             i__1 = k - 1;
00195             cswap_(&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 = k - 1;
00208             for (j = 1; j <= i__1; ++j) {
00209                 i__2 = k + j * f_dim1;
00210                 r_cnjg(&q__1, &f[k + j * f_dim1]);
00211                 f[i__2].r = q__1.r, f[i__2].i = q__1.i;
00212 /* L20: */
00213             }
00214             i__1 = *m - rk + 1;
00215             i__2 = k - 1;
00216             q__1.r = -1.f, q__1.i = -0.f;
00217             cgemv_("No transpose", &i__1, &i__2, &q__1, &a[rk + a_dim1], lda, 
00218                     &f[k + f_dim1], ldf, &c_b2, &a[rk + k * a_dim1], &c__1);
00219             i__1 = k - 1;
00220             for (j = 1; j <= i__1; ++j) {
00221                 i__2 = k + j * f_dim1;
00222                 r_cnjg(&q__1, &f[k + j * f_dim1]);
00223                 f[i__2].r = q__1.r, f[i__2].i = q__1.i;
00224 /* L30: */
00225             }
00226         }
00227 
00228 /*        Generate elementary reflector H(k). */
00229 
00230         if (rk < *m) {
00231             i__1 = *m - rk + 1;
00232             clarfp_(&i__1, &a[rk + k * a_dim1], &a[rk + 1 + k * a_dim1], &
00233                     c__1, &tau[k]);
00234         } else {
00235             clarfp_(&c__1, &a[rk + k * a_dim1], &a[rk + k * a_dim1], &c__1, &
00236                     tau[k]);
00237         }
00238 
00239         i__1 = rk + k * a_dim1;
00240         akk.r = a[i__1].r, akk.i = a[i__1].i;
00241         i__1 = rk + k * a_dim1;
00242         a[i__1].r = 1.f, a[i__1].i = 0.f;
00243 
00244 /*        Compute Kth column of F: */
00245 
00246 /*        Compute  F(K+1:N,K) := tau(K)*A(RK:M,K+1:N)'*A(RK:M,K). */
00247 
00248         if (k < *n) {
00249             i__1 = *m - rk + 1;
00250             i__2 = *n - k;
00251             cgemv_("Conjugate transpose", &i__1, &i__2, &tau[k], &a[rk + (k + 
00252                     1) * a_dim1], lda, &a[rk + k * a_dim1], &c__1, &c_b1, &f[
00253                     k + 1 + k * f_dim1], &c__1);
00254         }
00255 
00256 /*        Padding F(1:K,K) with zeros. */
00257 
00258         i__1 = k;
00259         for (j = 1; j <= i__1; ++j) {
00260             i__2 = j + k * f_dim1;
00261             f[i__2].r = 0.f, f[i__2].i = 0.f;
00262 /* L40: */
00263         }
00264 
00265 /*        Incremental updating of F: */
00266 /*        F(1:N,K) := F(1:N,K) - tau(K)*F(1:N,1:K-1)*A(RK:M,1:K-1)' */
00267 /*                    *A(RK:M,K). */
00268 
00269         if (k > 1) {
00270             i__1 = *m - rk + 1;
00271             i__2 = k - 1;
00272             i__3 = k;
00273             q__1.r = -tau[i__3].r, q__1.i = -tau[i__3].i;
00274             cgemv_("Conjugate transpose", &i__1, &i__2, &q__1, &a[rk + a_dim1]
00275 , lda, &a[rk + k * a_dim1], &c__1, &c_b1, &auxv[1], &c__1);
00276 
00277             i__1 = k - 1;
00278             cgemv_("No transpose", n, &i__1, &c_b2, &f[f_dim1 + 1], ldf, &
00279                     auxv[1], &c__1, &c_b2, &f[k * f_dim1 + 1], &c__1);
00280         }
00281 
00282 /*        Update the current row of A: */
00283 /*        A(RK,K+1:N) := A(RK,K+1:N) - A(RK,1:K)*F(K+1:N,1:K)'. */
00284 
00285         if (k < *n) {
00286             i__1 = *n - k;
00287             q__1.r = -1.f, q__1.i = -0.f;
00288             cgemm_("No transpose", "Conjugate transpose", &c__1, &i__1, &k, &
00289                     q__1, &a[rk + a_dim1], lda, &f[k + 1 + f_dim1], ldf, &
00290                     c_b2, &a[rk + (k + 1) * a_dim1], lda);
00291         }
00292 
00293 /*        Update partial column norms. */
00294 
00295         if (rk < lastrk) {
00296             i__1 = *n;
00297             for (j = k + 1; j <= i__1; ++j) {
00298                 if (vn1[j] != 0.f) {
00299 
00300 /*                 NOTE: The following 4 lines follow from the analysis in */
00301 /*                 Lapack Working Note 176. */
00302 
00303                     temp = c_abs(&a[rk + j * a_dim1]) / vn1[j];
00304 /* Computing MAX */
00305                     r__1 = 0.f, r__2 = (temp + 1.f) * (1.f - temp);
00306                     temp = dmax(r__1,r__2);
00307 /* Computing 2nd power */
00308                     r__1 = vn1[j] / vn2[j];
00309                     temp2 = temp * (r__1 * r__1);
00310                     if (temp2 <= tol3z) {
00311                         vn2[j] = (real) lsticc;
00312                         lsticc = j;
00313                     } else {
00314                         vn1[j] *= sqrt(temp);
00315                     }
00316                 }
00317 /* L50: */
00318             }
00319         }
00320 
00321         i__1 = rk + k * a_dim1;
00322         a[i__1].r = akk.r, a[i__1].i = akk.i;
00323 
00324 /*        End of while loop. */
00325 
00326         goto L10;
00327     }
00328     *kb = k;
00329     rk = *offset + *kb;
00330 
00331 /*     Apply the block reflector to the rest of the matrix: */
00332 /*     A(OFFSET+KB+1:M,KB+1:N) := A(OFFSET+KB+1:M,KB+1:N) - */
00333 /*                         A(OFFSET+KB+1:M,1:KB)*F(KB+1:N,1:KB)'. */
00334 
00335 /* Computing MIN */
00336     i__1 = *n, i__2 = *m - *offset;
00337     if (*kb < min(i__1,i__2)) {
00338         i__1 = *m - rk;
00339         i__2 = *n - *kb;
00340         q__1.r = -1.f, q__1.i = -0.f;
00341         cgemm_("No transpose", "Conjugate transpose", &i__1, &i__2, kb, &q__1, 
00342                  &a[rk + 1 + a_dim1], lda, &f[*kb + 1 + f_dim1], ldf, &c_b2, &
00343                 a[rk + 1 + (*kb + 1) * a_dim1], lda);
00344     }
00345 
00346 /*     Recomputation of difficult columns. */
00347 
00348 L60:
00349     if (lsticc > 0) {
00350         itemp = i_nint(&vn2[lsticc]);
00351         i__1 = *m - rk;
00352         vn1[lsticc] = scnrm2_(&i__1, &a[rk + 1 + lsticc * a_dim1], &c__1);
00353 
00354 /*        NOTE: The computation of VN1( LSTICC ) relies on the fact that */
00355 /*        SNRM2 does not fail on vectors with norm below the value of */
00356 /*        SQRT(DLAMCH('S')) */
00357 
00358         vn2[lsticc] = vn1[lsticc];
00359         lsticc = itemp;
00360         goto L60;
00361     }
00362 
00363     return 0;
00364 
00365 /*     End of CLAQPS */
00366 
00367 } /* claqps_ */


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