Basic arithmetric opt-in hack attempt: not allowed by Rust. draft dev

Mon, 23 Dec 2024 23:27:45 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 23 Dec 2024 23:27:45 -0500
branch
dev
changeset 80
f802ddbabcfc
parent 68
c5f70e767511

Basic arithmetric opt-in hack attempt: not allowed by Rust.

src/bisection_tree/btfn.rs file | annotate | diff | comparison | revisions
src/bisection_tree/either.rs file | annotate | diff | comparison | revisions
src/bisection_tree/support.rs file | annotate | diff | comparison | revisions
src/convex.rs file | annotate | diff | comparison | revisions
src/discrete_gradient.rs file | annotate | diff | comparison | revisions
src/linops.rs file | annotate | diff | comparison | revisions
src/loc.rs file | annotate | diff | comparison | revisions
src/mapping.rs file | annotate | diff | comparison | revisions
src/nalgebra_support.rs file | annotate | diff | comparison | revisions
src/norms.rs file | annotate | diff | comparison | revisions
src/operator_arithmetic.rs file | annotate | diff | comparison | revisions
--- a/src/bisection_tree/btfn.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/bisection_tree/btfn.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -6,7 +6,7 @@
 use crate::types::Float;
 use crate::mapping::{
     Instance, Mapping, DifferentiableImpl, DifferentiableMapping, Space,
-    BasicDecomposition,
+    BasicDecomposition, ArithmeticFalse,
 };
 //use crate::linops::{Apply, Linear};
 use crate::sets::Set;
@@ -415,6 +415,7 @@
 {
 
     type Codomain = V;
+    type ArithmeticOptIn = ArithmeticFalse;
 
     fn apply<I : Instance<Loc<F,N>>>(&self, x : I) -> Self::Codomain {
         let xc = x.cow();
--- a/src/bisection_tree/either.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/bisection_tree/either.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -9,6 +9,7 @@
     DifferentiableImpl,
     DifferentiableMapping,
     Space,
+    ArithmeticTrue,
 };
 use crate::iter::{Mappable, MapF, MapZ};
 use crate::sets::Cube;
@@ -191,6 +192,7 @@
     S2 : Mapping<X, Codomain=F>,
 {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<X>>(&self, x : I) -> F {
--- a/src/bisection_tree/support.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/bisection_tree/support.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -7,7 +7,8 @@
 use crate::types::{Float, Num};
 use crate::maputil::map2;
 use crate::mapping::{
-    Instance, Mapping, DifferentiableImpl, DifferentiableMapping, Space
+    Instance, Mapping, DifferentiableImpl, DifferentiableMapping, Space,
+    ArithmeticTrue
 };
 use crate::sets::Cube;
 use crate::loc::Loc;
@@ -112,6 +113,7 @@
 impl<'a, T, V : Space, F : Float, const N : usize> Mapping<Loc<F, N>> for Shift<T,F,N>
 where T : Mapping<Loc<F, N>, Codomain=V> {
     type Codomain = V;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
@@ -295,6 +297,7 @@
 impl<'a, T, F : Float, const N : usize> Mapping<Loc<F, N>> for Normalised<T>
 where T : Norm<F, L1> + Mapping<Loc<F,N>, Codomain=F> {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
--- a/src/convex.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/convex.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -4,9 +4,9 @@
 
 use std::marker::PhantomData;
 use crate::types::*;
-use crate::mapping::{Mapping, Space};
+use crate::mapping::{Mapping, Space, ArithmeticTrue};
 use crate::linops::IdOp;
-use crate::instance::{Instance, InstanceMut, DecompositionMut};
+use crate::instance::{Instance, InstanceMut, DecompositionMut,};
 use crate::norms::*;
 
 /// Trait for convex mappings. Has no features, just serves as a constraint
@@ -85,6 +85,7 @@
     E : NormExponent,
 {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<Domain>>(&self, d : I) -> F {
         if d.eval(|x| x.norm(self.0.exponent)) <= F::ONE {
@@ -118,6 +119,53 @@
     }
 }
 
+impl<Domain, E, F> Prox<Domain> for NormConjugate<F, E>
+where
+    Domain : Space + Norm<F, E>,
+    E : NormExponent,
+    F : Float,
+    NormProjection<F, E> : Mapping<Domain, Codomain=Domain>,
+{
+    type Prox<'a> = NormProjection<F, E> where Self : 'a;
+
+    #[inline]
+    fn prox_mapping(&self, τ : Self::Codomain) -> Self::Prox<'_> {
+        NormProjection{ α : τ, exponent : self.0.exponent }
+    }
+}
+
+pub struct NormProjection<F : Float, E : NormExponent> {
+    α : F,
+    exponent : E,
+}
+
+/*
+impl<F, Domain> Mapping<Domain> for NormProjection<F, L2>
+where
+    Domain : Space + Euclidean<F> + std::ops::MulAssign<F>,
+    F : Float,
+{
+    type Codomain = Domain;
+
+    fn apply<I : Instance<Domain>>(&self, d : I) -> Domain {
+        d.own().proj_ball2(self.α)
+    }
+}
+*/
+
+impl<F, E, Domain> Mapping<Domain> for NormProjection<F, E>
+where
+    Domain : Space + Projection<F, E> + std::ops::MulAssign<F>,
+    F : Float,
+    E : NormExponent,
+{
+    type Codomain = Domain;
+    type ArithmeticOptIn = ArithmeticTrue;
+
+    fn apply<I : Instance<Domain>>(&self, d : I) -> Domain {
+        d.own().proj_ball(self.α, self.exponent)
+    }
+}
 
 /// The zero mapping
 pub struct Zero<Domain : Space, F : Num>(PhantomData<(Domain, F)>);
@@ -130,6 +178,7 @@
 
 impl<Domain : Space, F : Num> Mapping<Domain> for Zero<Domain, F> {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     /// Compute the value of `self` at `x`.
     fn apply<I : Instance<Domain>>(&self, _x : I) -> Self::Codomain {
@@ -183,6 +232,7 @@
 
 impl<Domain : Normed<F>, F : Float> Mapping<Domain> for ZeroIndicator<Domain, F> {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     /// Compute the value of `self` at `x`.
     fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain {
--- a/src/discrete_gradient.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/discrete_gradient.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -7,6 +7,7 @@
 };
 use crate::types::Float;
 use crate::instance::Instance;
+use crate::mapping::ArithmeticTrue;
 use crate::linops::{Mapping, Linear, BoundedLinear, Adjointable, GEMV};
 use crate::norms::{Norm, L2};
 
@@ -258,6 +259,8 @@
     F : Float + nalgebra::RealField,
 {
     type Codomain = DVector<F>;
+    type ArithmeticOptIn = ArithmeticTrue;
+
     fn apply<I : Instance<DVector<F>>>(&self, i : I) -> DVector<F> {
         let mut y = DVector::zeros(N * self.len());
         self.apply_add(&mut y, i);
@@ -302,6 +305,8 @@
     F : Float + nalgebra::RealField,
 {
     type Codomain = DVector<F>;
+    type ArithmeticOptIn = ArithmeticTrue;
+
     fn apply<I : Instance<DVector<F>>>(&self, i : I) -> DVector<F> {
         let mut y = DVector::zeros(self.len());
         self.apply_add(&mut y, i);
--- a/src/linops.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/linops.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -6,7 +6,7 @@
 use std::marker::PhantomData;
 use serde::Serialize;
 use crate::types::*;
-pub use crate::mapping::{Mapping, Space, Composition};
+pub use crate::mapping::{Mapping, Space, Composition, ArithmeticTrue};
 use crate::direct_product::Pair;
 use crate::instance::Instance;
 use crate::norms::{NormExponent, PairNorm, L1, L2, Linfinity, Norm};
@@ -137,6 +137,7 @@
 
 impl<X : Clone + Space> Mapping<X> for IdOp<X> {
     type Codomain = X;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<X>>(&self, x : I) -> X {
         x.own()
@@ -204,6 +205,7 @@
 
 impl<'a, F : Num, X : Space, XD, Y : AXPY<F> + Clone> Mapping<X> for ZeroOp<'a, X, XD, Y, F> {
     type Codomain = Y;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<X>>(&self, _x : I) -> Y {
         self.zero.clone()
@@ -335,6 +337,7 @@
 
 {
     type Codomain = <S::Codomain as Add<T::Codomain>>::Output;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<Pair<A, B>>>(&self, x : I) -> Self::Codomain {
         let Pair(a, b) = x.decompose();
@@ -392,6 +395,7 @@
     T : Mapping<A>,
 {
     type Codomain = Pair<S::Codomain, T::Codomain>;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<A>>(&self, a : I) -> Self::Codomain {
         Pair(self.0.apply(a.ref_instance()), self.1.apply(a))
@@ -527,6 +531,7 @@
     T : Mapping<B>,
 {
     type Codomain = Pair<S::Codomain, T::Codomain>;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<Pair<A, B>>>(&self, x : I) -> Self::Codomain {
         let Pair(a, b) = x.decompose();
--- a/src/loc.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/loc.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -12,7 +12,7 @@
 use crate::norms::*;
 use crate::linops::{AXPY, Mapping, Linear};
 use crate::instance::{Instance, BasicDecomposition};
-use crate::mapping::Space;
+use crate::mapping::{Space, ArithmeticFalse};
 use serde::ser::{Serialize, Serializer, SerializeSeq};
 
 
@@ -697,6 +697,7 @@
 
 impl<F : Float, const N : usize> Mapping<Loc<F, N>> for Loc<F, N> {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticFalse;
 
     fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
         x.eval(|x̃| self.dot(x̃))
--- a/src/mapping.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/mapping.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -9,11 +9,20 @@
 pub use crate::instance::{Instance, Decomposition, BasicDecomposition, Space};
 use crate::norms::{Norm, NormExponent};
 
+pub trait ArithmeticOptIn {}
+
+pub struct ArithmeticTrue;
+pub struct ArithmeticFalse;
+
+impl ArithmeticOptIn for ArithmeticTrue {}
+impl ArithmeticOptIn for ArithmeticFalse {}
+
 /// A mapping from `Domain` to `Codomain`.
 ///
 /// This is automatically implemented when the relevant [`Apply`] are implemented.
 pub trait Mapping<Domain : Space> {
     type Codomain : Space;
+    type ArithmeticOptIn : ArithmeticOptIn;
 
     /// Compute the value of `self` at `x`.
     fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain;
@@ -154,6 +163,7 @@
     M::Codomain : std::iter::Sum + Clone
 {
     type Codomain = M::Codomain;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain {
         let xr = x.ref_instance();
@@ -193,6 +203,7 @@
     G : Clone + DifferentiableMapping<X>
 {
     type Codomain = G::DerivativeDomain;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain {
@@ -212,6 +223,7 @@
     G: Mapping<X, Codomain=Loc<F, 1>>
 {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain {
@@ -244,6 +256,7 @@
     G : Mapping<X, Codomain=Loc<F, N>> + Clone,
 {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain {
@@ -290,6 +303,7 @@
     S : Mapping<T::Codomain>
 {
     type Codomain = S::Codomain;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain {
--- a/src/nalgebra_support.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/nalgebra_support.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -23,7 +23,7 @@
 use num_traits::identities::{Zero, One};
 use crate::linops::*;
 use crate::euclidean::*;
-use crate::mapping::{Space, BasicDecomposition};
+use crate::mapping::{Space, BasicDecomposition, ArithmeticFalse};
 use crate::types::Float;
 use crate::norms::*;
 use crate::instance::Instance;
@@ -45,6 +45,7 @@
         DefaultAllocator : Allocator<N,M>,
         DefaultAllocator : Allocator<M,N> {
     type Codomain = OMatrix<E,N,K>;
+    type ArithmeticOptIn = ArithmeticFalse;
 
     #[inline]
     fn apply<I : Instance<Matrix<E,M,K,SV>>>(
--- a/src/norms.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/norms.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -6,7 +6,7 @@
 use std::marker::PhantomData;
 use crate::types::*;
 use crate::euclidean::*;
-use crate::mapping::{Mapping, Space, Instance};
+use crate::mapping::{Mapping, Space, Instance, ArithmeticTrue};
 
 //
 // Abstract norms
@@ -195,6 +195,7 @@
     Domain : Space + Norm<F, E>,
 {
     type Codomain = F;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<Domain>>(&self, x : I) -> F {
--- a/src/operator_arithmetic.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/operator_arithmetic.rs	Mon Dec 23 23:27:45 2024 -0500
@@ -5,7 +5,7 @@
 use serde::Serialize;
 use crate::types::*;
 use crate::instance::{Space, Instance};
-use crate::mapping::{Mapping, DifferentiableImpl, DifferentiableMapping};
+use crate::mapping::{Mapping, ArithmeticTrue, DifferentiableImpl, DifferentiableMapping};
 
 /// A trait for encoding constant [`Float`] values
 pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> {
@@ -40,6 +40,7 @@
     C : Constant<Type=F>
 {
     type Codomain = V;
+    type ArithmeticOptIn = ArithmeticTrue;
 
     #[inline]
     fn apply<I : Instance<D>>(&self, x : I) -> Self::Codomain {

mercurial