src/mapping.rs

branch
dev
changeset 128
f75bf34adda0
parent 124
6aa955ad8122
child 133
2b13f8a0c8ba
equal deleted inserted replaced
127:212f75931da0 128:f75bf34adda0
1 /*! 1 /*!
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 pub use crate::instance::{BasicDecomposition, Decomposition, Instance, Space}; 7 pub use crate::instance::{BasicDecomposition, Decomposition, Instance, Space};
7 use crate::loc::Loc; 8 use crate::loc::Loc;
8 use crate::norms::{Norm, NormExponent}; 9 use crate::norms::{Norm, NormExponent};
9 use crate::operator_arithmetic::{Constant, Weighted}; 10 use crate::operator_arithmetic::{Constant, Weighted};
10 use crate::types::{ClosedMul, Float, Num}; 11 use crate::types::{ClosedMul, Float, Num};
11 use std::borrow::Cow;
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> {
122 } 122 }
123 123
124 impl<T, Domain> DifferentiableMapping<Domain> for T 124 impl<T, Domain> DifferentiableMapping<Domain> for T
125 where 125 where
126 Domain: Space, 126 Domain: Space,
127 T: Clone + Mapping<Domain> + DifferentiableImpl<Domain>, 127 T: Mapping<Domain> + DifferentiableImpl<Domain>,
128 { 128 {
129 type DerivativeDomain = T::Derivative; 129 type DerivativeDomain = T::Derivative;
130 type Differential<'b> 130 type Differential<'b>
131 = Differential<'b, Domain, Self> 131 = Differential<'b, Domain, Self>
132 where 132 where
137 self.differential_impl(x) 137 self.differential_impl(x)
138 } 138 }
139 139
140 fn diff(self) -> Differential<'static, Domain, Self> { 140 fn diff(self) -> Differential<'static, Domain, Self> {
141 Differential { 141 Differential {
142 g: Cow::Owned(self), 142 g: MyCow::Owned(self),
143 _space: PhantomData, 143 _space: PhantomData,
144 } 144 }
145 } 145 }
146 146
147 fn diff_ref(&self) -> Differential<'_, Domain, Self> { 147 fn diff_ref(&self) -> Differential<'_, Domain, Self> {
148 Differential { 148 Differential {
149 g: Cow::Borrowed(self), 149 g: MyCow::Borrowed(self),
150 _space: PhantomData, 150 _space: PhantomData,
151 } 151 }
152 } 152 }
153 } 153 }
154 154
155 /// Container for the differential [`Mapping`] of a [`DifferentiableMapping`]. 155 /// Container for the differential [`Mapping`] of a [`DifferentiableMapping`].
156 pub struct Differential<'a, X, G: Clone> { 156 pub struct Differential<'a, X, G> {
157 g: Cow<'a, G>, 157 g: MyCow<'a, G>,
158 _space: PhantomData<X>, 158 _space: PhantomData<X>,
159 } 159 }
160 160
161 impl<'a, X, G: Clone> Differential<'a, X, G> { 161 impl<'a, X, G> Differential<'a, X, G> {
162 pub fn base_fn(&self) -> &G { 162 pub fn base_fn(&self) -> &G {
163 &self.g 163 &self.g
164 } 164 }
165 } 165 }
166 166
167 impl<'a, X, G> Mapping<X> for Differential<'a, X, G> 167 impl<'a, X, G> Mapping<X> for Differential<'a, X, G>
168 where 168 where
169 X: Space, 169 X: Space,
170 G: Clone + DifferentiableMapping<X>, 170 G: DifferentiableMapping<X>,
171 { 171 {
172 type Codomain = G::DerivativeDomain; 172 type Codomain = G::DerivativeDomain;
173 173
174 #[inline] 174 #[inline]
175 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { 175 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
209 } 209 }
210 210
211 impl<X: Space, F, G: Sized + Mapping<X, Codomain = Loc<1, F>>> FlattenCodomain<X, F> for G {} 211 impl<X: Space, F, G: Sized + Mapping<X, Codomain = Loc<1, F>>> FlattenCodomain<X, F> for G {}
212 212
213 /// Container for dimensional slicing [`Loc`]`<N, F>` codomain of a [`Mapping`] to `F`. 213 /// Container for dimensional slicing [`Loc`]`<N, F>` codomain of a [`Mapping`] to `F`.
214 pub struct SlicedCodomain<'a, X, F, G: Clone, const N: usize> { 214 pub struct SlicedCodomain<'a, X, F, G, const N: usize> {
215 g: Cow<'a, G>, 215 g: MyCow<'a, G>,
216 slice: usize, 216 slice: usize,
217 _phantoms: PhantomData<(X, F)>, 217 _phantoms: PhantomData<(X, F)>,
218 } 218 }
219 219
220 impl<'a, X, F, G, const N: usize> Mapping<X> for SlicedCodomain<'a, X, F, G, N> 220 impl<'a, X, F, G, const N: usize> Mapping<X> for SlicedCodomain<'a, X, F, G, N>
221 where 221 where
222 X: Space, 222 X: Space,
223 F: Copy + Space, 223 F: Copy + Space,
224 G: Mapping<X, Codomain = Loc<N, F>> + Clone, 224 G: Mapping<X, Codomain = Loc<N, F>>,
225 { 225 {
226 type Codomain = F; 226 type Codomain = F;
227 227
228 #[inline] 228 #[inline]
229 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { 229 fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
234 } 234 }
235 235
236 /// An auto-trait for constructing a [`FlattenCodomain`] structure for 236 /// An auto-trait for constructing a [`FlattenCodomain`] structure for
237 /// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`. 237 /// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`.
238 pub trait SliceCodomain<X: Space, const N: usize, F: Copy = f64>: 238 pub trait SliceCodomain<X: Space, const N: usize, F: Copy = f64>:
239 Mapping<X, Codomain = Loc<N, F>> + Clone + Sized 239 Mapping<X, Codomain = Loc<N, F>> + Sized
240 { 240 {
241 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. 241 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
242 fn slice_codomain(self, slice: usize) -> SlicedCodomain<'static, X, F, Self, N> { 242 fn slice_codomain(self, slice: usize) -> SlicedCodomain<'static, X, F, Self, N> {
243 assert!(slice < N); 243 assert!(slice < N);
244 SlicedCodomain { 244 SlicedCodomain {
245 g: Cow::Owned(self), 245 g: MyCow::Owned(self),
246 slice, 246 slice,
247 _phantoms: PhantomData, 247 _phantoms: PhantomData,
248 } 248 }
249 } 249 }
250 250
251 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. 251 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
252 fn slice_codomain_ref(&self, slice: usize) -> SlicedCodomain<'_, X, F, Self, N> { 252 fn slice_codomain_ref(&self, slice: usize) -> SlicedCodomain<'_, X, F, Self, N> {
253 assert!(slice < N); 253 assert!(slice < N);
254 SlicedCodomain { 254 SlicedCodomain {
255 g: Cow::Borrowed(self), 255 g: MyCow::Borrowed(self),
256 slice, 256 slice,
257 _phantoms: PhantomData, 257 _phantoms: PhantomData,
258 } 258 }
259 } 259 }
260 } 260 }
261 261
262 impl<X: Space, F: Copy, G: Sized + Mapping<X, Codomain = Loc<N, F>> + Clone, const N: usize> 262 impl<X: Space, F: Copy, G: Sized + Mapping<X, Codomain = Loc<N, F>>, const N: usize>
263 SliceCodomain<X, N, F> for G 263 SliceCodomain<X, N, F> for G
264 { 264 {
265 } 265 }
266 266
267 /// The composition S ∘ T. `E` is for storing a `NormExponent` for the intermediate space. 267 /// The composition S ∘ T. `E` is for storing a `NormExponent` for the intermediate space.
335 } 335 }
336 336
337 impl<'b, M, X, A> Lipschitz<M> for Differential<'b, X, A> 337 impl<'b, M, X, A> Lipschitz<M> for Differential<'b, X, A>
338 where 338 where
339 X: Space, 339 X: Space,
340 A: LipschitzDifferentiableImpl<X, M> + Clone, 340 A: LipschitzDifferentiableImpl<X, M>,
341 { 341 {
342 type FloatType = A::FloatType; 342 type FloatType = A::FloatType;
343 343
344 fn lipschitz_factor(&self, seminorm: M) -> DynResult<Self::FloatType> { 344 fn lipschitz_factor(&self, seminorm: M) -> DynResult<Self::FloatType> {
345 (*self.g).diff_lipschitz_factor(seminorm) 345 (*self.g).diff_lipschitz_factor(seminorm)

mercurial