Putting parentheses around -1.

14 views
Skip to first unread message

Ted Kosan

unread,
Jan 23, 2008, 8:04:10 PM1/23/08
to sage-s...@googlegroups.com
Does anyone have any thoughts on why the following 2 code samples give
different results?:

#SAGE Version 2.10, Release Date: 2008-01-18


sage: n(-1^(1/3))
-1.00000000000000

sage: n((-1)^(1/3))
0.500000000000000 + 0.866025403784439*I

The only difference between them is that parentheses have been placed around -1.

Thanks,

Ted

Mike Hansen

unread,
Jan 23, 2008, 8:07:14 PM1/23/08
to sage-s...@googlegroups.com
It is due to the fact that ^ has a higher precedence than - in Python.
n(-1^(1/3)) is the same as n((-1^(1/3))).
--Mike

Ted Kosan

unread,
Jan 23, 2008, 8:26:39 PM1/23/08
to sage-s...@googlegroups.com
Mike wrote:

> It is due to the fact that ^ has a higher precedence than - in Python.
> n(-1^(1/3)) is the same as n((-1^(1/3))).

Okay, here is how I ran into this:

https://sage.ssu.portsmouth.oh.us:9000/home/pub/21/

What I expected to get was -1.44224957030741. Which result should it produce?

Ted

Justin C. Walker

unread,
Jan 23, 2008, 8:41:09 PM1/23/08
to sage-s...@googlegroups.com

As MikeH noted, it's dictated by Python's precedence rules: the
"phrase" '-1^(1/3)' is by definition interpreted to mean '-(1^
(1/3))', which is '-1'. Unless you can somehow finagle Sage into
producing a cube root of unity from '1' :-}

Justin

--
Justin C. Walker, Curmudgeon-At-Large
Institute for the Enhancement of the Director's Income
--------
Experience is what you get
when you don't get what you want.
--------

kcrisman

unread,
Jan 23, 2008, 8:50:58 PM1/23/08
to sage-support
What's interesting here is that the output of the cube root of -1 is
not -1, but the "first clockwise" root from 1+0i, or the usual choice
for a primitive sixth root of unity. But what Ted really wanted was
just the real cube root of -1.

What is the "desired" output here by the developers? Or is this
Python-internal? Boy, I can really think of times I would want either
output without having to specify real or complex, and I suppose
sometimes one might want a list of all three roots.

- kcrisman

William Stein

unread,
Jan 23, 2008, 8:56:01 PM1/23/08
to sage-s...@googlegroups.com

Until a month ago (-1)^(1/3) would have given -1. This is the default
behavior dictated by Maxima. Then Paul Zimmerman complained
(with a great argument) that this was stupid, and Mike Hansen changed
the default Maxima behavior to what we currently have. He did
this by setting a variable when the symbolic arithmetic class starts maxima.

http://trac.sagemath.org/sage_trac/ticket/1425

If you saw Paul Zimmerman's talk at Sage Days 6, you get the very
strong impression that he's right about anything like this.

-- William

Ted Kosan

unread,
Jan 23, 2008, 9:17:03 PM1/23/08
to sage-s...@googlegroups.com
kcrisman wrote:

>But what Ted really wanted was just the real cube root of -1.

What I wanted was where the graph crossed the x axis as shown in the plot :-)

Ted

Ted Kosan

unread,
Jan 23, 2008, 9:19:11 PM1/23/08
to sage-s...@googlegroups.com
William wrote:

> Until a month ago (-1)^(1/3) would have given -1. This is the default
> behavior dictated by Maxima. Then Paul Zimmerman complained
> (with a great argument) that this was stupid, and Mike Hansen changed
> the default Maxima behavior to what we currently have. He did
> this by setting a variable when the symbolic arithmetic class starts maxima.
>
> http://trac.sagemath.org/sage_trac/ticket/1425
>
> If you saw Paul Zimmerman's talk at Sage Days 6, you get the very
> strong impression that he's right about anything like this.

Hmmm, on the worksheet I posted the plot for this equation shows the
graph crossing the x axis around -1.5 but solve indicates this value
is 0.721124785153704 + 1.24902476648341*I.

So why is solve placing parentheses around the 3rd root it returns if
it evaluates into an imaginary value?

[...,..,x == (-1)^(1/3)*3^(1/3)]


I ran into this issue while demonstrating the usefulness of the solve
function in front of a class of students. That was quite 'fun' :-)

Ted

Jacob Hicks

unread,
Jan 24, 2008, 12:07:25 AM1/24/08
to sage-s...@googlegroups.com
On Jan 23, 2008 9:19 PM, Ted Kosan <ted....@gmail.com> wrote:

[...,..,x == (-1)^(1/3)*3^(1/3)]


I ran into this issue while demonstrating the usefulness of the solve
function in front of a class of students.  That was quite 'fun' :-)

Ted
It does seem strange that the answer that looked like it should be real is actually not.  If you have sage evaluate the first value in the returned answers you see that despite its appearance it is the pure real number that you desire.

b[0].right().n()

you get
-1.44224957030741

So make sure that your students see that sage *did* return the desired value. But also remind them to be careful because all other things being equal technology tends to answer your questions in the way that makes the most sense to its programmer, which does not necessarily make the most sense to a student (or anyone else).


Jacob Hicks
Mathematics Teacher
Trinity Collegiate School

Ted Kosan

unread,
Jan 24, 2008, 12:23:39 AM1/24/08
to sage-s...@googlegroups.com
> So why is solve placing parentheses around the 3rd root it returns if
> it evaluates into an imaginary value?
>
> [...,..,x == (-1)^(1/3)*3^(1/3)]

"around the 3rd root" should be "around the -1 in the 3rd root"

Ted

Ted Kosan

unread,
Jan 24, 2008, 12:31:36 AM1/24/08
to sage-s...@googlegroups.com
Jacob wrote:

> It does seem strange that the answer that looked like it should be real is
> actually not. If you have sage evaluate the first value in the returned
> answers you see that despite its appearance it is the pure real number that
> you desire.
>
> b[0].right().n()
>
> you get
> -1.44224957030741
>
> So make sure that your students see that sage *did* return the desired
> value. But also remind them to be careful because all other things being
> equal technology tends to answer your questions in the way that makes the
> most sense to its programmer, which does not necessarily make the most sense
> to a student (or anyone else).

Thank you for clearing this up for me :-) It never occurred to me to
evaluate the other two values because of the way they were expressed.
I just learned something new and now I think I will add this
information to the newbies book.

Ted

Paul Zimmermann

unread,
Jan 24, 2008, 2:41:04 AM1/24/08
to sage-s...@googlegroups.com
> > [...,..,x == (-1)^(1/3)*3^(1/3)]
> >
> >
> > I ran into this issue while demonstrating the usefulness of the solve
> > function in front of a class of students. That was quite 'fun' :-)
> >
> > Ted
> >
> It does seem strange that the answer that looked like it should be real is
> actually not. If you have sage evaluate the first value in the returned
> answers you see that despite its appearance it is the pure real number that
> you desire.
>
> b[0].right().n()
>
> you get
>
> -1.44224957030741
>
> So make sure that your students see that sage *did* return the desired
> value. But also remind them to be careful because all other things
> being equal technology tends to answer your questions in the way that
> makes the most sense to its programmer, which does not necessarily
> make the most sense to a student (or anyone else).

right, as Jacob pointed it out, one has to be careful about values that look
real (resp. complex) and are not. In fact this is a very nice example to show
students that they should take care about the appearance of symbolic objects
(and the difference between classes where you have a canonical form like
integers, and other classes where no canonical form exists, more precisely
the problem is undecidable):

You can construct other nice examples: take the equation (x-1)*(x^2+1)=0,
with trivial root 1:

sage: expand((x-1)*(x^2+1))
x^3 - x^2 + x - 1

Then replace the constant term by a symbolic value a, and solve for the
degree 3 equation:

sage: var('a'); sol = solve(x^3 - x^2 + x - a==0, x); sol
a
[x == (-sqrt(3)*I/2 - 1/2)*(sqrt(27*a^2 - 14*a + 3)/(6*sqrt(3)) + (27*a - 7)/54)^(1/3) - 2*(sqrt(3)*I/2 - 1/2)/(9*(sqrt(27*a^2 - 14*a + 3)/(6*sqrt(3)) + (27*a - 7)/54)^(1/3)) + 1/3, x == (sqrt(3)*I/2 - 1/2)*(sqrt(27*a^2 - 14*a + 3)/(6*sqrt(3)) + (27*a - 7)/54)^(1/3) - 2*(-sqrt(3)*I/2 - 1/2)/(9*(sqrt(27*a^2 - 14*a + 3)/(6*sqrt(3)) + (27*a - 7)/54)^(1/3)) + 1/3, x == (sqrt(27*a^2 - 14*a + 3)/(6*sqrt(3)) + (27*a - 7)/54)^(1/3) - 2/(9*(sqrt(27*a^2 - 14*a + 3)/(6*sqrt(3)) + (27*a - 7)/54)^(1/3)) + 1/3]

You know one of the roots should evaluate to 1 for a=1, in fact it is sol[2]:

sage: sol[2].subs(a=1).right().n()
1.00000000000000

Thus you have constructed a nice expression for 1:

sage: sol[2].subs(a=1).right()
(2/(3*sqrt(3)) + 10/27)^(1/3) - 2/(9*(2/(3*sqrt(3)) + 10/27)^(1/3)) + 1/3

Quiz: how to simplify that expression to 1 within SAGE? I've tried simplify,
and radical_simplify, but neither succeeds...

Paul Zimmermann

kcrisman

unread,
Jan 24, 2008, 10:05:31 AM1/24/08
to sage-support

> Thus you have constructed a nice expression for 1:
>
> sage: sol[2].subs(a=1).right()
> (2/(3*sqrt(3)) + 10/27)^(1/3) - 2/(9*(2/(3*sqrt(3)) + 10/27)^(1/3)) + 1/3
>
> Quiz: how to simplify that expression to 1 within SAGE? I've tried simplify,
> and radical_simplify, but neither succeeds...
>
> Paul Zimmermann

Ted, I've been there - running into that sort of "nice" formula with
Sage in the class, presumably via Maxima. As cool as it is, it is
also confusing and disheartening to my students, who have no
experience to interpret it with.

More to the point, I would softly plead a different view on
(-1)^(1/3). As a mathematician, I think getting the "usual" primitive
sixth root of unity is wonderful (though perhaps even making that
choice is suspect, why not its complex conjugate?), but as a pedagogue
it would cause me to question using Sage in any environment where I
needed numerical solutions to simple algebraic equations, such as any
HS class or many (though not all) freshman non-major math courses.

I definitely want my students to know how to do it by hand - in fact,
they *should* solve x^3=-1 by hand. But as Ted points out, getting a
useful numerical approximation for x^3=-3 by typing (-3)^(1/3) is a
legitimate need, even for students who aren't ready for complex
numbers (and such students definitely exist). And yet,

sage: (-3)^(1/3)
(-1)^(1/3)*3^(1/3)
sage: n(_)
0.721124785153704 + 1.24902476648341*I

Even using the decimal point to ensure we get a numerical solution,
which does seems like something a student could understand why they
should do when describing symbolic versus numerical computation,
doesn't help:

sage: (-3.0)^(1/3)
0.721124785153704 + 1.24902476648341*I

and Sage fails something even my eight dollar CVS calculator can (to
my surprise) do! This seems problematic.

- kcrisman

Jason Grout

unread,
Jan 24, 2008, 10:55:40 AM1/24/08
to sage-s...@googlegroups.com

For the record, in Mathematica:

In[1]:= (-1)^(1/3)

Out[1]= (-1)^(1/3)

In[2]:= % // N

Out[2]= 0.5+ 0.866025 I

In[3]:= (-3)^(1/3) // N

Out[3]= 0.721125+ 1.24902 I


In previous versions of Mathematica, there was a "RealOnly" package
which defined odd roots as negative and printed "Nonreal" anytime a
complex number was unavoidable. The idea was that you could simplify
things for high school students or in situations in which you knew you
were only interested real numbers. That package has apparently been
deprecated now in version 6.0, being replaced by the functionality to
"Reduce" an equation over the reals, etc. For details, you can see the
package at http://library.wolfram.com/infocenter/MathSource/6771/

Jason

Carl Witty

unread,
Jan 24, 2008, 1:03:01 PM1/24/08
to sage-support
On Jan 23, 11:41 pm, Paul Zimmermann <Paul.Zimmerm...@loria.fr> wrote:
> Thus you have constructed a nice expression for 1:
>
> sage: sol[2].subs(a=1).right()
> (2/(3*sqrt(3)) + 10/27)^(1/3) - 2/(9*(2/(3*sqrt(3)) + 10/27)^(1/3)) + 1/3
>
> Quiz: how to simplify that expression to 1 within SAGE? I've tried simplify,
> and radical_simplify, but neither succeeds...

The Sage rings AA and QQbar can decide equalities between radical
expressions (over the reals and complex numbers respectively):

sage: a = AA((2/(3*sqrt(3)) + 10/27)^(1/3) - 2/(9*(2/(3*sqrt(3)) +
10/27)^(1/3)) + 1/3)
sage: a
[0.99999999999999988 .. 1.0000000000000003]
sage: a == 1
True

By the way, when I implemented AA/QQbar, I decided on the following
behavior for exponentiation:

sage: AA(-1)^(1/3)
-1
sage: QQbar(-1)^(1/3)
[0.49999999999999994 .. 0.50000000000000012] + [0.86602540378443859 ..
0.86602540378443871]*I

So when taking roots, for AA we prefer real roots if they exist, but
for QQbar we take the principal root.

Carl Witty

William Stein

unread,
Jan 24, 2008, 2:29:06 PM1/24/08
to sage-s...@googlegroups.com

Wow! That's all very impressive actually. It would be great if you
could add the above examples to the tutorials for AA and QQbar (i.e.,
the tops of the relevant code files). Nice.

-- William

Paul Zimmermann

unread,
Jan 25, 2008, 4:24:42 PM1/25/08
to sage-s...@googlegroups.com
> In previous versions of Mathematica, there was a "RealOnly" package
> which defined odd roots as negative and printed "Nonreal" anytime a
> complex number was unavoidable. The idea was that you could simplify
> things for high school students or in situations in which you knew you
> were only interested real numbers. That package has apparently been
> deprecated now in version 6.0, being replaced by the functionality to
> "Reduce" an equation over the reals, etc. For details, you can see the
> package at http://library.wolfram.com/infocenter/MathSource/6771/

the problem with such a package, which basically simplifies (-1)^(1/3) to -1,
is that it might have side effects with internal computations, and thus give
wrong results.

Imagine for example that for a given computation, which involves real numbers
only at the user interface level, SAGE needs to compute internally over the
complex numbers. If such an internal algorithm working on the complex numbers
was designed for the classical branch choice, i.e., (-1)^(1/3) = 1/2 +
sqrt(3)/2*I, then changing the rules will surely make this algorithm fail,
and thus return inconsistent or wrong results.

If one wants that (-1)^(1/3) simplifies to -1, the only clean solution I see
is to write a special function simplify_real to do that, but be prepared to
see inconsistent results.

Paul Zimmermann

John Cremona

unread,
Jan 25, 2008, 4:44:23 PM1/25/08
to sage-s...@googlegroups.com

+1

This is an ancient question which all CAS have to wrestle with at some
point (I remember when it was Maple's turn). What seems
superficially to be the "elementary" solution to the question of
odd'th roots of negative reals just leads to horrendous internal
problems if followed through. Maths is not always simple.

John

> Paul Zimmermann
>
> >
>


--
John Cremona

Reply all
Reply to author
Forward
0 new messages