ring.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. """Implementation of :class:`Ring` class. """
  2. from sympy.polys.domains.domain import Domain
  3. from sympy.polys.polyerrors import ExactQuotientFailed, NotInvertible, NotReversible
  4. from sympy.utilities import public
  5. @public
  6. class Ring(Domain):
  7. """Represents a ring domain. """
  8. is_Ring = True
  9. def get_ring(self):
  10. """Returns a ring associated with ``self``. """
  11. return self
  12. def exquo(self, a, b):
  13. """Exact quotient of ``a`` and ``b``, implies ``__floordiv__``. """
  14. if a % b:
  15. raise ExactQuotientFailed(a, b, self)
  16. else:
  17. return a // b
  18. def quo(self, a, b):
  19. """Quotient of ``a`` and ``b``, implies ``__floordiv__``. """
  20. return a // b
  21. def rem(self, a, b):
  22. """Remainder of ``a`` and ``b``, implies ``__mod__``. """
  23. return a % b
  24. def div(self, a, b):
  25. """Division of ``a`` and ``b``, implies ``__divmod__``. """
  26. return divmod(a, b)
  27. def invert(self, a, b):
  28. """Returns inversion of ``a mod b``. """
  29. s, t, h = self.gcdex(a, b)
  30. if self.is_one(h):
  31. return s % b
  32. else:
  33. raise NotInvertible("zero divisor")
  34. def revert(self, a):
  35. """Returns ``a**(-1)`` if possible. """
  36. if self.is_one(a) or self.is_one(-a):
  37. return a
  38. else:
  39. raise NotReversible('only units are reversible in a ring')
  40. def is_unit(self, a):
  41. try:
  42. self.revert(a)
  43. return True
  44. except NotReversible:
  45. return False
  46. def numer(self, a):
  47. """Returns numerator of ``a``. """
  48. return a
  49. def denom(self, a):
  50. """Returns denominator of `a`. """
  51. return self.one
  52. def free_module(self, rank):
  53. """
  54. Generate a free module of rank ``rank`` over self.
  55. >>> from sympy.abc import x
  56. >>> from sympy import QQ
  57. >>> QQ.old_poly_ring(x).free_module(2)
  58. QQ[x]**2
  59. """
  60. raise NotImplementedError
  61. def ideal(self, *gens):
  62. """
  63. Generate an ideal of ``self``.
  64. >>> from sympy.abc import x
  65. >>> from sympy import QQ
  66. >>> QQ.old_poly_ring(x).ideal(x**2)
  67. <x**2>
  68. """
  69. from sympy.polys.agca.ideals import ModuleImplementedIdeal
  70. return ModuleImplementedIdeal(self, self.free_module(1).submodule(
  71. *[[x] for x in gens]))
  72. def quotient_ring(self, e):
  73. """
  74. Form a quotient ring of ``self``.
  75. Here ``e`` can be an ideal or an iterable.
  76. >>> from sympy.abc import x
  77. >>> from sympy import QQ
  78. >>> QQ.old_poly_ring(x).quotient_ring(QQ.old_poly_ring(x).ideal(x**2))
  79. QQ[x]/<x**2>
  80. >>> QQ.old_poly_ring(x).quotient_ring([x**2])
  81. QQ[x]/<x**2>
  82. The division operator has been overloaded for this:
  83. >>> QQ.old_poly_ring(x)/[x**2]
  84. QQ[x]/<x**2>
  85. """
  86. from sympy.polys.agca.ideals import Ideal
  87. from sympy.polys.domains.quotientring import QuotientRing
  88. if not isinstance(e, Ideal):
  89. e = self.ideal(*e)
  90. return QuotientRing(self, e)
  91. def __truediv__(self, e):
  92. return self.quotient_ring(e)