src/bisection_tree/either.rs

branch
dev
changeset 81
d2acaaddd9af
parent 47
a0db98c16ab5
equal deleted inserted replaced
49:edb95d2b83cc 81:d2acaaddd9af
27 pub enum EitherSupport<A, B> { 27 pub enum EitherSupport<A, B> {
28 Left(A), 28 Left(A),
29 Right(B), 29 Right(B),
30 } 30 }
31 31
32 impl<A, B, F : Num> HasScalarField for EitherSupport<A, B>
33 where A : HasScalarField<Field = F>,
34 B : HasScalarField<Field = F> {
35 type Field = F;
36 }
37
32 // We need type alias bounds to access associate types. 38 // We need type alias bounds to access associate types.
33 #[allow(type_alias_bounds)] 39 #[allow(type_alias_bounds)]
34 type BothAllDataIter< 40 type BothAllDataIter<
35 'a, F, 41 'a,
36 G1 : SupportGenerator<F, N>, 42 G1 : SupportGenerator<N>,
37 G2 : SupportGenerator<F, N>, 43 G2 : SupportGenerator<N, RealField = G1::RealField>,
38 const N : usize 44 const N : usize
39 > = Chain< 45 > = Chain<
40 MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>, 46 MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>,
41 MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>, 47 MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>,
42 >; 48 >;
44 impl<G1, G2> BothGenerators<G1, G2> { 50 impl<G1, G2> BothGenerators<G1, G2> {
45 /// Helper for [`all_left_data`]. 51 /// Helper for [`all_left_data`].
46 #[inline] 52 #[inline]
47 fn map_left<F : Float, const N : usize>((d, support) : (G1::Id, G1::SupportType)) 53 fn map_left<F : Float, const N : usize>((d, support) : (G1::Id, G1::SupportType))
48 -> (usize, EitherSupport<G1::SupportType, G2::SupportType>) 54 -> (usize, EitherSupport<G1::SupportType, G2::SupportType>)
49 where G1 : SupportGenerator<F, N, Id=usize>, 55 where G1 : SupportGenerator<N, Id=usize, RealField =F>,
50 G2 : SupportGenerator<F, N, Id=usize> { 56 G2 : SupportGenerator<N, Id=usize, RealField = F> {
51 57
52 let id : usize = d.into(); 58 let id : usize = d.into();
53 (id.into(), EitherSupport::Left(support)) 59 (id.into(), EitherSupport::Left(support))
54 } 60 }
55 61
56 /// Helper for [`all_right_data`]. 62 /// Helper for [`all_right_data`].
57 #[inline] 63 #[inline]
58 fn map_right<F : Float, const N : usize>(n0 : &usize, (d, support) : (G2::Id, G2::SupportType)) 64 fn map_right<F : Float, const N : usize>(n0 : &usize, (d, support) : (G2::Id, G2::SupportType))
59 -> (usize, EitherSupport<G1::SupportType, G2::SupportType>) 65 -> (usize, EitherSupport<G1::SupportType, G2::SupportType>)
60 where G1 : SupportGenerator<F, N, Id=usize>, 66 where G1 : SupportGenerator<N, Id=usize, RealField = F>,
61 G2 : SupportGenerator<F, N, Id=usize> { 67 G2 : SupportGenerator<N, Id=usize, RealField = F> {
62 68
63 let id : usize = d.into(); 69 let id : usize = d.into();
64 ((n0+id).into(), EitherSupport::Right(support)) 70 ((n0+id).into(), EitherSupport::Right(support))
65 } 71 }
66 72
68 /// 74 ///
69 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`. 75 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`.
70 #[inline] 76 #[inline]
71 pub(super) fn all_left_data<F : Float, const N : usize>(&self) 77 pub(super) fn all_left_data<F : Float, const N : usize>(&self)
72 -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)> 78 -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>
73 where G1 : SupportGenerator<F, N, Id=usize>, 79 where G1 : SupportGenerator<N, Id=usize, RealField = F>,
74 G2 : SupportGenerator<F, N, Id=usize> { 80 G2 : SupportGenerator<N, Id=usize, RealField = F> {
75 self.0.all_data().mapF(Self::map_left) 81 self.0.all_data().mapF(Self::map_left)
76 } 82 }
77 83
78 /// Calls [`SupportGenerator::all_data`] on the “right” support generator. 84 /// Calls [`SupportGenerator::all_data`] on the “right” support generator.
79 /// 85 ///
80 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`. 86 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`.
81 #[inline] 87 #[inline]
82 pub(super) fn all_right_data<F : Float, const N : usize>(&self) 88 pub(super) fn all_right_data<F : Float, const N : usize>(&self)
83 -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)> 89 -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>
84 where G1 : SupportGenerator<F, N, Id=usize>, 90 where G1 : SupportGenerator<N, Id=usize, RealField=F>,
85 G2 : SupportGenerator<F, N, Id=usize> { 91 G2 : SupportGenerator<N, Id=usize, RealField=F> {
86 let n0 = self.0.support_count(); 92 let n0 = self.0.support_count();
87 self.1.all_data().mapZ(n0, Self::map_right) 93 self.1.all_data().mapZ(n0, Self::map_right)
88 } 94 }
89 } 95 }
90 96
97 impl<F : Float, G1, G2> HasScalarField for BothGenerators<G1, G2>
98 where G1 : HasScalarField<Field=F>,
99 G2 : HasScalarField<Field=F> {
100 type Field = F;
101 }
102
91 impl<F : Float, G1, G2, const N : usize> 103 impl<F : Float, G1, G2, const N : usize>
92 SupportGenerator<F, N> 104 SupportGenerator<N>
93 for BothGenerators<G1, G2> 105 for BothGenerators<G1, G2>
94 where G1 : SupportGenerator<F, N, Id=usize>, 106 where G1 : SupportGenerator<N, Id=usize> + HasRealField<RealField=F>,
95 G2 : SupportGenerator<F, N, Id=usize> { 107 G2 : SupportGenerator<N, Id=usize> + HasRealField<RealField=F>,
108 Self : HasRealField<RealField = F> {
96 109
97 type Id = usize; 110 type Id = usize;
98 type SupportType = EitherSupport<G1::SupportType, G2::SupportType>; 111 type SupportType = EitherSupport<G1::SupportType, G2::SupportType>;
99 type AllDataIter<'a> = BothAllDataIter<'a, F, G1, G2, N> where G1 : 'a, G2 : 'a; 112 type AllDataIter<'a> = BothAllDataIter<'a, G1, G2, N> where G1 : 'a, G2 : 'a;
100 113
101 #[inline] 114 #[inline]
102 fn support_for(&self, id : Self::Id) 115 fn support_for(&self, id : Self::Id)
103 -> Self::SupportType { 116 -> Self::SupportType {
104 let n0 = self.0.support_count(); 117 let n0 = self.0.support_count();
118 fn all_data(&self) -> Self::AllDataIter<'_> { 131 fn all_data(&self) -> Self::AllDataIter<'_> {
119 self.all_left_data().chain(self.all_right_data()) 132 self.all_left_data().chain(self.all_right_data())
120 } 133 }
121 } 134 }
122 135
123 impl<F: Float, S1, S2, const N : usize> Support<F, N> for EitherSupport<S1, S2> 136 impl<F: Float, S1, S2, const N : usize> Support<N> for EitherSupport<S1, S2>
124 where S1 : Support<F, N>, 137 where S1 : Support<N, RealField = F>,
125 S2 : Support<F, N> { 138 S2 : Support<N, RealField = F> {
126 139
127 #[inline] 140 #[inline]
128 fn support_hint(&self) -> Cube<F,N> { 141 fn support_hint(&self) -> Cube<F,N> {
129 match self { 142 match self {
130 EitherSupport::Left(ref a) => a.support_hint(), 143 EitherSupport::Left(ref a) => a.support_hint(),
147 EitherSupport::Right(ref b) => b.bisection_hint(cube), 160 EitherSupport::Right(ref b) => b.bisection_hint(cube),
148 } 161 }
149 } 162 }
150 } 163 }
151 164
152 impl<F : Float, A, S1, S2, const N : usize> LocalAnalysis<F, A, N> for EitherSupport<S1, S2> 165 impl<F : Float, A, S1, S2, const N : usize> LocalAnalysis<A, Cube<F, N>>
166 for EitherSupport<S1, S2>
153 where A : Aggregator, 167 where A : Aggregator,
154 S1 : LocalAnalysis<F, A, N>, 168 S1 : LocalAnalysis<A, Cube<F, N>>,
155 S2 : LocalAnalysis<F, A, N>, { 169 S2 : LocalAnalysis<A, Cube<F, N>> {
156 170
157 #[inline] 171 #[inline]
158 fn local_analysis(&self, cube : &Cube<F, N>) -> A { 172 fn local_analysis(&self, cube : &Cube<F, N>) -> A {
159 match self { 173 match self {
160 EitherSupport::Left(ref a) => a.local_analysis(cube), 174 EitherSupport::Left(ref a) => a.local_analysis(cube),
161 EitherSupport::Right(ref b) => b.local_analysis(cube), 175 EitherSupport::Right(ref b) => b.local_analysis(cube),
162 } 176 }
163 } 177 }
164 } 178 }
165 179
166 impl<F : Float, A, S1, S2> GlobalAnalysis<F, A> for EitherSupport<S1, S2> 180 impl<A, S1, S2> GlobalAnalysis<A> for EitherSupport<S1, S2>
167 where A : Aggregator, 181 where A : Aggregator,
168 S1 : GlobalAnalysis<F, A>, 182 S1 : GlobalAnalysis<A>,
169 S2 : GlobalAnalysis<F, A>, { 183 S2 : GlobalAnalysis<A>, {
170 184
171 #[inline] 185 #[inline]
172 fn global_analysis(&self) -> A { 186 fn global_analysis(&self) -> A {
173 match self { 187 match self {
174 EitherSupport::Left(ref a) => a.global_analysis(), 188 EitherSupport::Left(ref a) => a.global_analysis(),
188 EitherSupport::Right(ref b) => b.apply(x), 202 EitherSupport::Right(ref b) => b.apply(x),
189 } 203 }
190 } 204 }
191 } 205 }
192 206
193 impl<F, S1, S2, X> Differentiable<X> for EitherSupport<S1, S2> 207 impl<F : Float, S1, S2, X> Differentiable<X> for EitherSupport<S1, S2>
194 where S1 : Differentiable<X, Derivative=F>, 208 where S1 : Differentiable<X, Derivative=F, RealField=F>,
195 S2 : Differentiable<X, Derivative=F> { 209 S2 : Differentiable<X, Derivative=F, RealField=F> {
196 type Derivative = F; 210 type Derivative = F;
197 #[inline] 211 #[inline]
198 fn differential(&self, x : X) -> F { 212 fn differential(&self, x : X) -> F {
199 match self { 213 match self {
200 EitherSupport::Left(ref a) => a.differential(x), 214 EitherSupport::Left(ref a) => a.differential(x),

mercurial