def test_div_by_zero(): IntMod.modulus = 5 a = IntMod(4) b = IntMod(0) with pytest.raises(ZeroDivisionError): a // b # pylint: disable=pointless-statement
def test_create_with_coefs(): IntMod.modulus = 5 p = PolyMod([IntMod(2)]) assert p.coef_list == [IntMod(2)] assert p.degree == 0
def test_div_no_inverse(): IntMod.modulus = 8 a = IntMod(6) b = IntMod(4) with pytest.raises(ArithmeticError, match='No inverse for 6 with modulus 8'): a // b # pylint: disable=pointless-statement
def test_create_no_quotient(): IntMod.modulus = 0 rp = RemainderPoly(coef_list=[ IntMod(1), IntMod(4), IntMod(6), IntMod(4), IntMod(1) ]) x = str(rp) assert x == 'x^4 + 4x^3 + 6x^2 + 4x + 1'
def test_plus_no_quotient(): IntMod.modulus = 2 rp1 = RemainderPoly(coef_list=[IntMod(0), IntMod(1)]) rp2 = RemainderPoly(coef_list=[IntMod(1), IntMod(1)]) rp = rp1 + rp2 rp_expected = RemainderPoly(coef_list=[IntMod(1)]) assert rp == rp_expected
def __call__(self, const_term: Union[IntMod, int]) -> IntMod: value = const_term if isinstance(const_term, IntMod) else IntMod(const_term) result = IntMod(0) term = IntMod(1) for coef in self: result = result + coef * term term = term * value return result
def test_create_with_quotient(): IntMod.modulus = 7 qp = PolyMod([IntMod(1), IntMod(2), IntMod(1)]) RemainderPoly.quotient = qp rp = RemainderPoly([IntMod(1), IntMod(4), IntMod(6), IntMod(4), IntMod(1)]) rp._residue() # pylint: disable=protected-access x = str(rp) assert x == '0'
def __str__(self) -> str: if self.degree == 0 or all(c.value == 0 for c in self): return str(self.coef_list[0]) zero = IntMod(0) one = IntMod(1) content = [] for index, coef in reversed(list(enumerate(self))): if coef != zero: content.append("{}{}{}".format( str(coef) if coef != one or index == 0 else '', 'x' if index >= 1 else '', f'^{index}' if index >= 2 else '')) return ' + '.join(content)
def test_times(): IntMod.modulus = 3 qp = PolyMod([IntMod(1), IntMod(1), IntMod(1)]) RemainderPoly.quotient = qp rp1 = RemainderPoly(coef_list=[IntMod(1), IntMod(1)]) rp2 = RemainderPoly(coef_list=[IntMod(1), IntMod(1)]) rp = rp1 * rp2 rp_expected = RemainderPoly(coef_list=[IntMod(0), IntMod(1)]) assert rp == rp_expected
def is_reducible(self) -> bool: zero = IntMod(0) value = IntMod(0) if self(value) == zero: return True value += 1 while value != zero: # Check if p(value) = 0. if self(value) == zero: # If p( value )=0, then ( x - value ) factors p return True value += 1 return False
def test_plus_different_degrees(): IntMod.modulus = 2 rp1 = RemainderPoly(coef_list=[IntMod(0), IntMod(1)]) rp2 = RemainderPoly(coef_list=[IntMod(1), IntMod(1), IntMod(1)]) rp = rp1 + rp2 rp_expected = RemainderPoly(coef_list=[IntMod(1), IntMod(0), IntMod(1)]) assert rp == rp_expected
def __mul__(self, operand: 'RemainderPoly') -> 'RemainderPoly': result_degree = self.degree + operand.degree result = RemainderPoly(coef_list=[IntMod(0)] * (result_degree + 1)) for k in range(result_degree + 1): min_index = k - operand.degree if k - operand.degree > 0 else 0 max_index = k if k < self.degree else self.degree for m in range(min_index, max_index + 1): # pylint: disable=invalid-name result[k] = result[k] + self[m] * operand[k - m] result._residue() return result
def test_collapse_to_one_poly(): IntMod.modulus = 5 p = PolyMod([ IntMod(1), IntMod(0), IntMod(0), IntMod(0), IntMod(0), IntMod(0), IntMod(0) ]) p.collapse_degree() expected_p = PolyMod([IntMod(1)]) assert p == expected_p
def test_collapse_degree_all_zeros(): IntMod.modulus = 5 p = PolyMod([ IntMod(0), IntMod(0), IntMod(0), IntMod(0), IntMod(0), IntMod(0), IntMod(0) ]) p.collapse_degree() expected_p = PolyMod([IntMod(0)]) assert p == expected_p
def test_field_4(): f = Field(4) assert [str(e) for e in f.elements] == ['0', '1', 'x', 'x + 1'] assert f.elements == [ RemainderPoly(coef_list=[IntMod(0)]), RemainderPoly(coef_list=[IntMod(1)]), RemainderPoly(coef_list=[IntMod(0), IntMod(1)]), RemainderPoly(coef_list=[IntMod(1), IntMod(1)]) ]
def test_times(): IntMod.modulus = 5 a = IntMod(3) b = IntMod(3) assert a * b == IntMod(4)
def test_div_no_modulus(): IntMod.modulus = 0 a = IntMod(8) b = IntMod(4) assert a // b == IntMod(2)
def test_increment(): IntMod.modulus = 5 a = IntMod(4) a += 1 assert a == IntMod(0)
def test_create_default(): IntMod.modulus = 0 a = IntMod() assert a.value == 0
def test_str(): IntMod.modulus = 5 a = IntMod(4) assert str(a) == "4"
def test_increment_no_modulus(): IntMod.modulus = 0 a = IntMod(4) a += 1 assert a == IntMod(5)
def test_mod_create_with_value(): IntMod.modulus = 5 a = IntMod(7) assert a.value == 2
def constant(cls, value: int) -> 'RemainderPoly': return cls([IntMod(value)])
def test_not_equal_true(): IntMod.modulus = 5 a = IntMod(9) b = IntMod(3) assert a != b
def __add__(self, operand: 'RemainderPoly') -> 'RemainderPoly': coef_tuples = itertools.zip_longest(self, operand, fillvalue=IntMod(0)) result_coefs = [a + b for a, b in coef_tuples] result = RemainderPoly(result_coefs) result.collapse_degree() return result
def test_equal_false(): IntMod.modulus = 5 a = IntMod(9) b = IntMod(3) assert not a == b # pylint: disable=unneeded-not
def test_equal_true(): IntMod.modulus = 5 a = IntMod(8) b = IntMod(3) assert a == b
def test_mod_create_with_value_becomes_zero(): IntMod.modulus = 5 a = IntMod(10) assert a.value == 0
def test_mod_create_with_negative_value(): IntMod.modulus = 5 a = IntMod(-2) assert a.value == 3
def test_div(): IntMod.modulus = 5 a = IntMod(4) b = IntMod(3) assert a // b == IntMod(3)