1 #include <symengine/refine.h>
6 void RefineVisitor::bvisit(
const Abs &x)
8 auto farg = x.get_arg();
9 auto newarg = apply(farg);
10 if (is_true(is_nonnegative(*newarg, assumptions_))) {
12 }
else if (is_true(is_nonpositive(*newarg, assumptions_))) {
13 result_ =
neg(newarg);
14 }
else if (is_a<Conjugate>(*newarg)) {
15 result_ =
abs(down_cast<const Conjugate &>(*newarg).get_arg());
17 result_ =
abs(newarg);
21 void RefineVisitor::bvisit(
const Sign &x)
23 auto farg = x.get_arg();
24 auto newarg = apply(farg);
25 if (is_true(is_positive(*newarg, assumptions_))) {
27 }
else if (is_true(is_negative(*newarg, assumptions_))) {
29 }
else if (is_true(is_zero(*newarg, assumptions_))) {
32 result_ =
sign(newarg);
36 void RefineVisitor::bvisit(
const Floor &x)
38 auto farg = x.get_arg();
39 auto newarg = apply(farg);
40 if (is_true(is_integer(*newarg, assumptions_))) {
45 result_ =
floor(newarg);
49 void RefineVisitor::bvisit(
const Ceiling &x)
51 auto farg = x.get_arg();
52 auto newarg = apply(farg);
53 if (is_true(is_integer(*newarg, assumptions_))) {
62 void RefineVisitor::bvisit(
const Conjugate &x)
64 auto farg = x.get_arg();
65 auto newarg = apply(farg);
66 if (is_true(is_real(*newarg, assumptions_))) {
73 void RefineVisitor::bvisit(
const Max &x)
77 vec_basic nonpositive;
80 bool have_positive =
false;
81 bool have_nonnegative =
false;
82 for (
auto arg : x.get_args()) {
83 auto newarg = apply(arg);
84 if (is_true(is_positive(*newarg, assumptions_))) {
85 keep.push_back(newarg);
87 }
else if (is_true(is_nonnegative(*newarg, assumptions_))) {
88 keep.push_back(newarg);
89 have_nonnegative =
true;
90 }
else if (is_true(is_negative(*newarg, assumptions_))) {
91 negative.push_back(newarg);
92 }
else if (is_true(is_nonpositive(*newarg, assumptions_))) {
93 nonpositive.push_back(newarg);
95 keep.push_back(newarg);
98 if (not have_positive and not nonpositive.empty()) {
99 std::copy(nonpositive.begin(), nonpositive.end(),
102 if (not have_nonnegative and not have_positive and not negative.empty()) {
109 void RefineVisitor::bvisit(
const Min &x)
113 vec_basic nonnegative;
116 bool have_negative =
false;
117 bool have_nonpositive =
false;
118 for (
auto arg : x.get_args()) {
119 auto newarg = apply(arg);
120 if (is_true(is_negative(*newarg, assumptions_))) {
121 keep.push_back(newarg);
122 have_negative =
true;
123 }
else if (is_true(is_nonpositive(*newarg, assumptions_))) {
124 keep.push_back(newarg);
125 have_nonpositive =
true;
126 }
else if (is_true(is_positive(*newarg, assumptions_))) {
127 positive.push_back(newarg);
128 }
else if (is_true(is_nonnegative(*newarg, assumptions_))) {
129 nonnegative.push_back(newarg);
131 keep.push_back(newarg);
134 if (not have_negative and not nonnegative.empty()) {
135 std::copy(nonnegative.begin(), nonnegative.end(),
138 if (not have_nonpositive and not have_negative and not positive.empty()) {
145 void RefineVisitor::bvisit(
const Pow &x)
147 auto exp = x.get_exp();
148 auto newexp = apply(
exp);
149 auto base = x.get_base();
150 auto newbase = apply(base);
152 if (is_a<Pow>(*newbase) and
is_a_Number(*newexp)) {
153 const Pow &inner_pow = down_cast<const Pow &>(*newbase);
154 auto inner_exp = inner_pow.get_exp();
155 auto inner_base = inner_pow.get_base();
156 if (is_true(is_real(*inner_base, assumptions_))
158 and not down_cast<const Number &>(*inner_exp).is_complex()
159 and not down_cast<const Number &>(*newexp).is_complex()) {
160 if (is_true(is_positive(*inner_base, assumptions_))) {
161 result_ =
pow(inner_base,
mul(newexp, inner_exp));
163 result_ =
pow(
abs(inner_base),
mul(newexp, inner_exp));
168 result_ =
pow(newbase, newexp);
171 void RefineVisitor::bvisit(
const Log &x)
173 auto farg = x.get_arg();
174 auto newarg = apply(farg);
175 if (is_a<Pow>(*newarg)) {
176 auto base = down_cast<const Pow &>(*newarg).get_base();
177 if (is_true(is_positive(*base, assumptions_))) {
178 auto exp = down_cast<const Pow &>(*newarg).get_exp();
179 if (is_true(is_real(*
exp, assumptions_))) {
184 }
else if (is_a<Integer>(*newarg)) {
186 down_cast<const Integer &>(*newarg).as_integer_class());
187 if (base_exp.second != 1) {
188 result_ =
mul(make_rcp<const Integer>(base_exp.second),
189 log(make_rcp<const Integer>(base_exp.first)));
193 result_ =
log(newarg);
196 void RefineVisitor::bvisit(
const Interval &x)
198 if (
eq(*x.get_start(), *SymEngine::infty(-1))
199 and
eq(*x.get_end(), *SymEngine::infty(1))) {
203 result_ = x.rcp_from_this();
206 RCP<const Basic> refine(
const RCP<const Basic> &x,
207 const Assumptions *assumptions)
209 RefineVisitor b(assumptions);
T back_inserter(T... args)
Main namespace for SymEngine package.
bool is_a_Number(const Basic &b)
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
RCP< const Reals > reals()
RCP< const Basic > max(const vec_basic &arg)
Canonicalize Max:
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
RCP< const Basic > sign(const RCP< const Basic > &arg)
Canonicalize Sign.
RCP< const Basic > ceiling(const RCP< const Basic > &arg)
Canonicalize Ceiling:
RCP< const Basic > abs(const RCP< const Basic > &arg)
Canonicalize Abs:
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
bool could_extract_minus(const Basic &arg)
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
RCP< const Basic > floor(const RCP< const Basic > &arg)
Canonicalize Floor:
std::pair< integer_class, integer_class > mp_perfect_power_decomposition(const integer_class &n, bool lowest_exponent)
Decompose a positive integer into perfect powers.
RCP< const Basic > log(const RCP< const Basic > &arg)
Returns the Natural Logarithm from argument arg
RCP< const Basic > min(const vec_basic &arg)
Canonicalize Min:
RCP< const Basic > neg(const RCP< const Basic > &a)
Negation.
RCP< const Basic > conjugate(const RCP< const Basic > &arg)
Canonicalize Conjugate.