c07c3edb79d9ce62059b3e1f341f3868f6e00d9a
[ginac.git] / ginac / ex.h
1 /** @file ex.h
2  *
3  *  Interface to GiNaC's light-weight expression handles.
4  *
5  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #ifndef __GINAC_EX_H__
23 #define __GINAC_EX_H__
24
25 #include <iostream>
26 #include <ginac/basic.h>
27 #include <ginac/operators.h>
28
29 class ex;
30 class expand_options;
31 class status_flags;
32
33 class symbol;
34 class lst;
35
36 typedef vector<ex> exvector;
37
38 // enum definitions
39
40 ex const & exZERO(void);
41 ex const & exONE(void);
42 ex const & exTWO(void);
43 ex const & exTHREE(void);
44 ex const & exMINUSONE(void);
45 ex const & exHALF(void);
46 ex const & exMINUSHALF(void);
47
48 #define INLINE_EX_CONSTRUCTORS
49
50 /** Lightweight interface to GiNaC's symbolic objects. Basically all it does is
51  *  to hold a pointer to the other objects, manage the reference counting and
52  *  provide methods for manipulation of these objects. */
53 class ex
54 {
55     friend class basic;
56
57 // member functions
58
59     // default constructor, destructor, copy constructor assignment operator and helpers
60 public:
61     ex()
62 #ifdef INLINE_EX_CONSTRUCTORS
63     : bp(exZERO().bp)
64         {
65             debugmsg("ex default constructor",LOGLEVEL_CONSTRUCT);
66             ASSERT(exZERO().bp!=0);
67             ASSERT(exZERO().bp->flags & status_flags::dynallocated);
68             ASSERT(bp!=0);
69             ++bp->refcount;
70         }
71 #else
72 ;
73 #endif // def INLINE_EX_CONSTRUCTORS
74
75     ~ex()
76 #ifdef INLINE_EX_CONSTRUCTORS
77         {
78             debugmsg("ex destructor",LOGLEVEL_DESTRUCT);
79             ASSERT(bp!=0);
80             ASSERT(bp->flags & status_flags::dynallocated);
81             if (--bp->refcount == 0) {
82                 delete bp;
83             }
84         }
85 #else
86 ;
87 #endif // def INLINE_EX_CONSTRUCTORS
88         
89     ex(ex const & other)
90 #ifdef INLINE_EX_CONSTRUCTORS
91     : bp(other.bp)
92         {
93             debugmsg("ex copy constructor",LOGLEVEL_CONSTRUCT);
94             ASSERT(bp!=0);
95             ASSERT((bp->flags) & status_flags::dynallocated);
96             ++bp->refcount;
97         }
98 #else
99 ;
100 #endif // def INLINE_EX_CONSTRUCTORS
101         
102     ex const & operator=(ex const & other)
103 #ifdef INLINE_EX_CONSTRUCTORS
104         {
105             debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);
106             ASSERT(bp!=0);
107             ASSERT(bp->flags & status_flags::dynallocated);
108             ASSERT(other.bp!=0);
109             ASSERT(other.bp->flags & status_flags::dynallocated);
110             ++other.bp->refcount;
111             basic * tmpbp=other.bp;
112             if (--bp->refcount==0) {
113                 delete bp;
114             }
115             bp=tmpbp;
116             return *this;
117         }
118 #else
119 ;
120 #endif // def INLINE_EX_CONSTRUCTORS
121
122     // other constructors
123 public:
124     ex(basic const & other)
125 #ifdef INLINE_EX_CONSTRUCTORS
126     {
127         debugmsg("ex constructor from basic",LOGLEVEL_CONSTRUCT);
128         construct_from_basic(other);
129     }
130 #else
131 ;
132 #endif // def INLINE_EX_CONSTRUCTORS
133     
134     ex(int const i);
135     ex(unsigned int const i);
136     ex(long const i);
137     ex(unsigned long const i);
138     ex(double const d);
139
140     // functions overriding virtual functions from bases classes
141     // none
142     
143     // new virtual functions which can be overridden by derived classes
144     // none
145
146     // non-virtual functions in this class
147 public:
148     void swap(ex & other);
149     void printraw(ostream & os) const;
150     void printtree(ostream & os, unsigned indent=0) const;
151     void print(ostream & os, unsigned upper_precedence=0) const;
152     void printcsrc(ostream & os, unsigned type, const char *var_name) const;
153     void dbgprint(void) const;
154     void dbgprinttree(void) const;
155     bool info(unsigned inf) const;
156     int nops() const;
157     ex expand(unsigned options=0) const;
158     bool has(ex const & other) const;
159     int degree(symbol const & s) const;
160     int ldegree(symbol const & s) const;
161     ex coeff(symbol const & s, int const n=1) const;
162     ex lcoeff(symbol const & s) const { return coeff(s, degree(s)); }
163     ex tcoeff(symbol const & s) const { return coeff(s, ldegree(s)); }
164     ex numer(bool normalize = true) const;
165     ex denom(bool normalize = true) const;
166     ex unit(const symbol &x) const;
167     ex content(const symbol &x) const;
168     numeric integer_content(void) const;
169     ex primpart(const symbol &x) const;
170     ex primpart(const symbol &x, const ex &cont) const;
171     ex normal(int level = 0) const;
172     ex smod(const numeric &xi) const;
173     numeric max_coefficient(void) const;
174     ex collect(symbol const & s) const;
175     ex eval(int level = 0) const;
176     ex evalf(int level = 0) const;
177     ex diff(symbol const & s, unsigned nth = 1) const;
178     ex series(symbol const & s, ex const & point, int order = 6) const;
179     ex subs(lst const & ls, lst const & lr) const;
180     ex subs(ex const & e) const;
181     exvector get_indices(void) const;
182     ex simplify_ncmul(exvector const & v) const;
183     ex operator[](ex const & index) const;
184     ex operator[](int const i) const;
185     ex op(int const i) const;
186     ex & let_op(int const i);
187     int compare(ex const & other) const
188 #ifdef INLINE_EX_CONSTRUCTORS
189         {
190             ASSERT(bp!=0);
191             ASSERT(other.bp!=0);
192             if (bp==other.bp) {
193                 // special case: both expression point to same basic, trivially equal
194                 return 0; 
195             }
196             return bp->compare(*other.bp);
197         }
198 #else
199 ;
200 #endif // def INLINE_EX_CONSTRUCTORS
201     bool is_equal(ex const & other) const
202 #ifdef INLINE_EX_CONSTRUCTORS
203         {
204             ASSERT(bp!=0);
205             ASSERT(other.bp!=0);
206             if (bp==other.bp) {
207                 // special case: both expression point to same basic, trivially equal
208                 return true; 
209             }
210             return bp->is_equal(*other.bp);
211         }
212 #else
213 ;
214 #endif // def INLINE_EX_CONSTRUCTORS
215     bool is_zero(void) const {return compare(exZERO()) == 0;};
216         
217     unsigned return_type(void) const;
218     unsigned return_type_tinfo(void) const;
219     unsigned gethash(void) const;
220
221     ex exadd(ex const & rh) const;
222     ex exmul(ex const & rh) const;
223     ex exncmul(ex const & rh) const;
224 private:
225     void construct_from_basic(basic const & other);
226     void makewriteable();
227
228 // member variables
229
230 public:
231     basic *bp;
232
233 };
234
235 // wrapper functions around member functions
236 inline int nops(ex const & thisex)
237 { return thisex.nops(); }
238
239 inline ex expand(ex const & thisex, unsigned options = 0)
240 { return thisex.expand(options); }
241
242 inline bool has(ex const & thisex, ex const & other)
243 { return thisex.has(other); }
244
245 inline int degree(ex const & thisex, symbol const & s)
246 { return thisex.degree(s); }
247
248 inline int ldegree(ex const & thisex, symbol const & s)
249 { return thisex.ldegree(s); }
250
251 inline ex coeff(ex const & thisex, symbol const & s, int const n=1)
252 { return thisex.coeff(s, n); }
253
254 inline ex numer(ex const & thisex, bool normalize = true)
255 { return thisex.numer(normalize); }
256
257 inline ex denom(ex const & thisex, bool normalize = true)
258 { return thisex.denom(normalize); }
259
260 inline ex normal(ex const & thisex, int level=0)
261 { return thisex.normal(level); }
262
263 inline ex collect(ex const & thisex, symbol const & s)
264 { return thisex.collect(s); }
265
266 inline ex eval(ex const & thisex, int level = 0)
267 { return thisex.eval(level); }
268
269 inline ex evalf(ex const & thisex, int level = 0)
270 { return thisex.evalf(level); }
271
272 inline ex diff(ex const & thisex, symbol const & s, unsigned nth = 1)
273 { return thisex.diff(s, nth); }
274
275 inline ex subs(ex const & thisex, ex const & e)
276 { return thisex.subs(e); }
277
278 inline ex subs(ex const & thisex, lst const & ls, lst const & lr)
279 { return thisex.subs(ls, lr); }
280
281 inline void swap(ex & e1, ex & e2)
282 { e1.swap(e2); }
283
284 #endif // ndef __GINAC_EX_H__