use crate::*;
use approx::assert_relative_eq;
#[cfg(feature = "std")]
use std::f64::consts;
#[cfg(not(feature = "std"))]
use core::f64::consts;
type Cl3 = Multivector<3, 0, 0>;
#[cfg(test)]
mod constructor_tests {
use super::*;
#[test]
fn test_zero() {
let zero = Cl3::zero();
for i in 0..8 {
assert_eq!(zero.get(i), 0.0);
}
assert!(zero.is_zero());
}
#[test]
fn test_scalar() {
let mv = Cl3::scalar(5.0);
assert_eq!(mv.get(0), 5.0);
for i in 1..8 {
assert_eq!(mv.get(i), 0.0);
}
}
#[test]
fn test_basis_vector() {
let e1 = Cl3::basis_vector(0);
assert_eq!(e1.get(1), 1.0); for i in [0, 2, 3, 4, 5, 6, 7] {
assert_eq!(e1.get(i), 0.0);
}
}
#[test]
fn test_from_coefficients() {
let coeffs = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
let mv = Cl3::from_coefficients(coeffs.clone());
for (i, &coeff) in coeffs.iter().enumerate().take(8) {
assert_eq!(mv.get(i), coeff);
}
}
#[test]
fn test_from_slice() {
let coeffs = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
let mv = Cl3::from_slice(&coeffs);
for (i, &coeff) in coeffs.iter().enumerate() {
assert_eq!(mv.get(i), coeff);
}
}
}
#[cfg(test)]
mod accessor_tests {
use super::*;
#[test]
fn test_get_set() {
let mut mv = Cl3::zero();
mv.set(3, 42.0);
assert_eq!(mv.get(3), 42.0);
}
#[test]
fn test_scalar_part() {
let mv = Cl3::from_coefficients(vec![5.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0]);
assert_eq!(mv.scalar_part(), 5.0);
}
#[test]
fn test_set_scalar() {
let mut mv = Cl3::scalar(1.0);
mv.set_scalar(10.0);
assert_eq!(mv.scalar_part(), 10.0);
}
#[test]
fn test_vector_part() {
let mv = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 5.0, 0.0, 0.0, 0.0]);
let vec_part = mv.vector_part();
assert_eq!(vec_part.mv.get(1), 2.0); assert_eq!(vec_part.mv.get(2), 3.0); assert_eq!(vec_part.mv.get(4), 5.0); }
#[test]
fn test_bivector_part() {
let mv = Cl3::from_coefficients(vec![0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 3.0, 0.0]);
let biv_part = mv.bivector_part();
assert_eq!(biv_part.get(3), 1.0); assert_eq!(biv_part.get(5), 2.0); assert_eq!(biv_part.get(6), 3.0); }
#[test]
fn test_trivector_part() {
let mv = Cl3::from_coefficients(vec![0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0]);
assert_eq!(mv.trivector_part(), 5.0);
}
#[test]
fn test_set_vector_component() {
let mut mv = Cl3::zero();
mv.set_vector_component(1, 42.0); assert_eq!(mv.get(2), 42.0); }
#[test]
fn test_set_bivector_component() {
let mut mv = Cl3::zero();
mv.set_bivector_component(0, 42.0); assert_eq!(mv.get(3), 42.0);
}
#[test]
fn test_vector_component() {
let mv = Cl3::from_coefficients(vec![0.0, 1.0, 2.0, 0.0, 3.0, 0.0, 0.0, 0.0]);
assert_eq!(mv.vector_component(0), 1.0); assert_eq!(mv.vector_component(1), 2.0); assert_eq!(mv.vector_component(2), 3.0); }
#[test]
fn test_as_slice() {
let coeffs = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
let mv = Cl3::from_coefficients(coeffs.clone());
let slice = mv.as_slice();
assert_eq!(slice.len(), 8);
for i in 0..8 {
assert_eq!(slice[i], coeffs[i]);
}
}
}
#[cfg(test)]
mod arithmetic_tests {
use super::*;
#[test]
fn test_addition() {
let a = Cl3::scalar(2.0);
let b = Cl3::scalar(3.0);
let result = &a + &b;
assert_eq!(result.scalar_part(), 5.0);
}
#[test]
fn test_operator_addition() {
let a = Cl3::scalar(2.0);
let b = Cl3::scalar(3.0);
let result = &a + &b;
assert_eq!(result.scalar_part(), 5.0);
}
#[test]
fn test_operator_subtraction() {
let a = Cl3::scalar(5.0);
let b = Cl3::scalar(3.0);
let result = &a - &b;
assert_eq!(result.scalar_part(), 2.0);
}
#[test]
fn test_operator_negation() {
let a = Cl3::scalar(5.0);
let result = -a.clone();
assert_eq!(result.scalar_part(), -5.0);
}
#[test]
fn test_scalar_multiplication() {
let a = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0]);
let result = &a * 2.0;
assert_eq!(result.get(0), 2.0);
assert_eq!(result.get(1), 4.0);
assert_eq!(result.get(2), 6.0);
assert_eq!(result.get(3), 8.0);
}
}
#[cfg(test)]
mod product_tests {
use super::*;
#[test]
fn test_geometric_product() {
let e1 = Cl3::basis_vector(0);
let e2 = Cl3::basis_vector(1);
let result = e1.geometric_product(&e2);
assert_eq!(result.get(3), 1.0); }
#[test]
fn test_geometric_product_associativity() {
let a = Cl3::scalar(2.0);
let b = Cl3::basis_vector(0);
let c = Cl3::basis_vector(1);
let ab_c = a.geometric_product(&b).geometric_product(&c);
let a_bc = a.geometric_product(&b.geometric_product(&c));
for i in 0..8 {
assert_relative_eq!(ab_c.get(i), a_bc.get(i), epsilon = 1e-10);
}
}
#[test]
fn test_inner_product() {
let e1 = Cl3::basis_vector(0);
let e2 = Cl3::basis_vector(1);
let result = e1.inner_product(&e2);
assert!(result.is_zero());
}
#[test]
fn test_outer_product() {
let e1 = Cl3::basis_vector(0);
let e2 = Cl3::basis_vector(1);
let result = e1.outer_product(&e2);
assert_eq!(result.get(3), 1.0);
}
#[test]
fn test_outer_product_antisymmetric() {
let e1 = Cl3::basis_vector(0);
let e2 = Cl3::basis_vector(1);
let e1_e2 = e1.outer_product(&e2);
let e2_e1 = e2.outer_product(&e1);
for i in 0..8 {
assert_relative_eq!(e1_e2.get(i), -e2_e1.get(i), epsilon = 1e-10);
}
}
#[test]
fn test_scalar_product() {
let a = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let b = Cl3::from_coefficients(vec![2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let result = a.scalar_product(&b);
assert_eq!(result, 7.0);
}
}
#[cfg(test)]
mod operation_tests {
use super::*;
#[test]
fn test_reverse() {
let mv = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let rev = mv.reverse();
assert_eq!(rev.get(0), 1.0); assert_eq!(rev.get(1), 2.0); assert_eq!(rev.get(2), 3.0); assert_eq!(rev.get(3), -4.0); assert_eq!(rev.get(4), 5.0); assert_eq!(rev.get(5), -6.0); assert_eq!(rev.get(6), -7.0); assert_eq!(rev.get(7), -8.0); }
#[test]
fn test_grade_projection() {
let mv = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let grade0 = mv.grade_projection(0);
assert_eq!(grade0.get(0), 1.0);
for i in 1..8 {
assert_eq!(grade0.get(i), 0.0);
}
let grade1 = mv.grade_projection(1);
assert_eq!(grade1.get(0), 0.0);
assert_eq!(grade1.get(1), 2.0); assert_eq!(grade1.get(2), 3.0); assert_eq!(grade1.get(3), 0.0); assert_eq!(grade1.get(4), 5.0); for i in 5..8 {
assert_eq!(grade1.get(i), 0.0);
}
}
#[test]
fn test_grade() {
assert_eq!(Cl3::scalar(5.0).grade(), 0);
assert_eq!(Cl3::basis_vector(0).grade(), 1);
let bivector = Cl3::basis_vector(0).outer_product(&Cl3::basis_vector(1));
assert_eq!(bivector.grade(), 2);
}
}
#[cfg(test)]
mod utility_tests {
use super::*;
#[test]
fn test_is_zero() {
assert!(Cl3::zero().is_zero());
assert!(!Cl3::scalar(1.0).is_zero());
}
#[test]
fn test_norm_squared() {
let mv = Cl3::from_coefficients(vec![0.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
assert_eq!(mv.norm_squared(), 25.0); }
#[test]
fn test_equality() {
let a = Cl3::scalar(5.0);
let b = Cl3::scalar(5.0);
let c = Cl3::scalar(3.0);
assert_eq!(a, b);
assert_ne!(a, c);
}
#[test]
fn test_norm() {
let mv = Cl3::from_coefficients(vec![0.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
assert_eq!(mv.norm(), 5.0); }
#[test]
fn test_magnitude() {
let mv = Cl3::from_coefficients(vec![0.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
assert_eq!(mv.magnitude(), 5.0); assert_eq!(mv.magnitude(), mv.norm()); }
#[test]
fn test_abs() {
let mv = Cl3::from_coefficients(vec![0.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
assert_eq!(mv.abs(), 5.0); assert_eq!(mv.abs(), mv.magnitude());
}
#[test]
fn test_approx_eq() {
let a = Cl3::scalar(1.0);
let b = Cl3::scalar(1.00001);
let c = Cl3::scalar(1.1);
assert!(a.approx_eq(&b, 0.001));
assert!(!a.approx_eq(&b, 0.000001));
assert!(!a.approx_eq(&c, 0.001));
}
#[test]
fn test_normalize() {
let mv = Cl3::from_coefficients(vec![0.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let normalized = mv.normalize().expect("Should normalize successfully");
assert!((normalized.norm() - 1.0).abs() < 1e-10);
assert!((normalized.get(1) - 0.6).abs() < 1e-10); assert!((normalized.get(2) - 0.8).abs() < 1e-10); }
#[test]
fn test_normalize_zero() {
let zero = Cl3::zero();
let result = zero.normalize();
assert!(result.is_none());
}
#[test]
fn test_normalize_small() {
let small = Cl3::scalar(1e-15);
let result = small.normalize();
assert!(result.is_none());
}
#[test]
fn test_inverse() {
let scalar = Cl3::scalar(2.0);
let inv = scalar.inverse().expect("Scalar should have inverse");
let product = scalar.geometric_product(&inv);
assert!((product.scalar_part() - 1.0).abs() < 1e-10);
let vector = Cl3::from_coefficients(vec![0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let inv = vector.inverse().expect("Unit vector should have inverse");
let product = vector.geometric_product(&inv);
assert!((product.scalar_part() - 1.0).abs() < 1e-10);
}
#[test]
fn test_inverse_zero() {
let zero = Cl3::zero();
let result = zero.inverse();
assert!(result.is_none());
}
#[test]
fn test_inverse_small() {
let small = Cl3::scalar(1e-15);
let result = small.inverse();
assert!(result.is_none());
}
}
#[cfg(test)]
mod vector_tests {
use super::*;
#[test]
fn test_vector_zero() {
let v = Vector::<3, 0, 0>::zero();
assert!(v.mv.is_zero());
assert_eq!(v.magnitude(), 0.0);
}
#[test]
fn test_vector_from_components() {
let v = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
assert_eq!(v.mv.vector_component(0), 1.0);
assert_eq!(v.mv.vector_component(1), 2.0);
assert_eq!(v.mv.vector_component(2), 3.0);
}
#[test]
fn test_vector_basis_vectors() {
let e1 = Vector::<3, 0, 0>::e1();
let e2 = Vector::<3, 0, 0>::e2();
let e3 = Vector::<3, 0, 0>::e3();
assert_eq!(e1.mv.vector_component(0), 1.0);
assert_eq!(e1.mv.vector_component(1), 0.0);
assert_eq!(e1.mv.vector_component(2), 0.0);
assert_eq!(e2.mv.vector_component(0), 0.0);
assert_eq!(e2.mv.vector_component(1), 1.0);
assert_eq!(e2.mv.vector_component(2), 0.0);
assert_eq!(e3.mv.vector_component(0), 0.0);
assert_eq!(e3.mv.vector_component(1), 0.0);
assert_eq!(e3.mv.vector_component(2), 1.0);
}
#[test]
fn test_vector_from_multivector() {
let mv = Cl3::from_coefficients(vec![0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0]);
let v = Vector::from_multivector(&mv);
assert_eq!(v.mv.vector_component(0), 1.0);
assert_eq!(v.mv.vector_component(1), 2.0);
assert_eq!(v.mv.vector_component(2), 4.0);
assert_eq!(v.mv.scalar_part(), 0.0);
}
#[test]
fn test_vector_geometric_product_with_vector() {
let v1 = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let v2 = Vector::<3, 0, 0>::from_components(0.0, 1.0, 0.0);
let result = v1.geometric_product(&v2);
assert_eq!(result.scalar_part(), 0.0);
assert_eq!(result.get(3), 1.0); }
#[test]
fn test_vector_geometric_product_with_multivector() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let scalar = Cl3::scalar(2.0);
let result = v.geometric_product_with_multivector(&scalar);
assert_eq!(result.vector_component(0), 2.0);
assert_eq!(result.vector_component(1), 0.0);
assert_eq!(result.vector_component(2), 0.0);
}
#[test]
fn test_vector_geometric_product_with_bivector() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let bv = Bivector::<3, 0, 0>::e12();
let result = v.geometric_product_with_bivector(&bv);
assert_eq!(result.vector_component(1), 1.0);
}
#[test]
fn test_vector_geometric_product_with_scalar() {
let v = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
let s = Scalar::<3, 0, 0>::from(2.0);
let result = v.geometric_product_with_scalar(&s);
assert_eq!(result.vector_component(0), 2.0);
assert_eq!(result.vector_component(1), 4.0);
assert_eq!(result.vector_component(2), 6.0);
}
#[test]
fn test_vector_add() {
let v1 = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
let v2 = Vector::<3, 0, 0>::from_components(4.0, 5.0, 6.0);
let result = v1.add(&v2);
assert_eq!(result.mv.vector_component(0), 5.0);
assert_eq!(result.mv.vector_component(1), 7.0);
assert_eq!(result.mv.vector_component(2), 9.0);
}
#[test]
fn test_vector_magnitude() {
let v = Vector::<3, 0, 0>::from_components(3.0, 4.0, 0.0);
assert_eq!(v.magnitude(), 5.0); }
#[test]
fn test_vector_as_slice() {
let v = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
let slice = v.as_slice();
assert_eq!(slice[1], 1.0); assert_eq!(slice[2], 2.0); assert_eq!(slice[4], 3.0); }
#[test]
fn test_vector_inner_product() {
let v1 = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let v2 = Vector::<3, 0, 0>::from_components(0.0, 1.0, 0.0);
let result = v1.inner_product(&v2);
assert!(result.is_zero());
let v3 = Vector::<3, 0, 0>::from_components(2.0, 0.0, 0.0);
let result2 = v1.inner_product(&v3);
assert_eq!(result2.scalar_part(), 2.0);
}
#[test]
fn test_vector_inner_product_with_mv() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let mv = Cl3::from_coefficients(vec![0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let result = v.inner_product_with_mv(&mv);
assert_eq!(result.scalar_part(), 2.0);
}
#[test]
fn test_vector_inner_product_with_bivector() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let bv = Bivector::<3, 0, 0>::e12();
let result = v.inner_product_with_bivector(&bv);
assert_eq!(result.vector_component(1), 1.0); }
#[test]
fn test_vector_outer_product() {
let v1 = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let v2 = Vector::<3, 0, 0>::from_components(0.0, 1.0, 0.0);
let result = v1.outer_product(&v2);
assert_eq!(result.get(3), 1.0);
}
#[test]
fn test_vector_outer_product_with_mv() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let mv = Cl3::from_coefficients(vec![0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
let result = v.outer_product_with_mv(&mv);
assert_eq!(result.get(3), 1.0);
}
#[test]
fn test_vector_outer_product_with_bivector() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let bv = Bivector::<3, 0, 0>::e23();
let result = v.outer_product_with_bivector(&bv);
assert_eq!(result.get(7), 1.0); }
#[test]
fn test_vector_left_contraction() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let bv = Bivector::<3, 0, 0>::e12();
let result = v.left_contraction(&bv);
assert_eq!(result.vector_component(1), 1.0);
}
#[test]
fn test_vector_normalize() {
let v = Vector::<3, 0, 0>::from_components(3.0, 4.0, 0.0);
let normalized = v.normalize().expect("Should normalize successfully");
assert!((normalized.norm() - 1.0).abs() < 1e-10);
assert!((normalized.mv.vector_component(0) - 0.6).abs() < 1e-10); assert!((normalized.mv.vector_component(1) - 0.8).abs() < 1e-10); }
#[test]
fn test_vector_normalize_zero() {
let v = Vector::<3, 0, 0>::zero();
let result = v.normalize();
assert!(result.is_none());
}
#[test]
fn test_vector_norm_squared() {
let v = Vector::<3, 0, 0>::from_components(3.0, 4.0, 0.0);
assert_eq!(v.norm_squared(), 25.0); }
#[test]
fn test_vector_reverse() {
let v = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
let reversed = v.reverse();
assert_eq!(reversed.mv.vector_component(0), 1.0);
assert_eq!(reversed.mv.vector_component(1), 2.0);
assert_eq!(reversed.mv.vector_component(2), 3.0);
}
#[test]
fn test_vector_norm() {
let v = Vector::<3, 0, 0>::from_components(3.0, 4.0, 0.0);
assert_eq!(v.norm(), 5.0);
}
#[test]
fn test_vector_hodge_dual() {
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let dual = v.hodge_dual();
assert_eq!(dual.get(2), 1.0); }
}
#[cfg(test)]
mod bivector_tests {
use super::*;
#[test]
fn test_bivector_from_components() {
let bv = Bivector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
assert_eq!(bv.get(0), 1.0); assert_eq!(bv.get(1), 2.0); assert_eq!(bv.get(2), 3.0); }
#[test]
fn test_bivector_basis_bivectors() {
let e12 = Bivector::<3, 0, 0>::e12();
let e13 = Bivector::<3, 0, 0>::e13();
let e23 = Bivector::<3, 0, 0>::e23();
assert_eq!(e12.get(0), 1.0);
assert_eq!(e12.get(1), 0.0);
assert_eq!(e12.get(2), 0.0);
assert_eq!(e13.get(0), 0.0);
assert_eq!(e13.get(1), 1.0);
assert_eq!(e13.get(2), 0.0);
assert_eq!(e23.get(0), 0.0);
assert_eq!(e23.get(1), 0.0);
assert_eq!(e23.get(2), 1.0);
}
#[test]
fn test_bivector_from_multivector() {
let mv = Cl3::from_coefficients(vec![1.0, 0.0, 0.0, 2.0, 0.0, 3.0, 4.0, 0.0]);
let bv = Bivector::from_multivector(&mv);
assert_eq!(bv.get(0), 2.0); assert_eq!(bv.get(1), 3.0); assert_eq!(bv.get(2), 4.0); }
#[test]
fn test_bivector_geometric_product_with_vector() {
let bv = Bivector::<3, 0, 0>::e12();
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let result = bv.geometric_product(&v);
assert_eq!(result.vector_component(1), -1.0);
}
#[test]
fn test_bivector_geometric_product_with_bivector() {
let bv1 = Bivector::<3, 0, 0>::e12();
let bv2 = Bivector::<3, 0, 0>::e13();
let result = bv1.geometric_product_with_bivector(&bv2);
assert_eq!(result.get(6), -1.0); }
#[test]
fn test_bivector_magnitude() {
let bv = Bivector::<3, 0, 0>::from_components(3.0, 4.0, 0.0);
assert_eq!(bv.magnitude(), 5.0); }
#[test]
fn test_bivector_get() {
let bv = Bivector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
assert_eq!(bv.get(0), 1.0); assert_eq!(bv.get(1), 2.0); assert_eq!(bv.get(2), 3.0); assert_eq!(bv.get(999), 0.0); }
#[test]
fn test_bivector_inner_product() {
let bv1 = Bivector::<3, 0, 0>::e12();
let bv2 = Bivector::<3, 0, 0>::e13();
let result = bv1.inner_product(&bv2);
assert!(result.is_zero());
let bv3 = Bivector::<3, 0, 0>::from_components(2.0, 0.0, 0.0);
let result2 = bv1.inner_product(&bv3);
assert_eq!(result2.scalar_part(), -2.0); }
#[test]
fn test_bivector_inner_product_with_vector() {
let bv = Bivector::<3, 0, 0>::e12();
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let result = bv.inner_product_with_vector(&v);
assert_eq!(result.vector_component(1), -1.0); }
#[test]
fn test_bivector_outer_product() {
let bv1 = Bivector::<3, 0, 0>::e12();
let bv2 = Bivector::<3, 0, 0>::e13();
let result = bv1.outer_product(&bv2);
assert!(result.is_zero());
let bv3 = Bivector::<3, 0, 0>::e23();
let result2 = bv1.outer_product(&bv3);
let _ = result2; }
#[test]
fn test_bivector_outer_product_with_vector() {
let bv = Bivector::<3, 0, 0>::e12();
let v = Vector::<3, 0, 0>::from_components(0.0, 0.0, 1.0);
let result = bv.outer_product_with_vector(&v);
assert_eq!(result.get(7), 1.0);
}
#[test]
fn test_bivector_right_contraction() {
let bv = Bivector::<3, 0, 0>::e12();
let v = Vector::<3, 0, 0>::from_components(1.0, 0.0, 0.0);
let result = bv.right_contraction(&v);
assert_eq!(result.vector_component(1), -1.0);
}
#[test]
fn test_bivector_index_access() {
let bv = Bivector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
assert_eq!(bv[0], 1.0); assert_eq!(bv[1], 2.0); assert_eq!(bv[2], 3.0); }
}
#[cfg(test)]
mod scalar_tests {
use super::*;
#[test]
fn test_scalar_from() {
let s = Scalar::<3, 0, 0>::from(5.0);
assert_eq!(s.mv.scalar_part(), 5.0);
assert!(s.mv.vector_part().mv.is_zero());
}
#[test]
fn test_scalar_one() {
let s = Scalar::<3, 0, 0>::one();
assert_eq!(s.mv.scalar_part(), 1.0);
}
#[test]
fn test_scalar_from_trait() {
let s: Scalar<3, 0, 0> = 3.0.into();
assert_eq!(s.mv.scalar_part(), 3.0);
}
#[test]
fn test_scalar_geometric_product_with_multivector() {
let s = Scalar::<3, 0, 0>::from(2.0);
let mv = Cl3::from_coefficients(vec![1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]);
let result = s.geometric_product(&mv);
for i in 0..8 {
assert_eq!(result.get(i), 2.0);
}
}
#[test]
fn test_scalar_geometric_product_with_vector() {
let s = Scalar::<3, 0, 0>::from(3.0);
let v = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
let result = s.geometric_product_with_vector(&v);
assert_eq!(result.vector_component(0), 3.0);
assert_eq!(result.vector_component(1), 6.0);
assert_eq!(result.vector_component(2), 9.0);
}
#[test]
fn test_scalar_commutative_multiplication() {
let s = Scalar::<3, 0, 0>::from(2.0);
let v = Vector::<3, 0, 0>::from_components(1.0, 2.0, 3.0);
let sv = s.geometric_product_with_vector(&v);
let vs = v.geometric_product_with_scalar(&s);
for i in 0..8 {
assert_eq!(sv.get(i), vs.get(i));
}
}
#[test]
fn test_scalar_identity() {
let one = Scalar::<3, 0, 0>::one();
let mv = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let result = one.geometric_product(&mv);
for i in 0..8 {
assert_eq!(result.get(i), mv.get(i));
}
}
}
#[cfg(test)]
mod advanced_operations_tests {
use super::*;
#[test]
fn test_exp_bivector() {
let e1 = Cl3::basis_vector(0);
let e2 = Cl3::basis_vector(1);
let bivector = e1.outer_product(&e2) * (consts::PI / 4.0);
let rotor = bivector.exp();
assert!((rotor.norm() - 1.0).abs() < 1e-10);
let rotated_e1 = rotor
.geometric_product(&e1)
.geometric_product(&rotor.reverse());
assert!((rotated_e1.norm() - 1.0).abs() < 1e-10);
for i in [0, 3, 4, 5, 6, 7] {
assert!(rotated_e1.get(i).abs() < 1e-10);
}
assert!((rotated_e1.get(1) - 1.0).abs() > 1e-6); assert!(rotated_e1.get(2).abs() > 1e-6); }
#[test]
fn test_exp_scalar() {
let scalar = Cl3::scalar(1.0);
let exp_scalar = scalar.exp();
assert!((exp_scalar.scalar_part() - consts::E).abs() < 1e-10);
for i in 1..8 {
assert!(exp_scalar.get(i).abs() < 1e-10);
}
}
#[test]
fn test_exp_zero() {
let zero = Cl3::zero();
let exp_zero = zero.exp();
assert!((exp_zero.scalar_part() - 1.0).abs() < 1e-10);
for i in 1..8 {
assert!(exp_zero.get(i).abs() < 1e-10);
}
}
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[test]
fn test_basis_vector_squares() {
for i in 0..3 {
let ei = Cl3::basis_vector(i);
let ei_squared = ei.geometric_product(&ei);
assert_relative_eq!(ei_squared.scalar_part(), 1.0, epsilon = 1e-10);
}
}
#[test]
fn test_basis_vector_anticommutativity() {
let e1 = Cl3::basis_vector(0);
let e2 = Cl3::basis_vector(1);
let e1_e2 = e1.geometric_product(&e2);
let e2_e1 = e2.geometric_product(&e1);
for i in 0..8 {
assert_relative_eq!(e1_e2.get(i), -e2_e1.get(i), epsilon = 1e-10);
}
}
#[test]
fn test_distributivity() {
let a = Cl3::scalar(2.0);
let b = Cl3::basis_vector(0);
let c = Cl3::basis_vector(1);
let a_bc = a.geometric_product(&(&b + &c));
let ab_ac = &a.geometric_product(&b) + &a.geometric_product(&c);
for i in 0..8 {
assert_relative_eq!(a_bc.get(i), ab_ac.get(i), epsilon = 1e-10);
}
}
#[test]
fn test_identity_elements() {
let mv = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let one = Cl3::scalar(1.0);
let result = mv.geometric_product(&one);
assert_eq!(mv, result);
let zero = Cl3::zero();
let result = &mv + &zero;
assert_eq!(mv, result);
}
#[test]
fn test_reverse_involution() {
let a = Cl3::from_coefficients(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let b = Cl3::from_coefficients(vec![2.0, 1.0, 1.0, 1.0, 1.0, 2.0, 3.0, 1.0]);
let ab = a.geometric_product(&b);
let ab_rev = ab.reverse();
let a_rev = a.reverse();
let b_rev = b.reverse();
let ba_rev = b_rev.geometric_product(&a_rev);
for i in 0..8 {
assert_relative_eq!(ab_rev.get(i), ba_rev.get(i), epsilon = 1e-10);
}
}
}