Ticket #2420 (new enhancement)

Opened 9 months ago

Last modified 5 months ago

[with patch, needs work] Extending the gap interface to uni- and multivariate polynomial rings over number fields

Reported by: SimonKing Assigned to: SimonKing
Priority: major Milestone: sage-3.2.2
Component: interfaces Keywords: gap interface, polynomial rings, number fields, editor_mhansen
Cc: mabshoff

Description

Up to now, the gap interface did not work on polynomial rings over number fields. This patch extends the interface accordingly, so that now the following works. Univariate:

sage: F=CyclotomicField(8)
sage: R=PolynomialRing(F,'x')
sage: gap(R)
PolynomialRing( <algebraic extension over the Rationals of degree 4>, ["x"] )
sage: p=R('zeta8^2*x+zeta8')
sage: gap(p)^3
((-1*zeta8^2))*x^3+((-3*zeta8))*x^2+(!-3)*x+(zeta8^3)
sage: p^3
(-zeta8^2)*x^3 + (-3*zeta8)*x^2 + (-3)*x + zeta8^3

Multivariate:

sage: R=PolynomialRing(F,'x,y')
sage: gap(R)
PolynomialRing( <algebraic extension over the Rationals of degree
4>, ["x", "y"] )
sage: p=R('zeta8*x+zeta8^2*y')^2
sage: gap(p)
(zeta8^2)*x^2+(2*zeta8^3)*x*y-y^2
sage: p
zeta8^2*x^2 + 2*zeta8^3*x*y + (-1)*y^2

The patches also provide doc tests.

However, there is one problem: On my machine, the doc tests of sage.rings.polynomial.polynomial_element.pyx trigger the bug reported in #2419. That bug seems to occur only on few machines (up to now, only one other person can reproduce #2419).

So, there should be discussion how to deal with that issue.

Attachments

mpoly_over_numberfield.patch (5.7 kB) - added by SimonKing on 03/07/2008 04:35:50 PM.
new patch, adding more doctests, should apply to sage 2.10.3.rc2

Change History

(follow-up: ↓ 2 ) 03/07/2008 03:05:12 AM changed by mhansen

The _gap_init_ methods in a/sage/rings/polynomial/multi_polynomial_element.py and a/sage/rings/polynomial/multi_polynomial_ring_generic.pyx need doctests. Also, the "proper" way to do

sage: F=CyclotomicField(8)
sage: R=PolynomialRing(F,'x')
sage: p=R('zeta8^2*x+zeta8')

in Sage is

sage: F.<zeta8>=CyclotomicField(8)
sage: R.<x>=PolynomialRing(F)
sage: p=zeta8^2*x+zeta8

03/07/2008 04:35:50 PM changed by SimonKing

  • attachment mpoly_over_numberfield.patch added.

new patch, adding more doctests, should apply to sage 2.10.3.rc2

(in reply to: ↑ 1 ) 03/07/2008 04:45:51 PM changed by SimonKing

Replying to mhansen:

The _gap_init_ methods in a/sage/rings/polynomial/multi_polynomial_element.py and a/sage/rings/polynomial/multi_polynomial_ring_generic.pyx need doctests.

Thank you, simply i forgot to include them - the new patch contains tests, it uses the "proper" sage syntax you indicated, and also i had to put a bracket in a different place in _gap_init_ for multi_polynomial_element.py

One more example: With the new patch, it is even possible to have polynomial rings over polynomial rings over ... :

sage: F.<c> = CyclotomicField(8)
sage: r.<a,b> = PolynomialRing(F)
sage: R.<x,y> = PolynomialRing(r)
sage: p=R.random_element()+c^2*R.random_element()
sage: g=gap(p)
sage: p
((-2*c^2)*a^2 + (-2*c^2)*b^2 + c^2*a + (-c^2)*b - 2*c^2)*x^2 + (2*c^2*a^2 + (-2*c^2 - 2)*a*b + (2*c^2 + 2)*b^2 + c^2*a + (-1)*b + 2*c^2 - 2)*x*y + ((-2*c^2)*a^2 + 2*c^2*a*b + (2*c^2 - 1)*b^2 + (2*c^2 - 2)*a + b + 2)*y^2 + (2*b^2 + a + 1)*x + ((-2*c^2 + 2)*a^2 + (-c^2 - 2)*a*b + (-c^2 + 1)*b^2 + (-c^2 + 2)*a + c^2*b - 2)*y + (-2*c^2)*a^2 + (-2*c^2 - 2)*a*b + c^2*b^2 + a + (-2*c^2)*b + 2*c^2 + 1
sage: g
(((-2*c^2))*a^2+((-2*c^2))*b^2+(c^2)*a+((-1*c^2))*b+((-2*c^2)))*x^2+((2*c^2)*a^2+((-2-2*c^2))*a*b+((2+2*c^2))*b^2+(c^2)*a-b+((-2+2*c^2)))*x*y+(((-2*c^2))*a^2+(2*c^2)*a*b+((-1+2*c^2))*b^2+((-2+2*c^2))*a+b+!2)*y^2+(!2*b^2+a+!1)*x+(((2-2*c^2))*a^2+((-2-1*c^2))*a*b+((1-1*c^2))*b^2+((2-1*c^2))*a+(c^2)*b+(!-2))*y+(((-2*c^2))*a^2+((-2-2*c^2))*a*b+(c^2)*b^2+a+((-2*c^2))*b+((1+2*c^2)))
sage: g^3==gap(p^3)
True

03/11/2008 10:07:50 PM changed by rlm

  • milestone changed from sage-2.11 to sage-2.10.4.

03/13/2008 03:37:07 AM changed by SimonKing

I expected that with William's patch from #2419 the doc tests of polynomial_element.pyx would work, but they don't. And the strange thing is that they do work when sage is started from scratch:

Example from _gap_init_():

sage: F.<zeta8>=CyclotomicField(8)
sage: R.<x>=F[]
sage: p=zeta8^2*x+zeta8
sage: p._gap_init_()
'(GeneratorsOfField($sage2)[1]*IndeterminatesOfPolynomialRing($sage3)[1]^0)+(GeneratorsOfField($sage2)[1]^2*IndeterminatesOfPolynomialRing($sage3)[1]^1)'
sage: gap(p)^3
((-1*zeta8^2))*x^3+((-3*zeta8))*x^2+(!-3)*x+(zeta8^3)
sage: p^3
(-zeta8^2)*x^3 + (-3*zeta8)*x^2 + (-3)*x + zeta8^3

Example from _gap_():

sage: R.<y> = ZZ[]
sage: f = y^3 - 17*y + 5
sage: g = gap(f); g
y^3-17*y+5
sage: f._gap_init_()
'(5*IndeterminatesOfPolynomialRing($sage6)[1]^0)+(-17*IndeterminatesOfPolynomialRing($sage6)[1]^1)+(0*IndeterminatesOfPolynomialRing($sage6)[1]^2)+(1*IndeterminatesOfPolynomialRing($sage6)[1]^3)'
sage: R.<z> = ZZ[]
sage: gap(R)
PolynomialRing( Integers, ["z"] )
sage: g
y^3-17*y+5
sage: gap(z^2 + z)
z^2+z
sage: R.<y> = GF(7)[]
sage: f = y^3 - 17*y + 5
sage: g = gap(f); g
y^3+Z(7)^4*y+Z(7)^5
sage: g.Factors()
[ y+Z(7)^0, y+Z(7)^0, y+Z(7)^5 ]
sage: f.factor()
(y + 5) * (y + 1)^2

Agh! I got it! If one now does the examples for resultant, it crashes (at least on my machine):

sage: R.<x> = QQ[]
sage: f = x^3 + x + 1;  g = x^3 - x - 1
sage: r = f.resultant(g); r
-8
sage: r.parent() is QQ
True
sage: R.<a> = QQ[]
sage: S.<x> = R[]
sage: f = x^2 + a; g = x^3 + a
sage: r = f.resultant(g); r
a^3 + a^2
sage: r.parent() is R
True
sage: R.<a, b> = QQ[]
sage: S.<x> = R[]
sage: f = x^2 + a; g = x^3 + b
sage: r = f.resultant(g); r
---------------------------------------------------------------------------
<type 'exceptions.NameError'>             Traceback (most recent call last)
...
<type 'exceptions.NameError'>: name 'Mod' is not defined

But if sage is restarted, the example for resultant works fine!

Conclusion:

  • The patch from #2419 doesn't solve the problem.
  • Probably it is needed to do a synchronization (similar to #2419) for the gap interface as well.

03/13/2008 05:20:07 AM changed by SimonKing

Note that in the above example, eventually R has no dictionary, hasattr(R,'__dict__') is False!

Something else seems very strange to me. In my patch i define _gap_init_() as method for a polynomial ring like that:

def _gap_init_(self):
    return 'PolynomialRing(%s, ["%s"])'%(sage.interfaces.gap.gap(self.base_ring()).name(), self.variable_name())

If i define this function in sage (i.e., not as a method), i get

sage: R.<y> = GF(7)[]
sage: gap(_gap_init_(R)).name()
'$sage2'
sage: gap(_gap_init_(R)).name()
'$sage2'

so, the gap name is cached. But if _gap_init_ is a method of R, i obtain (re-starting sage)

sage: R.<y> = GF(7)[]
sage: gap(R).name()
'$sage2'
sage: gap(R).name()
'$sage3'
sage: gap(R).name()
'$sage3'

Hence, it seems that gap(R) doesn't properly caches the things.

Sorry that my post is rather confused, but this is what i am now.

03/15/2008 02:39:44 PM changed by mhansen

  • summary changed from [with patch, needs review] Extending the gap interface to uni- and multivariate polynomial rings over number fields to [with patch, needs work] Extending the gap interface to uni- and multivariate polynomial rings over number fields.

06/19/2008 09:45:58 PM changed by craigcitro

  • keywords changed from gap interface, polynomial rings, number fields to gap interface, polynomial rings, number fields, editor_mhansen.