DenseMatrix RMAExpressMatrixReader::read(std::istream& input, unsigned int opts) const { //TODO: interpret the passed options if(readString_(input) != "RMAExpressionValues") { return DenseMatrix(0,0); } uint32_t version; input.read(reinterpret_cast<char*>(&version), 4); if(version != 1) { return DenseMatrix(0,0); } skipString_(input); // Skip the RMAExpress version number skipString_(input); // Skip the chiptype uint32_t nrows, ncols; input.read(reinterpret_cast<char*>(&ncols), 4); input.read(reinterpret_cast<char*>(&nrows), 4); std::vector<std::string> colnames(ncols); std::vector<std::string> rownames(nrows); readStringVector_(input, colnames); readStringVector_(input, rownames); DenseMatrix result(std::move(rownames), std::move(colnames)); input.read(reinterpret_cast<char*>(result.matrix().data()), nrows * ncols * sizeof(double)); return result; }
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 fraction_free_gaussian_elimination_solve(const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) { SYMENGINE_ASSERT(A.row_ == A.col_); SYMENGINE_ASSERT(b.row_ == A.row_ and x.row_ == A.row_); SYMENGINE_ASSERT(x.col_ == b.col_); int i, j, k, col = A.col_, bcol = b.col_; DenseMatrix A_ = DenseMatrix(A.row_, A.col_, A.m_); DenseMatrix b_ = DenseMatrix(b.row_, b.col_, b.m_); for (i = 0; i < col - 1; i++) for (j = i + 1; j < col; j++) { for (k = 0; k < bcol; k++) { b_.m_[j * bcol + k] = sub(mul(A_.m_[i * col + i], b_.m_[j * bcol + k]), mul(A_.m_[j * col + i], b_.m_[i * bcol + k])); if (i > 0) b_.m_[j * bcol + k] = div(b_.m_[j * bcol + k], A_.m_[i * col - col + i - 1]); } for (k = i + 1; k < col; k++) { A_.m_[j * col + k] = sub(mul(A_.m_[i * col + i], A_.m_[j * col + k]), mul(A_.m_[j * col + i], A_.m_[i * col + k])); if (i > 0) A_.m_[j * col + k] = div(A_.m_[j * col + k], A_.m_[i * col - col + i - 1]); } A_.m_[j * col + i] = zero; } for (i = 0; i < col * bcol; i++) x.m_[i] = zero; // Integer zero; for (k = 0; k < bcol; k++) { for (i = col - 1; i >= 0; i--) { for (j = i + 1; j < col; j++) b_.m_[i * bcol + k] = sub(b_.m_[i * bcol + k], mul(A_.m_[i * col + j], x.m_[j * bcol + k])); x.m_[i * bcol + k] = div(b_.m_[i * bcol + k], A_.m_[i * col + i]); } } }
DenseMatrix project(RandomAccessIterator begin, RandomAccessIterator end, FeatureVectorCallback callback, IndexType dimension, const IndexType max_iter, const ScalarType epsilon, const IndexType target_dimension, const DenseVector& mean_vector) { timed_context context("Data projection"); // The number of data points const IndexType n = end-begin; // Dense representation of the data points DenseVector current_vector(dimension); DenseMatrix X = DenseMatrix::Zero(dimension,n); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { callback.vector(*iter,current_vector); X.col(iter-begin) = current_vector - mean_vector; } // Initialize FA model // Initial variances DenseMatrix sig = DenseMatrix::Identity(dimension,dimension); // Initial linear mapping DenseMatrix A = DenseMatrix::Random(dimension, target_dimension).cwiseAbs(); // Main loop IndexType iter = 0; DenseMatrix invC,M,SC; ScalarType ll = 0, newll = 0; while (iter < max_iter) { ++iter; // Perform E-step // Compute the inverse of the covariance matrix invC = (A*A.transpose() + sig).inverse(); M = A.transpose()*invC*X; SC = n*(DenseMatrix::Identity(target_dimension,target_dimension) - A.transpose()*invC*A) + M*M.transpose(); // Perform M-step A = (X*M.transpose())*SC.inverse(); sig = DenseMatrix(((X*X.transpose() - A*M*X.transpose()).diagonal()/n).asDiagonal()).array() + epsilon; // Compute log-likelihood of FA model newll = 0.5*(log(invC.determinant()) - (invC*X).cwiseProduct(X).sum()/n); // Check for convergence if ((iter > 1) && (fabs(newll - ll) < epsilon)) break; ll = newll; } return X.transpose()*A; }
void fraction_free_gauss_jordan_solve(const DenseMatrix &A, const DenseMatrix &b, DenseMatrix &x) { SYMENGINE_ASSERT(A.row_ == A.col_); SYMENGINE_ASSERT(b.row_ == A.row_ and x.row_ == A.row_); SYMENGINE_ASSERT(x.col_ == b.col_); unsigned i, j, k, col = A.col_, bcol = b.col_; RCP<const Basic> d; DenseMatrix A_ = DenseMatrix(A.row_, A.col_, A.m_); DenseMatrix b_ = DenseMatrix(b.row_, b.col_, b.m_); for (i = 0; i < col; i++) { if (i > 0) d = A_.m_[i * col - col + i - 1]; for (j = 0; j < col; j++) if (j != i) { for (k = 0; k < bcol; k++) { b_.m_[j * bcol + k] = sub(mul(A_.m_[i * col + i], b_.m_[j * bcol + k]), mul(A_.m_[j * col + i], b_.m_[i * bcol + k])); if (i > 0) b_.m_[j * bcol + k] = div(b_.m_[j * bcol + k], d); } for (k = 0; k < col; k++) { if (k != i) { A_.m_[j * col + k] = sub(mul(A_.m_[i * col + i], A_.m_[j * col + k]), mul(A_.m_[j * col + i], A_.m_[i * col + k])); if (i > 0) A_.m_[j * col + k] = div(A_.m_[j * col + k], d); } } } for (j = 0; j < col; j++) if (j != i) A_.m_[j * col + i] = zero; } // No checks are done to see if the diagonal entries are zero for (k = 0; k < bcol; k++) for (i = 0; i < col; i++) x.m_[i * bcol + k] = div(b_.m_[i * bcol + k], A_.m_[i * col + i]); }
int main(int argc, char *argv[]) { // tests(); // srand(time(10)); srand(10); if(argc < 4) { std::cout << "Input arguments:\n\t1: Filename for A matrix (as in A ~= WH)\n\t2: New desired dimension\n\t3: Max NMF iterations\n\t4: Max NNLS iterations\n\t5 (optional): delimiter (space is default)\n"; } else { std::string filename = argv[1]; int newDimension = atoi(argv[2]); int max_iter_nmf = atoi(argv[3]); int max_iter_nnls = atoi(argv[4]); char delimiter = (argc > 5) ? *argv[5] : ' '; DenseMatrix* A = readMatrix(filename,delimiter); A->copyColumnToRow(); printf("Sparsity of A: %f\n",sparsity(A)); DenseMatrix W = DenseMatrix(A->rows,newDimension); DenseMatrix H = DenseMatrix(newDimension,A->cols); NMF_Input input = NMF_Input(&W,&H,A,max_iter_nmf,max_iter_nnls); std::cout << "Starting NMF computation." << std::endl; std::clock_t start = std::clock(); double duration; // nmf_cpu(input); nmf_cpu_profile(input); duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC; std::cout << "NMF computation complete. Time: " << duration << " s." << std::endl; W.copyColumnToRow(); dtype AF = FrobeniusNorm(A); dtype WH_AF = Fnorm(W,H,*A); printf("Objective value: %f\n",WH_AF/AF); // DenseMatrix z1 = DenseMatrix(A->rows,newDimension); // DenseMatrix z2 = DenseMatrix(newDimension,A->cols); // printf("Calculated solution approximate Frobenius norm: %f\n",Fnorm(z1,z2,*A)); // printcolmajor(H.colmajor,H.rows,H.cols); if(A) delete A; } return 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; } }
// ----------------------------- Determinant ---------------------------------// RCP<const Basic> det_bareis(const DenseMatrix &A) { SYMENGINE_ASSERT(A.row_ == A.col_); unsigned n = A.row_; if (n == 1) { return A.m_[0]; } else if (n == 2) { // If A = [[a, b], [c, d]] then det(A) = ad - bc return sub(mul(A.m_[0], A.m_[3]), mul(A.m_[1], A.m_[2])); } else if (n == 3) { // if A = [[a, b, c], [d, e, f], [g, h, i]] then // det(A) = (aei + bfg + cdh) - (ceg + bdi + afh) return sub(add(add(mul(mul(A.m_[0], A.m_[4]), A.m_[8]), mul(mul(A.m_[1], A.m_[5]), A.m_[6])), mul(mul(A.m_[2], A.m_[3]), A.m_[7])), add(add(mul(mul(A.m_[2], A.m_[4]), A.m_[6]), mul(mul(A.m_[1], A.m_[3]), A.m_[8])), mul(mul(A.m_[0], A.m_[5]), A.m_[7]))); } else { DenseMatrix B = DenseMatrix(n, n, A.m_); unsigned i, sign = 1; RCP<const Basic> d; for (unsigned k = 0; k < n - 1; k++) { if (eq(*(B.m_[k * n + k]), *zero)) { for (i = k + 1; i < n; i++) if (neq(*(B.m_[i * n + k]), *zero)) { row_exchange_dense(B, i, k); sign *= -1; break; } if (i == n) return zero; } for (i = k + 1; i < n; i++) { for (unsigned j = k + 1; j < n; j++) { d = sub(mul(B.m_[k * n + k], B.m_[i * n + j]), mul(B.m_[i * n + k], B.m_[k * n + j])); if (k > 0) d = div(d, B.m_[(k - 1) * n + k - 1]); B.m_[i * n + j] = d; } } } return (sign == 1) ? B.m_[n * n - 1] : mul(minus_one, B.m_[n * n - 1]); } }
void inverse_gauss_jordan(const DenseMatrix &A, DenseMatrix &B) { CSYMPY_ASSERT(A.row_ == A.col_ && B.row_ == B.col_ && B.row_ == A.row_); unsigned n = A.row_; DenseMatrix e = DenseMatrix(n, n); // Initialize matrices for (unsigned i = 0; i < n; i++) for (unsigned j = 0; j < n; j++) { if (i != j) { e.m_[i*n + j] = zero; } else { e.m_[i*n + i] = one; } B.m_[i*n + j] = zero; } fraction_free_gauss_jordan_solve(A, e, B); }
// Solve the diophantine system Ax = 0 and return a basis set for solutions // Reference: // Evelyne Contejean, Herve Devie. An Efficient Incremental Algorithm for // Solving // Systems of Linear Diophantine Equations. Information and computation, // 113(1):143-172, // August 1994. void homogeneous_lde(std::vector<DenseMatrix> &basis, const DenseMatrix &A) { unsigned p = A.nrows(); unsigned q = A.ncols(); unsigned n; SYMENGINE_ASSERT(p > 0 and q > 1); DenseMatrix row_zero(1, q); zeros(row_zero); DenseMatrix col_zero(p, 1); zeros(col_zero); std::vector<DenseMatrix> P; P.push_back(row_zero); std::vector<std::vector<bool>> Frozen(q, std::vector<bool>(q, true)); for (unsigned j = 0; j < q; j++) { Frozen[0][j] = false; } std::vector<bool> F(q, false); DenseMatrix t, transpose, product, T; RCP<const Integer> dot; product = DenseMatrix(p, 1); transpose = DenseMatrix(q, 1); while (P.size() > 0) { n = P.size() - 1; t = P[n]; P.pop_back(); t.transpose(transpose); A.mul_matrix(transpose, product); if (product.eq(col_zero) and not t.eq(row_zero)) { basis.push_back(t); } else { for (unsigned i = 0; i < q; i++) { F[i] = Frozen[n][i]; } T = t; for (unsigned i = 0; i < q; i++) { SYMENGINE_ASSERT(is_a<Integer>(*T.get(0, i))); T.set(0, i, rcp_static_cast<const Integer>(T.get(0, i)) ->addint(*one)); if (i > 0) { SYMENGINE_ASSERT(is_a<Integer>(*T.get(0, i - 1))); T.set(0, i - 1, rcp_static_cast<const Integer>(T.get(0, i - 1)) ->subint(*one)); } dot = zero; for (unsigned j = 0; j < p; j++) { SYMENGINE_ASSERT(is_a<Integer>(*product.get(j, 0))); RCP<const Integer> p_j0 = rcp_static_cast<const Integer>(product.get(j, 0)); SYMENGINE_ASSERT(is_a<Integer>(*A.get(j, i))); RCP<const Integer> A_ji = rcp_static_cast<const Integer>(A.get(j, i)); dot = dot->addint(*p_j0->mulint(*A_ji)); } if (F[i] == false and ((dot->is_negative() and is_minimum(T, basis, basis.size())) or t.eq(row_zero))) { P.push_back(T); n = n + 1; for (unsigned j = 0; j < q; j++) { Frozen[n - 1][j] = F[j]; } F[i] = true; } } } } }
// Returns the coefficients of characterisitc polynomials of leading principal // minors of Matrix A as elements in `polys`. Principal leading minor of kth // order is the submatrix of A obtained by deleting last n-k rows and columns // from A. Here `n` is the dimension of the square matrix A. void berkowitz(const DenseMatrix &A, std::vector<DenseMatrix> &polys) { SYMENGINE_ASSERT(A.row_ == A.col_); unsigned col = A.col_; unsigned i, k, l, m; std::vector<DenseMatrix> items; std::vector<DenseMatrix> transforms; std::vector<RCP<const Basic>> items_; for (unsigned n = col; n > 1; n--) { items.clear(); k = n - 1; DenseMatrix T = DenseMatrix(n + 1, n); DenseMatrix C = DenseMatrix(k, 1); // Initialize T and C for (i = 0; i < n * (n + 1); i++) T.m_[i] = zero; for (i = 0; i < k; i++) C.m_[i] = A.m_[i * col + k]; items.push_back(C); for (i = 0; i < n - 2; i++) { DenseMatrix B = DenseMatrix(k, 1); for (l = 0; l < k; l++) { B.m_[l] = zero; for (m = 0; m < k; m++) B.m_[l] = add(B.m_[l], mul(A.m_[l * col + m], items[i].m_[m])); } items.push_back(B); } items_.clear(); for (i = 0; i < n - 1; i++) { RCP<const Basic> element = zero; for (l = 0; l < k; l++) element = add(element, mul(A.m_[k * col + l], items[i].m_[l])); items_.push_back(mul(minus_one, element)); } items_.insert(items_.begin(), mul(minus_one, A.m_[k * col + k])); items_.insert(items_.begin(), one); for (i = 0; i < n; i++) { for (l = 0; l < n - i + 1; l++) T.m_[(i + l) * n + i] = items_[l]; } transforms.push_back(T); } polys.push_back(DenseMatrix(2, 1, {one, mul(A.m_[0], minus_one)})); for (i = 0; i < col - 1; i++) { unsigned t_row = transforms[col - 2 - i].nrows(); unsigned t_col = transforms[col - 2 - i].ncols(); DenseMatrix B = DenseMatrix(t_row, 1); for (l = 0; l < t_row; l++) { B.m_[l] = zero; for (m = 0; m < t_col; m++) { B.m_[l] = add(B.m_[l], mul(transforms[col - 2 - i].m_[l * t_col + m], polys[i].m_[m])); B.m_[l] = expand(B.m_[l]); } } polys.push_back(B); } }