diff -r efa60bc4f743 -r b087e3eab191 src/seminorms.rs --- 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 : BoundedLinear, FloatType=F> -where F : Float + ToNalgebraRealField, - Domain : 'static { +pub trait DiscreteMeasureOp + : BoundedLinear, 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 where I : ExactSizeIterator + 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) -> Self::PreCodomain; } @@ -73,7 +78,7 @@ pub struct ConvolutionSupportGenerator where K : SimpleConvolutionKernel { kernel : K, - centres : DiscreteMeasure, F>, + centres : RNDM, } impl ConvolutionSupportGenerator @@ -130,9 +135,9 @@ where F : Float + ToNalgebraRealField, BT : BTImpl, K : SimpleConvolutionKernel { - /// 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, /// 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, kernel : K) -> Self { ConvolutionOp { depth : depth, @@ -157,7 +162,7 @@ } /// Returns the support generator for this convolution operator. - fn support_generator(&self, μ : DiscreteMeasure, F>) + fn support_generator(&self, μ : RNDM) -> ConvolutionSupportGenerator { // TODO: can we avoid cloning μ? @@ -173,94 +178,43 @@ } } -impl Apply, F>> +impl Mapping> for ConvolutionOp -where F : Float + ToNalgebraRealField, - BT : BTImpl, - K : SimpleConvolutionKernel, - Weighted, F> : LocalAnalysis { +where + F : Float + ToNalgebraRealField, + BT : BTImpl, + K : SimpleConvolutionKernel, + Weighted, F> : LocalAnalysis +{ - type Output = BTFN, BT, N>; + type Codomain = BTFN, BT, N>; - fn apply(&self, μ : DiscreteMeasure, F>) -> Self::Output { - let g = self.support_generator(μ); + fn apply(&self, μ : I) -> Self::Codomain + where I : Instance> { + 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, F>> +/// [`ConvolutionOp`]s as linear operators over [`DiscreteMeasure`]s. +impl Linear> +for ConvolutionOp +where + F : Float + ToNalgebraRealField, + BT : BTImpl, + K : SimpleConvolutionKernel, + Weighted, F> : LocalAnalysis +{ } + +impl +BoundedLinear, Radon, Linfinity, F> for ConvolutionOp where F : Float + ToNalgebraRealField, BT : BTImpl, K : SimpleConvolutionKernel, Weighted, F> : LocalAnalysis { - type Output = BTFN, BT, N>; - - fn apply(&self, μ : &'a DiscreteMeasure, F>) -> Self::Output { - self.apply(μ.clone()) - } -} - -/// [`ConvolutionOp`]s as linear operators over [`DiscreteMeasure`]s. -impl Linear, F>> -for ConvolutionOp -where F : Float + ToNalgebraRealField, - BT : BTImpl, - K : SimpleConvolutionKernel, - Weighted, F> : LocalAnalysis { - type Codomain = BTFN, BT, N>; -} - -impl Apply, F>> -for ConvolutionOp -where F : Float + ToNalgebraRealField, - BT : BTImpl, - K : SimpleConvolutionKernel { - - type Output = Weighted, F>; - - #[inline] - fn apply(&self, δ : DeltaMeasure, F>) -> Self::Output { - self.kernel.clone().shift(δ.x).weigh(δ.α) - } -} - -impl<'a, F, K, BT, const N : usize> Apply<&'a DeltaMeasure, F>> -for ConvolutionOp -where F : Float + ToNalgebraRealField, - BT : BTImpl, - K : SimpleConvolutionKernel { - - type Output = Weighted, F>; - - #[inline] - fn apply(&self, δ : &'a DeltaMeasure, 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 Linear, F>> -for ConvolutionOp -where F : Float + ToNalgebraRealField, - BT : BTImpl, - K : SimpleConvolutionKernel { - type Codomain = Weighted, F>; -} - -impl BoundedLinear, F>> -for ConvolutionOp -where F : Float + ToNalgebraRealField, - BT : BTImpl, - K : SimpleConvolutionKernel, - Weighted, F> : LocalAnalysis { - - 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, F>) -> Self::PreCodomain { + fn preapply(&self, μ : RNDM) -> Self::PreCodomain { BTFN::new_pre(self.support_generator(μ)) } }