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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:41