# Conformal Geometric Algebra¶

## Intro¶

Conformal Geometric Algebra (CGA) is a projective geometry tool which allows conformal transformations to be implemented with rotations. To do this, the original geometric algebra is extended by two dimensions, one of positive signature \(e_+\) and one of negative signature \(e_-\). Thus, if we started with \(G_p\), the conformal algebra is \(G_{p+1,1}\).

It is convenient to define a *null* basis given by

A vector in the original space \(x\) is *up-projected* into a
conformal vector \(X\) by

To map a conformal vector back into a vector from the original space, the vector is first normalized, then rejected from the minkowski plane \(E_0\),

then

To implement this in `clifford`

we could create a CGA by instantiating
the it directly, like `Cl(3,1)`

for example, and then making the
definitions and maps described above relating the various subspaces. Or,
we you can use the helper function `conformalize()`

.

## Using `conformalize()`

¶

The purpose of `conformalize()`

is to remove the redunancy assocaited
with creating a conformal geometric algebras. `conformalize()`

takes
an existing geometric algebra layout and *conformalizes* it by adding
two dimensions, as described above. Additionally, this function returns
a new layout for the CGA, a dict of blades for the CGA, and dictionary
containing the added basis vectors and up/down projection functions.

To demonstrate we will conformalize \(G_2\), producing a CGA of \(G_{3,1}\).

```
In [1]:
```

```
from numpy import pi,e
from clifford import Cl, conformalize
G2, blades_g2 = Cl(2)
blades_g2 # inspect the G2 blades
```

```
Out[1]:
```

```
{'e1': (1^e1), 'e2': (1^e2), 'e12': (1^e12)}
```

Now, conformalize it

```
In [2]:
```

```
G2c, blades_g2c, stuff = conformalize(G2)
blades_g2c #inspect the CGA blades
```

```
Out[2]:
```

```
{'e1': (1^e1),
'e2': (1^e2),
'e3': (1^e3),
'e4': (1^e4),
'e12': (1^e12),
'e13': (1^e13),
'e14': (1^e14),
'e23': (1^e23),
'e24': (1^e24),
'e34': (1^e34),
'e123': (1^e123),
'e124': (1^e124),
'e134': (1^e134),
'e234': (1^e234),
'e1234': (1^e1234)}
```

Additionally lets inspect `stuff`

```
In [3]:
```

```
stuff
```

```
Out[3]:
```

```
{'ep': (1^e3),
'en': (1^e4),
'eo': -(0.5^e3) + (0.5^e4),
'einf': (1^e3) + (1^e4),
'E0': (1.0^e34),
'up': <function clifford.conformalize.<locals>.up(x)>,
'down': <function clifford.conformalize.<locals>.down(x)>,
'homo': <function clifford.conformalize.<locals>.homo(x)>,
'I_base': (1.0^e12)}
```

It contains the following:

`ep`

- postive basis vector added`en`

- negative basis vector added`eo`

- zero vecror of null basis (=.5*(en-ep))`einf`

- infinity vector of null basis (=en+ep)`E0`

- minkowski bivector (=einf^eo)`up()`

- function to up-project a vector from GA to CGA`down()`

- function to down-project a vector from CGA to GA`homo()`

- function ot homogenize a CGA vector

We can put the `blades`

and the `stuff`

into the local namespace,

```
In [4]:
```

```
locals().update(blades_g2c)
locals().update(stuff)
```

Now we can use the `up()`

and `down()`

functions to go in and out of
CGA

```
In [5]:
```

```
x = e1+e2
X = up(x)
X
```

```
Out[5]:
```

```
(1.0^e1) + (1.0^e2) + (0.5^e3) + (1.5^e4)
```

```
In [6]:
```

```
down(X)
```

```
Out[6]:
```

```
(1.0^e1) + (1.0^e2)
```

## Operations¶

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,

- verser purely in \(E_0\)
- verser partly in \(E_0\)
- verser out of \(E_0\)

A three dimensional projection for conformal space with the relavant subspaces labeled is shown below.

```
In [7]:
```

```
from IPython.display import Image
Image(url='_static/conformal space.svg')
```

```
Out[7]:
```

## Versers purely in \(E_0\)¶

First we generate some vectors in G2, which we can operate on

```
In [8]:
```

```
a= 1*e1 + 2*e2
b= 3*e1 + 4*e2
```

### Inversions¶

Inversion is a reflection in \(e_+\), this swaps \(e_o\) and \(e_{\infty}\), as can be seen from the model above.

```
In [9]:
```

```
assert(down(ep*up(a)*ep) == a.inv())
```

### Dilations¶

```
In [11]:
```

```
from scipy import rand,log
D = lambda alpha: e**((-log(alpha)/2.)*(E0))
alpha = rand()
assert(down( D(alpha)*up(a)*~D(alpha)) == (alpha*a))
```

## Versers partly in \(E_0\)¶

### Translations¶

```
In [12]:
```

```
T = lambda x: e**(1/2.*(einf*x))
assert(down( T(a)*up(b)*~T(a)) == b+a)
```

### Transversions¶

A transversion is an inversion, followed by a translation, followed by a inversion. The verser is

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\),

the factor of 2 may be dropped, because the conformal vectors are null

```
In [13]:
```

```
V = ep * T(a) * ep
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 Out of \(E_0\)¶

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,

### Reflections¶

```
In [14]:
```

```
m = 5*e1 + 6*e2
n = 7*e1 + 8*e2
assert(down(m*up(a)*m) == -m*a*m.inv())
```

### Rotations¶

```
In [15]:
```

```
R = lambda theta: e**((-.5*theta)*(e12))
theta = pi/2
assert(down( R(theta)*up(a)*~R(theta)) == R(theta)*a*~R(theta))
```

## Combinations of Operations¶

### simple example¶

As a simple example consider the combination operations of translation,scaling, and inversion.

```
In [16]:
```

```
A = up(a)
V = T(e1)*E0*D(2)
B = V*A*~V
assert(down(B) == (-2*a)+e1 )
```

### Transversion¶

A transversion may be built from a inversion, translation, and inversion.

In conformal GA, this is accomplished by

```
In [17]:
```

```
A = up(a)
V = ep*T(b)*ep
C = V*A*~V
assert(down(C) ==1/(1/a +b))
```

### Rotation about a point¶

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.