| 70 pub trait Differentiable<X> : Sized { |
70 pub trait Differentiable<X> : Sized { |
| 71 type Derivative; |
71 type Derivative; |
| 72 |
72 |
| 73 /// Compute the differential of `self` at `x`. |
73 /// Compute the differential of `self` at `x`. |
| 74 fn differential(&self, x : X) -> Self::Derivative; |
74 fn differential(&self, x : X) -> Self::Derivative; |
| |
75 } |
| |
76 |
| |
77 impl<'g, X, G : Differentiable<X>> Differentiable<X> for &'g G { |
| |
78 type Derivative = G::Derivative; |
| |
79 #[inline] |
| |
80 fn differential(&self, x : X) -> Self::Derivative { |
| |
81 (*self).differential(x) |
| |
82 } |
| 75 } |
83 } |
| 76 |
84 |
| 77 /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials |
85 /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials |
| 78 /// `Differential`. |
86 /// `Differential`. |
| 79 /// |
87 /// |
| 97 where T : Mapping<Domain> |
105 where T : Mapping<Domain> |
| 98 + Differentiable<Domain, Derivative=Derivative> |
106 + Differentiable<Domain, Derivative=Derivative> |
| 99 + for<'a> Differentiable<&'a Domain,Derivative=Derivative> { |
107 + for<'a> Differentiable<&'a Domain,Derivative=Derivative> { |
| 100 type DerivativeDomain = Derivative; |
108 type DerivativeDomain = Derivative; |
| 101 type Differential = Differential<Domain, Self>; |
109 type Differential = Differential<Domain, Self>; |
| 102 type DifferentialRef<'b> = Differential<Domain, Ref<'b, Self>> where Self : 'b; |
110 type DifferentialRef<'b> = Differential<Domain, &'b Self> where Self : 'b; |
| 103 |
111 |
| 104 /// Form the differential mapping of `self`. |
112 /// Form the differential mapping of `self`. |
| 105 fn diff(self) -> Self::Differential { |
113 fn diff(self) -> Self::Differential { |
| 106 Differential{ g : self, _space : PhantomData } |
114 Differential{ g : self, _space : PhantomData } |
| 107 } |
115 } |
| 108 |
116 |
| 109 /// Form the differential mapping of `self`. |
117 /// Form the differential mapping of `self`. |
| 110 fn diff_ref(&self) -> Self::DifferentialRef<'_> { |
118 fn diff_ref(&self) -> Self::DifferentialRef<'_> { |
| 111 Differential{ g : Ref(self), _space : PhantomData } |
119 Differential{ g : self, _space : PhantomData } |
| 112 } |
120 } |
| 113 } |
121 } |
| 114 |
122 |
| 115 /// A sum of [`Mapping`]s. |
123 /// A sum of [`Mapping`]s. |
| 116 #[derive(Serialize, Debug, Clone)] |
124 #[derive(Serialize, Debug, Clone)] |
| 167 |
175 |
| 168 /// Container for the differential [`Mapping`] of a [`Differentiable`] mapping. |
176 /// Container for the differential [`Mapping`] of a [`Differentiable`] mapping. |
| 169 pub struct Differential<X, G : DifferentiableMapping<X>> { |
177 pub struct Differential<X, G : DifferentiableMapping<X>> { |
| 170 g : G, |
178 g : G, |
| 171 _space : PhantomData<X> |
179 _space : PhantomData<X> |
| |
180 } |
| |
181 |
| |
182 impl<X, G : DifferentiableMapping<X>> Differential<X, G> { |
| |
183 pub fn base_fn(&self) -> &G { |
| |
184 &self.g |
| |
185 } |
| 172 } |
186 } |
| 173 |
187 |
| 174 impl<X, G : DifferentiableMapping<X>> Apply<X> for Differential<X, G> { |
188 impl<X, G : DifferentiableMapping<X>> Apply<X> for Differential<X, G> { |
| 175 type Output = G::DerivativeDomain; |
189 type Output = G::DerivativeDomain; |
| 176 |
190 |
| 256 assert!(slice < N); |
270 assert!(slice < N); |
| 257 SlicedCodomain{ g : self, slice, _phantoms : PhantomData } |
271 SlicedCodomain{ g : self, slice, _phantoms : PhantomData } |
| 258 } |
272 } |
| 259 |
273 |
| 260 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. |
274 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. |
| 261 fn slice_codomain_ref(&self, slice : usize) -> SlicedCodomain<X, F, Ref<'_, Self>, N> { |
275 fn slice_codomain_ref(&self, slice : usize) -> SlicedCodomain<X, F, &'_ Self, N> { |
| 262 assert!(slice < N); |
276 assert!(slice < N); |
| 263 SlicedCodomain{ g : Ref(self), slice, _phantoms : PhantomData } |
277 SlicedCodomain{ g : self, slice, _phantoms : PhantomData } |
| 264 } |
278 } |
| 265 } |
279 } |
| 266 |
280 |
| 267 impl<X, F : Copy, G : Sized + Mapping<X, Codomain=Loc<F, N>>, const N : usize> |
281 impl<X, F : Copy, G : Sized + Mapping<X, Codomain=Loc<F, N>>, const N : usize> |
| 268 SliceCodomain<X, F, N> |
282 SliceCodomain<X, F, N> |
| 269 for G {} |
283 for G {} |
| 270 |
284 |
| 271 |
|
| 272 /// Helper struct for doing operations on references of mappings while avoiding |
|
| 273 /// conflicting implementations that `&'g G` would cause. |
|
| 274 pub struct Ref<'g, G>(&'g G); |
|
| 275 |
|
| 276 impl<'g, X, G : Apply<X>> Apply<X> for Ref<'g, G> { |
|
| 277 type Output = G::Output; |
|
| 278 #[inline] |
|
| 279 fn apply(&self, x : X) -> Self::Output { |
|
| 280 self.0.apply(x) |
|
| 281 } |
|
| 282 } |
|
| 283 |
|
| 284 impl<'g, X, G : Differentiable<X>> Differentiable<X> for Ref<'g, G> { |
|
| 285 type Derivative = G::Derivative; |
|
| 286 #[inline] |
|
| 287 fn differential(&self, x : X) -> Self::Derivative { |
|
| 288 self.0.differential(x) |
|
| 289 } |
|
| 290 } |
|