clifford-codegen
Code generator for optimized geometric algebra types from algebra specifications.
Workflow Overview
Generating a new algebra involves three steps:
- Discover - Analyze an algebra signature to find valid grade combinations
- Customize - Edit the generated TOML template with proper names and options
- Generate - Produce optimized Rust code from the specification
Step 1: Discover Entities
Use the discover command to analyze an algebra signature and generate a TOML template:
# Signature format: "p,q,r" (positive, negative, zero basis vectors)
# For algebras without negative or zero bases, you can omit them
# Euclidean 3D: Cl(3,0,0)
# Projective GA 3D: Cl(3,0,1)
# Conformal GA 3D: Cl(4,1,0)
# Print to stdout instead of file
The discover command outputs:
# Auto-discovered entities for Cl(3,0,0)
# Generated by clifford-codegen discover
#
# Review and customize:
# - Rename placeholder entities (Entity_*)
# - Add/remove types as needed
# - Customize descriptions
# - Configure constraints
[]
= "" # TODO: Fill in algebra name
= "" # TODO: Fill in module path
= "Cl(3,0,0)"
[]
= ["e1", "e2", "e3"]
= []
= []
# Discovered Types (6 entities satisfy geometric constraints)
[]
= [0]
[]
= [1]
[]
= [2]
[]
= [3]
[]
= [0, 2]
[]
= [1, 3]
Discovered Entities
The discover command finds the minimal closed set of geometric entities:
- Single-grade elements: Scalars, vectors, bivectors, etc.
- Even subalgebra: Grades 0, 2, 4, ... (rotors/motors live here)
- Odd subalgebra: Grades 1, 3, 5, ... (flectors/reflections)
Only grade combinations that satisfy the geometric constraint are included.
The geometric constraint requires that u * ũ (element times its reverse)
produces only a scalar.
Field Constraints
Some entities require field constraints for the geometric constraint to hold.
For example, PGA bivectors (lines) must satisfy e01*e23 + e02*e31 + e03*e12 = 0
for their direction and moment to be orthogonal.
When a constraint is needed, it appears in the TOML:
[]
= [2]
= "e01*e23 + e02*e31 + e03*e12 = 0"
Step 2: Customize the TOML
Edit the generated TOML to add meaningful names and configure options:
1. Fill in Algebra Metadata
[]
= "euclidean3" # Used for module naming
= "euclidean::dim3" # Rust module path
= "3D Euclidean Geometric Algebra"
2. Rename Entity Types
Replace placeholder names with meaningful geometric names:
# Before
[]
= [0]
[]
= [1]
[]
= [0, 2]
# After
[]
= [0]
= "Grade-0 scalar"
[]
= [1]
= "Grade-1 vector"
[]
= [0, 2]
= "3D rotation element"
3. Add Field Names
Map blade names to semantic field names for better ergonomics:
[]
= "x"
= "y"
= "z"
= "xy"
= "xz"
= "yz"
= "xyz"
[]
= [1]
= ["x", "y", "z"] # Uses blade mappings
4. Add Constraints
Define unit and nonzero constraints for types that need them:
[]
= [1]
= ["x", "y", "z"]
[]
# Generates UnitVector wrapper type
[]
# Generates NonZeroVector wrapper type
[]
= [0, 2]
= ["s", "xy", "xz", "yz"]
[]
# Generates UnitRotor wrapper type
5. Define Products
Specify which products to generate and their result types:
[]
= "Rotor"
= "Rotor"
= "UnitRotor"
[]
= "Bivector"
= "Trivector"
[]
= "T" # Returns the scalar type parameter
Step 3: Generate Rust Code
Use the generate command to produce Rust code from your specification:
# Generate to the clifford crate's src directory
# Preview what would be generated
# Overwrite existing files
# With verbose output
Generated Files
The generator creates a Rust module with:
my_algebra/
├── mod.rs # Module re-exports and allow attributes
├── types.rs # Type definitions (Vector, Bivector, Rotor, etc.)
├── products.rs # Product implementations (geometric, outer, inner)
├── traits.rs # Standard trait impls (Debug, Clone, PartialEq, ops)
└── conversions.rs # Multivector conversions
Integrating Generated Code
The generated code is designed to be used inside the clifford crate. It uses
crate:: imports for the Float trait, Multivector, Blade, and signatures.
To integrate generated code:
-
Generate into a subdirectory under
src/: -
Add the module to
src/lib.rs: -
Build and test:
Complete Example: Creating a 2D Euclidean Algebra
# 1. Discover entities
# 2. Edit the TOML (see example below)
# 3. Generate code into the clifford crate
# 4. Add module to lib.rs and test
Example customized euclidean2.toml:
[]
= "euclidean2"
= "euclidean::dim2"
= "2D Euclidean Geometric Algebra"
[]
= ["e1", "e2"]
[]
= "x"
= "y"
= "xy"
[]
= [0]
= "Grade-0 scalar"
= ["s"]
[]
= [1]
= "Grade-1 vector"
= ["x", "y"]
[]
[]
[]
= [2]
= "Grade-2 pseudoscalar"
= ["xy"]
[]
= [0, 2]
= "2D rotation element"
= ["s", "xy"]
[]
[]
= "Rotor"
= "Rotor"
= "UnitRotor"
[]
= "Bivector"
[]
= "T"
Other Commands
List Blades
List Products
Verify Generated Code
Common Algebras
| Algebra | Signature | Command |
|---|---|---|
| Euclidean 2D | Cl(2,0,0) | discover "2,0,0" |
| Euclidean 3D | Cl(3,0,0) | discover "3,0,0" |
| PGA 2D | Cl(2,0,1) | discover "2,0,1" |
| PGA 3D | Cl(3,0,1) | discover "3,0,1" |
| CGA 2D | Cl(3,1,0) | discover "3,1,0" |
| CGA 3D | Cl(4,1,0) | discover "4,1,0" |
| Spacetime | Cl(1,3,0) | discover "1,3,0" |