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