split_quad.rs
1 #![allow(missing_docs)] 2 #![allow(dead_code)] 3 4 use arrayvec::ArrayVec; 5 6 use super::Quadratic; 7 8 pub struct SplitQuadPart { 9 quad: Quadratic, 10 until: f64, 11 } 12 13 pub struct SplitQuad { 14 quads: ArrayVec<SplitQuadPart, 3>, 15 } 16 17 impl SplitQuad { 18 pub fn single(q: Quadratic) -> Self { 19 Self { 20 quads: [SplitQuadPart { 21 quad: q, 22 until: f64::INFINITY, 23 }] 24 .into_iter() 25 .collect(), 26 } 27 } 28 } 29 30 pub struct QuadBound { 31 upper: SplitQuad, 32 lower: SplitQuad, 33 } 34 35 impl QuadBound { 36 pub fn new(mut q: Quadratic, upper: f64, lower: f64, shift: f64) -> Self { 37 debug_assert!(lower <= 0.0 && 0.0 <= upper); 38 debug_assert!(shift >= 0.0); 39 let center = -q.c1 / (2.0 * q.c0); 40 let extremum = q.c0 + q.c1 * center; 41 if center.is_infinite() || extremum.is_infinite() { 42 // Our quad is close enough to linear. 43 q.c2 = 0.0; 44 let upper = q + upper; 45 let lower = q + lower; 46 47 let signed_shift = if q.c1 > 0.0 { shift } else { -shift }; 48 49 Self { 50 upper: SplitQuad::single(upper.shift(-signed_shift)), 51 lower: SplitQuad::single(lower.shift(signed_shift)), 52 } 53 } else { 54 todo!() 55 } 56 } 57 }