add::add()
{
- debugmsg("add default constructor",LOGLEVEL_CONSTRUCT);
- tinfo_key = TINFO_add;
+ debugmsg("add default constructor",LOGLEVEL_CONSTRUCT);
+ tinfo_key = TINFO_add;
}
add::~add()
{
- debugmsg("add destructor",LOGLEVEL_DESTRUCT);
- destroy(0);
+ debugmsg("add destructor",LOGLEVEL_DESTRUCT);
+ destroy(0);
}
add::add(const add & other)
{
- debugmsg("add copy constructor",LOGLEVEL_CONSTRUCT);
- copy(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(1);
- copy(other);
- }
- return *this;
+ debugmsg("add operator=",LOGLEVEL_ASSIGNMENT);
+ if (this != &other) {
+ destroy(1);
+ copy(other);
+ }
+ return *this;
}
// protected
void add::copy(const add & other)
{
- inherited::copy(other);
+ inherited::copy(other);
}
void add::destroy(bool call_parent)
{
- if (call_parent) inherited::destroy(call_parent);
+ if (call_parent) inherited::destroy(call_parent);
}
//////////
add::add(const ex & lh, const ex & rh)
{
- debugmsg("add constructor from ex,ex",LOGLEVEL_CONSTRUCT);
- tinfo_key = TINFO_add;
- overall_coeff = _ex0();
- construct_from_2_ex(lh,rh);
- GINAC_ASSERT(is_canonical());
+ debugmsg("add constructor from ex,ex",LOGLEVEL_CONSTRUCT);
+ tinfo_key = TINFO_add;
+ overall_coeff = _ex0();
+ construct_from_2_ex(lh,rh);
+ GINAC_ASSERT(is_canonical());
}
add::add(const exvector & v)
{
- debugmsg("add constructor from exvector",LOGLEVEL_CONSTRUCT);
- tinfo_key = TINFO_add;
- overall_coeff = _ex0();
- construct_from_exvector(v);
- GINAC_ASSERT(is_canonical());
+ debugmsg("add constructor from exvector",LOGLEVEL_CONSTRUCT);
+ tinfo_key = TINFO_add;
+ overall_coeff = _ex0();
+ construct_from_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;
+ 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
+ combine_same_terms(); // to build hashtab
#endif // def EXPAIRSEQ_USE_HASHTAB
- } else {
- construct_from_epvector(v);
- }
- GINAC_ASSERT(is_canonical());
+ } else {
+ construct_from_epvector(v);
+ }
+ GINAC_ASSERT(is_canonical());
}
*/
add::add(const epvector & v)
{
- debugmsg("add constructor from epvector",LOGLEVEL_CONSTRUCT);
- tinfo_key = TINFO_add;
- overall_coeff = _ex0();
- construct_from_epvector(v);
- GINAC_ASSERT(is_canonical());
+ debugmsg("add constructor from epvector",LOGLEVEL_CONSTRUCT);
+ tinfo_key = TINFO_add;
+ overall_coeff = _ex0();
+ construct_from_epvector(v);
+ GINAC_ASSERT(is_canonical());
}
add::add(const epvector & v, const ex & oc)
{
- debugmsg("add constructor from epvector,ex",LOGLEVEL_CONSTRUCT);
- tinfo_key = TINFO_add;
- overall_coeff = oc;
- construct_from_epvector(v);
- GINAC_ASSERT(is_canonical());
+ debugmsg("add constructor from epvector,ex",LOGLEVEL_CONSTRUCT);
+ tinfo_key = TINFO_add;
+ overall_coeff = oc;
+ construct_from_epvector(v);
+ GINAC_ASSERT(is_canonical());
}
add::add(epvector * vp, const ex & oc)
{
- debugmsg("add constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
- tinfo_key = TINFO_add;
- GINAC_ASSERT(vp!=0);
- overall_coeff = oc;
- construct_from_epvector(*vp);
- delete vp;
- GINAC_ASSERT(is_canonical());
+ debugmsg("add constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
+ tinfo_key = TINFO_add;
+ GINAC_ASSERT(vp!=0);
+ overall_coeff = oc;
+ construct_from_epvector(*vp);
+ delete vp;
+ GINAC_ASSERT(is_canonical());
}
//////////
/** Construct object from archive_node. */
add::add(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
{
- debugmsg("add constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ debugmsg("add constructor from archive_node", LOGLEVEL_CONSTRUCT);
}
/** Unarchive the object. */
ex add::unarchive(const archive_node &n, const lst &sym_lst)
{
- return (new add(n, sym_lst))->setflag(status_flags::dynallocated);
+ return (new add(n, sym_lst))->setflag(status_flags::dynallocated);
}
/** Archive the object. */
void add::archive(archive_node &n) const
{
- inherited::archive(n);
+ inherited::archive(n);
}
//////////
basic * add::duplicate() const
{
- debugmsg("add duplicate",LOGLEVEL_DUPLICATE);
- return new add(*this);
+ debugmsg("add duplicate",LOGLEVEL_DUPLICATE);
+ return new add(*this);
}
void add::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("add print",LOGLEVEL_PRINT);
- if (precedence<=upper_precedence) os << "(";
- numeric coeff;
- bool first = true;
- // first print the overall numeric coefficient, if present:
- if (!overall_coeff.is_zero()) {
- os << overall_coeff;
- first = false;
- }
- // then proceed with the remaining factors:
- for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- coeff = ex_to_numeric(cit->coeff);
- if (!first) {
- if (coeff.csgn()==-1) os << '-'; else os << '+';
- } else {
- if (coeff.csgn()==-1) os << '-';
- first = false;
- }
- if (!coeff.is_equal(_num1()) &&
- !coeff.is_equal(_num_1())) {
- if (coeff.is_rational()) {
- if (coeff.is_negative())
- os << -coeff;
- else
- os << coeff;
- } else {
- if (coeff.csgn()==-1)
- (-coeff).print(os, precedence);
- else
- coeff.print(os, precedence);
- }
- os << '*';
- }
- os << cit->rest;
- }
- if (precedence<=upper_precedence) os << ")";
+ debugmsg("add print",LOGLEVEL_PRINT);
+ if (precedence<=upper_precedence) os << "(";
+ numeric coeff;
+ bool first = true;
+ // first print the overall numeric coefficient, if present:
+ if (!overall_coeff.is_zero()) {
+ os << overall_coeff;
+ first = false;
+ }
+ // then proceed with the remaining factors:
+ for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
+ coeff = ex_to_numeric(cit->coeff);
+ if (!first) {
+ if (coeff.csgn()==-1) os << '-'; else os << '+';
+ } else {
+ if (coeff.csgn()==-1) os << '-';
+ first = false;
+ }
+ if (!coeff.is_equal(_num1()) &&
+ !coeff.is_equal(_num_1())) {
+ if (coeff.is_rational()) {
+ if (coeff.is_negative())
+ os << -coeff;
+ else
+ os << coeff;
+ } else {
+ if (coeff.csgn()==-1)
+ (-coeff).print(os, precedence);
+ else
+ coeff.print(os, precedence);
+ }
+ os << '*';
+ }
+ os << cit->rest;
+ }
+ if (precedence<=upper_precedence) os << ")";
}
void add::printraw(std::ostream & os) const
{
- debugmsg("add printraw",LOGLEVEL_PRINT);
+ debugmsg("add printraw",LOGLEVEL_PRINT);
- os << "+(";
- for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
- os << "(";
- (*it).rest.bp->printraw(os);
- os << ",";
- (*it).coeff.bp->printraw(os);
- os << "),";
- }
- os << ",hash=" << hashvalue << ",flags=" << flags;
- os << ")";
+ os << "+(";
+ for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
+ os << "(";
+ (*it).rest.bp->printraw(os);
+ os << ",";
+ (*it).coeff.bp->printraw(os);
+ os << "),";
+ }
+ os << ",hash=" << hashvalue << ",flags=" << flags;
+ os << ")";
}
void add::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
{
- 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);
- } else if (it->coeff.compare(_num_1()) == 0) {
- os << "-";
- it->rest.bp->printcsrc(os, type, precedence);
- } else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) {
- it->rest.bp->printcsrc(os, type, precedence);
- os << "/";
- ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence);
- } else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) {
- os << "-";
- it->rest.bp->printcsrc(os, type, precedence);
- os << "/";
- ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence);
- } else {
- it->coeff.bp->printcsrc(os, type, 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.info(info_flags::positive)) os << '+';
- overall_coeff.bp->printcsrc(os,type,precedence);
- }
-
- if (precedence <= upper_precedence)
- os << ")";
+ 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);
+ } else if (it->coeff.compare(_num_1()) == 0) {
+ os << "-";
+ it->rest.bp->printcsrc(os, type, precedence);
+ } else if (ex_to_numeric(it->coeff).numer().compare(_num1()) == 0) {
+ it->rest.bp->printcsrc(os, type, precedence);
+ os << "/";
+ ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence);
+ } else if (ex_to_numeric(it->coeff).numer().compare(_num_1()) == 0) {
+ os << "-";
+ it->rest.bp->printcsrc(os, type, precedence);
+ os << "/";
+ ex_to_numeric(it->coeff).denom().printcsrc(os, type, precedence);
+ } else {
+ it->coeff.bp->printcsrc(os, type, 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.info(info_flags::positive)) os << '+';
+ overall_coeff.bp->printcsrc(os,type,precedence);
+ }
+
+ if (precedence <= upper_precedence)
+ os << ")";
}
bool add::info(unsigned inf) const
{
- switch (inf) {
- case info_flags::polynomial:
- case info_flags::integer_polynomial:
- case info_flags::cinteger_polynomial:
- case info_flags::rational_polynomial:
- case info_flags::crational_polynomial:
- case info_flags::rational_function: {
- for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
- if (!(recombine_pair_to_ex(*i).info(inf)))
- return false;
- }
- return overall_coeff.info(inf);
- }
- case info_flags::algebraic: {
- for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
- if ((recombine_pair_to_ex(*i).info(inf)))
- return true;
- }
- return false;
- }
- }
- return inherited::info(inf);
+ switch (inf) {
+ case info_flags::polynomial:
+ case info_flags::integer_polynomial:
+ case info_flags::cinteger_polynomial:
+ case info_flags::rational_polynomial:
+ case info_flags::crational_polynomial:
+ case info_flags::rational_function: {
+ for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+ if (!(recombine_pair_to_ex(*i).info(inf)))
+ return false;
+ }
+ return overall_coeff.info(inf);
+ }
+ case info_flags::algebraic: {
+ for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+ if ((recombine_pair_to_ex(*i).info(inf)))
+ return true;
+ }
+ return false;
+ }
+ }
+ return inherited::info(inf);
}
int add::degree(const symbol & s) const
{
- int deg = INT_MIN;
- 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;
- }
- return deg;
+ int deg = INT_MIN;
+ 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;
+ }
+ return deg;
}
int add::ldegree(const symbol & s) const
{
- int deg = INT_MAX;
- 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);
- if (cur_deg<deg) deg=cur_deg;
- }
- return deg;
+ int deg = INT_MAX;
+ 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);
+ if (cur_deg<deg) deg=cur_deg;
+ }
+ return deg;
}
ex add::coeff(const symbol & s, int n) const
{
- epvector coeffseq;
- coeffseq.reserve(seq.size());
+ epvector coeffseq;
+ coeffseq.reserve(seq.size());
- 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;
- }
- if (n==0) {
- return (new add(coeffseq,overall_coeff))->setflag(status_flags::dynallocated);
- }
- return (new add(coeffseq))->setflag(status_flags::dynallocated);
+ 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;
+ }
+ if (n==0) {
+ return (new add(coeffseq,overall_coeff))->setflag(status_flags::dynallocated);
+ }
+ return (new add(coeffseq))->setflag(status_flags::dynallocated);
}
ex add::eval(int level) const
{
- // simplifications: +(;c) -> c
- // +(x;1) -> x
+ // simplifications: +(;c) -> c
+ // +(x;1) -> x
- debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION);
+ debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION);
- epvector * evaled_seqp=evalchildren(level);
- if (evaled_seqp!=0) {
- // do more evaluation later
- return (new add(evaled_seqp,overall_coeff))->
- setflag(status_flags::dynallocated);
- }
-
+ epvector * evaled_seqp=evalchildren(level);
+ if (evaled_seqp!=0) {
+ // do more evaluation later
+ return (new add(evaled_seqp,overall_coeff))->
+ 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)) {
- dbgprint();
- }
- GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,numeric));
- }
+ 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)) {
+ 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()));
- return *this;
- }
-
- int seq_size=seq.size();
- if (seq_size==0) {
- // +(;c) -> c
- return overall_coeff;
- } else if ((seq_size==1)&&overall_coeff.is_equal(_ex0())) {
- // +(x;0) -> x
- return recombine_pair_to_ex(*(seq.begin()));
- }
- return this->hold();
+
+ if (flags & status_flags::evaluated) {
+ GINAC_ASSERT(seq.size()>0);
+ GINAC_ASSERT((seq.size()>1)||!overall_coeff.is_equal(_ex0()));
+ return *this;
+ }
+
+ int seq_size=seq.size();
+ if (seq_size==0) {
+ // +(;c) -> c
+ return overall_coeff;
+ } 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();
+ // 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) {
- return inherited::simplify_ncmul(v);
- }
- return (*seq.begin()).rest.simplify_ncmul(v);
+ if (seq.size()==0) {
+ return inherited::simplify_ncmul(v);
+ }
+ return (*seq.begin()).rest.simplify_ncmul(v);
}
// protected
* @see ex::diff */
ex add::derivative(const symbol & s) const
{
- // D(a+b+c)=D(a)+D(b)+D(c)
- return (new add(diffchildren(s)))->setflag(status_flags::dynallocated);
+ // D(a+b+c)=D(a)+D(b)+D(c)
+ return (new add(diffchildren(s)))->setflag(status_flags::dynallocated);
}
int add::compare_same_type(const basic & other) const
{
- return inherited::compare_same_type(other);
+ return inherited::compare_same_type(other);
}
bool add::is_equal_same_type(const basic & other) const
{
- return inherited::is_equal_same_type(other);
+ return inherited::is_equal_same_type(other);
}
unsigned add::return_type(void) const
{
- if (seq.size()==0) {
- return return_types::commutative;
- }
- return (*seq.begin()).rest.return_type();
+ if (seq.size()==0) {
+ return return_types::commutative;
+ }
+ return (*seq.begin()).rest.return_type();
}
unsigned add::return_type_tinfo(void) const
{
- if (seq.size()==0) {
- return tinfo_key;
- }
- return (*seq.begin()).rest.return_type_tinfo();
+ if (seq.size()==0) {
+ return tinfo_key;
+ }
+ return (*seq.begin()).rest.return_type_tinfo();
}
ex add::thisexpairseq(const epvector & v, const ex & oc) const
{
- return (new add(v,oc))->setflag(status_flags::dynallocated);
+ return (new add(v,oc))->setflag(status_flags::dynallocated);
}
ex add::thisexpairseq(epvector * vp, const ex & oc) const
{
- return (new add(vp,oc))->setflag(status_flags::dynallocated);
+ return (new add(vp,oc))->setflag(status_flags::dynallocated);
}
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();
- mulcopyp->clearflag(status_flags::evaluated);
- mulcopyp->clearflag(status_flags::hash_calculated);
- return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor);
- }
- return expair(e,_ex1());
+ 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();
+ mulcopyp->clearflag(status_flags::evaluated);
+ mulcopyp->clearflag(status_flags::hash_calculated);
+ return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor);
+ }
+ return expair(e,_ex1());
}
expair add::combine_ex_with_coeff_to_pair(const ex & e,
- const ex & c) const
-{
- GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
- 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();
- mulcopyp->clearflag(status_flags::evaluated);
- mulcopyp->clearflag(status_flags::hash_calculated);
- if (are_ex_trivially_equal(c,_ex1())) {
- return expair(mulcopyp->setflag(status_flags::dynallocated),numfactor);
- } else if (are_ex_trivially_equal(numfactor,_ex1())) {
- return expair(mulcopyp->setflag(status_flags::dynallocated),c);
- }
- return expair(mulcopyp->setflag(status_flags::dynallocated),
- 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());
- }
- return expair(ex_to_numeric(e).mul_dyn(ex_to_numeric(c)),_ex1());
- }
- return expair(e,c);
-}
-
+ 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->clearflag(status_flags::evaluated);
+ mulcopyp->clearflag(status_flags::hash_calculated);
+ mulcopyp->setflag(status_flags::dynallocated);
+ if (are_ex_trivially_equal(c, one)) {
+ return expair(*mulcopyp, numfactor);
+ } else if (are_ex_trivially_equal(numfactor, one)) {
+ 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);
+ }
+ return expair(e, c);
+}
+
expair add::combine_pair_with_coeff_to_pair(const expair & p,
- const ex & c) const
+ const ex & c) const
{
- GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
- GINAC_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)) {
- GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(_num1())); // should be normalized
- return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),_ex1());
- }
+ if (is_ex_exactly_of_type(p.rest,numeric)) {
+ GINAC_ASSERT(ex_to_numeric(p.coeff).is_equal(_num1())); // should be normalized
+ return expair(ex_to_numeric(p.rest).mul_dyn(ex_to_numeric(c)),_ex1());
+ }
- return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
+ return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
}
-
+
ex add::recombine_pair_to_ex(const expair & p) const
{
- //if (p.coeff.compare(_ex1())==0) {
- //if (are_ex_trivially_equal(p.coeff,_ex1())) {
- if (ex_to_numeric(p.coeff).is_equal(_num1())) {
- return p.rest;
- } else {
- return p.rest*p.coeff;
- }
+ if (ex_to_numeric(p.coeff).is_equal(_num1()))
+ return p.rest;
+ else
+ return p.rest*p.coeff;
}
ex add::expand(unsigned options) const
{
- if (flags & status_flags::expanded)
- return *this;
-
- epvector * vp = expandchildren(options);
- if (vp==0)
- return *this;
-
- return (new add(vp,overall_coeff))->
- setflag(status_flags::expanded |
- status_flags::dynallocated);
+ if (flags & status_flags::expanded)
+ return *this;
+
+ epvector * vp = expandchildren(options);
+ if (vp==0)
+ return *this;
+
+ return (new add(vp,overall_coeff))->
+ setflag(status_flags::expanded |
+ status_flags::dynallocated);
}
//////////
/** Sum of expressions. */
class add : public expairseq
{
- GINAC_DECLARE_REGISTERED_CLASS(add, expairseq)
+ GINAC_DECLARE_REGISTERED_CLASS(add, expairseq)
- friend class mul;
- friend class ncmul;
- friend class power;
+ friend class mul;
+ friend class ncmul;
+ friend class power;
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- add();
- ~add();
- add(const add & other);
- const add & operator=(const add & other);
+ add();
+ ~add();
+ add(const add & other);
+ const add & operator=(const add & other);
protected:
- void copy(const add & other);
- void destroy(bool call_parent);
+ void copy(const add & other);
+ void destroy(bool call_parent);
- // other constructors
+ // 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
+ 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:
- basic * duplicate() const;
- void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printraw(std::ostream & os) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
- bool info(unsigned inf) const;
- int degree(const symbol & s) const;
- int ldegree(const symbol & s) const;
- ex coeff(const symbol & s, int n=1) const;
- ex eval(int level=0) const;
- ex series(const relational & r, int order, unsigned options = 0) const;
- ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
- numeric integer_content(void) const;
- ex smod(const numeric &xi) const;
- numeric max_coefficient(void) const;
- exvector get_indices(void) const;
- ex simplify_ncmul(const exvector & v) const;
+ basic * duplicate() const;
+ void print(std::ostream & os, unsigned upper_precedence=0) const;
+ void printraw(std::ostream & os) const;
+ void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+ bool info(unsigned inf) const;
+ int degree(const symbol & s) const;
+ int ldegree(const symbol & s) const;
+ ex coeff(const symbol & s, int n=1) const;
+ ex eval(int level=0) const;
+ ex series(const relational & r, int order, unsigned options = 0) const;
+ ex normal(lst &sym_lst, lst &repl_lst, int level=0) const;
+ numeric integer_content(void) const;
+ ex smod(const numeric &xi) const;
+ numeric max_coefficient(void) const;
+ exvector get_indices(void) const;
+ ex simplify_ncmul(const exvector & v) const;
protected:
- ex derivative(const symbol & s) const;
- int compare_same_type(const basic & other) const;
- bool is_equal_same_type(const basic & other) const;
- unsigned return_type(void) const;
- unsigned return_type_tinfo(void) const;
- ex thisexpairseq(const epvector & v, const ex & oc) const;
- 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;
- expair combine_pair_with_coeff_to_pair(const expair & p,
- const ex & c) const;
- ex recombine_pair_to_ex(const expair & p) const;
- ex expand(unsigned options=0) const;
-
- // new virtual functions which can be overridden by derived classes
- // none
-
- // non-virtual functions in this class
- // none
+ ex derivative(const symbol & s) const;
+ int compare_same_type(const basic & other) const;
+ bool is_equal_same_type(const basic & other) const;
+ unsigned return_type(void) const;
+ unsigned return_type_tinfo(void) const;
+ ex thisexpairseq(const epvector & v, const ex & oc) const;
+ 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;
+ expair combine_pair_with_coeff_to_pair(const expair & p,
+ const ex & c) const;
+ ex recombine_pair_to_ex(const expair & p) const;
+ ex expand(unsigned options=0) const;
+
+ // new virtual functions which can be overridden by derived classes
+ // none
+
+ // non-virtual functions in this class
+ // none
// member variables
protected:
- static unsigned precedence;
+ static unsigned precedence;
};
// global constants
write_unsigned(os, n.props[i].type | (n.props[i].name << 3));
write_unsigned(os, n.props[i].value);
}
- return os;
+ return os;
}
/** Write archive to binary data stream. */
write_unsigned(os, num_nodes);
for (unsigned int i=0; i<num_nodes; i++)
os << ar.nodes[i];
- return os;
+ return os;
}
/** Read archive_node from binary data stream. */
n.props[i].name = name_type >> 3;
n.props[i].value = read_unsigned(is);
}
- return is;
+ return is;
}
/** Read archive from binary data stream. */
ar.nodes.resize(num_nodes, ar);
for (unsigned int i=0; i<num_nodes; i++)
is >> ar.nodes[i];
- return is;
+ return is;
}
* ctor, which is currently a Cint-requirement. */
archive* archive_node::dummy_ar_creator(void)
{
- static archive* some_ar = new archive;
- return some_ar;
+ static archive* some_ar = new archive;
+ return some_ar;
}
#include <vector>
namespace std {
- class ostream;
- class istream;
+ class ostream;
+ class istream;
}
#ifndef NO_NAMESPACE_GINAC
#ifndef INLINE_BASIC_CONSTRUCTORS
basic::basic() : flags(0), refcount(0), tinfo_key(TINFO_BASIC)
{
- debugmsg("basic default constructor", LOGLEVEL_CONSTRUCT);
- // nothing to do
+ debugmsg("basic default constructor", LOGLEVEL_CONSTRUCT);
+ // nothing to do
}
basic::~basic()
{
- debugmsg("basic destructor", LOGLEVEL_DESTRUCT);
- destroy(0);
- GINAC_ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
+ debugmsg("basic destructor", LOGLEVEL_DESTRUCT);
+ destroy(0);
+ 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);
- copy(other);
+ debugmsg("basic copy constructor", LOGLEVEL_CONSTRUCT);
+ copy(other);
}
#endif
const basic & basic::operator=(const basic & other)
{
- debugmsg("basic operator=", LOGLEVEL_ASSIGNMENT);
- if (this != &other) {
- destroy(1);
- copy(other);
- }
- return *this;
+ debugmsg("basic operator=", LOGLEVEL_ASSIGNMENT);
+ if (this != &other) {
+ destroy(1);
+ copy(other);
+ }
+ return *this;
}
// protected
#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
+ debugmsg("basic constructor with tinfo_key", LOGLEVEL_CONSTRUCT);
+ // nothing to do
}
#endif
/** 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 constructor from archive_node", LOGLEVEL_CONSTRUCT);
- // Reconstruct tinfo_key from class name
- std::string class_name;
- if (n.find_string("class", class_name))
- tinfo_key = find_tinfo_key(class_name);
- else
- throw (std::runtime_error("archive node contains no class name"));
+ // Reconstruct tinfo_key from class name
+ std::string class_name;
+ if (n.find_string("class", class_name))
+ tinfo_key = find_tinfo_key(class_name);
+ else
+ throw (std::runtime_error("archive node contains no class name"));
}
/** Unarchive the object. */
ex basic::unarchive(const archive_node &n, const lst &sym_lst)
{
- return (new basic(n, sym_lst))->setflag(status_flags::dynallocated);
+ return (new basic(n, sym_lst))->setflag(status_flags::dynallocated);
}
/** Archive the object. */
void basic::archive(archive_node &n) const
{
- n.add_string("class", class_name());
+ n.add_string("class", class_name());
}
//////////
/** Output to stream formatted to be useful as ginsh input. */
void basic::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("basic print",LOGLEVEL_PRINT);
- os << "[basic object]";
+ debugmsg("basic print",LOGLEVEL_PRINT);
+ os << "[basic object]";
}
/** Output to stream in ugly raw format, so brave developers can have a look
* at the underlying structure. */
void basic::printraw(std::ostream & os) const
{
- debugmsg("basic printraw",LOGLEVEL_PRINT);
- os << "[basic object]";
+ debugmsg("basic printraw",LOGLEVEL_PRINT);
+ os << "[basic object]";
}
/** Output to stream formatted in tree- (indented-) form, so developers can
* have a look at the underlying structure. */
void basic::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("basic printtree",LOGLEVEL_PRINT);
- os << std::string(indent,' ') << "type=" << typeid(*this).name()
- << ", hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags
- << ", nops=" << nops() << std::endl;
- for (unsigned i=0; i<nops(); ++i) {
- op(i).printtree(os,indent+delta_indent);
- }
+ debugmsg("basic printtree",LOGLEVEL_PRINT);
+ os << std::string(indent,' ') << "type=" << class_name()
+ << ", hash=" << hashvalue
+ << " (0x" << std::hex << hashvalue << std::dec << ")"
+ << ", flags=" << flags
+ << ", nops=" << nops() << std::endl;
+ for (unsigned i=0; i<nops(); ++i) {
+ op(i).printtree(os,indent+delta_indent);
+ }
}
/** Output to stream formatted as C-source.
* @see ex::printcsrc */
void basic::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
{
- debugmsg("basic print csrc", LOGLEVEL_PRINT);
+ debugmsg("basic print csrc", LOGLEVEL_PRINT);
}
/** Little wrapper arount print to be called within a debugger. */
void basic::dbgprint(void) const
{
- print(std::cerr);
- std::cerr << std::endl;
+ print(std::cerr);
+ std::cerr << std::endl;
}
/** Little wrapper arount printtree to be called within a debugger. */
void basic::dbgprinttree(void) const
{
- printtree(std::cerr,0);
+ printtree(std::cerr,0);
}
basic * basic::duplicate() const
{
- debugmsg("basic duplicate",LOGLEVEL_DUPLICATE);
- return new basic(*this);
+ debugmsg("basic duplicate",LOGLEVEL_DUPLICATE);
+ return new basic(*this);
}
/** Information about the object.
* @see class info_flags */
bool basic::info(unsigned inf) const
{
- return false; // all possible properties are false for basic objects
+ return false; // all possible properties are false for basic objects
}
/** Number of operands/members. */
unsigned basic::nops() const
{
- // iterating from 0 to nops() on atomic objects should be an empty loop,
- // and accessing their elements is a range error. Container objects should
- // override this.
- return 0;
+ // iterating from 0 to nops() on atomic objects should be an empty loop,
+ // and accessing their elements is a range error. Container objects should
+ // override this.
+ return 0;
}
/** Return operand/member at position i. */
ex basic::op(int i) const
{
- return (const_cast<basic *>(this))->let_op(i);
+ return (const_cast<basic *>(this))->let_op(i);
}
/** Return modifyable operand/member at position i. */
ex & basic::let_op(int i)
{
- throw(std::out_of_range("op() out of range"));
+ throw(std::out_of_range("op() out of range"));
}
ex basic::operator[](const ex & index) const
{
- if (is_exactly_of_type(*index.bp,numeric))
- return op(static_cast<const numeric &>(*index.bp).to_int());
-
- throw(std::invalid_argument("non-numeric indices not supported by this type"));
+ if (is_exactly_of_type(*index.bp,numeric))
+ return op(static_cast<const numeric &>(*index.bp).to_int());
+
+ throw(std::invalid_argument("non-numeric indices not supported by this type"));
}
ex basic::operator[](int i) const
{
- return op(i);
+ return op(i);
}
/** Search ocurrences. An object 'has' an expression if it is the expression
* itself or one of the children 'has' it. */
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;
- }
- }
- return false;
+ 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;
+ }
+ }
+ return false;
}
/** Return degree of highest power in symbol s. */
int basic::degree(const symbol & s) const
{
- return 0;
+ return 0;
}
/** Return degree of lowest power in symbol s. */
int basic::ldegree(const symbol & s) const
{
- return 0;
+ return 0;
}
/** Return coefficient of degree n in symbol s. */
ex basic::coeff(const symbol & s, int n) const
{
- return n==0 ? *this : _ex0();
+ return n==0 ? *this : _ex0();
}
/** Sort expression in terms of powers of some symbol.
* @param s symbol to sort in. */
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++) {
- x += this->coeff(s,n)*power(s,n);
- }
- return x;
+ ex x;
+ int ldeg = this->ldegree(s);
+ int deg = this->degree(s);
+ for (int n=ldeg; n<=deg; n++) {
+ x += this->coeff(s,n)*power(s,n);
+ }
+ return x;
}
/* Perform automatic symbolic evaluations on expression. */
ex basic::eval(int level) const
{
- // There is nothing to do for basic objects:
- return this->hold();
+ // There is nothing to do for basic objects:
+ return this->hold();
}
/** Evaluate object numerically. */
ex basic::evalf(int level) const
{
- // There is nothing to do for basic objects:
- return *this;
+ // There is nothing to do for basic objects:
+ return *this;
}
/* Substitute a set of symbols. */
ex basic::subs(const lst & ls, const lst & lr) const
{
- return *this;
+ return *this;
}
/** Default interface of nth derivative ex::diff(s, n). It should be called
* @see ex::diff */
ex basic::diff(const symbol & s, unsigned nth) const
{
- // trivial: zeroth derivative
- if (nth==0)
- return ex(*this);
-
- // evaluate unevaluated *this before differentiating
- if (!(flags & status_flags::evaluated))
- return ex(*this).diff(s, nth);
-
- ex ndiff = this->derivative(s);
- while (!ndiff.is_zero() && // stop differentiating zeros
- nth>1) {
- ndiff = ndiff.diff(s);
- --nth;
- }
- return ndiff;
+ // trivial: zeroth derivative
+ if (nth==0)
+ return ex(*this);
+
+ // evaluate unevaluated *this before differentiating
+ if (!(flags & status_flags::evaluated))
+ return ex(*this).diff(s, nth);
+
+ ex ndiff = this->derivative(s);
+ while (!ndiff.is_zero() && // stop differentiating zeros
+ nth>1) {
+ ndiff = ndiff.diff(s);
+ --nth;
+ }
+ return ndiff;
}
exvector basic::get_indices(void) const
{
- return exvector(); // return an empty exvector
+ return exvector(); // return an empty exvector
}
ex basic::simplify_ncmul(const exvector & v) const
{
- return simplified_ncmul(v);
+ return simplified_ncmul(v);
}
// protected
* @see ex::diff */
ex basic::derivative(const symbol & s) const
{
- throw(std::logic_error("differentiation not supported by this type"));
+ 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. */
int basic::compare_same_type(const basic & other) const
{
- return compare_pointers(this, &other);
+ return compare_pointers(this, &other);
}
/** Returns true if two objects of same type are equal. Normally needs
* class, since it just calls complare_same_type(). */
bool basic::is_equal_same_type(const basic & other) const
{
- return compare_same_type(other)==0;
+ return compare_same_type(other)==0;
}
unsigned basic::return_type(void) const
{
- return return_types::commutative;
+ return return_types::commutative;
}
unsigned basic::return_type_tinfo(void) const
{
- return tinfo();
+ return tinfo();
}
unsigned basic::calchash(void) const
{
- unsigned v=golden_ratio_hash(tinfo());
- for (unsigned i=0; i<nops(); i++) {
- v=rotate_left_31(v);
- v ^= (const_cast<basic *>(this))->op(i).gethash();
- }
+ unsigned v=golden_ratio_hash(tinfo());
+ for (unsigned i=0; i<nops(); i++) {
+ v=rotate_left_31(v);
+ v ^= (const_cast<basic *>(this))->op(i).gethash();
+ }
- v = v & 0x7FFFFFFFU;
-
- // store calculated hash value only if object is already evaluated
- if (flags & status_flags::evaluated) {
- setflag(status_flags::hash_calculated);
- hashvalue=v;
- }
+ v = v & 0x7FFFFFFFU;
+
+ // store calculated hash value only if object is already evaluated
+ if (flags & status_flags::evaluated) {
+ setflag(status_flags::hash_calculated);
+ hashvalue=v;
+ }
- return v;
+ return v;
}
/** Expand expression, i.e. multiply it out and return the result as a new
* expression. */
ex basic::expand(unsigned options) const
{
- return this->setflag(status_flags::expanded);
+ return this->setflag(status_flags::expanded);
}
* In addition, an object of class idx can be used instead of a symbol. */
ex basic::subs(const ex & e) const
{
- if (e.info(info_flags::relation_equal)) {
- return subs(lst(e));
- }
- if (!e.info(info_flags::list)) {
- throw(std::invalid_argument("basic::subs(ex): argument must be a list"));
- }
- lst ls;
- lst lr;
- for (unsigned i=0; i<e.nops(); i++) {
- if (!e.op(i).info(info_flags::relation_equal)) {
- throw(std::invalid_argument("basic::subs(ex): argument must be a list or equations"));
- }
- if (!e.op(i).op(0).info(info_flags::symbol)) {
- if (!e.op(i).op(0).info(info_flags::idx)) {
- throw(std::invalid_argument("basic::subs(ex): lhs must be a symbol or an idx"));
- }
- }
- ls.append(e.op(i).op(0));
- lr.append(e.op(i).op(1));
- }
- return subs(ls,lr);
+ if (e.info(info_flags::relation_equal)) {
+ return subs(lst(e));
+ }
+ if (!e.info(info_flags::list)) {
+ throw(std::invalid_argument("basic::subs(ex): argument must be a list"));
+ }
+ lst ls;
+ lst lr;
+ for (unsigned i=0; i<e.nops(); i++) {
+ if (!e.op(i).info(info_flags::relation_equal)) {
+ throw(std::invalid_argument("basic::subs(ex): argument must be a list or equations"));
+ }
+ if (!e.op(i).op(0).info(info_flags::symbol)) {
+ if (!e.op(i).op(0).info(info_flags::idx)) {
+ throw(std::invalid_argument("basic::subs(ex): lhs must be a symbol or an idx"));
+ }
+ }
+ ls.append(e.op(i).op(0));
+ lr.append(e.op(i).op(1));
+ }
+ return subs(ls,lr);
}
/** Compare objects to establish canonical order.
* 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;
- */
- 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;
- */
- 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;
- */
- }
- return cmpval;
+ 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;
+ */
+ 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;
+ */
+ 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;
+ */
+ }
+ return cmpval;
}
/** Test for equality. */
bool basic::is_equal(const basic & other) const
{
- unsigned hash_this = gethash();
- unsigned hash_other = other.gethash();
+ unsigned hash_this = gethash();
+ unsigned hash_other = other.gethash();
- if (hash_this!=hash_other) return false;
+ if (hash_this!=hash_other) return false;
- unsigned typeid_this = tinfo();
- unsigned typeid_other = other.tinfo();
+ unsigned typeid_this = tinfo();
+ unsigned typeid_other = other.tinfo();
- if (typeid_this!=typeid_other) return false;
+ if (typeid_this!=typeid_other) return false;
- GINAC_ASSERT(typeid(*this)==typeid(other));
+ GINAC_ASSERT(typeid(*this)==typeid(other));
- return is_equal_same_type(other);
+ return is_equal_same_type(other);
}
// protected
* @see basic::eval */
const basic & basic::hold(void) const
{
- return setflag(status_flags::evaluated);
+ return setflag(status_flags::evaluated);
}
void basic::ensure_if_modifiable(void) const
{
- if (refcount>1) {
- throw(std::runtime_error("cannot modify multiply referenced object"));
- }
+ if (refcount>1) {
+ throw(std::runtime_error("cannot modify multiply referenced object"));
+ }
}
//////////
* It is responsible for the reference counting. */
class basic
{
- GINAC_DECLARE_REGISTERED_CLASS(basic, void)
+ GINAC_DECLARE_REGISTERED_CLASS(basic, void)
- friend class ex;
+ friend class ex;
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- basic()
+ basic()
#ifdef INLINE_BASIC_CONSTRUCTORS
- : tinfo_key(TINFO_basic), flags(0), refcount(0)
- {
- }
+ : tinfo_key(TINFO_basic), flags(0), refcount(0)
+ {
+ }
#else
;
#endif // def INLINE_BASIC_CONSTRUCTORS
- virtual ~basic()
+ virtual ~basic()
#ifdef INLINE_BASIC_CONSTRUCTORS
- {
- destroy(0);
- GINAC_ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
- }
+ {
+ destroy(0);
+ GINAC_ASSERT((!(flags & status_flags::dynallocated))||(refcount==0));
+ }
#else
;
#endif // def INLINE_BASIC_CONSTRUCTORS
- basic(const basic & other)
+ basic(const basic & other)
#ifdef INLINE_BASIC_CONSTRUCTORS
- {
- copy(other);
- }
+ {
+ copy(other);
+ }
#else
;
#endif // def INLINE_BASIC_CONSTRUCTORS
- virtual const basic & operator=(const basic & other);
-
+ virtual const basic & operator=(const basic & other);
+
protected:
- 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)
+ 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)
- {
- }
+ : tinfo_key(ti), flags(0), refcount(0)
+ {
+ }
#else
;
#endif // def INLINE_BASIC_CONSTRUCTORS
- // functions overriding virtual functions from bases classes
- // none
-
- // new virtual functions which can be overridden by derived classes
+ // functions overriding virtual functions from bases classes
+ // none
+
+ // new virtual functions which can be overridden by derived classes
public: // only const functions please (may break reference counting)
- virtual basic * duplicate() const;
- virtual void print(std::ostream & os,unsigned upper_precedence = 0) const;
- virtual void printraw(std::ostream & os) const;
- virtual void printtree(std::ostream & os, unsigned indent) const;
- virtual void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
- virtual void dbgprint(void) const;
- virtual void dbgprinttree(void) const;
- virtual bool info(unsigned inf) const;
- virtual unsigned nops() const;
- virtual ex op(int i) const;
- virtual ex & let_op(int i);
- virtual ex operator[](const ex & index) const;
- virtual ex operator[](int i) const;
- virtual bool has(const ex & other) const;
- virtual int degree(const symbol & s) const;
- virtual int ldegree(const symbol & s) const;
- virtual ex coeff(const symbol & s, int n = 1) const;
- virtual ex collect(const symbol & s) const;
- virtual ex eval(int level = 0) const;
- virtual ex evalf(int level = 0) const;
- virtual ex series(const relational & r, int order, unsigned options = 0) const;
- virtual ex subs(const lst & ls, const lst & lr) const;
- virtual ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const;
- virtual ex to_rational(lst &repl_lst) const;
- virtual numeric integer_content(void) const;
- virtual ex smod(const numeric &xi) const;
- virtual numeric max_coefficient(void) const;
- virtual exvector get_indices(void) const;
- virtual ex simplify_ncmul(const exvector & v) const;
+ virtual basic * duplicate() const;
+ virtual void print(std::ostream & os,unsigned upper_precedence = 0) const;
+ virtual void printraw(std::ostream & os) const;
+ virtual void printtree(std::ostream & os, unsigned indent) const;
+ virtual void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence = 0) const;
+ virtual void dbgprint(void) const;
+ virtual void dbgprinttree(void) const;
+ virtual bool info(unsigned inf) const;
+ virtual unsigned nops() const;
+ virtual ex op(int i) const;
+ virtual ex & let_op(int i);
+ virtual ex operator[](const ex & index) const;
+ virtual ex operator[](int i) const;
+ virtual bool has(const ex & other) const;
+ virtual int degree(const symbol & s) const;
+ virtual int ldegree(const symbol & s) const;
+ virtual ex coeff(const symbol & s, int n = 1) const;
+ virtual ex collect(const symbol & s) const;
+ virtual ex eval(int level = 0) const;
+ virtual ex evalf(int level = 0) const;
+ virtual ex series(const relational & r, int order, unsigned options = 0) const;
+ virtual ex subs(const lst & ls, const lst & lr) const;
+ virtual ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const;
+ virtual ex to_rational(lst &repl_lst) const;
+ virtual numeric integer_content(void) const;
+ virtual ex smod(const numeric &xi) const;
+ virtual numeric max_coefficient(void) const;
+ virtual exvector get_indices(void) const;
+ virtual ex simplify_ncmul(const exvector & v) const;
protected: // non-const functions should be called from class ex only
- virtual ex derivative(const symbol & s) const;
- virtual int compare_same_type(const basic & other) const;
- virtual bool is_equal_same_type(const basic & other) const;
- 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;
-
- // non-virtual functions in this class
+ virtual ex derivative(const symbol & s) const;
+ virtual int compare_same_type(const basic & other) const;
+ virtual bool is_equal_same_type(const basic & other) const;
+ 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;
+
+ // non-virtual functions in this class
public:
- ex subs(const ex & e) const;
- ex diff(const symbol & s, unsigned nth=1) const;
- 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 tinfo(void) const {return tinfo_key;}
- const basic & setflag(unsigned f) const {flags |= f; return *this;}
- const basic & clearflag(unsigned f) const {flags &= ~f; return *this;}
+ ex subs(const ex & e) const;
+ ex diff(const symbol & s, unsigned nth=1) const;
+ 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 tinfo(void) const {return tinfo_key;}
+ const basic & setflag(unsigned f) const {flags |= f; return *this;}
+ const basic & clearflag(unsigned f) const {flags &= ~f; return *this;}
protected:
- void ensure_if_modifiable(void) const;
+ 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;
+ mutable unsigned flags;
+ mutable unsigned hashvalue;
+ static unsigned precedence;
+ static unsigned delta_indent;
private:
- unsigned refcount;
+ unsigned refcount;
};
// global constants
#ifndef NO_NAMESPACE_GINAC
#define is_of_type(OBJ,TYPE) \
- (dynamic_cast<TYPE *>(const_cast<GiNaC::basic *>(&OBJ))!=0)
+ (dynamic_cast<TYPE *>(const_cast<GiNaC::basic *>(&OBJ))!=0)
#define is_exactly_of_type(OBJ,TYPE) \
- ((OBJ).tinfo()==GiNaC::TINFO_##TYPE)
+ ((OBJ).tinfo()==GiNaC::TINFO_##TYPE)
#define is_ex_of_type(OBJ,TYPE) \
- (dynamic_cast<TYPE *>(const_cast<GiNaC::basic *>((OBJ).bp))!=0)
+ (dynamic_cast<TYPE *>(const_cast<GiNaC::basic *>((OBJ).bp))!=0)
#define is_ex_exactly_of_type(OBJ,TYPE) \
- ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE)
+ ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE)
#else // ndef NO_NAMESPACE_GINAC
#define is_of_type(OBJ,TYPE) \
- (dynamic_cast<TYPE *>(const_cast<basic *>(&OBJ))!=0)
+ (dynamic_cast<TYPE *>(const_cast<basic *>(&OBJ))!=0)
#define is_exactly_of_type(OBJ,TYPE) \
- ((OBJ).tinfo()==TINFO_##TYPE)
+ ((OBJ).tinfo()==TINFO_##TYPE)
#define is_ex_of_type(OBJ,TYPE) \
- (dynamic_cast<TYPE *>(const_cast<basic *>((OBJ).bp))!=0)
+ (dynamic_cast<TYPE *>(const_cast<basic *>((OBJ).bp))!=0)
#define is_ex_exactly_of_type(OBJ,TYPE) \
- ((*(OBJ).bp).tinfo()==TINFO_##TYPE)
+ ((*(OBJ).bp).tinfo()==TINFO_##TYPE)
#endif // ndef NO_NAMESPACE_GINAC
clifford::clifford()
{
- debugmsg("clifford default constructor",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
- name=autoname_prefix()+ToString(serial);
- tinfo_key=TINFO_clifford;
+ debugmsg("clifford default constructor",LOGLEVEL_CONSTRUCT);
+ serial=next_serial++;
+ name=autoname_prefix()+ToString(serial);
+ tinfo_key=TINFO_clifford;
}
clifford::~clifford()
{
- debugmsg("clifford destructor",LOGLEVEL_DESTRUCT);
- destroy(0);
+ debugmsg("clifford destructor",LOGLEVEL_DESTRUCT);
+ destroy(0);
}
clifford::clifford(const clifford & other)
{
- debugmsg("clifford copy constructor",LOGLEVEL_CONSTRUCT);
- copy (other);
+ debugmsg("clifford copy constructor",LOGLEVEL_CONSTRUCT);
+ copy (other);
}
const clifford & clifford::operator=(const clifford & other)
{
- debugmsg("clifford operator=",LOGLEVEL_ASSIGNMENT);
- if (this != &other) {
- destroy(1);
- copy(other);
- }
- return *this;
+ debugmsg("clifford operator=",LOGLEVEL_ASSIGNMENT);
+ if (this != &other) {
+ destroy(1);
+ copy(other);
+ }
+ return *this;
}
// protected
void clifford::copy(const clifford & other)
{
- indexed::copy(other);
- name=other.name;
- serial=other.serial;
+ indexed::copy(other);
+ name=other.name;
+ serial=other.serial;
}
void clifford::destroy(bool call_parent)
{
- if (call_parent) {
- indexed::destroy(call_parent);
- }
+ if (call_parent) {
+ indexed::destroy(call_parent);
+ }
}
//////////
clifford::clifford(const std::string & initname)
{
- debugmsg("clifford constructor from string",LOGLEVEL_CONSTRUCT);
- name=initname;
- serial=next_serial++;
- tinfo_key=TINFO_clifford;
+ debugmsg("clifford constructor from string",LOGLEVEL_CONSTRUCT);
+ name=initname;
+ serial=next_serial++;
+ tinfo_key=TINFO_clifford;
}
//////////
basic * clifford::duplicate() const
{
- debugmsg("clifford duplicate",LOGLEVEL_DUPLICATE);
- return new clifford(*this);
+ debugmsg("clifford duplicate",LOGLEVEL_DUPLICATE);
+ return new clifford(*this);
}
void clifford::printraw(std::ostream & os) const
{
- debugmsg("clifford printraw",LOGLEVEL_PRINT);
- os << "clifford(" << "name=" << name << ",serial=" << serial
- << ",indices=";
- printrawindices(os);
- os << ",hash=" << hashvalue << ",flags=" << flags << ")";
+ debugmsg("clifford printraw",LOGLEVEL_PRINT);
+ os << "clifford(" << "name=" << name << ",serial=" << serial
+ << ",indices=";
+ printrawindices(os);
+ os << ",hash=" << hashvalue << ",flags=" << flags << ")";
}
void clifford::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("clifford printtree",LOGLEVEL_PRINT);
- os << std::string(indent,' ') << name << " (clifford): "
- << "serial=" << serial << ","
- << seq.size() << "indices=";
- printtreeindices(os, indent);
- os << ", hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags << std::endl;
+ debugmsg("clifford printtree",LOGLEVEL_PRINT);
+ os << std::string(indent,' ') << name << " (clifford): "
+ << "serial=" << serial << ","
+ << seq.size() << "indices=";
+ printtreeindices(os, indent);
+ os << ", hash=" << hashvalue
+ << " (0x" << std::hex << hashvalue << std::dec << ")"
+ << ", flags=" << flags << std::endl;
}
void clifford::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("clifford print",LOGLEVEL_PRINT);
- os << name;
- printindices(os);
+ debugmsg("clifford print",LOGLEVEL_PRINT);
+ os << name;
+ printindices(os);
}
void clifford::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
{
- debugmsg("clifford print csrc",LOGLEVEL_PRINT);
- print(os,upper_precedence);
+ debugmsg("clifford print csrc",LOGLEVEL_PRINT);
+ print(os,upper_precedence);
}
bool clifford::info(unsigned inf) const
{
- return indexed::info(inf);
+ return indexed::info(inf);
}
// protected
int clifford::compare_same_type(const basic & other) const
{
- GINAC_ASSERT(other.tinfo() == TINFO_clifford);
- const clifford *o = static_cast<const clifford *>(&other);
- if (serial==o->serial) {
- return indexed::compare_same_type(other);
- }
- return serial < o->serial ? -1 : 1;
+ GINAC_ASSERT(other.tinfo() == TINFO_clifford);
+ const clifford *o = static_cast<const clifford *>(&other);
+ if (serial==o->serial) {
+ return indexed::compare_same_type(other);
+ }
+ return serial < o->serial ? -1 : 1;
}
ex clifford::simplify_ncmul(const exvector & v) const
{
- return simplified_ncmul(v);
+ return simplified_ncmul(v);
}
unsigned clifford::calchash(void) const
{
- hashvalue=golden_ratio_hash(golden_ratio_hash(0x55555556U ^
- golden_ratio_hash(tinfo_key) ^
- serial));
- setflag(status_flags::hash_calculated);
- return hashvalue;
+ hashvalue=golden_ratio_hash(golden_ratio_hash(0x55555556U ^
+ golden_ratio_hash(tinfo_key) ^
+ serial));
+ setflag(status_flags::hash_calculated);
+ return hashvalue;
}
//////////
void clifford::setname(const std::string & n)
{
- name = n;
+ name = n;
}
// private
std::string & clifford::autoname_prefix(void)
{
- static std::string * s = new std::string("clifford");
- return *s;
+ static std::string * s = new std::string("clifford");
+ return *s;
}
//////////
{
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- clifford();
- ~clifford();
- clifford(const clifford & other);
- const clifford & operator=(const clifford & other);
+ clifford();
+ ~clifford();
+ clifford(const clifford & other);
+ const clifford & operator=(const clifford & other);
protected:
- void copy(const clifford & other);
- void destroy(bool call_parent);
+ void copy(const clifford & other);
+ void destroy(bool call_parent);
- // other constructors
+ // other constructors
public:
- explicit clifford(const std::string & initname);
+ explicit clifford(const std::string & initname);
- // functions overriding virtual functions from base classes
+ // functions overriding virtual functions from base classes
public:
- basic * duplicate() const;
- void printraw(std::ostream & os) const;
- void printtree(std::ostream & os, unsigned indent) const;
- void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
- bool info(unsigned inf) const;
+ basic * duplicate() const;
+ void printraw(std::ostream & os) const;
+ void printtree(std::ostream & os, unsigned indent) const;
+ void print(std::ostream & os, unsigned upper_precedence=0) const;
+ void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+ bool info(unsigned inf) const;
protected:
- int compare_same_type(const basic & other) const;
- ex simplify_ncmul(const exvector & v) const;
- unsigned calchash(void) const;
-
- // new virtual functions which can be overridden by derived classes
- // none
-
- // non-virtual functions in this class
+ int compare_same_type(const basic & other) const;
+ ex simplify_ncmul(const exvector & v) const;
+ unsigned calchash(void) const;
+
+ // new virtual functions which can be overridden by derived classes
+ // none
+
+ // non-virtual functions in this class
public:
- void setname(const std::string & n);
+ void setname(const std::string & n);
private:
- std::string & autoname_prefix(void);
+ std::string & autoname_prefix(void);
// member variables
protected:
- std::string name;
- unsigned serial; // unique serial number for comparision
+ std::string name;
+ unsigned serial; // unique serial number for comparision
private:
- static unsigned next_serial;
+ static unsigned next_serial;
};
// global constants
color::color() : type(invalid), representation_label(0)
{
- debugmsg("color default constructor",LOGLEVEL_CONSTRUCT);
- tinfo_key=TINFO_color;
+ debugmsg("color default constructor",LOGLEVEL_CONSTRUCT);
+ tinfo_key=TINFO_color;
}
color::~color()
{
- debugmsg("color destructor",LOGLEVEL_DESTRUCT);
- destroy(0);
+ debugmsg("color destructor",LOGLEVEL_DESTRUCT);
+ destroy(0);
}
color::color(const color & other)
{
- debugmsg("color copy constructor",LOGLEVEL_CONSTRUCT);
- copy (other);
+ debugmsg("color copy constructor",LOGLEVEL_CONSTRUCT);
+ copy (other);
}
const color & color::operator=(const color & other)
{
- debugmsg("color operator=",LOGLEVEL_ASSIGNMENT);
- if (this != &other) {
- destroy(1);
- copy(other);
- }
- return *this;
+ debugmsg("color operator=",LOGLEVEL_ASSIGNMENT);
+ if (this != &other) {
+ destroy(1);
+ copy(other);
+ }
+ return *this;
}
// protected
void color::copy(const color & other)
{
- inherited::copy(other);
- type=other.type;
- representation_label=other.representation_label;
+ inherited::copy(other);
+ type=other.type;
+ representation_label=other.representation_label;
}
void color::destroy(bool call_parent)
{
- if (call_parent) {
- inherited::destroy(call_parent);
- }
+ if (call_parent) {
+ inherited::destroy(call_parent);
+ }
}
//////////
color::color(color_types const t, unsigned rl) : type(t), representation_label(rl)
{
- debugmsg("color constructor from color_types,unsigned",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
- tinfo_key=TINFO_color;
- GINAC_ASSERT(all_of_type_coloridx());
+ debugmsg("color constructor from color_types,unsigned",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
+ tinfo_key=TINFO_color;
+ GINAC_ASSERT(all_of_type_coloridx());
}
color::color(color_types const t, const ex & i1, unsigned rl)
- : inherited(i1), type(t), representation_label(rl)
+ : inherited(i1), type(t), representation_label(rl)
{
- debugmsg("color constructor from color_types,ex,unsigned",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
- tinfo_key=TINFO_color;
- GINAC_ASSERT(all_of_type_coloridx());
+ debugmsg("color constructor from color_types,ex,unsigned",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
+ tinfo_key=TINFO_color;
+ GINAC_ASSERT(all_of_type_coloridx());
}
color::color(color_types const t, const ex & i1, const ex & i2, unsigned rl)
- : inherited(i1,i2), type(t), representation_label(rl)
+ : inherited(i1,i2), type(t), representation_label(rl)
{
- debugmsg("color constructor from color_types,ex,ex,unsigned",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
- tinfo_key=TINFO_color;
- GINAC_ASSERT(all_of_type_coloridx());
+ debugmsg("color constructor from color_types,ex,ex,unsigned",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
+ tinfo_key=TINFO_color;
+ GINAC_ASSERT(all_of_type_coloridx());
}
color::color(color_types const t, const ex & i1, const ex & i2, const ex & i3,
- unsigned rl) : inherited(i1,i2,i3), type(t), representation_label(rl)
+ unsigned rl) : inherited(i1,i2,i3), type(t), representation_label(rl)
{
- debugmsg("color constructor from color_types,ex,ex,ex,unsigned",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
- tinfo_key=TINFO_color;
- GINAC_ASSERT(all_of_type_coloridx());
+ debugmsg("color constructor from color_types,ex,ex,ex,unsigned",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
+ tinfo_key=TINFO_color;
+ GINAC_ASSERT(all_of_type_coloridx());
}
color::color(color_types const t, const exvector & iv, unsigned rl)
- : inherited(iv), type(t), representation_label(rl)
+ : inherited(iv), type(t), representation_label(rl)
{
- debugmsg("color constructor from color_types,exvector,unsigned",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
- tinfo_key=TINFO_color;
- GINAC_ASSERT(all_of_type_coloridx());
+ debugmsg("color constructor from color_types,exvector,unsigned",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
+ tinfo_key=TINFO_color;
+ GINAC_ASSERT(all_of_type_coloridx());
}
color::color(color_types const t, exvector * ivp, unsigned rl)
- : inherited(ivp), type(t), representation_label(rl)
+ : inherited(ivp), type(t), representation_label(rl)
{
- debugmsg("color constructor from color_types,exvector *,unsigned",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
- tinfo_key=TINFO_color;
- GINAC_ASSERT(all_of_type_coloridx());
+ debugmsg("color constructor from color_types,exvector *,unsigned",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(representation_label<MAX_REPRESENTATION_LABELS);
+ tinfo_key=TINFO_color;
+ GINAC_ASSERT(all_of_type_coloridx());
}
//////////
/** Construct object from archive_node. */
color::color(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
{
- debugmsg("color constructor from archive_node", LOGLEVEL_CONSTRUCT);
- unsigned int ty;
- if (!(n.find_unsigned("type", ty)))
- throw (std::runtime_error("unknown color type in archive"));
- type = (color_types)ty;
- if (!(n.find_unsigned("representation", representation_label)))
- throw (std::runtime_error("unknown color representation label in archive"));
+ debugmsg("color constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ unsigned int ty;
+ if (!(n.find_unsigned("type", ty)))
+ throw (std::runtime_error("unknown color type in archive"));
+ type = (color_types)ty;
+ if (!(n.find_unsigned("representation", representation_label)))
+ throw (std::runtime_error("unknown color representation label in archive"));
}
/** Unarchive the object. */
ex color::unarchive(const archive_node &n, const lst &sym_lst)
{
- return (new color(n, sym_lst))->setflag(status_flags::dynallocated);
+ return (new color(n, sym_lst))->setflag(status_flags::dynallocated);
}
/** Archive the object. */
void color::archive(archive_node &n) const
{
- inherited::archive(n);
- n.add_unsigned("type", type);
- n.add_unsigned("representation", representation_label);
+ inherited::archive(n);
+ n.add_unsigned("type", type);
+ n.add_unsigned("representation", representation_label);
}
//////////
basic * color::duplicate() const
{
- debugmsg("color duplicate",LOGLEVEL_DUPLICATE);
- return new color(*this);
+ debugmsg("color duplicate",LOGLEVEL_DUPLICATE);
+ return new color(*this);
}
void color::printraw(std::ostream & os) const
{
- debugmsg("color printraw",LOGLEVEL_PRINT);
- os << "color(type=" << (unsigned)type
- << ",representation_label=" << representation_label
- << ",indices=";
- printrawindices(os);
- os << ",hash=" << hashvalue << ",flags=" << flags << ")";
+ debugmsg("color printraw",LOGLEVEL_PRINT);
+ os << "color(type=" << (unsigned)type
+ << ",representation_label=" << representation_label
+ << ",indices=";
+ printrawindices(os);
+ os << ",hash=" << hashvalue << ",flags=" << flags << ")";
}
void color::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("color printtree",LOGLEVEL_PRINT);
- os << std::string(indent,' ') << "color object: "
- << "type=" << (unsigned)type
- << ",representation_label=" << representation_label << ", ";
- os << seq.size() << " indices" << std::endl;
- printtreeindices(os,indent);
- os << std::string(indent,' ') << "hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags << std::endl;
+ debugmsg("color printtree",LOGLEVEL_PRINT);
+ os << std::string(indent,' ') << "color object: "
+ << "type=" << (unsigned)type
+ << ",representation_label=" << representation_label << ", ";
+ os << seq.size() << " indices" << std::endl;
+ printtreeindices(os,indent);
+ os << std::string(indent,' ') << "hash=" << hashvalue
+ << " (0x" << std::hex << hashvalue << std::dec << ")"
+ << ", flags=" << flags << std::endl;
}
void color::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("color print",LOGLEVEL_PRINT);
- switch (type) {
- case color_T:
- os << "T";
- if (representation_label!=0) {
- os << "^(" << representation_label << ")";
- }
- break;
- case color_f:
- os << "f";
- break;
- case color_d:
- os << "d";
- break;
- case color_delta8:
- os << "delta8";
- break;
- case color_ONE:
- os << "color_ONE";
- break;
- case invalid:
- default:
- os << "INVALID_COLOR_OBJECT";
- break;
- }
- printindices(os);
+ debugmsg("color print",LOGLEVEL_PRINT);
+ switch (type) {
+ case color_T:
+ os << "T";
+ if (representation_label!=0) {
+ os << "^(" << representation_label << ")";
+ }
+ break;
+ case color_f:
+ os << "f";
+ break;
+ case color_d:
+ os << "d";
+ break;
+ case color_delta8:
+ os << "delta8";
+ break;
+ case color_ONE:
+ os << "color_ONE";
+ break;
+ case invalid:
+ default:
+ os << "INVALID_COLOR_OBJECT";
+ break;
+ }
+ printindices(os);
}
void color::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
{
- debugmsg("color print csrc",LOGLEVEL_PRINT);
- print(os,upper_precedence);
+ debugmsg("color print csrc",LOGLEVEL_PRINT);
+ print(os,upper_precedence);
}
bool color::info(unsigned inf) const
{
- return inherited::info(inf);
+ return inherited::info(inf);
}
#define CMPINDICES(A,B,C) ((idx1.get_value()==(A))&&(idx2.get_value()==(B))&&(idx3.get_value()==(C)))
ex color::eval(int level) const
{
- // canonicalize indices
-
- bool antisymmetric=false;
-
- switch (type) {
- case color_f:
- antisymmetric=true; // no break here!
- case color_d:
- case color_delta8:
- {
- exvector iv=seq;
- int sig=canonicalize_indices(iv,antisymmetric);
- if (sig!=INT_MAX) {
- // something has changed while sorting indices, more evaluations later
- if (sig==0) return _ex0();
- return ex(sig)*color(type,iv,representation_label);
- }
- }
- break;
- default:
- // nothing to canonicalize
- break;
- }
-
- switch (type) {
- case color_delta8:
- {
- GINAC_ASSERT(seq.size()==2);
- const coloridx & idx1=ex_to_coloridx(seq[0]);
- const coloridx & idx2=ex_to_coloridx(seq[1]);
-
- // check for delta8_{a,a} where a is a symbolic index, replace by 8
- if ((idx1.is_symbolic())&&(idx1.is_equal_same_type(idx2))) {
- return ex(COLOR_EIGHT);
- }
-
- // check for delta8_{a,b} where a and b are numeric indices, replace by 0 or 1
- if ((!idx1.is_symbolic())&&(!idx2.is_symbolic())) {
- if ((idx1.get_value()!=idx2.get_value())) {
- return _ex1();
- } else {
- return _ex0();
- }
- }
+ // canonicalize indices
+
+ bool antisymmetric=false;
+
+ switch (type) {
+ case color_f:
+ antisymmetric=true; // no break here!
+ case color_d:
+ case color_delta8:
+ {
+ exvector iv=seq;
+ int sig=canonicalize_indices(iv,antisymmetric);
+ if (sig!=INT_MAX) {
+ // something has changed while sorting indices, more evaluations later
+ if (sig==0) return _ex0();
+ return ex(sig)*color(type,iv,representation_label);
+ }
+ }
+ break;
+ default:
+ // nothing to canonicalize
+ break;
+ }
+
+ switch (type) {
+ case color_delta8:
+ {
+ GINAC_ASSERT(seq.size()==2);
+ const coloridx & idx1=ex_to_coloridx(seq[0]);
+ const coloridx & idx2=ex_to_coloridx(seq[1]);
+
+ // check for delta8_{a,a} where a is a symbolic index, replace by 8
+ if ((idx1.is_symbolic())&&(idx1.is_equal_same_type(idx2))) {
+ return ex(COLOR_EIGHT);
+ }
+
+ // check for delta8_{a,b} where a and b are numeric indices, replace by 0 or 1
+ if ((!idx1.is_symbolic())&&(!idx2.is_symbolic())) {
+ if ((idx1.get_value()!=idx2.get_value())) {
+ return _ex1();
+ } else {
+ return _ex0();
+ }
+ }
+ }
+ break;
+ case color_d:
+ // check for d_{a,a,c} (=0) when a is symbolic
+ {
+ GINAC_ASSERT(seq.size()==3);
+ const coloridx & idx1=ex_to_coloridx(seq[0]);
+ const coloridx & idx2=ex_to_coloridx(seq[1]);
+ const coloridx & idx3=ex_to_coloridx(seq[2]);
+
+ if (idx1.is_equal_same_type(idx2) && idx1.is_symbolic()) {
+ return _ex0();
+ } else if (idx2.is_equal_same_type(idx3) && idx2.is_symbolic()) {
+ return _ex0();
+ }
+
+ // check for three numeric indices
+ if (!(idx1.is_symbolic()||idx2.is_symbolic()||idx3.is_symbolic())) {
+ GINAC_ASSERT(idx1.get_value()<=idx2.get_value());
+ GINAC_ASSERT(idx2.get_value()<=idx3.get_value());
+ if (CMPINDICES(1,4,6)||CMPINDICES(1,5,7)||CMPINDICES(2,5,6)||
+ CMPINDICES(3,4,4)||CMPINDICES(3,5,5)) {
+ return _ex1_2();
+ } else if (CMPINDICES(2,4,7)||CMPINDICES(3,6,6)||CMPINDICES(3,7,7)) {
+ return -_ex1_2();
+ } else if (CMPINDICES(1,1,8)||CMPINDICES(2,2,8)||CMPINDICES(3,3,8)) {
+ return 1/sqrt(numeric(3));
+ } else if (CMPINDICES(8,8,8)) {
+ return -1/sqrt(numeric(3));
+ } else if (CMPINDICES(4,4,8)||CMPINDICES(5,5,8)||CMPINDICES(6,6,8)||CMPINDICES(7,7,8)) {
+ return -1/(2*sqrt(numeric(3)));
+ }
+ return _ex0();
+ }
+ }
+ break;
+ case color_f:
+ {
+ GINAC_ASSERT(seq.size()==3);
+ const coloridx & idx1=ex_to_coloridx(seq[0]);
+ const coloridx & idx2=ex_to_coloridx(seq[1]);
+ const coloridx & idx3=ex_to_coloridx(seq[2]);
+
+ // check for three numeric indices
+ if (!(idx1.is_symbolic()||idx2.is_symbolic()||idx3.is_symbolic())) {
+ GINAC_ASSERT(idx1.get_value()<=idx2.get_value());
+ GINAC_ASSERT(idx2.get_value()<=idx3.get_value());
+ if (CMPINDICES(1,2,3)) {
+ return _ex1();
+ } else if (CMPINDICES(1,4,7)||CMPINDICES(2,4,6)||
+ CMPINDICES(2,5,7)||CMPINDICES(3,4,5)) {
+ return _ex1_2();
+ } else if (CMPINDICES(1,5,6)||CMPINDICES(3,6,7)) {
+ return -_ex1_2();
+ } else if (CMPINDICES(4,5,8)||CMPINDICES(6,7,8)) {
+ return sqrt(numeric(3))/2;
+ } else if (CMPINDICES(8,8,8)) {
+ return -1/sqrt(numeric(3));
+ } else if (CMPINDICES(4,4,8)||CMPINDICES(5,5,8)||CMPINDICES(6,6,8)||CMPINDICES(7,7,8)) {
+ return -1/(2*sqrt(numeric(3)));
+ }
+ return _ex0();
+ }
+ break;
+ }
+ default:
+ // nothing to evaluate
+ break;
}
- break;
- case color_d:
- // check for d_{a,a,c} (=0) when a is symbolic
- {
- GINAC_ASSERT(seq.size()==3);
- const coloridx & idx1=ex_to_coloridx(seq[0]);
- const coloridx & idx2=ex_to_coloridx(seq[1]);
- const coloridx & idx3=ex_to_coloridx(seq[2]);
-
- if (idx1.is_equal_same_type(idx2) && idx1.is_symbolic()) {
- return _ex0();
- } else if (idx2.is_equal_same_type(idx3) && idx2.is_symbolic()) {
- return _ex0();
- }
-
- // check for three numeric indices
- if (!(idx1.is_symbolic()||idx2.is_symbolic()||idx3.is_symbolic())) {
- GINAC_ASSERT(idx1.get_value()<=idx2.get_value());
- GINAC_ASSERT(idx2.get_value()<=idx3.get_value());
- if (CMPINDICES(1,4,6)||CMPINDICES(1,5,7)||CMPINDICES(2,5,6)||
- CMPINDICES(3,4,4)||CMPINDICES(3,5,5)) {
- return _ex1_2();
- } else if (CMPINDICES(2,4,7)||CMPINDICES(3,6,6)||CMPINDICES(3,7,7)) {
- return -_ex1_2();
- } else if (CMPINDICES(1,1,8)||CMPINDICES(2,2,8)||CMPINDICES(3,3,8)) {
- return 1/sqrt(numeric(3));
- } else if (CMPINDICES(8,8,8)) {
- return -1/sqrt(numeric(3));
- } else if (CMPINDICES(4,4,8)||CMPINDICES(5,5,8)||CMPINDICES(6,6,8)||CMPINDICES(7,7,8)) {
- return -1/(2*sqrt(numeric(3)));
- }
- return _ex0();
- }
- }
- break;
- case color_f:
- {
- GINAC_ASSERT(seq.size()==3);
- const coloridx & idx1=ex_to_coloridx(seq[0]);
- const coloridx & idx2=ex_to_coloridx(seq[1]);
- const coloridx & idx3=ex_to_coloridx(seq[2]);
-
- // check for three numeric indices
- if (!(idx1.is_symbolic()||idx2.is_symbolic()||idx3.is_symbolic())) {
- GINAC_ASSERT(idx1.get_value()<=idx2.get_value());
- GINAC_ASSERT(idx2.get_value()<=idx3.get_value());
- if (CMPINDICES(1,2,3)) {
- return _ex1();
- } else if (CMPINDICES(1,4,7)||CMPINDICES(2,4,6)||
- CMPINDICES(2,5,7)||CMPINDICES(3,4,5)) {
- return _ex1_2();
- } else if (CMPINDICES(1,5,6)||CMPINDICES(3,6,7)) {
- return -_ex1_2();
- } else if (CMPINDICES(4,5,8)||CMPINDICES(6,7,8)) {
- return sqrt(numeric(3))/2;
- } else if (CMPINDICES(8,8,8)) {
- return -1/sqrt(numeric(3));
- } else if (CMPINDICES(4,4,8)||CMPINDICES(5,5,8)||CMPINDICES(6,6,8)||CMPINDICES(7,7,8)) {
- return -1/(2*sqrt(numeric(3)));
- }
- return _ex0();
- }
- break;
- }
- default:
- // nothing to evaluate
- break;
- }
-
- return this->hold();
-}
-
+
+ return this->hold();
+}
+
// protected
int color::compare_same_type(const basic & other) const
{
- GINAC_ASSERT(other.tinfo() == TINFO_color);
- const color *o = static_cast<const color *>(&other);
- if (type==o->type) {
- if (representation_label==o->representation_label) {
- return inherited::compare_same_type(other);
- }
- return representation_label < o->representation_label ? -1 : 1;
- }
- return type < o->type ? -1 : 1;
+ GINAC_ASSERT(other.tinfo() == TINFO_color);
+ const color *o = static_cast<const color *>(&other);
+ if (type==o->type) {
+ if (representation_label==o->representation_label) {
+ return inherited::compare_same_type(other);
+ }
+ return representation_label < o->representation_label ? -1 : 1;
+ }
+ return type < o->type ? -1 : 1;
}
bool color::is_equal_same_type(const basic & other) const
{
- GINAC_ASSERT(other.tinfo() == TINFO_color);
- const color *o = static_cast<const color *>(&other);
- if (type!=o->type) return false;
- if (representation_label!=o->representation_label) return false;
- return inherited::is_equal_same_type(other);
+ GINAC_ASSERT(other.tinfo() == TINFO_color);
+ const color *o = static_cast<const color *>(&other);
+ if (type!=o->type) return false;
+ if (representation_label!=o->representation_label) return false;
+ return inherited::is_equal_same_type(other);
}
#include <iostream>
ex color::simplify_ncmul(const exvector & v) const
{
- // simplifications: contract delta8_{a,b} where possible
- // sort delta8,f,d,T(rl=0),T(rl=1),...,ONE(rl=0),ONE(rl=1),...
- // remove superfluous ONEs
-
- // contract indices of delta8_{a,b} if they are different and symbolic
-
- exvector v_contracted=v;
- unsigned replacements;
- bool something_changed=false;
-
- exvector::iterator it=v_contracted.begin();
- while (it!=v_contracted.end()) {
- // process only delta8 objects
- if (is_ex_exactly_of_type(*it,color) && (ex_to_color(*it).type==color_delta8)) {
- color & d8=ex_to_nonconst_color(*it);
- GINAC_ASSERT(d8.seq.size()==2);
- const coloridx & first_idx=ex_to_coloridx(d8.seq[0]);
- const coloridx & second_idx=ex_to_coloridx(d8.seq[1]);
- // delta8_{a,a} should have been contracted in color::eval()
- GINAC_ASSERT((!first_idx.is_equal(second_idx))||(!first_idx.is_symbolic()));
- ex saved_delta8=*it; // save to restore it later
-
- // try to contract first index
- replacements=1;
- if (first_idx.is_symbolic()) {
- replacements = subs_index_in_exvector(v_contracted,first_idx,second_idx);
- if (replacements==1) {
- // not contracted except in itself, restore delta8 object
- *it=saved_delta8;
- } else {
- // a contracted index should occur exactly twice
- GINAC_ASSERT(replacements==2);
- *it=_ex1();
- something_changed=true;
- }
- }
-
- // try second index only if first was not contracted
- if ((replacements==1)&&(second_idx.is_symbolic())) {
- // first index not contracted, *it is guaranteed to be the original delta8 object
- replacements = subs_index_in_exvector(v_contracted,second_idx,first_idx);
- if (replacements==1) {
- // not contracted except in itself, restore delta8 object
- *it=saved_delta8;
- } else {
- // a contracted index should occur exactly twice
- GINAC_ASSERT(replacements==2);
- *it=_ex1();
- something_changed=true;
- }
- }
- }
- ++it;
- }
-
- if (something_changed) {
- // do more simplifications later
- return nonsimplified_ncmul(v_contracted);
- }
-
- // there were no indices to contract
- // sort delta8,f,d,T(rl=0),T(rl=1),...,ONE(rl=0),ONE(rl=1),...,unknown
- // (if there is at least one unknown object, all Ts will be unknown to not change the order)
-
- exvector delta8vec;
- exvector fvec;
- exvector dvec;
- exvectorvector Tvecs;
- Tvecs.resize(MAX_REPRESENTATION_LABELS);
- exvectorvector ONEvecs;
- ONEvecs.resize(MAX_REPRESENTATION_LABELS);
- exvector unknownvec;
-
- split_color_string_in_parts(v,delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec);
-
- // d_{a,k,l} f_{b,k,l}=0 (includes case a=b)
- if ((dvec.size()>=1)&&(fvec.size()>=1)) {
- for (exvector::iterator it1=dvec.begin(); it1!=dvec.end(); ++it1) {
- for (exvector::iterator it2=fvec.begin(); it2!=fvec.end(); ++it2) {
- GINAC_ASSERT(is_ex_exactly_of_type(*it1,color));
- GINAC_ASSERT(is_ex_exactly_of_type(*it2,color));
- const color & col1=ex_to_color(*it1);
- const color & col2=ex_to_color(*it2);
- exvector iv_intersect=idx_intersect(col1.seq,col2.seq);
- if (iv_intersect.size()>=2) return _ex0();
- }
- }
- }
-
- // d_{a,k,l} d_{b,k,l}=5/3 delta8_{a,b} (includes case a=b)
- if (dvec.size()>=2) {
- for (exvector::iterator it1=dvec.begin(); it1!=dvec.end()-1; ++it1) {
- for (exvector::iterator it2=it1+1; it2!=dvec.end(); ++it2) {
- GINAC_ASSERT(is_ex_exactly_of_type(*it1,color));
- GINAC_ASSERT(is_ex_exactly_of_type(*it2,color));
- const color & col1=ex_to_color(*it1);
- const color & col2=ex_to_color(*it2);
- exvector iv_intersect=idx_intersect(col1.seq,col2.seq);
- if (iv_intersect.size()>=2) {
- if (iv_intersect.size()==3) {
- *it1=numeric(40)/numeric(3);
- *it2=_ex1();
- } else {
- int sig1, sig2; // unimportant, since symmetric
- ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,false,&sig1);
- ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,false,&sig2);
- *it1=numeric(5)/numeric(3)*color(color_delta8,idx1,idx2);
- *it2=_ex1();
- }
- return nonsimplified_ncmul(recombine_color_string(
- delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
- }
- }
- }
- }
-
- // f_{a,k,l} f_{b,k,l}=3 delta8_{a,b} (includes case a=b)
- if (fvec.size()>=2) {
- for (exvector::iterator it1=fvec.begin(); it1!=fvec.end()-1; ++it1) {
- for (exvector::iterator it2=it1+1; it2!=fvec.end(); ++it2) {
- GINAC_ASSERT(is_ex_exactly_of_type(*it1,color));
- GINAC_ASSERT(is_ex_exactly_of_type(*it2,color));
- const color & col1=ex_to_color(*it1);
- const color & col2=ex_to_color(*it2);
- exvector iv_intersect=idx_intersect(col1.seq,col2.seq);
- if (iv_intersect.size()>=2) {
- if (iv_intersect.size()==3) {
- *it1=numeric(24);
- *it2=_ex1();
- } else {
- int sig1, sig2;
- ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,true,&sig1);
- ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,true,&sig2);
- *it1=numeric(sig1*sig2*5)/numeric(3)*color(color_delta8,idx1,idx2);
- *it2=_ex1();
- }
- return nonsimplified_ncmul(recombine_color_string(
- delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
- }
- }
- }
- }
-
- // d_{a,b,c} T_b T_c = 5/6 T_a
- // f_{a,b,c} T_b T_c = 3/2 I T_a
- for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
- if ((Tvecs[rl].size()>=2)&&((dvec.size()>=1)||(fvec.size()>=1))) {
- for (exvector::iterator it1=Tvecs[rl].begin(); it1!=Tvecs[rl].end()-1; ++it1) {
- exvector iv;
- GINAC_ASSERT(is_ex_exactly_of_type(*it1,color)&&ex_to_color(*it1).type==color_T);
- GINAC_ASSERT(is_ex_exactly_of_type(*(it1+1),color)&&ex_to_color(*(it1+1)).type==color_T);
- iv.push_back(ex_to_color(*it1).seq[0]);
- iv.push_back(ex_to_color(*(it1+1)).seq[0]);
-
- // d_{a,b,c} T_b T_c = 5/6 T_a
- for (exvector::iterator it2=dvec.begin(); it2!=dvec.end(); ++it2) {
- GINAC_ASSERT(is_ex_exactly_of_type(*it2,color)&&ex_to_color(*it2).type==color_d);
- const color & dref=ex_to_color(*it2);
- exvector iv_intersect=idx_intersect(dref.seq,iv);
- if (iv_intersect.size()==2) {
- int sig; // unimportant, since symmetric
- ex free_idx=permute_free_index_to_front(dref.seq,iv,false,&sig);
- *it1=color(color_T,free_idx,rl);
- *(it1+1)=color(color_ONE,rl);
- *it2=numeric(5)/numeric(6);
- return nonsimplified_ncmul(recombine_color_string(
- delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
- }
- }
-
- // f_{a,b,c} T_b T_c = 3/2 I T_a
- for (exvector::iterator it2=fvec.begin(); it2!=fvec.end(); ++it2) {
- GINAC_ASSERT(is_ex_exactly_of_type(*it2,color)&&ex_to_color(*it2).type==color_f);
- const color & fref=ex_to_color(*it2);
- exvector iv_intersect=idx_intersect(fref.seq,iv);
- if (iv_intersect.size()==2) {
- int sig;
- ex free_idx=permute_free_index_to_front(fref.seq,iv,true,&sig);
- *it1=color(color_T,free_idx,rl);
- *(it1+1)=color(color_ONE,rl);
- *it2=numeric(sig*3)/numeric(2)*I;
- return nonsimplified_ncmul(recombine_color_string(
- delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
- }
- }
- }
- }
- }
-
- // clear all ONEs when there is at least one corresponding color_T
- // in this representation, retain one ONE otherwise
- for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
- if (Tvecs[rl].size()!=0) {
- ONEvecs[rl].clear();
- } else if (ONEvecs[rl].size()!=0) {
- ONEvecs[rl].clear();
- ONEvecs[rl].push_back(color(color_ONE,rl));
- }
- }
-
- // return a sorted vector
- return simplified_ncmul(recombine_color_string(delta8vec,fvec,dvec,Tvecs,
- ONEvecs,unknownvec));
+ // simplifications: contract delta8_{a,b} where possible
+ // sort delta8,f,d,T(rl=0),T(rl=1),...,ONE(rl=0),ONE(rl=1),...
+ // remove superfluous ONEs
+
+ // contract indices of delta8_{a,b} if they are different and symbolic
+
+ exvector v_contracted=v;
+ unsigned replacements;
+ bool something_changed=false;
+
+ exvector::iterator it=v_contracted.begin();
+ while (it!=v_contracted.end()) {
+ // process only delta8 objects
+ if (is_ex_exactly_of_type(*it,color) && (ex_to_color(*it).type==color_delta8)) {
+ color & d8=ex_to_nonconst_color(*it);
+ GINAC_ASSERT(d8.seq.size()==2);
+ const coloridx & first_idx=ex_to_coloridx(d8.seq[0]);
+ const coloridx & second_idx=ex_to_coloridx(d8.seq[1]);
+ // delta8_{a,a} should have been contracted in color::eval()
+ GINAC_ASSERT((!first_idx.is_equal(second_idx))||(!first_idx.is_symbolic()));
+ ex saved_delta8=*it; // save to restore it later
+
+ // try to contract first index
+ replacements=1;
+ if (first_idx.is_symbolic()) {
+ replacements = subs_index_in_exvector(v_contracted,first_idx,second_idx);
+ if (replacements==1) {
+ // not contracted except in itself, restore delta8 object
+ *it=saved_delta8;
+ } else {
+ // a contracted index should occur exactly twice
+ GINAC_ASSERT(replacements==2);
+ *it=_ex1();
+ something_changed=true;
+ }
+ }
+
+ // try second index only if first was not contracted
+ if ((replacements==1)&&(second_idx.is_symbolic())) {
+ // first index not contracted, *it is guaranteed to be the original delta8 object
+ replacements = subs_index_in_exvector(v_contracted,second_idx,first_idx);
+ if (replacements==1) {
+ // not contracted except in itself, restore delta8 object
+ *it=saved_delta8;
+ } else {
+ // a contracted index should occur exactly twice
+ GINAC_ASSERT(replacements==2);
+ *it=_ex1();
+ something_changed=true;
+ }
+ }
+ }
+ ++it;
+ }
+
+ if (something_changed) {
+ // do more simplifications later
+ return nonsimplified_ncmul(v_contracted);
+ }
+
+ // there were no indices to contract
+ // sort delta8,f,d,T(rl=0),T(rl=1),...,ONE(rl=0),ONE(rl=1),...,unknown
+ // (if there is at least one unknown object, all Ts will be unknown to not change the order)
+
+ exvector delta8vec;
+ exvector fvec;
+ exvector dvec;
+ exvectorvector Tvecs;
+ Tvecs.resize(MAX_REPRESENTATION_LABELS);
+ exvectorvector ONEvecs;
+ ONEvecs.resize(MAX_REPRESENTATION_LABELS);
+ exvector unknownvec;
+
+ split_color_string_in_parts(v,delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec);
+
+ // d_{a,k,l} f_{b,k,l}=0 (includes case a=b)
+ if ((dvec.size()>=1)&&(fvec.size()>=1)) {
+ for (exvector::iterator it1=dvec.begin(); it1!=dvec.end(); ++it1) {
+ for (exvector::iterator it2=fvec.begin(); it2!=fvec.end(); ++it2) {
+ GINAC_ASSERT(is_ex_exactly_of_type(*it1,color));
+ GINAC_ASSERT(is_ex_exactly_of_type(*it2,color));
+ const color & col1=ex_to_color(*it1);
+ const color & col2=ex_to_color(*it2);
+ exvector iv_intersect=idx_intersect(col1.seq,col2.seq);
+ if (iv_intersect.size()>=2) return _ex0();
+ }
+ }
+ }
+
+ // d_{a,k,l} d_{b,k,l}=5/3 delta8_{a,b} (includes case a=b)
+ if (dvec.size()>=2) {
+ for (exvector::iterator it1=dvec.begin(); it1!=dvec.end()-1; ++it1) {
+ for (exvector::iterator it2=it1+1; it2!=dvec.end(); ++it2) {
+ GINAC_ASSERT(is_ex_exactly_of_type(*it1,color));
+ GINAC_ASSERT(is_ex_exactly_of_type(*it2,color));
+ const color & col1=ex_to_color(*it1);
+ const color & col2=ex_to_color(*it2);
+ exvector iv_intersect=idx_intersect(col1.seq,col2.seq);
+ if (iv_intersect.size()>=2) {
+ if (iv_intersect.size()==3) {
+ *it1=numeric(40)/numeric(3);
+ *it2=_ex1();
+ } else {
+ int sig1, sig2; // unimportant, since symmetric
+ ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,false,&sig1);
+ ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,false,&sig2);
+ *it1=numeric(5)/numeric(3)*color(color_delta8,idx1,idx2);
+ *it2=_ex1();
+ }
+ return nonsimplified_ncmul(recombine_color_string(
+ delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
+ }
+ }
+ }
+ }
+
+ // f_{a,k,l} f_{b,k,l}=3 delta8_{a,b} (includes case a=b)
+ if (fvec.size()>=2) {
+ for (exvector::iterator it1=fvec.begin(); it1!=fvec.end()-1; ++it1) {
+ for (exvector::iterator it2=it1+1; it2!=fvec.end(); ++it2) {
+ GINAC_ASSERT(is_ex_exactly_of_type(*it1,color));
+ GINAC_ASSERT(is_ex_exactly_of_type(*it2,color));
+ const color & col1=ex_to_color(*it1);
+ const color & col2=ex_to_color(*it2);
+ exvector iv_intersect=idx_intersect(col1.seq,col2.seq);
+ if (iv_intersect.size()>=2) {
+ if (iv_intersect.size()==3) {
+ *it1=numeric(24);
+ *it2=_ex1();
+ } else {
+ int sig1, sig2;
+ ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,true,&sig1);
+ ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,true,&sig2);
+ *it1=numeric(sig1*sig2*5)/numeric(3)*color(color_delta8,idx1,idx2);
+ *it2=_ex1();
+ }
+ return nonsimplified_ncmul(recombine_color_string(
+ delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
+ }
+ }
+ }
+ }
+
+ // d_{a,b,c} T_b T_c = 5/6 T_a
+ // f_{a,b,c} T_b T_c = 3/2 I T_a
+ for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
+ if ((Tvecs[rl].size()>=2)&&((dvec.size()>=1)||(fvec.size()>=1))) {
+ for (exvector::iterator it1=Tvecs[rl].begin(); it1!=Tvecs[rl].end()-1; ++it1) {
+ exvector iv;
+ GINAC_ASSERT(is_ex_exactly_of_type(*it1,color)&&ex_to_color(*it1).type==color_T);
+ GINAC_ASSERT(is_ex_exactly_of_type(*(it1+1),color)&&ex_to_color(*(it1+1)).type==color_T);
+ iv.push_back(ex_to_color(*it1).seq[0]);
+ iv.push_back(ex_to_color(*(it1+1)).seq[0]);
+
+ // d_{a,b,c} T_b T_c = 5/6 T_a
+ for (exvector::iterator it2=dvec.begin(); it2!=dvec.end(); ++it2) {
+ GINAC_ASSERT(is_ex_exactly_of_type(*it2,color)&&ex_to_color(*it2).type==color_d);
+ const color & dref=ex_to_color(*it2);
+ exvector iv_intersect=idx_intersect(dref.seq,iv);
+ if (iv_intersect.size()==2) {
+ int sig; // unimportant, since symmetric
+ ex free_idx=permute_free_index_to_front(dref.seq,iv,false,&sig);
+ *it1=color(color_T,free_idx,rl);
+ *(it1+1)=color(color_ONE,rl);
+ *it2=numeric(5)/numeric(6);
+ return nonsimplified_ncmul(recombine_color_string(
+ delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
+ }
+ }
+
+ // f_{a,b,c} T_b T_c = 3/2 I T_a
+ for (exvector::iterator it2=fvec.begin(); it2!=fvec.end(); ++it2) {
+ GINAC_ASSERT(is_ex_exactly_of_type(*it2,color)&&ex_to_color(*it2).type==color_f);
+ const color & fref=ex_to_color(*it2);
+ exvector iv_intersect=idx_intersect(fref.seq,iv);
+ if (iv_intersect.size()==2) {
+ int sig;
+ ex free_idx=permute_free_index_to_front(fref.seq,iv,true,&sig);
+ *it1=color(color_T,free_idx,rl);
+ *(it1+1)=color(color_ONE,rl);
+ *it2=numeric(sig*3)/numeric(2)*I;
+ return nonsimplified_ncmul(recombine_color_string(
+ delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
+ }
+ }
+ }
+ }
+ }
+
+ // clear all ONEs when there is at least one corresponding color_T
+ // in this representation, retain one ONE otherwise
+ for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
+ if (Tvecs[rl].size()!=0) {
+ ONEvecs[rl].clear();
+ } else if (ONEvecs[rl].size()!=0) {
+ ONEvecs[rl].clear();
+ ONEvecs[rl].push_back(color(color_ONE,rl));
+ }
+ }
+
+ // return a sorted vector
+ return simplified_ncmul(recombine_color_string(delta8vec,fvec,dvec,Tvecs,
+ ONEvecs,unknownvec));
}
ex color::thisexprseq(const exvector & v) const
{
- return color(type,v,representation_label);
+ return color(type,v,representation_label);
}
ex color::thisexprseq(exvector * vp) const
{
- return color(type,vp,representation_label);
+ return color(type,vp,representation_label);
}
bool color::all_of_type_coloridx(void) const
{
- // used only inside of ASSERTs
- for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- if (!is_ex_of_type(*cit,coloridx)) return false;
- }
- return true;
+ // used only inside of ASSERTs
+ for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
+ if (!is_ex_of_type(*cit,coloridx)) return false;
+ }
+ return true;
}
//////////
color color_ONE(unsigned rl)
{
- return color(color::color_ONE,rl);
+ return color(color::color_ONE,rl);
}
color color_T(const ex & a, unsigned rl)
{
- return color(color::color_T,a,rl);
+ return color(color::color_T,a,rl);
}
color color_f(const ex & a, const ex & b, const ex & c)
{
- return color(color::color_f,a,b,c);
+ return color(color::color_f,a,b,c);
}
color color_d(const ex & a, const ex & b, const ex & c)
{
- return color(color::color_d,a,b,c);
+ return color(color::color_d,a,b,c);
}
ex color_h(const ex & a, const ex & b, const ex & c)
{
- return color(color::color_d,a,b,c)+I*color(color::color_f,a,b,c);
+ return color(color::color_d,a,b,c)+I*color(color::color_f,a,b,c);
}
color color_delta8(const ex & a, const ex & b)
{
- return color(color::color_delta8,a,b);
+ return color(color::color_delta8,a,b);
}
void split_color_string_in_parts(const exvector & v, exvector & delta8vec,
- exvector & fvec, exvector & dvec,
- exvectorvector & Tvecs,
- exvectorvector & ONEvecs,
- exvector & unknownvec)
-{
- // if not all elements are of type color, put all Ts in unknownvec to
- // retain the ordering
- bool all_color=true;
- for (exvector::const_iterator cit=v.begin(); cit!=v.end(); ++cit) {
- if (!is_ex_exactly_of_type(*cit,color)) {
- all_color=false;
- break;
- }
- }
-
- for (exvector::const_iterator cit=v.begin(); cit!=v.end(); ++cit) {
- if (is_ex_exactly_of_type(*cit,color)) {
- switch (ex_to_color(*cit).type) {
- case color::color_delta8:
- delta8vec.push_back(*cit);
- break;
- case color::color_f:
- fvec.push_back(*cit);
- break;
- case color::color_d:
- dvec.push_back(*cit);
- break;
- case color::color_T:
- GINAC_ASSERT(ex_to_color(*cit).representation_label<MAX_REPRESENTATION_LABELS);
- if (all_color) {
- Tvecs[ex_to_color(*cit).representation_label].push_back(*cit);
- } else {
- unknownvec.push_back(*cit);
- }
- break;
- case color::color_ONE:
- GINAC_ASSERT(ex_to_color(*cit).representation_label<MAX_REPRESENTATION_LABELS);
- ONEvecs[ex_to_color(*cit).representation_label].push_back(*cit);
- break;
- default:
- throw(std::logic_error("invalid type in split_color_string_in_parts()"));
- }
- } else {
- unknownvec.push_back(*cit);
- }
- }
+ exvector & fvec, exvector & dvec,
+ exvectorvector & Tvecs,
+ exvectorvector & ONEvecs,
+ exvector & unknownvec)
+{
+ // if not all elements are of type color, put all Ts in unknownvec to
+ // retain the ordering
+ bool all_color=true;
+ for (exvector::const_iterator cit=v.begin(); cit!=v.end(); ++cit) {
+ if (!is_ex_exactly_of_type(*cit,color)) {
+ all_color=false;
+ break;
+ }
+ }
+
+ for (exvector::const_iterator cit=v.begin(); cit!=v.end(); ++cit) {
+ if (is_ex_exactly_of_type(*cit,color)) {
+ switch (ex_to_color(*cit).type) {
+ case color::color_delta8:
+ delta8vec.push_back(*cit);
+ break;
+ case color::color_f:
+ fvec.push_back(*cit);
+ break;
+ case color::color_d:
+ dvec.push_back(*cit);
+ break;
+ case color::color_T:
+ GINAC_ASSERT(ex_to_color(*cit).representation_label<MAX_REPRESENTATION_LABELS);
+ if (all_color) {
+ Tvecs[ex_to_color(*cit).representation_label].push_back(*cit);
+ } else {
+ unknownvec.push_back(*cit);
+ }
+ break;
+ case color::color_ONE:
+ GINAC_ASSERT(ex_to_color(*cit).representation_label<MAX_REPRESENTATION_LABELS);
+ ONEvecs[ex_to_color(*cit).representation_label].push_back(*cit);
+ break;
+ default:
+ throw(std::logic_error("invalid type in split_color_string_in_parts()"));
+ }
+ } else {
+ unknownvec.push_back(*cit);
+ }
+ }
}
exvector recombine_color_string(exvector & delta8vec, exvector & fvec,
- exvector & dvec, exvectorvector & Tvecs,
- exvectorvector & ONEvecs, exvector & unknownvec)
-{
- unsigned sz=delta8vec.size()+fvec.size()+dvec.size()+unknownvec.size();
- for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
- sz += Tvecs[rl].size();
- sz += ONEvecs[rl].size();
- }
- exvector v;
- v.reserve(sz);
-
- append_exvector_to_exvector(v,delta8vec);
- append_exvector_to_exvector(v,fvec);
- append_exvector_to_exvector(v,dvec);
- for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
- append_exvector_to_exvector(v,Tvecs[rl]);
- append_exvector_to_exvector(v,ONEvecs[rl]);
- }
- append_exvector_to_exvector(v,unknownvec);
- return v;
+ exvector & dvec, exvectorvector & Tvecs,
+ exvectorvector & ONEvecs, exvector & unknownvec)
+{
+ unsigned sz=delta8vec.size()+fvec.size()+dvec.size()+unknownvec.size();
+ for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
+ sz += Tvecs[rl].size();
+ sz += ONEvecs[rl].size();
+ }
+ exvector v;
+ v.reserve(sz);
+
+ append_exvector_to_exvector(v,delta8vec);
+ append_exvector_to_exvector(v,fvec);
+ append_exvector_to_exvector(v,dvec);
+ for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
+ append_exvector_to_exvector(v,Tvecs[rl]);
+ append_exvector_to_exvector(v,ONEvecs[rl]);
+ }
+ append_exvector_to_exvector(v,unknownvec);
+ return v;
}
ex color_trace_of_one_representation_label(const exvector & v)
{
- if (v.size()==0) {
- return numeric(COLOR_THREE);
- } else if (v.size()==1) {
- GINAC_ASSERT(is_ex_exactly_of_type(*(v.begin()),color));
- return _ex0();
- }
- exvector v1=v;
- ex last_element=v1.back();
- GINAC_ASSERT(is_ex_exactly_of_type(last_element,color));
- GINAC_ASSERT(ex_to_color(last_element).type==color::color_T);
- v1.pop_back();
- ex next_to_last_element=v1.back();
- GINAC_ASSERT(is_ex_exactly_of_type(next_to_last_element,color));
- GINAC_ASSERT(ex_to_color(next_to_last_element).type==color::color_T);
- v1.pop_back();
- exvector v2=v1;
-
- const ex & last_index=ex_to_color(last_element).seq[0];
- const ex & next_to_last_index=ex_to_color(next_to_last_element).seq[0];
- ex summation_index=coloridx();
-
- v2.push_back(color_T(summation_index)); // don't care about the representation_label
-
- // FIXME: check this formula for SU(N) with N!=3
- return numeric(1)/numeric(2*COLOR_THREE)*color_delta8(next_to_last_index,last_index)
- % color_trace_of_one_representation_label(v1)
- +numeric(1)/numeric(2)*color_h(next_to_last_index,last_index,summation_index)
- % color_trace_of_one_representation_label(v2);
- /*
- ex term1=numeric(1)/numeric(2*COLOR_THREE)*color_delta8(next_to_last_index,last_index)
- % color_trace_of_one_representation_label(v1);
- cout << "term 1 of trace of " << v.size() << " ts=" << term1 << endl;
- ex term2=numeric(1)/numeric(2)*color_h(next_to_last_index,last_index,summation_index)
- % color_trace_of_one_representation_label(v2);
- cout << "term 2 of trace of " << v.size() << " ts=" << term2 << endl;
- return term1+term2;
- */
+ if (v.size()==0) {
+ return numeric(COLOR_THREE);
+ } else if (v.size()==1) {
+ GINAC_ASSERT(is_ex_exactly_of_type(*(v.begin()),color));
+ return _ex0();
+ }
+ exvector v1=v;
+ ex last_element=v1.back();
+ GINAC_ASSERT(is_ex_exactly_of_type(last_element,color));
+ GINAC_ASSERT(ex_to_color(last_element).type==color::color_T);
+ v1.pop_back();
+ ex next_to_last_element=v1.back();
+ GINAC_ASSERT(is_ex_exactly_of_type(next_to_last_element,color));
+ GINAC_ASSERT(ex_to_color(next_to_last_element).type==color::color_T);
+ v1.pop_back();
+ exvector v2=v1;
+
+ const ex & last_index=ex_to_color(last_element).seq[0];
+ const ex & next_to_last_index=ex_to_color(next_to_last_element).seq[0];
+ ex summation_index=coloridx();
+
+ v2.push_back(color_T(summation_index)); // don't care about the representation_label
+
+ // FIXME: check this formula for SU(N) with N!=3
+ return numeric(1)/numeric(2*COLOR_THREE)*color_delta8(next_to_last_index,last_index)
+ % color_trace_of_one_representation_label(v1)
+ +numeric(1)/numeric(2)*color_h(next_to_last_index,last_index,summation_index)
+ % color_trace_of_one_representation_label(v2);
+ /*
+ ex term1=numeric(1)/numeric(2*COLOR_THREE)*color_delta8(next_to_last_index,last_index)
+ % color_trace_of_one_representation_label(v1);
+ cout << "term 1 of trace of " << v.size() << " ts=" << term1 << endl;
+ ex term2=numeric(1)/numeric(2)*color_h(next_to_last_index,last_index,summation_index)
+ % color_trace_of_one_representation_label(v2);
+ cout << "term 2 of trace of " << v.size() << " ts=" << term2 << endl;
+ return term1+term2;
+ */
}
ex color_trace(const exvector & v, unsigned rl)
{
- GINAC_ASSERT(rl<MAX_REPRESENTATION_LABELS);
-
- exvector v_rest;
- v_rest.reserve(v.size()+1); // max size if trace is empty
-
- exvector delta8vec;
- exvector fvec;
- exvector dvec;
- exvectorvector Tvecs;
- Tvecs.resize(MAX_REPRESENTATION_LABELS);
- exvectorvector ONEvecs;
- ONEvecs.resize(MAX_REPRESENTATION_LABELS);
- exvector unknownvec;
-
- split_color_string_in_parts(v,delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec);
-
- if (unknownvec.size()!=0) {
- throw(std::invalid_argument("color_trace(): expression must be expanded"));
- }
-
- append_exvector_to_exvector(v_rest,delta8vec);
- append_exvector_to_exvector(v_rest,fvec);
- append_exvector_to_exvector(v_rest,dvec);
- for (unsigned i=0; i<MAX_REPRESENTATION_LABELS; ++i) {
- if (i!=rl) {
- append_exvector_to_exvector(v_rest,Tvecs[i]);
- append_exvector_to_exvector(v_rest,ONEvecs[i]);
- } else {
- if (Tvecs[i].size()!=0) {
- v_rest.push_back(color_trace_of_one_representation_label(Tvecs[i]));
- } else if (ONEvecs[i].size()!=0) {
- v_rest.push_back(numeric(COLOR_THREE));
- } else {
- throw(std::logic_error("color_trace(): representation_label not in color string"));
- }
- }
- }
-
- return nonsimplified_ncmul(v_rest);
+ GINAC_ASSERT(rl<MAX_REPRESENTATION_LABELS);
+
+ exvector v_rest;
+ v_rest.reserve(v.size()+1); // max size if trace is empty
+
+ exvector delta8vec;
+ exvector fvec;
+ exvector dvec;
+ exvectorvector Tvecs;
+ Tvecs.resize(MAX_REPRESENTATION_LABELS);
+ exvectorvector ONEvecs;
+ ONEvecs.resize(MAX_REPRESENTATION_LABELS);
+ exvector unknownvec;
+
+ split_color_string_in_parts(v,delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec);
+
+ if (unknownvec.size()!=0) {
+ throw(std::invalid_argument("color_trace(): expression must be expanded"));
+ }
+
+ append_exvector_to_exvector(v_rest,delta8vec);
+ append_exvector_to_exvector(v_rest,fvec);
+ append_exvector_to_exvector(v_rest,dvec);
+ for (unsigned i=0; i<MAX_REPRESENTATION_LABELS; ++i) {
+ if (i!=rl) {
+ append_exvector_to_exvector(v_rest,Tvecs[i]);
+ append_exvector_to_exvector(v_rest,ONEvecs[i]);
+ } else {
+ if (Tvecs[i].size()!=0) {
+ v_rest.push_back(color_trace_of_one_representation_label(Tvecs[i]));
+ } else if (ONEvecs[i].size()!=0) {
+ v_rest.push_back(numeric(COLOR_THREE));
+ } else {
+ throw(std::logic_error("color_trace(): representation_label not in color string"));
+ }
+ }
+ }
+
+ return nonsimplified_ncmul(v_rest);
}
ex simplify_pure_color_string(const ex & e)
{
- GINAC_ASSERT(is_ex_exactly_of_type(e,ncmul));
-
- exvector delta8vec;
- exvector fvec;
- exvector dvec;
- exvectorvector Tvecs;
- Tvecs.resize(MAX_REPRESENTATION_LABELS);
- exvectorvector ONEvecs;
- ONEvecs.resize(MAX_REPRESENTATION_LABELS);
- exvector unknownvec;
-
- split_color_string_in_parts(ex_to_ncmul(e).get_factors(),delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec);
-
- // search for T_k S T_k (=1/2 Tr(S) - 1/6 S)
- for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
- if (Tvecs[rl].size()>=2) {
- for (unsigned i=0; i<Tvecs[rl].size()-1; ++i) {
- for (unsigned j=i+1; j<Tvecs[rl].size(); ++j) {
- ex & t1=Tvecs[rl][i];
- ex & t2=Tvecs[rl][j];
- GINAC_ASSERT(is_ex_exactly_of_type(t1,color)&&
- (ex_to_color(t1).type==color::color_T)&&
- (ex_to_color(t1).seq.size()==1));
- GINAC_ASSERT(is_ex_exactly_of_type(t2,color)&&
- (ex_to_color(t2).type==color::color_T)&&
- (ex_to_color(t2).seq.size()==1));
- const coloridx & idx1=ex_to_coloridx(ex_to_color(t1).seq[0]);
- const coloridx & idx2=ex_to_coloridx(ex_to_color(t2).seq[0]);
-
- if (idx1.is_equal(idx2) && idx1.is_symbolic()) {
- exvector S;
- for (unsigned k=i+1; k<j; ++k) {
- S.push_back(Tvecs[rl][k]);
- }
- t1=_ex1();
- t2=_ex1();
- ex term1=numeric(-1)/numeric(6)*nonsimplified_ncmul(recombine_color_string(
- delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
- for (unsigned k=i+1; k<j; ++k) {
- S.push_back(_ex1());
- }
- t1=color_trace_of_one_representation_label(S);
- ex term2=numeric(1)/numeric(2)*nonsimplified_ncmul(recombine_color_string(
- delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
- return simplify_color(term1+term2);
- }
- }
- }
- }
- }
-
- // FIXME: higher contractions
-
- return e;
-}
-
+ GINAC_ASSERT(is_ex_exactly_of_type(e,ncmul));
+
+ exvector delta8vec;
+ exvector fvec;
+ exvector dvec;
+ exvectorvector Tvecs;
+ Tvecs.resize(MAX_REPRESENTATION_LABELS);
+ exvectorvector ONEvecs;
+ ONEvecs.resize(MAX_REPRESENTATION_LABELS);
+ exvector unknownvec;
+
+ split_color_string_in_parts(ex_to_ncmul(e).get_factors(),delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec);
+
+ // search for T_k S T_k (=1/2 Tr(S) - 1/6 S)
+ for (unsigned rl=0; rl<MAX_REPRESENTATION_LABELS; ++rl) {
+ if (Tvecs[rl].size()>=2) {
+ for (unsigned i=0; i<Tvecs[rl].size()-1; ++i) {
+ for (unsigned j=i+1; j<Tvecs[rl].size(); ++j) {
+ ex & t1=Tvecs[rl][i];
+ ex & t2=Tvecs[rl][j];
+ GINAC_ASSERT(is_ex_exactly_of_type(t1,color)&&
+ (ex_to_color(t1).type==color::color_T)&&
+ (ex_to_color(t1).seq.size()==1));
+ GINAC_ASSERT(is_ex_exactly_of_type(t2,color)&&
+ (ex_to_color(t2).type==color::color_T)&&
+ (ex_to_color(t2).seq.size()==1));
+ const coloridx & idx1=ex_to_coloridx(ex_to_color(t1).seq[0]);
+ const coloridx & idx2=ex_to_coloridx(ex_to_color(t2).seq[0]);
+
+ if (idx1.is_equal(idx2) && idx1.is_symbolic()) {
+ exvector S;
+ for (unsigned k=i+1; k<j; ++k) {
+ S.push_back(Tvecs[rl][k]);
+ }
+ t1=_ex1();
+ t2=_ex1();
+ ex term1=numeric(-1)/numeric(6)*nonsimplified_ncmul(recombine_color_string(
+ delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
+ for (unsigned k=i+1; k<j; ++k) {
+ S.push_back(_ex1());
+ }
+ t1=color_trace_of_one_representation_label(S);
+ ex term2=numeric(1)/numeric(2)*nonsimplified_ncmul(recombine_color_string(
+ delta8vec,fvec,dvec,Tvecs,ONEvecs,unknownvec));
+ return simplify_color(term1+term2);
+ }
+ }
+ }
+ }
+ }
+
+ // FIXME: higher contractions
+
+ return e;
+}
+
ex simplify_color(const ex & e)
{
- // all simplification is done on expanded objects
- ex e_expanded=e.expand();
-
- // simplification of sum=sum of simplifications
- if (is_ex_exactly_of_type(e_expanded,add)) {
- ex sum=_ex0();
- for (unsigned i=0; i<e_expanded.nops(); ++i)
- sum += simplify_color(e_expanded.op(i));
-
- return sum;
- }
-
- // simplification of commutative product=commutative product of simplifications
- if (is_ex_exactly_of_type(e_expanded,mul)) {
- ex prod=_ex1();
- for (unsigned i=0; i<e_expanded.nops(); ++i)
- prod *= simplify_color(e_expanded.op(i));
-
- return prod;
- }
-
- // simplification of noncommutative product: test if everything is color
- if (is_ex_exactly_of_type(e_expanded,ncmul)) {
- bool all_color=true;
- for (unsigned i=0; i<e_expanded.nops(); ++i) {
- if (!is_ex_exactly_of_type(e_expanded.op(i),color)) {
- all_color=false;
- break;
- }
- }
- if (all_color) {
- return simplify_pure_color_string(e_expanded);
- }
- }
-
- // cannot do anything
- return e_expanded;
+ // all simplification is done on expanded objects
+ ex e_expanded=e.expand();
+
+ // simplification of sum=sum of simplifications
+ if (is_ex_exactly_of_type(e_expanded,add)) {
+ ex sum=_ex0();
+ for (unsigned i=0; i<e_expanded.nops(); ++i)
+ sum += simplify_color(e_expanded.op(i));
+
+ return sum;
+ }
+
+ // simplification of commutative product=commutative product of simplifications
+ if (is_ex_exactly_of_type(e_expanded,mul)) {
+ ex prod=_ex1();
+ for (unsigned i=0; i<e_expanded.nops(); ++i)
+ prod *= simplify_color(e_expanded.op(i));
+
+ return prod;
+ }
+
+ // simplification of noncommutative product: test if everything is color
+ if (is_ex_exactly_of_type(e_expanded,ncmul)) {
+ bool all_color=true;
+ for (unsigned i=0; i<e_expanded.nops(); ++i) {
+ if (!is_ex_exactly_of_type(e_expanded.op(i),color)) {
+ all_color=false;
+ break;
+ }
+ }
+ if (all_color) {
+ return simplify_pure_color_string(e_expanded);
+ }
+ }
+
+ // cannot do anything
+ return e_expanded;
}
ex brute_force_sum_color_indices(const ex & e)
{
- exvector iv_all=e.get_indices();
- exvector iv_double;
-
- // find double symbolic indices
- if (iv_all.size()<2) return e;
- for (exvector::const_iterator cit1=iv_all.begin(); cit1!=iv_all.end()-1; ++cit1) {
- GINAC_ASSERT(is_ex_of_type(*cit1,coloridx));
- for (exvector::const_iterator cit2=cit1+1; cit2!=iv_all.end(); ++cit2) {
- GINAC_ASSERT(is_ex_of_type(*cit2,coloridx));
- if (ex_to_coloridx(*cit1).is_symbolic() &&
- ex_to_coloridx(*cit1).is_equal(ex_to_coloridx(*cit2))) {
- iv_double.push_back(*cit1);
- break;
- }
- }
- }
-
- std::vector<int> counter;
- counter.resize(iv_double.size());
- int l;
- for (l=0; unsigned(l)<iv_double.size(); ++l) {
- counter[l]=1;
- }
-
- ex sum;
-
- while (1) {
- ex term = e;
- for (l=0; unsigned(l)<iv_double.size(); ++l) {
- term=term.subs(iv_double[l]==coloridx((unsigned)(counter[l])));
- //iv_double[l].print(cout);
- //cout << " " << counter[l] << " ";
- }
- //cout << endl;
- sum += term;
-
- // increment counter[]
- l = iv_double.size()-1;
- while ((l>=0)&&((++counter[l])>(int)COLOR_EIGHT)) {
- counter[l]=1;
- l--;
- }
- if (l<2) { std::cout << counter[0] << counter[1] << std::endl; }
- if (l<0) break;
- }
-
- return sum;
+ exvector iv_all=e.get_indices();
+ exvector iv_double;
+
+ // find double symbolic indices
+ if (iv_all.size()<2) return e;
+ for (exvector::const_iterator cit1=iv_all.begin(); cit1!=iv_all.end()-1; ++cit1) {
+ GINAC_ASSERT(is_ex_of_type(*cit1,coloridx));
+ for (exvector::const_iterator cit2=cit1+1; cit2!=iv_all.end(); ++cit2) {
+ GINAC_ASSERT(is_ex_of_type(*cit2,coloridx));
+ if (ex_to_coloridx(*cit1).is_symbolic() &&
+ ex_to_coloridx(*cit1).is_equal(ex_to_coloridx(*cit2))) {
+ iv_double.push_back(*cit1);
+ break;
+ }
+ }
+ }
+
+ std::vector<int> counter;
+ counter.resize(iv_double.size());
+ int l;
+ for (l=0; unsigned(l)<iv_double.size(); ++l) {
+ counter[l]=1;
+ }
+
+ ex sum;
+
+ while (1) {
+ ex term = e;
+ for (l=0; unsigned(l)<iv_double.size(); ++l) {
+ term=term.subs(iv_double[l]==coloridx((unsigned)(counter[l])));
+ //iv_double[l].print(cout);
+ //cout << " " << counter[l] << " ";
+ }
+ //cout << endl;
+ sum += term;
+
+ // increment counter[]
+ l = iv_double.size()-1;
+ while ((l>=0)&&((++counter[l])>(int)COLOR_EIGHT)) {
+ counter[l]=1;
+ l--;
+ }
+ if (l<2) { std::cout << counter[0] << counter[1] << std::endl; }
+ if (l<0) break;
+ }
+
+ return sum;
}
void append_exvector_to_exvector(exvector & dest, const exvector & source)
{
- for (exvector::const_iterator cit=source.begin(); cit!=source.end(); ++cit) {
- dest.push_back(*cit);
- }
+ for (exvector::const_iterator cit=source.begin(); cit!=source.end(); ++cit) {
+ dest.push_back(*cit);
+ }
}
#ifndef NO_NAMESPACE_GINAC
/** Base class for color object */
class color : public indexed
{
- GINAC_DECLARE_REGISTERED_CLASS(color, indexed)
+ GINAC_DECLARE_REGISTERED_CLASS(color, indexed)
// friends
- friend color color_ONE(unsigned rl);
- friend color color_T(const ex & a, unsigned rl);
- friend color color_f(const ex & a, const ex & b, const ex & c);
- friend color color_d(const ex & a, const ex & b, const ex & c);
- friend ex color_h(const ex & a, const ex & b, const ex & c);
- friend color color_delta8(const ex & a, const ex & b);
- friend unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir);
- friend void split_color_string_in_parts(const exvector & v, exvector & delta8vec,
- exvector & fvec, exvector & dvec,
- exvectorvector & Tvecs,
- exvectorvector & ONEvecs,
- exvector & unknownvec);
- friend exvector recombine_color_string(exvector & delta8vec, exvector & fvec,
- exvector & dvec, exvectorvector & Tvecs,
- exvectorvector & ONEvecs, exvector & unknownvec);
- friend ex color_trace_of_one_representation_label(const exvector & v);
- friend ex color_trace(const exvector & v, unsigned rl);
- friend ex simplify_pure_color_string(const ex & e);
- friend ex simplify_color(const ex & e);
-
-
+ friend color color_ONE(unsigned rl);
+ friend color color_T(const ex & a, unsigned rl);
+ friend color color_f(const ex & a, const ex & b, const ex & c);
+ friend color color_d(const ex & a, const ex & b, const ex & c);
+ friend ex color_h(const ex & a, const ex & b, const ex & c);
+ friend color color_delta8(const ex & a, const ex & b);
+ friend unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir);
+ friend void split_color_string_in_parts(const exvector & v, exvector & delta8vec,
+ exvector & fvec, exvector & dvec,
+ exvectorvector & Tvecs,
+ exvectorvector & ONEvecs,
+ exvector & unknownvec);
+ friend exvector recombine_color_string(exvector & delta8vec, exvector & fvec,
+ exvector & dvec, exvectorvector & Tvecs,
+ exvectorvector & ONEvecs, exvector & unknownvec);
+ friend ex color_trace_of_one_representation_label(const exvector & v);
+ friend ex color_trace(const exvector & v, unsigned rl);
+ friend ex simplify_pure_color_string(const ex & e);
+ friend ex simplify_color(const ex & e);
+
+
// types
public:
- typedef enum { invalid, // not properly constructed by one of the friend functions
- color_T,
- color_f,
- color_d,
- color_delta8,
- color_ONE
- } color_types;
-
+ typedef enum { invalid, // not properly constructed by one of the friend functions
+ color_T,
+ color_f,
+ color_d,
+ color_delta8,
+ color_ONE
+ } color_types;
+
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- color();
- ~color();
- color(const color & other);
- const color & operator=(const color & other);
+ color();
+ ~color();
+ color(const color & other);
+ const color & operator=(const color & other);
protected:
- void copy(const color & other);
- void destroy(bool call_parent);
+ void copy(const color & other);
+ void destroy(bool call_parent);
- // other constructors
+ // other constructors
protected:
- color(color_types const t, unsigned rl=0);
- color(color_types const t, const ex & i1, unsigned rl=0);
- color(color_types const t, const ex & i1, const ex & i2, unsigned rl=0);
- color(color_types const t, const ex & i1, const ex & i2, const ex & i3,
- unsigned rl=0);
- color(color_types const t, const exvector & iv, unsigned rl=0);
- color(color_types const t, exvector * ivp, unsigned rl=0);
-
- // functions overriding virtual functions from base classes
+ color(color_types const t, unsigned rl=0);
+ color(color_types const t, const ex & i1, unsigned rl=0);
+ color(color_types const t, const ex & i1, const ex & i2, unsigned rl=0);
+ color(color_types const t, const ex & i1, const ex & i2, const ex & i3,
+ unsigned rl=0);
+ color(color_types const t, const exvector & iv, unsigned rl=0);
+ color(color_types const t, exvector * ivp, unsigned rl=0);
+
+ // functions overriding virtual functions from base classes
public:
- basic * duplicate() const;
- void printraw(std::ostream & os) const;
- void printtree(std::ostream & os, unsigned indent) const;
- void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
- bool info(unsigned inf) const;
- ex eval(int level=0) const;
+ basic * duplicate() const;
+ void printraw(std::ostream & os) const;
+ void printtree(std::ostream & os, unsigned indent) const;
+ void print(std::ostream & os, unsigned upper_precedence=0) const;
+ void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+ bool info(unsigned inf) const;
+ ex eval(int level=0) const;
protected:
- int compare_same_type(const basic & other) const;
- bool is_equal_same_type(const basic & other) const;
- ex simplify_ncmul(const exvector & v) const;
- ex thisexprseq(const exvector & v) const;
- ex thisexprseq(exvector * vp) const;
-
- // new virtual functions which can be overridden by derived classes
- // none
-
- // non-virtual functions in this class
+ int compare_same_type(const basic & other) const;
+ bool is_equal_same_type(const basic & other) const;
+ ex simplify_ncmul(const exvector & v) const;
+ ex thisexprseq(const exvector & v) const;
+ ex thisexprseq(exvector * vp) const;
+
+ // new virtual functions which can be overridden by derived classes
+ // none
+
+ // non-virtual functions in this class
protected:
- bool all_of_type_coloridx(void) const;
-
+ bool all_of_type_coloridx(void) const;
+
// member variables
protected:
- color_types type;
- unsigned representation_label; // to distiguish independent color matrices coming from separated fermion lines
+ color_types type;
+ unsigned representation_label; // to distiguish independent color matrices coming from separated fermion lines
};
// global constants
ex color_h(const ex & a, const ex & b, const ex & c);
color color_delta8(const ex & a, const ex & b);
void split_color_string_in_parts(const exvector & v, exvector & delta8vec,
- exvector & fvec, exvector & dvec,
- exvectorvector & Tvecs,
- exvectorvector & ONEvecs,
- exvector & unknownvec);
+ exvector & fvec, exvector & dvec,
+ exvectorvector & Tvecs,
+ exvectorvector & ONEvecs,
+ exvector & unknownvec);
exvector recombine_color_string(exvector & delta8vec, exvector & fvec,
- exvector & dvec, exvectorvector & Tvecs,
- exvectorvector & ONEvecs, exvector & unknownvec);
+ exvector & dvec, exvectorvector & Tvecs,
+ exvectorvector & ONEvecs, exvector & unknownvec);
ex color_trace_of_one_representation_label(const exvector & v);
ex color_trace(const exvector & v, unsigned rl=0);
ex simplify_pure_color_string(const ex & e);
coloridx::coloridx()
{
- debugmsg("coloridx default constructor",LOGLEVEL_CONSTRUCT);
- // serial is incremented in idx::idx()
- name="color"+ToString(serial);
- tinfo_key=TINFO_coloridx;
+ debugmsg("coloridx default constructor",LOGLEVEL_CONSTRUCT);
+ // serial is incremented in idx::idx()
+ name="color"+ToString(serial);
+ tinfo_key=TINFO_coloridx;
}
coloridx::~coloridx()
{
- debugmsg("coloridx destructor",LOGLEVEL_DESTRUCT);
- destroy(0);
+ debugmsg("coloridx destructor",LOGLEVEL_DESTRUCT);
+ destroy(0);
}
coloridx::coloridx(const coloridx & other)
{
- debugmsg("coloridx copy constructor",LOGLEVEL_CONSTRUCT);
- copy(other);
+ debugmsg("coloridx copy constructor",LOGLEVEL_CONSTRUCT);
+ copy(other);
}
const coloridx & coloridx::operator=(const coloridx & other)
{
- debugmsg("coloridx operator=",LOGLEVEL_ASSIGNMENT);
- if (this != &other) {
- destroy(1);
- copy(other);
- }
- return *this;
+ debugmsg("coloridx operator=",LOGLEVEL_ASSIGNMENT);
+ if (this != &other) {
+ destroy(1);
+ copy(other);
+ }
+ return *this;
}
// protected
void coloridx::copy(const coloridx & other)
{
- inherited::copy(other);
+ inherited::copy(other);
}
void coloridx::destroy(bool call_parent)
{
- if (call_parent) inherited::destroy(call_parent);
+ if (call_parent) inherited::destroy(call_parent);
}
//////////
coloridx::coloridx(bool cov) : idx(cov)
{
- debugmsg("coloridx constructor from bool",LOGLEVEL_CONSTRUCT);
- // serial is incremented in idx::idx(bool)
- name="color"+ToString(serial);
- tinfo_key=TINFO_coloridx;
+ debugmsg("coloridx constructor from bool",LOGLEVEL_CONSTRUCT);
+ // serial is incremented in idx::idx(bool)
+ name="color"+ToString(serial);
+ tinfo_key=TINFO_coloridx;
}
coloridx::coloridx(const std::string & n, bool cov) : idx(n,cov)
{
- debugmsg("coloridx constructor from string,bool",LOGLEVEL_CONSTRUCT);
- tinfo_key=TINFO_coloridx;
+ debugmsg("coloridx constructor from string,bool",LOGLEVEL_CONSTRUCT);
+ tinfo_key=TINFO_coloridx;
}
coloridx::coloridx(const char * n, bool cov) : idx(n,cov)
{
- debugmsg("coloridx constructor from char*,bool",LOGLEVEL_CONSTRUCT);
- tinfo_key=TINFO_coloridx;
+ debugmsg("coloridx constructor from char*,bool",LOGLEVEL_CONSTRUCT);
+ tinfo_key=TINFO_coloridx;
}
coloridx::coloridx(unsigned v, bool cov) : idx(v,cov)
{
- debugmsg("coloridx constructor from unsigned,bool",LOGLEVEL_CONSTRUCT);
- tinfo_key=TINFO_coloridx;
+ debugmsg("coloridx constructor from unsigned,bool",LOGLEVEL_CONSTRUCT);
+ tinfo_key=TINFO_coloridx;
}
//////////
/** Construct object from archive_node. */
coloridx::coloridx(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
{
- debugmsg("coloridx constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ debugmsg("coloridx constructor from archive_node", LOGLEVEL_CONSTRUCT);
}
/** Unarchive the object. */
ex coloridx::unarchive(const archive_node &n, const lst &sym_lst)
{
- return (new coloridx(n, sym_lst))->setflag(status_flags::dynallocated);
+ return (new coloridx(n, sym_lst))->setflag(status_flags::dynallocated);
}
/** Archive the object. */
void coloridx::archive(archive_node &n) const
{
- inherited::archive(n);
+ inherited::archive(n);
}
//////////
basic * coloridx::duplicate() const
{
- debugmsg("coloridx duplicate",LOGLEVEL_DUPLICATE);
- return new coloridx(*this);
+ debugmsg("coloridx duplicate",LOGLEVEL_DUPLICATE);
+ return new coloridx(*this);
}
void coloridx::printraw(std::ostream & os) const
{
- debugmsg("coloridx printraw",LOGLEVEL_PRINT);
+ debugmsg("coloridx printraw",LOGLEVEL_PRINT);
- os << "coloridx(";
+ os << "coloridx(";
- if (symbolic) {
- os << "symbolic,name=" << name;
- } else {
- os << "non symbolic,value=" << value;
- }
+ if (symbolic) {
+ os << "symbolic,name=" << name;
+ } else {
+ os << "non symbolic,value=" << value;
+ }
- if (covariant) {
- os << ",covariant";
- } else {
- os << ",contravariant";
- }
+ if (covariant) {
+ os << ",covariant";
+ } else {
+ os << ",contravariant";
+ }
- os << ",serial=" << serial;
- os << ",hash=" << hashvalue << ",flags=" << flags;
- os << ")";
+ os << ",serial=" << serial;
+ os << ",hash=" << hashvalue << ",flags=" << flags;
+ os << ")";
}
void coloridx::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("coloridx printtree",LOGLEVEL_PRINT);
+ debugmsg("coloridx printtree",LOGLEVEL_PRINT);
- os << std::string(indent,' ') << "coloridx: ";
+ os << std::string(indent,' ') << "coloridx: ";
- if (symbolic) {
- os << "symbolic,name=" << name;
- } else {
- os << "non symbolic,value=" << value;
- }
+ if (symbolic) {
+ os << "symbolic,name=" << name;
+ } else {
+ os << "non symbolic,value=" << value;
+ }
- if (covariant) {
- os << ",covariant";
- } else {
- os << ",contravariant";
- }
+ if (covariant) {
+ os << ",covariant";
+ } else {
+ os << ",contravariant";
+ }
- os << ", serial=" << serial
- << ", hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags << std::endl;
+ os << ", serial=" << serial
+ << ", hash=" << hashvalue
+ << " (0x" << std::hex << hashvalue << std::dec << ")"
+ << ", flags=" << flags << std::endl;
}
void coloridx::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("coloridx print",LOGLEVEL_PRINT);
+ debugmsg("coloridx print",LOGLEVEL_PRINT);
- if (covariant) {
- os << "_";
- } else {
- os << "~";
- }
- if (symbolic) {
- os << name;
- } else {
- os << value;
- }
+ if (covariant) {
+ os << "_";
+ } else {
+ os << "~";
+ }
+ if (symbolic) {
+ os << name;
+ } else {
+ os << value;
+ }
}
bool coloridx::info(unsigned inf) const
{
- if (inf==info_flags::coloridx) return true;
- return idx::info(inf);
+ if (inf==info_flags::coloridx) return true;
+ return idx::info(inf);
}
//////////
class coloridx : public idx
{
- GINAC_DECLARE_REGISTERED_CLASS(coloridx, idx)
+ GINAC_DECLARE_REGISTERED_CLASS(coloridx, idx)
- friend class color;
+ friend class color;
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- coloridx();
- ~coloridx();
- coloridx (const coloridx & other);
- const coloridx & operator=(const coloridx & other);
+ coloridx();
+ ~coloridx();
+ coloridx (const coloridx & other);
+ const coloridx & operator=(const coloridx & other);
protected:
- void copy(const coloridx & other);
- void destroy(bool call_parent);
+ void copy(const coloridx & other);
+ void destroy(bool call_parent);
- // other constructors
+ // other constructors
public:
- explicit coloridx(bool cov);
- explicit coloridx(const std::string & n, bool cov=false);
- explicit coloridx(const char * n, bool cov=false);
- explicit coloridx(unsigned v, bool cov=false);
+ explicit coloridx(bool cov);
+ explicit coloridx(const std::string & n, bool cov=false);
+ explicit coloridx(const char * n, bool cov=false);
+ explicit coloridx(unsigned v, bool cov=false);
- // functions overriding virtual functions from bases classes
+ // functions overriding virtual functions from bases classes
public:
- basic * duplicate() const;
- void printraw(std::ostream & os) const;
- void printtree(std::ostream & os, unsigned indent) const;
- void print(std::ostream & os, unsigned upper_precedence=0) const;
- bool info(unsigned inf) const;
+ basic * duplicate() const;
+ void printraw(std::ostream & os) const;
+ void printtree(std::ostream & os, unsigned indent) const;
+ void print(std::ostream & os, unsigned upper_precedence=0) const;
+ bool info(unsigned inf) const;
- // new virtual functions which can be overridden by derived classes
- // none
+ // new virtual functions which can be overridden by derived classes
+ // none
- // non-virtual functions in this class
- // none
+ // non-virtual functions in this class
+ // none
- // member variables
- // none
+ // member variables
+ // none
};
// global constants
// public
constant::constant() :
- basic(TINFO_constant), name(""), ef(0),
- number(0), serial(next_serial++)
+ basic(TINFO_constant), name(""), ef(0),
+ number(0), serial(next_serial++)
{
- debugmsg("constant default constructor",LOGLEVEL_CONSTRUCT);
+ debugmsg("constant default constructor",LOGLEVEL_CONSTRUCT);
}
constant::~constant()
{
- debugmsg("constant destructor",LOGLEVEL_DESTRUCT);
- destroy(0);
+ debugmsg("constant destructor",LOGLEVEL_DESTRUCT);
+ destroy(0);
}
constant::constant(const constant & other)
{
- debugmsg("constant copy constructor",LOGLEVEL_CONSTRUCT);
- copy(other);
+ debugmsg("constant copy constructor",LOGLEVEL_CONSTRUCT);
+ copy(other);
}
// protected
void constant::copy(const constant & other)
{
- basic::copy(other);
- name=other.name;
- serial=other.serial;
- ef=other.ef;
- if (other.number != 0) {
- number = new numeric(*other.number);
- } else {
- number = 0;
- }
- // fct_assigned=other.fct_assigned;
+ basic::copy(other);
+ name=other.name;
+ serial=other.serial;
+ ef=other.ef;
+ if (other.number != 0) {
+ number = new numeric(*other.number);
+ } else {
+ number = 0;
+ }
+ // fct_assigned=other.fct_assigned;
}
void constant::destroy(bool call_parent)
{
- delete number;
- if (call_parent)
- basic::destroy(call_parent);
+ delete number;
+ if (call_parent)
+ basic::destroy(call_parent);
}
//////////
// public
constant::constant(const std::string & initname, evalffunctype efun) :
- basic(TINFO_constant), name(initname), ef(efun),
- // number(0), fct_assigned(true), serial(next_serial++)
- number(0), serial(next_serial++)
+ basic(TINFO_constant), name(initname), ef(efun),
+ // number(0), fct_assigned(true), serial(next_serial++)
+ number(0), serial(next_serial++)
{
- debugmsg("constant constructor from string, function",LOGLEVEL_CONSTRUCT);
+ debugmsg("constant constructor from string, function",LOGLEVEL_CONSTRUCT);
}
constant::constant(const std::string & initname, const numeric & initnumber) :
- basic(TINFO_constant), name(initname), ef(0),
- number(new numeric(initnumber)), /* fct_assigned(false),*/ serial(next_serial++)
+ basic(TINFO_constant), name(initname), ef(0),
+ number(new numeric(initnumber)), /* fct_assigned(false),*/ serial(next_serial++)
{
- debugmsg("constant constructor from string, numeric",LOGLEVEL_CONSTRUCT);
+ debugmsg("constant constructor from string, numeric",LOGLEVEL_CONSTRUCT);
}
//////////
/** 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 constructor from archive_node", LOGLEVEL_CONSTRUCT);
}
/** Unarchive the object. */
ex constant::unarchive(const archive_node &n, const lst &sym_lst)
{
- // Find constant by name (!! this is bad: 'twould be better if there
- // was a list of all global constants that we could search)
- std::string s;
- if (n.find_string("name", s)) {
- if (s == Pi.name)
- return Pi;
- else if (s == Catalan.name)
- return Catalan;
- else if (s == Euler.name)
- return Euler;
- else
- throw (std::runtime_error("unknown constant '" + s + "' in archive"));
- } else
- throw (std::runtime_error("unnamed constant in archive"));
+ // Find constant by name (!! this is bad: 'twould be better if there
+ // was a list of all global constants that we could search)
+ std::string s;
+ if (n.find_string("name", s)) {
+ if (s == Pi.name)
+ return Pi;
+ else if (s == Catalan.name)
+ return Catalan;
+ else if (s == Euler.name)
+ return Euler;
+ else
+ throw (std::runtime_error("unknown constant '" + s + "' in archive"));
+ } else
+ throw (std::runtime_error("unnamed constant in archive"));
}
/** Archive the object. */
void constant::archive(archive_node &n) const
{
- inherited::archive(n);
- n.add_string("name", name);
+ inherited::archive(n);
+ n.add_string("name", name);
}
//////////
basic * constant::duplicate() const
{
- debugmsg("constant duplicate",LOGLEVEL_DUPLICATE);
- return new constant(*this);
+ debugmsg("constant duplicate",LOGLEVEL_DUPLICATE);
+ return new constant(*this);
}
void constant::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("constant print",LOGLEVEL_PRINT);
- os << name;
+ debugmsg("constant print",LOGLEVEL_PRINT);
+ os << name;
}
void constant::printraw(std::ostream & os) const
{
- debugmsg("constant printraw",LOGLEVEL_PRINT);
- os << "constant(" << name << ")";
+ debugmsg("constant printraw",LOGLEVEL_PRINT);
+ os << "constant(" << name << ")";
}
void constant::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("constant printtree",LOGLEVEL_PRINT);
- os << std::string(indent,' ') << name
- << ", type=" << typeid(*this).name()
- << ", hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags << std::endl;
+ debugmsg("constant printtree",LOGLEVEL_PRINT);
+ os << std::string(indent,' ') << name
+ << ", type=" << class_name()
+ << ", hash=" << hashvalue
+ << " (0x" << std::hex << hashvalue << std::dec << ")"
+ << ", flags=" << flags << std::endl;
}
void constant::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
{
- debugmsg("constant print csrc",LOGLEVEL_PRINT);
- os << name;
+ debugmsg("constant print csrc",LOGLEVEL_PRINT);
+ os << name;
}
ex constant::evalf(int level) const
{
- if (ef!=0) {
- return ef();
- } else if (number != 0) {
- return *number;
- }
- return *this;
+ if (ef!=0) {
+ return ef();
+ } else if (number != 0) {
+ return *number;
+ }
+ return *this;
}
// protected
* @see ex::diff */
ex constant::derivative(const symbol & s) const
{
- return _ex0();
+ return _ex0();
}
int constant::compare_same_type(const basic & other) const
{
- GINAC_ASSERT(is_exactly_of_type(other, constant));
- // const constant & o=static_cast<constant &>(const_cast<basic &>(other));
- // return name.compare(o.name);
- const constant *o = static_cast<const constant *>(&other);
- if (serial==o->serial) return 0;
- return serial < o->serial ? -1 : 1;
+ GINAC_ASSERT(is_exactly_of_type(other, constant));
+ // const constant & o=static_cast<constant &>(const_cast<basic &>(other));
+ // return name.compare(o.name);
+ const constant *o = static_cast<const constant *>(&other);
+ if (serial==o->serial) return 0;
+ return serial < o->serial ? -1 : 1;
}
bool constant::is_equal_same_type(const basic & other) const
{
- GINAC_ASSERT(is_exactly_of_type(other, constant));
- const constant *o = static_cast<const constant *>(&other);
- return serial==o->serial;
+ GINAC_ASSERT(is_exactly_of_type(other, constant));
+ const constant *o = static_cast<const constant *>(&other);
+ return serial==o->serial;
}
//////////
#endif // ndef NO_NAMESPACE_GINAC
typedef ex (*evalffunctype)(void);
-
+
/** This class holds constants, symbols with specific numerical value. Each
* object of this class must either provide their own function to evaluate it
* to class numeric or provide the constant as a numeric (if it's an exact
* number). */
class constant : public basic
{
- GINAC_DECLARE_REGISTERED_CLASS(constant, basic)
+ GINAC_DECLARE_REGISTERED_CLASS(constant, basic)
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- constant();
- ~constant();
- constant(const constant & other);
- // const constant & operator=(const constant & other); /* it's pervert! */
+ constant();
+ ~constant();
+ constant(const constant & other);
+ // const constant & operator=(const constant & other); /* it's pervert! */
protected:
- void copy(const constant & other);
- void destroy(bool call_parent);
+ void copy(const constant & other);
+ void destroy(bool call_parent);
- // other constructors
+ // other constructors
public:
- constant(const std::string & initname, evalffunctype efun=0);
- constant(const std::string & initname, const numeric & initnumber);
+ constant(const std::string & initname, evalffunctype efun=0);
+ constant(const std::string & initname, const numeric & initnumber);
- // functions overriding virtual functions from bases classes
+ // functions overriding virtual functions from bases classes
public:
- basic * duplicate() 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;
+ basic * duplicate() 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;
protected:
- ex derivative(const symbol & s) const;
- int compare_same_type(const basic & other) const;
- bool is_equal_same_type(const basic & other) const;
-
- // new virtual functions which can be overridden by derived classes
- // none
+ ex derivative(const symbol & s) const;
+ int compare_same_type(const basic & other) const;
+ bool is_equal_same_type(const basic & other) const;
+
+ // new virtual functions which can be overridden by derived classes
+ // none
- // non-virtual functions in this class
- // none
+ // non-virtual functions in this class
+ // none
// member variables
private:
- std::string name;
- evalffunctype ef;
- numeric * number;
- // bool fct_assigned;
- unsigned serial; //!< unique serial number for comparision
- static unsigned next_serial;
+ std::string name;
+ evalffunctype ef;
+ numeric * number;
+ // bool fct_assigned;
+ unsigned serial; //!< unique serial number for comparision
+ static unsigned next_serial;
};
// global constants
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;
+ 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;
- }
+ 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;
+ 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;
+ 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
ex::ex(const basic & other)
{
- debugmsg("ex constructor from basic",LOGLEVEL_CONSTRUCT);
- construct_from_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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ debugmsg("ex constructor from string,lst",LOGLEVEL_CONSTRUCT);
+ construct_from_string_and_lst(s, l);
}
#endif // ndef INLINE_EX_CONSTRUCTORS
/** Swap the contents of two expressions. */
void ex::swap(ex & other)
{
- debugmsg("ex swap",LOGLEVEL_MEMBER_FUNCTION);
+ debugmsg("ex swap",LOGLEVEL_MEMBER_FUNCTION);
- GINAC_ASSERT(bp!=0);
- GINAC_ASSERT(bp->flags & status_flags::dynallocated);
- GINAC_ASSERT(other.bp!=0);
- GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
-
- basic * tmpbp=bp;
- bp=other.bp;
- other.bp=tmpbp;
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(other.bp!=0);
+ GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
+
+ basic * tmpbp=bp;
+ bp=other.bp;
+ other.bp=tmpbp;
}
/** Output formatted to be useful as ginsh input. */
void ex::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("ex print",LOGLEVEL_PRINT);
- GINAC_ASSERT(bp!=0);
- bp->print(os,upper_precedence);
+ debugmsg("ex print",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ bp->print(os,upper_precedence);
}
void ex::printraw(std::ostream & os) const
{
- debugmsg("ex printraw",LOGLEVEL_PRINT);
- GINAC_ASSERT(bp!=0);
- os << "ex(";
- bp->printraw(os);
- os << ")";
+ debugmsg("ex printraw",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ os << "ex(";
+ bp->printraw(os);
+ os << ")";
}
void ex::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("ex printtree",LOGLEVEL_PRINT);
- GINAC_ASSERT(bp!=0);
- // os << "refcount=" << bp->refcount << " ";
- bp->printtree(os,indent);
+ debugmsg("ex printtree",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ // os << "refcount=" << bp->refcount << " ";
+ bp->printtree(os,indent);
}
/** Print expression as a C++ statement. The output looks like
* @param var_name variable name to be printed */
void ex::printcsrc(std::ostream & os, unsigned type, const char *var_name) const
{
- debugmsg("ex print csrc", LOGLEVEL_PRINT);
- GINAC_ASSERT(bp!=0);
- switch (type) {
- case csrc_types::ctype_float:
- os << "float ";
- break;
- case csrc_types::ctype_double:
- os << "double ";
- break;
- case csrc_types::ctype_cl_N:
- os << "cl_N ";
- break;
- }
- os << var_name << " = ";
- bp->printcsrc(os, type, 0);
- os << ";\n";
+ debugmsg("ex print csrc", LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ switch (type) {
+ case csrc_types::ctype_float:
+ os << "float ";
+ break;
+ case csrc_types::ctype_double:
+ os << "double ";
+ break;
+ case csrc_types::ctype_cl_N:
+ os << "cl_N ";
+ break;
+ }
+ os << var_name << " = ";
+ bp->printcsrc(os, type, 0);
+ os << ";\n";
}
/** Little wrapper arount print to be called within a debugger. */
void ex::dbgprint(void) const
{
- debugmsg("ex dbgprint",LOGLEVEL_PRINT);
- GINAC_ASSERT(bp!=0);
- bp->dbgprint();
+ debugmsg("ex dbgprint",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ bp->dbgprint();
}
/** Little wrapper arount printtree to be called within a debugger. */
void ex::dbgprinttree(void) const
{
- debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
- GINAC_ASSERT(bp!=0);
- bp->dbgprinttree();
+ debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ bp->dbgprinttree();
}
bool ex::info(unsigned inf) const
{
- return bp->info(inf);
+ return bp->info(inf);
}
unsigned ex::nops() const
{
- GINAC_ASSERT(bp!=0);
- return bp->nops();
+ GINAC_ASSERT(bp!=0);
+ return bp->nops();
}
ex ex::expand(unsigned options) const
{
- GINAC_ASSERT(bp!=0);
- if (bp->flags & status_flags::expanded)
- return *bp;
- else
- return bp->expand(options);
+ GINAC_ASSERT(bp!=0);
+ if (bp->flags & status_flags::expanded)
+ return *bp;
+ else
+ return bp->expand(options);
}
bool ex::has(const ex & other) const
{
- GINAC_ASSERT(bp!=0);
- return bp->has(other);
+ GINAC_ASSERT(bp!=0);
+ return bp->has(other);
}
int ex::degree(const symbol & s) const
{
- GINAC_ASSERT(bp!=0);
- return bp->degree(s);
+ GINAC_ASSERT(bp!=0);
+ return bp->degree(s);
}
int ex::ldegree(const symbol & s) const
{
- GINAC_ASSERT(bp!=0);
- return bp->ldegree(s);
+ GINAC_ASSERT(bp!=0);
+ return bp->ldegree(s);
}
ex ex::coeff(const symbol & s, int n) const
{
- GINAC_ASSERT(bp!=0);
- return bp->coeff(s,n);
+ GINAC_ASSERT(bp!=0);
+ return bp->coeff(s,n);
}
ex ex::collect(const symbol & s) const
{
- GINAC_ASSERT(bp!=0);
- return bp->collect(s);
+ GINAC_ASSERT(bp!=0);
+ return bp->collect(s);
}
ex ex::eval(int level) const
{
- GINAC_ASSERT(bp!=0);
- return bp->eval(level);
+ GINAC_ASSERT(bp!=0);
+ return bp->eval(level);
}
ex ex::evalf(int level) const
{
- GINAC_ASSERT(bp!=0);
- return bp->evalf(level);
+ GINAC_ASSERT(bp!=0);
+ return bp->evalf(level);
}
/** Compute partial derivative of an expression.
* @return partial derivative as a new expression */
ex ex::diff(const symbol & s, unsigned nth) const
{
- GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
- if (!nth)
- return *this;
- else
- return bp->diff(s, nth);
+ if (!nth)
+ return *this;
+ else
+ return bp->diff(s, nth);
}
ex ex::subs(const lst & ls, const lst & lr) const
{
- GINAC_ASSERT(bp!=0);
- return bp->subs(ls,lr);
+ GINAC_ASSERT(bp!=0);
+ return bp->subs(ls,lr);
}
ex ex::subs(const ex & e) const
{
- GINAC_ASSERT(bp!=0);
- return bp->subs(e);
+ GINAC_ASSERT(bp!=0);
+ return bp->subs(e);
}
exvector ex::get_indices(void) const
{
- GINAC_ASSERT(bp!=0);
- return bp->get_indices();
+ GINAC_ASSERT(bp!=0);
+ return bp->get_indices();
}
ex ex::simplify_ncmul(const exvector & v) const
{
- GINAC_ASSERT(bp!=0);
- return bp->simplify_ncmul(v);
+ GINAC_ASSERT(bp!=0);
+ return bp->simplify_ncmul(v);
}
ex ex::operator[](const ex & index) const
{
- debugmsg("ex operator[ex]",LOGLEVEL_OPERATOR);
- GINAC_ASSERT(bp!=0);
- return (*bp)[index];
+ debugmsg("ex operator[ex]",LOGLEVEL_OPERATOR);
+ GINAC_ASSERT(bp!=0);
+ return (*bp)[index];
}
ex ex::operator[](int i) const
{
- debugmsg("ex operator[int]",LOGLEVEL_OPERATOR);
- GINAC_ASSERT(bp!=0);
- return (*bp)[i];
+ debugmsg("ex operator[int]",LOGLEVEL_OPERATOR);
+ GINAC_ASSERT(bp!=0);
+ return (*bp)[i];
}
/** Return operand/member at position i. */
ex ex::op(int i) const
{
- debugmsg("ex op()",LOGLEVEL_MEMBER_FUNCTION);
- GINAC_ASSERT(bp!=0);
- return bp->op(i);
+ debugmsg("ex op()",LOGLEVEL_MEMBER_FUNCTION);
+ GINAC_ASSERT(bp!=0);
+ return bp->op(i);
}
/** Return modifyable operand/member at position i. */
ex & ex::let_op(int i)
{
- debugmsg("ex let_op()",LOGLEVEL_MEMBER_FUNCTION);
- makewriteable();
- GINAC_ASSERT(bp!=0);
- return bp->let_op(i);
+ debugmsg("ex let_op()",LOGLEVEL_MEMBER_FUNCTION);
+ makewriteable();
+ GINAC_ASSERT(bp!=0);
+ return bp->let_op(i);
}
/** Left hand side of relational expression. */
ex ex::lhs(void) const
{
- debugmsg("ex lhs()",LOGLEVEL_MEMBER_FUNCTION);
- GINAC_ASSERT(is_ex_of_type(*this,relational));
- return (*static_cast<relational *>(bp)).lhs();
+ debugmsg("ex lhs()",LOGLEVEL_MEMBER_FUNCTION);
+ GINAC_ASSERT(is_ex_of_type(*this,relational));
+ return (*static_cast<relational *>(bp)).lhs();
}
/** Right hand side of relational expression. */
ex ex::rhs(void) const
{
- debugmsg("ex rhs()",LOGLEVEL_MEMBER_FUNCTION);
- GINAC_ASSERT(is_ex_of_type(*this,relational));
- return (*static_cast<relational *>(bp)).rhs();
+ debugmsg("ex rhs()",LOGLEVEL_MEMBER_FUNCTION);
+ GINAC_ASSERT(is_ex_of_type(*this,relational));
+ 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);
+ 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);
+ 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);
- return bp->return_type();
+ GINAC_ASSERT(bp!=0);
+ return bp->return_type();
}
unsigned ex::return_type_tinfo(void) const
{
- GINAC_ASSERT(bp!=0);
- return bp->return_type_tinfo();
+ GINAC_ASSERT(bp!=0);
+ return bp->return_type_tinfo();
}
unsigned ex::gethash(void) const
{
- GINAC_ASSERT(bp!=0);
- return bp->gethash();
+ GINAC_ASSERT(bp!=0);
+ return bp->gethash();
}
ex ex::exadd(const ex & rh) const
{
- return (new add(*this,rh))->setflag(status_flags::dynallocated);
+ return (new add(*this,rh))->setflag(status_flags::dynallocated);
}
ex ex::exmul(const ex & rh) const
{
- return (new mul(*this,rh))->setflag(status_flags::dynallocated);
+ return (new mul(*this,rh))->setflag(status_flags::dynallocated);
}
ex ex::exncmul(const ex & rh) const
{
- return (new ncmul(*this,rh))->setflag(status_flags::dynallocated);
+ return (new ncmul(*this,rh))->setflag(status_flags::dynallocated);
}
// private
void ex::makewriteable()
{
- debugmsg("ex makewriteable",LOGLEVEL_MEMBER_FUNCTION);
- GINAC_ASSERT(bp!=0);
- GINAC_ASSERT(bp->flags & status_flags::dynallocated);
- if (bp->refcount > 1) {
- basic * bp2 = bp->duplicate();
- ++bp2->refcount;
- bp2->setflag(status_flags::dynallocated);
- --bp->refcount;
- bp = bp2;
- }
- GINAC_ASSERT(bp->refcount == 1);
+ debugmsg("ex makewriteable",LOGLEVEL_MEMBER_FUNCTION);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+ if (bp->refcount > 1) {
+ basic * bp2 = bp->duplicate();
+ ++bp2->refcount;
+ bp2->setflag(status_flags::dynallocated);
+ --bp->refcount;
+ bp = bp2;
+ }
+ GINAC_ASSERT(bp->refcount == 1);
}
void ex::construct_from_basic(const basic & other)
{
- if ((other.flags & status_flags::evaluated)==0) {
- // cf. copy constructor
- 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)) {
- delete &const_cast<basic &>(other);
- }
- } else {
- if (other.flags & status_flags::dynallocated) {
- // it's on the heap, so just copy bp:
- bp = &const_cast<basic &>(other);
- } else {
- // create a duplicate on the heap:
- bp = other.duplicate();
- bp->setflag(status_flags::dynallocated);
- }
- GINAC_ASSERT(bp!=0);
- // bp->clearflag(status_flags::evaluated);
- ++bp->refcount;
- }
- GINAC_ASSERT(bp!=0);
- GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+ if ((other.flags & status_flags::evaluated)==0) {
+ // cf. copy constructor
+ 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)) {
+ delete &const_cast<basic &>(other);
+ }
+ } else {
+ if (other.flags & status_flags::dynallocated) {
+ // it's on the heap, so just copy bp:
+ bp = &const_cast<basic &>(other);
+ } else {
+ // create a duplicate on the heap:
+ bp = other.duplicate();
+ bp->setflag(status_flags::dynallocated);
+ }
+ GINAC_ASSERT(bp!=0);
+ // bp->clearflag(status_flags::evaluated);
+ ++bp->refcount;
+ }
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
}
void ex::construct_from_int(int i)
{
- switch (i) { // some tiny efficiency-hack
- case -2:
- bp = _ex_2().bp;
- ++bp->refcount;
- break;
- case -1:
- bp = _ex_1().bp;
- ++bp->refcount;
- break;
- case 0:
- bp = _ex0().bp;
- ++bp->refcount;
- break;
- case 1:
- bp = _ex1().bp;
- ++bp->refcount;
- break;
- case 2:
- bp = _ex2().bp;
- ++bp->refcount;
- break;
- default:
- bp = new numeric(i);
- bp->setflag(status_flags::dynallocated);
- ++bp->refcount;
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- GINAC_ASSERT(bp->refcount=1);
- }
-}
-
+ switch (i) { // some tiny efficiency-hack
+ case -2:
+ bp = _ex_2().bp;
+ ++bp->refcount;
+ break;
+ case -1:
+ bp = _ex_1().bp;
+ ++bp->refcount;
+ break;
+ case 0:
+ bp = _ex0().bp;
+ ++bp->refcount;
+ break;
+ case 1:
+ bp = _ex1().bp;
+ ++bp->refcount;
+ break;
+ case 2:
+ bp = _ex2().bp;
+ ++bp->refcount;
+ break;
+ default:
+ bp = new numeric(i);
+ bp->setflag(status_flags::dynallocated);
+ ++bp->refcount;
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+ GINAC_ASSERT(bp->refcount=1);
+ }
+}
+
void ex::construct_from_uint(unsigned int i)
{
- switch (i) { // some tiny efficiency-hack
- case -2:
- bp = _ex_2().bp;
- ++bp->refcount;
- break;
- case -1:
- bp = _ex_1().bp;
- ++bp->refcount;
- break;
- case 0:
- bp = _ex0().bp;
- ++bp->refcount;
- break;
- case 1:
- bp = _ex1().bp;
- ++bp->refcount;
- break;
- case 2:
- bp = _ex2().bp;
- ++bp->refcount;
- break;
- default:
- bp = new numeric(i);
- bp->setflag(status_flags::dynallocated);
- ++bp->refcount;
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- GINAC_ASSERT(bp->refcount=1);
- }
-}
-
+ switch (i) { // some tiny efficiency-hack
+ case -2:
+ bp = _ex_2().bp;
+ ++bp->refcount;
+ break;
+ case -1:
+ bp = _ex_1().bp;
+ ++bp->refcount;
+ break;
+ case 0:
+ bp = _ex0().bp;
+ ++bp->refcount;
+ break;
+ case 1:
+ bp = _ex1().bp;
+ ++bp->refcount;
+ break;
+ case 2:
+ bp = _ex2().bp;
+ ++bp->refcount;
+ break;
+ default:
+ bp = new numeric(i);
+ bp->setflag(status_flags::dynallocated);
+ ++bp->refcount;
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+ GINAC_ASSERT(bp->refcount=1);
+ }
+}
+
void ex::construct_from_long(long i)
{
- switch (i) { // some tiny efficiency-hack
- case -2:
- bp = _ex_2().bp;
- ++bp->refcount;
- break;
- case -1:
- bp = _ex_1().bp;
- ++bp->refcount;
- break;
- case 0:
- bp = _ex0().bp;
- ++bp->refcount;
- break;
- case 1:
- bp = _ex1().bp;
- ++bp->refcount;
- break;
- case 2:
- bp = _ex2().bp;
- ++bp->refcount;
- break;
- default:
- bp = new numeric(i);
- bp->setflag(status_flags::dynallocated);
- ++bp->refcount;
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- GINAC_ASSERT(bp->refcount=1);
- }
-}
-
+ switch (i) { // some tiny efficiency-hack
+ case -2:
+ bp = _ex_2().bp;
+ ++bp->refcount;
+ break;
+ case -1:
+ bp = _ex_1().bp;
+ ++bp->refcount;
+ break;
+ case 0:
+ bp = _ex0().bp;
+ ++bp->refcount;
+ break;
+ case 1:
+ bp = _ex1().bp;
+ ++bp->refcount;
+ break;
+ case 2:
+ bp = _ex2().bp;
+ ++bp->refcount;
+ break;
+ default:
+ bp = new numeric(i);
+ bp->setflag(status_flags::dynallocated);
+ ++bp->refcount;
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+ GINAC_ASSERT(bp->refcount=1);
+ }
+}
+
void ex::construct_from_ulong(unsigned long i)
{
- switch (i) { // some tiny efficiency-hack
- case -2:
- bp = _ex_2().bp;
- ++bp->refcount;
- break;
- case -1:
- bp = _ex_1().bp;
- ++bp->refcount;
- break;
- case 0:
- bp = _ex0().bp;
- ++bp->refcount;
- break;
- case 1:
- bp = _ex1().bp;
- ++bp->refcount;
- break;
- case 2:
- bp = _ex2().bp;
- ++bp->refcount;
- break;
- default:
- bp = new numeric(i);
- bp->setflag(status_flags::dynallocated);
- ++bp->refcount;
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- GINAC_ASSERT(bp->refcount=1);
- }
-}
-
+ switch (i) { // some tiny efficiency-hack
+ case -2:
+ bp = _ex_2().bp;
+ ++bp->refcount;
+ break;
+ case -1:
+ bp = _ex_1().bp;
+ ++bp->refcount;
+ break;
+ case 0:
+ bp = _ex0().bp;
+ ++bp->refcount;
+ break;
+ case 1:
+ bp = _ex1().bp;
+ ++bp->refcount;
+ break;
+ case 2:
+ bp = _ex2().bp;
+ ++bp->refcount;
+ break;
+ default:
+ bp = new numeric(i);
+ bp->setflag(status_flags::dynallocated);
+ ++bp->refcount;
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+ GINAC_ASSERT(bp->refcount=1);
+ }
+}
+
void ex::construct_from_double(double d)
{
- bp = new numeric(d);
- bp->setflag(status_flags::dynallocated);
- ++bp->refcount;
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- GINAC_ASSERT(bp->refcount=1);
+ bp = new numeric(d);
+ bp->setflag(status_flags::dynallocated);
+ ++bp->refcount;
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+ GINAC_ASSERT(bp->refcount=1);
}
void ex::construct_from_string_and_lst(const std::string &s, const ex &l)
{
- set_lexer_string(s);
- set_lexer_symbols(l);
- ginac_yyrestart(NULL);
- if (ginac_yyparse())
- throw (std::runtime_error(get_parser_error()));
- else {
- bp = parsed_ex.bp;
- GINAC_ASSERT(bp!=0);
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- ++bp->refcount;
- }
-}
-
+ set_lexer_string(s);
+ set_lexer_symbols(l);
+ ginac_yyrestart(NULL);
+ if (ginac_yyparse())
+ throw (std::runtime_error(get_parser_error()));
+ else {
+ bp = parsed_ex.bp;
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
+ ++bp->refcount;
+ }
+}
+
//////////
// static member variables
//////////
* provide methods for manipulation of these objects. */
class ex
{
- friend class basic;
+ friend class basic;
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
+ // default constructor, destructor, copy constructor assignment operator and helpers
public:
- ex()
+ 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;
+ : 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();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
- ~ex()
+ ~ex()
#ifdef INLINE_EX_CONSTRUCTORS
- {
- GINAC_ASSERT(bp!=0);
- GINAC_ASSERT(bp->flags & status_flags::dynallocated);
- if (--bp->refcount == 0) {
- delete bp;
- }
- }
+ {
+ 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)
+
+ ex(const ex & other)
#ifdef INLINE_EX_CONSTRUCTORS
- : bp(other.bp)
- {
- GINAC_ASSERT(bp!=0);
- GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
- ++bp->refcount;
+ : 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();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
-
- const ex & operator=(const ex & other)
+
+ 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;
+ {
+ 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();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- return *this;
- }
+ return *this;
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
- // other constructors
+ // other constructors
public:
- ex(const basic & other)
+ ex(const basic & other)
#ifdef INLINE_EX_CONSTRUCTORS
- {
- construct_from_basic(other);
+ {
+ construct_from_basic(other);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
-
- ex(int i)
+
+ ex(int i)
#ifdef INLINE_EX_CONSTRUCTORS
- {
- construct_from_int(i);
+ {
+ construct_from_int(i);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
- ex(unsigned int i)
+ ex(unsigned int i)
#ifdef INLINE_EX_CONSTRUCTORS
- {
- construct_from_uint(i);
+ {
+ construct_from_uint(i);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
-
- ex(long i)
+
+ ex(long i)
#ifdef INLINE_EX_CONSTRUCTORS
- {
- construct_from_long(i);
+ {
+ construct_from_long(i);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
- ex(unsigned long i)
+ ex(unsigned long i)
#ifdef INLINE_EX_CONSTRUCTORS
- {
- construct_from_ulong(i);
+ {
+ construct_from_ulong(i);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
-
- ex(double const d)
+
+ ex(double const d)
#ifdef INLINE_EX_CONSTRUCTORS
- {
- construct_from_double(d);
+ {
+ construct_from_double(d);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
- /** 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)
+ /** 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);
+ {
+ construct_from_string_and_lst(s, l);
#ifdef OBSCURE_CINT_HACK
- update_last_created_or_assigned_bp();
+ update_last_created_or_assigned_bp();
#endif // def OBSCURE_CINT_HACK
- }
+ }
#else
;
#endif // def INLINE_EX_CONSTRUCTORS
-
- // functions overriding virtual functions from bases classes
- // none
-
- // new virtual functions which can be overridden by derived classes
- // none
+
+ // functions overriding virtual functions from bases classes
+ // none
+
+ // new virtual functions which can be overridden by derived classes
+ // none
- // non-virtual functions in this class
+ // non-virtual functions in this class
public:
- void swap(ex & other);
- void printraw(std::ostream & os) const;
- void printtree(std::ostream & os, unsigned indent=0) const;
- void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printcsrc(std::ostream & os, unsigned type, const char *var_name) const;
- void dbgprint(void) const;
- void dbgprinttree(void) const;
- bool info(unsigned inf) const;
- unsigned nops() const;
- ex expand(unsigned options=0) const;
- bool has(const ex & other) const;
- int degree(const symbol & s) const;
- int ldegree(const symbol & s) const;
- ex coeff(const symbol & s, int n=1) const;
- ex lcoeff(const symbol & s) const { return coeff(s, degree(s)); }
- ex tcoeff(const symbol & s) const { return coeff(s, ldegree(s)); }
- ex numer(void) const;
- ex denom(void) const;
- ex unit(const symbol &x) const;
- ex content(const symbol &x) const;
- numeric integer_content(void) const;
- ex primpart(const symbol &x) const;
- ex primpart(const symbol &x, const ex &cont) const;
- ex normal(int level = 0) const;
- ex to_rational(lst &repl_lst) const;
- ex smod(const numeric &xi) const;
- numeric max_coefficient(void) const;
- ex collect(const symbol & s) const;
- ex eval(int level = 0) const;
- ex evalf(int level = 0) const;
- ex diff(const symbol & s, unsigned nth = 1) const;
- ex series(const ex & r, int order, unsigned options = 0) const;
- ex subs(const lst & ls, const lst & lr) const;
- ex subs(const ex & e) const;
- exvector get_indices(void) const;
- ex simplify_ncmul(const exvector & v) const;
- ex operator[](const ex & index) const;
- ex operator[](int i) const;
- ex op(int i) const;
- ex & let_op(int i);
- ex lhs(void) const;
- ex rhs(void) const;
- int compare(const ex & other) const
+ void swap(ex & other);
+ void printraw(std::ostream & os) const;
+ void printtree(std::ostream & os, unsigned indent=0) const;
+ void print(std::ostream & os, unsigned upper_precedence=0) const;
+ void printcsrc(std::ostream & os, unsigned type, const char *var_name) const;
+ void dbgprint(void) const;
+ void dbgprinttree(void) const;
+ bool info(unsigned inf) const;
+ unsigned nops() const;
+ ex expand(unsigned options=0) const;
+ bool has(const ex & other) const;
+ int degree(const symbol & s) const;
+ int ldegree(const symbol & s) const;
+ ex coeff(const symbol & s, int n=1) const;
+ ex lcoeff(const symbol & s) const { return coeff(s, degree(s)); }
+ ex tcoeff(const symbol & s) const { return coeff(s, ldegree(s)); }
+ ex numer(void) const;
+ ex denom(void) const;
+ ex unit(const symbol &x) const;
+ ex content(const symbol &x) const;
+ numeric integer_content(void) const;
+ ex primpart(const symbol &x) const;
+ ex primpart(const symbol &x, const ex &cont) const;
+ ex normal(int level = 0) const;
+ ex to_rational(lst &repl_lst) const;
+ ex smod(const numeric &xi) const;
+ numeric max_coefficient(void) const;
+ ex collect(const symbol & s) const;
+ ex eval(int level = 0) const;
+ ex evalf(int level = 0) const;
+ ex diff(const symbol & s, unsigned nth = 1) const;
+ ex series(const ex & r, int order, unsigned options = 0) const;
+ ex subs(const lst & ls, const lst & lr) const;
+ ex subs(const ex & e) const;
+ exvector get_indices(void) const;
+ ex simplify_ncmul(const exvector & v) const;
+ ex operator[](const ex & index) const;
+ ex operator[](int i) const;
+ ex op(int i) const;
+ 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);
- }
+ {
+ 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
+ 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);
- }
+ {
+ 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;};
-
- 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;
+ bool is_zero(void) const {return compare(_ex0())==0;};
+
+ 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;
private:
- void construct_from_basic(const basic & other);
- void construct_from_int(int i);
- void construct_from_uint(unsigned int i);
- void construct_from_long(long i);
- void construct_from_ulong(unsigned long i);
- void construct_from_double(double d);
- void construct_from_string_and_lst(const std::string &s, const ex &l);
- void makewriteable();
+ void construct_from_basic(const basic & other);
+ void construct_from_int(int i);
+ void construct_from_uint(unsigned int i);
+ void construct_from_long(long i);
+ void construct_from_ulong(unsigned long i);
+ void construct_from_double(double d);
+ void construct_from_string_and_lst(const std::string &s, const ex &l);
+ void makewriteable();
#ifdef OBSCURE_CINT_HACK
public:
- static bool last_created_or_assigned_bp_can_be_converted_to_ex(void)
- {
- if (last_created_or_assigned_bp==0) return false;
- if ((last_created_or_assigned_bp->flags &
- status_flags::dynallocated)==0) return false;
- if ((last_created_or_assigned_bp->flags &
- status_flags::evaluated)==0) return false;
- return true;
- }
+ static bool last_created_or_assigned_bp_can_be_converted_to_ex(void)
+ {
+ if (last_created_or_assigned_bp==0) return false;
+ if ((last_created_or_assigned_bp->flags &
+ status_flags::dynallocated)==0) return false;
+ if ((last_created_or_assigned_bp->flags &
+ status_flags::evaluated)==0) return false;
+ return true;
+ }
protected:
- void update_last_created_or_assigned_bp(void)
- {
- if (last_created_or_assigned_bp!=0) {
- if (--last_created_or_assigned_bp->refcount == 0) {
- delete last_created_or_assigned_bp;
- }
- }
- last_created_or_assigned_bp=bp;
- ++last_created_or_assigned_bp->refcount;
- last_created_or_assigned_exp=(long)(void *)(this);
- }
+ void update_last_created_or_assigned_bp(void)
+ {
+ if (last_created_or_assigned_bp!=0) {
+ if (--last_created_or_assigned_bp->refcount == 0) {
+ delete last_created_or_assigned_bp;
+ }
+ }
+ last_created_or_assigned_bp=bp;
+ ++last_created_or_assigned_bp->refcount;
+ last_created_or_assigned_exp=(long)(void *)(this);
+ }
#endif // def OBSCURE_CINT_HACK
// member variables
public:
- basic *bp;
+ basic *bp;
#ifdef OBSCURE_CINT_HACK
- static basic * last_created_or_assigned_bp;
- static basic * dummy_bp;
- static long last_created_or_assigned_exp;
+ static basic * last_created_or_assigned_bp;
+ static basic * dummy_bp;
+ static long last_created_or_assigned_exp;
#endif // def OBSCURE_CINT_HACK
};
class expair
{
public:
- expair() {}
- ~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;
- }
- return *this;
- }
- 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)));
- }
+ expair() {}
+ ~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;
+ }
+ return *this;
+ }
+ 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)));
+ }
- bool is_equal(const expair & other) const
- {
- return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
- }
- bool is_less(const expair & other) const
- {
- return (rest.compare(other.rest)<0) ||
- (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
- }
- 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_equal(const expair & other) const
+ {
+ return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
+ }
+ bool is_less(const expair & other) const
+ {
+ return (rest.compare(other.rest)<0) ||
+ (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
+ }
+ 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 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;
- }
+ 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 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;
+ }
- void printraw(std::ostream & os) const
- {
- os << "expair(";
- rest.printraw(os);
- os << ",";
- coeff.printraw(os);
- os << ")";
- }
+ void printraw(std::ostream & os) const
+ {
+ os << "expair(";
+ rest.printraw(os);
+ os << ",";
+ coeff.printraw(os);
+ os << ")";
+ }
- ex rest;
- ex coeff;
+ ex rest;
+ ex coeff;
};
class expair_is_less
{
public:
- bool operator()(const expair & lh, const expair & rh) const
- {
- return lh.is_less(rh);
- }
+ bool operator()(const expair & lh, const expair & rh) const
+ {
+ return lh.is_less(rh);
+ }
};
class expair_is_less_old
{
public:
- bool operator()(const expair & lh, const expair & rh) const
- {
- return lh.is_less_old(rh);
- }
+ bool operator()(const expair & lh, const expair & rh) const
+ {
+ return lh.is_less_old(rh);
+ }
};
#ifndef NO_NAMESPACE_GINAC
class epp_is_less
{
public:
- bool operator()(const epp & lh, const epp & rh) const
- {
- return (*lh).is_less(*rh);
- }
+ bool operator()(const epp & lh, const epp & rh) const
+ {
+ return (*lh).is_less(*rh);
+ }
};
//////////
expairseq::expairseq(const expairseq & other)
{
- debugmsg("expairseq copy constructor",LOGLEVEL_CONSTRUCT);
- copy(other);
+ debugmsg("expairseq copy constructor",LOGLEVEL_CONSTRUCT);
+ copy(other);
}
const expairseq & expairseq::operator=(const expairseq & other)
{
- debugmsg("expairseq operator=",LOGLEVEL_ASSIGNMENT);
- if (this != &other) {
- destroy(1);
- copy(other);
- }
- return *this;
+ debugmsg("expairseq operator=",LOGLEVEL_ASSIGNMENT);
+ if (this != &other) {
+ destroy(1);
+ copy(other);
+ }
+ return *this;
}
// protected
void expairseq::copy(const expairseq & other)
{
- inherited::copy(other);
- seq=other.seq;
- overall_coeff=other.overall_coeff;
+ inherited::copy(other);
+ seq=other.seq;
+ overall_coeff=other.overall_coeff;
#ifdef EXPAIRSEQ_USE_HASHTAB
- // copy hashtab
- hashtabsize=other.hashtabsize;
- if (hashtabsize!=0) {
- hashmask=other.hashmask;
- hashtab.resize(hashtabsize);
- 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();
- cit!=other.hashtab[i].end(); ++cit) {
- hashtab[i].push_back(seq.begin()+((*cit)-osb));
- }
- }
- } else {
- hashtab.clear();
- }
+ // copy hashtab
+ hashtabsize=other.hashtabsize;
+ if (hashtabsize!=0) {
+ hashmask=other.hashmask;
+ hashtab.resize(hashtabsize);
+ 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();
+ cit!=other.hashtab[i].end(); ++cit) {
+ hashtab[i].push_back(seq.begin()+((*cit)-osb));
+ }
+ }
+ } else {
+ hashtab.clear();
+ }
#endif // def EXPAIRSEQ_USE_HASHTAB
}
expairseq::expairseq(const ex & lh, const ex & rh) : inherited(TINFO_expairseq)
{
- debugmsg("expairseq constructor from ex,ex",LOGLEVEL_CONSTRUCT);
- construct_from_2_ex(lh,rh);
- GINAC_ASSERT(is_canonical());
+ debugmsg("expairseq constructor from ex,ex",LOGLEVEL_CONSTRUCT);
+ construct_from_2_ex(lh,rh);
+ GINAC_ASSERT(is_canonical());
}
expairseq::expairseq(const exvector & v) : inherited(TINFO_expairseq)
{
- debugmsg("expairseq constructor from exvector",LOGLEVEL_CONSTRUCT);
- construct_from_exvector(v);
- GINAC_ASSERT(is_canonical());
+ debugmsg("expairseq constructor from exvector",LOGLEVEL_CONSTRUCT);
+ construct_from_exvector(v);
+ GINAC_ASSERT(is_canonical());
}
/*
expairseq::expairseq(const epvector & v, bool do_not_canonicalize) :
- inherited(TINFO_expairseq)
+ inherited(TINFO_expairseq)
{
- debugmsg("expairseq constructor from epvector",LOGLEVEL_CONSTRUCT);
- if (do_not_canonicalize) {
- seq=v;
+ debugmsg("expairseq constructor from epvector",LOGLEVEL_CONSTRUCT);
+ if (do_not_canonicalize) {
+ seq=v;
#ifdef EXPAIRSEQ_USE_HASHTAB
- combine_same_terms(); // to build hashtab
+ combine_same_terms(); // to build hashtab
#endif // def EXPAIRSEQ_USE_HASHTAB
- } else {
- construct_from_epvector(v);
- }
- GINAC_ASSERT(is_canonical());
+ } else {
+ construct_from_epvector(v);
+ }
+ GINAC_ASSERT(is_canonical());
}
*/
expairseq::expairseq(const epvector & v, const ex & oc) :
- inherited(TINFO_expairseq), overall_coeff(oc)
+ inherited(TINFO_expairseq), overall_coeff(oc)
{
- debugmsg("expairseq constructor from epvector,ex",LOGLEVEL_CONSTRUCT);
- construct_from_epvector(v);
- GINAC_ASSERT(is_canonical());
+ debugmsg("expairseq constructor from epvector,ex",LOGLEVEL_CONSTRUCT);
+ construct_from_epvector(v);
+ GINAC_ASSERT(is_canonical());
}
expairseq::expairseq(epvector * vp, const ex & oc) :
- inherited(TINFO_expairseq), overall_coeff(oc)
+ inherited(TINFO_expairseq), overall_coeff(oc)
{
- debugmsg("expairseq constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
- GINAC_ASSERT(vp!=0);
- construct_from_epvector(*vp);
- delete vp;
- GINAC_ASSERT(is_canonical());
+ debugmsg("expairseq constructor from epvector *,ex",LOGLEVEL_CONSTRUCT);
+ GINAC_ASSERT(vp!=0);
+ construct_from_epvector(*vp);
+ delete vp;
+ GINAC_ASSERT(is_canonical());
}
//////////
/** Construct object from archive_node. */
expairseq::expairseq(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
#ifdef EXPAIRSEQ_USE_HASHTAB
- , hashtabsize(0)
+ , hashtabsize(0)
#endif
{
- debugmsg("expairseq constructor from archive_node", LOGLEVEL_CONSTRUCT);
- for (unsigned int i=0; true; i++) {
- ex rest;
- ex coeff;
- if (n.find_ex("rest", rest, sym_lst, i) && n.find_ex("coeff", coeff, sym_lst, i))
- seq.push_back(expair(rest, coeff));
- else
- break;
- }
- n.find_ex("overall_coeff", overall_coeff, sym_lst);
+ debugmsg("expairseq constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ for (unsigned int i=0; true; i++) {
+ ex rest;
+ ex coeff;
+ if (n.find_ex("rest", rest, sym_lst, i) && n.find_ex("coeff", coeff, sym_lst, i))
+ seq.push_back(expair(rest, coeff));
+ else
+ break;
+ }
+ n.find_ex("overall_coeff", overall_coeff, sym_lst);
}
/** Unarchive the object. */
ex expairseq::unarchive(const archive_node &n, const lst &sym_lst)
{
- return (new expairseq(n, sym_lst))->setflag(status_flags::dynallocated);
+ return (new expairseq(n, sym_lst))->setflag(status_flags::dynallocated);
}
/** Archive the object. */
void expairseq::archive(archive_node &n) const
{
- inherited::archive(n);
- epvector::const_iterator i = seq.begin(), iend = seq.end();
- while (i != iend) {
- n.add_ex("rest", i->rest);
- n.add_ex("coeff", i->coeff);
- i++;
- }
- n.add_ex("overall_coeff", overall_coeff);
+ inherited::archive(n);
+ epvector::const_iterator i = seq.begin(), iend = seq.end();
+ while (i != iend) {
+ n.add_ex("rest", i->rest);
+ n.add_ex("coeff", i->coeff);
+ i++;
+ }
+ n.add_ex("overall_coeff", overall_coeff);
}
//////////
basic * expairseq::duplicate() const
{
- debugmsg("expairseq duplicate",LOGLEVEL_DUPLICATE);
- return new expairseq(*this);
+ debugmsg("expairseq duplicate",LOGLEVEL_DUPLICATE);
+ return new expairseq(*this);
}
void expairseq::print(std::ostream & os, unsigned upper_precedence) const
{
- debugmsg("expairseq print",LOGLEVEL_PRINT);
- os << "[[";
- printseq(os,',',precedence,upper_precedence);
- os << "]]";
+ debugmsg("expairseq print",LOGLEVEL_PRINT);
+ os << "[[";
+ printseq(os,',',precedence,upper_precedence);
+ os << "]]";
}
void expairseq::printraw(std::ostream & os) const
{
- debugmsg("expairseq printraw",LOGLEVEL_PRINT);
+ debugmsg("expairseq printraw",LOGLEVEL_PRINT);
- os << "expairseq(";
- for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
- os << "(";
- (*cit).rest.printraw(os);
- os << ",";
- (*cit).coeff.printraw(os);
- os << "),";
- }
- os << ")";
+ os << "expairseq(";
+ for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
+ os << "(";
+ (*cit).rest.printraw(os);
+ os << ",";
+ (*cit).coeff.printraw(os);
+ os << "),";
+ }
+ os << ")";
}
void expairseq::printtree(std::ostream & os, unsigned indent) const
{
- debugmsg("expairseq printtree",LOGLEVEL_PRINT);
-
- os << std::string(indent,' ') << "type=" << typeid(*this).name()
- << ", hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags
- << ", nops=" << nops() << std::endl;
- for (unsigned i=0; i<seq.size(); ++i) {
- seq[i].rest.printtree(os,indent+delta_indent);
- seq[i].coeff.printtree(os,indent+delta_indent);
- if (i!=seq.size()-1) {
- os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
- }
- }
- if (!overall_coeff.is_equal(default_overall_coeff())) {
- os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
- os << std::string(indent+delta_indent,' ') << "overall_coeff" << std::endl;
- overall_coeff.printtree(os,indent+delta_indent);
- }
- os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
+ debugmsg("expairseq printtree",LOGLEVEL_PRINT);
+
+ os << std::string(indent,' ') << "type=" << class_name()
+ << ", hash=" << hashvalue
+ << " (0x" << std::hex << hashvalue << std::dec << ")"
+ << ", flags=" << flags
+ << ", nops=" << nops() << std::endl;
+ for (unsigned i=0; i<seq.size(); ++i) {
+ seq[i].rest.printtree(os,indent+delta_indent);
+ seq[i].coeff.printtree(os,indent+delta_indent);
+ if (i!=seq.size()-1) {
+ os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
+ }
+ }
+ if (!overall_coeff.is_equal(default_overall_coeff())) {
+ os << std::string(indent+delta_indent,' ') << "-----" << std::endl;
+ os << std::string(indent+delta_indent,' ') << "overall_coeff" << std::endl;
+ overall_coeff.printtree(os,indent+delta_indent);
+ }
+ os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
#ifdef EXPAIRSEQ_USE_HASHTAB
- os << std::string(indent+delta_indent,' ')
- << "hashtab size " << hashtabsize << std::endl;
- if (hashtabsize==0) return;
+ 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;
- unsigned this_bin_fill;
- unsigned cum_fill_sq = 0;
- unsigned cum_fill = 0;
- for (unsigned i=0; i<hashtabsize; ++i) {
- this_bin_fill=0;
- if (hashtab[i].size()>0) {
- os << std::string(indent+delta_indent,' ')
- << "bin " << i << " with entries ";
- for (epplist::const_iterator it=hashtab[i].begin();
- it!=hashtab[i].end(); ++it) {
- os << *it-seq.begin() << " ";
- this_bin_fill++;
- }
- os << std::endl;
- cum_fill += this_bin_fill;
- cum_fill_sq += this_bin_fill*this_bin_fill;
- }
- if (this_bin_fill<MAXCOUNT) {
- ++count[this_bin_fill];
- } else {
- ++count[MAXCOUNT];
- }
- }
- unsigned fact = 1;
- double cum_prob = 0;
- double lambda = (1.0*seq.size())/hashtabsize;
- for (int k=0; k<MAXCOUNT; ++k) {
- if (k>0) fact *= k;
- double prob = pow(lambda,k)/fact*exp(-lambda);
- cum_prob += prob;
- os << std::string(indent+delta_indent,' ') << "bins with " << k << " entries: "
- << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
- << int(prob*1000)/10.0 << ")" << std::endl;
- }
- os << std::string(indent+delta_indent,' ') << "bins with more entries: "
- << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
- << int((1-cum_prob)*1000)/10.0 << ")" << std::endl;
-
- os << std::string(indent+delta_indent,' ') << "variance: "
- << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
- << std::endl;
- os << std::string(indent+delta_indent,' ') << "average fill: "
- << (1.0*cum_fill)/hashtabsize
- << " (should be equal to " << (1.0*seq.size())/hashtabsize << ")" << std::endl;
+ unsigned count[MAXCOUNT+1];
+ for (int i=0; i<MAXCOUNT+1; ++i) count[i]=0;
+ unsigned this_bin_fill;
+ unsigned cum_fill_sq = 0;
+ unsigned cum_fill = 0;
+ for (unsigned i=0; i<hashtabsize; ++i) {
+ this_bin_fill=0;
+ if (hashtab[i].size()>0) {
+ os << std::string(indent+delta_indent,' ')
+ << "bin " << i << " with entries ";
+ for (epplist::const_iterator it=hashtab[i].begin();
+ it!=hashtab[i].end(); ++it) {
+ os << *it-seq.begin() << " ";
+ this_bin_fill++;
+ }
+ os << std::endl;
+ cum_fill += this_bin_fill;
+ cum_fill_sq += this_bin_fill*this_bin_fill;
+ }
+ if (this_bin_fill<MAXCOUNT) {
+ ++count[this_bin_fill];
+ } else {
+ ++count[MAXCOUNT];
+ }
+ }
+ unsigned fact = 1;
+ double cum_prob = 0;
+ double lambda = (1.0*seq.size())/hashtabsize;
+ for (int k=0; k<MAXCOUNT; ++k) {
+ if (k>0) fact *= k;
+ double prob = pow(lambda,k)/fact*exp(-lambda);
+ cum_prob += prob;
+ os << std::string(indent+delta_indent,' ') << "bins with " << k << " entries: "
+ << int(1000.0*count[k]/hashtabsize)/10.0 << "% (expected: "
+ << int(prob*1000)/10.0 << ")" << std::endl;
+ }
+ os << std::string(indent+delta_indent,' ') << "bins with more entries: "
+ << int(1000.0*count[MAXCOUNT]/hashtabsize)/10.0 << "% (expected: "
+ << int((1-cum_prob)*1000)/10.0 << ")" << std::endl;
+
+ os << std::string(indent+delta_indent,' ') << "variance: "
+ << 1.0/hashtabsize*cum_fill_sq-(1.0/hashtabsize*cum_fill)*(1.0/hashtabsize*cum_fill)
+ << std::endl;
+ 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
}
bool expairseq::info(unsigned inf) const
{
- return inherited::info(inf);
+ return inherited::info(inf);
}
unsigned expairseq::nops() const
{
- if (overall_coeff.is_equal(default_overall_coeff())) {
- return seq.size();
- }
- return seq.size()+1;
+ if (overall_coeff.is_equal(default_overall_coeff())) {
+ return seq.size();
+ }
+ return seq.size()+1;
}
ex expairseq::op(int i) const
{
- if (unsigned(i)<seq.size()) {
- return recombine_pair_to_ex(seq[i]);
- }
- GINAC_ASSERT(!overall_coeff.is_equal(default_overall_coeff()));
- return overall_coeff;
+ 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)
{
- throw(std::logic_error("let_op not defined for expairseq and derived classes (add,mul,...)"));
+ 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)) {
- return *this;
- }
+ if ((level==1)&&(flags & status_flags::evaluated)) {
+ return *this;
+ }
- epvector * vp=evalchildren(level);
- if (vp==0) {
- return this->hold();
- }
+ epvector * vp=evalchildren(level);
+ if (vp==0) {
+ return this->hold();
+ }
- return (new expairseq(vp,overall_coeff))
- ->setflag(status_flags::dynallocated |
- status_flags::evaluated );
+ return (new expairseq(vp,overall_coeff))
+ ->setflag(status_flags::dynallocated |
+ status_flags::evaluated );
}
ex expairseq::evalf(int level) const
{
- return thisexpairseq(evalfchildren(level),overall_coeff.evalf(level-1));
+ return thisexpairseq(evalfchildren(level),overall_coeff.evalf(level-1));
}
ex expairseq::normal(lst &sym_lst, lst &repl_lst, int level) const
{
- ex n = thisexpairseq(normalchildren(level),overall_coeff);
- return n.bp->basic::normal(sym_lst,repl_lst,level);
+ ex n = thisexpairseq(normalchildren(level),overall_coeff);
+ return n.bp->basic::normal(sym_lst,repl_lst,level);
}
ex expairseq::subs(const lst & ls, const lst & lr) const
{
- epvector * vp=subschildren(ls,lr);
- if (vp==0) {
- return *this;
- }
- return thisexpairseq(vp,overall_coeff);
+ epvector * vp=subschildren(ls,lr);
+ if (vp==0) {
+ return *this;
+ }
+ return thisexpairseq(vp,overall_coeff);
}
// protected
* @see ex::diff */
ex expairseq::derivative(const symbol & s) const
{
- return thisexpairseq(diffchildren(s),overall_coeff);
+ return thisexpairseq(diffchildren(s),overall_coeff);
}
int expairseq::compare_same_type(const basic & other) const
{
- GINAC_ASSERT(is_of_type(other, expairseq));
- const expairseq & o = static_cast<const expairseq &>(const_cast<basic &>(other));
+ GINAC_ASSERT(is_of_type(other, expairseq));
+ const expairseq & o = static_cast<const expairseq &>(const_cast<basic &>(other));
- int cmpval;
-
- // compare number of elements
- if (seq.size() != o.seq.size()) {
- return (seq.size()<o.seq.size()) ? -1 : 1;
- }
+ int cmpval;
+
+ // compare number of elements
+ 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;
+ // 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
+ //if (seq.size()==0) return 0; // empty expairseq's are equal
#ifdef EXPAIRSEQ_USE_HASHTAB
- GINAC_ASSERT(hashtabsize==o.hashtabsize);
- if (hashtabsize==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();
- epvector::const_iterator last2 = o.seq.end();
-
- for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
- cmpval = (*cit1).compare(*cit2);
- if (cmpval!=0) return cmpval;
- }
-
- GINAC_ASSERT(cit1==last1);
- GINAC_ASSERT(cit2==last2);
-
- return 0;
+ epvector::const_iterator cit1 = seq.begin();
+ epvector::const_iterator cit2 = o.seq.begin();
+ epvector::const_iterator last1 = seq.end();
+ epvector::const_iterator last2 = o.seq.end();
+
+ for (; (cit1!=last1)&&(cit2!=last2); ++cit1, ++cit2) {
+ cmpval = (*cit1).compare(*cit2);
+ if (cmpval!=0) return cmpval;
+ }
+
+ GINAC_ASSERT(cit1==last1);
+ GINAC_ASSERT(cit2==last2);
+
+ return 0;
#ifdef 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()) {
- 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();
- 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();
- while (it1!=eppl1.end()) {
- cmpval=(*(*it1)).compare(*(*it2));
- if (cmpval!=0) return cmpval;
- ++it1;
- ++it2;
- }
- }
- }
-
- return 0; // equal
+ }
+
+ // 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()) {
+ 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();
+ 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();
+ while (it1!=eppl1.end()) {
+ cmpval=(*(*it1)).compare(*(*it2));
+ if (cmpval!=0) return cmpval;
+ ++it1;
+ ++it2;
+ }
+ }
+ }
+
+ return 0; // equal
#endif // def EXPAIRSEQ_USE_HASHTAB
}
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;
+ // compare number of elements
+ if (seq.size() != o.seq.size()) return false;
- // compare overall_coeff
- if (!overall_coeff.is_equal(o.overall_coeff)) return false;
+ // compare overall_coeff
+ if (!overall_coeff.is_equal(o.overall_coeff)) return false;
#ifdef 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);
- }
-
- GINAC_ASSERT(hashtabsize==o.hashtabsize);
-
- if (hashtabsize==0) {
+ // 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);
+ }
+
+ 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();
-
- while (cit1!=last1) {
- if (!(*cit1).is_equal(*cit2)) return false;
- ++cit1;
- ++cit2;
- }
-
- return true;
+ 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;
+ ++cit1;
+ ++cit2;
+ }
+
+ return true;
#ifdef EXPAIRSEQ_USE_HASHTAB
- }
-
- for (unsigned i=0; i<hashtabsize; ++i) {
- 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();
- 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();
- while (it1!=eppl1.end()) {
- if (!(*(*it1)).is_equal(*(*it2))) return false;
- ++it1;
- ++it2;
- }
- }
- }
-
- return true;
+ }
+
+ for (unsigned i=0; i<hashtabsize; ++i) {
+ 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();
+ 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();
+ while (it1!=eppl1.end()) {
+ if (!(*(*it1)).is_equal(*(*it2))) return false;
+ ++it1;
+ ++it2;
+ }
+ }
+ }
+
+ return true;
#endif // def EXPAIRSEQ_USE_HASHTAB
}
unsigned expairseq::return_type(void) const
{
- return return_types::noncommutative_composite;
+ return return_types::noncommutative_composite;
}
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) {
+ 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
+ v=rotate_left_31(v); // rotation would spoil commutativity
#endif // ndef EXPAIRSEQ_USE_HASHTAB
- v ^= (*cit).rest.gethash();
- }
+ v ^= (*cit).rest.gethash();
+ }
- v ^= overall_coeff.gethash();
- v=v & 0x7FFFFFFFU;
-
- // store calculated hash value only if object is already evaluated
- if (flags & status_flags::evaluated) {
- setflag(status_flags::hash_calculated);
- hashvalue=v;
- }
+ v ^= overall_coeff.gethash();
+ v=v & 0x7FFFFFFFU;
+
+ // store calculated hash value only if object is already evaluated
+ if (flags & status_flags::evaluated) {
+ setflag(status_flags::hash_calculated);
+ hashvalue=v;
+ }
- return v;
+ return v;
}
ex expairseq::expand(unsigned options) const
{
- epvector * vp = expandchildren(options);
- if (vp==0) {
- return *this;
- }
- return thisexpairseq(vp,overall_coeff);
+ epvector * vp = expandchildren(options);
+ if (vp==0) {
+ return *this;
+ }
+ return thisexpairseq(vp,overall_coeff);
}
//////////
ex expairseq::thisexpairseq(const epvector & v, const ex & oc) const
{
- return expairseq(v,oc);
+ return expairseq(v,oc);
}
ex expairseq::thisexpairseq(epvector * vp, const ex & oc) const
{
- return expairseq(vp,oc);
+ return expairseq(vp,oc);
}
void expairseq::printpair(std::ostream & os, const expair & p, unsigned upper_precedence) const
{
- os << "[[";
- p.rest.bp->print(os,precedence);
- os << ",";
- p.coeff.bp->print(os,precedence);
- os << "]]";
+ os << "[[";
+ p.rest.bp->print(os,precedence);
+ os << ",";
+ p.coeff.bp->print(os,precedence);
+ os << "]]";
}
void expairseq::printseq(std::ostream & os, char delim,
- unsigned this_precedence,
- unsigned upper_precedence) const
-{
- if (this_precedence<=upper_precedence) os << "(";
- epvector::const_iterator it,it_last;
- it_last=seq.end();
- --it_last;
- for (it=seq.begin(); it!=it_last; ++it) {
- printpair(os,*it,this_precedence);
- os << delim;
- }
- printpair(os,*it,this_precedence);
- if (!overall_coeff.is_equal(default_overall_coeff())) {
- os << delim << overall_coeff;
- }
- if (this_precedence<=upper_precedence) os << ")";
-}
-
+ unsigned this_precedence,
+ unsigned upper_precedence) const
+{
+ if (this_precedence<=upper_precedence) os << "(";
+ epvector::const_iterator it,it_last;
+ it_last=seq.end();
+ --it_last;
+ for (it=seq.begin(); it!=it_last; ++it) {
+ printpair(os,*it,this_precedence);
+ os << delim;
+ }
+ printpair(os,*it,this_precedence);
+ if (!overall_coeff.is_equal(default_overall_coeff())) {
+ os << delim << overall_coeff;
+ }
+ if (this_precedence<=upper_precedence) os << ")";
+}
+
expair expairseq::split_ex_to_pair(const ex & e) const
{
- return expair(e,_ex1());
+ return expair(e,_ex1());
}
expair expairseq::combine_ex_with_coeff_to_pair(const ex & e,
- const ex & c) const
+ const ex & c) const
{
- GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
- return expair(e,c);
+ return expair(e,c);
}
expair expairseq::combine_pair_with_coeff_to_pair(const expair & p,
- const ex & c) const
+ const ex & c) const
{
- GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
- GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
-
- return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
+ GINAC_ASSERT(is_ex_exactly_of_type(p.coeff,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
+
+ return expair(p.rest,ex_to_numeric(p.coeff).mul_dyn(ex_to_numeric(c)));
}
ex expairseq::recombine_pair_to_ex(const expair & p) const
{
- return lst(p.rest,p.coeff);
+ return lst(p.rest,p.coeff);
}
bool expairseq::expair_needs_further_processing(epp it)
{
- return false;
+ return false;
}
ex expairseq::default_overall_coeff(void) const
{
- return _ex0();
+ return _ex0();
}
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));
+ 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)
{
- GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
- GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
- overall_coeff = ex_to_numeric(overall_coeff).
- add_dyn(ex_to_numeric(c1).mul(ex_to_numeric(c2)));
+ GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
+ GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
+ overall_coeff = ex_to_numeric(overall_coeff).
+ add_dyn(ex_to_numeric(c1).mul(ex_to_numeric(c2)));
}
bool expairseq::can_make_flat(const expair & p) const
{
- return true;
+ return true;
}
-
+
//////////
// non-virtual functions in this class
//////////
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);
+ exvector v;
+ v.reserve(2);
+ v.push_back(lh);
+ v.push_back(rh);
+ construct_from_exvector(v);
#ifdef EXPAIRSEQ_USE_HASHTAB
- GINAC_ASSERT((hashtabsize==0)||(hashtabsize>=minhashtabsize));
- GINAC_ASSERT(hashtabsize==calc_hashtabsize(seq.size()));
+ GINAC_ASSERT((hashtabsize==0)||(hashtabsize>=minhashtabsize));
+ GINAC_ASSERT(hashtabsize==calc_hashtabsize(seq.size()));
#endif // def EXPAIRSEQ_USE_HASHTAB
}
void expairseq::construct_from_2_ex(const ex & lh, const ex & rh)
{
- if (lh.bp->tinfo()==tinfo()) {
- if (rh.bp->tinfo()==tinfo()) {
+ if (lh.bp->tinfo()==tinfo()) {
+ if (rh.bp->tinfo()==tinfo()) {
#ifdef 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 {
+ 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
- construct_from_2_expairseq(ex_to_expairseq(lh),
- ex_to_expairseq(rh));
+ construct_from_2_expairseq(ex_to_expairseq(lh),
+ ex_to_expairseq(rh));
#ifdef EXPAIRSEQ_USE_HASHTAB
- }
+ }
#endif // def EXPAIRSEQ_USE_HASHTAB
- return;
- } else {
+ return;
+ } else {
#ifdef 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 {
+ 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
- construct_from_expairseq_ex(ex_to_expairseq(lh),rh);
+ construct_from_expairseq_ex(ex_to_expairseq(lh),rh);
#ifdef EXPAIRSEQ_USE_HASHTAB
- }
+ }
#endif // def EXPAIRSEQ_USE_HASHTAB
- return;
- }
- } else if (rh.bp->tinfo()==tinfo()) {
+ return;
+ }
+ } else if (rh.bp->tinfo()==tinfo()) {
#ifdef 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 {
+ 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
- construct_from_expairseq_ex(ex_to_expairseq(rh),lh);
+ construct_from_expairseq_ex(ex_to_expairseq(rh),lh);
#ifdef EXPAIRSEQ_USE_HASHTAB
- }
+ }
#endif // def EXPAIRSEQ_USE_HASHTAB
- return;
- }
+ return;
+ }
#ifdef EXPAIRSEQ_USE_HASHTAB
- if (calc_hashtabsize(2)!=0) {
- construct_from_2_ex_via_exvector(lh,rh);
- return;
- }
- hashtabsize=0;
+ if (calc_hashtabsize(2)!=0) {
+ construct_from_2_ex_via_exvector(lh,rh);
+ return;
+ }
+ hashtabsize=0;
#endif // def EXPAIRSEQ_USE_HASHTAB
-
- if (is_ex_exactly_of_type(lh,numeric)) {
- if (is_ex_exactly_of_type(rh,numeric)) {
- combine_overall_coeff(lh);
- combine_overall_coeff(rh);
- } else {
- combine_overall_coeff(lh);
- seq.push_back(split_ex_to_pair(rh));
- }
- } else {
- if (is_ex_exactly_of_type(rh,numeric)) {
- 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);
- 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()) {
- // no further processing is necessary, since this
- // one element will usually be recombined in eval()
- seq.push_back(p1);
- }
- } else {
- seq.reserve(2);
- if (cmpval<0) {
- seq.push_back(p1);
- seq.push_back(p2);
- } else {
- seq.push_back(p2);
- seq.push_back(p1);
- }
- }
- }
- }
+
+ if (is_ex_exactly_of_type(lh,numeric)) {
+ if (is_ex_exactly_of_type(rh,numeric)) {
+ combine_overall_coeff(lh);
+ combine_overall_coeff(rh);
+ } else {
+ combine_overall_coeff(lh);
+ seq.push_back(split_ex_to_pair(rh));
+ }
+ } else {
+ if (is_ex_exactly_of_type(rh,numeric)) {
+ 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);
+ 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()) {
+ // no further processing is necessary, since this
+ // one element will usually be recombined in eval()
+ seq.push_back(p1);
+ &