/** @file add.cpp
*
- * Implementation of GiNaC's sums of expressions.
- *
+ * Implementation of GiNaC's sums of expressions. */
+
+/*
* GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
*
* This program is free software; you can redistribute it and/or modify
#include "add.h"
#include "mul.h"
+#include "debugmsg.h"
+
+#ifndef NO_GINAC_NAMESPACE
+namespace GiNaC {
+#endif // ndef NO_GINAC_NAMESPACE
//////////
// default constructor, destructor, copy constructor assignment operator and helpers
tinfo_key = TINFO_add;
overall_coeff=exZERO();
construct_from_2_ex(lh,rh);
- ASSERT(is_canonical());
+ GINAC_ASSERT(is_canonical());
}
add::add(exvector const & v)
tinfo_key = TINFO_add;
overall_coeff=exZERO();
construct_from_exvector(v);
- ASSERT(is_canonical());
+ GINAC_ASSERT(is_canonical());
}
/*
} else {
construct_from_epvector(v);
}
- ASSERT(is_canonical());
+ GINAC_ASSERT(is_canonical());
}
*/
tinfo_key = TINFO_add;
overall_coeff=exZERO();
construct_from_epvector(v);
- ASSERT(is_canonical());
+ GINAC_ASSERT(is_canonical());
}
add::add(epvector const & v, ex const & oc)
tinfo_key = TINFO_add;
overall_coeff=oc;
construct_from_epvector(v);
- ASSERT(is_canonical());
+ GINAC_ASSERT(is_canonical());
}
add::add(epvector * vp, ex const & oc)
{
debugmsg("add constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_add;
- ASSERT(vp!=0);
+ GINAC_ASSERT(vp!=0);
overall_coeff=oc;
construct_from_epvector(*vp);
delete vp;
- ASSERT(is_canonical());
+ GINAC_ASSERT(is_canonical());
}
//////////
return (new add(coeffseq))->setflag(status_flags::dynallocated);
}
-/*
-ex add::eval(int level) const
-{
- // simplifications: +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric())
- // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize)
- // +(...,x,0) -> +(...,x)
- // +(x) -> x
- // +() -> 0
-
- debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION);
-
- epvector newseq=seq;
- epvector::iterator it1,it2;
-
- // +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric())
- it2=newseq.end()-1;
- it1=it2-1;
- while ((newseq.size()>=2)&&is_exactly_of_type(*(*it1).rest.bp,numeric)&&
- is_exactly_of_type(*(*it2).rest.bp,numeric)) {
- *it1=expair(ex_to_numeric((*it1).rest).mul(ex_to_numeric((*it1).coeff))
- .add(ex_to_numeric((*it2).rest).mul(ex_to_numeric((*it2).coeff))),exONE());
- newseq.pop_back();
- it2=newseq.end()-1;
- it1=it2-1;
- }
-
- if ((newseq.size()>=1)&&is_exactly_of_type(*(*it2).rest.bp,numeric)) {
- // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize)
- *it2=expair(ex_to_numeric((*it2).rest).mul(ex_to_numeric((*it2).coeff)),exONE());
- // +(...,x,0) -> +(...,x)
- if (ex_to_numeric((*it2).rest).compare(0)==0) {
- newseq.pop_back();
- }
- }
-
- if (newseq.size()==0) {
- // +() -> 0
- return exZERO();
- } else if (newseq.size()==1) {
- // +(x) -> x
- return recombine_pair_to_ex(*(newseq.begin()));
- }
-
- return (new add(newseq,1))->setflag(status_flags::dynallocated |
- status_flags::evaluated );
-}
-*/
-
-/*
-ex add::eval(int level) const
-{
- // simplifications: +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric())
- // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize)
- // +(...,x,0) -> +(...,x)
- // +(x) -> x
- // +() -> 0
-
- debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION);
-
- if ((level==1)&&(flags & status_flags::evaluated)) {
-#ifdef DOASSERT
- for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- ASSERT(!is_ex_exactly_of_type((*cit).rest,add));
- ASSERT(!(is_ex_exactly_of_type((*cit).rest,numeric)&&
- (ex_to_numeric((*cit).coeff).compare(numONE())!=0)));
- }
-#endif // def DOASSERT
- return *this;
- }
-
- epvector newseq;
- epvector::iterator it1,it2;
- bool seq_copied=false;
-
- epvector * evaled_seqp=evalchildren(level);
- if (evaled_seqp!=0) {
- // do more evaluation later
- return (new add(evaled_seqp))->setflag(status_flags::dynallocated);
- }
-
-#ifdef DOASSERT
- for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- ASSERT(!is_ex_exactly_of_type((*cit).rest,add));
- ASSERT(!(is_ex_exactly_of_type((*cit).rest,numeric)&&
- (ex_to_numeric((*cit).coeff).compare(numONE())!=0)));
- }
-#endif // def DOASSERT
-
- if (flags & status_flags::evaluated) {
- return *this;
- }
-
- expair const & last_expair=*(seq.end()-1);
- expair const & next_to_last_expair=*(seq.end()-2);
- int seq_size = seq.size();
-
- // +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric())
- if ((!seq_copied)&&(seq_size>=2)&&
- is_ex_exactly_of_type(last_expair.rest,numeric)&&
- is_ex_exactly_of_type(next_to_last_expair.rest,numeric)) {
- newseq=seq;
- seq_copied=true;
- it2=newseq.end()-1;
- it1=it2-1;
- }
- while (seq_copied&&(newseq.size()>=2)&&
- is_ex_exactly_of_type((*it1).rest,numeric)&&
- is_ex_exactly_of_type((*it2).rest,numeric)) {
- *it1=expair(ex_to_numeric((*it1).rest).mul(ex_to_numeric((*it1).coeff))
- .add_dyn(ex_to_numeric((*it2).rest).mul(ex_to_numeric((*it2).coeff))),exONE());
- newseq.pop_back();
- it2=newseq.end()-1;
- it1=it2-1;
- }
-
- // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize)
- if ((!seq_copied)&&(seq_size>=1)&&
- (is_ex_exactly_of_type(last_expair.rest,numeric))&&
- (ex_to_numeric(last_expair.coeff).compare(numONE())!=0)) {
- newseq=seq;
- seq_copied=true;
- it2=newseq.end()-1;
- }
- if (seq_copied&&(newseq.size()>=1)&&
- (is_ex_exactly_of_type((*it2).rest,numeric))&&
- (ex_to_numeric((*it2).coeff).compare(numONE())!=0)) {
- *it2=expair(ex_to_numeric((*it2).rest).mul_dyn(ex_to_numeric((*it2).coeff)),exONE());
- }
-
- // +(...,x,0) -> +(...,x)
- if ((!seq_copied)&&(seq_size>=1)&&
- (is_ex_exactly_of_type(last_expair.rest,numeric))&&
- (ex_to_numeric(last_expair.rest).is_zero())) {
- newseq=seq;
- seq_copied=true;
- it2=newseq.end()-1;
- }
- if (seq_copied&&(newseq.size()>=1)&&
- (is_ex_exactly_of_type((*it2).rest,numeric))&&
- (ex_to_numeric((*it2).rest).is_zero())) {
- newseq.pop_back();
- }
-
- // +() -> 0
- if ((!seq_copied)&&(seq_size==0)) {
- return exZERO();
- } else if (seq_copied&&(newseq.size()==0)) {
- return exZERO();
- }
-
- // +(x) -> x
- if ((!seq_copied)&&(seq_size==1)) {
- return recombine_pair_to_ex(*(seq.begin()));
- } else if (seq_copied&&(newseq.size()==1)) {
- return recombine_pair_to_ex(*(newseq.begin()));
- }
-
- if (!seq_copied) return this->hold();
-
- return (new add(newseq,1))->setflag(status_flags::dynallocated |
- status_flags::evaluated );
-}
-*/
-
ex add::eval(int level) const
{
// simplifications: +(;c) -> c
setflag(status_flags::dynallocated);
}
-#ifdef DOASSERT
+#ifdef DO_GINAC_ASSERT
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- ASSERT(!is_ex_exactly_of_type((*cit).rest,add));
+ GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,add));
if (is_ex_exactly_of_type((*cit).rest,numeric)) {
dbgprint();
}
- ASSERT(!is_ex_exactly_of_type((*cit).rest,numeric));
+ GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,numeric));
}
-#endif // def DOASSERT
+#endif // def DO_GINAC_ASSERT
if (flags & status_flags::evaluated) {
- ASSERT(seq.size()>0);
- ASSERT((seq.size()>1)||!overall_coeff.is_equal(exZERO()));
+ GINAC_ASSERT(seq.size()>0);
+ GINAC_ASSERT((seq.size()>1)||!overall_coeff.is_equal(exZERO()));
return *this;
}
exvector add::get_indices(void) const
{
- // 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) !!!!!!!!!!!
+ // 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 (new add(vp,oc))->setflag(status_flags::dynallocated);
}
-/*
-expair add::split_ex_to_pair(ex const & e) const
-{
- if (is_ex_exactly_of_type(e,mul)) {
- mul const & mulref=ex_to_mul(e);
- ASSERT(mulref.seq.size()>1);
- ex const & lastfactor_rest=(*(mulref.seq.end()-1)).rest;
- ex const & lastfactor_coeff=(*(mulref.seq.end()-1)).coeff;
- if (is_ex_exactly_of_type(lastfactor_rest,numeric) &&
- ex_to_numeric(lastfactor_coeff).is_equal(numONE())) {
- epvector s=mulref.seq;
- //s.pop_back();
- //return expair((new mul(s,1))->setflag(status_flags::dynallocated),
- // lastfactor);
- mul * mulp=static_cast<mul *>(mulref.duplicate());
-#ifdef EXPAIRSEQ_USE_HASHTAB
- mulp->remove_hashtab_entry(mulp->seq.end()-1);
-#endif // def EXPAIRSEQ_USE_HASHTAB
- mulp->seq.pop_back();
-#ifdef EXPAIRSEQ_USE_HASHTAB
- mulp->shrink_hashtab();
-#endif // def EXPAIRSEQ_USE_HASHTAB
- mulp->clearflag(status_flags::evaluated);
- mulp->clearflag(status_flags::hash_calculated);
- return expair(mulp->setflag(status_flags::dynallocated),lastfactor_rest);
- }
- }
- return expair(e,exONE());
-}
-*/
-
expair add::split_ex_to_pair(ex const & e) const
{
if (is_ex_exactly_of_type(e,mul)) {
return expair(e,exONE());
}
-/*
expair add::combine_ex_with_coeff_to_pair(ex const & e,
ex const & c) const
{
- ASSERT(is_ex_exactly_of_type(c,numeric));
- if (is_ex_exactly_of_type(e,mul)) {
- mul const & mulref=ex_to_mul(e);
- ASSERT(mulref.seq.size()>1);
- ex const & lastfactor_rest=(*(mulref.seq.end()-1)).rest;
- ex const & lastfactor_coeff=(*(mulref.seq.end()-1)).coeff;
- if (is_ex_exactly_of_type(lastfactor_rest,numeric) &&
- ex_to_numeric(lastfactor_coeff).is_equal(numONE())) {
- //epvector s=mulref.seq;
- //s.pop_back();
- //return expair((new mul(s,1))->setflag(status_flags::dynallocated),
- // ex_to_numeric(lastfactor).mul_dyn(ex_to_numeric(c)));
- mul * mulp=static_cast<mul *>(mulref.duplicate());
-#ifdef EXPAIRSEQ_USE_HASHTAB
- mulp->remove_hashtab_entry(mulp->seq.end()-1);
-#endif // def EXPAIRSEQ_USE_HASHTAB
- mulp->seq.pop_back();
-#ifdef EXPAIRSEQ_USE_HASHTAB
- mulp->shrink_hashtab();
-#endif // def EXPAIRSEQ_USE_HASHTAB
- mulp->clearflag(status_flags::evaluated);
- mulp->clearflag(status_flags::hash_calculated);
- if (are_ex_trivially_equal(c,exONE())) {
- return expair(mulp->setflag(status_flags::dynallocated),lastfactor_rest);
- } else if (are_ex_trivially_equal(lastfactor_rest,exONE())) {
- return expair(mulp->setflag(status_flags::dynallocated),c);
- }
- return expair(mulp->setflag(status_flags::dynallocated),
- ex_to_numeric(lastfactor_rest).mul_dyn(ex_to_numeric(c)));
- }
- }
- return expair(e,c);
-}
-*/
-
-expair add::combine_ex_with_coeff_to_pair(ex const & e,
- ex const & c) const
-{
- ASSERT(is_ex_exactly_of_type(c,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
if (is_ex_exactly_of_type(e,mul)) {
mul const & mulref=ex_to_mul(e);
ex numfactor=mulref.overall_coeff;
expair add::combine_pair_with_coeff_to_pair(expair const & p,
ex const & c) const
{
- ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
- ASSERT(is_ex_exactly_of_type(c,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
if (is_ex_exactly_of_type(p.rest,numeric)) {
- ASSERT(ex_to_numeric(p.coeff).is_equal(numONE())); // should be normalized
+ GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(numONE())); // should be normalized
return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),exONE());
}
const add some_add;
type_info const & typeid_add=typeid(some_add);
-
-
+#ifndef NO_GINAC_NAMESPACE
+} // namespace GiNaC
+#endif // ndef NO_GINAC_NAMESPACE