Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

forced coercion vs. automatic coercion #813

Closed
nbruin opened this issue Oct 3, 2007 · 29 comments
Closed

forced coercion vs. automatic coercion #813

nbruin opened this issue Oct 3, 2007 · 29 comments

Comments

@nbruin
Copy link
Contributor

nbruin commented Oct 3, 2007

This should give similar results, but it is inconsistent:

P1.<x>=QQ[]
L=P1.fraction_field()
x=L(x)
P2.<y>=P1[]

f=x+y

P3.<x,y>=QQ[]

P3(f)

0*P3.0+f

Apply

  1. attachment: trac813_univariate_coerce_from_multivariate.patch
  2. attachment: trac_813_review.patch

to the Sage library repository.

Depends on #9944

Component: coercion

Author: Simon King

Reviewer: Julian Rueth

Merged: sage-4.7.2.alpha3

Issue created by migration from https://trac.sagemath.org/ticket/813

@roed314
Copy link
Contributor

roed314 commented Oct 13, 2007

comment:3

I will work on this once Robert has added rdef'd functions to Sage (that way I don't have to redo the changes once this occurs)

@roed314 roed314 modified the milestones: sage-2.8.7, sage-2.9 Oct 13, 2007
@mwhansen
Copy link
Contributor

comment:5

This now gives a TypeError when doing the last arithmetic:

TypeError: unsupported operand parent(s) for '+': 'Multivariate Polynomial Ring in x, y over Rational Field' and 'Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field'

@simon-king-jena
Copy link
Member

comment:6

I accidentally came accross this stone age ticket.

For the record: Current behaviour as of sage-4.7.rc2 is

sage: P1.<x>=QQ[]
sage: L=P1.fraction_field()
sage: x=L(x)
sage: P2.<y>=P1[]
sage:
sage: f=x+y
sage:
sage: P3.<x,y>=QQ[]
sage:
sage: P3(f)
x + y
sage:
sage: 0*P3.0+f
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/king/<ipython console> in <module>()

/mnt/local/king/SAGE/sage-4.7.rc2/local/lib/python2.6/site-packages/sage/structure/element.so in sage.structure.element.RingElement.__add__ (sage/structure/element.c:11959)()

/mnt/local/king/SAGE/sage-4.7.rc2/local/lib/python2.6/site-packages/sage/structure/coerce.so in sage.structure.coerce.CoercionModel_cache_maps.bin_op (sage/structure/coerce.c:7382)()

TypeError: unsupported operand parent(s) for '+': 'Multivariate Polynomial Ring in x, y over Rational Field' and 'Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field'
sage: f.parent()
Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field
sage: P3
Multivariate Polynomial Ring in x, y over Rational Field

The question thus is: Should there be a coercion from P3 to the parent of f? Then one should implement it. Otherwise, the ticket should be closed as invalid.

Let fP be the parent of f, hence, the polynomial ring in y over the fraction field of the polynomial ring in x over the rationals.

There is a coercion to fP from the polyomial ring in y over the polynomial ring in x over the rationals:

sage: from sage.structure.element import get_coercion_model
sage: cm = get_coercion_model()
sage: fP = f.parent()
sage: cm.explain(fP, QQ[x][y])
Coercion on right operand via
    Conversion map:
      From: Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field
      To:   Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field
Arithmetic performed after coercions.
Result lives in Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field
Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field

However, there is no such coercion from the bivariate polynomial ring in x and y over the rationals:

sage: cm.explain(fP, QQ[x,y])
Will try _r_action and _l_action
Unknown result parent.

I think there should be such coercion! What do you think? I guess I'll also ask sage-devel.

@simon-king-jena
Copy link
Member

comment:7

For the record: I did post on sage-algebra, not sage-devel.

There, I argued that there should be no coercion/pushout between QQ[x][y] and QQ[y][x], even though there is a coercion between QQ[x,y] and QQ[y,x]. I wonder whether my argument is convincing, though.

However, even in that case, I could imagine that with a little more effort one could modify the algorithm behind sage.categories.pushout.pushout so that the pushout of Frac(QQ['x'])['y'] and QQ['x','y'] is Frac(QQ['x'])['y']. Do we want that behaviour of the pushout?

@simon-king-jena
Copy link
Member

comment:8

Meanwhile I believe that this is not invalid. Namely, we have the following:

sage: from sage.categories.pushout import pushout
sage: pushout(QQ['x','y'],Frac(QQ['x'])['y'])
Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field

Hence, arithmetic between QQ['x','y'] and Frac(QQ['x'])['y'] should work! But it doesn't:

sage: QQ['x','y'](1) + Frac(QQ['x'])['y'](1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/king/Projekte/MeatAxe/meataxe-2.2.4/<ipython console> in <module>()

/mnt/local/king/SAGE/sage-4.7.1.rc1/local/lib/python2.6/site-packages/sage/structure/element.so in sage.structure.element.RingElement.__add__ (sage/structure/element.c:11997)()

/mnt/local/king/SAGE/sage-4.7.1.rc1/local/lib/python2.6/site-packages/sage/structure/coerce.so in sage.structure.coerce.CoercionModel_cache_maps.bin_op (sage/structure/coerce.c:7382)()

TypeError: unsupported operand parent(s) for '+': 'Multivariate Polynomial Ring in x, y over Rational Field' and 'Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field'

What is the problem? The conversion is fine:

sage: Frac(QQ['x'])['y'](QQ['x','y'](1))
1

But in fact there is no coercion into the pushout:

sage: pushout(QQ['x','y'],Frac(QQ['x'])['y']).has_coerce_map_from(QQ['x','y'])
False

That's a bug, I think.

@simon-king-jena
Copy link
Member

comment:9

PS: In addition, since there is a coercion from QQ['y','x'] to QQ['x','y'], it is conceivable that the pushout of QQ['y','x'] with Frac(QQ['x'])['y'] should be Frac(QQ['x'])['y'] as well. But it isn't:

sage: pushout(QQ['y','x'],Frac(QQ['x'])['y'])
---------------------------------------------------------------------------
CoercionException                         Traceback (most recent call last)

/home/king/Projekte/MeatAxe/meataxe-2.2.4/<ipython console> in <module>()

/mnt/local/king/SAGE/sage-4.7.1.rc1/local/lib/python2.6/site-packages/sage/categories/pushout.pyc in pushout(R, S)
   3072                     if Rc[-1] in Sc:
   3073                         if Sc[-1] in Rc:
-> 3074                             raise CoercionException, ("Ambiguous Base Extension", R, S)
   3075                         else:
   3076                             all = Sc.pop() * all

CoercionException: ('Ambiguous Base Extension', Multivariate Polynomial Ring in y, x over Rational Field, Univariate Polynomial Ring in y over Fraction Field of Univariate Polynomial Ring in x over Rational Field)

@simon-king-jena
Copy link
Member

comment:10

Here is my plan for implementing a coercion of P = QQ['x','y'] into Q = Frac(QQ['x'])['y'].

Since conversion of P into Q works, we only need to make Q._coerce_map_from_(P) return True.

Let p be an element of P. When converting p into Q, the multivariate polynomial p is transformed into a univeriate polynomial via p. This is done using p._polynomial_(Q), which ultimately boils down to Q(p.polynomial(P('y'))):

sage: P = QQ['x','y']
sage: p = P.gen(0)
sage: Q = Frac(QQ['x'])['y']
sage: Q(p.polynomial(P('y')))
x

p.polynomial(P('y')).parent() lives in a stacked polynomial ring:

sage: p.polynomial(P('y')).parent()
Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Rational Field

That stacked ring coerces into Q:

sage: Q.has_coerce_map_from(p.polynomial(P('y')).parent())
True

Conclusion: If we want to test whether a multivariate polynomial ring P coerces into a univariate polynomial ring Q in variable y, then we need to try and transform P into a univariate polynomial ring P' in variable y; here, we have P'=QQ['x']['y']. There is a coercion from P into Q if and only if there is a coercion from P' into Q.

I already have a patch, but "surprisingly" the additional coercion yields some doctest errors in other places.

@simon-king-jena
Copy link
Member

comment:11

The problem with my approach is that it would create a bidirectional coercion, namely a coercion from QQ['x','y'] to QQ['x']['y'] in addition to the coercion from QQ['x']['y'] to QQ['x','y'] that already exists.

But I think I have an idea that would solve the problem.

My original idea was to have a coercion from P to Q if there is a coercion from P.remove_var(Q.variable_name()) to Q.base_ring(). That created the bidirectional coercion.

My modified idea is to have the coercion from P to Q only if P.remove_var(Q.variable_name()) is different from Q.base_ring(), but coerces into it. Hence, a coercion only takes place if the rings become more complicated, thus avoiding circles.

The tests in sage/rings/polynomial pass. I am now running all doc tests, and then I can hopefully submit my patch...

@simon-king-jena
Copy link
Member

Coercion from multivariate to univariate polynomial rings

@simon-king-jena
Copy link
Member

Author: Simon King

@simon-king-jena
Copy link
Member

comment:12

Attachment: trac813_univariate_coerce_from_multivariate.patch.gz

I think I was able to solve the problem. With my patch applied on top of sage-4.7.1.rc1, all tests seem to pass, and one can do

            sage: P = QQ['x','y']
            sage: Q = Frac(QQ['x'])['y']
            sage: Q.has_coerce_map_from(P)
            True
            sage: P.0+Q.0
            y + x

In order to avoid bidirectional coercions (that would break a lot of tests), I have

            sage: Q = QQ['x']['y']
            sage: Q.has_coerce_map_from(P)
            False
            sage: Q.base_ring() is P.remove_var(Q.variable_name())
            True

The rule is: If Q.base_ring() is P.remove_var(Q.variable_name()) then there can not be a coercion from the multivariate ring P to the univariate ring Q; in fact, there is a coercion in the opposite direction. But otherwise, there is a coercion if Q.base_ring() has a coercion from P.remove_var(Q.variable_name()).

@simon-king-jena
Copy link
Member

Dependencies: #9944

@simon-king-jena
Copy link
Member

comment:13

Any reviewer for a time-honoured ticket?

@saraedum
Copy link
Member

comment:14

Looking at your patch, was def univariate_ring(self, x): added by purpose? Apart from that it seems to be a perfectly good solution as long as we can not have cyclic coercions.

@saraedum
Copy link
Member

comment:15

btw., doctests pass when applied to 4.7.2.alpha2.

@simon-king-jena
Copy link
Member

comment:17

Replying to @saraedum:

Looking at your patch, was def univariate_ring(self, x): added by purpose?

Good question. I think it was meant as analogy to the method univariate_polynomial of multivariate polynomials. But really, it seems unneeded to have that method. Could probably be dropped, if you prefer (needs to be tested, though).

@saraedum
Copy link
Member

comment:18

Ok. In this case it makes sense to have this method. I made some minor changes to the docstrings.

Sorry, I created an extra attachment. Apply trac813_univariate_coerce_from_multivariate.patch, trac_813_review.2.patch.

@saraedum

This comment has been minimized.

@saraedum
Copy link
Member

Reviewer: Julian Rueth

@saraedum
Copy link
Member

comment:19

Apply trac813_univariate_coerce_from_multivariate.patch, trac_813_review.2.patch.

@saraedum
Copy link
Member

comment:20

Apply trac813_univariate_coerce_from_multivariate.patch, trac_813_review.patch

Sorry, struggling with the patchbot.

@saraedum

This comment has been minimized.

@nexttime
Copy link
Mannequin

nexttime mannequin commented Sep 23, 2011

Replying to @nbruin:

Apply

  1. attachment: trac813_univariate_coerce_from_multivariate.patch

  2. attachment: trac_813_review.2.patch

to the sage repository.

? The attachment comment of the second file says "ignore this file", and the "patch" is only 17 bytes in total...

So I guess the description should be updated, to apply the "old" reviewer patch.

@saraedum
Copy link
Member

comment:22

sure. sorry, only updated the patchbot instructions but not the ticket description.

@saraedum

This comment has been minimized.

@nexttime
Copy link
Mannequin

nexttime mannequin commented Sep 23, 2011

comment:24

Ok, I've deleted the 17 bytes...

@nexttime

This comment has been minimized.

@nexttime
Copy link
Mannequin

nexttime mannequin commented Sep 27, 2011

Merged: sage-4.7.2.alpha3

@nexttime nexttime mannequin removed the s: positive review label Sep 27, 2011
@nexttime nexttime mannequin closed this as completed Sep 27, 2011
@jdemeyer
Copy link

jdemeyer commented Oct 4, 2011

Attachment: trac_813_review.patch.gz

small changes to docstrings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants