src/mapping.rs

branch
dev
changeset 150
c4e394a9c84c
parent 133
2b13f8a0c8ba
child 151
402d717bb5c0
equal deleted inserted replaced
149:2f1798c65fd6 150:c4e394a9c84c
2 Traits for mathematical functions. 2 Traits for mathematical functions.
3 */ 3 */
4 4
5 use crate::error::DynResult; 5 use crate::error::DynResult;
6 use crate::instance::MyCow; 6 use crate::instance::MyCow;
7 pub use crate::instance::{BasicDecomposition, Decomposition, Instance, Space}; 7 pub use crate::instance::{BasicDecomposition, ClosedSpace, Decomposition, Instance, Space};
8 use crate::loc::Loc; 8 use crate::loc::Loc;
9 use crate::norms::{Norm, NormExponent}; 9 use crate::norms::{Norm, NormExponent};
10 use crate::operator_arithmetic::{Constant, Weighted}; 10 use crate::operator_arithmetic::{Constant, Weighted};
11 use crate::types::{ClosedMul, Float, Num}; 11 use crate::types::{ClosedMul, Float, Num};
12 use std::marker::PhantomData; 12 use std::marker::PhantomData;
13 use std::ops::Mul; 13 use std::ops::Mul;
14 14
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: Space; 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>>(&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
26 Self: Sized, 26 Self: Sized,
27 { 27 {
28 Composition { 28 Composition { outer: self, inner: other, intermediate_norm_exponent: () }
29 outer: self,
30 inner: other,
31 intermediate_norm_exponent: (),
32 }
33 } 29 }
34 30
35 #[inline] 31 #[inline]
36 /// Form the composition `self ∘ other`, assigning a norm to the inermediate space 32 /// Form the composition `self ∘ other`, assigning a norm to the inermediate space
37 fn compose_with_norm<F, X, T, E>(self, other: T, norm: E) -> Composition<Self, T, E> 33 fn compose_with_norm<F, X, T, E>(self, other: T, norm: E) -> Composition<Self, T, E>
41 T: Mapping<X, Codomain = Domain>, 37 T: Mapping<X, Codomain = Domain>,
42 E: NormExponent, 38 E: NormExponent,
43 Domain: Norm<E, F>, 39 Domain: Norm<E, F>,
44 F: Num, 40 F: Num,
45 { 41 {
46 Composition { 42 Composition { outer: self, inner: other, intermediate_norm_exponent: norm }
47 outer: self,
48 inner: other,
49 intermediate_norm_exponent: norm,
50 }
51 } 43 }
52 44
53 /// Multiply `self` by the scalar `a`. 45 /// Multiply `self` by the scalar `a`.
54 #[inline] 46 #[inline]
55 fn weigh<C>(self, a: C) -> Weighted<Self, C> 47 fn weigh<C>(self, a: C) -> Weighted<Self, C>
56 where 48 where
57 Self: Sized, 49 Self: Sized,
58 C: Constant, 50 C: Constant,
59 Self::Codomain: ClosedMul<C::Type>, 51 Self::Codomain: ClosedMul<C::Type>,
60 { 52 {
61 Weighted { 53 Weighted { weight: a, base_fn: self }
62 weight: a,
63 base_fn: self,
64 }
65 } 54 }
66 } 55 }
67 56
68 /// Automatically implemented shorthand for referring to [`Mapping`]s from [`Loc<N, F>`] to `F`. 57 /// Automatically implemented shorthand for referring to [`Mapping`]s from [`Loc<N, F>`] to `F`.
69 pub trait RealMapping<const N: usize, F: Float = f64>: Mapping<Loc<N, F>, Codomain = F> {} 58 pub trait RealMapping<const N: usize, F: Float = f64>: Mapping<Loc<N, F>, Codomain = F> {}
84 /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials 73 /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials
85 /// `Differential`. 74 /// `Differential`.
86 /// 75 ///
87 /// This is automatically implemented when [`DifferentiableImpl`] is. 76 /// This is automatically implemented when [`DifferentiableImpl`] is.
88 pub trait DifferentiableMapping<Domain: Space>: Mapping<Domain> { 77 pub trait DifferentiableMapping<Domain: Space>: Mapping<Domain> {
89 type DerivativeDomain: Space; 78 type DerivativeDomain: ClosedSpace;
90 type Differential<'b>: Mapping<Domain, Codomain = Self::DerivativeDomain> 79 type Differential<'b>: Mapping<Domain, Codomain = Self::DerivativeDomain>
91 where 80 where
92 Self: 'b; 81 Self: 'b;
93 82
94 /// Calculate differential at `x` 83 /// Calculate differential at `x`
113 { 102 {
114 } 103 }
115 104
116 /// Helper trait for implementing [`DifferentiableMapping`] 105 /// Helper trait for implementing [`DifferentiableMapping`]
117 pub trait DifferentiableImpl<X: Space>: Sized { 106 pub trait DifferentiableImpl<X: Space>: Sized {
118 type Derivative: Space; 107 type Derivative: ClosedSpace;
119 108
120 /// Compute the differential of `self` at `x`, consuming the input. 109 /// Compute the differential of `self` at `x`, consuming the input.
121 fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative; 110 fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative;
122 } 111 }
123 112
136 fn differential<I: Instance<Domain>>(&self, x: I) -> Self::DerivativeDomain { 125 fn differential<I: Instance<Domain>>(&self, x: I) -> Self::DerivativeDomain {
137 self.differential_impl(x) 126 self.differential_impl(x)
138 } 127 }
139 128
140 fn diff(self) -> Differential<'static, Domain, Self> { 129 fn diff(self) -> Differential<'static, Domain, Self> {
141 Differential { 130 Differential { g: MyCow::Owned(self), _space: PhantomData }
142 g: MyCow::Owned(self),
143 _space: PhantomData,
144 }
145 } 131 }
146 132
147 fn diff_ref(&self) -> Differential<'_, Domain, Self> { 133 fn diff_ref(&self) -> Differential<'_, Domain, Self> {
148 Differential { 134 Differential { g: MyCow::Borrowed(self), _space: PhantomData }
149 g: MyCow::Borrowed(self),
150 _space: PhantomData,
151 }
152 } 135 }
153 } 136 }
154 137
155 /// Container for the differential [`Mapping`] of a [`DifferentiableMapping`]. 138 /// Container for the differential [`Mapping`] of a [`DifferentiableMapping`].
156 pub struct Differential<'a, X, G> { 139 pub struct Differential<'a, X, G> {
199 /// An auto-trait for constructing a [`FlattenCodomain`] structure for 182 /// An auto-trait for constructing a [`FlattenCodomain`] structure for
200 /// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`. 183 /// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`.
201 pub trait FlattenCodomain<X: Space, F>: Mapping<X, Codomain = Loc<1, F>> + Sized { 184 pub trait FlattenCodomain<X: Space, F>: Mapping<X, Codomain = Loc<1, F>> + Sized {
202 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. 185 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
203 fn flatten_codomain(self) -> FlattenedCodomain<X, F, Self> { 186 fn flatten_codomain(self) -> FlattenedCodomain<X, F, Self> {
204 FlattenedCodomain { 187 FlattenedCodomain { g: self, _phantoms: PhantomData }
205 g: self,
206 _phantoms: PhantomData,
207 }
208 } 188 }
209 } 189 }
210 190
211 impl<X: Space, F, G: Sized + Mapping<X, Codomain = Loc<1, F>>> FlattenCodomain<X, F> for G {} 191 impl<X: Space, F, G: Sized + Mapping<X, Codomain = Loc<1, F>>> FlattenCodomain<X, F> for G {}
212 192
239 Mapping<X, Codomain = Loc<N, F>> + Sized 219 Mapping<X, Codomain = Loc<N, F>> + Sized
240 { 220 {
241 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. 221 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
242 fn slice_codomain(self, slice: usize) -> SlicedCodomain<'static, X, F, Self, N> { 222 fn slice_codomain(self, slice: usize) -> SlicedCodomain<'static, X, F, Self, N> {
243 assert!(slice < N); 223 assert!(slice < N);
244 SlicedCodomain { 224 SlicedCodomain { g: MyCow::Owned(self), slice, _phantoms: PhantomData }
245 g: MyCow::Owned(self),
246 slice,
247 _phantoms: PhantomData,
248 }
249 } 225 }
250 226
251 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. 227 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
252 fn slice_codomain_ref(&self, slice: usize) -> SlicedCodomain<'_, X, F, Self, N> { 228 fn slice_codomain_ref(&self, slice: usize) -> SlicedCodomain<'_, X, F, Self, N> {
253 assert!(slice < N); 229 assert!(slice < N);
254 SlicedCodomain { 230 SlicedCodomain { g: MyCow::Borrowed(self), slice, _phantoms: PhantomData }
255 g: MyCow::Borrowed(self),
256 slice,
257 _phantoms: PhantomData,
258 }
259 } 231 }
260 } 232 }
261 233
262 impl<X: Space, F: Copy, G: Sized + Mapping<X, Codomain = Loc<N, F>>, const N: usize> 234 impl<X: Space, F: Copy, G: Sized + Mapping<X, Codomain = Loc<N, F>>, const N: usize>
263 SliceCodomain<X, N, F> for G 235 SliceCodomain<X, N, F> for G
292 T: DifferentiableImpl<X> + Mapping<X>, 264 T: DifferentiableImpl<X> + Mapping<X>,
293 S: DifferentiableImpl<T::Codomain>, 265 S: DifferentiableImpl<T::Codomain>,
294 E: Copy, 266 E: Copy,
295 //Composition<S::Derivative, T::Derivative, E>: Space, 267 //Composition<S::Derivative, T::Derivative, E>: Space,
296 S::Derivative: Mul<T::Derivative, Output = Y>, 268 S::Derivative: Mul<T::Derivative, Output = Y>,
297 Y: Space, 269 Y: ClosedSpace,
298 { 270 {
299 //type Derivative = Composition<S::Derivative, T::Derivative, E>; 271 //type Derivative = Composition<S::Derivative, T::Derivative, E>;
300 type Derivative = Y; 272 type Derivative = Y;
301 273
302 /// Compute the differential of `self` at `x`, consuming the input. 274 /// Compute the differential of `self` at `x`, consuming the input.

mercurial