diff -r edb95d2b83cc -r d2acaaddd9af src/bisection_tree/btfn.rs --- a/src/bisection_tree/btfn.rs Sun Nov 10 09:02:57 2024 -0500 +++ b/src/bisection_tree/btfn.rs Tue Dec 31 09:12:43 2024 -0500 @@ -1,9 +1,8 @@ use numeric_literals::replace_float_literals; use std::iter::Sum; -use std::marker::PhantomData; use std::sync::Arc; -use crate::types::Float; +use crate::types::{Float, HasScalarField, HasRealField}; use crate::mapping::{Apply, Mapping, Differentiable}; //use crate::linops::{Apply, Linear}; use crate::sets::Set; @@ -29,21 +28,23 @@ /// for a [`PreBTFN`] that is only useful for vector space operations with a full [`BTFN`]. #[derive(Clone,Debug)] pub struct BTFN< - F : Float, - G : SupportGenerator, + G : SupportGenerator, BT /*: BTImpl*/, const N : usize -> /*where G::SupportType : LocalAnalysis*/ { +> { bt : BT, generator : Arc, - _phantoms : PhantomData, +} + +impl, BT, const N : usize> HasScalarField for BTFN { + type Field = G::Field; } impl -BTFN -where G : SupportGenerator, - G::SupportType : LocalAnalysis, - BT : BTImpl { +BTFN +where G : SupportGenerator, + G::SupportType : LocalAnalysis>, + BT : BTImpl { /// Create a new BTFN from a support generator and a pre-initialised bisection tree. /// @@ -60,7 +61,6 @@ BTFN { bt : bt, generator : generator, - _phantoms : std::marker::PhantomData, } } @@ -85,11 +85,11 @@ /// The top node of the created [`BT`] will have the given `domain`. /// /// See the documentation for [`BTFN`] on the role of the `generator`. - pub fn construct(domain : Cube, depth : BT::Depth, generator : G) -> Self { + pub fn construct(domain : Cube, depth : BT::Depth, generator : G) -> Self { Self::construct_arc(domain, depth, Arc::new(generator)) } - fn construct_arc(domain : Cube, depth : BT::Depth, generator : Arc) -> Self { + fn construct_arc(domain : Cube, depth : BT::Depth, generator : Arc) -> Self { let mut bt = BT::new(domain, depth); for (d, support) in generator.all_data() { bt.insert(d, &support); @@ -101,10 +101,10 @@ /// /// This will construct a [`BTFN`] with the same components and generator as the (consumed) /// `self`, but a new `BT` with [`Aggregator`]s of type `ANew`. - pub fn convert_aggregator(self) -> BTFN, N> + pub fn convert_aggregator(self) -> BTFN, N> where ANew : Aggregator, - G : SupportGenerator, - G::SupportType : LocalAnalysis { + G : SupportGenerator, + G::SupportType : LocalAnalysis> { BTFN::new_arc(self.bt.convert_aggregator(&*self.generator), self.generator) } @@ -121,16 +121,16 @@ } impl -BTFN -where G : SupportGenerator { +BTFN +where G : SupportGenerator { /// Change the [bisection tree][BTImpl] of the [`BTFN`] to a different one. /// /// This can be used to convert a [`PreBTFN`] to a full [`BTFN`], or the change /// the aggreagator; see also [`self.convert_aggregator`]. pub fn instantiate< BTNew : BTImpl, - > (self, domain : Cube, depth : BTNew::Depth) -> BTFN - where G::SupportType : LocalAnalysis { + > (self, domain : Cube, depth : BTNew::Depth) -> BTFN + where G::SupportType : LocalAnalysis> { BTFN::construct_arc(domain, depth, self.generator) } } @@ -140,30 +140,29 @@ /// Most BTFN methods are not available, but if a BTFN is going to be summed with another /// before other use, it will be more efficient to not construct an unnecessary bisection tree /// that would be shortly dropped. -pub type PreBTFN = BTFN; +pub type PreBTFN = BTFN; -impl PreBTFN where G : SupportGenerator { +impl PreBTFN where G : SupportGenerator { /// Create a new [`PreBTFN`] with no bisection tree. pub fn new_pre(generator : G) -> Self { BTFN { bt : (), generator : Arc::new(generator), - _phantoms : std::marker::PhantomData, } } } impl -BTFN -where G : SupportGenerator, - G::SupportType : LocalAnalysis, +BTFN +where G : SupportGenerator, + G::SupportType : LocalAnalysis>, BT : BTImpl { /// Helper function for implementing [`std::ops::Add`]. - fn add_another(&self, g2 : Arc) -> BTFN, BT, N> - where G2 : SupportGenerator, - G2::SupportType : LocalAnalysis { + fn add_another(&self, g2 : Arc) -> BTFN, BT, N> + where G2 : SupportGenerator, + G2::SupportType : LocalAnalysis> { let mut bt = self.bt.clone(); let both = BothGenerators(Arc::clone(&self.generator), g2); @@ -175,7 +174,6 @@ BTFN { bt : bt, generator : Arc::new(both), - _phantoms : std::marker::PhantomData, } } } @@ -183,54 +181,54 @@ macro_rules! make_btfn_add { ($lhs:ty, $preprocess:path, $($extra_trait:ident)?) => { impl<'a, F : Float, G1, G2, BT1, BT2, const N : usize> - std::ops::Add> for + std::ops::Add> for $lhs where BT1 : BTImpl, - G1 : SupportGenerator + $($extra_trait)?, - G2 : SupportGenerator, - G1::SupportType : LocalAnalysis, - G2::SupportType : LocalAnalysis { - type Output = BTFN, BT1, N>; + G1 : SupportGenerator + $($extra_trait)?, + G2 : SupportGenerator, + G1::SupportType : LocalAnalysis>, + G2::SupportType : LocalAnalysis> { + type Output = BTFN, BT1, N>; #[inline] - fn add(self, other : BTFN) -> Self::Output { + fn add(self, other : BTFN) -> Self::Output { $preprocess(self).add_another(other.generator) } } impl<'a, 'b, F : Float, G1, G2, BT1, BT2, const N : usize> - std::ops::Add<&'b BTFN> for + std::ops::Add<&'b BTFN> for $lhs where BT1 : BTImpl, - G1 : SupportGenerator + $($extra_trait)?, - G2 : SupportGenerator, - G1::SupportType : LocalAnalysis, - G2::SupportType : LocalAnalysis { + G1 : SupportGenerator + $($extra_trait)?, + G2 : SupportGenerator, + G1::SupportType : LocalAnalysis>, + G2::SupportType : LocalAnalysis> { - type Output = BTFN, BT1, N>; + type Output = BTFN, BT1, N>; #[inline] - fn add(self, other : &'b BTFN) -> Self::Output { + fn add(self, other : &'b BTFN) -> Self::Output { $preprocess(self).add_another(other.generator.clone()) } } } } -make_btfn_add!(BTFN, std::convert::identity, ); -make_btfn_add!(&'a BTFN, Clone::clone, ); +make_btfn_add!(BTFN, std::convert::identity, ); +make_btfn_add!(&'a BTFN, Clone::clone, ); macro_rules! make_btfn_sub { ($lhs:ty, $preprocess:path, $($extra_trait:ident)?) => { impl<'a, F : Float, G1, G2, BT1, BT2, const N : usize> - std::ops::Sub> for + std::ops::Sub> for $lhs where BT1 : BTImpl, - G1 : SupportGenerator + $($extra_trait)?, - G2 : SupportGenerator, - G1::SupportType : LocalAnalysis, - G2::SupportType : LocalAnalysis { - type Output = BTFN, BT1, N>; + G1 : SupportGenerator + $($extra_trait)?, + G2 : SupportGenerator, + G1::SupportType : LocalAnalysis>, + G2::SupportType : LocalAnalysis> { + type Output = BTFN, BT1, N>; #[inline] - fn sub(self, other : BTFN) -> Self::Output { + fn sub(self, other : BTFN) -> Self::Output { $preprocess(self).add_another(Arc::new( Arc::try_unwrap(other.generator) .unwrap_or_else(|arc| (*arc).clone()) @@ -240,35 +238,35 @@ } impl<'a, 'b, F : Float, G1, G2, BT1, BT2, const N : usize> - std::ops::Sub<&'b BTFN> for + std::ops::Sub<&'b BTFN> for $lhs where BT1 : BTImpl, - G1 : SupportGenerator + $($extra_trait)?, - G2 : SupportGenerator + Clone, - G1::SupportType : LocalAnalysis, - G2::SupportType : LocalAnalysis, + G1 : SupportGenerator + $($extra_trait)?, + G2 : SupportGenerator + Clone, + G1::SupportType : LocalAnalysis>, + G2::SupportType : LocalAnalysis>, &'b G2 : std::ops::Neg { - type Output = BTFN, BT1, N>; + type Output = BTFN, BT1, N>; #[inline] - fn sub(self, other : &'b BTFN) -> Self::Output { + fn sub(self, other : &'b BTFN) -> Self::Output { $preprocess(self).add_another(Arc::new((*other.generator).clone().neg())) } } } } -make_btfn_sub!(BTFN, std::convert::identity, ); -make_btfn_sub!(&'a BTFN, std::convert::identity, ); +make_btfn_sub!(BTFN, std::convert::identity, ); +make_btfn_sub!(&'a BTFN, std::convert::identity, ); macro_rules! make_btfn_scalarop_rhs { ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { impl std::ops::$trait_assign - for BTFN + for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis { + G : SupportGenerator, + G::SupportType : LocalAnalysis> { #[inline] fn $fn_assign(&mut self, t : F) { Arc::make_mut(&mut self.generator).$fn_assign(t); @@ -278,10 +276,10 @@ impl std::ops::$trait - for BTFN + for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis { + G : SupportGenerator, + G::SupportType : LocalAnalysis> { type Output = Self; #[inline] fn $fn(mut self, t : F) -> Self::Output { @@ -293,12 +291,12 @@ impl<'a, F : Float, G, BT, const N : usize> std::ops::$trait - for &'a BTFN + for &'a BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis, + G : SupportGenerator, + G::SupportType : LocalAnalysis>, &'a G : std::ops::$trait { - type Output = BTFN; + type Output = BTFN; #[inline] fn $fn(self, t : F) -> Self::Output { self.new_generator(self.generator.$fn(t)) @@ -313,14 +311,14 @@ macro_rules! make_btfn_scalarop_lhs { ($trait:ident, $fn:ident, $fn_assign:ident, $($f:ident)+) => { $( impl - std::ops::$trait> + std::ops::$trait> for $f where BT : BTImpl<$f, N>, - G : SupportGenerator<$f, N, Id=BT::Data>, - G::SupportType : LocalAnalysis<$f, BT::Agg, N> { - type Output = BTFN<$f, G, BT, N>; + G : SupportGenerator, + G::SupportType : LocalAnalysis> { + type Output = BTFN; #[inline] - fn $fn(self, mut a : BTFN<$f, G, BT, N>) -> Self::Output { + fn $fn(self, mut a : BTFN) -> Self::Output { Arc::make_mut(&mut a.generator).$fn_assign(self); a.refresh_aggregator(); a @@ -328,16 +326,16 @@ } impl<'a, G, BT, const N : usize> - std::ops::$trait<&'a BTFN<$f, G, BT, N>> + std::ops::$trait<&'a BTFN> for $f where BT : BTImpl<$f, N>, - G : SupportGenerator<$f, N, Id=BT::Data> + Clone, - G::SupportType : LocalAnalysis<$f, BT::Agg, N>, + G : SupportGenerator + Clone, + G::SupportType : LocalAnalysis>, // FIXME: This causes compiler overflow /*&'a G : std::ops::$trait<$f,Output=G>*/ { - type Output = BTFN<$f, G, BT, N>; + type Output = BTFN; #[inline] - fn $fn(self, a : &'a BTFN<$f, G, BT, N>) -> Self::Output { + fn $fn(self, a : &'a BTFN) -> Self::Output { let mut tmp = (*a.generator).clone(); tmp.$fn_assign(self); a.new_generator(tmp) @@ -355,10 +353,10 @@ ($trait:ident, $fn:ident) => { impl std::ops::$trait - for BTFN + for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis { + G : SupportGenerator, + G::SupportType : LocalAnalysis> { type Output = Self; #[inline] fn $fn(mut self) -> Self::Output { @@ -391,10 +389,11 @@ // impl<'a, F : Float, G, BT, V, const N : usize> Apply<&'a Loc> -for BTFN +for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis + Apply<&'a Loc, Output = V>, + G : SupportGenerator, + G::SupportType : LocalAnalysis> + + Apply<&'a Loc, Output = V>, V : Sum { type Output = V; @@ -406,10 +405,11 @@ } impl Apply> -for BTFN +for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis + Apply, Output = V>, + G : SupportGenerator, + G::SupportType : LocalAnalysis> + + Apply, Output = V>, V : Sum { type Output = V; @@ -420,11 +420,13 @@ } } -impl<'a, F : Float, G, BT, V, const N : usize> Differentiable<&'a Loc> -for BTFN +impl<'a, F : Float, G, BT, V : HasRealField, const N : usize> +Differentiable<&'a Loc> +for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis + Differentiable<&'a Loc, Derivative = V>, + G : SupportGenerator, + G::SupportType : LocalAnalysis> + + Differentiable<&'a Loc, Derivative = V>, V : Sum { type Derivative = V; @@ -437,11 +439,12 @@ } impl Differentiable> -for BTFN +for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis + Differentiable, Derivative = V>, - V : Sum { + G : SupportGenerator, + G::SupportType : LocalAnalysis> + + Differentiable, Derivative = V>, + V : Sum + HasRealField { type Derivative = V; @@ -456,11 +459,11 @@ // GlobalAnalysis // -impl GlobalAnalysis -for BTFN +impl GlobalAnalysis +for BTFN where BT : BTImpl, - G : SupportGenerator, - G::SupportType : LocalAnalysis { + G : SupportGenerator, + G::SupportType : LocalAnalysis> { #[inline] fn global_analysis(&self) -> BT::Agg { @@ -617,12 +620,12 @@ how : T, } -impl Refiner, G, N> +impl Refiner, G, N> for P2Refiner where Cube : P2Minimise, F>, - G : SupportGenerator, + G : SupportGenerator, G::SupportType : Mapping, Codomain=F> - + LocalAnalysis, N> { + + LocalAnalysis, Cube> { type Result = Option<(Loc, F)>; type Sorting = UpperBoundSorting; @@ -674,12 +677,12 @@ } -impl Refiner, G, N> +impl Refiner, G, N> for P2Refiner where Cube : P2Minimise, F>, - G : SupportGenerator, + G : SupportGenerator, G::SupportType : Mapping, Codomain=F> - + LocalAnalysis, N> { + + LocalAnalysis, Cube> { type Result = Option<(Loc, F)>; type Sorting = LowerBoundSorting; @@ -754,9 +757,9 @@ how : T, } -impl Refiner, G, N> +impl Refiner, G, N> for BoundRefiner -where G : SupportGenerator { +where G : SupportGenerator { type Result = bool; type Sorting = UpperBoundSorting; @@ -788,9 +791,9 @@ } } -impl Refiner, G, N> +impl Refiner, G, N> for BoundRefiner -where G : SupportGenerator { +where G : SupportGenerator { type Result = bool; type Sorting = UpperBoundSorting; @@ -837,11 +840,11 @@ // there should be a result, or new nodes above the `glb` inserted into the queue. Then the waiting // threads can also continue processing. If, however, numerical inaccuracy destroyes the `glb`, // the queue may run out, and we get “Refiner failure”. -impl BTFN +impl BTFN where BT : BTSearch>, - G : SupportGenerator, + G : SupportGenerator, G::SupportType : Mapping,Codomain=F> - + LocalAnalysis, N>, + + LocalAnalysis, Cube>, Cube : P2Minimise, F> { /// Maximise the `BTFN` within stated value `tolerance`.