| 1 |
1 |
| 2 /*! |
2 /*! |
| 3 Traits for representing the support of a [`Mapping`], and analysing the mapping on a [`Cube`]. |
3 Traits for representing the support of a [`Apply`], and analysing the mapping on a [`Cube`]. |
| 4 */ |
4 */ |
| 5 use serde::Serialize; |
5 use serde::Serialize; |
| 6 use std::ops::{MulAssign,DivAssign,Neg}; |
6 use std::ops::{MulAssign,DivAssign,Neg}; |
| 7 use crate::types::{Float, Num}; |
7 use crate::types::{Float, Num}; |
| 8 use crate::maputil::map2; |
8 use crate::maputil::map2; |
| 25 #[inline] |
25 #[inline] |
| 26 fn value(&self) -> F { *self } |
26 fn value(&self) -> F { *self } |
| 27 } |
27 } |
| 28 |
28 |
| 29 |
29 |
| 30 /// A trait for working with the supports of [`Mapping`]s. |
30 /// A trait for working with the supports of [`Apply`]s. |
| 31 /// |
31 /// |
| 32 /// Mapping is not a super-trait to allow more general use. |
32 /// Apply is not a super-trait to allow more general use. |
| 33 pub trait Support<F : Num, const N : usize> : Sized + Sync + Send + 'static { |
33 pub trait Support<F : Num, const N : usize> : Sized + Sync + Send + 'static { |
| 34 /// Return a cube containing the support of the function represented by `self`. |
34 /// Return a cube containing the support of the function represented by `self`. |
| 35 /// |
35 /// |
| 36 /// The hint may be larger than the actual support, but must contain it. |
36 /// The hint may be larger than the actual support, but must contain it. |
| 37 fn support_hint(&self) -> Cube<F,N>; |
37 fn support_hint(&self) -> Cube<F,N>; |
| 68 fn weigh<C : Constant<Type=F>>(self, a : C) -> Weighted<Self, C> { |
68 fn weigh<C : Constant<Type=F>>(self, a : C) -> Weighted<Self, C> { |
| 69 Weighted { weight : a, base_fn : self } |
69 Weighted { weight : a, base_fn : self } |
| 70 } |
70 } |
| 71 } |
71 } |
| 72 |
72 |
| 73 /// Trait for globally analysing a property `A` of a [`Mapping`]. |
73 /// Trait for globally analysing a property `A` of a [`Apply`]. |
| 74 /// |
74 /// |
| 75 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
75 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
| 76 /// [`Bounds`][super::aggregator::Bounds]. |
76 /// [`Bounds`][super::aggregator::Bounds]. |
| 77 pub trait GlobalAnalysis<F : Num, A> { |
77 pub trait GlobalAnalysis<F : Num, A> { |
| 78 /// Perform global analysis of the property `A` of `Self`. |
78 /// Perform global analysis of the property `A` of `Self`. |
| 89 // fn global_analysis(&self) -> Bounds<F> { |
89 // fn global_analysis(&self) -> Bounds<F> { |
| 90 // self.local_analysis(&self.support_hint()) |
90 // self.local_analysis(&self.support_hint()) |
| 91 // } |
91 // } |
| 92 // } |
92 // } |
| 93 |
93 |
| 94 /// Trait for locally analysing a property `A` of a [`Mapping`] (implementing [`Support`]) |
94 /// Trait for locally analysing a property `A` of a [`Apply`] (implementing [`Support`]) |
| 95 /// within a [`Cube`]. |
95 /// within a [`Cube`]. |
| 96 /// |
96 /// |
| 97 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
97 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
| 98 /// [`Bounds`][super::aggregator::Bounds]. |
98 /// [`Bounds`][super::aggregator::Bounds]. |
| 99 pub trait LocalAnalysis<F : Num, A, const N : usize> : GlobalAnalysis<F, A> + Support<F, N> { |
99 pub trait LocalAnalysis<F : Num, A, const N : usize> : GlobalAnalysis<F, A> + Support<F, N> { |
| 103 /// this function will return upper and lower bounds within `cube` for the mapping |
103 /// this function will return upper and lower bounds within `cube` for the mapping |
| 104 /// represented by `self`. |
104 /// represented by `self`. |
| 105 fn local_analysis(&self, cube : &Cube<F, N>) -> A; |
105 fn local_analysis(&self, cube : &Cube<F, N>) -> A; |
| 106 } |
106 } |
| 107 |
107 |
| 108 /// Trait for determining the upper and lower bounds of an float-valued [`Mapping`]. |
108 /// Trait for determining the upper and lower bounds of an float-valued [`Apply`]. |
| 109 /// |
109 /// |
| 110 /// This is a blanket-implemented alias for [`GlobalAnalysis`]`<F, Bounds<F>>` |
110 /// This is a blanket-implemented alias for [`GlobalAnalysis`]`<F, Bounds<F>>` |
| 111 /// [`Mapping`] is not a supertrait to allow flexibility in the implementation of either |
111 /// [`Apply`] is not a supertrait to allow flexibility in the implementation of either |
| 112 /// reference or non-reference arguments. |
112 /// reference or non-reference arguments. |
| 113 pub trait Bounded<F : Float> : GlobalAnalysis<F, Bounds<F>> { |
113 pub trait Bounded<F : Float> : GlobalAnalysis<F, Bounds<F>> { |
| 114 /// Return lower and upper bounds for the values of of `self`. |
114 /// Return lower and upper bounds for the values of of `self`. |
| 115 #[inline] |
115 #[inline] |
| 116 fn bounds(&self) -> Bounds<F> { |
116 fn bounds(&self) -> Bounds<F> { |
| 118 } |
118 } |
| 119 } |
119 } |
| 120 |
120 |
| 121 impl<F : Float, T : GlobalAnalysis<F, Bounds<F>>> Bounded<F> for T { } |
121 impl<F : Float, T : GlobalAnalysis<F, Bounds<F>>> Bounded<F> for T { } |
| 122 |
122 |
| 123 /// Shift of [`Support`] and [`Mapping`]; output of [`Support::shift`]. |
123 /// Shift of [`Support`] and [`Apply`]; output of [`Support::shift`]. |
| 124 #[derive(Copy,Clone,Debug,Serialize)] // Serialize! but not implemented by Loc. |
124 #[derive(Copy,Clone,Debug,Serialize)] // Serialize! but not implemented by Loc. |
| 125 pub struct Shift<T, F, const N : usize> { |
125 pub struct Shift<T, F, const N : usize> { |
| 126 shift : Loc<F, N>, |
126 shift : Loc<F, N>, |
| 127 base_fn : T, |
127 base_fn : T, |
| 128 } |
128 } |
| 198 )* } |
198 )* } |
| 199 } |
199 } |
| 200 |
200 |
| 201 impl_shift_norm!(L1 L2 Linfinity); |
201 impl_shift_norm!(L1 L2 Linfinity); |
| 202 |
202 |
| 203 /// Weighting of a [`Support`] and [`Mapping`] by scalar multiplication; |
203 /// Weighting of a [`Support`] and [`Apply`] by scalar multiplication; |
| 204 /// output of [`Support::weigh`]. |
204 /// output of [`Support::weigh`]. |
| 205 #[derive(Copy,Clone,Debug,Serialize)] |
205 #[derive(Copy,Clone,Debug,Serialize)] |
| 206 pub struct Weighted<T, C : Constant> { |
206 pub struct Weighted<T, C : Constant> { |
| 207 /// The weight |
207 /// The weight |
| 208 pub weight : C, |
208 pub weight : C, |
| 209 /// The base [`Support`] or [`Mapping`] being weighted. |
209 /// The base [`Support`] or [`Apply`] being weighted. |
| 210 pub base_fn : T, |
210 pub base_fn : T, |
| 211 } |
211 } |
| 212 |
212 |
| 213 impl<'a, T, V, F : Float, C, const N : usize> Apply<&'a Loc<F, N>> for Weighted<T, C> |
213 impl<'a, T, V, F : Float, C, const N : usize> Apply<&'a Loc<F, N>> for Weighted<T, C> |
| 214 where T : for<'b> Apply<&'b Loc<F, N>, Output=V>, |
214 where T : for<'b> Apply<&'b Loc<F, N>, Output=V>, |
| 329 } |
329 } |
| 330 |
330 |
| 331 impl_weighted_norm!(L1 L2 Linfinity); |
331 impl_weighted_norm!(L1 L2 Linfinity); |
| 332 |
332 |
| 333 |
333 |
| 334 /// Normalisation of [`Support`] and [`Mapping`] to L¹ norm 1. |
334 /// Normalisation of [`Support`] and [`Apply`] to L¹ norm 1. |
| 335 /// |
335 /// |
| 336 /// Currently only scalar-valued functions are supported. |
336 /// Currently only scalar-valued functions are supported. |
| 337 #[derive(Copy, Clone, Debug, Serialize, PartialEq)] |
337 #[derive(Copy, Clone, Debug, Serialize, PartialEq)] |
| 338 pub struct Normalised<T>( |
338 pub struct Normalised<T>( |
| 339 /// The base [`Support`] or [`Mapping`]. |
339 /// The base [`Support`] or [`Apply`]. |
| 340 pub T |
340 pub T |
| 341 ); |
341 ); |
| 342 |
342 |
| 343 impl<'a, T, F : Float, const N : usize> Apply<&'a Loc<F, N>> for Normalised<T> |
343 impl<'a, T, F : Float, const N : usize> Apply<&'a Loc<F, N>> for Normalised<T> |
| 344 where T : Norm<F, L1> + for<'b> Apply<&'b Loc<F, N>, Output=F> { |
344 where T : Norm<F, L1> + for<'b> Apply<&'b Loc<F, N>, Output=F> { |
| 447 /// [ids][`Self::Id`]. |
447 /// [ids][`Self::Id`]. |
| 448 pub trait SupportGenerator<F : Float, const N : usize> |
448 pub trait SupportGenerator<F : Float, const N : usize> |
| 449 : MulAssign<F> + DivAssign<F> + Neg<Output=Self> + Clone + Sync + Send + 'static { |
449 : MulAssign<F> + DivAssign<F> + Neg<Output=Self> + Clone + Sync + Send + 'static { |
| 450 /// The identification type |
450 /// The identification type |
| 451 type Id : 'static + Copy; |
451 type Id : 'static + Copy; |
| 452 /// The type of the [`Support`] (often also a [`Mapping`]). |
452 /// The type of the [`Support`] (often also a [`Apply`]). |
| 453 type SupportType : 'static + Support<F, N>; |
453 type SupportType : 'static + Support<F, N>; |
| 454 /// An iterator over all the [`Support`]s of the generator. |
454 /// An iterator over all the [`Support`]s of the generator. |
| 455 type AllDataIter<'a> : Iterator<Item=(Self::Id, Self::SupportType)> where Self : 'a; |
455 type AllDataIter<'a> : Iterator<Item=(Self::Id, Self::SupportType)> where Self : 'a; |
| 456 |
456 |
| 457 /// Returns the component identified by `id`. |
457 /// Returns the component identified by `id`. |