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 std::string type_code_name(TypeID id);
56 
57 #include "basic-methods.inc"
58 
59 class Visitor;
60 class Symbol;
61 
96 class 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  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 bool eq(const Basic &a, const Basic &b);
244 
246 bool neq(const Basic &a, const Basic &b);
247 
251 template <class T>
252 bool is_a(const Basic &b);
253 
255 bool is_a_Atom(const Basic &b);
256 
263 template <class T>
264 bool is_a_sub(const Basic &b);
265 
267 bool is_same_type(const Basic &a, const Basic &b);
268 
270 RCP<const Basic> expand(const RCP<const Basic> &self, bool deep = true);
271 void as_numer_denom(const RCP<const Basic> &x,
272  const Ptr<RCP<const Basic>> &numer,
273  const Ptr<RCP<const Basic>> &denom);
274 
275 void as_real_imag(const RCP<const Basic> &x, const Ptr<RCP<const Basic>> &real,
276  const Ptr<RCP<const Basic>> &imag);
277 
278 RCP<const Basic> rewrite_as_exp(const RCP<const Basic> &x);
279 RCP<const Basic> rewrite_as_sin(const RCP<const Basic> &x);
280 RCP<const Basic> rewrite_as_cos(const RCP<const Basic> &x);
281 
282 // Common subexpression elimination of symbolic expressions
283 // Return a vector of replacement pairs and a vector of reduced exprs
284 void cse(vec_pair &replacements, vec_basic &reduced_exprs,
285  const vec_basic &exprs);
286 
294 
310 template <class T>
311 void hash_combine(hash_t &seed, const T &v);
312 
313 const char *get_version();
314 
315 } // namespace SymEngine
316 
317 namespace std
318 {
320 template <>
321 struct hash<SymEngine::Basic>;
322 } // namespace std
323 
325 #include "basic-inl.h"
326 #include <symengine/tribool.h>
327 
328 // Macro to define the type_code_id variable and its getter method
329 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
330 #define IMPLEMENT_TYPEID(SYMENGINE_ID) \
331  \
332  const static TypeID type_code_id = SYMENGINE_ID; \
333  \
334  virtual TypeID get_type_code() const \
335  { \
336  return type_code_id; \
337  }; \
338  SYMENGINE_INCLUDE_METHODS_DERIVED()
339 #else
340 #define IMPLEMENT_TYPEID(SYMENGINE_ID) \
341  \
342  const static TypeID type_code_id = SYMENGINE_ID; \
343  SYMENGINE_INCLUDE_METHODS_DERIVED()
344 #endif
345 
346 #ifdef WITH_SYMENGINE_VIRTUAL_TYPEID
347 #define SYMENGINE_ASSIGN_TYPEID()
348 #else
349 #define SYMENGINE_ASSIGN_TYPEID() this->type_code_ = type_code_id;
350 #endif
351 
352 #endif
The lowest unit of symbolic representation.
Definition: basic.h:97
bool __neq__(const Basic &o) const
true if this is not equal to o.
Definition: basic-inl.h:15
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.
RCP< const Basic > subs(const map_basic_basic &subs_dict) const
Substitutes 'subs_dict' into 'self'.
Definition: basic.cpp:80
std::string dumps() const
Returns a string of the instance serialized.
Definition: basic.cpp:51
Basic & operator=(const Basic &)=delete
Assignment operator in continuation with above.
std::string __str__() const
Definition: basic.cpp:46
static RCP< const Basic > loads(const std::string &)
Creates an instance of a serialized string.
Definition: basic.cpp:61
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
int __cmp__(const Basic &o) const
Comparison operator.
Definition: basic.cpp:31
virtual int compare(const Basic &o) const =0
Basic & operator=(Basic &&)=delete
Assignment operator in continuation with above.
hash_t hash() const
Definition: basic-inl.h:7
Main namespace for SymEngine package.
Definition: add.cpp:19
bool is_a_sub(const Basic &b)
Definition: basic-inl.h:42
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition: basic-inl.h:21
void hash_combine(hash_t &seed, const T &v)
Definition: basic-inl.h:95
bool is_a(const Basic &b)
Templatised version to check is_a type.
Definition: basic-inl.h:36
TypeID
Definition: basic.h:43
@ TypeID_Count
Definition: basic.h:52
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:95
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:47
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
Definition: basic-inl.h:29
RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self
Definition: expand.cpp:369
std::ostream & operator<<(std::ostream &out, const SymEngine::Basic &p)
<< Operator
Definition: basic-inl.h:53
STL namespace.
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