#![allow(clippy::assign_op_pattern)]
use crate::{*, simd::*};
use std::ops::{Add, Neg, Sub, Mul, Div};
#[derive(Clone, Copy)]
pub struct Scalar {
pub g0: f32,
}
#[derive(Clone, Copy)]
pub struct MultiVector {
pub g0: Simd32x2,
}
impl Zero for Scalar {
fn zero() -> Self {
Scalar { g0: 0.0 }
}
}
impl One for Scalar {
fn one() -> Self {
Scalar { g0: 1.0 }
}
}
impl Neg for Scalar {
type Output = Scalar;
fn neg(self) -> Scalar {
Scalar { g0: self.g0 * -1.0 }
}
}
impl Automorph for Scalar {
type Output = Scalar;
fn automorph(self) -> Scalar {
Scalar { g0: self.g0 }
}
}
impl Transpose for Scalar {
type Output = Scalar;
fn transpose(self) -> Scalar {
Scalar { g0: self.g0 }
}
}
impl Conjugate for Scalar {
type Output = Scalar;
fn conjugate(self) -> Scalar {
Scalar { g0: self.g0 }
}
}
impl Add<Scalar> for Scalar {
type Output = Scalar;
fn add(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 + other.g0 }
}
}
impl Sub<Scalar> for Scalar {
type Output = Scalar;
fn sub(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 - other.g0 }
}
}
impl GeometricProduct<Scalar> for Scalar {
type Output = Scalar;
fn geometric_product(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 * other.g0 }
}
}
impl OuterProduct<Scalar> for Scalar {
type Output = Scalar;
fn outer_product(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 * other.g0 }
}
}
impl InnerProduct<Scalar> for Scalar {
type Output = Scalar;
fn inner_product(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 * other.g0 }
}
}
impl LeftContraction<Scalar> for Scalar {
type Output = Scalar;
fn left_contraction(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 * other.g0 }
}
}
impl RightContraction<Scalar> for Scalar {
type Output = Scalar;
fn right_contraction(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 * other.g0 }
}
}
impl ScalarProduct<Scalar> for Scalar {
type Output = Scalar;
fn scalar_product(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0 * other.g0 }
}
}
impl Add<MultiVector> for Scalar {
type Output = MultiVector;
fn add(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0) * Simd32x2::from([1.0, 0.0]) + other.g0 }
}
}
impl Sub<MultiVector> for Scalar {
type Output = MultiVector;
fn sub(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0) * Simd32x2::from([1.0, 0.0]) - other.g0 }
}
}
impl GeometricProduct<MultiVector> for Scalar {
type Output = MultiVector;
fn geometric_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0) * other.g0 }
}
}
impl RegressiveProduct<MultiVector> for Scalar {
type Output = Scalar;
fn regressive_product(self, other: MultiVector) -> Scalar {
Scalar { g0: self.g0 * other.g0.get_f(1) }
}
}
impl OuterProduct<MultiVector> for Scalar {
type Output = MultiVector;
fn outer_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0) * other.g0 }
}
}
impl InnerProduct<MultiVector> for Scalar {
type Output = MultiVector;
fn inner_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0) * other.g0 }
}
}
impl LeftContraction<MultiVector> for Scalar {
type Output = MultiVector;
fn left_contraction(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0) * other.g0 }
}
}
impl RightContraction<MultiVector> for Scalar {
type Output = Scalar;
fn right_contraction(self, other: MultiVector) -> Scalar {
Scalar { g0: self.g0 * other.g0.get_f(0) }
}
}
impl ScalarProduct<MultiVector> for Scalar {
type Output = Scalar;
fn scalar_product(self, other: MultiVector) -> Scalar {
Scalar { g0: self.g0 * other.g0.get_f(0) }
}
}
impl SquaredMagnitude for Scalar {
type Output = Scalar;
fn squared_magnitude(self) -> Scalar {
self.scalar_product(self.conjugate())
}
}
impl Magnitude for Scalar {
type Output = Scalar;
fn magnitude(self) -> Scalar {
Scalar { g0: self.squared_magnitude().g0.sqrt() }
}
}
impl Signum for Scalar {
type Output = Scalar;
fn signum(self) -> Scalar {
self.geometric_product(Scalar { g0: 1.0 / self.magnitude().g0 })
}
}
impl Inverse for Scalar {
type Output = Scalar;
fn inverse(self) -> Scalar {
self.conjugate().geometric_product(Scalar { g0: 1.0 / self.squared_magnitude().g0 })
}
}
impl Zero for MultiVector {
fn zero() -> Self {
MultiVector { g0: Simd32x2::from(0.0) }
}
}
impl One for MultiVector {
fn one() -> Self {
MultiVector { g0: Simd32x2::from([1.0, 0.0]) }
}
}
impl Neg for MultiVector {
type Output = MultiVector;
fn neg(self) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from(-1.0) }
}
}
impl Automorph for MultiVector {
type Output = MultiVector;
fn automorph(self) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from([1.0, -1.0]) }
}
}
impl Transpose for MultiVector {
type Output = MultiVector;
fn transpose(self) -> MultiVector {
MultiVector { g0: self.g0 }
}
}
impl Conjugate for MultiVector {
type Output = MultiVector;
fn conjugate(self) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from([1.0, -1.0]) }
}
}
impl Dual for MultiVector {
type Output = MultiVector;
fn dual(self) -> MultiVector {
MultiVector { g0: swizzle!(self.g0, 1, 0) }
}
}
impl Into<Scalar> for MultiVector {
fn into(self) -> Scalar {
Scalar { g0: self.g0.get_f(0) }
}
}
impl Add<Scalar> for MultiVector {
type Output = MultiVector;
fn add(self, other: Scalar) -> MultiVector {
MultiVector { g0: self.g0 + Simd32x2::from(other.g0) * Simd32x2::from([1.0, 0.0]) }
}
}
impl Sub<Scalar> for MultiVector {
type Output = MultiVector;
fn sub(self, other: Scalar) -> MultiVector {
MultiVector { g0: self.g0 - Simd32x2::from(other.g0) * Simd32x2::from([1.0, 0.0]) }
}
}
impl GeometricProduct<Scalar> for MultiVector {
type Output = MultiVector;
fn geometric_product(self, other: Scalar) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from(other.g0) }
}
}
impl RegressiveProduct<Scalar> for MultiVector {
type Output = Scalar;
fn regressive_product(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0.get_f(1) * other.g0 }
}
}
impl OuterProduct<Scalar> for MultiVector {
type Output = MultiVector;
fn outer_product(self, other: Scalar) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from(other.g0) }
}
}
impl InnerProduct<Scalar> for MultiVector {
type Output = MultiVector;
fn inner_product(self, other: Scalar) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from(other.g0) }
}
}
impl LeftContraction<Scalar> for MultiVector {
type Output = Scalar;
fn left_contraction(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0.get_f(0) * other.g0 }
}
}
impl RightContraction<Scalar> for MultiVector {
type Output = MultiVector;
fn right_contraction(self, other: Scalar) -> MultiVector {
MultiVector { g0: self.g0 * Simd32x2::from(other.g0) }
}
}
impl ScalarProduct<Scalar> for MultiVector {
type Output = Scalar;
fn scalar_product(self, other: Scalar) -> Scalar {
Scalar { g0: self.g0.get_f(0) * other.g0 }
}
}
impl Add<MultiVector> for MultiVector {
type Output = MultiVector;
fn add(self, other: MultiVector) -> MultiVector {
MultiVector { g0: self.g0 + other.g0 }
}
}
impl Sub<MultiVector> for MultiVector {
type Output = MultiVector;
fn sub(self, other: MultiVector) -> MultiVector {
MultiVector { g0: self.g0 - other.g0 }
}
}
impl GeometricProduct<MultiVector> for MultiVector {
type Output = MultiVector;
fn geometric_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0.get_f(0)) * other.g0 + Simd32x2::from(self.g0.get_f(1)) * swizzle!(other.g0, 1, 0) * Simd32x2::from([-1.0, 1.0]) }
}
}
impl RegressiveProduct<MultiVector> for MultiVector {
type Output = MultiVector;
fn regressive_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0.get_f(1)) * other.g0 + Simd32x2::from(self.g0.get_f(0)) * swizzle!(other.g0, 1, 0) * Simd32x2::from([1.0, 0.0]) }
}
}
impl OuterProduct<MultiVector> for MultiVector {
type Output = MultiVector;
fn outer_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0.get_f(0)) * other.g0 + self.g0 * Simd32x2::from(other.g0.get_f(0)) * Simd32x2::from([0.0, 1.0]) }
}
}
impl InnerProduct<MultiVector> for MultiVector {
type Output = MultiVector;
fn inner_product(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0.get_f(0)) * other.g0 + Simd32x2::from(self.g0.get_f(1)) * swizzle!(other.g0, 1, 0) * Simd32x2::from([-1.0, 1.0]) }
}
}
impl LeftContraction<MultiVector> for MultiVector {
type Output = MultiVector;
fn left_contraction(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0.get_f(0)) * other.g0 + Simd32x2::from(self.g0.get_f(1)) * Simd32x2::from(other.g0.get_f(1)) * Simd32x2::from([-1.0, 0.0]) }
}
}
impl RightContraction<MultiVector> for MultiVector {
type Output = MultiVector;
fn right_contraction(self, other: MultiVector) -> MultiVector {
MultiVector { g0: Simd32x2::from(self.g0.get_f(1)) * swizzle!(other.g0, 1, 0) * Simd32x2::from([-1.0, 1.0]) + Simd32x2::from(self.g0.get_f(0)) * Simd32x2::from(other.g0.get_f(0)) * Simd32x2::from([1.0, 0.0]) }
}
}
impl ScalarProduct<MultiVector> for MultiVector {
type Output = Scalar;
fn scalar_product(self, other: MultiVector) -> Scalar {
Scalar { g0: self.g0.get_f(0) * other.g0.get_f(0) - self.g0.get_f(1) * other.g0.get_f(1) }
}
}
impl SquaredMagnitude for MultiVector {
type Output = Scalar;
fn squared_magnitude(self) -> Scalar {
self.scalar_product(self.conjugate())
}
}
impl Magnitude for MultiVector {
type Output = Scalar;
fn magnitude(self) -> Scalar {
Scalar { g0: self.squared_magnitude().g0.sqrt() }
}
}
impl Signum for MultiVector {
type Output = MultiVector;
fn signum(self) -> MultiVector {
self.geometric_product(Scalar { g0: 1.0 / self.magnitude().g0 })
}
}
impl Inverse for MultiVector {
type Output = MultiVector;
fn inverse(self) -> MultiVector {
self.conjugate().geometric_product(Scalar { g0: 1.0 / self.squared_magnitude().g0 })
}
}
impl Mul<MultiVector> for Scalar {
type Output = MultiVector;
fn mul(self, other: MultiVector) -> MultiVector {
self.geometric_product(other)
}
}
impl Div<MultiVector> for Scalar {
type Output = MultiVector;
fn div(self, other: MultiVector) -> MultiVector {
self.geometric_product(other.inverse())
}
}
impl Reflection<MultiVector> for Scalar {
type Output = MultiVector;
fn reflection(self, other: MultiVector) -> MultiVector {
self.geometric_product(other).geometric_product(self)
}
}
impl Transformation<MultiVector> for Scalar {
type Output = MultiVector;
fn transformation(self, other: MultiVector) -> MultiVector {
self.geometric_product(other).geometric_product(self.conjugate())
}
}
impl Mul<Scalar> for Scalar {
type Output = Scalar;
fn mul(self, other: Scalar) -> Scalar {
self.geometric_product(other)
}
}
impl Powi for Scalar {
type Output = Scalar;
fn powi(self, exponent: isize) -> Scalar {
if exponent == 0 {
return Scalar::one();
}
let mut x: Scalar = if exponent < 0 { self.inverse() } else { self };
let mut y: Scalar = Scalar::one();
let mut n: isize = exponent.abs();
while 1 < n {
if n & 1 == 1 {
y = x.geometric_product(y);
}
x = x.geometric_product(x);
n = n >> 1;
}
x.geometric_product(y)
}
}
impl Div<Scalar> for Scalar {
type Output = Scalar;
fn div(self, other: Scalar) -> Scalar {
self.geometric_product(other.inverse())
}
}
impl Reflection<Scalar> for Scalar {
type Output = Scalar;
fn reflection(self, other: Scalar) -> Scalar {
self.geometric_product(other).geometric_product(self)
}
}
impl Transformation<Scalar> for Scalar {
type Output = Scalar;
fn transformation(self, other: Scalar) -> Scalar {
self.geometric_product(other).geometric_product(self.conjugate())
}
}
impl Mul<MultiVector> for MultiVector {
type Output = MultiVector;
fn mul(self, other: MultiVector) -> MultiVector {
self.geometric_product(other)
}
}
impl Powi for MultiVector {
type Output = MultiVector;
fn powi(self, exponent: isize) -> MultiVector {
if exponent == 0 {
return MultiVector::one();
}
let mut x: MultiVector = if exponent < 0 { self.inverse() } else { self };
let mut y: MultiVector = MultiVector::one();
let mut n: isize = exponent.abs();
while 1 < n {
if n & 1 == 1 {
y = x.geometric_product(y);
}
x = x.geometric_product(x);
n = n >> 1;
}
x.geometric_product(y)
}
}
impl Div<MultiVector> for MultiVector {
type Output = MultiVector;
fn div(self, other: MultiVector) -> MultiVector {
self.geometric_product(other.inverse())
}
}
impl Reflection<MultiVector> for MultiVector {
type Output = MultiVector;
fn reflection(self, other: MultiVector) -> MultiVector {
self.geometric_product(other).geometric_product(self)
}
}
impl Transformation<MultiVector> for MultiVector {
type Output = MultiVector;
fn transformation(self, other: MultiVector) -> MultiVector {
self.geometric_product(other).geometric_product(self.conjugate())
}
}
impl Mul<Scalar> for MultiVector {
type Output = MultiVector;
fn mul(self, other: Scalar) -> MultiVector {
self.geometric_product(other)
}
}
impl Div<Scalar> for MultiVector {
type Output = MultiVector;
fn div(self, other: Scalar) -> MultiVector {
self.geometric_product(other.inverse())
}
}
impl Reflection<Scalar> for MultiVector {
type Output = Scalar;
fn reflection(self, other: Scalar) -> Scalar {
self.geometric_product(other).geometric_product(self).into()
}
}
impl Transformation<Scalar> for MultiVector {
type Output = Scalar;
fn transformation(self, other: Scalar) -> Scalar {
self.geometric_product(other).geometric_product(self.conjugate()).into()
}
}