src/mapping.rs

branch
dev
changeset 48
3f3e00e81755
parent 47
a0db98c16ab5
child 49
edb95d2b83cc
equal deleted inserted replaced
47:a0db98c16ab5 48:3f3e00e81755
1 /*! 1 /*!
2 Traits for mathematical functions. 2 Traits for mathematical functions.
3 */ 3 */
4 4
5 use std::marker::PhantomData; 5 use std::marker::PhantomData;
6 use crate::types::{Float}; 6 use crate::types::Float;
7 use serde::Serialize; 7 use serde::Serialize;
8 use crate::loc::Loc; 8 use crate::loc::Loc;
9 9
10 /// Trait for application of `Self` as a mathematical function or operator on `X`. 10 /// Trait for application of `Self` as a mathematical function or operator on `X`.
11 pub trait Apply<X> { 11 pub trait Apply<X> {
50 where T : Mapping<Loc<F, N>, Codomain = F> {} 50 where T : Mapping<Loc<F, N>, Codomain = F> {}
51 51
52 /// Automatically implemented shorthand for referring to differentiable [`Mapping`]s from 52 /// Automatically implemented shorthand for referring to differentiable [`Mapping`]s from
53 /// [`Loc<F, N>`] to `F`. 53 /// [`Loc<F, N>`] to `F`.
54 pub trait DifferentiableRealMapping<F : Float, const N : usize> 54 pub trait DifferentiableRealMapping<F : Float, const N : usize>
55 : DifferentiableMapping<Loc<F, N>, Codomain = F, Differential=Loc<F, N>> {} 55 : DifferentiableMapping<Loc<F, N>, Codomain = F, DerivativeDomain=Loc<F, N>> {}
56 56
57 impl<F : Float, T, const N : usize> DifferentiableRealMapping<F, N> for T 57 impl<F : Float, T, const N : usize> DifferentiableRealMapping<F, N> for T
58 where T : DifferentiableMapping<Loc<F, N>, Codomain = F, Differential=Loc<F, N>> {} 58 where T : DifferentiableMapping<Loc<F, N>, Codomain = F, DerivativeDomain=Loc<F, N>> {}
59 59
60 60
61 /// A helper trait alias for referring to [`Mapping`]s from [`Loc<F, N>`] to [`Loc<F, M>`]. 61 /// A helper trait alias for referring to [`Mapping`]s from [`Loc<F, N>`] to [`Loc<F, M>`].
62 pub trait RealVectorField<F : Float, const N : usize, const M : usize> 62 pub trait RealVectorField<F : Float, const N : usize, const M : usize>
63 : Mapping<Loc<F, N>, Codomain = Loc<F, M>> {} 63 : Mapping<Loc<F, N>, Codomain = Loc<F, M>> {}
78 /// `Differential`. 78 /// `Differential`.
79 /// 79 ///
80 /// This is automatically implemented when the relevant [`Differentiate`] are implemented. 80 /// This is automatically implemented when the relevant [`Differentiate`] are implemented.
81 pub trait DifferentiableMapping<Domain> 81 pub trait DifferentiableMapping<Domain>
82 : Mapping<Domain> 82 : Mapping<Domain>
83 + Differentiable<Domain, Derivative=Self::Differential> 83 + Differentiable<Domain, Derivative=Self::DerivativeDomain>
84 + for<'a> Differentiable<&'a Domain, Derivative=Self::Differential> { 84 + for<'a> Differentiable<&'a Domain, Derivative=Self::DerivativeDomain> {
85 type Differential; 85 type DerivativeDomain;
86 86 type Differential : Mapping<Domain, Codomain=Self::DerivativeDomain>;
87 /// Form the differential mapping of `self`. 87 type DifferentialRef<'b> : Mapping<Domain, Codomain=Self::DerivativeDomain> where Self : 'b;
88 fn diff(self) -> Differential<Domain, Self> { 88
89 /// Form the differential mapping of `self`.
90 fn diff(self) -> Self::Differential;
91 /// Form the differential mapping of `self`.
92 fn diff_ref(&self) -> Self::DifferentialRef<'_>;
93 }
94
95
96 impl<Domain, Derivative, T> DifferentiableMapping<Domain> for T
97 where T : Mapping<Domain>
98 + Differentiable<Domain, Derivative=Derivative>
99 + for<'a> Differentiable<&'a Domain,Derivative=Derivative> {
100 type DerivativeDomain = Derivative;
101 type Differential = Differential<Domain, Self>;
102 type DifferentialRef<'b> = Differential<Domain, Ref<'b, Self>> where Self : 'b;
103
104 /// Form the differential mapping of `self`.
105 fn diff(self) -> Self::Differential {
89 Differential{ g : self, _space : PhantomData } 106 Differential{ g : self, _space : PhantomData }
90 } 107 }
91 108
92 /// Form the differential mapping of `self`. 109 /// Form the differential mapping of `self`.
93 fn diff_ref(&self) -> Differential<Domain, Ref<'_, Self>> { 110 fn diff_ref(&self) -> Self::DifferentialRef<'_> {
94 Differential{ g : Ref(self), _space : PhantomData } 111 Differential{ g : Ref(self), _space : PhantomData }
95 } 112 }
96 }
97
98
99 impl<Domain, Differential, T> DifferentiableMapping<Domain> for T
100 where T : Mapping<Domain>
101 + Differentiable<Domain, Derivative=Differential>
102 + for<'a> Differentiable<&'a Domain, Derivative=Differential> {
103 type Differential = Differential;
104 } 113 }
105 114
106 /// A sum of [`Mapping`]s. 115 /// A sum of [`Mapping`]s.
107 #[derive(Serialize, Debug, Clone)] 116 #[derive(Serialize, Debug, Clone)]
108 pub struct Sum<Domain, M : Mapping<Domain>> { 117 pub struct Sum<Domain, M : Mapping<Domain>> {
144 } 153 }
145 154
146 impl<Domain, M> Differentiable<Domain> for Sum<Domain, M> 155 impl<Domain, M> Differentiable<Domain> for Sum<Domain, M>
147 where M : DifferentiableMapping<Domain>, 156 where M : DifferentiableMapping<Domain>,
148 M :: Codomain : std::iter::Sum, 157 M :: Codomain : std::iter::Sum,
149 M :: Differential : std::iter::Sum, 158 M :: DerivativeDomain : std::iter::Sum,
150 Domain : Copy { 159 Domain : Copy {
151 160
152 type Derivative = M::Differential; 161 type Derivative = M::DerivativeDomain;
153 162
154 fn differential(&self, x : Domain) -> Self::Derivative { 163 fn differential(&self, x : Domain) -> Self::Derivative {
155 self.components.iter().map(|c| c.differential(x)).sum() 164 self.components.iter().map(|c| c.differential(x)).sum()
156 } 165 }
157 } 166 }
161 g : G, 170 g : G,
162 _space : PhantomData<X> 171 _space : PhantomData<X>
163 } 172 }
164 173
165 impl<X, G : DifferentiableMapping<X>> Apply<X> for Differential<X, G> { 174 impl<X, G : DifferentiableMapping<X>> Apply<X> for Differential<X, G> {
166 type Output = G::Differential; 175 type Output = G::DerivativeDomain;
167 176
168 #[inline] 177 #[inline]
169 fn apply(&self, x : X) -> G::Differential { 178 fn apply(&self, x : X) -> Self::Output {
170 self.g.differential(x) 179 self.g.differential(x)
171 } 180 }
172 } 181 }
173 182
174 impl<'a, X, G : DifferentiableMapping<X>> Apply<&'a X> for Differential<X, G> { 183 impl<'a, X, G : DifferentiableMapping<X>> Apply<&'a X> for Differential<X, G> {
175 type Output = G::Differential; 184 type Output = G::DerivativeDomain;
176 185
177 #[inline] 186 #[inline]
178 fn apply(&self, x : &'a X) -> G::Differential { 187 fn apply(&self, x : &'a X) -> Self::Output {
179 self.g.differential(x) 188 self.g.differential(x)
180 } 189 }
181 } 190 }
182 191
183 192

mercurial