Dear all, I added the step function to GiNaCs repertoire of built-in functions. It is the real function step(x)=1 for x>0 and step(x)=0 for x<0. Considering the fact that numerical evaluation may yield a small imaginary part due to rounding errors, a possible imaginary part of a numerical argument is ignored. Furthermore step(0)=1/2. This, however, should not be taken too seriously as there is also the automatic evaluation step(x)^2 -> step(x). In the sense of distributions it does not matter what the value of step(0) is. Best, Chris
"CD" == Chris Dams <Chris.Dams@mi.infn.it> writes: CD> ignored. Furthermore step(0)=1/2. This, however, should not be CD> taken too seriously as there is also the automatic evaluation CD> step(x)^2 -> step(x).
For a bigger consistency I would prefer to have either step(0)=0 or step(0)=1. Such a small features which is easy to overlook sometimes takes hours to realise. If three-values are really needed we may have another function sign(x)=1, x>0 sign(x)=0, x=0 sign(x)=-1, x<0 with the property sign(x)^3 -> sign(x). The current step(x) is then (sign(x)+1)/2. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
Dear Vladimir, On Thu, 2006-03-09 at 16:31 +0000, Vladimir Kisil wrote:
"CD" == Chris Dams <Chris.Dams@mi.infn.it> writes: CD> ignored. Furthermore step(0)=1/2. This, however, should not be CD> taken too seriously as there is also the automatic evaluation CD> step(x)^2 -> step(x).
For a bigger consistency I would prefer to have either step(0)=0 or step(0)=1. Such a small features which is easy to overlook sometimes takes hours to realise.
Yes, that is a good point. I made step(0) equal to 1.
If three-values are really needed we may have another function sign(x)=1, x>0 sign(x)=0, x=0 sign(x)=-1, x<0
That function already more or less exists as csgn(x). The reason that it is useful to have both functions is that the combination (csgn(x)+1)/2 is kept together even when expanding and so on if one writes it as step(x). When looking at output it is more easy to see that step(P)*Q does not contribute if one knows that P happens to be negative then it is when it is to be canceled by another term equal to Q. Best wishes, Chris
"CD" == Chris Dams <Chris.Dams@mi.infn.it> writes: CD> That function already more or less exists as csgn(x).
I missed it. Should we add its power property like that: static ex csgn_power(const ex & arg, const ex & exp) { if (is_a<numeric>(exp) && exp.info(info_flags::positive)) { if (ex_to<numeric>(exp).is_odd()) return csgn(arg); else return power(csgn(arg), _ex2).hold(); } else return power(csgn(arg), exp).hold(); } CD> The reason that it is useful to have both functions Yes, I agree. So far I used home-brewed definition in http://arxiv.org/abs/cs.MS/0512073, now I can switch to the "official" one. ;-) CD> (csgn(x)+1)/2 is kept together even when expanding and so on if CD> one writes it as step(x). When looking at output it is more easy I agree again. My comment was intended only for the case, when the intermediate value is important. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
Hi! Vladimir Kisil wrote:
CD> That function already more or less exists as csgn(x).
I missed it. Should we add its power property like that:
static ex csgn_power(const ex & arg, const ex & exp) { if (is_a<numeric>(exp) && exp.info(info_flags::positive)) { if (ex_to<numeric>(exp).is_odd()) return csgn(arg); else return power(csgn(arg), _ex2).hold(); } else return power(csgn(arg), exp).hold(); }
But that appears to be missing the possibiliby of fractional powers.
CD> The reason that it is useful to have both functions
Yes, I agree. So far I used home-brewed definition in http://arxiv.org/abs/cs.MS/0512073, now I can switch to the "official" one. ;-)
CD> (csgn(x)+1)/2 is kept together even when expanding and so on if CD> one writes it as step(x). When looking at output it is more easy
I agree again. My comment was intended only for the case, when the intermediate value is important.
I'm not totally convinced. Just one experience: I once was collecting lots of such theta functions in computations where they were falling out as constraints from complex residue integrations: Is the contour around the pole (parametrized as f(x)) or isn't it? The Laurent series of the integrand at the poles was known to have only odd negative powers which allows one to elegantly take care of the situation where the contour crosses the pole: just add Pi*I times the residue (instead of 2*Pi*I). Here, it was clearly an advantage to lump them all together with the weight theta(f(x))=(1+csgn(f(x)))/2. Some of the term-rewriting rules wouldn't work without the intermediate value. I don't want to argue one way or the other. It's quite possible that what I was doing was exotic. But I would recommend that if step(x) cannot be expressed in terms of csgn(x), then it should be prominently documented so. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Dear Richy and Vladimir, On Thu, 2006-03-09 at 22:44 +0100, Richard B. Kreckel wrote:
Hi!
Vladimir Kisil wrote:
CD> That function already more or less exists as csgn(x).
I missed it. Should we add its power property like that:
static ex csgn_power(const ex & arg, const ex & exp) { if (is_a<numeric>(exp) && exp.info(info_flags::positive)) { if (ex_to<numeric>(exp).is_odd()) return csgn(arg); else return power(csgn(arg), _ex2).hold(); } else return power(csgn(arg), exp).hold(); }
But that appears to be missing the possibiliby of fractional powers.
CD> The reason that it is useful to have both functions
Yes, I agree. So far I used home-brewed definition in http://arxiv.org/abs/cs.MS/0512073, now I can switch to the "official" one. ;-)
CD> (csgn(x)+1)/2 is kept together even when expanding and so on if CD> one writes it as step(x). When looking at output it is more easy
I agree again. My comment was intended only for the case, when the intermediate value is important.
I'm not totally convinced. Just one experience: I once was collecting lots of such theta functions in computations where they were falling out as constraints from complex residue integrations: Is the contour around the pole (parametrized as f(x)) or isn't it? The Laurent series of the integrand at the poles was known to have only odd negative powers which allows one to elegantly take care of the situation where the contour crosses the pole: just add Pi*I times the residue (instead of 2*Pi*I). Here, it was clearly an advantage to lump them all together with the weight theta(f(x))=(1+csgn(f(x)))/2. Some of the term-rewriting rules wouldn't work without the intermediate value.
Yes, one would, for instance, have integral(x,-infty,infty, exp(I*k*x)/(x+I*epsilon)) = -2*Pi*I*step(k). This would give precisely the same right result also at k=0 if step(0)=1/2. For cases like this it seems that 1/2 is the best value. So maybe the best thing to do would be to have step(0)=1/2 and not to do a simplification step(x)^2 -> step(x). After all, if desired, such a simplification could also be done by the user. (S)he could do .subs(step(wild())*step(wild())==step(wild()), subs_options::algebraic). Can everybody live with that? Best, Chris
CD> Yes, one would, for instance, have CD> integral(x,-infty,infty, exp(I*k*x)/(x+I*epsilon)) = -2*Pi*I*step(k). CD> This would give precisely the same right result also at k=0 if CD> step(0)=1/2. For cases like this it seems that 1/2 is the best value. Yes, this is an important case, which needs such a function. CD> maybe the best thing to do would be to have step(0)=1/2 and not to do a CD> simplification step(x)^2 -> step(x). CD> Can everybody live with that? Since it is consistent no reasons to object. CD> After all, if desired, such a CD> simplification could also be done by the user. (S)he could do CD> .subs(step(wild())*step(wild())==step(wild()), subs_options::algebraic). In heavy calculations it is important that some simplifications are made automatically on intermediate cases. To this end we may have (in the core GiNaC or user-defined) another function (say "jump") which have the property jump^2(t) -> jump(t). RC> > I missed it. Should we add its power property like that: RC> > RC> >static ex csgn_power(const ex & arg, const ex & exp) RC> >{ RC> >} RC> RC> But that appears to be missing the possibiliby of fractional powers. I am not sure what fractional powers of a negative values should be... Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
Dear Vladimir, On Fri, 2006-03-10 at 10:33 +0000, Vladimir Kisil wrote:
CD> maybe the best thing to do would be to have step(0)=1/2 and not to do a CD> simplification step(x)^2 -> step(x). CD> Can everybody live with that?
Since it is consistent no reasons to object.
OK.
CD> After all, if desired, such a CD> simplification could also be done by the user. (S)he could do CD> .subs(step(wild())*step(wild())==step(wild()), subs_options::algebraic).
In heavy calculations it is important that some simplifications are made automatically on intermediate cases. To this end we may have (in the core GiNaC or user-defined) another function (say "jump") which have the property jump^2(t) -> jump(t).
I would prefer not to have such a function in GiNaC itself. The difference between "jump" and "step" would be too small to justify introducing another object IMO. I did not follow the discussion on the new function system that Jens seems to be building, but what would be ideal is if the user could implement "jump" by deriving from "step" and simply add the automatic simplification jump^2 -> jump. I would think that the number of users that needs this simplification to be done in the midst of a calculation is not so large as to justify adding the function "jump" to the library. Best, Chris
I did not follow the discussion on the new function system that Jens seems to be building, but what would be ideal is if the user could implement "jump" by deriving from "step" and simply add the automatic simplification jump^2 -> jump
Anyway it is not difficult to cut&past the entire definition of step to user's code, rename and make few desirable alterations. -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
Hi, Vladimir Vladimir Kisil wrote:
RC> But that appears to be missing the possibiliby of fractional powers.
I am not sure what fractional powers of a negative values should be...
For example csgn(x)^(1/2) where it later turns out that x==-1. It seems to me that the rewriting rule you suggested would get that wrong. Cheers -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
For example csgn(x)^(1/2) where it later turns out that x==-1.
Now I see the ommision, this one should be better: static ex csgn_power(const ex & arg, const ex & exp) { if (is_a<numeric>(exp) && exp.info(info_flags::positive) && ex_to<numeric>(exp).is_integer()) { if (ex_to<numeric>(exp).is_odd()) return csgn(arg); else return power(csgn(arg), _ex2).hold(); } else return power(csgn(arg), exp).hold(); } Best, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/
participants (3)
-
Chris Dams
-
Richard B. Kreckel
-
Vladimir Kisil