Exemple #1
0
 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));
}
Exemple #4
0
// 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();
}