X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fmul.cpp;h=15dee661c735f831789bb5e1df634621634f009c;hp=a83b771d91d8f40f842b67a7528e931037caf4e3;hb=c12c8ec3c5cf0c75f061f6c52d04206277bbdcca;hpb=ae6c004bd31e02dda37357d74b641c101b116c73 diff --git a/ginac/mul.cpp b/ginac/mul.cpp index a83b771d..15dee661 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's products 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 @@ -89,6 +89,13 @@ mul::mul(const epvector & v, const ex & oc, bool do_index_renaming) GINAC_ASSERT(is_canonical()); } +mul::mul(epvector && vp) +{ + overall_coeff = _ex1; + construct_from_epvector(std::move(vp)); + GINAC_ASSERT(is_canonical()); +} + mul::mul(epvector && vp, const ex & oc, bool do_index_renaming) { overall_coeff = oc; @@ -285,13 +292,6 @@ bool mul::info(unsigned inf) const return true; return overall_coeff.info(inf); } - case info_flags::algebraic: { - for (auto & it : seq) { - if (recombine_pair_to_ex(it).info(inf)) - return true; - } - return false; - } case info_flags::positive: case info_flags::negative: { if ((inf==info_flags::positive) && (flags & status_flags::is_positive)) @@ -464,17 +464,16 @@ ex mul::coeff(const ex & s, int n) const * - *(+(x1,x2,...);c) -> *(+(*(x1,c),*(x2,c),...)) * - *(x;1) -> x * - *(;c) -> c - * - * @param level cut-off in recursive evaluation */ -ex mul::eval(int level) const + */ +ex mul::eval() const { - if ((level == 1) && (flags & status_flags::evaluated)) { + if (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); + const epvector evaled = evalchildren(); if (unlikely(!evaled.empty())) { // start over evaluating a new object return dynallocate(std::move(evaled), overall_coeff); @@ -501,7 +500,7 @@ ex mul::eval(int level) const distrseq.push_back(addref.combine_pair_with_coeff_to_pair(it, overall_coeff)); } return dynallocate(std::move(distrseq), - ex_to(addref.overall_coeff).mul_dyn(ex_to(overall_coeff))) + 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 @@ -555,9 +554,9 @@ ex mul::eval(int level) const 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); - + for (auto & ai : primitive.seq) + ai.coeff = ex_to(ai.coeff).div_dyn(c); + s.push_back(expair(primitive, _ex1)); ++i; @@ -575,22 +574,14 @@ ex mul::eval(int level) const return this->hold(); } -ex mul::evalf(int level) const +ex mul::evalf() const { - if (level==1) - return mul(seq,overall_coeff); - - if (level==-max_recursion_level) - throw(std::runtime_error("max recursion level reached")); - epvector s; s.reserve(seq.size()); - --level; - for (auto & it : seq) { - s.push_back(expair(it.rest.evalf(level), it.coeff)); - } - return dynallocate(std::move(s), overall_coeff.evalf(level)); + for (auto & it : seq) + s.push_back(expair(it.rest.evalf(), it.coeff)); + return dynallocate(std::move(s), overall_coeff.evalf()); } void mul::find_real_imag(ex & rp, ex & ip) const @@ -798,10 +789,10 @@ retry1: subsed[j] = true; ex subsed_pattern = it.first.subs(repls, subs_options::no_pattern); - divide_by *= power(subsed_pattern, nummatches); + divide_by *= pow(subsed_pattern, nummatches); ex subsed_result = it.second.subs(repls, subs_options::no_pattern); - multiply_by *= power(subsed_result, nummatches); + multiply_by *= pow(subsed_result, nummatches); goto retry1; } else { @@ -813,10 +804,10 @@ retry1: subsed[j] = true; ex subsed_pattern = it.first.subs(repls, subs_options::no_pattern); - divide_by *= power(subsed_pattern, nummatches); + divide_by *= pow(subsed_pattern, nummatches); ex subsed_result = it.second.subs(repls, subs_options::no_pattern); - multiply_by *= power(subsed_result, nummatches); + multiply_by *= pow(subsed_result, nummatches); } } } @@ -880,7 +871,7 @@ ex mul::derivative(const symbol & s) const auto i = seq.begin(), end = seq.end(); auto i2 = mulseq.begin(); while (i != end) { - expair ep = split_ex_to_pair(power(i->rest, i->coeff - _ex1) * + expair ep = split_ex_to_pair(pow(i->rest, i->coeff - _ex1) * i->rest.diff(s)); ep.swap(*i2); addseq.push_back(dynallocate(mulseq, overall_coeff * i->coeff)); @@ -978,7 +969,7 @@ expair mul::combine_ex_with_coeff_to_pair(const ex & e, if (c.is_equal(_ex1)) return split_ex_to_pair(e); - return split_ex_to_pair(power(e,c)); + return split_ex_to_pair(pow(e,c)); } expair mul::combine_pair_with_coeff_to_pair(const expair & p, @@ -994,7 +985,7 @@ expair mul::combine_pair_with_coeff_to_pair(const expair & p, if (c.is_equal(_ex1)) return p; - return split_ex_to_pair(power(recombine_pair_to_ex(p),c)); + return split_ex_to_pair(pow(recombine_pair_to_ex(p),c)); } ex mul::recombine_pair_to_ex(const expair & p) const @@ -1072,20 +1063,22 @@ bool mul::can_be_further_expanded(const ex & e) ex mul::expand(unsigned options) const { - { - // trivial case: expanding the monomial (~ 30% of all calls) - epvector::const_iterator i = seq.begin(), seq_end = seq.end(); - while ((i != seq.end()) && is_a(i->rest) && i->coeff.info(info_flags::integer)) - ++i; - if (i == seq_end) { - setflag(status_flags::expanded); - return *this; + // Check for trivial case: expanding the monomial (~ 30% of all calls) + bool monomial_case = true; + for (const auto & i : seq) { + if (!is_a(i.rest) || !i.coeff.info(info_flags::integer)) { + monomial_case = false; + break; } } + if (monomial_case) { + setflag(status_flags::expanded); + return *this; + } // do not rename indices if the object has no indices at all if ((!(options & expand_options::expand_rename_idx)) && - this->info(info_flags::has_indices)) + this->info(info_flags::has_indices)) options |= expand_options::expand_rename_idx; const bool skip_idx_rename = !(options & expand_options::expand_rename_idx);