zgehrd.c
Go to the documentation of this file.
00001 /* zgehrd.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_b2 = {1.,0.};
00019 static integer c__1 = 1;
00020 static integer c_n1 = -1;
00021 static integer c__3 = 3;
00022 static integer c__2 = 2;
00023 static integer c__65 = 65;
00024 
00025 /* Subroutine */ int zgehrd_(integer *n, integer *ilo, integer *ihi, 
00026         doublecomplex *a, integer *lda, doublecomplex *tau, doublecomplex *
00027         work, integer *lwork, integer *info)
00028 {
00029     /* System generated locals */
00030     integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
00031     doublecomplex z__1;
00032 
00033     /* Local variables */
00034     integer i__, j;
00035     doublecomplex t[4160]       /* was [65][64] */;
00036     integer ib;
00037     doublecomplex ei;
00038     integer nb, nh, nx, iws, nbmin, iinfo;
00039     extern /* Subroutine */ int zgemm_(char *, char *, integer *, integer *, 
00040             integer *, doublecomplex *, doublecomplex *, integer *, 
00041             doublecomplex *, integer *, doublecomplex *, doublecomplex *, 
00042             integer *), ztrmm_(char *, char *, char *, char *, 
00043              integer *, integer *, doublecomplex *, doublecomplex *, integer *
00044 , doublecomplex *, integer *), 
00045             zaxpy_(integer *, doublecomplex *, doublecomplex *, integer *, 
00046             doublecomplex *, integer *), zgehd2_(integer *, integer *, 
00047             integer *, doublecomplex *, integer *, doublecomplex *, 
00048             doublecomplex *, integer *), zlahr2_(integer *, integer *, 
00049             integer *, doublecomplex *, integer *, doublecomplex *, 
00050             doublecomplex *, integer *, doublecomplex *, integer *), xerbla_(
00051             char *, integer *);
00052     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00053             integer *, integer *);
00054     extern /* Subroutine */ int zlarfb_(char *, char *, char *, char *, 
00055             integer *, integer *, integer *, doublecomplex *, integer *, 
00056             doublecomplex *, integer *, doublecomplex *, integer *, 
00057             doublecomplex *, integer *);
00058     integer ldwork, lwkopt;
00059     logical lquery;
00060 
00061 
00062 /*  -- LAPACK routine (version 3.2) -- */
00063 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00064 /*     November 2006 */
00065 
00066 /*     .. Scalar Arguments .. */
00067 /*     .. */
00068 /*     .. Array Arguments .. */
00069 /*     .. */
00070 
00071 /*  Purpose */
00072 /*  ======= */
00073 
00074 /*  ZGEHRD reduces a complex general matrix A to upper Hessenberg form H by */
00075 /*  an unitary similarity transformation:  Q' * A * Q = H . */
00076 
00077 /*  Arguments */
00078 /*  ========= */
00079 
00080 /*  N       (input) INTEGER */
00081 /*          The order of the matrix A.  N >= 0. */
00082 
00083 /*  ILO     (input) INTEGER */
00084 /*  IHI     (input) INTEGER */
00085 /*          It is assumed that A is already upper triangular in rows */
00086 /*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally */
00087 /*          set by a previous call to ZGEBAL; otherwise they should be */
00088 /*          set to 1 and N respectively. See Further Details. */
00089 /*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. */
00090 
00091 /*  A       (input/output) COMPLEX*16 array, dimension (LDA,N) */
00092 /*          On entry, the N-by-N general matrix to be reduced. */
00093 /*          On exit, the upper triangle and the first subdiagonal of A */
00094 /*          are overwritten with the upper Hessenberg matrix H, and the */
00095 /*          elements below the first subdiagonal, with the array TAU, */
00096 /*          represent the unitary matrix Q as a product of elementary */
00097 /*          reflectors. See Further Details. */
00098 
00099 /*  LDA     (input) INTEGER */
00100 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00101 
00102 /*  TAU     (output) COMPLEX*16 array, dimension (N-1) */
00103 /*          The scalar factors of the elementary reflectors (see Further */
00104 /*          Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to */
00105 /*          zero. */
00106 
00107 /*  WORK    (workspace/output) COMPLEX*16 array, dimension (LWORK) */
00108 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */
00109 
00110 /*  LWORK   (input) INTEGER */
00111 /*          The length of the array WORK.  LWORK >= max(1,N). */
00112 /*          For optimum performance LWORK >= N*NB, where NB is the */
00113 /*          optimal blocksize. */
00114 
00115 /*          If LWORK = -1, then a workspace query is assumed; the routine */
00116 /*          only calculates the optimal size of the WORK array, returns */
00117 /*          this value as the first entry of the WORK array, and no error */
00118 /*          message related to LWORK is issued by XERBLA. */
00119 
00120 /*  INFO    (output) INTEGER */
00121 /*          = 0:  successful exit */
00122 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00123 
00124 /*  Further Details */
00125 /*  =============== */
00126 
00127 /*  The matrix Q is represented as a product of (ihi-ilo) elementary */
00128 /*  reflectors */
00129 
00130 /*     Q = H(ilo) H(ilo+1) . . . H(ihi-1). */
00131 
00132 /*  Each H(i) has the form */
00133 
00134 /*     H(i) = I - tau * v * v' */
00135 
00136 /*  where tau is a complex scalar, and v is a complex vector with */
00137 /*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on */
00138 /*  exit in A(i+2:ihi,i), and tau in TAU(i). */
00139 
00140 /*  The contents of A are illustrated by the following example, with */
00141 /*  n = 7, ilo = 2 and ihi = 6: */
00142 
00143 /*  on entry,                        on exit, */
00144 
00145 /*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a ) */
00146 /*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a ) */
00147 /*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h ) */
00148 /*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h ) */
00149 /*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h ) */
00150 /*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h ) */
00151 /*  (                         a )    (                          a ) */
00152 
00153 /*  where a denotes an element of the original matrix A, h denotes a */
00154 /*  modified element of the upper Hessenberg matrix H, and vi denotes an */
00155 /*  element of the vector defining H(i). */
00156 
00157 /*  This file is a slight modification of LAPACK-3.0's ZGEHRD */
00158 /*  subroutine incorporating improvements proposed by Quintana-Orti and */
00159 /*  Van de Geijn (2005). */
00160 
00161 /*  ===================================================================== */
00162 
00163 /*     .. Parameters .. */
00164 /*     .. */
00165 /*     .. Local Scalars .. */
00166 /*     .. */
00167 /*     .. Local Arrays .. */
00168 /*     .. */
00169 /*     .. External Subroutines .. */
00170 /*     .. */
00171 /*     .. Intrinsic Functions .. */
00172 /*     .. */
00173 /*     .. External Functions .. */
00174 /*     .. */
00175 /*     .. Executable Statements .. */
00176 
00177 /*     Test the input parameters */
00178 
00179     /* Parameter adjustments */
00180     a_dim1 = *lda;
00181     a_offset = 1 + a_dim1;
00182     a -= a_offset;
00183     --tau;
00184     --work;
00185 
00186     /* Function Body */
00187     *info = 0;
00188 /* Computing MIN */
00189     i__1 = 64, i__2 = ilaenv_(&c__1, "ZGEHRD", " ", n, ilo, ihi, &c_n1);
00190     nb = min(i__1,i__2);
00191     lwkopt = *n * nb;
00192     work[1].r = (doublereal) lwkopt, work[1].i = 0.;
00193     lquery = *lwork == -1;
00194     if (*n < 0) {
00195         *info = -1;
00196     } else if (*ilo < 1 || *ilo > max(1,*n)) {
00197         *info = -2;
00198     } else if (*ihi < min(*ilo,*n) || *ihi > *n) {
00199         *info = -3;
00200     } else if (*lda < max(1,*n)) {
00201         *info = -5;
00202     } else if (*lwork < max(1,*n) && ! lquery) {
00203         *info = -8;
00204     }
00205     if (*info != 0) {
00206         i__1 = -(*info);
00207         xerbla_("ZGEHRD", &i__1);
00208         return 0;
00209     } else if (lquery) {
00210         return 0;
00211     }
00212 
00213 /*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero */
00214 
00215     i__1 = *ilo - 1;
00216     for (i__ = 1; i__ <= i__1; ++i__) {
00217         i__2 = i__;
00218         tau[i__2].r = 0., tau[i__2].i = 0.;
00219 /* L10: */
00220     }
00221     i__1 = *n - 1;
00222     for (i__ = max(1,*ihi); i__ <= i__1; ++i__) {
00223         i__2 = i__;
00224         tau[i__2].r = 0., tau[i__2].i = 0.;
00225 /* L20: */
00226     }
00227 
00228 /*     Quick return if possible */
00229 
00230     nh = *ihi - *ilo + 1;
00231     if (nh <= 1) {
00232         work[1].r = 1., work[1].i = 0.;
00233         return 0;
00234     }
00235 
00236 /*     Determine the block size */
00237 
00238 /* Computing MIN */
00239     i__1 = 64, i__2 = ilaenv_(&c__1, "ZGEHRD", " ", n, ilo, ihi, &c_n1);
00240     nb = min(i__1,i__2);
00241     nbmin = 2;
00242     iws = 1;
00243     if (nb > 1 && nb < nh) {
00244 
00245 /*        Determine when to cross over from blocked to unblocked code */
00246 /*        (last block is always handled by unblocked code) */
00247 
00248 /* Computing MAX */
00249         i__1 = nb, i__2 = ilaenv_(&c__3, "ZGEHRD", " ", n, ilo, ihi, &c_n1);
00250         nx = max(i__1,i__2);
00251         if (nx < nh) {
00252 
00253 /*           Determine if workspace is large enough for blocked code */
00254 
00255             iws = *n * nb;
00256             if (*lwork < iws) {
00257 
00258 /*              Not enough workspace to use optimal NB:  determine the */
00259 /*              minimum value of NB, and reduce NB or force use of */
00260 /*              unblocked code */
00261 
00262 /* Computing MAX */
00263                 i__1 = 2, i__2 = ilaenv_(&c__2, "ZGEHRD", " ", n, ilo, ihi, &
00264                         c_n1);
00265                 nbmin = max(i__1,i__2);
00266                 if (*lwork >= *n * nbmin) {
00267                     nb = *lwork / *n;
00268                 } else {
00269                     nb = 1;
00270                 }
00271             }
00272         }
00273     }
00274     ldwork = *n;
00275 
00276     if (nb < nbmin || nb >= nh) {
00277 
00278 /*        Use unblocked code below */
00279 
00280         i__ = *ilo;
00281 
00282     } else {
00283 
00284 /*        Use blocked code */
00285 
00286         i__1 = *ihi - 1 - nx;
00287         i__2 = nb;
00288         for (i__ = *ilo; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
00289 /* Computing MIN */
00290             i__3 = nb, i__4 = *ihi - i__;
00291             ib = min(i__3,i__4);
00292 
00293 /*           Reduce columns i:i+ib-1 to Hessenberg form, returning the */
00294 /*           matrices V and T of the block reflector H = I - V*T*V' */
00295 /*           which performs the reduction, and also the matrix Y = A*V*T */
00296 
00297             zlahr2_(ihi, &i__, &ib, &a[i__ * a_dim1 + 1], lda, &tau[i__], t, &
00298                     c__65, &work[1], &ldwork);
00299 
00300 /*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the */
00301 /*           right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set */
00302 /*           to 1 */
00303 
00304             i__3 = i__ + ib + (i__ + ib - 1) * a_dim1;
00305             ei.r = a[i__3].r, ei.i = a[i__3].i;
00306             i__3 = i__ + ib + (i__ + ib - 1) * a_dim1;
00307             a[i__3].r = 1., a[i__3].i = 0.;
00308             i__3 = *ihi - i__ - ib + 1;
00309             z__1.r = -1., z__1.i = -0.;
00310             zgemm_("No transpose", "Conjugate transpose", ihi, &i__3, &ib, &
00311                     z__1, &work[1], &ldwork, &a[i__ + ib + i__ * a_dim1], lda, 
00312                      &c_b2, &a[(i__ + ib) * a_dim1 + 1], lda);
00313             i__3 = i__ + ib + (i__ + ib - 1) * a_dim1;
00314             a[i__3].r = ei.r, a[i__3].i = ei.i;
00315 
00316 /*           Apply the block reflector H to A(1:i,i+1:i+ib-1) from the */
00317 /*           right */
00318 
00319             i__3 = ib - 1;
00320             ztrmm_("Right", "Lower", "Conjugate transpose", "Unit", &i__, &
00321                     i__3, &c_b2, &a[i__ + 1 + i__ * a_dim1], lda, &work[1], &
00322                     ldwork);
00323             i__3 = ib - 2;
00324             for (j = 0; j <= i__3; ++j) {
00325                 z__1.r = -1., z__1.i = -0.;
00326                 zaxpy_(&i__, &z__1, &work[ldwork * j + 1], &c__1, &a[(i__ + j 
00327                         + 1) * a_dim1 + 1], &c__1);
00328 /* L30: */
00329             }
00330 
00331 /*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the */
00332 /*           left */
00333 
00334             i__3 = *ihi - i__;
00335             i__4 = *n - i__ - ib + 1;
00336             zlarfb_("Left", "Conjugate transpose", "Forward", "Columnwise", &
00337                     i__3, &i__4, &ib, &a[i__ + 1 + i__ * a_dim1], lda, t, &
00338                     c__65, &a[i__ + 1 + (i__ + ib) * a_dim1], lda, &work[1], &
00339                     ldwork);
00340 /* L40: */
00341         }
00342     }
00343 
00344 /*     Use unblocked code to reduce the rest of the matrix */
00345 
00346     zgehd2_(n, &i__, ihi, &a[a_offset], lda, &tau[1], &work[1], &iinfo);
00347     work[1].r = (doublereal) iws, work[1].i = 0.;
00348 
00349     return 0;
00350 
00351 /*     End of ZGEHRD */
00352 
00353 } /* zgehrd_ */


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