Replaces Scale trait by impl Mul<f32>.

This commit is contained in:
Alexander Meißner 2023-09-20 16:51:28 +02:00
parent c806f94dc1
commit 642d8bdbdb
4 changed files with 21 additions and 41 deletions

View file

@ -657,13 +657,7 @@ impl MultiVectorClass {
name, name,
data_type: geometric_product_result.data_type.clone(), data_type: geometric_product_result.data_type.clone(),
}, },
parameters: vec![ parameters: vec![parameter_a.clone(), parameter_b.clone()],
parameter_a.clone(),
Parameter {
name: "other",
data_type: DataType::SimdVector(1),
},
],
body: vec![AstNode::ReturnStatement { body: vec![AstNode::ReturnStatement {
expression: Box::new(Expression { expression: Box::new(Expression {
size: 1, size: 1,
@ -676,7 +670,7 @@ impl MultiVectorClass {
geometric_product_result.name, geometric_product_result.name,
geometric_product_result.data_type.clone(), geometric_product_result.data_type.clone(),
vec![( vec![(
DataType::MultiVector(parameter_b.multi_vector_class()), parameter_b.data_type.clone(),
Expression { Expression {
size: 1, size: 1,
content: ExpressionContent::InvokeClassMethod( content: ExpressionContent::InvokeClassMethod(

View file

@ -142,8 +142,10 @@ fn main() {
for (parameter_b, pair_trait_implementations) in pair_trait_implementations.values() { for (parameter_b, pair_trait_implementations) in pair_trait_implementations.values() {
if let Some(geometric_product) = pair_trait_implementations.get("GeometricProduct") { if let Some(geometric_product) = pair_trait_implementations.get("GeometricProduct") {
if parameter_b.data_type.is_scalar() { if parameter_b.data_type.is_scalar() {
let scale = MultiVectorClass::derive_scale("Scale", geometric_product, &parameter_a, parameter_b); if !parameter_a.data_type.is_scalar() {
emitter.emit(&scale).unwrap(); let scale = MultiVectorClass::derive_scale("Mul", geometric_product, &parameter_a, parameter_b);
emitter.emit(&scale).unwrap();
}
if let Some(magnitude) = single_trait_implementations.get("Magnitude") { if let Some(magnitude) = single_trait_implementations.get("Magnitude") {
let signum = MultiVectorClass::derive_signum("Signum", geometric_product, magnitude, &parameter_a); let signum = MultiVectorClass::derive_signum("Signum", geometric_product, magnitude, &parameter_a);
emitter.emit(&signum).unwrap(); emitter.emit(&signum).unwrap();

View file

@ -110,14 +110,6 @@ impl Magnitude for f32 {
} }
} }
impl Scale for f32 {
type Output = f32;
fn scale(self, other: f32) -> f32 {
self.geometric_product(other)
}
}
impl Signum for f32 { impl Signum for f32 {
type Output = f32; type Output = f32;
@ -206,7 +198,7 @@ impl Ln for ppga2d::Translator {
fn ln(self) -> ppga2d::IdealPoint { fn ln(self) -> ppga2d::IdealPoint {
let result: ppga2d::IdealPoint = self.into(); let result: ppga2d::IdealPoint = self.into();
result.scale(1.0 / self[0]) result * (1.0 / self[0])
} }
} }
@ -214,7 +206,7 @@ impl Powf for ppga2d::Translator {
type Output = Self; type Output = Self;
fn powf(self, exponent: f32) -> Self { fn powf(self, exponent: f32) -> Self {
self.ln().scale(exponent).exp() (self.ln() * exponent).exp()
} }
} }
@ -253,7 +245,7 @@ impl Powf for ppga2d::Motor {
type Output = Self; type Output = Self;
fn powf(self, exponent: f32) -> Self { fn powf(self, exponent: f32) -> Self {
self.ln().scale(exponent).exp() (self.ln() * exponent).exp()
} }
} }
@ -270,7 +262,7 @@ impl Ln for ppga3d::Translator {
fn ln(self) -> ppga3d::IdealPoint { fn ln(self) -> ppga3d::IdealPoint {
let result: ppga3d::IdealPoint = self.into(); let result: ppga3d::IdealPoint = self.into();
result.scale(1.0 / self[0]) result * (1.0 / self[0])
} }
} }
@ -278,7 +270,7 @@ impl Powf for ppga3d::Translator {
type Output = Self; type Output = Self;
fn powf(self, exponent: f32) -> Self { fn powf(self, exponent: f32) -> Self {
self.ln().scale(exponent).exp() (self.ln() * exponent).exp()
} }
} }
@ -322,7 +314,7 @@ impl Powf for ppga3d::Motor {
type Output = Self; type Output = Self;
fn powf(self, exponent: f32) -> Self { fn powf(self, exponent: f32) -> Self {
self.ln().scale(exponent).exp() (self.ln() * exponent).exp()
} }
} }
@ -426,12 +418,6 @@ pub trait Transformation<T> {
fn transformation(self, other: T) -> Self::Output; fn transformation(self, other: T) -> Self::Output;
} }
/// Geometric product with a scalar
pub trait Scale {
type Output;
fn scale(self, other: f32) -> Self::Output;
}
/// Square of the magnitude /// Square of the magnitude
pub trait SquaredMagnitude { pub trait SquaredMagnitude {
type Output; type Output;

View file

@ -1,9 +1,7 @@
//! Solves polynomials with real valued coefficients up to degree 4 //! Solves polynomials with real valued coefficients up to degree 4
#![allow(clippy::many_single_char_names)] #![allow(clippy::many_single_char_names)]
use crate::{ use crate::{epga1d::*, GeometricProduct, GeometricQuotient, Powf, Reversal, SquaredMagnitude};
epga1d::*, GeometricProduct, GeometricQuotient, Powf, Reversal, Scale, SquaredMagnitude,
};
/// Represents a complex root as homogeneous coordinates /// Represents a complex root as homogeneous coordinates
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -94,13 +92,13 @@ pub fn solve_cubic(coefficients: [f32; 4], error_margin: f32) -> (f32, Vec<Root>
let mut solutions = Vec::with_capacity(3); let mut solutions = Vec::with_capacity(3);
let discriminant = d[1].powi(2) - 4.0 * d[0].powi(3); let discriminant = d[1].powi(2) - 4.0 * d[0].powi(3);
let c = discriminant.sqrt(); let c = discriminant.sqrt();
let c = ((c + ComplexNumber::new(if c + d[1] == 0.0 { -d[1] } else { d[1] }, 0.0)).scale(0.5)) let c = ((c + ComplexNumber::new(if c + d[1] == 0.0 { -d[1] } else { d[1] }, 0.0)) * 0.5)
.powf(1.0 / 3.0); .powf(1.0 / 3.0);
for root_of_unity in &ROOTS_OF_UNITY_3 { for root_of_unity in &ROOTS_OF_UNITY_3 {
let ci = c.geometric_product(*root_of_unity); let ci = c.geometric_product(*root_of_unity);
let denominator = ci.scale(3.0 * coefficients[3]); let denominator = ci * (3.0 * coefficients[3]);
let numerator = let numerator =
(ci.scale(-coefficients[2]) - ci.geometric_product(ci) - ComplexNumber::new(d[0], 0.0)) (ci * -coefficients[2] - ci.geometric_product(ci) - ComplexNumber::new(d[0], 0.0))
.geometric_product(denominator.reversal()); .geometric_product(denominator.reversal());
solutions.push(Root { solutions.push(Root {
numerator, numerator,
@ -144,19 +142,19 @@ pub fn solve_quartic(coefficients: [f32; 5], error_margin: f32) -> (f32, Vec<Roo
]; ];
let discriminant = d[1].powi(2) - 4.0 * d[0].powi(3); let discriminant = d[1].powi(2) - 4.0 * d[0].powi(3);
let c = discriminant.sqrt(); let c = discriminant.sqrt();
let c = ((c + ComplexNumber::new(if c + d[1] == 0.0 { -d[1] } else { d[1] }, 0.0)).scale(0.5)) let c = ((c + ComplexNumber::new(if c + d[1] == 0.0 { -d[1] } else { d[1] }, 0.0)) * 0.5)
.powf(1.0 / 3.0); .powf(1.0 / 3.0);
let e = ((c + ComplexNumber::new(d[0], 0.0).geometric_quotient(c)) let e = ((c + ComplexNumber::new(d[0], 0.0).geometric_quotient(c))
.scale(1.0 / (3.0 * coefficients[4])) * (1.0 / (3.0 * coefficients[4]))
- ComplexNumber::new(p * 2.0 / 3.0, 0.0)) - ComplexNumber::new(p * 2.0 / 3.0, 0.0))
.powf(0.5) .powf(0.5)
.scale(0.5); * 0.5;
let mut solutions = Vec::with_capacity(4); let mut solutions = Vec::with_capacity(4);
for i in 0..4 { for i in 0..4 {
let f = (e.geometric_product(e).scale(-4.0) - ComplexNumber::new(2.0 * p, 0.0) let f = (e.geometric_product(e) * -4.0 - ComplexNumber::new(2.0 * p, 0.0)
+ ComplexNumber::new(if i & 2 == 0 { q } else { -q }, 0.0).geometric_quotient(e)) + ComplexNumber::new(if i & 2 == 0 { q } else { -q }, 0.0).geometric_quotient(e))
.powf(0.5) .powf(0.5)
.scale(0.5); * 0.5;
let g = ComplexNumber::new(-coefficients[3] / (4.0 * coefficients[4]), 0.0) let g = ComplexNumber::new(-coefficients[3] / (4.0 * coefficients[4]), 0.0)
+ if i & 2 == 0 { -e } else { e } + if i & 2 == 0 { -e } else { e }
+ if i & 1 == 0 { -f } else { f }; + if i & 1 == 0 { -f } else { f };