Re: collect() eats fractions
Hi again, I am now convinced that what's in the subject is a bug. It is related to the assumption in the basic::collect function that this->ldegree(s) <= this->degree(s) but it is not always true:
ldegree(1/(1+x),x),degree(1/(1+x),x) (0, -1)
As a fix, the collect function should be ex basic::collect(const ex & s) const { ex x; int ldeg = this->ldegree(s); int deg = this->degree(s); int n_start = min(ldeg,deg); int n_end = max(ldeg,deg); for (int n=n_start; n<=n_end; n++) x += this->coeff(s,n)*power(s,n); return x; } Note that then
coeff(1/(1+x),x,0),coeff(1/(1+x),x,-1) (1 + x) ** (-1), 0
and consequently collect(1/(1+x),x) will result correctly in (1+x) ** (-1) Regards, Pearu On Thu, 12 Apr 2001, Pearu Peterson wrote:
Hi!
In ginsh (ginac V0.8.0):
x/(1+x); (1+x)^(-1)*x collect(x/(1+x),x); 0 <----??? collect(1+x/(1+x),x); 1 <----??? collect(x+x/(1+x),x); (1+(1+x)^(-1))*x
Is this GiNaC bug or feature?
Pearu
- To UNSUBSCRIBE, email to ginac-list@ginac.de with a subject of "unsubscribe".
Sorry to bother you again but my previous fix didn't work. Below is given a working version. Any ideas how to optimize it? Btw, I have noticed that you use frequently for (int n=this->ldegree(s); n<=this->degree(s); n++) instead of more efficient for (int n=this->ldegree(s), m=this->degree(s); n<=m; ++n) that saves repeated calling of the degree() method. On Fri, 13 Apr 2001, Pearu Peterson wrote:
As a fix, the collect function should be
ex basic::collect(const ex & s) const { ex x; for (int n=this->ldegree(s); n<=this->degree(s); n++) x += this->coeff(s,n)*power(s,n); x += (*this - x).expand(); return x; } Regards, Pearu
Hi, On Sat, 14 Apr 2001, Pearu Peterson wrote:
Sorry to bother you again but my previous fix didn't work. Below is given a working version. Any ideas how to optimize it?
Nope. There are some functions of this sort where an algorithm works only in a subdomain and we correct the final result in a similar manner to account for this. If I remember correctly another example is Yun's algorithm which works only in the monic case. So we multiply with the polynomial quotient of the result of Yun's algorithm and its original argument before returning the final result in sqrfree(). I would consider this approach valid. Thank you for the patch, I've added it to the pile of things to commit later this day.
Btw, I have noticed that you use frequently
for (int n=this->ldegree(s); n<=this->degree(s); n++)
instead of more efficient
for (int n=this->ldegree(s), m=this->degree(s); n<=m; ++n)
that saves repeated calling of the degree() method.
Indeed, it does. But where else besides in basic::collect() do you see occurences of this? Regards -richy. -- Richard Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
A couple of hours ago, I wrote: [...]
Btw, I have noticed that you use frequently
for (int n=this->ldegree(s); n<=this->degree(s); n++)
instead of more efficient
for (int n=this->ldegree(s), m=this->degree(s); n<=m; ++n)
that saves repeated calling of the degree() method.
Indeed, it does. But where else besides in basic::collect() do you see occurences of this?
-- Richard Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
On Sat, 14 Apr 2001, Richard B. Kreckel got some nervous twitch in his left hand and sent an unfinished email to innocent ginac-devel subscribers:
A couple of hours ago, I wrote: [...]
Btw, I have noticed that you use frequently
for (int n=this->ldegree(s); n<=this->degree(s); n++)
instead of more efficient
for (int n=this->ldegree(s), m=this->degree(s); n<=m; ++n)
that saves repeated calling of the degree() method.
Indeed, it does. But where else besides in basic::collect() do you see occurences of this?
No, it does not safe calls. Please look at the assembler output, maybe after stripping off all unessential stuff, since it tends to be quite longish! Regards -richy. -- Richard Kreckel <Richard.Kreckel@Uni-Mainz.DE> <http://wwwthep.physik.uni-mainz.de/~kreckel/>
On Sat, 14 Apr 2001, Richard B. Kreckel wrote:
On Sat, 14 Apr 2001, Richard B. Kreckel got some nervous twitch in his left hand and sent an unfinished email to innocent ginac-devel subscribers:
A couple of hours ago, I wrote: [...]
Btw, I have noticed that you use frequently
for (int n=this->ldegree(s); n<=this->degree(s); n++)
instead of more efficient
for (int n=this->ldegree(s), m=this->degree(s); n<=m; ++n)
that saves repeated calling of the degree() method.
Indeed, it does. But where else besides in basic::collect() do you see occurences of this?
Do grep "for (" *.cpp | grep "()" and there are numerous cases like for (unsigned i=0; i<sym_lst.nops(); i++) { for (unsigned i=0; i<seq.size(); ++i) { for (int p = 1; it!=factors.end(); ++it, ++p) Ok, they are not as bad as above and can be left for fixing them in future (if at all).
No, it does not safe calls. Please look at the assembler output, maybe
That's interesting indeed! It must be a optimization "feature" of a compiler. I guess int m = this->degree(s); for (int n=this->ldegree(s); n<=m; ++n) will do the job. Pearu
participants (2)
-
Pearu Peterson
-
Richard B. Kreckel