* ginac/registrar.h: dtor is inlined now.
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Wed, 28 Feb 2001 15:54:52 +0000 (15:54 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Wed, 28 Feb 2001 15:54:52 +0000 (15:54 +0000)
* ginac/basic.h, ginac/ex.h: removed INLINE_FOO_CONSTRUCTORS and hand-inlined
  stuff instead, since the macros turned out to get in the way while
  fine-tuning the inlining.
* ginac/utils.h: if 'long long' works, use that one for computing the hash
  value instead of floating point tricks.  2 Reasons: on Intel the assembler
  is terrible and slow otherwise, 'long long' will appear in C++ anyways when
  they adapt to the C99 standard.
* Several other small performance tweaks.
* ginac/constant.cpp: (constant::calchash()) implement, caring for serial.
* ginac/function.pl (function::calchash()): implement, caring for serial.
* ginac/expairseq.cpp: honor coeff's hash value.
* ginac/pseries.cpp: (pseries::power_const()) fix problems with zero pseries.
* Added several pounds of in-source documentation in doxygen style.

76 files changed:
ginac/add.cpp
ginac/add.h
ginac/archive.cpp
ginac/archive.h
ginac/assertion.h
ginac/basic.cpp
ginac/basic.h
ginac/clifford.cpp
ginac/clifford.h
ginac/color.cpp
ginac/color.h
ginac/coloridx.cpp
ginac/coloridx.h
ginac/constant.cpp
ginac/constant.h
ginac/container.pl
ginac/debugmsg.h
ginac/ex.cpp
ginac/ex.h
ginac/expair.h
ginac/expairseq.cpp
ginac/expairseq.h
ginac/exprseq_suppl.cpp
ginac/fail.cpp
ginac/fail.h
ginac/flags.h
ginac/function.pl
ginac/idx.cpp
ginac/idx.h
ginac/indexed.cpp
ginac/indexed.h
ginac/inifcns.cpp
ginac/inifcns.h
ginac/inifcns_gamma.cpp
ginac/inifcns_trans.cpp
ginac/inifcns_zeta.cpp
ginac/input_lexer.h
ginac/isospin.cpp
ginac/isospin.h
ginac/lorentzidx.cpp
ginac/lorentzidx.h
ginac/lortensor.cpp
ginac/lortensor.h
ginac/lst_suppl.cpp
ginac/matrix.cpp
ginac/matrix.h
ginac/mul.cpp
ginac/mul.h
ginac/ncmul.cpp
ginac/ncmul.h
ginac/normal.cpp
ginac/normal.h
ginac/numeric.cpp
ginac/numeric.h
ginac/operators.cpp
ginac/operators.h
ginac/power.cpp
ginac/power.h
ginac/pseries.cpp
ginac/pseries.h
ginac/registrar.cpp
ginac/registrar.h
ginac/relational.cpp
ginac/relational.h
ginac/remember.cpp
ginac/remember.h
ginac/simp_lor.cpp
ginac/simp_lor.h
ginac/structure.cpp
ginac/structure.h
ginac/structure.pl
ginac/symbol.cpp
ginac/symbol.h
ginac/tinfos.h
ginac/utils.cpp
ginac/utils.h

index 2f227fc..0c22465 100644 (file)
@@ -29,9 +29,7 @@
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(add, expairseq)
 
@@ -49,6 +47,7 @@ add::add()
 
 // protected
 
+/** For use by copy ctor and assignment operator. */
 void add::copy(const add & other)
 {
        inherited::copy(other);
@@ -83,23 +82,6 @@ add::add(const exvector & v)
        GINAC_ASSERT(is_canonical());
 }
 
-/*
-add::add(const epvector & v, bool do_not_canonicalize)
-{
-       debugmsg("add constructor from epvector,bool",LOGLEVEL_CONSTRUCT);
-       tinfo_key = TINFO_add;
-       if (do_not_canonicalize) {
-               seq=v;
-#ifdef EXPAIRSEQ_USE_HASHTAB
-               combine_same_terms(); // to build hashtab
-#endif // def EXPAIRSEQ_USE_HASHTAB
-       } else {
-               construct_from_epvector(v);
-       }
-       GINAC_ASSERT(is_canonical());
-}
-*/
-
 add::add(const epvector & v)
 {
        debugmsg("add constructor from epvector",LOGLEVEL_CONSTRUCT);
@@ -218,12 +200,12 @@ void add::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence)
        debugmsg("add print csrc", LOGLEVEL_PRINT);
        if (precedence <= upper_precedence)
                os << "(";
-
+       
        // Print arguments, separated by "+"
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
-
+               
                // If the coefficient is -1, it is replaced by a single minus sign
                if (it->coeff.compare(_num1()) == 0) {
                        it->rest.bp->printcsrc(os, type, precedence);
@@ -244,14 +226,14 @@ void add::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence)
                        os << "*";
                        it->rest.bp->printcsrc(os, type, precedence);
                }
-
+               
                // Separator is "+", except if the following expression would have a leading minus sign
                it++;
                if (it != itend && !(it->coeff.compare(_num0()) < 0 || (it->coeff.compare(_num1()) == 0 && is_ex_exactly_of_type(it->rest, numeric) && it->rest.compare(_num0()) < 0)))
                        os << "+";
        }
        
-       if (!overall_coeff.is_equal(_ex0())) {
+       if (!overall_coeff.is_zero()) {
                if (overall_coeff.info(info_flags::positive)) os << '+';
                overall_coeff.bp->printcsrc(os,type,precedence);
        }
@@ -289,13 +271,14 @@ bool add::info(unsigned inf) const
 int add::degree(const symbol & s) const
 {
        int deg = INT_MIN;
-       if (!overall_coeff.is_equal(_ex0())) {
+       if (!overall_coeff.is_equal(_ex0()))
                deg = 0;
-       }
+       
        int cur_deg;
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               cur_deg=(*cit).rest.degree(s);
-               if (cur_deg>deg) deg=cur_deg;
+               cur_deg = (*cit).rest.degree(s);
+               if (cur_deg>deg)
+                       deg = cur_deg;
        }
        return deg;
 }
@@ -303,9 +286,9 @@ int add::degree(const symbol & s) const
 int add::ldegree(const symbol & s) const
 {
        int deg = INT_MAX;
-       if (!overall_coeff.is_equal(_ex0())) {
+       if (!overall_coeff.is_equal(_ex0()))
                deg = 0;
-       }
+       
        int cur_deg;
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
                cur_deg = (*cit).rest.ldegree(s);
@@ -335,10 +318,10 @@ ex add::eval(int level) const
 {
        // simplifications: +(;c) -> c
        //                  +(x;1) -> x
-
+       
        debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION);
-
-       epvector * evaled_seqp=evalchildren(level);
+       
+       epvector * evaled_seqp = evalchildren(level);
        if (evaled_seqp!=0) {
                // do more evaluation later
                return (new add(evaled_seqp,overall_coeff))->
@@ -348,24 +331,23 @@ ex add::eval(int level) const
 #ifdef DO_GINAC_ASSERT
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
                GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,add));
-               if (is_ex_exactly_of_type((*cit).rest,numeric)) {
+               if (is_ex_exactly_of_type((*cit).rest,numeric))
                        dbgprint();
-               }
                GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,numeric));
        }
 #endif // def DO_GINAC_ASSERT
        
        if (flags & status_flags::evaluated) {
                GINAC_ASSERT(seq.size()>0);
-               GINAC_ASSERT((seq.size()>1)||!overall_coeff.is_equal(_ex0()));
+               GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_zero());
                return *this;
        }
        
-       int seq_size=seq.size();
+       int seq_size = seq.size();
        if (seq_size==0) {
                // +(;c) -> c
                return overall_coeff;
-       } else if ((seq_size==1)&&overall_coeff.is_equal(_ex0())) {
+       } else if ((seq_size==1) && overall_coeff.is_equal(_ex0())) {
                // +(x;0) -> x
                return recombine_pair_to_ex(*(seq.begin()));
        }
@@ -440,14 +422,14 @@ 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);
+               const mul &mulref = ex_to_mul(e);
                ex numfactor = mulref.overall_coeff;
-               // mul * mulcopyp = static_cast<mul *>(mulref.duplicate());
-               mul * mulcopyp = new mul(mulref);
+               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);
+               mulcopyp->setflag(status_flags::dynallocated);
+               return expair(*mulcopyp,numfactor);
        }
        return expair(e,_ex1());
 }
@@ -464,12 +446,12 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
                mulcopyp->clearflag(status_flags::evaluated);
                mulcopyp->clearflag(status_flags::hash_calculated);
                mulcopyp->setflag(status_flags::dynallocated);
-               if (are_ex_trivially_equal(c, _ex1())) {
+               if (are_ex_trivially_equal(c, _ex1()))
                        return expair(*mulcopyp, numfactor);
-               } else if (are_ex_trivially_equal(numfactor, _ex1())) {
+               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
+                       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, _ex1()))
                        return expair(e, _ex1());
@@ -477,7 +459,7 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
        }
        return expair(e, c);
 }
-       
+
 expair add::combine_pair_with_coeff_to_pair(const expair & p,
                                                                                        const ex & c) const
 {
@@ -506,8 +488,11 @@ ex add::expand(unsigned options) const
                return *this;
        
        epvector * vp = expandchildren(options);
-       if (vp==0)
+       if (vp==0) {
+               // the terms have not changed, so it is safe to declare this expanded
+               setflag(status_flags::expanded);
                return *this;
+       }
        
        return (new add(vp,overall_coeff))->setflag(status_flags::expanded | status_flags::dynallocated);
 }
@@ -520,6 +505,4 @@ ex add::expand(unsigned options) const
 
 unsigned add::precedence = 40;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 0c8e37c..8a93186 100644 (file)
 
 #include "expairseq.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** Sum of expressions. */
 class add : public expairseq
 {
        GINAC_DECLARE_REGISTERED_CLASS(add, expairseq)
-
+       
        friend class mul;
        friend class ncmul;
        friend class power;
-
+       
        // other constructors
 public:
        add(const ex & lh, const ex & rh);
        add(const exvector & v);
        add(const epvector & v);
-       //add(const epvector & v, bool do_not_canonicalize=0);
        add(const epvector & v, const ex & oc);
        add(epvector * vp, const ex & oc);
-
+       
        // functions overriding virtual functions from bases classes
 public:
        void print(std::ostream & os, unsigned upper_precedence=0) const;
@@ -73,9 +70,9 @@ protected:
        ex thisexpairseq(epvector * vp, const ex & oc) const;
        expair split_ex_to_pair(const ex & e) const;
        expair combine_ex_with_coeff_to_pair(const ex & e,
-                                                                                const ex & c) const;
+                                            const ex & c) const;
        expair combine_pair_with_coeff_to_pair(const expair & p,
-                                                                                  const ex & c) const;
+                                              const ex & c) const;
        ex recombine_pair_to_ex(const expair & p) const;
        ex expand(unsigned options=0) const;
        
@@ -97,8 +94,6 @@ inline const add &ex_to_add(const ex &e)
        return static_cast<const add &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_ADD_H__
index 61d60c2..849da9b 100644 (file)
@@ -29,9 +29,7 @@
 #include "config.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** Archive an expression.
@@ -591,6 +589,4 @@ archive* archive_node::dummy_ar_creator(void)
 }
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index d56c0e6..24c6d5d 100644 (file)
@@ -29,9 +29,7 @@
 #include <vector>
 #include <iostream>
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class lst;
 class archive;
@@ -183,8 +181,6 @@ std::ostream &operator<<(std::ostream &os, const archive &ar);
 std::istream &operator>>(std::istream &is, archive &ar);
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_ARCHIVE_H__
index 8e6c29f..536a18a 100644 (file)
 #ifndef __GINAC_ASSERTION_H__
 #define __GINAC_ASSERTION_H__
 
-extern "C" {
-#include <assert.h>
-}
+#include <cassert>
 
 #if !defined(GINAC_ASSERT)
 #if defined(DO_GINAC_ASSERT)
+/** Assertion macro for checking invariances. */
 #define GINAC_ASSERT(X) assert(X)
 #else
+/** Assertion macro for checking invariances. */
 #define GINAC_ASSERT(X) ((void)0)
 #endif
 #endif
index a33433d..6adc4c4 100644 (file)
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS_NO_CTORS(basic, void)
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
-#ifndef INLINE_BASIC_CONSTRUCTORS
-basic::basic() : flags(0), refcount(0), tinfo_key(TINFO_BASIC)
+basic::basic(const basic & other) : tinfo_key(TINFO_basic), flags(0), refcount(0)
 {
-       debugmsg("basic default constructor", LOGLEVEL_CONSTRUCT);
-       // nothing to do
-}
-
-basic::~basic() 
-{
-       debugmsg("basic destructor", LOGLEVEL_DESTRUCT);
-       destroy(false);
-       GINAC_ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
-}
-
-basic::basic(const basic & other) : flags(0), refcount(0), tinfo_key(TINFO_BASIC)
-{
-       debugmsg("basic copy constructor", LOGLEVEL_CONSTRUCT);
+       debugmsg("basic copy ctor", LOGLEVEL_CONSTRUCT);
        copy(other);
 }
-#endif
 
 const basic & basic::operator=(const basic & other)
 {
@@ -80,19 +63,13 @@ const basic & basic::operator=(const basic & other)
 
 // protected
 
-// none (all inlined)
+// none (all conditionally inlined)
 
 //////////
-// other constructors
+// other ctors
 //////////
 
-#ifndef INLINE_BASIC_CONSTRUCTORS
-basic::basic(unsigned ti) : flags(0), refcount(0), tinfo_key(ti)
-{
-       debugmsg("basic constructor with tinfo_key", LOGLEVEL_CONSTRUCT);
-       // nothing to do
-}
-#endif
+// none (all conditionally inlined)
 
 //////////
 // archiving
@@ -101,7 +78,7 @@ basic::basic(unsigned ti) : flags(0), refcount(0), tinfo_key(ti)
 /** Construct object from archive_node. */
 basic::basic(const archive_node &n, const lst &sym_lst) : flags(0), refcount(0)
 {
-       debugmsg("basic constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("basic ctor from archive_node", LOGLEVEL_CONSTRUCT);
 
        // Reconstruct tinfo_key from class name
        std::string class_name;
@@ -135,14 +112,15 @@ void basic::archive(archive_node &n) const
 
 // public
 
-/** Output to stream formatted to be useful as ginsh input. */
+/** Output to ostream formatted as parsable (as in ginsh) input.
+ *  Generally, superfluous parenthesis should be avoided as far as possible. */
 void basic::print(std::ostream & os, unsigned upper_precedence) const
 {
        debugmsg("basic print",LOGLEVEL_PRINT);
        os << "[basic object]";
 }
 
-/** Output to stream in ugly raw format, so brave developers can have a look
+/** Output to ostream in ugly raw format, so brave developers can have a look
  *  at the underlying structure. */
 void basic::printraw(std::ostream & os) const
 {
@@ -150,7 +128,7 @@ void basic::printraw(std::ostream & os) const
        os << "[basic object]";
 }
 
-/** Output to stream formatted in tree- (indented-) form, so developers can
+/** Output to ostream formatted in tree- (indented-) form, so developers can
  *  have a look at the underlying structure. */
 void basic::printtree(std::ostream & os, unsigned indent) const
 {
@@ -165,7 +143,7 @@ void basic::printtree(std::ostream & os, unsigned indent) const
        }
 }
 
-/** Output to stream formatted as C-source.
+/** Output to ostream formatted as C-source.
  *
  *  @param os a stream for output
  *  @param type variable type (one of the csrc_types)
@@ -178,13 +156,13 @@ void basic::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedenc
 
 /** 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.
+ *  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);
+       this->print(std::cerr);
        std::cerr << std::endl;
 }
 
@@ -194,9 +172,12 @@ void basic::dbgprint(void) const
  *  @see basic::printtree */
 void basic::dbgprinttree(void) const
 {
-       printtree(std::cerr,0);
+       this->printtree(std::cerr,0);
 }
 
+/** Create a new copy of this on the heap.  One can think of this as simulating
+ *  a virtual copy constructor which is needed for instance by the refcounted
+ *  construction of an ex from a basic. */
 basic * basic::duplicate() const
 {
        debugmsg("basic duplicate",LOGLEVEL_DUPLICATE);
@@ -208,7 +189,8 @@ basic * basic::duplicate() const
  *  @see class info_flags */
 bool basic::info(unsigned inf) const
 {
-       return false; // all possible properties are false for basic objects
+       // all possible properties are false for basic objects
+       return false;
 }
 
 /** Number of operands/members. */
@@ -246,16 +228,19 @@ ex basic::operator[](int i) const
 }
 
 /** Search ocurrences.  An object  'has' an expression if it is the expression
- *  itself or one of the children 'has' it. */
+ *  itself or one of the children 'has' it.  As a consequence (according to
+ *  the definition of children) given e=x+y+z, e.has(x) is true but e.has(x+y)
+ *  is false. */
 bool basic::has(const ex & other) const
 {
        GINAC_ASSERT(other.bp!=0);
        if (is_equal(*other.bp)) return true;
        if (nops()>0) {
-               for (unsigned i=0; i<nops(); i++) {
-                       if (op(i).has(other)) return true;
-               }
+               for (unsigned i=0; i<nops(); i++)
+                       if (op(i).has(other))
+                               return true;
        }
+       
        return false;
 }
 
@@ -282,15 +267,13 @@ ex basic::coeff(const symbol & s, int n) const
 ex basic::collect(const symbol & s) const
 {
        ex x;
-       int ldeg = this->ldegree(s);
-       int deg = this->degree(s);
-       for (int n=ldeg; n<=deg; n++) {
+       for (int n=this->ldegree(s); n<=this->degree(s); n++)
                x += this->coeff(s,n)*power(s,n);
-       }
+       
        return x;
 }
 
-/* Perform automatic symbolic evaluations on expression. */
+/** Perform automatic non-interruptive symbolic evaluation on expression. */
 ex basic::eval(int level) const
 {
        // There is nothing to do for basic objects:
@@ -304,7 +287,8 @@ ex basic::evalf(int level) const
        return *this;
 }
 
-/* Substitute a set of symbols. */
+/** Substitute a set of symbols by arbitrary expressions. The ex returned
+ *  will already be evaluated. */
 ex basic::subs(const lst & ls, const lst & lr) const
 {
        return *this;
@@ -357,8 +341,10 @@ ex basic::derivative(const symbol & s) const
        throw(std::logic_error("differentiation not supported by this type"));
 }
 
-/** Returns order relation between two objects of same type.  Needs to be
- *  implemented by each class. */
+/** Returns order relation between two objects of same type.  This needs to be
+ *  implemented by each class. It may never return anything else than 0,
+ *  signalling equality, or +1 and -1 signalling inequality and determining
+ *  the canonical ordering. */
 int basic::compare_same_type(const basic & other) const
 {
        return compare_pointers(this, &other);
@@ -366,10 +352,12 @@ int basic::compare_same_type(const basic & other) const
 
 /** Returns true if two objects of same type are equal.  Normally needs
  *  not be reimplemented as long as it wasn't overwritten by some parent
- *  class, since it just calls complare_same_type(). */
+ *  class, since it just calls compare_same_type().  The reason why this
+ *  function exists is that sometimes it is easier to determine equality
+ *  than an order relation and then it can be overridden. */
 bool basic::is_equal_same_type(const basic & other) const
 {
-       return compare_same_type(other)==0;
+       return this->compare_same_type(other)==0;
 }
 
 unsigned basic::return_type(void) const
@@ -382,20 +370,27 @@ unsigned basic::return_type_tinfo(void) const
        return tinfo();
 }
 
+/** Compute the hash value of an object and if it makes sense to store it in
+ *  the objects status_flags, do so.  The method inherited from class basic
+ *  computes a hash value based on the type and hash values of possible
+ *  members.  For this reason it is well suited for container classes but
+ *  atomic classes should override this implementation because otherwise they
+ *  would all end up with the same hashvalue. */
 unsigned basic::calchash(void) const
 {
-       unsigned v=golden_ratio_hash(tinfo());
+       unsigned v = golden_ratio_hash(tinfo());
        for (unsigned i=0; i<nops(); i++) {
-               v=rotate_left_31(v);
+               v = rotate_left_31(v);
                v ^= (const_cast<basic *>(this))->op(i).gethash();
        }
-
-       v = v & 0x7FFFFFFFU;
+       
+       // mask out numeric hashes:
+       v &= 0x7FFFFFFFU;
        
        // store calculated hash value only if object is already evaluated
        if (flags & status_flags::evaluated) {
                setflag(status_flags::hash_calculated);
-               hashvalue=v;
+               hashvalue = v;
        }
 
        return v;
@@ -445,89 +440,86 @@ ex basic::subs(const ex & e) const
        return subs(ls,lr);
 }
 
-/** Compare objects to establish canonical order.
+/** Compare objects to establish canonical ordering.
  *  All compare functions return: -1 for *this less than other, 0 equal,
  *  1 greater. */
 int basic::compare(const basic & other) const
 {
        unsigned hash_this = gethash();
        unsigned hash_other = other.gethash();
-
+       
        if (hash_this<hash_other) return -1;
        if (hash_this>hash_other) return 1;
-
+       
        unsigned typeid_this = tinfo();
        unsigned typeid_other = other.tinfo();
-
+       
        if (typeid_this<typeid_other) {
-               /*
-               cout << "hash collision, different types: " 
-                        << *this << " and " << other << endl;
-               this->printraw(cout);
-               cout << " and ";
-               other.printraw(cout);
-               cout << endl;
-               */
+//             std::cout << "hash collision, different types: " 
+//                       << *this << " and " << other << std::endl;
+//             this->printraw(std::cout);
+//             std::cout << " and ";
+//             other.printraw(std::cout);
+//             std::cout << std::endl;
                return -1;
        }
        if (typeid_this>typeid_other) {
-               /*
-               cout << "hash collision, different types: " 
-                        << *this << " and " << other << endl;
-               this->printraw(cout);
-               cout << " and ";
-               other.printraw(cout);
-               cout << endl;
-               */
+//             std::cout << "hash collision, different types: " 
+//                       << *this << " and " << other << std::endl;
+//             this->printraw(std::cout);
+//             std::cout << " and ";
+//             other.printraw(std::cout);
+//             std::cout << std::endl;
                return 1;
        }
-
+       
        GINAC_ASSERT(typeid(*this)==typeid(other));
-
-       int cmpval=compare_same_type(other);
-       if ((cmpval!=0)&&(hash_this<0x80000000U)) {
-               /*
-               cout << "hash collision, same type: " 
-                        << *this << " and " << other << endl;
-               this->printraw(cout);
-               cout << " and ";
-               other.printraw(cout);
-               cout << endl;
-               */
+       
+       int cmpval = compare_same_type(other);
+       if ((cmpval!=0) && (hash_this<0x80000000U)) {
+//             std::cout << "hash collision, same type: " 
+//                       << *this << " and " << other << std::endl;
+//             this->printraw(std::cout);
+//             std::cout << " and ";
+//             other.printraw(std::cout);
+//             std::cout << std::endl;
        }
        return cmpval;
 }
 
-/** Test for equality. */
+/** Test for equality.
+ *  This is only a quick test, meaning objects should be in the same domain.
+ *  You might have to .expand(), .normal() objects first, depending on the
+ *  domain of your computation, to get a more reliable answer.
+ *
+ *  @see is_equal_same_type */
 bool basic::is_equal(const basic & other) const
 {
-       unsigned hash_this = gethash();
-       unsigned hash_other = other.gethash();
-
-       if (hash_this!=hash_other) return false;
-
-       unsigned typeid_this = tinfo();
-       unsigned typeid_other = other.tinfo();
-
-       if (typeid_this!=typeid_other) return false;
-
+       if (this->gethash()!=other.gethash())
+               return false;
+       if (this->tinfo()!=other.tinfo())
+               return false;
+       
        GINAC_ASSERT(typeid(*this)==typeid(other));
-
-       return is_equal_same_type(other);
+       
+       return this->is_equal_same_type(other);
 }
 
 // protected
 
 /** Stop further evaluation.
+ *
  *  @see basic::eval */
 const basic & basic::hold(void) const
 {
-       return setflag(status_flags::evaluated);
+       return this->setflag(status_flags::evaluated);
 }
 
+/** Ensure the object may be modified without hurting others, throws if this
+ *  is not the case. */
 void basic::ensure_if_modifiable(void) const
 {
-       if (refcount>1)
+       if (this->refcount>1)
                throw(std::runtime_error("cannot modify multiply referenced object"));
 }
 
@@ -544,8 +536,6 @@ unsigned basic::delta_indent = 4;
 // global variables
 //////////
 
-int max_recursion_level=1024;
+int max_recursion_level = 1024;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index a75f4c0..e132574 100644 (file)
 #include "tinfos.h"
 #include "assertion.h"
 #include "registrar.h"
+/*#include "debugmsg.h"*/
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
-class basic;
 class ex;
 class symbol;
 class lst;
@@ -50,74 +48,53 @@ class archive_node;
 // Cint doesn't like vector<..,default_alloc> but malloc_alloc is
 // unstandardized and not supported by newer GCCs.
 #if defined(__GNUC__) && ((__GNUC__ == 2) && (__GNUC_MINOR__ < 97))
-typedef std::vector<ex,malloc_alloc> exvector;
+  typedef std::vector<ex,malloc_alloc> exvector;
 #else
-typedef std::vector<ex> exvector;
+  typedef std::vector<ex> exvector;
 #endif
 
-#define INLINE_BASIC_CONSTRUCTORS
-
 /** This class is the ABC (abstract base class) of GiNaC's class hierarchy.
  *  It is responsible for the reference counting. */
 class basic
 {
        GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(basic, void)
-
+       
        friend class ex;
-
+       
 // member functions
-
-       // default constructor, destructor, copy constructor assignment operator and helpers
+       
+       // default ctor, dtor, copy ctor assignment operator and helpers
 public:
-       basic()
-#ifdef INLINE_BASIC_CONSTRUCTORS
-               : tinfo_key(TINFO_basic), flags(0), refcount(0)
+       basic() : tinfo_key(TINFO_basic), flags(0), refcount(0)
        {
+               /* debugmsg("basic default ctor", LOGLEVEL_CONSTRUCT); */
        }
-#else
-;
-#endif // def INLINE_BASIC_CONSTRUCTORS
-
+       /** basic dtor, virtual because class ex will delete objects via ptr. */
        virtual ~basic()
-#ifdef INLINE_BASIC_CONSTRUCTORS
        {
-               destroy(0);
+               /* debugmsg("basic dtor", LOGLEVEL_DESTRUCT); */
+               destroy(false);
                GINAC_ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
        }
-#else
-;
-#endif // def INLINE_BASIC_CONSTRUCTORS
-
-       basic(const basic & other)
-#ifdef INLINE_BASIC_CONSTRUCTORS
-       {
-               copy(other);
-       }
-#else
-;
-#endif // def INLINE_BASIC_CONSTRUCTORS
-
+       basic(const basic & other);
        const basic & operator=(const basic & other);
-
 protected:
+       /** For use by copy ctor and assignment operator. */
        void copy(const basic & other)
        {
                flags = other.flags & ~status_flags::dynallocated;
                hashvalue = other.hashvalue;
                tinfo_key = other.tinfo_key;
        }
-       void destroy(bool call_parent) {}
-
-       // other constructors
-       basic(unsigned ti)
-#ifdef INLINE_BASIC_CONSTRUCTORS
-                          : tinfo_key(ti), flags(0), refcount(0)
+       /** For use by dtor and assignment operator. */
+       virtual void destroy(bool call_parent) { }
+       
+       // other ctors
+       /** ctor with specified tinfo_key */
+       basic(unsigned ti) : tinfo_key(ti), flags(0), refcount(0)
        {
+               /* debugmsg("basic ctor with tinfo_key", LOGLEVEL_CONSTRUCT); */
        }
-#else
-;
-#endif // def INLINE_BASIC_CONSTRUCTORS
-
        // functions overriding virtual functions from bases classes
        // none
        
@@ -159,8 +136,8 @@ protected: // non-const functions should be called from class ex only
        virtual unsigned return_type(void) const;
        virtual unsigned return_type_tinfo(void) const;
        virtual unsigned calchash(void) const;
-       virtual ex expand(unsigned options=0) const;
-
+       virtual ex expand(unsigned options = 0) const;
+       
        // non-virtual functions in this class
 public:
        ex subs(const ex & e) const;
@@ -168,23 +145,25 @@ public:
        int compare(const basic & other) const;
        bool is_equal(const basic & other) const;
        const basic & hold(void) const;
-       unsigned gethash(void) const {if (flags & status_flags::hash_calculated) return hashvalue; else return calchash();}
+       unsigned gethash(void) const { if (flags & status_flags::hash_calculated) return hashvalue; else return calchash(); }
        unsigned tinfo(void) const {return tinfo_key;}
+       /** Set some status_flags. */
        const basic & setflag(unsigned f) const {flags |= f; return *this;}
+       /** Clear some status_flags. */
        const basic & clearflag(unsigned f) const {flags &= ~f; return *this;}
 protected:
        void ensure_if_modifiable(void) const;
-
+       
 // member variables
        
 protected:
-       unsigned tinfo_key;
-       mutable unsigned flags;
-       mutable unsigned hashvalue;
-       static unsigned precedence;
-       static unsigned delta_indent;
+       unsigned tinfo_key;                 ///< typeinfo
+       mutable unsigned flags;             ///< of type status_flags
+       mutable unsigned hashvalue;         ///< hash value
+       static unsigned precedence;         ///< precedence for printing parens
+       static unsigned delta_indent;       ///< precedence for printtree
 private:
-       unsigned refcount;
+       unsigned refcount;                  ///< Number of reference counts
 };
 
 // global variables
@@ -193,8 +172,6 @@ extern int max_recursion_level;
 
 // convenience macros
 
-#ifndef NO_NAMESPACE_GINAC
-
 /** Check if OBJ is a TYPE, including base classes. */
 #define is_of_type(OBJ,TYPE) \
        (dynamic_cast<const TYPE *>(&OBJ)!=0)
@@ -211,24 +188,6 @@ extern int max_recursion_level;
 #define is_ex_exactly_of_type(OBJ,TYPE) \
        ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE)
 
-#else // ndef NO_NAMESPACE_GINAC
-
-#define is_of_type(OBJ,TYPE) \
-       (dynamic_cast<const TYPE *>(&OBJ)!=0)
-
-#define is_exactly_of_type(OBJ,TYPE) \
-       ((OBJ).tinfo()==TINFO_##TYPE)
-
-#define is_ex_of_type(OBJ,TYPE) \
-       (dynamic_cast<const TYPE *>((OBJ).bp)!=0)
-
-#define is_ex_exactly_of_type(OBJ,TYPE) \
-       ((*(OBJ).bp).tinfo()==TINFO_##TYPE)
-
-#endif // ndef NO_NAMESPACE_GINAC
-
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_BASIC_H__
index 0dc0518..a3f26c9 100644 (file)
@@ -30,9 +30,7 @@
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(clifford, lortensor)
 
@@ -190,6 +188,4 @@ clifford clifford_gamma(const ex & mu)
        return clifford("gamma", mu);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index aed2b16..86978e9 100644 (file)
@@ -26,9 +26,7 @@
 #include <string>
 #include "lortensor.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** This class holds an object representing an element of the Clifford
@@ -79,8 +77,6 @@ inline const clifford &ex_to_clifford(const ex &e)
 
 clifford clifford_gamma(const ex & mu);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_CLIFFORD_H__
index f2360c3..9e355cb 100644 (file)
@@ -37,9 +37,7 @@
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(color, indexed)
 
@@ -1033,6 +1031,4 @@ ex brute_force_sum_color_indices(const ex & e)
        return sum;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 6f126a3..4d4169a 100644 (file)
@@ -28,9 +28,7 @@
 #include "indexed.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 const unsigned MAX_REPRESENTATION_LABELS = 4;
 const unsigned COLOR_EIGHT = 8; // N*N-1
@@ -163,8 +161,6 @@ ex simplify_color(const ex & e);
 
 ex brute_force_sum_color_indices(const ex & e);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_COLOR_H__
index d034ba4..cb8b629 100644 (file)
@@ -27,9 +27,7 @@
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(coloridx, idx)
 
@@ -212,6 +210,4 @@ int coloridx::compare_same_type(const basic & other) const
        return inherited::compare_same_type(other);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index a727b91..ab78abb 100644 (file)
@@ -28,9 +28,7 @@
 #include "idx.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** Class of indices for color algebra objects, to tell them apart from
@@ -75,8 +73,6 @@ inline const coloridx &ex_to_coloridx(const ex &e)
        return static_cast<const coloridx &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_COLORIDX_H__
index dcf2837..56f5a85 100644 (file)
 #include "ex.h"
 #include "archive.h"
 #include "debugmsg.h"
+#include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(constant, basic)
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
 constant::constant() : basic(TINFO_constant), name(""), ef(0), number(0), serial(next_serial++)
 {
-       debugmsg("constant default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("constant default ctor",LOGLEVEL_CONSTRUCT);
 }
 
 // protected
 
+/** For use by copy ctor and assignment operator. */
 void constant::copy(const constant & other)
 {
-       basic::copy(other);
-       name=other.name;
-       serial=other.serial;
-       ef=other.ef;
-       if (other.number != 0) {
+       inherited::copy(other);
+       name = other.name;
+       serial = other.serial;
+       ef = other.ef;
+       if (other.number != 0)
                number = new numeric(*other.number);
-       } else {
+       else
                number = 0;
-       }
 }
 
 void constant::destroy(bool call_parent)
 {
        delete number;
        if (call_parent)
-               basic::destroy(call_parent);
+               inherited::destroy(call_parent);
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
@@ -77,13 +76,15 @@ void constant::destroy(bool call_parent)
 constant::constant(const std::string & initname, evalffunctype efun)
   : basic(TINFO_constant), name(initname), ef(efun), number(0), serial(next_serial++)
 {
-       debugmsg("constant constructor from string, function",LOGLEVEL_CONSTRUCT);
+       debugmsg("constant ctor from string, function",LOGLEVEL_CONSTRUCT);
+       setflag(status_flags::evaluated);
 }
 
 constant::constant(const std::string & initname, const numeric & initnumber)
   : basic(TINFO_constant), name(initname), ef(0), number(new numeric(initnumber)), serial(next_serial++)
 {
-       debugmsg("constant constructor from string, numeric",LOGLEVEL_CONSTRUCT);
+       debugmsg("constant ctor from string, numeric",LOGLEVEL_CONSTRUCT);
+       setflag(status_flags::evaluated);
 }
 
 //////////
@@ -93,7 +94,7 @@ constant::constant(const std::string & initname, const numeric & initnumber)
 /** Construct object from archive_node. */
 constant::constant(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("constant constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("constant ctor from archive_node", LOGLEVEL_CONSTRUCT);
 }
 
 /** Unarchive the object. */
@@ -161,7 +162,7 @@ ex constant::evalf(int level) const
        if (ef!=0) {
                return ef();
        } else if (number != 0) {
-               return *number;
+               return number->evalf();
        }
        return *this;
 }
@@ -193,6 +194,17 @@ bool constant::is_equal_same_type(const basic & other) const
        return serial==o->serial;
 }
 
+unsigned constant::calchash(void) const
+{
+       hashvalue = golden_ratio_hash(tinfo() ^ serial);
+       // mask out numeric hashes:
+       hashvalue &= 0x7FFFFFFFU;
+       
+       setflag(status_flags::hash_calculated);
+       
+       return hashvalue;
+}
+
 //////////
 // new virtual functions which can be overridden by derived classes
 //////////
@@ -209,7 +221,7 @@ bool constant::is_equal_same_type(const basic & other) const
 // static member variables
 //////////
 
-unsigned constant::next_serial=0;
+unsigned constant::next_serial = 0;
 
 //////////
 // global constants
@@ -225,6 +237,4 @@ const constant Euler("Euler", EulerEvalf);
 /** Catalan's constant. (0.91597...)  Diverts straight into CLN for evalf(). */
 const constant Catalan("Catalan", CatalanEvalf);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index f29e546..b30fc26 100644 (file)
 
 #include <string>
 #include "basic.h"
+#include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 typedef ex (*evalffunctype)(void);
        
@@ -39,38 +38,39 @@ typedef ex (*evalffunctype)(void);
 class constant : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(constant, basic)
-
+       
 // member functions
-
-       // other constructors
+       
+       // other ctors
 public:
-       constant(const std::string & initname, evalffunctype efun=0);
+       constant(const std::string & initname, evalffunctype efun = 0);
        constant(const std::string & initname, const numeric & initnumber);
-
+       
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned upper_precedence=0) const;
+       void print(std::ostream & os, unsigned upper_precedence = 0) const;
        void printraw(std::ostream & os) const;
        void printtree(std::ostream & os, unsigned indent) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
-       ex evalf(int level=0) const;
+       void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+       ex evalf(int level = 0) const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
+       unsigned calchash(void) const;
        
        // new virtual functions which can be overridden by derived classes
        // none
-
+       
        // non-virtual functions in this class
        // none
-
+       
 // member variables
-
+       
 private:
-       std::string name;
+       std::string name;   ///< printname of this constant
        evalffunctype ef;
-       numeric * number;
-       unsigned serial;  //!  unique serial number for comparision
+       numeric *number;    ///< numerical value this constant evalf()s to
+       unsigned serial;    ///< unique serial number for comparison
        static unsigned next_serial;
 };
 
@@ -78,8 +78,12 @@ extern const constant Pi;
 extern const constant Catalan;
 extern const constant Euler;
 
-#ifndef NO_NAMESPACE_GINAC
+// utility functions
+inline const constant &ex_to_constant(const ex &e)
+{
+       return static_cast<const constant &>(*e.bp);
+}
+
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_CONSTANT_H__
index d2c5bb4..80fb9fa 100755 (executable)
@@ -132,7 +132,7 @@ $constructors_implementation=generate(
        <<'END_OF_CONSTRUCTORS_IMPLEMENTATION','const ex & param${N}',', ','    seq.push_back(param${N});',"\n");
 ${CONTAINER}::${CONTAINER}(${SEQ1}) : basic(TINFO_${CONTAINER})
 {
-       debugmsg(\"${CONTAINER} constructor from ${N}*ex\",LOGLEVEL_CONSTRUCT);
+       debugmsg(\"${CONTAINER} ctor from ${N}*ex\",LOGLEVEL_CONSTRUCT);
        RESERVE(seq,${N});
 ${SEQ2}
 }
@@ -183,9 +183,7 @@ $interface=<<END_OF_INTERFACE;
 #include "basic.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 // Cint does not like ${STLHEADER}<..,default_alloc> but malloc_alloc is
@@ -263,9 +261,7 @@ inline ${CONTAINER} &ex_to_nonconst_${CONTAINER}(const ex &e)
        return static_cast<${CONTAINER} &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_${CONTAINER_UC}_H__
 
@@ -313,23 +309,21 @@ $implementation=<<END_OF_IMPLEMENTATION;
 #include "archive.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(${CONTAINER}, basic)
 
 ${RESERVE_IMPLEMENTATION}
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
 ${CONTAINER}::${CONTAINER}() : basic(TINFO_${CONTAINER})
 {
-       debugmsg("${CONTAINER} default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("${CONTAINER} default ctor",LOGLEVEL_CONSTRUCT);
 }
 
 // protected
@@ -347,14 +341,14 @@ void ${CONTAINER}::destroy(bool call_parent)
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
 
 ${CONTAINER}::${CONTAINER}(${STLT} const & s, bool discardable) :  basic(TINFO_${CONTAINER})
 {
-       debugmsg("${CONTAINER} constructor from ${STLT}", LOGLEVEL_CONSTRUCT);
+       debugmsg("${CONTAINER} ctor from ${STLT}", LOGLEVEL_CONSTRUCT);
        if (discardable) {
                seq.swap(const_cast<${STLT} &>(s));
        } else {
@@ -364,7 +358,7 @@ ${CONTAINER}::${CONTAINER}(${STLT} const & s, bool discardable) :  basic(TINFO_$
 
 ${CONTAINER}::${CONTAINER}(${STLT} * vp) : basic(TINFO_${CONTAINER})
 {
-       debugmsg("${CONTAINER} constructor from ${STLT} *",LOGLEVEL_CONSTRUCT);
+       debugmsg("${CONTAINER} ctor from ${STLT} *",LOGLEVEL_CONSTRUCT);
        GINAC_ASSERT(vp!=0);
        seq.swap(*vp);
        delete vp;
@@ -379,7 +373,7 @@ ${constructors_implementation}
 /** Construct object from archive_node. */
 ${CONTAINER}::${CONTAINER}(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("${CONTAINER} constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("${CONTAINER} ctor from archive_node", LOGLEVEL_CONSTRUCT);
        for (unsigned int i=0; true; i++) {
                ex e;
                if (n.find_ex("seq", e, sym_lst, i))
@@ -753,7 +747,7 @@ ${STLT} * ${CONTAINER}::subschildren(const lst & ls, const lst & lr) const
 
 // protected
 
-unsigned ${CONTAINER}::precedence=10;
+unsigned ${CONTAINER}::precedence = 10;
 
 //////////
 // global constants
@@ -762,9 +756,7 @@ unsigned ${CONTAINER}::precedence=10;
 const ${CONTAINER} some_${CONTAINER};
 const std::type_info & typeid_${CONTAINER} = typeid(some_${CONTAINER});
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 END_OF_IMPLEMENTATION
 
index 91ea079..08457b5 100644 (file)
@@ -44,7 +44,7 @@
 // #define LOGMASK (LOGLEVEL_PRINT | LOGLEVEL_ASSIGNMENT | LOGLEVEL_OPERATOR | LOGLEVEL_DUPLICATE | LOGLEVEL_OPERATOR | LOGLEVEL_MEMBER_FUNCTION | LOGLEVEL_NONMEMBER_FUNCTION)
 
 #ifdef VERBOSE
-#define debugmsg(msg, loglevel) if ((loglevel) & ~LOGMASK) std::clog << (msg) << endl;
+#define debugmsg(msg, loglevel) if ((loglevel) & ~LOGMASK) std::clog << (msg) << std::endl;
 #else
 #define debugmsg(msg, loglevel)
 #endif // def VERBOSE
index 1fb016c..6acde9f 100644 (file)
 #include <iostream>
 #include <stdexcept>
 
-#include "ex.h"
+#if defined(VERBOSE)
+#  define GINAC_CONDITIONAL_INLINE
+#  include "ex.h"
+#  undef GINAC_CONDITIONAL_INLINE
+#else
+#  include "ex.h"
+#endif
+
 #include "add.h"
 #include "mul.h"
 #include "ncmul.h"
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// other ctors
 //////////
 
-// public
-
-#ifndef INLINE_EX_CONSTRUCTORS
-
-ex::ex() : bp(_ex0().bp)
-{
-       debugmsg("ex default constructor",LOGLEVEL_CONSTRUCT);
-       GINAC_ASSERT(_ex0().bp!=0);
-       GINAC_ASSERT(_ex0().bp->flags & status_flags::dynallocated);
-       GINAC_ASSERT(bp!=0);
-       ++bp->refcount;
-}
-
-ex::~ex()
-{
-       debugmsg("ex destructor",LOGLEVEL_DESTRUCT);
-       GINAC_ASSERT(bp!=0);
-       GINAC_ASSERT(bp->flags & status_flags::dynallocated);
-       if (--bp->refcount == 0) {
-               delete bp;
-       }
-}
-
-ex::ex(const ex & other) : bp(other.bp)
-{
-       debugmsg("ex copy constructor",LOGLEVEL_CONSTRUCT);
-       GINAC_ASSERT(bp!=0);
-       GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
-       ++bp->refcount;
-}
-
-const ex & ex::operator=(const ex & other)
-{
-       debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);
-       GINAC_ASSERT(bp!=0);
-       GINAC_ASSERT(bp->flags & status_flags::dynallocated);
-       GINAC_ASSERT(other.bp!=0);
-       GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
-       ++other.bp->refcount;
-       basic * tmpbp = other.bp;
-       if (--bp->refcount==0)
-               delete bp;
-       bp = tmpbp;
-       return *this;
-}
-
-#endif // ndef INLINE_EX_CONSTRUCTORS
-
-//////////
-// other constructors
-//////////
-
-// public
-
-#ifndef INLINE_EX_CONSTRUCTORS
-
-ex::ex(const basic & other)
-{
-       debugmsg("ex constructor from basic",LOGLEVEL_CONSTRUCT);
-       construct_from_basic(other);
-}
-
-ex::ex(int i)
-{
-       debugmsg("ex constructor from int",LOGLEVEL_CONSTRUCT);
-       construct_from_int(i);
-}
-
-ex::ex(unsigned int i)
-{
-       debugmsg("ex constructor from unsigned int",LOGLEVEL_CONSTRUCT);
-       construct_from_uint(i);
-}
-
-ex::ex(long i)
-{
-       debugmsg("ex constructor from long",LOGLEVEL_CONSTRUCT);
-       construct_from_long(i);
-}
-
-ex::ex(unsigned long i)
-{
-       debugmsg("ex constructor from unsigned long",LOGLEVEL_CONSTRUCT);
-       construct_from_ulong(i);
-}
-
-ex::ex(double const d)
-{
-       debugmsg("ex constructor from double",LOGLEVEL_CONSTRUCT);
-       construct_from_double(d);
-}
-
-ex::ex(const std::string &s, const ex &l)
-{
-       debugmsg("ex constructor from string,lst",LOGLEVEL_CONSTRUCT);
-       construct_from_string_and_lst(s, l);
-}
-
-#endif // ndef INLINE_EX_CONSTRUCTORS
+// none (all inlined)
 
 //////////
 // functions overriding virtual functions from bases classes
@@ -160,7 +67,7 @@ ex::ex(const std::string &s, const ex &l)
 
 // public
 
-/** Swap the contents of two expressions. */
+/** Efficiently swap the contents of two expressions. */
 void ex::swap(ex & other)
 {
        debugmsg("ex swap",LOGLEVEL_MEMBER_FUNCTION);
@@ -170,9 +77,9 @@ void ex::swap(ex & other)
        GINAC_ASSERT(other.bp!=0);
        GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
        
-       basic * tmpbp=bp;
-       bp=other.bp;
-       other.bp=tmpbp;
+       basic * tmpbp = bp;
+       bp = other.bp;
+       other.bp = tmpbp;
 }
 
 /** Output formatted to be useful as ginsh input. */
@@ -183,6 +90,7 @@ void ex::print(std::ostream & os, unsigned upper_precedence) const
        bp->print(os,upper_precedence);
 }
 
+/** Unreadable output with detailed type information. */
 void ex::printraw(std::ostream & os) const
 {
        debugmsg("ex printraw",LOGLEVEL_PRINT);
@@ -192,6 +100,7 @@ void ex::printraw(std::ostream & os) const
        os << ")";
 }
 
+/** Very detailed and unreadable output with type information and all this. */
 void ex::printtree(std::ostream & os, unsigned indent) const
 {
        debugmsg("ex printtree",LOGLEVEL_PRINT);
@@ -391,32 +300,6 @@ ex ex::rhs(void) const
        return (*static_cast<relational *>(bp)).rhs();
 }
 
-#ifndef INLINE_EX_CONSTRUCTORS
-int ex::compare(const ex & other) const
-{
-       GINAC_ASSERT(bp!=0);
-       GINAC_ASSERT(other.bp!=0);
-       if (bp==other.bp) {
-               // special case: both expression point to same basic, trivially equal
-               return 0; 
-       }
-       return bp->compare(*other.bp);
-}
-#endif // ndef INLINE_EX_CONSTRUCTORS
-
-#ifndef INLINE_EX_CONSTRUCTORS
-bool ex::is_equal(const ex & other) const
-{
-       GINAC_ASSERT(bp!=0);
-       GINAC_ASSERT(other.bp!=0);
-       // if both expression point to same basic they are trivially equal
-       if (bp==other.bp)
-               return true;
-       
-       return bp->is_equal(*other.bp);
-}
-#endif // ndef INLINE_EX_CONSTRUCTORS
-
 unsigned ex::return_type(void) const
 {
        GINAC_ASSERT(bp!=0);
@@ -452,6 +335,8 @@ ex ex::exncmul(const ex & rh) const
 
 // private
 
+/** Make this ex writable (if more than one ex handle the same basic) by 
+ *  unlinking the object and creating an unshared copy of it. */
 void ex::makewriteable()
 {
        debugmsg("ex makewriteable",LOGLEVEL_MEMBER_FUNCTION);
@@ -467,21 +352,22 @@ void ex::makewriteable()
        GINAC_ASSERT(bp->refcount==1);
 }
 
+/** Ctor from basic implementation.
+ *  @see ex::ex(const basic &) */
 void ex::construct_from_basic(const basic & other)
 {
        if ((other.flags & status_flags::evaluated)==0) {
-               // cf. copy constructor
+               // cf. copy ctor
                const ex & tmpex = other.eval(1); // evaluate only one (top) level
                bp = tmpex.bp;
                GINAC_ASSERT(bp!=0);
                GINAC_ASSERT(bp->flags & status_flags::dynallocated);
                ++bp->refcount;
-               if ((other.flags & status_flags::dynallocated)&&(other.refcount==0)) {
+               if ((other.flags & status_flags::dynallocated)&&(other.refcount==0))
                        delete &const_cast<basic &>(other);
-               }
        } else {
                if (other.flags & status_flags::dynallocated) {
-                       // it's on the heap, so just copy bp:
+                       // ok, it is already on the heap, so just copy bp:
                        bp = &const_cast<basic &>(other);
                } else {
                        // create a duplicate on the heap:
@@ -651,6 +537,4 @@ void ex::construct_from_string_and_lst(const std::string &s, const ex &l)
 // none
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 30b40eb..0e2adaf 100644 (file)
 #ifndef __GINAC_EX_H__
 #define __GINAC_EX_H__
 
-#include <iostream>
 #include "basic.h"
 #include "operators.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
-
-class ex;
-class symbol;
-class lst;
 
 // Sorry, this is the only constant to pollute the global scope, the other ones
 // are defined in utils.h and not visible from outside.
-extern const ex & _ex0(void);     //  single ex(numeric(0))
+class ex;
+extern const ex & _ex0(void);     ///<  single ex(numeric(0))
 
-#define INLINE_EX_CONSTRUCTORS
+class symbol;
+class lst;
 
 /** Lightweight wrapper for GiNaC's symbolic objects.  Basically all it does is
  *  to hold a pointer to the other objects, manage the reference counting and
@@ -47,168 +42,28 @@ extern const ex & _ex0(void);     //  single ex(numeric(0))
 class ex
 {
        friend class basic;
-
+       
 // member functions
-
-       // default constructor, destructor, copy constructor assignment operator and helpers
+       
+       // default ctor, dtor, copy ctor assignment operator and helpers
 public:
-       ex()
-#ifdef INLINE_EX_CONSTRUCTORS
-            : bp(_ex0().bp)
-       {
-               GINAC_ASSERT(_ex0().bp!=0);
-               GINAC_ASSERT(_ex0().bp->flags & status_flags::dynallocated);
-               GINAC_ASSERT(bp!=0);
-               ++bp->refcount;
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-
-       ~ex()
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               GINAC_ASSERT(bp!=0);
-               GINAC_ASSERT(bp->flags & status_flags::dynallocated);
-               if (--bp->refcount == 0) {
-                       delete bp;
-               }
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-               
-       ex(const ex & other)
-#ifdef INLINE_EX_CONSTRUCTORS
-                            : bp(other.bp)
-       {
-               GINAC_ASSERT(bp!=0);
-               GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
-               ++bp->refcount;
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-               
-       const ex & operator=(const ex & other)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               GINAC_ASSERT(bp!=0);
-               GINAC_ASSERT(bp->flags & status_flags::dynallocated);
-               GINAC_ASSERT(other.bp!=0);
-               GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
-               ++other.bp->refcount;
-               basic * tmpbp=other.bp;
-               if (--bp->refcount==0) {
-                       delete bp;
-               }
-               bp=tmpbp;
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-               return *this;
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-
-
-       // other constructors
+       ex();
+       ~ex();
+       ex(const ex & other);
+       const ex & operator=(const ex & other);
+       // other ctors
 public:
-       ex(const basic & other)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_basic(other);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-       
-       ex(int i)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_int(i);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-
-       ex(unsigned int i)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_uint(i);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-       
-       ex(long i)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_long(i);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-
-       ex(unsigned long i)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_ulong(i);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-       
-       ex(double const d)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_double(d);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-
+       ex(const basic & other);
+       ex(int i);
+       ex(unsigned int i);
+       ex(long i);
+       ex(unsigned long i);
+       ex(double const d);
        /** Construct ex from string and a list of symbols. The input grammar is
         *  similar to the GiNaC output format. All symbols to be used in the
         *  expression must be specified in a lst in the second argument. Undefined
         *  symbols and other parser errors will throw an exception. */
-       ex(const std::string &s, const ex &l)
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               construct_from_string_and_lst(s, l);
-#ifdef OBSCURE_CINT_HACK
-               update_last_created_or_assigned_bp();
-#endif // def OBSCURE_CINT_HACK
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-
+       ex(const std::string &s, const ex &l);
        
        // functions overriding virtual functions from bases classes
        // none
@@ -260,40 +115,14 @@ public:
        ex & let_op(int i);
        ex lhs(void) const;
        ex rhs(void) const;
-       int compare(const ex & other) const
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               GINAC_ASSERT(bp!=0);
-               GINAC_ASSERT(other.bp!=0);
-               if (bp==other.bp) {
-                       // special case: both expression point to same basic, trivially equal
-                       return 0; 
-               }
-               return bp->compare(*other.bp);
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-       bool is_equal(const ex & other) const
-#ifdef INLINE_EX_CONSTRUCTORS
-       {
-               GINAC_ASSERT(bp!=0);
-               GINAC_ASSERT(other.bp!=0);
-               if (bp==other.bp) {
-                       // special case: both expression point to same basic, trivially equal
-                       return true; 
-               }
-               return bp->is_equal(*other.bp);
-       }
-#else
-;
-#endif // def INLINE_EX_CONSTRUCTORS
-       bool is_zero(void) const {return compare(_ex0())==0;};
-               
+       int compare(const ex & other) const;
+       bool is_equal(const ex & other) const;
+       bool is_zero(void) const { return is_equal(_ex0()); }
+       
        unsigned return_type(void) const;
        unsigned return_type_tinfo(void) const;
        unsigned gethash(void) const;
-
+       
        ex exadd(const ex & rh) const;
        ex exmul(const ex & rh) const;
        ex exncmul(const ex & rh) const;
@@ -326,16 +155,16 @@ protected:
                                delete last_created_or_assigned_bp;
                        }
                }
-               last_created_or_assigned_bp=bp;
+               last_created_or_assigned_bp = bp;
                ++last_created_or_assigned_bp->refcount;
-               last_created_or_assigned_exp=(long)(void *)(this);
+               last_created_or_assigned_exp = (long)(void *)(this);
        }
 #endif // def OBSCURE_CINT_HACK
 
 // member variables
 
 public:
-       basic *bp;
+       basic *bp;      ///< pointer to basic object managed by this
 #ifdef OBSCURE_CINT_HACK
        static basic * last_created_or_assigned_bp;
        static basic * dummy_bp;
@@ -343,6 +172,153 @@ public:
 #endif // def OBSCURE_CINT_HACK
 };
 
+
+// performance-critical inlined method implementations
+
+inline
+ex::ex() : bp(_ex0().bp)
+{
+       /*debugmsg("ex default ctor",LOGLEVEL_CONSTRUCT);*/
+       GINAC_ASSERT(_ex0().bp!=0);
+       GINAC_ASSERT(_ex0().bp->flags & status_flags::dynallocated);
+       GINAC_ASSERT(bp!=0);
+       ++bp->refcount;
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::~ex()
+{
+       /*debugmsg("ex dtor",LOGLEVEL_DESTRUCT);*/
+       GINAC_ASSERT(bp!=0);
+       GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+       if (--bp->refcount == 0)
+               delete bp;
+}
+
+inline
+ex::ex(const ex & other) : bp(other.bp)
+{
+       /*debugmsg("ex copy ctor",LOGLEVEL_CONSTRUCT);*/
+       GINAC_ASSERT(bp!=0);
+       GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+       ++bp->refcount;
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+const ex & ex::operator=(const ex & other)
+{
+       /*debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);*/
+       GINAC_ASSERT(bp!=0);
+       GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+       GINAC_ASSERT(other.bp!=0);
+       GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
+       if (--bp->refcount==0)
+               delete bp;
+       ++other.bp->refcount;
+       bp = other.bp;
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+       return *this;
+}
+
+inline
+ex::ex(const basic & other)
+{
+       /*debugmsg("ex ctor from basic",LOGLEVEL_CONSTRUCT);*/
+       construct_from_basic(other);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::ex(int i)
+{
+       /*debugmsg("ex ctor from int",LOGLEVEL_CONSTRUCT);*/
+       construct_from_int(i);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::ex(unsigned int i)
+{
+       /*debugmsg("ex ctor from unsigned int",LOGLEVEL_CONSTRUCT);*/
+       construct_from_uint(i);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::ex(long i)
+{
+       /*debugmsg("ex ctor from long",LOGLEVEL_CONSTRUCT);*/
+       construct_from_long(i);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::ex(unsigned long i)
+{
+       /*debugmsg("ex ctor from unsigned long",LOGLEVEL_CONSTRUCT);*/
+       construct_from_ulong(i);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::ex(double const d)
+{
+       /*debugmsg("ex ctor from double",LOGLEVEL_CONSTRUCT);*/
+       construct_from_double(d);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+ex::ex(const std::string &s, const ex &l)
+{
+       /*debugmsg("ex ctor from string,lst",LOGLEVEL_CONSTRUCT);*/
+       construct_from_string_and_lst(s, l);
+#ifdef OBSCURE_CINT_HACK
+       update_last_created_or_assigned_bp();
+#endif // def OBSCURE_CINT_HACK
+}
+
+inline
+int ex::compare(const ex & other) const
+{
+       GINAC_ASSERT(bp!=0);
+       GINAC_ASSERT(other.bp!=0);
+       if (bp==other.bp)  // trivial case: both expressions point to same basic
+               return 0;
+       return bp->compare(*other.bp);
+}
+
+inline
+bool ex::is_equal(const ex & other) const
+{
+       GINAC_ASSERT(bp!=0);
+       GINAC_ASSERT(other.bp!=0);
+       if (bp==other.bp)  // trivial case: both expressions point to same basic
+               return true;
+       return bp->is_equal(*other.bp);
+}
+
+
 // utility functions
 inline bool are_ex_trivially_equal(const ex &e1, const ex &e2)
 {
@@ -416,9 +392,6 @@ inline bool is_zero(const ex & thisex)
 inline void swap(ex & e1, ex & e2)
 { e1.swap(e2); }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_EX_H__
-
index 30562cd..2f34b4b 100644 (file)
 #include "ex.h"
 #include "numeric.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** A pair of expressions.
- *  This similar to, but slightly extended STL's pair<> but we need to account
- *  for methods like .compare() */
+ *  This is similar to STL's pair<>.  It is slightly extended since we need to
+ *  account for methods like .compare().  Also, since this is meant for use by
+ *  class expairseq it must satisfy the invariance that the member coeff must
+ *  be of type numeric. */
 class expair
 {
 public:
-       expair() {}
-       ~expair() {}
-
+       expair() : rest(0), coeff(1) { }
+       ~expair() { }
        expair(const expair & other) : rest(other.rest), coeff(other.coeff)
        {
                GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
        }
-
        const expair & operator=(const expair & other)
        {
                if (this != &other) {
-                       rest=other.rest;
-                       coeff=other.coeff;
+                       rest = other.rest;
+                       coeff = other.coeff;
                }
                return *this;
        }
-
+       
+       /** Construct an expair from two ex. */
        expair(const ex & r, const ex & c) : rest(r), coeff(c)
        {
                GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
        }
        
-       bool is_numeric_with_coeff_1(void) const
-       {
-               GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
-               return is_ex_exactly_of_type(rest,numeric)
-                   && (coeff.is_equal(ex(1)));
-       }
-
+       /** Member-wise check for canonical ordering equality. */
        bool is_equal(const expair & other) const
        {
                return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
        }
-
+       
+       /** Member-wise check for canonical ordering lessness. */
        bool is_less(const expair & other) const 
        {
-               return (rest.compare(other.rest)<0)
-                   || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
+               int restcmp = rest.compare(other.rest);
+               return ((restcmp<0) ||
+                       (!(restcmp>0) && (coeff.compare(other.coeff)<0)));
        }
-
+       
+       /** Member-wise check for canonical ordering. */
        int compare(const expair & other) const
        {
-               int cmpval=rest.compare(other.rest);
-               if (cmpval!=0) return cmpval;
-               cmpval=coeff.compare(other.coeff);
-               return cmpval;
-       }
-
-       bool is_less_old2(const expair & other) const 
-       {
-               /*
-               bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
-               bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
-               if (this_numeric_with_coeff_1) {
-                       if (other_numeric_with_coeff_1) {
-                               // both have coeff 1: compare rests
-                               return rest.compare(other.rest)<0;
-                       }
-                       // only this has coeff 1: >
-                       return false;
-               } else if (other_numeric_with_coeff_1) {
-                       // only other has coeff 1: <
-                       return true;
-               }
-               return (rest.compare(other.rest)<0)
-                   || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
-               */
-               if (is_ex_exactly_of_type(rest,numeric) &&
-                       is_ex_exactly_of_type(other.rest,numeric)) {
-                       if (coeff.is_equal(ex(1))) {
-                               if ((other.coeff).is_equal(ex(1))) {
-                                       // both have coeff 1: compare rests
-                                       return rest.compare(other.rest)<0;
-                               }
-                               // only this has coeff 1: >
-                               return false;
-                       } else if ((other.coeff).is_equal(ex(1))) {
-                               // only other has coeff 1: <
-                               return true;
-                       }
-                       // neither has coeff 1: usual compare        
-               }
-               return (rest.compare(other.rest)<0)
-                   || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
+               int restcmp = rest.compare(other.rest);
+               if (restcmp!=0)
+                       return restcmp;
+               else
+                       return coeff.compare(other.coeff);
        }
-
-       int compare_old2(const expair & other) const
-       {
-               if (is_ex_exactly_of_type(rest,numeric) &&
-                       is_ex_exactly_of_type(other.rest,numeric)) {
-                       if ((coeff).is_equal(ex(1))) {
-                               if ((other.coeff).is_equal(ex(1))) {
-                                       // both have coeff 1: compare rests
-                                       return rest.compare(other.rest);
-                               }
-                               // only this has coeff 1: >
-                               return 1;
-                       } else if ((other.coeff).is_equal(ex(1))) {
-                               // only other has coeff 1: <
-                               return -1;
-                       }
-                       // neither has coeff 1: usual compare        
-               }
-               /*
-               bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
-               bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
-               if (this_numeric_with_coeff_1) {
-                       if (other_numeric_with_coeff_1) {
-                               // both have coeff 1: compare rests
-                               return rest.compare(other.rest);
-                       }
-                       // only this has coeff 1: >
-                       return 1;
-               } else if (other_numeric_with_coeff_1) {
-                       // only other has coeff 1: <
-                       return -1;
-                       // neither has coeff 1: usual compare        
-               }
-               */
-               int cmpval=rest.compare(other.rest);
-               if (cmpval!=0) return cmpval;
-               return coeff.compare(other.coeff);
-       }
-
-       bool is_less_old(const expair & other) const 
-       {
-               return (rest.compare(other.rest)<0)
-                   || (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
-       }
-       int compare_old(const expair & other) const
-       {
-               int cmpval=rest.compare(other.rest);
-               if (cmpval!=0) return cmpval;
-               cmpval=coeff.compare(other.coeff);
-               return cmpval;
-       }
-
+       
+       /** Output to ostream in ugly raw format. */
        void printraw(std::ostream & os) const
        {
                os << "expair(";
@@ -181,31 +90,29 @@ public:
                coeff.printraw(os);
                os << ")";
        }
-
-       ex rest;
-       ex coeff;
-};
-
-class expair_is_less
-{
-public:
-       bool operator()(const expair & lh, const expair & rh) const
+       
+       /** True if this is of the form (numeric,ex(1)). */
+       bool is_canonical_numeric(void) const
        {
-               return lh.is_less(rh);
+               GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
+               return (is_ex_exactly_of_type(rest,numeric) &&
+                       (coeff.is_equal(1)));
        }
+       
+       ex rest;    ///< first member of pair, an arbitrary expression
+       ex coeff;   ///< second member of pair, must be numeric
 };
 
-class expair_is_less_old
+/** Function object for insertion into third argument of STL's sort() etc. */
+class expair_is_less
 {
 public:
-       bool operator()(const expair & lh, const expair & rh) const
+       bool operator()(const expair &lh, const expair &rh) const
        {
-               return lh.is_less_old(rh);
+               return lh.is_less(rh);
        }
 };
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_EXPAIR_H__
index 246424f..3e84134 100644 (file)
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
-namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
+#if EXPAIRSEQ_USE_HASHTAB
+#include <cmath>
+#endif // EXPAIRSEQ_USE_HASHTAB
 
-#ifdef EXPAIRSEQ_USE_HASHTAB
-#error "FIXME: expair_needs_further_processing not yet implemented for hashtabs, sorry. A.F."
-#endif // def EXPAIRSEQ_USE_HASHTAB
+namespace GiNaC {
 
 GINAC_IMPLEMENT_REGISTERED_CLASS_NO_CTORS(expairseq, basic)
 
@@ -47,25 +45,25 @@ GINAC_IMPLEMENT_REGISTERED_CLASS_NO_CTORS(expairseq, basic)
 class epp_is_less
 {
 public:
-       bool operator()(const epp & lh, const epp & rh) const
+       bool operator()(const epp &lh, const epp &rh) const
        {
                return (*lh).is_less(*rh);
        }
 };
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
-expairseq::expairseq(const expairseq & other)
+expairseq::expairseq(const expairseq &other)
 {
-       debugmsg("expairseq copy constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("expairseq copy ctor",LOGLEVEL_CONSTRUCT);
        copy(other);
 }
 
-const expairseq & expairseq::operator=(const expairseq & other)
+const expairseq &expairseq::operator=(const expairseq &other)
 {
        debugmsg("expairseq operator=",LOGLEVEL_ASSIGNMENT);
        if (this != &other) {
@@ -77,18 +75,19 @@ const expairseq & expairseq::operator=(const expairseq & other)
 
 // protected
 
-void expairseq::copy(const expairseq & other)
+/** For use by copy ctor and assignment operator. */
+void expairseq::copy(const expairseq &other)
 {
        inherited::copy(other);
-       seq=other.seq;
-       overall_coeff=other.overall_coeff;
-#ifdef EXPAIRSEQ_USE_HASHTAB
+       seq = other.seq;
+       overall_coeff = other.overall_coeff;
+#if EXPAIRSEQ_USE_HASHTAB
        // copy hashtab
-       hashtabsize=other.hashtabsize;
+       hashtabsize = other.hashtabsize;
        if (hashtabsize!=0) {
-       hashmask=other.hashmask;
+               hashmask = other.hashmask;
                hashtab.resize(hashtabsize);
-               epvector::const_iterator osb=other.seq.begin();
+               epvector::const_iterator osb = other.seq.begin();
                for (unsigned i=0; i<hashtabsize; ++i) {
                        hashtab[i].clear();
                        for (epplist::const_iterator cit=other.hashtab[i].begin();
@@ -99,56 +98,45 @@ void expairseq::copy(const expairseq & other)
        } else {
                hashtab.clear();
        }
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
+}
+
+void expairseq::destroy(bool call_parent)
+{
+       if (call_parent)
+               basic::destroy(call_parent);
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
-expairseq::expairseq(const ex & lh, const ex & rh) : inherited(TINFO_expairseq)
+expairseq::expairseq(const ex &lh, const ex &rh) : inherited(TINFO_expairseq)
 {
-       debugmsg("expairseq constructor from ex,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("expairseq ctor from ex,ex",LOGLEVEL_CONSTRUCT);
        construct_from_2_ex(lh,rh);
        GINAC_ASSERT(is_canonical());
 }
 
-expairseq::expairseq(const exvector & v) : inherited(TINFO_expairseq)
+expairseq::expairseq(const exvector &v) : inherited(TINFO_expairseq)
 {
-       debugmsg("expairseq constructor from exvector",LOGLEVEL_CONSTRUCT);
+       debugmsg("expairseq ctor from exvector",LOGLEVEL_CONSTRUCT);
        construct_from_exvector(v);
        GINAC_ASSERT(is_canonical());
 }
 
-/*
-expairseq::expairseq(const epvector & v, bool do_not_canonicalize)
-  : inherited(TINFO_expairseq)
-{
-       debugmsg("expairseq constructor from epvector",LOGLEVEL_CONSTRUCT);
-       if (do_not_canonicalize) {
-               seq=v;
-#ifdef EXPAIRSEQ_USE_HASHTAB
-               combine_same_terms(); // to build hashtab
-#endif // def EXPAIRSEQ_USE_HASHTAB
-       } else {
-               construct_from_epvector(v);
-       }
-       GINAC_ASSERT(is_canonical());
-}
-*/
-
-expairseq::expairseq(const epvector & v, const ex & oc)
+expairseq::expairseq(const epvector &v, const ex &oc)
   : inherited(TINFO_expairseq), overall_coeff(oc)
 {
-       debugmsg("expairseq constructor from epvector,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("expairseq ctor from epvector,ex",LOGLEVEL_CONSTRUCT);
        construct_from_epvector(v);
        GINAC_ASSERT(is_canonical());
 }
 
-expairseq::expairseq(epvector * vp, const ex & oc)
+expairseq::expairseq(epvector *vp, const ex &oc)
   : inherited(TINFO_expairseq), overall_coeff(oc)
 {
-       debugmsg("expairseq constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("expairseq ctor from epvector *,ex",LOGLEVEL_CONSTRUCT);
        GINAC_ASSERT(vp!=0);
        construct_from_epvector(*vp);
        delete vp;
@@ -161,11 +149,11 @@ expairseq::expairseq(epvector * vp, const ex & oc)
 
 /** Construct object from archive_node. */
 expairseq::expairseq(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        , hashtabsize(0)
 #endif
 {
-       debugmsg("expairseq constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("expairseq ctor from archive_node", LOGLEVEL_CONSTRUCT);
        for (unsigned int i=0; true; i++) {
                ex rest;
                ex coeff;
@@ -202,13 +190,13 @@ void expairseq::archive(archive_node &n) const
 
 // public
 
-basic * expairseq::duplicate() const
+basic *expairseq::duplicate() const
 {
        debugmsg("expairseq duplicate",LOGLEVEL_DUPLICATE);
        return new expairseq(*this);
 }
 
-void expairseq::print(std::ostream & os, unsigned upper_precedence) const
+void expairseq::print(std::ostream &os, unsigned upper_precedence) const
 {
        debugmsg("expairseq print",LOGLEVEL_PRINT);
        os << "[[";
@@ -216,10 +204,10 @@ void expairseq::print(std::ostream & os, unsigned upper_precedence) const
        os << "]]";
 }
 
-void expairseq::printraw(std::ostream & os) const
+void expairseq::printraw(std::ostream &os) const
 {
        debugmsg("expairseq printraw",LOGLEVEL_PRINT);
-
+       
        os << "expairseq(";
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
                os << "(";
@@ -231,7 +219,7 @@ void expairseq::printraw(std::ostream & os) const
        os << ")";
 }
 
-void expairseq::printtree(std::ostream & os, unsigned indent) const
+void expairseq::printtree(std::ostream &os, unsigned indent) const
 {
        debugmsg("expairseq printtree",LOGLEVEL_PRINT);
 
@@ -243,9 +231,8 @@ void expairseq::printtree(std::ostream & os, unsigned indent) const
        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) {
+               if (i!=seq.size()-1)
                        os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
-               }
        }
        if (!overall_coeff.is_equal(default_overall_coeff())) {
                os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
@@ -253,23 +240,24 @@ void expairseq::printtree(std::ostream & os, unsigned indent) const
                overall_coeff.printtree(os,indent+delta_indent);
        }
        os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        os << std::string(indent+delta_indent,' ')
           << "hashtab size " << hashtabsize << std::endl;
        if (hashtabsize==0) return;
 #define MAXCOUNT 5
        unsigned count[MAXCOUNT+1];
-       for (int i=0; i<MAXCOUNT+1; ++i) count[i]=0;
+       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;
+               this_bin_fill = 0;
                if (hashtab[i].size()>0) {
                        os << std::string(indent+delta_indent,' ') 
                           << "bin " << i << " with entries ";
                        for (epplist::const_iterator it=hashtab[i].begin();
-                                it!=hashtab[i].end(); ++it) {
+                            it!=hashtab[i].end(); ++it) {
                                os << *it-seq.begin() << " ";
                                ++this_bin_fill;
                        }
@@ -277,18 +265,18 @@ void expairseq::printtree(std::ostream & os, unsigned indent) const
                        cum_fill += this_bin_fill;
                        cum_fill_sq += this_bin_fill*this_bin_fill;
                }
-               if (this_bin_fill<MAXCOUNT) {
+               if (this_bin_fill<MAXCOUNT)
                        ++count[this_bin_fill];
-               } else {
+               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);
+               if (k>0)
+                       fact *= k;
+               double prob = std::pow(lambda,k)/fact * std::exp(-lambda);
                cum_prob += prob;
                os << std::string(indent+delta_indent,' ') << "bins with " << k << " entries: "
                   << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
@@ -304,7 +292,7 @@ void expairseq::printtree(std::ostream & os, unsigned indent) const
        os << std::string(indent+delta_indent,' ') << "average fill: "
           << (1.0*cum_fill)/hashtabsize
           << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl;
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
 }
 
 bool expairseq::info(unsigned inf) const
@@ -314,37 +302,34 @@ bool expairseq::info(unsigned inf) const
 
 unsigned expairseq::nops() const
 {
-       if (overall_coeff.is_equal(default_overall_coeff())) {
+       if (overall_coeff.is_equal(default_overall_coeff()))
                return seq.size();
-       }
-       return seq.size()+1;
+       else
+               return seq.size()+1;
 }
 
 ex expairseq::op(int i) const
 {
-       if (unsigned(i)<seq.size()) {
+       if (unsigned(i)<seq.size())
                return recombine_pair_to_ex(seq[i]);
-       }
        GINAC_ASSERT(!overall_coeff.is_equal(default_overall_coeff()));
        return overall_coeff;
 }
 
-ex & expairseq::let_op(int i)
+ex &expairseq::let_op(int i)
 {
        throw(std::logic_error("let_op not defined for expairseq and derived classes (add,mul,...)"));
 }
 
 ex expairseq::eval(int level) const
 {
-       if ((level==1)&&(flags & status_flags::evaluated)) {
+       if ((level==1) && (flags &status_flags::evaluated))
                return *this;
-       }
-
-       epvector * vp=evalchildren(level);
-       if (vp==0) {
+       
+       epvector *vp = evalchildren(level);
+       if (vp==0)
                return this->hold();
-       }
-
+       
        return (new expairseq(vp,overall_coeff))->setflag(status_flags::dynallocated | status_flags::evaluated);
 }
 
@@ -359,47 +344,45 @@ ex expairseq::normal(lst &sym_lst, lst &repl_lst, int level) const
        return n.bp->basic::normal(sym_lst,repl_lst,level);
 }
 
-ex expairseq::subs(const lst & ls, const lst & lr) const
+ex expairseq::subs(const lst &ls, const lst &lr) const
 {
-       epvector * vp=subschildren(ls,lr);
-       if (vp==0) {
+       epvector *vp = subschildren(ls,lr);
+       if (vp==0)
                return *this;
-       }
+       
        return thisexpairseq(vp,overall_coeff);
 }
 
 // protected
 
-/** Implementation of ex::diff() for an expairseq. It differentiates all elements of the
- *  sequence.
+/** Implementation of ex::diff() for an expairseq.
+ *  It differentiates all elements of the sequence.
  *  @see ex::diff */
-ex expairseq::derivative(const symbol & s) const
+ex expairseq::derivative(const symbol &s) const
 {
        return thisexpairseq(diffchildren(s),overall_coeff);
 }
 
-int expairseq::compare_same_type(const basic & other) const
+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));
-
+       const expairseq &o = static_cast<const expairseq &>(const_cast<basic &>(other));
+       
        int cmpval;
        
        // compare number of elements
-       if (seq.size() != o.seq.size()) {
+       if (seq.size() != o.seq.size())
                return (seq.size()<o.seq.size()) ? -1 : 1;
-       }
-
+       
        // compare 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
+       if (cmpval!=0)
+               return cmpval;
+       
+#if EXPAIRSEQ_USE_HASHTAB
        GINAC_ASSERT(hashtabsize==o.hashtabsize);
        if (hashtabsize==0) {
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                epvector::const_iterator cit1 = seq.begin();
                epvector::const_iterator cit2 = o.seq.begin();
                epvector::const_iterator last1 = seq.end();
@@ -409,33 +392,33 @@ int expairseq::compare_same_type(const basic & other) const
                        cmpval = (*cit1).compare(*cit2);
                        if (cmpval!=0) return cmpval;
                }
-
+               
                GINAC_ASSERT(cit1==last1);
                GINAC_ASSERT(cit2==last2);
                
                return 0;
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        }
-
+       
        // compare number of elements in each hashtab entry
        for (unsigned i=0; i<hashtabsize; ++i) {
                unsigned cursize=hashtab[i].size();
-               if (cursize != o.hashtab[i].size()) {
+               if (cursize != o.hashtab[i].size())
                        return (cursize < o.hashtab[i].size()) ? -1 : 1;
-               }
        }
        
        // compare individual (sorted) hashtab entries
        for (unsigned i=0; i<hashtabsize; ++i) {
-               unsigned sz=hashtab[i].size();
+               unsigned sz = hashtab[i].size();
                if (sz>0) {
-                       const epplist & eppl1=hashtab[i];
-                       const epplist & eppl2=o.hashtab[i];
-                       epplist::const_iterator it1=eppl1.begin();
-                       epplist::const_iterator it2=eppl2.begin();
+                       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()) {
-                               cmpval=(*(*it1)).compare(*(*it2));
-                               if (cmpval!=0) return cmpval;
+                               cmpval = (*(*it1)).compare(*(*it2));
+                               if (cmpval!=0)
+                                       return cmpval;
                                ++it1;
                                ++it2;
                        }
@@ -443,35 +426,37 @@ int expairseq::compare_same_type(const basic & other) const
        }
        
        return 0; // equal
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
 }
 
-bool expairseq::is_equal_same_type(const basic & other) const
+bool expairseq::is_equal_same_type(const basic &other) const
 {
-       const expairseq & o=dynamic_cast<const expairseq &>(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;
-
+       if (seq.size()!=o.seq.size())
+               return false;
+       
        // compare overall_coeff
-       if (!overall_coeff.is_equal(o.overall_coeff)) return false;
-
-#ifdef EXPAIRSEQ_USE_HASHTAB
+       if (!overall_coeff.is_equal(o.overall_coeff))
+               return false;
+       
+#if EXPAIRSEQ_USE_HASHTAB
        // compare number of elements in each hashtab entry
        if (hashtabsize!=o.hashtabsize) {
-               cout << "this:" << std::endl;
-               printtree(cout,0);
-               cout << "other:" << std::endl;
-               other.printtree(cout,0);
+               std::cout << "this:" << std::endl;
+               printtree(std::cout,0);
+               std::cout << "other:" << std::endl;
+               other.printtree(std::cout,0);
        }
                
        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();
+#endif // EXPAIRSEQ_USE_HASHTAB
+               epvector::const_iterator cit1 = seq.begin();
+               epvector::const_iterator cit2 = o.seq.begin();
+               epvector::const_iterator last1 = seq.end();
                
                while (cit1!=last1) {
                        if (!(*cit1).is_equal(*cit2)) return false;
@@ -480,21 +465,22 @@ bool expairseq::is_equal_same_type(const basic & other) const
                }
                
                return true;
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        }
-
+       
        for (unsigned i=0; i<hashtabsize; ++i) {
-               if (hashtab[i].size() != o.hashtab[i].size()) return false;
+               if (hashtab[i].size() != o.hashtab[i].size())
+                       return false;
        }
 
        // compare individual sorted hashtab entries
        for (unsigned i=0; i<hashtabsize; ++i) {
-               unsigned sz=hashtab[i].size();
+               unsigned sz = hashtab[i].size();
                if (sz>0) {
-                       const epplist & eppl1=hashtab[i];
-                       const epplist & eppl2=o.hashtab[i];
-                       epplist::const_iterator it1=eppl1.begin();
-                       epplist::const_iterator it2=eppl2.begin();
+                       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()) {
                                if (!(*(*it1)).is_equal(*(*it2))) return false;
                                ++it1;
@@ -502,9 +488,9 @@ bool expairseq::is_equal_same_type(const basic & other) const
                        }
                }
        }
-
+       
        return true;
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
 }
 
 unsigned expairseq::return_type(void) const
@@ -514,33 +500,39 @@ unsigned expairseq::return_type(void) const
 
 unsigned expairseq::calchash(void) const
 {
-       unsigned v=golden_ratio_hash(tinfo());
-       epvector::const_iterator last=seq.end();
-       for (epvector::const_iterator cit=seq.begin(); cit!=last; ++cit) {
-#ifndef EXPAIRSEQ_USE_HASHTAB
-               v=rotate_left_31(v); // rotation would spoil commutativity
-#endif // ndef EXPAIRSEQ_USE_HASHTAB
-               v ^= (*cit).rest.gethash();
+       unsigned v = golden_ratio_hash(tinfo());
+       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
+#if !EXPAIRSEQ_USE_HASHTAB
+               v = rotate_left_31(v); // rotation would spoil commutativity
+#endif // EXPAIRSEQ_USE_HASHTAB
+               v ^= cit->rest.gethash();
+#if !EXPAIRSEQ_USE_HASHTAB
+               v = rotate_left_31(v);
+               v ^= cit->coeff.gethash();
+#endif // EXPAIRSEQ_USE_HASHTAB
        }
-
+       
        v ^= overall_coeff.gethash();
-       v=v & 0x7FFFFFFFU;
+       v &= 0x7FFFFFFFU;
        
        // store calculated hash value only if object is already evaluated
-       if (flags & status_flags::evaluated) {
+       if (flags &status_flags::evaluated) {
                setflag(status_flags::hash_calculated);
-               hashvalue=v;
+               hashvalue = v;
        }
-
+       
        return v;
 }
 
 ex expairseq::expand(unsigned options) const
 {
-       epvector * vp = expandchildren(options);
+       epvector *vp = expandchildren(options);
        if (vp==0) {
+               // the terms have not changed, so it is safe to declare this expanded
+               setflag(status_flags::expanded);
                return *this;
        }
+       
        return thisexpairseq(vp,overall_coeff);
 }
 
@@ -550,17 +542,25 @@ ex expairseq::expand(unsigned options) const
 
 // protected
 
-ex expairseq::thisexpairseq(const epvector & v, const ex & oc) const
+/** Create an object of this type.
+ *  This method works similar to a constructor.  It is useful because expairseq
+ *  has (at least) two possible different semantics but we want to inherit
+ *  methods thus avoiding code duplication.  Sometimes a method in expairseq
+ *  has to create a new one of the same semantics, which cannot be done by a
+ *  ctor because the name (add, mul,...) is unknown on the expaiseq level.  In
+ *  order for this trick to work a derived class must of course override this
+ *  definition. */
+ex expairseq::thisexpairseq(const epvector &v, const ex &oc) const
 {
        return expairseq(v,oc);
 }
 
-ex expairseq::thisexpairseq(epvector * vp, const ex & oc) const
+ex expairseq::thisexpairseq(epvector *vp, const ex &oc) const
 {
        return expairseq(vp,oc);
 }
 
-void expairseq::printpair(std::ostream & os, const expair & p, unsigned upper_precedence) const
+void expairseq::printpair(std::ostream &os, const expair &p, unsigned upper_precedence) const
 {
        os << "[[";
        p.rest.bp->print(os,precedence);
@@ -569,11 +569,12 @@ void expairseq::printpair(std::ostream & os, const expair & p, unsigned upper_pr
        os << "]]";
 }
 
-void expairseq::printseq(std::ostream & os, char delim,
+void expairseq::printseq(std::ostream &os, char delim,
                          unsigned this_precedence,
                          unsigned upper_precedence) const
 {
-       if (this_precedence<=upper_precedence) os << "(";
+       if (this_precedence<=upper_precedence)
+               os << "(";
        epvector::const_iterator it,it_last;
        it_last=seq.end();
        --it_last;
@@ -582,27 +583,33 @@ void expairseq::printseq(std::ostream & os, char delim,
                os << delim;
        }
        printpair(os,*it,this_precedence);
-       if (!overall_coeff.is_equal(default_overall_coeff())) {
+       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
+       if (this_precedence<=upper_precedence)
+               os << ")";
+}
+
+
+/** Form an expair from an ex, using the corresponding semantics.
+ *  @see expairseq::recombine_pair_to_ex() */
+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
+
+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(const expair & p,
-                                                  const ex & c) const
+
+expair expairseq::combine_pair_with_coeff_to_pair(const expair &p,
+                                                  const ex &c) const
 {
        GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
@@ -610,13 +617,19 @@ expair expairseq::combine_pair_with_coeff_to_pair(const expair & p,
        return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
 }
 
-ex expairseq::recombine_pair_to_ex(const expair & p) const
+
+/** Form an ex out of an expair, using the corresponding semantics.
+ *  @see expairseq::split_ex_to_pair() */
+ex expairseq::recombine_pair_to_ex(const expair &p) const
 {
        return lst(p.rest,p.coeff);
 }
 
 bool expairseq::expair_needs_further_processing(epp it)
 {
+#if EXPAIRSEQ_USE_HASHTAB
+       //#  error "FIXME: expair_needs_further_processing not yet implemented for hashtabs, sorry. A.F."
+#endif // EXPAIRSEQ_USE_HASHTAB
        return false;
 }
 
@@ -625,14 +638,14 @@ ex expairseq::default_overall_coeff(void) const
        return _ex0();
 }
 
-void expairseq::combine_overall_coeff(const ex & c)
+void expairseq::combine_overall_coeff(const ex &c)
 {
        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(const ex & c1, const ex & c2)
+void expairseq::combine_overall_coeff(const ex &c1, const ex &c2)
 {
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
        GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
@@ -641,80 +654,80 @@ void expairseq::combine_overall_coeff(const ex & c1, const ex & c2)
                        add_dyn(ex_to_numeric(c1).mul(ex_to_numeric(c2)));
 }
 
-bool expairseq::can_make_flat(const expair & p) const
+bool expairseq::can_make_flat(const expair &p) const
 {
        return true;
 }
 
-       
+
 //////////
 // non-virtual functions in this class
 //////////
 
-void expairseq::construct_from_2_ex_via_exvector(const ex & lh, const ex & rh)
+void expairseq::construct_from_2_ex_via_exvector(const ex &lh, const ex &rh)
 {
        exvector v;
        v.reserve(2);
        v.push_back(lh);
        v.push_back(rh);
        construct_from_exvector(v);
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        GINAC_ASSERT((hashtabsize==0)||(hashtabsize>=minhashtabsize));
        GINAC_ASSERT(hashtabsize==calc_hashtabsize(seq.size()));
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
 }
 
-void expairseq::construct_from_2_ex(const ex & lh, const ex & rh)
+void expairseq::construct_from_2_ex(const ex &lh, const ex &rh)
 {
        if (lh.bp->tinfo()==tinfo()) {
                if (rh.bp->tinfo()==tinfo()) {
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
                        unsigned totalsize = ex_to_expairseq(lh).seq.size() +
                                             ex_to_expairseq(rh).seq.size();
                        if (calc_hashtabsize(totalsize)!=0) {
                                construct_from_2_ex_via_exvector(lh,rh);
                        } else {
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                                construct_from_2_expairseq(ex_to_expairseq(lh),
                                                           ex_to_expairseq(rh));
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
                        }
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                        return;
                } else {
-#ifdef EXPAIRSEQ_USE_HASHTAB
-                       unsigned totalsize=ex_to_expairseq(lh).seq.size()+1;
-                       if (calc_hashtabsize(totalsize) != 0) {
+#if EXPAIRSEQ_USE_HASHTAB
+                       unsigned totalsize = ex_to_expairseq(lh).seq.size()+1;
+                       if (calc_hashtabsize(totalsize)!=0) {
                                construct_from_2_ex_via_exvector(lh, rh);
                        } else {
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                                construct_from_expairseq_ex(ex_to_expairseq(lh), rh);
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
                        }
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                        return;
                }
        } else if (rh.bp->tinfo()==tinfo()) {
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
                unsigned totalsize=ex_to_expairseq(rh).seq.size()+1;
                if (calc_hashtabsize(totalsize)!=0) {
                        construct_from_2_ex_via_exvector(lh,rh);
                } else {
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                        construct_from_expairseq_ex(ex_to_expairseq(rh),lh);
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
                }
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
                return;
        }
-
-#ifdef EXPAIRSEQ_USE_HASHTAB
+       
+#if EXPAIRSEQ_USE_HASHTAB
        if (calc_hashtabsize(2)!=0) {
                construct_from_2_ex_via_exvector(lh,rh);
                return;
        }
-       hashtabsize=0;
-#endif // def EXPAIRSEQ_USE_HASHTAB
+       hashtabsize = 0;
+#endif // EXPAIRSEQ_USE_HASHTAB
        
        if (is_ex_exactly_of_type(lh,numeric)) {
                if (is_ex_exactly_of_type(rh,numeric)) {
@@ -729,10 +742,10 @@ void expairseq::construct_from_2_ex(const ex & lh, const ex & rh)
                        combine_overall_coeff(rh);
                        seq.push_back(split_ex_to_pair(lh));
                } else {
-                       expair p1=split_ex_to_pair(lh);
-                       expair p2=split_ex_to_pair(rh);
-
-                       int cmpval=p1.rest.compare(p2.rest);
+                       expair p1 = split_ex_to_pair(lh);
+                       expair p2 = split_ex_to_pair(rh);
+                       
+                       int cmpval = p1.rest.compare(p2.rest);
                        if (cmpval==0) {
                                p1.coeff=ex_to_numeric(p1.coeff).add_dyn(ex_to_numeric(p2.coeff));
                                if (!ex_to_numeric(p1.coeff).is_zero()) {
@@ -754,26 +767,26 @@ void expairseq::construct_from_2_ex(const ex & lh, const ex & rh)
        }
 }
 
-void expairseq::construct_from_2_expairseq(const expairseq & s1,
-                                                                                  const expairseq & 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);
 
-       epvector::const_iterator first1=s1.seq.begin();
-       epvector::const_iterator last1=s1.seq.end();
-       epvector::const_iterator first2=s2.seq.begin();
-       epvector::const_iterator last2=s2.seq.end();
+       epvector::const_iterator first1 = s1.seq.begin();
+       epvector::const_iterator last1 = s1.seq.end();
+       epvector::const_iterator first2 = s2.seq.begin();
+       epvector::const_iterator last2 = s2.seq.end();
 
        seq.reserve(s1.seq.size()+s2.seq.size());
 
        bool needs_further_processing=false;
        
        while (first1!=last1 && first2!=last2) {
-               int cmpval=(*first1).rest.compare((*first2).rest);
+               int cmpval = (*first1).rest.compare((*first2).rest);
                if (cmpval==0) {
                        // combine terms
-                       const numeric & 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));
@@ -800,39 +813,39 @@ void expairseq::construct_from_2_expairseq(const expairseq & s1,
                seq.push_back(*first2);
                ++first2;
        }
-
+       
        if (needs_further_processing) {
-               epvector v=seq;
+               epvector v = seq;
                seq.clear();
                construct_from_epvector(v);
        }
 }
 
-void expairseq::construct_from_expairseq_ex(const expairseq & s,
-                                                                                       const ex & 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)) {
                combine_overall_coeff(e);
-               seq=s.seq;
+               seq = s.seq;
                return;
        }
-
-       epvector::const_iterator first=s.seq.begin();
-       epvector::const_iterator last=s.seq.end();
-       expair p=split_ex_to_pair(e);
-
+       
+       epvector::const_iterator first = s.seq.begin();
+       epvector::const_iterator last = s.seq.end();
+       expair p = split_ex_to_pair(e);
+       
        seq.reserve(s.seq.size()+1);
-       bool p_pushed=0;
-
+       bool p_pushed = false;
+       
        bool needs_further_processing=false;
-
+       
        // merge p into s.seq
        while (first!=last) {
                int cmpval=(*first).rest.compare(p.rest);
                if (cmpval==0) {
                        // combine terms
-                       const numeric & 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));
@@ -841,18 +854,18 @@ void expairseq::construct_from_expairseq_ex(const expairseq & s,
                                }
                        }
                        ++first;
-                       p_pushed=1;
+                       p_pushed = true;
                        break;
                } else if (cmpval<0) {
                        seq.push_back(*first);
                        ++first;
                } else {
                        seq.push_back(p);
-                       p_pushed=1;
+                       p_pushed = true;
                        break;
                }
        }
-
+       
        if (p_pushed) {
                // while loop exited because p was pushed, now push rest of s.seq
                while (first!=last) {
@@ -865,13 +878,13 @@ void expairseq::construct_from_expairseq_ex(const expairseq & s,
        }
 
        if (needs_further_processing) {
-               epvector v=seq;
+               epvector v = seq;
                seq.clear();
                construct_from_epvector(v);
        }
 }
 
-void expairseq::construct_from_exvector(const exvector & 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)
@@ -879,15 +892,16 @@ void expairseq::construct_from_exvector(const exvector & v)
        //                  (same for (+,*) -> (*,^)
 
        make_flat(v);
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        combine_same_terms();
 #else
        canonicalize();
        combine_same_terms_sorted_seq();
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
+       return;
 }
 
-void expairseq::construct_from_epvector(const epvector & 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)
@@ -895,93 +909,93 @@ void expairseq::construct_from_epvector(const epvector & v)
        //                  (same for (+,*) -> (*,^)
 
        make_flat(v);
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        combine_same_terms();
 #else
        canonicalize();
        combine_same_terms_sorted_seq();
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
+       return;
 }
 
-void expairseq::make_flat(const exvector & v)
+/** Combine this expairseq with argument exvector.
+ *  It cares for associativity as well as for special handling of numerics. */
+void expairseq::make_flat(const exvector &v)
 {
-       exvector::const_iterator cit, citend = v.end();
-
+       exvector::const_iterator cit;
+       
        // count number of operands which are of same expairseq derived type
        // and their cumulative number of operands
-       int nexpairseqs=0;
-       int noperands=0;
-       cit=v.begin();
-       while (cit!=citend) {
-               if (cit->bp->tinfo()==tinfo()) {
+       int nexpairseqs = 0;
+       int noperands = 0;
+       
+       cit = v.begin();
+       while (cit!=v.end()) {
+               if (cit->bp->tinfo()==this->tinfo()) {
                        ++nexpairseqs;
-                       noperands+=ex_to_expairseq(*cit).seq.size();
+                       noperands += ex_to_expairseq(*cit).seq.size();
                }
                ++cit;
        }
-
+       
        // reserve seq and coeffseq which will hold all operands
        seq.reserve(v.size()+noperands-nexpairseqs);
-
+       
        // copy elements and split off numerical part
-       cit=v.begin();
-       while (cit!=citend) {
-               if (cit->bp->tinfo()==tinfo()) {
-                       const expairseq & subseqref=ex_to_expairseq(*cit);
+       cit = v.begin();
+       while (cit!=v.end()) {
+               if (cit->bp->tinfo()==this->tinfo()) {
+                       const expairseq &subseqref = ex_to_expairseq(*cit);
                        combine_overall_coeff(subseqref.overall_coeff);
-                       epvector::const_iterator cit_s=subseqref.seq.begin();
+                       epvector::const_iterator cit_s = subseqref.seq.begin();
                        while (cit_s!=subseqref.seq.end()) {
                                seq.push_back(*cit_s);
                                ++cit_s;
                        }
                } else {
-                       if (is_ex_exactly_of_type(*cit,numeric)) {
+                       if (is_ex_exactly_of_type(*cit,numeric))
                                combine_overall_coeff(*cit);
-                       } else {
+                       else
                                seq.push_back(split_ex_to_pair(*cit));
-                       }
                }
                ++cit;
        }
-
-       /*
-       cout << "after make flat" << std::endl;
-       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               (*cit).printraw(cout);
-       }
-       cout << std::endl;
-       */
+       
+       return;
 }
 
-void expairseq::make_flat(const epvector & v)
+/** Combine this expairseq with argument epvector.
+ *  It cares for associativity as well as for special handling of numerics. */
+void expairseq::make_flat(const epvector &v)
 {
-       epvector::const_iterator cit, citend = v.end();
-
+       epvector::const_iterator cit;
+       
        // count number of operands which are of same expairseq derived type
        // and their cumulative number of operands
-       int nexpairseqs=0;
-       int noperands=0;
-
+       int nexpairseqs = 0;
+       int noperands = 0;
+       
        cit = v.begin();
-       while (cit!=citend) {
-               if (cit->rest.bp->tinfo()==tinfo()) {
+       while (cit!=v.end()) {
+               if (cit->rest.bp->tinfo()==this->tinfo()) {
                        ++nexpairseqs;
                        noperands += ex_to_expairseq((*cit).rest).seq.size();
                }
                ++cit;
        }
-
+       
        // reserve seq and coeffseq which will hold all operands
        seq.reserve(v.size()+noperands-nexpairseqs);
-
+       
        // copy elements and split off numerical part
        cit = v.begin();
-       while (cit!=citend) {
-               if ((cit->rest.bp->tinfo()==tinfo())&&can_make_flat(*cit)) {
-                       const expairseq & subseqref=ex_to_expairseq((*cit).rest);
+       while (cit!=v.end()) {
+               if (cit->rest.bp->tinfo()==this->tinfo() &&
+                   this->can_make_flat(*cit)) {
+                       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();
+                       epvector::const_iterator cit_s = subseqref.seq.begin();
                        while (cit_s!=subseqref.seq.end()) {
                                seq.push_back(expair((*cit_s).rest,
                                                     ex_to_numeric((*cit_s).coeff).mul_dyn(ex_to_numeric((*cit).coeff))));
@@ -990,216 +1004,101 @@ void expairseq::make_flat(const epvector & v)
                                ++cit_s;
                        }
                } else {
-                       if ((*cit).is_numeric_with_coeff_1()) {
-                               combine_overall_coeff((*cit).rest);
-                       //if (is_ex_exactly_of_type((*cit).rest,numeric)) {
-                       //    combine_overall_coeff(recombine_pair_to_ex(*cit));
-                       } else {
+                       if (cit->is_canonical_numeric())
+                               combine_overall_coeff(cit->rest);
+                       else
                                seq.push_back(*cit);
-                       }
                }
                ++cit;
        }
+       return;
 }
 
-epvector * expairseq::bubblesort(epvector::iterator itbegin, epvector::iterator itend)
-{
-       unsigned n=itend-itbegin;
-
-       epvector * sp=new epvector;
-       sp->reserve(n);
-
-       epvector::iterator last=itend-1;
-       for (epvector::iterator it1=itbegin; it1!=last; ++it1) {
-               for (epvector::iterator it2=it1+1; it2!=itend; ++it2) {
-                       if ((*it2).rest.compare((*it1).rest)<0) {
-                               iter_swap(it1,it2);
-                       }
-               }
-               sp->push_back(*it1);
-       }
-       sp->push_back(*last);
-       return sp;
-}
-
-epvector * expairseq::mergesort(epvector::iterator itbegin, epvector::iterator itend)
-{
-       unsigned n=itend-itbegin;
-       /*
-       if (n==1) {
-               epvector * sp=new epvector;
-               sp->push_back(*itbegin);
-               return sp;
-       }
-       */
-       if (n<16) return bubblesort(itbegin, itend);
-       unsigned m=n/2;
-       
-       epvector * s1p=mergesort(itbegin, itbegin+m);
-       epvector * s2p=mergesort(itbegin+m, itend);
-
-       epvector * sp=new epvector;
-       sp->reserve(s1p->size()+s2p->size());
-
-       epvector::iterator first1=s1p->begin();
-       epvector::iterator last1=s1p->end();
-
-       epvector::iterator first2=s2p->begin();
-       epvector::iterator last2=s2p->end();
-       
-       while (first1 != last1 && first2 != last2) {
-               if ((*first1).rest.compare((*first2).rest)<0) {
-                       sp->push_back(*first1);
-                       ++first1;
-               } else {
-                       sp->push_back(*first2);
-                       ++first2;
-               }
-       }
-
-       if (first1 != last1) {
-               while (first1 != last1) {
-                       sp->push_back(*first1);
-                       ++first1;
-               }
-       } else {
-               while (first2 != last2) {
-                       sp->push_back(*first2);
-                       ++first2;
-               }
-       }
-
-       delete s1p;
-       delete s2p;
-       
-       return sp;
-}
-                       
 
+/** Brings this expairseq into a sorted (canonical) form. */
 void expairseq::canonicalize(void)
 {
        // canonicalize
        sort(seq.begin(),seq.end(),expair_is_less());
-       /*
-       sort(seq.begin(),seq.end(),expair_is_less_old());
-       if (seq.size()>1) {
-               if (is_ex_exactly_of_type((*(seq.begin())).rest,numeric)) {
-                       sort(seq.begin(),seq.end(),expair_is_less());
-               } else {
-                       epvector::iterator last_numeric=seq.end();
-                       do {
-                               last_numeric--;
-                       } while (is_ex_exactly_of_type((*last_numeric).rest,numeric));
-                       ++last_numeric;
-                       sort(last_numeric,seq.end(),expair_is_less());
-               }
-       }
-       */
-       
-       /*
-       epvector * sorted_seqp=mergesort(seq.begin(),seq.end());
-       epvector::iterator last=sorted_seqp->end();
-       epvector::iterator it2=seq.begin();
-       for (epvector::iterator it1=sorted_seqp->begin(); it1!=last; ++it1, ++it2) {
-               iter_swap(it1,it2);
-       }
-       delete sorted_seqp;
-       */
-
-       /*
-       cout << "after canonicalize" << std::endl;
-       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               (*cit).printraw(cout);
-       }
-       cout << std::endl;
-       cout.flush();
-       */
+       return;
 }
 
+
+/** Compact a presorted expairseq by combining all matching expairs to one
+ *  each.  On an add object, this is responsible for 2*x+3*x+y -> 5*x+y, for
+ *  instance. */
 void expairseq::combine_same_terms_sorted_seq(void)
 {
-       bool needs_further_processing=false;
+       bool needs_further_processing = false;
        
-       // combine same terms, drop term with coeff 0
        if (seq.size()>1) {
-               epvector::iterator itin1=seq.begin();
-               epvector::iterator itin2=itin1+1;
-               epvector::iterator itout=itin1;
-               epvector::iterator last=seq.end();
-               // must_copy will be set to true the first time some combination is possible
-               // from then on the sequence has changed and must be compacted
-               bool must_copy=false;
+               epvector::iterator itin1 = seq.begin();
+               epvector::iterator itin2 = itin1+1;
+               epvector::iterator itout = itin1;
+               epvector::iterator last = seq.end();
+               // must_copy will be set to true the first time some combination is 
+               // possible from then on the sequence has changed and must be compacted
+               bool must_copy = false;
                while (itin2!=last) {
                        if ((*itin1).rest.compare((*itin2).rest)==0) {
                                (*itin1).coeff = ex_to_numeric((*itin1).coeff).
                                                 add_dyn(ex_to_numeric((*itin2).coeff));
-                               if (expair_needs_further_processing(itin1)) {
+                               if (expair_needs_further_processing(itin1))
                                        needs_further_processing = true;
-                               }
-                               must_copy=true;
+                               must_copy = true;
                        } else {
                                if (!ex_to_numeric((*itin1).coeff).is_zero()) {
-                                       if (must_copy) {
-                                               *itout=*itin1;
-                                       }
+                                       if (must_copy)
+                                               *itout = *itin1;
                                        ++itout;
                                }
-                               itin1=itin2;
+                               itin1 = itin2;
                        }
                        ++itin2;
                }
                if (!ex_to_numeric((*itin1).coeff).is_zero()) {
-                       if (must_copy) {
-                               *itout=*itin1;
-                       }
+                       if (must_copy)
+                               *itout = *itin1;
                        ++itout;
                }
-               if (itout!=last) {
+               if (itout!=last)
                        seq.erase(itout,last);
-               }
        }
-
-       /*
-       cout << "after combine" << std::endl;
-       for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               (*cit).printraw(cout);
-       }
-       cout << std::endl;
-       cout.flush();
-       */
        
        if (needs_further_processing) {
-               epvector v=seq;
+               epvector v = seq;
                seq.clear();
                construct_from_epvector(v);
        }
+       return;
 }
 
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
 
 unsigned expairseq::calc_hashtabsize(unsigned sz) const
 {
        unsigned size;
        unsigned nearest_power_of_2 = 1 << log2(sz);
-       //    if (nearest_power_of_2 < maxhashtabsize/hashtabfactor) {
-       //  size=nearest_power_of_2*hashtabfactor;
-       size=nearest_power_of_2/hashtabfactor;
-       if (size<minhashtabsize) return 0;
+       // if (nearest_power_of_2 < maxhashtabsize/hashtabfactor) {
+       //  size = nearest_power_of_2*hashtabfactor;
+       size = nearest_power_of_2/hashtabfactor;
+       if (size<minhashtabsize)
+               return 0;
        GINAC_ASSERT(hashtabsize<=0x8000000U); // really max size due to 31 bit hashing
        // hashtabsize must be a power of 2
        GINAC_ASSERT((1U << log2(size))==size);
        return size;
 }
 
-unsigned expairseq::calc_hashindex(const ex & e) const
+unsigned expairseq::calc_hashindex(const ex &e) const
 {
        // calculate hashindex
-       unsigned hash=e.gethash();
+       unsigned hash = e.gethash();
        unsigned hashindex;
        if (is_a_numeric_hash(hash)) {
                hashindex = hashmask;
        } else {
-               hashindex = hash & hashmask;
+               hashindex = hash &hashmask;
                // last hashtab entry is reserved for numerics
                if (hashindex==hashmask) hashindex = 0;
        }
@@ -1221,7 +1120,7 @@ void expairseq::shrink_hashtab(void)
                }
                
                // shrink by a factor of 2
-               unsigned half_hashtabsize=hashtabsize/2;
+               unsigned half_hashtabsize = hashtabsize/2;
                for (unsigned i=0; i<half_hashtabsize-1; ++i)
                        hashtab[i].merge(hashtab[i+half_hashtabsize],epp_is_less());
                // special treatment for numeric hashes
@@ -1235,13 +1134,14 @@ void expairseq::shrink_hashtab(void)
 
 void expairseq::remove_hashtab_entry(epvector::const_iterator element)
 {
-       if (hashtabsize==0) return; // nothing to do
+       if (hashtabsize==0)
+               return; // nothing to do
        
        // calculate hashindex of element to be deleted
        unsigned hashindex = calc_hashindex((*element).rest);
 
        // find it in hashtab and remove it
-       epplist & eppl = hashtab[hashindex];
+       epplist &eppl = hashtab[hashindex];
        epplist::iterator epplit = eppl.begin();
        bool erased = false;
        while (epplit!=eppl.end()) {
@@ -1258,7 +1158,7 @@ void expairseq::remove_hashtab_entry(epvector::const_iterator element)
                cout << "size " << seq.end()-seq.begin() << std::endl;
 
                unsigned hashindex = calc_hashindex((*element).rest);
-               epplist & eppl = hashtab[hashindex];
+               epplist &eppl = hashtab[hashindex];
                epplist::iterator epplit=eppl.begin();
                bool erased=false;
                while (epplit!=eppl.end()) {
@@ -1275,7 +1175,7 @@ void expairseq::remove_hashtab_entry(epvector::const_iterator element)
 }
 
 void expairseq::move_hashtab_entry(epvector::const_iterator oldpos,
-                                                                  epvector::iterator newpos)
+                                   epvector::iterator newpos)
 {
        GINAC_ASSERT(hashtabsize!=0);
        
@@ -1283,11 +1183,11 @@ void expairseq::move_hashtab_entry(epvector::const_iterator oldpos,
        unsigned hashindex=calc_hashindex((*newpos).rest);
 
        // find it in hashtab and modify it
-       epplist & eppl = hashtab[hashindex];
-       epplist::iterator epplit=eppl.begin();
+       epplist &eppl = hashtab[hashindex];
+       epplist::iterator epplit = eppl.begin();
        while (epplit!=eppl.end()) {
                if (*epplit == oldpos) {
-                       *epplit=newpos;
+                       *epplit = newpos;
                        break;
                }
                ++epplit;
@@ -1295,7 +1195,7 @@ void expairseq::move_hashtab_entry(epvector::const_iterator oldpos,
        GINAC_ASSERT(epplit!=eppl.end());
 }
 
-void expairseq::sorted_insert(epplist & eppl, epp elem)
+void expairseq::sorted_insert(epplist &eppl, epp elem)
 {
        epplist::iterator current = eppl.begin();
        while ((current!=eppl.end())&&((*(*current)).is_less(*elem))) {
@@ -1304,10 +1204,10 @@ void expairseq::sorted_insert(epplist & eppl, epp elem)
        eppl.insert(current,elem);
 }    
 
-void expairseq::build_hashtab_and_combine(epvector::iterator & first_numeric,
-                                          epvector::iterator & last_non_zero,
-                                          vector<bool> & touched,
-                                          unsigned & number_of_zeroes)
+void expairseq::build_hashtab_and_combine(epvector::iterator &first_numeric,
+                                          epvector::iterator &last_non_zero,
+                                          vector<bool> &touched,
+                                          unsigned &number_of_zeroes)
 {
        epp current=seq.begin();
 
@@ -1317,13 +1217,14 @@ void expairseq::build_hashtab_and_combine(epvector::iterator & first_numeric,
                        iter_swap(current,first_numeric);
                } else {
                        // calculate hashindex
-                       unsigned currenthashindex=calc_hashindex((*current).rest);
+                       unsigned currenthashindex = calc_hashindex((*current).rest);
 
                        // test if there is already a matching expair in the hashtab-list
-                       epplist & eppl=hashtab[currenthashindex];
-                       epplist::iterator epplit=eppl.begin();
+                       epplist &eppl=hashtab[currenthashindex];
+                       epplist::iterator epplit = eppl.begin();
                        while (epplit!=eppl.end()) {
-                               if ((*current).rest.is_equal((*(*epplit)).rest)) break;
+                               if ((*current).rest.is_equal((*(*epplit)).rest))
+                                       break;
                                ++epplit;
                        }
                        if (epplit==eppl.end()) {
@@ -1347,27 +1248,27 @@ void expairseq::build_hashtab_and_combine(epvector::iterator & first_numeric,
                        }
                }
        }
-}    
+}
 
-void expairseq::drop_coeff_0_terms(epvector::iterator & first_numeric,
-                                   epvector::iterator & last_non_zero,
-                                   vector<bool> & touched,
-                                   unsigned & number_of_zeroes)
+void expairseq::drop_coeff_0_terms(epvector::iterator &first_numeric,
+                                   epvector::iterator &last_non_zero,
+                                   vector<bool> &touched,
+                                   unsigned &number_of_zeroes)
 {
        // move terms with coeff 0 to end and remove them from hashtab
        // check only those elements which have been touched
-       epp current=seq.begin();
-       unsigned i=0;
+       epp current = seq.begin();
+       unsigned i = 0;
        while (current!=first_numeric) {
                if (!touched[i]) {
                        ++current;
                        ++i;
-               } else if (!ex_to_numeric((*current).coeff).is_equal(_num0())) {
+               } else if (!ex_to_numeric((*current).coeff).is_zero()) {
                        ++current;
                        ++i;
                } else {
                        remove_hashtab_entry(current);
-
+                       
                        // move element to the end, unless it is already at the end
                        if (current!=last_non_zero) {
                                iter_swap(current,last_non_zero);
@@ -1376,12 +1277,11 @@ void expairseq::drop_coeff_0_terms(epvector::iterator & first_numeric,
                                if (numeric_swapped) iter_swap(first_numeric,current);
                                epvector::iterator changed_entry;
 
-                               if (numeric_swapped) {
-                                       changed_entry=first_numeric;
-                               } else {
-                                       changed_entry=last_non_zero;
-                               }
-
+                               if (numeric_swapped)
+                                       changed_entry = first_numeric;
+                               else
+                                       changed_entry = last_non_zero;
+                               
                                --last_non_zero;
                                ++number_of_zeroes;
 
@@ -1389,7 +1289,7 @@ void expairseq::drop_coeff_0_terms(epvector::iterator & first_numeric,
 
                                        // change entry in hashtab which referred to first_numeric or last_non_zero to current
                                        move_hashtab_entry(changed_entry,current);
-                                       touched[current-seq.begin()]=touched[changed_entry-seq.begin()];
+                                       touched[current-seq.begin()] = touched[changed_entry-seq.begin()];
                                }
                        } else {
                                --first_numeric;
@@ -1404,9 +1304,8 @@ void expairseq::drop_coeff_0_terms(epvector::iterator & first_numeric,
 bool expairseq::has_coeff_0(void) const
 {
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               if ((*cit).coeff.is_equal(_ex0())) {
+               if ((*cit).coeff.is_zero())
                        return true;
-               }
        }
        return false;
 }
@@ -1415,9 +1314,9 @@ void expairseq::add_numerics_to_hashtab(epvector::iterator first_numeric,
                                                                                epvector::const_iterator last_non_zero)
 {
        if (first_numeric==seq.end()) return; // no numerics    
-
-       epvector::iterator current=first_numeric;
-       epvector::const_iterator last=last_non_zero+1;
+       
+       epvector::iterator current = first_numeric;
+       epvector::const_iterator last = last_non_zero+1;
        while (current!=last) {
                sorted_insert(hashtab[hashmask],current);
                ++current;
@@ -1430,32 +1329,32 @@ void expairseq::combine_same_terms(void)
        
        // calculate size of hashtab
        hashtabsize = calc_hashtabsize(seq.size());
-
+       
        // hashtabsize is a power of 2
        hashmask = hashtabsize-1;
-
+       
        // allocate hashtab
        hashtab.clear();
        hashtab.resize(hashtabsize);
-
+       
        if (hashtabsize==0) {
                canonicalize();
                combine_same_terms_sorted_seq();
                GINAC_ASSERT(!has_coeff_0());
                return;
        }
-
+       
        // iterate through seq, move numerics to end,
        // fill hashtab and combine same terms
-       epvector::iterator first_numeric=seq.end();
-       epvector::iterator last_non_zero=seq.end()-1;
-
+       epvector::iterator first_numeric = seq.end();
+       epvector::iterator last_non_zero = seq.end()-1;
+       
        vector<bool> touched;
        touched.reserve(seq.size());
        for (unsigned i=0; i<seq.size(); ++i) touched[i]=false;
-
+       
        unsigned number_of_zeroes = 0;
-
+       
        GINAC_ASSERT(!has_coeff_0());
        build_hashtab_and_combine(first_numeric,last_non_zero,touched,number_of_zeroes);
        /*
@@ -1486,31 +1385,34 @@ void expairseq::combine_same_terms(void)
                cout << "end in combine after drop" << std::endl;
                */
        }
-
+       
        add_numerics_to_hashtab(first_numeric,last_non_zero);
-
+       
        // pop zero elements
        for (unsigned i=0; i<number_of_zeroes; ++i) {
                seq.pop_back();
        }
-
+       
        // shrink hashtabsize to calculated value
        GINAC_ASSERT(!has_coeff_0());
-
+       
        shrink_hashtab();
-
+       
        GINAC_ASSERT(!has_coeff_0());
 }
 
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
 
+/** Check if this expairseq is in sorted (canonical) form.  Useful mainly for
+ *  debugging or in assertions since being sorted is an invariance. */
 bool expairseq::is_canonical() const
 {
-       if (seq.size()<=1) return 1;
-
-#ifdef EXPAIRSEQ_USE_HASHTAB
+       if (seq.size()<=1)
+               return 1;
+       
+#if EXPAIRSEQ_USE_HASHTAB
        if (hashtabsize>0) return 1; // not canoncalized
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
        
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator it_last = it;
@@ -1539,18 +1441,24 @@ bool expairseq::is_canonical() const
        return 1;
 }
 
+
+/** Member-wise expand the expairs in this sequence.
+ *
+ *  @see expairseq::expand()
+ *  @return pointer to epvector containing expanded pairs or zero pointer,
+ *  if no members were changed. */
 epvector * expairseq::expandchildren(unsigned options) const
 {
        epvector::const_iterator last = seq.end();
        epvector::const_iterator cit = seq.begin();
        while (cit!=last) {
-               const ex & 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
-                       epvector *s=new epvector;
+                       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) {
@@ -1572,33 +1480,38 @@ epvector * expairseq::expandchildren(unsigned options) const
                ++cit;
        }
        
-       return 0; // nothing has changed
+       return 0; // signalling nothing has changed
 }
-   
+
+
+/** Member-wise evaluate the expairs in this sequence.
+ *
+ *  @see expairseq::eval()
+ *  @return pointer to epvector containing evaluated pairs or zero pointer,
+ *  if no members were changed. */
 epvector * 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) {
+       if (level==1)
                return 0;
-       }
-       if (level == -max_recursion_level) {
+       
+       if (level == -max_recursion_level)
                throw(std::runtime_error("max recursion level reached"));
-       }
-
+       
        --level;
        epvector::const_iterator last=seq.end();
        epvector::const_iterator cit=seq.begin();
        while (cit!=last) {
-               const ex & 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;
                        s->reserve(seq.size());
-
+                       
                        // copy parts of seq which are known not to have changed
                        epvector::const_iterator cit2=seq.begin();
                        while (cit2!=cit) {
@@ -1620,14 +1533,19 @@ epvector * expairseq::evalchildren(int level) const
                ++cit;
        }
        
-       return 0; // nothing has changed
+       return 0; // signalling nothing has changed
 }
 
+
+/** Member-wise evaluate numerically all expairs in this sequence.
+ *
+ *  @see expairseq::evalf()
+ *  @return epvector with all entries evaluated numerically. */
 epvector expairseq::evalfchildren(int level) const
 {
        if (level==1)
                return seq;
-
+       
        if (level==-max_recursion_level)
                throw(std::runtime_error("max recursion level reached"));
        
@@ -1642,17 +1560,22 @@ epvector expairseq::evalfchildren(int level) const
        return s;
 }
 
+
+/** Member-wise normalize all expairs in this sequence.
+ *
+ *  @see expairseq::normal()
+ *  @return epvector with all entries normalized. */
 epvector expairseq::normalchildren(int level) const
 {
        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.normal(level),
@@ -1661,11 +1584,16 @@ epvector expairseq::normalchildren(int level) const
        return s;
 }
 
-epvector expairseq::diffchildren(const symbol & y) const
+
+/** Member-wise differentiate all expairs in this sequence.
+ *
+ *  @see expairseq::diff()
+ *  @return epvector with all entries differentiated. */
+epvector expairseq::diffchildren(const symbol &y) 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.diff(y),
                                                          (*it).coeff));
@@ -1673,17 +1601,23 @@ epvector expairseq::diffchildren(const symbol & y) const
        return s;
 }
 
-epvector * expairseq::subschildren(const lst & ls, const lst & lr) const
+
+/** Member-wise substitute in this sequence.
+ *
+ *  @see expairseq::subs()
+ *  @return pointer to epvector containing pairs after application of subs or zero
+ *  pointer, if no members were changed. */
+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();
+       epvector::const_iterator last = seq.end();
+       epvector::const_iterator cit = seq.begin();
        while (cit!=last) {
-               const ex & 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
@@ -1691,7 +1625,7 @@ epvector * expairseq::subschildren(const lst & ls, const lst & lr) 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;
@@ -1711,7 +1645,7 @@ epvector * expairseq::subschildren(const lst & ls, const lst & lr) const
                ++cit;
        }
        
-       return 0; // nothing has changed
+       return 0; // signalling nothing has changed
 }
 
 //////////
@@ -1720,14 +1654,12 @@ epvector * expairseq::subschildren(const lst & ls, const lst & lr) const
 
 // protected
 
-unsigned expairseq::precedence=10;
+unsigned expairseq::precedence = 10;
 
-#ifdef EXPAIRSEQ_USE_HASHTAB
-unsigned expairseq::maxhashtabsize=0x4000000U;
-unsigned expairseq::minhashtabsize=0x1000U;
-unsigned expairseq::hashtabfactor=1;
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
+unsigned expairseq::maxhashtabsize = 0x4000000U;
+unsigned expairseq::minhashtabsize = 0x1000U;
+unsigned expairseq::hashtabfactor = 1;
+#endif // EXPAIRSEQ_USE_HASHTAB
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index bba0902..665daed 100644 (file)
 
 #include <vector>
 #include <list>
-
 // CINT needs <algorithm> to work properly with <vector> and <list>
 #include <algorithm>
 
 #include "expair.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
-
-//#define EXPAIRSEQ_USE_HASHTAB
-
-typedef std::vector<expair> epvector;
-typedef epvector::iterator epviter;
-
-inline void iter_swap(epvector::iterator it1, epvector::iterator it2)
-{
-       (*it1).rest.swap((*it2).rest);
-       (*it1).coeff.swap((*it2).coeff);
-}
 
-typedef epvector::iterator epp;
-typedef std::list<epp> epplist;
-typedef std::vector<epplist> epplistvector;
+/** Using hash tables can potentially enhance the asymptotic behaviour of
+ *  combining n terms into one large sum (or n terms into one large product)
+ *  from O(n*log(n)) to about O(n).  There are, however, several drawbacks.
+ *  The constant in front of O(n) is quite large, when copying such an object
+ *  one also has to copy the has table, comparison is quite expensive because
+ *  there is no ordering any more, it doesn't help at all when combining two
+ *  expairseqs because due to the presorted nature the behaviour would be
+ *  O(n) anyways, the code is quite messy, etc, etc.  The code is here as
+ *  an example for following generations to tinker with. */
+#define EXPAIRSEQ_USE_HASHTAB 0
+
+typedef std::vector<expair> epvector;       ///< expair-vector
+typedef epvector::iterator epviter;         ///< expair-vector iterator
+typedef epvector::iterator epp;             ///< expair-vector pointer
+typedef std::list<epp> epplist;             ///< list of expair-vector pointers
+typedef std::vector<epplist> epplistvector; ///< vector of epplist
 
 /** A sequence of class expair.
  *  This is used for time-critical classes like sums and products of terms
  *  since handling a list of coeff and rest is much faster than handling a
- *  list of products or powers, respectively. (Incidentally, Maple does it
- *  the same way.) */
+ *  list of products or powers, respectively. (Not incidentally, Maple does it
+ *  the same way, maybe others too.)  The semantics is (at least) twofold:
+ *  one for addition and one for multiplication and several methods have to
+ *  be overridden by derived classes to reflect the change in semantics.
+ *  However, most functionality turns out to be shared between addition and
+ *  multiplication, which is the reason why there is this base class. */
 class expairseq : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(expairseq, basic)
 
 // member functions
 
-       // default constructor, destructor, copy constructor assignment operator and helpers
+       // default ctor, dtor, copy ctor assignment operator and helpers
 public:
        expairseq() : basic(TINFO_expairseq)
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
                                            , hashtabsize(0)
-#endif // def EXPAIRSEQ_USE_HASHTAB
-       {
-       }
-       ~expairseq()
-       {
-               destroy(0);
-       }
+#endif // EXPAIRSEQ_USE_HASHTAB
+       { }
+       ~expairseq() { destroy(false); }
        expairseq(const expairseq & other);
        const expairseq & operator=(const expairseq & other);
 protected:
        void copy(const expairseq & other);
-       void destroy(bool call_parent)
-       {
-               if (call_parent) basic::destroy(call_parent);
-       };
-
-       // other constructors
+       void destroy(bool call_parent);
+       // other ctors
 public:
        expairseq(const ex & lh, const ex & rh);
        expairseq(const exvector & v);
        expairseq(const epvector & v, const ex & oc);
        expairseq(epvector * vp, const ex & oc); // vp will be deleted
-
+       
        // functions overriding virtual functions from bases classes
 public:
        basic * duplicate() const;
@@ -111,7 +106,7 @@ protected:
        unsigned return_type(void) const;
        unsigned calchash(void) const;
        ex expand(unsigned options=0) const;
-
+       
        // new virtual functions which can be overridden by derived classes
 protected:
        virtual ex thisexpairseq(const epvector & v, const ex & oc) const;
@@ -145,11 +140,9 @@ protected:
        void construct_from_epvector(const epvector & v);
        void make_flat(const exvector & v);
        void make_flat(const epvector & v);
-       epvector * bubblesort(epvector::iterator itbegin, epvector::iterator itend);
-       epvector * mergesort(epvector::iterator itbegin, epvector::iterator itend);
        void canonicalize(void);
        void combine_same_terms_sorted_seq(void);
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        void combine_same_terms(void);
        unsigned calc_hashtabsize(unsigned sz) const;
        unsigned calc_hashindex(const ex & e) const;
@@ -169,7 +162,7 @@ protected:
        bool has_coeff_0(void) const;
        void add_numerics_to_hashtab(epvector::iterator first_numeric,
                                     epvector::const_iterator last_non_zero);
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
        bool is_canonical() const;
        epvector * expandchildren(unsigned options) const;
        epvector * evalchildren(int level) const;
@@ -184,14 +177,14 @@ protected:
        epvector seq;
        ex overall_coeff;
        static unsigned precedence;
-#ifdef EXPAIRSEQ_USE_HASHTAB
+#if EXPAIRSEQ_USE_HASHTAB
        epplistvector hashtab;
        unsigned hashtabsize;
        unsigned hashmask;
        static unsigned maxhashtabsize;
        static unsigned minhashtabsize;
        static unsigned hashtabfactor;
-#endif // def EXPAIRSEQ_USE_HASHTAB
+#endif // EXPAIRSEQ_USE_HASHTAB
 };
 
 // utility functions
@@ -200,8 +193,6 @@ inline const expairseq &ex_to_expairseq(const ex &e)
        return static_cast<const expairseq &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_EXPAIRSEQ_H__
index acd65c9..cf7de6e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file exprseq_suppl.cpp
  *
- *  Supplement to exprseq.cpp, contains the parts which were
- *  not automatically generated. */
+ *  Supplement to exprseq.cpp, contains the parts which were not automatically
+ *  generated. */
 
 /*
  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
@@ -24,9 +24,7 @@
 #include "exprseq.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 bool exprseq::info(unsigned inf) const
 {
@@ -39,10 +37,8 @@ ex & exprseq::let_op(int i)
 {
        GINAC_ASSERT(i>=0);
        GINAC_ASSERT(i<nops());
-
+       
        return seq[i];
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 0bbe01c..4fd0199 100644 (file)
 #include "archive.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(fail, basic)
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
 fail::fail() : inherited(TINFO_fail)
 {
-       debugmsg("fail default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("fail default ctor",LOGLEVEL_CONSTRUCT);
 }
 
 // protected
@@ -61,7 +59,7 @@ void fail::destroy(bool call_parent)
 /** Construct object from archive_node. */
 fail::fail(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("fail constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("fail ctor from archive_node", LOGLEVEL_CONSTRUCT);
 }
 
 /** Unarchive the object. */
@@ -102,6 +100,4 @@ int fail::compare_same_type(const basic & other) const
        return 0;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index c2942cc..f3104d8 100644 (file)
 
 #include "basic.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class fail : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(fail, basic)
-
-       // other constructors
+       
+       // other ctors
        // none
-
+       
        // functions overriding virtual functions from bases classes
 public:
        void print(std::ostream & os, unsigned upper_precedence=0) const;
@@ -46,16 +44,14 @@ protected:
        
        // new virtual functions which can be overridden by derived classes
        // none
-
+       
        // non-virtual functions in this class
        // none
-
+       
        // member variables
        // none
 };
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_FAIL_H__
index 1178665..93506f1 100644 (file)
@@ -23,9 +23,7 @@
 #ifndef __GINAC_FLAGS_H__
 #define __GINAC_FLAGS_H__
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class expand_options {
 public:
@@ -46,11 +44,11 @@ public:
 class determinant_algo {
 public:
        enum {
-               automatic,                      //! Let the system choose
-               gauss,                          //! Gauss elimiation
-               divfree,                        //! Division-free elimination
-               laplace,                        //! Laplace (or minor) elimination
-               bareiss                         //! Bareiss fraction-free elimination
+               automatic,                      ///< Let the system choose
+               gauss,                          ///< Gauss elimiation
+               divfree,                        ///< Division-free elimination
+               laplace,                        ///< Laplace (or minor) elimination
+               bareiss                         ///< Bareiss fraction-free elimination
        };
 };
 
@@ -58,21 +56,22 @@ public:
 class solve_algo {
 public:
        enum {
-               automatic,                      //! Let the system choose
-               gauss,                          //! Gauss elimiation
-               divfree,                        //! Division-free elimination
-               bareiss                         //! Bareiss fraction-free elimination
+               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. */
+/** Flags to store information about the state of an object.
+ *  @see basic::flags */
 class status_flags {
 public:
        enum {
-               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
+               dynallocated    = 0x0001,       ///< Heap-allocated (i.e. created by new if we want to be clever and bypass the stack)
+               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
        };
 };
 
@@ -162,15 +161,13 @@ public:
 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
+               delete_lru,     ///< Least recently used
+               delete_lfu,     ///< Least frequently used
+               delete_cyclic   ///< First (oldest) one in list
        };
 };
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_FLAGS_H__
index de453fe..0a15766 100755 (executable)
@@ -34,7 +34,7 @@ sub generate {
        return generate_from_to($template,$seq_template1,$seq_template2,1,$maxargs);
 }
 
-$declare_function_macro_namespace = <<'END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NAMESPACE';
+$declare_function_macro = <<'END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO';
 #define DECLARE_FUNCTION_1P(NAME) \
 extern const unsigned function_index_##NAME; \
 inline GiNaC::function NAME(const GiNaC::ex & p1) { \
@@ -46,41 +46,17 @@ inline GiNaC::function NAME(const GiNaC::ex & p1, const GiNaC::ex & p2) { \
        return GiNaC::function(function_index_##NAME, p1, p2); \
 }
 
-END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NAMESPACE
+END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO
 
-$declare_function_macro_namespace .= generate_from_to(
-       <<'END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE','const GiNaC::ex & p${N}','p${N}',3,$maxargs);
+$declare_function_macro .= generate_from_to(
+       <<'END_OF_DECLARE_FUNCTION_MACRO','const GiNaC::ex & p${N}','p${N}',3,$maxargs);
 #define DECLARE_FUNCTION_${N}P(NAME) \\
 extern const unsigned function_index_##NAME; \\
 inline GiNaC::function NAME(${SEQ1}) { \\
        return GiNaC::function(function_index_##NAME, ${SEQ2}); \\
 }
 
-END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE
-
-$declare_function_macro_no_namespace = <<'END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NO_NAMESPACE';
-#define DECLARE_FUNCTION_1P(NAME) \
-extern const unsigned function_index_##NAME; \
-inline function NAME(const ex & p1) { \
-       return function(function_index_##NAME, p1); \
-}
-#define DECLARE_FUNCTION_2P(NAME) \
-extern const unsigned function_index_##NAME; \
-inline function NAME(const ex & p1, const ex & p2) { \
-       return function(function_index_##NAME, p1, p2); \
-}
-
-END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NO_NAMESPACE
-
-$declare_function_macro_no_namespace .= generate_from_to(
-       <<'END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE','const ex & p${N}','p${N}',3,$maxargs);
-#define DECLARE_FUNCTION_${N}P(NAME) \\
-extern const unsigned function_index_##NAME; \\
-inline function NAME(${SEQ1}) { \\
-       return function(function_index_##NAME, ${SEQ2}); \\
-}
-
-END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE
+END_OF_DECLARE_FUNCTION_MACRO
 
 $typedef_eval_funcp=generate(
 'typedef ex (* eval_funcp_${N})(${SEQ1});'."\n",
@@ -115,7 +91,7 @@ $constructors_implementation=generate(
 function::function(unsigned ser, ${SEQ1})
        : exprseq(${SEQ2}), serial(ser)
 {
-       debugmsg(\"function constructor from unsigned,${N}*ex\",LOGLEVEL_CONSTRUCT);
+       debugmsg(\"function ctor from unsigned,${N}*ex\",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_function;
 }
 END_OF_CONSTRUCTORS_IMPLEMENTATION
@@ -228,22 +204,10 @@ $interface=<<END_OF_INTERFACE;
 
 #include "exprseq.h"
 
-#ifndef NO_NAMESPACE_GINAC
-
-// the following lines have been generated for max. ${maxargs} parameters
-$declare_function_macro_namespace
-// end of generated lines
-
-#else // ndef NO_NAMESPACE_GINAC
-
 // the following lines have been generated for max. ${maxargs} parameters
-$declare_function_macro_no_namespace
+$declare_function_macro
 // end of generated lines
 
-#endif // ndef NO_NAMESPACE_GINAC
-
-#ifndef NO_NAMESPACE_GINAC
-
 #define REGISTER_FUNCTION(NAME,OPT) \\
 const unsigned function_index_##NAME= \\
        GiNaC::function::register_new(GiNaC::function_options(#NAME).OPT);
@@ -256,22 +220,6 @@ const unsigned function_index_##NAME= \\
                                      derivative_func(D). \\
                                      series_func(S));
 
-#else // ndef NO_NAMESPACE_GINAC
-
-#define REGISTER_FUNCTION(NAME,OPT) \\
-const unsigned function_index_##NAME= \\
-       function::register_new(function_options(#NAME).OPT);
-
-#define REGISTER_FUNCTION_OLD(NAME,E,EF,D,S) \\
-const unsigned function_index_##NAME= \\
-       function::register_new(function_options(#NAME). \\
-                              eval_func(E). \\
-                              evalf_func(EF). \\
-                              derivative_func(D). \\
-                              series_func(S));
-
-#endif // ndef NO_NAMESPACE_GINAC
-
 #define BEGIN_TYPECHECK \\
 bool automatic_typecheck=true;
 
@@ -280,31 +228,18 @@ if (!is_ex_exactly_of_type(VAR,TYPE)) { \\
        automatic_typecheck=false; \\
 } else
 
-#ifndef NO_NAMESPACE_GINAC
-
 #define TYPECHECK_INTEGER(VAR) \\
 if (!(VAR).info(GiNaC::info_flags::integer)) { \\
        automatic_typecheck=false; \\
 } else
 
-#else // ndef NO_NAMESPACE_GINAC
-
-#define TYPECHECK_INTEGER(VAR) \\
-if (!(VAR).info(info_flags::integer)) { \\
-       automatic_typecheck=false; \\
-} else
-
-#endif // ndef NO_NAMESPACE_GINAC
-
 #define END_TYPECHECK(RV) \\
 {} \\
 if (!automatic_typecheck) { \\
        return RV.hold(); \\
 }
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class function;
 
@@ -386,7 +321,7 @@ class function : public exprseq
 
 // member functions
 
-       // other constructors
+       // other ctors
 public:
        function(unsigned ser);
        // the following lines have been generated for max. ${maxargs} parameters
@@ -405,6 +340,7 @@ public:
        ex expand(unsigned options=0) const;
        ex eval(int level=0) const;
        ex evalf(int level=0) const;
+       unsigned calchash(void) const;
        ex series(const relational & r, int order, unsigned options = 0) const;
        ex thisexprseq(const exvector & v) const;
        ex thisexprseq(exvector * vp) const;
@@ -440,26 +376,15 @@ inline const function &ex_to_function(const ex &e)
        return static_cast<const function &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
-
 #define is_ex_the_function(OBJ, FUNCNAME) \\
        (is_ex_exactly_of_type(OBJ, function) && static_cast<GiNaC::function *>(OBJ.bp)->getserial() == function_index_##FUNCNAME)
 
-#else // ndef NO_NAMESPACE_GINAC
-
-#define is_ex_the_function(OBJ, FUNCNAME) \\
-       (is_ex_exactly_of_type(OBJ, function) && static_cast<function *>(OBJ.bp)->getserial() == function_index_##FUNCNAME)
-
-#endif // ndef NO_NAMESPACE_GINAC
-
 // global constants
 
 extern const function some_function;
 extern const std::type_info & typeid_function;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_FUNCTION_H__
 
@@ -505,9 +430,7 @@ $implementation=<<END_OF_IMPLEMENTATION;
 #include "debugmsg.h"
 #include "remember.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 //////////
 // helper class function_options
@@ -607,14 +530,14 @@ void function_options::test_and_set_nparams(unsigned n)
 GINAC_IMPLEMENT_REGISTERED_CLASS(function, exprseq)
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
 function::function() : serial(0)
 {
-       debugmsg("function default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("function default ctor",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_function;
 }
 
@@ -632,14 +555,14 @@ void function::destroy(bool call_parent)
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
 
 function::function(unsigned ser) : serial(ser)
 {
-       debugmsg("function constructor from unsigned",LOGLEVEL_CONSTRUCT);
+       debugmsg("function ctor from unsigned",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_function;
 }
 
@@ -649,21 +572,21 @@ $constructors_implementation
 
 function::function(unsigned ser, const exprseq & es) : exprseq(es), serial(ser)
 {
-       debugmsg("function constructor from unsigned,exprseq",LOGLEVEL_CONSTRUCT);
+       debugmsg("function ctor from unsigned,exprseq",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_function;
 }
 
 function::function(unsigned ser, const exvector & v, bool discardable) 
   : exprseq(v,discardable), serial(ser)
 {
-       debugmsg("function constructor from string,exvector,bool",LOGLEVEL_CONSTRUCT);
+       debugmsg("function ctor from string,exvector,bool",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_function;
 }
 
 function::function(unsigned ser, exvector * vp) 
   : exprseq(vp), serial(ser)
 {
-       debugmsg("function constructor from unsigned,exvector *",LOGLEVEL_CONSTRUCT);
+       debugmsg("function ctor from unsigned,exvector *",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_function;
 }
 
@@ -674,7 +597,7 @@ function::function(unsigned ser, exvector * vp)
 /** Construct object from archive_node. */
 function::function(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("function constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("function ctor from archive_node", LOGLEVEL_CONSTRUCT);
 
        // Find serial number by function name
        std::string s;
@@ -834,6 +757,21 @@ ${evalf_switch_statement}
        throw(std::logic_error("function::evalf(): invalid nparams"));
 }
 
+unsigned function::calchash(void) const
+{
+       unsigned v = golden_ratio_hash(golden_ratio_hash(tinfo()) ^ serial);
+       for (unsigned i=0; i<nops(); i++) {
+               v = rotate_left_31(v);
+               v ^= this->op(i).gethash();
+       }
+       v &= 0x7FFFFFFFU;
+       if (flags & status_flags::evaluated) {
+               setflag(status_flags::hash_calculated);
+               hashvalue = v;
+       }
+       return v;
+}
+
 ex function::thisexprseq(const exvector & v) const
 {
        return function(serial,v);
@@ -1043,9 +981,7 @@ unsigned function::find_function(const std::string &name, unsigned nparams)
 const function some_function;
 const std::type_info & typeid_function=typeid(some_function);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 END_OF_IMPLEMENTATION
 
index 480da0f..3c37884 100644 (file)
@@ -30,9 +30,7 @@
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(idx, basic)
 
@@ -527,6 +525,4 @@ ex subs_indices(const ex & e, const exvector & idxv_subs, const exvector & idxv_
        return res;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 3c8ec34..66e2502 100644 (file)
@@ -28,9 +28,7 @@
 #include "basic.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** This class holds one index of an indexed object. Indices can be symbolic
@@ -105,8 +103,6 @@ unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir);
 ex subs_indices(const ex & e, const exvector & idxv_contra, const exvector & idxv_co);
 unsigned count_index(const ex & e, const ex & i);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_IDX_H__
index be4a7cb..9456f38 100644 (file)
@@ -27,9 +27,7 @@
 #include "idx.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(indexed, exprseq)
 
@@ -310,6 +308,4 @@ bool indexed::all_of_type_idx(void) const
        return true;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index cc604f1..94ba0e6 100644 (file)
@@ -26,9 +26,7 @@
 #include <string>
 #include "exprseq.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** Base class for objects with indices. */
@@ -84,8 +82,6 @@ inline const indexed &ex_to_indexed(const ex &e)
        return static_cast<const indexed &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_INDEXED_H__
index d5c90e1..fbdceb7 100644 (file)
@@ -37,9 +37,7 @@
 #include "symbol.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 //////////
 // absolute value
@@ -527,6 +525,4 @@ ex ncpower(const ex &basis, unsigned exponent)
 unsigned force_include_tgamma = function_index_tgamma;
 unsigned force_include_zeta1 = function_index_zeta1;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index eaf8488..73fff21 100644 (file)
@@ -26,9 +26,7 @@
 #include "function.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** Absolute value. */
 DECLARE_FUNCTION_1P(abs)
@@ -142,8 +140,6 @@ inline bool is_order_function(const ex & e)
        return is_ex_the_function(e, Order);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_INIFCNS_H__
index d180065..57dbeb3 100644 (file)
@@ -33,9 +33,7 @@
 #include "symbol.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 //////////
 // Logarithm of Gamma function
@@ -546,6 +544,4 @@ const unsigned function_index_psi2 =
                               overloaded(2));
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index cceaad9..dbbb122 100644 (file)
@@ -34,9 +34,7 @@
 #include "pseries.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 //////////
 // exponential function
@@ -1055,6 +1053,4 @@ REGISTER_FUNCTION(atanh, eval_func(atanh_eval).
                          series_func(atanh_series));
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index a39d8e6..0f06908 100644 (file)
@@ -30,9 +30,7 @@
 #include "symbol.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 //////////
 // Riemann's Zeta-function
@@ -120,6 +118,4 @@ const unsigned function_index_zeta2 =
                               derivative_func(zeta2_deriv).
                               overloaded(2));
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index dfb221e..0b4f8bd 100644 (file)
@@ -43,9 +43,7 @@ extern char *ginac_yytext;
 extern char ginac_yytext[];
 #endif
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class ex;
 
@@ -67,8 +65,6 @@ extern ex parsed_ex;
 /** Get error message from the parser. */
 extern std::string get_parser_error(void);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_INPUT_LEXER_H__
index 1be79d5..2a2a254 100644 (file)
@@ -31,9 +31,7 @@
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(isospin, indexed)
 
@@ -214,9 +212,7 @@ std::string & isospin::autoname_prefix(void)
 
 // private
 
-unsigned isospin::next_serial=0;
+unsigned isospin::next_serial = 0;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
index d9d93a8..925ef63 100644 (file)
@@ -26,9 +26,7 @@
 #include <string>
 #include "indexed.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** Base class for isospin object */
 class isospin : public indexed
@@ -74,8 +72,6 @@ inline const isospin &ex_to_isospin(const ex &e)
        return static_cast<const isospin &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_ISOSPIN_H__
index ca88d94..783316c 100644 (file)
@@ -29,9 +29,7 @@
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(lorentzidx, idx)
 
@@ -296,6 +294,4 @@ ex Dim(void)
        return *d;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 20be2b5..d4226e1 100644 (file)
@@ -27,9 +27,7 @@
 #include <vector>
 #include "idx.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** Class of indices for Lorentz tensors, to tell them apart from other
@@ -91,8 +89,6 @@ inline const lorentzidx &ex_to_lorentzidx(const ex &e)
 
 ex Dim(void);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_LORENTZIDX_H__
index e8f4f87..1dae91a 100644 (file)
@@ -40,9 +40,7 @@
 #include "utils.h"
 #include "config.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(lortensor, indexed)
 
@@ -554,7 +552,7 @@ ex simplify_lortensor_mul(const ex & m)
 ex simplify_lortensor(const ex & e)
 {
        // all simplification is done on expanded objects
-       ex e_expanded=e.expand();
+       ex e_expanded = e.expand();
 
        // simplification of sum=sum of simplifications
        if (is_ex_exactly_of_type(e_expanded,add)) {
@@ -574,6 +572,4 @@ ex simplify_lortensor(const ex & e)
        return e_expanded;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 8da739d..8fbadd3 100644 (file)
@@ -29,9 +29,7 @@
 #include "indexed.h"
 #include "lorentzidx.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 
 /** This class holds an object carrying Lorentz indices (of class
@@ -48,8 +46,8 @@ class lortensor : public indexed
        friend lortensor lortensor_delta(const ex & mu, const ex & nu);
        friend lortensor lortensor_epsilon(const ex & mu, const ex & nu,
                                                                           const ex & rho, const ex & sigma);
-       friend lortensor lortensor_vector(const string & n, const ex & mu);
-       friend lortensor lortensor_symbolic(const string & name, const exvector & iv);
+       friend lortensor lortensor_vector(const std::string & n, const ex & mu);
+       friend lortensor lortensor_symbolic(const std::string & name, const exvector & iv);
 
        friend ex simplify_lortensor_mul(const ex & m);
        friend ex simplify_lortensor(const ex & e);
@@ -130,14 +128,12 @@ lortensor lortensor_g(const ex & mu, const ex & nu);
 lortensor lortensor_delta(const ex & mu, const ex & nu);
 lortensor lortensor_epsilon(const ex & mu, const ex & nu,
                             const ex & rho, const ex & sigma);
-lortensor lortensor_vector(const string & n, const ex & mu);
-lortensor lortensor_symbolic(const string & name, const exvector & iv);
+lortensor lortensor_vector(const std::string & n, const ex & mu);
+lortensor lortensor_symbolic(const std::string & name, const exvector & iv);
 
 ex simplify_lortensor_mul(const ex & m);
 ex simplify_lortensor(const ex & e);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_LORTENSOR_H__
index ae8df02..36b6d14 100644 (file)
@@ -1,7 +1,7 @@
 /** @file lst_suppl.cpp
  *
- *  Supplement to lst.cpp, contains the parts which were
- *  not automatically generated. */
+ *  Supplement to lst.cpp, contains the parts which were not automatically
+ *  generated. */
 
 /*
  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
@@ -23,9 +23,7 @@
 
 #include "lst.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 bool lst::info(unsigned inf) const
 {
@@ -33,6 +31,4 @@ bool lst::info(unsigned inf) const
        return basic::info(inf);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 81d31bd..0c32a76 100644 (file)
 #include "symbol.h"
 #include "normal.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(matrix, basic)
 
 //////////
-// default constructor, destructor, copy constructor, assignment operator
-// and helpers:
+// default ctor, dtor, copy ctor, assignment operator and helpers:
 //////////
 
 // public
@@ -50,12 +47,13 @@ GINAC_IMPLEMENT_REGISTERED_CLASS(matrix, basic)
 /** Default ctor.  Initializes to 1 x 1-dimensional zero-matrix. */
 matrix::matrix() : inherited(TINFO_matrix), row(1), col(1)
 {
-       debugmsg("matrix default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("matrix default ctor",LOGLEVEL_CONSTRUCT);
        m.push_back(_ex0());
 }
 
 // protected
 
+/** For use by copy ctor and assignment operator. */
 void matrix::copy(const matrix & other)
 {
        inherited::copy(other);
@@ -70,7 +68,7 @@ void matrix::destroy(bool call_parent)
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
@@ -82,7 +80,7 @@ void matrix::destroy(bool call_parent)
 matrix::matrix(unsigned r, unsigned c)
   : inherited(TINFO_matrix), row(r), col(c)
 {
-       debugmsg("matrix constructor from unsigned,unsigned",LOGLEVEL_CONSTRUCT);
+       debugmsg("matrix ctor from unsigned,unsigned",LOGLEVEL_CONSTRUCT);
        m.resize(r*c, _ex0());
 }
 
@@ -92,7 +90,7 @@ matrix::matrix(unsigned r, unsigned c)
 matrix::matrix(unsigned r, unsigned c, const exvector & m2)
   : inherited(TINFO_matrix), row(r), col(c), m(m2)
 {
-       debugmsg("matrix constructor from unsigned,unsigned,exvector",LOGLEVEL_CONSTRUCT);
+       debugmsg("matrix ctor from unsigned,unsigned,exvector",LOGLEVEL_CONSTRUCT);
 }
 
 //////////
@@ -102,7 +100,7 @@ matrix::matrix(unsigned r, unsigned c, const exvector & m2)
 /** Construct object from archive_node. */
 matrix::matrix(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("matrix constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("matrix ctor from archive_node", LOGLEVEL_CONSTRUCT);
        if (!(n.find_unsigned("row", row)) || !(n.find_unsigned("col", col)))
                throw (std::runtime_error("unknown matrix dimensions in archive"));
        m.reserve(row * col);
@@ -1192,6 +1190,4 @@ ex lst_to_matrix(const ex &l)
        return m;
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index c04a592..02203e0 100644 (file)
 #include "basic.h"
 #include "ex.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** Symbolic matrices. */
 class matrix : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(matrix, basic)
-
-       // other constructors
+       
+       // other ctors
 public:
        matrix(unsigned r, unsigned c);
        matrix(unsigned r, unsigned c, const exvector & m2);
-   
+       
        // functions overriding virtual functions from bases classes
 public:
        void print(std::ostream & os, unsigned upper_precedence=0) const;
@@ -60,9 +58,9 @@ protected:
        
        // non-virtual functions in this class
 public:
-       unsigned rows(void) const        //! Get number of rows.
+       unsigned rows(void) const        /// Get number of rows.
                { return row; }
-       unsigned cols(void) const        //! Get number of columns.
+       unsigned cols(void) const        /// Get number of columns.
                { return col; }
        matrix add(const matrix & other) const;
        matrix sub(const matrix & other) const;
@@ -85,9 +83,9 @@ protected:
        
 // member variables
 protected:
-       unsigned row;             /**< number of rows      */
-       unsigned col;             /**< number of columns   */
-       exvector m;               /**< representation (cols indexed first) */
+       unsigned row;             ///< number of rows
+       unsigned col;             ///< number of columns
+       exvector m;               ///< representation (cols indexed first)
        static unsigned precedence;
 };
 
@@ -138,8 +136,6 @@ inline const matrix &ex_to_matrix(const ex &e)
 
 extern ex lst_to_matrix(const ex &l);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_MATRIX_H__
index 02029c5..70c161c 100644 (file)
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(mul, expairseq)
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dctor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
 mul::mul()
 {
-       debugmsg("mul default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul default ctor",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
 }
 
 // protected
 
+/** For use by copy ctor and assignment operator. */
 void mul::copy(const mul & other)
 {
        inherited::copy(other);
@@ -61,14 +60,14 @@ void mul::destroy(bool call_parent)
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
 
 mul::mul(const ex & lh, const ex & rh)
 {
-       debugmsg("mul constructor from ex,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from ex,ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
        overall_coeff = _ex1();
        construct_from_2_ex(lh,rh);
@@ -77,7 +76,7 @@ mul::mul(const ex & lh, const ex & rh)
 
 mul::mul(const exvector & v)
 {
-       debugmsg("mul constructor from exvector",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from exvector",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
        overall_coeff = _ex1();
        construct_from_exvector(v);
@@ -86,7 +85,7 @@ mul::mul(const exvector & v)
 
 mul::mul(const epvector & v)
 {
-       debugmsg("mul constructor from epvector",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from epvector",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
        overall_coeff = _ex1();
        construct_from_epvector(v);
@@ -95,7 +94,7 @@ mul::mul(const epvector & v)
 
 mul::mul(const epvector & v, const ex & oc)
 {
-       debugmsg("mul constructor from epvector,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from epvector,ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
        overall_coeff = oc;
        construct_from_epvector(v);
@@ -104,7 +103,7 @@ mul::mul(const epvector & v, const ex & oc)
 
 mul::mul(epvector * vp, const ex & oc)
 {
-       debugmsg("mul constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from epvector *,ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
        GINAC_ASSERT(vp!=0);
        overall_coeff = oc;
@@ -115,7 +114,7 @@ mul::mul(epvector * vp, const ex & oc)
 
 mul::mul(const ex & lh, const ex & mh, const ex & rh)
 {
-       debugmsg("mul constructor from ex,ex,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from ex,ex,ex",LOGLEVEL_CONSTRUCT);
        tinfo_key = TINFO_mul;
        exvector factors;
        factors.reserve(3);
@@ -134,7 +133,7 @@ mul::mul(const ex & lh, const ex & mh, const ex & rh)
 /** Construct object from archive_node. */
 mul::mul(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("mul constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("mul ctor from archive_node", LOGLEVEL_CONSTRUCT);
 }
 
 /** Unarchive the object. */
@@ -159,7 +158,7 @@ void mul::print(std::ostream & os, unsigned upper_precedence) const
 {
        debugmsg("mul print",LOGLEVEL_PRINT);
        if (precedence<=upper_precedence) os << "(";
-       bool first=true;
+       bool first = true;
        // first print the overall numeric coefficient:
        numeric coeff = ex_to_numeric(overall_coeff);
        if (coeff.csgn()==-1) os << '-';
@@ -276,8 +275,6 @@ bool mul::info(unsigned inf) const
        return inherited::info(inf);
 }
 
-typedef std::vector<int> intvector;
-
 int mul::degree(const symbol & s) const
 {
        int deg_sum = 0;
@@ -342,54 +339,53 @@ ex mul::eval(int level) const
        //                  *(+(x,y,...);c) -> *(+(*(x,c),*(y,c),...)) (c numeric())
        //                  *(x;1) -> x
        //                  *(;c) -> c
-
+       
        debugmsg("mul eval",LOGLEVEL_MEMBER_FUNCTION);
-
-       epvector * evaled_seqp=evalchildren(level);
+       
+       epvector * evaled_seqp = evalchildren(level);
        if (evaled_seqp!=0) {
                // do more evaluation later
                return (new mul(evaled_seqp,overall_coeff))->
-                                  setflag(status_flags::dynallocated);
+                          setflag(status_flags::dynallocated);
        }
-
+       
 #ifdef DO_GINAC_ASSERT
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul))||
-                          (!(ex_to_numeric((*cit).coeff).is_integer())));
-               GINAC_ASSERT(!((*cit).is_numeric_with_coeff_1()));
-               if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric)) {
-                       printtree(cerr,0);
-               }
+               GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul)) ||
+                            (!(ex_to_numeric((*cit).coeff).is_integer())));
+               GINAC_ASSERT(!(cit->is_canonical_numeric()));
+               if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric))
+                   printtree(std::cerr,0);
                GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric));
                /* for paranoia */
-               expair p=split_ex_to_pair(recombine_pair_to_ex(*cit));
+               expair p = split_ex_to_pair(recombine_pair_to_ex(*cit));
                GINAC_ASSERT(p.rest.is_equal((*cit).rest));
                GINAC_ASSERT(p.coeff.is_equal((*cit).coeff));
                /* end paranoia */
        }
 #endif // def DO_GINAC_ASSERT
-
+       
        if (flags & status_flags::evaluated) {
                GINAC_ASSERT(seq.size()>0);
-               GINAC_ASSERT((seq.size()>1)||!overall_coeff.is_equal(_ex1()));
+               GINAC_ASSERT(seq.size()>1 || !overall_coeff.is_equal(_ex1()));
                return *this;
        }
-
-       int seq_size=seq.size();
+       
+       int seq_size = seq.size();
        if (overall_coeff.is_equal(_ex0())) {
                // *(...,x;0) -> 0
                return _ex0();
        } else if (seq_size==0) {
                // *(;c) -> c
                return overall_coeff;
-       } else if ((seq_size==1)&&overall_coeff.is_equal(_ex1())) {
+       } else if (seq_size==1 && overall_coeff.is_equal(_ex1())) {
                // *(x;1) -> x
                return recombine_pair_to_ex(*(seq.begin()));
        } else if ((seq_size==1) &&
                   is_ex_exactly_of_type((*seq.begin()).rest,add) &&
                   ex_to_numeric((*seq.begin()).coeff).is_equal(_num1())) {
                // *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
-               const add & addref=ex_to_add((*seq.begin()).rest);
+               const add & addref = ex_to_add((*seq.begin()).rest);
                epvector distrseq;
                distrseq.reserve(addref.seq.size());
                for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) {
@@ -429,9 +425,8 @@ exvector mul::get_indices(void) const
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
                exvector subiv=(*cit).rest.get_indices();
                iv.reserve(iv.size()+subiv.size());
-               for (exvector::const_iterator cit2=subiv.begin(); cit2!=subiv.end(); ++cit2) {
+               for (exvector::const_iterator cit2=subiv.begin(); cit2!=subiv.end(); ++cit2)
                        iv.push_back(*cit2);
-               }
        }
        return iv;
 }
@@ -476,11 +471,11 @@ unsigned mul::return_type(void) const
                // mul without factors: should not happen, but commutes
                return return_types::commutative;
        }
-
+       
        bool all_commutative = 1;
        unsigned rt;
        epvector::const_iterator cit_noncommutative_element; // point to first found nc element
-
+       
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
                rt=(*cit).rest.return_type();
                if (rt==return_types::noncommutative_composite) return rt; // one ncc -> mul also ncc
@@ -503,15 +498,13 @@ unsigned mul::return_type(void) const
    
 unsigned mul::return_type_tinfo(void) const
 {
-       if (seq.size()==0) {
-               // mul without factors: should not happen
-               return tinfo_key;
-       }
+       if (seq.size()==0)
+               return tinfo_key;  // mul without factors: should not happen
+       
        // return type_info of first noncommutative element
        for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
-               if ((*cit).rest.return_type()==return_types::noncommutative) {
+               if ((*cit).rest.return_type()==return_types::noncommutative)
                        return (*cit).rest.return_type_tinfo();
-               }
        }
        // no noncommutative element found, should not happen
        return tinfo_key;
@@ -530,10 +523,9 @@ ex mul::thisexpairseq(epvector * vp, const ex & oc) const
 expair mul::split_ex_to_pair(const ex & e) const
 {
        if (is_ex_exactly_of_type(e,power)) {
-               const power & powerref=ex_to_power(e);
-               if (is_ex_exactly_of_type(powerref.exponent,numeric)) {
+               const power & powerref = ex_to_power(e);
+               if (is_ex_exactly_of_type(powerref.exponent,numeric))
                        return expair(powerref.basis,powerref.exponent);
-               }
        }
        return expair(e,_ex1());
 }
@@ -577,14 +569,14 @@ bool mul::expair_needs_further_processing(epp it)
        if (is_ex_exactly_of_type((*it).rest,mul) &&
                ex_to_numeric((*it).coeff).is_integer()) {
                // combined pair is product with integer power -> expand it
-               *it=split_ex_to_pair(recombine_pair_to_ex(*it));
+               *it = split_ex_to_pair(recombine_pair_to_ex(*it));
                return true;
        }
        if (is_ex_exactly_of_type((*it).rest,numeric)) {
                expair ep=split_ex_to_pair(recombine_pair_to_ex(*it));
                if (!ep.is_equal(*it)) {
                        // combined pair is a numeric power which can be simplified
-                       *it=ep;
+                       *it = ep;
                        return true;
                }
                if (ex_to_numeric((*it).coeff).is_equal(_num1())) {
@@ -630,7 +622,6 @@ ex mul::expand(unsigned options) const
                return *this;
        
        exvector sub_expanded_seq;
-       intvector positions_of_adds;
        
        epvector * expanded_seqp = expandchildren(options);
        
@@ -641,7 +632,7 @@ ex mul::expand(unsigned options) const
        non_adds.reserve(expanded_seq.size());
        epvector::const_iterator cit = expanded_seq.begin();
        epvector::const_iterator last = expanded_seq.end();
-       ex last_expanded=_ex1();
+       ex last_expanded = _ex1();
        while (cit!=last) {
                if (is_ex_exactly_of_type((*cit).rest,add) &&
                        ((*cit).coeff.is_equal(_ex1()))) {
@@ -699,6 +690,14 @@ ex mul::expand(unsigned options) const
 // non-virtual functions in this class
 //////////
 
+
+/** Member-wise expand the expairs representing this sequence.  This must be
+ *  overridden from expairseq::expandchildren() and done iteratively in order
+ *  to allow for early cancallations and thus safe memory.
+ *
+ *  @see mul::expand()
+ *  @return pointer to epvector containing expanded representation or zero
+ *  pointer, if sequence is unchanged. */
 epvector * mul::expandchildren(unsigned options) const
 {
        epvector::const_iterator last = seq.end();
@@ -709,7 +708,7 @@ epvector * mul::expandchildren(unsigned options) const
                if (!are_ex_trivially_equal(factor,expanded_factor)) {
                        
                        // something changed, copy seq, eval and return it
-                       epvector *s=new epvector;
+                       epvector *s = new epvector;
                        s->reserve(seq.size());
                        
                        // copy parts of seq which are known not to have changed
@@ -733,7 +732,7 @@ epvector * mul::expandchildren(unsigned options) const
        
        return 0; // nothing has changed
 }
-   
+
 //////////
 // static member variables
 //////////
@@ -742,6 +741,4 @@ epvector * mul::expandchildren(unsigned options) const
 
 unsigned mul::precedence = 50;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index cad3b9b..dba5daf 100644 (file)
 
 #include "expairseq.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** Product of expressions. */
 class mul : public expairseq
 {
        GINAC_DECLARE_REGISTERED_CLASS(mul, expairseq)
-
+       
        friend class add;
        friend class ncmul;
        friend class power;
-
-       // other constructors
+       
+       // other ctors
 public:
        mul(const ex & lh, const ex & rh);
        mul(const exvector & v);
@@ -46,7 +44,7 @@ public:
        mul(const epvector & v, const ex & oc);
        mul(epvector * vp, const ex & oc);
        mul(const ex & lh, const ex & mh, const ex & rh);
-
+       
        // functions overriding virtual functions from bases classes
 public:
        void print(std::ostream & os, unsigned upper_precedence) const;
@@ -87,13 +85,13 @@ protected:
        
        // new virtual functions which can be overridden by derived classes
        // none
-
+       
        // non-virtual functions in this class
 protected:
        epvector * expandchildren(unsigned options) const;
-
+       
 // member variables
-
+       
 protected:
        static unsigned precedence;
 };
@@ -104,8 +102,6 @@ inline const mul &ex_to_mul(const ex &e)
        return static_cast<const mul &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_MUL_H__
index 8650111..745cf96 100644 (file)
@@ -32,9 +32,7 @@
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(ncmul, exprseq)
 
@@ -596,7 +594,7 @@ const exvector & ncmul::get_factors(void) const
 
 // protected
 
-unsigned ncmul::precedence=50;
+unsigned ncmul::precedence = 50;
 
 //////////
 // friend functions
@@ -618,6 +616,4 @@ ex simplified_ncmul(const exvector & v)
                                       status_flags::evaluated);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 5373a75..cc186a0 100644 (file)
@@ -25,9 +25,7 @@
 
 #include "exprseq.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 /** Non-commutative product of expressions. */
 class ncmul : public exprseq
@@ -101,8 +99,6 @@ inline const ncmul &ex_to_ncmul(const ex &e)
        return static_cast <const ncmul &>(*e.bp);
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_NCMUL_H__
index 3eaf420..c1698ff 100644 (file)
@@ -23,7 +23,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <stdexcept>
 #include <algorithm>
 #include <map>
 
@@ -45,9 +44,7 @@
 #include "symbol.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 // If comparing expressions (ex::compare()) is fast, you can set this to 1.
 // Some routines like quo(), rem() and gcd() will then return a quick answer
@@ -621,9 +618,10 @@ typedef std::pair<ex, ex> ex2;
 typedef std::pair<ex, bool> exbool;
 
 struct ex2_less {
-       bool operator() (const ex2 p, const ex2 q) const 
+       bool operator() (const ex2 &p, const ex2 &q) const 
        {
-               return p.first.compare(q.first) < 0 || (!(q.first.compare(p.first) < 0) && p.second.compare(q.second) < 0);        
+               int cmp = p.first.compare(q.first);
+               return ((cmp<0) || (!(cmp>0) && p.second.compare(q.second)<0));
        }
 };
 
@@ -1183,6 +1181,8 @@ numeric ex::max_coefficient(void) const
        return bp->max_coefficient();
 }
 
+/** Implementation ex::max_coefficient().
+ *  @see heur_gcd */
 numeric basic::max_coefficient(void) const
 {
        return _num1();
@@ -1245,11 +1245,7 @@ ex basic::smod(const numeric &xi) const
 
 ex numeric::smod(const numeric &xi) const
 {
-#ifndef NO_NAMESPACE_GINAC
        return GiNaC::smod(*this, xi);
-#else // ndef NO_NAMESPACE_GINAC
-       return ::smod(*this, xi);
-#endif // ndef NO_NAMESPACE_GINAC
 }
 
 ex add::smod(const numeric &xi) const
@@ -1260,21 +1256,13 @@ ex add::smod(const numeric &xi) const
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
                GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
-#ifndef NO_NAMESPACE_GINAC
                numeric coeff = GiNaC::smod(ex_to_numeric(it->coeff), xi);
-#else // ndef NO_NAMESPACE_GINAC
-               numeric coeff = ::smod(ex_to_numeric(it->coeff), xi);
-#endif // ndef NO_NAMESPACE_GINAC
                if (!coeff.is_zero())
                        newseq.push_back(expair(it->rest, coeff));
                it++;
        }
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-#ifndef NO_NAMESPACE_GINAC
        numeric coeff = GiNaC::smod(ex_to_numeric(overall_coeff), xi);
-#else // ndef NO_NAMESPACE_GINAC
-       numeric coeff = ::smod(ex_to_numeric(overall_coeff), xi);
-#endif // ndef NO_NAMESPACE_GINAC
        return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
 }
 
@@ -1290,11 +1278,7 @@ ex mul::smod(const numeric &xi) const
 #endif // def DO_GINAC_ASSERT
        mul * mulcopyp=new mul(*this);
        GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-#ifndef NO_NAMESPACE_GINAC
        mulcopyp->overall_coeff = GiNaC::smod(ex_to_numeric(overall_coeff),xi);
-#else // ndef NO_NAMESPACE_GINAC
-       mulcopyp->overall_coeff = ::smod(ex_to_numeric(overall_coeff),xi);
-#endif // ndef NO_NAMESPACE_GINAC
        mulcopyp->clearflag(status_flags::evaluated);
        mulcopyp->clearflag(status_flags::hash_calculated);
        return mulcopyp->setflag(status_flags::dynallocated);
@@ -2064,8 +2048,8 @@ ex power::normal(lst &sym_lst, lst &repl_lst, int level) const
 }
 
 
-/** Implementation of ex::normal() for pseries. It normalizes each coefficient and
- *  replaces the series by a temporary symbol.
+/** Implementation of ex::normal() for pseries. It normalizes each coefficient
+ *  and replaces the series by a temporary symbol.
  *  @see ex::normal */
 ex pseries::normal(lst &sym_lst, lst &repl_lst, int level) const
 {
@@ -2244,6 +2228,4 @@ ex ex::to_rational(lst &repl_lst) const
 }
 
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index b8424af..b461dcf 100644 (file)
@@ -26,9 +26,7 @@
 #ifndef __GINAC_NORMAL_H__
 #define __GINAC_NORMAL_H__
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class ex;
 class symbol;
@@ -54,8 +52,6 @@ extern ex lcm(const ex &a, const ex &b, bool check_args = true);
 // Square-free factorization of a polynomial a(x)
 extern ex sqrfree(const ex &a, const symbol &x);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_NORMAL_H__
index 358ad45..b40e71f 100644 (file)
 #include <cln/complex_ring.h>
 #include <cln/numtheory.h>
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif  // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(numeric, basic)
 
 //////////
-// default constructor, destructor, copy constructor assignment
+// default ctor, dtor, copy ctor assignment
 // operator and helpers
 //////////
 
@@ -79,36 +77,34 @@ GINAC_IMPLEMENT_REGISTERED_CLASS(numeric, basic)
 /** default ctor. Numerically it initializes to an integer zero. */
 numeric::numeric() : basic(TINFO_numeric)
 {
-       debugmsg("numeric default constructor", LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric default ctor", LOGLEVEL_CONSTRUCT);
        value = cln::cl_I(0);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 // protected
 
-void numeric::copy(const numeric & other)
+/** For use by copy ctor and assignment operator. */
+void numeric::copy(const numeric &other)
 {
-       basic::copy(other);
+       inherited::copy(other);
        value = other.value;
 }
 
 void numeric::destroy(bool call_parent)
 {
-       if (call_parent) basic::destroy(call_parent);
+       if (call_parent) inherited::destroy(call_parent);
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
 
 numeric::numeric(int i) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from int",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from int",LOGLEVEL_CONSTRUCT);
        // Not the whole int-range is available if we don't cast to long
        // first.  This is due to the behaviour of the cl_I-ctor, which
        // emphasizes efficiency.  However, if the integer is small enough, 
@@ -118,16 +114,13 @@ numeric::numeric(int i) : basic(TINFO_numeric)
                value = cln::cl_I(i);
        else
                value = cln::cl_I((long) i);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 
 numeric::numeric(unsigned int i) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from uint",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from uint",LOGLEVEL_CONSTRUCT);
        // Not the whole uint-range is available if we don't cast to ulong
        // first.  This is due to the behaviour of the cl_I-ctor, which
        // emphasizes efficiency.  However, if the integer is small enough, 
@@ -137,32 +130,23 @@ numeric::numeric(unsigned int i) : basic(TINFO_numeric)
                value = cln::cl_I(i);
        else
                value = cln::cl_I((unsigned long) i);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 
 numeric::numeric(long i) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from long",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from long",LOGLEVEL_CONSTRUCT);
        value = cln::cl_I(i);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 
 numeric::numeric(unsigned long i) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from ulong",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from ulong",LOGLEVEL_CONSTRUCT);
        value = cln::cl_I(i);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 /** Ctor for rational numerics a/b.
@@ -170,35 +154,30 @@ numeric::numeric(unsigned long i) : basic(TINFO_numeric)
  *  @exception overflow_error (division by zero) */
 numeric::numeric(long numer, long denom) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from long/long",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from long/long",LOGLEVEL_CONSTRUCT);
        if (!denom)
                throw std::overflow_error("division by zero");
        value = cln::cl_I(numer) / cln::cl_I(denom);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 
 numeric::numeric(double d) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from double",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from double",LOGLEVEL_CONSTRUCT);
        // We really want to explicitly use the type cl_LF instead of the
        // more general cl_F, since that would give us a cl_DF only which
        // will not be promoted to cl_LF if overflow occurs:
        value = cln::cl_float(d, cln::default_float_format);
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
+
 /** ctor from C-style string.  It also accepts complex numbers in GiNaC
  *  notation like "2+5*I". */
 numeric::numeric(const char *s) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from string",LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from string",LOGLEVEL_CONSTRUCT);
        cln::cl_N ctorval = 0;
        // parse complex numbers (functional but not completely safe, unfortunately
        // std::string does not understand regexpese):
@@ -270,22 +249,17 @@ numeric::numeric(const char *s) : basic(TINFO_numeric)
                }
        } while(delim != std::string::npos);
        value = ctorval;
-       calchash();
-       setflag(status_flags::evaluated |
-                       status_flags::expanded |
-                       status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
+
 /** Ctor from CLN types.  This is for the initiated user or internal use
  *  only. */
-numeric::numeric(const cln::cl_N & z) : basic(TINFO_numeric)
+numeric::numeric(const cln::cl_N &z) : basic(TINFO_numeric)
 {
-       debugmsg("numeric constructor from cl_N", LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from cl_N", LOGLEVEL_CONSTRUCT);
        value = z;
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 //////////
@@ -295,7 +269,7 @@ numeric::numeric(const cln::cl_N & z) : basic(TINFO_numeric)
 /** Construct object from archive_node. */
 numeric::numeric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("numeric constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("numeric ctor from archive_node", LOGLEVEL_CONSTRUCT);
        cln::cl_N ctorval = 0;
 
        // Read number as string
@@ -327,10 +301,7 @@ numeric::numeric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_l
                }
        }
        value = ctorval;
-       calchash();
-       setflag(status_flags::evaluated |
-               status_flags::expanded |
-               status_flags::hash_calculated);
+       setflag(status_flags::evaluated | status_flags::expanded);
 }
 
 /** Unarchive the object. */
@@ -388,7 +359,7 @@ void numeric::archive(archive_node &n) const
  *  want to visibly distinguish from cl_LF.
  *
  *  @see numeric::print() */
-static void print_real_number(std::ostream & os, const cln::cl_R & num)
+static void print_real_number(std::ostream &os, const cln::cl_R &num)
 {
        cln::cl_print_flags ourflags;
        if (cln::instanceof(num, cln::cl_RA_ring)) {
@@ -408,7 +379,7 @@ static void print_real_number(std::ostream & os, const cln::cl_R & num)
  *  with the other routines and produces something compatible to ginsh input.
  *  
  *  @see print_real_number() */
-void numeric::print(std::ostream & os, unsigned upper_precedence) const
+void numeric::print(std::ostream &os, unsigned upper_precedence) const
 {
        debugmsg("numeric print", LOGLEVEL_PRINT);
        cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
@@ -473,7 +444,7 @@ void numeric::print(std::ostream & os, unsigned upper_precedence) const
 }
 
 
-void numeric::printraw(std::ostream & os) const
+void numeric::printraw(std::ostream &os) const
 {
        // The method printraw doesn't do much, it simply uses CLN's operator<<()
        // for output, which is ugly but reliable. e.g: 2+2i
@@ -482,7 +453,7 @@ void numeric::printraw(std::ostream & os) const
 }
 
 
-void numeric::printtree(std::ostream & os, unsigned indent) const
+void numeric::printtree(std::ostream &os, unsigned indent) const
 {
        debugmsg("numeric printtree", LOGLEVEL_PRINT);
        os << std::string(indent,' ') << cln::the<cln::cl_N>(value)
@@ -493,7 +464,7 @@ void numeric::printtree(std::ostream & os, unsigned indent) const
 }
 
 
-void numeric::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
+void numeric::printcsrc(std::ostream &os, unsigned type, unsigned upper_precedence) const
 {
        debugmsg("numeric print csrc", LOGLEVEL_PRINT);
        std::ios::fmtflags oldflags = os.flags();
@@ -579,11 +550,11 @@ bool numeric::info(unsigned inf) const
  *  results:  (2+I).has(-2) -> true.  But this is consistent, since we also
  *  would like to have (-2+I).has(2) -> true and we want to think about the
  *  sign as a multiplicative factor. */
-bool numeric::has(const ex & other) const
+bool numeric::has(const ex &other) const
 {
        if (!is_exactly_of_type(*other.bp, numeric))
                return false;
-       const numeric & o = static_cast<numeric &>(const_cast<basic &>(*other.bp));
+       const numeric &o = static_cast<numeric &>(const_cast<basic &>(*other.bp));
        if (this->is_equal(o) || this->is_equal(-o))
                return true;
        if (o.imag().is_zero())  // e.g. scan for 3 in -3*I
@@ -620,30 +591,21 @@ ex numeric::evalf(int level) const
 {
        // level can safely be discarded for numeric objects.
        return numeric(cln::cl_float(1.0, cln::default_float_format) *
-                                  (cln::the<cln::cl_N>(value)));
+                      (cln::the<cln::cl_N>(value)));
 }
 
 // protected
 
-/** Implementation of ex::diff() for a numeric. It always returns 0.
- *
- *  @see ex::diff */
-ex numeric::derivative(const symbol & s) const
-{
-       return _ex0();
-}
-
-
-int numeric::compare_same_type(const basic & other) const
+int numeric::compare_same_type(const basic &other) const
 {
        GINAC_ASSERT(is_exactly_of_type(other, numeric));
-       const numeric & o = static_cast<numeric &>(const_cast<basic &>(other));
+       const numeric &o = static_cast<numeric &>(const_cast<basic &>(other));
        
        return this->compare(o);
 }
 
 
-bool numeric::is_equal_same_type(const basic & other) const
+bool numeric::is_equal_same_type(const basic &other) const
 {
        GINAC_ASSERT(is_exactly_of_type(other,numeric));
        const numeric *o = static_cast<const numeric *>(&other);
@@ -657,6 +619,7 @@ unsigned numeric::calchash(void) const
        // Use CLN's hashcode.  Warning: It depends only on the number's value, not
        // its type or precision (i.e. a true equivalence relation on numbers).  As
        // a consequence, 3 and 3.0 share the same hashvalue.
+       setflag(status_flags::hash_calculated);
        return (hashvalue = cln::equal_hashcode(cln::the<cln::cl_N>(value)) | 0x80000000U);
 }
 
@@ -674,8 +637,8 @@ unsigned numeric::calchash(void) const
 // public
 
 /** Numerical addition method.  Adds argument to *this and returns result as
- *  a new numeric object. */
-const numeric numeric::add(const numeric & other) const
+ *  a numeric object. */
+const numeric numeric::add(const numeric &other) const
 {
        // Efficiency shortcut: trap the neutral element by pointer.
        static const numeric * _num0p = &_num0();
@@ -689,16 +652,16 @@ const numeric numeric::add(const numeric & other) const
 
 
 /** Numerical subtraction method.  Subtracts argument from *this and returns
- *  result as a new numeric object. */
-const numeric numeric::sub(const numeric & other) const
+ *  result as a numeric object. */
+const numeric numeric::sub(const numeric &other) const
 {
        return numeric(cln::the<cln::cl_N>(value)-cln::the<cln::cl_N>(other.value));
 }
 
 
 /** Numerical multiplication method.  Multiplies *this and argument and returns
- *  result as a new numeric object. */
-const numeric numeric::mul(const numeric & other) const
+ *  result as a numeric object. */
+const numeric numeric::mul(const numeric &other) const
 {
        // Efficiency shortcut: trap the neutral element by pointer.
        static const numeric * _num1p = &_num1();
@@ -712,10 +675,10 @@ const numeric numeric::mul(const numeric & other) const
 
 
 /** Numerical division method.  Divides *this by argument and returns result as
- *  a new numeric object.
+ *  a numeric object.
  *
  *  @exception overflow_error (division by zero) */
-const numeric numeric::div(const numeric & other) const
+const numeric numeric::div(const numeric &other) const
 {
        if (cln::zerop(cln::the<cln::cl_N>(other.value)))
                throw std::overflow_error("numeric::div(): division by zero");
@@ -723,7 +686,9 @@ const numeric numeric::div(const numeric & other) const
 }
 
 
-const numeric numeric::power(const numeric & other) const
+/** Numerical exponentiation.  Raises *this to the power given as argument and
+ *  returns result as a numeric object. */
+const numeric numeric::power(const numeric &other) const
 {
        // Efficiency shortcut: trap the neutral exponent by pointer.
        static const numeric * _num1p = &_num1();
@@ -744,7 +709,7 @@ const numeric numeric::power(const numeric & other) const
 }
 
 
-const numeric & numeric::add_dyn(const numeric & other) const
+const numeric &numeric::add_dyn(const numeric &other) const
 {
        // Efficiency shortcut: trap the neutral element by pointer.
        static const numeric * _num0p = &_num0();
@@ -758,14 +723,14 @@ const numeric & numeric::add_dyn(const numeric & other) const
 }
 
 
-const numeric & numeric::sub_dyn(const numeric & other) const
+const numeric &numeric::sub_dyn(const numeric &other) const
 {
        return static_cast<const numeric &>((new numeric(cln::the<cln::cl_N>(value)-cln::the<cln::cl_N>(other.value)))->
                                                                                setflag(status_flags::dynallocated));
 }
 
 
-const numeric & numeric::mul_dyn(const numeric & other) const
+const numeric &numeric::mul_dyn(const numeric &other) const
 {
        // Efficiency shortcut: trap the neutral element by pointer.
        static const numeric * _num1p = &_num1();
@@ -779,7 +744,7 @@ const numeric & numeric::mul_dyn(const numeric & other) const
 }
 
 
-const numeric & numeric::div_dyn(const numeric & other) const
+const numeric &numeric::div_dyn(const numeric &other) const
 {
        if (cln::zerop(cln::the<cln::cl_N>(other.value)))
                throw std::overflow_error("division by zero");
@@ -788,7 +753,7 @@ const numeric & numeric::div_dyn(const numeric & other) const
 }
 
 
-const numeric & numeric::power_dyn(const numeric & other) const
+const numeric &numeric::power_dyn(const numeric &other) const
 {
        // Efficiency shortcut: trap the neutral exponent by pointer.
        static const numeric * _num1p=&_num1();
@@ -810,37 +775,37 @@ const numeric & numeric::power_dyn(const numeric & other) const
 }
 
 
-const numeric & numeric::operator=(int i)
+const numeric &numeric::operator=(int i)
 {
        return operator=(numeric(i));
 }
 
 
-const numeric & numeric::operator=(unsigned int i)
+const numeric &numeric::operator=(unsigned int i)
 {
        return operator=(numeric(i));
 }
 
 
-const numeric & numeric::operator=(long i)
+const numeric &numeric::operator=(long i)
 {
        return operator=(numeric(i));
 }
 
 
-const numeric & numeric::operator=(unsigned long i)
+const numeric &numeric::operator=(unsigned long i)
 {
        return operator=(numeric(i));
 }
 
 
-const numeric & numeric::operator=(double d)
+const numeric &numeric::operator=(double d)
 {
        return operator=(numeric(d));
 }
 
 
-const numeric & numeric::operator=(const char * s)
+const numeric &numeric::operator=(const char * s)
 {
        return operator=(numeric(s));
 }
@@ -859,7 +824,7 @@ const numeric numeric::inverse(void) const
  *  csgn(x)==0 for x==0, csgn(x)==1 for Re(x)>0 or Re(x)=0 and Im(x)>0,
  *  csgn(x)==-1 for Re(x)<0 or Re(x)=0 and Im(x)<0.
  *
- *  @see numeric::compare(const numeric & other) */
+ *  @see numeric::compare(const numeric &other) */
 int numeric::csgn(void) const
 {
        if (cln::zerop(cln::the<cln::cl_N>(value)))
@@ -886,7 +851,7 @@ int numeric::csgn(void) const
  *
  *  @return csgn(*this-other)
  *  @see numeric::csgn(void) */
-int numeric::compare(const numeric & other) const
+int numeric::compare(const numeric &other) const
 {
        // Comparing two real numbers?
        if (cln::instanceof(value, cln::cl_R_ring) &&
@@ -904,7 +869,7 @@ int numeric::compare(const numeric & other) const
 }
 
 
-bool numeric::is_equal(const numeric & other) const
+bool numeric::is_equal(const numeric &other) const
 {
        return cln::equal(cln::the<cln::cl_N>(value),cln::the<cln::cl_N>(other.value));
 }
@@ -994,13 +959,13 @@ bool numeric::is_real(void) const
 }
 
 
-bool numeric::operator==(const numeric & other) const
+bool numeric::operator==(const numeric &other) const
 {
        return equal(cln::the<cln::cl_N>(value), cln::the<cln::cl_N>(other.value));
 }
 
 
-bool numeric::operator!=(const numeric & other) const
+bool numeric::operator!=(const numeric &other) const
 {
        return !equal(cln::the<cln::cl_N>(value), cln::the<cln::cl_N>(other.value));
 }
@@ -1039,7 +1004,7 @@ bool numeric::is_crational(void) const
 /** Numerical comparison: less.
  *
  *  @exception invalid_argument (complex inequality) */ 
-bool numeric::operator<(const numeric & other) const
+bool numeric::operator<(const numeric &other) const
 {
        if (this->is_real() && other.is_real())
                return (cln::the<cln::cl_R>(value) < cln::the<cln::cl_R>(other.value));
@@ -1050,7 +1015,7 @@ bool numeric::operator<(const numeric & other) const
 /** Numerical comparison: less or equal.
  *
  *  @exception invalid_argument (complex inequality) */ 
-bool numeric::operator<=(const numeric & other) const
+bool numeric::operator<=(const numeric &other) const
 {
        if (this->is_real() && other.is_real())
                return (cln::the<cln::cl_R>(value) <= cln::the<cln::cl_R>(other.value));
@@ -1061,7 +1026,7 @@ bool numeric::operator<=(const numeric & other) const
 /** Numerical comparison: greater.
  *
  *  @exception invalid_argument (complex inequality) */ 
-bool numeric::operator>(const numeric & other) const
+bool numeric::operator>(const numeric &other) const
 {
        if (this->is_real() && other.is_real())
                return (cln::the<cln::cl_R>(value) > cln::the<cln::cl_R>(other.value));
@@ -1072,7 +1037,7 @@ bool numeric::operator>(const numeric & other) const
 /** Numerical comparison: greater or equal.
  *
  *  @exception invalid_argument (complex inequality) */  
-bool numeric::operator>=(const numeric & other) const
+bool numeric::operator>=(const numeric &other) const
 {
        if (this->is_real() && other.is_real())
                return (cln::the<cln::cl_R>(value) >= cln::the<cln::cl_R>(other.value));
@@ -1220,14 +1185,15 @@ unsigned numeric::precedence = 30;
 //////////
 
 /** Imaginary unit.  This is not a constant but a numeric since we are
- *  natively handing complex numbers anyways. */
+ *  natively handing complex numbers anyways, so in each expression containing
+ *  an I it is automatically eval'ed away anyhow. */
 const numeric I = numeric(cln::complex(cln::cl_I(0),cln::cl_I(1)));
 
 
 /** Exponential function.
  *
  *  @return  arbitrary precision numerical exp(x). */
-const numeric exp(const numeric & x)
+const numeric exp(const numeric &x)
 {
        return cln::exp(x.to_cl_N());
 }
@@ -1238,7 +1204,7 @@ const numeric exp(const numeric & x)
  *  @param z complex number
  *  @return  arbitrary precision numerical log(x).
  *  @exception pole_error("log(): logarithmic pole",0) */
-const numeric log(const numeric & z)
+const numeric log(const numeric &z)
 {
        if (z.is_zero())
                throw pole_error("log(): logarithmic pole",0);
@@ -1249,7 +1215,7 @@ const numeric log(const numeric & z)
 /** Numeric sine (trigonometric function).
  *
  *  @return  arbitrary precision numerical sin(x). */
-const numeric sin(const numeric & x)
+const numeric sin(const numeric &x)
 {
        return cln::sin(x.to_cl_N());
 }
@@ -1258,7 +1224,7 @@ const numeric sin(const numeric & x)
 /** Numeric cosine (trigonometric function).
  *
  *  @return  arbitrary precision numerical cos(x). */
-const numeric cos(const numeric & x)
+const numeric cos(const numeric &x)
 {
        return cln::cos(x.to_cl_N());
 }
@@ -1267,7 +1233,7 @@ const numeric cos(const numeric & x)
 /** Numeric tangent (trigonometric function).
  *
  *  @return  arbitrary precision numerical tan(x). */
-const numeric tan(const numeric & x)
+const numeric tan(const numeric &x)
 {
        return cln::tan(x.to_cl_N());
 }
@@ -1276,7 +1242,7 @@ const numeric tan(const numeric & x)
 /** Numeric inverse sine (trigonometric function).
  *
  *  @return  arbitrary precision numerical asin(x). */
-const numeric asin(const numeric & x)
+const numeric asin(const numeric &x)
 {
        return cln::asin(x.to_cl_N());
 }
@@ -1285,7 +1251,7 @@ const numeric asin(const numeric & x)
 /** Numeric inverse cosine (trigonometric function).
  *
  *  @return  arbitrary precision numerical acos(x). */
-const numeric acos(const numeric & x)
+const numeric acos(const numeric &x)
 {
        return cln::acos(x.to_cl_N());
 }
@@ -1296,7 +1262,7 @@ const numeric acos(const numeric & x)
  *  @param z complex number
  *  @return atan(z)
  *  @exception pole_error("atan(): logarithmic pole",0) */
-const numeric atan(const numeric & x)
+const numeric atan(const numeric &x)
 {
        if (!x.is_real() &&
            x.real().is_zero() &&
@@ -1311,7 +1277,7 @@ const numeric atan(const numeric & x)
  *  @param x real number
  *  @param y real number
  *  @return atan(y/x) */
-const numeric atan(const numeric & y, const numeric & x)
+const numeric atan(const numeric &y, const numeric &x)
 {
        if (x.is_real() && y.is_real())
                return cln::atan(cln::the<cln::cl_R>(x.to_cl_N()),
@@ -1324,7 +1290,7 @@ const numeric atan(const numeric & y, const numeric & x)
 /** Numeric hyperbolic sine (trigonometric function).
  *
  *  @return  arbitrary precision numerical sinh(x). */
-const numeric sinh(const numeric & x)
+const numeric sinh(const numeric &x)
 {
        return cln::sinh(x.to_cl_N());
 }
@@ -1333,7 +1299,7 @@ const numeric sinh(const numeric & x)
 /** Numeric hyperbolic cosine (trigonometric function).
  *
  *  @return  arbitrary precision numerical cosh(x). */
-const numeric cosh(const numeric & x)
+const numeric cosh(const numeric &x)
 {
        return cln::cosh(x.to_cl_N());
 }
@@ -1342,7 +1308,7 @@ const numeric cosh(const numeric & x)
 /** Numeric hyperbolic tangent (trigonometric function).
  *
  *  @return  arbitrary precision numerical tanh(x). */
-const numeric tanh(const numeric & x)
+const numeric tanh(const numeric &x)
 {
        return cln::tanh(x.to_cl_N());
 }
@@ -1351,7 +1317,7 @@ const numeric tanh(const numeric & x)
 /** Numeric inverse hyperbolic sine (trigonometric function).
  *
  *  @return  arbitrary precision numerical asinh(x). */
-const numeric asinh(const numeric & x)
+const numeric asinh(const numeric &x)
 {
        return cln::asinh(x.to_cl_N());
 }
@@ -1360,7 +1326,7 @@ const numeric asinh(const numeric & x)
 /** Numeric inverse hyperbolic cosine (trigonometric function).
  *
  *  @return  arbitrary precision numerical acosh(x). */
-const numeric acosh(const numeric & x)
+const numeric acosh(const numeric &x)
 {
        return cln::acosh(x.to_cl_N());
 }
@@ -1369,14 +1335,14 @@ const numeric acosh(const numeric & x)
 /** Numeric inverse hyperbolic tangent (trigonometric function).
  *
  *  @return  arbitrary precision numerical atanh(x). */
-const numeric atanh(const numeric & x)
+const numeric atanh(const numeric &x)
 {
        return cln::atanh(x.to_cl_N());
 }
 
 
-/*static cln::cl_N Li2_series(const ::cl_N & x,
-                            const ::float_format_t & prec)
+/*static cln::cl_N Li2_series(const ::cl_N &x,
+                            const ::float_format_t &prec)
 {
        // Note: argument must be in the unit circle
        // This is very inefficient unless we have fast floating point Bernoulli
@@ -1403,8 +1369,8 @@ const numeric atanh(const numeric & x)
 
 /** Numeric evaluation of Dilogarithm within circle of convergence (unit
  *  circle) using a power series. */
-static cln::cl_N Li2_series(const cln::cl_N & x,
-                            const cln::float_format_t & prec)
+static cln::cl_N Li2_series(const cln::cl_N &x,
+                            const cln::float_format_t &prec)
 {
        // Note: argument must be in the unit circle
        cln::cl_N aug, acc;
@@ -1422,8 +1388,8 @@ static cln::cl_N Li2_series(const cln::cl_N & x,
 }
 
 /** Folds Li2's argument inside a small rectangle to enhance convergence. */
-static cln::cl_N Li2_projection(const cln::cl_N & x,
-                                const cln::float_format_t & prec)
+static cln::cl_N Li2_projection(const cln::cl_N &x,
+                                const cln::float_format_t &prec)
 {
        const cln::cl_R re = cln::realpart(x);
        const cln::cl_R im = cln::imagpart(x);
@@ -1448,7 +1414,7 @@ static cln::cl_N Li2_projection(const cln::cl_N & x,
  *  continuous with quadrant IV.
  *
  *  @return  arbitrary precision numerical Li2(x). */
-const numeric Li2(const numeric & x)
+const numeric Li2(const numeric &x)
 {
        if (x.is_zero())
                return _num0();
@@ -1478,7 +1444,7 @@ const numeric Li2(const numeric & x)
 
 /** Numeric evaluation of Riemann's Zeta function.  Currently works only for
  *  integer arguments. */
-const numeric zeta(const numeric & x)
+const numeric zeta(const numeric &x)
 {
        // A dirty hack to allow for things like zeta(3.0), since CLN currently
        // only knows about integer arguments and zeta(3).evalf() automatically
@@ -1491,7 +1457,7 @@ const numeric zeta(const numeric & x)
                        return cln::zeta(aux);
        }
        std::clog << "zeta(" << x
-                         << "): Does anybody know good way to calculate this numerically?"
+                         << "): Does anybody know good way to calculate this numerically?"
                          << std::endl;
        return numeric(0);
 }
@@ -1499,17 +1465,17 @@ const numeric zeta(const numeric & x)
 
 /** The Gamma function.
  *  This is only a stub! */
-const numeric lgamma(const numeric & x)
+const numeric lgamma(const numeric &x)
 {
        std::clog << "lgamma(" << x
-                 << "): Does anybody know good way to calculate this numerically?"
+                 << "): Does anybody know good way to calculate this numerically?"
                  << std::endl;
        return numeric(0);
 }
-const numeric tgamma(const numeric & x)
+const numeric tgamma(const numeric &x)
 {
        std::clog << "tgamma(" << x
-                 << "): Does anybody know good way to calculate this numerically?"
+                 << "): Does anybody know good way to calculate this numerically?"
                  << std::endl;
        return numeric(0);
 }
@@ -1517,10 +1483,10 @@ const numeric tgamma(const numeric & x)
 
 /** The psi function (aka polygamma function).
  *  This is only a stub! */
-const numeric psi(const numeric & x)
+const numeric psi(const numeric &x)
 {
        std::clog << "psi(" << x
-                 << "): Does anybody know good way to calculate this numerically?"
+                 << "): Does anybody know good way to calculate this numerically?"
                  << std::endl;
        return numeric(0);
 }
@@ -1528,10 +1494,10 @@ const numeric psi(const numeric & x)
 
 /** The psi functions (aka polygamma functions).
  *  This is only a stub! */
-const numeric psi(const numeric & n, const numeric & x)
+const numeric psi(const numeric &n, const numeric &x)
 {
        std::clog << "psi(" << n << "," << x
-                 << "): Does anybody know good way to calculate this numerically?"
+                 << "): Does anybody know good way to calculate this numerically?"
                  << std::endl;
        return numeric(0);
 }
@@ -1541,7 +1507,7 @@ const numeric psi(const numeric & n, const numeric & x)
  *
  *  @param n  integer argument >= 0
  *  @exception range_error (argument must be integer >= 0) */
-const numeric factorial(const numeric & n)
+const numeric factorial(const numeric &n)
 {
        if (!n.is_nonneg_integer())
                throw std::range_error("numeric::factorial(): argument must be integer >= 0");
@@ -1555,9 +1521,9 @@ const numeric factorial(const numeric & n)
  *  @param n  integer argument >= -1
  *  @return n!! == n * (n-2) * (n-4) * ... * ({1|2}) with 0!! == (-1)!! == 1
  *  @exception range_error (argument must be integer >= -1) */
-const numeric doublefactorial(const numeric & n)
+const numeric doublefactorial(const numeric &n)
 {
-       if (n == numeric(-1))
+       if (n.is_equal(_num_1()))
                return _num1();
        
        if (!n.is_nonneg_integer())
@@ -1571,7 +1537,7 @@ const numeric doublefactorial(const numeric & n)
  *  integer n and k and positive n this is the number of ways of choosing k
  *  objects from n distinct objects.  If n is negative, the formula
  *  binomial(n,k) == (-1)^k*binomial(k-n-1,k) is used to compute the result. */
-const numeric binomial(const numeric & n, const numeric & k)
+const numeric binomial(const numeric &n, const numeric &k)
 {
        if (n.is_integer() && k.is_integer()) {
                if (n.is_nonneg_integer()) {
@@ -1594,7 +1560,7 @@ const numeric binomial(const numeric & n, const numeric & k)
  *
  *  @return the nth Bernoulli number (a rational number).
  *  @exception range_error (argument must be integer >= 0) */
-const numeric bernoulli(const numeric & nn)
+const numeric bernoulli(const numeric &nn)
 {
        if (!nn.is_integer() || nn.is_negative())
                throw std::range_error("numeric::bernoulli(): argument must be integer >= 0");
@@ -1671,7 +1637,7 @@ const numeric bernoulli(const numeric & nn)
  *  @param n an integer
  *  @return the nth Fibonacci number F(n) (an integer number)
  *  @exception range_error (argument must be an integer) */
-const numeric fibonacci(const numeric & n)
+const numeric fibonacci(const numeric &n)
 {
        if (!n.is_integer())
                throw std::range_error("numeric::fibonacci(): argument must be integer");
@@ -1738,7 +1704,7 @@ const numeric abs(const numeric& x)
  *
  *  @return a mod b in the range [0,abs(b)-1] with sign of b if both are
  *  integer, 0 otherwise. */
-const numeric mod(const numeric & a, const numeric & b)
+const numeric mod(const numeric &a, const numeric &b)
 {
        if (a.is_integer() && b.is_integer())
                return cln::mod(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1752,7 +1718,7 @@ const numeric mod(const numeric & a, const numeric & b)
  *  Equivalent to Maple's mods.
  *
  *  @return a mod b in the range [-iquo(abs(m)-1,2), iquo(abs(m),2)]. */
-const numeric smod(const numeric & a, const numeric & b)
+const numeric smod(const numeric &a, const numeric &b)
 {
        if (a.is_integer() && b.is_integer()) {
                const cln::cl_I b2 = cln::ceiling1(cln::the<cln::cl_I>(b.to_cl_N()) >> 1) - 1;
@@ -1769,7 +1735,7 @@ const numeric smod(const numeric & a, const numeric & b)
  *  sign of a or is zero.
  *
  *  @return remainder of a/b if both are integer, 0 otherwise. */
-const numeric irem(const numeric & a, const numeric & b)
+const numeric irem(const numeric &a, const numeric &b)
 {
        if (a.is_integer() && b.is_integer())
                return cln::rem(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1786,7 +1752,7 @@ const numeric irem(const numeric & a, const numeric & b)
  *
  *  @return remainder of a/b and quotient stored in q if both are integer,
  *  0 otherwise. */
-const numeric irem(const numeric & a, const numeric & b, numeric & q)
+const numeric irem(const numeric &a, const numeric &b, numeric &q)
 {
        if (a.is_integer() && b.is_integer()) {
                const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1804,7 +1770,7 @@ const numeric irem(const numeric & a, const numeric & b, numeric & q)
  *  Equivalent to Maple's iquo as far as sign conventions are concerned.
  *  
  *  @return truncated quotient of a/b if both are integer, 0 otherwise. */
-const numeric iquo(const numeric & a, const numeric & b)
+const numeric iquo(const numeric &a, const numeric &b)
 {
        if (a.is_integer() && b.is_integer())
                return truncate1(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1820,7 +1786,7 @@ const numeric iquo(const numeric & a, const numeric & b)
  *
  *  @return truncated quotient of a/b and remainder stored in r if both are
  *  integer, 0 otherwise. */
-const numeric iquo(const numeric & a, const numeric & b, numeric & r)
+const numeric iquo(const numeric &a, const numeric &b, numeric &r)
 {
        if (a.is_integer() && b.is_integer()) {
                const cln::cl_I_div_t rem_quo = cln::truncate2(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1838,7 +1804,7 @@ const numeric iquo(const numeric & a, const numeric & b, numeric & r)
  *   
  *  @return  The GCD of two numbers if both are integer, a numerical 1
  *  if they are not. */
-const numeric gcd(const numeric & a, const numeric & b)
+const numeric gcd(const numeric &a, const numeric &b)
 {
        if (a.is_integer() && b.is_integer())
                return cln::gcd(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1852,7 +1818,7 @@ const numeric gcd(const numeric & a, const numeric & b)
  *   
  *  @return  The LCM of two numbers if both are integer, the product of those
  *  two numbers if they are not. */
-const numeric lcm(const numeric & a, const numeric & b)
+const numeric lcm(const numeric &a, const numeric &b)
 {
        if (a.is_integer() && b.is_integer())
                return cln::lcm(cln::the<cln::cl_I>(a.to_cl_N()),
@@ -1870,14 +1836,14 @@ const numeric lcm(const numeric & a, const numeric & b)
  *  @return square root of z. Branch cut along negative real axis, the negative
  *  real axis itself where imag(z)==0 and real(z)<0 belongs to the upper part
  *  where imag(z)>0. */
-const numeric sqrt(const numeric & z)
+const numeric sqrt(const numeric &z)
 {
        return cln::sqrt(z.to_cl_N());
 }
 
 
 /** Integer numeric square root. */
-const numeric isqrt(const numeric & x)
+const numeric isqrt(const numeric &x)
 {
        if (x.is_integer()) {
                cln::cl_I root;
@@ -1909,13 +1875,15 @@ ex CatalanEvalf(void)
 }
 
 
+/** _numeric_digits default ctor, checking for singleton invariance. */
 _numeric_digits::_numeric_digits()
   : digits(17)
 {
        // It initializes to 17 digits, because in CLN float_format(17) turns out
        // to be 61 (<64) while float_format(18)=65.  The reason is we want to
        // have a cl_LF instead of cl_SF, cl_FF or cl_DF.
-       assert(!too_late);
+       if (too_late)
+               throw(std::runtime_error("I told you not to do instantiate me!"));
        too_late = true;
        cln::default_float_format = cln::float_format(17);
 }
@@ -1939,14 +1907,14 @@ _numeric_digits::operator long()
 
 
 /** Append global Digits object to ostream. */
-void _numeric_digits::print(std::ostream & os) const
+void _numeric_digits::print(std::ostream &os) const
 {
        debugmsg("_numeric_digits print", LOGLEVEL_PRINT);
        os << digits;
 }
 
 
-std::ostream& operator<<(std::ostream& os, const _numeric_digits & e)
+std::ostream& operator<<(std::ostream &os, const _numeric_digits &e)
 {
        e.print(os);
        return os;
@@ -1965,6 +1933,4 @@ bool _numeric_digits::too_late = false;
  *  assignment from C++ unsigned ints and evaluated like any built-in type. */
 _numeric_digits Digits;
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index b4d61fa..ce50406 100644 (file)
@@ -38,15 +38,13 @@ namespace cln { class cl_N; }
   #include <cln/complex_class.h>
 #endif
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 #define HASHVALUE_NUMERIC 0x80000001U
 
-/** This class is used to instantiate a global object Digits which
- *  behaves just like Maple's Digits.  We need an object rather than a
- *  dumber basic type since as a side-effect we let it change
+/** This class is used to instantiate a global singleton object Digits
+ *  which behaves just like Maple's Digits.  We need an object rather 
+ *  than a dumber basic type since as a side-effect we let it change
  *  cl_default_float_format when it gets changed.  The only other
  *  meaningful thing to do with it is converting it to an unsigned,
  *  for temprary storing its value e.g.  The user must not create an
@@ -60,11 +58,11 @@ public:
        _numeric_digits();
        _numeric_digits& operator=(long prec);
        operator long();
-       void print(std::ostream & os) const;
+       void print(std::ostream &os) const;
 // member variables
 private:
-       long digits;
-       static bool too_late;
+       long digits;                        ///< Number of decimal digits
+       static bool too_late;               ///< Already one object present
 };
 
 /** This class is a wrapper around CLN-numbers within the GiNaC class
@@ -72,10 +70,10 @@ private:
 class numeric : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(numeric, basic)
-
+       
 // member functions
-
-       // other constructors
+       
+       // other ctors
 public:
        explicit numeric(int i);
        explicit numeric(unsigned int i);
@@ -87,49 +85,51 @@ public:
        
        // functions overriding virtual functions from bases classes
 public:
-       void print(std::ostream & os, unsigned precedence=0) const;
-       void printraw(std::ostream & os) const;
-       void printtree(std::ostream & os, unsigned indent) const;
-       void printcsrc(std::ostream & os, unsigned type, unsigned precedence=0) const;
+       void print(std::ostream &os, unsigned precedence = 0) const;
+       void printraw(std::ostream &os) const;
+       void printtree(std::ostream &os, unsigned indent) const;
+       void printcsrc(std::ostream &os, unsigned type, unsigned precedence=0) const;
        bool info(unsigned inf) const;
-       bool has(const ex & other) const;
+       bool has(const ex &other) 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 normal(lst &sym_lst, lst &repl_lst, int level = 0) const;
        ex to_rational(lst &repl_lst) const;
        numeric integer_content(void) const;
        ex smod(const numeric &xi) const;
        numeric max_coefficient(void) const;
 protected:
-       ex derivative(const symbol & s) const;
-       bool is_equal_same_type(const basic & other) const;
+       /** Implementation of ex::diff for a numeric always returns 0.
+        *  @see ex::diff */
+       ex derivative(const symbol &s) const { return _ex0(); }
+       bool is_equal_same_type(const basic &other) const;
        unsigned calchash(void) const;
-
+       
        // new virtual functions which can be overridden by derived classes
        // (none)
-
+       
        // non-virtual functions in this class
 public:
-       const numeric add(const numeric & other) const;
-       const numeric sub(const numeric & other) const;
-       const numeric mul(const numeric & other) const;
-       const numeric div(const numeric & other) const;
-       const numeric power(const numeric & other) const;
-       const numeric & add_dyn(const numeric & other) const;
-       const numeric & sub_dyn(const numeric & other) const;
-       const numeric & mul_dyn(const numeric & other) const;
-       const numeric & div_dyn(const numeric & other) const;
-       const numeric & power_dyn(const numeric & other) const;
+       const numeric add(const numeric &other) const;
+       const numeric sub(const numeric &other) const;
+       const numeric mul(const numeric &other) const;
+       const numeric div(const numeric &other) const;
+       const numeric power(const numeric &other) const;
+       const numeric & add_dyn(const numeric &other) const;
+       const numeric & sub_dyn(const numeric &other) const;
+       const numeric & mul_dyn(const numeric &other) const;
+       const numeric & div_dyn(const numeric &other) const;
+       const numeric & power_dyn(const numeric &other) const;
        const numeric & operator=(int i);
        const numeric & operator=(unsigned int i);
        const numeric & operator=(long i);
        const numeric & operator=(unsigned long i);
        const numeric & operator=(double d);
-       const numeric & operator=(const char * s);
+       const numeric & operator=(const char *s);
        const numeric inverse(void) const;
        int csgn(void) const;
-       int compare(const numeric & other) const;
-       bool is_equal(const numeric & other) const;
+       int compare(const numeric &other) const;
+       bool is_equal(const numeric &other) const;
        bool is_zero(void) const;
        bool is_positive(void) const;
        bool is_negative(void) const;
@@ -143,12 +143,12 @@ public:
        bool is_real(void) const;
        bool is_cinteger(void) const;
        bool is_crational(void) const;
-       bool operator==(const numeric & other) const;
-       bool operator!=(const numeric & other) const;
-       bool operator<(const numeric & other) const;
-       bool operator<=(const numeric & other) const;
-       bool operator>(const numeric & other) const;
-       bool operator>=(const numeric & other) const;
+       bool operator==(const numeric &other) const;
+       bool operator!=(const numeric &other) const;
+       bool operator<(const numeric &other) const;
+       bool operator<=(const numeric &other) const;
+       bool operator>(const numeric &other) const;
+       bool operator>=(const numeric &other) const;
        int to_int(void) const;
        long to_long(void) const;
        double to_double(void) const;
@@ -159,7 +159,7 @@ public:
        const numeric denom(void) const;
        int int_length(void) const;
        // converting routines for interfacing with CLN:
-       numeric(const cln::cl_N & z);
+       numeric(const cln::cl_N &z);
 
 // member variables
 
@@ -173,118 +173,115 @@ protected:
 extern const numeric I;
 extern _numeric_digits Digits;
 
-//#define is_a_numeric_hash(x) ((x)==HASHVALUE_NUMERIC)
-// may have to be changed to ((x)>=0x80000000U)
-
-// has been changed
-//#define is_a_numeric_hash(x) ((x)&0x80000000U)
+// deprecated macro, for internal use only
+#define is_a_numeric_hash(x) ((x)&0x80000000U)
 
 // global functions
 
-const numeric exp(const numeric & x);
-const numeric log(const numeric & x);
-const numeric sin(const numeric & x);
-const numeric cos(const numeric & x);
-const numeric tan(const numeric & x);
-const numeric asin(const numeric & x);
-const numeric acos(const numeric & x);
-const numeric atan(const numeric & x);
-const numeric atan(const numeric & y, const numeric & x);
-const numeric sinh(const numeric & x);
-const numeric cosh(const numeric & x);
-const numeric tanh(const numeric & x);
-const numeric asinh(const numeric & x);
-const numeric acosh(const numeric & x);
-const numeric atanh(const numeric & x);
-const numeric Li2(const numeric & x);
-const numeric zeta(const numeric & x);
-const numeric lgamma(const numeric & x);
-const numeric tgamma(const numeric & x);
-const numeric psi(const numeric & x);
-const numeric psi(const numeric & n, const numeric & x);
-const numeric factorial(const numeric & n);
-const numeric doublefactorial(const numeric & n);
-const numeric binomial(const numeric & n, const numeric & k);
-const numeric bernoulli(const numeric & n);
-const numeric fibonacci(const numeric & n);
-const numeric abs(const numeric & x);
-const numeric isqrt(const numeric & x);
-const numeric sqrt(const numeric & x);
-const numeric abs(const numeric & x);
-const numeric mod(const numeric & a, const numeric & b);
-const numeric smod(const numeric & a, const numeric & b);
-const numeric irem(const numeric & a, const numeric & b);
-const numeric irem(const numeric & a, const numeric & b, numeric & q);
-const numeric iquo(const numeric & a, const numeric & b);
-const numeric iquo(const numeric & a, const numeric & b, numeric & r);
-const numeric gcd(const numeric & a, const numeric & b);
-const numeric lcm(const numeric & a, const numeric & b);
+const numeric exp(const numeric &x);
+const numeric log(const numeric &x);
+const numeric sin(const numeric &x);
+const numeric cos(const numeric &x);
+const numeric tan(const numeric &x);
+const numeric asin(const numeric &x);
+const numeric acos(const numeric &x);
+const numeric atan(const numeric &x);
+const numeric atan(const numeric &y, const numeric &x);
+const numeric sinh(const numeric &x);
+const numeric cosh(const numeric &x);
+const numeric tanh(const numeric &x);
+const numeric asinh(const numeric &x);
+const numeric acosh(const numeric &x);
+const numeric atanh(const numeric &x);
+const numeric Li2(const numeric &x);
+const numeric zeta(const numeric &x);
+const numeric lgamma(const numeric &x);
+const numeric tgamma(const numeric &x);
+const numeric psi(const numeric &x);
+const numeric psi(const numeric &n, const numeric &x);
+const numeric factorial(const numeric &n);
+const numeric doublefactorial(const numeric &n);
+const numeric binomial(const numeric &n, const numeric &k);
+const numeric bernoulli(const numeric &n);
+const numeric fibonacci(const numeric &n);
+const numeric abs(const numeric &x);
+const numeric isqrt(const numeric &x);
+const numeric sqrt(const numeric &x);
+const numeric abs(const numeric &x);
+const numeric mod(const numeric &a, const numeric &b);
+const numeric smod(const numeric &a, const numeric &b);
+const numeric irem(const numeric &a, const numeric &b);
+const numeric irem(const numeric &a, const numeric &b, numeric &q);
+const numeric iquo(const numeric &a, const numeric &b);
+const numeric iquo(const numeric &a, const numeric &b, numeric &r);
+const numeric gcd(const numeric &a, const numeric &b);
+const numeric lcm(const numeric &a, const numeric &b);
 
 // wrapper functions around member functions
-inline const numeric pow(const numeric & x, const numeric & y)
+inline const numeric pow(const numeric &x, const numeric &y)
 { return x.power(y); }
 
-inline const numeric inverse(const numeric & x)
+inline const numeric inverse(const numeric &x)
 { return x.inverse(); }
 
-inline int csgn(const numeric & x)
+inline int csgn(const numeric &x)
 { return x.csgn(); }
 
-inline bool is_zero(const numeric & x)
+inline bool is_zero(const numeric &x)
 { return x.is_zero(); }
 
-inline bool is_positive(const numeric & x)
+inline bool is_positive(const numeric &x)
 { return x.is_positive(); }
 
-inline bool is_integer(const numeric & x)
+inline bool is_integer(const numeric &x)
 { return x.is_integer(); }
 
-inline bool is_pos_integer(const numeric & x)
+inline bool is_pos_integer(const numeric &x)
 { return x.is_pos_integer(); }
 
-inline bool is_nonneg_integer(const numeric & x)
+inline bool is_nonneg_integer(const numeric &x)
 { return x.is_nonneg_integer(); }
 
-inline bool is_even(const numeric & x)
+inline bool is_even(const numeric &x)
 { return x.is_even(); }
 
-inline bool is_odd(const numeric & x)
+inline bool is_odd(const numeric &x)
 { return x.is_odd(); }
 
-inline bool is_prime(const numeric & x)
+inline bool is_prime(const numeric &x)
 { return x.is_prime(); }
 
-inline bool is_rational(const numeric & x)
+inline bool is_rational(const numeric &x)
 { return x.is_rational(); }
 
-inline bool is_real(const numeric & x)
+inline bool is_real(const numeric &x)
 { return x.is_real(); }
 
-inline bool is_cinteger(const numeric & x)
+inline bool is_cinteger(const numeric &x)
 { return x.is_cinteger(); }
 
-inline bool is_crational(const numeric & x)
+inline bool is_crational(const numeric &x)
 { return x.is_crational(); }
 
-inline int to_int(const numeric & x)
+inline int to_int(const numeric &x)
 { return x.to_int(); }
 
-inline long to_long(const numeric & x)
+inline long to_long(const numeric &x)
 { return x.to_long(); }
 
-inline double to_double(const numeric & x)
+inline double to_double(const numeric &x)
 { return x.to_double(); }
 
-inline const numeric real(const numeric & x)
+inline const numeric real(const numeric &x)
 { return x.real(); }
 
-inline const numeric imag(const numeric & x)
+inline const numeric imag(const numeric &x)
 { return x.imag(); }
 
-inline const numeric numer(const numeric & x)
+inline const numeric numer(const numeric &x)
 { return x.numer(); }
 
-inline const numeric denom(const numeric & x)
+inline const numeric denom(const numeric &x)
 { return x.denom(); }
 
 // numeric evaluation functions for class constant objects:
@@ -300,10 +297,7 @@ inline const numeric &ex_to_numeric(const ex &e)
        return static_cast<const numeric &>(*e.bp);
 }
 
-
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #ifdef __MAKECINT__
 #pragma link off defined_in cln/number.h;
index 11b2783..4e5781a 100644 (file)
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <iostream>
-#include <stdexcept>
-
 #include "operators.h"
-#include "basic.h"
-#include "ex.h"
 #include "numeric.h"
 #include "power.h"
 #include "relational.h"
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 // binary arithmetic operators ex with ex
 
@@ -101,25 +94,25 @@ numeric operator/(const numeric & lh, const numeric & rh)
 const ex & operator+=(ex & lh, const ex & rh)
 {
        debugmsg("operator+=(ex,ex)",LOGLEVEL_OPERATOR);
-       return (lh=lh+rh);
+       return (lh=lh.exadd(rh));
 }
 
 const ex & operator-=(ex & lh, const ex & rh)
 {
        debugmsg("operator-=(ex,ex)",LOGLEVEL_OPERATOR);
-       return (lh=lh-rh);
+       return (lh=lh.exadd(rh.exmul(_ex_1())));
 }
 
 const ex & operator*=(ex & lh, const ex & rh)
 {
        debugmsg("operator*=(ex,ex)",LOGLEVEL_OPERATOR);
-       return (lh=lh*rh);
+       return (lh=lh.exmul(rh));
 }
 
 const ex & operator/=(ex & lh, const ex & rh)
 {
        debugmsg("operator/=(ex,ex)",LOGLEVEL_OPERATOR);
-       return (lh=lh/rh);
+       return (lh=lh.exmul(power(rh,_ex_1())));
 }
 
 const ex & operator%=(ex & lh, const ex & rh)
@@ -178,14 +171,14 @@ numeric operator+(const numeric & lh)
 numeric operator-(const numeric & lh)
 {
        debugmsg("operator-(numeric)",LOGLEVEL_OPERATOR);
-       return _num_1()*lh;
+       return _num_1().mul(lh);
 }
 
 /** Numeric prefix increment.  Adds 1 and returns incremented number. */
 numeric& operator++(numeric & rh)
 {
        debugmsg("operator++(numeric)",LOGLEVEL_OPERATOR);
-       rh = rh+_num1();
+       rh = rh.add(_num1());
        return rh;
 }
 
@@ -193,7 +186,7 @@ numeric& operator++(numeric & rh)
 numeric& operator--(numeric & rh)
 {
        debugmsg("operator--(numeric)",LOGLEVEL_OPERATOR);
-       rh = rh-_num1();
+       rh = rh.add(_num_1());
        return rh;
 }
 
@@ -202,8 +195,8 @@ numeric& operator--(numeric & rh)
 numeric operator++(numeric & lh, int)
 {
        debugmsg("operator++(numeric,int)",LOGLEVEL_OPERATOR);
-       numeric tmp = lh;
-       lh = lh+_num1();
+       numeric tmp(lh);
+       lh = lh.add(_num1());
        return tmp;
 }
 
@@ -212,8 +205,8 @@ numeric operator++(numeric & lh, int)
 numeric operator--(numeric & lh, int)
 {
        debugmsg("operator--(numeric,int)",LOGLEVEL_OPERATOR);
-       numeric tmp = lh;
-       lh = lh-_num1();
+       numeric tmp(lh);
+       lh = lh.add(_num_1());
        return tmp;
 }
 
@@ -268,6 +261,4 @@ std::istream & operator>>(std::istream & is, ex & e)
        throw (std::logic_error("expression input from streams not implemented"));
 }
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
index 18b1b92..8636e21 100644 (file)
@@ -25,9 +25,7 @@
 
 #include <iostream>
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 class ex;
 class numeric;
@@ -82,8 +80,6 @@ relational operator>=(const ex & lh, const ex & rh);
 std::ostream & operator<<(std::ostream & os, const ex & e);
 std::istream & operator>>(std::istream & is, ex & e);
 
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
 
 #endif // ndef __GINAC_OPERATORS_H__
index 7324ca9..5ebeae6 100644 (file)
 #include "debugmsg.h"
 #include "utils.h"
 
-#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(power, basic)
 
 typedef std::vector<int> intvector;
 
 //////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
 //////////
 
 // public
 
 power::power() : basic(TINFO_power)
 {
-       debugmsg("power default constructor",LOGLEVEL_CONSTRUCT);
+       debugmsg("power default ctor",LOGLEVEL_CONSTRUCT);
 }
 
 // protected
@@ -60,8 +58,8 @@ power::power() : basic(TINFO_power)
 void power::copy(const power & other)
 {
        inherited::copy(other);
-       basis=other.basis;
-       exponent=other.exponent;
+       basis = other.basis;
+       exponent = other.exponent;
 }
 
 void power::destroy(bool call_parent)
@@ -70,20 +68,20 @@ void power::destroy(bool call_parent)
 }
 
 //////////
-// other constructors
+// other ctors
 //////////
 
 // public
 
 power::power(const ex & lh, const ex & rh) : basic(TINFO_power), basis(lh), exponent(rh)
 {
-       debugmsg("power constructor from ex,ex",LOGLEVEL_CONSTRUCT);
+       debugmsg("power ctor from ex,ex",LOGLEVEL_CONSTRUCT);
        GINAC_ASSERT(basis.return_type()==return_types::commutative);
 }
 
 power::power(const ex & lh, const numeric & rh) : basic(TINFO_power), basis(lh), exponent(rh)
 {
-       debugmsg("power constructor from ex,numeric",LOGLEVEL_CONSTRUCT);
+       debugmsg("power ctor from ex,numeric",LOGLEVEL_CONSTRUCT);
        GINAC_ASSERT(basis.return_type()==return_types::commutative);
 }
 
@@ -94,7 +92,7 @@ power::power(const ex & lh, const numeric & rh) : basic(TINFO_power), basis(lh),
 /** Construct object from archive_node. */
 power::power(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
 {
-       debugmsg("power constructor from archive_node", LOGLEVEL_CONSTRUCT);
+       debugmsg("power ctor from archive_node", LOGLEVEL_CONSTRUCT);
        n.find_ex("basis", basis, sym_lst);
        n.find_ex("exponent", exponent, sym_lst);
 }
@@ -158,7