expression.h
Go to the documentation of this file.
1 
7 #ifndef SYMENGINE_EXPRESSION_H
8 #define SYMENGINE_EXPRESSION_H
9 
10 #include <symengine/add.h>
11 #include <symengine/pow.h>
12 #include <symengine/symbol.h>
13 #include <symengine/complex_double.h>
14 #include <symengine/eval_double.h>
15 #include <symengine/printers.h>
16 
17 namespace SymEngine
18 {
19 
20 // Forward declare these here to avoid including derivative.h and break the
21 // cycle
22 RCP<const Basic> diff(const RCP<const Basic> &arg, const RCP<const Symbol> &x,
23  bool cache);
24 
25 RCP<const Basic> sdiff(const RCP<const Basic> &arg, const RCP<const Basic> &x,
26  bool cache);
27 
29 {
30 private:
31  RCP<const Basic> m_basic;
32 
33 public:
35  Expression() : m_basic(integer(0)) {}
37  template <class T>
39  T n,
40  typename std::enable_if<std::is_integral<T>::value>::type * = nullptr)
41  : m_basic(integer(n))
42  {
43  }
45  template <class T>
48  * = nullptr)
49  : m_basic(real_double(n))
50  {
51  }
53  template <class T>
56  * = nullptr)
57  : m_basic(complex_double(n))
58  {
59  }
60 
61  Expression(const integer_class &n) : m_basic(integer(n)) {}
62 
63  Expression(const rational_class &n) : m_basic(Rational::from_mpq(n)) {}
64 
65  Expression(RCP<const Basic> &&o) : m_basic(o) {}
66 
67  Expression(const RCP<const Basic> &o) : m_basic(o) {}
68 
69  Expression(const std::string &s);
70 
72  Expression(const Expression &) = default;
74  Expression(Expression &&other) SYMENGINE_NOEXCEPT
75  : m_basic(std::move(other.m_basic))
76  {
77  }
79  Expression &operator=(const Expression &) = default;
81  Expression &operator=(Expression &&other) SYMENGINE_NOEXCEPT
82  {
83  if (this != &other) {
84  this->m_basic = std::move(other.m_basic);
85  }
86  return *this;
87  }
89  virtual ~Expression() SYMENGINE_NOEXCEPT {}
91  friend std::ostream &operator<<(std::ostream &os, const Expression &expr)
92  {
93  os << expr.m_basic->__str__();
94  return os;
95  }
97  friend Expression operator+(const Expression &a, const Expression &b)
98  {
99  return Expression(add(a.m_basic, b.m_basic));
100  }
101  friend Expression operator+(const RCP<const Basic> &a, const Expression &b)
102  {
103  return Expression(add(a, b.m_basic));
104  }
105  friend Expression operator+(const Expression &a, const RCP<const Basic> &b)
106  {
107  return Expression(add(a.m_basic, b));
108  }
111  {
112  m_basic = add(m_basic, other.m_basic);
113  return *this;
114  }
115  Expression &operator+=(const RCP<const Basic> &other)
116  {
117  m_basic = add(m_basic, other);
118  return *this;
119  }
121  friend Expression operator-(const Expression &a, const Expression &b)
122  {
123  return Expression(sub(a.m_basic, b.m_basic));
124  }
125  friend Expression operator-(const RCP<const Basic> &a, const Expression &b)
126  {
127  return Expression(sub(a, b.m_basic));
128  }
129  friend Expression operator-(const Expression &a, const RCP<const Basic> &b)
130  {
131  return Expression(sub(a.m_basic, b));
132  }
133  operator const RCP<const Basic> &() const
134  {
135  return m_basic;
136  }
138  Expression diff(const RCP<const Symbol> &x, bool cache = true) const
139  {
140  return Expression(SymEngine::diff(m_basic, x, cache));
141  }
143  Expression diff(const RCP<const Basic> &x, bool cache = true) const
144  {
145  return Expression(sdiff(m_basic, x, cache));
146  }
148  Expression subs(const map_basic_basic &subs_map) const
149  {
150  return Expression(m_basic->subs(subs_map));
151  }
153  template <typename T,
154  typename
156  explicit operator T() const
157  {
158  return T(eval_double(*get_basic()));
159  }
161  template <typename T,
162  typename
164  explicit operator std::complex<T>() const
165  {
166  return std::complex<T>(eval_complex_double(*get_basic()));
167  }
168  operator const Basic &() const
169  {
170  return *m_basic;
171  }
174  {
175  Expression retval(*this);
176  retval *= -1;
177  return retval;
178  }
181  {
182  m_basic = sub(m_basic, other.m_basic);
183  return *this;
184  }
185  Expression &operator-=(const RCP<const Basic> &other)
186  {
187  m_basic = sub(m_basic, other);
188  return *this;
189  }
191  friend Expression operator*(const Expression &a, const Expression &b)
192  {
193  return Expression(mul(a.m_basic, b.m_basic));
194  }
195  friend Expression operator*(const RCP<const Basic> &a, const Expression &b)
196  {
197  return Expression(mul(a, b.m_basic));
198  }
199  friend Expression operator*(const Expression &a, const RCP<const Basic> &b)
200  {
201  return Expression(mul(a.m_basic, b));
202  }
205  {
206  m_basic = mul(m_basic, other.m_basic);
207  return *this;
208  }
209  Expression &operator*=(const RCP<const Basic> &other)
210  {
211  m_basic = mul(m_basic, other);
212  return *this;
213  }
215  friend Expression operator/(const Expression &a, const Expression &b)
216  {
217  return Expression(div(a.m_basic, b.m_basic));
218  }
219  friend Expression operator/(const RCP<const Basic> &a, const Expression &b)
220  {
221  return Expression(div(a, b.m_basic));
222  }
223  friend Expression operator/(const Expression &a, const RCP<const Basic> &b)
224  {
225  return Expression(div(a.m_basic, b));
226  }
229  {
230  m_basic = div(m_basic, other.m_basic);
231  return *this;
232  }
233  Expression &operator/=(const RCP<const Basic> &other)
234  {
235  m_basic = div(m_basic, other);
236  return *this;
237  }
239  bool operator==(const Expression &other) const
240  {
241  return eq(*m_basic, *other.m_basic);
242  }
243  bool operator==(const RCP<const Basic> &other) const
244  {
245  return eq(*m_basic, *other);
246  }
247 
249  bool operator!=(const Expression &other) const
250  {
251  return not(*this == other);
252  }
253  bool operator!=(const RCP<const Basic> &other) const
254  {
255  return not(*this == other);
256  }
257 
259  const RCP<const Basic> &get_basic() const
260  {
261  return m_basic;
262  }
263 };
264 
265 inline Expression pow(const Expression &base, const Expression &exp)
266 {
267  return pow(base.get_basic(), exp.get_basic());
268 }
269 
270 inline Expression expand(const Expression &arg)
271 {
272  return expand(arg.get_basic());
273 }
274 
275 inline bool unified_eq(const Expression &a, const Expression &b)
276 {
277  return a == b;
278 }
279 
280 inline int unified_compare(const Expression &a, const Expression &b)
281 {
282  return unified_compare(a.get_basic(), b.get_basic());
283 }
284 
285 // Utility functions for piranha
286 
287 namespace detail
288 {
289 // This function must have external linkage
290 std::string poly_print(const Expression &x);
291 } // namespace detail
292 
293 } // namespace SymEngine
294 
295 #ifdef HAVE_SYMENGINE_PIRANHA
296 
297 #include <piranha/math.hpp>
298 #include <piranha/pow.hpp>
299 #include <piranha/print_coefficient.hpp>
300 namespace piranha
301 {
302 namespace math
303 {
304 
305 template <typename T>
306 struct partial_impl<T, typename std::enable_if<std::is_same<
307  T, SymEngine::Expression>::value>::type> {
309 
312  SymEngine::Expression operator()(const SymEngine::Expression &,
313  const std::string &) const
314  {
315  return SymEngine::Expression(0);
316  }
317 };
318 
319 template <typename T, typename U>
320 struct pow_impl<
321  T, U,
322  typename std::enable_if<std::is_same<T, SymEngine::Expression>::value
323  && std::is_integral<U>::value>::type> {
324  SymEngine::Expression operator()(const SymEngine::Expression &x,
325  const U &y) const
326  {
327  return SymEngine::pow(SymEngine::Expression(x).get_basic(),
328  SymEngine::integer(y));
329  }
330 };
331 } // namespace math
332 
333 template <typename U>
334 struct print_coefficient_impl<U, typename std::enable_if<std::is_same<
335  U, SymEngine::Expression>::value>::type> {
336  auto operator()(std::ostream &os, const U &cf) const -> decltype(os << cf)
337  {
338  return os << SymEngine::detail::poly_print(cf);
339  }
340 };
341 } // namespace piranha
342 #endif // HAVE_SYMENGINE_PIRANHA
343 
344 // Utility functions for xeus-cling
345 namespace SymEngine
346 {
347 
348 #ifdef __CLING__
349 // clang-format off
350 #if defined(__has_include) && __has_include(<nlohmann/json.hpp>)
351 // clang-format on
352 #include <nlohmann/json.hpp>
353 
354 inline nlohmann::json mime_bundle_repr(const Expression &i)
355 {
356  auto bundle = nlohmann::json::object();
357  bundle["text/plain"] = str(i);
358  bundle["text/latex"] = "$" + latex(i) + "$";
359  return bundle;
360 }
361 #endif
362 #endif
363 
364 } // namespace SymEngine
365 
366 #endif // SYMENGINE_EXPRESSION_H
Classes and functions relating to the binary operation of addition.
The lowest unit of symbolic representation.
Definition: basic.h:97
Expression(T n, typename std::enable_if< std::is_floating_point< T >::value >::type *=nullptr)
Construct Expression from floating point types.
Definition: expression.h:46
Expression & operator-=(const Expression &other)
Overload subtraction and assignment(-=)
Definition: expression.h:180
Expression(const Expression &)=default
Construct Expression from Expression.
Expression(T n, typename std::enable_if< std::is_integral< T >::value >::type *=nullptr)
Construct Expression from integral types.
Definition: expression.h:38
friend Expression operator+(const Expression &a, const Expression &b)
Overload addition.
Definition: expression.h:97
Expression diff(const RCP< const Symbol > &x, bool cache=true) const
Differentiation.
Definition: expression.h:138
Expression subs(const map_basic_basic &subs_map) const
Substitution.
Definition: expression.h:148
const RCP< const Basic > & get_basic() const
Method to get Basic from Expression.
Definition: expression.h:259
friend Expression operator/(const Expression &a, const Expression &b)
Overload Division.
Definition: expression.h:215
Expression & operator=(Expression &&other) SYMENGINE_NOEXCEPT
Overload assignment operator for reference.
Definition: expression.h:81
friend Expression operator-(const Expression &a, const Expression &b)
Overload subtraction.
Definition: expression.h:121
Expression diff(const RCP< const Basic > &x, bool cache=true) const
Differentiation.
Definition: expression.h:143
friend Expression operator*(const Expression &a, const Expression &b)
Overload multiplication.
Definition: expression.h:191
Expression & operator/=(const Expression &other)
Overload Division and assignment (/=)
Definition: expression.h:228
virtual ~Expression() SYMENGINE_NOEXCEPT
Destructor of Expression.
Definition: expression.h:89
friend std::ostream & operator<<(std::ostream &os, const Expression &expr)
Overload stream operator.
Definition: expression.h:91
bool operator==(const Expression &other) const
Overload check equality (==)
Definition: expression.h:239
Expression & operator=(const Expression &)=default
Overload assignment operator.
Expression & operator*=(const Expression &other)
Overload multiplication and assignment (*=)
Definition: expression.h:204
Expression operator-() const
Overload unary negative.
Definition: expression.h:173
Expression(Expression &&other) SYMENGINE_NOEXCEPT
Construct Expression from reference to Expression.
Definition: expression.h:74
Expression()
Plain constructor of Expression.
Definition: expression.h:35
Expression & operator+=(const Expression &other)
Overload addition and assignment(+=)
Definition: expression.h:110
Expression(std::complex< T > n, typename std::enable_if< std::is_floating_point< T >::value >::type *=nullptr)
Construct Expression from std::complex<> types.
Definition: expression.h:54
bool operator!=(const Expression &other) const
Overload check not equal (!=)
Definition: expression.h:249
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition: mul.cpp:431
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
RCP< const Basic > sub(const RCP< const Basic > &a, const RCP< const Basic > &b)
Substracts b from a.
Definition: add.cpp:495
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
Definition: pow.cpp:271
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition: add.cpp:425
int unified_compare(const T &a, const T &b)
Definition: dict.h:205
RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self
Definition: expand.cpp:369
STL namespace.