| 15 /// A mapping from `Domain` to `Self::Codomain`. |
15 /// A mapping from `Domain` to `Self::Codomain`. |
| 16 pub trait Mapping<Domain: Space> { |
16 pub trait Mapping<Domain: Space> { |
| 17 type Codomain: ClosedSpace; |
17 type Codomain: ClosedSpace; |
| 18 |
18 |
| 19 /// Compute the value of `self` at `x`. |
19 /// Compute the value of `self` at `x`. |
| 20 fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain; |
20 fn apply<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::Codomain; |
| 21 |
21 |
| 22 #[inline] |
22 #[inline] |
| 23 /// Form the composition `self ∘ other` |
23 /// Form the composition `self ∘ other` |
| 24 fn compose<X: Space, T: Mapping<X, Codomain = Domain>>(self, other: T) -> Composition<Self, T> |
24 fn compose<X: Space, T: Mapping<X, Codomain = Domain>>(self, other: T) -> Composition<Self, T> |
| 25 where |
25 where |
| 79 type Differential<'b>: Mapping<Domain, Codomain = Self::DerivativeDomain> |
79 type Differential<'b>: Mapping<Domain, Codomain = Self::DerivativeDomain> |
| 80 where |
80 where |
| 81 Self: 'b; |
81 Self: 'b; |
| 82 |
82 |
| 83 /// Calculate differential at `x` |
83 /// Calculate differential at `x` |
| 84 fn differential<I: Instance<Domain>>(&self, x: I) -> Self::DerivativeDomain; |
84 fn differential<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::DerivativeDomain; |
| 85 |
85 |
| 86 /// Form the differential mapping of `self`. |
86 /// Form the differential mapping of `self`. |
| 87 fn diff(self) -> Self::Differential<'static>; |
87 fn diff(self) -> Self::Differential<'static>; |
| 88 |
88 |
| 89 /// Form the differential mapping of `self`. |
89 /// Form the differential mapping of `self`. |
| 105 /// Helper trait for implementing [`DifferentiableMapping`] |
105 /// Helper trait for implementing [`DifferentiableMapping`] |
| 106 pub trait DifferentiableImpl<X: Space>: Sized { |
106 pub trait DifferentiableImpl<X: Space>: Sized { |
| 107 type Derivative: ClosedSpace; |
107 type Derivative: ClosedSpace; |
| 108 |
108 |
| 109 /// Compute the differential of `self` at `x`, consuming the input. |
109 /// Compute the differential of `self` at `x`, consuming the input. |
| 110 fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative; |
110 fn differential_impl<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Derivative; |
| 111 } |
111 } |
| 112 |
112 |
| 113 impl<T, Domain> DifferentiableMapping<Domain> for T |
113 impl<T, Domain> DifferentiableMapping<Domain> for T |
| 114 where |
114 where |
| 115 Domain: Space, |
115 Domain: Space, |
| 120 = Differential<'b, Domain, Self> |
120 = Differential<'b, Domain, Self> |
| 121 where |
121 where |
| 122 Self: 'b; |
122 Self: 'b; |
| 123 |
123 |
| 124 #[inline] |
124 #[inline] |
| 125 fn differential<I: Instance<Domain>>(&self, x: I) -> Self::DerivativeDomain { |
125 fn differential<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::DerivativeDomain { |
| 126 self.differential_impl(x) |
126 self.differential_impl(x) |
| 127 } |
127 } |
| 128 |
128 |
| 129 fn diff(self) -> Differential<'static, Domain, Self> { |
129 fn diff(self) -> Differential<'static, Domain, Self> { |
| 130 Differential { g: MyCow::Owned(self), _space: PhantomData } |
130 Differential { g: MyCow::Owned(self), _space: PhantomData } |
| 153 G: DifferentiableMapping<X>, |
153 G: DifferentiableMapping<X>, |
| 154 { |
154 { |
| 155 type Codomain = G::DerivativeDomain; |
155 type Codomain = G::DerivativeDomain; |
| 156 |
156 |
| 157 #[inline] |
157 #[inline] |
| 158 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { |
158 fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain { |
| 159 (*self.g).differential(x) |
159 (*self.g).differential(x) |
| 160 } |
160 } |
| 161 } |
161 } |
| 162 |
162 |
| 163 /// Container for flattening [`Loc`]`<F, 1>` codomain of a [`Mapping`] to `F`. |
163 /// Container for flattening [`Loc`]`<F, 1>` codomain of a [`Mapping`] to `F`. |
| 173 G: Mapping<X, Codomain = Loc<1, F>>, |
173 G: Mapping<X, Codomain = Loc<1, F>>, |
| 174 { |
174 { |
| 175 type Codomain = F; |
175 type Codomain = F; |
| 176 |
176 |
| 177 #[inline] |
177 #[inline] |
| 178 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { |
178 fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain { |
| 179 self.g.apply(x).flatten1d() |
179 self.g.apply(x).flatten1d() |
| 180 } |
180 } |
| 181 } |
181 } |
| 182 |
182 |
| 183 /// An auto-trait for constructing a [`FlattenCodomain`] structure for |
183 /// An auto-trait for constructing a [`FlattenCodomain`] structure for |
| 205 G: Mapping<X, Codomain = Loc<N, F>>, |
205 G: Mapping<X, Codomain = Loc<N, F>>, |
| 206 { |
206 { |
| 207 type Codomain = F; |
207 type Codomain = F; |
| 208 |
208 |
| 209 #[inline] |
209 #[inline] |
| 210 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { |
210 fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain { |
| 211 let tmp: [F; N] = (*self.g).apply(x).into(); |
211 let tmp: [F; N] = (*self.g).apply(x).into(); |
| 212 // Safety: `slice_codomain` below checks the range. |
212 // Safety: `slice_codomain` below checks the range. |
| 213 unsafe { *tmp.get_unchecked(self.slice) } |
213 unsafe { *tmp.get_unchecked(self.slice) } |
| 214 } |
214 } |
| 215 } |
215 } |
| 251 S: Mapping<T::Codomain>, |
251 S: Mapping<T::Codomain>, |
| 252 { |
252 { |
| 253 type Codomain = S::Codomain; |
253 type Codomain = S::Codomain; |
| 254 |
254 |
| 255 #[inline] |
255 #[inline] |
| 256 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { |
256 fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain { |
| 257 self.outer.apply(self.inner.apply(x)) |
257 self.outer.apply(self.inner.apply(x)) |
| 258 } |
258 } |
| 259 } |
259 } |
| 260 |
260 |
| 261 /// Helper trait for implementing [`DifferentiableMapping`] |
261 /// Helper trait for implementing [`DifferentiableMapping`] |
| 271 { |
271 { |
| 272 //type Derivative = Composition<S::Derivative, T::Derivative, E>; |
272 //type Derivative = Composition<S::Derivative, T::Derivative, E>; |
| 273 type Derivative = Y; |
273 type Derivative = Y; |
| 274 |
274 |
| 275 /// Compute the differential of `self` at `x`, consuming the input. |
275 /// Compute the differential of `self` at `x`, consuming the input. |
| 276 fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative { |
276 fn differential_impl<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Derivative { |
| 277 // Composition { |
277 // Composition { |
| 278 // outer: self |
278 // outer: self |
| 279 // .outer |
279 // .outer |
| 280 // .differential_impl(self.inner.apply(x.ref_instance())), |
280 // .differential_impl(self.inner.apply(x.ref_instance())), |
| 281 // inner: self.inner.differential_impl(x), |
281 // inner: self.inner.differential_impl(x), |