]> www.ginac.de Git - ginac.git/blobdiff - ginac/expairseq.cpp
- added ex::to_rational() to convert general expression to rational expression
[ginac.git] / ginac / expairseq.cpp
index 96811383a99ed76420b040f2aecbb88e00a8725d..d4e13188c21c5cff02bd8b1ae2d66e370d49e165 100644 (file)
@@ -1,15 +1,46 @@
-/** @file expairseq.cpp */
+/** @file expairseq.cpp
+ *
+ *  Implementation of sequences of expression pairs. */
+
+/*
+ *  GiNaC Copyright (C) 1999-2000 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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
 
 #include <algorithm>
 #include <string>
 #include <stdexcept>
+#include <cmath>
+
+#include "expairseq.h"
+#include "lst.h"
+#include "archive.h"
+#include "debugmsg.h"
+#include "utils.h"
 
-#include "ginac.h"
+#ifndef NO_NAMESPACE_GINAC
+namespace GiNaC {
+#endif // ndef NO_NAMESPACE_GINAC
 
 #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
 
+GINAC_IMPLEMENT_REGISTERED_CLASS(expairseq, basic)
+
 //////////
 // helper classes
 //////////
@@ -17,7 +48,7 @@
 class epp_is_less
 {
 public:
-    bool operator()(epp const & lh, epp const & rh) const
+    bool operator()(const epp & lh, const epp & rh) const
     {
         return (*lh).is_less(*rh);
     }
@@ -29,13 +60,13 @@ public:
 
 // public
 
-expairseq::expairseq(expairseq const & other)
+expairseq::expairseq(const expairseq & other)
 {
     debugmsg("expairseq copy constructor",LOGLEVEL_CONSTRUCT);
     copy(other);
 }
 
-expairseq const & expairseq::operator=(expairseq const & other)
+const expairseq & expairseq::operator=(const expairseq & other)
 {
     debugmsg("expairseq operator=",LOGLEVEL_ASSIGNMENT);
     if (this != &other) {
@@ -47,9 +78,9 @@ expairseq const & expairseq::operator=(expairseq const & other)
 
 // protected
 
-void expairseq::copy(expairseq const & other)
+void expairseq::copy(const expairseq & other)
 {
-    basic::copy(other);
+    inherited::copy(other);
     seq=other.seq;
     overall_coeff=other.overall_coeff;
 #ifdef EXPAIRSEQ_USE_HASHTAB
@@ -76,23 +107,23 @@ void expairseq::copy(expairseq const & other)
 // other constructors
 //////////
 
-expairseq::expairseq(ex const & lh, ex const & rh) : basic(TINFO_EXPAIRSEQ)
+expairseq::expairseq(const ex & lh, const ex & rh) : inherited(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(const exvector & v) : inherited(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)
+expairseq::expairseq(const epvector & v, bool do_not_canonicalize) :
+    inherited(TINFO_expairseq)
 {
     debugmsg("expairseq constructor from epvector",LOGLEVEL_CONSTRUCT);
     if (do_not_canonicalize) {
@@ -103,26 +134,67 @@ 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)
+expairseq::expairseq(const epvector & v, const ex & oc) :
+    inherited(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)
+expairseq::expairseq(epvector * vp, const ex & oc) :
+    inherited(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());
+}
+
+//////////
+// archiving
+//////////
+
+/** Construct object from archive_node. */
+expairseq::expairseq(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
+#ifdef EXPAIRSEQ_USE_HASHTAB
+    , hashtabsize(0)
+#endif
+{
+    debugmsg("expairseq constructor from archive_node", LOGLEVEL_CONSTRUCT);
+    for (unsigned int i=0; true; i++) {
+        ex rest;
+        ex coeff;
+        if (n.find_ex("rest", rest, sym_lst, i) && n.find_ex("coeff", coeff, sym_lst, i))
+            seq.push_back(expair(rest, coeff));
+        else
+            break;
+    }
+    n.find_ex("overall_coeff", overall_coeff, sym_lst);
+}
+
+/** Unarchive the object. */
+ex expairseq::unarchive(const archive_node &n, const lst &sym_lst)
+{
+    return (new expairseq(n, sym_lst))->setflag(status_flags::dynallocated);
+}
+
+/** Archive the object. */
+void expairseq::archive(archive_node &n) const
+{
+    inherited::archive(n);
+    epvector::const_iterator i = seq.begin(), iend = seq.end();
+    while (i != iend) {
+        n.add_ex("rest", i->rest);
+        n.add_ex("coeff", i->coeff);
+        i++;
+    }
+    n.add_ex("overall_coeff", overall_coeff);
 }
 
 //////////
@@ -137,12 +209,110 @@ 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; i<seq.size(); ++i) {
+        seq[i].rest.printtree(os,indent+delta_indent);
+        seq[i].coeff.printtree(os,indent+delta_indent);
+        if (i!=seq.size()-1) {
+            os << string(indent+delta_indent,' ') << "-----" << endl;
+        }
+    }
+    if (!overall_coeff.is_equal(default_overall_coeff())) {
+        os << string(indent+delta_indent,' ') << "-----" << endl;
+        os << string(indent+delta_indent,' ') << "overall_coeff" << endl;
+        overall_coeff.printtree(os,indent+delta_indent);
+    }
+    os << string(indent+delta_indent,' ') << "=====" << endl;
+#ifdef EXPAIRSEQ_USE_HASHTAB
+    os << string(indent+delta_indent,' ')
+       << "hashtab size " << hashtabsize << endl;
+    if (hashtabsize==0) return;
+#define MAXCOUNT 5
+    unsigned count[MAXCOUNT+1];
+    for (int i=0; i<MAXCOUNT+1; ++i) count[i]=0;
+    unsigned this_bin_fill;
+    unsigned cum_fill_sq = 0;
+    unsigned cum_fill = 0;
+    for (unsigned i=0; i<hashtabsize; ++i) {
+        this_bin_fill=0;
+        if (hashtab[i].size()>0) {
+            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_fill<MAXCOUNT) {
+            ++count[this_bin_fill];
+        } else {
+            ++count[MAXCOUNT];
+        }
+    }
+    unsigned fact = 1;
+    double cum_prob = 0;
+    double lambda = (1.0*seq.size())/hashtabsize;
+    for (int k=0; k<MAXCOUNT; ++k) {
+        if (k>0) 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);
+    return inherited::info(inf);
 }
 
-int expairseq::nops() const
+unsigned expairseq::nops() const
 {
     if (overall_coeff.is_equal(default_overall_coeff())) {
         return seq.size();
@@ -150,16 +320,16 @@ int expairseq::nops() const
     return seq.size()+1;
 }
 
-ex expairseq::op(int const i) const
+ex expairseq::op(int i) const
 {
     if (unsigned(i)<seq.size()) {
         return recombine_pair_to_ex(seq[i]);
     }
-    ASSERT(!overall_coeff.is_equal(default_overall_coeff()));
+    GINAC_ASSERT(!overall_coeff.is_equal(default_overall_coeff()));
     return overall_coeff;
 }
 
-ex & expairseq::let_op(int const i)
+ex & expairseq::let_op(int i)
 {
     throw(std::logic_error("let_op not defined for expairseq and derived classes (add,mul,...)"));
 }
@@ -182,16 +352,27 @@ ex expairseq::eval(int level) const
 
 ex expairseq::evalf(int level) const
 {
-    return thisexpairseq(evalfchildren(level),overall_coeff);
+    return thisexpairseq(evalfchildren(level),overall_coeff.evalf(level-1));
 }
 
 ex expairseq::normal(lst &sym_lst, lst &repl_lst, int level) const
 {
-    ex n=thisexpairseq(normalchildren(level),overall_coeff);
+    ex n = thisexpairseq(normalchildren(level),overall_coeff);
     return n.bp->basic::normal(sym_lst,repl_lst,level);
 }
 
-ex expairseq::subs(lst const & ls, lst const & lr) const
+ex expairseq::to_rational(lst &repl_lst) const
+{
+    epvector s;
+    s.reserve(seq.size());
+    for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
+        s.push_back(combine_ex_with_coeff_to_pair((*it).rest.to_rational(repl_lst),
+                                                  (*it).coeff));
+    }
+    return thisexpairseq(s, overall_coeff);
+}
+
+ex expairseq::subs(const lst & ls, const lst & lr) const
 {
     epvector * vp=subschildren(ls,lr);
     if (vp==0) {
@@ -202,10 +383,18 @@ ex expairseq::subs(lst const & ls, lst const & lr) const
 
 // protected
 
-int expairseq::compare_same_type(basic const & other) const
+/** Implementation of ex::diff() for an expairseq. It differentiates all elements of the
+ *  sequence.
+ *  @see ex::diff */
+ex expairseq::derivative(const symbol & s) const
 {
-    ASSERT(is_of_type(other, expairseq));
-    expairseq const & o=static_cast<expairseq const &>(const_cast<basic &>(other));
+    return thisexpairseq(diffchildren(s),overall_coeff);
+}
+
+int expairseq::compare_same_type(const basic & other) const
+{
+    GINAC_ASSERT(is_of_type(other, expairseq));
+    const expairseq & o = static_cast<const expairseq &>(const_cast<basic &>(other));
 
     int cmpval;
     
@@ -215,27 +404,27 @@ int expairseq::compare_same_type(basic const & other) const
     }
 
     // compare overall_coeff
-    cmpval=overall_coeff.compare(o.overall_coeff);
+    cmpval = overall_coeff.compare(o.overall_coeff);
     if (cmpval!=0) return cmpval;
 
     //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();
-        epvector::const_iterator cit2=o.seq.begin();
-        epvector::const_iterator last1=seq.end();
-        epvector::const_iterator last2=o.seq.end();
+        epvector::const_iterator cit1 = seq.begin();
+        epvector::const_iterator cit2 = o.seq.begin();
+        epvector::const_iterator last1 = seq.end();
+        epvector::const_iterator last2 = o.seq.end();
         
         for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
-            cmpval=(*cit1).compare(*cit2);
+            cmpval = (*cit1).compare(*cit2);
             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
@@ -253,8 +442,8 @@ int expairseq::compare_same_type(basic const & other) const
     for (unsigned i=0; i<hashtabsize; ++i) {
         unsigned sz=hashtab[i].size();
         if (sz>0) {
-            epplist const & eppl1=hashtab[i];
-            epplist const & eppl2=o.hashtab[i];
+            const epplist & eppl1=hashtab[i];
+            const epplist & eppl2=o.hashtab[i];
             epplist::const_iterator it1=eppl1.begin();
             epplist::const_iterator it2=eppl2.begin();
             while (it1!=eppl1.end()) {
@@ -270,9 +459,9 @@ int expairseq::compare_same_type(basic const & other) const
 #endif // def EXPAIRSEQ_USE_HASHTAB
 }
 
-bool expairseq::is_equal_same_type(basic const & other) const
+bool expairseq::is_equal_same_type(const basic & other) const
 {
-    expairseq const & o=dynamic_cast<expairseq const &>(const_cast<basic &>(other));
+    const expairseq & o=dynamic_cast<const expairseq &>(const_cast<basic &>(other));
 
     // compare number of elements
     if (seq.size() != o.seq.size()) return false;
@@ -289,7 +478,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
@@ -315,8 +504,8 @@ bool expairseq::is_equal_same_type(basic const & other) const
     for (unsigned i=0; i<hashtabsize; ++i) {
         unsigned sz=hashtab[i].size();
         if (sz>0) {
-            epplist const & eppl1=hashtab[i];
-            epplist const & eppl2=o.hashtab[i];
+            const epplist & eppl1=hashtab[i];
+            const epplist & eppl2=o.hashtab[i];
             epplist::const_iterator it1=eppl1.begin();
             epplist::const_iterator it2=eppl2.begin();
             while (it1!=eppl1.end()) {
@@ -361,7 +550,7 @@ unsigned expairseq::calchash(void) const
 
 ex expairseq::expand(unsigned options) const
 {
-    epvector * vp=expandchildren(options);
+    epvector * vp = expandchildren(options);
     if (vp==0) {
         return *this;
     }
@@ -374,39 +563,66 @@ ex expairseq::expand(unsigned options) const
 
 // protected
 
-ex expairseq::thisexpairseq(epvector const & v,ex const & oc) const
+ex expairseq::thisexpairseq(const epvector & v,const ex & oc) const
 {
     return expairseq(v,oc);
 }
 
-ex expairseq::thisexpairseq(epvector * vp, ex const & oc) const
+ex expairseq::thisexpairseq(epvector * vp, const ex & oc) const
 {
     return expairseq(vp,oc);
 }
 
-expair expairseq::split_ex_to_pair(ex const & e) const
+void expairseq::printpair(ostream & os, const expair & p, unsigned upper_precedence) const
 {
-    return expair(e,exONE());
+    os << "[[";
+    p.rest.bp->print(os,precedence);
+    os << ",";
+    p.coeff.bp->print(os,precedence);
+    os << "]]";
 }
 
-expair expairseq::combine_ex_with_coeff_to_pair(ex const & e,
-                                                ex const & c) const
+void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
+                         unsigned upper_precedence) const
 {
-    ASSERT(is_ex_exactly_of_type(c,numeric));
+    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(const ex & e) const
+{
+    return expair(e,_ex1());
+}
+
+expair expairseq::combine_ex_with_coeff_to_pair(const ex & e,
+                                                const ex & c) const
+{
+    GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
 
     return expair(e,c);
 }
 
-expair expairseq::combine_pair_with_coeff_to_pair(expair const & p,
-                                                  ex const & c) const
+expair expairseq::combine_pair_with_coeff_to_pair(const expair & p,
+                                                  const ex & 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)));
 }
 
-ex expairseq::recombine_pair_to_ex(expair const & p) const
+ex expairseq::recombine_pair_to_ex(const expair & p) const
 {
     return lst(p.rest,p.coeff);
 }
@@ -418,26 +634,26 @@ 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)
+void expairseq::combine_overall_coeff(const ex & 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)
+void expairseq::combine_overall_coeff(const ex & c1, const ex & 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)));
 }
 
-bool expairseq::can_make_flat(expair const & p) const
+bool expairseq::can_make_flat(const expair & p) const
 {
     return true;
 }
@@ -447,7 +663,7 @@ bool expairseq::can_make_flat(expair const & p) const
 // non-virtual functions in this class
 //////////
 
-void expairseq::construct_from_2_ex_via_exvector(ex const & lh, ex const & rh)
+void expairseq::construct_from_2_ex_via_exvector(const ex & lh, const ex & rh)
 {
     exvector v;
     v.reserve(2);
@@ -455,12 +671,12 @@ 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
 }
 
-void expairseq::construct_from_2_ex(ex const & lh, ex const & rh)
+void expairseq::construct_from_2_ex(const ex & lh, const ex & rh)
 {
     if (lh.bp->tinfo()==tinfo()) {
        if (rh.bp->tinfo()==tinfo()) {
@@ -550,8 +766,8 @@ void expairseq::construct_from_2_ex(ex const & lh, ex const & rh)
     }
 }
 
-void expairseq::construct_from_2_expairseq(expairseq const & s1,
-                                           expairseq const & s2)
+void expairseq::construct_from_2_expairseq(const expairseq & s1,
+                                           const expairseq & s2)
 {
     combine_overall_coeff(s1.overall_coeff);
     combine_overall_coeff(s2.overall_coeff);
@@ -569,7 +785,7 @@ void expairseq::construct_from_2_expairseq(expairseq const & s1,
         int cmpval=(*first1).rest.compare((*first2).rest);
         if (cmpval==0) {
             // combine terms
-            numeric const & newcoeff=ex_to_numeric((*first1).coeff).
+            const numeric & newcoeff=ex_to_numeric((*first1).coeff).
                                      add(ex_to_numeric((*first2).coeff));
             if (!newcoeff.is_zero()) {
                 seq.push_back(expair((*first1).rest,newcoeff));
@@ -604,8 +820,8 @@ void expairseq::construct_from_2_expairseq(expairseq const & s1,
     }
 }
 
-void expairseq::construct_from_expairseq_ex(expairseq const & s,
-                                            ex const & e)
+void expairseq::construct_from_expairseq_ex(const expairseq & s,
+                                            const ex & e)
 {
     combine_overall_coeff(s.overall_coeff);
     if (is_ex_exactly_of_type(e,numeric)) {
@@ -628,7 +844,7 @@ void expairseq::construct_from_expairseq_ex(expairseq const & s,
         int cmpval=(*first).rest.compare(p.rest);
         if (cmpval==0) {
             // combine terms
-            numeric const & newcoeff=ex_to_numeric((*first).coeff).
+            const numeric & newcoeff=ex_to_numeric((*first).coeff).
                                      add(ex_to_numeric(p.coeff));
             if (!newcoeff.is_zero()) {
                 seq.push_back(expair((*first).rest,newcoeff));
@@ -667,7 +883,7 @@ void expairseq::construct_from_expairseq_ex(expairseq const & s,
     }
 }
 
-void expairseq::construct_from_exvector(exvector const & v)
+void expairseq::construct_from_exvector(const exvector & v)
 {
     // simplifications: +(a,+(b,c),d) -> +(a,b,c,d) (associativity)
     //                  +(d,b,c,a) -> +(a,b,c,d) (canonicalization)
@@ -683,7 +899,7 @@ void expairseq::construct_from_exvector(exvector const & v)
 #endif // def EXPAIRSEQ_USE_HASHTAB
 }
 
-void expairseq::construct_from_epvector(epvector const & v)
+void expairseq::construct_from_epvector(const epvector & v)
 {
     // simplifications: +(a,+(b,c),d) -> +(a,b,c,d) (associativity)
     //                  +(d,b,c,a) -> +(a,b,c,d) (canonicalization)
@@ -701,7 +917,7 @@ void expairseq::construct_from_epvector(epvector const & v)
 
 #include <iostream>
 
-void expairseq::make_flat(exvector const & v)
+void expairseq::make_flat(const exvector & v)
 {
     exvector::const_iterator cit, citend = v.end();
 
@@ -725,7 +941,7 @@ void expairseq::make_flat(exvector const & v)
     cit=v.begin();
     while (cit!=citend) {
         if (cit->bp->tinfo()==tinfo()) {
-            expairseq const & subseqref=ex_to_expairseq(*cit);
+            const expairseq & subseqref=ex_to_expairseq(*cit);
             combine_overall_coeff(subseqref.overall_coeff);
             epvector::const_iterator cit_s=subseqref.seq.begin();
             while (cit_s!=subseqref.seq.end()) {
@@ -748,11 +964,10 @@ void expairseq::make_flat(exvector const & v)
         (*cit).printraw(cout);
     }
     cout << endl;
-    cout.flush();
     */
 }
 
-void expairseq::make_flat(epvector const & v)
+void expairseq::make_flat(const epvector & v)
 {
     epvector::const_iterator cit, citend = v.end();
 
@@ -760,11 +975,12 @@ void expairseq::make_flat(epvector const & v)
     // and their cumulative number of operands
     int nexpairseqs=0;
     int noperands=0;
-    cit=v.begin();
+
+    cit = v.begin();
     while (cit!=citend) {
         if (cit->rest.bp->tinfo()==tinfo()) {
             nexpairseqs++;
-            noperands+=ex_to_expairseq((*cit).rest).seq.size();
+            noperands += ex_to_expairseq((*cit).rest).seq.size();
         }
         ++cit;
     }
@@ -773,10 +989,10 @@ void expairseq::make_flat(epvector const & v)
     seq.reserve(v.size()+noperands-nexpairseqs);
 
     // copy elements and split off numerical part
-    cit=v.begin();
+    cit = v.begin();
     while (cit!=citend) {
         if ((cit->rest.bp->tinfo()==tinfo())&&can_make_flat(*cit)) {
-            expairseq const & subseqref=ex_to_expairseq((*cit).rest);
+            const expairseq & subseqref=ex_to_expairseq((*cit).rest);
             combine_overall_coeff(ex_to_numeric(subseqref.overall_coeff),
                                   ex_to_numeric((*cit).coeff));
             epvector::const_iterator cit_s=subseqref.seq.begin();
@@ -983,13 +1199,13 @@ unsigned expairseq::calc_hashtabsize(unsigned sz) const
     //  size=nearest_power_of_2*hashtabfactor;
     size=nearest_power_of_2/hashtabfactor;
     if (size<minhashtabsize) return 0;
-    ASSERT(hashtabsize<=0x8000000U); // really max size due to 31 bit hashing
+    GINAC_ASSERT(hashtabsize<=0x8000000U); // really max size due to 31 bit hashing
     // hashtabsize must be a power of 2
-    ASSERT((1U << log2(size))==size);
+    GINAC_ASSERT((1U << log2(size))==size);
     return size;
 }
 
-unsigned expairseq::calc_hashindex(ex const & e) const
+unsigned expairseq::calc_hashindex(const ex & e) const
 {
     // calculate hashindex
     unsigned hash=e.gethash();
@@ -1001,8 +1217,8 @@ unsigned expairseq::calc_hashindex(ex const & e) const
         // last hashtab entry is reserved for numerics
         if (hashindex==hashmask) hashindex=0;
     }
-    ASSERT(hashindex>=0);
-    ASSERT((hashindex<hashtabsize)||(hashtabsize==0));
+    GINAC_ASSERT(hashindex>=0);
+    GINAC_ASSERT((hashindex<hashtabsize)||(hashtabsize==0));
     return hashindex;
 }
 
@@ -1010,7 +1226,7 @@ void expairseq::shrink_hashtab(void)
 {
     unsigned new_hashtabsize;
     while (hashtabsize!=(new_hashtabsize=calc_hashtabsize(seq.size()))) {
-        ASSERT(new_hashtabsize<hashtabsize);
+        GINAC_ASSERT(new_hashtabsize<hashtabsize);
         if (new_hashtabsize==0) {
             hashtab.clear();
             hashtabsize=0;
@@ -1068,15 +1284,15 @@ void expairseq::remove_hashtab_entry(epvector::const_iterator element)
             }
             ++epplit;
         }
-        ASSERT(erased);
+        GINAC_ASSERT(erased);
     }
-    ASSERT(erased);
+    GINAC_ASSERT(erased);
 }
 
 void expairseq::move_hashtab_entry(epvector::const_iterator oldpos,
                                    epvector::iterator newpos)
 {
-    ASSERT(hashtabsize!=0);
+    GINAC_ASSERT(hashtabsize!=0);
     
     // calculate hashindex of element which was moved
     unsigned hashindex=calc_hashindex((*newpos).rest);
@@ -1091,7 +1307,7 @@ void expairseq::move_hashtab_entry(epvector::const_iterator oldpos,
         }
         ++epplit;
     }
-    ASSERT(epplit!=eppl.end());
+    GINAC_ASSERT(epplit!=eppl.end());
 }
 
 void expairseq::sorted_insert(epplist & eppl, epp elem)
@@ -1161,7 +1377,7 @@ void expairseq::drop_coeff_0_terms(epvector::iterator & first_numeric,
         if (!touched[i]) {
             ++current;
             ++i;
-        } else if (!ex_to_numeric((*current).coeff).is_equal(numZERO())) {
+        } else if (!ex_to_numeric((*current).coeff).is_equal(_num0())) {
             ++current;
             ++i;
         } else {
@@ -1197,13 +1413,13 @@ void expairseq::drop_coeff_0_terms(epvector::iterator & first_numeric,
             }
         }
     }
-    ASSERT(i==current-seq.begin());
+    GINAC_ASSERT(i==current-seq.begin());
 }
 
 bool expairseq::has_coeff_0(void) const
 {
     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-        if ((*cit).coeff.is_equal(exZERO())) {
+        if ((*cit).coeff.is_equal(_ex0())) {
             return true;
         }
     }
@@ -1240,7 +1456,7 @@ void expairseq::combine_same_terms(void)
     if (hashtabsize==0) {
         canonicalize();
         combine_same_terms_sorted_seq();
-        ASSERT(!has_coeff_0());
+        GINAC_ASSERT(!has_coeff_0());
         return;
     }
 
@@ -1255,7 +1471,7 @@ void expairseq::combine_same_terms(void)
 
     unsigned number_of_zeroes=0;
 
-    ASSERT(!has_coeff_0());
+    GINAC_ASSERT(!has_coeff_0());
     build_hashtab_and_combine(first_numeric,last_non_zero,touched,number_of_zeroes);
     /*
     cout << "in combine:" << endl;
@@ -1294,11 +1510,11 @@ void expairseq::combine_same_terms(void)
     }
 
     // shrink hashtabsize to calculated value
-    ASSERT(!has_coeff_0());
+    GINAC_ASSERT(!has_coeff_0());
 
     shrink_hashtab();
 
-    ASSERT(!has_coeff_0());
+    GINAC_ASSERT(!has_coeff_0());
 }
 
 #endif // def EXPAIRSEQ_USE_HASHTAB
@@ -1311,8 +1527,8 @@ bool expairseq::is_canonical() const
     if (hashtabsize>0) return 1; // not canoncalized
 #endif // def EXPAIRSEQ_USE_HASHTAB
     
-    epvector::const_iterator it=seq.begin();
-    epvector::const_iterator it_last=it;
+    epvector::const_iterator it = seq.begin();
+    epvector::const_iterator it_last = it;
     for (++it; it!=seq.end(); it_last=it, ++it) {
         if (!((*it_last).is_less(*it)||(*it_last).is_equal(*it))) {
             if (!is_ex_exactly_of_type((*it_last).rest,numeric)||
@@ -1340,10 +1556,10 @@ bool expairseq::is_canonical() const
 
 epvector * expairseq::expandchildren(unsigned options) const
 {
-    epvector::const_iterator last=seq.end();
-    epvector::const_iterator cit=seq.begin();
+    epvector::const_iterator last = seq.end();
+    epvector::const_iterator cit = seq.begin();
     while (cit!=last) {
-        ex const & expanded_ex=(*cit).rest.expand(options);
+        const ex & expanded_ex=(*cit).rest.expand(options);
         if (!are_ex_trivially_equal((*cit).rest,expanded_ex)) {
 
             // something changed, copy seq, eval and return it
@@ -1351,7 +1567,7 @@ epvector * expairseq::expandchildren(unsigned options) const
             s->reserve(seq.size());
 
             // copy parts of seq which are known not to have changed
-            epvector::const_iterator cit2=seq.begin();
+            epvector::const_iterator cit2 = seq.begin();
             while (cit2!=cit) {
                 s->push_back(*cit2);
                 ++cit2;
@@ -1391,11 +1607,11 @@ epvector * expairseq::evalchildren(int level) const
     epvector::const_iterator last=seq.end();
     epvector::const_iterator cit=seq.begin();
     while (cit!=last) {
-        ex const & evaled_ex=(*cit).rest.eval(level);
+        const ex & evaled_ex=(*cit).rest.eval(level);
         if (!are_ex_trivially_equal((*cit).rest,evaled_ex)) {
 
-           // something changed, copy seq, eval and return it
-            epvector *s=new epvector;
+            // something changed, copy seq, eval and return it
+            epvector *s = new epvector;
             s->reserve(seq.size());
 
             // copy parts of seq which are known not to have changed
@@ -1424,34 +1640,34 @@ epvector * expairseq::evalchildren(int level) const
 
 epvector expairseq::evalfchildren(int level) const
 {
-    epvector s;
-    s.reserve(seq.size());
-
-    if (level==1) {
+    if (level==1)
         return seq;
-    }
-    if (level == -max_recursion_level) {
+
+    if (level==-max_recursion_level)
         throw(std::runtime_error("max recursion level reached"));
-    }
+    
+    epvector s;
+    s.reserve(seq.size());
+    
     --level;
     for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
         s.push_back(combine_ex_with_coeff_to_pair((*it).rest.evalf(level),
-                                                  (*it).coeff));
+                                                  (*it).coeff.evalf(level)));
     }
     return s;
 }
 
 epvector expairseq::normalchildren(int level) const
 {
+    if (level==1)
+        return seq;
+    
+    if (level == -max_recursion_level)
+        throw(std::runtime_error("max recursion level reached"));
+
     epvector s;
     s.reserve(seq.size());
 
-    if (level==1) {
-        return seq;
-    }
-    if (level == -max_recursion_level) {
-        throw(std::runtime_error("max recursion level reached"));
-    }
     --level;
     for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
         s.push_back(combine_ex_with_coeff_to_pair((*it).rest.normal(level),
@@ -1460,7 +1676,7 @@ epvector expairseq::normalchildren(int level) const
     return s;
 }
 
-epvector expairseq::diffchildren(symbol const & y) const
+epvector expairseq::diffchildren(const symbol & y) const
 {
     epvector s;
     s.reserve(seq.size());
@@ -1472,22 +1688,23 @@ epvector expairseq::diffchildren(symbol const & y) const
     return s;
 }
 
-epvector * expairseq::subschildren(lst const & ls, lst const & lr) const
+epvector * expairseq::subschildren(const lst & ls, const lst & 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);
+        const ex & 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) {
@@ -1503,7 +1720,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;
@@ -1512,75 +1729,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
 //////////
@@ -1600,5 +1748,8 @@ unsigned expairseq::hashtabfactor=1;
 //////////
 
 const expairseq some_expairseq;
-type_info const & typeid_expairseq=typeid(some_expairseq);
+const type_info & typeid_expairseq=typeid(some_expairseq);
 
+#ifndef NO_NAMESPACE_GINAC
+} // namespace GiNaC
+#endif // ndef NO_NAMESPACE_GINAC