--- a/src/bisection_tree/bt.rs Sun Nov 10 09:02:57 2024 -0500 +++ b/src/bisection_tree/bt.rs Tue Dec 31 09:12:43 2024 -0500 @@ -243,10 +243,11 @@ /// 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>>( + pub(super) fn new_with<S>( domain : &Cube<F,N>, support : &S - ) -> Self { + ) -> Self + where S : Support<N, RealField=F> + LocalAnalysis<A, Cube<F, N>> { let hint = support.bisection_hint(domain); let branch_at = map2(&hint, domain, |h, r| { h.unwrap_or_else(|| (r[0]+r[1])/F::TWO).max(r[0]).min(r[1]) @@ -321,14 +322,15 @@ /// * `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>>( + pub(super) fn insert<'refs, 'scope, M : Depth, S>( &mut self, domain : &Cube<F,N>, d : D, new_leaf_depth : M, support : &S, task_budget : TaskBudget<'scope, 'refs>, - ) { + ) + where S : Support<N, RealField=F> + LocalAnalysis<A, Cube<F, N>> { let support_hint = support.support_hint(); self.recurse(domain, task_budget, |_, subcube| support_hint.intersects(&subcube), @@ -348,8 +350,8 @@ domain : &Cube<F, N> ) -> Branches<F,D,ANew,N,P> where ANew : Aggregator, - G : SupportGenerator<F, N, Id=D>, - G::SupportType : LocalAnalysis<F, ANew, N> { + G : SupportGenerator<N, Id=D, RealField = F>, + G::SupportType : LocalAnalysis<ANew, Cube<F, N>> { let branch_at = self.branch_at; let subcube_iter = self.iter_subcubes(domain); let new_nodes = self.nodes.into_iter().zip(subcube_iter).map(|(node, subcube)| { @@ -370,8 +372,8 @@ generator : &G, domain : &Cube<F, N>, task_budget : TaskBudget<'scope, 'refs>, - ) where G : SupportGenerator<F, N, Id=D>, - G::SupportType : LocalAnalysis<F, A, N> { + ) where G : SupportGenerator<N, Id=D, RealField = F>, + G::SupportType : LocalAnalysis<A, Cube<F, N>> { self.recurse(domain, task_budget, |_, _| true, move |node, subcube, new_budget| node.refresh_aggregator(generator, subcube, @@ -434,14 +436,15 @@ /// 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>>( + pub(super) fn insert<'refs, 'scope, M : Depth, S>( &mut self, domain : &Cube<F,N>, d : D, new_leaf_depth : M, support : &S, task_budget : TaskBudget<'scope, 'refs>, - ) { + ) + where S : Support<N, RealField = F> + LocalAnalysis<A, Cube<F, N>> { match &mut self.data { NodeOption::Uninitialised => { // Replace uninitialised node with a leaf or a branch @@ -493,8 +496,8 @@ domain : &Cube<F, N> ) -> Node<F,D,ANew,N,P> where ANew : Aggregator, - G : SupportGenerator<F, N, Id=D>, - G::SupportType : LocalAnalysis<F, ANew, N> { + G : SupportGenerator<N, Id=D, RealField = F>, + G::SupportType : LocalAnalysis<ANew, Cube<F, N>> { // The mem::replace is needed due to the [`Drop`] implementation to extract self.data. match std::mem::replace(&mut self.data, NodeOption::Uninitialised) { @@ -537,8 +540,8 @@ generator : &G, domain : &Cube<F, N>, task_budget : TaskBudget<'scope, 'refs>, - ) where G : SupportGenerator<F, N, Id=D>, - G::SupportType : LocalAnalysis<F, A, N> { + ) where G : SupportGenerator<N, Id=D, RealField = F>, + G::SupportType : LocalAnalysis<A, Cube<F, N>> { match &mut self.data { NodeOption::Uninitialised => { }, NodeOption::Leaf(v) => { @@ -580,7 +583,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> : std::fmt::Debug + Clone + GlobalAnalysis<F, Self::Agg> { +pub trait BTImpl<F : Float, const N : usize> : std::fmt::Debug + Clone + GlobalAnalysis<Self::Agg> { /// The data type stored in the tree type Data : 'static + Copy + Send + Sync; /// The depth type of the tree @@ -595,11 +598,12 @@ /// /// Every leaf node of the tree that intersects the `support` will contain a copy of /// `d`. - fn insert<S : LocalAnalysis<F, Self::Agg, N>>( + fn insert<S>( &mut self, d : Self::Data, support : &S - ); + ) + where S: Support<N, RealField=F> + LocalAnalysis<Self::Agg, Cube<F, N>>; /// Construct a new instance of the tree for a different aggregator /// @@ -608,8 +612,8 @@ fn convert_aggregator<ANew, G>(self, generator : &G) -> Self::Converted<ANew> where ANew : Aggregator, - G : SupportGenerator<F, N, Id=Self::Data>, - G::SupportType : LocalAnalysis<F, ANew, N>; + G : SupportGenerator< N, Id=Self::Data, RealField = F>, + G::SupportType : LocalAnalysis<ANew, Cube<F, N>>; /// Refreshes the aggregator of the three after possible changes to the support generator. @@ -617,8 +621,8 @@ /// The `generator` is used to convert the data of type [`Self::Data`] contained in the tree /// into corresponding [`Support`]s. fn refresh_aggregator<G>(&mut self, generator : &G) - where G : SupportGenerator<F, N, Id=Self::Data>, - G::SupportType : LocalAnalysis<F, Self::Agg, N>; + where G : SupportGenerator<N, Id=Self::Data, RealField = F>, + G::SupportType : LocalAnalysis<Self::Agg, Cube<F, 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>; @@ -672,11 +676,12 @@ type Agg = A; type Converted<ANew> = BT<M,F,D,ANew,$n> where ANew : Aggregator; - fn insert<S: LocalAnalysis<F, A, $n>>( + fn insert<S>( &mut self, d : D, support : &S - ) { + ) + where S : Support<$n, RealField = F> + LocalAnalysis<A, Cube<F, $n>> { with_task_budget(|task_budget| self.topnode.insert( &self.domain, @@ -690,8 +695,8 @@ fn convert_aggregator<ANew, G>(self, generator : &G) -> Self::Converted<ANew> where ANew : Aggregator, - G : SupportGenerator<F, $n, Id=D>, - G::SupportType : LocalAnalysis<F, ANew, $n> { + G : SupportGenerator<$n, Id=D, RealField = F>, + G::SupportType : LocalAnalysis<ANew, Cube<F, $n>> { let topnode = self.topnode.convert_aggregator(generator, &self.domain); BT { @@ -702,8 +707,8 @@ } fn refresh_aggregator<G>(&mut self, generator : &G) - where G : SupportGenerator<F, $n, Id=Self::Data>, - G::SupportType : LocalAnalysis<F, Self::Agg, $n> { + where G : SupportGenerator<$n, Id=Self::Data, RealField = F>, + G::SupportType : LocalAnalysis<Self::Agg, Cube<F, $n>> { with_task_budget(|task_budget| self.topnode.refresh_aggregator(generator, &self.domain, task_budget) ) @@ -726,7 +731,7 @@ } } - impl<M,F,D,A> GlobalAnalysis<F,A> for BT<M,F,D,A,$n> + impl<M,F,D,A> GlobalAnalysis<A> for BT<M,F,D,A,$n> where M : Depth, F : Float, D : 'static + Copy + Send + Sync + std::fmt::Debug,