Tue, 31 Dec 2024 08:48:50 -0500
Split out and generalise Weighted
src/bisection_tree/support.rs | file | annotate | diff | comparison | revisions | |
src/lib.rs | file | annotate | diff | comparison | revisions | |
src/mapping.rs | file | annotate | diff | comparison | revisions | |
src/operator_arithmetic.rs | file | annotate | diff | comparison | revisions |
--- a/src/bisection_tree/support.rs Mon Dec 30 09:49:08 2024 -0500 +++ b/src/bisection_tree/support.rs Tue Dec 31 08:48:50 2024 -0500 @@ -13,21 +13,7 @@ use crate::loc::Loc; use super::aggregator::Bounds; use crate::norms::{Norm, L1, L2, Linfinity}; - -/// A trait for encoding constant [`Float`] values -pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> { - /// The type of the value - type Type : Float; - /// Returns the value of the constant - fn value(&self) -> Self::Type; -} - -impl<F : Float> Constant for F { - type Type = F; - #[inline] - fn value(&self) -> F { *self } -} - +pub use crate::operator_arithmetic::{Weighted, Constant}; /// A trait for working with the supports of [`Apply`]s. /// @@ -64,12 +50,6 @@ fn shift(self, x : Loc<F, N>) -> Shift<Self, F, N> { Shift { shift : x, base_fn : self } } - - /// Multiply `self` by the scalar `a`. - #[inline] - fn weigh<C : Constant<Type=F>>(self, a : C) -> Weighted<Self, C> { - Weighted { weight : a, base_fn : self } - } } /// Trait for globally analysing a property `A` of a [`Apply`]. @@ -204,40 +184,6 @@ impl_shift_norm!(L1 L2 Linfinity); -/// Weighting of a [`Support`] and [`Apply`] by scalar multiplication; -/// output of [`Support::weigh`]. -#[derive(Copy,Clone,Debug,Serialize)] -pub struct Weighted<T, C : Constant> { - /// The weight - pub weight : C, - /// The base [`Support`] or [`Apply`] being weighted. - pub base_fn : T, -} - -impl<'a, T, V, F : Float, C, const N : usize> Mapping<Loc<F, N>> for Weighted<T, C> -where T : Mapping<Loc<F, N>, Codomain=V>, - V : Space + std::ops::Mul<F,Output=V>, - C : Constant<Type=F> { - type Codomain = V; - - #[inline] - fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain { - self.base_fn.apply(x) * self.weight.value() - } -} - -impl<'a, T, V, F : Float, C, const N : usize> DifferentiableImpl<Loc<F, N>> for Weighted<T, C> -where T : DifferentiableMapping<Loc<F, N>, DerivativeDomain=V>, - V : Space + std::ops::Mul<F, Output=V>, - C : Constant<Type=F> { - type Derivative = V; - - #[inline] - fn differential_impl<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Derivative { - self.base_fn.differential(x) * self.weight.value() - } -} - impl<'a, T, F : Float, C, const N : usize> Support<F,N> for Weighted<T, C> where T : Support<F, N>, C : Constant<Type=F> {
--- a/src/lib.rs Mon Dec 30 09:49:08 2024 -0500 +++ b/src/lib.rs Tue Dec 31 08:48:50 2024 -0500 @@ -42,5 +42,7 @@ pub(crate) mod metaprogramming; pub mod direct_product; pub mod convex; +pub mod discrete_gradient; +pub mod operator_arithmetic; pub use types::*;
--- a/src/mapping.rs Mon Dec 30 09:49:08 2024 -0500 +++ b/src/mapping.rs Tue Dec 31 08:48:50 2024 -0500 @@ -4,8 +4,7 @@ use std::marker::PhantomData; use std::borrow::Cow; -use crate::types::{Num, Float}; -use serde::Serialize; +use crate::types::{Num, Float, ClosedMul}; use crate::loc::Loc; pub use crate::instance::{Instance, Decomposition, BasicDecomposition, Space}; use crate::norms::{Norm, NormExponent}; @@ -45,6 +44,17 @@ { Composition{ outer : self, inner : other, intermediate_norm_exponent : norm } } + + /// Multiply `self` by the scalar `a`. + #[inline] + fn weigh<C>(self, a : C) -> Weighted<Self, C> + where + Self : Sized, + C : Constant, + Self::Codomain : ClosedMul<C::Type>, + { + Weighted { weight : a, base_fn : self } + } } /// Automatically implemented shorthand for referring to [`Mapping`]s from [`Loc<F, N>`] to `F`.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/operator_arithmetic.rs Tue Dec 31 08:48:50 2024 -0500 @@ -0,0 +1,64 @@ +/*! +Arithmetic of [`Mapping`]s. + */ + +use serde::Serialize; +use crate::types::*; +use crate::instance::{Space, Instance}; +use crate::mapping::{Mapping, DifferentiableImpl, DifferentiableMapping}; + +/// A trait for encoding constant [`Float`] values +pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> { + /// The type of the value + type Type : Float; + /// Returns the value of the constant + fn value(&self) -> Self::Type; +} + +impl<F : Float> Constant for F { + type Type = F; + #[inline] + fn value(&self) -> F { *self } +} + +/// Weighting of a [`Support`] and [`Apply`] by scalar multiplication; +/// output of [`Support::weigh`]. +#[derive(Copy,Clone,Debug,Serialize)] +pub struct Weighted<T, C : Constant> { + /// The weight + pub weight : C, + /// The base [`Support`] or [`Apply`] being weighted. + pub base_fn : T, +} + +impl<'a, T, V, D, F, C> Mapping<D> for Weighted<T, C> +where + F : Float, + D : Space, + T : Mapping<D, Codomain=V>, + V : Space + ClosedMul<F>, + C : Constant<Type=F> +{ + type Codomain = V; + + #[inline] + fn apply<I : Instance<D>>(&self, x : I) -> Self::Codomain { + self.base_fn.apply(x) * self.weight.value() + } +} + +impl<'a, T, V, D, F, C> DifferentiableImpl<D> for Weighted<T, C> +where + F : Float, + D : Space, + T : DifferentiableMapping<D, DerivativeDomain=V>, + V : Space + std::ops::Mul<F, Output=V>, + C : Constant<Type=F> +{ + type Derivative = V; + + #[inline] + fn differential_impl<I : Instance<D>>(&self, x : I) -> Self::Derivative { + self.base_fn.differential(x) * self.weight.value() + } +}