enterpolation/weights/
mod.rs1mod 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#[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 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
71pub trait IntoWeight {
75 type Element;
77 type Weight;
79 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}