from clifford import *
pretty()
layout, blades = Cl(3,1)
rb = lambda g:randomMV(layout, grades=[g])
eps(1e-11)
Vectors in the orignal space are mapped to vectors in conformal space through the map:
$X = x + \frac{1}{2} x^2 e_{\infty} +e_o $
The inverse map is the made by normalizing the conformal vector, then rejection from the minkowski plane $E_0$,
$ X = \frac{X}{X \cdot e_{\infty}}$
then
$x = X \wedge E_0\, E_0^{-1}$
e0,e1,e2,e3 = [blades['e%i'%k] for k in range(4)]
# setup null basis, and minkowski subspace bivector
eo = .5^(e3-e2)
einf= e2+e3
E0= einf^eo
v4 = lambda : rb(1)
def v2():
x=v4()
return x- E0.project(x)
up = lambda x: x + (.5^((x**2)*einf)) + eo
homo = lambda x: x * (-x|einf).normalInv() # homogenise conformal vector
down = lambda x: (homo(x)^E0)*E0
c2v = lambda x: (x.real*e0) + (x.imag*e1) # complex2vector
v2c = lambda x: float(x|e0)+ float(x|e1)*1j
eo^einf == -E0
eo
einf*eo
einf-(2^eo)
x = v2()
x
X=up(x)
X
x = v2()
X = up(x)
assert(X**2 ==0)
assert(down(X) ==x)
Conformal transformations in $G^n$ are achieved through versers in the conformal space $G^{n+1,1}$. These versers can be categorized by their relation to the added minkowski plane, $E_0$. There are three categories,
from IPython.display import Image,SVG
Image('img/conformal space.png')
eps(1e-13)
a = v2()
b = v2()
$ e_+ X e_+$
Inversion is a reflection in hyperplane normal to $e_-$, this swaps $e_o$ and $e_{\infty}$
assert(down(e2&up(a)&e2) == a.inv())
$E_0 X E_0$
assert(down(E0&up(a)&E0) == -a)
$D_\alpha = e^{-\frac{\ln{\alpha}}{2} \,E_0} $
$D_\alpha \, X \, \tilde{D_\alpha} $
D = lambda alpha: e**((-log(alpha)/2.)&(E0))
alpha = rand()
assert(down( D(alpha)&up(a)&~D(alpha)) == (alpha&a))
T = lambda x: e**(1/2.&(einf&x))
assert(down( T(a)&up(b)&~T(a)) == b+a)
A transversion is an inversion, followed by a translation, followed by a inversion. The verser is
$$V= e_+ T_a e_+$$which is recognised as the translation bivector reflected in the $e_+$ vector. From the diagram, it is seen that this is equivalent to the bivector in $x\wedge e_o$,
$$ e_+ (1+e_{\infty}a)e_+ $$$$ e_+^2 + e_+e_{\infty}a e_+$$$$2 +2e_o a$$the factor of 2 may be dropped, because the conformal vectors are null
V = e2 & T(a) & e2
assert ( V == 1+(eo&a))
K = lambda x: 1+(eo&a)
B= up(b)
assert( down(K(a) & B & ~K(a)) == 1/(a+1/b) )
Versers that are out of $E_0$ are made up of the versers within the original space. These include reflections and rotations, and their conformal representation is identical to their form in $G^n$, except the minus sign is dropped for reflections,
m = v2()
m = m/abs(m)
assert(down(m&up(a)&m) == -m&a&m)
R = lambda theta: e**((-.5*theta)&(e0^e1))
theta = pi/2
assert(down( R(theta)&up(a)&~R(theta)) == R(theta)&a&~R(theta))
As a simple example consider the combination operations of translation,scaling, and inversion.
A = up(a)
V = T(e0)&E0&D(2)
B = V&A&~V
assert(down(B) == (-2&a)+e0 )
A transversion may be built from a inversion, translation, and inversion.
$$c = (a^{-1}+b)^{-1}$$In conformal GA, this is accomplished by
$$C = VA\tilde{V}$$$$V= e_+ T_b e_+$$A = up(a)
V = e2&T(b)&e2
C = V&A&~V
assert(down(C) ==1/(1/a +b))
Rotation about a point, $a$ can be achieved by translating the origina to $a$ then rotating, then translating back. Just like the transversion can be thought of as translating the involution operator, rotation about a point can also be thought of as translating the Rotor itself. Covariance.
r = R(pi/2.)
Q =T(a)&r&~T(a)
B= up(b)
C=Q&B&~Q
c=down(C)
c
The incorperation of complex number can be done in a number of ways. One way is to translate the complex numbers to 2D vectors. This is done first by identifying the complex numbers with the even grade elements in $G^2$, which are spinors.
$$ \mathbb{C}\Longrightarrow G^{2+} \Longrightarrow G^{2-}\\ \mathbf{a}\Longrightarrow A\Longrightarrow a $$All spinors in $G^2$ can be expressed as the product of a chosen 'real' vector, such as $e_0$, and another vector,
\begin{eqnarray*} A & = & e_{0}a\\ \tilde{A} & = & ae_{0}\\ A^{-1} = \frac{\tilde{A}}{\tilde{A}A}& = & a^{-1}e_{0} \end{eqnarray*}Left multiplying a spinor by $e_0$ converts them into vectors. \begin{eqnarray*} A & \rightarrow & a\\ \tilde{A} & \rightarrow & e_{0}ae_{0}\\ A^{-1} & \rightarrow & e_{0}a^{-1}e_{0}\\ AB=BA & \rightarrow & ae_{0}b=be_{0}a \end{eqnarray*}
Note the order of translation is important, for operations to be transformed properly. For example, given the product $\mathbf{ab}$, one is tempted to write $\mathbf{ab}=ab$, which would be wrong. First, $\mathbf{a}$ and $\mathbf{b}$ must be translated to spinors $A$ and $B$, then converted to vectors. $$ AB = e_0ae_0b \rightarrow e_0^2 a e_0 b = a e_0 b $$
Starting with the transform $$ s = \frac{\mathbf{z}-1}{\mathbf{z}+1} $$
where $\mathbf{z}$ is a complex number. This can be rewritten as a series of operations as such,
\begin{eqnarray*} -2(\mathbf{z}+1)^{-1}+1 \end{eqnarray*}then expression can be converted into one containing vectors.
\begin{eqnarray*} -2e_0(z+e_0)^{-1}+e_0 \end{eqnarray*}where $z= e_0 Z$
The verser representation is
$$V = T_{e_0} E_0 D_2 e_0 e_+ T_{e_0} $$[This can probaly be simplified]
z = v2()
z_ = v2c(z)
(z_-1)/(z_+1)
(-2 & e0 & (z+e0).inv() & e0) + e0
Z = up(z)
Q = T(e0) & D(2)&e0 & e2 & T(e0)
S = -Q&Z&~Q
s = down(S)
s
Q = T(e0) & D(2)&e0 & e2 & T(e0)
theta = arccos(float(Q(0)))
R = e**((theta)&(Q(2)/abs(Q(2))))
theta/pi
$\mathbf{m} = \mathbf{s_{00}}+ \mathbf{s_{01}}(\mathbf{a}^{-1}-\mathbf{s_{11}})^{-1}$
s11_, s00_, s01_, a_= rf.rand_c(4)
s11,s00,s01,a = map(c2v,(s11_, s00_, s01_,a_))
#assert( ((e01&((e0&a.inv()&e0)-e11).inv())&e0)+ (e00) ==\
# c2v(e00_ + e01_/(1/a_ -e11_)))
a,b,c,d = [v2() for k in range(4)]
A,B,C,D = map(up, (a,b,c,d))
d= a&b&c
d
e01 = e0^e1
c2s = lambda c: c.real + (c.imag&e01) # complex to G2 Spinor
c_ =rand()+rand()*1j
c = c2s(c_)
c
assert(down(up(c)) == c)
C = up(C)
C
down(T(e0) & C & ~T(e0))
e0&a.inv()&e0 == (e0&a&e0).inv()
(a.inv()&b.inv()) - (a&b).inv()