src/bisection_tree/either.rs

branch
dev
changeset 124
6aa955ad8122
parent 59
9226980e45a7
child 150
c4e394a9c84c
equal deleted inserted replaced
122:495448cca603 124:6aa955ad8122
1
2 use std::iter::Chain; 1 use std::iter::Chain;
3 use std::sync::Arc; 2 use std::sync::Arc;
4 3
4 use crate::iter::{MapF, MapZ, Mappable};
5 use crate::loc::Loc;
6 use crate::mapping::{DifferentiableImpl, DifferentiableMapping, Instance, Mapping, Space};
7 use crate::sets::Cube;
5 use crate::types::*; 8 use crate::types::*;
6 use crate::mapping::{ 9
7 Instance, 10 use super::aggregator::*;
8 Mapping,
9 DifferentiableImpl,
10 DifferentiableMapping,
11 Space,
12 };
13 use crate::iter::{Mappable, MapF, MapZ};
14 use crate::sets::Cube;
15 use crate::loc::Loc;
16
17 use super::support::*; 11 use super::support::*;
18 use super::aggregator::*;
19 12
20 /// A structure for storing two [`SupportGenerator`]s summed/chain together. 13 /// A structure for storing two [`SupportGenerator`]s summed/chain together.
21 /// 14 ///
22 /// This is needed to work with sums of different types of [`Support`]s. 15 /// This is needed to work with sums of different types of [`Support`]s.
23 #[derive(Debug,Clone)] 16 #[derive(Debug, Clone)]
24 pub struct BothGenerators<A, B>( 17 pub struct BothGenerators<A, B>(pub(super) Arc<A>, pub(super) Arc<B>);
25 pub(super) Arc<A>,
26 pub(super) Arc<B>,
27 );
28 18
29 /// A structure for a [`Support`] that can be either `A` or `B`. 19 /// A structure for a [`Support`] that can be either `A` or `B`.
30 /// 20 ///
31 /// This is needed to work with sums of different types of [`Support`]s. 21 /// This is needed to work with sums of different types of [`Support`]s.
32 #[derive(Debug,Clone)] 22 #[derive(Debug, Clone)]
33 pub enum EitherSupport<A, B> { 23 pub enum EitherSupport<B, A> {
34 Left(A), 24 Left(A),
35 Right(B), 25 Right(B),
36 } 26 }
37 27
38 // We need type alias bounds to access associate types. 28 // We need type alias bounds to access associate types.
39 #[allow(type_alias_bounds)] 29 #[allow(type_alias_bounds)]
40 type BothAllDataIter< 30 type BothAllDataIter<
41 'a, F, 31 'a,
42 G1 : SupportGenerator<F, N>, 32 F,
43 G2 : SupportGenerator<F, N>, 33 G1: SupportGenerator<N, F>,
44 const N : usize 34 G2: SupportGenerator<N, F>,
35 const N: usize,
45 > = Chain< 36 > = Chain<
46 MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>, 37 MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>,
47 MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>, 38 MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>,
48 >; 39 >;
49 40
50 impl<G1, G2> BothGenerators<G1, G2> { 41 impl<G1, G2> BothGenerators<G1, G2> {
51 /// Helper for [`all_left_data`]. 42 /// Helper for [`all_left_data`].
52 #[inline] 43 #[inline]
53 fn map_left<F : Float, const N : usize>((d, support) : (G1::Id, G1::SupportType)) 44 fn map_left<F: Float, const N: usize>(
54 -> (usize, EitherSupport<G1::SupportType, G2::SupportType>) 45 (d, support): (G1::Id, G1::SupportType),
55 where G1 : SupportGenerator<F, N, Id=usize>, 46 ) -> (usize, EitherSupport<G2::SupportType, G1::SupportType>)
56 G2 : SupportGenerator<F, N, Id=usize> { 47 where
57 48 G1: SupportGenerator<N, F, Id = usize>,
58 let id : usize = d.into(); 49 G2: SupportGenerator<N, F, Id = usize>,
50 {
51 let id: usize = d.into();
59 (id.into(), EitherSupport::Left(support)) 52 (id.into(), EitherSupport::Left(support))
60 } 53 }
61 54
62 /// Helper for [`all_right_data`]. 55 /// Helper for [`all_right_data`].
63 #[inline] 56 #[inline]
64 fn map_right<F : Float, const N : usize>(n0 : &usize, (d, support) : (G2::Id, G2::SupportType)) 57 fn map_right<F: Float, const N: usize>(
65 -> (usize, EitherSupport<G1::SupportType, G2::SupportType>) 58 n0: &usize,
66 where G1 : SupportGenerator<F, N, Id=usize>, 59 (d, support): (G2::Id, G2::SupportType),
67 G2 : SupportGenerator<F, N, Id=usize> { 60 ) -> (usize, EitherSupport<G2::SupportType, G1::SupportType>)
68 61 where
69 let id : usize = d.into(); 62 G1: SupportGenerator<N, F, Id = usize>,
70 ((n0+id).into(), EitherSupport::Right(support)) 63 G2: SupportGenerator<N, F, Id = usize>,
64 {
65 let id: usize = d.into();
66 ((n0 + id).into(), EitherSupport::Right(support))
71 } 67 }
72 68
73 /// Calls [`SupportGenerator::all_data`] on the “left” support generator. 69 /// Calls [`SupportGenerator::all_data`] on the “left” support generator.
74 /// 70 ///
75 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`. 71 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`.
76 #[inline] 72 #[inline]
77 pub(super) fn all_left_data<F : Float, const N : usize>(&self) 73 pub(super) fn all_left_data<F: Float, const N: usize>(
78 -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)> 74 &self,
79 where G1 : SupportGenerator<F, N, Id=usize>, 75 ) -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>
80 G2 : SupportGenerator<F, N, Id=usize> { 76 where
77 G1: SupportGenerator<N, F, Id = usize>,
78 G2: SupportGenerator<N, F, Id = usize>,
79 {
81 self.0.all_data().mapF(Self::map_left) 80 self.0.all_data().mapF(Self::map_left)
82 } 81 }
83 82
84 /// Calls [`SupportGenerator::all_data`] on the “right” support generator. 83 /// Calls [`SupportGenerator::all_data`] on the “right” support generator.
85 /// 84 ///
86 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`. 85 /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`.
87 #[inline] 86 #[inline]
88 pub(super) fn all_right_data<F : Float, const N : usize>(&self) 87 pub(super) fn all_right_data<F: Float, const N: usize>(
89 -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)> 88 &self,
90 where G1 : SupportGenerator<F, N, Id=usize>, 89 ) -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>
91 G2 : SupportGenerator<F, N, Id=usize> { 90 where
91 G1: SupportGenerator<N, F, Id = usize>,
92 G2: SupportGenerator<N, F, Id = usize>,
93 {
92 let n0 = self.0.support_count(); 94 let n0 = self.0.support_count();
93 self.1.all_data().mapZ(n0, Self::map_right) 95 self.1.all_data().mapZ(n0, Self::map_right)
94 } 96 }
95 } 97 }
96 98
97 impl<F : Float, G1, G2, const N : usize> 99 impl<F: Float, G1, G2, const N: usize> SupportGenerator<N, F> for BothGenerators<G1, G2>
98 SupportGenerator<F, N> 100 where
99 for BothGenerators<G1, G2> 101 G1: SupportGenerator<N, F, Id = usize>,
100 where G1 : SupportGenerator<F, N, Id=usize>, 102 G2: SupportGenerator<N, F, Id = usize>,
101 G2 : SupportGenerator<F, N, Id=usize> { 103 {
102
103 type Id = usize; 104 type Id = usize;
104 type SupportType = EitherSupport<G1::SupportType, G2::SupportType>; 105 type SupportType = EitherSupport<G2::SupportType, G1::SupportType>;
105 type AllDataIter<'a> = BothAllDataIter<'a, F, G1, G2, N> where G1 : 'a, G2 : 'a; 106 type AllDataIter<'a>
106 107 = BothAllDataIter<'a, F, G1, G2, N>
107 #[inline] 108 where
108 fn support_for(&self, id : Self::Id) 109 G1: 'a,
109 -> Self::SupportType { 110 G2: 'a;
111
112 #[inline]
113 fn support_for(&self, id: Self::Id) -> Self::SupportType {
110 let n0 = self.0.support_count(); 114 let n0 = self.0.support_count();
111 if id < n0 { 115 if id < n0 {
112 EitherSupport::Left(self.0.support_for(id.into())) 116 EitherSupport::Left(self.0.support_for(id.into()))
113 } else { 117 } else {
114 EitherSupport::Right(self.1.support_for((id-n0).into())) 118 EitherSupport::Right(self.1.support_for((id - n0).into()))
115 } 119 }
116 } 120 }
117 121
118 #[inline] 122 #[inline]
119 fn support_count(&self) -> usize { 123 fn support_count(&self) -> usize {
124 fn all_data(&self) -> Self::AllDataIter<'_> { 128 fn all_data(&self) -> Self::AllDataIter<'_> {
125 self.all_left_data().chain(self.all_right_data()) 129 self.all_left_data().chain(self.all_right_data())
126 } 130 }
127 } 131 }
128 132
129 impl<F: Float, S1, S2, const N : usize> Support<F, N> for EitherSupport<S1, S2> 133 impl<F: Float, S1, S2, const N: usize> Support<N, F> for EitherSupport<S2, S1>
130 where S1 : Support<F, N>, 134 where
131 S2 : Support<F, N> { 135 S1: Support<N, F>,
132 136 S2: Support<N, F>,
133 #[inline] 137 {
134 fn support_hint(&self) -> Cube<F,N> { 138 #[inline]
139 fn support_hint(&self) -> Cube<N, F> {
135 match self { 140 match self {
136 EitherSupport::Left(ref a) => a.support_hint(), 141 EitherSupport::Left(ref a) => a.support_hint(),
137 EitherSupport::Right(ref b) => b.support_hint(), 142 EitherSupport::Right(ref b) => b.support_hint(),
138 } 143 }
139 } 144 }
140 145
141 #[inline] 146 #[inline]
142 fn in_support(&self, x : &Loc<F,N>) -> bool { 147 fn in_support(&self, x: &Loc<N, F>) -> bool {
143 match self { 148 match self {
144 EitherSupport::Left(ref a) => a.in_support(x), 149 EitherSupport::Left(ref a) => a.in_support(x),
145 EitherSupport::Right(ref b) => b.in_support(x), 150 EitherSupport::Right(ref b) => b.in_support(x),
146 } 151 }
147 } 152 }
148 153
149 #[inline] 154 #[inline]
150 fn bisection_hint(&self, cube : &Cube<F, N>) -> [Option<F>; N] { 155 fn bisection_hint(&self, cube: &Cube<N, F>) -> [Option<F>; N] {
151 match self { 156 match self {
152 EitherSupport::Left(ref a) => a.bisection_hint(cube), 157 EitherSupport::Left(ref a) => a.bisection_hint(cube),
153 EitherSupport::Right(ref b) => b.bisection_hint(cube), 158 EitherSupport::Right(ref b) => b.bisection_hint(cube),
154 } 159 }
155 } 160 }
156 } 161 }
157 162
158 impl<F : Float, A, S1, S2, const N : usize> LocalAnalysis<F, A, N> for EitherSupport<S1, S2> 163 impl<F: Float, A, S1, S2, const N: usize> LocalAnalysis<F, A, N> for EitherSupport<S2, S1>
159 where A : Aggregator, 164 where
160 S1 : LocalAnalysis<F, A, N>, 165 A: Aggregator,
161 S2 : LocalAnalysis<F, A, N>, { 166 S1: LocalAnalysis<F, A, N>,
162 167 S2: LocalAnalysis<F, A, N>,
163 #[inline] 168 {
164 fn local_analysis(&self, cube : &Cube<F, N>) -> A { 169 #[inline]
170 fn local_analysis(&self, cube: &Cube<N, F>) -> A {
165 match self { 171 match self {
166 EitherSupport::Left(ref a) => a.local_analysis(cube), 172 EitherSupport::Left(ref a) => a.local_analysis(cube),
167 EitherSupport::Right(ref b) => b.local_analysis(cube), 173 EitherSupport::Right(ref b) => b.local_analysis(cube),
168 } 174 }
169 } 175 }
170 } 176 }
171 177
172 impl<F : Float, A, S1, S2> GlobalAnalysis<F, A> for EitherSupport<S1, S2> 178 impl<F: Float, A, S1, S2> GlobalAnalysis<F, A> for EitherSupport<S2, S1>
173 where A : Aggregator, 179 where
174 S1 : GlobalAnalysis<F, A>, 180 A: Aggregator,
175 S2 : GlobalAnalysis<F, A>, { 181 S1: GlobalAnalysis<F, A>,
176 182 S2: GlobalAnalysis<F, A>,
183 {
177 #[inline] 184 #[inline]
178 fn global_analysis(&self) -> A { 185 fn global_analysis(&self) -> A {
179 match self { 186 match self {
180 EitherSupport::Left(ref a) => a.global_analysis(), 187 EitherSupport::Left(ref a) => a.global_analysis(),
181 EitherSupport::Right(ref b) => b.global_analysis(), 188 EitherSupport::Right(ref b) => b.global_analysis(),
182 } 189 }
183 } 190 }
184 } 191 }
185 192
186 impl<F, S1, S2, X> Mapping<X> for EitherSupport<S1, S2> 193 impl<F, S1, S2, X> Mapping<X> for EitherSupport<S2, S1>
187 where 194 where
188 F : Space, 195 F: Space,
189 X : Space, 196 X: Space,
190 S1 : Mapping<X, Codomain=F>, 197 S1: Mapping<X, Codomain = F>,
191 S2 : Mapping<X, Codomain=F>, 198 S2: Mapping<X, Codomain = F>,
192 { 199 {
193 type Codomain = F; 200 type Codomain = F;
194 201
195 #[inline] 202 #[inline]
196 fn apply<I : Instance<X>>(&self, x : I) -> F { 203 fn apply<I: Instance<X>>(&self, x: I) -> F {
197 match self { 204 match self {
198 EitherSupport::Left(ref a) => a.apply(x), 205 EitherSupport::Left(ref a) => a.apply(x),
199 EitherSupport::Right(ref b) => b.apply(x), 206 EitherSupport::Right(ref b) => b.apply(x),
200 } 207 }
201 } 208 }
202 } 209 }
203 210
204 impl<X, S1, S2, O> DifferentiableImpl<X> for EitherSupport<S1, S2> 211 impl<X, S1, S2, O> DifferentiableImpl<X> for EitherSupport<S2, S1>
205 where 212 where
206 O : Space, 213 O: Space,
207 X : Space, 214 X: Space,
208 S1 : DifferentiableMapping<X, DerivativeDomain=O>, 215 S1: DifferentiableMapping<X, DerivativeDomain = O>,
209 S2 : DifferentiableMapping<X, DerivativeDomain=O>, 216 S2: DifferentiableMapping<X, DerivativeDomain = O>,
210 { 217 {
211 type Derivative = O; 218 type Derivative = O;
212 219
213 #[inline] 220 #[inline]
214 fn differential_impl<I : Instance<X>>(&self, x : I) -> O { 221 fn differential_impl<I: Instance<X>>(&self, x: I) -> O {
215 match self { 222 match self {
216 EitherSupport::Left(ref a) => a.differential(x), 223 EitherSupport::Left(ref a) => a.differential(x),
217 EitherSupport::Right(ref b) => b.differential(x), 224 EitherSupport::Right(ref b) => b.differential(x),
218 } 225 }
219 } 226 }
220 } 227 }
221 228
222 macro_rules! make_either_scalarop_rhs { 229 macro_rules! make_either_scalarop_rhs {
223 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { 230 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
224 impl<F : Float, G1, G2> 231 impl<F: Float, G1, G2> std::ops::$trait_assign<F> for BothGenerators<G1, G2>
225 std::ops::$trait_assign<F> 232 where
226 for BothGenerators<G1, G2> 233 G1: std::ops::$trait_assign<F> + Clone,
227 where G1 : std::ops::$trait_assign<F> + Clone, 234 G2: std::ops::$trait_assign<F> + Clone,
228 G2 : std::ops::$trait_assign<F> + Clone, { 235 {
229 #[inline] 236 #[inline]
230 fn $fn_assign(&mut self, t : F) { 237 fn $fn_assign(&mut self, t: F) {
231 Arc::make_mut(&mut self.0).$fn_assign(t); 238 Arc::make_mut(&mut self.0).$fn_assign(t);
232 Arc::make_mut(&mut self.1).$fn_assign(t); 239 Arc::make_mut(&mut self.1).$fn_assign(t);
233 } 240 }
234 } 241 }
235 242
236 impl<'a, F : Float, G1, G2> 243 impl<'a, F: Float, G1, G2> std::ops::$trait<F> for &'a BothGenerators<G1, G2>
237 std::ops::$trait<F> 244 where
238 for &'a BothGenerators<G1, G2> 245 &'a G1: std::ops::$trait<F, Output = G1>,
239 where &'a G1 : std::ops::$trait<F,Output=G1>, 246 &'a G2: std::ops::$trait<F, Output = G2>,
240 &'a G2 : std::ops::$trait<F,Output=G2> { 247 {
241 type Output = BothGenerators<G1, G2>; 248 type Output = BothGenerators<G1, G2>;
242 #[inline] 249 #[inline]
243 fn $fn(self, t : F) -> BothGenerators<G1, G2> { 250 fn $fn(self, t: F) -> BothGenerators<G1, G2> {
244 BothGenerators(Arc::new(self.0.$fn(t)), 251 BothGenerators(Arc::new(self.0.$fn(t)), Arc::new(self.1.$fn(t)))
245 Arc::new(self.1.$fn(t)))
246 } 252 }
247 } 253 }
248 } 254 };
249 } 255 }
250 256
251 make_either_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); 257 make_either_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
252 make_either_scalarop_rhs!(Div, div, DivAssign, div_assign); 258 make_either_scalarop_rhs!(Div, div, DivAssign, div_assign);
253 259
254 impl<G1, G2> std::ops::Neg for BothGenerators<G1, G2> 260 impl<G1, G2> std::ops::Neg for BothGenerators<G1, G2>
255 where G1 : std::ops::Neg + Clone, 261 where
256 G2 : std::ops::Neg + Clone, { 262 G1: std::ops::Neg + Clone,
263 G2: std::ops::Neg + Clone,
264 {
257 type Output = BothGenerators<G1::Output, G2::Output>; 265 type Output = BothGenerators<G1::Output, G2::Output>;
258 #[inline] 266 #[inline]
259 fn neg(self) -> Self::Output { 267 fn neg(self) -> Self::Output {
260 BothGenerators(Arc::new(Arc::unwrap_or_clone(self.0).neg()), 268 BothGenerators(
261 Arc::new(Arc::unwrap_or_clone(self.1).neg())) 269 Arc::new(Arc::unwrap_or_clone(self.0).neg()),
270 Arc::new(Arc::unwrap_or_clone(self.1).neg()),
271 )
262 } 272 }
263 } 273 }
264 /* 274 /*
265 impl<'a, G1, G2> std::ops::Neg for &'a BothGenerators<G1, G2> 275 impl<'a, G1, G2> std::ops::Neg for &'a BothGenerators<G1, G2>
266 where &'a G1 : std::ops::Neg, &'a G2 : std::ops::Neg, { 276 where &'a G1 : std::ops::Neg, &'a G2 : std::ops::Neg, {

mercurial