| 46 pub trait RealMapping<F : Float, const N : usize> |
46 pub trait RealMapping<F : Float, const N : usize> |
| 47 : Mapping<Loc<F, N>, Codomain = F> {} |
47 : Mapping<Loc<F, N>, Codomain = F> {} |
| 48 |
48 |
| 49 impl<F : Float, T, const N : usize> RealMapping<F, N> for T |
49 impl<F : Float, T, const N : usize> RealMapping<F, N> for T |
| 50 where T : Mapping<Loc<F, N>, Codomain = F> {} |
50 where T : Mapping<Loc<F, N>, Codomain = F> {} |
| |
51 |
| |
52 /// A helper trait alias for referring to [`Mapping`]s from [`Loc<F, N>`] to [`Loc<F, M>`]. |
| |
53 pub trait RealVectorField<F : Float, const N : usize, const M : usize> |
| |
54 : Mapping<Loc<F, N>, Codomain = Loc<F, M>> {} |
| |
55 |
| |
56 impl<F : Float, T, const N : usize, const M : usize> RealVectorField<F, N, M> for T |
| |
57 where T : Mapping<Loc<F, N>, Codomain = Loc<F, M>> {} |
| 51 |
58 |
| 52 |
59 |
| 53 /// Trait for calculation the differential of `Self` as a mathematical function on `X`. |
60 /// Trait for calculation the differential of `Self` as a mathematical function on `X`. |
| 54 pub trait Differentiable<X> : Sized { |
61 pub trait Differentiable<X> : Sized { |
| 55 type Output; |
62 type Output; |
| 142 fn apply(&self, x : &'a X) -> G::Differential { |
149 fn apply(&self, x : &'a X) -> G::Differential { |
| 143 self.g.differential(x) |
150 self.g.differential(x) |
| 144 } |
151 } |
| 145 } |
152 } |
| 146 |
153 |
| |
154 |
| |
155 /// Container for flattening [`Loc`]`<F, 1>` codomain of a [`Mapping`] to `F`. |
| |
156 pub struct FlattenedCodomain<X, F, G : Mapping<X, Codomain=Loc<F, 1>>> { |
| |
157 g : G, |
| |
158 _phantoms : PhantomData<(X, F)> |
| |
159 } |
| |
160 |
| |
161 impl<X, F, G : Mapping<X, Codomain=Loc<F, 1>>> Apply<X> for FlattenedCodomain<X, F, G> { |
| |
162 type Output = F; |
| |
163 |
| 147 #[inline] |
164 #[inline] |
| 148 fn apply(&self, x : X) -> Self::Output { |
165 fn apply(&self, x : X) -> Self::Output { |
| 149 self.g.differential(x) |
166 self.g.apply(x).flatten1d() |
| 150 } |
167 } |
| 151 } |
168 } |
| |
169 |
| |
170 /// An auto-trait for constructing a [`FlattenCodomain`] structure for |
| |
171 /// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`. |
| |
172 pub trait FlattenCodomain<X, F> : Mapping<X, Codomain=Loc<F, 1>> + Sized { |
| |
173 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. |
| |
174 fn flatten_codomain(self) -> FlattenedCodomain<X, F, Self> { |
| |
175 FlattenedCodomain{ g : self, _phantoms : PhantomData } |
| |
176 } |
| |
177 } |
| |
178 |
| |
179 impl<X, F, G : Sized + Mapping<X, Codomain=Loc<F, 1>>> FlattenCodomain<X, F> for G {} |
| |
180 |
| |
181 |
| |
182 /// Container for dimensional slicing [`Loc`]`<F, N>` codomain of a [`Mapping`] to `F`. |
| |
183 pub struct SlicedCodomain<X, F, G : Mapping<X, Codomain=Loc<F, N>>, const N : usize> { |
| |
184 g : G, |
| |
185 slice : usize, |
| |
186 _phantoms : PhantomData<(X, F)> |
| |
187 } |
| |
188 |
| |
189 impl<X, F : Copy, G : Mapping<X, Codomain=Loc<F, N>>, const N : usize> Apply<X> |
| |
190 for SlicedCodomain<X, F, G, N> { |
| |
191 type Output = F; |
| |
192 |
| |
193 #[inline] |
| |
194 fn apply(&self, x : X) -> Self::Output { |
| |
195 let tmp : [F; N] = self.g.apply(x).into(); |
| |
196 // Safety: `slice_codomain` below checks the range. |
| |
197 unsafe { *tmp.get_unchecked(self.slice) } |
| |
198 } |
| |
199 } |
| |
200 |
| |
201 impl<'a, X, F : Copy, G : Mapping<X, Codomain=Loc<F, N>>, const N : usize> Apply<&'a X> |
| |
202 for SlicedCodomain<X, F, G, N> { |
| |
203 type Output = F; |
| |
204 |
| |
205 #[inline] |
| |
206 fn apply(&self, x : &'a X) -> Self::Output { |
| |
207 let tmp : [F; N] = self.g.apply(x).into(); |
| |
208 // Safety: `slice_codomain` below checks the range. |
| |
209 unsafe { *tmp.get_unchecked(self.slice) } |
| |
210 } |
| |
211 } |
| |
212 |
| |
213 /// An auto-trait for constructing a [`FlattenCodomain`] structure for |
| |
214 /// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`. |
| |
215 pub trait SliceCodomain<X, F : Copy, const N : usize> : Mapping<X, Codomain=Loc<F, N>> + Sized { |
| |
216 /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`. |
| |
217 fn slice_codomain(self, slice : usize) -> SlicedCodomain<X, F, Self, N> { |
| |
218 assert!(slice < N); |
| |
219 SlicedCodomain{ g : self, slice, _phantoms : PhantomData } |
| |
220 } |
| |
221 } |
| |
222 |
| |
223 impl<X, F : Copy, G : Sized + Mapping<X, Codomain=Loc<F, N>>, const N : usize> |
| |
224 SliceCodomain<X, F, N> |
| |
225 for G {} |
| |
226 |