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 |