src/bisection_tree/either.rs

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

mercurial