| 1 |
1 |
| 2 /*! |
2 /*! |
| 3 Traits for representing the support of a [`Apply`], and analysing the mapping on a [`Cube`]. |
3 Traits for representing the support of a [`Mapping`], 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; |
| 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 pub use crate::operator_arithmetic::{Weighted, Constant}; |
16 pub use crate::operator_arithmetic::{Weighted, Constant}; |
| 17 |
17 |
| 18 /// A trait for working with the supports of [`Apply`]s. |
18 /// A trait for working with the supports of [`Mapping`]s. |
| 19 /// |
19 /// |
| 20 /// Apply is not a super-trait to allow more general use. |
20 /// `Mapping` is not a super-trait to allow more general use. |
| 21 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 { |
| 22 /// Return a cube containing the support of the function represented by `self`. |
22 /// Return a cube containing the support of the function represented by `self`. |
| 23 /// |
23 /// |
| 24 /// The hint may be larger than the actual support, but must contain it. |
24 /// The hint may be larger than the actual support, but must contain it. |
| 25 fn support_hint(&self) -> Cube<F,N>; |
25 fn support_hint(&self) -> Cube<F,N>; |
| 50 fn shift(self, x : Loc<F, N>) -> Shift<Self, F, N> { |
50 fn shift(self, x : Loc<F, N>) -> Shift<Self, F, N> { |
| 51 Shift { shift : x, base_fn : self } |
51 Shift { shift : x, base_fn : self } |
| 52 } |
52 } |
| 53 } |
53 } |
| 54 |
54 |
| 55 /// Trait for globally analysing a property `A` of a [`Apply`]. |
55 /// Trait for globally analysing a property `A` of a [`Mapping`]. |
| 56 /// |
56 /// |
| 57 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
57 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
| 58 /// [`Bounds`][super::aggregator::Bounds]. |
58 /// [`Bounds`][super::aggregator::Bounds]. |
| 59 pub trait GlobalAnalysis<F : Num, A> { |
59 pub trait GlobalAnalysis<F : Num, A> { |
| 60 /// Perform global analysis of the property `A` of `Self`. |
60 /// Perform global analysis of the property `A` of `Self`. |
| 71 // fn global_analysis(&self) -> Bounds<F> { |
71 // fn global_analysis(&self) -> Bounds<F> { |
| 72 // self.local_analysis(&self.support_hint()) |
72 // self.local_analysis(&self.support_hint()) |
| 73 // } |
73 // } |
| 74 // } |
74 // } |
| 75 |
75 |
| 76 /// Trait for locally analysing a property `A` of a [`Apply`] (implementing [`Support`]) |
76 /// Trait for locally analysing a property `A` of a [`Mapping`] (implementing [`Support`]) |
| 77 /// within a [`Cube`]. |
77 /// within a [`Cube`]. |
| 78 /// |
78 /// |
| 79 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
79 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as |
| 80 /// [`Bounds`][super::aggregator::Bounds]. |
80 /// [`Bounds`][super::aggregator::Bounds]. |
| 81 pub trait LocalAnalysis<F : Num, A, const N : usize> : GlobalAnalysis<F, A> + Support<F, N> { |
81 pub trait LocalAnalysis<F : Num, A, const N : usize> : GlobalAnalysis<F, A> + Support<F, N> { |
| 85 /// this function will return upper and lower bounds within `cube` for the mapping |
85 /// this function will return upper and lower bounds within `cube` for the mapping |
| 86 /// represented by `self`. |
86 /// represented by `self`. |
| 87 fn local_analysis(&self, cube : &Cube<F, N>) -> A; |
87 fn local_analysis(&self, cube : &Cube<F, N>) -> A; |
| 88 } |
88 } |
| 89 |
89 |
| 90 /// Trait for determining the upper and lower bounds of an float-valued [`Apply`]. |
90 /// Trait for determining the upper and lower bounds of an float-valued [`Mapping`]. |
| 91 /// |
91 /// |
| 92 /// This is a blanket-implemented alias for [`GlobalAnalysis`]`<F, Bounds<F>>` |
92 /// This is a blanket-implemented alias for [`GlobalAnalysis`]`<F, Bounds<F>>` |
| 93 /// [`Apply`] is not a supertrait to allow flexibility in the implementation of either |
93 /// [`Mapping`] is not a supertrait to allow flexibility in the implementation of either |
| 94 /// reference or non-reference arguments. |
94 /// reference or non-reference arguments. |
| 95 pub trait Bounded<F : Float> : GlobalAnalysis<F, Bounds<F>> { |
95 pub trait Bounded<F : Float> : GlobalAnalysis<F, Bounds<F>> { |
| 96 /// Return lower and upper bounds for the values of of `self`. |
96 /// Return lower and upper bounds for the values of of `self`. |
| 97 #[inline] |
97 #[inline] |
| 98 fn bounds(&self) -> Bounds<F> { |
98 fn bounds(&self) -> Bounds<F> { |
| 100 } |
100 } |
| 101 } |
101 } |
| 102 |
102 |
| 103 impl<F : Float, T : GlobalAnalysis<F, Bounds<F>>> Bounded<F> for T { } |
103 impl<F : Float, T : GlobalAnalysis<F, Bounds<F>>> Bounded<F> for T { } |
| 104 |
104 |
| 105 /// Shift of [`Support`] and [`Apply`]; output of [`Support::shift`]. |
105 /// Shift of [`Support`] and [`Mapping`]; output of [`Support::shift`]. |
| 106 #[derive(Copy,Clone,Debug,Serialize)] // Serialize! but not implemented by Loc. |
106 #[derive(Copy,Clone,Debug,Serialize)] // Serialize! but not implemented by Loc. |
| 107 pub struct Shift<T, F, const N : usize> { |
107 pub struct Shift<T, F, const N : usize> { |
| 108 shift : Loc<F, N>, |
108 shift : Loc<F, N>, |
| 109 base_fn : T, |
109 base_fn : T, |
| 110 } |
110 } |
| 281 } |
281 } |
| 282 |
282 |
| 283 impl_weighted_norm!(L1 L2 Linfinity); |
283 impl_weighted_norm!(L1 L2 Linfinity); |
| 284 |
284 |
| 285 |
285 |
| 286 /// Normalisation of [`Support`] and [`Apply`] to L¹ norm 1. |
286 /// Normalisation of [`Support`] and [`Mapping`] to L¹ norm 1. |
| 287 /// |
287 /// |
| 288 /// Currently only scalar-valued functions are supported. |
288 /// Currently only scalar-valued functions are supported. |
| 289 #[derive(Copy, Clone, Debug, Serialize, PartialEq)] |
289 #[derive(Copy, Clone, Debug, Serialize, PartialEq)] |
| 290 pub struct Normalised<T>( |
290 pub struct Normalised<T>( |
| 291 /// The base [`Support`] or [`Apply`]. |
291 /// The base [`Support`] or [`Mapping`]. |
| 292 pub T |
292 pub T |
| 293 ); |
293 ); |
| 294 |
294 |
| 295 impl<'a, T, F : Float, const N : usize> Mapping<Loc<F, N>> for Normalised<T> |
295 impl<'a, T, F : Float, const N : usize> Mapping<Loc<F, N>> for Normalised<T> |
| 296 where T : Norm<F, L1> + Mapping<Loc<F,N>, Codomain=F> { |
296 where T : Norm<F, L1> + Mapping<Loc<F,N>, Codomain=F> { |
| 390 /// [ids][`Self::Id`]. |
390 /// [ids][`Self::Id`]. |
| 391 pub trait SupportGenerator<F : Float, const N : usize> |
391 pub trait SupportGenerator<F : Float, const N : usize> |
| 392 : MulAssign<F> + DivAssign<F> + Neg<Output=Self> + Clone + Sync + Send + 'static { |
392 : MulAssign<F> + DivAssign<F> + Neg<Output=Self> + Clone + Sync + Send + 'static { |
| 393 /// The identification type |
393 /// The identification type |
| 394 type Id : 'static + Copy; |
394 type Id : 'static + Copy; |
| 395 /// The type of the [`Support`] (often also a [`Apply`]). |
395 /// The type of the [`Support`] (often also a [`Mapping`]). |
| 396 type SupportType : 'static + Support<F, N>; |
396 type SupportType : 'static + Support<F, N>; |
| 397 /// An iterator over all the [`Support`]s of the generator. |
397 /// An iterator over all the [`Support`]s of the generator. |
| 398 type AllDataIter<'a> : Iterator<Item=(Self::Id, Self::SupportType)> where Self : 'a; |
398 type AllDataIter<'a> : Iterator<Item=(Self::Id, Self::SupportType)> where Self : 'a; |
| 399 |
399 |
| 400 /// Returns the component identified by `id`. |
400 /// Returns the component identified by `id`. |