| 7 use crate::types::{Num, Float, ClosedMul}; |
7 use crate::types::{Num, Float, ClosedMul}; |
| 8 use crate::loc::Loc; |
8 use crate::loc::Loc; |
| 9 pub use crate::instance::{Instance, Decomposition, BasicDecomposition, Space}; |
9 pub use crate::instance::{Instance, Decomposition, BasicDecomposition, Space}; |
| 10 use crate::norms::{Norm, NormExponent}; |
10 use crate::norms::{Norm, NormExponent}; |
| 11 |
11 |
| |
12 pub trait ArithmeticOptIn {} |
| |
13 |
| |
14 pub struct ArithmeticTrue; |
| |
15 pub struct ArithmeticFalse; |
| |
16 |
| |
17 impl ArithmeticOptIn for ArithmeticTrue {} |
| |
18 impl ArithmeticOptIn for ArithmeticFalse {} |
| |
19 |
| 12 /// A mapping from `Domain` to `Codomain`. |
20 /// A mapping from `Domain` to `Codomain`. |
| 13 /// |
21 /// |
| 14 /// This is automatically implemented when the relevant [`Apply`] are implemented. |
22 /// This is automatically implemented when the relevant [`Apply`] are implemented. |
| 15 pub trait Mapping<Domain : Space> { |
23 pub trait Mapping<Domain : Space> { |
| 16 type Codomain : Space; |
24 type Codomain : Space; |
| |
25 type ArithmeticOptIn : ArithmeticOptIn; |
| 17 |
26 |
| 18 /// Compute the value of `self` at `x`. |
27 /// Compute the value of `self` at `x`. |
| 19 fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain; |
28 fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain; |
| 20 |
29 |
| 21 #[inline] |
30 #[inline] |
| 152 Domain : Space + Clone, |
161 Domain : Space + Clone, |
| 153 M : Mapping<Domain>, |
162 M : Mapping<Domain>, |
| 154 M::Codomain : std::iter::Sum + Clone |
163 M::Codomain : std::iter::Sum + Clone |
| 155 { |
164 { |
| 156 type Codomain = M::Codomain; |
165 type Codomain = M::Codomain; |
| |
166 type ArithmeticOptIn = ArithmeticTrue; |
| 157 |
167 |
| 158 fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain { |
168 fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain { |
| 159 let xr = x.ref_instance(); |
169 let xr = x.ref_instance(); |
| 160 self.components.iter().map(|c| c.apply(xr)).sum() |
170 self.components.iter().map(|c| c.apply(xr)).sum() |
| 161 } |
171 } |
| 191 where |
201 where |
| 192 X : Space, |
202 X : Space, |
| 193 G : Clone + DifferentiableMapping<X> |
203 G : Clone + DifferentiableMapping<X> |
| 194 { |
204 { |
| 195 type Codomain = G::DerivativeDomain; |
205 type Codomain = G::DerivativeDomain; |
| |
206 type ArithmeticOptIn = ArithmeticTrue; |
| 196 |
207 |
| 197 #[inline] |
208 #[inline] |
| 198 fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain { |
209 fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain { |
| 199 (*self.g).differential(x) |
210 (*self.g).differential(x) |
| 200 } |
211 } |
| 242 X : Space, |
254 X : Space, |
| 243 F : Copy + Space, |
255 F : Copy + Space, |
| 244 G : Mapping<X, Codomain=Loc<F, N>> + Clone, |
256 G : Mapping<X, Codomain=Loc<F, N>> + Clone, |
| 245 { |
257 { |
| 246 type Codomain = F; |
258 type Codomain = F; |
| |
259 type ArithmeticOptIn = ArithmeticTrue; |
| 247 |
260 |
| 248 #[inline] |
261 #[inline] |
| 249 fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain { |
262 fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain { |
| 250 let tmp : [F; N] = (*self.g).apply(x).into(); |
263 let tmp : [F; N] = (*self.g).apply(x).into(); |
| 251 // Safety: `slice_codomain` below checks the range. |
264 // Safety: `slice_codomain` below checks the range. |
| 288 X : Space, |
301 X : Space, |
| 289 T : Mapping<X>, |
302 T : Mapping<X>, |
| 290 S : Mapping<T::Codomain> |
303 S : Mapping<T::Codomain> |
| 291 { |
304 { |
| 292 type Codomain = S::Codomain; |
305 type Codomain = S::Codomain; |
| |
306 type ArithmeticOptIn = ArithmeticTrue; |
| 293 |
307 |
| 294 #[inline] |
308 #[inline] |
| 295 fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain { |
309 fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain { |
| 296 self.outer.apply(self.inner.apply(x)) |
310 self.outer.apply(self.inner.apply(x)) |
| 297 } |
311 } |