src/bisection_tree/support.rs

branch
dev
changeset 124
6aa955ad8122
parent 97
4e80fb049dca
child 150
c4e394a9c84c
--- a/src/bisection_tree/support.rs	Thu May 01 08:40:33 2025 -0500
+++ b/src/bisection_tree/support.rs	Thu May 01 13:06:58 2025 -0500
@@ -16,14 +16,14 @@
 /// A trait for working with the supports of [`Mapping`]s.
 ///
 /// `Mapping` is not a super-trait to allow more general use.
-pub trait Support<F: Num, const N: usize>: Sized + Sync + Send + 'static {
+pub trait Support<const N: usize, F: Num>: Sized + Sync + Send + 'static {
     /// Return a cube containing the support of the function represented by `self`.
     ///
     /// The hint may be larger than the actual support, but must contain it.
-    fn support_hint(&self) -> Cube<F, N>;
+    fn support_hint(&self) -> Cube<N, F>;
 
     /// Indicate whether `x` is in the support of the function represented by `self`.
-    fn in_support(&self, x: &Loc<F, N>) -> bool;
+    fn in_support(&self, x: &Loc<N, F>) -> bool;
 
     // Indicate whether `cube` is fully in the support of the function represented by `self`.
     //fn fully_in_support(&self, cube : &Cube<F,N>) -> bool;
@@ -39,13 +39,13 @@
     /// The default implementation returns `[None; N]`.
     #[inline]
     #[allow(unused_variables)]
-    fn bisection_hint(&self, cube: &Cube<F, N>) -> [Option<F>; N] {
+    fn bisection_hint(&self, cube: &Cube<N, F>) -> [Option<F>; N] {
         [None; N]
     }
 
     /// Translate `self` by `x`.
     #[inline]
-    fn shift(self, x: Loc<F, N>) -> Shift<Self, F, N> {
+    fn shift(self, x: Loc<N, F>) -> Shift<Self, N, F> {
         Shift {
             shift: x,
             base_fn: self,
@@ -55,46 +55,46 @@
 
 /// Shift of [`Support`] and [`Mapping`]; output of [`Support::shift`].
 #[derive(Copy, Clone, Debug, Serialize)] // Serialize! but not implemented by Loc.
-pub struct Shift<T, F, const N: usize> {
-    shift: Loc<F, N>,
+pub struct Shift<T, const N: usize, F = f64> {
+    shift: Loc<N, F>,
     base_fn: T,
 }
 
-impl<'a, T, V: Space, F: Float, const N: usize> Mapping<Loc<F, N>> for Shift<T, F, N>
+impl<'a, T, V: Space, F: Float, const N: usize> Mapping<Loc<N, F>> for Shift<T, N, F>
 where
-    T: Mapping<Loc<F, N>, Codomain = V>,
+    T: Mapping<Loc<N, F>, Codomain = V>,
 {
     type Codomain = V;
 
     #[inline]
-    fn apply<I: Instance<Loc<F, N>>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain {
         self.base_fn.apply(x.own() - &self.shift)
     }
 }
 
-impl<'a, T, V: Space, F: Float, const N: usize> DifferentiableImpl<Loc<F, N>> for Shift<T, F, N>
+impl<'a, T, V: Space, F: Float, const N: usize> DifferentiableImpl<Loc<N, F>> for Shift<T, N, F>
 where
-    T: DifferentiableMapping<Loc<F, N>, DerivativeDomain = V>,
+    T: DifferentiableMapping<Loc<N, F>, DerivativeDomain = V>,
 {
     type Derivative = V;
 
     #[inline]
-    fn differential_impl<I: Instance<Loc<F, N>>>(&self, x: I) -> Self::Derivative {
+    fn differential_impl<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Derivative {
         self.base_fn.differential(x.own() - &self.shift)
     }
 }
 
-impl<'a, T, F: Float, const N: usize> Support<F, N> for Shift<T, F, N>
+impl<'a, T, F: Float, const N: usize> Support<N, F> for Shift<T, N, F>
 where
-    T: Support<F, N>,
+    T: Support<N, F>,
 {
     #[inline]
-    fn support_hint(&self) -> Cube<F, N> {
+    fn support_hint(&self) -> Cube<N, F> {
         self.base_fn.support_hint().shift(&self.shift)
     }
 
     #[inline]
-    fn in_support(&self, x: &Loc<F, N>) -> bool {
+    fn in_support(&self, x: &Loc<N, F>) -> bool {
         self.base_fn.in_support(&(x - &self.shift))
     }
 
@@ -104,13 +104,13 @@
     // }
 
     #[inline]
-    fn bisection_hint(&self, cube: &Cube<F, N>) -> [Option<F>; N] {
+    fn bisection_hint(&self, cube: &Cube<N, F>) -> [Option<F>; N] {
         let base_hint = self.base_fn.bisection_hint(cube);
         map2(base_hint, &self.shift, |h, s| h.map(|z| z + *s))
     }
 }
 
-impl<'a, T, F: Float, const N: usize> GlobalAnalysis<F, Bounds<F>> for Shift<T, F, N>
+impl<'a, T, F: Float, const N: usize> GlobalAnalysis<F, Bounds<F>> for Shift<T, N, F>
 where
     T: LocalAnalysis<F, Bounds<F>, N>,
 {
@@ -120,20 +120,20 @@
     }
 }
 
-impl<'a, T, F: Float, const N: usize> LocalAnalysis<F, Bounds<F>, N> for Shift<T, F, N>
+impl<'a, T, F: Float, const N: usize> LocalAnalysis<F, Bounds<F>, N> for Shift<T, N, F>
 where
     T: LocalAnalysis<F, Bounds<F>, N>,
 {
     #[inline]
-    fn local_analysis(&self, cube: &Cube<F, N>) -> Bounds<F> {
+    fn local_analysis(&self, cube: &Cube<N, F>) -> Bounds<F> {
         self.base_fn.local_analysis(&cube.shift(&(-self.shift)))
     }
 }
 
 macro_rules! impl_shift_norm {
     ($($norm:ident)*) => { $(
-        impl<'a, T, F : Float, const N : usize> Norm<F, $norm> for Shift<T,F,N>
-        where T : Norm<F, $norm> {
+        impl<'a, T, F : Float, const N : usize> Norm<$norm, F> for Shift<T, N, F>
+        where T : Norm<$norm, F> {
             #[inline]
             fn norm(&self, n : $norm) -> F {
                 self.base_fn.norm(n)
@@ -144,18 +144,18 @@
 
 impl_shift_norm!(L1 L2 Linfinity);
 
-impl<'a, T, F: Float, C, const N: usize> Support<F, N> for Weighted<T, C>
+impl<'a, T, F: Float, C, const N: usize> Support<N, F> for Weighted<T, C>
 where
-    T: Support<F, N>,
+    T: Support<N, F>,
     C: Constant<Type = F>,
 {
     #[inline]
-    fn support_hint(&self) -> Cube<F, N> {
+    fn support_hint(&self) -> Cube<N, F> {
         self.base_fn.support_hint()
     }
 
     #[inline]
-    fn in_support(&self, x: &Loc<F, N>) -> bool {
+    fn in_support(&self, x: &Loc<N, F>) -> bool {
         self.base_fn.in_support(x)
     }
 
@@ -164,7 +164,7 @@
     // }
 
     #[inline]
-    fn bisection_hint(&self, cube: &Cube<F, N>) -> [Option<F>; N] {
+    fn bisection_hint(&self, cube: &Cube<N, F>) -> [Option<F>; N] {
         self.base_fn.bisection_hint(cube)
     }
 }
@@ -191,7 +191,7 @@
     C: Constant<Type = F>,
 {
     #[inline]
-    fn local_analysis(&self, cube: &Cube<F, N>) -> Bounds<F> {
+    fn local_analysis(&self, cube: &Cube<N, F>) -> Bounds<F> {
         let Bounds(lower, upper) = self.base_fn.local_analysis(cube);
         debug_assert!(lower <= upper);
         match self.weight.value() {
@@ -240,8 +240,8 @@
 
 macro_rules! impl_weighted_norm {
     ($($norm:ident)*) => { $(
-        impl<'a, T, F : Float> Norm<F, $norm> for Weighted<T,F>
-        where T : Norm<F, $norm> {
+        impl<'a, T, F : Float> Norm<$norm, F> for Weighted<T,F>
+        where T : Norm<$norm, F> {
             #[inline]
             fn norm(&self, n : $norm) -> F {
                 self.base_fn.norm(n) * self.weight.abs()
@@ -261,14 +261,14 @@
     pub T,
 );
 
-impl<'a, T, F: Float, const N: usize> Mapping<Loc<F, N>> for Normalised<T>
+impl<'a, T, F: Float, const N: usize> Mapping<Loc<N, F>> for Normalised<T>
 where
-    T: Norm<F, L1> + Mapping<Loc<F, N>, Codomain = F>,
+    T: Norm<L1, F> + Mapping<Loc<N, F>, Codomain = F>,
 {
     type Codomain = F;
 
     #[inline]
-    fn apply<I: Instance<Loc<F, N>>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<Loc<N, F>>>(&self, x: I) -> Self::Codomain {
         let w = self.0.norm(L1);
         if w == F::ZERO {
             F::ZERO
@@ -278,17 +278,17 @@
     }
 }
 
-impl<'a, T, F: Float, const N: usize> Support<F, N> for Normalised<T>
+impl<'a, T, F: Float, const N: usize> Support<N, F> for Normalised<T>
 where
-    T: Norm<F, L1> + Support<F, N>,
+    T: Norm<L1, F> + Support<N, F>,
 {
     #[inline]
-    fn support_hint(&self) -> Cube<F, N> {
+    fn support_hint(&self) -> Cube<N, F> {
         self.0.support_hint()
     }
 
     #[inline]
-    fn in_support(&self, x: &Loc<F, N>) -> bool {
+    fn in_support(&self, x: &Loc<N, F>) -> bool {
         self.0.in_support(x)
     }
 
@@ -297,14 +297,14 @@
     // }
 
     #[inline]
-    fn bisection_hint(&self, cube: &Cube<F, N>) -> [Option<F>; N] {
+    fn bisection_hint(&self, cube: &Cube<N, F>) -> [Option<F>; N] {
         self.0.bisection_hint(cube)
     }
 }
 
 impl<'a, T, F: Float> GlobalAnalysis<F, Bounds<F>> for Normalised<T>
 where
-    T: Norm<F, L1> + GlobalAnalysis<F, Bounds<F>>,
+    T: Norm<L1, F> + GlobalAnalysis<F, Bounds<F>>,
 {
     #[inline]
     fn global_analysis(&self) -> Bounds<F> {
@@ -318,10 +318,10 @@
 
 impl<'a, T, F: Float, const N: usize> LocalAnalysis<F, Bounds<F>, N> for Normalised<T>
 where
-    T: Norm<F, L1> + LocalAnalysis<F, Bounds<F>, N>,
+    T: Norm<L1, F> + LocalAnalysis<F, Bounds<F>, N>,
 {
     #[inline]
-    fn local_analysis(&self, cube: &Cube<F, N>) -> Bounds<F> {
+    fn local_analysis(&self, cube: &Cube<N, F>) -> Bounds<F> {
         let Bounds(lower, upper) = self.0.local_analysis(cube);
         debug_assert!(lower <= upper);
         let w = self.0.norm(L1);
@@ -330,9 +330,9 @@
     }
 }
 
-impl<'a, T, F: Float> Norm<F, L1> for Normalised<T>
+impl<'a, T, F: Float> Norm<L1, F> for Normalised<T>
 where
-    T: Norm<F, L1>,
+    T: Norm<L1, F>,
 {
     #[inline]
     fn norm(&self, _: L1) -> F {
@@ -347,8 +347,8 @@
 
 macro_rules! impl_normalised_norm {
     ($($norm:ident)*) => { $(
-        impl<'a, T, F : Float> Norm<F, $norm> for Normalised<T>
-        where T : Norm<F, $norm> + Norm<F, L1> {
+        impl<'a, T, F : Float> Norm<$norm, F> for Normalised<T>
+        where T : Norm<$norm, F> + Norm<L1, F> {
             #[inline]
             fn norm(&self, n : $norm) -> F {
                 let w = self.0.norm(L1);
@@ -361,26 +361,26 @@
 impl_normalised_norm!(L2 Linfinity);
 
 /*
-impl<F : Num, S : Support<F, N>, const N : usize> LocalAnalysis<F, NullAggregator, N> for S {
-    fn local_analysis(&self, _cube : &Cube<F, N>) -> NullAggregator { NullAggregator }
+impl<F : Num, S : Support< N, F>, const N : usize> LocalAnalysis<F, NullAggregator, N> for S {
+    fn local_analysis(&self, _cube : &Cube<N, F>) -> NullAggregator { NullAggregator }
 }
 
 impl<F : Float, S : Bounded<F>, const N : usize> LocalAnalysis<F, Bounds<F>, N> for S {
     #[inline]
-    fn local_analysis(&self, cube : &Cube<F, N>) -> Bounds<F> {
+    fn local_analysis(&self, cube : &Cube<N, F>) -> Bounds<F> {
         self.bounds(cube)
     }
 }*/
 
 /// Generator of [`Support`]-implementing component functions based on low storage requirement
 /// [ids][`Self::Id`].
-pub trait SupportGenerator<F: Float, const N: usize>:
+pub trait SupportGenerator<const N: usize, F: Float = f64>:
     MulAssign<F> + DivAssign<F> + Neg<Output = Self> + Clone + Sync + Send + 'static
 {
     /// The identification type
     type Id: 'static + Copy;
     /// The type of the [`Support`] (often also a [`Mapping`]).
-    type SupportType: 'static + Support<F, N>;
+    type SupportType: 'static + Support<N, F>;
     /// An iterator over all the [`Support`]s of the generator.
     type AllDataIter<'a>: Iterator<Item = (Self::Id, Self::SupportType)>
     where

mercurial