Sun, 07 Sep 2025 10:00:14 -0500
StaticEuclidean Principal reference fix
| src/discrete_gradient.rs | file | annotate | diff | comparison | revisions | |
| src/euclidean.rs | file | annotate | diff | comparison | revisions | |
| src/linops.rs | file | annotate | diff | comparison | revisions |
--- a/src/discrete_gradient.rs Sun Sep 07 09:51:26 2025 -0500 +++ b/src/discrete_gradient.rs Sun Sep 07 10:00:14 2025 -0500 @@ -3,7 +3,7 @@ */ use crate::error::DynResult; use crate::instance::Instance; -use crate::linops::{Adjointable, BoundedLinear, Linear, Mapping, GEMV}; +use crate::linops::{Adjointable, BoundedLinear, Linear, Mapping, SimplyAdjointable, GEMV}; use crate::norms::{Norm, L2}; use crate::types::Float; use nalgebra::{DVector, Dyn, Matrix, Storage, StorageMut, U1}; @@ -207,14 +207,7 @@ fn new(dims: &'a [usize; N], d: usize) -> Self { let d_stride = dims[0..d].iter().product::<usize>(); let len = dims.iter().product::<usize>(); - Iter { - dims, - d, - d_stride, - i: [0; N], - k: 0, - len, - } + Iter { dims, d, d_stride, i: [0; N], k: 0, len } } } @@ -336,11 +329,7 @@ /// Creates a new discrete gradient operator for the vector `u`, verifying dimensions. pub fn new_for(u: &DVector<F>, h: F, dims: [usize; N], discretisation: B) -> Option<Self> { if u.len() == dims.iter().product::<usize>() { - Some(Grad { - dims, - h, - discretisation, - }) + Some(Grad { dims, h, discretisation }) } else { None } @@ -359,11 +348,7 @@ /// Creates a new discrete gradient operator for the vector `u`, verifying dimensions. pub fn new_for(u: &DVector<F>, h: F, dims: [usize; N], discretisation: B) -> Option<Self> { if u.len() == dims.iter().product::<usize>() * N { - Some(Div { - dims, - h, - discretisation, - }) + Some(Div { dims, h, discretisation }) } else { None } @@ -425,13 +410,21 @@ where Self: 'a; - /// Form the adjoint operator of `self`. fn adjoint(&self) -> Self::Adjoint<'_> { - Div { - dims: self.dims, - h: -self.h, - discretisation: self.discretisation.opposite(), - } + Div { dims: self.dims, h: -self.h, discretisation: self.discretisation.opposite() } + } +} + +impl<F, B, const N: usize> SimplyAdjointable<DVector<F>, DVector<F>> for Grad<F, B, N> +where + B: Discretisation<F>, + F: Float + nalgebra::RealField, +{ + type AdjointCodomain = DVector<F>; + type SimpleAdjoint = Div<F, B::Opposite, N>; + + fn adjoint(&self) -> Self::SimpleAdjoint { + Div { dims: self.dims, h: -self.h, discretisation: self.discretisation.opposite() } } } @@ -446,13 +439,21 @@ where Self: 'a; - /// Form the adjoint operator of `self`. fn adjoint(&self) -> Self::Adjoint<'_> { - Grad { - dims: self.dims, - h: -self.h, - discretisation: self.discretisation.opposite(), - } + Grad { dims: self.dims, h: -self.h, discretisation: self.discretisation.opposite() } + } +} + +impl<F, B, const N: usize> SimplyAdjointable<DVector<F>, DVector<F>> for Div<F, B, N> +where + B: Discretisation<F>, + F: Float + nalgebra::RealField, +{ + type AdjointCodomain = DVector<F>; + type SimpleAdjoint = Grad<F, B::Opposite, N>; + + fn adjoint(&self) -> Self::SimpleAdjoint { + Grad { dims: self.dims, h: -self.h, discretisation: self.discretisation.opposite() } } }
--- a/src/euclidean.rs Sun Sep 07 09:51:26 2025 -0500 +++ b/src/euclidean.rs Sun Sep 07 10:00:14 2025 -0500 @@ -90,5 +90,5 @@ /// Trait for [`Euclidean`] spaces with dimensions known at compile time. pub trait StaticEuclidean<F: Float = f64>: Euclidean<F> { /// Returns the origin - fn origin() -> <Self as VectorSpace>::PrincipalV; + fn origin() -> <Self as Euclidean<F>>::PrincipalE; }
--- a/src/linops.rs Sun Sep 07 09:51:26 2025 -0500 +++ b/src/linops.rs Sun Sep 07 10:00:14 2025 -0500 @@ -366,7 +366,9 @@ #[derive(Copy, Clone, Debug)] pub struct StaticEuclideanOriginGenerator; -impl<Y: StaticEuclidean> OriginGenerator<Y> for StaticEuclideanOriginGenerator { +impl<Y: StaticEuclidean<F, Field = F>, F: Float> OriginGenerator<Y> + for StaticEuclideanOriginGenerator +{ type Ref<'b> = Self where