static RCP<const Basic> diff(const UnivariatePolynomial &self, const RCP<const Symbol> &x) { if (self.get_var()->__eq__(*x)) { map_uint_mpz d; for (const auto &p : self.get_dict()) { d[p.first - 1] = p.second * p.first; } return make_rcp<const UnivariatePolynomial>(self.get_var(), (--(d.end()))->first, std::move(d)); } else { return zero; } }
RCP<const UnivariatePolynomial> neg_uni_poly(const UnivariatePolynomial &a) { map_int_Expr dict; for (const auto &it : a.get_dict()) dict[it.first] = -1 * it.second; return univariate_polynomial(a.get_var(), std::move(dict)); }
RCP<const UnivariatePolynomial> sub_uni_poly(const UnivariatePolynomial &a, const UnivariatePolynomial &b) { map_int_Expr dict; RCP<const Symbol> var = symbol(""); if (a.get_var()->get_name() == "") { var = b.get_var(); } else if (b.get_var()->get_name() == "") { var = a.get_var(); } else if (!(a.get_var()->__eq__(*b.get_var()))) { throw std::runtime_error("Error: variables must agree."); } else { var = a.get_var(); } for (const auto &it : a.get_dict()) dict[it.first] = it.second; for (const auto &it : b.get_dict()) dict[it.first] -= it.second; return univariate_polynomial(var, std::move(dict)); }
// UnivariatePolynomial printing, tests taken from SymPy and printing ensures // that there is compatibility void StrPrinter::bvisit(const UnivariatePolynomial &x) { std::ostringstream s; // bool variable needed to take care of cases like -5, -x, -3*x etc. bool first = true; // we iterate over the map in reverse order so that highest degree gets // printed first for (auto it = x.get_dict().rbegin(); it != x.get_dict().rend(); ++it) { std::string t; // if exponent is 0, then print only coefficient if (it->first == 0) { if (first) { s << it->second; } else { t = parenthesizeLT(it->second.get_basic(), PrecedenceEnum::Mul); if (t[0] == '-') { s << " - " << t.substr(1); } else { s << " + " << t; } } first = false; continue; } // if the coefficient of a term is +1 or -1 if (it->second == 1 or it->second == -1) { // in cases of -x, print -x // in cases of x**2 - x, print - x if (first) { if (it->second == -1) s << "-"; } else { s << " " << _print_sign(static_cast<const Integer &>( *it->second.get_basic()) .as_mpz()) << " "; } } // same logic is followed as above else { // in cases of -2*x, print -2*x // in cases of x**2 - 2*x, print - 2*x if (first) { s << parenthesizeLT(it->second.get_basic(), PrecedenceEnum::Mul) << "*"; } else { t = parenthesizeLT(it->second.get_basic(), PrecedenceEnum::Mul); if (t[0] == '-') { s << " - " << t.substr(1); } else { s << " + " << t; } s << "*"; } } s << x.get_var()->get_name(); // if exponent is not 1, print the exponent; if (it->first > 1) { s << "**" << it->first; } else if (it->first < 0) { s << "**(" << it->first << ")"; } // corner cases of only first term handled successfully, switch the bool first = false; } if (x.get_dict().size() == 0) s << "0"; str_ = s.str(); }