def test_setitem_column_as_int(self): all_matrices = copy.deepcopy(utils.ALL_MATRICES) for mat, k in itertools.product(all_matrices, utils.ALL_SCALARS): vec = Vector([k] * mat.num_rows) for start in range(0, mat.num_columns): mat[:, start] = k utils.assert_vectors_almost_equal(mat[:, start], vec)
def test_make_unitary(self): for vec in utils.ALL_VECTORS: if vec.norm > 0: v = Vector.make_unitary(vec) self.assertAlmostEqual(v.norm, 1, PRECISION) self.assertEqual(v.dim, vec.dim) utils.assert_vectors_almost_equal(vec.norm * v, vec)
def _make_identity_rowvectors(num_rows, num_columns): rowvectors = [] for i in range(num_rows): components = [0] * num_columns if i < num_columns: components[i] = 1 rowvectors.append(Vector(components)) return rowvectors
def make_row_addition( cls, num_rows: int, num_columns: int, i: int, j: int, m: t.Union[int, float] ): rowvectors = _make_identity_rowvectors(num_rows, num_columns) rowvectors[j] = rowvectors[j] + Vector( m if j_ == i else 0 for j_ in range(num_columns) ) return cls(rowvectors)
def test_cross_jacobi_identity(self): for v1, v2 in itertools.product(utils.ALL_VECTORS, utils.ALL_VECTORS): for v3 in utils.ALL_VECTORS: vec1 = vector_ops.cross(v1, vector_ops.cross(v2, v3)) vec2 = vector_ops.cross(v2, vector_ops.cross(v3, v1)) vec3 = vector_ops.cross(v3, vector_ops.cross(v1, v2)) utils.assert_vectors_almost_equal(vec1 + vec2 + vec3, Vector.make_zero(3))
def test_setitem_column_as_sequence(self): factories = [lambda x: x, lambda x: x.components, list, tuple] all_matrices = copy.deepcopy(utils.ALL_MATRICES) for mat, k in itertools.product(all_matrices, utils.ALL_SCALARS): vec = Vector([k] * mat.num_rows) for start in range(0, mat.num_columns): for fac in factories: mat[:, start] = fac(vec) utils.assert_vectors_almost_equal(mat[:, start], vec)
def test_setitem_column_slice_as_int(self): all_matrices = copy.deepcopy(utils.ALL_MATRICES) for mat, k in itertools.product(all_matrices, utils.ALL_SCALARS): vec = Vector([k] * mat.num_rows) for start in range(0, mat.num_columns): for stop in range(start + 1, mat.num_columns + 1): for step in range(1, stop): mat[:, start:stop:step] = k for i in range(start, stop, step): utils.assert_vectors_almost_equal(mat[:, i], vec)
def test_setitem_slice_to_sequence(self): all_vecs = copy.deepcopy(utils.ALL_VECTORS) for vec, k in itertools.product(all_vecs, utils.ALL_SCALARS): for start in range(0, vec.dim + 1): for stop in range(start + 1, vec.dim + 2): for step in range(1, stop): length = math.ceil((stop - start) / step) expected = Vector([k] * length) vec[start:stop:step] = expected real = vec[start:stop:step] self.assertIsInstance(real, Vector) self.assertEqual(real, expected)
def __getitem__(self, slice_): if isinstance(slice_, int): return self._rowvectors[slice_] elif isinstance(slice_, slice): rowvectors = self._rowvectors[slice_] return type(self)(rowvectors) elif isinstance(slice_, tuple): row, col = slice_ if isinstance(row, int) and isinstance(col, int): return self._rowvectors[row][col] elif isinstance(row, slice) and isinstance(col, int): return Vector(v[col] for v in self.iterrows()) elif isinstance(row, int) and isinstance(col, slice): return Vector(self._rowvectors[row][col]) else: start, stop, step = self._read_slice(row, self.num_rows) rowvectors = ( self._rowvectors[i][col] for i in range(start, stop, step) ) return type(self)(rowvectors) else: raise RuntimeError(f"unsupported slice type {slice_}")
def from_columnvectors(cls, vectors: t.Iterable[Vector]): vectors = list(vectors) _validate_vector_dimensions(vectors) rowvectors = [Vector(v[i] for v in vectors) for i in range(vectors[0].dim)] return cls(rowvectors)
def itercolumns(self) -> t.Generator[Vector, None, None]: for j in range(self.num_columns): yield Vector(self._rowvectors[i][j] for i in range(self.num_rows))
import math import lac.vector as vector_ops import lac.matrix as matrix_ops from lac import Matrix, Vector VEC1 = Vector([1, 2, -3]) VEC2 = Vector([0, 0, 0]) VEC3 = Vector([math.pi, 1 / math.pi, math.e]) ALL_VECTORS = [VEC1, VEC2, VEC3] ALL_SCALARS = [0, 1, -1, -math.pi, 0.5] MAT1 = Matrix([Vector([1, 0, 0]), Vector([0, 1, 0]), Vector([0, 0, 1])]) REDUCED_MATRICES = [ ( Matrix([ Vector([2, 5, 8, 7]), Vector([5, 2, 2, 8]), Vector([7, 5, 6, 6]), Vector([5, 4, 4, 8]), ]), Matrix([ Vector([7, 5, 6, 6]), Vector( [0, 3.5714285714285716, 6.285714285714286, 5.285714285714286]), Vector([0, 0, -1.04, 3.08]), Vector([0, 0, 0, 7.46153846153846]), ]),
def test_make_zero(self): dim = 3 vec = Vector.make_zero(dim) self.assertEqual(vec.norm, 0, PRECISION) self.assertEqual(vec.dim, dim)
def test_angle_between_antiparallel(self): v1 = Vector([-1, 0, 0]) v2 = Vector([2, 0, 0]) self.assertAlmostEqual(vector_ops.angle_between(v1, v2), math.pi, PRECISION)
def test_angle_between_orthogonal(self): v1 = Vector([0, 1, 0]) v2 = Vector([1, 0, 0]) self.assertAlmostEqual(vector_ops.angle_between(v1, v2), math.pi / 2, PRECISION)
def test_dot_orthogonal(self): v1 = Vector([0, 1, 0]) v2 = Vector([1, 0, 0]) self.assertAlmostEqual(vector_ops.dot(v1, v2), 0, PRECISION)
def test_cross_parallel(self): v1 = Vector([1, 0, 0]) v2 = Vector([2, 0, 0]) utils.assert_vectors_almost_equal(vector_ops.cross(v1, v2), Vector.make_zero(3))
def test_cross_orthogonal(self): v1 = Vector([0, 1, 0]) v2 = Vector([1, 0, 0]) utils.assert_vectors_almost_equal(vector_ops.cross(v1, v2), Vector([0, 0, -1]))
def test_cross_self(self): for v1, v2 in itertools.product(utils.ALL_VECTORS, utils.ALL_VECTORS): if v1 == v2: vec = vector_ops.cross(v1, v2) utils.assert_vectors_almost_equal(vec, Vector.make_zero(3))
def make_random(cls, num_rows: int, num_columns: int): """A Matrix built out of random unit row vectors. """ return cls(Vector.make_random(num_columns) for _ in range(num_rows))
def test_dim(self): components = [3, 2, 1] vec = Vector(components) self.assertEqual(len(components), vec.dim)
def make_zero(cls, num_rows: int, num_columns: int): return cls(Vector.make_zero(num_columns) for _ in range(num_rows))
def test_from_columnvectors(self): mat = Matrix.from_columnvectors( [Vector([1, 0]), Vector([0, 1]), Vector([0, 0])]) self.assertTupleEqual(mat.shape, (2, 3))
def __init__(self, rowvectors: t.Iterable[t.Union[Vector, t.Iterable[t.Union[int, float]]]]): self._rowvectors = [ Vector(row) if not isinstance(row, Vector) else row for row in rowvectors ] _validate_vector_dimensions(self._rowvectors)
def make_random(self): dim = 3 vec = Vector.make_random(dim) self.assertEqual(vec.norm, 1, PRECISION)