src/mapping.rs

branch
dev
changeset 49
edb95d2b83cc
parent 48
3f3e00e81755
child 53
08db78e3a654
child 81
d2acaaddd9af
equal deleted inserted replaced
48:3f3e00e81755 49:edb95d2b83cc
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 }

mercurial