use super::{ChebyError, ChebyTime};
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Domain<X> {
start: X,
end: X,
mid: X,
half: X,
}
impl<X: ChebyTime> Domain<X> {
#[inline]
pub fn try_new(start: X, end: X) -> Result<Self, ChebyError> {
if !start.is_finite() || !end.is_finite() {
return Err(ChebyError::NonFiniteInput);
}
let width = end - start;
if width == X::zero() {
return Err(ChebyError::EmptyDomain);
}
if width < X::zero() {
return Err(ChebyError::InvalidDomain);
}
let half = width * 0.5;
let mid = start + half;
Ok(Self {
start,
end,
mid,
half,
})
}
#[inline]
pub fn new(start: X, end: X) -> Self {
Self::try_new(start, end).expect("invalid Chebyshev domain")
}
#[inline]
pub fn start(&self) -> X {
self.start
}
#[inline]
pub fn end(&self) -> X {
self.end
}
#[inline]
pub fn midpoint(&self) -> X {
self.mid
}
#[inline]
pub fn half_width(&self) -> X {
self.half
}
#[inline]
pub fn normalize(&self, x: X) -> f64 {
(x - self.start) / self.half - 1.0
}
#[inline]
pub fn contains(&self, x: X) -> bool {
x >= self.start && x <= self.end
}
#[inline]
pub fn denormalize(&self, tau: f64) -> X {
self.mid + self.half * tau
}
}