
template <typename Scalar>
void ei_qrfac(int m, int n, Scalar *a, int
        lda, int pivot, int *ipvt, Scalar *rdiag,
        Scalar *acnorm)
{
    /* System generated locals */
    int a_dim1, a_offset;

    /* Local variables */
    int i, j, k, jp1;
    Scalar sum;
    int kmax;
    Scalar temp;
    int minmn;
    Scalar ajnorm;

    Matrix< Scalar, Dynamic, 1 > wa(n+1);

    /* Parameter adjustments */
    --acnorm;
    --rdiag;
    a_dim1 = lda;
    a_offset = 1 + a_dim1 * 1;
    a -= a_offset;
    --ipvt;

    /* Function Body */
    const Scalar epsmch = epsilon<Scalar>();

    /*     compute the initial column norms and initialize several arrays. */

    for (j = 1; j <= n; ++j) {
        acnorm[j] = Map< Matrix< Scalar, Dynamic, 1 > >(&a[j * a_dim1 + 1],m).blueNorm();
        rdiag[j] = acnorm[j];
        wa[j] = rdiag[j];
        if (pivot) {
            ipvt[j] = j;
        }
        /* L10: */
    }

    /*     reduce a to r with householder transformations. */

    minmn = std::min(m,n);
    for (j = 1; j <= minmn; ++j) {
        if (! (pivot)) {
            goto L40;
        }

        /*        bring the column of largest norm into the pivot position. */

        kmax = j;
        for (k = j; k <= n; ++k) {
            if (rdiag[k] > rdiag[kmax]) {
                kmax = k;
            }
            /* L20: */
        }
        if (kmax == j) {
            goto L40;
        }
        for (i = 1; i <= m; ++i) {
            temp = a[i + j * a_dim1];
            a[i + j * a_dim1] = a[i + kmax * a_dim1];
            a[i + kmax * a_dim1] = temp;
            /* L30: */
        }
        rdiag[kmax] = rdiag[j];
        wa[kmax] = wa[j];
        k = ipvt[j];
        ipvt[j] = ipvt[kmax];
        ipvt[kmax] = k;
L40:

        /*        compute the householder transformation to reduce the */
        /*        j-th column of a to a multiple of the j-th unit vector. */

        ajnorm = Map< Matrix< Scalar, Dynamic, 1 > >(&a[j + j * a_dim1],m-j+1).blueNorm();
        if (ajnorm == 0.) {
            goto L100;
        }
        if (a[j + j * a_dim1] < 0.) {
            ajnorm = -ajnorm;
        }
        for (i = j; i <= m; ++i) {
            a[i + j * a_dim1] /= ajnorm;
            /* L50: */
        }
        a[j + j * a_dim1] += 1.;

        /*        apply the transformation to the remaining columns */
        /*        and update the norms. */

        jp1 = j + 1;
        if (n < jp1) {
            goto L100;
        }
        for (k = jp1; k <= n; ++k) {
            sum = 0.;
            for (i = j; i <= m; ++i) {
                sum += a[i + j * a_dim1] * a[i + k * a_dim1];
                /* L60: */
            }
            temp = sum / a[j + j * a_dim1];
            for (i = j; i <= m; ++i) {
                a[i + k * a_dim1] -= temp * a[i + j * a_dim1];
                /* L70: */
            }
            if (! (pivot) || rdiag[k] == 0.) {
                goto L80;
            }
            temp = a[j + k * a_dim1] / rdiag[k];
            /* Computing MAX */
            /* Computing 2nd power */
            rdiag[k] *= ei_sqrt((std::max(Scalar(0.), Scalar(1.)-ei_abs2(temp))));
            /* Computing 2nd power */
            if (Scalar(.05) * ei_abs2(rdiag[k] / wa[k]) > epsmch) {
                goto L80;
            }
            rdiag[k] = Map< Matrix< Scalar, Dynamic, 1 > >(&a[jp1 + k * a_dim1],m-j).blueNorm();
            wa[k] = rdiag[k];
L80:
            /* L90: */
            ;
        }
L100:
        rdiag[j] = -ajnorm;
        /* L110: */
    }
    return;

    /*     last card of subroutine qrfac. */

} /* qrfac_ */

