src/bisection_tree/either.rs

branch
dev
changeset 124
6aa955ad8122
parent 59
9226980e45a7
child 150
c4e394a9c84c
--- a/src/bisection_tree/either.rs	Thu May 01 08:40:33 2025 -0500
+++ b/src/bisection_tree/either.rs	Thu May 01 13:06:58 2025 -0500
@@ -1,36 +1,26 @@
-
 use std::iter::Chain;
 use std::sync::Arc;
 
+use crate::iter::{MapF, MapZ, Mappable};
+use crate::loc::Loc;
+use crate::mapping::{DifferentiableImpl, DifferentiableMapping, Instance, Mapping, Space};
+use crate::sets::Cube;
 use crate::types::*;
-use crate::mapping::{
-    Instance,
-    Mapping,
-    DifferentiableImpl,
-    DifferentiableMapping,
-    Space,
-};
-use crate::iter::{Mappable, MapF, MapZ};
-use crate::sets::Cube;
-use crate::loc::Loc;
 
+use super::aggregator::*;
 use super::support::*;
-use super::aggregator::*;
 
 /// A structure for storing two [`SupportGenerator`]s summed/chain together.
 ///
 /// This is needed to work with sums of different types of [`Support`]s.
-#[derive(Debug,Clone)]
-pub struct BothGenerators<A, B>(
-    pub(super) Arc<A>,
-    pub(super) Arc<B>,
-);
+#[derive(Debug, Clone)]
+pub struct BothGenerators<A, B>(pub(super) Arc<A>, pub(super) Arc<B>);
 
 /// A structure for a [`Support`] that can be either `A` or `B`.
 ///
 /// This is needed to work with sums of different types of [`Support`]s.
-#[derive(Debug,Clone)]
-pub enum EitherSupport<A, B> {
+#[derive(Debug, Clone)]
+pub enum EitherSupport<B, A> {
     Left(A),
     Right(B),
 }
@@ -38,46 +28,55 @@
 // We need type alias bounds to access associate types.
 #[allow(type_alias_bounds)]
 type BothAllDataIter<
-    'a, F,
-    G1 : SupportGenerator<F, N>,
-    G2 : SupportGenerator<F, N>,
-    const N : usize
+    'a,
+    F,
+    G1: SupportGenerator<N, F>,
+    G2: SupportGenerator<N, F>,
+    const N: usize,
 > = Chain<
-    MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>,
-    MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>,
+    MapF<G1::AllDataIter<'a>, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>,
+    MapZ<G2::AllDataIter<'a>, usize, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>,
 >;
 
 impl<G1, G2> BothGenerators<G1, G2> {
     /// Helper for [`all_left_data`].
     #[inline]
-    fn map_left<F : Float, const N : usize>((d, support) : (G1::Id, G1::SupportType))
-    -> (usize, EitherSupport<G1::SupportType, G2::SupportType>)
-    where G1 : SupportGenerator<F, N, Id=usize>,
-          G2 : SupportGenerator<F, N, Id=usize> {
-
-        let id : usize = d.into();
+    fn map_left<F: Float, const N: usize>(
+        (d, support): (G1::Id, G1::SupportType),
+    ) -> (usize, EitherSupport<G2::SupportType, G1::SupportType>)
+    where
+        G1: SupportGenerator<N, F, Id = usize>,
+        G2: SupportGenerator<N, F, Id = usize>,
+    {
+        let id: usize = d.into();
         (id.into(), EitherSupport::Left(support))
     }
 
     /// Helper for [`all_right_data`].
     #[inline]
-    fn map_right<F : Float, const N : usize>(n0 : &usize, (d, support) : (G2::Id, G2::SupportType))
-    -> (usize, EitherSupport<G1::SupportType, G2::SupportType>)
-    where G1 : SupportGenerator<F, N, Id=usize>,
-          G2 : SupportGenerator<F, N, Id=usize> {
-
-        let id : usize = d.into();
-        ((n0+id).into(), EitherSupport::Right(support))
+    fn map_right<F: Float, const N: usize>(
+        n0: &usize,
+        (d, support): (G2::Id, G2::SupportType),
+    ) -> (usize, EitherSupport<G2::SupportType, G1::SupportType>)
+    where
+        G1: SupportGenerator<N, F, Id = usize>,
+        G2: SupportGenerator<N, F, Id = usize>,
+    {
+        let id: usize = d.into();
+        ((n0 + id).into(), EitherSupport::Right(support))
     }
 
     /// Calls [`SupportGenerator::all_data`] on the “left” support generator.
     ///
     /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`.
     #[inline]
-    pub(super) fn all_left_data<F : Float, const N : usize>(&self)
-    -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>
-    where G1 : SupportGenerator<F, N, Id=usize>,
-          G2 : SupportGenerator<F, N, Id=usize> {
+    pub(super) fn all_left_data<F: Float, const N: usize>(
+        &self,
+    ) -> MapF<G1::AllDataIter<'_>, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>
+    where
+        G1: SupportGenerator<N, F, Id = usize>,
+        G2: SupportGenerator<N, F, Id = usize>,
+    {
         self.0.all_data().mapF(Self::map_left)
     }
 
@@ -85,33 +84,38 @@
     ///
     /// Converts both the id and the [`Support`] into a form that corresponds to `BothGenerators`.
     #[inline]
-    pub(super) fn all_right_data<F : Float, const N : usize>(&self)
-    -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G1::SupportType, G2::SupportType>)>
-    where G1 : SupportGenerator<F, N, Id=usize>,
-          G2 : SupportGenerator<F, N, Id=usize> {
+    pub(super) fn all_right_data<F: Float, const N: usize>(
+        &self,
+    ) -> MapZ<G2::AllDataIter<'_>, usize, (usize, EitherSupport<G2::SupportType, G1::SupportType>)>
+    where
+        G1: SupportGenerator<N, F, Id = usize>,
+        G2: SupportGenerator<N, F, Id = usize>,
+    {
         let n0 = self.0.support_count();
         self.1.all_data().mapZ(n0, Self::map_right)
     }
 }
 
-impl<F : Float, G1, G2, const N : usize>
-SupportGenerator<F, N>
-for BothGenerators<G1, G2>
-where G1 : SupportGenerator<F, N, Id=usize>,
-      G2 : SupportGenerator<F, N, Id=usize> {
-
+impl<F: Float, G1, G2, const N: usize> SupportGenerator<N, F> for BothGenerators<G1, G2>
+where
+    G1: SupportGenerator<N, F, Id = usize>,
+    G2: SupportGenerator<N, F, Id = usize>,
+{
     type Id = usize;
-    type SupportType = EitherSupport<G1::SupportType, G2::SupportType>;
-    type AllDataIter<'a> = BothAllDataIter<'a, F, G1, G2, N> where G1 : 'a, G2 : 'a;
+    type SupportType = EitherSupport<G2::SupportType, G1::SupportType>;
+    type AllDataIter<'a>
+        = BothAllDataIter<'a, F, G1, G2, N>
+    where
+        G1: 'a,
+        G2: 'a;
 
     #[inline]
-    fn support_for(&self,  id : Self::Id)
-    -> Self::SupportType {
+    fn support_for(&self, id: Self::Id) -> Self::SupportType {
         let n0 = self.0.support_count();
         if id < n0 {
             EitherSupport::Left(self.0.support_for(id.into()))
         } else {
-            EitherSupport::Right(self.1.support_for((id-n0).into()))
+            EitherSupport::Right(self.1.support_for((id - n0).into()))
         }
     }
 
@@ -126,12 +130,13 @@
     }
 }
 
-impl<F: Float, S1, S2, const N : usize> Support<F, N> for EitherSupport<S1, S2>
-where S1 : Support<F, N>,
-      S2 : Support<F, N> {
-
+impl<F: Float, S1, S2, const N: usize> Support<N, F> for EitherSupport<S2, S1>
+where
+    S1: Support<N, F>,
+    S2: Support<N, F>,
+{
     #[inline]
-    fn support_hint(&self) -> Cube<F,N> {
+    fn support_hint(&self) -> Cube<N, F> {
         match self {
             EitherSupport::Left(ref a) => a.support_hint(),
             EitherSupport::Right(ref b) => b.support_hint(),
@@ -139,7 +144,7 @@
     }
 
     #[inline]
-    fn in_support(&self, x : &Loc<F,N>) -> bool {
+    fn in_support(&self, x: &Loc<N, F>) -> bool {
         match self {
             EitherSupport::Left(ref a) => a.in_support(x),
             EitherSupport::Right(ref b) => b.in_support(x),
@@ -147,7 +152,7 @@
     }
 
     #[inline]
-    fn bisection_hint(&self, cube : &Cube<F, N>) -> [Option<F>; N] {
+    fn bisection_hint(&self, cube: &Cube<N, F>) -> [Option<F>; N] {
         match self {
             EitherSupport::Left(ref a) => a.bisection_hint(cube),
             EitherSupport::Right(ref b) => b.bisection_hint(cube),
@@ -155,13 +160,14 @@
     }
 }
 
-impl<F : Float, A, S1, S2, const N : usize> LocalAnalysis<F, A, N> for EitherSupport<S1, S2>
-where A : Aggregator,
-      S1 : LocalAnalysis<F, A, N>,
-      S2 : LocalAnalysis<F, A, N>, {
-
+impl<F: Float, A, S1, S2, const N: usize> LocalAnalysis<F, A, N> for EitherSupport<S2, S1>
+where
+    A: Aggregator,
+    S1: LocalAnalysis<F, A, N>,
+    S2: LocalAnalysis<F, A, N>,
+{
     #[inline]
-    fn local_analysis(&self, cube : &Cube<F, N>) -> A {
+    fn local_analysis(&self, cube: &Cube<N, F>) -> A {
         match self {
             EitherSupport::Left(ref a) => a.local_analysis(cube),
             EitherSupport::Right(ref b) => b.local_analysis(cube),
@@ -169,11 +175,12 @@
     }
 }
 
-impl<F : Float, A, S1, S2> GlobalAnalysis<F, A> for EitherSupport<S1, S2>
-where A : Aggregator,
-      S1 : GlobalAnalysis<F, A>,
-      S2 : GlobalAnalysis<F, A>, {
-
+impl<F: Float, A, S1, S2> GlobalAnalysis<F, A> for EitherSupport<S2, S1>
+where
+    A: Aggregator,
+    S1: GlobalAnalysis<F, A>,
+    S2: GlobalAnalysis<F, A>,
+{
     #[inline]
     fn global_analysis(&self) -> A {
         match self {
@@ -183,17 +190,17 @@
     }
 }
 
-impl<F, S1, S2, X> Mapping<X> for EitherSupport<S1, S2>
+impl<F, S1, S2, X> Mapping<X> for EitherSupport<S2, S1>
 where
-    F : Space,
-    X : Space,
-    S1 : Mapping<X, Codomain=F>,
-    S2 : Mapping<X, Codomain=F>,
+    F: Space,
+    X: Space,
+    S1: Mapping<X, Codomain = F>,
+    S2: Mapping<X, Codomain = F>,
 {
     type Codomain = F;
 
     #[inline]
-    fn apply<I : Instance<X>>(&self, x : I) -> F {
+    fn apply<I: Instance<X>>(&self, x: I) -> F {
         match self {
             EitherSupport::Left(ref a) => a.apply(x),
             EitherSupport::Right(ref b) => b.apply(x),
@@ -201,17 +208,17 @@
     }
 }
 
-impl<X, S1, S2, O> DifferentiableImpl<X> for EitherSupport<S1, S2>
+impl<X, S1, S2, O> DifferentiableImpl<X> for EitherSupport<S2, S1>
 where
-    O : Space,
-    X : Space,
-    S1 : DifferentiableMapping<X, DerivativeDomain=O>,
-    S2 : DifferentiableMapping<X, DerivativeDomain=O>,
+    O: Space,
+    X: Space,
+    S1: DifferentiableMapping<X, DerivativeDomain = O>,
+    S2: DifferentiableMapping<X, DerivativeDomain = O>,
 {
     type Derivative = O;
 
     #[inline]
-    fn differential_impl<I : Instance<X>>(&self, x : I) -> O {
+    fn differential_impl<I: Instance<X>>(&self, x: I) -> O {
         match self {
             EitherSupport::Left(ref a) => a.differential(x),
             EitherSupport::Right(ref b) => b.differential(x),
@@ -221,44 +228,47 @@
 
 macro_rules! make_either_scalarop_rhs {
     ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
-        impl<F : Float, G1, G2>
-        std::ops::$trait_assign<F>
-        for BothGenerators<G1, G2>
-        where G1 : std::ops::$trait_assign<F> + Clone,
-              G2 : std::ops::$trait_assign<F> + Clone, {
+        impl<F: Float, G1, G2> std::ops::$trait_assign<F> for BothGenerators<G1, G2>
+        where
+            G1: std::ops::$trait_assign<F> + Clone,
+            G2: std::ops::$trait_assign<F> + Clone,
+        {
             #[inline]
-            fn $fn_assign(&mut self, t : F) {
+            fn $fn_assign(&mut self, t: F) {
                 Arc::make_mut(&mut self.0).$fn_assign(t);
                 Arc::make_mut(&mut self.1).$fn_assign(t);
             }
         }
 
-        impl<'a, F : Float, G1, G2>
-        std::ops::$trait<F>
-        for &'a BothGenerators<G1, G2>
-        where &'a G1 : std::ops::$trait<F,Output=G1>,
-              &'a G2 : std::ops::$trait<F,Output=G2> {
+        impl<'a, F: Float, G1, G2> std::ops::$trait<F> for &'a BothGenerators<G1, G2>
+        where
+            &'a G1: std::ops::$trait<F, Output = G1>,
+            &'a G2: std::ops::$trait<F, Output = G2>,
+        {
             type Output = BothGenerators<G1, G2>;
             #[inline]
-            fn $fn(self, t : F) -> BothGenerators<G1, G2> {
-                BothGenerators(Arc::new(self.0.$fn(t)),
-                               Arc::new(self.1.$fn(t)))
+            fn $fn(self, t: F) -> BothGenerators<G1, G2> {
+                BothGenerators(Arc::new(self.0.$fn(t)), Arc::new(self.1.$fn(t)))
             }
         }
-    }
+    };
 }
 
 make_either_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
 make_either_scalarop_rhs!(Div, div, DivAssign, div_assign);
 
 impl<G1, G2> std::ops::Neg for BothGenerators<G1, G2>
-where G1 : std::ops::Neg + Clone,
-      G2 : std::ops::Neg + Clone, {
+where
+    G1: std::ops::Neg + Clone,
+    G2: std::ops::Neg + Clone,
+{
     type Output = BothGenerators<G1::Output, G2::Output>;
     #[inline]
     fn neg(self) -> Self::Output {
-        BothGenerators(Arc::new(Arc::unwrap_or_clone(self.0).neg()),
-                       Arc::new(Arc::unwrap_or_clone(self.1).neg()))
+        BothGenerators(
+            Arc::new(Arc::unwrap_or_clone(self.0).neg()),
+            Arc::new(Arc::unwrap_or_clone(self.1).neg()),
+        )
     }
 }
 /*
@@ -270,4 +280,4 @@
         BothGenerators(self.0.neg(), self.1.neg())
     }
 }
-*/
\ No newline at end of file
+*/

mercurial