From 0224b1b604b9da2bd2ae4e42f3a8b809d4553d24 Mon Sep 17 00:00:00 2001 From: Mateusz Kowalczyk Date: Thu, 29 Aug 2024 14:29:31 +0900 Subject: [PATCH] Mark things inline --- src/log_poly.rs | 52 ++++++++++++++++++++ src/piecewise.rs | 30 ++++++++++++ src/poly.rs | 120 +++++++++++++++++++++++++++++++++++++++++++++++ src/spline.rs | 1 + 4 files changed, 203 insertions(+) diff --git a/src/log_poly.rs b/src/log_poly.rs index 09411b1..b6fa47e 100644 --- a/src/log_poly.rs +++ b/src/log_poly.rs @@ -15,24 +15,28 @@ pub struct Log(pub T); impl> Mul for Log { type Output = Log; + #[inline] fn mul(self, rhs: Scalar) -> Self::Output { Log(self.0 * rhs) } } impl> MulAssign for Log { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0 *= rhs; } } impl Evaluate for Log { + #[inline] fn evaluate(&self, v: f64) -> f64 { self.0.evaluate(v.ln()) } } impl Translate for Log { + #[inline] fn translate(&mut self, v: f64) { self.0.translate(v); } @@ -43,10 +47,12 @@ where T: PartialEq + AbsDiffEq, { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } @@ -56,10 +62,12 @@ impl RelativeEq for Log where T: AbsDiffEq + RelativeEq, { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -76,6 +84,7 @@ pub struct IntOfLog { } impl Default for IntOfLog { + #[inline] fn default() -> Self { IntOfLog { k: 0.0, @@ -86,6 +95,7 @@ impl Default for IntOfLog { impl Add for IntOfLog { type Output = IntOfLog; + #[inline] fn add(self, other: Self) -> Self::Output { IntOfLog { k: self.k + other.k, @@ -103,6 +113,7 @@ where T: Mul, { type Output = IntOfLog; + #[inline] fn mul(self, rhs: Scalar) -> Self::Output { IntOfLog { k: rhs * self.k, @@ -112,6 +123,7 @@ where } impl> MulAssign for IntOfLog { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.k *= rhs; self.poly *= rhs; @@ -120,6 +132,7 @@ impl> MulAssign for IntOfLog { impl Neg for IntOfLog { type Output = IntOfLog; + #[inline] fn neg(self) -> Self::Output { IntOfLog { k: self.k.neg(), @@ -129,12 +142,14 @@ impl Neg for IntOfLog { } impl Evaluate for IntOfLog { + #[inline] fn evaluate(&self, v: f64) -> f64 { self.k + self.poly.evaluate(v.ln()) } } impl Translate for IntOfLog { + #[inline] fn translate(&mut self, v: f64) { self.k += v; } @@ -145,10 +160,12 @@ where T: PartialEq + AbsDiffEq, { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.k.abs_diff_eq(&other.k, eps) && self.poly.abs_diff_eq(&other.poly, eps) } @@ -158,10 +175,12 @@ impl RelativeEq for IntOfLog where T: AbsDiffEq + RelativeEq, { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.k.relative_eq(&other.k, eps, max_relative) && self.poly.relative_eq(&other.poly, eps, max_relative) @@ -182,6 +201,7 @@ pub struct IntOfLogPoly4 { impl Add for IntOfLogPoly4 { type Output = Self; + #[inline] fn add(mut self, other: Self) -> Self::Output { self.k += other.k; self.coeffs @@ -195,6 +215,7 @@ impl Add for IntOfLogPoly4 { impl Add<&IntOfLogPoly4> for &IntOfLogPoly4 { type Output = IntOfLogPoly4; + #[inline] fn add(self, other: &IntOfLogPoly4) -> Self::Output { *self + *other } @@ -202,6 +223,7 @@ impl Add<&IntOfLogPoly4> for &IntOfLogPoly4 { impl Neg for IntOfLogPoly4 { type Output = Self; + #[inline] fn neg(self) -> Self::Output { IntOfLogPoly4 { k: self.k.neg(), @@ -218,6 +240,7 @@ impl Neg for IntOfLogPoly4 { impl Mul for IntOfLogPoly4 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self::Output { IntOfLogPoly4 { k: self.k * rhs, @@ -234,6 +257,7 @@ impl Mul for IntOfLogPoly4 { impl Sub for IntOfLogPoly4 { type Output = Self; + #[inline] fn sub(mut self, other: Self) -> Self::Output { self.k -= other.k; self.coeffs @@ -247,6 +271,7 @@ impl Sub for IntOfLogPoly4 { impl Sub<&IntOfLogPoly4> for &IntOfLogPoly4 { type Output = IntOfLogPoly4; + #[inline] fn sub(self, other: &IntOfLogPoly4) -> Self::Output { *self - *other } @@ -254,10 +279,12 @@ impl Sub<&IntOfLogPoly4> for &IntOfLogPoly4 { impl AbsDiffEq for IntOfLogPoly4 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.k.abs_diff_eq(&other.k, eps) && self.coeffs.abs_diff_eq(&other.coeffs, eps) @@ -266,10 +293,12 @@ impl AbsDiffEq for IntOfLogPoly4 { } impl RelativeEq for IntOfLogPoly4 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.k.relative_eq(&other.k, eps, max_relative) && self.coeffs.relative_eq(&other.coeffs, eps, max_relative) @@ -279,6 +308,7 @@ impl RelativeEq for IntOfLogPoly4 { // Hide ugly taylor expansion stuff mod taylor { + #[inline] fn exp_5_tail_anal(x: f64) -> f64 { let x = x.recip(); @@ -299,6 +329,7 @@ mod taylor { t2.mul_add(x4, t1.mul_add(x2, t0)) } + #[inline] fn exp_5_tail_taylor(x: f64) -> f64 { // (((C0+C1x) + (C2+C3x)x2) + ((C4+C5x) + (C6+C7x)x2)x4) + (((C8+C9x) + (C10+C11x)x2) + ((C12+C13x) + (C14+C15x)x2)x4)x8 let c0: f64 = 1.0 / 120.0; @@ -363,6 +394,7 @@ mod taylor { bot.mul_add(x8, top) } + #[inline] pub fn exp_5_taylor(x: f64) -> f64 { const LOWER_THRES: f64 = -1.71; const UPPER_THRES: f64 = 1.72; @@ -397,6 +429,7 @@ mod taylor { } impl Evaluate for IntOfLogPoly4 { + #[inline] fn evaluate(&self, v: f64) -> f64 { let x = v.ln().neg(); @@ -423,6 +456,7 @@ impl Evaluate for IntOfLogPoly4 { } impl Translate for IntOfLogPoly4 { + #[inline] fn translate(&mut self, v: f64) { self.k += v; } @@ -430,6 +464,7 @@ impl Translate for IntOfLogPoly4 { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { IntOfLog { k: 0.0, @@ -437,6 +472,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -446,6 +482,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let b = (self.0).0[1]; let a = (self.0).0[0] - b; @@ -455,6 +492,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -464,6 +502,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let c = (self.0).0[2]; let b = (self.0).0[1] - 2.0 * c; @@ -474,6 +513,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -483,6 +523,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let d = (self.0).0[3]; let c = (self.0).0[2] - 3.0 * d; @@ -494,6 +535,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -504,6 +546,7 @@ impl HasIntegral for Log { // NB: special case impl HasIntegral for Log { type IntegralOf = IntOfLogPoly4; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let a = (self.0).0[0].neg(); let b = (a + (self.0).0[1]) * (1.0 / 2.0); @@ -517,6 +560,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -526,6 +570,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let f = (self.0).0[5]; let e = (self.0).0[4] - 5.0 * f; @@ -539,6 +584,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -548,6 +594,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let g = (self.0).0[6]; let f = (self.0).0[5] - 6.0 * g; @@ -562,6 +609,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -571,6 +619,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let h = (self.0).0[7]; let g = (self.0).0[6] - 7.0 * h; @@ -586,6 +635,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -595,6 +645,7 @@ impl HasIntegral for Log { impl HasIntegral for Log { type IntegralOf = IntOfLog; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let i = (self.0).0[8]; let h = (self.0).0[7] - 8.0 * i; @@ -611,6 +662,7 @@ impl HasIntegral for Log { } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); diff --git a/src/piecewise.rs b/src/piecewise.rs index 9fbcf3e..67feea6 100644 --- a/src/piecewise.rs +++ b/src/piecewise.rs @@ -22,6 +22,7 @@ pub struct Segment { } impl Evaluate for Segment { + #[inline] fn evaluate(&self, v: f64) -> f64 { self.poly.evaluate(v) } @@ -32,6 +33,7 @@ where T: Mul + Copy, { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self::Output { Segment { end: self.end, @@ -41,12 +43,14 @@ where } impl> MulAssign for Segment { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.poly *= rhs } } impl> MulAssign for &mut Segment { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.poly *= rhs } @@ -54,6 +58,7 @@ impl> MulAssign for &mut Segment { impl HasDerivative for Segment { type DerivativeOf = Segment; + #[inline] fn derivative(&self) -> Self::DerivativeOf { Segment { end: self.end, @@ -63,6 +68,7 @@ impl HasDerivative for Segment { } impl Translate for Segment { + #[inline] fn translate(&mut self, v: f64) { self.poly.translate(v); } @@ -74,12 +80,14 @@ where T::IntegralOf: Translate, { type IntegralOf = Segment; + #[inline] fn indefinite(&self) -> Self::IntegralOf { Segment { end: self.end, poly: self.poly.indefinite(), } } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -92,10 +100,12 @@ where T: AbsDiffEq, { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.end.abs_diff_eq(&other.end, eps) && self.poly.abs_diff_eq(&other.poly, eps) } @@ -105,10 +115,12 @@ impl RelativeEq for Segment where T: AbsDiffEq + RelativeEq, { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.end.relative_eq(&other.end, eps, max_relative) && self.poly.relative_eq(&other.poly, eps, max_relative) @@ -204,10 +216,12 @@ where T: PartialEq + AbsDiffEq, { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.segments.abs_diff_eq(&other.segments, eps) } @@ -217,10 +231,12 @@ impl RelativeEq for Piecewise where T: AbsDiffEq + RelativeEq, { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.segments .relative_eq(&other.segments, eps, max_relative) @@ -228,6 +244,7 @@ where } impl Default for Piecewise { + #[inline] fn default() -> Self { Piecewise { segments: Vec::new(), @@ -240,6 +257,7 @@ where Segment: Mul> + Copy, { type Output = Self; + #[inline] fn mul(mut self, rhs: f64) -> Self::Output { for seg in &mut self.segments { *seg = *seg * rhs; @@ -252,6 +270,7 @@ impl> MulAssign for Piecewise where Segment: MulAssign, { + #[inline] fn mul_assign(&mut self, rhs: f64) { for mut seg in &mut self.segments { seg *= rhs; @@ -264,6 +283,7 @@ where T: Neg + Copy, { type Output = Self; + #[inline] fn neg(mut self) -> Self::Output { for seg in &mut self.segments { seg.poly = seg.poly.neg(); @@ -277,6 +297,7 @@ where &'a T: Add<&'b T, Output = T>, { type Output = Piecewise; + #[inline] fn add(self, other: &'b Piecewise) -> Self::Output { let mut res = Vec::with_capacity(self.segments.len() + other.segments.len() - 1); @@ -356,6 +377,7 @@ impl<'a, T: Evaluate> PiecewiseEvaluator<'a, T> { /// /// Assumes that segments are sorted properly: you won't get undefined /// behaviour if they aren't, but the results might be strange. + #[inline] pub fn new(segments: &'a [Segment]) -> Self { let (last, front) = segments.split_last().expect("no segments to pick from"); PiecewiseEvaluator { @@ -371,6 +393,7 @@ impl<'a, T: Evaluate> PiecewiseEvaluator<'a, T> { // Does not live in Evaluated as types differ in mutability. I // think the evaluate API needs fixing to support this with // instances for references. + #[inline] pub fn evaluate(&mut self, x: f64) -> f64 { // If the new evaluation is for value higher than previous // one, we want to start searching for the segment from the @@ -455,6 +478,7 @@ impl<'a, T: Evaluate> PiecewiseEvaluator<'a, T> { } impl Evaluate for Piecewise { + #[inline] fn evaluate(&self, x: f64) -> f64 { assert!(!self.segments.is_empty(), "no segments to pick from"); match self.segments.iter().position(|seg| seg.end > x) { @@ -470,6 +494,7 @@ where &'a T: Sub<&'b T, Output = T>, { type Output = Piecewise; + #[inline] fn sub(self, other: &'b Piecewise) -> Self::Output { let mut res = Vec::with_capacity(self.segments.len() + other.segments.len() - 1); @@ -533,6 +558,7 @@ impl Piecewise { /// points. When the latter is sufficiently densely wrt the /// former, this is faster than doing a binary search of the /// segments every time, as evaluate does. + #[inline] pub fn evaluate_v<'a, 'b, I>(&'a self, xs: I) -> impl Iterator + 'a where I: IntoIterator, @@ -561,6 +587,7 @@ where T: HasDerivative, { type DerivativeOf = Piecewise; + #[inline] fn derivative(&self) -> Self::DerivativeOf { Piecewise { segments: self.segments.iter().map(|seg| seg.derivative()).collect(), @@ -574,6 +601,7 @@ where T::IntegralOf: Translate, { type IntegralOf = Piecewise; + #[inline] fn indefinite(&self) -> Self::IntegralOf { if self.segments.is_empty() { return Default::default(); @@ -597,6 +625,7 @@ where } // TODO: slow when using iter! + #[inline] fn integral(&self, knot0: Knot) -> Self::IntegralOf { // Slightly slower than manually inlined version... but only slightly; // perhaps come back to this. @@ -607,6 +636,7 @@ where } impl Translate for Piecewise { + #[inline] fn translate(&mut self, v: f64) { for seg in &mut self.segments { seg.translate(v); diff --git a/src/poly.rs b/src/poly.rs index dd9bb81..c2e3877 100644 --- a/src/poly.rs +++ b/src/poly.rs @@ -53,6 +53,7 @@ pub trait Translate { #[derive(Debug, PartialEq, Clone, Arbitrary)] pub struct PolyN(pub Vec); impl Evaluate for PolyN { + #[inline] fn evaluate(&self, x: f64) -> f64 { let mut iter = self.0.iter().rev(); match iter.next() { @@ -62,6 +63,7 @@ impl Evaluate for PolyN { } } impl Translate for PolyN { + #[inline] fn translate(&mut self, v: f64) { match self.0.get_mut(0) { None => self.0.push(v), @@ -72,20 +74,24 @@ impl Translate for PolyN { impl AbsDiffEq for PolyN { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for PolyN { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -101,27 +107,32 @@ impl RelativeEq for PolyN { )] pub struct Poly0(pub f64); impl Evaluate for Poly0 { + #[inline] fn evaluate(&self, _: f64) -> f64 { self.0 } } impl HasDerivative for Poly0 { type DerivativeOf = Poly0; + #[inline] fn derivative(&self) -> Self::DerivativeOf { Poly0(0.0) } } impl Translate for Poly0 { + #[inline] fn translate(&mut self, v: f64) { self.0 += v } } impl HasIntegral for Poly0 { type IntegralOf = Poly1; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [0.0, self.0]; Poly1(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -131,12 +142,14 @@ impl HasIntegral for Poly0 { impl Mul for Poly0 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly0(self.0 * rhs) } } impl MulAssign for Poly0 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0 *= rhs; } @@ -144,12 +157,14 @@ impl MulAssign for Poly0 { impl Neg for Poly0 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly0 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly0(self.0 + other.0) } @@ -157,20 +172,24 @@ impl Add for Poly0 { impl AbsDiffEq for Poly0 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly0 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -186,6 +205,7 @@ impl RelativeEq for Poly0 { )] pub struct Poly1(pub [f64; 2]); impl Evaluate for Poly1 { + #[inline] fn evaluate(&self, x: f64) -> f64 { let c = self.0; c[1].mul_add(x, c[0]) @@ -193,21 +213,25 @@ impl Evaluate for Poly1 { } impl HasDerivative for Poly1 { type DerivativeOf = Poly0; + #[inline] fn derivative(&self) -> Self::DerivativeOf { Poly0(self.0[1]) } } impl Translate for Poly1 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly1 { type IntegralOf = Poly2; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [0.0, self.0[0], self.0[1] / 2.0]; Poly2(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -216,12 +240,14 @@ impl HasIntegral for Poly1 { } impl Mul for Poly1 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly1([self.0[0] * rhs, self.0[1] * rhs]) } } impl MulAssign for Poly1 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -229,12 +255,14 @@ impl MulAssign for Poly1 { impl Neg for Poly1 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly1 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly1([self.0[0] + other.0[0], self.0[1] + other.0[1]]) } @@ -242,20 +270,24 @@ impl Add for Poly1 { impl AbsDiffEq for Poly1 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly1 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -271,6 +303,7 @@ impl RelativeEq for Poly1 { )] pub struct Poly2(pub [f64; 3]); impl Evaluate for Poly2 { + #[inline] fn evaluate(&self, x: f64) -> f64 { let x2 = x * x; let c = self.0; @@ -279,6 +312,7 @@ impl Evaluate for Poly2 { } impl HasDerivative for Poly2 { type DerivativeOf = Poly1; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [coeffs[1], 2.0 * coeffs[2]]; @@ -286,16 +320,19 @@ impl HasDerivative for Poly2 { } } impl Translate for Poly2 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly2 { type IntegralOf = Poly3; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [0.0, self.0[0], self.0[1] / 2.0, self.0[2] / 3.0]; Poly3(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -304,12 +341,14 @@ impl HasIntegral for Poly2 { } impl Mul for Poly2 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly2([self.0[0] * rhs, self.0[1] * rhs, self.0[2] * rhs]) } } impl MulAssign for Poly2 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -317,12 +356,14 @@ impl MulAssign for Poly2 { impl Neg for Poly2 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly2 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly2([ self.0[0] + other.0[0], @@ -334,20 +375,24 @@ impl Add for Poly2 { impl AbsDiffEq for Poly2 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly2 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -363,6 +408,7 @@ impl RelativeEq for Poly2 { )] pub struct Poly3(pub [f64; 4]); impl Evaluate for Poly3 { + #[inline] fn evaluate(&self, x: f64) -> f64 { // P3(x) = (C0 + C1x) + (C2 + C3x) x2 let x2 = x * x; @@ -376,6 +422,7 @@ impl Evaluate for Poly3 { } impl HasDerivative for Poly3 { type DerivativeOf = Poly2; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [coeffs[1], 2.0 * coeffs[2], 3.0 * coeffs[3]]; @@ -383,12 +430,14 @@ impl HasDerivative for Poly3 { } } impl Translate for Poly3 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly3 { type IntegralOf = Poly4; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [ 0.0, @@ -399,6 +448,7 @@ impl HasIntegral for Poly3 { ]; Poly4(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -407,6 +457,7 @@ impl HasIntegral for Poly3 { } impl Mul for Poly3 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly3([ self.0[0] * rhs, @@ -418,6 +469,7 @@ impl Mul for Poly3 { } impl MulAssign for Poly3 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -425,12 +477,14 @@ impl MulAssign for Poly3 { impl Neg for Poly3 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly3 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly3([ self.0[0] + other.0[0], @@ -443,20 +497,24 @@ impl Add for Poly3 { impl AbsDiffEq for Poly3 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly3 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -472,6 +530,7 @@ impl RelativeEq for Poly3 { )] pub struct Poly4(pub [f64; 5]); impl Evaluate for Poly4 { + #[inline] fn evaluate(&self, x: f64) -> f64 { // P4(x) = (C0 + C1x) + (C2 + C3x) x2 + C4x4 let c = self.0; @@ -489,6 +548,7 @@ impl Evaluate for Poly4 { } impl HasDerivative for Poly4 { type DerivativeOf = Poly3; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [coeffs[1], 2.0 * coeffs[2], 3.0 * coeffs[3], 4.0 * coeffs[4]]; @@ -496,12 +556,14 @@ impl HasDerivative for Poly4 { } } impl Translate for Poly4 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly4 { type IntegralOf = Poly5; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [ 0.0, @@ -513,6 +575,7 @@ impl HasIntegral for Poly4 { ]; Poly5(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -521,6 +584,7 @@ impl HasIntegral for Poly4 { } impl Mul for Poly4 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly4([ self.0[0] * rhs, @@ -533,6 +597,7 @@ impl Mul for Poly4 { } impl MulAssign for Poly4 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -540,12 +605,14 @@ impl MulAssign for Poly4 { impl Neg for Poly4 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly4 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly4([ self.0[0] + other.0[0], @@ -559,20 +626,24 @@ impl Add for Poly4 { impl AbsDiffEq for Poly4 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly4 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -588,6 +659,7 @@ impl RelativeEq for Poly4 { )] pub struct Poly5(pub [f64; 6]); impl Evaluate for Poly5 { + #[inline] fn evaluate(&self, x: f64) -> f64 { // P5(x) = (C0 + C1x) + (C2 + C3x) x2 + (C4 + C5x) x4 let c = self.0; @@ -606,6 +678,7 @@ impl Evaluate for Poly5 { impl HasDerivative for Poly5 { type DerivativeOf = Poly4; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [ @@ -619,12 +692,14 @@ impl HasDerivative for Poly5 { } } impl Translate for Poly5 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly5 { type IntegralOf = Poly6; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [ 0.0, @@ -637,6 +712,7 @@ impl HasIntegral for Poly5 { ]; Poly6(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -645,6 +721,7 @@ impl HasIntegral for Poly5 { } impl Mul for Poly5 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly5([ self.0[0] * rhs, @@ -658,6 +735,7 @@ impl Mul for Poly5 { } impl MulAssign for Poly5 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -665,12 +743,14 @@ impl MulAssign for Poly5 { impl Neg for Poly5 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly5 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly5([ self.0[0] + other.0[0], @@ -685,20 +765,24 @@ impl Add for Poly5 { impl AbsDiffEq for Poly5 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly5 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -714,6 +798,7 @@ impl RelativeEq for Poly5 { )] pub struct Poly6(pub [f64; 7]); impl Evaluate for Poly6 { + #[inline] fn evaluate(&self, x: f64) -> f64 { // P6(x) = (C0 + C1x) + (C2 + C3x) x2 + ((C4 + C5x) + C6x2)x4 let x2 = x * x; @@ -729,6 +814,7 @@ impl Evaluate for Poly6 { } impl HasDerivative for Poly6 { type DerivativeOf = Poly5; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [ @@ -743,12 +829,14 @@ impl HasDerivative for Poly6 { } } impl Translate for Poly6 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly6 { type IntegralOf = Poly7; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [ 0.0, @@ -762,6 +850,7 @@ impl HasIntegral for Poly6 { ]; Poly7(dst) } + #[inline] fn integral(&self, knot: Knot) -> Self::IntegralOf { let mut indef = self.indefinite(); indef.translate(knot.y - indef.evaluate(knot.x)); @@ -770,6 +859,7 @@ impl HasIntegral for Poly6 { } impl Mul for Poly6 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly6([ self.0[0] * rhs, @@ -784,6 +874,7 @@ impl Mul for Poly6 { } impl MulAssign for Poly6 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -791,12 +882,14 @@ impl MulAssign for Poly6 { impl Neg for Poly6 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly6 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly6([ self.0[0] + other.0[0], @@ -812,20 +905,24 @@ impl Add for Poly6 { impl AbsDiffEq for Poly6 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly6 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -841,6 +938,7 @@ impl RelativeEq for Poly6 { )] pub struct Poly7(pub [f64; 8]); impl Evaluate for Poly7 { + #[inline] fn evaluate(&self, x: f64) -> f64 { // P7(x) = (C0 + C1x) + (C2 + C3x) x2 + ((C4 + C5x) + (C6 + C7x) x2)x4 let c = self.0; @@ -860,6 +958,7 @@ impl Evaluate for Poly7 { } impl HasDerivative for Poly7 { type DerivativeOf = Poly6; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [ @@ -875,12 +974,14 @@ impl HasDerivative for Poly7 { } } impl Translate for Poly7 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl HasIntegral for Poly7 { type IntegralOf = Poly8; + #[inline] fn indefinite(&self) -> Self::IntegralOf { let dst = [ 0.0, @@ -903,6 +1004,7 @@ impl HasIntegral for Poly7 { } impl Mul for Poly7 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly7([ self.0[0] * rhs, @@ -918,6 +1020,7 @@ impl Mul for Poly7 { } impl MulAssign for Poly7 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -925,12 +1028,14 @@ impl MulAssign for Poly7 { impl Neg for Poly7 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly7 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly7([ self.0[0] + other.0[0], @@ -947,20 +1052,24 @@ impl Add for Poly7 { impl AbsDiffEq for Poly7 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly7 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } @@ -976,6 +1085,7 @@ impl RelativeEq for Poly7 { )] pub struct Poly8(pub [f64; 9]); impl Evaluate for Poly8 { + #[inline] fn evaluate(&self, x: f64) -> f64 { // P8(x) = (C0 + C1x) + (C2 + C3x) x2 + ((C4 + C5x) + (C6 + C7x) x2)x4 + C8x8 let c = self.0; @@ -1002,6 +1112,7 @@ impl Evaluate for Poly8 { impl HasDerivative for Poly8 { type DerivativeOf = Poly7; + #[inline] fn derivative(&self) -> Self::DerivativeOf { let coeffs = self.0; let dst = [ @@ -1018,12 +1129,14 @@ impl HasDerivative for Poly8 { } } impl Translate for Poly8 { + #[inline] fn translate(&mut self, v: f64) { self.0[0] += v; } } impl Mul for Poly8 { type Output = Self; + #[inline] fn mul(self, rhs: f64) -> Self { Poly8([ self.0[0] * rhs, @@ -1040,6 +1153,7 @@ impl Mul for Poly8 { } impl MulAssign for Poly8 { + #[inline] fn mul_assign(&mut self, rhs: f64) { self.0.iter_mut().for_each(|x| *x *= rhs); } @@ -1047,12 +1161,14 @@ impl MulAssign for Poly8 { impl Neg for Poly8 { type Output = Self; + #[inline] fn neg(self) -> Self { self * -1.0 } } impl Add for Poly8 { type Output = Self; + #[inline] fn add(self, other: Self) -> Self { Poly8([ self.0[0] + other.0[0], @@ -1070,20 +1186,24 @@ impl Add for Poly8 { impl AbsDiffEq for Poly8 { type Epsilon = f64; + #[inline] fn default_epsilon() -> Self::Epsilon { ::default_epsilon() } + #[inline] fn abs_diff_eq(&self, other: &Self, eps: Self::Epsilon) -> bool { self.0.abs_diff_eq(&other.0, eps) } } impl RelativeEq for Poly8 { + #[inline] fn default_max_relative() -> Self::Epsilon { ::default_max_relative() } + #[inline] fn relative_eq(&self, other: &Self, eps: Self::Epsilon, max_relative: Self::Epsilon) -> bool { self.0.relative_eq(&other.0, eps, max_relative) } diff --git a/src/spline.rs b/src/spline.rs index b65360d..71d0a98 100644 --- a/src/spline.rs +++ b/src/spline.rs @@ -6,6 +6,7 @@ use std::iter; /// /// Taken from “Constrained Cubic Spline Interpolation for Chemical /// Engineering Applications” by CJC Kruger. +#[inline] pub fn constrained_spline(ks0n: &[Knot]) -> Piecewise { assert!(ks0n.len() >= 3, "need at least 3 knots");