Tue, 25 Oct 2022 23:05:40 +0300
Added NormExponent trait for exponents of norms
| 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 | } |