Skip to content

Commit

Permalink
exomorphism antispace mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
ickk committed May 28, 2024
1 parent f16355e commit 5c8059d
Show file tree
Hide file tree
Showing 3 changed files with 357 additions and 4 deletions.
342 changes: 342 additions & 0 deletions rga/src/exomorphisms/matrix4x4/antimorph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,342 @@
use {
super::*,
crate::{exomorphisms::Antiexomorphism, helpers::return_empty, values::*},
};

macro_rules! impl_antiexomorphism {
($($antimorph:ty, $arg:ty => $ret:ty: $antimorph_fn:ident;)*) => {
$(impl Antiexomorphism<$arg> for $antimorph {
#[inline]
fn antimorph(self, arg: $arg) -> $ret {
$antimorph_fn(self, arg)
}
})*
};
}

impl_antiexomorphism! {
Matrix4x4, Scalar => Scalar: antimorph_scalar;
Matrix4x4, Vector => Vector: antimorph_vector;
Matrix4x4, Bivector => Bivector: antimorph_bivector;
Matrix4x4, Trivector => Trivector: antimorph_trivector;
Matrix4x4, Antiscalar => Antiscalar: antimorph_antiscalar;
Matrix4x4, Multivector => Multivector: antimorph_multivector;
Matrix4x4, DualNumber => DualNumber: antimorph_dual_number;
Matrix4x4, OddGrade => OddGrade: antimorph_odd_grade;
Matrix4x4, EvenGrade => EvenGrade: antimorph_even_grade;
Matrix4x4, Empty => Empty: return_empty;
}

#[inline]
fn antimorph_scalar(matrix: Matrix4x4, Scalar { s }: Scalar) -> Scalar {
let antiscalar_dual = Antiscalar { e1234: s };
let Antiscalar { e1234 } = morph_antiscalar(matrix, antiscalar_dual);
Scalar { s: e1234 }
}
#[rustfmt::skip]
#[inline]
fn antimorph_vector(
matrix: Matrix4x4,
Vector { e1, e2, e3, e4 }: Vector,
) -> Vector {
let trivector_dual = Trivector {
e423: e1, e431: e2, e412: e3, e321: e4,
};
let Trivector { e423, e431, e412, e321 }
= morph_trivector(matrix, trivector_dual);
Vector { e1: e423, e2: e431, e3: e412, e4: e321 }
}
#[rustfmt::skip]
#[inline]
fn antimorph_bivector(
matrix: Matrix4x4,
Bivector {
e41: b41, e42: b42, e43: b43,
e23: b23, e31: b31, e12: b12,
}: Bivector
) -> Bivector {
let bivector_dual = Bivector {
e41: b23, e42: b31, e43: b12,
e23: b41, e31: b42, e12: b43,
};
let Bivector {
e41: m41, e42: m42, e43: m43,
e23: m23, e31: m31, e12: m12,
} = morph_bivector(matrix, bivector_dual);
Bivector {
e41: m23, e42: m31, e43: m12,
e23: m41, e31: m42, e12: m43,
}
}
#[rustfmt::skip]
#[inline]
fn antimorph_trivector(
matrix: Matrix4x4,
Trivector { e423, e431, e412, e321 }: Trivector
) -> Trivector {
let vector_dual = Vector {
e1: e423, e2: e431, e3: e412, e4: e321,
};
let Vector { e1, e2, e3, e4 }
= morph_vector(matrix, vector_dual);
Trivector { e423: e1, e431: e2, e412: e3, e321: e4 }
}
#[inline]
fn antimorph_antiscalar(_: Matrix4x4, antiscalar: Antiscalar) -> Antiscalar {
antiscalar
}
#[rustfmt::skip]
#[inline]
fn antimorph_multivector(
matrix: Matrix4x4,
Multivector {
s,
e1, e2, e3, e4,
e41, e42, e43, e23, e31, e12,
e423, e431, e412, e321,
e1234,
}: Multivector,
) -> Multivector {

let Scalar { s } = antimorph_scalar(
matrix, Scalar { s }
);
let Vector { e1, e2, e3, e4 } = antimorph_vector(
matrix, Vector { e1, e2, e3, e4 }
);
let Bivector { e41, e42, e43, e23, e31, e12 } = antimorph_bivector(
matrix, Bivector { e41, e42, e43, e23, e31, e12 },
);
let Trivector { e423, e431, e412, e321 } = antimorph_trivector(
matrix, Trivector { e423, e431, e412, e321 }
);
let Antiscalar { e1234 } = antimorph_antiscalar(
matrix, Antiscalar { e1234 }
);
Multivector {
s,
e1, e2, e3, e4,
e41, e42, e43, e23, e31, e12,
e423, e431, e412, e321,
e1234,
}
}
#[rustfmt::skip]
#[inline]
fn antimorph_dual_number(
matrix: Matrix4x4,
DualNumber { s, e1234 }: DualNumber,
) -> DualNumber {
let Scalar { s } = antimorph_scalar(matrix, Scalar { s });
let Antiscalar { e1234 } = antimorph_antiscalar(matrix, Antiscalar { e1234 });
DualNumber { s, e1234 }
}
#[rustfmt::skip]
#[inline]
fn antimorph_odd_grade(
matrix: Matrix4x4,
OddGrade {
e1, e2, e3, e4,
e423, e431, e412, e321,
}: OddGrade,
) -> OddGrade {
let Vector { e1, e2, e3, e4 } = antimorph_vector(
matrix, Vector { e1, e2, e3, e4 }
);
let Trivector { e423, e431, e412, e321 } = antimorph_trivector(
matrix, Trivector { e423, e431, e412, e321 }
);
OddGrade {
e1, e2, e3, e4,
e423, e431, e412, e321,
}
}
#[rustfmt::skip]
#[inline]
fn antimorph_even_grade(
matrix: Matrix4x4,
EvenGrade {
s,
e41, e42, e43, e23, e31, e12,
e1234,
}: EvenGrade,
) -> EvenGrade {
let Scalar { s } = antimorph_scalar(
matrix, Scalar { s }
);
let Bivector { e41, e42, e43, e23, e31, e12 } = antimorph_bivector(
matrix, Bivector { e41, e42, e43, e23, e31, e12 },
);
let Antiscalar { e1234 } = antimorph_antiscalar(
matrix, Antiscalar { e1234 }
);
EvenGrade {
s,
e41, e42, e43, e23, e31, e12,
e1234,
}
}

#[cfg(any(test, doctest))]
mod tests {
use {
super::*,
crate::{free_functions::*, test_values::*},
};

#[rustfmt::skip]
pub const MATRIX_A: Matrix4x4 = Matrix4x4 {
m11: 2., m12: 3., m13: 5., m14: 7.,
m21: 11., m22: 13., m23: 17., m24: 19.,
m31: 23., m32: 29., m33: 31., m34: 37.,
m41: 41., m42: 43., m43: 47., m44: 53.,
};

mod vector {
use super::*;

#[test]
fn matrix_a_antimorph() {
let bivector = grade_2(MULTIVECTOR_A);
let trivector = grade_3(MULTIVECTOR_B);

assert_eq!(
antiwedge_product(
MATRIX_A.antimorph(bivector),
MATRIX_A.antimorph(trivector)
),
MATRIX_A.antimorph(antiwedge_product(bivector, trivector,)),
);

assert_eq!(
left_complement(wedge_product(
right_complement(MATRIX_A.antimorph(bivector)),
right_complement(MATRIX_A.antimorph(trivector))
)),
antiwedge_product(
MATRIX_A.antimorph(bivector),
MATRIX_A.antimorph(trivector)
),
);
}
}

mod scalar {
use super::*;

#[test]
fn matrix_a_antimorph() {
let trivector = grade_2(MULTIVECTOR_A);
let bivector = grade_2(MULTIVECTOR_B);

assert_eq!(
antiwedge_product(
MATRIX_A.antimorph(bivector),
MATRIX_A.antimorph(trivector)
),
MATRIX_A.antimorph(antiwedge_product(bivector, trivector,)),
);

assert_eq!(
left_complement(wedge_product(
right_complement(MATRIX_A.antimorph(bivector)),
right_complement(MATRIX_A.antimorph(trivector))
)),
antiwedge_product(
MATRIX_A.antimorph(bivector),
MATRIX_A.antimorph(trivector)
),
);
}
}

mod bivector {
use super::*;

#[test]
fn matrix_a_antimorph() {
let trivector_a = grade_3(MULTIVECTOR_A);
let trivector_b = grade_3(MULTIVECTOR_B);

assert_eq!(
antiwedge_product(
MATRIX_A.antimorph(trivector_a),
MATRIX_A.antimorph(trivector_b)
),
MATRIX_A.antimorph(antiwedge_product(trivector_a, trivector_b)),
);

assert_eq!(
left_complement(wedge_product(
right_complement(MATRIX_A.antimorph(trivector_a)),
right_complement(MATRIX_A.antimorph(trivector_b))
)),
antiwedge_product(
MATRIX_A.antimorph(trivector_a),
MATRIX_A.antimorph(trivector_b)
),
);
}
}

mod trivector {
use super::*;

#[rustfmt::skip]
#[test]
fn antimorph_morph_equivalence() {
let vector = grade_1(MULTIVECTOR_A);
let trivector = Trivector {
e423: vector.e1, e431: vector.e2, e412: vector.e3, e321: vector.e4,
};

let vector_morph = MATRIX_A.morph(vector);
let trivector_antimorph = MATRIX_A.antimorph(trivector);

assert_eq!(
vector_morph.e1,
trivector_antimorph.e423,
);
assert_eq!(
vector_morph.e2,
trivector_antimorph.e431,
);
assert_eq!(
vector_morph.e3,
trivector_antimorph.e412,
);
assert_eq!(
vector_morph.e4,
trivector_antimorph.e321,
);
}
}

mod antiscalar {
use super::*;

#[test]
fn matrix_a_antimorph() {
let antiscalar = grade_4(MULTIVECTOR_A);

assert_eq!(MATRIX_A.antimorph(antiscalar), antiscalar);
}
}

mod multivector {
use super::*;

#[test]
fn matrix_a_antimorph() {
assert_eq!(
dbg!(antiwedge_product(
MATRIX_A.antimorph(MULTIVECTOR_A),
MATRIX_A.antimorph(MULTIVECTOR_B),
)),
dbg!(
MATRIX_A.antimorph(antiwedge_product(MULTIVECTOR_A, MULTIVECTOR_B))
)
);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use {
super::Exomorphism,
crate::{helpers::*, values::*, F},
};
mod antimorph;

use crate::{exomorphisms::Exomorphism, helpers::return_empty, values::*, F};

/// A matrix whose column vectors have basis `[e1, e2, e3, e4]`
///
Expand Down Expand Up @@ -48,6 +47,7 @@ impl Zero for Matrix4x4 {
macro_rules! impl_exomorphism {
($($morph:ty, $arg:ty => $ret:ty: $morph_fn:ident;)*) => {
$(impl Exomorphism<$arg> for $morph {
#[inline]
fn morph(self, arg: $arg) -> $ret {
$morph_fn(self, arg)
}
Expand Down
11 changes: 11 additions & 0 deletions rga/src/exomorphisms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ mod matrix4x4;
pub use matrix4x4::Matrix4x4;

/// A linear mapping extended to multivectors
///
/// Distributes over the wedge product.
pub trait Exomorphism<Arg> {
fn morph(self, arg: Arg) -> Arg;
}

/// A linear mapping that maps the antispace elements
///
/// i.e. Transforms Trivectors as if they are Vectors.
///
/// Distributes over the antiwedge product.
pub trait Antiexomorphism<Arg> {
fn antimorph(self, arg: Arg) -> Arg;
}

0 comments on commit 5c8059d

Please sign in to comment.