Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
31716: more scalar conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
videlec committed Apr 22, 2021
1 parent de32db6 commit e2a22cb
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 103 deletions.
103 changes: 78 additions & 25 deletions src/sage/rings/fraction_field_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -753,34 +753,97 @@ cdef class FractionFieldElement(FieldElement):
else:
raise TypeError("denominator must equal 1")

def _integer_(self, Z=ZZ):
def __float__(self):
"""
EXAMPLES::
sage: K.<x,y> = Frac(ZZ['x,y'])
sage: float(x/x + y/y)
2.0
"""
return float(self.__numerator) / float(self.__denominator)

def __complex__(self):
"""
EXAMPLES::
sage: K.<x,y> = Frac(I.parent()['x,y'])
sage: complex(x/(I*x) + (I*y)/y)
0j
"""
return complex(self.__numerator) / complex(self.__denominator)

def _rational_(self):
r"""
TESTS::
sage: K = Frac(ZZ['x'])
sage: QQ(K(x) / K(2*x))
1/2
"""
return self._conversion(QQ)

def _conversion(self, R):
r"""
Generic conversion
TESTS::
sage: K = Frac(ZZ['x'])
sage: K(5)._integer_()
sage: ZZ(K(5)) # indirect doctest
5
sage: ZZ(K(1) / K(2))
Traceback (most recent call last):
...
ArithmeticError: inverse does not exist
sage: RDF(K(1) / K(2))
0.5
sage: K.<x> = Frac(RR['x'])
sage: ZZ(2*x/x)
2
"""
if self.__denominator != 1:
self.reduce()
if self.__denominator == 1:
return Z(self.__numerator)
raise TypeError("no way to coerce to an integer.")

def _rational_(self, Q=QQ):
"""
EXAMPLES::
sage: RDF(x)
Traceback (most recent call last):
...
TypeError: cannot convert nonconstant polynomial
sage: K.<x> = Frac(QQ['x'])
sage: K(1/2)._rational_()
sage: QQ(K(1/2))
1/2
sage: K(1/2 + x/x)._rational_()
sage: QQ(K(1/2 + x/x))
3/2
sage: x = polygen(QQ)
sage: A.<u> = NumberField(x^3 - 2)
sage: A((x+3) / (2*x - 1))
14/15*u^2 + 7/15*u + 11/15
sage: B = A['y'].fraction_field()
sage: A(B(u))
u
sage: C = A['x,y'].fraction_field()
sage: A(C(u))
u
"""
return Q(self.__numerator) / Q(self.__denominator)
if self.__denominator.is_one():
return R(self.__numerator)
else:
self.reduce()
num = R(self.__numerator)
inv_den = R(self.__denominator).inverse_of_unit()
return num * inv_den

_real_double_ = _conversion
_complex_double_ = _conversion
_mpfr_ = _conversion
_complex_mpfr_ = _conversion
_real_mpfi_ = _conversion
_complex_mpfi_ = _conversion
_arb_ = _conversion
_acb_ = _conversion
_integer_ = _conversion
_algebraic_ = _conversion
_number_field_ = _conversion

def __pow__(self, right, dummy):
r"""
Expand Down Expand Up @@ -871,16 +934,6 @@ cdef class FractionFieldElement(FieldElement):
return self.__class__(self._parent,
self.__denominator, self.__numerator, coerce=False, reduce=False)

def __float__(self):
"""
EXAMPLES::
sage: K.<x,y> = Frac(ZZ['x,y'])
sage: float(x/x + y/y)
2.0
"""
return float(self.__numerator) / float(self.__denominator)

cpdef _richcmp_(self, other, int op):
"""
EXAMPLES::
Expand Down
140 changes: 62 additions & 78 deletions src/sage/rings/polynomial/multi_polynomial.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -35,45 +35,8 @@ cdef class MPolynomial(CommutativeRingElement):
####################
# Some standard conversions
####################
def __int__(self):
"""
TESTS::
sage: type(RR['x,y'])
<class 'sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_domain_with_category'>
sage: type(RR['x, y'](0))
<class 'sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict'>
sage: int(RR['x,y'](0)) # indirect doctest
0
sage: int(RR['x,y'](10))
10
sage: int(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to an integer
"""
if self.degree() <= 0:
return int(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to an integer")

def __float__(self):
"""
TESTS::
sage: float(RR['x,y'](0)) # indirect doctest
0.0
sage: float(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a float
"""
if self.degree() <= 0:
return float(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to a float")

def _mpfr_(self, R):
"""
def _scalar_conversion(self, R):
r"""
TESTS::
sage: RR(RR['x,y'](0)) # indirect doctest
Expand All @@ -82,75 +45,66 @@ cdef class MPolynomial(CommutativeRingElement):
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a real number
"""
if self.degree() <= 0:
return R(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to a real number")

def _complex_mpfr_field_(self, R):
"""
TESTS::
sage: CC(RR['x,y'](0)) # indirect doctest
0.000000000000000
sage: CC(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a complex number
"""
if self.degree() <= 0:
return R(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to a complex number")

def _complex_double_(self, R):
"""
TESTS::
sage: CDF(RR['x,y'](0)) # indirect doctest
0.0
sage: CDF(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a complex number
"""
if self.degree() <= 0:
return R(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to a complex number")

def _real_double_(self, R):
"""
TESTS::
sage: RDF(RR['x,y'](0))
0.0
sage: RDF(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a real number
sage: x = polygen(QQ)
sage: A.<u> = NumberField(x^3 - 2)
sage: A(A['x,y'](u))
u
"""
if self.degree() <= 0:
return R(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to a real number")
raise TypeError(f"unable to convert non-constant polynomial {self} to {R}")

_real_double_ = _scalar_conversion
_complex_double_ = _scalar_conversion
_mpfr_ = _scalar_conversion
_complex_mpfr_ = _scalar_conversion
_real_mpfi_ = _scalar_conversion
_complex_mpfi_ = _scalar_conversion
_arb_ = _scalar_conversion
_acb_ = _scalar_conversion
_integer_ = _scalar_conversion
_algebraic_ = _scalar_conversion
_number_field_ = _scalar_conversion

def _rational_(self):
def __int__(self):
"""
TESTS::
sage: QQ(RR['x,y'](0.5)) # indirect doctest
1/2
sage: QQ(RR['x,y'].gen(0))
sage: type(RR['x,y'])
<class 'sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_domain_with_category'>
sage: type(RR['x, y'](0))
<class 'sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict'>
sage: int(RR['x,y'](0)) # indirect doctest
0
sage: int(RR['x,y'](10))
10
sage: int(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a rational
"""
if self.degree() <= 0:
from sage.rings.rational import Rational
return Rational(self.constant_coefficient())
raise TypeError(f"unable to convert non-constant polynomial {self} to a rational")

def _integer_(self, ZZ=None):
"""
TESTS::
TypeError: unable to convert non-constant polynomial x to an integer
sage: ZZ(RR['x,y'](0)) # indirect doctest
0
Expand All @@ -163,6 +117,36 @@ cdef class MPolynomial(CommutativeRingElement):
...
TypeError: unable to convert non-constant polynomial x to an integer
"""
return self._scalar_conversion(int)

def __float__(self):
"""
TESTS::
sage: float(RR['x,y'](0)) # indirect doctest
0.0
sage: float(ZZ['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a float
"""
return self._scalar_conversion(float)

def _rational_(self):
"""
TESTS::
sage: QQ(RR['x,y'](0.5)) # indirect doctest
1/2
sage: QQ(RR['x,y'].gen(0))
Traceback (most recent call last):
...
TypeError: unable to convert non-constant polynomial x to a rational
"""
from sage.rings.rational_field import QQ
return self._scalar_conversion(QQ)

def _integer_(self, ZZ=None):
if self.degree() <= 0:
from sage.rings.integer import Integer
return Integer(self.constant_coefficient())
Expand Down
5 changes: 5 additions & 0 deletions src/sage/rings/polynomial/polynomial_element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,11 @@ cdef class Polynomial(CommutativeAlgebraElement):
Traceback (most recent call last):
...
TypeError: cannot convert nonconstant polynomial
sage: x = polygen(QQ)
sage: A.<u> = NumberField(x^3 - 2)
sage: A(A['x'](u))
u
"""
if self.degree() > 0:
raise TypeError("cannot convert nonconstant polynomial")
Expand Down

0 comments on commit e2a22cb

Please sign in to comment.