FFElement FiniteField::makeElement(const Polynomial& p) const { assert(p.getMod() == getP()); if (p.getDomain() == domain) return FFElement(p, this); std::vector<FieldElement> coeffs; for (auto& c : p.getCoeffs()) coeffs.push_back(domain->getField()->makeElement(c.getVal())); return FFElement(domain->makeElement(coeffs), this); }
Intervals PolynomialIntervalSolver::findPolyIntervals(const Polynomial &poly) { const double eps = 1e-8; int leadcoeff=0; std::vector<Interval> empty; std::vector<Interval> all; all. push_back(Interval(-std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity())); const std::vector<double> &coeffs = poly.getCoeffs(); int deg = coeffs.size()-1; for(int i=0; i<(int)coeffs.size(); i++) assert(!isnan(coeffs[i])); // get rid of leading 0s // for(leadcoeff=0; leadcoeff < (int)coeffs.size() && fabs(coeffs[leadcoeff]) < eps; leadcoeff++) // { // deg--; // } // check for the zero polynomial if(deg < 0) { return Intervals(empty); } // check for constant polynomial if(deg == 0) { double val = poly.evaluate(0); if(val > 0) { return Intervals(all); } return Intervals(empty); } // nonconstant polynomial... rpoly time!!! assert(deg <= 6); double zeror[6]; double zeroi[6]; int numroots = rf.rpoly(&coeffs[leadcoeff], deg, zeror, zeroi); std::vector<double> roots; for(int i=0; i<numroots; i++) if( fabs(zeroi[i]) < eps ) roots.push_back(zeror[i]); // no roots: check at 0 if(roots.size() == 0) { double val = poly.evaluate(0); if(val > 0) return Intervals(all); return Intervals(empty); } std::sort(roots.begin(), roots.end()); std::vector<Interval> intervals; for(int i=0; i<(int)roots.size(); i++) { if(i == 0) { //check poly on (-inf, r) double t = roots[i]-1; double val = poly.evaluate(t); if(val > 0) { intervals.push_back(Interval(-std::numeric_limits<double>::infinity(), roots[i])); } } if(i == (int)roots.size()-1) { //check poly on (r, inf) double t = roots[i]+1; double val = poly.evaluate(t); if(val > 0) { intervals.push_back(Interval(roots[i], std::numeric_limits<double>::infinity())); } } if(i < (int)roots.size()-1) { // check poly on (r, r+1) double t = 0.5*(roots[i]+roots[i+1]); double val = poly.evaluate(t); if(val > 0) { intervals.push_back(Interval(roots[i], roots[i+1])); } } } return Intervals(intervals); }