#!/usr/bin/env python # coding: utf-8 # # Space Time Algebra # ## Intro # This notebook demonstrates how to use `clifford` to work with Space Time Algebra. The Pauli algebra of space $\mathbb{P}$, and Dirac algebra of space-time $\mathbb{D}$, are related using the *spacetime split*. The split is implemented by using a `BladeMap`, which maps a subset of blades in $\mathbb{D}$ to the blades in $\mathbb{P}$. This *split* allows a spacetime bivector $F$ to be broken up into relative electric and magnetic fields in space. Lorentz transformations are implemented as rotations in $\mathbb{D}$, and the effects on the relative fields are computed with the split. # # # ## Setup # # First we import `clifford`, instantiate the two algebras, and populate the namespace with the blades of each algebra. The elements of $\mathbb{D}$ are prefixed with $d$, while the elements of $\mathbb{P}$ are prefixed with $p$. Although unconventional, it is easier to read and to translate into code. # In[ ]: from clifford import Cl, pretty pretty(precision=1) # Dirac Algebra `D` D, D_blades = Cl(1,3, firstIdx=0, names='d') # Pauli Algebra `P` P, P_blades = Cl(3, names='p') # put elements of each in namespace locals().update(D_blades) locals().update(P_blades) # ## The Space Time Split # To two algebras can be related by the spacetime-split. First, we create a `BladeMap` which relates the bivectors in $\mathbb{D}$ to the vectors/bivectors in $\mathbb{P}$. The scalars and pseudo-scalars in each algebra are equated. # In[ ]: from IPython.display import SVG SVG('_static/split.svg') # In[ ]: from clifford import BladeMap bm = BladeMap([(d01,p1), (d02,p2), (d03,p3), (d12,p12), (d23,p23), (d13,p13), (d0123, p123)]) # ## Splitting a space-time vector (an event) # A vector in $\mathbb{D}$, represents a unique place in space and time, i.e. an event. To illustrate the split, create a random event $X$. # In[ ]: X = D.randomV()*10 X # This can be *split* into time and space components by multiplying with the time-vector $d_0$, # In[ ]: X*d0 # and applying the `BladeMap`, which results in a scalar+vector in $\mathbb{P}$ # # In[ ]: bm(X*d0) # The space and time components can be separated by grade projection, # In[ ]: x = bm(X*d0) x(0) # the time component # In[ ]: x(1) # the space component # We therefor define a `split()` function, which has a simple condition allowing it to act on a vector or a multivector in $\mathbb{D}$. Splitting a spacetime bivector will be treated in the next section. # In[ ]: def split(X): return bm(X.odd*d0+X.even) # In[ ]: split(X) # The split can be inverted by applying the `BladeMap` again, and multiplying by $d_0$ # In[ ]: x = split(X) bm(x)*d0 # ## Splitting a Bivector # Given a random bivector $F$ in $\mathbb{D}$, # In[ ]: F = D.randomMV()(2) F # $F$ *splits* into a vector/bivector in $\mathbb{P}$ # In[ ]: split(F) # If $F$ is interpreted as the electromagnetic bivector, the Electric and Magnetic fields can be separated by grade # In[ ]: E = split(F)(1) iB = split(F)(2) E # In[ ]: iB # ## Lorentz Transformations # Lorentz Transformations are rotations in $\mathbb{D}$, which are implemented with Rotors. A rotor in G4 will, in general, have scalar, bivector, and quadvector components. # In[ ]: R = D.randomRotor() R # In this way, the effect of a lorentz transformation on the electric and magnetic fields can be computed by rotating the bivector with $F \rightarrow RF\tilde{R}$ # In[ ]: F_ = R*F*~R F_ # Then splitting into $E$ and $B$ fields # In[ ]: E_ = split(F_)(1) E_ # In[ ]: iB_ = split(F_)(2) iB_ # ## Lorentz Invariants # Since lorentz rotations in $\mathbb{D}$, the magnitude of elements of $\mathbb{D}$ are invariants of the lorentz transformation. For example, the magnitude of electromagnetic bivector $F$ is invariant, and it can be related to $E$ and $B$ fields in $\mathbb{P}$ through the split, # In[ ]: i = p123 E = split(F)(1) B = -i*split(F)(2) # In[ ]: F**2 # In[ ]: split(F**2) == E**2 - B**2 + (2*E|B)*i