X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fadd.cpp;h=279933d3ecb3f907e1940e4ebeee83357aefb0c1;hp=c4e53360b1ed665dd9f7047bc7c63ba178697f1b;hb=3a63743e24046766b37c3d1bd38605542ee0a536;hpb=708e9e647029af699333fceffc0a76bef70a4709 diff --git a/ginac/add.cpp b/ginac/add.cpp index c4e53360..279933d3 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -27,7 +27,6 @@ #include "mul.h" #include "matrix.h" #include "archive.h" -#include "debugmsg.h" #include "utils.h" namespace GiNaC { @@ -35,12 +34,11 @@ namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS(add, expairseq) ////////// -// default constructor, destructor, copy constructor assignment operator and helpers +// default ctor, dtor, copy ctor, assignment operator and helpers ////////// add::add() { - debugmsg("add default constructor",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_add; } @@ -55,34 +53,30 @@ DEFAULT_DESTROY(add) add::add(const ex & lh, const ex & rh) { - debugmsg("add constructor from ex,ex",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_add; - overall_coeff = _ex0(); + overall_coeff = _ex0; construct_from_2_ex(lh,rh); GINAC_ASSERT(is_canonical()); } add::add(const exvector & v) { - debugmsg("add constructor from exvector",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_add; - overall_coeff = _ex0(); + overall_coeff = _ex0; construct_from_exvector(v); GINAC_ASSERT(is_canonical()); } add::add(const epvector & v) { - debugmsg("add constructor from epvector",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_add; - overall_coeff = _ex0(); + overall_coeff = _ex0; construct_from_epvector(v); GINAC_ASSERT(is_canonical()); } add::add(const epvector & v, const ex & oc) { - debugmsg("add constructor from epvector,ex",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_add; overall_coeff = oc; construct_from_epvector(v); @@ -91,7 +85,6 @@ add::add(const epvector & v, const ex & oc) add::add(epvector * vp, const ex & oc) { - debugmsg("add constructor from epvector *,ex",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_add; GINAC_ASSERT(vp!=0); overall_coeff = oc; @@ -107,15 +100,13 @@ add::add(epvector * vp, const ex & oc) DEFAULT_ARCHIVING(add) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public void add::print(const print_context & c, unsigned level) const { - debugmsg("add print", LOGLEVEL_PRINT); - if (is_a(c)) { inherited::print(c, level); @@ -130,41 +121,53 @@ void add::print(const print_context & c, unsigned level) const while (it != itend) { // If the coefficient is -1, it is replaced by a single minus sign - if (it->coeff.compare(_num1()) == 0) { - it->rest.bp->print(c, precedence()); - } else if (it->coeff.compare(_num_1()) == 0) { + if (it->coeff.compare(_num1) == 0) { + it->rest.print(c, precedence()); + } else if (it->coeff.compare(_num_1) == 0) { c.s << "-"; - it->rest.bp->print(c, precedence()); - } else if (ex_to(it->coeff).numer().compare(_num1()) == 0) { - it->rest.bp->print(c, precedence()); + it->rest.print(c, precedence()); + } else if (ex_to(it->coeff).numer().compare(_num1) == 0) { + it->rest.print(c, precedence()); c.s << "/"; ex_to(it->coeff).denom().print(c, precedence()); - } else if (ex_to(it->coeff).numer().compare(_num_1()) == 0) { + } else if (ex_to(it->coeff).numer().compare(_num_1) == 0) { c.s << "-"; - it->rest.bp->print(c, precedence()); + it->rest.print(c, precedence()); c.s << "/"; ex_to(it->coeff).denom().print(c, precedence()); } else { - it->coeff.bp->print(c, precedence()); + it->coeff.print(c, precedence()); c.s << "*"; - it->rest.bp->print(c, precedence()); + it->rest.print(c, precedence()); } // Separator is "+", except if the following expression would have a leading minus sign - it++; - if (it != itend && !(it->coeff.compare(_num0()) < 0 || (it->coeff.compare(_num1()) == 0 && is_exactly_a(it->rest) && it->rest.compare(_num0()) < 0))) + ++it; + if (it != itend && !(it->coeff.compare(_num0) < 0 || (it->coeff.compare(_num1) == 0 && is_exactly_a(it->rest) && it->rest.compare(_num0) < 0))) c.s << "+"; } if (!overall_coeff.is_zero()) { if (overall_coeff.info(info_flags::positive)) c.s << '+'; - overall_coeff.bp->print(c, precedence()); + overall_coeff.print(c, precedence()); } - + if (precedence() <= level) c.s << ")"; + } else if (is_a(c)) { + + c.s << class_name() << '('; + unsigned end = nops(); + if (end) + op(0).print(c); + for (unsigned i=1; irest.print(c, precedence()); - it++; + ++it; } if (precedence() <= level) { @@ -304,16 +307,18 @@ ex add::coeff(const ex & s, int n) const ++i; } - return (new add(coeffseq, n==0 ? overall_coeff : _ex0()))->setflag(status_flags::dynallocated); + return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); } +/** Perform automatic term rewriting rules in this class. In the following + * x stands for a symbolic variables of type ex and c stands for such + * an expression that contain a plain number. + * - +(;c) -> c + * - +(x;1) -> x + * + * @param level cut-off in recursive evaluation */ ex add::eval(int level) const { - // simplifications: +(;c) -> c - // +(x;1) -> x - - debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION); - epvector *evaled_seqp = evalchildren(level); if (evaled_seqp) { // do more evaluation later @@ -324,10 +329,10 @@ ex add::eval(int level) const #ifdef DO_GINAC_ASSERT epvector::const_iterator i = seq.begin(), end = seq.end(); while (i != end) { - GINAC_ASSERT(!is_ex_exactly_of_type(i->rest,add)); + GINAC_ASSERT(!is_exactly_a(i->rest)); if (is_ex_exactly_of_type(i->rest,numeric)) dbgprint(); - GINAC_ASSERT(!is_ex_exactly_of_type(i->rest,numeric)); + GINAC_ASSERT(!is_exactly_a(i->rest)); ++i; } #endif // def DO_GINAC_ASSERT @@ -339,12 +344,14 @@ ex add::eval(int level) const } int seq_size = seq.size(); - if (seq_size==0) { + if (seq_size == 0) { // +(;c) -> c return overall_coeff; - } else if ((seq_size==1) && overall_coeff.is_zero()) { + } else if (seq_size == 1 && overall_coeff.is_zero()) { // +(x;0) -> x return recombine_pair_to_ex(*(seq.begin())); + } else if (!overall_coeff.is_zero() && seq[0].rest.return_type() != return_types::commutative) { + throw (std::logic_error("add::eval(): sum of non-commutative objects has non-zero numeric term")); } return this->hold(); } @@ -372,7 +379,7 @@ ex add::evalm(void) const sum = sum.add(ex_to(m)); } else all_matrices = false; - it++; + ++it; } if (all_matrices) { @@ -407,7 +414,7 @@ ex add::derivative(const symbol & y) const s->push_back(combine_ex_with_coeff_to_pair(i->rest.diff(y), i->coeff)); ++i; } - return (new add(s, _ex0()))->setflag(status_flags::dynallocated); + return (new add(s, _ex0))->setflag(status_flags::dynallocated); } int add::compare_same_type(const basic & other) const @@ -450,39 +457,39 @@ expair add::split_ex_to_pair(const ex & e) const { if (is_ex_exactly_of_type(e,mul)) { const mul &mulref(ex_to(e)); - ex numfactor = mulref.overall_coeff; + const ex &numfactor = mulref.overall_coeff; mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = _ex1(); + mulcopyp->overall_coeff = _ex1; mulcopyp->clearflag(status_flags::evaluated); mulcopyp->clearflag(status_flags::hash_calculated); mulcopyp->setflag(status_flags::dynallocated); return expair(*mulcopyp,numfactor); } - return expair(e,_ex1()); + return expair(e,_ex1); } expair add::combine_ex_with_coeff_to_pair(const ex & e, const ex & c) const { - GINAC_ASSERT(is_ex_exactly_of_type(c, numeric)); + GINAC_ASSERT(is_exactly_a(c)); if (is_ex_exactly_of_type(e, mul)) { const mul &mulref(ex_to(e)); - ex numfactor = mulref.overall_coeff; + const ex &numfactor = mulref.overall_coeff; mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = _ex1(); + mulcopyp->overall_coeff = _ex1; mulcopyp->clearflag(status_flags::evaluated); mulcopyp->clearflag(status_flags::hash_calculated); mulcopyp->setflag(status_flags::dynallocated); - if (are_ex_trivially_equal(c, _ex1())) + if (are_ex_trivially_equal(c, _ex1)) return expair(*mulcopyp, numfactor); - else if (are_ex_trivially_equal(numfactor, _ex1())) + else if (are_ex_trivially_equal(numfactor, _ex1)) return expair(*mulcopyp, c); else return expair(*mulcopyp, ex_to(numfactor).mul_dyn(ex_to(c))); } else if (is_ex_exactly_of_type(e, numeric)) { - if (are_ex_trivially_equal(c, _ex1())) - return expair(e, _ex1()); - return expair(ex_to(e).mul_dyn(ex_to(c)), _ex1()); + if (are_ex_trivially_equal(c, _ex1)) + return expair(e, _ex1); + return expair(ex_to(e).mul_dyn(ex_to(c)), _ex1); } return expair(e, c); } @@ -490,12 +497,12 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e, expair add::combine_pair_with_coeff_to_pair(const expair & p, const ex & c) const { - GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric)); - GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); + GINAC_ASSERT(is_exactly_a(p.coeff)); + GINAC_ASSERT(is_exactly_a(c)); if (is_ex_exactly_of_type(p.rest,numeric)) { - GINAC_ASSERT(ex_to(p.coeff).is_equal(_num1())); // should be normalized - return expair(ex_to(p.rest).mul_dyn(ex_to(c)),_ex1()); + GINAC_ASSERT(ex_to(p.coeff).is_equal(_num1)); // should be normalized + return expair(ex_to(p.rest).mul_dyn(ex_to(c)),_ex1); } return expair(p.rest,ex_to(p.coeff).mul_dyn(ex_to(c))); @@ -503,17 +510,14 @@ expair add::combine_pair_with_coeff_to_pair(const expair & p, ex add::recombine_pair_to_ex(const expair & p) const { - if (ex_to(p.coeff).is_equal(_num1())) + if (ex_to(p.coeff).is_equal(_num1)) return p.rest; else - return p.rest*p.coeff; + return (new mul(p.rest,p.coeff))->setflag(status_flags::dynallocated); } ex add::expand(unsigned options) const { - if (options == 0 && (flags & status_flags::expanded)) - return *this; - epvector *vp = expandchildren(options); if (vp == NULL) { // the terms have not changed, so it is safe to declare this expanded