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 } |