]> www.ginac.de Git - ginac.git/blobdiff - ginac/add.cpp
- revamped indexed objects
[ginac.git] / ginac / add.cpp
index fa42153072269da7dd6cad27d134fae1e350b594..6c6a163831a9e3a0e6856e6144f288fc9dedfc04 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's sums of expressions. */
 
 /*
- *  GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -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)
 
@@ -47,30 +45,9 @@ add::add()
        tinfo_key = TINFO_add;
 }
 
-add::~add()
-{
-       debugmsg("add destructor",LOGLEVEL_DESTRUCT);
-       destroy(false);
-}
-
-add::add(const add & other)
-{
-       debugmsg("add copy constructor",LOGLEVEL_CONSTRUCT);
-       copy(other);
-}
-
-const add & add::operator=(const add & other)
-{
-       debugmsg("add operator=",LOGLEVEL_ASSIGNMENT);
-       if (this != &other) {
-               destroy(true);
-               copy(other);
-       }
-       return *this;
-}
-
 // protected
 
+/** For use by copy ctor and assignment operator. */
 void add::copy(const add & other)
 {
        inherited::copy(other);
@@ -105,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);
@@ -179,12 +139,6 @@ void add::archive(archive_node &n) const
 
 // public
 
-basic * add::duplicate() const
-{
-       debugmsg("add duplicate",LOGLEVEL_DUPLICATE);
-       return new add(*this);
-}
-
 void add::print(std::ostream & os, unsigned upper_precedence) const
 {
        debugmsg("add print",LOGLEVEL_PRINT);
@@ -206,7 +160,7 @@ void add::print(std::ostream & os, unsigned upper_precedence) const
                        first = false;
                }
                if (!coeff.is_equal(_num1()) &&
-                       !coeff.is_equal(_num_1())) {
+                   !coeff.is_equal(_num_1())) {
                        if (coeff.is_rational()) {
                                if (coeff.is_negative())
                                        os << -coeff;
@@ -220,7 +174,7 @@ void add::print(std::ostream & os, unsigned upper_precedence) const
                        }
                        os << '*';
                }
-               os << cit->rest;
+               cit->rest.print(os, precedence);
        }
        if (precedence<=upper_precedence) os << ")";
 }
@@ -246,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);
@@ -272,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);
        }
@@ -317,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;
 }
@@ -331,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);
@@ -350,7 +305,7 @@ ex add::coeff(const symbol & s, int n) const
        epvector::const_iterator it=seq.begin();
        while (it!=seq.end()) {
                coeffseq.push_back(combine_ex_with_coeff_to_pair((*it).rest.coeff(s,n),
-                                                                                                                (*it).coeff));
+                                                                (*it).coeff));
                ++it;
        }
        if (n==0) {
@@ -363,54 +318,42 @@ 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))->
-                                  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,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()));
        }
        return this->hold();
 }
 
-exvector add::get_indices(void) const
-{
-       // FIXME: all terms in the sum should have the same indices (compatible
-       // tensors) however this is not checked, since there is no function yet
-       // which compares indices (idxvector can be unsorted)
-       if (seq.size()==0) {
-               return exvector();
-       }
-       return (seq.begin())->rest.get_indices();
-}    
-
 ex add::simplify_ncmul(const exvector & v) const
 {
        if (seq.size()==0) {
@@ -468,14 +411,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);
-               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 = 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());
 }
@@ -484,30 +427,28 @@ 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
+                       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);
 }
-       
+
 expair add::combine_pair_with_coeff_to_pair(const expair & p,
                                                                                        const ex & c) const
 {
@@ -536,24 +477,15 @@ 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);
 }
 
-//////////
-// new virtual functions which can be overridden by derived classes
-//////////
-
-// none
-
-//////////
-// non-virtual functions in this class
-//////////
-
-// none
-
 //////////
 // static member variables
 //////////
@@ -562,13 +494,4 @@ ex add::expand(unsigned options) const
 
 unsigned add::precedence = 40;
 
-//////////
-// global constants
-//////////
-
-const add some_add;
-const type_info & typeid_add = typeid(some_add);
-
-#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC