Wed, 26 Oct 2022 22:16:57 +0300
Added tag unthreaded for changeset d80b87b8acd0
5 | 1 | /*! |
2 | Traits for mathematical functions. | |
3 | */ | |
0 | 4 | |
5 | use std::marker::PhantomData; | |
6 | use crate::types::{Float}; | |
7 | use serde::Serialize; | |
8 | use crate::loc::Loc; | |
9 | ||
5 | 10 | /// A mapping from `Domain` to `Codomain`. |
0 | 11 | pub trait Mapping<Domain> { |
12 | type Codomain; | |
13 | ||
5 | 14 | /// Calculate the value of the mapping at `x`. |
0 | 15 | fn value(&self, x : Domain) -> Self::Codomain; |
16 | } | |
17 | ||
5 | 18 | /// A helper trait alias for referring to `Mapping`s from references to floats. |
0 | 19 | pub trait RealRefMapping<F : Float, const N : usize> |
20 | : for<'a> Mapping<&'a Loc<F, N>, Codomain=F> {} | |
21 | ||
22 | impl<F : Float, T, const N : usize> RealRefMapping<F, N> for T | |
23 | where T : for<'a> Mapping<&'a Loc<F, N>, Codomain=F> {} | |
24 | ||
5 | 25 | |
26 | /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials | |
27 | /// `Differential`. | |
0 | 28 | pub trait DifferentiableMapping<Domain> : Mapping<Domain> { |
29 | type Differential; | |
30 | ||
5 | 31 | /// Calculate the differentialeof the mapping at `x`. |
0 | 32 | fn differential(&self, x : Domain) -> Self::Differential; |
33 | } | |
34 | ||
5 | 35 | /// A `Mapping` whose minimum and maximum can be computed. |
0 | 36 | pub trait RealMapping<Domain> : Mapping<Domain> where Self::Codomain : Float { |
5 | 37 | /// Calculate a minimum and a minimiser of the mapping. |
0 | 38 | fn minimise(&self, tolerance : Self::Codomain) -> (Domain, Self::Codomain); |
5 | 39 | /// Calculate a maximum and a maximiser of the mapping. |
0 | 40 | fn maximise(&self, tolerance : Self::Codomain) -> (Domain, Self::Codomain); |
41 | } | |
42 | ||
5 | 43 | /// A sum of [`Mapping`]s. |
0 | 44 | #[derive(Serialize, Debug, Clone)] |
45 | pub struct Sum<Domain, M : Mapping<Domain>> { | |
46 | components : Vec<M>, | |
47 | _domain : PhantomData<Domain>, | |
48 | } | |
49 | ||
5 | 50 | impl<Domain, M : Mapping<Domain>> Sum<Domain, M> { |
51 | /// Construct from an iterator. | |
52 | pub fn new<I : Iterator<Item = M>>(iter : I) -> Self { | |
53 | Sum { components : iter.collect(), _domain : PhantomData } | |
54 | } | |
55 | } | |
56 | ||
57 | ||
0 | 58 | impl<Domain, M> Mapping<Domain> for Sum<Domain,M> |
59 | where M : Mapping<Domain>, | |
60 | M :: Codomain : std::iter::Sum, | |
61 | Domain : Copy { | |
62 | ||
63 | type Codomain = M::Codomain; | |
64 | ||
65 | fn value(&self, x : Domain) -> Self::Codomain { | |
66 | self.components.iter().map(|c| c.value(x)).sum() | |
67 | } | |
68 | } | |
69 | ||
70 | impl<Domain, M> DifferentiableMapping<Domain> for Sum<Domain,M> | |
71 | where M : DifferentiableMapping<Domain>, | |
72 | M :: Codomain : std::iter::Sum, | |
73 | M :: Differential : std::iter::Sum, | |
74 | Domain : Copy { | |
75 | ||
76 | type Differential = M::Differential; | |
77 | ||
78 | fn differential(&self, x : Domain) -> Self::Differential { | |
79 | self.components.iter().map(|c| c.differential(x)).sum() | |
80 | } | |
81 | } |