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


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