ring_elem SchurRing2::from_partition(M2_arrayint part) const { ring_elem result; schur_poly *f = new schur_poly; f->coeffs.push_back(coefficientRing->one()); int len = last_nonzero(part) + 1; f->monoms.push_back(len + 1); for (int i=0; i<len; i++) f->monoms.push_back(part->array[i]); result.schur_poly_val = f; return result; }
// Check for identically zero polynomials using randomized polynomial identity testing template<class R,class PerturbedT> static void assert_last_nonzero(void(*const polynomial)(R,RawArray<const Vector<Exact<1>,PerturbedT::m>>), R result, RawArray<const PerturbedT> X, const char* message) { typedef Vector<Exact<1>,PerturbedT::m> EV; const int n = X.size(); const auto Z = GEODE_RAW_ALLOCA(n,EV); for (const int k : range(20)) { for (int i=0;i<n;i++) Z[i] = EV(perturbation<PerturbedT::m>(k<<10,X[i].seed())); polynomial(result,Z); if (last_nonzero(result)) // Even a single nonzero means we're all good return; } // If we reach this point, the chance of a nonzero nonmalicious polynomial is something like (1e-5)^20 = 1e-100. Thus, we can safely assume that for the lifetime // of this code, we will never treat a nonzero polynomial as zero. If this comes up, we can easily bump the threshold a bit further. throw AssertionError(format("%s (there is likely a bug in the calling code), X = %s",message,str(X))); }