src/bisection_tree/bt.rs

branch
dev
changeset 124
6aa955ad8122
parent 97
4e80fb049dca
--- a/src/bisection_tree/bt.rs	Thu May 01 08:40:33 2025 -0500
+++ b/src/bisection_tree/bt.rs	Thu May 01 13:06:58 2025 -0500
@@ -51,7 +51,7 @@
 #[derive(Clone, Debug)]
 pub(super) struct Branches<F: Num, D, A: Aggregator, const N: usize, const P: usize> {
     /// Point for subdivision of the (unstored) [`Cube`] corresponding to the node.
-    pub(super) branch_at: Loc<F, N>,
+    pub(super) branch_at: Loc<N, F>,
     /// Subnodes
     pub(super) nodes: [Node<F, D, A, N, P>; P],
 }
@@ -184,7 +184,7 @@
     ///
     /// This only takes the branch subdivision point $d$ into account, so is always succesfull.
     /// Thus, for this point, each branch corresponds to a quadrant of $ℝ^N$ relative to $d$.
-    fn get_node_index(&self, x: &Loc<F, N>) -> usize {
+    fn get_node_index(&self, x: &Loc<N, F>) -> usize {
         izip!(0..P, x.iter(), self.branch_at.iter())
             .map(|(i, x_i, branch_i)| if x_i > branch_i { 1 << i } else { 0 })
             .sum()
@@ -195,25 +195,25 @@
     /// This only takes the branch subdivision point $d$ into account, so is always succesfull.
     /// Thus, for this point, each branch corresponds to a quadrant of $ℝ^N$ relative to $d$.
     #[inline]
-    fn get_node(&self, x: &Loc<F, N>) -> &Node<F, D, A, N, P> {
+    fn get_node(&self, x: &Loc<N, F>) -> &Node<F, D, A, N, P> {
         &self.nodes[self.get_node_index(x)]
     }
 }
 
 /// An iterator over the $P=2^N$ subcubes of a [`Cube`] subdivided at a point `d`.
 pub(super) struct SubcubeIter<'b, F: Float, const N: usize, const P: usize> {
-    domain: &'b Cube<F, N>,
-    branch_at: Loc<F, N>,
+    domain: &'b Cube<N, F>,
+    branch_at: Loc<N, F>,
     index: usize,
 }
 
 /// Returns the `i`:th subcube of `domain` subdivided at `branch_at`.
 #[inline]
 fn get_subcube<F: Float, const N: usize>(
-    branch_at: &Loc<F, N>,
-    domain: &Cube<F, N>,
+    branch_at: &Loc<N, F>,
+    domain: &Cube<N, F>,
     i: usize,
-) -> Cube<F, N> {
+) -> Cube<N, F> {
     map2_indexed(branch_at, domain, move |j, &branch, &[start, end]| {
         if i & (1 << j) != 0 {
             [branch, end]
@@ -225,7 +225,7 @@
 }
 
 impl<'a, 'b, F: Float, const N: usize, const P: usize> Iterator for SubcubeIter<'b, F, N, P> {
-    type Item = Cube<F, N>;
+    type Item = Cube<N, F>;
     #[inline]
     fn next(&mut self) -> Option<Self::Item> {
         if self.index < P {
@@ -246,8 +246,8 @@
 {
     /// Creates a new node branching structure, subdividing `domain` based on the
     /// [hint][Support::support_hint] of `support`.
-    pub(super) fn new_with<S: LocalAnalysis<F, A, N> + Support<F, N>>(
-        domain: &Cube<F, N>,
+    pub(super) fn new_with<S: LocalAnalysis<F, A, N> + Support<N, F>>(
+        domain: &Cube<N, F>,
         support: &S,
     ) -> Self {
         let hint = support.bisection_hint(domain);
@@ -272,7 +272,7 @@
     /// Returns an iterator over the subcubes of `domain` subdivided at the branching point
     /// of `self`.
     #[inline]
-    pub(super) fn iter_subcubes<'b>(&self, domain: &'b Cube<F, N>) -> SubcubeIter<'b, F, N, P> {
+    pub(super) fn iter_subcubes<'b>(&self, domain: &'b Cube<N, F>) -> SubcubeIter<'b, F, N, P> {
         SubcubeIter {
             domain: domain,
             branch_at: self.branch_at,
@@ -283,7 +283,7 @@
     /*
     /// Returns an iterator over all nodes and corresponding subcubes of `self`.
     #[inline]
-    pub(super) fn nodes_and_cubes<'a, 'b>(&'a self, domain : &'b Cube<F, N>)
+    pub(super) fn nodes_and_cubes<'a, 'b>(&'a self, domain : &'b Cube<N, F>)
     -> std::iter::Zip<Iter<'a, Node<F,D,A,N,P>>, SubcubeIter<'b, F, N, P>> {
         self.nodes.iter().zip(self.iter_subcubes(domain))
     }
@@ -293,7 +293,7 @@
     #[inline]
     pub(super) fn nodes_and_cubes_mut<'a, 'b>(
         &'a mut self,
-        domain: &'b Cube<F, N>,
+        domain: &'b Cube<N, F>,
     ) -> std::iter::Zip<IterMut<'a, Node<F, D, A, N, P>>, SubcubeIter<'b, F, N, P>> {
         let subcube_iter = self.iter_subcubes(domain);
         self.nodes.iter_mut().zip(subcube_iter)
@@ -303,10 +303,10 @@
     #[inline]
     fn recurse<'scope, 'smaller, 'refs>(
         &'smaller mut self,
-        domain: &'smaller Cube<F, N>,
+        domain: &'smaller Cube<N, F>,
         task_budget: TaskBudget<'scope, 'refs>,
-        guard: impl Fn(&Node<F, D, A, N, P>, &Cube<F, N>) -> bool + Send + 'smaller,
-        mut f: impl for<'a> FnMut(&mut Node<F, D, A, N, P>, &Cube<F, N>, TaskBudget<'smaller, 'a>)
+        guard: impl Fn(&Node<F, D, A, N, P>, &Cube<N, F>) -> bool + Send + 'smaller,
+        mut f: impl for<'a> FnMut(&mut Node<F, D, A, N, P>, &Cube<N, F>, TaskBudget<'smaller, 'a>)
             + Send
             + Copy
             + 'smaller,
@@ -332,9 +332,9 @@
     ///  * `support` is the [`Support`] that is used determine with which subcubes of `domain`
     ///     (at subdivision depth `new_leaf_depth`) the data `d` is to be associated with.
     ///
-    pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<F, N>>(
+    pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<N, F>>(
         &mut self,
-        domain: &Cube<F, N>,
+        domain: &Cube<N, F>,
         d: D,
         new_leaf_depth: M,
         support: &S,
@@ -360,11 +360,11 @@
     pub(super) fn convert_aggregator<ANew, G>(
         self,
         generator: &G,
-        domain: &Cube<F, N>,
+        domain: &Cube<N, F>,
     ) -> Branches<F, D, ANew, N, P>
     where
         ANew: Aggregator,
-        G: SupportGenerator<F, N, Id = D>,
+        G: SupportGenerator<N, F, Id = D>,
         G::SupportType: LocalAnalysis<F, ANew, N>,
     {
         let branch_at = self.branch_at;
@@ -387,10 +387,10 @@
     pub(super) fn refresh_aggregator<'refs, 'scope, G>(
         &mut self,
         generator: &G,
-        domain: &Cube<F, N>,
+        domain: &Cube<N, F>,
         task_budget: TaskBudget<'scope, 'refs>,
     ) where
-        G: SupportGenerator<F, N, Id = D>,
+        G: SupportGenerator<N, F, Id = D>,
         G::SupportType: LocalAnalysis<F, A, N>,
     {
         self.recurse(
@@ -422,7 +422,7 @@
     /*
     /// Get leaf data
     #[inline]
-    pub(super) fn get_leaf_data(&self, x : &Loc<F, N>) -> Option<&Vec<D>> {
+    pub(super) fn get_leaf_data(&self, x : &Loc<N, F>) -> Option<&Vec<D>> {
         match self.data {
             NodeOption::Uninitialised => None,
             NodeOption::Leaf(ref data) => Some(data),
@@ -432,7 +432,7 @@
 
     /// Get leaf data iterator
     #[inline]
-    pub(super) fn get_leaf_data_iter(&self, x: &Loc<F, N>) -> Option<std::slice::Iter<'_, D>> {
+    pub(super) fn get_leaf_data_iter(&self, x: &Loc<N, F>) -> Option<std::slice::Iter<'_, D>> {
         match self.data {
             NodeOption::Uninitialised => None,
             NodeOption::Leaf(ref data) => Some(data.iter()),
@@ -459,9 +459,9 @@
     /// If `self` is a [`NodeOption::Branches`], the data is passed to branches whose subcubes
     /// `support` intersects. If an [`NodeOption::Uninitialised`] node is encountered, a new leaf is
     /// created at a minimum depth of `new_leaf_depth`.
-    pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<F, N>>(
+    pub(super) fn insert<'refs, 'scope, M: Depth, S: LocalAnalysis<F, A, N> + Support<N, F>>(
         &mut self,
-        domain: &Cube<F, N>,
+        domain: &Cube<N, F>,
         d: D,
         new_leaf_depth: M,
         support: &S,
@@ -515,11 +515,11 @@
     pub(super) fn convert_aggregator<ANew, G>(
         mut self,
         generator: &G,
-        domain: &Cube<F, N>,
+        domain: &Cube<N, F>,
     ) -> Node<F, D, ANew, N, P>
     where
         ANew: Aggregator,
-        G: SupportGenerator<F, N, Id = D>,
+        G: SupportGenerator<N, F, Id = D>,
         G::SupportType: LocalAnalysis<F, ANew, N>,
     {
         // The mem::replace is needed due to the [`Drop`] implementation to extract self.data.
@@ -561,10 +561,10 @@
     pub(super) fn refresh_aggregator<'refs, 'scope, G>(
         &mut self,
         generator: &G,
-        domain: &Cube<F, N>,
+        domain: &Cube<N, F>,
         task_budget: TaskBudget<'scope, 'refs>,
     ) where
-        G: SupportGenerator<F, N, Id = D>,
+        G: SupportGenerator<N, F, Id = D>,
         G::SupportType: LocalAnalysis<F, A, N>,
     {
         match &mut self.data {
@@ -610,7 +610,7 @@
 /// Basic interface to a [`BT`] bisection tree.
 ///
 /// Further routines are provided by the [`BTSearch`][super::refine::BTSearch] trait.
-pub trait BTImpl<F: Float, const N: usize>:
+pub trait BTImpl<const N: usize, F: Float = f64>:
     std::fmt::Debug + Clone + GlobalAnalysis<F, Self::Agg>
 {
     /// The data type stored in the tree
@@ -621,7 +621,7 @@
     /// of the tree.
     type Agg: Aggregator;
     /// The type of the tree with the aggregator converted to `ANew`.
-    type Converted<ANew>: BTImpl<F, N, Data = Self::Data, Agg = ANew>
+    type Converted<ANew>: BTImpl<N, F, Data = Self::Data, Agg = ANew>
     where
         ANew: Aggregator;
 
@@ -629,7 +629,7 @@
     ///
     /// Every leaf node of the tree that intersects the `support` will contain a copy of
     /// `d`.
-    fn insert<S: LocalAnalysis<F, Self::Agg, N> + Support<F, N>>(
+    fn insert<S: LocalAnalysis<F, Self::Agg, N> + Support<N, F>>(
         &mut self,
         d: Self::Data,
         support: &S,
@@ -642,7 +642,7 @@
     fn convert_aggregator<ANew, G>(self, generator: &G) -> Self::Converted<ANew>
     where
         ANew: Aggregator,
-        G: SupportGenerator<F, N, Id = Self::Data>,
+        G: SupportGenerator<N, F, Id = Self::Data>,
         G::SupportType: LocalAnalysis<F, ANew, N>;
 
     /// Refreshes the aggregator of the three after possible changes to the support generator.
@@ -651,19 +651,19 @@
     /// into corresponding [`Support`]s.
     fn refresh_aggregator<G>(&mut self, generator: &G)
     where
-        G: SupportGenerator<F, N, Id = Self::Data>,
+        G: SupportGenerator<N, F, Id = Self::Data>,
         G::SupportType: LocalAnalysis<F, Self::Agg, N>;
 
     /// Returns an iterator over all [`Self::Data`] items at the point `x` of the domain.
-    fn iter_at(&self, x: &Loc<F, N>) -> std::slice::Iter<'_, Self::Data>;
+    fn iter_at(&self, x: &Loc<N, F>) -> std::slice::Iter<'_, Self::Data>;
 
     /*
     /// Returns all [`Self::Data`] items at the point `x` of the domain.
-    fn data_at(&self, x : &Loc<F,N>) -> Arc<Vec<Self::Data>>;
+    fn data_at(&self, x : &Loc<N, F>) -> Arc<Vec<Self::Data>>;
     */
 
     /// Create a new tree on `domain` of indicated `depth`.
-    fn new(domain: Cube<F, N>, depth: Self::Depth) -> Self;
+    fn new(domain: Cube<N, F>, depth: Self::Depth) -> Self;
 }
 
 /// The main bisection tree structure.
@@ -679,7 +679,7 @@
     /// The depth of the tree (initial, before refinement)
     pub(super) depth: M,
     /// The domain of the toplevel node
-    pub(super) domain: Cube<F, N>,
+    pub(super) domain: Cube<N, F>,
     /// The toplevel node of the tree
     pub(super) topnode: <BTNodeLookup as BTNode<F, D, A, N>>::Node,
 }
@@ -693,7 +693,7 @@
             type Node = Node<F,D,A,$n,{pow(2, $n)}>;
         }
 
-        impl<M,F,D,A> BTImpl<F,$n> for BT<M,F,D,A,$n>
+        impl<M,F,D,A> BTImpl<$n, F> for BT<M,F,D,A,$n>
         where M : Depth,
               F : Float,
               D : 'static + Copy + Send + Sync + std::fmt::Debug,
@@ -703,7 +703,7 @@
             type Agg = A;
             type Converted<ANew> = BT<M,F,D,ANew,$n> where ANew : Aggregator;
 
-            fn insert<S: LocalAnalysis<F, A, $n> + Support<F, $n>>(
+            fn insert<S: LocalAnalysis<F, A, $n> + Support< $n, F>>(
                 &mut self,
                 d : D,
                 support : &S
@@ -721,7 +721,7 @@
 
             fn convert_aggregator<ANew, G>(self, generator : &G) -> Self::Converted<ANew>
             where ANew : Aggregator,
-                  G : SupportGenerator<F, $n, Id=D>,
+                  G : SupportGenerator< $n, F, Id=D>,
                   G::SupportType : LocalAnalysis<F, ANew, $n> {
                 let topnode = self.topnode.convert_aggregator(generator, &self.domain);
 
@@ -733,22 +733,22 @@
             }
 
             fn refresh_aggregator<G>(&mut self, generator : &G)
-            where G : SupportGenerator<F, $n, Id=Self::Data>,
+            where G : SupportGenerator< $n, F, Id=Self::Data>,
                 G::SupportType : LocalAnalysis<F, Self::Agg, $n> {
                 with_task_budget(|task_budget|
                     self.topnode.refresh_aggregator(generator, &self.domain, task_budget)
                 )
             }
 
-            /*fn data_at(&self, x : &Loc<F,$n>) -> Arc<Vec<D>> {
+            /*fn data_at(&self, x : &Loc<$n, F>) -> Arc<Vec<D>> {
                 self.topnode.get_leaf_data(x).unwrap_or_else(|| Arc::new(Vec::new()))
             }*/
 
-            fn iter_at(&self, x : &Loc<F,$n>) -> std::slice::Iter<'_, D> {
+            fn iter_at(&self, x : &Loc<$n, F>) -> std::slice::Iter<'_, D> {
                 self.topnode.get_leaf_data_iter(x).unwrap_or_else(|| [].iter())
             }
 
-            fn new(domain : Cube<F, $n>, depth : M) -> Self {
+            fn new(domain : Cube<$n, F>, depth : M) -> Self {
                 BT {
                     depth : depth,
                     domain : domain,

mercurial