Implements ln(), exp(), powf() for epga1d::ComplexNumber, ppga2d::Motor and ppga3d::Motor.
This commit is contained in:
parent
dd2fa358d6
commit
4eca234241
1 changed files with 170 additions and 5 deletions
175
src/lib.rs
175
src/lib.rs
|
|
@ -46,19 +46,166 @@ impl epga1d::ComplexNumber {
|
||||||
self.g0[1]
|
self.g0[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_polar(magnitude: f32, angle: f32) -> Self {
|
pub fn from_polar(magnitude: f32, argument: f32) -> Self {
|
||||||
Self::new(magnitude * angle.cos(), magnitude * angle.sin())
|
Self::new(magnitude * argument.cos(), magnitude * argument.sin())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn arg(self) -> f32 {
|
pub fn arg(self) -> f32 {
|
||||||
self.imaginary().atan2(self.real())
|
self.imaginary().atan2(self.real())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn powf(self, exponent: f32) -> Self {
|
impl Exp for epga1d::ComplexNumber {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn exp(self) -> Self {
|
||||||
|
Self::from_polar(self.g0[0].exp(), self.g0[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ln for epga1d::ComplexNumber {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn ln(self) -> Self {
|
||||||
|
Self::new(self.magnitude().g0.ln(), self.arg())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Powf for epga1d::ComplexNumber {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn powf(self, exponent: f32) -> Self {
|
||||||
Self::from_polar(self.magnitude().g0.powf(exponent), self.arg() * exponent)
|
Self::from_polar(self.magnitude().g0.powf(exponent), self.arg() * exponent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Exp for ppga2d::Point {
|
||||||
|
type Output = ppga2d::Motor;
|
||||||
|
|
||||||
|
fn exp(self) -> ppga2d::Motor {
|
||||||
|
let det = self.g0[0] * self.g0[0];
|
||||||
|
if det <= 0.0 {
|
||||||
|
return ppga2d::Motor {
|
||||||
|
g0: simd::Simd32x4 {
|
||||||
|
f32x4: [1.0, 0.0, self.g0[1], self.g0[2]],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let a = det.sqrt();
|
||||||
|
let c = a.cos();
|
||||||
|
let s = a.sin() / a;
|
||||||
|
let g0 = simd::Simd32x3::from(s) * self.g0;
|
||||||
|
ppga2d::Motor {
|
||||||
|
g0: simd::Simd32x4 {
|
||||||
|
f32x4: [c, g0[0], g0[1], g0[2]],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ln for ppga2d::Motor {
|
||||||
|
type Output = ppga2d::Point;
|
||||||
|
|
||||||
|
fn ln(self) -> ppga2d::Point {
|
||||||
|
let det = 1.0 - self.g0[0] * self.g0[0];
|
||||||
|
if det <= 0.0 {
|
||||||
|
return ppga2d::Point {
|
||||||
|
g0: simd::Simd32x3 {
|
||||||
|
f32x3: [0.0, self.g0[2], self.g0[3]],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let a = 1.0 / det;
|
||||||
|
let b = self.g0[0].acos() * a.sqrt();
|
||||||
|
let g0 = simd::Simd32x4::from(b) * self.g0;
|
||||||
|
return ppga2d::Point {
|
||||||
|
g0: simd::Simd32x3 {
|
||||||
|
f32x3: [g0[1], g0[2], g0[3]],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Powf for ppga2d::Motor {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn powf(self, exponent: f32) -> Self {
|
||||||
|
(ppga2d::Scalar { g0: exponent } * self.ln()).exp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Exp for ppga3d::Line {
|
||||||
|
type Output = ppga3d::Motor;
|
||||||
|
|
||||||
|
fn exp(self) -> ppga3d::Motor {
|
||||||
|
let det = self.g1[0] * self.g1[0] + self.g1[1] * self.g1[1] + self.g1[2] * self.g1[2];
|
||||||
|
if det <= 0.0 {
|
||||||
|
return ppga3d::Motor {
|
||||||
|
g0: simd::Simd32x4 {
|
||||||
|
f32x4: [1.0, 0.0, 0.0, 0.0],
|
||||||
|
},
|
||||||
|
g1: simd::Simd32x4 {
|
||||||
|
f32x4: [0.0, self.g0[0], self.g0[1], self.g0[2]],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let a = det.sqrt();
|
||||||
|
let c = a.cos();
|
||||||
|
let s = a.sin() / a;
|
||||||
|
let m = self.g0[0] * self.g1[0] + self.g0[1] * self.g1[1] + self.g0[2] * self.g1[2];
|
||||||
|
let t = m / det * (c - s);
|
||||||
|
let g0 = simd::Simd32x3::from(s) * self.g1;
|
||||||
|
let g1 = simd::Simd32x3::from(s) * self.g0 + simd::Simd32x3::from(t) * self.g1;
|
||||||
|
ppga3d::Motor {
|
||||||
|
g0: simd::Simd32x4 {
|
||||||
|
f32x4: [c, g0[0], g0[1], g0[2]],
|
||||||
|
},
|
||||||
|
g1: simd::Simd32x4 {
|
||||||
|
f32x4: [s * m, g1[0], g1[1], g1[2]],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ln for ppga3d::Motor {
|
||||||
|
type Output = ppga3d::Line;
|
||||||
|
|
||||||
|
fn ln(self) -> ppga3d::Line {
|
||||||
|
let det = 1.0 - self.g0[0] * self.g0[0];
|
||||||
|
if det <= 0.0 {
|
||||||
|
return ppga3d::Line {
|
||||||
|
g0: simd::Simd32x3 {
|
||||||
|
f32x3: [self.g1[1], self.g1[2], self.g1[3]],
|
||||||
|
},
|
||||||
|
g1: simd::Simd32x3 {
|
||||||
|
f32x3: [0.0, 0.0, 0.0],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let a = 1.0 / det;
|
||||||
|
let b = self.g0[0].acos() * a.sqrt();
|
||||||
|
let c = a * self.g1[0] * (1.0 - self.g0[0] * b);
|
||||||
|
let g0 = simd::Simd32x4::from(b) * self.g1 + simd::Simd32x4::from(c) * self.g0;
|
||||||
|
let g1 = simd::Simd32x4::from(b) * self.g0;
|
||||||
|
return ppga3d::Line {
|
||||||
|
g0: simd::Simd32x3 {
|
||||||
|
f32x3: [g0[1], g0[2], g0[3]],
|
||||||
|
},
|
||||||
|
g1: simd::Simd32x3 {
|
||||||
|
f32x3: [g1[1], g1[2], g1[3]],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Powf for ppga3d::Motor {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn powf(self, exponent: f32) -> Self {
|
||||||
|
(ppga3d::Scalar { g0: exponent } * self.ln()).exp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// All elements set to `0.0`
|
/// All elements set to `0.0`
|
||||||
pub trait Zero {
|
pub trait Zero {
|
||||||
fn zero() -> Self;
|
fn zero() -> Self;
|
||||||
|
|
@ -175,14 +322,32 @@ pub trait Signum {
|
||||||
fn signum(self) -> Self::Output;
|
fn signum(self) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exponentiation by scalar `-1.0`
|
/// Raises a number to the scalar power of `-1.0`
|
||||||
pub trait Inverse {
|
pub trait Inverse {
|
||||||
type Output;
|
type Output;
|
||||||
fn inverse(self) -> Self::Output;
|
fn inverse(self) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exponentiation by a scalar integer
|
/// The natural logarithm
|
||||||
|
pub trait Ln {
|
||||||
|
type Output;
|
||||||
|
fn ln(self) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The exponential function
|
||||||
|
pub trait Exp {
|
||||||
|
type Output;
|
||||||
|
fn exp(self) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raises a number to an integer scalar power
|
||||||
pub trait Powi {
|
pub trait Powi {
|
||||||
type Output;
|
type Output;
|
||||||
fn powi(self, exponent: isize) -> Self::Output;
|
fn powi(self, exponent: isize) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Raises a number to an floating point scalar power
|
||||||
|
pub trait Powf {
|
||||||
|
type Output;
|
||||||
|
fn powf(self, exponent: f32) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue