X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fadd.cpp;h=241516e07283b7e49a3a7fd7bf47490bebb1c9f9;hp=547bee32d72b166c2ae95b292cd34b1c1c8455c5;hb=59fa68b8930779dfc419291d028b57b0d91d33d0;hpb=12fefbca9b424cb8e9ae05d83883b96e17c7b96e diff --git a/ginac/add.cpp b/ginac/add.cpp index 547bee32..241516e0 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's sums of expressions. */ /* - * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2010 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,11 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include -#include - #include "add.h" #include "mul.h" #include "archive.h" @@ -33,6 +28,12 @@ #include "utils.h" #include "clifford.h" #include "ncmul.h" +#include "compiler.h" + +#include +#include +#include +#include namespace GiNaC { @@ -49,7 +50,6 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, add::add() { - tinfo_key = &add::tinfo_static; } ////////// @@ -60,7 +60,6 @@ add::add() add::add(const ex & lh, const ex & rh) { - tinfo_key = &add::tinfo_static; overall_coeff = _ex0; construct_from_2_ex(lh,rh); GINAC_ASSERT(is_canonical()); @@ -68,7 +67,6 @@ add::add(const ex & lh, const ex & rh) add::add(const exvector & v) { - tinfo_key = &add::tinfo_static; overall_coeff = _ex0; construct_from_exvector(v); GINAC_ASSERT(is_canonical()); @@ -76,7 +74,6 @@ add::add(const exvector & v) add::add(const epvector & v) { - tinfo_key = &add::tinfo_static; overall_coeff = _ex0; construct_from_epvector(v); GINAC_ASSERT(is_canonical()); @@ -84,7 +81,6 @@ add::add(const epvector & v) add::add(const epvector & v, const ex & oc) { - tinfo_key = &add::tinfo_static; overall_coeff = oc; construct_from_epvector(v); GINAC_ASSERT(is_canonical()); @@ -92,7 +88,6 @@ add::add(const epvector & v, const ex & oc) add::add(std::auto_ptr vp, const ex & oc) { - tinfo_key = &add::tinfo_static; GINAC_ASSERT(vp.get()!=0); overall_coeff = oc; construct_from_epvector(*vp); @@ -103,7 +98,7 @@ add::add(std::auto_ptr vp, const ex & oc) // archiving ////////// -DEFAULT_ARCHIVING(add) +GINAC_BIND_UNARCHIVER(add); ////////// // functions overriding virtual functions from base classes @@ -230,6 +225,16 @@ bool add::info(unsigned inf) const case info_flags::integer_polynomial: case info_flags::cinteger_polynomial: case info_flags::rational_polynomial: + case info_flags::real: + case info_flags::rational: + case info_flags::integer: + case info_flags::crational: + case info_flags::cinteger: + case info_flags::positive: + case info_flags::nonnegative: + case info_flags::posint: + case info_flags::nonnegint: + case info_flags::even: case info_flags::crational_polynomial: case info_flags::rational_function: { epvector::const_iterator i = seq.begin(), end = seq.end(); @@ -238,6 +243,8 @@ bool add::info(unsigned inf) const return false; ++i; } + if (overall_coeff.is_zero() && (inf == info_flags::positive || inf == info_flags::posint)) + return true; return overall_coeff.info(inf); } case info_flags::algebraic: { @@ -337,9 +344,6 @@ ex add::eval(int level) const epvector::const_iterator i = seq.begin(), end = seq.end(); while (i != end) { GINAC_ASSERT(!is_exactly_a(i->rest)); - if (is_exactly_a(i->rest)) - dbgprint(); - GINAC_ASSERT(!is_exactly_a(i->rest)); ++i; } #endif // def DO_GINAC_ASSERT @@ -360,6 +364,33 @@ ex add::eval(int level) const } 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")); } + + // if any terms in the sum still are purely numeric, then they are more + // appropriately collected into the overall coefficient + epvector::const_iterator last = seq.end(); + epvector::const_iterator j = seq.begin(); + int terms_to_collect = 0; + while (j != last) { + if (unlikely(is_a(j->rest))) + ++terms_to_collect; + ++j; + } + if (terms_to_collect) { + std::auto_ptr s(new epvector); + s->reserve(seq_size - terms_to_collect); + numeric oc = *_num1_p; + j = seq.begin(); + while (j != last) { + if (unlikely(is_a(j->rest))) + oc = oc.mul(ex_to(j->rest)).mul(ex_to(j->coeff)); + else + s->push_back(*j); + ++j; + } + return (new add(s, ex_to(overall_coeff).add_dyn(oc))) + ->setflag(status_flags::dynallocated); + } + return this->hold(); }