|
GiNaC
1.6.2
|
00001 00005 /* 00006 * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #ifndef GINAC_BASIC_H 00024 #define GINAC_BASIC_H 00025 00026 #include "flags.h" 00027 #include "ptr.h" 00028 #include "assertion.h" 00029 #include "registrar.h" 00030 00031 // CINT needs <algorithm> to work properly with <vector> 00032 #include <algorithm> 00033 #include <cstddef> // for size_t 00034 #include <map> 00035 #include <set> 00036 #include <typeinfo> // for typeid 00037 #include <vector> 00038 00039 namespace GiNaC { 00040 00041 class ex; 00042 class ex_is_less; 00043 class symbol; 00044 class numeric; 00045 class relational; 00046 class archive_node; 00047 class print_context; 00048 00049 typedef std::vector<ex> exvector; 00050 typedef std::set<ex, ex_is_less> exset; 00051 typedef std::map<ex, ex, ex_is_less> exmap; 00052 00053 // Define this to enable some statistical output for comparisons and hashing 00054 #undef GINAC_COMPARE_STATISTICS 00055 00056 #ifdef GINAC_COMPARE_STATISTICS 00057 class compare_statistics_t { 00058 public: 00059 compare_statistics_t() 00060 : total_compares(0), nontrivial_compares(0), total_basic_compares(0), compare_same_hashvalue(0), compare_same_type(0), 00061 total_is_equals(0), nontrivial_is_equals(0), total_basic_is_equals(0), is_equal_same_hashvalue(0), is_equal_same_type(0), 00062 total_gethash(0), gethash_cached(0) {} 00063 ~compare_statistics_t(); 00064 00065 unsigned long total_compares; 00066 unsigned long nontrivial_compares; 00067 unsigned long total_basic_compares; 00068 unsigned long compare_same_hashvalue; 00069 unsigned long compare_same_type; 00070 00071 unsigned long total_is_equals; 00072 unsigned long nontrivial_is_equals; 00073 unsigned long total_basic_is_equals; 00074 unsigned long is_equal_same_hashvalue; 00075 unsigned long is_equal_same_type; 00076 00077 unsigned long total_gethash; 00078 unsigned long gethash_cached; 00079 }; 00080 00081 extern compare_statistics_t compare_statistics; 00082 #endif 00083 00084 00086 struct map_function { 00087 virtual ~map_function() {} 00088 typedef const ex & argument_type; 00089 typedef ex result_type; 00090 virtual ex operator()(const ex & e) = 0; 00091 }; 00092 00093 00097 class visitor { 00098 protected: 00099 virtual ~visitor() {} 00100 }; 00101 00102 00104 class basic : public refcounted 00105 { 00106 GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(basic, void) 00107 00108 friend class ex; 00109 00110 // default constructor, destructor, copy constructor and assignment operator 00111 protected: 00112 basic() : flags(0) {} 00113 00114 public: 00117 virtual ~basic() 00118 { 00119 GINAC_ASSERT((!(flags & status_flags::dynallocated)) || (get_refcount() == 0)); 00120 } 00121 basic(const basic & other); 00122 const basic & operator=(const basic & other); 00123 00124 protected: 00125 // new virtual functions which can be overridden by derived classes 00126 public: // only const functions please (may break reference counting) 00127 00131 virtual basic * duplicate() const { return new basic(*this); } 00132 00133 // evaluation 00134 virtual ex eval(int level = 0) const; 00135 virtual ex evalf(int level = 0) const; 00136 virtual ex evalm() const; 00137 virtual ex eval_integ() const; 00138 protected: 00139 virtual ex eval_ncmul(const exvector & v) const; 00140 public: 00141 virtual ex eval_indexed(const basic & i) const; 00142 00143 // printing 00144 virtual void print(const print_context & c, unsigned level = 0) const; 00145 virtual void dbgprint() const; 00146 virtual void dbgprinttree() const; 00147 virtual unsigned precedence() const; 00148 00149 // info 00150 virtual bool info(unsigned inf) const; 00151 00152 // operand access 00153 virtual size_t nops() const; 00154 virtual ex op(size_t i) const; 00155 virtual ex operator[](const ex & index) const; 00156 virtual ex operator[](size_t i) const; 00157 virtual ex & let_op(size_t i); 00158 virtual ex & operator[](const ex & index); 00159 virtual ex & operator[](size_t i); 00160 00161 // pattern matching 00162 virtual bool has(const ex & other, unsigned options = 0) const; 00163 virtual bool match(const ex & pattern, exmap & repls) const; 00164 protected: 00165 virtual bool match_same_type(const basic & other) const; 00166 public: 00167 00168 // substitutions 00169 virtual ex subs(const exmap & m, unsigned options = 0) const; 00170 00171 // function mapping 00172 virtual ex map(map_function & f) const; 00173 00174 // visitors and tree traversal 00175 virtual void accept(GiNaC::visitor & v) const 00176 { 00177 if (visitor *p = dynamic_cast<visitor *>(&v)) 00178 p->visit(*this); 00179 } 00180 00181 // degree/coeff 00182 virtual bool is_polynomial(const ex & var) const; 00183 virtual int degree(const ex & s) const; 00184 virtual int ldegree(const ex & s) const; 00185 virtual ex coeff(const ex & s, int n = 1) const; 00186 00187 // expand/collect 00188 virtual ex expand(unsigned options = 0) const; 00189 virtual ex collect(const ex & s, bool distributed = false) const; 00190 00191 // differentiation and series expansion 00192 protected: 00193 virtual ex derivative(const symbol & s) const; 00194 public: 00195 virtual ex series(const relational & r, int order, unsigned options = 0) const; 00196 00197 // rational functions 00198 virtual ex normal(exmap & repl, exmap & rev_lookup, int level = 0) const; 00199 virtual ex to_rational(exmap & repl) const; 00200 virtual ex to_polynomial(exmap & repl) const; 00201 00202 // polynomial algorithms 00203 virtual numeric integer_content() const; 00204 virtual ex smod(const numeric &xi) const; 00205 virtual numeric max_coefficient() const; 00206 00207 // indexed objects 00208 virtual exvector get_free_indices() const; 00209 virtual ex add_indexed(const ex & self, const ex & other) const; 00210 virtual ex scalar_mul_indexed(const ex & self, const numeric & other) const; 00211 virtual bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const; 00212 00213 // noncommutativity 00214 virtual unsigned return_type() const; 00215 virtual return_type_t return_type_tinfo() const; 00216 00217 // functions for complex expressions 00218 virtual ex conjugate() const; 00219 virtual ex real_part() const; 00220 virtual ex imag_part() const; 00221 00222 // functions that should be called from class ex only 00223 protected: 00224 virtual int compare_same_type(const basic & other) const; 00225 virtual bool is_equal_same_type(const basic & other) const; 00226 00227 virtual unsigned calchash() const; 00228 00229 // non-virtual functions in this class 00230 public: 00236 template <class T> 00237 void print_dispatch(const print_context & c, unsigned level) const 00238 { 00239 print_dispatch(T::get_class_info_static(), c, level); 00240 } 00241 00242 void print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const; 00243 00250 virtual void archive(archive_node& n) const; 00259 virtual void read_archive(const archive_node& n, lst& syms); // no const 00260 00261 ex subs_one_level(const exmap & m, unsigned options) const; 00262 ex diff(const symbol & s, unsigned nth = 1) const; 00263 int compare(const basic & other) const; 00264 bool is_equal(const basic & other) const; 00265 const basic & hold() const; 00266 00267 unsigned gethash() const 00268 { 00269 #ifdef GINAC_COMPARE_STATISTICS 00270 compare_statistics.total_gethash++; 00271 #endif 00272 if (flags & status_flags::hash_calculated) { 00273 #ifdef GINAC_COMPARE_STATISTICS 00274 compare_statistics.gethash_cached++; 00275 #endif 00276 return hashvalue; 00277 } else { 00278 return calchash(); 00279 } 00280 } 00281 00283 const basic & setflag(unsigned f) const {flags |= f; return *this;} 00284 00286 const basic & clearflag(unsigned f) const {flags &= ~f; return *this;} 00287 00288 protected: 00289 void ensure_if_modifiable() const; 00290 00291 void do_print(const print_context & c, unsigned level) const; 00292 void do_print_tree(const print_tree & c, unsigned level) const; 00293 void do_print_python_repr(const print_python_repr & c, unsigned level) const; 00294 00295 // member variables 00296 protected: 00297 mutable unsigned flags; 00298 mutable unsigned hashvalue; 00299 }; 00300 00301 00302 // global variables 00303 00304 extern int max_recursion_level; 00305 00306 00307 // convenience type checker template functions 00308 00310 template <class T> 00311 inline bool is_a(const basic &obj) 00312 { 00313 return dynamic_cast<const T *>(&obj) != 0; 00314 } 00315 00317 template <class T> 00318 inline bool is_exactly_a(const basic & obj) 00319 { 00320 return typeid(T) == typeid(obj); 00321 } 00322 00323 } // namespace GiNaC 00324 00325 #endif // ndef GINAC_BASIC_H