StaticEuclidean Principal reference fix dev

Sun, 07 Sep 2025 10:00:14 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sun, 07 Sep 2025 10:00:14 -0500
branch
dev
changeset 186
afe04e6b4a5b
parent 185
e6829fbe2737
child 187
76c77e49581a

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

mercurial