Ask Your Question
0

Conversion fraction field(QQ[X]) to fraction field(ZZ[X])

asked 2017-02-10 12:54:37 +0100

Clemens Heuberger gravatar image

How to I convert an element of the fraction field of QQ[X] to the fraction field of ZZ[X]?

sage: R.<x> = ZZ[]
sage: F = R.fraction_field()
sage: e = (1/2)/(x+1)
sage: e.parent()
Fraction Field of Univariate Polynomial Ring in x over Rational Field
sage: F(e)
Traceback (most recent call last):
...
TypeError: no conversion of this rational to integer

In my use case, e is the result of a lengthy computation where at some point beyond my control the result was coerced into QQ[X]. In my particular case, I prefer the fraction field of ZZ[X] because the output is nicer.

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
0

answered 2017-03-14 03:32:53 +0100

dan_fulea gravatar image

A hack would be to factor e and get the unit and the factors. For instance:

sage: R.<x> = ZZ[]
sage: F = R.fraction_field()
sage: e = (1/2)/(x+1)
sage: ef = e.factor()    # e factorized, as an instance of the class
sage: ef.parent()
<class 'sage.structure.factorization.Factorization'>
sage: ef.unit()
1/2
sage: ef.__dict__
{'_Factorization__cr': False,
 '_Factorization__unit': 1/2,
 '_Factorization__universe': Univariate Polynomial Ring in x over Rational Field,
 '_Factorization__x': [(x + 1, -1)]

Just a hack. An other one would be to get the lcm of the denominators of the coefficients appearing in the fraction. Explicitly. Here is an awful example, taken so to test if things work in a real mess.

sage: v = ( 1/6 * x^2 + 1/7 *x - 1/199 ) / (x+1/17) / 6 / (1/11*x+3/29)
sage: v
(1/6*x^2 + 1/7*x - 1/199)/(6/11*x^2 + 3540/5423*x + 18/493)
sage: vn = v.numerator()
sage: vd = v.denominator()
sage: vn, vd
(1/6*x^2 + 1/7*x - 1/199, 6/11*x^2 + 3540/5423*x + 18/493)
sage: vn.coefficients(), vd.coefficients()
([-1/199, 1/7, 1/6], [18/493, 3540/5423, 6/11])
sage: vnlcm = lcm( [ c.denominator() for c in vn.coefficients() ] )
sage: vdlcm = lcm( [ c.denominator() for c in vd.coefficients() ] )
sage: vnlcm, vdlcm
(8358, 5423)
sage: F( (vn*vnlcm) / (vd*vdlcm) )
(1393*x^2 + 1194*x - 42)/(2958*x^2 + 3540*x + 198)
sage: vdlcm / vnlcm * _ == v
True
edit flag offensive delete link more

Comments

I know, it is not a good idea to look into the __dict__, the internal representation may change in time. But this one particular __dict__ is very stable.

dan_fulea gravatar imagedan_fulea ( 2017-03-14 03:39:00 +0100 )edit
0

answered 2017-03-14 04:57:20 +0100

nbruin gravatar image

Rescaling numerator and denominator by the lcm of the denominators of the coefficients is the right thing to do:

sage: S=ZZ['x'].fraction_field()
sage: D=lcm([u.denominator() for u in e.numerator().coefficients() + e.denominator().coefficients()])
sage: S(D*e.numerator())/S(D*e.denominator())
1/(2*x + 2)

However, there is something much worse here:

sage: R=QQ['x'].fraction_field()
sage: a=(1/2)/(R.0+1)
sage: b=(1)/(2*R.0+2)
sage: a,b
(1/2/(x + 1), 1/(2*x + 2))
sage: a==b
True
sage: hash(a) == hash(b)
False

There's a report about this, though: https://trac.sagemath.org/ticket/15297

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-02-10 12:54:37 +0100

Seen: 967 times

Last updated: Mar 14 '17