From: Richard Kreckel Date: Thu, 22 Mar 2001 21:24:32 +0000 (+0000) Subject: * Eliminated overloaded operator% for noncommunistic objects for good. X-Git-Tag: release_0-8-0~9 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=b1f684b10d31daafc4e4a5bdaee02ba455abe747;ds=sidebyside * Eliminated overloaded operator% for noncommunistic objects for good. End of story. There was just too much risk involved in somebody not caring enough whether there are noncommutatating objects inside expressions to be multiplied and it could potentially end up in people using operator% instead of operator* all the time, just to be safe. In any case, it was our firm believe that noncommutatividity is a property of the class objects belong to and hence of the objects and not at all of the sign to symbol the object (as Maple, Reduce and others want to make us believe). Finally we found out how to code operator* so that it handles both cases without any performance loss. It couldn't be less intrusive! There is no measurable performance degradation. (Except perhaps for the tgamma-expansion which seems to show some 3% loss while others mysteriously become somewhat faster -- my brain is melting.) Enough, now... --- diff --git a/NEWS b/NEWS index 8c11cffc..de39569d 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ This file records noteworthy changes. * sqrfree() factorization fixed and improved syntactically. * subs() works on matrices. * Fixed memory leak in expand(). +* Operator% for objects of class ncmul has gone. Use operator* now for that + case too, which is much more natural. 0.7.3 (28 February 2001) * Several bugfixes and minor performance tunings. diff --git a/ginac/ex.cpp b/ginac/ex.cpp index 55482551..7570618d 100644 --- a/ginac/ex.cpp +++ b/ginac/ex.cpp @@ -342,19 +342,23 @@ unsigned ex::gethash(void) const return bp->gethash(); } +/** Used internally by operator+() to add two ex objects together. */ ex ex::exadd(const ex & rh) const { return (new add(*this,rh))->setflag(status_flags::dynallocated); } +/** Used internally by operator*() to multiply two ex objects together. */ ex ex::exmul(const ex & rh) const { - 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); + // Check if we are constructing a mul object or a ncmul object. Due to + // ncmul::eval()'s rule to pull out commutative elements we need to check + // only one of the elements. + if (rh.bp->return_type()==return_types::commutative || + bp->return_type()==return_types::commutative) + return (new mul(*this,rh))->setflag(status_flags::dynallocated); + else + return (new ncmul(*this,rh))->setflag(status_flags::dynallocated); } // private diff --git a/ginac/ex.h b/ginac/ex.h index ce0fe8c1..d034dec2 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -129,7 +129,6 @@ public: 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); diff --git a/ginac/input_parser.yy b/ginac/input_parser.yy index af46af0a..d1e87669 100644 --- a/ginac/input_parser.yy +++ b/ginac/input_parser.yy @@ -109,7 +109,6 @@ exp : T_NUMBER {$$ = $1;} | exp '-' exp {$$ = $1 - $3;} | exp '*' exp {$$ = $1 * $3;} | exp '/' exp {$$ = $1 / $3;} - | exp '%' exp {$$ = $1 % $3;} | '-' exp %prec NEG {$$ = -$2;} | '+' exp %prec NEG {$$ = $2;} | exp '^' exp {$$ = pow($1, $3);} diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp index 1433a3a8..44c5d30e 100644 --- a/ginac/ncmul.cpp +++ b/ginac/ncmul.cpp @@ -143,13 +143,13 @@ void ncmul::archive(archive_node &n) const void ncmul::print(std::ostream & os, unsigned upper_precedence) const { debugmsg("ncmul print",LOGLEVEL_PRINT); - printseq(os,'(','%',')',precedence,upper_precedence); + printseq(os,'(','*',')',precedence,upper_precedence); } void ncmul::printraw(std::ostream & os) const { debugmsg("ncmul printraw",LOGLEVEL_PRINT); - os << "%("; + os << "ncmul("; for (exvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) { (*it).bp->printraw(os); os << ","; @@ -344,7 +344,7 @@ ex ncmul::eval(int level) const // ncmul(ncmul(x1,x2,...),X,ncmul(y1,y2,...) // (X noncommutative_composite) - if ((level==1)&&(flags & status_flags::evaluated)) { + if ((level==1) && (flags & status_flags::evaluated)) { return *this; } @@ -353,16 +353,14 @@ ex ncmul::eval(int level) const // ncmul(...,*(x1,x2),...,ncmul(x3,x4),...) -> // ncmul(...,x1,x2,...,x3,x4,...) (associativity) unsigned factors=0; - for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit) { + for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit) factors += count_factors(*cit); - } - + exvector assocseq; assocseq.reserve(factors); - for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit) { + for (exvector::const_iterator cit=evaledseq.begin(); cit!=evaledseq.end(); ++cit) append_factors(assocseq,*cit); - } - + // ncmul(x) -> x if (assocseq.size()==1) return *(seq.begin()); @@ -402,11 +400,10 @@ ex ncmul::eval(int level) const exvector noncommutativeseq; noncommutativeseq.reserve(assocseq.size()-count_commutative); for (i=0; isetflag(status_flags::dynallocated)); return (new mul(commutativeseq))->setflag(status_flags::dynallocated); @@ -454,16 +451,15 @@ ex ncmul::eval(int level) const #endif // def DO_GINAC_ASSERT // if all elements are of same type, simplify the string - if (evv.size()==1) { + if (evv.size()==1) return evv[0][0].simplify_ncmul(evv[0]); - } exvector splitseq; splitseq.reserve(evv.size()); for (i=0; isetflag(status_flags::dynallocated)); } - + return (new mul(splitseq))->setflag(status_flags::dynallocated); } diff --git a/ginac/operators.cpp b/ginac/operators.cpp index 4e5781a6..bd9a4425 100644 --- a/ginac/operators.cpp +++ b/ginac/operators.cpp @@ -55,12 +55,6 @@ ex operator/(const ex & lh, const ex & rh) return lh.exmul(power(rh,_ex_1())); } -ex operator%(const ex & lh, const ex & rh) -{ - debugmsg("operator%(ex,ex)",LOGLEVEL_OPERATOR); - return lh.exncmul(rh); -} - // binary arithmetic operators numeric with numeric @@ -115,12 +109,6 @@ const ex & operator/=(ex & lh, const ex & rh) return (lh=lh.exmul(power(rh,_ex_1()))); } -const ex & operator%=(ex & lh, const ex & rh) -{ - debugmsg("operator%=(ex,ex)",LOGLEVEL_OPERATOR); - return (lh=lh%rh); -} - // binary arithmetic assignment operators with numeric diff --git a/ginac/operators.h b/ginac/operators.h index 8636e212..47d1b745 100644 --- a/ginac/operators.h +++ b/ginac/operators.h @@ -36,7 +36,6 @@ ex operator+(const ex & lh, const ex & rh); ex operator-(const ex & lh, const ex & rh); ex operator*(const ex & lh, const ex & rh); ex operator/(const ex & lh, const ex & rh); -ex operator%(const ex & lh, const ex & rh); // non-commutative multiplication // binary arithmetic operators numeric with numeric numeric operator+(const numeric & lh, const numeric & rh); @@ -49,7 +48,6 @@ const ex & operator+=(ex & lh, const ex & rh); const ex & operator-=(ex & lh, const ex & rh); const ex & operator*=(ex & lh, const ex & rh); const ex & operator/=(ex & lh, const ex & rh); -const ex & operator%=(ex & lh, const ex & rh); // non-commutative multiplication // binary arithmetic assignment operators with numeric const numeric & operator+=(numeric & lh, const numeric & rh); diff --git a/ginsh/ginsh_parser.yy b/ginsh/ginsh_parser.yy index 784af1cb..d7153476 100644 --- a/ginsh/ginsh_parser.yy +++ b/ginsh/ginsh_parser.yy @@ -215,7 +215,6 @@ exp : T_NUMBER {$$ = $1;} | exp '-' exp {$$ = $1 - $3;} | exp '*' exp {$$ = $1 * $3;} | exp '/' exp {$$ = $1 / $3;} - | exp '%' exp {$$ = $1 % $3;} | '-' exp %prec NEG {$$ = -$2;} | '+' exp %prec NEG {$$ = $2;} | exp '^' exp {$$ = power($1, $3);}