Coverage for /usr/lib/python3/dist-packages/sympy/polys/domains/rationalfield.py: 59%

69 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1"""Implementation of :class:`RationalField` class. """ 

2 

3 

4from sympy.external.gmpy import MPQ 

5 

6from sympy.polys.domains.groundtypes import SymPyRational 

7 

8from sympy.polys.domains.characteristiczero import CharacteristicZero 

9from sympy.polys.domains.field import Field 

10from sympy.polys.domains.simpledomain import SimpleDomain 

11from sympy.polys.polyerrors import CoercionFailed 

12from sympy.utilities import public 

13 

14@public 

15class RationalField(Field, CharacteristicZero, SimpleDomain): 

16 r"""Abstract base class for the domain :ref:`QQ`. 

17 

18 The :py:class:`RationalField` class represents the field of rational 

19 numbers $\mathbb{Q}$ as a :py:class:`~.Domain` in the domain system. 

20 :py:class:`RationalField` is a superclass of 

21 :py:class:`PythonRationalField` and :py:class:`GMPYRationalField` one of 

22 which will be the implementation for :ref:`QQ` depending on whether either 

23 of ``gmpy`` or ``gmpy2`` is installed or not. 

24 

25 See also 

26 ======== 

27 

28 Domain 

29 """ 

30 

31 rep = 'QQ' 

32 alias = 'QQ' 

33 

34 is_RationalField = is_QQ = True 

35 is_Numerical = True 

36 

37 has_assoc_Ring = True 

38 has_assoc_Field = True 

39 

40 dtype = MPQ 

41 zero = dtype(0) 

42 one = dtype(1) 

43 tp = type(one) 

44 

45 def __init__(self): 

46 pass 

47 

48 def get_ring(self): 

49 """Returns ring associated with ``self``. """ 

50 from sympy.polys.domains import ZZ 

51 return ZZ 

52 

53 def to_sympy(self, a): 

54 """Convert ``a`` to a SymPy object. """ 

55 return SymPyRational(int(a.numerator), int(a.denominator)) 

56 

57 def from_sympy(self, a): 

58 """Convert SymPy's Integer to ``dtype``. """ 

59 if a.is_Rational: 

60 return MPQ(a.p, a.q) 

61 elif a.is_Float: 

62 from sympy.polys.domains import RR 

63 return MPQ(*map(int, RR.to_rational(a))) 

64 else: 

65 raise CoercionFailed("expected `Rational` object, got %s" % a) 

66 

67 def algebraic_field(self, *extension, alias=None): 

68 r"""Returns an algebraic field, i.e. `\mathbb{Q}(\alpha, \ldots)`. 

69 

70 Parameters 

71 ========== 

72 

73 *extension : One or more :py:class:`~.Expr` 

74 Generators of the extension. These should be expressions that are 

75 algebraic over `\mathbb{Q}`. 

76 

77 alias : str, :py:class:`~.Symbol`, None, optional (default=None) 

78 If provided, this will be used as the alias symbol for the 

79 primitive element of the returned :py:class:`~.AlgebraicField`. 

80 

81 Returns 

82 ======= 

83 

84 :py:class:`~.AlgebraicField` 

85 A :py:class:`~.Domain` representing the algebraic field extension. 

86 

87 Examples 

88 ======== 

89 

90 >>> from sympy import QQ, sqrt 

91 >>> QQ.algebraic_field(sqrt(2)) 

92 QQ<sqrt(2)> 

93 """ 

94 from sympy.polys.domains import AlgebraicField 

95 return AlgebraicField(self, *extension, alias=alias) 

96 

97 def from_AlgebraicField(K1, a, K0): 

98 """Convert a :py:class:`~.ANP` object to :ref:`QQ`. 

99 

100 See :py:meth:`~.Domain.convert` 

101 """ 

102 if a.is_ground: 

103 return K1.convert(a.LC(), K0.dom) 

104 

105 def from_ZZ(K1, a, K0): 

106 """Convert a Python ``int`` object to ``dtype``. """ 

107 return MPQ(a) 

108 

109 def from_ZZ_python(K1, a, K0): 

110 """Convert a Python ``int`` object to ``dtype``. """ 

111 return MPQ(a) 

112 

113 def from_QQ(K1, a, K0): 

114 """Convert a Python ``Fraction`` object to ``dtype``. """ 

115 return MPQ(a.numerator, a.denominator) 

116 

117 def from_QQ_python(K1, a, K0): 

118 """Convert a Python ``Fraction`` object to ``dtype``. """ 

119 return MPQ(a.numerator, a.denominator) 

120 

121 def from_ZZ_gmpy(K1, a, K0): 

122 """Convert a GMPY ``mpz`` object to ``dtype``. """ 

123 return MPQ(a) 

124 

125 def from_QQ_gmpy(K1, a, K0): 

126 """Convert a GMPY ``mpq`` object to ``dtype``. """ 

127 return a 

128 

129 def from_GaussianRationalField(K1, a, K0): 

130 """Convert a ``GaussianElement`` object to ``dtype``. """ 

131 if a.y == 0: 

132 return MPQ(a.x) 

133 

134 def from_RealField(K1, a, K0): 

135 """Convert a mpmath ``mpf`` object to ``dtype``. """ 

136 return MPQ(*map(int, K0.to_rational(a))) 

137 

138 def exquo(self, a, b): 

139 """Exact quotient of ``a`` and ``b``, implies ``__truediv__``. """ 

140 return MPQ(a) / MPQ(b) 

141 

142 def quo(self, a, b): 

143 """Quotient of ``a`` and ``b``, implies ``__truediv__``. """ 

144 return MPQ(a) / MPQ(b) 

145 

146 def rem(self, a, b): 

147 """Remainder of ``a`` and ``b``, implies nothing. """ 

148 return self.zero 

149 

150 def div(self, a, b): 

151 """Division of ``a`` and ``b``, implies ``__truediv__``. """ 

152 return MPQ(a) / MPQ(b), self.zero 

153 

154 def numer(self, a): 

155 """Returns numerator of ``a``. """ 

156 return a.numerator 

157 

158 def denom(self, a): 

159 """Returns denominator of ``a``. """ 

160 return a.denominator 

161 

162 

163QQ = RationalField()