Source code for polynomials_on_simplices.algebra.modular_arithmetic

"""Functionality for modular arithmetic."""


[docs]class IntegerModuloN: r""" Integer modulo n (element of :math:`\mathbb{Z}/n\mathbb{Z})`. We have .. math:: \mathbb{Z}/n\mathbb{Z} = \mathbb{Z}/\sim, where .. math:: a \sim b \text{ if } a \bmod n = b \bmod n \iff \exists c \in n\mathbb{Z} \text{ such that } a + c = b. This class defines the ring structure of integers modulo n. **Addition:** .. math:: + : \mathbb{Z}/n\mathbb{Z} \times \mathbb{Z}/n\mathbb{Z} \to \mathbb{Z}/n\mathbb{Z}, .. math:: [a] + [b] = [a + b]. **Multiplication:** .. math:: \cdot : \mathbb{Z}/n\mathbb{Z} \times \mathbb{Z}/n\mathbb{Z} \to \mathbb{Z}/n\mathbb{Z}, .. math:: [a] \cdot [b] = [a \cdot b]. """ def __init__(self, value, n): """ :param value: Value of the integer. :param n: Modulus of the integer. """ self.i = value % n self.n = n def __repr__(self): return "polynomials_on_simplices.algebra.modular_arithmetic.IntegerModuloN(" + str(self.i) + ", " + str(self.n) + ")" def __str__(self): return str(self.i) + "_" + str(self.n) def __hash__(self): return self.i def __eq__(self, other): if isinstance(other, IntegerModuloN): if self.n != other.n: raise ValueError("Can not compare integer modulo " + str(self.n) + "with integer modulo " + str(other.n) + ".") return self.i == other.i return self.i == other def __ne__(self, other): return not (self == other) def __lt__(self, other): if isinstance(other, IntegerModuloN): if self.n != other.n: raise ValueError("Can not compare integer modulo " + str(self.n) + "with integer modulo " + str(other.n) + ".") return self.i < other.i return self.i < other def __gt__(self, other): if isinstance(other, IntegerModuloN): if self.n != other.n: raise ValueError("Can not compare integer modulo " + str(self.n) + "with integer modulo " + str(other.n) + ".") return self.i > other.i return self.i > other.i def __le__(self, other): return not (self > other) def __ge__(self, other): return not (self < other) def __neg__(self): return IntegerModuloN(-self.i, self.n) def __add__(self, other): if isinstance(other, IntegerModuloN): if self.n != other.n: raise ValueError("Can not add integer modulo " + str(self.n) + "with integer modulo " + str(other.n) + ".") return IntegerModuloN(self.i + other.i, self.n) return IntegerModuloN(self.i + other, self.n) def __sub__(self, other): if isinstance(other, IntegerModuloN): if self.n != other.n: raise ValueError("Can not subtract integer modulo " + str(other.n) + "from integer modulo " + str(self.n) + ".") return IntegerModuloN(self.i - other.i, self.n) return IntegerModuloN(self.i - other, self.n) def __mul__(self, other): if isinstance(other, IntegerModuloN): if self.n != other.n: raise ValueError("Can not multiply integer modulo " + str(self.n) + "with integer modulo " + str(other.n) + ".") return IntegerModuloN(self.i * other.i, self.n) return IntegerModuloN(self.i * other, self.n) def __radd__(self, other): return self + other def __rsub__(self, other): return -(self - other) def __rmul__(self, other): return self * other def __int__(self): return int(self.i)