From: Richard Kreckel Date: Sat, 17 Feb 2001 21:07:08 +0000 (+0000) Subject: pseries::expand(): do not generate zero terms. X-Git-Tag: release_0-7-2 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=refs%2Ftags%2Frelease_0-7-2;hp=90f335d685c2e54b2dc36a0bf029b30914bbd9b1 pseries::expand(): do not generate zero terms. pseries::print(): print trivial case, too. others: documentation updates. --- diff --git a/ginac/add.cpp b/ginac/add.cpp index 9cc2cc01..2f227fcf 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -440,11 +440,11 @@ ex add::thisexpairseq(epvector * vp, const ex & oc) const expair add::split_ex_to_pair(const ex & e) const { if (is_ex_exactly_of_type(e,mul)) { - const mul & mulref=ex_to_mul(e); - ex numfactor=mulref.overall_coeff; - // mul * mulcopyp=static_cast(mulref.duplicate()); - mul * mulcopyp=new mul(mulref); - mulcopyp->overall_coeff=_ex1(); + const mul & mulref = ex_to_mul(e); + ex numfactor = mulref.overall_coeff; + // mul * mulcopyp = static_cast(mulref.duplicate()); + mul * mulcopyp = new mul(mulref); + mulcopyp->overall_coeff = _ex1(); mulcopyp->clearflag(status_flags::evaluated); mulcopyp->clearflag(status_flags::hash_calculated); return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor); @@ -456,26 +456,24 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e, const ex & c) const { GINAC_ASSERT(is_ex_exactly_of_type(c, numeric)); - ex one = _ex1(); if (is_ex_exactly_of_type(e, mul)) { const mul &mulref = ex_to_mul(e); ex numfactor = mulref.overall_coeff; mul *mulcopyp = new mul(mulref); - mulcopyp->overall_coeff = one; + mulcopyp->overall_coeff = _ex1(); mulcopyp->clearflag(status_flags::evaluated); mulcopyp->clearflag(status_flags::hash_calculated); mulcopyp->setflag(status_flags::dynallocated); - if (are_ex_trivially_equal(c, one)) { + if (are_ex_trivially_equal(c, _ex1())) { return expair(*mulcopyp, numfactor); - } else if (are_ex_trivially_equal(numfactor, one)) { + } else if (are_ex_trivially_equal(numfactor, _ex1())) { return expair(*mulcopyp, c); } return expair(*mulcopyp, ex_to_numeric(numfactor).mul_dyn(ex_to_numeric(c))); } else if (is_ex_exactly_of_type(e, numeric)) { - if (are_ex_trivially_equal(c, one)) { - return expair(e, one); - } - return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)), one); + if (are_ex_trivially_equal(c, _ex1())) + return expair(e, _ex1()); + return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)), _ex1()); } return expair(e, c); } diff --git a/ginac/basic.cpp b/ginac/basic.cpp index 9f0bbf53..a33433da 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -143,7 +143,7 @@ void basic::print(std::ostream & os, unsigned upper_precedence) const } /** Output to stream in ugly raw format, so brave developers can have a look - * at the underlying structure. */ + * at the underlying structure. */ void basic::printraw(std::ostream & os) const { debugmsg("basic printraw",LOGLEVEL_PRINT); @@ -176,14 +176,22 @@ void basic::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedenc debugmsg("basic print csrc", LOGLEVEL_PRINT); } -/** Little wrapper arount print to be called within a debugger. */ +/** Little wrapper arount print to be called within a debugger. + * This is needed because you cannot call foo.print(cout) from within the + * debugger because it might not know what cout is. This method can be invoked + * with no argument and it will simply print to stdout. + * + * @see basic::print*/ void basic::dbgprint(void) const { print(std::cerr); std::cerr << std::endl; } -/** Little wrapper arount printtree to be called within a debugger. */ +/** Little wrapper arount printtree to be called within a debugger. + * + * @see basic::dbgprint + * @see basic::printtree */ void basic::dbgprinttree(void) const { printtree(std::cerr,0); @@ -519,9 +527,8 @@ const basic & basic::hold(void) const void basic::ensure_if_modifiable(void) const { - if (refcount>1) { + if (refcount>1) throw(std::runtime_error("cannot modify multiply referenced object")); - } } ////////// diff --git a/ginac/basic.h b/ginac/basic.h index e7238e57..1f7af71b 100644 --- a/ginac/basic.h +++ b/ginac/basic.h @@ -96,9 +96,9 @@ public: #else ; #endif // def INLINE_BASIC_CONSTRUCTORS - + const basic & operator=(const basic & other); - + protected: void copy(const basic & other) { diff --git a/ginac/constant.cpp b/ginac/constant.cpp index bc1179c5..dcf28374 100644 --- a/ginac/constant.cpp +++ b/ginac/constant.cpp @@ -59,7 +59,6 @@ void constant::copy(const constant & other) } else { number = 0; } - // fct_assigned=other.fct_assigned; } void constant::destroy(bool call_parent) diff --git a/ginac/constant.h b/ginac/constant.h index cf31814f..f29e5462 100644 --- a/ginac/constant.h +++ b/ginac/constant.h @@ -70,8 +70,7 @@ private: std::string name; evalffunctype ef; numeric * number; - // bool fct_assigned; - unsigned serial; //!< unique serial number for comparision + unsigned serial; //! unique serial number for comparision static unsigned next_serial; }; diff --git a/ginac/ex.h b/ginac/ex.h index 2d36edf9..30b40eb5 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -32,9 +32,6 @@ namespace GiNaC { #endif // ndef NO_NAMESPACE_GINAC class ex; -class expand_options; -class status_flags; - class symbol; class lst; diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 56fcba68..246424f7 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -191,7 +191,7 @@ void expairseq::archive(archive_node &n) const while (i != iend) { n.add_ex("rest", i->rest); n.add_ex("coeff", i->coeff); - i++; + ++i; } n.add_ex("overall_coeff", overall_coeff); } @@ -271,7 +271,7 @@ void expairseq::printtree(std::ostream & os, unsigned indent) const for (epplist::const_iterator it=hashtab[i].begin(); it!=hashtab[i].end(); ++it) { os << *it-seq.begin() << " "; - this_bin_fill++; + ++this_bin_fill; } os << std::endl; cum_fill += this_bin_fill; @@ -914,7 +914,7 @@ void expairseq::make_flat(const exvector & v) cit=v.begin(); while (cit!=citend) { if (cit->bp->tinfo()==tinfo()) { - nexpairseqs++; + ++nexpairseqs; noperands+=ex_to_expairseq(*cit).seq.size(); } ++cit; @@ -965,7 +965,7 @@ void expairseq::make_flat(const epvector & v) cit = v.begin(); while (cit!=citend) { if (cit->rest.bp->tinfo()==tinfo()) { - nexpairseqs++; + ++nexpairseqs; noperands += ex_to_expairseq((*cit).rest).seq.size(); } ++cit; @@ -1090,7 +1090,7 @@ void expairseq::canonicalize(void) do { last_numeric--; } while (is_ex_exactly_of_type((*last_numeric).rest,numeric)); - last_numeric++; + ++last_numeric; sort(last_numeric,seq.end(),expair_is_less()); } } @@ -1197,11 +1197,11 @@ unsigned expairseq::calc_hashindex(const ex & e) const unsigned hash=e.gethash(); unsigned hashindex; if (is_a_numeric_hash(hash)) { - hashindex=hashmask; + hashindex = hashmask; } else { - hashindex=hash & hashmask; + hashindex = hash & hashmask; // last hashtab entry is reserved for numerics - if (hashindex==hashmask) hashindex=0; + if (hashindex==hashmask) hashindex = 0; } GINAC_ASSERT(hashindex>=0); GINAC_ASSERT((hashindexreserve(seq.size()); // copy parts of seq which are known not to have changed diff --git a/ginac/flags.h b/ginac/flags.h index 1b11dceb..11786653 100644 --- a/ginac/flags.h +++ b/ginac/flags.h @@ -34,6 +34,7 @@ public: }; }; +/** Flags to control series expansion. */ class series_options { public: enum { @@ -41,34 +42,37 @@ public: }; }; +/** Switch to control algorithm for determinant computation. */ class determinant_algo { public: enum { - automatic, - gauss, - divfree, - laplace, - bareiss + automatic, //! Let the system choose + gauss, //! Gauss elimiation + divfree, //! Division-free elimination + laplace, //! Laplace (or minor) elimination + bareiss //! Bareiss fraction-free elimination }; }; +/** Switch to control algorithm for linear system solving. */ class solve_algo { public: enum { - automatic, - gauss, - divfree, - bareiss + automatic, //! Let the system choose + gauss, //! Gauss elimiation + divfree, //! Division-free elimination + bareiss //! Bareiss fraction-free elimination }; }; +/** Flags to store information about the stato of an object. */ class status_flags { public: enum { - dynallocated = 0x0001, - evaluated = 0x0002, - expanded = 0x0004, - hash_calculated = 0x0008 + dynallocated = 0x0001, //! Heap-allocated (i.e. created by new) + evaluated = 0x0002, //! .eval() has already done its job + expanded = 0x0004, //! .expand() has already done its job + hash_calculated = 0x0008 //! .calchash() has already done its job }; }; @@ -153,13 +157,15 @@ public: }; }; +/** Strategies how to clean up the function remember cache. + * @see remember_table */ class remember_strategies { public: enum { - delete_never, // let table grow undefinitely, not recommmended, but currently default - delete_lru, // least recently used - delete_lfu, // least frequently used - delete_cyclic // first (oldest) one in list + delete_never, //! Let table grow undefinitely, not recommmended, but currently default + delete_lru, //! Least recently used + delete_lfu, //! Least frequently used + delete_cyclic //! First (oldest) one in list }; }; diff --git a/ginac/inifcns_gamma.cpp b/ginac/inifcns_gamma.cpp index cd21ce4c..d180065d 100644 --- a/ginac/inifcns_gamma.cpp +++ b/ginac/inifcns_gamma.cpp @@ -25,7 +25,6 @@ #include #include "inifcns.h" -#include "ex.h" #include "constant.h" #include "pseries.h" #include "numeric.h" diff --git a/ginac/inifcns_zeta.cpp b/ginac/inifcns_zeta.cpp index 9a3f7a4f..a39d8e6a 100644 --- a/ginac/inifcns_zeta.cpp +++ b/ginac/inifcns_zeta.cpp @@ -24,7 +24,6 @@ #include #include "inifcns.h" -#include "ex.h" #include "constant.h" #include "numeric.h" #include "power.h" diff --git a/ginac/lortensor.cpp b/ginac/lortensor.cpp index 6c326e2b..f9d5f44a 100644 --- a/ginac/lortensor.cpp +++ b/ginac/lortensor.cpp @@ -31,7 +31,6 @@ #include "add.h" #include "mul.h" #include "debugmsg.h" -#include "flags.h" #include "lst.h" #include "lortensor.h" #include "operators.h" diff --git a/ginac/numeric.h b/ginac/numeric.h index 3a972bc9..b4d61faa 100644 --- a/ginac/numeric.h +++ b/ginac/numeric.h @@ -93,8 +93,8 @@ public: void printcsrc(std::ostream & os, unsigned type, unsigned precedence=0) const; bool info(unsigned inf) const; bool has(const ex & other) const; - ex eval(int level=0) const; - ex evalf(int level=0) const; + ex eval(int level = 0) const; + ex evalf(int level = 0) const; ex normal(lst &sym_lst, lst &repl_lst, int level=0) const; ex to_rational(lst &repl_lst) const; numeric integer_content(void) const; diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 2d873a26..409947f4 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -136,10 +136,11 @@ void pseries::print(std::ostream &os, unsigned upper_precedence) const { debugmsg("pseries print", LOGLEVEL_PRINT); if (precedence<=upper_precedence) os << "("; + // objects of type pseries must not have any zero entries, so the + // trivial (zero) pseries needs a special treatment here: + if (seq.size()==0) + os << '0'; for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) { - // omit zero terms - if (i->rest.is_zero()) - continue; // print a sign, if needed if (i!=seq.begin()) os << '+'; @@ -177,9 +178,8 @@ void pseries::printraw(std::ostream &os) const { debugmsg("pseries printraw", LOGLEVEL_PRINT); os << "pseries(" << var << ";" << point << ";"; - for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) { + for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) os << "(" << (*i).rest << "," << (*i).coeff << "),"; - } os << ")"; } @@ -302,6 +302,13 @@ int pseries::ldegree(const symbol &s) const } } +/** Return coefficient of degree n in power series if s is the expansion + * variable. If the expansion point is nonzero, by definition the n=1 + * coefficient in s of a+b*(s-z)+c*(s-z)^2+Order((s-z)^3) is b (assuming + * the expansion took place in the s in the first place). + * If s is not the expansion variable, an attempt is made to convert the + * series to a polynomial and return the corresponding coefficient from + * there. */ ex pseries::coeff(const symbol &s, int n) const { if (var.is_equal(s)) { @@ -333,7 +340,7 @@ ex pseries::coeff(const symbol &s, int n) const return convert_to_poly().coeff(s, n); } - +/** Does nothing. */ ex pseries::collect(const symbol &s) const { return *this; @@ -410,8 +417,11 @@ ex pseries::expand(unsigned options) const { epvector newseq; newseq.reserve(seq.size()); - for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) - newseq.push_back(expair(i->rest.expand(), i->coeff)); + for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) { + ex restexp = i->rest.expand(); + if (!restexp.is_zero()) + newseq.push_back(expair(restexp, i->coeff)); + } return (new pseries(relational(var,point), newseq)) ->setflag(status_flags::dynallocated | status_flags::expanded); } diff --git a/ginac/symbol.h b/ginac/symbol.h index 21b7e411..c604bf56 100644 --- a/ginac/symbol.h +++ b/ginac/symbol.h @@ -46,10 +46,10 @@ class symbol : public basic /** Symbols as keys to expressions. */ class assigned_ex_info { public: - assigned_ex_info(); //!< Default ctor - bool is_assigned; //!< True if there is an expression assigned - ex assigned_expression; //!< The actual expression - unsigned refcount; //!< Yet another refcounter. PLEASE EXPLAIN! + assigned_ex_info(); //! Default ctor + bool is_assigned; //! True if there is an expression assigned + ex assigned_expression; //! The actual expression + unsigned refcount; //! Yet another refcounter. PLEASE EXPLAIN! }; // member functions