Hugo Hadfield
Cambridge University PhD student, Signal Processing and Communications Laboratory
Part 1
Hugo Hadfield 2018
FOCUSES ON CLEAN SYNTAX AND USEFUL ALGORITHMS
THE GOAL IS TO BE EASY TO USE NOT SUPER SUPER FAST (although it is pretty fast too...)
pip install clifford
or
conda install clifford -c conda-forge
Syntax | Operation |
---|---|
| | Symetric inner product |
<< | Left contraction |
^ | Outer product |
* | Geometric product |
X(i) | Return the section of the multivector X of grade i |
X(ei) | Return the section of the multivector X for which ei is the pseudo scalar |
X[i] | Return the i'th coefficient from the multivector X |
X.normal() | Return the normalised multivector so that X*~X is +- 1 |
up(x) | Maps a multivector from ND euclidean space to its (N+1,1) conformal equivalent point |
from clifford.g3c import *
A = up( 4*e1 - 5.1*e2 + 9*e3 ) # Mapping 3DGA to Conformal:
(4.0^e1) - (5.1^e2) + (9.0^e3) + (61.005^e4) + (62.005^e5)
B = up( -2.2*e1 + 3*e2 + 6.8*e3 ) # Mapping 3DGA to Conformal
-(2.2^e1) + (3.0^e2) + (6.8^e3) + (29.54^e4) + (30.54^e5)
A|B # Symmetric inner product
-54.445
A^B # Outer product
(0.78^e12) + (47.0^e13) + (252.371^e14) + (258.571^e15) - (61.68^e23) - (333.669^e24) - (341.769^e25) - (148.974^e34) - (146.774^e35) + (31.465^e45)
A << (A ^ B) # Asymmetric left contraction
(217.78^e1) - (277.6695^e2) + (490.005^e3) + (3321.41723^e4) + (3375.86223^e5)
A*B # Geometric product
-54.445 + (0.78^e12) + (47.0^e13) + (252.371^e14) + (258.571^e15) - (61.68^e23) - (333.669^e24) - (341.769^e25) - (148.974^e34) - (146.774^e35) + (31.465^e45)
(A * B)(2) # Grade selection
(0.78^e12) + (47.0^e13) + (252.371^e14) + (258.571^e15) - (61.68^e23) - (333.669^e24) - (341.769^e25) - (148.974^e34) - (146.774^e35) + (31.465^e45)
(A * B)(1) # Grade selection
0
(A * B)(e123) # Subalgebra selection
-54.445 + (0.78^e12) + (47.0^e13) - (61.68^e23)
(A * B)[0] # Coefficient selection
-54.445000000000164
Grade | Construction | Interpretation |
---|---|---|
1 | up(x) | Point |
2 | A^B | Point pair |
3 | A^B^C | Circle |
3 | A^B^einf | Line |
4 | A^B^C^D | Sphere |
4 | A^B^C^einf | Plane |
from clifford.g3c import * # Import Conformal GA (4,1)
from clifford.tools.g3c import * # Import prebuilt tools for conformal GA
random_conformal_point()
(0.3492^e1) + (16.36818^e2) - (1.09622^e3) + (134.12051^e4) + (135.12051^e5)
random_point_pair()
(0.14781^e12) + (0.2147^e13) + (3.91966^e14) + (3.94971^e15) + (0.26825^e23) + (6.25298^e24) + (6.31054^e25) + (1.9694^e34) + (1.99847^e35) + (0.25491^e45)
random_circle()
(0.00893^e123) - (1.58332^e124) - (1.6043^e125) - (4.67362^e134) - (4.73433^e135) - (0.21387^e145) + (2.53838^e234) + (2.57207^e235) - (0.0124^e245) - (0.37947^e345)
random_line()
(0.54733^e124) + (0.54733^e125) + (4.48487^e134) + (4.48487^e135) - (0.29013^e145) - (9.78048^e234) - (9.78048^e235) + (0.53594^e245) - (0.79284^e345)
random_sphere()
(4.85087^e1234) + (4.84582^e1235) + (0.01843^e1245) - (1.01612^e1345) - (0.12664^e2345)
random_plane()
-(14.57447^e1234) - (14.57447^e1235) + (0.75755^e1245) - (0.45902^e1345) + (0.46414^e2345)
# Import Conformal GA (4,1)
from clifford.g3c import *
# Import prebuilt tools for conformal GA
from clifford.tools.g3c import *
# Import pyganja for visualisation
from pyganja import *
object_array = [
random_conformal_point(),
random_point_pair(),
random_circle(),
random_line(),
random_sphere(),
random_plane()
]
# The simplest way to use pyganja
draw(object_array,
static=False ,
scale=0.1)
# Import Conformal GA (4,1)
from clifford.g3c import *
# Import prebuilt tools for conformal GA
from clifford.tools.g3c import *
# Import pyganja for visualisation
from pyganja import *
# Make a load of stuff
object_array = [
random_conformal_point(),
random_point_pair(),
random_circle(),
random_line()
]
# Make a plane to reflect it in
P = random_plane()
# Reflect it all in the plane
object_array2 = [P*X*P
for X in object_array]
# Pyganja scene api
gs = GanjaScene()
gs.add_objects(object_array,
color=int('AA000000',16),
static=False)
gs.add_objects(object_array2,
color=int('AAFF0000',16),
static=False)
gs.add_objects([P], color=int('0000FF00',16),
static=False)
render_cef_script(str(gs), scale=0.1)
Rotors in CGA perform
conformal transformations
Rotation
Translation
Dilation
Inversion
# Import Conformal GA (4,1)
from clifford.g3c import *
# Import prebuilt tools for conformal GA
from clifford.tools.g3c import *
# Import pyganja for visualisation
from pyganja import *
# Create a random circle
X1 = random_circle()
# Create a random rigid rotor
R_TR = random_rotation_translation_rotor(maximum_translation=0.25,
maximum_angle=np.pi/16)
# Create a dilation rotor
R_d = generate_dilation_rotor(0.9)
# Combine the rotors
R = R_TR*R_d
# Apply the rotor taken to successively higher powers to create a list of circles
circle_list = [ (R**i) * X1 * ~(R**i) for i in range(20) ]
# Draw the list of circles
draw(circle_list, static=False , scale=0.1)
from clifford.tools.g3c import *
from clifford.tools.g3c.rotor_parameterisation import *
from pyganja import *
# Create two objects
X1 = random_circle()
X2 = random_circle()
# Find the rotor between them
R = rotor_between_objects(X1, X2)
# Take the log of the rotor
logR = general_logarithm(R)
# Blend from 0 to 1
rotor_list = [general_exp(0.1*alpha*logR)
for alpha in range(10)]
# Apply the interpolated rotors
object_list = [R_int*X1*~R_int
for R_int in rotor_list]
# The simplest way to use pyganja
draw(object_list ,
static=False ,
scale=0.1)
This allows us to acheive complex tasks like splining and clustering
from clifford.g3c import *
from clifford.tools.g3c import *
from clifford.tools.g3c.object_clustering import *
from pyganja import *
# Set up parameters for clustering
object_generator = random_circle
n_clusters = 3
n_objects_per_cluster = 10
n_shotgunning = 60
# Generate the objects for clustering
all_objects, object_clusters = generate_n_clusters(object_generator,
n_clusters,
n_objects_per_cluster)
# Perform the k-means clustering
cluster_result = n_clusters_objects(n_clusters, all_objects,
initial_centroids=None,
n_shotgunning=n_shotgunning,
averaging_method='unweighted')
[new_labels, centroids, start_labels, start_centroids] = cluster_result
# Visualise the result
gs = GanjaScene()
gs.add_objects([all_objects[i] for i,l in enumerate(new_labels) if l==0],
static=False, color=int('00FF0000',16))
gs.add_objects([all_objects[i] for i,l in enumerate(new_labels) if l==1],
static=False, color=int('0000FF00',16))
gs.add_objects([all_objects[i] for i,l in enumerate(new_labels) if l==2],
static=False, color=int('000000FF',16))
# render_notebook_script(str(gs),scale=0.1)
# render_cef_script(str(gs),scale=0.1)
from clifford.g3c import *
from clifford.tools.g3c import *
from pyganja import *
# Make a load of lines in an MVArray
line_array = MVArray( generate_random_object_cluster(10, random_line) )
# Save the array as a .ga file
line_array.save('line_array.ga')
# We can also load .ga files
line_array_loaded = layout.load_ga_file('line_array.ga')
By Hugo Hadfield
A tutorial presentation on Conformal Geometric Algebra and the python clifford package for geometric algebra. Originally presented to faculty and students from Brno University of Technology and Masaryk University. The clifford python package can be found here: https://github.com/pygae/clifford
Cambridge University PhD student, Signal Processing and Communications Laboratory