conjugates of power objects
On Mon, 26 Apr 2010 18:02:40 -0700 (PDT) kcrisman <kcrisman@gmail.com> wrote:
On Apr 26, 4:09 pm, John Cremona <john.crem...@gmail.com> wrote:
This is certainly a bug:
sage: a = sqrt(-3) sage: a sqrt(-3) sage: a.conjugate() sqrt(-3)
sage: bool(a==a.conjugate()) True
Yeah, this is bad, and according to a.conjugate?? it seems to be something wrong with our Ginac/Pynac use.
This is a bug in GiNaC: ginsh - GiNaC Interactive Shell (ginac V1.5.7) __, _______ Copyright (C) 1999-2010 Johannes Gutenberg University Mainz, (__) * | Germany. This is free software with ABSOLUTELY NO WARRANTY. ._) i N a C | You are welcome to redistribute it under certain conditions. <-------------' For details type `warranty;'. Type ?? for a list of help topics.
sqrt(-3); sqrt(-3) conjugate(sqrt(-3)); sqrt(-3)
For conjugation, power objects just compute the conjugate of the basis and the exponent, and construct a new power object from these. Here is the relevant function: http://pynac.sagemath.org/hg/file/3ece9ba22005/ginac/power.cpp#l805 Cheers, Burcin
Hello, On Tue, Apr 27, 2010 at 03:16:00AM +0200, Burcin Erocal wrote:
For conjugation, power objects just compute the conjugate of the basis and the exponent, and construct a new power object from these.
Proof: (a^b)* = exp(b log(a))* = exp((b log(a))*) = exp(b* (log(a))*) (log(a))* = ( log |a| + i arg(a))* = log |a| - i arg(a) = log |a*| + i arg(a*) = log(a*) So (a^b)* = exp(b* log(a*)) = (a*)^(b*)
conjugate(sqrt(-3)); sqrt(-3)
You are trying to compute the value of the function on the branch cut (which is ill defined), so you get the nonsense result. Please note: it's a midnight now (here in Ukraine), and I had a busy day, so the above might be a total nonsense. Feel free to point out mistakes (if any). Best regards, Alexei
Hi! Alexei Sheplyakov wrote:
On Tue, Apr 27, 2010 at 03:16:00AM +0200, Burcin Erocal wrote:
conjugate(sqrt(-3)); sqrt(-3)
You are trying to compute the value of the function on the branch cut (which is ill defined), so you get the nonsense result.
Trying to argue that sqrt(-1) is ill-defined is going to rise an eyebrow or two, I guess. ;-) Some background: GiNaC has been following the convention of counter clockwise continuity (CCC) ever since. Functions are continuous as the cut is approached coming around the finite endpoint of the cut in a counter clockwise direction. GiNaC has inherited this from CLN, which has followed Steele's CLTL2 in this respect. Later, the same convention was adopted by C99 and C++. Most CAS follow it, too. (I haven't checked yet, but I suppose this convention is also adopted by the LIA-3 standard.) A popular extension due to this is the one advocated by W. Kahan and standardized in IEEE754, where a distinction is made betweenn +0 and -0. This is not a panacea because it opens the problem that one has to agree on what an unqualified 0 is supposed to be. CLN/GiNaC (and all CASs I am aware of) has no signed zero. I heartily recommend the article "Function evaluation on branch cuts" by Albert Rich and David Jeffrey. It is a short but very inspiring read! Alas, I think that automatic evaluation of conjugation is too aggressive in GiNaC. It just keeps giving incorrect results on branch cuts. Here are some examples, using ginsh:
conjugate(sqrt(x)); sqrt(conjugate(x)) conjugate(sqrt(x))-sqrt(conjugate(x)); 0 conjugate(sqrt(-1))-sqrt(conjugate(-1)); -2*I conjugate(log(x)); log(conjugate(x)) conjugate(log(x))-log(conjugate(x)); 0 conjugate(log(-1))-log(conjugate(-1)); -(2*I)*Pi
I suggest to disable automatic evaluateion of conjugation where these kinds of problems can appear. Opinions? Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Hello, On Fri, Apr 30, 2010 at 09:06:03AM +0200, Richard B. Kreckel wrote:
Trying to argue that sqrt(-1) is ill-defined is going to rise an eyebrow or two, I guess. ;-)
I agree. Let's put it another way: unfortunately GiNaC gives no way to figure out if sqrt(-1) really stands for sqrt(-1 + I 0) or sqrt(-1 - I 0), so we don't really know the if it's +I or -I. Does this explanation make any sense?
Alas, I think that automatic evaluation of conjugation is too aggressive in GiNaC. It just keeps giving incorrect results on branch cuts. Here are some examples, using ginsh:
conjugate(sqrt(x)); sqrt(conjugate(x)) conjugate(sqrt(x))-sqrt(conjugate(x)); 0 conjugate(sqrt(-1))-sqrt(conjugate(-1)); -2*I conjugate(log(x)); log(conjugate(x)) conjugate(log(x))-log(conjugate(x)); 0 conjugate(log(-1))-log(conjugate(-1)); -(2*I)*Pi
I suggest to disable automatic evaluateion of conjugation where these kinds of problems can appear.
Opinions?
Should we stop evaluating x/x to 1, too? It gives incorrect result if x is zero. Best regards, Alexei
Hi! Alexei Sheplyakov wrote:
I agree. Let's put it another way: unfortunately GiNaC gives no way to figure out if sqrt(-1) really stands for sqrt(-1 + I 0) or sqrt(-1 - I 0), so we don't really know the if it's +I or -I.
Focus on the imaginary part and it becomes clear that this is equivalent to saying "GiNaC doesn't know whether 0 corresponds to +eps or -eps for eps -> 0". But the question remains: What about an unqualified 0? Or, taking the limit towards (-1,0) along the real axis? This question should be answered, too, and it is answered by a convention. BTW: I don't think that resorting to the signed zero argument is of any help at all. I have always wondered how one can justify sqrt(-1-0*I)!=sqrt(-1+0*I) but accept -1-0*I==-1+0*I, as the standards demand. See <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20758> for a discussion.
Opinions?
Should we stop evaluating x/x to 1, too? It gives incorrect result if x is zero.
Good point. I certainly don't argue to stop evaluating x/x -> 1. Let me try to justify: x/x is 1 for any complex limit path x->0. In contrast, conjugate(sqrt(-1+x))==sqrt(conjugate(-1+x)) only if the limit path is not running along the real axis. Is that convincing? Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Hi, Am 30.04.2010 09:06, schrieb Richard B. Kreckel:
I suggest to disable automatic evaluateion of conjugation where these kinds of problems can appear.
Opinions?
I'd also switch the evaluation off for problematic cases. To keep things simple, it would mean to switch it off for almost all kinds of power objects, though. I'd just keep it active for z^n, if z is a number or a symbol (or also a polynomial, maybe?), and n is integer. Checking the base for known functions and applying some knowledge about the branch cut position is too tedious to implement, I think. Regards, Jens
Hi, Sorry for the slow response. I'm on a research visit and I need to spend my time on real work these days. :) On Fri, 30 Apr 2010 09:06:03 +0200 "Richard B. Kreckel" <kreckel@ginac.de> wrote:
Alexei Sheplyakov wrote:
On Tue, Apr 27, 2010 at 03:16:00AM +0200, Burcin Erocal wrote:
conjugate(sqrt(-3)); sqrt(-3)
You are trying to compute the value of the function on the branch cut (which is ill defined), so you get the nonsense result.
Trying to argue that sqrt(-1) is ill-defined is going to rise an eyebrow or two, I guess. ;-)
Some background: GiNaC has been following the convention of counter clockwise continuity (CCC) ever since. Functions are continuous as the cut is approached coming around the finite endpoint of the cut in a counter clockwise direction. GiNaC has inherited this from CLN, which has followed Steele's CLTL2 in this respect. Later, the same convention was adopted by C99 and C++. Most CAS follow it, too. (I haven't checked yet, but I suppose this convention is also adopted by the LIA-3 standard.)
A popular extension due to this is the one advocated by W. Kahan and standardized in IEEE754, where a distinction is made betweenn +0 and -0. This is not a panacea because it opens the problem that one has to agree on what an unqualified 0 is supposed to be. CLN/GiNaC (and all CASs I am aware of) has no signed zero.
I heartily recommend the article "Function evaluation on branch cuts" by Albert Rich and David Jeffrey. It is a short but very inspiring read!
Wow! Thanks for this explanation. This should be put in the documentation somewhere.
Alas, I think that automatic evaluation of conjugation is too aggressive in GiNaC. It just keeps giving incorrect results on branch cuts. Here are some examples, using ginsh:
conjugate(sqrt(x)); sqrt(conjugate(x)) conjugate(sqrt(x))-sqrt(conjugate(x)); 0 conjugate(sqrt(-1))-sqrt(conjugate(-1)); -2*I conjugate(log(x)); log(conjugate(x)) conjugate(log(x))-log(conjugate(x)); 0 conjugate(log(-1))-log(conjugate(-1)); -(2*I)*Pi
I suggest to disable automatic evaluateion of conjugation where these kinds of problems can appear.
Opinions?
I agree that the automatic evaluation should be disabled for most cases. I don't immediately see a good definition for these cases though, but then I am not knowledgeable in this area at all. Maple seems to convert sqrt(-3) to sqrt(3)*I automatically:
sqrt(-3); 1/2 3 I
Perhaps adding this automatic evaluation rule for power objects would simplify the conditions we need to consider for automatic evaluation of conjugation. Comments? Thank you. Burcin
Hi, I attached a patch with my attempts to solve this problem. It is based on the latest version of pynac. I hope it applies cleanly to GiNaC as well. On Mon, 3 May 2010 17:50:44 +0200 Burcin Erocal <burcin@erocal.org> wrote:
On Fri, 30 Apr 2010 09:06:03 +0200 "Richard B. Kreckel" <kreckel@ginac.de> wrote:
Alas, I think that automatic evaluation of conjugation is too aggressive in GiNaC. It just keeps giving incorrect results on branch cuts. Here are some examples, using ginsh:
conjugate(sqrt(x)); sqrt(conjugate(x)) conjugate(sqrt(x))-sqrt(conjugate(x)); 0 conjugate(sqrt(-1))-sqrt(conjugate(-1)); -2*I conjugate(log(x)); log(conjugate(x)) conjugate(log(x))-log(conjugate(x)); 0 conjugate(log(-1))-log(conjugate(-1)); -(2*I)*Pi
I suggest to disable automatic evaluateion of conjugation where these kinds of problems can appear.
Opinions?
I agree that the automatic evaluation should be disabled for most cases. I don't immediately see a good definition for these cases though, but then I am not knowledgeable in this area at all.
For some time now, pynac doesn't automatically evaluate conjugates of function objects: http://pynac.sagemath.org/hg/rev/4c0f8441d460 This prevents the problems with log() above.
Maple seems to convert sqrt(-3) to sqrt(3)*I automatically:
sqrt(-3); 1/2 3 I
Perhaps adding this automatic evaluation rule for power objects would simplify the conditions we need to consider for automatic evaluation of conjugation.
Attached patch adds a rule to power::eval() to transform ^(-c1, c2) to *(^(-1, c2), (c1, c2)) when c1 and c2 are both rational. I got this idea from maxima. I also restrict the automatic conjugation unless the basis is real and the exponent is a rational, returning *this in this case. This seems to give an acceptable response to conjugate(sqrt(-3)): sage: conjugate(sqrt(-3)) -I*sqrt(3) Comments? Cheers, Burcin
Hello, On Thu, May 06, 2010 at 05:16:01AM +0200, Burcin Erocal wrote:
I attached a patch with my attempts to solve this problem. It is based on the latest version of pynac. I hope it applies cleanly to GiNaC as well.
Attached patch adds a rule to power::eval() to transform ^(-c1, c2) to *(^(-1, c2), (c1, c2)) when c1 and c2 are both rational. I got this idea from maxima.
No objections here.
I also restrict the automatic conjugation unless the basis is real and the exponent is a rational, returning *this in this case.
Now conjugate() is unable to handle pow(complex-valued polynomial, integer). I think this makes conjugate() practically useless. So, I'm afraid this change is not acceptable.
diff --git a/ginac/power.cpp b/ginac/power.cpp --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -567,6 +567,14 @@ }
if (exponent_is_rational) { + // ^(-c1, c2) -> ((-1)^c2)*(c1^c2) + // for example sqrt(-2) -> I*sqrt(2) + if (num_basis->is_negative() && + !num_basis->is_equal(*_num_1_p)) + return mul(power(_ex_1, *num_exponent), + power((*num_basis)*(*_num_1_p), + *num_exponent)); +
A few minor corrections: 1) pow(_ex_1, *num_exponent)*pow((*num_basis)*(*num_1_p), *num_exponent) would be easier to read 2) If you insist on constructing the mul object manually, do return new mul(foo, bar)->setflags(status_flags::dynallocated); Best regards, Alexei
Hi! Okay, these are two distinct patches, IIANM. One about restricting automatic conjugation, one about adding rules to power::eval(). Let's treat them as separate, please! Burcin Erocal wrote:
Attached patch adds a rule to power::eval() to transform ^(-c1, c2) to *(^(-1, c2), (c1, c2)) when c1 and c2 are both rational. I got this idea from maxima. I also restrict the automatic conjugation unless the basis is real and the exponent is a rational, returning *this in this case.
This seems to give an acceptable response to conjugate(sqrt(-3)):
sage: conjugate(sqrt(-3)) -I*sqrt(3)
Comments?
Burcin, I suppose you were unaware of <http://www.ginac.de/ginac.git?p=ginac.git;a=blob_plain;f=doc/powerlaws.tex;hb=master> but can provide a rigorous proof of this rule, right? Best wishes -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
participants (4)
-
Alexei Sheplyakov
-
Burcin Erocal
-
Jens Vollinga
-
Richard B. Kreckel