5
The reference D&L is "Geometric Algebra for Physicists" by Doran and Lasenby
10
from sympy.external import import_module
11
numpy = import_module('numpy')
15
sys.path.append('../')
16
from sympy.galgebra.GA import MV, ZERO, HALF, S
22
Conformal Mapping Function from 3D Euclidean space to 5D conformal space
23
where the images of all maps are null vectors.
25
Fx = HALF*((x*x)*n + 2*x - nbar)
32
Test for commutative scalar multiplication. Leftover from when sympy and
33
numpy were not working together and __mul__ and __rmul__ would not give the
36
x, y, z = MV.setup('x y z')
37
a, b, c = sympy.symbols('a b c')
39
assert HALF*x == x*HALF
43
def test_contraction():
45
Test for inner product and left and right contraction
48
e_1, e_2, e_3 = MV.setup('e_1 e_2 e_3', '1 0 0, 0 1 0, 0 0 1', offset=1)
50
assert ((e_1 ^ e_3) | e_1) == -e_3
51
assert ((e_1 ^ e_3) > e_1) == -e_3
52
assert (e_1 | (e_1 ^ e_3)) == e_3
53
assert (e_1 < (e_1 ^ e_3)) == e_3
54
assert ((e_1 ^ e_3) < e_1) == 0
55
assert (e_1 > (e_1 ^ e_3)) == 0
58
def test_substitution():
60
e_x, e_y, e_z = MV.setup('e_x e_y e_z', '1 0 0, 0 1 0, 0 0 1', offset=1)
61
x, y, z = sympy.symbols('x y z')
63
X = x*e_x + y*e_y + z*e_z
64
Y = X.subs([(x, 2), (y, 3), (z, 4)])
65
assert Y == 2*e_x + 3*e_y + 4*e_z
68
def test_vector_extraction():
70
Show that conformal bivector encodes two points. See D&L Section 10.4.1
72
metric = ' 0 -1 #,' + \
76
P1, P2, a = MV.setup('P1 P2 a', metric)
78
P1 and P2 are null vectors and hence encode points in conformal space.
79
Show that P1 and P2 can be extracted from the bivector B = P1^P2. a is a
80
third vector in the conformal space with a.B not 0.
87
P1dota = sympy.Symbol('(P1.a)')
88
P2dota = sympy.Symbol('(P2.a)')
89
Ap_test = (-2*P2dota)*P1
90
Am_test = (-2*P1dota)*P2
106
Test specific metrics (diagpq, arbitrary_metric, arbitrary_metric_conformal)
108
from sympy.galgebra.GA import diagpq, arbitrary_metric, arbitrary_metric_conformal
110
p1, p2, p3 = MV.setup('p1 p2 p3', metric, debug=0)
112
x1, y1, z1 = sympy.symbols('x1 y1 z1')
113
x2, y2, z2 = sympy.symbols('x2 y2 z2')
114
v1 = x1*p1 + y1*p2 + z1*p3
115
v2 = x2*p1 + y2*p2 + z2*p3
117
prod2 = (v1|v2) + (v1^v2)
121
metric = arbitrary_metric(3)
122
p1, p2, p3 = MV.setup('p1 p2 p3', metric, debug=0)
123
v1 = x1*p1 + y1*p2 + z1*p3
124
v2 = x2*p1 + y2*p2 + z2*p3
126
prod2 = (v1|v2) + (v1^v2)
130
metric = arbitrary_metric_conformal(3)
131
p1, p2, p3 = MV.setup('p1 p2 p3', metric, debug=0)
132
v1 = x1*p1 + y1*p2 + z1*p3
133
v2 = x2*p1 + y2*p2 + z2*p3
135
prod2 = (v1|v2) + (v1^v2)
142
Test conformal geometric description of circles, lines, spheres, and planes.
144
metric = '1 0 0 0 0,' + \
150
e0, e1, e2, n, nbar = MV.setup('e0 e1 e2 n nbar', metric, debug=0)
152
#conformal representation of points
154
A = F(e0, n, nbar) # point a = (1,0,0) A = F(a)
155
B = F(e1, n, nbar) # point b = (0,1,0) B = F(b)
156
C = F(-1*e0, n, nbar) # point c = (-1,0,0) C = F(c)
157
D = F(e2, n, nbar) # point d = (0,0,1) D = F(d)
158
x0, x1, x2 = sympy.symbols('x0 x1 x2')
159
X = F(MV([x0, x1, x2], 'vector'), n, nbar)
161
Circle = A ^ B ^ C ^ X
163
Sphere = A ^ B ^ C ^ D ^ X
164
Plane = A ^ B ^ n ^ D ^ X
166
#Circle through a, b, and c
167
Circle_test = -x2*(e0 ^ e1 ^ e2 ^ n) + x2*(
168
e0 ^ e1 ^ e2 ^ nbar) + HALF*(-1 + x0**2 + x1**2 + x2**2)*(e0 ^ e1 ^ n ^ nbar)
169
diff = Circle - Circle_test
173
#Line through a and b
174
Line_test = -x2*(e0 ^ e1 ^ e2 ^ n) + \
175
HALF*(-1 + x0 + x1)*(e0 ^ e1 ^ n ^ nbar) + \
176
(HALF*x2)*(e0 ^ e2 ^ n ^ nbar) + \
177
(-HALF*x2)*(e1 ^ e2 ^ n ^ nbar)
178
diff = Line - Line_test
182
#Sphere through a, b, c, and d
183
Sphere_test = HALF*(1 - x0**2 - x1**2 - x2**2)*(e0 ^ e1 ^ e2 ^ n ^ nbar)
184
diff = Sphere - Sphere_test
188
#Plane through a, b, and d
189
Plane_test = HALF*(1 - x0 - x1 - x2)*(e0 ^ e1 ^ e2 ^ n ^ nbar)
190
diff = Plane - Plane_test
195
def test_extract_plane_and_line():
197
Show that conformal trivector encodes planes and lines. See D&L section
200
metric = '# # # 0 0,' + \
206
p1, p2, p3, n, nbar = MV.setup('p1 p2 p3 n nbar', metric, debug=0)
213
#Line through p1 and p2
215
delta = (L | n) | nbar
216
delta_test = 2*p1 - 2*p2
217
diff = delta - delta_test
221
#Plane through p1, p2, and p3
223
delta = ((C ^ n) | n) | nbar
224
delta_test = 2*(p1 ^ p2) - 2*(p1 ^ p3) + 2*(p2 ^ p3)
225
diff = delta - delta_test
230
def test_reciprocal_frame():
232
Test of formula for general reciprocal frame of three vectors.
233
Let three independent vectors be e1, e2, and e3. The reciprocal
234
vectors E1, E2, and E3 obey the relations:
236
e_i.E_j = delta_ij*(e1^e2^e3)**2
238
metric = '1 # #,' + \
242
e1, e2, e3 = MV.setup('e1 e2 e3', metric)
247
E2 = (-1)*(e1 ^ e3)*E
284
def test_derivative():
285
coords = x, y, z = sympy.symbols('x y z')
286
e_x, e_y, e_z = MV.setup('e', '1 0 0, 0 1 0, 0 0 1', coords=coords)
287
X = x*e_x + y*e_y + z*e_z
288
a = MV('a', 'vector')
290
assert ((X | a).grad()) == a
291
assert ((X*X).grad()) == 2*X
292
assert (X*X*X).grad() == 5*X*X
293
assert X.grad_int() == 3
297
e_1, e_2, e_3 = MV.setup('e_1 e_2 e_3', '1 0 0, 0 1 0, 0 0 1')
300
assert str(X) == 'x+x__0*e_1+x__1*e_2+x__2*e_3+x__01*e_1e_2+x__02*e_1e_3+x__12*e_2e_3+x__012*e_1e_2e_3'
301
Y = MV('y', 'spinor')
302
assert str(Y) == 'y+y__01*e_1e_2+y__02*e_1e_3+y__12*e_2e_3'
304
assert str(Z) == 'x+y+x__0*e_1+x__1*e_2+x__2*e_3+(x__01+y__01)*e_1e_2+(x__02+y__02)*e_1e_3+(x__12+y__12)*e_2e_3+x__012*e_1e_2e_3'
305
assert str(e_1 | e_1) == '1'
309
MV.setup('e_1 e_2 e_3', '[1,1,1]')
310
assert str(MV.metric) == '[[1 0 0]\n [0 1 0]\n [0 0 1]]'
313
def test_constructor():
315
Test various multivector constructors
317
e_1, e_2, e_3 = MV.setup('e_1 e_2 e_3', '[1,1,1]')
318
x = sympy.symbols('x')
319
assert str(S(1)) == '1'
320
assert str(S(x)) == 'x'
321
assert str(MV('a', 'scalar')) == 'a'
322
assert str(MV('a', 'vector')) == 'a__0*e_1+a__1*e_2+a__2*e_3'
323
assert str(MV('a', 'pseudo')) == 'a*e_1e_2e_3'
324
assert str(MV('a', 'spinor')) == 'a+a__01*e_1e_2+a__02*e_1e_3+a__12*e_2e_3'
325
assert str(MV('a')) == 'a+a__0*e_1+a__1*e_2+a__2*e_3+a__01*e_1e_2+a__02*e_1e_3+a__12*e_2e_3+a__012*e_1e_2e_3'
327
MV([2, 'a'], 'grade')) == 'a__01*e_1e_2+a__02*e_1e_3+a__12*e_2e_3'
328
assert str(MV('a', 'grade2')) == 'a__01*e_1e_2+a__02*e_1e_3+a__12*e_2e_3'
331
def test__print_Mul_Add():
332
from sympy.galgebra.latex_ex import LatexPrinter
333
from sympy import symbols
334
n, m = symbols('n,m', negative=True)
337
assert l._print_Mul(n*m) == 'm n'
338
assert l._print_Mul(-2*m) == '- 2 m'
339
assert l._print_Mul(2*m) == '2 m'
340
assert l._print_Add(-5 + 4*z) == '-5 + 4 z'
341
assert l._print_Add(-5 - 4*z) == '-5 - 4 z'
342
assert l._print_Add(n - 2) == '-2 + n'