X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fpseries.cpp;h=b675c02eb2ecd3b6429bcaede30dcadce7365d9c;hp=899a8599d8f33c4cc7485971defb5bae2ac3af84;hb=f9880838cc42de5dfbedcbc181eaedf6c07bfc75;hpb=bb68d77b93ad9aab1be3705e052d7091cee94d56 diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 899a8599..b675c02e 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -4,7 +4,7 @@ * methods for series expansion. */ /* - * GiNaC Copyright (C) 1999-2016 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2020 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 @@ -119,17 +119,15 @@ pseries::pseries(const ex &rel_, epvector &&ops_) void pseries::read_archive(const archive_node &n, lst &sym_lst) { inherited::read_archive(n, sym_lst); - auto first = n.find_first("coeff"); - auto last = n.find_last("power"); - ++last; - seq.reserve((last-first)/2); + auto range = n.find_property_range("coeff", "power"); + seq.reserve((range.end-range.begin)/2); - for (auto loc = first; loc < last;) { + for (auto loc = range.begin; loc < range.end;) { ex rest; ex coeff; n.find_ex_by_loc(loc++, rest, sym_lst); n.find_ex_by_loc(loc++, coeff, sym_lst); - seq.push_back(expair(rest, coeff)); + seq.emplace_back(expair(rest, coeff)); } n.find_ex("var", var, sym_lst); @@ -396,17 +394,7 @@ ex pseries::collect(const ex &s, bool distributed) const /** Perform coefficient-wise automatic term rewriting rules in this class. */ ex pseries::eval() const { - if (flags & status_flags::evaluated) { - return *this; - } - - // Construct a new series with evaluated coefficients - epvector new_seq; - new_seq.reserve(seq.size()); - for (auto & it : seq) - new_seq.push_back(expair(it.rest, it.coeff)); - - return dynallocate(relational(var,point), std::move(new_seq)).setflag(status_flags::evaluated); + return hold(); } /** Evaluate coefficients numerically. */ @@ -416,7 +404,7 @@ ex pseries::evalf() const epvector new_seq; new_seq.reserve(seq.size()); for (auto & it : seq) - new_seq.push_back(expair(it.rest, it.coeff)); + new_seq.emplace_back(expair(it.rest.evalf(), it.coeff)); return dynallocate(relational(var,point), std::move(new_seq)).setflag(status_flags::evaluated); } @@ -447,7 +435,7 @@ ex pseries::real_part() const epvector v; v.reserve(seq.size()); for (auto & it : seq) - v.push_back(expair((it.rest).real_part(), it.coeff)); + v.emplace_back(expair(it.rest.real_part(), it.coeff)); return dynallocate(var==point, std::move(v)); } @@ -462,7 +450,7 @@ ex pseries::imag_part() const epvector v; v.reserve(seq.size()); for (auto & it : seq) - v.push_back(expair((it.rest).imag_part(), it.coeff)); + v.emplace_back(expair(it.rest.imag_part(), it.coeff)); return dynallocate(var==point, std::move(v)); } @@ -471,7 +459,7 @@ ex pseries::eval_integ() const std::unique_ptr newseq(nullptr); for (auto i=seq.begin(); i!=seq.end(); ++i) { if (newseq) { - newseq->push_back(expair(i->rest.eval_integ(), i->coeff)); + newseq->emplace_back(expair(i->rest.eval_integ(), i->coeff)); continue; } ex newterm = i->rest.eval_integ(); @@ -480,7 +468,7 @@ ex pseries::eval_integ() const newseq->reserve(seq.size()); for (auto j=seq.begin(); j!=i; ++j) newseq->push_back(*j); - newseq->push_back(expair(newterm, i->coeff)); + newseq->emplace_back(expair(newterm, i->coeff)); } } @@ -499,7 +487,7 @@ ex pseries::evalm() const if (something_changed) { ex newcoeff = i->rest.evalm(); if (!newcoeff.is_zero()) - newseq.push_back(expair(newcoeff, i->coeff)); + newseq.emplace_back(expair(newcoeff, i->coeff)); } else { ex newcoeff = i->rest.evalm(); if (!are_ex_trivially_equal(newcoeff, i->rest)) { @@ -507,7 +495,7 @@ ex pseries::evalm() const newseq.reserve(seq.size()); std::copy(seq.begin(), i, std::back_inserter(newseq)); if (!newcoeff.is_zero()) - newseq.push_back(expair(newcoeff, i->coeff)); + newseq.emplace_back(expair(newcoeff, i->coeff)); } } } @@ -530,7 +518,7 @@ ex pseries::subs(const exmap & m, unsigned options) const epvector newseq; newseq.reserve(seq.size()); for (auto & it : seq) - newseq.push_back(expair(it.rest.subs(m, options), it.coeff)); + newseq.emplace_back(expair(it.rest.subs(m, options), it.coeff)); return dynallocate(relational(var,point.subs(m, options)), std::move(newseq)); } @@ -542,7 +530,7 @@ ex pseries::expand(unsigned options) const for (auto & it : seq) { ex restexp = it.rest.expand(); if (!restexp.is_zero()) - newseq.push_back(expair(restexp, it.coeff)); + newseq.emplace_back(expair(restexp, it.coeff)); } return dynallocate(relational(var,point), std::move(newseq)).setflag(options == 0 ? status_flags::expanded : 0); } @@ -558,11 +546,11 @@ ex pseries::derivative(const symbol & s) const // FIXME: coeff might depend on var for (auto & it : seq) { if (is_order_function(it.rest)) { - new_seq.push_back(expair(it.rest, it.coeff - 1)); + new_seq.emplace_back(expair(it.rest, it.coeff - 1)); } else { ex c = it.rest * it.coeff; if (!c.is_zero()) - new_seq.push_back(expair(c, it.coeff - 1)); + new_seq.emplace_back(expair(c, it.coeff - 1)); } } @@ -574,7 +562,7 @@ ex pseries::derivative(const symbol & s) const } else { ex c = it.rest.diff(s); if (!c.is_zero()) - new_seq.push_back(expair(c, it.coeff)); + new_seq.emplace_back(expair(c, it.coeff)); } } } @@ -628,7 +616,7 @@ ex basic::series(const relational & r, int order, unsigned options) const // default for order-values that make no sense for Taylor expansion if ((order <= 0) && this->has(s)) { - seq.push_back(expair(Order(_ex1), order)); + seq.emplace_back(expair(Order(_ex1), order)); return pseries(r, std::move(seq)); } @@ -638,7 +626,7 @@ ex basic::series(const relational & r, int order, unsigned options) const ex coeff = deriv.subs(r, subs_options::no_pattern); if (!coeff.is_zero()) { - seq.push_back(expair(coeff, _ex0)); + seq.emplace_back(expair(coeff, _ex0)); } int n; @@ -653,13 +641,13 @@ ex basic::series(const relational & r, int order, unsigned options) const coeff = deriv.subs(r, subs_options::no_pattern); if (!coeff.is_zero()) - seq.push_back(expair(fac * coeff, n)); + seq.emplace_back(expair(fac * coeff, n)); } // Higher-order terms, if present deriv = deriv.diff(s); if (!deriv.expand().is_zero()) - seq.push_back(expair(Order(_ex1), n)); + seq.emplace_back(expair(Order(_ex1), n)); return pseries(r, std::move(seq)); } @@ -674,13 +662,13 @@ ex symbol::series(const relational & r, int order, unsigned options) const if (this->is_equal_same_type(ex_to(r.lhs()))) { if (order > 0 && !point.is_zero()) - seq.push_back(expair(point, _ex0)); + seq.emplace_back(expair(point, _ex0)); if (order > 1) - seq.push_back(expair(_ex1, _ex1)); + seq.emplace_back(expair(_ex1, _ex1)); else - seq.push_back(expair(Order(_ex1), numeric(order))); + seq.emplace_back(expair(Order(_ex1), numeric(order))); } else - seq.push_back(expair(*this, _ex0)); + seq.emplace_back(expair(*this, _ex0)); return pseries(r, std::move(seq)); } @@ -741,12 +729,12 @@ ex pseries::add_series(const pseries &other) const } else { // Add coefficient of a and b if (is_order_function((*a).rest) || is_order_function((*b).rest)) { - new_seq.push_back(expair(Order(_ex1), (*a).coeff)); + new_seq.emplace_back(expair(Order(_ex1), (*a).coeff)); break; // Order term ends the sequence } else { ex sum = (*a).rest + (*b).rest; if (!(sum.is_zero())) - new_seq.push_back(expair(sum, numeric(pow_a))); + new_seq.emplace_back(expair(sum, numeric(pow_a))); ++a; ++b; } @@ -795,7 +783,7 @@ ex pseries::mul_const(const numeric &other) const for (auto & it : seq) { if (!is_order_function(it.rest)) - new_seq.push_back(expair(it.rest * other, it.coeff)); + new_seq.emplace_back(expair(it.rest * other, it.coeff)); else new_seq.push_back(it); } @@ -862,10 +850,10 @@ ex pseries::mul_series(const pseries &other) const co += ita->second * itb->second; } if (!co.is_zero()) - new_seq.push_back(expair(co, numeric(cdeg))); + new_seq.emplace_back(expair(co, numeric(cdeg))); } if (higher_order_c < std::numeric_limits::max()) - new_seq.push_back(expair(Order(_ex1), numeric(higher_order_c))); + new_seq.emplace_back(expair(Order(_ex1), numeric(higher_order_c))); return pseries(relational(var, point), std::move(new_seq)); } @@ -959,9 +947,8 @@ ex mul::series(const relational & r, int order, unsigned options) const int degsum = std::accumulate(ldegrees.begin(), ldegrees.end(), 0); - if (degsum >= order) { - epvector epv { expair(Order(_ex1), order) }; - return dynallocate(r, std::move(epv)); + if (degsum > order) { + return dynallocate(r, epvector{{Order(_ex1), order}}); } // Multiply with remaining terms @@ -1057,14 +1044,14 @@ ex pseries::power_const(const numeric &p, int deg) const bool higher_order = false; for (int i=0; i(exponent).to_int() < order) - new_seq.push_back(expair(_ex1, exponent)); + new_seq.emplace_back(expair(_ex1, exponent)); else - new_seq.push_back(expair(Order(_ex1), exponent)); + new_seq.emplace_back(expair(Order(_ex1), exponent)); return pseries(r, std::move(new_seq)); } @@ -1193,7 +1180,7 @@ ex pseries::series(const relational & r, int order, unsigned options) const for (auto & it : seq) { int o = ex_to(it.coeff).to_int(); if (o >= order) { - new_seq.push_back(expair(Order(_ex1), o)); + new_seq.emplace_back(expair(Order(_ex1), o)); break; } new_seq.push_back(it); @@ -1219,7 +1206,7 @@ ex integral::series(const relational & r, int order, unsigned options) const ? currcoeff : integral(x, a.subs(r), b.subs(r), currcoeff); if (currcoeff != 0) - fexpansion.push_back( + fexpansion.emplace_back( expair(currcoeff, ex_to(fseries).exponop(i))); }