/ test / test_versors.py
test_versors.py
 1  import unittest
 2  from galgebra.ga import Ga
 3  from sympy import S
 4  
 5  
 6  class TestVersors(unittest.TestCase):
 7      def setUp(self):
 8          # Set up different geometric algebras for testing
 9  
10          # G(3,0) - Euclidean 3-space
11          self.g3d = Ga("e1 e2 e3", g=[1, 1, 1])
12  
13          # G(1,3) - Spacetime algebra
14          self.sta = Ga("e0 e1 e2 e3", g=[1, -1, -1, -1])
15  
16  
17      def test_basis_vectors_are_versors(self):
18          """Individual basis vectors should be versors"""
19          e1, e2, e3 = self.g3d.mv()
20          self.assertTrue(e1.is_versor())
21          self.assertTrue(e2.is_versor())
22          self.assertTrue(e3.is_versor())
23  
24      def test_mixed_grades_not_versor(self):
25          """A sum of different grades cannot be a versor"""
26          e1, e2, e3 = self.g3d.mv()
27          mixed = e1 + e2 * e3  # vector + bivector
28          self.assertFalse(mixed.is_versor())
29  
30      def test_dorst_counterexample(self):
31          """Test Greg1950's counterexample from the spacetime algebra"""
32          e0, e1, e2, e3 = self.sta.mv()
33          V = S.One + self.sta.I()  # 1 + I
34          self.assertFalse(V.is_versor())
35  
36      def test_rotors_are_versors(self):
37          """Test that rotors (even-grade versors) are properly detected"""
38          e1, e2, e3 = self.g3d.mv()
39          rotor = S.One + e1 * e2  # 1 + e1e2
40          self.assertTrue(rotor.is_versor())
41  
42      def test_null_is_not_versor(self):
43          """Test that null multivectors are not versors"""
44          e1, e2, e3 = self.g3d.mv()
45          null_mv = e1 + e1 * self.g3d.I()  # v + vI (squares to 0)
46          self.assertFalse(null_mv.is_versor())
47  
48      def test_scalar_versor(self):
49          """Test that nonzero scalars are versors"""
50          self.assertTrue(self.g3d.mv(2).is_versor())
51          self.assertFalse(self.g3d.mv(0).is_versor())
52  
53      def test_bivector_exponential(self):
54          """Test that exponentials of bivectors are versors"""
55          e1, e2, e3 = self.g3d.mv()
56          B = e1 * e2  # bivector
57          rotor = (B/2).exp()  # exp(B/2) is a rotor
58          self.assertTrue(rotor.is_versor())
59  
60      def test_product_of_vectors(self):
61          """Test that products of vectors are versors"""
62          e1, e2, e3 = self.g3d.mv()
63          v1 = e1 + 2*e2  # vector
64          v2 = 3*e1 - e3  # vector
65          self.assertTrue((v1 * v2).is_versor())
66  
67      def test_degenerate_metric(self):
68          """Test versor detection in a degenerate metric G(2,0,1) (PGA)"""
69          pga = Ga("e0 e1 e2", g=[0, 1, 1])  # e0^2=0, e1^2=1, e2^2=1
70          e0, e1, e2 = pga.mv()
71          # Non-null basis vectors are versors
72          self.assertTrue(e1.is_versor())
73          self.assertTrue(e2.is_versor())
74          # Null vector (e0^2 = 0) is not a versor
75          self.assertFalse(e0.is_versor())
76          # Product of non-null vectors is a versor
77          self.assertTrue((e1 * e2).is_versor())