basic.h
Go to the documentation of this file.
1 
11 #ifndef SYMENGINE_BASIC_H
12 #define SYMENGINE_BASIC_H
13 
14 // Include all C++ headers here
15 #include <sstream>
16 #include <typeinfo>
17 #include <map>
18 #include <vector>
19 #include <set>
20 #include <unordered_map>
21 #include <unordered_set>
22 #include <cassert>
23 #include <cmath>
24 #include <complex>
25 #include <vector>
26 #include <type_traits>
27 #include <functional>
28 #include <algorithm>
29 
30 #include <symengine/symengine_config.h>
31 #include <symengine/symengine_exception.h>
32 
33 #ifdef WITH_SYMENGINE_THREAD_SAFE
34 #include <atomic>
35 #endif
36 
37 #include <symengine/dict.h>
38 
40 namespace SymEngine
41 {
42 
43 enum TypeID {
44 #define SYMENGINE_INCLUDE_ALL
45 #define SYMENGINE_ENUM(type, Class) type,
46 #include "symengine/type_codes.inc"
47 #undef SYMENGINE_ENUM
48 #undef SYMENGINE_INCLUDE_ALL
53 };
54 
55 SYMENGINE_EXPORT std::string type_code_name(TypeID id);
56 
57 #include "basic-methods.inc"
58 
59 class Visitor;
60 class Symbol;
61 
96 class SYMENGINE_EXPORT Basic : public EnableRCPFromThis<Basic>
97 {
98 private:
100 // The hash_ is defined as mutable, because its value is initialized to 0
101 // in the constructor and then it can be changed in Basic::hash() to the
102 // current hash (which is always the same for the given instance). The
103 // state of the instance does not change, so we define hash_ as mutable.
104 #if defined(WITH_SYMENGINE_THREAD_SAFE)
105  mutable std::atomic<hash_t> hash_; // This holds the hash value
106 #else
107  mutable hash_t hash_; // This holds the hash value
108 #endif // WITH_SYMENGINE_THREAD_SAFE
109 public:
110 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
111  virtual TypeID get_type_code() const = 0;
112 #else
113  TypeID type_code_;
114  inline TypeID get_type_code() const
115  {
116  return type_code_;
117  };
118 #endif
120  Basic() : hash_{0} {}
121  // Destructor must be explicitly defined as virtual here to avoid problems
122  // with undefined behavior while deallocating derived classes.
123  virtual ~Basic() {}
124 
126  Basic(const Basic &) = delete;
128  Basic &operator=(const Basic &) = delete;
129 
131  Basic(Basic &&) = delete;
133  Basic &operator=(Basic &&) = delete;
134 
140  virtual hash_t __hash__() const = 0;
141 
153  inline hash_t hash() const;
154 
165  virtual bool __eq__(const Basic &o) const = 0;
166 
168  bool __neq__(const Basic &o) const;
169 
171  int __cmp__(const Basic &o) const;
172 
178  virtual int compare(const Basic &o) const = 0;
179 
182  std::string __str__() const;
183 
185  std::string dumps() const;
186 
188  static RCP<const Basic> loads(const std::string &);
189 
191  RCP<const Basic> subs(const map_basic_basic &subs_dict) const;
192 
193  RCP<const Basic> xreplace(const map_basic_basic &subs_dict) const;
194 
196  virtual RCP<const Basic> expand_as_exp() const
197  {
198  throw NotImplementedError("Not Implemented");
199  }
200 
202  virtual vec_basic get_args() const = 0;
203 
204  SYMENGINE_INCLUDE_METHODS_BASE()
205 
206  RCP<const Basic> diff(const RCP<const Symbol> &x, bool cache = true) const;
207 };
208 
210 struct RCPBasicHash {
212  size_t operator()(const RCP<const Basic> &k) const
213  {
214  return static_cast<size_t>(k->hash());
215  }
216 };
217 
221  bool operator()(const RCP<const Basic> &x, const RCP<const Basic> &y) const
222  {
223  return eq(*x, *y);
224  }
225 };
226 
230  bool operator()(const RCP<const Basic> &x, const RCP<const Basic> &y) const
231  {
232  hash_t xh = x->hash(), yh = y->hash();
233  if (xh != yh)
234  return xh < yh;
235  if (eq(*x, *y))
236  return false;
237  return x->__cmp__(*y) == -1;
238  }
239 };
240 
241 // Convenience functions
243 inline bool eq(const Basic &a, const Basic &b);
244 
246 SYMENGINE_EXPORT bool neq(const Basic &a, const Basic &b);
247 
251 template <class T>
252 bool is_a(const Basic &b);
253 
255 SYMENGINE_EXPORT bool is_a_Atom(const Basic &b);
256 
263 template <class T>
264 bool is_a_sub(const Basic &b);
265 
267 SYMENGINE_EXPORT bool is_same_type(const Basic &a, const Basic &b);
268 
270 SYMENGINE_EXPORT RCP<const Basic> expand(const RCP<const Basic> &self,
271  bool deep = true);
272 SYMENGINE_EXPORT void as_numer_denom(const RCP<const Basic> &x,
273  const Ptr<RCP<const Basic>> &numer,
274  const Ptr<RCP<const Basic>> &denom);
275 
276 SYMENGINE_EXPORT void as_real_imag(const RCP<const Basic> &x,
277  const Ptr<RCP<const Basic>> &real,
278  const Ptr<RCP<const Basic>> &imag);
279 
280 SYMENGINE_EXPORT RCP<const Basic> rewrite_as_exp(const RCP<const Basic> &x);
281 SYMENGINE_EXPORT RCP<const Basic> rewrite_as_sin(const RCP<const Basic> &x);
282 SYMENGINE_EXPORT RCP<const Basic> rewrite_as_cos(const RCP<const Basic> &x);
283 
284 // Common subexpression elimination of symbolic expressions
285 // Return a vector of replacement pairs and a vector of reduced exprs
286 SYMENGINE_EXPORT
287 void cse(vec_pair &replacements, vec_basic &reduced_exprs,
288  const vec_basic &exprs);
289 
296 SYMENGINE_EXPORT std::ostream &operator<<(std::ostream &out,
297  const SymEngine::Basic &p);
298 
314 template <class T>
315 void hash_combine(hash_t &seed, const T &v);
316 
317 SYMENGINE_EXPORT const char *get_version();
318 
319 } // namespace SymEngine
320 
321 namespace std
322 {
324 template <>
325 struct hash<SymEngine::Basic>;
326 } // namespace std
327 
329 #include "basic-inl.h"
330 #include <symengine/tribool.h>
331 
332 // Macro to define the type_code_id variable and its getter method
333 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
334 #define IMPLEMENT_TYPEID(SYMENGINE_ID) \
335  \
336  const static TypeID type_code_id = SYMENGINE_ID; \
337  \
338  virtual TypeID get_type_code() const \
339  { \
340  return type_code_id; \
341  }; \
342  SYMENGINE_INCLUDE_METHODS_DERIVED()
343 #else
344 #define IMPLEMENT_TYPEID(SYMENGINE_ID) \
345  \
346  const static TypeID type_code_id = SYMENGINE_ID; \
347  SYMENGINE_INCLUDE_METHODS_DERIVED()
348 #endif
349 
350 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
351 #define SYMENGINE_ASSIGN_TYPEID()
352 #else
353 #define SYMENGINE_ASSIGN_TYPEID() this->type_code_ = type_code_id;
354 #endif
355 
356 #endif
The lowest unit of symbolic representation.
Definition: basic.h:97
Basic(Basic &&)=delete
Delete the move constructor and assignment.
Basic()
Constructor.
Definition: basic.h:120
virtual RCP< const Basic > expand_as_exp() const
expands the special function in terms of exp function
Definition: basic.h:196
virtual vec_basic get_args() const =0
Returns the list of arguments.
Basic & operator=(const Basic &)=delete
Assignment operator in continuation with above.
Basic(const Basic &)=delete
Delete the copy constructor and assignment.
virtual bool __eq__(const Basic &o) const =0
Test equality.
virtual hash_t __hash__() const =0
hash_t hash_
Private variables.
Definition: basic.h:107
virtual int compare(const Basic &o) const =0
Basic & operator=(Basic &&)=delete
Assignment operator in continuation with above.
Main namespace for SymEngine package.
Definition: add.cpp:19
bool is_a_sub(const Basic &b)
void hash_combine(hash_t &seed, const T &v)
Definition: basic-inl.h:97
bool is_a(const Basic &b)
Templatised version to check is_a type.
Definition: basic-inl.h:36
bool is_a_Atom(const Basic &b)
Returns true if b is an atom. i.e. b.get_args returns an empty vector.
Definition: basic.cpp:105
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
bool is_same_type(const Basic &a, const Basic &b)
Returns true if a and b are exactly the same type T.
Definition: basic-inl.h:49
TypeID
Definition: basic.h:43
@ TypeID_Count
Definition: basic.h:52
std::ostream & operator<<(std::ostream &out, const SymEngine::Basic &p)
<< Operator
Definition: basic-inl.h:55
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
Definition: basic-inl.h:29
SYMENGINE_EXPORT RCP< const Basic > xreplace(const RCP< const Basic > &x, const map_basic_basic &subs_dict, bool cache=true)
Mappings in the subs_dict are applied to the expression tree of x
Definition: subs.h:351
SYMENGINE_EXPORT RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self
Definition: expand.cpp:369
size_t operator()(const RCP< const Basic > &k) const
Returns the hashed value.
Definition: basic.h:212
Our comparison (==)
Definition: basic.h:219
bool operator()(const RCP< const Basic > &x, const RCP< const Basic > &y) const
Comparison Operator ==
Definition: basic.h:221
Our less operator (<):
Definition: basic.h:228
bool operator()(const RCP< const Basic > &x, const RCP< const Basic > &y) const
true if x < y, false otherwise
Definition: basic.h:230