| 41 where T : Apply<Domain, Output=Codomain> + for<'a> Apply<&'a Domain, Output=Codomain> { |
41 where T : Apply<Domain, Output=Codomain> + for<'a> Apply<&'a Domain, Output=Codomain> { |
| 42 type Codomain = Codomain; |
42 type Codomain = Codomain; |
| 43 } |
43 } |
| 44 |
44 |
| 45 |
45 |
| 46 /// A helper trait alias for referring to [`Mapping`]s from [`Loc<F, N>`] to `F` a [`Float`]. |
46 pub trait RealMapping<F : Float, const N : usize> |
| 47 pub trait RealMapping<F : Float, const N : usize> : 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 |
51 |
| 52 |
52 |
| 53 /// Trait for calculation the differential of `Self` as a mathematical function on `X`. |
53 /// Trait for calculation the differential of `Self` as a mathematical function on `X`. |
| 54 pub trait Differentiable<X> { |
54 pub trait Differentiable<X> : Sized { |
| 55 type Output; |
55 type Output; |
| 56 |
56 |
| 57 /// Compute the differential of `self` at `x`. |
57 /// Compute the differential of `self` at `x`. |
| 58 fn differential(&self, x : X) -> Self::Output; |
58 fn differential(&self, x : X) -> Self::Output; |
| 59 } |
59 } |
| 60 |
|
| 61 |
60 |
| 62 /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials |
61 /// A differentiable mapping from `Domain` to [`Mapping::Codomain`], with differentials |
| 63 /// `Differential`. |
62 /// `Differential`. |
| 64 /// |
63 /// |
| 65 /// This is automatically implemented when the relevant [`Differentiate`] are implemented. |
64 /// This is automatically implemented when the relevant [`Differentiate`] are implemented. |
| 66 pub trait DifferentiableMapping<Domain> |
65 pub trait DifferentiableMapping<Domain> |
| 67 : Mapping<Domain> |
66 : Mapping<Domain> |
| 68 + Differentiable<Domain, Output=Self::Differential> |
67 + Differentiable<Domain, Output=Self::Differential> |
| 69 + for<'a> Differentiable<&'a Domain, Output=Self::Differential>{ |
68 + for<'a> Differentiable<&'a Domain, Output=Self::Differential> { |
| 70 type Differential; |
69 type Differential; |
| |
70 |
| |
71 /// Form the differential mapping of `self`. |
| |
72 fn diff(self) -> Differential<Domain, Self> { |
| |
73 Differential{ g : self, _space : PhantomData } |
| |
74 } |
| 71 } |
75 } |
| 72 |
76 |
| 73 |
77 |
| 74 impl<Domain, Differential, T> DifferentiableMapping<Domain> for T |
78 impl<Domain, Differential, T> DifferentiableMapping<Domain> for T |
| 75 where T : Mapping<Domain> |
79 where T : Mapping<Domain> |
| 113 |
117 |
| 114 fn differential(&self, x : Domain) -> Self::Output { |
118 fn differential(&self, x : Domain) -> Self::Output { |
| 115 self.components.iter().map(|c| c.differential(x)).sum() |
119 self.components.iter().map(|c| c.differential(x)).sum() |
| 116 } |
120 } |
| 117 } |
121 } |
| |
122 |
| |
123 /// Container for the differential [`Mapping`] of a [`Differentiable`] mapping. |
| |
124 pub struct Differential<X, G : DifferentiableMapping<X>> { |
| |
125 g : G, |
| |
126 _space : PhantomData<X> |
| |
127 } |
| |
128 |
| |
129 impl<X, G : DifferentiableMapping<X>> Apply<X> for Differential<X, G> { |
| |
130 type Output = G::Differential; |
| |
131 |
| |
132 #[inline] |
| |
133 fn apply(&self, x : X) -> G::Differential { |
| |
134 self.g.differential(x) |
| |
135 } |
| |
136 } |
| |
137 |
| |
138 impl<'a, X, G : DifferentiableMapping<X>> Apply<&'a X> for Differential<X, G> { |
| |
139 type Output = G::Differential; |
| |
140 |
| |
141 #[inline] |
| |
142 fn apply(&self, x : &'a X) -> G::Differential { |
| |
143 self.g.differential(x) |
| |
144 } |
| |
145 } |
| |
146 |
| |
147 #[inline] |
| |
148 fn apply(&self, x : X) -> Self::Output { |
| |
149 self.g.differential(x) |
| |
150 } |
| |
151 } |