diff --git a/rga/src/operators/antireverse.rs b/rga/src/operators/antireverse.rs index 5a99d2e..ebb6371 100644 --- a/rga/src/operators/antireverse.rs +++ b/rga/src/operators/antireverse.rs @@ -166,11 +166,11 @@ mod tests { ); assert_eq!( - dbg!(left_weight_dual(MULTIVECTOR_A)), - dbg!(geometric_antiproduct( + left_weight_dual(MULTIVECTOR_A), + geometric_antiproduct( Multivector { s: 1., ..zero() }, antireverse(MULTIVECTOR_A) - )) + ) ); } diff --git a/rga/src/operators/antisupport.rs b/rga/src/operators/antisupport.rs index f3753e7..dd81dd9 100644 --- a/rga/src/operators/antisupport.rs +++ b/rga/src/operators/antisupport.rs @@ -102,8 +102,8 @@ mod tests { #[test] fn definition() { assert_eq!( - dbg!(antisupport(MULTIVECTOR_A)), - dbg!(central_antiprojection(Multivector::E4, MULTIVECTOR_A)) + antisupport(MULTIVECTOR_A), + central_antiprojection(Multivector::E4, MULTIVECTOR_A) ); } diff --git a/rga/src/operators/antiwedge_product.rs b/rga/src/operators/antiwedge_product.rs index bae99f6..259fffe 100644 --- a/rga/src/operators/antiwedge_product.rs +++ b/rga/src/operators/antiwedge_product.rs @@ -2776,11 +2776,11 @@ mod tests { )) ); assert_eq!( - dbg!(Multivector::from(antiwedge_product(even_grade, trivector))), - dbg!(Multivector::from(antiwedge_product( + Multivector::from(antiwedge_product(even_grade, trivector)), + Multivector::from(antiwedge_product( Multivector::from(even_grade), Multivector::from(trivector) - ))) + )) ); assert_eq!( Multivector::from(antiwedge_product(even_grade, antiscalar)), diff --git a/rga/src/operators/bulk_contraction.rs b/rga/src/operators/bulk_contraction.rs index de4ad3b..15ec0d8 100644 --- a/rga/src/operators/bulk_contraction.rs +++ b/rga/src/operators/bulk_contraction.rs @@ -1864,8 +1864,8 @@ mod tests { #[test] fn definition() { assert_eq!( - dbg!(bulk_contraction(MULTIVECTOR_A, MULTIVECTOR_B)), - dbg!(antiwedge_product(MULTIVECTOR_A, bulk_dual(MULTIVECTOR_B))) + bulk_contraction(MULTIVECTOR_A, MULTIVECTOR_B), + antiwedge_product(MULTIVECTOR_A, bulk_dual(MULTIVECTOR_B)) ); } @@ -2495,11 +2495,11 @@ mod tests { )) ); assert_eq!( - dbg!(Multivector::from(bulk_contraction(even_grade, trivector))), - dbg!(Multivector::from(bulk_contraction( + Multivector::from(bulk_contraction(even_grade, trivector)), + Multivector::from(bulk_contraction( Multivector::from(even_grade), Multivector::from(trivector) - ))) + )) ); assert_eq!( Multivector::from(bulk_contraction(even_grade, antiscalar)), diff --git a/rga/src/operators/bulk_expansion.rs b/rga/src/operators/bulk_expansion.rs index 4f8c3d1..746022f 100644 --- a/rga/src/operators/bulk_expansion.rs +++ b/rga/src/operators/bulk_expansion.rs @@ -1298,8 +1298,8 @@ mod tests { #[test] fn definition() { assert_eq!( - dbg!(bulk_expansion(MULTIVECTOR_A, MULTIVECTOR_B)), - dbg!(wedge_product(MULTIVECTOR_A, bulk_dual(MULTIVECTOR_B))) + bulk_expansion(MULTIVECTOR_A, MULTIVECTOR_B), + wedge_product(MULTIVECTOR_A, bulk_dual(MULTIVECTOR_B)) ); } @@ -1915,11 +1915,11 @@ mod tests { )) ); assert_eq!( - dbg!(Multivector::from(bulk_expansion(even_grade, trivector))), - dbg!(Multivector::from(bulk_expansion( + Multivector::from(bulk_expansion(even_grade, trivector)), + Multivector::from(bulk_expansion( Multivector::from(even_grade), Multivector::from(trivector) - ))) + )) ); assert_eq!( Multivector::from(bulk_expansion(even_grade, antiscalar)), diff --git a/rga/src/operators/dot_product.rs b/rga/src/operators/dot_product.rs index 89233ac..c65e69e 100644 --- a/rga/src/operators/dot_product.rs +++ b/rga/src/operators/dot_product.rs @@ -704,11 +704,11 @@ mod tests { #[test] fn de_morgans_laws() { assert_eq!( - dbg!(antidot_product(MULTIVECTOR_A, MULTIVECTOR_B)), - dbg!(right_complement(dot_product( + antidot_product(MULTIVECTOR_A, MULTIVECTOR_B), + right_complement(dot_product( left_complement(MULTIVECTOR_A), left_complement(MULTIVECTOR_B) - ))) + )) ); } diff --git a/rga/src/operators/geometric_antiproduct.rs b/rga/src/operators/geometric_antiproduct.rs index f9c52cd..84effb7 100644 --- a/rga/src/operators/geometric_antiproduct.rs +++ b/rga/src/operators/geometric_antiproduct.rs @@ -3230,11 +3230,11 @@ mod tests { #[test] fn de_morgans_laws() { assert_eq!( - dbg!(geometric_antiproduct(MULTIVECTOR_A, MULTIVECTOR_B)), - dbg!(right_complement(geometric_product( + geometric_antiproduct(MULTIVECTOR_A, MULTIVECTOR_B), + right_complement(geometric_product( left_complement(MULTIVECTOR_A), left_complement(MULTIVECTOR_B) - ))) + )) ); assert_eq!( @@ -3858,13 +3858,13 @@ mod tests { )) ); assert_eq!( - dbg!(Multivector::from(geometric_antiproduct( + Multivector::from(geometric_antiproduct( even_grade, trivector - ))), - dbg!(Multivector::from(geometric_antiproduct( + )), + Multivector::from(geometric_antiproduct( Multivector::from(even_grade), Multivector::from(trivector) - ))) + )) ); assert_eq!( Multivector::from(geometric_antiproduct(even_grade, antiscalar)), diff --git a/rga/src/operators/geometric_product.rs b/rga/src/operators/geometric_product.rs index b08416d..ca3970d 100644 --- a/rga/src/operators/geometric_product.rs +++ b/rga/src/operators/geometric_product.rs @@ -3875,11 +3875,11 @@ mod tests { )) ); assert_eq!( - dbg!(Multivector::from(geometric_product(even_grade, trivector))), - dbg!(Multivector::from(geometric_product( + Multivector::from(geometric_product(even_grade, trivector)), + Multivector::from(geometric_product( Multivector::from(even_grade), Multivector::from(trivector) - ))) + )) ); assert_eq!( Multivector::from(geometric_product(even_grade, antiscalar)), diff --git a/rga/src/operators/reverse.rs b/rga/src/operators/reverse.rs index 3ac80b7..91880b4 100644 --- a/rga/src/operators/reverse.rs +++ b/rga/src/operators/reverse.rs @@ -176,11 +176,11 @@ mod tests { ); assert_eq!( - dbg!(left_bulk_dual(MULTIVECTOR_A)), - dbg!(geometric_product( + left_bulk_dual(MULTIVECTOR_A), + geometric_product( Multivector::E1234, reverse(MULTIVECTOR_A) - )) + ) ); } diff --git a/rga/src/operators/right_bulk_dual.rs b/rga/src/operators/right_bulk_dual.rs index c26961a..e378ba0 100644 --- a/rga/src/operators/right_bulk_dual.rs +++ b/rga/src/operators/right_bulk_dual.rs @@ -186,8 +186,8 @@ mod tests { #[test] fn definition() { assert_eq!( - dbg!(bulk_dual(MULTIVECTOR_A)), - dbg!(right_complement(bulk(MULTIVECTOR_A))), + bulk_dual(MULTIVECTOR_A), + right_complement(bulk(MULTIVECTOR_A)), "The Right Bulk Dual of an object is defined as the Right Complement of \ the Bulk of an object" ); diff --git a/rga/src/operators/support.rs b/rga/src/operators/support.rs index 93b579b..23b0392 100644 --- a/rga/src/operators/support.rs +++ b/rga/src/operators/support.rs @@ -54,8 +54,8 @@ mod tests { ); assert_eq!( - dbg!(support(MULTIVECTOR_A)), - dbg!(orthogonal_projection(Multivector::E4, MULTIVECTOR_A)) + support(MULTIVECTOR_A), + orthogonal_projection(Multivector::E4, MULTIVECTOR_A) ); } } diff --git a/rga/src/operators/wedge_product.rs b/rga/src/operators/wedge_product.rs index abfd506..6e38203 100644 --- a/rga/src/operators/wedge_product.rs +++ b/rga/src/operators/wedge_product.rs @@ -1,4 +1,4 @@ -use crate::values::*; +use crate::{return_empty, values::*}; // free function #[inline] @@ -33,8 +33,118 @@ macro_rules! impl_wedge_product { impl_wedge_product! { multivector_wedge_multivector: Multivector, Multivector => Multivector; + multivector_wedge_scalar: Multivector, Scalar => Multivector; + multivector_wedge_vector: Multivector, Vector => Multivector; + multivector_wedge_bivector: Multivector, Bivector => Multivector; + multivector_wedge_trivector: Multivector, Trivector => Multivector; + multivector_wedge_antiscalar: Multivector, Antiscalar => Antiscalar; + multivector_wedge_dual_number: Multivector, DualNumber => Multivector; + multivector_wedge_odd_grade: Multivector, OddGrade => Multivector; + multivector_wedge_even_grade: Multivector, EvenGrade => Multivector; + return_empty: Multivector, Empty => Empty; + + scalar_wedge_multivector: Scalar, Multivector => Multivector; + scalar_wedge_scalar: Scalar, Scalar => Scalar; + scalar_wedge_vector: Scalar, Vector => Vector; + scalar_wedge_bivector: Scalar, Bivector => Bivector; + scalar_wedge_trivector: Scalar, Trivector => Trivector; + scalar_wedge_antiscalar: Scalar, Antiscalar => Antiscalar; + scalar_wedge_dual_number: Scalar, DualNumber => DualNumber; + scalar_wedge_odd_grade: Scalar, OddGrade => OddGrade; + scalar_wedge_even_grade: Scalar, EvenGrade => EvenGrade; + return_empty: Scalar, Empty => Empty; + + vector_wedge_multivector: Vector, Multivector => Multivector; + vector_wedge_scalar: Vector, Scalar => Vector; + vector_wedge_vector: Vector, Vector => Bivector; + vector_wedge_bivector: Vector, Bivector => Trivector; + vector_wedge_trivector: Vector, Trivector => Antiscalar; + return_empty: Vector, Antiscalar => Empty; + vector_wedge_dual_number: Vector, DualNumber => Vector; + vector_wedge_odd_grade: Vector, OddGrade => EvenGrade; + vector_wedge_even_grade: Vector, EvenGrade => OddGrade; + return_empty: Vector, Empty => Empty; + + bivector_wedge_multivector: Bivector, Multivector => Multivector; + bivector_wedge_scalar: Bivector, Scalar => Bivector; + bivector_wedge_vector: Bivector, Vector => Trivector; + bivector_wedge_bivector: Bivector, Bivector => Antiscalar; + return_empty: Bivector, Trivector => Empty; + return_empty: Bivector, Antiscalar => Empty; + bivector_wedge_dual_number: Bivector, DualNumber => Bivector; + bivector_wedge_odd_grade: Bivector, OddGrade => Trivector; + bivector_wedge_even_grade: Bivector, EvenGrade => EvenGrade; + return_empty: Bivector, Empty => Empty; + + trivector_wedge_multivector: Trivector, Multivector => Multivector; + trivector_wedge_scalar: Trivector, Scalar => Trivector; + trivector_wedge_vector: Trivector, Vector => Antiscalar; + return_empty: Trivector, Bivector => Empty; + return_empty: Trivector, Trivector => Empty; + return_empty: Trivector, Antiscalar => Empty; + trivector_wedge_dual_number: Trivector, DualNumber => Trivector; + trivector_wedge_odd_grade: Trivector, OddGrade => Antiscalar; + trivector_wedge_even_grade: Trivector, EvenGrade => Trivector; + return_empty: Trivector, Empty => Empty; + + antiscalar_wedge_multivector: Antiscalar, Multivector => Antiscalar; + antiscalar_wedge_scalar: Antiscalar, Scalar => Antiscalar; + return_empty: Antiscalar, Vector => Empty; + return_empty: Antiscalar, Bivector => Empty; + return_empty: Antiscalar, Trivector => Empty; + return_empty: Antiscalar, Antiscalar => Empty; + antiscalar_wedge_dual_number: Antiscalar, DualNumber => Antiscalar; + return_empty: Antiscalar, OddGrade => Empty; + antiscalar_wedge_even_grade: Antiscalar, EvenGrade => Antiscalar; + return_empty: Antiscalar, Empty => Empty; + + dual_number_wedge_multivector: DualNumber, Multivector => Multivector; + dual_number_wedge_scalar: DualNumber, Scalar => DualNumber; + dual_number_wedge_vector: DualNumber, Vector => Vector; + dual_number_wedge_bivector: DualNumber, Bivector => Bivector; + dual_number_wedge_trivector: DualNumber, Trivector => Trivector; + dual_number_wedge_antiscalar: DualNumber, Antiscalar => Antiscalar; + dual_number_wedge_dual_number: DualNumber, DualNumber => DualNumber; + dual_number_wedge_odd_grade: DualNumber, OddGrade => OddGrade; + dual_number_wedge_even_grade: DualNumber, EvenGrade => EvenGrade; + return_empty: DualNumber, Empty => Empty; + + odd_grade_wedge_multivector: OddGrade, Multivector => Multivector; + odd_grade_wedge_scalar: OddGrade, Scalar => OddGrade; + odd_grade_wedge_vector: OddGrade, Vector => EvenGrade; + odd_grade_wedge_bivector: OddGrade, Bivector => Trivector; + odd_grade_wedge_trivector: OddGrade, Trivector => Antiscalar; + return_empty: OddGrade, Antiscalar => Empty; + odd_grade_wedge_dual_number: OddGrade, DualNumber => OddGrade; + odd_grade_wedge_odd_grade: OddGrade, OddGrade => EvenGrade; + odd_grade_wedge_even_grade: OddGrade, EvenGrade => OddGrade; + return_empty: OddGrade, Empty => Empty; + + even_grade_wedge_multivector: EvenGrade, Multivector => Multivector; + even_grade_wedge_scalar: EvenGrade, Scalar => EvenGrade; + even_grade_wedge_vector: EvenGrade, Vector => OddGrade; + even_grade_wedge_bivector: EvenGrade, Bivector => EvenGrade; + even_grade_wedge_trivector: EvenGrade, Trivector => Trivector; + even_grade_wedge_antiscalar: EvenGrade, Antiscalar => Antiscalar; + even_grade_wedge_dual_number: EvenGrade, DualNumber => EvenGrade; + even_grade_wedge_odd_grade: EvenGrade, OddGrade => OddGrade; + even_grade_wedge_even_grade: EvenGrade, EvenGrade => EvenGrade; + return_empty: EvenGrade, Empty => Empty; + + return_empty: Empty, Multivector => Empty; + return_empty: Empty, Scalar => Empty; + return_empty: Empty, Vector => Empty; + return_empty: Empty, Bivector => Empty; + return_empty: Empty, Trivector => Empty; + return_empty: Empty, Antiscalar => Empty; + return_empty: Empty, DualNumber => Empty; + return_empty: Empty, OddGrade => Empty; + return_empty: Empty, EvenGrade => Empty; + return_empty: Empty, Empty => Empty; } +// multivector + #[rustfmt::skip] #[inline] fn multivector_wedge_multivector( @@ -109,65 +219,2605 @@ fn multivector_wedge_multivector( } } -#[cfg(any(test, doctest))] -mod tests { - use crate::*; +#[rustfmt::skip] +#[inline] +fn multivector_wedge_scalar( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e423: l423, e431: l431, e412: l412, e321: l321, + e1234: l1234, + }: Multivector, + Scalar { s: rs }: Scalar, +) -> Multivector { - #[rustfmt::skip] - const A: Multivector = Multivector { - e1: 2., e2: 3., e3: 5., e4: 7., - ..Multivector::ZERO - }; - #[rustfmt::skip] - const B: Multivector = Multivector { - e1: -11., e2: -13., e3: -17., e4: -19., - ..Multivector::ZERO - }; - #[rustfmt::skip] - const C: Multivector = Multivector { - e1: -11., e2: -13., e3: -17., e4: -19., - ..Multivector::ZERO - }; + let s = ls*rs; - #[test] - fn vector_self_product() { - assert_eq!( - wedge_product(A, A), - zero(), - "The Wedge Product of any Vector with itself should be zero" - ); + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + let e1234 = l1234*rs; + + Multivector { + s, + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, } +} - #[test] - fn vector_product_anticommutivity() { - assert_eq!( - wedge_product(A, B), - -wedge_product(B, A), - "The Wedge Product of two Vectors anticommutes" - ); +#[rustfmt::skip] +#[inline] +fn multivector_wedge_vector( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e423: l423, e431: l431, e412: l412, e321: l321, + .. + }: Multivector, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> Multivector { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e423 = l23*r4 + + l42*r3 + - l43*r2; + let e431 = l31*r4 + + l43*r1 + - l41*r3; + let e412 = l12*r4 + + l41*r2 + - l42*r1; + let e321 = -l23*r1 + - l12*r3 + - l31*r2; + + let e1234 = -l321*r4 + - l423*r1 + - l431*r2 + - l412*r3; + + Multivector { + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + ..zero() } +} - #[test] - fn vector_product_associativity() { - assert_eq!( - wedge_product(A, wedge_product(B, C)), - wedge_product(wedge_product(A, B), C), - "The Wedge Product of two Vectors is associative" - ); +#[rustfmt::skip] +#[inline] +fn multivector_wedge_bivector( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + .. + }: Multivector, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> Multivector { + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + let e423 = l4*r23 + + l3*r42 + - l2*r43; + let e431 = l4*r31 + + l1*r43 + - l3*r41; + let e412 = l4*r12 + + l2*r41 + - l1*r42; + let e321 = -l1*r23 + - l3*r12 + - l2*r31; + + let e1234 = -(l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + Multivector { + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + ..zero() } +} - #[test] - fn vector_product_distributivity() { - assert_eq!( - wedge_product(A, B + C), - wedge_product(A, B) + wedge_product(A, C), - "The Wedge Product of two Vectors distributes over addition" - ); +#[rustfmt::skip] +#[inline] +fn multivector_wedge_trivector( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + .. + }: Multivector, + Trivector { e423: r423, e431: r431, e412: r412, e321: r321 }: Trivector, +) -> Multivector { - assert_eq!( - wedge_product(A + B, C), - wedge_product(A, C) + wedge_product(B, C), - "The Wedge Product of two Vectors distributes over addition" - ) + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + let e1234 = l4*r321 + + l1*r423 + + l2*r431 + + l3*r412; + + Multivector { + e423, e431, e412, e321, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn multivector_wedge_antiscalar( + Multivector { s: ls, .. }: Multivector, + Antiscalar { e1234: r1234 }: Antiscalar, +) -> Antiscalar { + + let e1234 = ls*r1234; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn multivector_wedge_dual_number( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e423: l423, e431: l431, e412: l412, e321: l321, + e1234: l1234, + }: Multivector, + DualNumber { s: rs, e1234: r1234 }: DualNumber, +) -> Multivector { + + let s = ls*rs; + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + let e1234 = ls*r1234 + l1234*rs; + + Multivector { + s, + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + } +} + +#[rustfmt::skip] +#[inline] +fn multivector_wedge_odd_grade( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e423: l423, e431: l431, e412: l412, e321: l321, + .. + }: Multivector, + OddGrade { + e1: r1, e2: r2, e3: r3, e4: r4, + e423: r423, e431: r431, e412: r412, e321: r321, + }: OddGrade, +) -> Multivector { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e423 = ls*r423 + + l23*r4 + + l42*r3 + - l43*r2; + let e431 = ls*r431 + + l31*r4 + + l43*r1 + - l41*r3; + let e412 = ls*r412 + + l12*r4 + + l41*r2 + - l42*r1; + let e321 = ls*r321 + - l23*r1 + - l12*r3 + - l31*r2; + + let e1234 = (l4*r321 - l321*r4) + + (l1*r423 - l423*r1) + + (l2*r431 - l431*r2) + + (l3*r412 - l412*r3); + + Multivector { + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn multivector_wedge_even_grade( + Multivector { + s: ls, + e1: l1, e2: l2, e3: l3, e4: l4, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e423: l423, e431: l431, e412: l412, e321: l321, + e1234: l1234, + }: Multivector, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e1234: r1234, + }: EvenGrade, +) -> Multivector { + + let s = ls*rs; + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e41 = ls*r41 + l41*rs; + let e42 = ls*r42 + l42*rs; + let e43 = ls*r43 + l43*rs; + let e23 = ls*r23 + l23*rs; + let e31 = ls*r31 + l31*rs; + let e12 = ls*r12 + l12*rs; + + let e423 = rs*l423 + + l4*r23 + + l3*r42 + - l2*r43; + let e431 = rs*l431 + + l4*r31 + + l1*r43 + - l3*r41; + let e412 = rs*l412 + + l4*r12 + + l2*r41 + - l1*r42; + let e321 = rs*l321 + - l1*r23 + - l3*r12 + - l2*r31; + + let e1234 = (ls*r1234 + l1234*rs) + - (l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + Multivector { + s, + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + } +} + +// scalar + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_multivector( + Scalar { s: ls }: Scalar, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e423: r423, e431: r431, e412: r412, e321: r321, + e1234: r1234, + }: Multivector, +) -> Multivector { + + let s = ls*rs; + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + let e1234 = ls*r1234; + + Multivector { + s, + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_scalar( + Scalar { s: ls }: Scalar, + Scalar { s: rs }: Scalar, +) -> Scalar { + + let s = ls*rs; + + Scalar { s } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_vector( + Scalar { s: ls }: Scalar, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> Vector { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + Vector { e1, e2, e3, e4 } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_bivector( + Scalar { s: ls }: Scalar, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> Bivector { + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + Bivector { e41, e42, e43, e23, e31, e12 } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_trivector( + Scalar { s: ls }: Scalar, + Trivector { e423: r423, e431: r431, e412: r412, e321: r321 }: Trivector, +) -> Trivector { + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_antiscalar( + Scalar { s: ls }: Scalar, + Antiscalar { e1234: r1234 }: Antiscalar, +) -> Antiscalar { + + let e1234 = ls*r1234; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_dual_number( + Scalar { s: ls }: Scalar, + DualNumber { s: rs, e1234: r1234 }: DualNumber, +) -> DualNumber { + + let s = ls*rs; + let e1234 = ls*r1234; + + DualNumber { s, e1234 } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_odd_grade( + Scalar { s: ls }: Scalar, + OddGrade { + e1: r1, e2: r2, e3: r3, e4: r4, + e423: r423, e431: r431, e412: r412, e321: r321, + }: OddGrade, +) -> OddGrade { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +#[rustfmt::skip] +#[inline] +fn scalar_wedge_even_grade( + Scalar { s: ls }: Scalar, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e1234: r1234, + }: EvenGrade, +) -> EvenGrade { + + let s = ls*rs; + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + let e1234 = ls*r1234; + + EvenGrade { + s, + e41, e42, e43, e23, e31, e12, + e1234, + } +} + +// vector + +#[rustfmt::skip] +#[inline] +fn vector_wedge_multivector( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e423: r423, e431: r431, e412: r412, e321: r321, + .. + }: Multivector, +) -> Multivector { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e423 = l4*r23 + + l3*r42 + - l2*r43; + let e431 = l4*r31 + + l1*r43 + - l3*r41; + let e412 = l4*r12 + + l2*r41 + - l1*r42; + let e321 = -l1*r23 + - l3*r12 + - l2*r31; + + let e1234 = l4*r321 + + l1*r423 + + l2*r431 + + l3*r412; + + Multivector { + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_scalar( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + Scalar { s: rs }: Scalar, +) -> Vector { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + Vector { e1, e2, e3, e4 } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_vector( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> Bivector { + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + Bivector { e41, e42, e43, e23, e31, e12 } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_bivector( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> Trivector { + + let e423 = l4*r23 + + l3*r42 + - l2*r43; + let e431 = l4*r31 + + l1*r43 + - l3*r41; + let e412 = l4*r12 + + l2*r41 + - l1*r42; + let e321 = -l1*r23 + - l3*r12 + - l2*r31; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_trivector( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + Trivector { e423: r423, e431: r431, e412: r412, e321: r321 }: Trivector, +) -> Antiscalar { + + let e1234 = l4*r321 + + l1*r423 + + l2*r431 + + l3*r412; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_dual_number( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + DualNumber { s: rs, .. }: DualNumber, +) -> Vector { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + Vector { e1, e2, e3, e4 } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_odd_grade( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + OddGrade { + e1: r1, e2: r2, e3: r3, e4: r4, + e423: r423, e431: r431, e412: r412, e321: r321, + }: OddGrade, +) -> EvenGrade { + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e1234 = l4*r321 + + l1*r423 + + l2*r431 + + l3*r412; + + EvenGrade { + e41, e42, e43, e23, e31, e12, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn vector_wedge_even_grade( + Vector { e1: l1, e2: l2, e3: l3, e4: l4 }: Vector, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + .. + }: EvenGrade, +) -> OddGrade { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e423 = l4*r23 + + l3*r42 + - l2*r43; + let e431 = l4*r31 + + l1*r43 + - l3*r41; + let e412 = l4*r12 + + l2*r41 + - l1*r42; + let e321 = -l1*r23 + - l3*r12 + - l2*r31; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + ..zero() + } +} + +// bivector + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_multivector( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + .. + }: Multivector, +) -> Multivector { + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + let e423 = l23*r4 + + l42*r3 + - l43*r2; + let e431 = l31*r4 + + l43*r1 + - l41*r3; + let e412 = l12*r4 + + l41*r2 + - l42*r1; + let e321 = -l23*r1 + - l12*r3 + - l31*r2; + + let e1234 = -(l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + Multivector { + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_scalar( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + Scalar { s: rs }: Scalar, +) -> Bivector { + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + Bivector { e41, e42, e43, e23, e31, e12 } +} + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_vector( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> Trivector { + + let e423 = l23*r4 + + l42*r3 + - l43*r2; + let e431 = l31*r4 + + l43*r1 + - l41*r3; + let e412 = l12*r4 + + l41*r2 + - l42*r1; + let e321 = -l23*r1 + - l12*r3 + - l31*r2; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_bivector( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> Antiscalar { + + let e1234 = -(l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_dual_number( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + DualNumber { s: rs, .. }: DualNumber, +) -> Bivector { + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + Bivector { e41, e42, e43, e23, e31, e12 } +} + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_odd_grade( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + OddGrade { e1: r1, e2: r2, e3: r3, e4: r4, .. }: OddGrade, +) -> Trivector { + + let e423 = l23*r4 + + l42*r3 + - l43*r2; + let e431 = l31*r4 + + l43*r1 + - l41*r3; + let e412 = l12*r4 + + l41*r2 + - l42*r1; + let e321 = -l23*r1 + - l12*r3 + - l31*r2; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn bivector_wedge_even_grade( + Bivector { + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + }: Bivector, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + .. + }: EvenGrade, +) -> EvenGrade { + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + let e1234 = -(l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + EvenGrade { + e41, e42, e43, e23, e31, e12, + e1234, + ..zero() + } +} + +// trivector + +#[rustfmt::skip] +#[inline] +fn trivector_wedge_multivector( + Trivector { e423: l423, e431: l431, e412: l412, e321: l321 }: Trivector, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + .. + }: Multivector, +) -> Multivector { + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + let e1234 = -l321*r4 + - l423*r1 + - l431*r2 + - l412*r3; + + Multivector { + e423, e431, e412, e321, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn trivector_wedge_scalar( + Trivector { e423: l423, e431: l431, e412: l412, e321: l321 }: Trivector, + Scalar { s: rs }: Scalar, +) -> Trivector { + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn trivector_wedge_vector( + Trivector { e423: l423, e431: l431, e412: l412, e321: l321 }: Trivector, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> Antiscalar { + + let e1234 = -l321*r4 + - l423*r1 + - l431*r2 + - l412*r3; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn trivector_wedge_dual_number( + Trivector { e423: l423, e431: l431, e412: l412, e321: l321 }: Trivector, + DualNumber { s: rs, .. }: DualNumber, +) -> Trivector { + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn trivector_wedge_odd_grade( + Trivector { e423: l423, e431: l431, e412: l412, e321: l321 }: Trivector, + OddGrade { e1: r1, e2: r2, e3: r3, e4: r4, .. }: OddGrade, +) -> Antiscalar { + + let e1234 = -l321*r4 + - l423*r1 + - l431*r2 + - l412*r3; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn trivector_wedge_even_grade( + Trivector { e423: l423, e431: l431, e412: l412, e321: l321 }: Trivector, + EvenGrade { s: rs, .. }: EvenGrade, +) -> Trivector { + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + Trivector { e423, e431, e412, e321 } +} + +// antiscalar + +#[rustfmt::skip] +#[inline] +fn antiscalar_wedge_multivector( + Antiscalar { e1234: l1234 }: Antiscalar, + Multivector { s: rs, .. }: Multivector, +) -> Antiscalar { + + let e1234 = l1234*rs; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn antiscalar_wedge_scalar( + Antiscalar { e1234: l1234 }: Antiscalar, + Scalar { s: rs }: Scalar, +) -> Antiscalar { + + let e1234 = l1234*rs; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn antiscalar_wedge_dual_number( + Antiscalar { e1234: l1234 }: Antiscalar, + DualNumber { s: rs, .. }: DualNumber, +) -> Antiscalar { + + let e1234 = l1234*rs; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn antiscalar_wedge_even_grade( + Antiscalar { e1234: l1234 }: Antiscalar, + EvenGrade { s: rs, .. }: EvenGrade, +) -> Antiscalar { + + let e1234 = l1234*rs; + + Antiscalar { e1234 } +} + +// dual number + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_multivector( + DualNumber { s: ls, e1234: l1234 }: DualNumber, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e423: r423, e431: r431, e412: r412, e321: r321, + e1234: r1234, + }: Multivector, +) -> Multivector { + + let s = ls*rs; + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + let e1234 = ls*r1234 + l1234*rs; + + Multivector { + s, + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_scalar( + DualNumber { s: ls, e1234: l1234 }: DualNumber, + Scalar { s: rs }: Scalar, +) -> DualNumber { + + let s = ls*rs; + let e1234 = l1234*rs; + + DualNumber { s, e1234 } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_vector( + DualNumber { s: ls, .. }: DualNumber, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> Vector { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + Vector { e1, e2, e3, e4 } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_bivector( + DualNumber { s: ls, .. }: DualNumber, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> Bivector { + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + Bivector { e41, e42, e43, e23, e31, e12 } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_trivector( + DualNumber { s: ls, .. }: DualNumber, + Trivector { e423: r423, e431: r431, e412: r412, e321: r321 }: Trivector, +) -> Trivector { + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_antiscalar( + DualNumber { s: ls, .. }: DualNumber, + Antiscalar { e1234: r1234 }: Antiscalar +) -> Antiscalar { + + let e1234 = ls*r1234; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_dual_number( + DualNumber { s: ls, e1234: l1234 }: DualNumber, + DualNumber { s: rs, e1234: r1234 }: DualNumber, +) -> DualNumber { + + let s = ls*rs; + let e1234 = ls*r1234 + l1234*rs; + + DualNumber { s, e1234 } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_odd_grade( + DualNumber { s: ls, .. }: DualNumber, + OddGrade { + e1: r1, e2: r2, e3: r3, e4: r4, + e423: r423, e431: r431, e412: r412, e321: r321, + }: OddGrade, +) -> OddGrade { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +#[rustfmt::skip] +#[inline] +fn dual_number_wedge_even_grade( + DualNumber { s: ls, e1234: l1234 }: DualNumber, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e1234: r1234, + }: EvenGrade, +) -> EvenGrade { + + let s = ls*rs; + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + let e1234 = ls*r1234 + l1234*rs; + + EvenGrade { + s, + e41, e42, e43, e23, e31, e12, + e1234, + } +} + +// odd grade + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_multivector( + OddGrade { + e1: l1, e2: l2, e3: l3, e4: l4, + e423: l423, e431: l431, e412: l412, e321: l321, + }: OddGrade, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e423: r423, e431: r431, e412: r412, e321: r321, + .. + }: Multivector, +) -> Multivector { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e423 = rs*l423 + + l4*r23 + + l3*r42 + - l2*r43; + let e431 = rs*l431 + + l4*r31 + + l1*r43 + - l3*r41; + let e412 = rs*l412 + + l4*r12 + + l2*r41 + - l1*r42; + let e321 = rs*l321 + - l1*r23 + - l3*r12 + - l2*r31; + + let e1234 = (l4*r321 - l321*r4) + + (l1*r423 - l423*r1) + + (l2*r431 - l431*r2) + + (l3*r412 - l412*r3); + + Multivector { + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_scalar( + OddGrade { + e1: l1, e2: l2, e3: l3, e4: l4, + e423: l423, e431: l431, e412: l412, e321: l321, + }: OddGrade, + Scalar { s: rs }: Scalar, +) -> OddGrade { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_vector( + OddGrade { + e1: l1, e2: l2, e3: l3, e4: l4, + e423: l423, e431: l431, e412: l412, e321: l321, + }: OddGrade, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> EvenGrade { + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e1234 = -l321*r4 + - l423*r1 + - l431*r2 + - l412*r3; + + EvenGrade { + e41, e42, e43, e23, e31, e12, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_bivector( + OddGrade { e1: l1, e2: l2, e3: l3, e4: l4, .. }: OddGrade, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> Trivector { + + let e423 = l4*r23 + + l3*r42 + - l2*r43; + let e431 = l4*r31 + + l1*r43 + - l3*r41; + let e412 = l4*r12 + + l2*r41 + - l1*r42; + let e321 = -l1*r23 + - l3*r12 + - l2*r31; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_trivector( + OddGrade { e1: l1, e2: l2, e3: l3, e4: l4, .. }: OddGrade, + Trivector { e423: r423, e431: r431, e412: r412, e321: r321 }: Trivector, +) -> Antiscalar { + + let e1234 = l4*r321 + + l1*r423 + + l2*r431 + + l3*r412; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_dual_number( + OddGrade { + e1: l1, e2: l2, e3: l3, e4: l4, + e423: l423, e431: l431, e412: l412, e321: l321, + }: OddGrade, + DualNumber { s: rs, .. }: DualNumber, +) -> OddGrade { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e423 = rs*l423; + let e431 = rs*l431; + let e412 = rs*l412; + let e321 = rs*l321; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_odd_grade( + OddGrade { + e1: l1, e2: l2, e3: l3, e4: l4, + e423: l423, e431: l431, e412: l412, e321: l321, + }: OddGrade, + OddGrade { + e1: r1, e2: r2, e3: r3, e4: r4, + e423: r423, e431: r431, e412: r412, e321: r321, + .. + }: OddGrade, +) -> EvenGrade { + + let e41 = l4*r1 - l1*r4; + let e42 = l4*r2 - l2*r4; + let e43 = l4*r3 - l3*r4; + let e23 = l2*r3 - l3*r2; + let e31 = l3*r1 - l1*r3; + let e12 = l1*r2 - l2*r1; + + let e1234 = (l4*r321 - l321*r4) + + (l1*r423 - l423*r1) + + (l2*r431 - l431*r2) + + (l3*r412 - l412*r3); + + EvenGrade { + e41, e42, e43, e23, e31, e12, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn odd_grade_wedge_even_grade( + OddGrade { + e1: l1, e2: l2, e3: l3, e4: l4, + e423: l423, e431: l431, e412: l412, e321: l321, + }: OddGrade, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + .. + }: EvenGrade, +) -> OddGrade { + + let e1 = l1*rs; + let e2 = l2*rs; + let e3 = l3*rs; + let e4 = l4*rs; + + let e423 = rs*l423 + + l4*r23 + + l3*r42 + - l2*r43; + let e431 = rs*l431 + + l4*r31 + + l1*r43 + - l3*r41; + let e412 = rs*l412 + + l4*r12 + + l2*r41 + - l1*r42; + let e321 = rs*l321 + - l1*r23 + - l3*r12 + - l2*r31; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +// even grade + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_multivector( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e1234: l1234, + }: EvenGrade, + Multivector { + s: rs, + e1: r1, e2: r2, e3: r3, e4: r4, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e423: r423, e431: r431, e412: r412, e321: r321, + e1234: r1234, + }: Multivector, +) -> Multivector { + + let s = ls*rs; + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e41 = ls*r41 + l41*rs; + let e42 = ls*r42 + l42*rs; + let e43 = ls*r43 + l43*rs; + let e23 = ls*r23 + l23*rs; + let e31 = ls*r31 + l31*rs; + let e12 = ls*r12 + l12*rs; + + let e423 = ls*r423 + + l23*r4 + + l42*r3 + - l43*r2; + let e431 = ls*r431 + + l31*r4 + + l43*r1 + - l41*r3; + let e412 = ls*r412 + + l12*r4 + + l41*r2 + - l42*r1; + let e321 = ls*r321 + - l23*r1 + - l12*r3 + - l31*r2; + + let e1234 = (ls*r1234 + l1234*rs) + - (l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + Multivector { + s, + e1, e2, e3, e4, + e41, e42, e43, e23, e31, e12, + e423, e431, e412, e321, + e1234, + } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_scalar( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e1234: l1234, + }: EvenGrade, + Scalar { s: rs }: Scalar, +) -> EvenGrade { + + let s = ls*rs; + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + let e1234 = l1234*rs; + + EvenGrade { + s, + e41, e42, e43, e23, e31, e12, + e1234, + } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_vector( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + .. + }: EvenGrade, + Vector { e1: r1, e2: r2, e3: r3, e4: r4 }: Vector, +) -> OddGrade { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e423 = l23*r4 + + l42*r3 + - l43*r2; + let e431 = l31*r4 + + l43*r1 + - l41*r3; + let e412 = l12*r4 + + l41*r2 + - l42*r1; + let e321 = -l23*r1 + - l12*r3 + - l31*r2; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_bivector( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + .. + }: EvenGrade, + Bivector { + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + }: Bivector, +) -> EvenGrade { + + let e41 = ls*r41; + let e42 = ls*r42; + let e43 = ls*r43; + let e23 = ls*r23; + let e31 = ls*r31; + let e12 = ls*r12; + + let e1234 = -(l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + EvenGrade { + e41, e42, e43, e23, e31, e12, + e1234, + ..zero() + } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_trivector( + EvenGrade { s: ls, .. }: EvenGrade, + Trivector { e423: r423, e431: r431, e412: r412, e321: r321 }: Trivector, +) -> Trivector { + + let e423 = ls*r423; + let e431 = ls*r431; + let e412 = ls*r412; + let e321 = ls*r321; + + Trivector { e423, e431, e412, e321 } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_antiscalar( + EvenGrade { s: ls, .. }: EvenGrade, + Antiscalar { e1234: r1234 }: Antiscalar, +) -> Antiscalar { + + let e1234 = ls*r1234; + + Antiscalar { e1234 } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_dual_number( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e1234: l1234, + }: EvenGrade, + DualNumber { s: rs, e1234: r1234 }: DualNumber, +) -> EvenGrade { + + let s = ls*rs; + + let e41 = l41*rs; + let e42 = l42*rs; + let e43 = l43*rs; + let e23 = l23*rs; + let e31 = l31*rs; + let e12 = l12*rs; + + let e1234 = ls*r1234 + l1234*rs; + + EvenGrade { + s, + e41, e42, e43, e23, e31, e12, + e1234, + } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_odd_grade( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + .. + }: EvenGrade, + OddGrade { + e1: r1, e2: r2, e3: r3, e4: r4, + e423: r423, e431: r431, e412: r412, e321: r321, + }: OddGrade, +) -> OddGrade { + + let e1 = ls*r1; + let e2 = ls*r2; + let e3 = ls*r3; + let e4 = ls*r4; + + let e423 = ls*r423 + + l23*r4 + + l42*r3 + - l43*r2; + let e431 = ls*r431 + + l31*r4 + + l43*r1 + - l41*r3; + let e412 = ls*r412 + + l12*r4 + + l41*r2 + - l42*r1; + let e321 = ls*r321 + - l23*r1 + - l12*r3 + - l31*r2; + + OddGrade { + e1, e2, e3, e4, + e423, e431, e412, e321, + } +} + +#[rustfmt::skip] +#[inline] +fn even_grade_wedge_even_grade( + EvenGrade { + s: ls, + e41: l41, e42: l42, e43: l43, e23: l23, e31: l31, e12: l12, + e1234: l1234, + }: EvenGrade, + EvenGrade { + s: rs, + e41: r41, e42: r42, e43: r43, e23: r23, e31: r31, e12: r12, + e1234: r1234, + }: EvenGrade, +) -> EvenGrade { + + let s = ls*rs; + + let e41 = ls*r41 + l41*rs; + let e42 = ls*r42 + l42*rs; + let e43 = ls*r43 + l43*rs; + let e23 = ls*r23 + l23*rs; + let e31 = ls*r31 + l31*rs; + let e12 = ls*r12 + l12*rs; + + let e1234 = (ls*r1234 + l1234*rs) + - (l41*r23 + l23*r41) + - (l42*r31 + l31*r42) + - (l43*r12 + l12*r43); + + EvenGrade { + s, + e41, e42, e43, e23, e31, e12, + e1234, + } +} + +#[cfg(any(test, doctest))] +mod tests { + use crate::{test_values::*, *}; + + #[rustfmt::skip] + const A: Multivector = Multivector { + e1: 2., e2: 3., e3: 5., e4: 7., + ..Multivector::ZERO + }; + #[rustfmt::skip] + const B: Multivector = Multivector { + e1: -11., e2: -13., e3: -17., e4: -19., + ..Multivector::ZERO + }; + #[rustfmt::skip] + const C: Multivector = Multivector { + e1: -11., e2: -13., e3: -17., e4: -19., + ..Multivector::ZERO + }; + + #[test] + fn vector_self_product() { + assert_eq!( + wedge_product(A, A), + zero(), + "The Wedge Product of any Vector with itself should be zero" + ); + } + + #[test] + fn vector_product_anticommutivity() { + assert_eq!( + wedge_product(A, B), + -wedge_product(B, A), + "The Wedge Product of two Vectors anticommutes" + ); + } + + #[test] + fn vector_product_associativity() { + assert_eq!( + wedge_product(A, wedge_product(B, C)), + wedge_product(wedge_product(A, B), C), + "The Wedge Product of two Vectors is associative" + ); + } + + #[test] + fn vector_product_distributivity() { + assert_eq!( + wedge_product(A, B + C), + wedge_product(A, B) + wedge_product(A, C), + "The Wedge Product of two Vectors distributes over addition" + ); + + assert_eq!( + wedge_product(A + B, C), + wedge_product(A, C) + wedge_product(B, C), + "The Wedge Product of two Vectors distributes over addition" + ) + } + + #[test] + fn sparse_implementations() { + // check the sparse implementations agree with the multivector op + + let multivector = MULTIVECTOR_A; + let scalar = multivector.grade_0(); + let vector = multivector.grade_1(); + let bivector = multivector.grade_2(); + let trivector = multivector.grade_3(); + let antiscalar = multivector.grade_4(); + let dual_number = scalar + antiscalar; + let odd_grade = vector + trivector; + let even_grade = scalar + bivector + antiscalar; + let empty = Empty; + + assert_eq!( + Multivector::from(wedge_product(multivector, multivector)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, scalar)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, vector)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, bivector)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, trivector)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, dual_number)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, even_grade)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(multivector, empty)), + Multivector::from(wedge_product( + Multivector::from(multivector), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(scalar, multivector)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, scalar)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, vector)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, bivector)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, trivector)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, dual_number)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, even_grade)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(scalar, empty)), + Multivector::from(wedge_product( + Multivector::from(scalar), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(vector, multivector)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, scalar)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, vector)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, bivector)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, trivector)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, dual_number)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, even_grade)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(vector, empty)), + Multivector::from(wedge_product( + Multivector::from(vector), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(bivector, multivector)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, scalar)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, vector)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, bivector)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, trivector)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, dual_number)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, even_grade)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(bivector, empty)), + Multivector::from(wedge_product( + Multivector::from(bivector), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(trivector, multivector)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, scalar)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, vector)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, bivector)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, trivector)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, dual_number)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, even_grade)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(trivector, empty)), + Multivector::from(wedge_product( + Multivector::from(trivector), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(antiscalar, multivector)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, scalar)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, vector)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, bivector)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, trivector)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, dual_number)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, even_grade)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(antiscalar, empty)), + Multivector::from(wedge_product( + Multivector::from(antiscalar), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(dual_number, multivector)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, scalar)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, vector)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, bivector)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, trivector)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, dual_number)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, even_grade)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(dual_number, empty)), + Multivector::from(wedge_product( + Multivector::from(dual_number), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(odd_grade, multivector)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, scalar)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, vector)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, bivector)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, trivector)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, dual_number)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, even_grade)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(odd_grade, empty)), + Multivector::from(wedge_product( + Multivector::from(odd_grade), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(even_grade, multivector)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, scalar)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, vector)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, bivector)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, trivector)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, dual_number)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, even_grade)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(even_grade, empty)), + Multivector::from(wedge_product( + Multivector::from(even_grade), + Multivector::from(empty) + )) + ); + + assert_eq!( + Multivector::from(wedge_product(empty, multivector)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(multivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, scalar)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(scalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, vector)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(vector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, bivector)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(bivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, trivector)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(trivector) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, antiscalar)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(antiscalar) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, dual_number)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(dual_number) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, odd_grade)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(odd_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, even_grade)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(even_grade) + )) + ); + assert_eq!( + Multivector::from(wedge_product(empty, empty)), + Multivector::from(wedge_product( + Multivector::from(empty), + Multivector::from(empty) + )) + ); } } diff --git a/rga/src/operators/weight_contraction.rs b/rga/src/operators/weight_contraction.rs index 5b91bbd..3c12985 100644 --- a/rga/src/operators/weight_contraction.rs +++ b/rga/src/operators/weight_contraction.rs @@ -83,8 +83,8 @@ mod tests { #[test] fn definition() { assert_eq!( - dbg!(weight_contraction(MULTIVECTOR_A, MULTIVECTOR_B)), - dbg!(antiwedge_product(MULTIVECTOR_A, weight_dual(MULTIVECTOR_B))) + weight_contraction(MULTIVECTOR_A, MULTIVECTOR_B), + antiwedge_product(MULTIVECTOR_A, weight_dual(MULTIVECTOR_B)) ); } } diff --git a/rga/src/operators/weight_expansion.rs b/rga/src/operators/weight_expansion.rs index 32b59e3..48d035e 100644 --- a/rga/src/operators/weight_expansion.rs +++ b/rga/src/operators/weight_expansion.rs @@ -93,8 +93,8 @@ mod tests { #[test] fn definition() { assert_eq!( - dbg!(weight_expansion(MULTIVECTOR_A, MULTIVECTOR_B)), - dbg!(wedge_product(MULTIVECTOR_A, weight_dual(MULTIVECTOR_B))) + weight_expansion(MULTIVECTOR_A, MULTIVECTOR_B), + wedge_product(MULTIVECTOR_A, weight_dual(MULTIVECTOR_B)) ); }