use crate::weights::Homogeneous;
use crate::{Curve, Signal};
use core::ops::Div;
use num_traits::real::Real;
#[derive(Debug, Copy, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Weighted<G> {
inner: G,
}
impl<G> Weighted<G> {
pub fn new(signal: G) -> Self {
Weighted { inner: signal }
}
pub fn inner(self) -> G {
self.inner
}
}
impl<G, I> Signal<I> for Weighted<G>
where
G: Signal<I>,
G::Output: Project,
{
type Output = <G::Output as Project>::Element;
fn eval(&self, input: I) -> Self::Output {
self.inner.eval(input).project()
}
}
impl<G, R> Curve<R> for Weighted<G>
where
G: Curve<R>,
G::Output: Project,
R: Real,
{
fn domain(&self) -> [R; 2] {
self.inner.domain()
}
}
pub trait Project {
type Element;
type Weight;
fn project(self) -> Self::Element;
}
impl<T, R> Project for Homogeneous<T, R>
where
T: Div<R, Output = T>,
{
type Element = T;
type Weight = R;
fn project(self) -> Self::Element {
self.project()
}
}