3 * Implementation of 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
33 #ifndef NO_GINAC_NAMESPACE
35 #endif // ndef NO_GINAC_NAMESPACE
38 // default constructor, destructor, copy constructor assignment operator and helpers
43 #ifndef INLINE_EX_CONSTRUCTORS
45 ex::ex() : bp(exZERO().bp)
47 debugmsg("ex default constructor",LOGLEVEL_CONSTRUCT);
48 GINAC_ASSERT(exZERO().bp!=0);
49 GINAC_ASSERT(exZERO().bp->flags & status_flags::dynallocated);
56 debugmsg("ex destructor",LOGLEVEL_DESTRUCT);
58 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
59 if (--bp->refcount == 0) {
64 ex::ex(ex const & other) : bp(other.bp)
66 debugmsg("ex copy constructor",LOGLEVEL_CONSTRUCT);
68 GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
72 ex const & ex::operator=(ex const & other)
74 debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);
76 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
77 GINAC_ASSERT(other.bp!=0);
78 GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
80 basic * tmpbp=other.bp;
81 if (--bp->refcount==0) {
88 #endif // ndef INLINE_EX_CONSTRUCTORS
96 #ifndef INLINE_EX_CONSTRUCTORS
97 ex::ex(basic const & other)
99 debugmsg("ex constructor from basic",LOGLEVEL_CONSTRUCT);
100 construct_from_basic(other);
106 debugmsg("ex constructor from int",LOGLEVEL_CONSTRUCT);
107 construct_from_basic(numeric(i));
110 ex::ex(unsigned int const i)
112 debugmsg("ex constructor from unsigned int",LOGLEVEL_CONSTRUCT);
113 construct_from_basic(numeric(i));
118 debugmsg("ex constructor from long",LOGLEVEL_CONSTRUCT);
119 construct_from_basic(numeric(i));
122 ex::ex(unsigned long const i)
124 debugmsg("ex constructor from unsigned long",LOGLEVEL_CONSTRUCT);
125 construct_from_basic(numeric(i));
128 ex::ex(double const d)
130 debugmsg("ex constructor from double",LOGLEVEL_CONSTRUCT);
131 construct_from_basic(numeric(d));
135 // functions overriding virtual functions from bases classes
141 // new virtual functions which can be overridden by derived classes
147 // non-virtual functions in this class
152 /** Swap the contents of two expressions. */
153 void ex::swap(ex & other)
155 debugmsg("ex swap",LOGLEVEL_MEMBER_FUNCTION);
158 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
159 GINAC_ASSERT(other.bp!=0);
160 GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
167 /** Output formatted to be useful as ginsh input. */
168 void ex::print(ostream & os, unsigned upper_precedence) const
170 debugmsg("ex print",LOGLEVEL_PRINT);
172 bp->print(os,upper_precedence);
175 void ex::printraw(ostream & os) const
177 debugmsg("ex printraw",LOGLEVEL_PRINT);
184 void ex::printtree(ostream & os, unsigned indent) const
186 debugmsg("ex printtree",LOGLEVEL_PRINT);
188 // os << "refcount=" << bp->refcount << " ";
189 bp->printtree(os,indent);
192 /** Print expression as a C++ statement. The output looks like
193 * "<type> <var_name> = <expression>;". The "type" parameter has an effect
194 * on how number literals are printed.
196 * @param os output stream
197 * @param type variable type (one of the csrc_types)
198 * @param var_name variable name to be printed */
199 void ex::printcsrc(ostream & os, unsigned type, const char *var_name) const
201 debugmsg("ex print csrc", LOGLEVEL_PRINT);
204 case csrc_types::ctype_float:
207 case csrc_types::ctype_double:
210 case csrc_types::ctype_cl_N:
214 os << var_name << " = ";
215 bp->printcsrc(os, type, 0);
219 /** Little wrapper arount print to be called within a debugger. */
220 void ex::dbgprint(void) const
222 debugmsg("ex dbgprint",LOGLEVEL_PRINT);
227 /** Little wrapper arount printtree to be called within a debugger. */
228 void ex::dbgprinttree(void) const
230 debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
235 bool ex::info(unsigned inf) const
237 if (inf == info_flags::normal_form) {
239 // Polynomials are in normal form
240 if (info(info_flags::polynomial))
243 // polynomial^(-int) is in normal form
244 if (is_ex_exactly_of_type(*this, power))
245 return op(1).info(info_flags::negint);
247 // polynomial^(int) * polynomial^(int) * ... is in normal form
248 if (!is_ex_exactly_of_type(*this, mul))
250 for (int i=0; i<nops(); i++) {
251 if (is_ex_exactly_of_type(op(i), power)) {
252 if (!op(i).op(1).info(info_flags::integer))
254 if (!op(i).op(0).info(info_flags::polynomial))
257 if (!op(i).info(info_flags::polynomial))
262 return bp->info(inf);
272 ex ex::expand(unsigned options) const
275 return bp->expand(options);
278 bool ex::has(ex const & other) const
281 return bp->has(other);
284 int ex::degree(symbol const & s) const
287 return bp->degree(s);
290 int ex::ldegree(symbol const & s) const
293 return bp->ldegree(s);
296 ex ex::coeff(symbol const & s, int const n) const
299 return bp->coeff(s,n);
302 ex ex::numer(bool normalize) const
305 if (normalize && !info(info_flags::normal_form))
311 if (n.info(info_flags::polynomial))
315 if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
318 // something^(int) * something^(int) * ...
319 if (!is_ex_exactly_of_type(n, mul))
322 for (int i=0; i<n.nops(); i++) {
323 if (!is_ex_exactly_of_type(n.op(i), power) || !n.op(i).op(1).info(info_flags::negint))
329 ex ex::denom(bool normalize) const
332 if (normalize && !info(info_flags::normal_form))
338 if (n.info(info_flags::polynomial))
342 if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
343 return power(n.op(0), -(n.op(1)));
345 // something^(int) * something^(int) * ...
346 if (!is_ex_exactly_of_type(n, mul))
349 for (int i=0; i<n.nops(); i++) {
350 if (is_ex_exactly_of_type(n.op(i), power) && n.op(i).op(1).info(info_flags::negint))
351 res *= power(n.op(i), -1);
356 ex ex::collect(symbol const & s) const
359 return bp->collect(s);
362 ex ex::eval(int level) const
365 return bp->eval(level);
368 ex ex::evalf(int level) const
371 return bp->evalf(level);
374 ex ex::subs(lst const & ls, lst const & lr) const
377 return bp->subs(ls,lr);
380 ex ex::subs(ex const & e) const
386 exvector ex::get_indices(void) const
389 return bp->get_indices();
392 ex ex::simplify_ncmul(exvector const & v) const
395 return bp->simplify_ncmul(v);
398 ex ex::operator[](ex const & index) const
400 debugmsg("ex operator[ex]",LOGLEVEL_OPERATOR);
405 ex ex::operator[](int const i) const
407 debugmsg("ex operator[int]",LOGLEVEL_OPERATOR);
412 ex ex::op(int const i) const
414 debugmsg("ex op()",LOGLEVEL_MEMBER_FUNCTION);
419 ex & ex::let_op(int const i)
421 debugmsg("ex let_op()",LOGLEVEL_MEMBER_FUNCTION);
424 return bp->let_op(i);
427 #ifndef INLINE_EX_CONSTRUCTORS
428 int ex::compare(ex const & other) const
431 GINAC_ASSERT(other.bp!=0);
433 // special case: both expression point to same basic, trivially equal
436 return bp->compare(*other.bp);
438 #endif // ndef INLINE_EX_CONSTRUCTORS
440 #ifndef INLINE_EX_CONSTRUCTORS
441 bool ex::is_equal(ex const & other) const
444 GINAC_ASSERT(other.bp!=0);
446 // special case: both expression point to same basic, trivially equal
449 return bp->is_equal(*other.bp);
451 #endif // ndef INLINE_EX_CONSTRUCTORS
453 unsigned ex::return_type(void) const
456 return bp->return_type();
459 unsigned ex::return_type_tinfo(void) const
462 return bp->return_type_tinfo();
465 unsigned ex::gethash(void) const
468 return bp->gethash();
471 ex ex::exadd(ex const & rh) const
473 return (new add(*this,rh))->setflag(status_flags::dynallocated);
476 ex ex::exmul(ex const & rh) const
478 return (new mul(*this,rh))->setflag(status_flags::dynallocated);
481 ex ex::exncmul(ex const & rh) const
483 return (new ncmul(*this,rh))->setflag(status_flags::dynallocated);
488 void ex::makewriteable()
490 debugmsg("ex makewriteable",LOGLEVEL_MEMBER_FUNCTION);
492 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
493 if (bp->refcount > 1) {
494 basic * bp2=bp->duplicate();
496 bp2->setflag(status_flags::dynallocated);
500 GINAC_ASSERT(bp->refcount == 1);
503 void ex::construct_from_basic(basic const & other)
505 if ((other.flags & status_flags::evaluated)==0) {
506 // cf. copy constructor
507 ex const & tmpex = other.eval(1); // evaluate only one (top) level
510 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
512 if ((other.flags & status_flags::dynallocated)&&(other.refcount==0)) {
513 delete &const_cast<basic &>(other);
516 if (other.flags & status_flags::dynallocated) {
517 bp=&const_cast<basic &>(other);
519 bp=other.duplicate();
520 bp->setflag(status_flags::dynallocated);
523 // bp->clearflag(status_flags::evaluated);
527 GINAC_ASSERT(bp->flags & status_flags::dynallocated);
531 // static member variables
537 // functions which are not member functions
546 ex const & exZERO(void)
548 static ex * eZERO=new ex(numZERO());
552 ex const & exONE(void)
554 static ex * eONE=new ex(numONE());
558 ex const & exTWO(void)
560 static ex * eTWO=new ex(numTWO());
564 ex const & exTHREE(void)
566 static ex * eTHREE=new ex(numTHREE());
570 ex const & exMINUSONE(void)
572 static ex * eMINUSONE=new ex(numMINUSONE());
576 ex const & exHALF(void)
578 static ex * eHALF=new ex(ex(1)/ex(2));
582 ex const & exMINUSHALF(void)
584 static ex * eMINUSHALF=new ex(numeric(-1,2));
588 #ifndef NO_GINAC_NAMESPACE
590 #endif // ndef NO_GINAC_NAMESPACE