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