Exemple #1
0
    def test_mul_inverse(self):
        ga = GeometricAlgebra(metric=dual_metric)

        # a = 2
        a = ga.fill([], fill_value=2.0, kind="scalar")

        # b = 3 + 3e0
        b = ga.fill([], fill_value=3.0, kind="mv")

        # a * b = 2 * (3 + 3e0) = 6 + 6e0
        c = a * b
        self.assertEqual(c, 6.0 + 6.0 * ga.basis_mvs[0])

        # a^-1 = 1 / 2
        a_inv = a.inverse()
        self.assertEqual(a_inv, 0.5)

        # c = a * b
        # => a_inv * c = b
        self.assertEqual(a_inv * c, b)

        # Since a is scalar, should commute too.
        # => c * a_inv = b
        self.assertEqual(c * a_inv, b)

        # b is not invertible and will throw an exception
        self.assertRaises(Exception, b.inverse)
Exemple #2
0
    def test_geometric_sandwich_product_dense_v_v(self):
        sta = GeometricAlgebra([1, -1, -1, -1])

        geom_tensor = tf.concat(
            [tf.zeros([32, 6, 1]),
             tf.ones([32, 6, 4]),
             tf.zeros([32, 6, 11])],
            axis=-1)

        vector_blade_indices = [1, 2, 3, 4]

        result_indices = tf.concat([
            sta.get_kind_blade_indices(BladeKind.VECTOR),
            sta.get_kind_blade_indices(BladeKind.TRIVECTOR)
        ],
                                   axis=0)

        geom_prod_layer = GeometricSandwichProductDense(
            sta,
            8,
            blade_indices_kernel=vector_blade_indices,
            blade_indices_bias=result_indices,
            bias_initializer=tf.keras.initializers.RandomNormal())

        result = geom_prod_layer(geom_tensor)

        # vector * vector * ~vector + vector -> vector + trivector

        self.assertTrue(sta.is_pure(result, result_indices))
Exemple #3
0
    def test_exp_eq_approx_exp_e01_e02(self):
        pga = GeometricAlgebra(pga_signature)

        # a = 3e01 + 5e02
        a = 3 * pga.e01 + 5 * pga.e02

        # exp(a) = 1 + 3e01 + 5e02
        self.assertTensorsApproxEqual(pga.approx_exp(a), pga.exp(a))
Exemple #4
0
    def test_exp_eq_approx_exp_e12_e23(self):
        pga = GeometricAlgebra(pga_signature)

        # a = 3e12 + 5e23
        a = 3 * pga.e12 + 5 * pga.e23

        # exp(a) ~= 0.90 - 0.22e12 -0.37e23
        self.assertTensorsApproxEqual(pga.approx_exp(a), pga.exp(a))
Exemple #5
0
    def test_mul_tf_mv(self):
        ga = GeometricAlgebra(metric=dual_metric)

        zero = ga.zeros([], kind="scalar")
        zero_tf = ga.as_mv(tf.convert_to_tensor(0.0, dtype=tf.float32))
        one = ga.ones([], kind="scalar")
        one_tf = ga.as_mv(tf.convert_to_tensor(1.0, dtype=tf.float32))
        eps = ga.ones([], kind="pseudoscalar")
        ten = ga.fill([], fill_value=10.0, kind="scalar")
        ten_tf = ga.as_mv(tf.convert_to_tensor([10.0], dtype=tf.float32))

        self.assertEqual(one * one_tf, one)
        self.assertEqual(one_tf * one, one)
        self.assertEqual(zero * one_tf, zero)
        self.assertEqual(one_tf * zero, zero)
        self.assertEqual(zero_tf * one, zero)
        self.assertEqual(one * zero_tf, zero)
        self.assertEqual(one_tf * eps, eps)
        self.assertEqual(eps * one_tf, eps)
        self.assertEqual(zero_tf * zero, zero)
        self.assertEqual(zero * zero_tf, zero)
        self.assertEqual(ten_tf * zero, zero)
        self.assertEqual(zero * ten_tf, zero)
        self.assertEqual(ten * zero_tf, zero)
        self.assertEqual(zero_tf * ten, zero)
        self.assertEqual((ten_tf * eps) * eps, zero)
        self.assertEqual(ten_tf * one, ten)
        self.assertEqual(one * ten_tf, ten)
        self.assertEqual(ten * one_tf, ten)
        self.assertEqual(one_tf * ten, ten)
Exemple #6
0
    def test_inverse(self):
        pga = GeometricAlgebra(pga_signature)

        # a = 3e12 + 5e23
        a = 3 * pga.e12 + 5 * pga.e23

        # a_inv: -0.09*e_12 + -0.15*e_23
        a_inv = pga.inverse(a)

        # a a_inv should be 1
        self.assertTensorsApproxEqual(pga.geom_prod(a, a_inv), 1 * pga.e(""))
Exemple #7
0
    def test_geom_exp_serializable(self):
        # Create algebra
        ga = GeometricAlgebra([1, 1, 1])

        inputs = ga.from_tensor_with_kind(
            tf.random.normal([3], seed=0), BladeKind.BIVECTOR
        )

        # Create model
        self._test_layer_serializable(GeometricAlgebraExp(
            ga
        ), inputs)
Exemple #8
0
    def test_geometric_product_dense_sequence(self):
        sta = GeometricAlgebra([1, -1, -1, -1])

        tensor = tf.ones([20, 6, 4])

        vector_blade_indices = [1, 2, 3, 4]
        mv_blade_indices = list(range(16))

        # vector * vector + vector -> scalar + bivector + vector
        scalar_bivector_blade_indices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        sequence = tf.keras.Sequential([
            TensorToGeometric(sta, blade_indices=vector_blade_indices),
            GeometricProductDense(
                sta,
                8,
                blade_indices_kernel=vector_blade_indices,
                blade_indices_bias=vector_blade_indices,
                bias_initializer=tf.keras.initializers.RandomNormal()),
            GeometricToTensor(sta, blade_indices=scalar_bivector_blade_indices)
        ])

        result = sequence(tensor)

        self.assertEqual(result.shape[-1], len(scalar_bivector_blade_indices))
Exemple #9
0
    def test_geom_to_tensor_serializable(self):
        # Create algebra
        sta = GeometricAlgebra([1, -1, -1, -1])
        vector_blade_indices = [1, 2, 3, 4]

        # Create model
        self._test_layer_serializable(GeometricToTensor(
            sta, blade_indices=vector_blade_indices
        ), tf.random.normal([1, 2, 3, sta.num_blades], seed=0))
Exemple #10
0
    def test_tensor_to_geom_serializable(self):
        # Create algebra
        sta = GeometricAlgebra([1, -1, -1, -1])
        vector_blade_indices = [1, 2, 3, 4]

        # Create model
        self._test_layer_serializable(TensorToGeometric(
            sta, blade_indices=vector_blade_indices
        ), tf.random.normal([1, 2, 3, len(vector_blade_indices)], seed=0))
Exemple #11
0
    def test_sandwich_elementwise_serializable(self):
        # Create algebra
        sta = GeometricAlgebra([1, -1, -1, -1])
        vector_blade_indices = [1, 2, 3, 4]
        mv_blade_indices = list(range(16))

        # Create model
        self._test_layer_serializable(GeometricSandwichProductElementwise(
            sta,
            blade_indices_kernel=mv_blade_indices,
            blade_indices_bias=vector_blade_indices
        ), tf.random.normal([3, 6, sta.num_blades], seed=0))
Exemple #12
0
    def test_mul_py_mv(self):
        ga = GeometricAlgebra(metric=dual_metric)

        zero = ga.zeros([], kind="scalar")
        zero_py = 0.0
        one = ga.ones([], kind="scalar")
        one_py = 1.0
        eps = ga.ones([], kind="pseudoscalar")
        ten = ga.fill([], fill_value=10.0, kind="scalar")
        ten_py = 10.0

        self.assertEqual(one * one_py, one)
        self.assertEqual(one_py * one, one)
        self.assertEqual(zero * one_py, zero)
        self.assertEqual(one_py * zero, zero)
        self.assertEqual(zero_py * one, zero)
        self.assertEqual(one * zero_py, zero)
        self.assertEqual(one_py * eps, eps)
        self.assertEqual(eps * one_py, eps)
        self.assertEqual(zero_py * zero, zero)
        self.assertEqual(zero * zero_py, zero)
        self.assertEqual(ten_py * zero, zero)
        self.assertEqual(zero * ten_py, zero)
        self.assertEqual(ten * zero_py, zero)
        self.assertEqual(zero_py * ten, zero)
        self.assertEqual((ten_py * eps) * eps, zero)
        self.assertEqual(ten_py * one, ten)
        self.assertEqual(one * ten_py, ten)
        self.assertEqual(ten * one_py, ten)
        self.assertEqual(one_py * ten, ten)
Exemple #13
0
    def test_batched_auto_diff_square(self):
        """Test automatic differentiation using
        dual numbers for the square function.
        Use batch with identical elements.
        f(x) = x^2
        f'(x) = d/dx f(x) = 2x
        """
        ga = GeometricAlgebra(metric=dual_metric)

        batch_shape = [3, 4]

        one = ga.ones(batch_shape, kind="scalar")
        five = 5.0 * ga.ones(batch_shape, kind="scalar")
        eps = ga.ones(batch_shape, kind="pseudoscalar")

        x = one + eps
        self.assertEqual(x[""], one)
        self.assertEqual(x["0"], eps)
        self.assertAllElementsEqualTo(x.scalar, 1.0)
        self.assertEqual(x.mv_of_kind("pseudoscalar"), eps)
        self.assertAllElementsEqualTo(x.tensor_of_kind("scalar"), 1.0)
        self.assertAllElementsEqualTo(x.tensor_of_kind("pseudoscalar"), 1.0)

        # f(1) = 1^2 = 1, f'(1) = 2
        x_squared = x * x
        self.assertAllElementsEqualTo(x_squared.scalar, 1.0)
        self.assertEqual(x_squared["0"], 2.0 * eps)

        y = five + eps
        self.assertEqual(y[""], five)
        self.assertEqual(y["0"], eps)
        self.assertAllElementsEqualTo(y.scalar, 5.0)
        self.assertEqual(y.mv_of_kind("pseudoscalar"), eps)
        self.assertAllElementsEqualTo(y.tensor_of_kind("scalar"), 5.0)
        self.assertAllElementsEqualTo(y.tensor_of_kind("pseudoscalar"), 1.0)

        # f(5) = 5^2 = 25, f'(5) = 10
        y_squared = y * y
        self.assertAllElementsEqualTo(y_squared.scalar, 25.0)
        self.assertEqual(y_squared["0"], eps * 10.0)
Exemple #14
0
    def test_geom_prod_conv1d_serializable(self):
        # Create algebra
        sta = GeometricAlgebra([1, -1, -1, -1])
        vector_blade_indices = [1, 2, 3, 4]
        mv_blade_indices = list(range(16))

        # Create model
        self._test_layer_serializable(GeometricProductConv1D(
            sta, filters=8, kernel_size=3,
            padding="SAME", stride=2,
            blade_indices_kernel=mv_blade_indices,
            blade_indices_bias=vector_blade_indices
        ), tf.random.normal([3, 8, 4, sta.num_blades], seed=0))
Exemple #15
0
    def test_geometric_to_tensor(self):
        sta = GeometricAlgebra([1, -1, -1, -1])
        gt_tensor = tf.ones([32, 4])
        geom_tensor = tf.concat(
            [tf.zeros([32, 1]),
             tf.ones([32, 4]),
             tf.zeros([32, 11])], axis=-1)

        vector_blade_indices = [1, 2, 3, 4]

        geom_to_tensor_layer = GeometricToTensor(sta, vector_blade_indices)

        self.assertTensorsEqual(geom_to_tensor_layer(geom_tensor), gt_tensor)
Exemple #16
0
    def test_geometric_product_dense_v_v(self):
        sta = GeometricAlgebra([1, -1, -1, -1])

        geom_tensor = tf.concat(
            [tf.zeros([32, 6, 1]), tf.ones([32, 6, 4]), tf.zeros([32, 6, 11])],
            axis=-1
        )

        vector_blade_indices = [1, 2, 3, 4]

        geom_prod_layer = GeometricProductDense(
            sta, 8,
            blade_indices_kernel=vector_blade_indices,
            blade_indices_bias=vector_blade_indices,
            bias_initializer=tf.keras.initializers.RandomNormal()
        )

        result = geom_prod_layer(geom_tensor)

        # vector * vector + vector -> scalar + bivector + vector
        expected_result_indices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        self.assertTrue(sta.is_pure(result, expected_result_indices))
Exemple #17
0
    def test_tensor_with_kind_to_geometric(self):
        sta = GeometricAlgebra([1, -1, -1, -1])
        tensor = tf.ones([32, 4])
        gt_geom_tensor = tf.concat(
            [tf.zeros([32, 1]),
             tf.ones([32, 4]),
             tf.zeros([32, 11])], axis=-1)

        vector_blade_indices = [1, 2, 3, 4]

        tensor_kind_to_geom_layer = TensorWithKindToGeometric(
            sta, BladeKind.VECTOR)

        self.assertTensorsEqual(tensor_kind_to_geom_layer(tensor),
                                gt_geom_tensor)
Exemple #18
0
    def test_geometric_product_dense_s_mv(self):
        sta = GeometricAlgebra([1, -1, -1, -1])

        geom_tensor = tf.concat(
            [tf.ones([20, 6, 1]), tf.zeros([20, 6, 15])], axis=-1)

        mv_blade_indices = list(range(16))

        geom_prod_layer = GeometricProductDense(
            sta,
            8,
            blade_indices_kernel=mv_blade_indices,
            blade_indices_bias=mv_blade_indices)

        result = geom_prod_layer(geom_tensor)

        # scalar * multivector + multivector -> multivector
        # Check that nothing is zero (it would be extremely unlikely
        # but not impossible to randomly get a zero here).
        self.assertTrue(tf.reduce_all(result != 0.0))
Exemple #19
0
def test_tfga_mul_mv_mv(num_elements, benchmark):
    ga = GeometricAlgebra([1, -1, -1, -1])
    a = tf.ones([num_elements, ga.num_blades])
    b = tf.ones([num_elements, ga.num_blades])
    benchmark(_tfga_mul, ga, a, b)
Exemple #20
0
    def test_auto_diff_square(self):
        """Test automatic differentiation using
        dual numbers for the square function.
        f(x) = x^2
        f'(x) = d/dx f(x) = 2x
        """
        ga = GeometricAlgebra(metric=dual_metric)

        one = ga.from_scalar(1.0)
        five = ga.from_scalar(5.0)
        eps = ga.from_tensor_with_kind(tf.ones(1), kind="pseudoscalar")

        x = one + eps

        # f(1) = 1^2 = 1, f'(1) = 2
        x_squared = ga.geom_prod(x, x)
        self.assertTensorsEqual(ga.select_blades(x_squared, ""), 1.0)
        self.assertTensorsEqual(ga.select_blades(x_squared, "0"), 2.0)

        y = five + eps

        # f(5) = 5^2 = 25, f'(5) = 10
        y_squared = ga.geom_prod(y, y)
        self.assertTensorsEqual(ga.select_blades(y_squared, ""), 25.0)
        self.assertTensorsEqual(ga.select_blades(y_squared, "0"), 10.0)
Exemple #21
0
    def test_mul_tf_mv(self):
        ga = GeometricAlgebra(metric=dual_metric)

        zero = ga.from_scalar(0.0)
        one = ga.from_scalar(1.0)
        eps = ga.from_tensor_with_kind(tf.ones(1), kind="pseudoscalar")
        ten = ga.from_scalar(10.0)

        zero_tf = tf.convert_to_tensor([0, 0], dtype=tf.float32)
        one_tf = tf.convert_to_tensor([1, 0], dtype=tf.float32)
        eps_tf = tf.convert_to_tensor([0, 1], dtype=tf.float32)
        ten_tf = tf.convert_to_tensor([10, 0], dtype=tf.float32)

        self.assertTensorsEqual(ga.geom_prod(one, one_tf), one)
        self.assertTensorsEqual(ga.geom_prod(one_tf, one), one)
        self.assertTensorsEqual(ga.geom_prod(zero, one_tf), zero)
        self.assertTensorsEqual(ga.geom_prod(one_tf, zero), zero)
        self.assertTensorsEqual(ga.geom_prod(zero_tf, one), zero)
        self.assertTensorsEqual(ga.geom_prod(one, zero_tf), zero)
        self.assertTensorsEqual(ga.geom_prod(one_tf, eps), eps)
        self.assertTensorsEqual(ga.geom_prod(eps, one_tf), eps)
        self.assertTensorsEqual(ga.geom_prod(zero_tf, zero), zero)
        self.assertTensorsEqual(ga.geom_prod(zero, zero_tf), zero)
        self.assertTensorsEqual(ga.geom_prod(ten_tf, zero), zero)
        self.assertTensorsEqual(ga.geom_prod(zero, ten_tf), zero)
        self.assertTensorsEqual(ga.geom_prod(ten, zero_tf), zero)
        self.assertTensorsEqual(ga.geom_prod(zero_tf, ten), zero)
        self.assertTensorsEqual(ga.geom_prod(ga.geom_prod(ten_tf, eps), eps),
                                zero)
        self.assertTensorsEqual(ga.geom_prod(ten_tf, one), ten)
        self.assertTensorsEqual(ga.geom_prod(one, ten_tf), ten)
        self.assertTensorsEqual(ga.geom_prod(ten, one_tf), ten)
        self.assertTensorsEqual(ga.geom_prod(one_tf, ten), ten)
Exemple #22
0
    def test_mul_mv_mv(self):
        ga = GeometricAlgebra(metric=dual_metric)

        zero = ga.from_scalar(0.0)
        one = ga.from_scalar(1.0)
        eps = ga.from_tensor_with_kind(tf.ones(1), kind="pseudoscalar")
        ten = ga.from_scalar(10.0)

        self.assertTensorsEqual(ga.geom_prod(eps, eps), zero)
        self.assertTensorsEqual(ga.geom_prod(one, one), one)
        self.assertTensorsEqual(ga.geom_prod(zero, one), zero)
        self.assertTensorsEqual(ga.geom_prod(one, zero), zero)
        self.assertTensorsEqual(ga.geom_prod(one, eps), eps)
        self.assertTensorsEqual(ga.geom_prod(eps, one), eps)
        self.assertTensorsEqual(ga.geom_prod(zero, zero), zero)
        self.assertTensorsEqual(ga.geom_prod(ten, zero), zero)
        self.assertTensorsEqual(ga.geom_prod(zero, ten), zero)
        self.assertTensorsEqual(ga.geom_prod(ga.geom_prod(ten, eps), eps),
                                zero)
        self.assertTensorsEqual(ga.geom_prod(ten, one), ten)
        self.assertTensorsEqual(ga.geom_prod(one, ten), ten)
Exemple #23
0
    def test_mul_inverse(self):
        ga = GeometricAlgebra(metric=dual_metric)

        # a = 2
        a = ga.from_tensor_with_kind(tf.fill([1], 2.0), kind="scalar")

        # b = 3 + 3e0
        b = ga.from_tensor_with_kind(tf.fill([2], 3.0), kind="mv")

        # a * b = 2 * (3 + 3e0) = 6 + 6e0
        c = ga.geom_prod(a, b)
        self.assertTensorsEqual(c, ga.from_scalar(6.0) + 6.0 * ga.e("0"))

        # a^-1 = 1 / 2
        a_inv = ga.inverse(a)
        self.assertTensorsEqual(ga.select_blades(a_inv, ""), 0.5)

        # c = a * b
        # => a_inv * c = b
        self.assertTensorsEqual(ga.geom_prod(a_inv, c), b)

        # Since a is scalar, should commute too.
        # => c * a_inv = b
        self.assertTensorsEqual(ga.geom_prod(c, a_inv), b)

        # b is not invertible and will throw an exception
        self.assertRaises(Exception, ga.inverse, b)