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 |