4 #include <symengine/symengine_exception.h>
5 #include <symengine/test_visitors.h>
10 Pow::Pow(
const RCP<const Basic> &base,
const RCP<const Basic> &
exp)
11 : base_{base}, exp_{
exp}
13 SYMENGINE_ASSIGN_TYPEID()
20 if (is_a<Integer>(base) and down_cast<const Integer &>(base).is_zero()) {
28 if (is_a<Integer>(base) and down_cast<const Integer &>(base).is_one())
34 if (is_a<Integer>(
exp) and down_cast<const Integer &>(
exp).is_one())
37 if ((is_a<Integer>(base) or is_a<Rational>(base)) and is_a<Integer>(
exp))
40 if (is_a<Mul>(base) and is_a<Integer>(
exp))
43 if (is_a<Pow>(base) and is_a<Integer>(
exp))
47 if ((is_a<Rational>(base) or is_a<Integer>(base)) and is_a<Rational>(
exp)
48 and (down_cast<const Rational &>(
exp).as_rational_class() < 0
49 or down_cast<const Rational &>(
exp).as_rational_class() > 1))
53 if (is_a<Complex>(base) and down_cast<const Complex &>(base).is_re_zero()
54 and is_a<Integer>(
exp))
58 and (not down_cast<const Number &>(base).is_exact()
59 or not down_cast<const Number &>(
exp).is_exact()))
66 hash_t seed = SYMENGINE_POW;
67 hash_combine<Basic>(seed, *base_);
68 hash_combine<Basic>(seed, *exp_);
74 if (is_a<Pow>(o) and
eq(*base_, *(down_cast<const Pow &>(o).base_))
75 and
eq(*exp_, *(down_cast<const Pow &>(o).exp_)))
83 SYMENGINE_ASSERT(is_a<Pow>(o))
84 const Pow &s = down_cast<const Pow &>(o);
85 int base_cmp = base_->__cmp__(*s.base_);
87 return exp_->__cmp__(*s.exp_);
92 RCP<const Basic> pow(
const RCP<const Basic> &a,
const RCP<const Basic> &b)
96 return addnum(one, rcp_static_cast<const Number>(b));
103 and rcp_static_cast<const Number>(b)->is_positive()) {
106 and rcp_static_cast<const Number>(b)->is_negative()) {
109 return make_rcp<const Pow>(a, b);
115 if (
eq(*a, *minus_one)) {
116 if (is_a<Integer>(*b)) {
117 return is_a<Integer>(*
div(b,
integer(2))) ? one : minus_one;
118 }
else if (is_a<Rational>(*b) and
eq(*b, *
rational(1, 2))) {
125 if (is_a<Integer>(*b)) {
126 return down_cast<const Number &>(*a).pow(
127 *rcp_static_cast<const Number>(b));
128 }
else if (is_a<Rational>(*b)) {
129 if (is_a<Rational>(*a)) {
130 return down_cast<const Rational &>(*a).powrat(
131 down_cast<const Rational &>(*b));
132 }
else if (is_a<Integer>(*a)) {
133 return down_cast<const Rational &>(*b).rpowrat(
134 down_cast<const Integer &>(*a));
135 }
else if (is_a<Complex>(*a)) {
136 return make_rcp<const Pow>(a, b);
138 return down_cast<const Number &>(*a).pow(
139 *rcp_static_cast<const Number>(b));
141 }
else if (is_a<Complex>(*b)
142 and down_cast<const Number &>(*a).is_exact()) {
143 return make_rcp<const Pow>(a, b);
145 return down_cast<const Number &>(*a).pow(
146 *rcp_static_cast<const Number>(b));
148 }
else if (
eq(*a, *E)) {
149 RCP<const Number> p = rcp_static_cast<const Number>(b);
150 if (not p->is_exact()) {
152 return p->get_eval().exp(*p);
154 }
else if (is_a<Mul>(*a)) {
157 RCP<const Number> coef = one;
158 down_cast<const Mul &>(*a).power_num(
159 outArg(coef), d, rcp_static_cast<const Number>(b));
163 if (is_a<Pow>(*a) and is_a<Integer>(*b)) {
166 RCP<const Pow> A = rcp_static_cast<const Pow>(a);
167 return pow(A->get_base(),
mul(A->get_exp(), b));
170 and
eq(*down_cast<const Pow &>(*a).get_exp(), *minus_one)) {
172 RCP<const Pow> A = rcp_static_cast<const Pow>(a);
173 return pow(A->get_base(),
neg(b));
175 return make_rcp<const Pow>(a, b);
181 void multinomial_coefficients(
unsigned m,
unsigned n, map_vec_uint &r)
184 unsigned j, tj, start, k;
185 unsigned long long int v;
187 throw SymEngineException(
"multinomial_coefficients: m >= 2 must hold.");
211 for (k = start; k < m; k++) {
219 r[t] = (v * tj) / (n - t[0]);
224 void multinomial_coefficients_mpz(
unsigned m,
unsigned n, map_vec_mpz &r)
227 unsigned j, tj, start, k;
230 throw SymEngineException(
"multinomial_coefficients: m >= 2 must hold.");
254 for (k = start; k < m; k++) {
262 r[t] = (v * tj) / (n - t[0]);
268 return {base_, exp_};
271 RCP<const Basic>
exp(
const RCP<const Basic> &x)
Classes and functions relating to the binary operation of addition.
The lowest unit of symbolic representation.
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
hash_t __hash__() const override
Pow(const RCP< const Basic > &base, const RCP< const Basic > &exp)
Pow Constructor.
bool __eq__(const Basic &o) const override
vec_basic get_args() const override
Returns the list of arguments.
bool is_canonical(const Basic &base, const Basic &exp) const
int compare(const Basic &o) const override
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)
bool is_number_and_zero(const Basic &b)
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.
RCP< const Number > rational(long n, long d)
convenience creator from two longs
RCP< const Number > addnum(const RCP< const Number > &self, const RCP< const Number > &other)
Add self and other
RCP< const Basic > neg(const RCP< const Basic > &a)
Negation.