| 119 } |
119 } |
| 120 |
120 |
| 121 } |
121 } |
| 122 |
122 |
| 123 impl<F : Float, G, BT, const N : usize> |
123 impl<F : Float, G, BT, const N : usize> |
| 124 BTFN<F, G, BT, N> |
124 BTFN<G, BT, N> |
| 125 where G : SupportGenerator<F, N> { |
125 where G : SupportGenerator<N, RealField = F> { |
| 126 /// Change the [bisection tree][BTImpl] of the [`BTFN`] to a different one. |
126 /// Change the [bisection tree][BTImpl] of the [`BTFN`] to a different one. |
| 127 /// |
127 /// |
| 128 /// This can be used to convert a [`PreBTFN`] to a full [`BTFN`], or the change |
128 /// This can be used to convert a [`PreBTFN`] to a full [`BTFN`], or the change |
| 129 /// the aggreagator; see also [`self.convert_aggregator`]. |
129 /// the aggreagator; see also [`self.convert_aggregator`]. |
| 130 pub fn instantiate< |
130 pub fn instantiate< |
| 131 BTNew : BTImpl<F, N, Data=G::Id>, |
131 BTNew : BTImpl<F, N, Data=G::Id>, |
| 132 > (self, domain : Cube<F, N>, depth : BTNew::Depth) -> BTFN<F, G, BTNew, N> |
132 > (self, domain : Cube<F, N>, depth : BTNew::Depth) -> BTFN<G, BTNew, N> |
| 133 where G::SupportType : LocalAnalysis<F, BTNew::Agg, N> { |
133 where G::SupportType : LocalAnalysis<BTNew::Agg, Cube<F, N>> { |
| 134 BTFN::construct_arc(domain, depth, self.generator) |
134 BTFN::construct_arc(domain, depth, self.generator) |
| 135 } |
135 } |
| 136 } |
136 } |
| 137 |
137 |
| 138 /// A BTFN with no bisection tree. |
138 /// A BTFN with no bisection tree. |
| 139 /// |
139 /// |
| 140 /// Most BTFN methods are not available, but if a BTFN is going to be summed with another |
140 /// Most BTFN methods are not available, but if a BTFN is going to be summed with another |
| 141 /// before other use, it will be more efficient to not construct an unnecessary bisection tree |
141 /// before other use, it will be more efficient to not construct an unnecessary bisection tree |
| 142 /// that would be shortly dropped. |
142 /// that would be shortly dropped. |
| 143 pub type PreBTFN<F, G, const N : usize> = BTFN<F, G, (), N>; |
143 pub type PreBTFN<G, const N : usize> = BTFN<G, (), N>; |
| 144 |
144 |
| 145 impl<F : Float, G, const N : usize> PreBTFN<F, G, N> where G : SupportGenerator<F, N> { |
145 impl<G, const N : usize> PreBTFN<G, N> where G : SupportGenerator<N> { |
| 146 |
146 |
| 147 /// Create a new [`PreBTFN`] with no bisection tree. |
147 /// Create a new [`PreBTFN`] with no bisection tree. |
| 148 pub fn new_pre(generator : G) -> Self { |
148 pub fn new_pre(generator : G) -> Self { |
| 149 BTFN { |
149 BTFN { |
| 150 bt : (), |
150 bt : (), |
| 151 generator : Arc::new(generator), |
151 generator : Arc::new(generator), |
| 152 _phantoms : std::marker::PhantomData, |
|
| 153 } |
152 } |
| 154 } |
153 } |
| 155 } |
154 } |
| 156 |
155 |
| 157 impl<F : Float, G, BT, const N : usize> |
156 impl<F : Float, G, BT, const N : usize> |
| 158 BTFN<F, G, BT, N> |
157 BTFN<G, BT, N> |
| 159 where G : SupportGenerator<F, N, Id=usize>, |
158 where G : SupportGenerator<N, Id=usize, RealField = F>, |
| 160 G::SupportType : LocalAnalysis<F, BT::Agg, N>, |
159 G::SupportType : LocalAnalysis<BT::Agg, Cube<F, N>>, |
| 161 BT : BTImpl<F, N, Data=usize> { |
160 BT : BTImpl<F, N, Data=usize> { |
| 162 |
161 |
| 163 /// Helper function for implementing [`std::ops::Add`]. |
162 /// Helper function for implementing [`std::ops::Add`]. |
| 164 fn add_another<G2>(&self, g2 : Arc<G2>) -> BTFN<F, BothGenerators<G, G2>, BT, N> |
163 fn add_another<G2>(&self, g2 : Arc<G2>) -> BTFN<BothGenerators<G, G2>, BT, N> |
| 165 where G2 : SupportGenerator<F, N, Id=usize>, |
164 where G2 : SupportGenerator<N, Id=usize, RealField = F>, |
| 166 G2::SupportType : LocalAnalysis<F, BT::Agg, N> { |
165 G2::SupportType : LocalAnalysis<BT::Agg, Cube<F, N>> { |
| 167 |
166 |
| 168 let mut bt = self.bt.clone(); |
167 let mut bt = self.bt.clone(); |
| 169 let both = BothGenerators(Arc::clone(&self.generator), g2); |
168 let both = BothGenerators(Arc::clone(&self.generator), g2); |
| 170 |
169 |
| 171 for (d, support) in both.all_right_data() { |
170 for (d, support) in both.all_right_data() { |
| 173 } |
172 } |
| 174 |
173 |
| 175 BTFN { |
174 BTFN { |
| 176 bt : bt, |
175 bt : bt, |
| 177 generator : Arc::new(both), |
176 generator : Arc::new(both), |
| 178 _phantoms : std::marker::PhantomData, |
|
| 179 } |
177 } |
| 180 } |
178 } |
| 181 } |
179 } |
| 182 |
180 |
| 183 macro_rules! make_btfn_add { |
181 macro_rules! make_btfn_add { |
| 184 ($lhs:ty, $preprocess:path, $($extra_trait:ident)?) => { |
182 ($lhs:ty, $preprocess:path, $($extra_trait:ident)?) => { |
| 185 impl<'a, F : Float, G1, G2, BT1, BT2, const N : usize> |
183 impl<'a, F : Float, G1, G2, BT1, BT2, const N : usize> |
| 186 std::ops::Add<BTFN<F, G2, BT2, N>> for |
184 std::ops::Add<BTFN<G2, BT2, N>> for |
| 187 $lhs |
185 $lhs |
| 188 where BT1 : BTImpl<F, N, Data=usize>, |
186 where BT1 : BTImpl<F, N, Data=usize>, |
| 189 G1 : SupportGenerator<F, N, Id=usize> + $($extra_trait)?, |
187 G1 : SupportGenerator<N, Id=usize, RealField = F> + $($extra_trait)?, |
| 190 G2 : SupportGenerator<F, N, Id=usize>, |
188 G2 : SupportGenerator<N, Id=usize, RealField = F>, |
| 191 G1::SupportType : LocalAnalysis<F, BT1::Agg, N>, |
189 G1::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>>, |
| 192 G2::SupportType : LocalAnalysis<F, BT1::Agg, N> { |
190 G2::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>> { |
| 193 type Output = BTFN<F, BothGenerators<G1, G2>, BT1, N>; |
191 type Output = BTFN<BothGenerators<G1, G2>, BT1, N>; |
| 194 #[inline] |
192 #[inline] |
| 195 fn add(self, other : BTFN<F, G2, BT2, N>) -> Self::Output { |
193 fn add(self, other : BTFN<G2, BT2, N>) -> Self::Output { |
| 196 $preprocess(self).add_another(other.generator) |
194 $preprocess(self).add_another(other.generator) |
| 197 } |
195 } |
| 198 } |
196 } |
| 199 |
197 |
| 200 impl<'a, 'b, F : Float, G1, G2, BT1, BT2, const N : usize> |
198 impl<'a, 'b, F : Float, G1, G2, BT1, BT2, const N : usize> |
| 201 std::ops::Add<&'b BTFN<F, G2, BT2, N>> for |
199 std::ops::Add<&'b BTFN<G2, BT2, N>> for |
| 202 $lhs |
200 $lhs |
| 203 where BT1 : BTImpl<F, N, Data=usize>, |
201 where BT1 : BTImpl<F, N, Data=usize>, |
| 204 G1 : SupportGenerator<F, N, Id=usize> + $($extra_trait)?, |
202 G1 : SupportGenerator<N, Id=usize, RealField = F> + $($extra_trait)?, |
| 205 G2 : SupportGenerator<F, N, Id=usize>, |
203 G2 : SupportGenerator<N, Id=usize, RealField = F>, |
| 206 G1::SupportType : LocalAnalysis<F, BT1::Agg, N>, |
204 G1::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>>, |
| 207 G2::SupportType : LocalAnalysis<F, BT1::Agg, N> { |
205 G2::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>> { |
| 208 |
206 |
| 209 type Output = BTFN<F, BothGenerators<G1, G2>, BT1, N>; |
207 type Output = BTFN<BothGenerators<G1, G2>, BT1, N>; |
| 210 #[inline] |
208 #[inline] |
| 211 fn add(self, other : &'b BTFN<F, G2, BT2, N>) -> Self::Output { |
209 fn add(self, other : &'b BTFN<G2, BT2, N>) -> Self::Output { |
| 212 $preprocess(self).add_another(other.generator.clone()) |
210 $preprocess(self).add_another(other.generator.clone()) |
| 213 } |
211 } |
| 214 } |
212 } |
| 215 } |
213 } |
| 216 } |
214 } |
| 217 |
215 |
| 218 make_btfn_add!(BTFN<F, G1, BT1, N>, std::convert::identity, ); |
216 make_btfn_add!(BTFN<G1, BT1, N>, std::convert::identity, ); |
| 219 make_btfn_add!(&'a BTFN<F, G1, BT1, N>, Clone::clone, ); |
217 make_btfn_add!(&'a BTFN<G1, BT1, N>, Clone::clone, ); |
| 220 |
218 |
| 221 macro_rules! make_btfn_sub { |
219 macro_rules! make_btfn_sub { |
| 222 ($lhs:ty, $preprocess:path, $($extra_trait:ident)?) => { |
220 ($lhs:ty, $preprocess:path, $($extra_trait:ident)?) => { |
| 223 impl<'a, F : Float, G1, G2, BT1, BT2, const N : usize> |
221 impl<'a, F : Float, G1, G2, BT1, BT2, const N : usize> |
| 224 std::ops::Sub<BTFN<F, G2, BT2, N>> for |
222 std::ops::Sub<BTFN<G2, BT2, N>> for |
| 225 $lhs |
223 $lhs |
| 226 where BT1 : BTImpl<F, N, Data=usize>, |
224 where BT1 : BTImpl<F, N, Data=usize>, |
| 227 G1 : SupportGenerator<F, N, Id=usize> + $($extra_trait)?, |
225 G1 : SupportGenerator<N, Id=usize, RealField = F> + $($extra_trait)?, |
| 228 G2 : SupportGenerator<F, N, Id=usize>, |
226 G2 : SupportGenerator<N, Id=usize, RealField = F>, |
| 229 G1::SupportType : LocalAnalysis<F, BT1::Agg, N>, |
227 G1::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>>, |
| 230 G2::SupportType : LocalAnalysis<F, BT1::Agg, N> { |
228 G2::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>> { |
| 231 type Output = BTFN<F, BothGenerators<G1, G2>, BT1, N>; |
229 type Output = BTFN<BothGenerators<G1, G2>, BT1, N>; |
| 232 #[inline] |
230 #[inline] |
| 233 fn sub(self, other : BTFN<F, G2, BT2, N>) -> Self::Output { |
231 fn sub(self, other : BTFN<G2, BT2, N>) -> Self::Output { |
| 234 $preprocess(self).add_another(Arc::new( |
232 $preprocess(self).add_another(Arc::new( |
| 235 Arc::try_unwrap(other.generator) |
233 Arc::try_unwrap(other.generator) |
| 236 .unwrap_or_else(|arc| (*arc).clone()) |
234 .unwrap_or_else(|arc| (*arc).clone()) |
| 237 .neg() |
235 .neg() |
| 238 )) |
236 )) |
| 239 } |
237 } |
| 240 } |
238 } |
| 241 |
239 |
| 242 impl<'a, 'b, F : Float, G1, G2, BT1, BT2, const N : usize> |
240 impl<'a, 'b, F : Float, G1, G2, BT1, BT2, const N : usize> |
| 243 std::ops::Sub<&'b BTFN<F, G2, BT2, N>> for |
241 std::ops::Sub<&'b BTFN<G2, BT2, N>> for |
| 244 $lhs |
242 $lhs |
| 245 where BT1 : BTImpl<F, N, Data=usize>, |
243 where BT1 : BTImpl<F, N, Data=usize>, |
| 246 G1 : SupportGenerator<F, N, Id=usize> + $($extra_trait)?, |
244 G1 : SupportGenerator<N, Id=usize, RealField = F> + $($extra_trait)?, |
| 247 G2 : SupportGenerator<F, N, Id=usize> + Clone, |
245 G2 : SupportGenerator<N, Id=usize, RealField = F> + Clone, |
| 248 G1::SupportType : LocalAnalysis<F, BT1::Agg, N>, |
246 G1::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>>, |
| 249 G2::SupportType : LocalAnalysis<F, BT1::Agg, N>, |
247 G2::SupportType : LocalAnalysis<BT1::Agg, Cube<F, N>>, |
| 250 &'b G2 : std::ops::Neg<Output=G2> { |
248 &'b G2 : std::ops::Neg<Output=G2> { |
| 251 |
249 |
| 252 type Output = BTFN<F, BothGenerators<G1, G2>, BT1, N>; |
250 type Output = BTFN<BothGenerators<G1, G2>, BT1, N>; |
| 253 #[inline] |
251 #[inline] |
| 254 fn sub(self, other : &'b BTFN<F, G2, BT2, N>) -> Self::Output { |
252 fn sub(self, other : &'b BTFN<G2, BT2, N>) -> Self::Output { |
| 255 $preprocess(self).add_another(Arc::new((*other.generator).clone().neg())) |
253 $preprocess(self).add_another(Arc::new((*other.generator).clone().neg())) |
| 256 } |
254 } |
| 257 } |
255 } |
| 258 } |
256 } |
| 259 } |
257 } |
| 260 |
258 |
| 261 make_btfn_sub!(BTFN<F, G1, BT1, N>, std::convert::identity, ); |
259 make_btfn_sub!(BTFN<G1, BT1, N>, std::convert::identity, ); |
| 262 make_btfn_sub!(&'a BTFN<F, G1, BT1, N>, std::convert::identity, ); |
260 make_btfn_sub!(&'a BTFN<G1, BT1, N>, std::convert::identity, ); |
| 263 |
261 |
| 264 macro_rules! make_btfn_scalarop_rhs { |
262 macro_rules! make_btfn_scalarop_rhs { |
| 265 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
263 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
| 266 impl<F : Float, G, BT, const N : usize> |
264 impl<F : Float, G, BT, const N : usize> |
| 267 std::ops::$trait_assign<F> |
265 std::ops::$trait_assign<F> |
| 268 for BTFN<F, G, BT, N> |
266 for BTFN<G, BT, N> |
| 269 where BT : BTImpl<F, N>, |
267 where BT : BTImpl<F, N>, |
| 270 G : SupportGenerator<F, N, Id=BT::Data>, |
268 G : SupportGenerator<N, Id=BT::Data, RealField = F>, |
| 271 G::SupportType : LocalAnalysis<F, BT::Agg, N> { |
269 G::SupportType : LocalAnalysis<BT::Agg, Cube<F, N>> { |
| 272 #[inline] |
270 #[inline] |
| 273 fn $fn_assign(&mut self, t : F) { |
271 fn $fn_assign(&mut self, t : F) { |
| 274 Arc::make_mut(&mut self.generator).$fn_assign(t); |
272 Arc::make_mut(&mut self.generator).$fn_assign(t); |
| 275 self.refresh_aggregator(); |
273 self.refresh_aggregator(); |
| 276 } |
274 } |
| 277 } |
275 } |
| 278 |
276 |
| 279 impl<F : Float, G, BT, const N : usize> |
277 impl<F : Float, G, BT, const N : usize> |
| 280 std::ops::$trait<F> |
278 std::ops::$trait<F> |
| 281 for BTFN<F, G, BT, N> |
279 for BTFN<G, BT, N> |
| 282 where BT : BTImpl<F, N>, |
280 where BT : BTImpl<F, N>, |
| 283 G : SupportGenerator<F, N, Id=BT::Data>, |
281 G : SupportGenerator<N, Id=BT::Data, RealField = F>, |
| 284 G::SupportType : LocalAnalysis<F, BT::Agg, N> { |
282 G::SupportType : LocalAnalysis<BT::Agg, Cube<F, N>> { |
| 285 type Output = Self; |
283 type Output = Self; |
| 286 #[inline] |
284 #[inline] |
| 287 fn $fn(mut self, t : F) -> Self::Output { |
285 fn $fn(mut self, t : F) -> Self::Output { |
| 288 Arc::make_mut(&mut self.generator).$fn_assign(t); |
286 Arc::make_mut(&mut self.generator).$fn_assign(t); |
| 289 self.refresh_aggregator(); |
287 self.refresh_aggregator(); |
| 311 make_btfn_scalarop_rhs!(Div, div, DivAssign, div_assign); |
309 make_btfn_scalarop_rhs!(Div, div, DivAssign, div_assign); |
| 312 |
310 |
| 313 macro_rules! make_btfn_scalarop_lhs { |
311 macro_rules! make_btfn_scalarop_lhs { |
| 314 ($trait:ident, $fn:ident, $fn_assign:ident, $($f:ident)+) => { $( |
312 ($trait:ident, $fn:ident, $fn_assign:ident, $($f:ident)+) => { $( |
| 315 impl<G, BT, const N : usize> |
313 impl<G, BT, const N : usize> |
| 316 std::ops::$trait<BTFN<$f, G, BT, N>> |
314 std::ops::$trait<BTFN<G, BT, N>> |
| 317 for $f |
315 for $f |
| 318 where BT : BTImpl<$f, N>, |
316 where BT : BTImpl<$f, N>, |
| 319 G : SupportGenerator<$f, N, Id=BT::Data>, |
317 G : SupportGenerator<N, Id=BT::Data, RealField = $f>, |
| 320 G::SupportType : LocalAnalysis<$f, BT::Agg, N> { |
318 G::SupportType : LocalAnalysis<BT::Agg, Cube<$f, N>> { |
| 321 type Output = BTFN<$f, G, BT, N>; |
319 type Output = BTFN<G, BT, N>; |
| 322 #[inline] |
320 #[inline] |
| 323 fn $fn(self, mut a : BTFN<$f, G, BT, N>) -> Self::Output { |
321 fn $fn(self, mut a : BTFN<G, BT, N>) -> Self::Output { |
| 324 Arc::make_mut(&mut a.generator).$fn_assign(self); |
322 Arc::make_mut(&mut a.generator).$fn_assign(self); |
| 325 a.refresh_aggregator(); |
323 a.refresh_aggregator(); |
| 326 a |
324 a |
| 327 } |
325 } |
| 328 } |
326 } |
| 329 |
327 |
| 330 impl<'a, G, BT, const N : usize> |
328 impl<'a, G, BT, const N : usize> |
| 331 std::ops::$trait<&'a BTFN<$f, G, BT, N>> |
329 std::ops::$trait<&'a BTFN<G, BT, N>> |
| 332 for $f |
330 for $f |
| 333 where BT : BTImpl<$f, N>, |
331 where BT : BTImpl<$f, N>, |
| 334 G : SupportGenerator<$f, N, Id=BT::Data> + Clone, |
332 G : SupportGenerator<N, Id=BT::Data, RealField = $f> + Clone, |
| 335 G::SupportType : LocalAnalysis<$f, BT::Agg, N>, |
333 G::SupportType : LocalAnalysis<BT::Agg, Cube<$f, N>>, |
| 336 // FIXME: This causes compiler overflow |
334 // FIXME: This causes compiler overflow |
| 337 /*&'a G : std::ops::$trait<$f,Output=G>*/ { |
335 /*&'a G : std::ops::$trait<$f,Output=G>*/ { |
| 338 type Output = BTFN<$f, G, BT, N>; |
336 type Output = BTFN<G, BT, N>; |
| 339 #[inline] |
337 #[inline] |
| 340 fn $fn(self, a : &'a BTFN<$f, G, BT, N>) -> Self::Output { |
338 fn $fn(self, a : &'a BTFN<G, BT, N>) -> Self::Output { |
| 341 let mut tmp = (*a.generator).clone(); |
339 let mut tmp = (*a.generator).clone(); |
| 342 tmp.$fn_assign(self); |
340 tmp.$fn_assign(self); |
| 343 a.new_generator(tmp) |
341 a.new_generator(tmp) |
| 344 // FIXME: Prevented by the compiler overflow above. |
342 // FIXME: Prevented by the compiler overflow above. |
| 345 //a.new_generator(a.generator.$fn(a)) |
343 //a.new_generator(a.generator.$fn(a)) |
| 404 .map(|&d| self.generator.support_for(d).apply(x)).sum() |
403 .map(|&d| self.generator.support_for(d).apply(x)).sum() |
| 405 } |
404 } |
| 406 } |
405 } |
| 407 |
406 |
| 408 impl<F : Float, G, BT, V, const N : usize> Apply<Loc<F, N>> |
407 impl<F : Float, G, BT, V, const N : usize> Apply<Loc<F, N>> |
| 409 for BTFN<F, G, BT, N> |
408 for BTFN<G, BT, N> |
| 410 where BT : BTImpl<F, N>, |
409 where BT : BTImpl<F, N>, |
| 411 G : SupportGenerator<F, N, Id=BT::Data>, |
410 G : SupportGenerator<N, Id=BT::Data, RealField = F>, |
| 412 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Apply<Loc<F, N>, Output = V>, |
411 G::SupportType : LocalAnalysis<BT::Agg, Cube<F, N>> |
| |
412 + Apply<Loc<F, N>, Output = V>, |
| 413 V : Sum { |
413 V : Sum { |
| 414 |
414 |
| 415 type Output = V; |
415 type Output = V; |
| 416 |
416 |
| 417 fn apply(&self, x : Loc<F, N>) -> Self::Output { |
417 fn apply(&self, x : Loc<F, N>) -> Self::Output { |
| 418 self.bt.iter_at(&x) |
418 self.bt.iter_at(&x) |
| 419 .map(|&d| self.generator.support_for(d).apply(x)).sum() |
419 .map(|&d| self.generator.support_for(d).apply(x)).sum() |
| 420 } |
420 } |
| 421 } |
421 } |
| 422 |
422 |
| 423 impl<'a, F : Float, G, BT, V, const N : usize> Differentiable<&'a Loc<F, N>> |
423 impl<'a, F : Float, G, BT, V : HasRealField<RealField=F>, const N : usize> |
| 424 for BTFN<F, G, BT, N> |
424 Differentiable<&'a Loc<F, N>> |
| |
425 for BTFN<G, BT, N> |
| 425 where BT : BTImpl<F, N>, |
426 where BT : BTImpl<F, N>, |
| 426 G : SupportGenerator<F, N, Id=BT::Data>, |
427 G : SupportGenerator<N, Id=BT::Data, RealField = F>, |
| 427 G::SupportType : LocalAnalysis<F, BT::Agg, N> + Differentiable<&'a Loc<F, N>, Derivative = V>, |
428 G::SupportType : LocalAnalysis<BT::Agg, Cube<F, N>> |
| |
429 + Differentiable<&'a Loc<F, N>, Derivative = V>, |
| 428 V : Sum { |
430 V : Sum { |
| 429 |
431 |
| 430 type Derivative = V; |
432 type Derivative = V; |
| 431 |
433 |
| 432 fn differential(&self, x : &'a Loc<F, N>) -> Self::Derivative { |
434 fn differential(&self, x : &'a Loc<F, N>) -> Self::Derivative { |