src/bisection_tree/bt.rs

branch
dev
changeset 124
6aa955ad8122
parent 97
4e80fb049dca
equal deleted inserted replaced
122:495448cca603 124:6aa955ad8122
49 /// 49 ///
50 /// For the type and const parameters, see the [module level documentation][super]. 50 /// For the type and const parameters, see the [module level documentation][super].
51 #[derive(Clone, Debug)] 51 #[derive(Clone, Debug)]
52 pub(super) struct Branches<F: Num, D, A: Aggregator, const N: usize, const P: usize> { 52 pub(super) struct Branches<F: Num, D, A: Aggregator, const N: usize, const P: usize> {
53 /// Point for subdivision of the (unstored) [`Cube`] corresponding to the node. 53 /// Point for subdivision of the (unstored) [`Cube`] corresponding to the node.
54 pub(super) branch_at: Loc<F, N>, 54 pub(super) branch_at: Loc<N, F>,
55 /// Subnodes 55 /// Subnodes
56 pub(super) nodes: [Node<F, D, A, N, P>; P], 56 pub(super) nodes: [Node<F, D, A, N, P>; P],
57 } 57 }
58 58
59 /// Dirty workaround to broken Rust drop, see [https://github.com/rust-lang/rust/issues/58068](). 59 /// Dirty workaround to broken Rust drop, see [https://github.com/rust-lang/rust/issues/58068]().
182 { 182 {
183 /// Returns the index in {0, …, `P`-1} for the branch to which the point `x` corresponds. 183 /// Returns the index in {0, …, `P`-1} for the branch to which the point `x` corresponds.
184 /// 184 ///
185 /// This only takes the branch subdivision point $d$ into account, so is always succesfull. 185 /// This only takes the branch subdivision point $d$ into account, so is always succesfull.
186 /// Thus, for this point, each branch corresponds to a quadrant of $ℝ^N$ relative to $d$. 186 /// Thus, for this point, each branch corresponds to a quadrant of $ℝ^N$ relative to $d$.
187 fn get_node_index(&self, x: &Loc<F, N>) -> usize { 187 fn get_node_index(&self, x: &Loc<N, F>) -> usize {
188 izip!(0..P, x.iter(), self.branch_at.iter()) 188 izip!(0..P, x.iter(), self.branch_at.iter())
189 .map(|(i, x_i, branch_i)| if x_i > branch_i { 1 << i } else { 0 }) 189 .map(|(i, x_i, branch_i)| if x_i > branch_i { 1 << i } else { 0 })
190 .sum() 190 .sum()
191 } 191 }
192 192
193 /// Returns the node within `Self` containing the point `x`. 193 /// Returns the node within `Self` containing the point `x`.
194 /// 194 ///
195 /// This only takes the branch subdivision point $d$ into account, so is always succesfull. 195 /// This only takes the branch subdivision point $d$ into account, so is always succesfull.
196 /// Thus, for this point, each branch corresponds to a quadrant of $ℝ^N$ relative to $d$. 196 /// Thus, for this point, each branch corresponds to a quadrant of $ℝ^N$ relative to $d$.
197 #[inline] 197 #[inline]
198 fn get_node(&self, x: &Loc<F, N>) -> &Node<F, D, A, N, P> { 198 fn get_node(&self, x: &Loc<N, F>) -> &Node<F, D, A, N, P> {
199 &self.nodes[self.get_node_index(x)] 199 &self.nodes[self.get_node_index(x)]
200 } 200 }
201 } 201 }
202 202
203 /// An iterator over the $P=2^N$ subcubes of a [`Cube`] subdivided at a point `d`. 203 /// An iterator over the $P=2^N$ subcubes of a [`Cube`] subdivided at a point `d`.
204 pub(super) struct SubcubeIter<'b, F: Float, const N: usize, const P: usize> { 204 pub(super) struct SubcubeIter<'b, F: Float, const N: usize, const P: usize> {
205 domain: &'b Cube<F, N>, 205 domain: &'b Cube<N, F>,
206 branch_at: Loc<F, N>, 206 branch_at: Loc<N, F>,
207 index: usize, 207 index: usize,
208 } 208 }
209 209
210 /// Returns the `i`:th subcube of `domain` subdivided at `branch_at`. 210 /// Returns the `i`:th subcube of `domain` subdivided at `branch_at`.
211 #[inline] 211 #[inline]
212 fn get_subcube<F: Float, const N: usize>( 212 fn get_subcube<F: Float, const N: usize>(
213 branch_at: &Loc<F, N>, 213 branch_at: &Loc<N, F>,
214 domain: &Cube<F, N>, 214 domain: &Cube<N, F>,
215 i: usize, 215 i: usize,
216 ) -> Cube<F, N> { 216 ) -> Cube<N, F> {
217 map2_indexed(branch_at, domain, move |j, &branch, &[start, end]| { 217 map2_indexed(branch_at, domain, move |j, &branch, &[start, end]| {
218 if i & (1 << j) != 0 { 218 if i & (1 << j) != 0 {
219 [branch, end] 219 [branch, end]
220 } else { 220 } else {
221 [start, branch] 221 [start, branch]
223 }) 223 })
224 .into() 224 .into()
225 } 225 }
226 226
227 impl<'a, 'b, F: Float, const N: usize, const P: usize> Iterator for SubcubeIter<'b, F, N, P> { 227 impl<'a, 'b, F: Float, const N: usize, const P: usize> Iterator for SubcubeIter<'b, F, N, P> {
228 type Item = Cube<F, N>; 228 type Item = Cube<N, F>;
229 #[inline] 229 #[inline]
230 fn next(&mut self) -> Option<Self::Item> { 230 fn next(&mut self) -> Option<Self::Item> {
231 if self.index < P { 231 if self.index < P {
232 let i = self.index; 232 let i = self.index;
233 self.index += 1; 233 self.index += 1;
244 A: Aggregator, 244 A: Aggregator,
245 D: 'static + Copy + Send + Sync, 245 D: 'static + Copy + Send + Sync,
246 { 246 {
247 /// Creates a new node branching structure, subdividing `domain` based on the 247 /// Creates a new node branching structure, subdividing `domain` based on the
248 /// [hint][Support::support_hint] of `support`. 248 /// [hint][Support::support_hint] of `support`.
249 pub(super) fn new_with<S: LocalAnalysis<F, A, N> + Support<F, N>>( 249 pub(super) fn new_with<S: LocalAnalysis<F, A, N> + Support<N, F>>(
250 domain: &Cube<F, N>, 250 domain: &Cube<N, F>,
251 support: &S, 251 support: &S,
252 ) -> Self { 252 ) -> Self {
253 let hint = support.bisection_hint(domain); 253 let hint = support.bisection_hint(domain);
254 let branch_at = map2(&hint, domain, |h, r| { 254 let branch_at = map2(&hint, domain, |h, r| {
255 h.unwrap_or_else(|| (r[0] + r[1]) / F::TWO) 255 h.unwrap_or_else(|| (r[0] + r[1]) / F::TWO)
270 } 270 }
271 271
272 /// Returns an iterator over the subcubes of `domain` subdivided at the branching point 272 /// Returns an iterator over the subcubes of `domain` subdivided at the branching point
273 /// of `self`. 273 /// of `self`.
274 #[inline] 274 #[inline]
275 pub(super) fn iter_subcubes<'b>(&self, domain: &'b Cube<F, N>) -> SubcubeIter<'b, F, N, P> { 275 pub(super) fn iter_subcubes<'b>(&self, domain: &'b Cube<N, F>) -> SubcubeIter<'b, F, N, P> {
276 SubcubeIter { 276 SubcubeIter {
277 domain: domain, 277 domain: domain,
278 branch_at: self.branch_at, 278 branch_at: self.branch_at,
279 index: 0, 279 index: 0,
280 } 280 }
281 } 281 }
282 282
283 /* 283 /*
284 /// Returns an iterator over all nodes and corresponding subcubes of `self`. 284 /// Returns an iterator over all nodes and corresponding subcubes of `self`.
285 #[inline] 285 #[inline]
286 pub(super) fn nodes_and_cubes<'a, 'b>(&'a self, domain : &'b Cube<F, N>) 286 pub(super) fn nodes_and_cubes<'a, 'b>(&'a self, domain : &'b Cube<N, F>)
287 -> std::iter::Zip<Iter<'a, Node<F,D,A,N,P>>, SubcubeIter<'b, F, N, P>> { 287 -> std::iter::Zip<Iter<'a, Node<F,D,A,N,P>>, SubcubeIter<'b, F, N, P>> {
288 self.nodes.iter().zip(self.iter_subcubes(domain)) 288 self.nodes.iter().zip(self.iter_subcubes(domain))
289 } 289 }
290 */ 290 */
291 291
292 /// Mutably iterate over all nodes and corresponding subcubes of `self`. 292 /// Mutably iterate over all nodes and corresponding subcubes of `self`.
293 #[inline] 293 #[inline]
294 pub(super) fn nodes_and_cubes_mut<'a, 'b>( 294 pub(super) fn nodes_and_cubes_mut<'a, 'b>(
295 &'a mut self, 295 &'a mut self,
296 domain: &'b Cube<F, N>, 296 domain: &'b Cube<N, F>,
297 ) -> std::iter::Zip<IterMut<'a, Node<F, D, A, N, P>>, SubcubeIter<'b, F, N, P>> { 297 ) -> std::iter::Zip<IterMut<'a, Node<F, D, A, N, P>>, SubcubeIter<'b, F, N, P>> {
298 let subcube_iter = self.iter_subcubes(domain); 298 let subcube_iter = self.iter_subcubes(domain);
299 self.nodes.iter_mut().zip(subcube_iter) 299 self.nodes.iter_mut().zip(subcube_iter)
300 } 300 }
301 301
302 /// Call `f` on all `(subnode, subcube)` pairs in multiple threads, if `guard` so deems. 302 /// Call `f` on all `(subnode, subcube)` pairs in multiple threads, if `guard` so deems.
303 #[inline] 303 #[inline]
304 fn recurse<'scope, 'smaller, 'refs>( 304 fn recurse<'scope, 'smaller, 'refs>(
305 &'smaller mut self, 305 &'smaller mut self,
306 domain: &'smaller Cube<F, N>, 306 domain: &'smaller Cube<N, F>,
307 task_budget: TaskBudget<'scope, 'refs>, 307 task_budget: TaskBudget<'scope, 'refs>,
308 guard: impl Fn(&Node<F, D, A, N, P>, &Cube<F, N>) -> bool + Send + 'smaller, 308 guard: impl Fn(&Node<F, D, A, N, P>, &Cube<N, F>) -> bool + Send + 'smaller,
309 mut f: impl for<'a> FnMut(&mut Node<F, D, A, N, P>, &Cube<F, N>, TaskBudget<'smaller, 'a>) 309 mut f: impl for<'a> FnMut(&mut Node<F, D, A, N, P>, &Cube<N, F>, TaskBudget<'smaller, 'a>)
310 + Send 310 + Send
311 + Copy 311 + Copy
312 + 'smaller, 312 + 'smaller,
313 ) where 313 ) where
314 'scope: 'smaller, 314 'scope: 'smaller,
330 /// * `d` is the data to be inserted 330 /// * `d` is the data to be inserted
331 /// * `new_leaf_depth` is the depth relative to `self` at which the data is to be inserted. 331 /// * `new_leaf_depth` is the depth relative to `self` at which the data is to be inserted.
332 /// * `support` is the [`Support`] that is used determine with which subcubes of `domain` 332 /// * `support` is the [`Support`] that is used determine with which subcubes of `domain`
333 /// (at subdivision depth `new_leaf_depth`) the data `d` is to be associated with. 333 /// (at subdivision depth `new_leaf_depth`) the data `d` is to be associated with.
334 /// 334 ///
335 pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<F, N>>( 335 pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<N, F>>(
336 &mut self, 336 &mut self,
337 domain: &Cube<F, N>, 337 domain: &Cube<N, F>,
338 d: D, 338 d: D,
339 new_leaf_depth: M, 339 new_leaf_depth: M,
340 support: &S, 340 support: &S,
341 task_budget: TaskBudget<'scope, 'refs>, 341 task_budget: TaskBudget<'scope, 'refs>,
342 ) { 342 ) {
358 /// The type parameter `ANew´ is the new aggregator, and needs to be implemented for the 358 /// The type parameter `ANew´ is the new aggregator, and needs to be implemented for the
359 /// generator's `SupportType`. 359 /// generator's `SupportType`.
360 pub(super) fn convert_aggregator<ANew, G>( 360 pub(super) fn convert_aggregator<ANew, G>(
361 self, 361 self,
362 generator: &G, 362 generator: &G,
363 domain: &Cube<F, N>, 363 domain: &Cube<N, F>,
364 ) -> Branches<F, D, ANew, N, P> 364 ) -> Branches<F, D, ANew, N, P>
365 where 365 where
366 ANew: Aggregator, 366 ANew: Aggregator,
367 G: SupportGenerator<F, N, Id = D>, 367 G: SupportGenerator<N, F, Id = D>,
368 G::SupportType: LocalAnalysis<F, ANew, N>, 368 G::SupportType: LocalAnalysis<F, ANew, N>,
369 { 369 {
370 let branch_at = self.branch_at; 370 let branch_at = self.branch_at;
371 let subcube_iter = self.iter_subcubes(domain); 371 let subcube_iter = self.iter_subcubes(domain);
372 let new_nodes = self 372 let new_nodes = self
385 /// The `generator` is used to convert the data of type `D` of the branch into corresponding 385 /// The `generator` is used to convert the data of type `D` of the branch into corresponding
386 /// [`Support`]s. The `domain` is the cube corresponding to `self`. 386 /// [`Support`]s. The `domain` is the cube corresponding to `self`.
387 pub(super) fn refresh_aggregator<'refs, 'scope, G>( 387 pub(super) fn refresh_aggregator<'refs, 'scope, G>(
388 &mut self, 388 &mut self,
389 generator: &G, 389 generator: &G,
390 domain: &Cube<F, N>, 390 domain: &Cube<N, F>,
391 task_budget: TaskBudget<'scope, 'refs>, 391 task_budget: TaskBudget<'scope, 'refs>,
392 ) where 392 ) where
393 G: SupportGenerator<F, N, Id = D>, 393 G: SupportGenerator<N, F, Id = D>,
394 G::SupportType: LocalAnalysis<F, A, N>, 394 G::SupportType: LocalAnalysis<F, A, N>,
395 { 395 {
396 self.recurse( 396 self.recurse(
397 domain, 397 domain,
398 task_budget, 398 task_budget,
420 } 420 }
421 421
422 /* 422 /*
423 /// Get leaf data 423 /// Get leaf data
424 #[inline] 424 #[inline]
425 pub(super) fn get_leaf_data(&self, x : &Loc<F, N>) -> Option<&Vec<D>> { 425 pub(super) fn get_leaf_data(&self, x : &Loc<N, F>) -> Option<&Vec<D>> {
426 match self.data { 426 match self.data {
427 NodeOption::Uninitialised => None, 427 NodeOption::Uninitialised => None,
428 NodeOption::Leaf(ref data) => Some(data), 428 NodeOption::Leaf(ref data) => Some(data),
429 NodeOption::Branches(ref b) => b.get_node(x).get_leaf_data(x), 429 NodeOption::Branches(ref b) => b.get_node(x).get_leaf_data(x),
430 } 430 }
431 }*/ 431 }*/
432 432
433 /// Get leaf data iterator 433 /// Get leaf data iterator
434 #[inline] 434 #[inline]
435 pub(super) fn get_leaf_data_iter(&self, x: &Loc<F, N>) -> Option<std::slice::Iter<'_, D>> { 435 pub(super) fn get_leaf_data_iter(&self, x: &Loc<N, F>) -> Option<std::slice::Iter<'_, D>> {
436 match self.data { 436 match self.data {
437 NodeOption::Uninitialised => None, 437 NodeOption::Uninitialised => None,
438 NodeOption::Leaf(ref data) => Some(data.iter()), 438 NodeOption::Leaf(ref data) => Some(data.iter()),
439 NodeOption::Branches(ref b) => b.get_node(x).get_leaf_data_iter(x), 439 NodeOption::Branches(ref b) => b.get_node(x).get_leaf_data_iter(x),
440 } 440 }
457 /// 457 ///
458 /// If `self` is already [`NodeOption::Leaf`], the data is inserted directly in this node. 458 /// If `self` is already [`NodeOption::Leaf`], the data is inserted directly in this node.
459 /// If `self` is a [`NodeOption::Branches`], the data is passed to branches whose subcubes 459 /// If `self` is a [`NodeOption::Branches`], the data is passed to branches whose subcubes
460 /// `support` intersects. If an [`NodeOption::Uninitialised`] node is encountered, a new leaf is 460 /// `support` intersects. If an [`NodeOption::Uninitialised`] node is encountered, a new leaf is
461 /// created at a minimum depth of `new_leaf_depth`. 461 /// created at a minimum depth of `new_leaf_depth`.
462 pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<F, N>>( 462 pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<N, F>>(
463 &mut self, 463 &mut self,
464 domain: &Cube<F, N>, 464 domain: &Cube<N, F>,
465 d: D, 465 d: D,
466 new_leaf_depth: M, 466 new_leaf_depth: M,
467 support: &S, 467 support: &S,
468 task_budget: TaskBudget<'scope, 'refs>, 468 task_budget: TaskBudget<'scope, 'refs>,
469 ) { 469 ) {
513 /// The type parameter `ANew´ is the new aggregator, and needs to be implemented for the 513 /// The type parameter `ANew´ is the new aggregator, and needs to be implemented for the
514 /// generator's `SupportType`. 514 /// generator's `SupportType`.
515 pub(super) fn convert_aggregator<ANew, G>( 515 pub(super) fn convert_aggregator<ANew, G>(
516 mut self, 516 mut self,
517 generator: &G, 517 generator: &G,
518 domain: &Cube<F, N>, 518 domain: &Cube<N, F>,
519 ) -> Node<F, D, ANew, N, P> 519 ) -> Node<F, D, ANew, N, P>
520 where 520 where
521 ANew: Aggregator, 521 ANew: Aggregator,
522 G: SupportGenerator<F, N, Id = D>, 522 G: SupportGenerator<N, F, Id = D>,
523 G::SupportType: LocalAnalysis<F, ANew, N>, 523 G::SupportType: LocalAnalysis<F, ANew, N>,
524 { 524 {
525 // The mem::replace is needed due to the [`Drop`] implementation to extract self.data. 525 // The mem::replace is needed due to the [`Drop`] implementation to extract self.data.
526 match std::mem::replace(&mut self.data, NodeOption::Uninitialised) { 526 match std::mem::replace(&mut self.data, NodeOption::Uninitialised) {
527 NodeOption::Uninitialised => Node { 527 NodeOption::Uninitialised => Node {
559 /// The `generator` is used to convert the data of type `D` of the node into corresponding 559 /// The `generator` is used to convert the data of type `D` of the node into corresponding
560 /// [`Support`]s. The `domain` is the cube corresponding to `self`. 560 /// [`Support`]s. The `domain` is the cube corresponding to `self`.
561 pub(super) fn refresh_aggregator<'refs, 'scope, G>( 561 pub(super) fn refresh_aggregator<'refs, 'scope, G>(
562 &mut self, 562 &mut self,
563 generator: &G, 563 generator: &G,
564 domain: &Cube<F, N>, 564 domain: &Cube<N, F>,
565 task_budget: TaskBudget<'scope, 'refs>, 565 task_budget: TaskBudget<'scope, 'refs>,
566 ) where 566 ) where
567 G: SupportGenerator<F, N, Id = D>, 567 G: SupportGenerator<N, F, Id = D>,
568 G::SupportType: LocalAnalysis<F, A, N>, 568 G::SupportType: LocalAnalysis<F, A, N>,
569 { 569 {
570 match &mut self.data { 570 match &mut self.data {
571 NodeOption::Uninitialised => {} 571 NodeOption::Uninitialised => {}
572 NodeOption::Leaf(v) => { 572 NodeOption::Leaf(v) => {
608 pub struct BTNodeLookup; 608 pub struct BTNodeLookup;
609 609
610 /// Basic interface to a [`BT`] bisection tree. 610 /// Basic interface to a [`BT`] bisection tree.
611 /// 611 ///
612 /// Further routines are provided by the [`BTSearch`][super::refine::BTSearch] trait. 612 /// Further routines are provided by the [`BTSearch`][super::refine::BTSearch] trait.
613 pub trait BTImpl<F: Float, const N: usize>: 613 pub trait BTImpl<const N: usize, F: Float = f64>:
614 std::fmt::Debug + Clone + GlobalAnalysis<F, Self::Agg> 614 std::fmt::Debug + Clone + GlobalAnalysis<F, Self::Agg>
615 { 615 {
616 /// The data type stored in the tree 616 /// The data type stored in the tree
617 type Data: 'static + Copy + Send + Sync; 617 type Data: 'static + Copy + Send + Sync;
618 /// The depth type of the tree 618 /// The depth type of the tree
619 type Depth: Depth; 619 type Depth: Depth;
620 /// The type for the [aggregate information][Aggregator] about the `Data` stored in each node 620 /// The type for the [aggregate information][Aggregator] about the `Data` stored in each node
621 /// of the tree. 621 /// of the tree.
622 type Agg: Aggregator; 622 type Agg: Aggregator;
623 /// The type of the tree with the aggregator converted to `ANew`. 623 /// The type of the tree with the aggregator converted to `ANew`.
624 type Converted<ANew>: BTImpl<F, N, Data = Self::Data, Agg = ANew> 624 type Converted<ANew>: BTImpl<N, F, Data = Self::Data, Agg = ANew>
625 where 625 where
626 ANew: Aggregator; 626 ANew: Aggregator;
627 627
628 /// Insert the data `d` into the tree for `support`. 628 /// Insert the data `d` into the tree for `support`.
629 /// 629 ///
630 /// Every leaf node of the tree that intersects the `support` will contain a copy of 630 /// Every leaf node of the tree that intersects the `support` will contain a copy of
631 /// `d`. 631 /// `d`.
632 fn insert<S: LocalAnalysis<F, Self::Agg, N> + Support<F, N>>( 632 fn insert<S: LocalAnalysis<F, Self::Agg, N> + Support<N, F>>(
633 &mut self, 633 &mut self,
634 d: Self::Data, 634 d: Self::Data,
635 support: &S, 635 support: &S,
636 ); 636 );
637 637
640 /// The `generator` is used to convert the data of type [`Self::Data`] contained in the tree 640 /// The `generator` is used to convert the data of type [`Self::Data`] contained in the tree
641 /// into corresponding [`Support`]s. 641 /// into corresponding [`Support`]s.
642 fn convert_aggregator<ANew, G>(self, generator: &G) -> Self::Converted<ANew> 642 fn convert_aggregator<ANew, G>(self, generator: &G) -> Self::Converted<ANew>
643 where 643 where
644 ANew: Aggregator, 644 ANew: Aggregator,
645 G: SupportGenerator<F, N, Id = Self::Data>, 645 G: SupportGenerator<N, F, Id = Self::Data>,
646 G::SupportType: LocalAnalysis<F, ANew, N>; 646 G::SupportType: LocalAnalysis<F, ANew, N>;
647 647
648 /// Refreshes the aggregator of the three after possible changes to the support generator. 648 /// Refreshes the aggregator of the three after possible changes to the support generator.
649 /// 649 ///
650 /// The `generator` is used to convert the data of type [`Self::Data`] contained in the tree 650 /// The `generator` is used to convert the data of type [`Self::Data`] contained in the tree
651 /// into corresponding [`Support`]s. 651 /// into corresponding [`Support`]s.
652 fn refresh_aggregator<G>(&mut self, generator: &G) 652 fn refresh_aggregator<G>(&mut self, generator: &G)
653 where 653 where
654 G: SupportGenerator<F, N, Id = Self::Data>, 654 G: SupportGenerator<N, F, Id = Self::Data>,
655 G::SupportType: LocalAnalysis<F, Self::Agg, N>; 655 G::SupportType: LocalAnalysis<F, Self::Agg, N>;
656 656
657 /// Returns an iterator over all [`Self::Data`] items at the point `x` of the domain. 657 /// Returns an iterator over all [`Self::Data`] items at the point `x` of the domain.
658 fn iter_at(&self, x: &Loc<F, N>) -> std::slice::Iter<'_, Self::Data>; 658 fn iter_at(&self, x: &Loc<N, F>) -> std::slice::Iter<'_, Self::Data>;
659 659
660 /* 660 /*
661 /// Returns all [`Self::Data`] items at the point `x` of the domain. 661 /// Returns all [`Self::Data`] items at the point `x` of the domain.
662 fn data_at(&self, x : &Loc<F,N>) -> Arc<Vec<Self::Data>>; 662 fn data_at(&self, x : &Loc<N, F>) -> Arc<Vec<Self::Data>>;
663 */ 663 */
664 664
665 /// Create a new tree on `domain` of indicated `depth`. 665 /// Create a new tree on `domain` of indicated `depth`.
666 fn new(domain: Cube<F, N>, depth: Self::Depth) -> Self; 666 fn new(domain: Cube<N, F>, depth: Self::Depth) -> Self;
667 } 667 }
668 668
669 /// The main bisection tree structure. 669 /// The main bisection tree structure.
670 /// 670 ///
671 /// It should be accessed via the [`BTImpl`] trait to hide the `const P : usize` parameter until 671 /// It should be accessed via the [`BTImpl`] trait to hide the `const P : usize` parameter until
677 BTNodeLookup: BTNode<F, D, A, N>, 677 BTNodeLookup: BTNode<F, D, A, N>,
678 { 678 {
679 /// The depth of the tree (initial, before refinement) 679 /// The depth of the tree (initial, before refinement)
680 pub(super) depth: M, 680 pub(super) depth: M,
681 /// The domain of the toplevel node 681 /// The domain of the toplevel node
682 pub(super) domain: Cube<F, N>, 682 pub(super) domain: Cube<N, F>,
683 /// The toplevel node of the tree 683 /// The toplevel node of the tree
684 pub(super) topnode: <BTNodeLookup as BTNode<F, D, A, N>>::Node, 684 pub(super) topnode: <BTNodeLookup as BTNode<F, D, A, N>>::Node,
685 } 685 }
686 686
687 macro_rules! impl_bt { 687 macro_rules! impl_bt {
691 D : 'static + Copy + Send + Sync + std::fmt::Debug, 691 D : 'static + Copy + Send + Sync + std::fmt::Debug,
692 A : Aggregator { 692 A : Aggregator {
693 type Node = Node<F,D,A,$n,{pow(2, $n)}>; 693 type Node = Node<F,D,A,$n,{pow(2, $n)}>;
694 } 694 }
695 695
696 impl<M,F,D,A> BTImpl<F,$n> for BT<M,F,D,A,$n> 696 impl<M,F,D,A> BTImpl<$n, F> for BT<M,F,D,A,$n>
697 where M : Depth, 697 where M : Depth,
698 F : Float, 698 F : Float,
699 D : 'static + Copy + Send + Sync + std::fmt::Debug, 699 D : 'static + Copy + Send + Sync + std::fmt::Debug,
700 A : Aggregator { 700 A : Aggregator {
701 type Data = D; 701 type Data = D;
702 type Depth = M; 702 type Depth = M;
703 type Agg = A; 703 type Agg = A;
704 type Converted<ANew> = BT<M,F,D,ANew,$n> where ANew : Aggregator; 704 type Converted<ANew> = BT<M,F,D,ANew,$n> where ANew : Aggregator;
705 705
706 fn insert<S: LocalAnalysis<F, A, $n> + Support<F, $n>>( 706 fn insert<S: LocalAnalysis<F, A, $n> + Support< $n, F>>(
707 &mut self, 707 &mut self,
708 d : D, 708 d : D,
709 support : &S 709 support : &S
710 ) { 710 ) {
711 with_task_budget(|task_budget| 711 with_task_budget(|task_budget|
719 ) 719 )
720 } 720 }
721 721
722 fn convert_aggregator<ANew, G>(self, generator : &G) -> Self::Converted<ANew> 722 fn convert_aggregator<ANew, G>(self, generator : &G) -> Self::Converted<ANew>
723 where ANew : Aggregator, 723 where ANew : Aggregator,
724 G : SupportGenerator<F, $n, Id=D>, 724 G : SupportGenerator< $n, F, Id=D>,
725 G::SupportType : LocalAnalysis<F, ANew, $n> { 725 G::SupportType : LocalAnalysis<F, ANew, $n> {
726 let topnode = self.topnode.convert_aggregator(generator, &self.domain); 726 let topnode = self.topnode.convert_aggregator(generator, &self.domain);
727 727
728 BT { 728 BT {
729 depth : self.depth, 729 depth : self.depth,
731 topnode 731 topnode
732 } 732 }
733 } 733 }
734 734
735 fn refresh_aggregator<G>(&mut self, generator : &G) 735 fn refresh_aggregator<G>(&mut self, generator : &G)
736 where G : SupportGenerator<F, $n, Id=Self::Data>, 736 where G : SupportGenerator< $n, F, Id=Self::Data>,
737 G::SupportType : LocalAnalysis<F, Self::Agg, $n> { 737 G::SupportType : LocalAnalysis<F, Self::Agg, $n> {
738 with_task_budget(|task_budget| 738 with_task_budget(|task_budget|
739 self.topnode.refresh_aggregator(generator, &self.domain, task_budget) 739 self.topnode.refresh_aggregator(generator, &self.domain, task_budget)
740 ) 740 )
741 } 741 }
742 742
743 /*fn data_at(&self, x : &Loc<F,$n>) -> Arc<Vec<D>> { 743 /*fn data_at(&self, x : &Loc<$n, F>) -> Arc<Vec<D>> {
744 self.topnode.get_leaf_data(x).unwrap_or_else(|| Arc::new(Vec::new())) 744 self.topnode.get_leaf_data(x).unwrap_or_else(|| Arc::new(Vec::new()))
745 }*/ 745 }*/
746 746
747 fn iter_at(&self, x : &Loc<F,$n>) -> std::slice::Iter<'_, D> { 747 fn iter_at(&self, x : &Loc<$n, F>) -> std::slice::Iter<'_, D> {
748 self.topnode.get_leaf_data_iter(x).unwrap_or_else(|| [].iter()) 748 self.topnode.get_leaf_data_iter(x).unwrap_or_else(|| [].iter())
749 } 749 }
750 750
751 fn new(domain : Cube<F, $n>, depth : M) -> Self { 751 fn new(domain : Cube<$n, F>, depth : M) -> Self {
752 BT { 752 BT {
753 depth : depth, 753 depth : depth,
754 domain : domain, 754 domain : domain,
755 topnode : Node::new(), 755 topnode : Node::new(),
756 } 756 }

mercurial