MutableMatrix* ResF4toM2Interface::to_M2_MutableMatrix( const Ring* K, SchreyerFrame& C, int lev, int degree) { // Now we loop through the elements of degree 'degree' at level 'lev' auto& thislevel = C.level(lev); int n = 0; for (auto p=thislevel.begin(); p != thislevel.end(); ++p) { if (p->mDegree == degree) n++; } auto& prevlevel = C.level(lev-1); int* newcomps = new int[prevlevel.size()]; int nextcomp = 0; for (int i=0; i<prevlevel.size(); i++) if (prevlevel[i].mDegree == degree) newcomps[i] = nextcomp++; else newcomps[i] = -1; // create the mutable matrix MutableMatrix* result = MutableMatrix::zero_matrix(K, nextcomp, n, true); // Now loop through the elements at thislevel, // and for each, loop through the terms of mSyzygy. // if the component x satisfies newcomps[x] >= 0, then place // this coeff into the mutable matrix. int col = 0; for (auto p=thislevel.begin(); p != thislevel.end(); ++p) { if (p->mDegree != degree) continue; auto& f = p->mSyzygy; auto end = poly_iter(C.ring(), f, 1); auto i = poly_iter(C.ring(), f); for ( ; i != end; ++i) { long comp = C.monoid().get_component(i.monomial()); if (newcomps[comp] >= 0) { ring_elem a; a = K->from_long(C.ring().resGausser().coeff_to_int(i.coefficient())); result->set_entry(newcomps[comp], col, a); } } ++col; } delete [] newcomps; return result; }
inline void display_poly(std::ostream& o, const ResPolyRing& R, const poly& f) { auto end = poly_iter(R, f, 1); // end int i = 0; for (auto it = poly_iter(R, f); it != end; ++it, ++i) { R.resGausser().out(o, f.coeffs, i); res_const_packed_monomial mon = it.monomial(); R.monoid().showAlpha(mon); } }
void F4Res::loadRow(Row& r) { // std::cout << "loadRow: " << std::endl; r.mCoeffs = resGausser().allocateCoefficientVector(); // monoid().showAlpha(r.mLeadTerm); // std::cout << std::endl; int skew_sign; // will be set to 1, unless ring().isSkewCommutative() is // true, then it can be -1,0,1. // however, if it is 0, then "val" below will also be -1. long comp = monoid().get_component(r.mLeadTerm); auto& thiselement = mFrame.level(mThisLevel - 1)[comp]; // std::cout << " comp=" << comp << " mDegree=" << thiselement.mDegree << " // mThisDegree=" << mThisDegree << std::endl; if (thiselement.mDegree == mThisDegree) { // We only need to add in the current monomial // fprintf(stdout, "USING degree 0 monomial\n"); ComponentIndex val = processMonomialProduct(r.mLeadTerm, thiselement.mMonom, skew_sign); if (val < 0) fprintf(stderr, "ERROR: expected monomial to live\n"); r.mComponents.push_back(val); if (skew_sign > 0) mRing.resGausser().pushBackOne(r.mCoeffs); else { // Only happens if we are in a skew commuting ring. ring().resGausser().pushBackMinusOne(r.mCoeffs); } return; } auto& p = thiselement.mSyzygy; auto end = poly_iter(mRing, p, 1); auto i = poly_iter(mRing, p); for (; i != end; ++i) { ComponentIndex val = processMonomialProduct(r.mLeadTerm, i.monomial(), skew_sign); // std::cout << " monom: " << val << " skewsign=" << skew_sign << " // mColumns.size=" << mColumns.size() << std::endl; if (val < 0) continue; r.mComponents.push_back(val); if (skew_sign > 0) mRing.resGausser().pushBackElement( r.mCoeffs, p.coeffs, i.coefficient_index()); else { // Only happens if we are in a skew commuting ring. mRing.resGausser().pushBackNegatedElement( r.mCoeffs, p.coeffs, i.coefficient_index()); } } }
inline void display_poly(FILE* fil, const ResPolyRing& R, const poly& f) { auto end = poly_iter(R, f, 1); // end for (auto it = poly_iter(R, f); it != end; ++it) { FieldElement c = R.resGausser().coeff_to_int(it.coefficient()); packed_monomial mon = it.monomial(); if (c != 1) fprintf(fil, "%d", c); R.monoid().showAlpha(mon); } }
int SchreyerFrame::rank(int slanted_degree, int lev) { // As above, get the size of the matrix, and 'newcols' // Now we loop through the elements of degree 'slanted_degree + lev' at level 'lev' if (not (lev > 0 and lev <= maxLevel()) and not (slanted_degree >= mLoSlantedDegree and slanted_degree < mHiSlantedDegree)) { std::cerr << "ERROR: called rank(" << slanted_degree << "," << lev << ")" << std::endl; return 0; } assert(lev > 0 and lev <= maxLevel()); assert(slanted_degree >= mLoSlantedDegree and slanted_degree < mHiSlantedDegree); int degree = slanted_degree + lev; auto& thislevel = level(lev); int ncols = 0; for (auto p=thislevel.begin(); p != thislevel.end(); ++p) { if (p->mDegree == degree) ncols++; } auto& prevlevel = level(lev-1); int* newcomps = new int[prevlevel.size()]; int nrows = 0; for (int i=0; i<prevlevel.size(); i++) if (prevlevel[i].mDegree == degree) newcomps[i] = nrows++; else newcomps[i] = -1; // Create the ARing // Create a DMat // M2::ARingZZpFlint R(gausser().get_ring()->characteristic()); // DMat<M2::ARingZZpFlint> M(R, nrows, ncols); #if 0 // TODO: Change this M2::ARingZZpFFPACK R(gausser().get_ring()->characteristic()); DMat<M2::ARingZZpFFPACK> M(R, nrows, ncols); #endif // Fill in DMat // loop through the elements at thislevel, // and for each, loop through the terms of mSyzygy. // if the component x satisfies newcomps[x] >= 0, then place // this coeff into the mutable matrix. int col = 0; long nnonzeros = 0; for (auto p=thislevel.begin(); p != thislevel.end(); ++p) { if (p->mDegree != degree) continue; auto& f = p->mSyzygy; auto end = poly_iter(ring(), f, 1); auto i = poly_iter(ring(), f); for ( ; i != end; ++i) { long comp = monoid().get_component(i.monomial()); if (newcomps[comp] >= 0) { #if 0 // TODO: change this line: M.entry(newcomps[comp], col) = gausser().coeff_to_int(i.coefficient()); #endif nnonzeros++; } } ++col; } double frac_nonzero = (nrows*ncols); frac_nonzero = nnonzeros / frac_nonzero; // buffer o; // displayMat(o, M); // std::cout << o.str() << std::endl; // call rank // auto a = DMatLinAlg<M2::ARingZZpFlint>(M); #if 0 // TODO: change this line auto a = DMatLinAlg<M2::ARingZZpFFPACK>(M); long numrows = M.numRows(); long numcols = M.numColumns(); #endif long numrows = 0; long numcols = 0; clock_t begin_time0 = clock(); int rk = 0; // TODO: static_cast<int>(a.rank()); clock_t end_time0 = clock(); double nsecs0 = (double)(end_time0 - begin_time0)/CLOCKS_PER_SEC; if (M2_gbTrace >= 2) { std::cout << "rank (" << slanted_degree << "," << lev << ") = " << rk << " time " << nsecs0 << " size= " << numrows << " x " << numcols << " nonzero " << nnonzeros << std::endl; } return rk; }
double ResF4toM2Interface::setDegreeZeroMap(SchreyerFrame& C, DMat<RingType>& result, int slanted_degree, int lev) // 'result' should be previously initialized, but will be resized. // return value: -1 means (slanted_degree, lev) is out of range, and the zero matrix was returned. // otherwise: the fraction of non-zero elements is returned. { // As above, get the size of the matrix, and 'newcols' // Now we loop through the elements of degree 'slanted_degree + lev' at level 'lev' const RingType& R = result.ring(); if (not (lev > 0 and lev <= C.maxLevel())) { result.resize(0,0); return -1; } assert(lev > 0 and lev <= C.maxLevel()); int degree = slanted_degree + lev; auto& thislevel = C.level(lev); int ncols = 0; for (auto p=thislevel.begin(); p != thislevel.end(); ++p) { if (p->mDegree == degree) ncols++; } auto& prevlevel = C.level(lev-1); int* newcomps = new int[prevlevel.size()]; int nrows = 0; for (int i=0; i<prevlevel.size(); i++) if (prevlevel[i].mDegree == degree) newcomps[i] = nrows++; else newcomps[i] = -1; result.resize(nrows, ncols); int col = 0; long nnonzeros = 0; for (auto p=thislevel.begin(); p != thislevel.end(); ++p) { if (p->mDegree != degree) continue; auto& f = p->mSyzygy; auto end = poly_iter(C.ring(), f, 1); auto i = poly_iter(C.ring(), f); for ( ; i != end; ++i) { long comp = C.monoid().get_component(i.monomial()); if (newcomps[comp] >= 0) { R.set_from_long(result.entry(newcomps[comp], col), C.gausser().coeff_to_int(i.coefficient())); nnonzeros++; } } ++col; } double frac_nonzero = (nrows*ncols); frac_nonzero = static_cast<double>(nnonzeros) / frac_nonzero; delete[] newcomps; return frac_nonzero; }