def test_multiplication_neutral_element(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) assert a * Matrix(shape, 1) == a assert a * 1 == a assert a * 1.0 == a
def test_distributivity(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) b = Matrix(shape, range(1, length + 1)) c = Matrix(shape, range(2, length + 2)) assert a * (b + c) == a * b + a * c
def test_addition_inverse(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) b = Matrix(shape, range(1, length + 1)) assert -a == Matrix(a.shape, (-s for s in a)) assert a + -b == a - b assert a + +b == a + b
def test_all_close(self, shape): epsilon = 7 / 3 - 4 / 3 - 1 a = Matrix(shape, epsilon) b = Matrix(shape, 0) c = 0 d = 0.0 assert a.all_close(b) is True assert a.all_close(c) is True assert a.all_close(d) is True
def test_multiplication_commutativity(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(1, length + 1)) b = Matrix(shape, range(4, length + 4)) c = 5 d = 5.0 assert a * b == b * a assert a * c == c * a assert a * d == d * a
def test_addition_commutativity(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) b = Matrix(shape, range(1, length + 1)) c = 5 d = 5.0 assert a + b == b + a assert a + c == c + a assert a + d == d + a
def test_multiplication_associativity(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) b = Matrix(shape, range(1, length + 1)) c = Matrix(shape, range(2, length + 2)) d = 5 e = 6 f = 5.0 g = 6.0 assert b * (a * c) == (b * a) * c assert d * (a * e) == (d * a) * e assert f * (a * g) == (f * a) * g
def test_addition_associativity(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) b = Matrix(shape, range(1, length + 1)) c = Matrix(shape, range(2, length + 2)) d = 5 e = 6 f = 5.0 g = 6.0 assert b + (a + c) == (b + a) + c assert d + (a + e) == (d + a) + e assert f + (a + g) == (f + a) + g
def test_total_ordering(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, 0) b = Matrix(shape, -1) c = Matrix(shape, range(1, length + 1)) assert a == a assert a >= a assert a <= a assert a > b assert a >= b assert b < a assert b <= a assert a != b assert a != c
def test_transpose(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(length)) assert a == a.t.t assert a.shape == a.t.shape[::-1] for i, j in itertools.product(range(a.shape[0]), range(a.shape[1])): assert a[i, j] == a.t[j, i]
def test_is_close(self, shape): epsilon = 7 / 3 - 4 / 3 - 1 a = Matrix(shape, epsilon) b = Matrix(shape, 0) c = 0 d = 0.0 assert a.is_close(b) == Matrix(shape, 1, data_type="B") assert a.is_close(c) == Matrix(shape, 1, data_type="B") assert a.is_close(d) == Matrix(shape, 1, data_type="B")
def test_instantiation(self, shape): Matrix(shape) Matrix(shape, data_type="f", transposed=False) Matrix(shape, 2) Matrix(shape, range(shape[0] * shape[1])) Matrix(shape, list(range(shape[0] * shape[1]))) a = Matrix(shape) assert Matrix(shape, a._data)._data is a._data
def test_determinant(self, shape): a = Matrix(shape) if a.is_square and not a.is_scalar: if a.shape[0] <= 4: assert a.determinant() == 1 else: with pytest.raises(NotImplementedError): a.determinant() else: with pytest.raises(ValueError): a.determinant()
def test_multiplication_inverse(self, shape): length = functools.reduce(operator.mul, shape) a = Matrix(shape, range(1, length + 1)) b = Matrix(shape, range(4, length + 4)) assert all_close( Matrix(shape, 1) / a, Matrix(a.shape, (1 / s for s in a))) assert all_close(1 / a, Matrix(a.shape, (1 / s for s in a))) assert all_close(1.0 / a, Matrix(a.shape, (1 / s for s in a))) assert all_close(a * (Matrix(shape, 1) / b), a / b) assert all_close(a * (1 / b), a / b) assert all_close(a * (1.0 / b), a / b)
def test_setitem(self): m = Matrix((4, 4), range(16)) m[0, 1] = 100 assert m[0, 1] == 100 m = Matrix((4, 4), range(16)) m[1, :3] = Matrix((1, 3), 100) assert m[1, :3] == Matrix((1, 3), 100) m = Matrix((4, 4), range(16)) m[:2, :2] = (100, 100, 100, 100) assert m[:2, :2] == Matrix((2, 2), 100) m = Matrix((4, 4), range(16)) m[0, (0, 1, 3)] = 100 assert m[0, (0, 1, 3)] == Matrix((1, 3), 100)
def test_from_iterable(self): data = ((0, 1), (2, 3)) assert Matrix.from_iterable(data) == Matrix((2, 2), range(4)) data = (0, 1, 2, 3) assert Matrix.from_iterable(data) == Matrix((4, 1), range(4)) data = ((0, 1), (0, 1, 2)) with pytest.raises(ValueError): Matrix.from_iterable(data)
def test_dot_product_inverse(self): a = Matrix((2, 2), (4, 3, 2, 1)) b = Matrix((2, 2), (-0.5, 1.5, 1, -2)) assert a @ b == Matrix.identity(2) assert b @ a == Matrix.identity(2)
def test_is_scalar(self): assert Matrix((4, 4)).is_scalar is False assert Matrix((4, 1)).is_scalar is False assert Matrix((1, 4)).is_scalar is False assert Matrix((1, 1)).is_scalar is True
def test_multiplication_shapes(self): with pytest.raises(ValueError): Matrix((2, 2)) * Matrix((3, 3)) with pytest.raises(ValueError): Matrix((2, 2)) / Matrix((3, 3))
def test_quaternion_vectors(self): a = Quaternion(0, 0, 0, 1) b = Matrix((4, 1), (1, 2, 3, 4)) assert a @ b @ a.inverse() == Quaternion(1, 2, 3, 4)
def test_is_row_vector(self): assert Matrix((4, 4)).is_row_vector is False assert Matrix((4, 1)).is_row_vector is False assert Matrix((1, 4)).is_row_vector is True assert Matrix((1, 1)).is_row_vector is False
def test_matrix(self): assert Quaternion().matrix == Matrix.identity(4)
def test_transform(self): a = Quaternion(0, 0, 0, 1) b = Matrix((4, 1), (1, 2, 3, 4)) assert a.transform(b) == b
def test_dot_product_vectors(self): assert Matrix((1, 3), 1) @ Matrix((3, 1), 1) == 3
def test_is_square(self): assert Matrix((4, 4)).is_square is True assert Matrix((4, 1)).is_square is False assert Matrix((1, 4)).is_square is False assert Matrix((1, 1)).is_square is True
def test_dot_product_shapes(self): with pytest.raises(ValueError): Matrix((4, 3)) @ Matrix((2, 2))
def test_dot_distributivity(self): a = Matrix((2, 2), range(4)) b = Matrix((2, 2), range(1, 5)) c = Matrix((2, 2), range(2, 6)) assert a @ (b + c) == a @ b + a @ c
def test_length(self, shape): assert len(Matrix(shape)) == functools.reduce(operator.mul, shape)
def test_dot_product_associativity(self): a = Matrix((2, 2), range(4)) b = Matrix((2, 2), range(1, 5)) c = Matrix((2, 2), range(2, 6)) assert b @ (a @ c) == (b @ a) @ c
def test_dot_product_neutral_element(self): a = Matrix((2, 2), range(4)) b = Matrix.identity(2) assert a @ b == a assert a @ b == b @ a