3 * Interface to GiNaC's light-weight expression handles. */
6 * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #ifndef __GINAC_EX_H__
24 #define __GINAC_EX_H__
27 #include <ginac/basic.h>
28 #include <ginac/operators.h>
30 #ifndef NO_GINAC_NAMESPACE
32 #endif // ndef NO_GINAC_NAMESPACE
41 // typedef vector<ex> exvector;
45 ex const & exZERO(void);
46 ex const & exONE(void);
47 ex const & exTWO(void);
48 ex const & exTHREE(void);
49 ex const & exMINUSONE(void);
50 ex const & exHALF(void);
51 ex const & exMINUSHALF(void);
53 #define INLINE_EX_CONSTRUCTORS
55 /** Lightweight interface to GiNaC's symbolic objects. Basically all it does is
56 * to hold a pointer to the other objects, manage the reference counting and
57 * provide methods for manipulation of these objects. */
64 // default constructor, destructor, copy constructor assignment operator and helpers
67 #ifdef INLINE_EX_CONSTRUCTORS
70 GINAC_ASSERT(exZERO().bp!=0);
71 GINAC_ASSERT(exZERO().bp->flags & status_flags::dynallocated);
74 #ifdef OBSCURE_CINT_HACK
75 update_last_created_or_assigned_bp();
76 #endif // def OBSCURE_CINT_HACK
80 #endif // def INLINE_EX_CONSTRUCTORS
83 #ifdef INLINE_EX_CONSTRUCTORS
86 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
87 if (--bp->refcount == 0) {
93 #endif // def INLINE_EX_CONSTRUCTORS
96 #ifdef INLINE_EX_CONSTRUCTORS
100 GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
102 #ifdef OBSCURE_CINT_HACK
103 update_last_created_or_assigned_bp();
104 #endif // def OBSCURE_CINT_HACK
108 #endif // def INLINE_EX_CONSTRUCTORS
110 ex const & operator=(ex const & other)
111 #ifdef INLINE_EX_CONSTRUCTORS
114 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
115 GINAC_ASSERT(other.bp!=0);
116 GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
117 ++other.bp->refcount;
118 basic * tmpbp=other.bp;
119 if (--bp->refcount==0) {
123 #ifdef OBSCURE_CINT_HACK
124 update_last_created_or_assigned_bp();
125 #endif // def OBSCURE_CINT_HACK
130 #endif // def INLINE_EX_CONSTRUCTORS
132 // other constructors
134 ex(basic const & other)
135 #ifdef INLINE_EX_CONSTRUCTORS
137 construct_from_basic(other);
138 #ifdef OBSCURE_CINT_HACK
139 update_last_created_or_assigned_bp();
140 #endif // def OBSCURE_CINT_HACK
144 #endif // def INLINE_EX_CONSTRUCTORS
147 ex(unsigned int const i);
149 ex(unsigned long const i);
152 // functions overriding virtual functions from bases classes
155 // new virtual functions which can be overridden by derived classes
158 // non-virtual functions in this class
160 void swap(ex & other);
161 void printraw(ostream & os) const;
162 void printtree(ostream & os, unsigned indent=0) const;
163 void print(ostream & os, unsigned upper_precedence=0) const;
164 void printcsrc(ostream & os, unsigned type, const char *var_name) const;
165 void dbgprint(void) const;
166 void dbgprinttree(void) const;
167 bool info(unsigned inf) const;
169 ex expand(unsigned options=0) const;
170 bool has(ex const & other) const;
171 int degree(symbol const & s) const;
172 int ldegree(symbol const & s) const;
173 ex coeff(symbol const & s, int const n=1) const;
174 ex lcoeff(symbol const & s) const { return coeff(s, degree(s)); }
175 ex tcoeff(symbol const & s) const { return coeff(s, ldegree(s)); }
176 ex numer(bool normalize = true) const;
177 ex denom(bool normalize = true) const;
178 ex unit(const symbol &x) const;
179 ex content(const symbol &x) const;
180 numeric integer_content(void) const;
181 ex primpart(const symbol &x) const;
182 ex primpart(const symbol &x, const ex &cont) const;
183 ex normal(int level = 0) const;
184 ex smod(const numeric &xi) const;
185 numeric max_coefficient(void) const;
186 ex collect(symbol const & s) const;
187 ex eval(int level = 0) const;
188 ex evalf(int level = 0) const;
189 ex diff(symbol const & s, unsigned nth = 1) const;
190 ex series(symbol const & s, ex const & point, int order = 6) const;
191 ex subs(lst const & ls, lst const & lr) const;
192 ex subs(ex const & e) const;
193 exvector get_indices(void) const;
194 ex simplify_ncmul(exvector const & v) const;
195 ex operator[](ex const & index) const;
196 ex operator[](int const i) const;
197 ex op(int const i) const;
198 ex & let_op(int const i);
199 int compare(ex const & other) const
200 #ifdef INLINE_EX_CONSTRUCTORS
203 GINAC_ASSERT(other.bp!=0);
205 // special case: both expression point to same basic, trivially equal
208 return bp->compare(*other.bp);
212 #endif // def INLINE_EX_CONSTRUCTORS
213 bool is_equal(ex const & other) const
214 #ifdef INLINE_EX_CONSTRUCTORS
217 GINAC_ASSERT(other.bp!=0);
219 // special case: both expression point to same basic, trivially equal
222 return bp->is_equal(*other.bp);
226 #endif // def INLINE_EX_CONSTRUCTORS
227 bool is_zero(void) const {return compare(exZERO()) == 0;};
229 unsigned return_type(void) const;
230 unsigned return_type_tinfo(void) const;
231 unsigned gethash(void) const;
233 ex exadd(ex const & rh) const;
234 ex exmul(ex const & rh) const;
235 ex exncmul(ex const & rh) const;
237 void construct_from_basic(basic const & other);
238 void makewriteable();
240 #ifdef OBSCURE_CINT_HACK
242 static bool last_created_or_assigned_bp_can_be_converted_to_ex(void)
244 if (last_created_or_assigned_bp==0) return false;
245 if ((last_created_or_assigned_bp->flags &
246 status_flags::dynallocated)==0) return false;
247 if ((last_created_or_assigned_bp->flags &
248 status_flags::evaluated)==0) return false;
252 void update_last_created_or_assigned_bp(void)
254 if (last_created_or_assigned_bp!=0) {
255 if (--last_created_or_assigned_bp->refcount == 0) {
256 delete last_created_or_assigned_bp;
259 last_created_or_assigned_bp=bp;
260 ++last_created_or_assigned_bp->refcount;
261 last_created_or_assigned_bp_modified=true;
263 #endif // def OBSCURE_CINT_HACK
269 #ifdef OBSCURE_CINT_HACK
270 static basic *last_created_or_assigned_bp;
271 static bool last_created_or_assigned_bp_modified;
272 #endif // def OBSCURE_CINT_HACK
276 inline bool are_ex_trivially_equal(const ex &e1, const ex &e2)
278 return e1.bp == e2.bp;
281 // wrapper functions around member functions
282 inline int nops(ex const & thisex)
283 { return thisex.nops(); }
285 inline ex expand(ex const & thisex, unsigned options = 0)
286 { return thisex.expand(options); }
288 inline bool has(ex const & thisex, ex const & other)
289 { return thisex.has(other); }
291 inline int degree(ex const & thisex, symbol const & s)
292 { return thisex.degree(s); }
294 inline int ldegree(ex const & thisex, symbol const & s)
295 { return thisex.ldegree(s); }
297 inline ex coeff(ex const & thisex, symbol const & s, int const n=1)
298 { return thisex.coeff(s, n); }
300 inline ex numer(ex const & thisex, bool normalize = true)
301 { return thisex.numer(normalize); }
303 inline ex denom(ex const & thisex, bool normalize = true)
304 { return thisex.denom(normalize); }
306 inline ex normal(ex const & thisex, int level=0)
307 { return thisex.normal(level); }
309 inline ex collect(ex const & thisex, symbol const & s)
310 { return thisex.collect(s); }
312 inline ex eval(ex const & thisex, int level = 0)
313 { return thisex.eval(level); }
315 inline ex evalf(ex const & thisex, int level = 0)
316 { return thisex.evalf(level); }
318 inline ex diff(ex const & thisex, symbol const & s, unsigned nth = 1)
319 { return thisex.diff(s, nth); }
321 inline ex subs(ex const & thisex, ex const & e)
322 { return thisex.subs(e); }
324 inline ex subs(ex const & thisex, lst const & ls, lst const & lr)
325 { return thisex.subs(ls, lr); }
327 inline void swap(ex & e1, ex & e2)
330 #ifndef NO_GINAC_NAMESPACE
332 #endif // ndef NO_GINAC_NAMESPACE
334 #endif // ndef __GINAC_EX_H__