X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fseries.cpp;h=0cc2be34d42ae208a7dacc06d736b1c08dcfd0e2;hp=668cb6baaf184803e2146ac41090b3d247a47ccb;hb=721cff7b2f8d555e085202f6f3f47801b92d0413;hpb=a8507b8af1c08d9b27d98d57f95c7ca1a8671e27 diff --git a/ginac/series.cpp b/ginac/series.cpp index 668cb6ba..0cc2be34 100644 --- a/ginac/series.cpp +++ b/ginac/series.cpp @@ -1,8 +1,9 @@ /** @file series.cpp * * Implementation of class for extended truncated power-series and - * methods for series expansion. - * + * methods for series expansion. */ + +/* * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify @@ -20,14 +21,24 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ginac.h" +#include "series.h" +#include "add.h" +#include "inifcns.h" +#include "mul.h" +#include "power.h" +#include "relational.h" +#include "symbol.h" +#include "debugmsg.h" +#ifndef NO_GINAC_NAMESPACE +namespace GiNaC { +#endif // ndef NO_GINAC_NAMESPACE /* * Default constructor, destructor, copy constructor, assignment operator and helpers */ -series::series() : basic(TINFO_SERIES) +series::series() : basic(TINFO_series) { debugmsg("series default constructor", LOGLEVEL_CONSTRUCT); } @@ -84,10 +95,10 @@ void series::destroy(bool call_parent) * @param ops_ vector of {coefficient, power} pairs (coefficient must not be zero) * @return newly constructed series */ series::series(ex const &var_, ex const &point_, epvector const &ops_) - : basic(TINFO_SERIES), seq(ops_), var(var_), point(point_) + : basic(TINFO_series), seq(ops_), var(var_), point(point_) { debugmsg("series constructor from ex,ex,epvector", LOGLEVEL_CONSTRUCT); - ASSERT(is_ex_exactly_of_type(var_, symbol)); + GINAC_ASSERT(is_ex_exactly_of_type(var_, symbol)); } @@ -101,10 +112,26 @@ basic *series::duplicate() const return new series(*this); } +void series::print(ostream &os, unsigned upper_precedence) const +{ + debugmsg("symbol print", LOGLEVEL_PRINT); + convert_to_poly().print(os, upper_precedence); +} + +void series::printraw(ostream &os) const +{ + debugmsg("symbol printraw", LOGLEVEL_PRINT); + os << "series(" << var << ";" << point << ";"; + for (epvector::const_iterator i=seq.begin(); i!=seq.end(); i++) { + os << "(" << (*i).rest << "," << (*i).coeff << "),"; + } + os << ")"; +} + // Highest degree of variable int series::degree(symbol const &s) const { - if (var == s) { + if (var.is_equal(s)) { // Return last exponent if (seq.size()) return ex_to_numeric((*(seq.end() - 1)).coeff).to_int(); @@ -128,7 +155,7 @@ int series::degree(symbol const &s) const // Lowest degree of variable int series::ldegree(symbol const &s) const { - if (var == s) { + if (var.is_equal(s)) { // Return first exponent if (seq.size()) return ex_to_numeric((*(seq.begin())).coeff).to_int(); @@ -152,7 +179,7 @@ int series::ldegree(symbol const &s) const // Coefficient of variable ex series::coeff(symbol const &s, int n) const { - if (var == s) { + if (var.is_equal(s)) { epvector::const_iterator it = seq.begin(), itend = seq.end(); while (it != itend) { int pow = ex_to_numeric(it->coeff).to_int(); @@ -171,7 +198,7 @@ ex series::eval(int level) const { if (level == 1) return this->hold(); - + // Construct a new series with evaluated coefficients epvector new_seq; new_seq.reserve(seq.size()); @@ -183,12 +210,12 @@ ex series::eval(int level) const return (new series(var, point, new_seq))->setflag(status_flags::dynallocated | status_flags::evaluated); } +/** Evaluate numerically. The order term is dropped. */ ex series::evalf(int level) const { return convert_to_poly().evalf(level); } - /* * Construct expression (polynomial) out of series */ @@ -200,7 +227,7 @@ ex series::convert_to_poly(bool no_order) const { ex e; epvector::const_iterator it = seq.begin(), itend = seq.end(); - + while (it != itend) { if (is_order_function(it->rest)) { if (!no_order) @@ -227,7 +254,7 @@ ex basic::series(symbol const & s, ex const & point, int order) const ex coeff = deriv.subs(s == point); if (!coeff.is_zero()) seq.push_back(expair(coeff, numeric(0))); - + int n; for (n=1; nrest.series(s, point, order); if (!it->coeff.is_equal(exONE())) op = ex_to_series(op).mul_const(ex_to_numeric(it->coeff)); - + // Series addition acc = ex_to_series(acc).add_series(ex_to_series(op)); } @@ -395,7 +422,7 @@ ex series::mul_const(const numeric &other) const { epvector new_seq; new_seq.reserve(seq.size()); - + epvector::const_iterator it = seq.begin(), itend = seq.end(); while (it != itend) { if (!is_order_function(it->rest)) @@ -425,7 +452,7 @@ ex series::mul_series(const series &other) const // Series multiplication epvector new_seq; - + const symbol *s = static_cast(var.bp); int a_max = degree(*s); int b_max = other.degree(*s); @@ -433,7 +460,7 @@ ex series::mul_series(const series &other) const int b_min = other.ldegree(*s); int cdeg_min = a_min + b_min; int cdeg_max = a_max + b_max; - + int higher_order_a = INT_MAX; int higher_order_b = INT_MAX; if (is_order_function(coeff(*s, a_max))) @@ -443,7 +470,7 @@ ex series::mul_series(const series &other) const int higher_order_c = min(higher_order_a, higher_order_b); if (cdeg_max >= higher_order_c) cdeg_max = higher_order_c - 1; - + for (int cdeg=cdeg_min; cdeg<=cdeg_max; cdeg++) { ex co = exZERO(); // c(i)=a(0)b(i)+...+a(i)b(0) @@ -462,8 +489,6 @@ ex series::mul_series(const series &other) const } -/** Implementation of ex::series() for product. This performs series multiplication when multiplying series. - * @see ex::series */ /* ex mul::series(symbol const & s, ex const & point, int order) const { @@ -502,13 +527,16 @@ ex mul::series(symbol const & s, ex const & point, int order) const } */ +/** Implementation of ex::series() for product. This performs series + * multiplication when multiplying series. + * @see ex::series */ ex mul::series(symbol const & s, ex const & point, int order) const { ex acc; // Series accumulator - + // Get first term from overall_coeff acc = overall_coeff.series(s, point, order); - + // Multiply with remaining terms epvector::const_iterator it = seq.begin(); epvector::const_iterator itend = seq.end(); @@ -540,7 +568,7 @@ ex series::power_const(const numeric &p, int deg) const int i; const symbol *s = static_cast(var.bp); int ldeg = ldegree(*s); - + // Calculate coefficients of powered series exvector co; co.reserve(deg); @@ -561,7 +589,7 @@ ex series::power_const(const numeric &p, int deg) const all_sums_zero = false; co.push_back(co0 * sum / numeric(i)); } - + // Construct new series (of non-zero coefficients) epvector new_seq; bool higher_order = false; @@ -589,18 +617,18 @@ ex power::series(symbol const & s, ex const & point, int order) const // Basis is not a series, may there be a singulary? if (!exponent.info(info_flags::negint)) return basic::series(s, point, order); - + // Expression is of type something^(-int), check for singularity if (!basis.subs(s == point).is_zero()) return basic::series(s, point, order); - + // Singularity encountered, expand basis into series e = basis.series(s, point, order); } else { // Basis is a series e = basis; } - + // Power e return ex_to_series(e).power_const(ex_to_numeric(exponent), order); } @@ -617,7 +645,7 @@ ex power::series(symbol const & s, ex const & point, int order) const * @return an expression holding a series object */ ex ex::series(symbol const &s, ex const &point, int order) const { - ASSERT(bp!=0); + GINAC_ASSERT(bp!=0); return bp->series(s, point, order); } @@ -625,3 +653,7 @@ ex ex::series(symbol const &s, ex const &point, int order) const // Global constants const series some_series; type_info const & typeid_series = typeid(some_series); + +#ifndef NO_GINAC_NAMESPACE +} // namespace GiNaC +#endif // ndef NO_GINAC_NAMESPACE