Opened 9 years ago

Closed 6 years ago

Last modified 4 years ago

#15605 closed defect (fixed)

(-1)^(2/3) evaluates to 1

Reported by: Marc Mezzarobba Owned by:
Priority: major Milestone: sage-7.6
Component: symbolics Keywords:
Cc: Vincent Delecroix Merged in:
Authors: Ralf Stephan Reviewers: Vincent Delecroix
Report Upstream: N/A Work issues:
Branch: 69f75ec (Commits, GitHub, GitLab) Commit:
Dependencies: Stopgaps:

Status badges

Description (last modified by Vincent Delecroix)

Likely a duplicate, but I couldn't find it elsewhere...

sage: (-1)^(2/3)
1

Of course, this is inconsistent with virtually all interpretations and conversions of symbolic expressions...

sage: CC(-1)^(2/3)
-0.500000000000000 + 0.866025403784439*I
sage: QQbar(-1)^(2/3)
-0.500000000000000? + 0.866025403784439?*I
sage: RR(-1)^(2/3)
-0.500000000000000 + 0.866025403784439*I

Also:

sage: (-1)^(-1/3)
-1
sage: 1 / ((-1)^(1/3))
-1
sage: (-1)^(1/3)*(-1)^(1/5)
1

but

sage: (-1)^(1/15)
(-1)^(1/15)

Change History (29)

comment:1 Changed 9 years ago by Marc Mezzarobba

Description: modified (diff)

comment:2 Changed 9 years ago by Marc Mezzarobba

Description: modified (diff)

comment:3 Changed 9 years ago by For batch modifications

Milestone: sage-6.1sage-6.2

comment:4 Changed 9 years ago by Frédéric Chapoton

Description: modified (diff)

Seems to be a problem about "even" powers:

sage: [(-1)^(i/77) for i in range(9)]
[1, (-1)^(1/77), 1, (-1)^(3/77), 1, (-1)^(5/77), 1, (-1)^(1/11), 1]

comment:5 Changed 9 years ago by For batch modifications

Milestone: sage-6.2sage-6.3

comment:6 Changed 8 years ago by For batch modifications

Milestone: sage-6.3sage-6.4

comment:7 in reply to:  description ; Changed 8 years ago by Thierry Monteil

Replying to mmezzarobba:

Likely a duplicate, but I couldn't find it elsewhere...

It is indeed a known issue since at least this ask answer, and i use this example in my presentations about Sage and the need to define objects within a reliable parent.

I did not report that on trac because this is somehow a feature of the symbolic ring : no semantics. I remember a discussion with you at sd49 (Orsay) about that precise example and the benefits (or not!) of having such kind of symbolic expressions that are able to make all kind of simplifications/derivatives/evaluations without context.

If one want to have something that both:

  • applies rules such as a^(bc) = (a^b)^c systematically,
  • takes principal branches of multi-valued complex function when evaluating,

then we should accept that kind of behaviour.

It would however be awesome to have a well-designed object to work with holomorphic functions, along the same lines that what is done with polynomials, i guess it is a very hard task, and i do not know whether there exists libraries for that.

comment:8 in reply to:  7 Changed 8 years ago by Ralf Stephan

Replying to tmonteil:

If one want to have something that both:

  • applies rules such as a^(bc) = (a^b)^c systematically,
  • takes principal branches of multi-valued complex function when evaluating,

then we should accept that kind of behaviour.

I think that with bc numeric (and it only makes sense to me if rational) and a negative the rule a^(bc) = (a^b)^c should not be applied simply because then a^b loses information. With symbolic exponent the user will probaby expect simplification.

comment:9 in reply to:  7 Changed 8 years ago by Marc Mezzarobba

Replying to tmonteil:

this is somehow a feature of the symbolic ring : no semantics.

I agree in part only. Sure, general symbolic expressions have very weak semantics—essentially, I view them as straight-line programs that are just required to evaluate to what you'd expect when you assign values to free variables. Many operations on symbolic expressions, however, only make sense with stronger assumptions on the expressions. Typically, simplifications are supposed to transform these ”programs“ into ”equivalent“ ones, but of course whether two ”programs“ are equivalent depends on what the variables can represent.

The sensible thing to do IMO is to view all variables as complex by default, and require simplifications to be valid for arbitrary complex values of all variables (or more accurately, for a generic choice of complex values: for example, we probably do want x/x to simplify to 1). At least what's what Maple does, and Maple arguably has the best implementation of ”general symbolic expressions” over there.

We'll still get nonsense in many cases when trying to simplify expressions containing constants from finite fields or other parents that do not fit well into this model, but I don't know how to avoid that. (Something that may be worth trying would be to define new symbolic ”rings“ parametrized by a parent. For instance, in SR(QQ), all variables would be assumed to represent elements of QQ, constants would automatically be coerced into QQ, and arithmetic operations between constants would take place there. But that's not how the existing SR works.)

If one want to have something that both:

  • applies rules such as a^(bc) = (a^b)^c systematically,

I don't think we want that. IMO this rule should be applied only if either assumptions on a, b, c make it safe (e.g., c is known to be an integer) or the user explicitely asked for it. Of course, safe simplification routines are more cumbersome to use. To mitigate the issue, Maple's simplify accepts an option (symbolic) that tells it to disregard all analytical issues related to multivalued functions and just take any branch it likes. Something like that would be convenient in Sage as well.

comment:10 Changed 8 years ago by Vincent Delecroix

Cc: Vincent Delecroix added

comment:11 Changed 8 years ago by Vincent Delecroix

Description: modified (diff)

comment:12 Changed 8 years ago by Vincent Delecroix

Just to give some concrete motivations, in #16222 (and #17516) we need a rather small subsets of symbolic expressions that modelize (some) algebraic numbers. Namely:

  • no variable
  • rational coefficients
  • I
  • exp(2*I*pi*a), cos(2*pi*a), sin(2*pi*a) with a rational
  • rational powers
  • taking real and imaginary parts

An example of such expression is

((cos(pi/7) + (-1)^(1/3))^(2/3)).real()

Do you think this must be out of the symbolic ring?

Vincent

comment:13 in reply to:  12 ; Changed 8 years ago by Marc Mezzarobba

Replying to vdelecroix:

Do you think this must be out of the symbolic ring?

I for one don't really see a problem with using the symbolic ring, but it depends if you have more use cases in mind.

comment:14 in reply to:  13 ; Changed 8 years ago by Vincent Delecroix

Replying to mmezzarobba:

Replying to vdelecroix:

Do you think this must be out of the symbolic ring?

I for one don't really see a problem with using the symbolic ring, but it depends if you have more use cases in mind.

Here is one problem with using the symbolic ring for constants:

sage: 0.1 * cos(pi/13)
0.100000000000000*cos(1/13*pi)

The answer should be a floating point real number!

Vincent

comment:15 in reply to:  14 ; Changed 8 years ago by Marc Mezzarobba

Replying to vdelecroix:

Here is one problem with using the symbolic ring for constants:

sage: 0.1 * cos(pi/13)
0.100000000000000*cos(1/13*pi)

The answer should be a floating point real number!

Yes, perhaps, I'm not sure. Perhaps it should be a symbolic expression wrapping a FP number. Or perhaps it should just stay unevaluated. For instance, if 0.1 * cos(pi/13) evaluates to a FP number, what should 0.1 * x * cos(pi/13) do?

comment:16 in reply to:  15 Changed 8 years ago by Vincent Delecroix

Replying to mmezzarobba:

Replying to vdelecroix:

Here is one problem with using the symbolic ring for constants:

sage: 0.1 * cos(pi/13)
0.100000000000000*cos(1/13*pi)

The answer should be a floating point real number!

Yes, perhaps, I'm not sure. Perhaps it should be a symbolic expression wrapping a FP number. Or perhaps it should just stay unevaluated. For instance, if 0.1 * cos(pi/13) evaluates to a FP number, what should 0.1 * x * cos(pi/13) do?

0.1 * x * cos(pi/13) should be an element of the symbolic ring (which might not necessarily be equal to 0.1 * cos(pi/13) * x). As soon as a variable appear, just go to the symbolic ring. I do not want to remove it, just to get off some part of it that would make something coherent.

This is why I am arguing for having a new intermediate world:

  • symbolic ring (the same as today),
  • some rings of symbolic constants, explicitely embedded in RR or CC, in which equality is known to be decidable (for example the one I mentioned above).

Having some False positive is also very annoying with respect to my perspective.

Vincent

comment:17 in reply to:  15 Changed 7 years ago by Ralf Stephan

Replying to mmezzarobba:

Replying to vdelecroix:

Here is one problem with using the symbolic ring for constants:

sage: 0.1 * cos(pi/13)
0.100000000000000*cos(1/13*pi)

The answer should be a floating point real number!

Yes, perhaps, I'm not sure. Perhaps it should be a symbolic expression wrapping a FP number. Or perhaps it should just stay unevaluated. For instance, if 0.1 * cos(pi/13) evaluates to a FP number, what should 0.1 * x * cos(pi/13) do?

But that would be then a different case? Anyway, the non-symbolic issue is now #18697.

comment:18 Changed 6 years ago by Ralf Stephan

Back to the original issue. The actual problem is in the Pynac logic for powers where usually the Python / Cython code for Rational.rational_power_parts is called and used. Apparently to speed things up this is only called if a numeric computation does not return a rational (which does not work as expected).

However, we cannot just say always use rational_power_parts because that is wrong too,

sage: from sage.rings.rational import rational_power_parts
sage: rational_power_parts(-1,1/3)
(1, -1)
sage: rational_power_parts(-1,2/3)
(1, 1)
sage: [rational_power_parts(-1, i/77) for i in range(9)]
[(1, 1), (1, -1), (1, 1), (1, -1), (1, 1), (1, -1), (1, 1), (1, -1), (1, 1)]

i.e. both wrong results in the following are from independent bugs:

sage: SR(-1)^(2/3)
1
sage: QQ(-1)^(2/3)
1

comment:19 Changed 6 years ago by Ralf Stephan

The symbolic issue is https://github.com/pynac/pynac/issues/221. We can then fix the Cython code in the rational ring, as well.

comment:20 Changed 6 years ago by Ralf Stephan

Branch: u/rws/__1___2_3__evaluates_to_1

comment:21 Changed 6 years ago by git

Commit: 046c9f9c4c8e465af7ed5799267b4162639f7eac

Branch pushed to git repo; I updated commit sha1. New commits:

046c9f915605: -1 special case was badly handled

comment:22 Changed 6 years ago by Ralf Stephan

Authors: Ralf Stephan
Milestone: sage-6.4sage-7.6
Status: newneeds_review

Actually fixing this in rational.pyx fixes both instances.

comment:23 Changed 6 years ago by Vincent Delecroix

Nice!

Some more tests

sage: bool((-1)^(2/3) == -1/2 + sqrt(3)/2*I)
True
sage: all((-1)^(p/q) == cos(p*pi/q) + I * sin(p*pi/q) for p in srange(1,6) for q in srange(1,6))
True

comment:24 Changed 6 years ago by git

Commit: 046c9f9c4c8e465af7ed5799267b4162639f7eac69f75eccbfeb3dbd370f382f6a4129a12a86d7da

Branch pushed to git repo; I updated commit sha1. New commits:

c1f1583Merge branch 'develop' into t/15605/__1___2_3__evaluates_to_1
69f75ecmore tests

comment:25 Changed 6 years ago by Vincent Delecroix

Reviewers: Vincent Delecroix
Status: needs_reviewpositive_review

good enough. Thanks for the fix!

comment:26 Changed 6 years ago by Ralf Stephan

Thanks for the review.

comment:27 Changed 6 years ago by Volker Braun

Branch: u/rws/__1___2_3__evaluates_to_169f75eccbfeb3dbd370f382f6a4129a12a86d7da
Resolution: fixed
Status: positive_reviewclosed

comment:28 Changed 4 years ago by Jeroen Demeyer

Commit: 69f75eccbfeb3dbd370f382f6a4129a12a86d7da

I disagree with the fix here. It seems to me that we really should catch more generally (-a)^(even rational) instead of only (-1)^(even rational).

comment:29 Changed 4 years ago by Jeroen Demeyer

See #26414 for a follow-up.

Note: See TracTickets for help on using tickets.