X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fmul.cpp;h=a83b771d91d8f40f842b67a7528e931037caf4e3;hp=943095bb3a9c0e1a88aa023c37916bc701178eae;hb=ae6c004bd31e02dda37357d74b641c101b116c73;hpb=1b8bcb068171ce9d5c8202ae3c76647b65c9a06d diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 943095bb..a83b771d 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -435,7 +435,7 @@ ex mul::coeff(const ex & s, int n) const for (auto & it : seq) coeffseq.push_back(recombine_pair_to_ex(it).coeff(s,n)); coeffseq.push_back(overall_coeff); - return (new mul(coeffseq))->setflag(status_flags::dynallocated); + return dynallocate(coeffseq); } bool coeff_found = false; @@ -451,7 +451,7 @@ ex mul::coeff(const ex & s, int n) const } if (coeff_found) { coeffseq.push_back(overall_coeff); - return (new mul(coeffseq))->setflag(status_flags::dynallocated); + return dynallocate(coeffseq); } return _ex0; @@ -468,19 +468,18 @@ ex mul::coeff(const ex & s, int n) const * @param level cut-off in recursive evaluation */ ex mul::eval(int level) const { - epvector evaled = evalchildren(level); - if (!evaled.empty()) { - // do more evaluation later - return (new mul(std::move(evaled), overall_coeff))-> - setflag(status_flags::dynallocated); - } - - if (flags & status_flags::evaluated) { + if ((level == 1) && (flags & status_flags::evaluated)) { GINAC_ASSERT(seq.size()>0); GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_equal(_ex1)); return *this; } - + + const epvector evaled = evalchildren(level); + if (unlikely(!evaled.empty())) { + // start over evaluating a new object + return dynallocate(std::move(evaled), overall_coeff); + } + size_t seq_size = seq.size(); if (overall_coeff.is_zero()) { // *(...,x;0) -> 0 @@ -501,10 +500,9 @@ ex mul::eval(int level) const for (auto & it : addref.seq) { distrseq.push_back(addref.combine_pair_with_coeff_to_pair(it, overall_coeff)); } - return (new add(std::move(distrseq), - ex_to(addref.overall_coeff). - mul_dyn(ex_to(overall_coeff))) - )->setflag(status_flags::dynallocated | status_flags::evaluated); + return dynallocate(std::move(distrseq), + ex_to(addref.overall_coeff).mul_dyn(ex_to(overall_coeff))) + .setflag(status_flags::evaluated); } else if ((seq_size >= 2) && (! (flags & status_flags::expanded))) { // Strip the content and the unit part from each term. Thus // things like (-x+a)*(3*x-3*a) automagically turn into - 3*(x-a)^2 @@ -554,14 +552,13 @@ ex mul::eval(int level) const // divide add by the number in place to save at least 2 .eval() calls const add& addref = ex_to(i->rest); - add* primitive = new add(addref); - primitive->setflag(status_flags::dynallocated); - primitive->clearflag(status_flags::hash_calculated); - primitive->overall_coeff = ex_to(primitive->overall_coeff).div_dyn(c); - for (epvector::iterator ai = primitive->seq.begin(); ai != primitive->seq.end(); ++ai) + add & primitive = dynallocate(addref); + primitive.clearflag(status_flags::hash_calculated); + primitive.overall_coeff = ex_to(primitive.overall_coeff).div_dyn(c); + for (epvector::iterator ai = primitive.seq.begin(); ai != primitive.seq.end(); ++ai) ai->coeff = ex_to(ai->coeff).div_dyn(c); - s.push_back(expair(*primitive, _ex1)); + s.push_back(expair(primitive, _ex1)); ++i; ++j; @@ -571,8 +568,7 @@ ex mul::eval(int level) const s.push_back(*j); ++j; } - return (new mul(std::move(s), ex_to(overall_coeff).mul_dyn(oc)) - )->setflag(status_flags::dynallocated); + return dynallocate(std::move(s), ex_to(overall_coeff).mul_dyn(oc)); } } @@ -592,10 +588,9 @@ ex mul::evalf(int level) const --level; for (auto & it : seq) { - s.push_back(combine_ex_with_coeff_to_pair(it.rest.evalf(level), - it.coeff)); + s.push_back(expair(it.rest.evalf(level), it.coeff)); } - return mul(std::move(s), overall_coeff.evalf(level)); + return dynallocate(std::move(s), overall_coeff.evalf(level)); } void mul::find_real_imag(ex & rp, ex & ip) const @@ -664,11 +659,11 @@ ex mul::evalm() const // into that matrix. matrix m = ex_to(the_matrix->rest); s.erase(the_matrix); - ex scalar = (new mul(std::move(s), overall_coeff))->setflag(status_flags::dynallocated); + ex scalar = dynallocate(std::move(s), overall_coeff); return m.mul_scalar(scalar); } else - return (new mul(std::move(s), overall_coeff))->setflag(status_flags::dynallocated); + return dynallocate(std::move(s), overall_coeff); } ex mul::eval_ncmul(const exvector & v) const @@ -888,11 +883,11 @@ ex mul::derivative(const symbol & s) const expair ep = split_ex_to_pair(power(i->rest, i->coeff - _ex1) * i->rest.diff(s)); ep.swap(*i2); - addseq.push_back((new mul(mulseq, overall_coeff * i->coeff))->setflag(status_flags::dynallocated)); + addseq.push_back(dynallocate(mulseq, overall_coeff * i->coeff)); ep.swap(*i2); ++i; ++i2; } - return (new add(addseq))->setflag(status_flags::dynallocated); + return dynallocate(addseq); } int mul::compare_same_type(const basic & other) const @@ -949,12 +944,12 @@ return_type_t mul::return_type_tinfo() const ex mul::thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming) const { - return (new mul(v, oc, do_index_renaming))->setflag(status_flags::dynallocated); + return dynallocate(v, oc, do_index_renaming); } ex mul::thisexpairseq(epvector && vp, const ex & oc, bool do_index_renaming) const { - return (new mul(std::move(vp), oc, do_index_renaming))->setflag(status_flags::dynallocated); + return dynallocate(std::move(vp), oc, do_index_renaming); } expair mul::split_ex_to_pair(const ex & e) const @@ -970,6 +965,12 @@ expair mul::split_ex_to_pair(const ex & e) const expair mul::combine_ex_with_coeff_to_pair(const ex & e, const ex & c) const { + GINAC_ASSERT(is_exactly_a(c)); + + // First, try a common shortcut: + if (is_exactly_a(e)) + return expair(e, c); + // to avoid duplication of power simplification rules, // we create a temporary power object // otherwise it would be hard to correctly evaluate @@ -983,6 +984,9 @@ expair mul::combine_ex_with_coeff_to_pair(const ex & e, expair mul::combine_pair_with_coeff_to_pair(const expair & p, const ex & c) const { + GINAC_ASSERT(is_exactly_a(p.coeff)); + GINAC_ASSERT(is_exactly_a(c)); + // to avoid duplication of power simplification rules, // we create a temporary power object // otherwise it would be hard to correctly evaluate @@ -998,7 +1002,7 @@ ex mul::recombine_pair_to_ex(const expair & p) const if (ex_to(p.coeff).is_equal(*_num1_p)) return p.rest; else - return (new power(p.rest,p.coeff))->setflag(status_flags::dynallocated); + return dynallocate(p.rest, p.coeff); } bool mul::expair_needs_further_processing(epp it) @@ -1047,10 +1051,9 @@ void mul::combine_overall_coeff(const ex & c1, const ex & c2) bool mul::can_make_flat(const expair & p) const { GINAC_ASSERT(is_exactly_a(p.coeff)); - // this assertion will probably fail somewhere - // it would require a more careful make_flat, obeying the power laws - // probably should return true only if p.coeff is integer - return ex_to(p.coeff).is_equal(*_num1_p); + + // (x*y)^c == x^c*y^c if c ∈ ℤ + return p.coeff.info(info_flags::integer); } bool mul::can_be_further_expanded(const ex & e) @@ -1135,7 +1138,7 @@ ex mul::expand(unsigned options) const } // Compute the new overall coefficient and put it together: - ex tmp_accu = (new add(distrseq, add1.overall_coeff*add2.overall_coeff))->setflag(status_flags::dynallocated); + ex tmp_accu = dynallocate(distrseq, add1.overall_coeff*add2.overall_coeff); exvector add1_dummy_indices, add2_dummy_indices, add_indices; lst dummy_subs; @@ -1169,14 +1172,14 @@ ex mul::expand(unsigned options) const for (const auto & i1 : add1.seq) { // Don't push_back expairs which might have a rest that evaluates to a numeric, // since that would violate an invariant of expairseq: - const ex rest = (new mul(i1.rest, i2_new))->setflag(status_flags::dynallocated); + const ex rest = dynallocate(i1.rest, i2_new); if (is_exactly_a(rest)) { oc += ex_to(rest).mul(ex_to(i1.coeff).mul(ex_to(i2.coeff))); } else { distrseq2.push_back(expair(rest, ex_to(i1.coeff).mul_dyn(ex_to(i2.coeff)))); } } - tmp_accu += (new add(distrseq2, oc))->setflag(status_flags::dynallocated); + tmp_accu += dynallocate(std::move(distrseq2), oc); } last_expanded = tmp_accu; } else { @@ -1208,7 +1211,7 @@ ex mul::expand(unsigned options) const factors.push_back(split_ex_to_pair(last_expanded.op(i))); else factors.push_back(split_ex_to_pair(rename_dummy_indices_uniquely(va, last_expanded.op(i)))); - ex term = (new mul(factors, overall_coeff))->setflag(status_flags::dynallocated); + ex term = dynallocate(factors, overall_coeff); if (can_be_further_expanded(term)) { distrseq.push_back(term.expand()); } else { @@ -1218,12 +1221,11 @@ ex mul::expand(unsigned options) const } } - return ((new add(distrseq))-> - setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); + return dynallocate(distrseq).setflag(options == 0 ? status_flags::expanded : 0); } non_adds.push_back(split_ex_to_pair(last_expanded)); - ex result = (new mul(non_adds, overall_coeff))->setflag(status_flags::dynallocated); + ex result = dynallocate(non_adds, overall_coeff); if (can_be_further_expanded(result)) { return result.expand(); } else {