| 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 |