Ejemplo n.º 1
0
void LU_solve(const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x)
{
    DenseMatrix L = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix U = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix x_ = DenseMatrix(b.nrows(), b.ncols());

    LU(A, L, U);
    forward_substitution(L, b, x_);
    back_substitution(U, x_, x);
}
Ejemplo n.º 2
0
void fraction_free_LU_solve(const DenseMatrix &A, const DenseMatrix &b,
                            DenseMatrix &x)
{
    DenseMatrix LU = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix x_ = DenseMatrix(b.nrows(), b.ncols());

    fraction_free_LU(A, LU);
    forward_substitution(LU, b, x_);
    back_substitution(LU, x_, x);
}
Ejemplo n.º 3
0
void pivoted_LU_solve(const DenseMatrix &A, const DenseMatrix &b,
                      DenseMatrix &x)
{
    DenseMatrix L = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix U = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix x_ = DenseMatrix(b);
    permutelist pl;

    pivoted_LU(A, L, U, pl);
    permuteFwd(x_, pl);
    forward_substitution(L, x_, x_);
    back_substitution(U, x_, x);
}
Ejemplo n.º 4
0
void LDL_solve(const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x)
{
    DenseMatrix L = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix D = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix x_ = DenseMatrix(b.nrows(), b.ncols());

    if (not is_symmetric_dense(A))
        throw SymEngineException("Matrix must be symmetric");

    LDL(A, L, D);
    forward_substitution(L, b, x);
    diagonal_solve(D, x, x_);
    transpose_dense(L, D);
    back_substitution(D, x_, x);
}
Ejemplo n.º 5
0
void LDL_solve(const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x)
{
    DenseMatrix L = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix D = DenseMatrix(A.nrows(), A.ncols());
    DenseMatrix x_ = DenseMatrix(b.nrows(), 1);

    if (!is_symmetric_dense(A))
        throw std::runtime_error("Matrix must be symmetric");

    LDL(A, L, D);
    forward_substitution(L, b, x);
    diagonal_solve(D, x, x_);
    transpose_dense(L, D);
    back_substitution(D, x_, x);
}
Ejemplo n.º 6
0
void inverse_LU(const DenseMatrix &A, DenseMatrix &B)
{
    SYMENGINE_ASSERT(A.row_ == A.col_ and B.row_ == B.col_
                     and B.row_ == A.row_);

    unsigned n = A.row_, i;
    DenseMatrix L = DenseMatrix(n, n);
    DenseMatrix U = DenseMatrix(n, n);
    DenseMatrix e = DenseMatrix(n, 1);
    DenseMatrix x = DenseMatrix(n, 1);
    DenseMatrix x_ = DenseMatrix(n, 1);

    // Initialize matrices
    for (i = 0; i < n * n; i++) {
        L.m_[i] = zero;
        U.m_[i] = zero;
        B.m_[i] = zero;
    }

    for (i = 0; i < n; i++) {
        e.m_[i] = zero;
        x.m_[i] = zero;
        x_.m_[i] = zero;
    }

    LU(A, L, U);

    // We solve AX_{i} = e_{i} for i = 1, 2, .. n and combine the column vectors
    // X_{1}, X_{2}, ... X_{n} to form the inverse of A. Here, e_{i}'s are the
    // elements of the standard basis.
    for (unsigned j = 0; j < n; j++) {
        e.m_[j] = one;

        forward_substitution(L, e, x_);
        back_substitution(U, x_, x);

        for (i = 0; i < n; i++)
            B.m_[i * n + j] = x.m_[i];

        e.m_[j] = zero;
    }
}
Ejemplo n.º 7
0
/*
 * LARS algorithm.
 *
 *
 * Suppose we expect a response variable to be determined by a linear
 * combination of a subset of potential covariates. Then the LARS
 * algorithm provides a means of producing an estimate of which
 * variables to include, as well as their coefficients.
 *
 * Instead of giving a vector result, the LARS solution consists of a
 * curve denoting the solution for each value of the L1 norm of the
 * parameter vector. The algorithm is similar to forward stepwise
 * regression, but instead of including variables at each step, the
 * estimated parameters are increased in a direction equiangular to
 * each one's correlations with the residual.
 *
 *
 * Parameters
 * ----------
 * predictors are expected to be normalized
 *
 *  X is (features, nsamples), b is (nsamples,1)
 *
 * beta is the returned array with the parameters of the regression
 * problem.
 *
 * b will be modified to store the current residual.
 *
 * TODO
 * ----
 * The case when two vectors have equal correlation.
 *
 */
void lars_fit(double *X, double *b, double *beta, int *ind, double *L, int nfeatures, int nsamples, int stop)
{
    /* temp variables. way too much */
    double *dir = (double *) calloc(nsamples, sizeof(double));
    double *dd  = (double *) malloc(nfeatures * sizeof(double));
    double *w   = (double *) malloc(nfeatures * sizeof(double));
    double *v   = (double *) malloc(nsamples * sizeof(double));
    /* TODO: we could use v and w as the same */

    double gamma = 0, tgamma, temp, cov_max, Aa = 0;
    int i, j, k, sum_k=0, sign;

    struct dllist *unused, *used_indices, *cur;
    struct dllist *pmax; /* maximum covariance (current working variable) */

    unused = (struct dllist *) malloc((nfeatures+2) * sizeof(struct dllist));

    /* if stop == nfeatures: raise Exception */

    /* create index table as a linked list */
    for (i=0; i<=nfeatures; ++i) {
        unused[i].index = i-1;
        unused[i].next = unused + i + 1;
        unused[i].prev = unused + i - 1;
    }
    cur = unused + nfeatures;
    used_indices = cur->next;

    /* set sentinels */
    used_indices->prev = NULL;
    cur->next = NULL;

    /* main loop, we iterate over the user-suplied number of iterations */
    for (k=0; k < stop; ++k) {

        /* Update residual */
        for (i=0, cur=used_indices; cur;  cur=cur->prev, ++i) {
            temp = 0;
            for (j = 0; j<k; ++j)
                temp += X[i*nsamples + ind[j]] * beta[sum_k + j];
            b[ind[i]] -= temp;
        }

        cov_max = 0;
        /* calculate covariances (c_hat), and get maximum covariance (C_hat)*/
        for (cur = unused->next; cur; cur = cur->next) {
            temp = cblas_ddot (nsamples, X + cur->index, nfeatures, b, 1);
            cur->cov = temp;
            if (fabs(temp) > cov_max) {
                sign = copysign (1.0, temp);
                cov_max = fabs (temp);
                pmax = cur;
            }
        }

        /* add pmax to the active set */
        pmax->prev->next = pmax->next;
        if (pmax->next) pmax->next->prev = pmax->prev;
        pmax->prev = used_indices;
        used_indices = pmax;

        /*
         * We compute some intermediate results that we will need to
         * compute the least-squares direction.
         */
        for (i=k, cur=used_indices; cur; cur=cur->prev, --i) {
            /*
             * To update the cholesky decomposition, we need to calculate
             *
             *                    v  = Xa' * cur
             *                    dd = Xa' * res
             *
             * where res is the current residual and cur is the last
             * vector to enter the active set.
             */
            v[i] = sign * cblas_ddot(nsamples, X + cur->index, nfeatures, X + pmax->index, nfeatures);
            dd[i] = cur->cov;
        }

        /*
         * Compute least squares solution by the method of normal equations
         * (Golub & Van Loan, 1996)
         *
         * Update L:
         *          ( L   w )
         *   L  ->  (       )  ,  where w = (L^-1) v
         *          ( 0  Ln )
         *
         * And solve ...
         *
         * sum_k is the number such that L[sum_k] is the first
         * unwritten field in L.
         *
         */
        sum_k = k * (k+1) / 2;
        back_substitution (L, v, L + sum_k, k);
        L[sum_k + k] = sqrt (cblas_dnrm2(nsamples, X + pmax->index, nfeatures)  - \
                             cblas_dnrm2(k, L + sum_k, 1));
        forward_substitution (L, dd, w, k + 1);
        back_substitution (L, w, dir, k + 1); /* dir is now the least squares direction */

        /*
         * Compute gamma.
         * We iterate over unused indices.
         */
        Aa = pmax->cov;
        gamma = INFINITY;
        for (cur = unused->next; cur; cur = cur->next) {
            temp = cblas_ddot(nsamples, X + cur->index, nfeatures, b, 1);
            tgamma = fmin_pos (cov_max - cur->cov / (Aa - temp),
                               cov_max + cur->cov / (Aa + temp));
            gamma = fmin (tgamma, gamma);
        }

        /* Set up return values */
        ind[k] = pmax->index;
        for(i=0; i<k; ++i) {
            beta[sum_k + i] = beta[sum_k - k + i] + gamma * dir[i];
        }
        beta[sum_k + k] = gamma * dir[k];
    }

    free(v);
    free(dir);
    free(unused);
}