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 [1]:
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 [2]:
from IPython.display import SVG
SVG('_static/split.svg')
Out[2]:
_images/SpaceTimeAlgebra_8_0.svg
In [3]:
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 [4]:
X = D.randomV()*10
X
Out[4]:
(10.4^d0) - (12.9^d1) - (13.0^d2) - (15.8^d3)

This can be split into time and space components by multiplying with the time-vector \(d_0\),

In [5]:
X*d0
Out[5]:
10.4 + (12.9^d01) + (13.0^d02) + (15.8^d03)

and applying the BladeMap, which results in a scalar+vector in \(\mathbb{P}\)

In [6]:
bm(X*d0)
Out[6]:
10.4 + (12.9^p1) + (13.0^p2) + (15.8^p3)

The space and time components can be separated by grade projection,

In [7]:
x = bm(X*d0)
x(0) # the time component
Out[7]:
10.4
In [8]:
x(1) # the space component
Out[8]:
(12.9^p1) + (13.0^p2) + (15.8^p3)

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 [9]:
def split(X):
    return bm(X.odd*d0+X.even)
In [10]:
split(X)
Out[10]:
10.4 + (12.9^p1) + (13.0^p2) + (15.8^p3)

The split can be inverted by applying the BladeMap again, and multiplying by \(d_0\)

In [11]:
x = split(X)
bm(x)*d0
Out[11]:
(10.4^d0) - (12.9^d1) - (13.0^d2) - (15.8^d3)

Splitting a Bivector

Given a random bivector \(F\) in \(\mathbb{D}\),

In [12]:
F = D.randomMV()(2)
F
Out[12]:
-(1.3^d01) - (0.2^d02) - (1.8^d03) - (0.4^d12) - (0.8^d13) - (0.4^d23)

\(F\) splits into a vector/bivector in \(\mathbb{P}\)

In [13]:
split(F)
Out[13]:
-(1.3^p1) - (0.2^p2) - (1.8^p3) - (0.4^p12) - (0.8^p13) - (0.4^p23)

If \(F\) is interpreted as the electromagnetic bivector, the Electric and Magnetic fields can be separated by grade

In [14]:
E = split(F)(1)
iB = split(F)(2)

E
Out[14]:
-(1.3^p1) - (0.2^p2) - (1.8^p3)
In [15]:
iB
Out[15]:
-(0.4^p12) - (0.8^p13) - (0.4^p23)

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 [16]:
R = D.randomRotor()
R
Out[16]:
-1.4 - (1.4^d01) + (0.0^d02) - (0.7^d03) + (0.8^d12) + (0.3^d13) - (1.4^d23) - (1.0^d0123)

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 [17]:
F_ = R*F*~R
F_
Out[17]:
(2.5^d01) + (6.8^d02) + (7.8^d03) - (7.0^d12) - (7.1^d13) + (3.1^d23)

Then splitting into \(E\) and \(B\) fields

In [18]:
E_ = split(F_)(1)
E_
Out[18]:
(2.5^p1) + (6.8^p2) + (7.8^p3)
In [19]:
iB_ = split(F_)(2)
iB_
Out[19]:
-(7.0^p12) - (7.1^p13) + (3.1^p23)

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 [20]:
i = p123
E = split(F)(1)
B = -i*split(F)(2)
In [21]:
F**2
Out[21]:
4.3 + (2.3^d0123)
In [22]:
split(F**2) == E**2 - B**2 + (2*E|B)*i
Out[22]:
True