long SchreyerFrame::computeIdealQuotient(int lev, long begin, long elem) { /// std::cout << "computeIdealQuotient(" << lev << "," << begin << "," << elem << ")" << std::endl; // Returns the number of elements added res_packed_monomial m = monomial(lev, elem); std::vector<PreElement*> elements; if (ring().isSkewCommutative()) { auto skewvars = new int[ring().monoid().n_vars()]; int a = ring().monoid().skew_vars(ring().skewInfo(), m, skewvars); // std::cout << "adding " << a << " syz from skew" << std::endl; for (int i=0; i<a; ++i) { PreElement* vp = mPreElements.allocate(); vp->vp = mVarpowers.reserve(mMaxVPSize); monoid().variable_as_vp(skewvars[i], vp->vp); vp->degree = monoid().degree_of_vp(vp->vp); int len = static_cast<int>(res_varpower_monomials::length(vp->vp)); mVarpowers.intern(len); elements.push_back(vp); } delete [] skewvars; } for (long i=begin; i<elem; i++) elements.push_back(createQuotientElement(monomial(lev,i), m)); typedef ResF4MonomialLookupTableT<int32_t> MonomialLookupTable; MonomialLookupTable montab(monoid().n_vars()); #if 0 std::cout << " #pre elements = " << elements.size() << std::endl; for (auto i=elements.begin(); i != elements.end(); ++i) { varpower_monomials::elem_text_out(stdout, (*i)->vp); fprintf(stdout, "\n"); } #endif PreElementSorter C; std::stable_sort(elements.begin(), elements.end(), C); long n_elems = 0; for (auto i = elements.begin(); i != elements.end(); ++i) { int32_t not_used; bool inideal = montab.find_one_divisor_vp(0, (*i)->vp, not_used); if (inideal) continue; // Now we create a res_packed_monomial, and insert it into 'lev+1' montab.insert_minimal_vp(0, (*i)->vp, 0); res_packed_monomial monom = monomialBlock().allocate(monoid().max_monomial_size()); monoid().from_varpower_monomial((*i)->vp, elem, monom); // Now insert it into the frame insertBasic(currentLevel(), monom, (*i)->degree + degree(currentLevel()-1, monoid().get_component(monom))); n_elems++; } //std::cout << " returns " << n_elems << std::endl; return n_elems; }
Polynomial<2> count_generator(int symmetries) { // Make the color generating function Polynomial<2> f; f.x[vec(0,0)]++; f.x[vec(1,0)]++; f.x[vec(0,1)]++; // List symmetries Array<symmetry_t> group; if (symmetries==1) group.append(symmetry_t(0)); else if (symmetries==8) for (int g=0;g<8;g++) group.append(symmetry_t(g,0)); else if (symmetries==2048) for (symmetry_t s : pentago::symmetries) group.append(s); else GEODE_ASSERT(false); // Generate the cycle index Polynomial<36> Z; for (symmetry_t s : group) { Vector<int,36> cycles; for (int i=0;i<4;i++) for (int j=0;j<9;j++) { side_t start = (side_t)1<<(16*i+j); side_t side = start; for (int o=1;;o++) { side = transform_side(s,side); if (side==start) { cycles[o-1]++; break; } } } for (int i=0;i<36;i++) { GEODE_ASSERT(cycles[i]%(i+1)==0); cycles[i] /= i+1; } Z.x[cycles]++; } // Compute f(b^k,w^k) for k = 1 to 36 vector<Polynomial<2>> fk(36); for (int k=1;k<=36;k++) fk[k-1] = compose(f,vec(monomial(vec(k,0)),monomial(vec(0,k)))); // Compose Zg and fk to get F auto F = compose(Z,fk); for (auto& m : F.x) { GEODE_ASSERT(m.second%symmetries==0); m.second /= symmetries; } return F; }
void Polynom::interpolate(const Vec &x, const Vec &y, const int n) { if((x.nn==n) && (y.nn==n)) { int i,j,k; //First we compute the divided differences and we store them in the upper-left //triangular side of the matrix A Mat A(n,n); for(i=0;i<n;i++) A[i][0]=y[i]; for(j=1;j<n;j++) { k=n-j; for(i=0;i<k;i++) A[i][j]=(A[i+1][j-1]-A[i][j-1])/(x[i+j] - x[i]); } //Now we construct the polynomial Polynom p(0); //Interpolating polynomial (degree 0 at the begining of //the iteration) Polynom aux(1.0,0); //Auxiliar polynomial Polynom monomial(1.0,1); //Monomial (x-x_i) p[0]=A[0][0]; for(i=1; i<n; i++) { monomial[0]=-x[i-1]; aux=aux*monomial; //We compute the polynom (x-x_0)...(x-x_i) p = p + aux*A[0][i]; //We actualize the interpolating polynomial } *this=p; } }
// 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; }
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; }
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; }
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); } }
void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) { Ref<GF256Poly> poly(new GF256Poly(field, received)); #ifdef DEBUG cout << "decoding with poly " << *poly << "\n"; #endif ArrayRef<int> syndromeCoefficients(new Array<int> (twoS)); #ifdef DEBUG cout << "syndromeCoefficients array = " << syndromeCoefficients.array_ << "\n"; #endif bool dataMatrix = (&field == &GF256::DATA_MATRIX_FIELD); bool noError = true; for (int i = 0; i < twoS; i++) { int eval = poly->evaluateAt(field.exp(dataMatrix ? i + 1 : i)); syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval; if (eval != 0) { noError = false; } } if (noError) { return; } Ref<GF256Poly> syndrome(new GF256Poly(field, syndromeCoefficients)); Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1)); vector<Ref<GF256Poly> > sigmaOmega(runEuclideanAlgorithm(monomial, syndrome, twoS)); ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]); ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations, dataMatrix); for (unsigned i = 0; i < errorLocations->size(); i++) { int position = received->size() - 1 - field.log(errorLocations[i]); //TODO: check why the position would be invalid if (position < 0 || (size_t)position >= received.size()) throw IllegalArgumentException("Invalid position (ReedSolomonDecoder)"); received[position] = GF256::addOrSubtract(received[position], errorMagitudes[i]); } }
void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) { Ref<GF256Poly> poly(new GF256Poly(field, received)); #ifdef DEBUG cout << "decoding with poly " << *poly << "\n"; #endif ArrayRef<int> syndromeCoefficients(new Array<int>(twoS)); #ifdef DEBUG cout << "syndromeCoefficients array = " << syndromeCoefficients.array_ << "\n"; #endif bool noError = true; for (int i = 0; i < twoS; i++) { int eval = poly->evaluateAt(field.exp(i)); syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval; if (eval != 0) { noError = false; } } if (noError) { return; } Ref<GF256Poly> syndrome(new GF256Poly(field, syndromeCoefficients)); Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1)); vector<Ref<GF256Poly> > sigmaOmega (runEuclideanAlgorithm(monomial, syndrome, twoS)); ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]); ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1], errorLocations); for (unsigned i = 0; i < errorLocations->size(); i++) { int position = received->size() - 1 - field.log(errorLocations[i]); received[position] = GF256::addOrSubtract(received[position], errorMagitudes[i]); } }
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 }
// Not efficient, efficiency not needed at the moment RingElem Facet2RingElem(const SparsePolyRing& theP,const DynamicBitset& b) { return monomial(theP, 1, NewPP(PPM(theP), b)); }//Facet2RingElem
MC *new_monomial(MC *var1, MC *var2) { MC *ans = monomial(var1, var2); return ans; }
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; }