Coercion between quadratic fields fails (by default)

132 views
Skip to first unread message

Jonathan Kliem

unread,
Nov 29, 2019, 3:45:45 PM11/29/19
to sage-devel
The following leads to a TypeError:

sage: K2.<sqrt2> = QuadraticField(2)
sage
: K3.<sqrt3> = QuadraticField(3)
sage
: sqrt2 + sqrt3

Both of them are real embedded by default, so coercion should work (at least this is my opinion).

This can be fixed by specifying that both of them are embedded into the algebraic reals (at the moment RLF is default).
Also casting sqrt2 to AA does not work at the moment (at least not without numerical noise).

Is it reasonable to apply this by default (i.e. embed quadratic fields into AA/QQbar)?
This would lead to failing doctests for mostly two reasons:
  • numerical approximation works differently for AA and RLF
  • cyclotomic should be standard embedded into QQbar then
Are there specific reasons, that they are embedded into RLF resp. CLF at the moment?

I opened a 28774 for this.

My motivation: It seems very natural to construct a polyhedron over quadratic fields. However, coercion of those polyhedra does not work. See 28776

Nils Bruin

unread,
Nov 29, 2019, 4:47:13 PM11/29/19
to sage-devel


On Friday, November 29, 2019 at 12:45:45 PM UTC-8, Jonathan Kliem wrote:
The following leads to a TypeError:

sage: K2.<sqrt2> = QuadraticField(2)
sage
: K3.<sqrt3> = QuadraticField(3)
sage
: sqrt2 + sqrt3

Both of them are real embedded by default, so coercion should work (at least this is my opinion).

This can be fixed by specifying that both of them are embedded into the algebraic reals (at the moment RLF is default).

Embedding into RLF is really meant to be "embedding into real floats, with yet-to-be-specified precision". Float arithmetic has very different properties from AA/QQbar: it's reliably quick, but imprecise and with no equality test., whereas AA/QQbar is unpredictable in computation speed and possibly VERY expensive (but reliable) equality test.

I don't know if the choice of RLF was appropriate for a default embedding, but I'd be wary of embedding in AA/QQbar by default, because they are so unpredictable in their performance. Generally, you should NOT be computing in them except for exploratory work. It's usually possible to be more specific about the desired field with a bit of analysis and then you'll get much better and reliable performance.

Jonathan Kliem

unread,
Nov 30, 2019, 4:47:47 PM11/30/19
to sage-devel
Thanks for the comment.


Am Freitag, 29. November 2019 22:47:13 UTC+1 schrieb Nils Bruin:


On Friday, November 29, 2019 at 12:45:45 PM UTC-8, Jonathan Kliem wrote:
The following leads to a TypeError:

sage: K2.<sqrt2> = QuadraticField(2)
sage
: K3.<sqrt3> = QuadraticField(3)
sage
: sqrt2 + sqrt3

Both of them are real embedded by default, so coercion should work (at least this is my opinion).

This can be fixed by specifying that both of them are embedded into the algebraic reals (at the moment RLF is default).

Embedding into RLF is really meant to be "embedding into real floats, with yet-to-be-specified precision". Float arithmetic has very different properties from AA/QQbar: it's reliably quick, but imprecise and with no equality test., whereas AA/QQbar is unpredictable in computation speed and possibly VERY expensive (but reliable) equality test.

I don't know if the choice of RLF was appropriate for a default embedding, but I'd be wary of embedding in AA/QQbar by default, because they are so unpredictable in their performance. Generally, you should NOT be computing in them except for exploratory work. It's usually possible to be more specific about the desired field with a bit of analysis and then you'll get much better and reliable performance.

So is the current setup is meant to tell the user to think and figure out a good conversion him/herself?

I mean there is composite field and one can always convert to that and work there. Or convert to the reals, if one looks for a numerical solution.

Still conversion to AA and QQbar should work without numerical noise. But that is a different topic.

Nils Bruin

unread,
Nov 30, 2019, 5:52:44 PM11/30/19
to sage-devel


On Saturday, November 30, 2019 at 1:47:47 PM UTC-8, Jonathan Kliem wrote:

I don't know if the choice of RLF was appropriate for a default embedding, but I'd be wary of embedding in AA/QQbar by default, because they are so unpredictable in their performance. Generally, you should NOT be computing in them except for exploratory work. It's usually possible to be more specific about the desired field with a bit of analysis and then you'll get much better and reliable performance.

So is the current setup is meant to tell the user to think and figure out a good conversion him/herself?

That's how I interpret it, yes, and from experience, one should probably think of getting a good representation of the relevant field for one's purposes, since I don't think there is a universally good choice.
 
I mean there is composite field and one can always convert to that and work there.

Indeed, and I think for most algebraic purposes that will perform best.
 

Still conversion to AA and QQbar should work without numerical noise. But that is a different topic.

And I think they do. Those fields use an algebraic representation, together with interval arithmetic. So things might print with numerical noise but that's just an artifact of using the interval arithmetic representation.
Magma, for instance, uses an implementation of QQbar that is backed by finite field arithmetic instead of interval arithmetic. That is probably cheaper and more predictable performance-wise in most cases, but carries the low-probability event of a characteristic-based disaster, where it turns out the residue characteristic prime shows up in a numerator or a denominator.
 
There's no numerical noise as far as I can see:

sage: A.<a>=QuadraticField(2,embedding=AA(2).sqrt())
sage: B.<b>=QuadraticField(3,embedding=AA(3).sqrt())
sage: c=a+b; c #this is just how it prints
3.146264369941973?
sage: c.minpoly()
x^4 - 10*x^2 + 1
sage: (a+b)*(a-b)*(b-a)*(-a-b)
1

Vincent Delecroix

unread,
Nov 30, 2019, 8:10:48 PM11/30/19
to sage-...@googlegroups.com
Calling c.minpoly() triggers some exactification. Compare with

sage: a = AA(2).sqrt()
sage: b = AA(3).sqrt()
sage: (a + b) * (a - b) * (b - a) * (-a -b)
1.000000000000000?

Nils Bruin

unread,
Dec 1, 2019, 2:46:43 AM12/1/19
to sage-devel
On Saturday, November 30, 2019 at 5:10:48 PM UTC-8, vdelecroix wrote:

Calling c.minpoly() triggers some exactification. Compare with

sage: a = AA(2).sqrt()
sage: b = AA(3).sqrt()
sage: (a + b) * (a - b) * (b - a) * (-a -b)
1.000000000000000?
Sure, but there is no "numerical noise" other than in the internal interval arithmetic and perhaps a little strange printing. In all cases, the quantity computed is exactly 1.

Brent W. Baccala

unread,
Dec 2, 2019, 10:55:23 AM12/2/19
to sage-devel
I'd suggest setting AA.options.display_format = 'radical' to eliminate the "numerical noise".


Michael Orlitzky

unread,
Dec 2, 2019, 6:18:20 PM12/2/19
to sage-...@googlegroups.com
On 12/2/19 10:55 AM, Brent W. Baccala wrote:
> I'd suggest setting AA.options.display_format = 'radical' to eliminate
> the "numerical noise".

Who do I have to make a campaign donation to if I want this to be the
default?

Nils Bruin

unread,
Dec 2, 2019, 6:48:09 PM12/2/19
to sage-devel


On Monday, December 2, 2019 at 3:18:20 PM UTC-8, Michael Orlitzky wrote:
Who do I have to make a campaign donation to if I want this to be the
default?

The Society for the Prevention of Predictable Performance would be a good place to start.

Trying to find a radical expression for an algebraic number can be pretty expensive and, of course, may fail:

sage: QQbar.options.display_format="radical"
sage: QQbar['x'](x^5+x+3).roots()
[(-1.132997565885066?, 1),
 (-0.4753807566695497? - 1.129701725095409?*I, 1),
 (-0.4753807566695497? + 1.129701725095409?*I, 1),
 (1.041879539612083? - 0.822870338109958?*I, 1),
 (1.041879539612083? + 0.822870338109958?*I, 1)]

so I don't think it will ever be a default.

Michael Orlitzky

unread,
Dec 2, 2019, 7:10:23 PM12/2/19
to sage-...@googlegroups.com
On 12/2/19 6:48 PM, Nils Bruin wrote:
>
>
> On Monday, December 2, 2019 at 3:18:20 PM UTC-8, Michael Orlitzky wrote:
>
> Who do I have to make a campaign donation to if I want this to be the
> default?
>
>
> The Society for the Prevention of Predictable Performance would be a
> good place to start.
>
> Trying to find a radical expression for an algebraic number can be
> pretty expensive and, of course, may fail:
>

Sure, I'm not asking for a miracle. I don't even want sage to guess at a
radical expression unless it already knows one. But if I type sqrt(2)
into a matrix over QQbar, or if it e.g. arises from the 2-norm of (1,1),
then it should be pretty easy to output "sqrt(2)" and not make my
doctests look horrendous.

Simon King

unread,
Dec 3, 2019, 7:16:30 AM12/3/19
to sage-...@googlegroups.com
Hi Nils,
Hang on, does that mean that with display_format="radical", Sage will
show a radical expression when it finds one, and will show numerical
noise when it finds none (i.e., it does not simply raise an error)?

Indeed:
sage: QQbar['x'](((x^2+3)*(x^2-3)*(x^2+15)).expand()).roots()
[(-sqrt(3), 1),
(sqrt(3), 1),
(-I*sqrt(15), 1),
(-I*sqrt(3), 1),
(I*sqrt(3), 1),
(I*sqrt(15), 1)]

That's actually quite nice! So, it would be a good default -- if
performance wouldn't be a problem.

Anyway, thank you for pointing to this option, because I wasn't aware
that it exists and would have liked to use it from time to time.

Best regards,
Simon

Jonathan Kliem

unread,
Dec 5, 2019, 9:32:11 AM12/5/19
to sage-devel
According to the above discussion I marked https://trac.sagemath.org/ticket/28774 as wontfix, please review.
Reply all
Reply to author
Forward
0 new messages