src/seminorms.rs

branch
dev
changeset 35
b087e3eab191
parent 32
56c8adc32b09
child 54
b3312eee105c
--- a/src/seminorms.rs	Thu Aug 29 00:00:00 2024 -0500
+++ b/src/seminorms.rs	Tue Dec 31 09:25:45 2024 -0500
@@ -12,9 +12,11 @@
 use alg_tools::bisection_tree::*;
 use alg_tools::mapping::RealMapping;
 use alg_tools::iter::{Mappable, FilterMapX};
-use alg_tools::linops::{Apply, Linear, BoundedLinear};
+use alg_tools::linops::{Mapping, Linear, BoundedLinear};
+use alg_tools::instance::Instance;
 use alg_tools::nalgebra_support::ToNalgebraRealField;
-use crate::measures::{DiscreteMeasure, DeltaMeasure, SpikeIter};
+use alg_tools::norms::Linfinity;
+use crate::measures::{DiscreteMeasure, DeltaMeasure, SpikeIter, Radon, RNDM};
 use nalgebra::DMatrix;
 use std::marker::PhantomData;
 use itertools::Itertools;
@@ -22,9 +24,12 @@
 /// Abstraction for operators $𝒟 ∈ 𝕃(𝒵(Ω); C_c(Ω))$.
 ///
 /// Here $𝒵(Ω) ⊂ ℳ(Ω)$ is the space of sums of delta measures, presented by [`DiscreteMeasure`].
-pub trait DiscreteMeasureOp<Domain, F> : BoundedLinear<DiscreteMeasure<Domain, F>, FloatType=F>
-where F : Float + ToNalgebraRealField,
-      Domain : 'static {
+pub trait DiscreteMeasureOp<Domain, F>
+    : BoundedLinear<DiscreteMeasure<Domain, F>, Radon, Linfinity, F>
+where
+    F : Float + ToNalgebraRealField,
+    Domain : 'static + Clone + PartialEq,
+{
     /// The output type of [`Self::preapply`].
     type PreCodomain;
 
@@ -38,7 +43,7 @@
     fn findim_matrix<'a, I>(&self, points : I) -> DMatrix<F::MixedType>
     where I : ExactSizeIterator<Item=&'a Domain> + Clone;
 
-    /// [`Apply::apply`] that typically returns an uninitialised [`PreBTFN`]
+    /// [`Mapping`] that typically returns an uninitialised [`PreBTFN`]
     /// instead of a full [`BTFN`].
     fn preapply(&self, μ : DiscreteMeasure<Domain, F>) -> Self::PreCodomain;
 }
@@ -73,7 +78,7 @@
 pub struct ConvolutionSupportGenerator<F : Float, K, const N : usize>
 where K : SimpleConvolutionKernel<F, N> {
     kernel : K,
-    centres : DiscreteMeasure<Loc<F, N>, F>,
+    centres : RNDM<F, N>,
 }
 
 impl<F : Float, K, const N : usize> ConvolutionSupportGenerator<F, K, N>
@@ -130,9 +135,9 @@
 where F : Float + ToNalgebraRealField,
       BT : BTImpl<F, N, Data=usize>,
       K : SimpleConvolutionKernel<F, N> {
-    /// Depth of the [`BT`] bisection tree for the outputs [`Apply::apply`].
+    /// Depth of the [`BT`] bisection tree for the outputs [`Mapping::apply`].
     depth : BT::Depth,
-    /// Domain of the [`BT`] bisection tree for the outputs [`Apply::apply`].
+    /// Domain of the [`BT`] bisection tree for the outputs [`Mapping::apply`].
     domain : Cube<F, N>,
     /// The convolution kernel
     kernel : K,
@@ -146,7 +151,7 @@
 
     /// Creates a new convolution operator $𝒟$ with `kernel` on `domain`.
     ///
-    /// The output of [`Apply::apply`] is a [`BT`] of given `depth`.
+    /// The output of [`Mapping::apply`] is a [`BT`] of given `depth`.
     pub fn new(depth : BT::Depth, domain : Cube<F, N>, kernel : K) -> Self {
         ConvolutionOp {
             depth : depth,
@@ -157,7 +162,7 @@
     }
 
     /// Returns the support generator for this convolution operator.
-    fn support_generator(&self, μ : DiscreteMeasure<Loc<F, N>, F>)
+    fn support_generator(&self, μ : RNDM<F, N>)
     -> ConvolutionSupportGenerator<F, K, N> {
 
         // TODO: can we avoid cloning μ?
@@ -173,94 +178,43 @@
     }
 }
 
-impl<F, K, BT, const N : usize> Apply<DiscreteMeasure<Loc<F, N>, F>>
+impl<F, K, BT, const N : usize> Mapping<RNDM<F, N>>
 for ConvolutionOp<F, K, BT, N>
-where F : Float + ToNalgebraRealField,
-      BT : BTImpl<F, N, Data=usize>,
-      K : SimpleConvolutionKernel<F, N>,
-      Weighted<Shift<K, F, N>, F> : LocalAnalysis<F, BT::Agg, N> {
+where
+    F : Float + ToNalgebraRealField,
+    BT : BTImpl<F, N, Data=usize>,
+    K : SimpleConvolutionKernel<F, N>,
+    Weighted<Shift<K, F, N>, F> : LocalAnalysis<F, BT::Agg, N>
+{
 
-    type Output = BTFN<F, ConvolutionSupportGenerator<F, K, N>, BT, N>;
+    type Codomain = BTFN<F, ConvolutionSupportGenerator<F, K, N>, BT, N>;
 
-    fn apply(&self, μ : DiscreteMeasure<Loc<F, N>, F>) -> Self::Output {
-        let g = self.support_generator(μ);
+    fn apply<I>(&self, μ : I) -> Self::Codomain
+    where I : Instance<RNDM<F, N>> {
+        let g = self.support_generator(μ.own());
         BTFN::construct(self.domain.clone(), self.depth, g)
     }
 }
 
-impl<'a, F, K, BT, const N : usize> Apply<&'a DiscreteMeasure<Loc<F, N>, F>>
+/// [`ConvolutionOp`]s as linear operators over [`DiscreteMeasure`]s.
+impl<F, K, BT, const N : usize> Linear<RNDM<F, N>>
+for ConvolutionOp<F, K, BT, N>
+where
+    F : Float + ToNalgebraRealField,
+    BT : BTImpl<F, N, Data=usize>,
+    K : SimpleConvolutionKernel<F, N>,
+    Weighted<Shift<K, F, N>, F> : LocalAnalysis<F, BT::Agg, N>
+{ }
+
+impl<F, K, BT, const N : usize>
+BoundedLinear<RNDM<F, N>, Radon, Linfinity, F>
 for ConvolutionOp<F, K, BT, N>
 where F : Float + ToNalgebraRealField,
       BT : BTImpl<F, N, Data=usize>,
       K : SimpleConvolutionKernel<F, N>,
       Weighted<Shift<K, F, N>, F> : LocalAnalysis<F, BT::Agg, N> {
 
-    type Output = BTFN<F, ConvolutionSupportGenerator<F, K, N>, BT, N>;
-
-    fn apply(&self, μ : &'a DiscreteMeasure<Loc<F, N>, F>) -> Self::Output {
-        self.apply(μ.clone())
-    }
-}
-
-/// [`ConvolutionOp`]s as linear operators over [`DiscreteMeasure`]s.
-impl<F, K, BT, const N : usize> Linear<DiscreteMeasure<Loc<F, N>, F>>
-for ConvolutionOp<F, K, BT, N>
-where F : Float + ToNalgebraRealField,
-      BT : BTImpl<F, N, Data=usize>,
-      K : SimpleConvolutionKernel<F, N>,
-      Weighted<Shift<K, F, N>, F> : LocalAnalysis<F, BT::Agg, N> {
-    type Codomain = BTFN<F, ConvolutionSupportGenerator<F, K, N>, BT, N>;
-}
-
-impl<F, K, BT, const N : usize> Apply<DeltaMeasure<Loc<F, N>, F>>
-for ConvolutionOp<F, K, BT, N>
-where F : Float + ToNalgebraRealField,
-      BT : BTImpl<F, N, Data=usize>,
-      K : SimpleConvolutionKernel<F, N> {
-
-    type Output = Weighted<Shift<K, F, N>, F>;
-
-    #[inline]
-    fn apply(&self, δ : DeltaMeasure<Loc<F, N>, F>) -> Self::Output {
-        self.kernel.clone().shift(δ.x).weigh(δ.α)
-    }
-}
-
-impl<'a, F, K, BT, const N : usize> Apply<&'a DeltaMeasure<Loc<F, N>, F>>
-for ConvolutionOp<F, K, BT, N>
-where F : Float + ToNalgebraRealField,
-      BT : BTImpl<F, N, Data=usize>,
-      K : SimpleConvolutionKernel<F, N> {
-
-    type Output = Weighted<Shift<K, F, N>, F>;
-
-    #[inline]
-    fn apply(&self, δ : &'a DeltaMeasure<Loc<F, N>, F>) -> Self::Output {
-        self.kernel.clone().shift(δ.x).weigh(δ.α)
-    }
-}
-
-/// [`ConvolutionOp`]s as linear operators over [`DeltaMeasure`]s.
-///
-/// The codomain is different from the implementation for [`DiscreteMeasure`].
-impl<F, K, BT, const N : usize> Linear<DeltaMeasure<Loc<F, N>, F>>
-for ConvolutionOp<F, K, BT, N>
-where F : Float + ToNalgebraRealField,
-      BT : BTImpl<F, N, Data=usize>,
-      K : SimpleConvolutionKernel<F, N> {
-    type Codomain = Weighted<Shift<K, F, N>, F>;
-}
-
-impl<F, K, BT, const N : usize> BoundedLinear<DiscreteMeasure<Loc<F, N>, F>>
-for ConvolutionOp<F, K, BT, N>
-where F : Float + ToNalgebraRealField,
-      BT : BTImpl<F, N, Data=usize>,
-      K : SimpleConvolutionKernel<F, N>,
-      Weighted<Shift<K, F, N>, F> : LocalAnalysis<F, BT::Agg, N> {
-
-    type FloatType = F;
-
-    fn opnorm_bound(&self) -> F {
+    fn opnorm_bound(&self, _ : Radon, _ : Linfinity) -> F {
         // With μ = ∑_i α_i δ_{x_i}, we have
         // |𝒟μ|_∞
         // = sup_z |∑_i α_i φ(z - x_i)|
@@ -292,10 +246,10 @@
         DMatrix::from_iterator(n, n, values)
     }
 
-    /// A version of [`Apply::apply`] that does not instantiate the [`BTFN`] codomain with
+    /// A version of [`Mapping::apply`] that does not instantiate the [`BTFN`] codomain with
     /// a bisection tree, instead returning a [`PreBTFN`]. This can improve performance when
     /// the output is to be added as the right-hand-side operand to a proper BTFN.
-    fn preapply(&self, μ : DiscreteMeasure<Loc<F, N>, F>) -> Self::PreCodomain {
+    fn preapply(&self, μ : RNDM<F, N>) -> Self::PreCodomain {
         BTFN::new_pre(self.support_generator(μ))
     }
 }

mercurial