pseries::expand(): do not generate zero terms. release_0-7-2
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sat, 17 Feb 2001 21:07:08 +0000 (21:07 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Sat, 17 Feb 2001 21:07:08 +0000 (21:07 +0000)
pseries::print(): print trivial case, too.
others: documentation updates.

14 files changed:
ginac/add.cpp
ginac/basic.cpp
ginac/basic.h
ginac/constant.cpp
ginac/constant.h
ginac/ex.h
ginac/expairseq.cpp
ginac/flags.h
ginac/inifcns_gamma.cpp
ginac/inifcns_zeta.cpp
ginac/lortensor.cpp
ginac/numeric.h
ginac/pseries.cpp
ginac/symbol.h

index 9cc2cc01c4e05908cd304813edb67e6b6b248fdd..2f227fcf595b6c76e7b832846f0d861422de9001 100644 (file)
@@ -440,11 +440,11 @@ ex add::thisexpairseq(epvector * vp, const ex & oc) const
 expair add::split_ex_to_pair(const ex & e) const
 {
        if (is_ex_exactly_of_type(e,mul)) {
-               const mul & mulref=ex_to_mul(e);
-               ex numfactor=mulref.overall_coeff;
-               // mul * mulcopyp=static_cast<mul *>(mulref.duplicate());
-               mul * mulcopyp=new mul(mulref);
-               mulcopyp->overall_coeff=_ex1();
+               const mul & mulref = ex_to_mul(e);
+               ex numfactor = mulref.overall_coeff;
+               // mul * mulcopyp = static_cast<mul *>(mulref.duplicate());
+               mul * mulcopyp = new mul(mulref);
+               mulcopyp->overall_coeff = _ex1();
                mulcopyp->clearflag(status_flags::evaluated);
                mulcopyp->clearflag(status_flags::hash_calculated);
                return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor);
@@ -456,26 +456,24 @@ expair add::combine_ex_with_coeff_to_pair(const ex & e,
                                                                                  const ex & c) const
 {
        GINAC_ASSERT(is_ex_exactly_of_type(c, numeric));
-       ex one = _ex1();
        if (is_ex_exactly_of_type(e, mul)) {
                const mul &mulref = ex_to_mul(e);
                ex numfactor = mulref.overall_coeff;
                mul *mulcopyp = new mul(mulref);
-               mulcopyp->overall_coeff = one;
+               mulcopyp->overall_coeff = _ex1();
                mulcopyp->clearflag(status_flags::evaluated);
                mulcopyp->clearflag(status_flags::hash_calculated);
                mulcopyp->setflag(status_flags::dynallocated);
-               if (are_ex_trivially_equal(c, one)) {
+               if (are_ex_trivially_equal(c, _ex1())) {
                        return expair(*mulcopyp, numfactor);
-               } else if (are_ex_trivially_equal(numfactor, one)) {
+               } else if (are_ex_trivially_equal(numfactor, _ex1())) {
                        return expair(*mulcopyp, c);
                }
                return expair(*mulcopyp, ex_to_numeric(numfactor).mul_dyn(ex_to_numeric(c)));
        } else if (is_ex_exactly_of_type(e, numeric)) {
-               if (are_ex_trivially_equal(c, one)) {
-                       return expair(e, one);
-               }
-               return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)), one);
+               if (are_ex_trivially_equal(c, _ex1()))
+                       return expair(e, _ex1());
+               return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)), _ex1());
        }
        return expair(e, c);
 }
index 9f0bbf534640162ef1f0f9909e0f8d81937d046b..a33433daf262863df202c7e0f231b93f1ab2398d 100644 (file)
@@ -143,7 +143,7 @@ void basic::print(std::ostream & os, unsigned upper_precedence) const
 }
 
 /** Output to stream in ugly raw format, so brave developers can have a look
- * at the underlying structure. */
+ *  at the underlying structure. */
 void basic::printraw(std::ostream & os) const
 {
        debugmsg("basic printraw",LOGLEVEL_PRINT);
@@ -176,14 +176,22 @@ void basic::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedenc
        debugmsg("basic print csrc", LOGLEVEL_PRINT);
 }
 
-/** Little wrapper arount print to be called within a debugger. */
+/** Little wrapper arount print to be called within a debugger.
+ *  This is needed because you cannot call foo.print(cout) from within the
+ *  debugger because it might not know what cout is.  This method can be invoked
+ *  with no argument and it will simply print to stdout.
+ *
+ *  @see basic::print*/
 void basic::dbgprint(void) const
 {
        print(std::cerr);
        std::cerr << std::endl;
 }
 
-/** Little wrapper arount printtree to be called within a debugger. */
+/** Little wrapper arount printtree to be called within a debugger.
+ *
+ *  @see basic::dbgprint
+ *  @see basic::printtree */
 void basic::dbgprinttree(void) const
 {
        printtree(std::cerr,0);
@@ -519,9 +527,8 @@ const basic & basic::hold(void) const
 
 void basic::ensure_if_modifiable(void) const
 {
-       if (refcount>1) {
+       if (refcount>1)
                throw(std::runtime_error("cannot modify multiply referenced object"));
-       }
 }
 
 //////////
index e7238e5705ac2c74f29736bf47cff6d194c2580b..1f7af71bb59d038d0bea6ee1729854ea62438351 100644 (file)
@@ -96,9 +96,9 @@ public:
 #else
 ;
 #endif // def INLINE_BASIC_CONSTRUCTORS
-       
+
        const basic & operator=(const basic & other);
-       
+
 protected:
        void copy(const basic & other)
        {
index bc1179c5edbcdd8b6250d3c2024b401a5a273040..dcf283749c442f526f4e3c0b9efac4013671a6d0 100644 (file)
@@ -59,7 +59,6 @@ void constant::copy(const constant & other)
        } else {
                number = 0;
        }
-       // fct_assigned=other.fct_assigned;
 }
 
 void constant::destroy(bool call_parent)
index cf31814f510939ac94e952ac602056bdff7ed417..f29e5462121382801588e0ac258c5885c9148671 100644 (file)
@@ -70,8 +70,7 @@ private:
        std::string name;
        evalffunctype ef;
        numeric * number;
-       // bool fct_assigned;
-       unsigned serial;  //!< unique serial number for comparision
+       unsigned serial;  //!  unique serial number for comparision
        static unsigned next_serial;
 };
 
index 2d36edf9de7ce1f0aee032da099d28f7c04b66e6..30b40eb59e6554f69f0e477e674400011dab4df1 100644 (file)
@@ -32,9 +32,6 @@ namespace GiNaC {
 #endif // ndef NO_NAMESPACE_GINAC
 
 class ex;
-class expand_options;
-class status_flags;
-
 class symbol;
 class lst;
 
index 56fcba68fda4489dc60ef2f32629f76f7be2aff8..246424f7559ff394651c5c7ee0564993fc8380ea 100644 (file)
@@ -191,7 +191,7 @@ void expairseq::archive(archive_node &n) const
        while (i != iend) {
                n.add_ex("rest", i->rest);
                n.add_ex("coeff", i->coeff);
-               i++;
+               ++i;
        }
        n.add_ex("overall_coeff", overall_coeff);
 }
@@ -271,7 +271,7 @@ void expairseq::printtree(std::ostream & os, unsigned indent) const
                        for (epplist::const_iterator it=hashtab[i].begin();
                                 it!=hashtab[i].end(); ++it) {
                                os << *it-seq.begin() << " ";
-                               this_bin_fill++;
+                               ++this_bin_fill;
                        }
                        os << std::endl;
                        cum_fill += this_bin_fill;
@@ -914,7 +914,7 @@ void expairseq::make_flat(const exvector & v)
        cit=v.begin();
        while (cit!=citend) {
                if (cit->bp->tinfo()==tinfo()) {
-                       nexpairseqs++;
+                       ++nexpairseqs;
                        noperands+=ex_to_expairseq(*cit).seq.size();
                }
                ++cit;
@@ -965,7 +965,7 @@ void expairseq::make_flat(const epvector & v)
        cit = v.begin();
        while (cit!=citend) {
                if (cit->rest.bp->tinfo()==tinfo()) {
-                       nexpairseqs++;
+                       ++nexpairseqs;
                        noperands += ex_to_expairseq((*cit).rest).seq.size();
                }
                ++cit;
@@ -1090,7 +1090,7 @@ void expairseq::canonicalize(void)
                        do {
                                last_numeric--;
                        } while (is_ex_exactly_of_type((*last_numeric).rest,numeric));
-                       last_numeric++;
+                       ++last_numeric;
                        sort(last_numeric,seq.end(),expair_is_less());
                }
        }
@@ -1197,11 +1197,11 @@ unsigned expairseq::calc_hashindex(const ex & e) const
        unsigned hash=e.gethash();
        unsigned hashindex;
        if (is_a_numeric_hash(hash)) {
-               hashindex=hashmask;
+               hashindex = hashmask;
        } else {
-               hashindex=hash & hashmask;
+               hashindex = hash & hashmask;
                // last hashtab entry is reserved for numerics
-               if (hashindex==hashmask) hashindex=0;
+               if (hashindex==hashmask) hashindex = 0;
        }
        GINAC_ASSERT(hashindex>=0);
        GINAC_ASSERT((hashindex<hashtabsize)||(hashtabsize==0));
@@ -1215,22 +1215,21 @@ void expairseq::shrink_hashtab(void)
                GINAC_ASSERT(new_hashtabsize<hashtabsize);
                if (new_hashtabsize==0) {
                        hashtab.clear();
-                       hashtabsize=0;
+                       hashtabsize = 0;
                        canonicalize();
                        return;
                }
                
                // shrink by a factor of 2
                unsigned half_hashtabsize=hashtabsize/2;
-               for (unsigned i=0; i<half_hashtabsize-1; ++i) {
+               for (unsigned i=0; i<half_hashtabsize-1; ++i)
                        hashtab[i].merge(hashtab[i+half_hashtabsize],epp_is_less());
-               }
                // special treatment for numeric hashes
                hashtab[0].merge(hashtab[half_hashtabsize-1],epp_is_less());
-               hashtab[half_hashtabsize-1]=hashtab[hashtabsize-1];
+               hashtab[half_hashtabsize-1] = hashtab[hashtabsize-1];
                hashtab.resize(half_hashtabsize);
-               hashtabsize=half_hashtabsize;
-               hashmask=hashtabsize-1;
+               hashtabsize = half_hashtabsize;
+               hashmask = hashtabsize-1;
        }
 }
 
@@ -1239,16 +1238,16 @@ void expairseq::remove_hashtab_entry(epvector::const_iterator element)
        if (hashtabsize==0) return; // nothing to do
        
        // calculate hashindex of element to be deleted
-       unsigned hashindex=calc_hashindex((*element).rest);
+       unsigned hashindex = calc_hashindex((*element).rest);
 
        // find it in hashtab and remove it
-       epplist & eppl=hashtab[hashindex];
-       epplist::iterator epplit=eppl.begin();
-       bool erased=false;
+       epplist & eppl = hashtab[hashindex];
+       epplist::iterator epplit = eppl.begin();
+       bool erased = false;
        while (epplit!=eppl.end()) {
                if (*epplit == element) {
                        eppl.erase(epplit);
-                       erased=true;
+                       erased = true;
                        break;
                }
                ++epplit;
@@ -1258,14 +1257,14 @@ void expairseq::remove_hashtab_entry(epvector::const_iterator element)
                cout << "tried to erase " << element-seq.begin() << std::endl;
                cout << "size " << seq.end()-seq.begin() << std::endl;
 
-               unsigned hashindex=calc_hashindex((*element).rest);
-               epplist & eppl=hashtab[hashindex];
+               unsigned hashindex = calc_hashindex((*element).rest);
+               epplist & eppl = hashtab[hashindex];
                epplist::iterator epplit=eppl.begin();
                bool erased=false;
                while (epplit!=eppl.end()) {
                        if (*epplit == element) {
                                eppl.erase(epplit);
-                               erased=true;
+                               erased = true;
                                break;
                        }
                        ++epplit;
@@ -1284,7 +1283,7 @@ 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 & eppl = hashtab[hashindex];
        epplist::iterator epplit=eppl.begin();
        while (epplit!=eppl.end()) {
                if (*epplit == oldpos) {
@@ -1298,7 +1297,7 @@ void expairseq::move_hashtab_entry(epvector::const_iterator oldpos,
 
 void expairseq::sorted_insert(epplist & eppl, epp elem)
 {
-       epplist::iterator current=eppl.begin();
+       epplist::iterator current = eppl.begin();
        while ((current!=eppl.end())&&((*(*current)).is_less(*elem))) {
                ++current;
        }
@@ -1430,10 +1429,10 @@ void expairseq::combine_same_terms(void)
        // combine same terms, drop term with coeff 0, move numerics to end
        
        // calculate size of hashtab
-       hashtabsize=calc_hashtabsize(seq.size());
+       hashtabsize = calc_hashtabsize(seq.size());
 
        // hashtabsize is a power of 2
-       hashmask=hashtabsize-1;
+       hashmask = hashtabsize-1;
 
        // allocate hashtab
        hashtab.clear();
@@ -1455,7 +1454,7 @@ void expairseq::combine_same_terms(void)
        touched.reserve(seq.size());
        for (unsigned i=0; i<seq.size(); ++i) touched[i]=false;
 
-       unsigned number_of_zeroes=0;
+       unsigned number_of_zeroes = 0;
 
        GINAC_ASSERT(!has_coeff_0());
        build_hashtab_and_combine(first_numeric,last_non_zero,touched,number_of_zeroes);
@@ -1688,7 +1687,7 @@ epvector * expairseq::subschildren(const lst & ls, const lst & lr) const
                if (!are_ex_trivially_equal((*cit).rest,subsed_ex)) {
                        
                        // something changed, copy seq, subs 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
index 1b11dceb635ad41ca37b766b1405630acbc1bb44..11786653ed46f17805fbbfc7e83548c235692c4e 100644 (file)
@@ -34,6 +34,7 @@ public:
        };
 };
 
+/** Flags to control series expansion. */
 class series_options {
 public:
        enum {
@@ -41,34 +42,37 @@ public:
        };
 };
 
+/** Switch to control algorithm for determinant computation. */
 class determinant_algo {
 public:
        enum {
-               automatic,
-               gauss,
-               divfree,
-               laplace,
-               bareiss
+               automatic,                      //! Let the system choose
+               gauss,                          //! Gauss elimiation
+               divfree,                        //! Division-free elimination
+               laplace,                        //! Laplace (or minor) elimination
+               bareiss                         //! Bareiss fraction-free elimination
        };
 };
 
+/** Switch to control algorithm for linear system solving. */
 class solve_algo {
 public:
        enum {
-               automatic,
-               gauss,
-               divfree,
-               bareiss
+               automatic,                      //! Let the system choose
+               gauss,                          //! Gauss elimiation
+               divfree,                        //! Division-free elimination
+               bareiss                         //! Bareiss fraction-free elimination
        };
 };
 
+/** Flags to store information about the stato of an object. */
 class status_flags {
 public:
        enum {
-               dynallocated    = 0x0001,
-               evaluated       = 0x0002,
-               expanded        = 0x0004,
-               hash_calculated = 0x0008
+               dynallocated    = 0x0001,       //! Heap-allocated (i.e. created by new)
+               evaluated       = 0x0002,       //! .eval() has already done its job
+               expanded        = 0x0004,       //! .expand() has already done its job
+               hash_calculated = 0x0008        //! .calchash() has already done its job
        };
 };
 
@@ -153,13 +157,15 @@ public:
        };
 };
 
+/** Strategies how to clean up the function remember cache.
+ *  @see remember_table */
 class remember_strategies {
 public:
        enum {
-               delete_never, // let table grow undefinitely, not recommmended, but currently default
-               delete_lru,   // least recently used
-               delete_lfu,   // least frequently used
-               delete_cyclic // first (oldest) one in list
+               delete_never,   //! Let table grow undefinitely, not recommmended, but currently default
+               delete_lru,     //! Least recently used
+               delete_lfu,     //! Least frequently used
+               delete_cyclic   //! First (oldest) one in list
        };
 };
 
index cd21ce4c85a69b36eeb957d99eb10a2c741260c5..d180065dbce9e743706097e086278fa9a51e630d 100644 (file)
@@ -25,7 +25,6 @@
 #include <stdexcept>
 
 #include "inifcns.h"
-#include "ex.h"
 #include "constant.h"
 #include "pseries.h"
 #include "numeric.h"
index 9a3f7a4fabac57e2a7a8710cf6a0bc0682e3178f..a39d8e6aa1fd542c2e015a99e227c8ecb0f50ffb 100644 (file)
@@ -24,7 +24,6 @@
 #include <stdexcept>
 
 #include "inifcns.h"
-#include "ex.h"
 #include "constant.h"
 #include "numeric.h"
 #include "power.h"
index 6c326e2b01af3dfe4fe1d4b168352802b700814d..f9d5f44a8196be1eadbfce0c064f7cab21c33ccf 100644 (file)
@@ -31,7 +31,6 @@
 #include "add.h"
 #include "mul.h"
 #include "debugmsg.h"
-#include "flags.h"
 #include "lst.h"
 #include "lortensor.h"
 #include "operators.h"
index 3a972bc925d036569cb0a6f4a272da879763c6f5..b4d61faa78cdbaa2e90054322b205b57d6d0ff9e 100644 (file)
@@ -93,8 +93,8 @@ public:
        void printcsrc(std::ostream & os, unsigned type, unsigned precedence=0) const;
        bool info(unsigned inf) const;
        bool has(const ex & other) const;
-       ex eval(int level=0) const;
-       ex evalf(int level=0) const;
+       ex eval(int level = 0) const;
+       ex evalf(int level = 0) const;
        ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
        ex to_rational(lst &repl_lst) const;
        numeric integer_content(void) const;
index 2d873a2626c5eae2591b5549a56caa82aca3ac45..409947f473cad7cb41515979fb1dd76fd4800f95 100644 (file)
@@ -136,10 +136,11 @@ void pseries::print(std::ostream &os, unsigned upper_precedence) const
 {
        debugmsg("pseries print", LOGLEVEL_PRINT);
        if (precedence<=upper_precedence) os << "(";
+       // objects of type pseries must not have any zero entries, so the
+       // trivial (zero) pseries needs a special treatment here:
+       if (seq.size()==0)
+               os << '0';
        for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
-               // omit zero terms
-               if (i->rest.is_zero())
-                       continue;
                // print a sign, if needed
                if (i!=seq.begin())
                        os << '+';
@@ -177,9 +178,8 @@ void pseries::printraw(std::ostream &os) const
 {
        debugmsg("pseries printraw", LOGLEVEL_PRINT);
        os << "pseries(" << var << ";" << point << ";";
-       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
                os << "(" << (*i).rest << "," << (*i).coeff << "),";
-       }
        os << ")";
 }
 
@@ -302,6 +302,13 @@ int pseries::ldegree(const symbol &s) const
        }
 }
 
+/** Return coefficient of degree n in power series if s is the expansion
+ *  variable.  If the expansion point is nonzero, by definition the n=1
+ *  coefficient in s of a+b*(s-z)+c*(s-z)^2+Order((s-z)^3) is b (assuming
+ *  the expansion took place in the s in the first place).
+ *  If s is not the expansion variable, an attempt is made to convert the
+ *  series to a polynomial and return the corresponding coefficient from
+ *  there. */
 ex pseries::coeff(const symbol &s, int n) const
 {
        if (var.is_equal(s)) {
@@ -333,7 +340,7 @@ ex pseries::coeff(const symbol &s, int n) const
                return convert_to_poly().coeff(s, n);
 }
 
-
+/** Does nothing. */
 ex pseries::collect(const symbol &s) const
 {
        return *this;
@@ -410,8 +417,11 @@ ex pseries::expand(unsigned options) const
 {
        epvector newseq;
        newseq.reserve(seq.size());
-       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i)
-               newseq.push_back(expair(i->rest.expand(), i->coeff));
+       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+               ex restexp = i->rest.expand();
+               if (!restexp.is_zero())
+                       newseq.push_back(expair(restexp, i->coeff));
+       }
        return (new pseries(relational(var,point), newseq))
                ->setflag(status_flags::dynallocated | status_flags::expanded);
 }
index 21b7e41122d16dad954e1fd3c6ed85f8f4039d7f..c604bf56895f5a9c145b55802f64a9addb5424de 100644 (file)
@@ -46,10 +46,10 @@ class symbol : public basic
        /** Symbols as keys to expressions. */
        class assigned_ex_info {
        public:
-               assigned_ex_info();     //!< Default ctor
-               bool is_assigned;       //!< True if there is an expression assigned
-               ex assigned_expression; //!< The actual expression
-               unsigned refcount;      //!< Yet another refcounter. PLEASE EXPLAIN!
+               assigned_ex_info();     //! Default ctor
+               bool is_assigned;       //! True if there is an expression assigned
+               ex assigned_expression; //! The actual expression
+               unsigned refcount;      //! Yet another refcounter. PLEASE EXPLAIN!
        };
        
 // member functions