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

50 statements  

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

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

2 

3 

4from sympy.polys.domains.domain import Domain 

5from sympy.polys.polyerrors import ExactQuotientFailed, NotInvertible, NotReversible 

6 

7from sympy.utilities import public 

8 

9@public 

10class Ring(Domain): 

11 """Represents a ring domain. """ 

12 

13 is_Ring = True 

14 

15 def get_ring(self): 

16 """Returns a ring associated with ``self``. """ 

17 return self 

18 

19 def exquo(self, a, b): 

20 """Exact quotient of ``a`` and ``b``, implies ``__floordiv__``. """ 

21 if a % b: 

22 raise ExactQuotientFailed(a, b, self) 

23 else: 

24 return a // b 

25 

26 def quo(self, a, b): 

27 """Quotient of ``a`` and ``b``, implies ``__floordiv__``. """ 

28 return a // b 

29 

30 def rem(self, a, b): 

31 """Remainder of ``a`` and ``b``, implies ``__mod__``. """ 

32 return a % b 

33 

34 def div(self, a, b): 

35 """Division of ``a`` and ``b``, implies ``__divmod__``. """ 

36 return divmod(a, b) 

37 

38 def invert(self, a, b): 

39 """Returns inversion of ``a mod b``. """ 

40 s, t, h = self.gcdex(a, b) 

41 

42 if self.is_one(h): 

43 return s % b 

44 else: 

45 raise NotInvertible("zero divisor") 

46 

47 def revert(self, a): 

48 """Returns ``a**(-1)`` if possible. """ 

49 if self.is_one(a) or self.is_one(-a): 

50 return a 

51 else: 

52 raise NotReversible('only units are reversible in a ring') 

53 

54 def is_unit(self, a): 

55 try: 

56 self.revert(a) 

57 return True 

58 except NotReversible: 

59 return False 

60 

61 def numer(self, a): 

62 """Returns numerator of ``a``. """ 

63 return a 

64 

65 def denom(self, a): 

66 """Returns denominator of `a`. """ 

67 return self.one 

68 

69 def free_module(self, rank): 

70 """ 

71 Generate a free module of rank ``rank`` over self. 

72 

73 >>> from sympy.abc import x 

74 >>> from sympy import QQ 

75 >>> QQ.old_poly_ring(x).free_module(2) 

76 QQ[x]**2 

77 """ 

78 raise NotImplementedError 

79 

80 def ideal(self, *gens): 

81 """ 

82 Generate an ideal of ``self``. 

83 

84 >>> from sympy.abc import x 

85 >>> from sympy import QQ 

86 >>> QQ.old_poly_ring(x).ideal(x**2) 

87 <x**2> 

88 """ 

89 from sympy.polys.agca.ideals import ModuleImplementedIdeal 

90 return ModuleImplementedIdeal(self, self.free_module(1).submodule( 

91 *[[x] for x in gens])) 

92 

93 def quotient_ring(self, e): 

94 """ 

95 Form a quotient ring of ``self``. 

96 

97 Here ``e`` can be an ideal or an iterable. 

98 

99 >>> from sympy.abc import x 

100 >>> from sympy import QQ 

101 >>> QQ.old_poly_ring(x).quotient_ring(QQ.old_poly_ring(x).ideal(x**2)) 

102 QQ[x]/<x**2> 

103 >>> QQ.old_poly_ring(x).quotient_ring([x**2]) 

104 QQ[x]/<x**2> 

105 

106 The division operator has been overloaded for this: 

107 

108 >>> QQ.old_poly_ring(x)/[x**2] 

109 QQ[x]/<x**2> 

110 """ 

111 from sympy.polys.agca.ideals import Ideal 

112 from sympy.polys.domains.quotientring import QuotientRing 

113 if not isinstance(e, Ideal): 

114 e = self.ideal(*e) 

115 return QuotientRing(self, e) 

116 

117 def __truediv__(self, e): 

118 return self.quotient_ring(e)