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


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