//PROTOTYPE IMPL!!!!!!!! //BUG BUG Result ought to be dense/sparse/diag according as M is.... matrix apply(RingHom phi, ConstMatrixView M) { CoCoA_ASSERT(domain(phi) == RingOf(M)); matrix NewM(NewDenseMat(codomain(phi), NumRows(M), NumCols(M))); for (long i=0; i < NumRows(M); ++i) for (long j=0; j < NumCols(M); ++j) SetEntry(NewM, i, j, phi(M(i,j))); return NewM; }
void CNumMat::operator-=(const CNumMat &m) { assert(NumCols()==m.NumCols()); assert(NumRows()==m.NumRows()); if(gsl_matrix_sub(m_mat,m.m_mat)) throw BPException("gsl_matrix_sub"); }
const double &CNumMat::operator()(unsigned row, unsigned col) const { assert(m_mat!=NULL); assert(row<NumRows()); assert(col<NumCols()); return(*gsl_matrix_ptr(m_mat,row, col)); }
// Simple rather than efficient (esp. the call to eval) std::vector<RingElem> BM_generic(const SparsePolyRing& P, const ConstMatrixView& pts) { if (CoeffRing(P) != RingOf(pts)) CoCoA_ERROR(ERR::MixedRings, "Buchberger-Moeller"); if (NumIndets(P) < NumCols(pts)) CoCoA_ERROR(ERR::IncompatDims, "Buchberger-Moeller"); const long NumPts = NumRows(pts); const long dim = NumCols(pts); const ring k = CoeffRing(P); vector<RingElem> GB; const PPMonoid TT = PPM(P); QBGenerator QBG(TT); QBG.myCornerPPIntoQB(one(TT)); matrix M = NewDenseMat(k, 1, NumPts); // Fill first row with 1: for (int i=0; i<NumPts; ++i) SetEntry(M,0,i, 1); // The next loop removes the last indets from consideration. for (int i=dim; i < NumIndets(TT); ++i) QBG.myCornerPPIntoAvoidSet(indet(TT,i)); while (!QBG.myCorners().empty()) { const PPMonoidElem t = QBG.myCorners().front(); const vector<RingElem> v = eval(t, pts); ConstMatrixView NewRow = RowMat(v); const matrix a = LinSolve(transpose(M), transpose(NewRow)); if (IsValidSolution(a)) { QBG.myCornerPPIntoAvoidSet(t); RingElem NewGBElem = monomial(P, one(k), t); const vector<PPMonoidElem>& QB = QBG.myQB(); for (int i=0; i < NumRows(M); ++i) NewGBElem -= monomial(P, a(i,0), QB[i]); GB.push_back(NewGBElem); } else { QBG.myCornerPPIntoQB(t); M = NewDenseMat(ConcatVer(M, NewRow)); } } return GB; }
// I bet this makes lots of wasteful copies... matrix NewDenseMat(ConstMatrixView M) { const long r = NumRows(M); const long c = NumCols(M); matrix ans(new DenseMatImpl(RingOf(M), r, c)); for (long i=0; i < r; ++i) for (long j=0; j < c; ++j) SetEntry(ans, i, j, M(i, j)); return ans; }
void CNumMat::resize(unsigned rows, unsigned cols) { assert(rows>0 && cols>0); if(m_mat!=NULL) { if(NumRows()==rows && NumCols()==cols) return; gsl_matrix_free(m_mat); } m_mat=gsl_matrix_alloc(rows,cols); }
ideal IdealOfPoints(const SparsePolyRing& P, const ConstMatrixView& M) { if (CoeffRing(P) != RingOf(M)) CoCoA_ERROR(ERR::MixedRings, "IdealOfPoints"); if (NumIndets(P) != NumCols(M)) CoCoA_ERROR(ERR::BadMatrixSize, "IdealOfPoints"); if (DuplicateRows(M)) CoCoA_ERROR("Duplicate points", "IdealOfPoints"); ideal I(P, std::vector<RingElem>(0)); if (IsFiniteField(CoeffRing(P))) I = ideal(P, BM_modp(P, M)); else if (IsQQ(CoeffRing(P))) I = ideal(P, BM_QQ(P, M)); // generic case else I = ideal(P, BM_generic(P, M)); SetGBasisAsGens(I); return I; }
/* CloneSMatrix: return a clone of given Matrix */ SMatrix CloneSMatrix(MemHeap *hmem, SMatrix s, Boolean sharing) { SMatrix t; /* the target */ if (s==NULL) return NULL; if (GetUse(s)>0 && sharing) { IncUse(s); return s; } t = CreateSMatrix(hmem,NumRows(s),NumCols(s)); CopyMatrix(s,t); return t; }
bool DuplicateRows(const ConstMatrixView& M) { const long nrows = NumRows(M); const long ncols = NumCols(M); for (long i1=0; i1 < nrows; ++i1) for (long i2=i1+1; i2 < nrows; ++i2) { bool NoDifference = true; for (long j=0; NoDifference && j < ncols; ++j) NoDifference = (M(i1,j) == M(i2,j)); if (NoDifference) return true; } return false; }
PODVector<CubeTerrain*>* Terrain::GetColumnCubes(CubeTerrain *cube, DIR dir) { const int dRow[8] = { 0, -1, -1, -1, 0, 1, 1, 1}; const int dCol[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; uint row = (uint)((int)cube->row + dRow[dir]); uint col = (uint)((int)cube->col + dCol[dir]); if(row > NumRows() - 1 || col > NumCols() - 1) { return nullptr; } return &columnsCubes[row][col]; }
std::vector<RingElem> BM_modp(const SparsePolyRing& P, const ConstMatrixView& pts) { ring Fp = CoeffRing(P); const int NumPts = NumRows(pts); const int NumVars = NumCols(pts); const long p = ConvertTo<long>(characteristic(Fp)); FF FFp = FFctor(p); FFselect(FFp); FFelem** points_p = (FFelem**)malloc(NumPts*sizeof(FFelem*)); for (int i=0; i < NumPts; ++i) { points_p[i] = (FFelem*)malloc(NumVars*sizeof(FFelem)); for (int j=0; j < NumVars; ++j) { points_p[i][j] = ConvertTo<FFelem>(LeastNNegRemainder(ConvertTo<BigInt>(pts(i,j)), p)); } } pp_cmp_PPM = &PPM(P); const BM modp = BM_affine_mod_p(NumVars, NumPts, points_p, pp_cmp); if (modp == NULL) return std::vector<RingElem>(); // empty list means error const int GBsize = modp->GBsize; std::vector<RingElem> GB(GBsize); vector<long> expv(NumVars); for (int i=0; i < GBsize; ++i) { for (int var = 0; var < NumVars; ++var) expv[var] = modp->pp[modp->GB[i]][var]; RingElem GBelem = monomial(P, 1, expv); for (int j=0; j < NumPts; ++j) { const int c = modp->M[modp->GB[i]][j+NumPts]; if (c == 0) continue; for (int var = 0; var < NumVars; ++var) expv[var] = modp->pp[modp->sep[j]][var]; GBelem += monomial(P, c, expv); } GB[i] = GBelem; } BM_dtor(modp); return GB; }
/* CheckLRTransP determine wheter transition matrix is left-to-right, i.e. no backward transitions */ static Boolean CheckLRTransP (SMatrix transP) { int r,c,N; N = NumCols (transP); assert (N == NumRows (transP)); for (r = 1; r <= N; ++r) { for (c = 1; c < r; ++c) { if (transP[r][c] > LSMALL) return FALSE; } for (c = r+2; c < r; ++c) { if (transP[r][c] > LSMALL) return FALSE; } } return TRUE; }
std::vector<RingElem> BM_QQ(const SparsePolyRing& P, const ConstMatrixView& pts_in) { const long NumPts = NumRows(pts_in); const long dim = NumCols(pts_in); matrix pts = NewDenseMat(RingQQ(), NumPts, dim); for (long i=0; i < NumPts; ++i) for (long j=0; j < dim; ++j) { BigRat q; if (!IsRational(q, pts_in(i,j))) throw 999; SetEntry(pts,i,j, q); } // Ensure input pts have integer coords by using // scale factors for each indet. vector<BigInt> ScaleFactor(dim, BigInt(1)); for (long j=0; j < dim; ++j) for (long i=0; i < NumPts; ++i) ScaleFactor[j] = lcm(ScaleFactor[j], ConvertTo<BigInt>(den(pts(i,j)))); mpz_t **points = (mpz_t**)malloc(NumPts*sizeof(mpz_t*)); for (long i=0; i < NumPts; ++i) { points[i] = (mpz_t*)malloc(dim*sizeof(mpz_t)); for (long j=0; j < dim; ++j) mpz_init(points[i][j]); for (long j=0; j < dim; ++j) { mpz_set(points[i][j], mpzref(ConvertTo<BigInt>(ScaleFactor[j]*pts(i,j)))); } } BMGB char0; // these will be "filled in" by BM_affine below BM modp; // pp_cmp_PPM = &PPM(P); // not threadsafe! BM_affine(&char0, &modp, dim, NumPts, points, pp_cmp); // THIS CALL DOES THE REAL WORK!!! pp_cmp_PPM = NULL; for (long i=NumPts-1; i >=0 ; --i) { for (long j=0; j < dim; ++j) mpz_clear(points[i][j]); free(points[i]); } free(points); if (modp == NULL) { if (char0 != NULL) BMGB_dtor(char0); CoCoA_ERROR("Something went wrong", "BM_QQ"); } // Now extract the answer... const int GBsize = char0->GBsize; std::vector<RingElem> GB(GBsize); const long NumVars = dim; vector<long> expv(NumVars); // buffer for creating monomials for (int i=0; i < GBsize; ++i) { BigInt denom(1); // scale factor needed to make GB elem monic. for (int var = 0; var < NumVars; ++var) { expv[var] = modp->pp[modp->GB[i]][var]; denom *= power(ScaleFactor[var], expv[var]); } RingElem GBelem = monomial(P, 1, expv); for (int j=0; j < NumPts; ++j) { if (mpq_sgn(char0->GB[i][j])==0) continue; BigRat c(char0->GB[i][j]); for (int var = 0; var < NumVars; ++var) { expv[var] = modp->pp[modp->sep[j]][var]; c *= power(ScaleFactor[var], expv[var]); } GBelem += monomial(P, c/denom, expv); } GB[i] = GBelem; } BMGB_dtor(char0); BM_dtor(modp); return GB; // ignoring separators for the moment }
int exampleSolver(const std::string file_input, const int prunecut, const int max_concurrency, const int nrhs, const int mb, const int nb, const bool verbose) { typedef typename Kokkos::Impl::is_space<DeviceSpaceType>::host_mirror_space::execution_space HostSpaceType ; const bool detail = false; std::cout << "DeviceSpace:: "; DeviceSpaceType::print_configuration(std::cout, detail); std::cout << "HostSpace:: "; HostSpaceType::print_configuration(std::cout, detail); typedef Solver<value_type,ordinal_type,size_type,DeviceSpaceType> SolverType; #ifdef HAVE_SHYLUTACHO_VTUNE __itt_pause(); #endif int r_val = 0; Kokkos::Impl::Timer timer; SolverType tacho("Tacho::CholSolver"); tacho.setPolicy(max_concurrency); tacho.setBlocksize(mb, nb); /// /// Read from matrix market /// /// input - file /// output - AA /// struct { size_type *ap; ordinal_type *aj; value_type *ax; value_type *b; bool is_allocated; } data; // non standard initialization and icpc complains //= { .ap = NULL, .aj = NULL, .ax = NULL, //.b = NULL, .is_allocated = false }; timer.reset(); if (file_input.compare("null") != 0) { data.is_allocated = false; std::cout << "Solver:: " << "Matrix market input is selected" << std::endl; // matrix market example typename SolverType::CrsMatrixBaseHostType AA("AA"); std::ifstream in; in.open(file_input); if (!in.good()) { std::cout << "Failed in open the file: " << file_input << std::endl; return -1; } MatrixMarket::read(AA, in); typename SolverType::DenseMatrixBaseHostType BB("BB", AA.NumRows(), nrhs), XX("XX"); XX.createConfTo(BB); srand(time(NULL)); const ordinal_type m = BB.NumRows(); for (auto rhs=0;rhs<nrhs;++rhs) for (auto i=0;i<m;++i) BB.Value(i, rhs) = ((value_type)rand()/(RAND_MAX)); //tacho.setProblem(AA, BB, XX); tacho.setMatrix(AA); tacho.setLeftHandSide(XX); tacho.setRightHandSide(BB); } else { data.is_allocated = true; std::cout << "Solver:: " << "user data input is selected" << std::endl; const ordinal_type m = 12, nnz = 46; data.ap = new size_type[m+1]{ 0, 3, 7, 11, 15, 20, 23, 26, 31, 35, 39, 43, 46 }; data.aj = new ordinal_type[nnz]{ 0, 1, 2, 0, 1, 3, 4, 0, 2, 4, 5, 1, 3, 6, 7, 1, 2, 4, 7, 8, 2, 5, 8, 3, 6, 9, 3, 4, 7, 9, 10, 4, 5, 8, 10, 6, 7, 9, 11, 7, 8, 10, 11, 9, 10, 11 }; data.ax = new value_type[nnz]{ 10, 1, 1, 1, 10, 1, 2, 1, 10, 1, 1, 1, 10, 1, 1, 2, 1, 10, 2, 2, 1, 10, 1, 1, 10, 2, 1, 2, 10, 2, 1, 2, 1, 10, 1, 2, 2, 10, 2, 1, 1, 10, 1, 2, 1, 10 }; data.b = new value_type[m*nrhs]; srand(time(NULL)); for (auto rhs=0;rhs<nrhs;++rhs) for (auto i=0;i<m;++i) data.b[i+m*rhs] = ((value_type)rand()/(RAND_MAX)); typename SolverType::CrsMatrixBaseHostType AA("AA", m, m, nnz); // copy user data for (auto i=0;i<m;++i) { AA.RowPtrBegin(i) = data.ap[i]; AA.RowPtrEnd(i) = data.ap[i+1]; } for (auto k=0;k<nnz;++k) { AA.Col(k) = data.aj[k]; AA.Value(k) = data.ax[k]; } typename SolverType::DenseMatrixBaseHostType BB("BB", m, nrhs), XX("XX"); XX.createConfTo(BB); for (auto rhs=0;rhs<nrhs;++rhs) for (auto i=0;i<m;++i) BB.Value(i, rhs) = data.b[i+m*rhs]; tacho.setProblem(AA, BB, XX); } const double t_input = timer.seconds(); std::cout << "Solver:: " << "input generation = " << t_input << " [sec] " << std::endl; if (verbose) { tacho.getA().showMe(std::cout) << std::endl; tacho.getB().showMe(std::cout) << std::endl; tacho.getX().showMe(std::cout) << std::endl; } /// /// Solver interface /// TACHO_SOLVER_RUN(tacho.reorder(prunecut), t_reorder); TACHO_SOLVER_RUN(tacho.analyze(), t_analyze); #ifdef HAVE_SHYLUTACHO_VTUNE __itt_resume(); #endif TACHO_SOLVER_RUN(tacho.factorize(), t_factorize); #ifdef HAVE_SHYLUTACHO_VTUNE __itt_pause(); #endif TACHO_SOLVER_RUN(tacho.solve(), t_solve); double norm, error; tacho.check(norm, error); /// /// Print out /// { const auto prec = std::cout.precision(); std::cout.precision(4); const auto AA = tacho.getA(); const auto UU = tacho.getFlatU(); const auto HU = tacho.getHierU(); std::cout << std::scientific; std::cout << "Solver:: given matrix = " << AA.NumRows() << " x " << AA.NumCols() << ", nnz = " << AA.NumNonZeros() << std::endl; std::cout << "Solver:: factored matrix = " << UU.NumRows() << " x " << UU.NumCols() << ", nnz = " << UU.NumNonZeros() << std::endl; std::cout << "Solver:: hier matrix = " << HU.NumRows() << " x " << HU.NumCols() << ", nnz = " << HU.NumNonZeros() << std::endl; std::cout << "Solver:: " << "input generation = " << t_input << " [sec], " << std::endl << "Solver:: " << "reorder = " << t_reorder << " [sec] " << std::endl << "Solver:: " << "analyze = " << t_analyze << " [sec] " << std::endl << "Solver:: " << "factorize = " << t_factorize << " [sec] " << std::endl << "Solver:: " << "solve = " << t_solve << " [sec] " << std::endl << "Solver:: " << "norm = " << norm << ", error = " << error << ", rel error = " << (error/norm) << std::endl; std::cout << std::endl; std::cout.unsetf(std::ios::scientific); std::cout.precision(prec); } if (data.is_allocated) { delete []data.ap; delete []data.aj; delete []data.ax; delete []data.b; } return r_val; }