X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fexpairseq.cpp;h=2c359b4ae6698642f4a21c271c15179a77fcbd67;hp=5abdbc04b9e111c46f83176e58ad2845f9df76ef;hb=ba0b56c5ac76274c5d748eaa29fbd83cb1d4fb9e;hpb=5ef801553eb39aed7bd2df9dd1aff9d752c3ea9d diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 5abdbc04..2c359b4a 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -3,7 +3,7 @@ * Implementation of sequences of expression pairs. */ /* - * GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2004 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 @@ -31,7 +31,6 @@ #include "power.h" #include "relational.h" #include "wildcard.h" -#include "print.h" #include "archive.h" #include "operators.h" #include "utils.h" @@ -43,7 +42,10 @@ namespace GiNaC { -GINAC_IMPLEMENT_REGISTERED_CLASS(expairseq, basic) +GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(expairseq, basic, + print_func(&expairseq::do_print). + print_func(&expairseq::do_print_tree)) + ////////// // helper classes @@ -123,13 +125,12 @@ expairseq::expairseq(const epvector &v, const ex &oc) GINAC_ASSERT(is_canonical()); } -expairseq::expairseq(epvector *vp, const ex &oc) +expairseq::expairseq(std::auto_ptr vp, const ex &oc) : inherited(TINFO_expairseq), overall_coeff(oc) { - GINAC_ASSERT(vp!=0); + GINAC_ASSERT(vp.get()!=0); GINAC_ASSERT(is_a(oc)); construct_from_epvector(*vp); - delete vp; GINAC_ASSERT(is_canonical()); } @@ -177,88 +178,85 @@ DEFAULT_UNARCHIVE(expairseq) // public -void expairseq::print(const print_context &c, unsigned level) const +void expairseq::do_print(const print_context & c, unsigned level) const { - if (is_a(c)) { - - unsigned delta_indent = static_cast(c).delta_indent; - - c.s << std::string(level, ' ') << class_name() - << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec - << ", nops=" << nops() - << std::endl; - size_t num = seq.size(); - for (size_t i=0; i 0) { - c.s << std::string(level + delta_indent, ' ') - << "bin " << i << " with entries "; - for (epplist::const_iterator it=hashtab[i].begin(); - it!=hashtab[i].end(); ++it) { - c.s << *it-seq.begin() << " "; - ++this_bin_fill; - } - c.s << std::endl; - cum_fill += this_bin_fill; - cum_fill_sq += this_bin_fill*this_bin_fill; + unsigned count[MAXCOUNT+1]; + for (int i=0; i 0) { + c.s << std::string(level + c.delta_indent, ' ') + << "bin " << i << " with entries "; + for (epplist::const_iterator it=hashtab[i].begin(); + it!=hashtab[i].end(); ++it) { + c.s << *it-seq.begin() << " "; + ++this_bin_fill; } - if (this_bin_fill0) - fact *= k; - double prob = std::pow(lambda,k)/fact * std::exp(-lambda); - cum_prob += prob; - c.s << std::string(level + delta_indent, ' ') << "bins with " << k << " entries: " - << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: " - << int(prob*1000)/10.0 << ")" << std::endl; + c.s << std::endl; + cum_fill += this_bin_fill; + cum_fill_sq += this_bin_fill*this_bin_fill; } - c.s << std::string(level + delta_indent, ' ') << "bins with more entries: " - << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: " - << int((1-cum_prob)*1000)/10.0 << ")" << std::endl; - - c.s << std::string(level + delta_indent, ' ') << "variance: " - << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill) - << std::endl; - c.s << std::string(level + delta_indent, ' ') << "average fill: " - << (1.0*cum_fill)/hashtabsize - << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl; -#endif // EXPAIRSEQ_USE_HASHTAB - - } else { - c.s << "[["; - printseq(c, ',', precedence(), level); - c.s << "]]"; + if (this_bin_fill0) + fact *= k; + double prob = std::pow(lambda,k)/fact * std::exp(-lambda); + cum_prob += prob; + c.s << std::string(level + c.delta_indent, ' ') << "bins with " << k << " entries: " + << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: " + << int(prob*1000)/10.0 << ")" << std::endl; } + c.s << std::string(level + c.delta_indent, ' ') << "bins with more entries: " + << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: " + << int((1-cum_prob)*1000)/10.0 << ")" << std::endl; + + c.s << std::string(level + c.delta_indent, ' ') << "variance: " + << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill) + << std::endl; + c.s << std::string(level + c.delta_indent, ' ') << "average fill: " + << (1.0*cum_fill)/hashtabsize + << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl; +#endif // EXPAIRSEQ_USE_HASHTAB } bool expairseq::info(unsigned inf) const @@ -284,7 +282,7 @@ ex expairseq::op(size_t i) const ex expairseq::map(map_function &f) const { - epvector *v = new epvector; + std::auto_ptr v(new epvector); v->reserve(seq.size()); epvector::const_iterator cit = seq.begin(), last = seq.end(); @@ -305,11 +303,47 @@ ex expairseq::eval(int level) const if ((level==1) && (flags &status_flags::evaluated)) return *this; - epvector *vp = evalchildren(level); - if (vp==0) + std::auto_ptr vp = evalchildren(level); + if (vp.get() == 0) return this->hold(); - return (new expairseq(vp,overall_coeff))->setflag(status_flags::dynallocated | status_flags::evaluated); + return (new expairseq(vp, overall_coeff))->setflag(status_flags::dynallocated | status_flags::evaluated); +} + +epvector* conjugateepvector(const epvector&epv) +{ + epvector *newepv = 0; + for (epvector::const_iterator i=epv.begin(); i!=epv.end(); ++i) { + if(newepv) { + newepv->push_back(i->conjugate()); + continue; + } + expair x = i->conjugate(); + if (x.is_equal(*i)) { + continue; + } + newepv = new epvector; + newepv->reserve(epv.size()); + for (epvector::const_iterator j=epv.begin(); j!=i; ++j) { + newepv->push_back(*j); + } + newepv->push_back(x); + } + return newepv; +} + +ex expairseq::conjugate() const +{ + epvector* newepv = conjugateepvector(seq); + ex x = overall_coeff.conjugate(); + if (!newepv && are_ex_trivially_equal(x, overall_coeff)) { + return *this; + } + ex result = thisexpairseq(newepv ? *newepv : seq, x); + if (newepv) { + delete newepv; + } + return result; } bool expairseq::match(const ex & pattern, lst & repl_lst) const @@ -364,7 +398,7 @@ found: ; // it has already been matched before, in which case the matches // must be equal) size_t num = ops.size(); - epvector *vp = new epvector(); + std::auto_ptr vp(new epvector); vp->reserve(num); for (size_t i=0; ipush_back(split_ex_to_pair(ops[i])); @@ -388,10 +422,10 @@ found: ; ex expairseq::subs(const exmap & m, unsigned options) const { - epvector *vp = subschildren(m, options); - if (vp) + std::auto_ptr vp = subschildren(m, options); + if (vp.get()) return ex_to(thisexpairseq(vp, overall_coeff)); - else if ((options & subs_options::subs_algebraic) && is_exactly_a(*this)) + else if ((options & subs_options::algebraic) && is_exactly_a(*this)) return static_cast(this)->algebraic_subs_mul(m, options); else return subs_one_level(m, options); @@ -562,12 +596,13 @@ unsigned expairseq::calchash() const ex expairseq::expand(unsigned options) const { - epvector *vp = expandchildren(options); - if (vp == NULL) { + std::auto_ptr vp = expandchildren(options); + if (vp.get()) + return thisexpairseq(vp, overall_coeff); + else { // The terms have not changed, so it is safe to declare this expanded return (options == 0) ? setflag(status_flags::expanded) : *this; - } else - return thisexpairseq(vp, overall_coeff); + } } ////////// @@ -586,12 +621,12 @@ ex expairseq::expand(unsigned options) const * definition. */ ex expairseq::thisexpairseq(const epvector &v, const ex &oc) const { - return expairseq(v,oc); + return expairseq(v, oc); } -ex expairseq::thisexpairseq(epvector *vp, const ex &oc) const +ex expairseq::thisexpairseq(std::auto_ptr vp, const ex &oc) const { - return expairseq(vp,oc); + return expairseq(vp, oc); } void expairseq::printpair(const print_context & c, const expair & p, unsigned upper_precedence) const @@ -1451,7 +1486,7 @@ bool expairseq::is_canonical() const * @see expairseq::expand() * @return pointer to epvector containing expanded pairs or zero pointer, * if no members were changed. */ -epvector * expairseq::expandchildren(unsigned options) const +std::auto_ptr expairseq::expandchildren(unsigned options) const { const epvector::const_iterator last = seq.end(); epvector::const_iterator cit = seq.begin(); @@ -1460,7 +1495,7 @@ epvector * expairseq::expandchildren(unsigned options) const if (!are_ex_trivially_equal(cit->rest,expanded_ex)) { // something changed, copy seq, eval and return it - epvector *s = new epvector; + std::auto_ptr s(new epvector); s->reserve(seq.size()); // copy parts of seq which are known not to have changed @@ -1469,10 +1504,12 @@ epvector * expairseq::expandchildren(unsigned options) const s->push_back(*cit2); ++cit2; } + // copy first changed element s->push_back(combine_ex_with_coeff_to_pair(expanded_ex, cit2->coeff)); ++cit2; + // copy rest while (cit2!=last) { s->push_back(combine_ex_with_coeff_to_pair(cit2->rest.expand(options), @@ -1484,7 +1521,7 @@ epvector * expairseq::expandchildren(unsigned options) const ++cit; } - return 0; // signalling nothing has changed + return std::auto_ptr(0); // signalling nothing has changed } @@ -1493,14 +1530,14 @@ epvector * expairseq::expandchildren(unsigned options) const * @see expairseq::eval() * @return pointer to epvector containing evaluated pairs or zero pointer, * if no members were changed. */ -epvector * expairseq::evalchildren(int level) const +std::auto_ptr expairseq::evalchildren(int level) const { // returns a NULL pointer if nothing had to be evaluated // returns a pointer to a newly created epvector otherwise // (which has to be deleted somewhere else) if (level==1) - return 0; + return std::auto_ptr(0); if (level == -max_recursion_level) throw(std::runtime_error("max recursion level reached")); @@ -1513,7 +1550,7 @@ epvector * expairseq::evalchildren(int level) const if (!are_ex_trivially_equal(cit->rest,evaled_ex)) { // something changed, copy seq, eval and return it - epvector *s = new epvector; + std::auto_ptr s(new epvector); s->reserve(seq.size()); // copy parts of seq which are known not to have changed @@ -1522,10 +1559,12 @@ epvector * expairseq::evalchildren(int level) const s->push_back(*cit2); ++cit2; } + // copy first changed element s->push_back(combine_ex_with_coeff_to_pair(evaled_ex, cit2->coeff)); ++cit2; + // copy rest while (cit2!=last) { s->push_back(combine_ex_with_coeff_to_pair(cit2->rest.eval(level), @@ -1537,7 +1576,7 @@ epvector * expairseq::evalchildren(int level) const ++cit; } - return 0; // signalling nothing has changed + return std::auto_ptr(0); // signalling nothing has changed } @@ -1546,7 +1585,7 @@ epvector * expairseq::evalchildren(int level) const * @see expairseq::subs() * @return pointer to epvector containing pairs after application of subs, * or NULL pointer if no members were changed. */ -epvector * expairseq::subschildren(const exmap & m, unsigned options) const +std::auto_ptr expairseq::subschildren(const exmap & m, unsigned options) const { // When any of the objects to be substituted is a product or power // we have to recombine the pairs because the numeric coefficients may @@ -1575,7 +1614,7 @@ epvector * expairseq::subschildren(const exmap & m, unsigned options) const if (!are_ex_trivially_equal(orig_ex, subsed_ex)) { // Something changed, copy seq, subs and return it - epvector *s = new epvector; + std::auto_ptr s(new epvector); s->reserve(seq.size()); // Copy parts of seq which are known not to have changed @@ -1606,7 +1645,7 @@ epvector * expairseq::subschildren(const exmap & m, unsigned options) const if (!are_ex_trivially_equal(cit->rest, subsed_ex)) { // Something changed, copy seq, subs and return it - epvector *s = new epvector; + std::auto_ptr s(new epvector); s->reserve(seq.size()); // Copy parts of seq which are known not to have changed @@ -1630,7 +1669,7 @@ epvector * expairseq::subschildren(const exmap & m, unsigned options) const } // Nothing has changed - return NULL; + return std::auto_ptr(0); } //////////