X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Fadd.cpp;h=06890ba4ce570b766d3d4386788572caa335d7a8;hb=1a59d8a443e6156da26028e4b951c0d4a28b2b0e;hp=fd83de1134876f448835f9e48722f990c04402a5;hpb=2bf56ec52a7bed4ac3d02be8887b0287b5acd189;p=ginac.git diff --git a/ginac/add.cpp b/ginac/add.cpp index fd83de11..06890ba4 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's sums of expressions. */ /* - * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2016 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 @@ -86,6 +86,13 @@ add::add(const epvector & v, const ex & oc) GINAC_ASSERT(is_canonical()); } +add::add(epvector && vp) +{ + overall_coeff = _ex0; + construct_from_epvector(std::move(vp)); + GINAC_ASSERT(is_canonical()); +} + add::add(epvector && vp, const ex & oc) { overall_coeff = oc; @@ -240,15 +247,6 @@ bool add::info(unsigned inf) const return true; return overall_coeff.info(inf); } - case info_flags::algebraic: { - epvector::const_iterator i = seq.begin(), end = seq.end(); - while (i != end) { - if ((recombine_pair_to_ex(*i).info(inf))) - return true; - ++i; - } - return false; - } } return inherited::info(inf); } @@ -307,18 +305,18 @@ ex add::coeff(const ex & s, int n) const if (!restcoeff.is_zero()) { if (do_clifford) { if (clifford_max_label(restcoeff) == -1) { - coeffseq_cliff.push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i.coeff)); + coeffseq_cliff.push_back(expair(ncmul(restcoeff, dirac_ONE(rl)), i.coeff)); } else { - coeffseq_cliff.push_back(combine_ex_with_coeff_to_pair(restcoeff, i.coeff)); + coeffseq_cliff.push_back(expair(restcoeff, i.coeff)); nonscalar = true; } } - coeffseq.push_back(combine_ex_with_coeff_to_pair(restcoeff, i.coeff)); + coeffseq.push_back(expair(restcoeff, i.coeff)); } } - return (new add(nonscalar ? std::move(coeffseq_cliff) : std::move(coeffseq), - n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); + return dynallocate(nonscalar ? std::move(coeffseq_cliff) : std::move(coeffseq), + n==0 ? overall_coeff : _ex0); } /** Perform automatic term rewriting rules in this class. In the following @@ -326,15 +324,19 @@ ex add::coeff(const ex & s, int n) const * an expression that contain a plain number. * - +(;c) -> c * - +(x;0) -> x - * - * @param level cut-off in recursive evaluation */ -ex add::eval(int level) const + */ +ex add::eval() const { - epvector evaled = evalchildren(level); + if (flags & status_flags::evaluated) { + GINAC_ASSERT(seq.size()>0); + GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero()); + return *this; + } + + const epvector evaled = evalchildren(); if (unlikely(!evaled.empty())) { - // do more evaluation later - return (new add(std::move(evaled), overall_coeff))-> - setflag(status_flags::dynallocated); + // start over evaluating a new object + return dynallocate(std::move(evaled), overall_coeff); } #ifdef DO_GINAC_ASSERT @@ -342,14 +344,8 @@ ex add::eval(int level) const GINAC_ASSERT(!is_exactly_a(i.rest)); } #endif // def DO_GINAC_ASSERT - - if (flags & status_flags::evaluated) { - GINAC_ASSERT(seq.size()>0); - GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero()); - return *this; - } - - int seq_size = seq.size(); + + size_t seq_size = seq.size(); if (seq_size == 0) { // +(;c) -> c return overall_coeff; @@ -359,28 +355,7 @@ 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 - int terms_to_collect = 0; - for (auto & it : seq) { - if (unlikely(is_a(it.rest))) - ++terms_to_collect; - } - if (terms_to_collect) { - epvector s; - s.reserve(seq_size - terms_to_collect); - numeric oc = *_num1_p; - for (auto & it : seq) { - if (unlikely(is_a(it.rest))) - oc = oc.mul(ex_to(it.rest)).mul(ex_to(it.coeff)); - else - s.push_back(it); - } - return (new add(std::move(s), ex_to(overall_coeff).add_dyn(oc))) - ->setflag(status_flags::dynallocated); - } - + return this->hold(); } @@ -411,7 +386,7 @@ ex add::evalm() const if (all_matrices) return sum + overall_coeff; else - return (new add(std::move(s), overall_coeff))->setflag(status_flags::dynallocated); + return dynallocate(std::move(s), overall_coeff); } ex add::conjugate() const @@ -452,8 +427,7 @@ ex add::real_part() const if (!rp.is_zero()) v.push_back(split_ex_to_pair(rp)); } - return (new add(std::move(v), overall_coeff.real_part())) - -> setflag(status_flags::dynallocated); + return dynallocate(std::move(v), overall_coeff.real_part()); } ex add::imag_part() const @@ -470,8 +444,7 @@ ex add::imag_part() const if (!ip.is_zero()) v.push_back(split_ex_to_pair(ip)); } - return (new add(std::move(v), overall_coeff.imag_part())) - -> setflag(status_flags::dynallocated); + return dynallocate(std::move(v), overall_coeff.imag_part()); } ex add::eval_ncmul(const exvector & v) const @@ -495,9 +468,9 @@ ex add::derivative(const symbol & y) const // than the default implementation in basic::derivative() although // if performs the same function (differentiate each term). for (auto & it : seq) - s.push_back(combine_ex_with_coeff_to_pair(it.rest.diff(y), it.coeff)); + s.push_back(expair(it.rest.diff(y), it.coeff)); - return (new add(std::move(s), _ex0))->setflag(status_flags::dynallocated); + return dynallocate(std::move(s)); } int add::compare_same_type(const basic & other) const @@ -524,13 +497,13 @@ return_type_t add::return_type_tinfo() const // Note: do_index_renaming is ignored because it makes no sense for an add. ex add::thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming) const { - return (new add(v,oc))->setflag(status_flags::dynallocated); + return dynallocate(v, oc); } // Note: do_index_renaming is ignored because it makes no sense for an add. ex add::thisexpairseq(epvector && vp, const ex & oc, bool do_index_renaming) const { - return (new add(std::move(vp), oc))->setflag(status_flags::dynallocated); + return dynallocate(std::move(vp), oc); } expair add::split_ex_to_pair(const ex & e) const @@ -538,12 +511,12 @@ expair add::split_ex_to_pair(const ex & e) const if (is_exactly_a(e)) { const mul &mulref(ex_to(e)); const ex &numfactor = mulref.overall_coeff; - mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = _ex1; - mulcopyp->clearflag(status_flags::evaluated); - mulcopyp->clearflag(status_flags::hash_calculated); - mulcopyp->setflag(status_flags::dynallocated); - return expair(*mulcopyp,numfactor); + if (numfactor.is_equal(_ex1)) + return expair(e, _ex1); + mul & mulcopy = dynallocate(mulref); + mulcopy.overall_coeff = _ex1; + mulcopy.clearflag(status_flags::evaluated | status_flags::hash_calculated); + return expair(mulcopy, numfactor); } return expair(e,_ex1); } @@ -555,20 +528,20 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e, if (is_exactly_a(e)) { const mul &mulref(ex_to(e)); const ex &numfactor = mulref.overall_coeff; - mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = _ex1; - mulcopyp->clearflag(status_flags::evaluated); - mulcopyp->clearflag(status_flags::hash_calculated); - mulcopyp->setflag(status_flags::dynallocated); + if (likely(numfactor.is_equal(_ex1))) + return expair(e, c); + mul & mulcopy = dynallocate(mulref); + mulcopy.overall_coeff = _ex1; + mulcopy.clearflag(status_flags::evaluated | status_flags::hash_calculated); if (c.is_equal(_ex1)) - return expair(*mulcopyp, numfactor); - else if (numfactor.is_equal(_ex1)) - return expair(*mulcopyp, c); + return expair(mulcopy, numfactor); else - return expair(*mulcopyp, ex_to(numfactor).mul_dyn(ex_to(c))); + return expair(mulcopy, ex_to(numfactor).mul_dyn(ex_to(c))); } else if (is_exactly_a(e)) { if (c.is_equal(_ex1)) return expair(e, _ex1); + if (e.is_equal(_ex1)) + return expair(c, _ex1); return expair(ex_to(e).mul_dyn(ex_to(c)), _ex1); } return expair(e, c); @@ -593,7 +566,7 @@ ex add::recombine_pair_to_ex(const expair & p) const if (ex_to(p.coeff).is_equal(*_num1_p)) return p.rest; else - return (new mul(p.rest,p.coeff))->setflag(status_flags::dynallocated); + return dynallocate(p.rest, p.coeff); } ex add::expand(unsigned options) const @@ -602,8 +575,7 @@ ex add::expand(unsigned options) const if (expanded.empty()) return (options == 0) ? setflag(status_flags::expanded) : *this; - return (new add(std::move(expanded), overall_coeff))->setflag(status_flags::dynallocated | - (options == 0 ? status_flags::expanded : 0)); + return dynallocate(std::move(expanded), overall_coeff).setflag(options == 0 ? status_flags::expanded : 0); } } // namespace GiNaC