X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fexpairseq.cpp;h=1fa592e7ec158f411887f8eb56dfb4043bc53362;hp=7f8664eed926d459aa1b5a8454c89c91b711fa97;hb=955cb185a85535ab328ffedbfccdc508ce80fa91;hpb=a8507b8af1c08d9b27d98d57f95c7ca1a8671e27 diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 7f8664ee..1fa592e7 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -1,5 +1,8 @@ /** @file expairseq.cpp * + * Implementation of sequences of expression pairs. */ + +/* * GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify @@ -20,11 +23,19 @@ #include #include #include +#include + +#include "expairseq.h" +#include "lst.h" +#include "debugmsg.h" +#include "utils.h" -#include "ginac.h" +#ifndef NO_GINAC_NAMESPACE +namespace GiNaC { +#endif // ndef NO_GINAC_NAMESPACE #ifdef EXPAIRSEQ_USE_HASHTAB -#error "!!!!!!!!TODO: expair_needs_further_processing not yet implemented for hashtabs, sorry. A.F." +#error "FIXME: expair_needs_further_processing not yet implemented for hashtabs, sorry. A.F." #endif // def EXPAIRSEQ_USE_HASHTAB ////////// @@ -93,23 +104,23 @@ void expairseq::copy(expairseq const & other) // other constructors ////////// -expairseq::expairseq(ex const & lh, ex const & rh) : basic(TINFO_EXPAIRSEQ) +expairseq::expairseq(ex const & lh, ex const & rh) : basic(TINFO_expairseq) { debugmsg("expairseq constructor from ex,ex",LOGLEVEL_CONSTRUCT); construct_from_2_ex(lh,rh); - ASSERT(is_canonical()); + GINAC_ASSERT(is_canonical()); } -expairseq::expairseq(exvector const & v) : basic(TINFO_EXPAIRSEQ) +expairseq::expairseq(exvector const & v) : basic(TINFO_expairseq) { debugmsg("expairseq constructor from exvector",LOGLEVEL_CONSTRUCT); construct_from_exvector(v); - ASSERT(is_canonical()); + GINAC_ASSERT(is_canonical()); } /* expairseq::expairseq(epvector const & v, bool do_not_canonicalize) : - basic(TINFO_EXPAIRSEQ) + basic(TINFO_expairseq) { debugmsg("expairseq constructor from epvector",LOGLEVEL_CONSTRUCT); if (do_not_canonicalize) { @@ -120,26 +131,26 @@ expairseq::expairseq(epvector const & v, bool do_not_canonicalize) : } else { construct_from_epvector(v); } - ASSERT(is_canonical()); + GINAC_ASSERT(is_canonical()); } */ expairseq::expairseq(epvector const & v, ex const & oc) : - basic(TINFO_EXPAIRSEQ), overall_coeff(oc) + basic(TINFO_expairseq), overall_coeff(oc) { debugmsg("expairseq constructor from epvector,ex",LOGLEVEL_CONSTRUCT); construct_from_epvector(v); - ASSERT(is_canonical()); + GINAC_ASSERT(is_canonical()); } expairseq::expairseq(epvector * vp, ex const & oc) : - basic(TINFO_EXPAIRSEQ), overall_coeff(oc) + basic(TINFO_expairseq), overall_coeff(oc) { debugmsg("expairseq constructor from epvector *,ex",LOGLEVEL_CONSTRUCT); - ASSERT(vp!=0); + GINAC_ASSERT(vp!=0); construct_from_epvector(*vp); delete vp; - ASSERT(is_canonical()); + GINAC_ASSERT(is_canonical()); } ////////// @@ -154,6 +165,104 @@ basic * expairseq::duplicate() const return new expairseq(*this); } +void expairseq::print(ostream & os, unsigned upper_precedence) const +{ + debugmsg("expairseq print",LOGLEVEL_PRINT); + os << "[["; + printseq(os,',',precedence,upper_precedence); + os << "]]"; +} + +void expairseq::printraw(ostream & os) const +{ + debugmsg("expairseq printraw",LOGLEVEL_PRINT); + + os << "expairseq("; + for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) { + os << "("; + (*cit).rest.printraw(os); + os << ","; + (*cit).coeff.printraw(os); + os << "),"; + } + os << ")"; +} + +void expairseq::printtree(ostream & os, unsigned indent) const +{ + debugmsg("expairseq printtree",LOGLEVEL_PRINT); + + os << string(indent,' ') << "type=" << typeid(*this).name() + << ", hash=" << hashvalue << " (0x" << hex << hashvalue << dec << ")" + << ", flags=" << flags + << ", nops=" << nops() << endl; + for (unsigned i=0; i0) { + os << string(indent+delta_indent,' ') + << "bin " << i << " with entries "; + for (epplist::const_iterator it=hashtab[i].begin(); + it!=hashtab[i].end(); ++it) { + os << *it-seq.begin() << " "; + this_bin_fill++; + } + os << endl; + cum_fill += this_bin_fill; + cum_fill_sq += this_bin_fill*this_bin_fill; + } + if (this_bin_fill0) fact *= k; + double prob=pow(lambda,k)/fact*exp(-lambda); + cum_prob += prob; + os << string(indent+delta_indent,' ') << "bins with " << k << " entries: " + << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: " + << int(prob*1000)/10.0 << ")" << endl; + } + os << string(indent+delta_indent,' ') << "bins with more entries: " + << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: " + << int((1-cum_prob)*1000)/10.0 << ")" << endl; + + os << string(indent+delta_indent,' ') << "variance: " + << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill) + << endl; + os << string(indent+delta_indent,' ') << "average fill: " + << (1.0*cum_fill)/hashtabsize + << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << endl; +#endif // def EXPAIRSEQ_USE_HASHTAB +} + bool expairseq::info(unsigned inf) const { return basic::info(inf); @@ -172,7 +281,7 @@ ex expairseq::op(int const i) const if (unsigned(i)(const_cast(other)); int cmpval; @@ -238,7 +347,7 @@ int expairseq::compare_same_type(basic const & other) const //if (seq.size()==0) return 0; // empty expairseq's are equal #ifdef EXPAIRSEQ_USE_HASHTAB - ASSERT(hashtabsize==o.hashtabsize); + GINAC_ASSERT(hashtabsize==o.hashtabsize); if (hashtabsize==0) { #endif // def EXPAIRSEQ_USE_HASHTAB epvector::const_iterator cit1=seq.begin(); @@ -251,8 +360,8 @@ int expairseq::compare_same_type(basic const & other) const if (cmpval!=0) return cmpval; } - ASSERT(cit1==last1); - ASSERT(cit2==last2); + GINAC_ASSERT(cit1==last1); + GINAC_ASSERT(cit2==last2); return 0; #ifdef EXPAIRSEQ_USE_HASHTAB @@ -306,7 +415,7 @@ bool expairseq::is_equal_same_type(basic const & other) const other.printtree(cout,0); } - ASSERT(hashtabsize==o.hashtabsize); + GINAC_ASSERT(hashtabsize==o.hashtabsize); if (hashtabsize==0) { #endif // def EXPAIRSEQ_USE_HASHTAB @@ -401,15 +510,42 @@ ex expairseq::thisexpairseq(epvector * vp, ex const & oc) const return expairseq(vp,oc); } +void expairseq::printpair(ostream & os, expair const & p, unsigned upper_precedence) const +{ + os << "[["; + p.rest.bp->print(os,precedence); + os << ","; + p.coeff.bp->print(os,precedence); + os << "]]"; +} + +void expairseq::printseq(ostream & os, char delim, unsigned this_precedence, + unsigned upper_precedence) const +{ + if (this_precedence<=upper_precedence) os << "("; + epvector::const_iterator it,it_last; + it_last=seq.end(); + --it_last; + for (it=seq.begin(); it!=it_last; ++it) { + printpair(os,*it,this_precedence); + os << delim; + } + printpair(os,*it,this_precedence); + if (!overall_coeff.is_equal(default_overall_coeff())) { + os << delim << overall_coeff; + } + if (this_precedence<=upper_precedence) os << ")"; +} + expair expairseq::split_ex_to_pair(ex const & e) const { - return expair(e,exONE()); + return expair(e,_ex1()); } expair expairseq::combine_ex_with_coeff_to_pair(ex const & e, ex const & c) const { - ASSERT(is_ex_exactly_of_type(c,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); return expair(e,c); } @@ -417,8 +553,8 @@ expair expairseq::combine_ex_with_coeff_to_pair(ex const & e, expair expairseq::combine_pair_with_coeff_to_pair(expair const & p, ex const & c) const { - ASSERT(is_ex_exactly_of_type(p.coeff,numeric)); - ASSERT(is_ex_exactly_of_type(c,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c))); } @@ -435,21 +571,21 @@ bool expairseq::expair_needs_further_processing(epp it) ex expairseq::default_overall_coeff(void) const { - return exZERO(); + return _ex0(); } void expairseq::combine_overall_coeff(ex const & c) { - ASSERT(is_ex_exactly_of_type(overall_coeff,numeric)); - ASSERT(is_ex_exactly_of_type(c,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); overall_coeff = ex_to_numeric(overall_coeff).add_dyn(ex_to_numeric(c)); } void expairseq::combine_overall_coeff(ex const & c1, ex const & c2) { - ASSERT(is_ex_exactly_of_type(overall_coeff,numeric)); - ASSERT(is_ex_exactly_of_type(c1,numeric)); - ASSERT(is_ex_exactly_of_type(c2,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric)); + GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric)); overall_coeff = ex_to_numeric(overall_coeff). add_dyn(ex_to_numeric(c1).mul(ex_to_numeric(c2))); } @@ -472,8 +608,8 @@ void expairseq::construct_from_2_ex_via_exvector(ex const & lh, ex const & rh) v.push_back(rh); construct_from_exvector(v); #ifdef EXPAIRSEQ_USE_HASHTAB - ASSERT((hashtabsize==0)||(hashtabsize>=minhashtabsize)); - ASSERT(hashtabsize==calc_hashtabsize(seq.size())); + GINAC_ASSERT((hashtabsize==0)||(hashtabsize>=minhashtabsize)); + GINAC_ASSERT(hashtabsize==calc_hashtabsize(seq.size())); #endif // def EXPAIRSEQ_USE_HASHTAB } @@ -1000,9 +1136,9 @@ unsigned expairseq::calc_hashtabsize(unsigned sz) const // size=nearest_power_of_2*hashtabfactor; size=nearest_power_of_2/hashtabfactor; if (size=0); - ASSERT((hashindex=0); + GINAC_ASSERT((hashindexreserve(seq.size()); @@ -1494,17 +1630,18 @@ epvector * expairseq::subschildren(lst const & ls, lst const & lr) const // returns a NULL pointer if nothing had to be substituted // returns a pointer to a newly created epvector otherwise // (which has to be deleted somewhere else) - + GINAC_ASSERT(ls.nops()==lr.nops()); + epvector::const_iterator last=seq.end(); epvector::const_iterator cit=seq.begin(); while (cit!=last) { ex const & subsed_ex=(*cit).rest.subs(ls,lr); if (!are_ex_trivially_equal((*cit).rest,subsed_ex)) { - + // something changed, copy seq, subs and return it epvector *s=new epvector; s->reserve(seq.size()); - + // copy parts of seq which are known not to have changed epvector::const_iterator cit2=seq.begin(); while (cit2!=cit) { @@ -1520,7 +1657,7 @@ epvector * expairseq::subschildren(lst const & ls, lst const & lr) const s->push_back(combine_ex_with_coeff_to_pair((*cit2).rest.subs(ls,lr), (*cit2).coeff)); ++cit2; - } + } return s; } ++cit; @@ -1529,75 +1666,6 @@ epvector * expairseq::subschildren(lst const & ls, lst const & lr) const return 0; // nothing has changed } -/* -epvector expairseq::subschildren(lst const & ls, lst const & lr) const -{ - epvector s; - s.reserve(seq.size()); - - for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) { - s.push_back(split_ex_to_pair((*it).rest.subs(ls,lr),(*it).coeff)); - } - return s; -} -*/ - -/* -void expairseq::sort(epviter first, epviter last, expair_is_less comp) -{ - if (first != last) { - introsort_loop(first, last, lg(last - first) * 2, comp); - __final_insertion_sort(first, last, comp); - } -} - -ptrdiff_t expairseq::lg(ptrdiff_t n) -{ - ptrdiff_t k; - for (k = 0; n > 1; n >>= 1) ++k; - return k; -} - -void expairseq::introsort_loop(epviter first, epviter last, - ptrdiff_t depth_limit, expair_is_less comp) -{ - while (last - first > stl_threshold) { - if (depth_limit == 0) { - partial_sort(first, last, last, comp); - return; - } - --depth_limit; - epviter cut = unguarded_partition(first, last, - expair(__median(*first, *(first + (last - first)/2), - *(last - 1), comp)), comp); - introsort_loop(cut, last, depth_limit, comp); - last = cut; - } -} - -epviter expairseq::unguarded_partition(epviter first, epviter last, - expair pivot, expair_is_less comp) -{ - while (1) { - while (comp(*first, pivot)) ++first; - --last; - while (comp(pivot, *last)) --last; - if (!(first < last)) return first; - iter_swap(first, last); - ++first; - } -} - -void expairseq::partial_sort(epviter first, epviter middle, epviter last, - expair_is_less comp) { - make_heap(first, middle, comp); - for (RandomAccessIterator i = middle; i < last; ++i) - if (comp(*i, *first)) - __pop_heap(first, middle, i, T(*i), comp, distance_type(first)); - sort_heap(first, middle, comp); -} -*/ - ////////// // static member variables ////////// @@ -1619,3 +1687,6 @@ unsigned expairseq::hashtabfactor=1; const expairseq some_expairseq; type_info const & typeid_expairseq=typeid(some_expairseq); +#ifndef NO_GINAC_NAMESPACE +} // namespace GiNaC +#endif // ndef NO_GINAC_NAMESPACE