rationalfield.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. """Implementation of :class:`RationalField` class. """
  2. from sympy.external.gmpy import MPQ
  3. from sympy.polys.domains.groundtypes import SymPyRational
  4. from sympy.polys.domains.characteristiczero import CharacteristicZero
  5. from sympy.polys.domains.field import Field
  6. from sympy.polys.domains.simpledomain import SimpleDomain
  7. from sympy.polys.polyerrors import CoercionFailed
  8. from sympy.utilities import public
  9. @public
  10. class RationalField(Field, CharacteristicZero, SimpleDomain):
  11. r"""Abstract base class for the domain :ref:`QQ`.
  12. The :py:class:`RationalField` class represents the field of rational
  13. numbers $\mathbb{Q}$ as a :py:class:`~.Domain` in the domain system.
  14. :py:class:`RationalField` is a superclass of
  15. :py:class:`PythonRationalField` and :py:class:`GMPYRationalField` one of
  16. which will be the implementation for :ref:`QQ` depending on whether either
  17. of ``gmpy`` or ``gmpy2`` is installed or not.
  18. See also
  19. ========
  20. Domain
  21. """
  22. rep = 'QQ'
  23. alias = 'QQ'
  24. is_RationalField = is_QQ = True
  25. is_Numerical = True
  26. has_assoc_Ring = True
  27. has_assoc_Field = True
  28. dtype = MPQ
  29. zero = dtype(0)
  30. one = dtype(1)
  31. tp = type(one)
  32. def __init__(self):
  33. pass
  34. def get_ring(self):
  35. """Returns ring associated with ``self``. """
  36. from sympy.polys.domains import ZZ
  37. return ZZ
  38. def to_sympy(self, a):
  39. """Convert ``a`` to a SymPy object. """
  40. return SymPyRational(int(a.numerator), int(a.denominator))
  41. def from_sympy(self, a):
  42. """Convert SymPy's Integer to ``dtype``. """
  43. if a.is_Rational:
  44. return MPQ(a.p, a.q)
  45. elif a.is_Float:
  46. from sympy.polys.domains import RR
  47. return MPQ(*map(int, RR.to_rational(a)))
  48. else:
  49. raise CoercionFailed("expected `Rational` object, got %s" % a)
  50. def algebraic_field(self, *extension):
  51. r"""Returns an algebraic field, i.e. `\mathbb{Q}(\alpha, \ldots)`.
  52. Parameters
  53. ==========
  54. *extension: One or more Expr
  55. Generators of the extension. These should be expressions that are
  56. algebraic over `\mathbb{Q}`.
  57. Returns
  58. =======
  59. :py:class:`~.AlgebraicField`
  60. A :py:class:`~.Domain` representing the algebraic field extension.
  61. Examples
  62. ========
  63. >>> from sympy import QQ, sqrt
  64. >>> QQ.algebraic_field(sqrt(2))
  65. QQ<sqrt(2)>
  66. """
  67. from sympy.polys.domains import AlgebraicField
  68. return AlgebraicField(self, *extension)
  69. def from_AlgebraicField(K1, a, K0):
  70. """Convert a :py:class:`~.ANP` object to :ref:`QQ`.
  71. See :py:meth:`~.Domain.convert`
  72. """
  73. if a.is_ground:
  74. return K1.convert(a.LC(), K0.dom)
  75. def from_ZZ(K1, a, K0):
  76. """Convert a Python ``int`` object to ``dtype``. """
  77. return MPQ(a)
  78. def from_ZZ_python(K1, a, K0):
  79. """Convert a Python ``int`` object to ``dtype``. """
  80. return MPQ(a)
  81. def from_QQ(K1, a, K0):
  82. """Convert a Python ``Fraction`` object to ``dtype``. """
  83. return MPQ(a.numerator, a.denominator)
  84. def from_QQ_python(K1, a, K0):
  85. """Convert a Python ``Fraction`` object to ``dtype``. """
  86. return MPQ(a.numerator, a.denominator)
  87. def from_ZZ_gmpy(K1, a, K0):
  88. """Convert a GMPY ``mpz`` object to ``dtype``. """
  89. return MPQ(a)
  90. def from_QQ_gmpy(K1, a, K0):
  91. """Convert a GMPY ``mpq`` object to ``dtype``. """
  92. return a
  93. def from_GaussianRationalField(K1, a, K0):
  94. """Convert a ``GaussianElement`` object to ``dtype``. """
  95. if a.y == 0:
  96. return MPQ(a.x)
  97. def from_RealField(K1, a, K0):
  98. """Convert a mpmath ``mpf`` object to ``dtype``. """
  99. return MPQ(*map(int, K0.to_rational(a)))
  100. def exquo(self, a, b):
  101. """Exact quotient of ``a`` and ``b``, implies ``__truediv__``. """
  102. return MPQ(a) / MPQ(b)
  103. def quo(self, a, b):
  104. """Quotient of ``a`` and ``b``, implies ``__truediv__``. """
  105. return MPQ(a) / MPQ(b)
  106. def rem(self, a, b):
  107. """Remainder of ``a`` and ``b``, implies nothing. """
  108. return self.zero
  109. def div(self, a, b):
  110. """Division of ``a`` and ``b``, implies ``__truediv__``. """
  111. return MPQ(a) / MPQ(b), self.zero
  112. def numer(self, a):
  113. """Returns numerator of ``a``. """
  114. return a.numerator
  115. def denom(self, a):
  116. """Returns denominator of ``a``. """
  117. return a.denominator
  118. QQ = RationalField()