enterpolation/weights/
mod.rs

1//! Module with structures for homogeneous datapoints, non-uniform inerpolations, weighted interpolations
2//! and adapters to handle these better.
3
4mod homogeneous;
5mod weighted;
6
7pub use homogeneous::Homogeneous;
8pub use weighted::Weighted;
9
10use crate::{Chain, ConstChain, Curve, Signal};
11use core::ops::Mul;
12use num_traits::identities::Zero;
13use num_traits::real::Real;
14
15/// Signal adaptor to transform `(T,R)` to `Homogeneous<T,R>`.
16///
17/// Weights given by the signal who equal `R::zero()` are considered to be at infinity.
18#[derive(Debug, Copy, Clone, PartialEq)]
19#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
20pub struct Weights<G> {
21    signal: G,
22}
23
24impl<G> Weights<G> {
25    /// Transform given signal such that it outputs homogeneous data.
26    pub fn new(signal: G) -> Self {
27        Weights { signal }
28    }
29}
30
31impl<G, Input> Signal<Input> for Weights<G>
32where
33    G: Signal<Input>,
34    G::Output: IntoWeight,
35{
36    type Output =
37        Homogeneous<<G::Output as IntoWeight>::Element, <G::Output as IntoWeight>::Weight>;
38    fn eval(&self, input: Input) -> Self::Output {
39        self.signal.eval(input).into_weight()
40    }
41}
42
43impl<G> Chain for Weights<G>
44where
45    G: Chain,
46    G::Output: IntoWeight,
47{
48    fn len(&self) -> usize {
49        self.signal.len()
50    }
51}
52
53impl<G, const N: usize> ConstChain<N> for Weights<G>
54where
55    G: ConstChain<N>,
56    G::Output: IntoWeight,
57{
58}
59
60impl<C, R> Curve<R> for Weights<C>
61where
62    C: Curve<R>,
63    C::Output: IntoWeight,
64    R: Real,
65{
66    fn domain(&self) -> [R; 2] {
67        self.signal.domain()
68    }
69}
70
71/// Trait for all structs which can be transformed into homogeneous data.
72///
73/// This trait is used to be able to implement Signals for Weights without having to add other generic variables.
74pub trait IntoWeight {
75    /// The element/direction of the homogeneous data.
76    type Element;
77    /// The weight/rational of the homogeneous data.
78    type Weight;
79    /// Method to convert self into homogeneous data.
80    fn into_weight(self) -> Homogeneous<Self::Element, Self::Weight>;
81}
82
83impl<T, R> IntoWeight for (T, R)
84where
85    T: Mul<R, Output = T>,
86    R: Zero + Copy,
87{
88    type Element = T;
89    type Weight = R;
90    fn into_weight(self) -> Homogeneous<T, R> {
91        Homogeneous::weighted_or_infinite(self.0, self.1)
92    }
93}
94
95impl<T, R> IntoWeight for Homogeneous<T, R>
96where
97    T: Mul<R, Output = T>,
98    R: Zero + Copy,
99{
100    type Element = T;
101    type Weight = R;
102    fn into_weight(self) -> Homogeneous<T, R> {
103        self
104    }
105}