Example #1
0
 int dgehrd_(int *n, int *ilo, int *ihi, 
	double *a, int *lda, double *tau, double *work, 
	int *lwork, int *info)
{
    /* System generated locals */
    int a_dim1, a_offset, i__1, i__2, i__3, i__4;

    /* Local variables */
    int i__, j;
    double t[4160]	/* was [65][64] */;
    int ib;
    double ei;
    int nb, nh, nx, iws;
    extern  int dgemm_(char *, char *, int *, int *, 
	    int *, double *, double *, int *, double *, 
	    int *, double *, double *, int *);
    int nbmin, iinfo;
    extern  int dtrmm_(char *, char *, char *, char *, 
	    int *, int *, double *, double *, int *, 
	    double *, int *), daxpy_(
	    int *, double *, double *, int *, double *, 
	    int *), dgehd2_(int *, int *, int *, double *, 
	     int *, double *, double *, int *), dlahr2_(
	    int *, int *, int *, double *, int *, 
	    double *, double *, int *, double *, int *), 
	    dlarfb_(char *, char *, char *, char *, int *, int *, 
	    int *, double *, int *, double *, int *, 
	    double *, int *, double *, int *), xerbla_(char *, int *);
    extern int ilaenv_(int *, char *, char *, int *, int *, 
	    int *, int *);
    int ldwork, lwkopt;
    int lquery;


/*  -- LAPACK routine (version 3.2) -- */
/*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
/*     November 2006 */

/*     .. Scalar Arguments .. */
/*     .. */
/*     .. Array Arguments .. */
/*     .. */

/*  Purpose */
/*  ======= */

/*  DGEHRD reduces a float general matrix A to upper Hessenberg form H by */
/*  an orthogonal similarity transformation:  Q' * A * Q = H . */

/*  Arguments */
/*  ========= */

/*  N       (input) INTEGER */
/*          The order of the matrix A.  N >= 0. */

/*  ILO     (input) INTEGER */
/*  IHI     (input) INTEGER */
/*          It is assumed that A is already upper triangular in rows */
/*          and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally */
/*          set by a previous call to DGEBAL; otherwise they should be */
/*          set to 1 and N respectively. See Further Details. */
/*          1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0. */

/*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
/*          On entry, the N-by-N general matrix to be reduced. */
/*          On exit, the upper triangle and the first subdiagonal of A */
/*          are overwritten with the upper Hessenberg matrix H, and the */
/*          elements below the first subdiagonal, with the array TAU, */
/*          represent the orthogonal matrix Q as a product of elementary */
/*          reflectors. See Further Details. */

/*  LDA     (input) INTEGER */
/*          The leading dimension of the array A.  LDA >= MAX(1,N). */

/*  TAU     (output) DOUBLE PRECISION array, dimension (N-1) */
/*          The scalar factors of the elementary reflectors (see Further */
/*          Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to */
/*          zero. */

/*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (LWORK) */
/*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK. */

/*  LWORK   (input) INTEGER */
/*          The length of the array WORK.  LWORK >= MAX(1,N). */
/*          For optimum performance LWORK >= N*NB, where NB is the */
/*          optimal blocksize. */

/*          If LWORK = -1, then a workspace query is assumed; the routine */
/*          only calculates the optimal size of the WORK array, returns */
/*          this value as the first entry of the WORK array, and no error */
/*          message related to LWORK is issued by XERBLA. */

/*  INFO    (output) INTEGER */
/*          = 0:  successful exit */
/*          < 0:  if INFO = -i, the i-th argument had an illegal value. */

/*  Further Details */
/*  =============== */

/*  The matrix Q is represented as a product of (ihi-ilo) elementary */
/*  reflectors */

/*     Q = H(ilo) H(ilo+1) . . . H(ihi-1). */

/*  Each H(i) has the form */

/*     H(i) = I - tau * v * v' */

/*  where tau is a float scalar, and v is a float vector with */
/*  v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on */
/*  exit in A(i+2:ihi,i), and tau in TAU(i). */

/*  The contents of A are illustrated by the following example, with */
/*  n = 7, ilo = 2 and ihi = 6: */

/*  on entry,                        on exit, */

/*  ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a ) */
/*  (     a   a   a   a   a   a )    (      a   h   h   h   h   a ) */
/*  (     a   a   a   a   a   a )    (      h   h   h   h   h   h ) */
/*  (     a   a   a   a   a   a )    (      v2  h   h   h   h   h ) */
/*  (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h ) */
/*  (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h ) */
/*  (                         a )    (                          a ) */

/*  where a denotes an element of the original matrix A, h denotes a */
/*  modified element of the upper Hessenberg matrix H, and vi denotes an */
/*  element of the vector defining H(i). */

/*  This file is a slight modification of LAPACK-3.0's DGEHRD */
/*  subroutine incorporating improvements proposed by Quintana-Orti and */
/*  Van de Geijn (2005). */

/*  ===================================================================== */

/*     .. Parameters .. */
/*     .. */
/*     .. Local Scalars .. */
/*     .. */
/*     .. Local Arrays .. */
/*     .. */
/*     .. External Subroutines .. */
/*     .. */
/*     .. Intrinsic Functions .. */
/*     .. */
/*     .. External Functions .. */
/*     .. */
/*     .. Executable Statements .. */

/*     Test the input parameters */

    /* Parameter adjustments */
    a_dim1 = *lda;
    a_offset = 1 + a_dim1;
    a -= a_offset;
    --tau;
    --work;

    /* Function Body */
    *info = 0;
/* Computing MIN */
    i__1 = 64, i__2 = ilaenv_(&c__1, "DGEHRD", " ", n, ilo, ihi, &c_n1);
    nb = MIN(i__1,i__2);
    lwkopt = *n * nb;
    work[1] = (double) lwkopt;
    lquery = *lwork == -1;
    if (*n < 0) {
	*info = -1;
    } else if (*ilo < 1 || *ilo > MAX(1,*n)) {
	*info = -2;
    } else if (*ihi < MIN(*ilo,*n) || *ihi > *n) {
	*info = -3;
    } else if (*lda < MAX(1,*n)) {
	*info = -5;
    } else if (*lwork < MAX(1,*n) && ! lquery) {
	*info = -8;
    }
    if (*info != 0) {
	i__1 = -(*info);
	xerbla_("DGEHRD", &i__1);
	return 0;
    } else if (lquery) {
	return 0;
    }

/*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero */

    i__1 = *ilo - 1;
    for (i__ = 1; i__ <= i__1; ++i__) {
	tau[i__] = 0.;
/* L10: */
    }
    i__1 = *n - 1;
    for (i__ = MAX(1,*ihi); i__ <= i__1; ++i__) {
	tau[i__] = 0.;
/* L20: */
    }

/*     Quick return if possible */

    nh = *ihi - *ilo + 1;
    if (nh <= 1) {
	work[1] = 1.;
	return 0;
    }

/*     Determine the block size */

/* Computing MIN */
    i__1 = 64, i__2 = ilaenv_(&c__1, "DGEHRD", " ", n, ilo, ihi, &c_n1);
    nb = MIN(i__1,i__2);
    nbmin = 2;
    iws = 1;
    if (nb > 1 && nb < nh) {

/*        Determine when to cross over from blocked to unblocked code */
/*        (last block is always handled by unblocked code) */

/* Computing MAX */
	i__1 = nb, i__2 = ilaenv_(&c__3, "DGEHRD", " ", n, ilo, ihi, &c_n1);
	nx = MAX(i__1,i__2);
	if (nx < nh) {

/*           Determine if workspace is large enough for blocked code */

	    iws = *n * nb;
	    if (*lwork < iws) {

/*              Not enough workspace to use optimal NB:  determine the */
/*              minimum value of NB, and reduce NB or force use of */
/*              unblocked code */

/* Computing MAX */
		i__1 = 2, i__2 = ilaenv_(&c__2, "DGEHRD", " ", n, ilo, ihi, &
			c_n1);
		nbmin = MAX(i__1,i__2);
		if (*lwork >= *n * nbmin) {
		    nb = *lwork / *n;
		} else {
		    nb = 1;
		}
	    }
	}
    }
    ldwork = *n;

    if (nb < nbmin || nb >= nh) {

/*        Use unblocked code below */

	i__ = *ilo;

    } else {

/*        Use blocked code */

	i__1 = *ihi - 1 - nx;
	i__2 = nb;
	for (i__ = *ilo; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
/* Computing MIN */
	    i__3 = nb, i__4 = *ihi - i__;
	    ib = MIN(i__3,i__4);

/*           Reduce columns i:i+ib-1 to Hessenberg form, returning the */
/*           matrices V and T of the block reflector H = I - V*T*V' */
/*           which performs the reduction, and also the matrix Y = A*V*T */

	    dlahr2_(ihi, &i__, &ib, &a[i__ * a_dim1 + 1], lda, &tau[i__], t, &
		    c__65, &work[1], &ldwork);

/*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the */
/*           right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set */
/*           to 1 */

	    ei = a[i__ + ib + (i__ + ib - 1) * a_dim1];
	    a[i__ + ib + (i__ + ib - 1) * a_dim1] = 1.;
	    i__3 = *ihi - i__ - ib + 1;
	    dgemm_("No transpose", "Transpose", ihi, &i__3, &ib, &c_b25, &
		    work[1], &ldwork, &a[i__ + ib + i__ * a_dim1], lda, &
		    c_b26, &a[(i__ + ib) * a_dim1 + 1], lda);
	    a[i__ + ib + (i__ + ib - 1) * a_dim1] = ei;

/*           Apply the block reflector H to A(1:i,i+1:i+ib-1) from the */
/*           right */

	    i__3 = ib - 1;
	    dtrmm_("Right", "Lower", "Transpose", "Unit", &i__, &i__3, &c_b26, 
		     &a[i__ + 1 + i__ * a_dim1], lda, &work[1], &ldwork);
	    i__3 = ib - 2;
	    for (j = 0; j <= i__3; ++j) {
		daxpy_(&i__, &c_b25, &work[ldwork * j + 1], &c__1, &a[(i__ + 
			j + 1) * a_dim1 + 1], &c__1);
/* L30: */
	    }

/*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the */
/*           left */

	    i__3 = *ihi - i__;
	    i__4 = *n - i__ - ib + 1;
	    dlarfb_("Left", "Transpose", "Forward", "Columnwise", &i__3, &
		    i__4, &ib, &a[i__ + 1 + i__ * a_dim1], lda, t, &c__65, &a[
		    i__ + 1 + (i__ + ib) * a_dim1], lda, &work[1], &ldwork);
/* L40: */
	}
    }

/*     Use unblocked code to reduce the rest of the matrix */

    dgehd2_(n, &i__, ihi, &a[a_offset], lda, &tau[1], &work[1], &iinfo);
    work[1] = (double) iws;

    return 0;

/*     End of DGEHRD */

} /* dgehrd_ */
Example #2
0
/* Subroutine */ int dgehrd_(integer *n, integer *ilo, integer *ihi,
                             doublereal *a, integer *lda, doublereal *tau, doublereal *work,
                             integer *lwork, integer *info)
{
    /*  -- LAPACK routine (version 3.0) --
           Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
           Courant Institute, Argonne National Lab, and Rice University
           June 30, 1999


        Purpose
        =======

        DGEHRD reduces a real general matrix A to upper Hessenberg form H by
        an orthogonal similarity transformation:  Q' * A * Q = H .

        Arguments
        =========

        N       (input) INTEGER
                The order of the matrix A.  N >= 0.

        ILO     (input) INTEGER
        IHI     (input) INTEGER
                It is assumed that A is already upper triangular in rows
                and columns 1:ILO-1 and IHI+1:N. ILO and IHI are normally
                set by a previous call to DGEBAL; otherwise they should be
                set to 1 and N respectively. See Further Details.
                1 <= ILO <= IHI <= N, if N > 0; ILO=1 and IHI=0, if N=0.

        A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
                On entry, the N-by-N general matrix to be reduced.
                On exit, the upper triangle and the first subdiagonal of A
                are overwritten with the upper Hessenberg matrix H, and the
                elements below the first subdiagonal, with the array TAU,
                represent the orthogonal matrix Q as a product of elementary
                reflectors. See Further Details.

        LDA     (input) INTEGER
                The leading dimension of the array A.  LDA >= max(1,N).

        TAU     (output) DOUBLE PRECISION array, dimension (N-1)
                The scalar factors of the elementary reflectors (see Further
                Details). Elements 1:ILO-1 and IHI:N-1 of TAU are set to
                zero.

        WORK    (workspace/output) DOUBLE PRECISION array, dimension (LWORK)
                On exit, if INFO = 0, WORK(1) returns the optimal LWORK.

        LWORK   (input) INTEGER
                The length of the array WORK.  LWORK >= max(1,N).
                For optimum performance LWORK >= N*NB, where NB is the
                optimal blocksize.

                If LWORK = -1, then a workspace query is assumed; the routine
                only calculates the optimal size of the WORK array, returns
                this value as the first entry of the WORK array, and no error
                message related to LWORK is issued by XERBLA.

        INFO    (output) INTEGER
                = 0:  successful exit
                < 0:  if INFO = -i, the i-th argument had an illegal value.

        Further Details
        ===============

        The matrix Q is represented as a product of (ihi-ilo) elementary
        reflectors

           Q = H(ilo) H(ilo+1) . . . H(ihi-1).

        Each H(i) has the form

           H(i) = I - tau * v * v'

        where tau is a real scalar, and v is a real vector with
        v(1:i) = 0, v(i+1) = 1 and v(ihi+1:n) = 0; v(i+2:ihi) is stored on
        exit in A(i+2:ihi,i), and tau in TAU(i).

        The contents of A are illustrated by the following example, with
        n = 7, ilo = 2 and ihi = 6:

        on entry,                        on exit,

        ( a   a   a   a   a   a   a )    (  a   a   h   h   h   h   a )
        (     a   a   a   a   a   a )    (      a   h   h   h   h   a )
        (     a   a   a   a   a   a )    (      h   h   h   h   h   h )
        (     a   a   a   a   a   a )    (      v2  h   h   h   h   h )
        (     a   a   a   a   a   a )    (      v2  v3  h   h   h   h )
        (     a   a   a   a   a   a )    (      v2  v3  v4  h   h   h )
        (                         a )    (                          a )

        where a denotes an element of the original matrix A, h denotes a
        modified element of the upper Hessenberg matrix H, and vi denotes an
        element of the vector defining H(i).

        =====================================================================


           Test the input parameters

           Parameter adjustments */
    /* Table of constant values */
    static integer c__1 = 1;
    static integer c_n1 = -1;
    static integer c__3 = 3;
    static integer c__2 = 2;
    static integer c__65 = 65;
    static doublereal c_b25 = -1.;
    static doublereal c_b26 = 1.;

    /* System generated locals */
    integer a_dim1, a_offset, i__1, i__2, i__3, i__4;
    /* Local variables */
    static integer i__;
    static doublereal t[4160]	/* was [65][64] */;
    extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *,
                                       integer *, doublereal *, doublereal *, integer *, doublereal *,
                                       integer *, doublereal *, doublereal *, integer *);
    static integer nbmin, iinfo;
    extern /* Subroutine */ int dgehd2_(integer *, integer *, integer *,
                                        doublereal *, integer *, doublereal *, doublereal *, integer *);
    static integer ib;
    static doublereal ei;
    static integer nb, nh;
    extern /* Subroutine */ int dlarfb_(char *, char *, char *, char *,
                                        integer *, integer *, integer *, doublereal *, integer *,
                                        doublereal *, integer *, doublereal *, integer *, doublereal *,
                                        integer *), dlahrd_(integer *,
                                                integer *, integer *, doublereal *, integer *, doublereal *,
                                                doublereal *, integer *, doublereal *, integer *);
    static integer nx;
    extern /* Subroutine */ int xerbla_(char *, integer *);
    extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
                           integer *, integer *, ftnlen, ftnlen);
    static integer ldwork, lwkopt;
    static logical lquery;
    static integer iws;
#define a_ref(a_1,a_2) a[(a_2)*a_dim1 + a_1]


    a_dim1 = *lda;
    a_offset = 1 + a_dim1 * 1;
    a -= a_offset;
    --tau;
    --work;

    /* Function Body */
    *info = 0;
    /* Computing MIN */
    i__1 = 64, i__2 = ilaenv_(&c__1, "DGEHRD", " ", n, ilo, ihi, &c_n1, (
                                  ftnlen)6, (ftnlen)1);
    nb = min(i__1,i__2);
    lwkopt = *n * nb;
    work[1] = (doublereal) lwkopt;
    lquery = *lwork == -1;
    if (*n < 0) {
        *info = -1;
    } else if (*ilo < 1 || *ilo > max(1,*n)) {
        *info = -2;
    } else if (*ihi < min(*ilo,*n) || *ihi > *n) {
        *info = -3;
    } else if (*lda < max(1,*n)) {
        *info = -5;
    } else if (*lwork < max(1,*n) && ! lquery) {
        *info = -8;
    }
    if (*info != 0) {
        i__1 = -(*info);
        xerbla_("DGEHRD", &i__1);
        return 0;
    } else if (lquery) {
        return 0;
    }

    /*     Set elements 1:ILO-1 and IHI:N-1 of TAU to zero */

    i__1 = *ilo - 1;
    for (i__ = 1; i__ <= i__1; ++i__) {
        tau[i__] = 0.;
        /* L10: */
    }
    i__1 = *n - 1;
    for (i__ = max(1,*ihi); i__ <= i__1; ++i__) {
        tau[i__] = 0.;
        /* L20: */
    }

    /*     Quick return if possible */

    nh = *ihi - *ilo + 1;
    if (nh <= 1) {
        work[1] = 1.;
        return 0;
    }

    /*     Determine the block size.

       Computing MIN */
    i__1 = 64, i__2 = ilaenv_(&c__1, "DGEHRD", " ", n, ilo, ihi, &c_n1, (
                                  ftnlen)6, (ftnlen)1);
    nb = min(i__1,i__2);
    nbmin = 2;
    iws = 1;
    if (nb > 1 && nb < nh) {

        /*        Determine when to cross over from blocked to unblocked code
                  (last block is always handled by unblocked code).

           Computing MAX */
        i__1 = nb, i__2 = ilaenv_(&c__3, "DGEHRD", " ", n, ilo, ihi, &c_n1, (
                                      ftnlen)6, (ftnlen)1);
        nx = max(i__1,i__2);
        if (nx < nh) {

            /*           Determine if workspace is large enough for blocked code. */

            iws = *n * nb;
            if (*lwork < iws) {

                /*              Not enough workspace to use optimal NB:  determine the
                                minimum value of NB, and reduce NB or force use of
                                unblocked code.

                   Computing MAX */
                i__1 = 2, i__2 = ilaenv_(&c__2, "DGEHRD", " ", n, ilo, ihi, &
                                         c_n1, (ftnlen)6, (ftnlen)1);
                nbmin = max(i__1,i__2);
                if (*lwork >= *n * nbmin) {
                    nb = *lwork / *n;
                } else {
                    nb = 1;
                }
            }
        }
    }
    ldwork = *n;

    if (nb < nbmin || nb >= nh) {

        /*        Use unblocked code below */

        i__ = *ilo;

    } else {

        /*        Use blocked code */

        i__1 = *ihi - 1 - nx;
        i__2 = nb;
        for (i__ = *ilo; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
            /* Computing MIN */
            i__3 = nb, i__4 = *ihi - i__;
            ib = min(i__3,i__4);

            /*           Reduce columns i:i+ib-1 to Hessenberg form, returning the
                         matrices V and T of the block reflector H = I - V*T*V'
                         which performs the reduction, and also the matrix Y = A*V*T */

            dlahrd_(ihi, &i__, &ib, &a_ref(1, i__), lda, &tau[i__], t, &c__65,
                    &work[1], &ldwork);

            /*           Apply the block reflector H to A(1:ihi,i+ib:ihi) from the
                         right, computing  A := A - Y * V'. V(i+ib,ib-1) must be set
                         to 1. */

            ei = a_ref(i__ + ib, i__ + ib - 1);
            a_ref(i__ + ib, i__ + ib - 1) = 1.;
            i__3 = *ihi - i__ - ib + 1;
            dgemm_("No transpose", "Transpose", ihi, &i__3, &ib, &c_b25, &
                   work[1], &ldwork, &a_ref(i__ + ib, i__), lda, &c_b26, &
                   a_ref(1, i__ + ib), lda);
            a_ref(i__ + ib, i__ + ib - 1) = ei;

            /*           Apply the block reflector H to A(i+1:ihi,i+ib:n) from the
                         left */

            i__3 = *ihi - i__;
            i__4 = *n - i__ - ib + 1;
            dlarfb_("Left", "Transpose", "Forward", "Columnwise", &i__3, &
                    i__4, &ib, &a_ref(i__ + 1, i__), lda, t, &c__65, &a_ref(
                        i__ + 1, i__ + ib), lda, &work[1], &ldwork);
            /* L30: */
        }
    }

    /*     Use unblocked code to reduce the rest of the matrix */

    dgehd2_(n, &i__, ihi, &a[a_offset], lda, &tau[1], &work[1], &iinfo);
    work[1] = (doublereal) iws;

    return 0;

    /*     End of DGEHRD */

} /* dgehrd_ */