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 SYMENGINE_EXPORT
23 RCP<const Basic> diff(const RCP<const Basic> &arg, const RCP<const Symbol> &x,
24  bool cache);
25 
26 SYMENGINE_EXPORT
27 RCP<const Basic> sdiff(const RCP<const Basic> &arg, const RCP<const Basic> &x,
28  bool cache);
29 
30 class SYMENGINE_EXPORT Expression
31 {
32 private:
33  RCP<const Basic> m_basic;
34 
35 public:
37  Expression() : m_basic(integer(0)) {}
39  template <class T>
41  T n,
42  typename std::enable_if<std::is_integral<T>::value>::type * = nullptr)
43  : m_basic(integer(n))
44  {
45  }
47  template <class T>
49  typename std::enable_if<std::is_floating_point<T>::value>::type
50  * = nullptr)
51  : m_basic(real_double(n))
52  {
53  }
55  template <class T>
56  Expression(std::complex<T> n,
57  typename std::enable_if<std::is_floating_point<T>::value>::type
58  * = nullptr)
59  : m_basic(complex_double(n))
60  {
61  }
62 
63  Expression(const integer_class &n) : m_basic(integer(n)) {}
64 
65  Expression(const rational_class &n) : m_basic(Rational::from_mpq(n)) {}
66 
67  Expression(RCP<const Basic> &&o) : m_basic(o) {}
68 
69  Expression(const RCP<const Basic> &o) : m_basic(o) {}
70 
71  Expression(const std::string &s);
72 
74  Expression(const Expression &) = default;
76  Expression(Expression &&other) SYMENGINE_NOEXCEPT
77  : m_basic(std::move(other.m_basic))
78  {
79  }
81  Expression &operator=(const Expression &) = default;
83  Expression &operator=(Expression &&other) SYMENGINE_NOEXCEPT
84  {
85  if (this != &other) {
86  this->m_basic = std::move(other.m_basic);
87  }
88  return *this;
89  }
91  virtual ~Expression() SYMENGINE_NOEXCEPT {}
93  friend std::ostream &operator<<(std::ostream &os, const Expression &expr)
94  {
95  os << expr.m_basic->__str__();
96  return os;
97  }
99  friend Expression operator+(const Expression &a, const Expression &b)
100  {
101  return Expression(add(a.m_basic, b.m_basic));
102  }
103  friend Expression operator+(const RCP<const Basic> &a, const Expression &b)
104  {
105  return Expression(add(a, b.m_basic));
106  }
107  friend Expression operator+(const Expression &a, const RCP<const Basic> &b)
108  {
109  return Expression(add(a.m_basic, b));
110  }
113  {
114  m_basic = add(m_basic, other.m_basic);
115  return *this;
116  }
117  Expression &operator+=(const RCP<const Basic> &other)
118  {
119  m_basic = add(m_basic, other);
120  return *this;
121  }
123  friend Expression operator-(const Expression &a, const Expression &b)
124  {
125  return Expression(sub(a.m_basic, b.m_basic));
126  }
127  friend Expression operator-(const RCP<const Basic> &a, const Expression &b)
128  {
129  return Expression(sub(a, b.m_basic));
130  }
131  friend Expression operator-(const Expression &a, const RCP<const Basic> &b)
132  {
133  return Expression(sub(a.m_basic, b));
134  }
135  operator const RCP<const Basic> &() const
136  {
137  return m_basic;
138  }
140  Expression diff(const RCP<const Symbol> &x, bool cache = true) const
141  {
142  return Expression(SymEngine::diff(m_basic, x, cache));
143  }
145  Expression diff(const RCP<const Basic> &x, bool cache = true) const
146  {
147  return Expression(sdiff(m_basic, x, cache));
148  }
150  Expression subs(const map_basic_basic &subs_map) const
151  {
152  return Expression(m_basic->subs(subs_map));
153  }
155  template <typename T,
156  typename
157  = typename std::enable_if<std::is_arithmetic<T>::value>::type>
158  explicit operator T() const
159  {
160  return T(eval_double(*get_basic()));
161  }
163  template <typename T,
164  typename
165  = typename std::enable_if<std::is_arithmetic<T>::value>::type>
166  explicit operator std::complex<T>() const
167  {
168  return std::complex<T>(eval_complex_double(*get_basic()));
169  }
170  operator const Basic &() const
171  {
172  return *m_basic;
173  }
176  {
177  Expression retval(*this);
178  retval *= -1;
179  return retval;
180  }
183  {
184  m_basic = sub(m_basic, other.m_basic);
185  return *this;
186  }
187  Expression &operator-=(const RCP<const Basic> &other)
188  {
189  m_basic = sub(m_basic, other);
190  return *this;
191  }
193  friend Expression operator*(const Expression &a, const Expression &b)
194  {
195  return Expression(mul(a.m_basic, b.m_basic));
196  }
197  friend Expression operator*(const RCP<const Basic> &a, const Expression &b)
198  {
199  return Expression(mul(a, b.m_basic));
200  }
201  friend Expression operator*(const Expression &a, const RCP<const Basic> &b)
202  {
203  return Expression(mul(a.m_basic, b));
204  }
207  {
208  m_basic = mul(m_basic, other.m_basic);
209  return *this;
210  }
211  Expression &operator*=(const RCP<const Basic> &other)
212  {
213  m_basic = mul(m_basic, other);
214  return *this;
215  }
217  friend Expression operator/(const Expression &a, const Expression &b)
218  {
219  return Expression(div(a.m_basic, b.m_basic));
220  }
221  friend Expression operator/(const RCP<const Basic> &a, const Expression &b)
222  {
223  return Expression(div(a, b.m_basic));
224  }
225  friend Expression operator/(const Expression &a, const RCP<const Basic> &b)
226  {
227  return Expression(div(a.m_basic, b));
228  }
231  {
232  m_basic = div(m_basic, other.m_basic);
233  return *this;
234  }
235  Expression &operator/=(const RCP<const Basic> &other)
236  {
237  m_basic = div(m_basic, other);
238  return *this;
239  }
241  bool operator==(const Expression &other) const
242  {
243  return eq(*m_basic, *other.m_basic);
244  }
245  bool operator==(const RCP<const Basic> &other) const
246  {
247  return eq(*m_basic, *other);
248  }
249 
251  bool operator!=(const Expression &other) const
252  {
253  return not(*this == other);
254  }
255  bool operator!=(const RCP<const Basic> &other) const
256  {
257  return not(*this == other);
258  }
259 
261  const RCP<const Basic> &get_basic() const
262  {
263  return m_basic;
264  }
265 };
266 
267 inline Expression pow(const Expression &base, const Expression &exp)
268 {
269  return pow(base.get_basic(), exp.get_basic());
270 }
271 
272 inline void mp_pow_ui(Expression &res, const Expression &base,
273  unsigned long exp)
274 {
275  res = pow(base, Expression(integer(static_cast<signed long>(exp))));
276 }
277 
278 inline Expression expand(const Expression &arg)
279 {
280  return expand(arg.get_basic());
281 }
282 
283 inline bool unified_eq(const Expression &a, const Expression &b)
284 {
285  return a == b;
286 }
287 
288 inline int unified_compare(const Expression &a, const Expression &b)
289 {
290  return unified_compare(a.get_basic(), b.get_basic());
291 }
292 
293 // Utility functions for piranha
294 
295 namespace detail
296 {
297 // This function must have external linkage
298 SYMENGINE_EXPORT std::string poly_print(const Expression &x);
299 } // namespace detail
300 
301 } // namespace SymEngine
302 
303 #ifdef HAVE_SYMENGINE_PIRANHA
304 
305 #include <piranha/math.hpp>
306 #include <piranha/pow.hpp>
307 #include <piranha/print_coefficient.hpp>
308 namespace piranha
309 {
310 namespace math
311 {
312 
313 template <typename T>
314 struct partial_impl<T, typename std::enable_if<std::is_same<
315  T, SymEngine::Expression>::value>::type> {
317 
320  SymEngine::Expression operator()(const SymEngine::Expression &,
321  const std::string &) const
322  {
323  return SymEngine::Expression(0);
324  }
325 };
326 
327 template <typename T, typename U>
328 struct pow_impl<
329  T, U,
330  typename std::enable_if<std::is_same<T, SymEngine::Expression>::value
331  && std::is_integral<U>::value>::type> {
332  SymEngine::Expression operator()(const SymEngine::Expression &x,
333  const U &y) const
334  {
335  return SymEngine::pow(SymEngine::Expression(x).get_basic(),
336  SymEngine::integer(y));
337  }
338 };
339 } // namespace math
340 
341 template <typename U>
342 struct print_coefficient_impl<U, typename std::enable_if<std::is_same<
343  U, SymEngine::Expression>::value>::type> {
344  auto operator()(std::ostream &os, const U &cf) const -> decltype(os << cf)
345  {
346  return os << SymEngine::detail::poly_print(cf);
347  }
348 };
349 } // namespace piranha
350 #endif // HAVE_SYMENGINE_PIRANHA
351 
352 // Utility functions for xeus-cling and xeus-cpp-lite
353 #if defined(__CLING__) || (defined(__CLANG_REPL__) && defined(__EMSCRIPTEN__))
354 
355 // clang-format off
356 #if defined(__has_include) && __has_include(<nlohmann/json.hpp>)
357 // clang-format on
358 #include <nlohmann/json.hpp>
359 
360 namespace SymEngine
361 {
362 
363 inline nlohmann::json mime_bundle_repr(const Expression &i)
364 {
365  auto bundle = nlohmann::json::object();
366  bundle["text/plain"] = str(i);
367  bundle["text/latex"] = "$" + latex(i) + "$";
368  return bundle;
369 }
370 
371 } // namespace SymEngine
372 #endif
373 #endif
374 
375 #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:48
Expression & operator-=(const Expression &other)
Overload subtraction and assignment(-=)
Definition: expression.h:182
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:40
friend Expression operator+(const Expression &a, const Expression &b)
Overload addition.
Definition: expression.h:99
Expression diff(const RCP< const Symbol > &x, bool cache=true) const
Differentiation.
Definition: expression.h:140
Expression subs(const map_basic_basic &subs_map) const
Substitution.
Definition: expression.h:150
const RCP< const Basic > & get_basic() const
Method to get Basic from Expression.
Definition: expression.h:261
friend Expression operator/(const Expression &a, const Expression &b)
Overload Division.
Definition: expression.h:217
Expression & operator=(Expression &&other) SYMENGINE_NOEXCEPT
Overload assignment operator for reference.
Definition: expression.h:83
friend Expression operator-(const Expression &a, const Expression &b)
Overload subtraction.
Definition: expression.h:123
Expression diff(const RCP< const Basic > &x, bool cache=true) const
Differentiation.
Definition: expression.h:145
friend Expression operator*(const Expression &a, const Expression &b)
Overload multiplication.
Definition: expression.h:193
Expression & operator/=(const Expression &other)
Overload Division and assignment (/=)
Definition: expression.h:230
virtual ~Expression() SYMENGINE_NOEXCEPT
Destructor of Expression.
Definition: expression.h:91
friend std::ostream & operator<<(std::ostream &os, const Expression &expr)
Overload stream operator.
Definition: expression.h:93
bool operator==(const Expression &other) const
Overload check equality (==)
Definition: expression.h:241
Expression & operator=(const Expression &)=default
Overload assignment operator.
Expression & operator*=(const Expression &other)
Overload multiplication and assignment (*=)
Definition: expression.h:206
Expression operator-() const
Overload unary negative.
Definition: expression.h:175
Expression(Expression &&other) SYMENGINE_NOEXCEPT
Construct Expression from reference to Expression.
Definition: expression.h:76
Expression()
Plain constructor of Expression.
Definition: expression.h:37
Expression & operator+=(const Expression &other)
Overload addition and assignment(+=)
Definition: expression.h:112
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:56
bool operator!=(const Expression &other) const
Overload check not equal (!=)
Definition: expression.h:251
Main namespace for SymEngine package.
Definition: add.cpp:19
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition: add.cpp:425
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
Definition: pow.cpp:271
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 > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition: mul.cpp:431
int unified_compare(const T &a, const T &b)
Definition: dict.h:205
SYMENGINE_EXPORT RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self
Definition: expand.cpp:369