3 * Interface to GiNaC's light-weight expression handles. */
6 * GiNaC Copyright (C) 1999-2000 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 extern const ex & _ex0(void); /* FIXME: should this pollute headers? */
43 // typedef vector<ex> exvector;
45 #define INLINE_EX_CONSTRUCTORS
47 /** Lightweight wrapper for GiNaC's symbolic objects. Basically all it does is
48 * to hold a pointer to the other objects, manage the reference counting and
49 * provide methods for manipulation of these objects. */
56 // default constructor, destructor, copy constructor assignment operator and helpers
59 #ifdef INLINE_EX_CONSTRUCTORS
62 GINAC_ASSERT(_ex0().bp!=0);
63 GINAC_ASSERT(_ex0().bp->flags & status_flags::dynallocated);
66 #ifdef OBSCURE_CINT_HACK
67 update_last_created_or_assigned_bp();
68 #endif // def OBSCURE_CINT_HACK
72 #endif // def INLINE_EX_CONSTRUCTORS
75 #ifdef INLINE_EX_CONSTRUCTORS
78 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
79 if (--bp->refcount == 0) {
85 #endif // def INLINE_EX_CONSTRUCTORS
88 #ifdef INLINE_EX_CONSTRUCTORS
92 GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
94 #ifdef OBSCURE_CINT_HACK
95 update_last_created_or_assigned_bp();
96 #endif // def OBSCURE_CINT_HACK
100 #endif // def INLINE_EX_CONSTRUCTORS
102 const ex & operator=(const ex & other)
103 #ifdef INLINE_EX_CONSTRUCTORS
106 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
107 GINAC_ASSERT(other.bp!=0);
108 GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
109 ++other.bp->refcount;
110 basic * tmpbp=other.bp;
111 if (--bp->refcount==0) {
115 #ifdef OBSCURE_CINT_HACK
116 update_last_created_or_assigned_bp();
117 #endif // def OBSCURE_CINT_HACK
122 #endif // def INLINE_EX_CONSTRUCTORS
124 // other constructors
126 ex(const basic & other)
127 #ifdef INLINE_EX_CONSTRUCTORS
129 construct_from_basic(other);
130 #ifdef OBSCURE_CINT_HACK
131 update_last_created_or_assigned_bp();
132 #endif // def OBSCURE_CINT_HACK
136 #endif // def INLINE_EX_CONSTRUCTORS
144 // functions overriding virtual functions from bases classes
147 // new virtual functions which can be overridden by derived classes
150 // non-virtual functions in this class
152 void swap(ex & other);
153 void printraw(ostream & os) const;
154 void printtree(ostream & os, unsigned indent=0) const;
155 void print(ostream & os, unsigned upper_precedence=0) const;
156 void printcsrc(ostream & os, unsigned type, const char *var_name) const;
157 void dbgprint(void) const;
158 void dbgprinttree(void) const;
159 bool info(unsigned inf) const;
160 unsigned nops() const;
161 ex expand(unsigned options=0) const;
162 bool has(const ex & other) const;
163 int degree(const symbol & s) const;
164 int ldegree(const symbol & s) const;
165 ex coeff(const symbol & s, int n=1) const;
166 ex lcoeff(const symbol & s) const { return coeff(s, degree(s)); }
167 ex tcoeff(const symbol & s) const { return coeff(s, ldegree(s)); }
168 ex numer(bool normalize = true) const;
169 ex denom(bool normalize = true) const;
170 ex unit(const symbol &x) const;
171 ex content(const symbol &x) const;
172 numeric integer_content(void) const;
173 ex primpart(const symbol &x) const;
174 ex primpart(const symbol &x, const ex &cont) const;
175 ex normal(int level = 0) const;
176 ex smod(const numeric &xi) const;
177 numeric max_coefficient(void) const;
178 ex collect(const symbol & s) const;
179 ex eval(int level = 0) const;
180 ex evalf(int level = 0) const;
181 ex diff(const symbol & s, unsigned nth = 1) const;
182 ex series(const symbol & s, const ex & point, int order = 6) const;
183 ex subs(const lst & ls, const lst & lr) const;
184 ex subs(const ex & e) const;
185 exvector get_indices(void) const;
186 ex simplify_ncmul(const exvector & v) const;
187 ex operator[](const ex & index) const;
188 ex operator[](int i) const;
191 int compare(const ex & other) const
192 #ifdef INLINE_EX_CONSTRUCTORS
195 GINAC_ASSERT(other.bp!=0);
197 // special case: both expression point to same basic, trivially equal
200 return bp->compare(*other.bp);
204 #endif // def INLINE_EX_CONSTRUCTORS
205 bool is_equal(const ex & other) const
206 #ifdef INLINE_EX_CONSTRUCTORS
209 GINAC_ASSERT(other.bp!=0);
211 // special case: both expression point to same basic, trivially equal
214 return bp->is_equal(*other.bp);
218 #endif // def INLINE_EX_CONSTRUCTORS
219 bool is_zero(void) const {return compare(_ex0())==0;};
221 unsigned return_type(void) const;
222 unsigned return_type_tinfo(void) const;
223 unsigned gethash(void) const;
225 ex exadd(const ex & rh) const;
226 ex exmul(const ex & rh) const;
227 ex exncmul(const ex & rh) const;
229 void construct_from_basic(const basic & other);
230 void makewriteable();
232 #ifdef OBSCURE_CINT_HACK
234 static bool last_created_or_assigned_bp_can_be_converted_to_ex(void)
236 if (last_created_or_assigned_bp==0) return false;
237 if ((last_created_or_assigned_bp->flags &
238 status_flags::dynallocated)==0) return false;
239 if ((last_created_or_assigned_bp->flags &
240 status_flags::evaluated)==0) return false;
244 void update_last_created_or_assigned_bp(void)
246 if (last_created_or_assigned_bp!=0) {
247 if (--last_created_or_assigned_bp->refcount == 0) {
248 delete last_created_or_assigned_bp;
251 last_created_or_assigned_bp=bp;
252 ++last_created_or_assigned_bp->refcount;
254 #endif // def OBSCURE_CINT_HACK
260 #ifdef OBSCURE_CINT_HACK
261 static basic *last_created_or_assigned_bp;
262 #endif // def OBSCURE_CINT_HACK
266 inline bool are_ex_trivially_equal(const ex &e1, const ex &e2)
268 return e1.bp == e2.bp;
271 // wrapper functions around member functions
272 inline unsigned nops(const ex & thisex)
273 { return thisex.nops(); }
275 inline ex expand(const ex & thisex, unsigned options = 0)
276 { return thisex.expand(options); }
278 inline bool has(const ex & thisex, const ex & other)
279 { return thisex.has(other); }
281 inline int degree(const ex & thisex, const symbol & s)
282 { return thisex.degree(s); }
284 inline int ldegree(const ex & thisex, const symbol & s)
285 { return thisex.ldegree(s); }
287 inline ex coeff(const ex & thisex, const symbol & s, int n=1)
288 { return thisex.coeff(s, n); }
290 inline ex numer(const ex & thisex, bool normalize = true)
291 { return thisex.numer(normalize); }
293 inline ex denom(const ex & thisex, bool normalize = true)
294 { return thisex.denom(normalize); }
296 inline ex normal(const ex & thisex, int level=0)
297 { return thisex.normal(level); }
299 inline ex collect(const ex & thisex, const symbol & s)
300 { return thisex.collect(s); }
302 inline ex eval(const ex & thisex, int level = 0)
303 { return thisex.eval(level); }
305 inline ex evalf(const ex & thisex, int level = 0)
306 { return thisex.evalf(level); }
308 inline ex diff(const ex & thisex, const symbol & s, unsigned nth = 1)
309 { return thisex.diff(s, nth); }
311 inline ex series(const ex & thisex, const symbol & s, const ex & point, int order = 6)
312 { return thisex.series(s, point, order); }
314 inline ex subs(const ex & thisex, const ex & e)
315 { return thisex.subs(e); }
317 inline ex subs(const ex & thisex, const lst & ls, const lst & lr)
318 { return thisex.subs(ls, lr); }
320 inline void swap(ex & e1, ex & e2)
323 #ifndef NO_GINAC_NAMESPACE
325 #endif // ndef NO_GINAC_NAMESPACE
327 #endif // ndef __GINAC_EX_H__