Mon, 24 Oct 2022 10:52:19 +0300
Added type for numerical errors
0 | 1 | /// Traits for (mathematical) functions. |
2 | ||
3 | use std::marker::PhantomData; | |
4 | use crate::types::{Float}; | |
5 | use serde::Serialize; | |
6 | use crate::loc::Loc; | |
7 | ||
8 | pub trait Mapping<Domain> { | |
9 | type Codomain; | |
10 | ||
11 | fn value(&self, x : Domain) -> Self::Codomain; | |
12 | } | |
13 | ||
14 | pub trait RealRefMapping<F : Float, const N : usize> | |
15 | : for<'a> Mapping<&'a Loc<F, N>, Codomain=F> {} | |
16 | ||
17 | impl<F : Float, T, const N : usize> RealRefMapping<F, N> for T | |
18 | where T : for<'a> Mapping<&'a Loc<F, N>, Codomain=F> {} | |
19 | ||
20 | pub trait DifferentiableMapping<Domain> : Mapping<Domain> { | |
21 | type Differential; | |
22 | ||
23 | fn differential(&self, x : Domain) -> Self::Differential; | |
24 | } | |
25 | ||
26 | pub trait RealMapping<Domain> : Mapping<Domain> where Self::Codomain : Float { | |
27 | fn minimise(&self, tolerance : Self::Codomain) -> (Domain, Self::Codomain); | |
28 | fn maximise(&self, tolerance : Self::Codomain) -> (Domain, Self::Codomain); | |
29 | } | |
30 | ||
31 | // | |
32 | // Sum | |
33 | // | |
34 | ||
35 | #[derive(Serialize, Debug, Clone)] | |
36 | pub struct Sum<Domain, M : Mapping<Domain>> { | |
37 | components : Vec<M>, | |
38 | _domain : PhantomData<Domain>, | |
39 | } | |
40 | ||
41 | impl<Domain, M> Mapping<Domain> for Sum<Domain,M> | |
42 | where M : Mapping<Domain>, | |
43 | M :: Codomain : std::iter::Sum, | |
44 | Domain : Copy { | |
45 | ||
46 | type Codomain = M::Codomain; | |
47 | ||
48 | fn value(&self, x : Domain) -> Self::Codomain { | |
49 | self.components.iter().map(|c| c.value(x)).sum() | |
50 | } | |
51 | } | |
52 | ||
53 | impl<Domain, M> DifferentiableMapping<Domain> for Sum<Domain,M> | |
54 | where M : DifferentiableMapping<Domain>, | |
55 | M :: Codomain : std::iter::Sum, | |
56 | M :: Differential : std::iter::Sum, | |
57 | Domain : Copy { | |
58 | ||
59 | type Differential = M::Differential; | |
60 | ||
61 | fn differential(&self, x : Domain) -> Self::Differential { | |
62 | self.components.iter().map(|c| c.differential(x)).sum() | |
63 | } | |
64 | } |