// Very quickly (!) creates the appropriate instance (i.e. Add, Symbol, // Integer, Mul) depending on the size of the dictionary 'd'. // If d.size() > 1 then it just returns Add. This means that the dictionary // must be in canonical form already. For d.size == 1, it returns Mul, Pow, // Symbol or Integer, depending on the expression. RCP<Basic> Add::from_dict(const RCP<Number> &coef, const umap_basic_int &d) { if (d.size() == 0) { return coef; } else if (d.size() == 1 && coef->is_zero()) { auto p = d.begin(); if (is_a<Integer>(*(p->second))) { if (rcp_static_cast<Integer>(p->second)->is_zero()) { return zero; } if (rcp_static_cast<Integer>(p->second)->is_one()) { return p->first; } if (is_a<Mul>(*(p->first))) { return Mul::from_dict(p->second, rcp_static_cast<Mul>(p->first)->dict_); } map_basic_basic m; if (is_a<Pow>(*(p->first))) { insert(m, rcp_static_cast<Pow>(p->first)->base_, rcp_static_cast<Pow>(p->first)->exp_); } else { insert(m, p->first, one); } return rcp(new Mul(p->second, m)); } map_basic_basic m; if (is_a_Number(*p->second)) { if (is_a<Mul>(*(p->first))) { return Mul::from_dict(p->second, rcp_static_cast<Mul>(p->first)->dict_); } if (is_a<Pow>(*p->first)) { insert(m, rcp_static_cast<Pow>(p->first)->base_, rcp_static_cast<Pow>(p->first)->exp_); } else { insert(m, p->first, one); } return rcp(new Mul(p->second, m)); } else { insert(m, p->first, one); insert(m, p->second, one); return rcp(new Mul(one, m)); } } else { return rcp(new Add(coef, d)); } }
void expr2poly(const RCP<const Basic> &p, umap_basic_int &syms, umap_vec_mpz &P) { if (is_a<Add>(*p)) { int n = syms.size(); const umap_basic_int &d = rcp_static_cast<const Add>(p)->dict_; vec_int exp; mpz_class coef; for (auto &p: d) { if (!is_a<Integer>(*p.second)) throw std::runtime_error("Not implemented."); coef = rcp_static_cast<const Integer>(p.second)->as_mpz(); exp.assign(n, 0); // Initialize to [0]*n if (is_a<Mul>(*p.first)) { const map_basic_basic &term = rcp_static_cast<const Mul>(p.first)->dict_; for (auto &q: term) { RCP<const Basic> sym = q.first; if (!is_a<Integer>(*syms.at(sym))) throw std::runtime_error("Not implemented."); int i = rcp_static_cast<const Integer>(syms.at(sym))->as_int(); if (is_a<Integer>(*q.second)) { exp[i] = rcp_static_cast<const Integer>(q.second)->as_int(); } else { throw std::runtime_error("Cannot convert symbolic exponents to sparse polynomials with integer exponents."); } } } else if (is_a<Pow>(*p.first)) { RCP<const Basic> sym = rcp_static_cast<const Pow>(p.first)->base_; RCP<const Basic> exp_ = rcp_static_cast<const Pow>(p.first)->exp_; if (!is_a<Integer>(*syms.at(sym))) throw std::runtime_error("Not implemented."); int i = rcp_static_cast<const Integer>(syms.at(sym))->as_int(); if (!is_a<Integer>(*exp_)) throw std::runtime_error("Not implemented."); exp[i] = rcp_static_cast<const Integer>(exp_)->as_int(); } else if (is_a<Symbol>(*p.first)) { RCP<const Basic> sym = p.first; if (!is_a<Integer>(*syms.at(sym))) throw std::runtime_error("Not implemented."); int i = rcp_static_cast<const Integer>(syms.at(sym))->as_int(); exp[i] = 1; } else { throw std::runtime_error("Not implemented."); } P[exp] = coef; } } else { throw std::runtime_error("Not implemented."); } }