pub struct Algebra { /* private fields */ }Expand description
A geometric algebra defined by its metric signature.
The algebra encapsulates:
- The metric for each basis vector (can be +1, -1, or 0)
- Optional custom names for basis vectors and blades
§Metric Flexibility
Unlike the traditional (p, q, r) signature notation which assumes a fixed ordering (positive bases first, then negative, then degenerate), this struct supports arbitrary metric assignments per basis vector. This allows algebras like Minkowski spacetime to use physics conventions (e.g., e1=space with -1, e2=time with +1) without being constrained by positional ordering.
§Example
use clifford_codegen::algebra::Algebra;
// Create a 3D Euclidean algebra
let alg = Algebra::euclidean(3);
assert_eq!(alg.dim(), 3);
assert_eq!(alg.num_blades(), 8);
// Metric: all basis vectors square to +1
assert_eq!(alg.metric(0), 1);
assert_eq!(alg.metric(1), 1);
assert_eq!(alg.metric(2), 1);
// Create Minkowski with arbitrary metric assignment
let minkowski = Algebra::from_metrics(vec![-1, 1]); // e1²=-1 (space), e2²=+1 (time)
assert_eq!(minkowski.metric(0), -1);
assert_eq!(minkowski.metric(1), 1);Implementations§
Source§impl Algebra
impl Algebra
Sourcepub fn new(p: usize, q: usize, r: usize) -> Self
pub fn new(p: usize, q: usize, r: usize) -> Self
Creates a new algebra with signature (p, q, r).
Basis vectors are ordered: first p positive, then q negative, then r null.
For arbitrary metric assignments, use from_metrics.
§Example
use clifford_codegen::algebra::Algebra;
// PGA: 3 Euclidean + 1 degenerate
let pga = Algebra::new(3, 0, 1);
assert_eq!(pga.dim(), 4);
assert_eq!(pga.metric(0), 1); // e1 squares to +1
assert_eq!(pga.metric(3), 0); // e4 squares to 0Sourcepub fn from_metrics(metrics: Vec<i8>) -> Self
pub fn from_metrics(metrics: Vec<i8>) -> Self
Creates a new algebra from explicit per-basis metric values.
This allows arbitrary metric assignments without positional constraints. Each element in the vector specifies the metric for the corresponding basis vector: +1 (positive), -1 (negative), or 0 (degenerate).
§Example
use clifford_codegen::algebra::Algebra;
// Minkowski with physics convention: e1=space(-1), e2=time(+1)
let minkowski = Algebra::from_metrics(vec![-1, 1]);
assert_eq!(minkowski.dim(), 2);
assert_eq!(minkowski.metric(0), -1); // e1 squares to -1
assert_eq!(minkowski.metric(1), 1); // e2 squares to +1
assert_eq!(minkowski.signature(), (1, 1, 0)); // still reports (p,q,r)Sourcepub fn degenerate_indices(&self) -> impl Iterator<Item = usize> + '_
pub fn degenerate_indices(&self) -> impl Iterator<Item = usize> + '_
Returns the indices of degenerate (metric=0) basis vectors.
This is useful for PGA calculations that need to identify the projective basis vectors regardless of their position.
§Example
use clifford_codegen::algebra::Algebra;
// PGA with e0 as degenerate
let pga = Algebra::from_metrics(vec![0, 1, 1, 1]);
let degenerate: Vec<_> = pga.degenerate_indices().collect();
assert_eq!(degenerate, vec![0]);Sourcepub fn euclidean(n: usize) -> Self
pub fn euclidean(n: usize) -> Self
Creates a Euclidean algebra of dimension n.
All basis vectors square to +1.
§Example
use clifford_codegen::algebra::Algebra;
let e3 = Algebra::euclidean(3);
assert_eq!(e3.signature(), (3, 0, 0));Sourcepub fn pga(n: usize) -> Self
pub fn pga(n: usize) -> Self
Creates a Projective Geometric Algebra for n-dimensional space.
PGA(n) has signature (n, 0, 1) where the extra degenerate basis represents the point at infinity.
§Example
use clifford_codegen::algebra::Algebra;
let pga3 = Algebra::pga(3);
assert_eq!(pga3.dim(), 4);
assert_eq!(pga3.signature(), (3, 0, 1));Sourcepub fn cga(n: usize) -> Self
pub fn cga(n: usize) -> Self
Creates a Conformal Geometric Algebra for n-dimensional space.
CGA(n) has signature (n+1, 1, 0), adding two extra basis vectors e₊ (positive) and e₋ (negative) for the conformal model.
§Example
use clifford_codegen::algebra::Algebra;
let cga3 = Algebra::cga(3);
assert_eq!(cga3.dim(), 5);
assert_eq!(cga3.signature(), (4, 1, 0));Sourcepub fn minkowski(n: usize) -> Self
pub fn minkowski(n: usize) -> Self
Creates a Minkowski algebra with n spatial dimensions.
Minkowski(n) has signature (n, 1, 0), with n spatial dimensions and 1 time-like dimension (squares to -1).
§Example
use clifford_codegen::algebra::Algebra;
let minkowski = Algebra::minkowski(3);
assert_eq!(minkowski.dim(), 4);
assert_eq!(minkowski.signature(), (3, 1, 0));Sourcepub fn signature(&self) -> (usize, usize, usize)
pub fn signature(&self) -> (usize, usize, usize)
Returns the signature (p, q, r) by counting metric values.
Note: This counts the actual metrics, so it works correctly even
for algebras created with from_metrics where
positive/negative/zero bases may be interleaved.
Sourcepub fn num_blades(&self) -> usize
pub fn num_blades(&self) -> usize
Returns the total number of blades (2^dim).
Sourcepub fn metric(&self, i: usize) -> i8
pub fn metric(&self, i: usize) -> i8
Returns the metric value for basis vector i.
Returns the metric for the i-th basis vector:
+1for positive (Euclidean) bases-1for negative (anti-Euclidean/Minkowski) bases0for degenerate (null/projective) bases
§Example
use clifford_codegen::algebra::Algebra;
// Standard (p,q,r) ordering
let cga = Algebra::cga(3); // signature (4, 1, 0)
assert_eq!(cga.metric(0), 1); // e1 (positive)
assert_eq!(cga.metric(3), 1); // e+ (positive)
assert_eq!(cga.metric(4), -1); // e- (negative)
// Arbitrary metric assignment
let minkowski = Algebra::from_metrics(vec![-1, 1]);
assert_eq!(minkowski.metric(0), -1); // e1 (negative/spacelike)
assert_eq!(minkowski.metric(1), 1); // e2 (positive/timelike)Sourcepub fn basis_product(&self, a: usize, b: usize) -> (i8, usize)
pub fn basis_product(&self, a: usize, b: usize) -> (i8, usize)
Computes the product of two basis blades.
§Returns
A tuple (sign, result) where sign ∈ {-1, 0, +1} and result
is the blade index of the product.
§Example
use clifford_codegen::algebra::Algebra;
let alg = Algebra::euclidean(3);
// e1 * e2 = e12
let (sign, result) = alg.basis_product(0b001, 0b010);
assert_eq!(sign, 1);
assert_eq!(result, 0b011);
// e2 * e1 = -e12
let (sign, result) = alg.basis_product(0b010, 0b001);
assert_eq!(sign, -1);
assert_eq!(result, 0b011);Sourcepub fn blades_of_grade(&self, grade: usize) -> Vec<Blade>
pub fn blades_of_grade(&self, grade: usize) -> Vec<Blade>
Returns all blades of a given grade.
§Example
use clifford_codegen::algebra::Algebra;
let alg = Algebra::euclidean(3);
let bivectors = alg.blades_of_grade(2);
assert_eq!(bivectors.len(), 3);
assert_eq!(bivectors[0].index(), 0b011); // e12
assert_eq!(bivectors[1].index(), 0b101); // e13
assert_eq!(bivectors[2].index(), 0b110); // e23Sourcepub fn all_blades(&self) -> Vec<Blade>
pub fn all_blades(&self) -> Vec<Blade>
Returns all blades in the algebra.
Blades are returned in index order (canonical ordering).
Sourcepub fn set_basis_name(&mut self, i: usize, name: String)
pub fn set_basis_name(&mut self, i: usize, name: String)
Sets a custom name for a basis vector.
§Arguments
i- The basis vector index (0-based)name- The custom name
§Example
use clifford_codegen::algebra::Algebra;
let mut alg = Algebra::euclidean(3);
alg.set_basis_name(0, "x".to_string());
alg.set_basis_name(1, "y".to_string());
alg.set_basis_name(2, "z".to_string());
assert_eq!(alg.basis_name(0), "x");
assert_eq!(alg.basis_name(1), "y");
assert_eq!(alg.basis_name(2), "z");Sourcepub fn basis_name(&self, i: usize) -> &str
pub fn basis_name(&self, i: usize) -> &str
Returns the name of a basis vector.
Sourcepub fn set_blade_name(&mut self, blade: Blade, name: String)
pub fn set_blade_name(&mut self, blade: Blade, name: String)
Sets a custom name for a blade.
§Example
use clifford_codegen::algebra::{Algebra, Blade};
let mut alg = Algebra::euclidean(3);
alg.set_blade_name(Blade::from_index(0b011), "xy".to_string());
assert_eq!(alg.blade_name(Blade::from_index(0b011)), "xy");Sourcepub fn blade_name(&self, blade: Blade) -> String
pub fn blade_name(&self, blade: Blade) -> String
Returns the name for a blade.
If a custom name was set, returns that. Otherwise, builds the name from basis vector names.
§Example
use clifford_codegen::algebra::{Algebra, Blade};
let alg = Algebra::euclidean(3);
// Default names
assert_eq!(alg.blade_name(Blade::scalar()), "s");
assert_eq!(alg.blade_name(Blade::basis(0)), "e1");
assert_eq!(alg.blade_name(Blade::from_index(0b011)), "e1e2");Sourcepub fn blade_index_name(&self, blade: Blade) -> String
pub fn blade_index_name(&self, blade: Blade) -> String
Returns the canonical index-based name for a blade.
This produces names compatible with the TOML parser format:
- Scalar: “s” (but scalars shouldn’t be in blades section)
- Basis vectors: “e1”, “e2”, etc. (1-indexed)
- Higher blades: “e12”, “e123”, etc.
§Example
use clifford_codegen::algebra::{Algebra, Blade};
let alg = Algebra::euclidean(3);
assert_eq!(alg.blade_index_name(Blade::basis(0)), "e1");
assert_eq!(alg.blade_index_name(Blade::basis(1)), "e2");
assert_eq!(alg.blade_index_name(Blade::from_index(0b011)), "e12");
assert_eq!(alg.blade_index_name(Blade::from_index(0b111)), "e123");Trait Implementations§
Auto Trait Implementations§
impl Freeze for Algebra
impl RefUnwindSafe for Algebra
impl Send for Algebra
impl Sync for Algebra
impl Unpin for Algebra
impl UnwindSafe for Algebra
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
Source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
Source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
Source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more