#8992: Coercion of univariate quotient polynomial rings
-------------------------+--------------------------------------------------
Reporter: SimonKing | Owner: robertwb
Type: defect | Status: needs_review
Priority: major | Milestone: sage-5.0
Component: coercion | Keywords: coercion quotient ring
Work_issues: | Upstream: N/A
Reviewer: PatchBot | Author: Simon King
Merged: | Dependencies:
-------------------------+--------------------------------------------------
Changes (by SimonKing):
* status: needs_work => needs_review
* work_issues: rewrite, make polynomial division work =>
Old description:
> Consider the following setting:
> {{{
> sage: P.<x> = QQ[]
> sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)])
> sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)])
> }}}
>
> The gcd of the moduli is {{{(x^2+1)^2}}}, and so it should be true that
> the pushout of Q1 and Q2 is the quotient ring with this gcd as modulus.
> Currently, the pushout raises an error, but with #8800 one has:
> {{{
> sage: from sage.categories.pushout import pushout
> sage: Q = pushout(Q1,Q2); Q
> Univariate Quotient Polynomial Ring in xbar over Rational Field with
> modulus x^4 + 2*x^2 + 1
> }}}
>
> However, there remain two bugs that are not covered in #8800 and that
> prevent a proper coercion of Q1 and Q2.
>
> First bug:
> {{{
> sage: Q.has_coerce_map_from(Q1)
> False
> sage: Q.has_coerce_map_from(Q2)
> False
> }}}
>
> Second bug:
> {{{
> sage: Q(Q1.gen())
> ERROR: An unexpected error occurred while tokenizing input
> The following traceback may be corrupted or invalid
> The error message is: ('EOF in multi-line statement', (932, 0))
>
> ERROR: An unexpected error occurred while tokenizing input
> The following traceback may be corrupted or invalid
> The error message is: ('EOF in multi-line statement', (932, 0))
>
> ---------------------------------------------------------------------------
> TypeError Traceback (most recent call
> last)
>
> /home/king/SAGE/sage-4.3.1/devel/<ipython console> in <module>()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/polynomial/polynomial_quotient_ring.pyc in
> __call__(self, x)
> 272 return PolynomialQuotientRingElement(self,
> self.__ring(x.lift()), check=False)
> 273 return PolynomialQuotientRingElement(
> --> 274 self, self.__ring(x) , check=True)
> 275
> 276 def _is_valid_homomorphism_(self, codomain, im_gens):
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/parent.so in
> sage.structure.parent.Parent.__call__ (sage/structure/parent.c:6332)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3108)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3010)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/polynomial/polynomial_ring.pyc in
> _element_constructor_(self, x, check, is_gen, construct, **kwds)
> 310 x = x.Polrev()
> 311
> --> 312 return C(self, x, check, is_gen, construct=construct,
> **kwds)
> 313
> 314 def is_integral_domain(self, proof = True):
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/polynomial/polynomial_element_generic.pyc in
> __init__(self, parent, x, check, is_gen, construct)
> 654
> 655 if check:
> --> 656 x = [QQ(z) for z in x]
> 657
> 658 self.__list = list(x)
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/parent.so in
> sage.structure.parent.Parent.__call__ (sage/structure/parent.c:6332)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3108)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3010)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/rational.so in sage.rings.rational.Rational.__init__
> (sage/rings/rational.c:5781)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/rational.so in
> sage.rings.rational.Rational.__set_value (sage/rings/rational.c:7052)()
>
> TypeError: Unable to coerce xbar (<class
> 'sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement'>)
> to Rational
> sage: Q.gen()
> xbar
> }}}
>
> It could be that the following is an additional bug, but perhaps it is
> just a special case of the previous:
> {{{
> sage: Q(str(Q.gen()))
> ERROR: An unexpected error occurred while tokenizing input
> The following traceback may be corrupted or invalid
> The error message is: ('EOF in multi-line statement', (932, 0))
>
> ERROR: An unexpected error occurred while tokenizing input
> The following traceback may be corrupted or invalid
> The error message is: ('EOF in multi-line statement', (932, 0))
>
> ---------------------------------------------------------------------------
> TypeError Traceback (most recent call
> last)
>
> /home/king/SAGE/sage-4.3.1/devel/<ipython console> in <module>()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/polynomial/polynomial_quotient_ring.pyc in
> __call__(self, x)
> 272 return PolynomialQuotientRingElement(self,
> self.__ring(x.lift()), check=False)
> 273 return PolynomialQuotientRingElement(
> --> 274 self, self.__ring(x) , check=True)
> 275
> 276 def _is_valid_homomorphism_(self, codomain, im_gens):
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/parent.so in
> sage.structure.parent.Parent.__call__ (sage/structure/parent.c:6332)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3108)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3010)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/polynomial/polynomial_ring.pyc in
> _element_constructor_(self, x, check, is_gen, construct, **kwds)
> 297 R = self.base_ring()
> 298 p = Parser(Integer, R,
> LookupNameMaker({self.variable_name(): self.gen()}, R))
> --> 299 return self(p.parse(x))
> 300 except NameError:
> 301 raise TypeError,"Unable to coerce string"
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.parse
> (sage/misc/parser.c:3481)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.parse
> (sage/misc/parser.c:3345)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.p_eqn
> (sage/misc/parser.c:5136)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.p_expr
> (sage/misc/parser.c:5456)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.p_term
> (sage/misc/parser.c:5681)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.p_factor
> (sage/misc/parser.c:6044)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.p_power
> (sage/misc/parser.c:6158)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.Parser.p_atom
> (sage/misc/parser.c:6711)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/misc/parser.so in sage.misc.parser.LookupNameMaker.__call__
> (sage/misc/parser.c:7653)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/parent.so in
> sage.structure.parent.Parent.__call__ (sage/structure/parent.c:6332)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3108)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/structure/coerce_maps.so in
> sage.structure.coerce_maps.DefaultConvertMap_unique._call_
> (sage/structure/coerce_maps.c:3010)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/rational.so in sage.rings.rational.Rational.__init__
> (sage/rings/rational.c:5781)()
>
> /home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
> packages/sage/rings/rational.so in
> sage.rings.rational.Rational.__set_value (sage/rings/rational.c:6517)()
>
> TypeError: unable to convert xbar to a rational
> }}}
New description:
Consider the following setting:
{{{
sage: P.<x> = QQ[]
sage: Q1 = P.quo([(x^2+1)^2*(x^2-3)])
sage: Q2 = P.quo([(x^2+1)^2*(x^5+3)])
}}}
The gcd of the moduli is {{{(x^2+1)^2}}}, and so it should be true that
the pushout of Q1 and Q2 is the quotient ring with this gcd as modulus.
Currently, the pushout raises an error, but with #8800 one has:
{{{
sage: from sage.categories.pushout import pushout
sage: Q = pushout(Q1,Q2); Q
Univariate Quotient Polynomial Ring in xbar over Rational Field with
modulus x^4 + 2*x^2 + 1
}}}
However, there remain two bugs that are not covered in #8800 and that
prevent a proper coercion of Q1 and Q2.
First bug:
{{{
sage: Q.has_coerce_map_from(Q1)
False
sage: Q.has_coerce_map_from(Q2)
False
}}}
Second bug:
{{{
sage: Q(Q1.gen())
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (932, 0))
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (932, 0))
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)
/home/king/SAGE/sage-4.3.1/devel/<ipython console> in <module>()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/polynomial/polynomial_quotient_ring.pyc in
__call__(self, x)
272 return PolynomialQuotientRingElement(self,
self.__ring(x.lift()), check=False)
273 return PolynomialQuotientRingElement(
--> 274 self, self.__ring(x) , check=True)
275
276 def _is_valid_homomorphism_(self, codomain, im_gens):
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/parent.so in sage.structure.parent.Parent.__call__
(sage/structure/parent.c:6332)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3108)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3010)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/polynomial/polynomial_ring.pyc in
_element_constructor_(self, x, check, is_gen, construct, **kwds)
310 x = x.Polrev()
311
--> 312 return C(self, x, check, is_gen, construct=construct,
**kwds)
313
314 def is_integral_domain(self, proof = True):
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/polynomial/polynomial_element_generic.pyc in
__init__(self, parent, x, check, is_gen, construct)
654
655 if check:
--> 656 x = [QQ(z) for z in x]
657
658 self.__list = list(x)
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/parent.so in sage.structure.parent.Parent.__call__
(sage/structure/parent.c:6332)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3108)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3010)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/rational.so in sage.rings.rational.Rational.__init__
(sage/rings/rational.c:5781)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/rational.so in
sage.rings.rational.Rational.__set_value (sage/rings/rational.c:7052)()
TypeError: Unable to coerce xbar (<class
'sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement'>)
to Rational
sage: Q.gen()
xbar
}}}
It could be that the following is an additional bug, but perhaps it is
just a special case of the previous:
{{{
sage: Q(str(Q.gen()))
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (932, 0))
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (932, 0))
---------------------------------------------------------------------------
TypeError Traceback (most recent call
last)
/home/king/SAGE/sage-4.3.1/devel/<ipython console> in <module>()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/polynomial/polynomial_quotient_ring.pyc in
__call__(self, x)
272 return PolynomialQuotientRingElement(self,
self.__ring(x.lift()), check=False)
273 return PolynomialQuotientRingElement(
--> 274 self, self.__ring(x) , check=True)
275
276 def _is_valid_homomorphism_(self, codomain, im_gens):
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/parent.so in sage.structure.parent.Parent.__call__
(sage/structure/parent.c:6332)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3108)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3010)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/polynomial/polynomial_ring.pyc in
_element_constructor_(self, x, check, is_gen, construct, **kwds)
297 R = self.base_ring()
298 p = Parser(Integer, R,
LookupNameMaker({self.variable_name(): self.gen()}, R))
--> 299 return self(p.parse(x))
300 except NameError:
301 raise TypeError,"Unable to coerce string"
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.parse
(sage/misc/parser.c:3481)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.parse
(sage/misc/parser.c:3345)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.p_eqn
(sage/misc/parser.c:5136)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.p_expr
(sage/misc/parser.c:5456)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.p_term
(sage/misc/parser.c:5681)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.p_factor
(sage/misc/parser.c:6044)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.p_power
(sage/misc/parser.c:6158)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.Parser.p_atom
(sage/misc/parser.c:6711)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/misc/parser.so in sage.misc.parser.LookupNameMaker.__call__
(sage/misc/parser.c:7653)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/parent.so in sage.structure.parent.Parent.__call__
(sage/structure/parent.c:6332)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3108)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/structure/coerce_maps.so in
sage.structure.coerce_maps.DefaultConvertMap_unique._call_
(sage/structure/coerce_maps.c:3010)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/rational.so in sage.rings.rational.Rational.__init__
(sage/rings/rational.c:5781)()
/home/king/SAGE/sage-4.3.1/local/lib/python2.6/site-
packages/sage/rings/rational.so in
sage.rings.rational.Rational.__set_value (sage/rings/rational.c:6517)()
TypeError: unable to convert xbar to a rational
}}}
Apply [attachment:trac8992_conversion_polynomial_quotient_ring.patch]
--
Comment:
I have produced a new patch.
Recall that most problems mentioned in the ticket description have already
been solved in sage-5.0.beta7. The only remaining was conversion from
strings.
Here, I suggest to use a tool that I have introduced in my code for
infinite polynomial rings: It is a generalisation of the gens_dict of
polynomial rings. In contrast to gens_dict, it not only considers the
generator names of the ring, but it also considers (recursively) the
generator names of the base ring. This recursive version of gens_dict is
then passed to sage_eval.
Hence, if Q has generator 'xbar' and is the quotient ring of some
polynomial ring P with generator 'x', then `Q('x*xbar')` will be correctly
evaluated as `P.gen()*Q.gen()`, which in turn evaluates as
`Q(P.gen())*Q.gen()`.
Concerning the problem with `y.divides(...)`: The problem can arise, if Q1
and Q2 are two polynomial quotient rings and one asks
`Q1.has_coerce_map_from(Q2)`. It will try to divide the moduli of Q1 and
Q2. My suggestion is: If that division fails with an error, then there is
no coerce map.
After these changes, the tests in
sage/rings/polynomial/polynomial_quotient_ring.py and
.../polynomial_quotient_ring_element.py pass.
Let's see if the patchbot finds a reason to complain...
Apply trac8992_conversion_polynomial_quotient_ring.patch
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/8992#comment:10>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.