X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fpseries.cpp;h=4491915841b1cd746d32cde71c8effc395257d4c;hp=0f29e5f547698e08323e31525f6dc451a4ec49cc;hb=21ebb806befcb3873d58074454fcf8dcba138fa9;hpb=0a41902fc56d32309e21412c877305403b3b74c3;ds=sidebyside diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 0f29e5f5..44919158 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -35,9 +35,9 @@ #include "utils.h" #include "debugmsg.h" -#ifndef NO_GINAC_NAMESPACE +#ifndef NO_NAMESPACE_GINAC namespace GiNaC { -#endif // ndef NO_GINAC_NAMESPACE +#endif // ndef NO_NAMESPACE_GINAC GINAC_IMPLEMENT_REGISTERED_CLASS(pseries, basic) @@ -256,6 +256,14 @@ ex pseries::coeff(const symbol &s, int n) const return convert_to_poly().coeff(s, n); } +ex pseries::collect(const symbol &s) const +{ + if (var.is_equal(s)) + return convert_to_poly(); + else + return inherited::collect(s); +} + ex pseries::eval(int level) const { if (level == 1) @@ -298,6 +306,32 @@ ex pseries::subs(const lst & ls, const lst & lr) const return (new pseries(var, point.subs(ls, lr), new_seq))->setflag(status_flags::dynallocated); } +/** Implementation of ex::diff() for a power series. It treats the series as a + * polynomial. + * @see ex::diff */ +ex pseries::derivative(const symbol & s) const +{ + if (s == var) { + epvector new_seq; + epvector::const_iterator it = seq.begin(), itend = seq.end(); + + // FIXME: coeff might depend on var + while (it != itend) { + if (is_order_function(it->rest)) { + new_seq.push_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)); + } + it++; + } + return pseries(var, point, new_seq); + } else { + return *this; + } +} + /* * Construct ordinary polynomial out of series @@ -663,6 +697,31 @@ ex power::series(const symbol & s, const ex & point, int order) const } +/** Re-expansion of a pseries object. */ +ex pseries::series(const symbol & s, const ex & p, int order) const +{ + if (var.is_equal(s) && point.is_equal(p)) { + if (order > degree(s)) + return *this; + else { + epvector new_seq; + epvector::const_iterator it = seq.begin(), itend = seq.end(); + while (it != itend) { + int o = ex_to_numeric(it->coeff).to_int(); + if (o >= order) { + new_seq.push_back(expair(Order(_ex1()), o)); + break; + } + new_seq.push_back(*it); + it++; + } + return pseries(var, point, new_seq); + } + } else + return convert_to_poly().series(s, p, order); +} + + /** Compute the truncated series expansion of an expression. * This function returns an expression containing an object of class pseries to * represent the series. If the series does not terminate within the given @@ -683,6 +742,6 @@ ex ex::series(const symbol &s, const ex &point, int order) const const pseries some_pseries; const type_info & typeid_pseries = typeid(some_pseries); -#ifndef NO_GINAC_NAMESPACE +#ifndef NO_NAMESPACE_GINAC } // namespace GiNaC -#endif // ndef NO_GINAC_NAMESPACE +#endif // ndef NO_NAMESPACE_GINAC