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); }
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); }
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); }
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); }
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); }
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; } }
/* * 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); }