def test_sparse_multiply(self): algebras = [Cl(i) for i in [4]] + [conformalize(Cl(3)[0])] # For all the algebras we are interested in for alg in algebras: layout = alg[0] # Make two random multivectors a = layout.randomMV() b = layout.randomMV() # Project the multivectors to the grades required grades_possibilities = [] for r in range(1, len(layout.sig)): possible_grades = [ list(m) for m in list( itertools.combinations(range(len(layout.sig)), r)) ] grades_possibilities += possible_grades for i, grades_a in enumerate(grades_possibilities): sparse_mv_a = sum([a(k) for k in grades_a]) for j, grades_b in enumerate(grades_possibilities): sparse_mv_b = sum([b(k) for k in grades_b]) # Compute results gp = layout.gmt_func_generator(grades_a=grades_a, grades_b=grades_b) result_sparse = gp(sparse_mv_a.value, sparse_mv_b.value) result_dense = (sparse_mv_a * sparse_mv_b).value # Check they are the same testing.assert_almost_equal(result_sparse, result_dense) print(j + i * len(grades_possibilities), len(grades_possibilities)**2)
class TestBasicAlgebra: def test_gp_op_ip(self): layout = Cl(3)[0] e1 = layout.blades['e1'] e2 = layout.blades['e2'] e3 = layout.blades['e3'] print('outer product') e123 = layout.blades['e123'] np.testing.assert_almost_equal(e123.value, (e1 ^ e2 ^ e3).value) np.testing.assert_almost_equal(e123.value, (e1 * e2 * e3).value) print('outer product ordering') e12 = layout.blades['e12'] np.testing.assert_almost_equal(-e12.value, (e2 ^ e1).value) print('outer product zeros') np.testing.assert_almost_equal(0, (e1 ^ e1).value) np.testing.assert_almost_equal(0, (e2 ^ e2).value) np.testing.assert_almost_equal(0, (e3 ^ e3).value) print('scalar outer product') np.testing.assert_almost_equal(((1 + 0 * e1) ^ (1 + 0 * e1)).value, (1 + 0 * e1).value) print('scalar inner product') np.testing.assert_almost_equal(((1 + 0 * e1) | (1 + 0 * e1)).value, 0) @pytest.fixture(params=[Cl(i) for i in [3, 4]] + [conformalize(Cl(3)[0])], ids=['Cl(3)', 'Cl(4)', 'conformal Cl(3)']) def algebra(self, request): return request.param def test_grade_obj(self, algebra): layout = algebra[0] for i in range(len(layout.sig) + 1): mv = layout.randomMV()(i) assert i == grade_obj(mv) def test_left_multiplication_matrix(self, algebra): layout = algebra[0] for i in range(1000): mv = layout.randomMV() mv2 = layout.randomMV() np.testing.assert_almost_equal( np.matmul(layout.get_left_gmt_matrix(mv), mv2.value), (mv * mv2).value) def test_right_multiplication_matrix(self, algebra): layout = algebra[0] for i in range(1000): a = layout.randomMV() b = layout.randomMV() b_right = val_get_right_gmt_matrix(b.value, layout.k_list, layout.l_list, layout.m_list, layout.mult_table_vals, layout.gaDims) res = a * b res2 = layout.MultiVector(value=b_right @ a.value) np.testing.assert_almost_equal(res.value, res2.value)
def test_grade_obj(self): algebras = [Cl(i) for i in [3, 4]] + [conformalize(Cl(3)[0])] for alg in algebras: layout = alg[0] for i in range(len(layout.sig)+1): mv = layout.randomMV()(i) assert i == grade_obj(mv)
class TestCGA3D(_TestBase): layout, blades, stuff = clifford.conformalize(clifford.Cl(3)[0]) e1 = blades['e1'] e2 = blades['e2'] e3 = blades['e3'] @pytest.fixture(params=[ layout.scalar, e1, e1^e2, e1^e2^e3, ]) def direction(self, request): return request.param @pytest.fixture(params=[ layout.scalar * 0, 3*e1, ]) def location(self, request): return request.param def test_inferred_dims(self): """ Test that the appropriate subclass is inferred from arguments """ e1, e2, e3 = self.e1, self.e2, self.e3 C = Round(location=e1, direction=e2^e3, radius=1) assert isinstance(C, Circle) S = Round(location=e1, direction=e1^e2^e3, radius=1) assert isinstance(S, Sphere) # wrong grade with pytest.raises(ValueError): Sphere(location=e1, direction=e1^e2, radius=1) with pytest.raises(ValueError): Circle(location=e1, direction=e1^e2^e3, radius=1)
def test_left_multiplication_matrix(self): algebras = [Cl(i) for i in [3, 4]] + [conformalize(Cl(3)[0])] for alg in algebras: layout = alg[0] for i in range(1000): mv = layout.randomMV() mv2 = layout.randomMV() np.testing.assert_almost_equal(np.matmul(layout.get_left_gmt_matrix(mv),mv2.value), (mv*mv2).value)
def test_right_multiplication_matrix(self): algebras = [Cl(i) for i in [3, 4]] + [conformalize(Cl(3)[0])] for alg in algebras: layout = alg[0] for i in range(1000): a = layout.randomMV() b = layout.randomMV() b_right = val_get_right_gmt_matrix(b.value, layout.k_list, layout.l_list, layout.m_list, layout.mult_table_vals, layout.gaDims) res = a*b res2 = layout.MultiVector([email protected]) testing.assert_almost_equal(res.value, res2.value)
class TestInitialisation: @pytest.mark.parametrize( "n", [x for x in range(2, 7)] + [pytest.param(x, marks=too_slow_without_jit) for x in range(7, 9)]) def test_speed(self, n, benchmark): def generate_algebra(): layout = Cl(n)[0] layout.gmt_func layout.imt_func layout.omt_func layout.lcmt_func layout.adjoint_func layout.left_complement_func layout.right_complement_func layout.dual_func layout.vee_func layout.inv_func benchmark(generate_algebra) @too_slow_without_jit @pytest.mark.veryslow @pytest.mark.parametrize('algebra', [Cl(i) for i in [4]] + [conformalize(Cl(3)[0])], ids=['Cl(4)', 'conformalize(Cl(3))']) def test_sparse_multiply(self, algebra, rng): # noqa: F811 layout = algebra[0] # Make two random multivectors a = layout.randomMV(rng=rng) b = layout.randomMV(rng=rng) # Choose the grades we care about. # We skip the cases of: # - all grades # - no grades # - any multiplications including the pseudoscalar grades_possibilities = list(_powerset(range(layout.dims)))[1:-1] for i, grades_a in enumerate(grades_possibilities): sparse_mv_a = sum([a(k) for k in grades_a], layout.MultiVector()) for j, grades_b in enumerate(grades_possibilities): sparse_mv_b = sum([b(k) for k in grades_b], layout.MultiVector()) # Compute results gp = layout.gmt_func_generator(grades_a=grades_a, grades_b=grades_b) result_sparse = gp(sparse_mv_a.value, sparse_mv_b.value) result_dense = (sparse_mv_a * sparse_mv_b).value # Check they are the same np.testing.assert_almost_equal(result_sparse, result_dense) print(j + i * len(grades_possibilities), len(grades_possibilities)**2)
def test_factorise(self): layout_a = Cl(3)[0] layout,blades,stuff = conformalize(layout_a) e1 = layout.blades['e1'] e2 = layout.blades['e2'] e3 = layout.blades['e3'] e4 = layout.blades['e4'] e5 = layout.blades['e5'] up = stuff['up'] blade = up(e1 + 3*e2 + 4*e3)^up(5*e1 + 3.3*e2 + 10*e3)^up(-13.1*e1) basis, scale = blade.factorise() new_blade = (reduce(lambda a, b: a^b, basis)*scale) print(new_blade) print(blade) np.testing.assert_almost_equal(new_blade.value, blade.value, 5)
def test_vee(self): layout_a = Cl(3)[0] layout, blades, stuff = conformalize(layout_a) e1 = layout.blades['e1'] e2 = layout.blades['e2'] e3 = layout.blades['e3'] up = layout.up A = up(e1) B = up(e2) C = up(-e1) D = up(e3) sph = A^B^C^D pl = A^B^C^layout.einf assert sph & pl == 2*(A^B^C) assert pl & sph == -2*(A^B^C)
class TestCGA2D(_TestBase): layout, blades, stuff = clifford.conformalize(clifford.Cl(2)[0]) e1 = blades['e1'] e2 = blades['e2'] @pytest.fixture(params=[ layout.scalar, e1, e1^e2, ]) def direction(self, request): return request.param @pytest.fixture(params=[ layout.scalar * 0, 3*e1, ]) def location(self, request): return request.param
class TestInitialisation: def test_speed(self): algebras = range(2, 9) print() # So that the first number is on a new line for i in algebras: t_start = time.time() Cl(i) t_end = time.time() print(i, t_end - t_start) @pytest.mark.parametrize('algebra', [Cl(i) for i in [4]] + [conformalize(Cl(3)[0])], ids=['Cl(4)', 'conformalize(Cl(3))']) def test_sparse_multiply(self, algebra): layout = algebra[0] # Make two random multivectors a = layout.randomMV() b = layout.randomMV() # Project the multivectors to the grades required grades_possibilities = [] for r in range(1, len(layout.sig)): possible_grades = [ list(m) for m in list( itertools.combinations(range(len(layout.sig)), r)) ] grades_possibilities += possible_grades for i, grades_a in enumerate(grades_possibilities): sparse_mv_a = sum([a(k) for k in grades_a]) for j, grades_b in enumerate(grades_possibilities): sparse_mv_b = sum([b(k) for k in grades_b]) # Compute results gp = layout.gmt_func_generator(grades_a=grades_a, grades_b=grades_b) result_sparse = gp(sparse_mv_a.value, sparse_mv_b.value) result_dense = (sparse_mv_a * sparse_mv_b).value # Check they are the same np.testing.assert_almost_equal(result_sparse, result_dense) print(j + i * len(grades_possibilities), len(grades_possibilities)**2)
def test_sparse_multiply(self): algebras = [Cl(i) for i in [3, 4]] + [conformalize(Cl(3)[0])] # For all the algebras we are interested in for alg in algebras: layout = alg[0] # Make two random multivectors a = layout.randomMV() b = layout.randomMV() # Project the multivectors to the grades required grades_possibilities = [] for r in range(1,len(layout.sig)): possible_grades = [list(m) for m in list(itertools.combinations(range(len(layout.sig)), r))] grades_possibilities += possible_grades for i,grades_a in enumerate(grades_possibilities): sparse_mv_a = sum([a(k) for k in grades_a]) for j,grades_b in enumerate(grades_possibilities): sparse_mv_b = sum([b(k) for k in grades_b]) # Compute results gp = layout.gmt_func_generator(grades_a=grades_a,grades_b=grades_b) result_sparse = gp(sparse_mv_a.value,sparse_mv_b.value) result_dense = (sparse_mv_a*sparse_mv_b).value # Check they are the same testing.assert_almost_equal(result_sparse, result_dense) print(j+i*len(grades_possibilities),len(grades_possibilities)**2)
def g3c(g3): return conformalize(g3)[0]
def g3c(): return conformalize(Cl(3)[0])[0]