X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fpseries.cpp;h=4491915841b1cd746d32cde71c8effc395257d4c;hp=d674148dbad709f176a9f76d3a4e647d94d20b80;hb=21ebb806befcb3873d58074454fcf8dcba138fa9;hpb=2565309dd7c38635c191eacf2a4af9b23fc0d310 diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index d674148d..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) @@ -162,13 +162,13 @@ basic *pseries::duplicate() const void pseries::print(ostream &os, unsigned upper_precedence) const { - debugmsg("symbol print", LOGLEVEL_PRINT); - convert_to_poly().print(os, upper_precedence); + debugmsg("pseries print", LOGLEVEL_PRINT); + convert_to_poly().print(os, upper_precedence); } void pseries::printraw(ostream &os) const { - debugmsg("symbol printraw", LOGLEVEL_PRINT); + debugmsg("pseries printraw", LOGLEVEL_PRINT); os << "pseries(" << var << ";" << point << ";"; for (epvector::const_iterator i=seq.begin(); i!=seq.end(); i++) { os << "(" << (*i).rest << "," << (*i).coeff << "),"; @@ -178,14 +178,14 @@ void pseries::printraw(ostream &os) const unsigned pseries::nops(void) const { - return seq.size(); + return seq.size(); } ex pseries::op(int i) const { - if (i < 0 || i >= seq.size()) - throw (std::out_of_range("op() out of range")); - return seq[i].rest * power(var - point, seq[i].coeff); + if (i < 0 || unsigned(i) >= seq.size()) + throw (std::out_of_range("op() out of range")); + return seq[i].rest * power(var - point, seq[i].coeff); } ex &pseries::let_op(int i) @@ -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 @@ -377,8 +411,8 @@ ex symbol::series(const symbol & s, const ex & point, int order) const } -/** Add one series object to another, producing a pseries object that represents - * the sum. +/** Add one series object to another, producing a pseries object that + * represents the sum. * * @param other pseries object to add with * @return the sum as a pseries */ @@ -480,8 +514,8 @@ ex add::series(const symbol & s, const ex & point, int order) const } -/** Multiply a pseries object with a numeric constant, producing a pseries object - * that represents the product. +/** Multiply a pseries object with a numeric constant, producing a pseries + * object that represents the product. * * @param other constant to multiply with * @return the product as a pseries */ @@ -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