# coerce pari type or string to rational function workaround?

I am getting some rational functions from pari/gp and want to work with them in Sage. I can't figure out how to do the coercion. I tried coercing them directly, and even via a string.

Here's what I've tried:

Make a pari type rational function:

sage: test = gp.simplify((x+y)/y)


This is the field I want to put it in:

sage: R.<x,y> = PolynomialRing(QQ)
sage: S = R.fraction_field()


coercing directly doesn't work:

sage: S(test)
Traceback (most recent call last):
...
TypeError: unable to convert 1/y*x + 1 to a rational


So I tried making a string out of it:

sage: str(test)
'1/y*x + 1'


Of course, sage would accept that string if I typed it in directly:

sage: S(1/y*x + 1)
(x + y)/y


But it won't accept it as a string:

sage: S(str(test))
Traceback (most recent call last):
...
TypeError: no canonical coercion from Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field to Rational Field
sage: S('1/y*x + 1')
Traceback (most recent call last):
...
TypeError: no canonical coercion from Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field to Rational Field


All of this works fine for polynomials (just remove the denominator of y from the example above). I think these are bugs and I will report them as such, if you agree. But in the meantime, does anyone have a workaround I can use?

edit retag close merge delete

Thanks for the answers below. I've got my computation working (yay!), but I'm also going to find out if the bug(s) are known and report them if needed. I suspect this must be a known issue, so I'll add a comment when I've looked into it on the tracking system. Any comments or advice on that is welcome.

( 2011-05-23 01:04:29 +0200 )edit
( 2011-05-23 01:17:00 +0200 )edit

Sort by » oldest newest most voted

Here's how I'd get around the problem if I needed it to work Right Now(tm):

sage: var("x y")
(x, y)
sage: t = gp.simplify((x+y)/y)
sage:
sage: R.<x,y> = PolynomialRing(QQ)
sage: S = R.fraction_field()
sage:
sage: t2 = S(sage_eval(repr(t),locals=locals()))
sage: t2
(x + y)/y
sage: parent(t2)
Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field
sage: parent(t2) is S
True

more

Thanks! Right Now(tm) is exactly what I needed, and this did the trick.

( 2011-05-23 01:01:15 +0200 )edit

I think you're right that there are bugs here, but I don't quite know what they are either.

In any case, I think the Symbolic Ring can serve as a useful intermediary here. With your example, I did

sage: test_sr = SR(test)


You can see that it's still the right thing, but as a symbolic Sage object:

sage: test_sr
1/y*x + 1
sage: test_sr.parent()
Symbolic Ring


Unfortunately, converting straight to S still doesn't work:

sage: S(test_sr)
...
TypeError:


However, the method coeffs returns coefficients for powers of the given variable, and individual coefficients can be coerced to S:

sage: test_sr.coeffs(x)
[[1, 0], [1/y, 1]]
sage: test_sr.coeffs(y)
[[x, -1], [1, 0]]

sage: sum(S(c[0])*x^c[1] for c in test_sr.coeffs(x))
(x + y)/y
sage: sum(S(c[0])*y^c[1] for c in test_sr.coeffs(y))
(x + y)/y


Of course it's probably not helpful if S unsimplifies something that you specifically wanted simplified, but bear in mind that the rational function field will always try to give you elements which are ratios of polynomials. Even if that's not what you want, coercing the individual coefficients will of course work.

more

Thanks! This works, but for some reason it is extremely slow, at least on my machine.

( 2011-05-23 01:00:25 +0200 )edit