6 inline RCP<const Number> _mulnum(
const RCP<const Number> &x,
7 const RCP<const Number> &y)
16 inline void _imulnum(
const Ptr<RCP<const Number>> &
self,
17 const RCP<const Number> &other)
19 *
self = _mulnum(*
self, other);
26 RCP<const Number> coeff = zero;
27 RCP<const Number> multiply = one;
32 RCP<const Basic> apply(
const Basic &b)
38 void bvisit(
const Basic &x)
43 void bvisit(
const Number &x)
45 iaddnum(outArg(coeff),
49 void bvisit(
const Add &
self)
51 RCP<const Number> _multiply = multiply;
52 iaddnum(outArg(coeff), _mulnum(multiply,
self.get_coef()));
53 for (
auto &p :
self.get_dict()) {
54 multiply = _mulnum(_multiply, p.second);
56 p.first->accept(*
this);
64 void bvisit(
const Mul &
self)
66 for (
auto &p :
self.get_dict()) {
67 if (!is_a<Symbol>(*p.first)) {
68 RCP<const Basic> a, b;
69 self.as_two_terms(outArg(a), outArg(b));
70 a = expand_if_deep(a);
71 b = expand_if_deep(b);
76 this->_coef_dict_add_term(multiply,
self.rcp_from_this());
79 void mul_expand_two(
const RCP<const Basic> &a,
const RCP<const Basic> &b)
82 if (is_a<Add>(*a) && is_a<Add>(*b)) {
83 iaddnum(outArg(coeff),
85 _mulnum(down_cast<const Add &>(*a).get_coef(),
86 down_cast<const Add &>(*b).get_coef())));
88 #if defined(HAVE_SYMENGINE_RESERVE)
90 + (down_cast<const Add &>(*a)).get_dict().size()
91 * (down_cast<const Add &>(*b)).get_dict().size());
94 for (
auto &p : (down_cast<const Add &>(*a)).get_dict()) {
95 RCP<const Number> temp = _mulnum(p.second, multiply);
96 for (
auto &q : (down_cast<const Add &>(*b)).get_dict()) {
99 RCP<const Basic> term =
mul(p.first, q.first);
101 iaddnum(outArg(coeff),
102 _mulnum(_mulnum(temp, q.second),
103 rcp_static_cast<const Number>(term)));
106 && !(down_cast<const Mul &>(*term)
110 RCP<const Number> coef2
111 = down_cast<const Mul &>(*term).get_coef();
114 = down_cast<const Mul &>(*term).get_dict();
117 d_, _mulnum(_mulnum(temp, q.second), coef2),
126 d_, _mulnum(down_cast<const Add &>(*b).get_coef(), temp),
130 RCP<const Number> temp
131 = _mulnum(down_cast<const Add &>(*a).get_coef(), multiply);
132 for (
auto &q : (down_cast<const Add &>(*b)).get_dict()) {
136 }
else if (is_a<Add>(*a)) {
137 mul_expand_two(b, a);
139 }
else if (is_a<Add>(*b)) {
140 RCP<const Number> a_coef;
141 RCP<const Basic> a_term;
143 _imulnum(outArg(a_coef), multiply);
145 #if defined(HAVE_SYMENGINE_RESERVE)
147 + (down_cast<const Add &>(*b)).get_dict().size());
149 for (
auto &q : (down_cast<const Add &>(*b)).get_dict()) {
150 RCP<const Basic> term =
mul(a_term, q.first);
152 iaddnum(outArg(coeff),
153 _mulnum(_mulnum(q.second, a_coef),
154 rcp_static_cast<const Number>(term)));
157 && !(down_cast<const Mul &>(*term)
161 RCP<const Number> coef2
162 = down_cast<const Mul &>(*term).get_coef();
165 = down_cast<const Mul &>(*term).get_dict();
168 d_, _mulnum(_mulnum(q.second, a_coef), coef2),
176 if (
eq(*a_term, *one)) {
177 iaddnum(outArg(coeff),
178 _mulnum(down_cast<const Add &>(*b).get_coef(), a_coef));
181 d_, _mulnum(down_cast<const Add &>(*b).get_coef(), a_coef),
186 _coef_dict_add_term(multiply,
mul(a, b));
191 auto m = base_dict.
size();
192 #if defined(HAVE_SYMENGINE_RESERVE)
196 RCP<const Number> coef, two =
integer(2);
197 for (
auto p = base_dict.
begin(); p != base_dict.
end(); ++p) {
198 for (
auto q = p; q != base_dict.
end(); ++q) {
201 _mulnum(
mulnum((*p).second, (*p).second), multiply),
202 pow((*p).first, two));
205 _mulnum(multiply, _mulnum((*p).second,
206 _mulnum((*q).second, two))),
207 mul((*q).first, (*p).first));
216 unsigned m = numeric_cast<unsigned>(base_dict.
size());
217 multinomial_coefficients_mpz(m, n, r);
220 #if defined(HAVE_SYMENGINE_RESERVE)
224 auto power = p.first.begin();
225 auto i2 = base_dict.
begin();
227 RCP<const Number> overall_coeff = one;
228 for (; power != p.first.end(); ++power, ++i2) {
231 RCP<const Basic> base = i2->first;
232 if (is_a<Integer>(*base)) {
233 _imulnum(outArg(overall_coeff),
234 rcp_static_cast<const Number>(
235 down_cast<const Integer &>(*base).powint(
237 }
else if (is_a<Symbol>(*base)) {
240 RCP<const Basic> exp2, t, tmp;
241 tmp = pow(base,
exp);
242 if (is_a<Mul>(*tmp)) {
244 (down_cast<const Mul &>(*tmp)).get_dict()) {
245 Mul::dict_add_term_new(outArg(overall_coeff), d,
248 _imulnum(outArg(overall_coeff),
249 (down_cast<const Mul &>(*tmp)).get_coef());
251 _imulnum(outArg(overall_coeff),
252 rcp_static_cast<const Number>(tmp));
255 Mul::dict_add_term_new(outArg(overall_coeff), d,
259 if (!(i2->second->is_one())) {
260 _imulnum(outArg(overall_coeff),
262 rcp_static_cast<const Number>(
exp)));
267 RCP<const Number> coef2 =
integer(p.second);
269 iaddnum(outArg(coeff),
270 _mulnum(_mulnum(multiply,
271 rcp_static_cast<const Number>(term)),
275 && !(down_cast<const Mul &>(*term).get_coef()->is_one())) {
277 _imulnum(outArg(coef2),
278 down_cast<const Mul &>(*term).get_coef());
281 = down_cast<const Mul &>(*term).get_dict();
289 void bvisit(
const Pow &
self)
291 RCP<const Basic> _base = expand_if_deep(
self.get_base());
293 if (is_a<Integer>(*
self.get_exp()) && is_a<UExprPoly>(*_base)) {
294 unsigned q = numeric_cast<unsigned>(
295 down_cast<const Integer &>(*
self.get_exp()).as_uint());
296 RCP<const UExprPoly> p = rcp_static_cast<const UExprPoly>(_base);
297 RCP<const UExprPoly> r = pow_upoly(*p, q);
298 _coef_dict_add_term(multiply, r);
301 if (is_a<Integer>(*
self.get_exp()) && is_a<UIntPoly>(*_base)) {
302 unsigned q = numeric_cast<unsigned>(
303 down_cast<const Integer &>(*
self.get_exp()).as_uint());
304 RCP<const UIntPoly> p = rcp_static_cast<const UIntPoly>(_base);
305 RCP<const UIntPoly> r = pow_upoly(*p, q);
306 _coef_dict_add_term(multiply, r);
310 if (!is_a<Integer>(*
self.get_exp()) || !is_a<Add>(*_base)) {
311 if (
neq(*_base, *
self.get_base())) {
320 = down_cast<const Integer &>(*
self.get_exp()).as_integer_class();
322 return _coef_dict_add_term(
323 multiply,
div(one, expand_if_deep(pow(_base,
integer(-n)))));
324 RCP<const Add> base = rcp_static_cast<const Add>(_base);
326 if (!(base->get_coef()->is_zero())) {
329 insert(base_dict, base->get_coef(), one);
331 iaddnum(outArg(coeff), base->get_coef());
333 return square_expand(base_dict);
335 return pow_expand(base_dict, numeric_cast<unsigned>(mp_get_ui(n)));
338 inline void _coef_dict_add_term(
const RCP<const Number> &c,
339 const RCP<const Basic> &term)
342 iaddnum(outArg(coeff),
343 _mulnum(c, rcp_static_cast<const Number>(term)));
344 }
else if (is_a<Add>(*term)) {
345 for (
const auto &q : (down_cast<const Add &>(*term)).get_dict())
347 iaddnum(outArg(coeff),
348 _mulnum(down_cast<const Add &>(*term).get_coef(), c));
350 RCP<const Number> coef2;
358 RCP<const Basic> expand_if_deep(
const RCP<const Basic> &expr)
369 RCP<const Basic>
expand(
const RCP<const Basic> &
self,
bool deep)
372 return v.apply(*
self);
The base class for representing addition in symbolic expressions.
static RCP< const Basic > from_dict(const RCP< const Number > &coef, umap_basic_num &&d)
Create an appropriate instance from dictionary quickly.
static void dict_add_term(umap_basic_num &d, const RCP< const Number > &coef, const RCP< const Basic > &t)
Adds a new term to the expression.
static void as_coef_term(const RCP< const Basic > &self, const Ptr< RCP< const Number >> &coef, const Ptr< RCP< const Basic >> &term)
Converts a Basic self into the form of coefficient * term.
The lowest unit of symbolic representation.
RCP< const T2 > rcp_from_this_cast() const
Get RCP<T2> pointer to self (it will cast the pointer to T2)
RCP< T > rcp_from_this()
Get RCP<T> pointer to self (it will cast the pointer to T)
static void as_base_exp(const RCP< const Basic > &self, const Ptr< RCP< const Basic >> &exp, const Ptr< RCP< const Basic >> &base)
Convert to a base and exponent form.
static void dict_add_term(map_basic_basic &d, const RCP< const Basic > &exp, const RCP< const Basic > &t)
Add terms to dict.
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
Main namespace for SymEngine package.
bool is_a_Number(const Basic &b)
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
RCP< const Number > mulnum(const RCP< const Number > &self, const RCP< const Number > &other)
Multiply self and other
RCP< const Number > pownum(const RCP< const Number > &self, const RCP< const Number > &other)
Raise self to power other
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
void insert(T1 &m, const T2 &first, const T3 &second)
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self