| 11 }; |
11 }; |
| 12 use crate::sets::Cube; |
12 use crate::sets::Cube; |
| 13 use crate::loc::Loc; |
13 use crate::loc::Loc; |
| 14 use super::aggregator::Bounds; |
14 use super::aggregator::Bounds; |
| 15 use crate::norms::{Norm, L1, L2, Linfinity}; |
15 use crate::norms::{Norm, L1, L2, Linfinity}; |
| 16 |
16 pub use crate::operator_arithmetic::{Weighted, Constant}; |
| 17 /// A trait for encoding constant [`Float`] values |
|
| 18 pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> { |
|
| 19 /// The type of the value |
|
| 20 type Type : Float; |
|
| 21 /// Returns the value of the constant |
|
| 22 fn value(&self) -> Self::Type; |
|
| 23 } |
|
| 24 |
|
| 25 impl<F : Float> Constant for F { |
|
| 26 type Type = F; |
|
| 27 #[inline] |
|
| 28 fn value(&self) -> F { *self } |
|
| 29 } |
|
| 30 |
|
| 31 |
17 |
| 32 /// A trait for working with the supports of [`Apply`]s. |
18 /// A trait for working with the supports of [`Apply`]s. |
| 33 /// |
19 /// |
| 34 /// Apply is not a super-trait to allow more general use. |
20 /// Apply is not a super-trait to allow more general use. |
| 35 pub trait Support<F : Num, const N : usize> : Sized + Sync + Send + 'static { |
21 pub trait Support<F : Num, const N : usize> : Sized + Sync + Send + 'static { |
| 61 |
47 |
| 62 /// Translate `self` by `x`. |
48 /// Translate `self` by `x`. |
| 63 #[inline] |
49 #[inline] |
| 64 fn shift(self, x : Loc<F, N>) -> Shift<Self, F, N> { |
50 fn shift(self, x : Loc<F, N>) -> Shift<Self, F, N> { |
| 65 Shift { shift : x, base_fn : self } |
51 Shift { shift : x, base_fn : self } |
| 66 } |
|
| 67 |
|
| 68 /// Multiply `self` by the scalar `a`. |
|
| 69 #[inline] |
|
| 70 fn weigh<C : Constant<Type=F>>(self, a : C) -> Weighted<Self, C> { |
|
| 71 Weighted { weight : a, base_fn : self } |
|
| 72 } |
52 } |
| 73 } |
53 } |
| 74 |
54 |
| 75 /// Trait for globally analysing a property `A` of a [`Apply`]. |
55 /// Trait for globally analysing a property `A` of a [`Apply`]. |
| 76 /// |
56 /// |
| 201 } |
181 } |
| 202 )* } |
182 )* } |
| 203 } |
183 } |
| 204 |
184 |
| 205 impl_shift_norm!(L1 L2 Linfinity); |
185 impl_shift_norm!(L1 L2 Linfinity); |
| 206 |
|
| 207 /// Weighting of a [`Support`] and [`Apply`] by scalar multiplication; |
|
| 208 /// output of [`Support::weigh`]. |
|
| 209 #[derive(Copy,Clone,Debug,Serialize)] |
|
| 210 pub struct Weighted<T, C : Constant> { |
|
| 211 /// The weight |
|
| 212 pub weight : C, |
|
| 213 /// The base [`Support`] or [`Apply`] being weighted. |
|
| 214 pub base_fn : T, |
|
| 215 } |
|
| 216 |
|
| 217 impl<'a, T, V, F : Float, C, const N : usize> Mapping<Loc<F, N>> for Weighted<T, C> |
|
| 218 where T : Mapping<Loc<F, N>, Codomain=V>, |
|
| 219 V : Space + std::ops::Mul<F,Output=V>, |
|
| 220 C : Constant<Type=F> { |
|
| 221 type Codomain = V; |
|
| 222 |
|
| 223 #[inline] |
|
| 224 fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain { |
|
| 225 self.base_fn.apply(x) * self.weight.value() |
|
| 226 } |
|
| 227 } |
|
| 228 |
|
| 229 impl<'a, T, V, F : Float, C, const N : usize> DifferentiableImpl<Loc<F, N>> for Weighted<T, C> |
|
| 230 where T : DifferentiableMapping<Loc<F, N>, DerivativeDomain=V>, |
|
| 231 V : Space + std::ops::Mul<F, Output=V>, |
|
| 232 C : Constant<Type=F> { |
|
| 233 type Derivative = V; |
|
| 234 |
|
| 235 #[inline] |
|
| 236 fn differential_impl<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Derivative { |
|
| 237 self.base_fn.differential(x) * self.weight.value() |
|
| 238 } |
|
| 239 } |
|
| 240 |
186 |
| 241 impl<'a, T, F : Float, C, const N : usize> Support<F,N> for Weighted<T, C> |
187 impl<'a, T, F : Float, C, const N : usize> Support<F,N> for Weighted<T, C> |
| 242 where T : Support<F, N>, |
188 where T : Support<F, N>, |
| 243 C : Constant<Type=F> { |
189 C : Constant<Type=F> { |
| 244 |
190 |