src/preadjoint_helper.rs

Fri, 16 Jan 2026 19:39:22 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Fri, 16 Jan 2026 19:39:22 -0500
branch
dev
changeset 62
32328a74c790
parent 61
4f468d35fa29
permissions
-rw-r--r--

Lipschitz estimation attempt (incomplete, not implemented for sliding. Doesn't work anyway for basic FB either.)

/*!
Preadjoint construction helper
*/

use alg_tools::error::DynResult;
pub use alg_tools::linops::*;
use alg_tools::norms::{HasDualExponent, Norm};
use alg_tools::types::*;
use std::marker::PhantomData;

/// Helper structure for constructing preadjoints of `S` where `S : Linear<X>`.
/// [`Linear`] needs to be implemented for each instance, but [`Adjointable`]
/// and [`BoundedLinear`] have blanket implementations.
#[derive(Clone, Debug)]
pub struct PreadjointHelper<'a, S: 'a, X> {
    pub forward_op: &'a S,
    _domain: PhantomData<X>,
}

impl<'a, S: 'a, X> PreadjointHelper<'a, S, X> {
    pub fn new(forward_op: &'a S) -> Self {
        PreadjointHelper {
            forward_op,
            _domain: PhantomData,
        }
    }
}

impl<'a, X, Ypre, S> Adjointable<Ypre, X> for PreadjointHelper<'a, S, X>
where
    X: Space,
    Ypre: Space,
    Self: Linear<Ypre>,
    S: Clone + Linear<X>,
{
    type AdjointCodomain = S::Codomain;
    type Adjoint<'b>
        = S
    where
        Self: 'b;

    fn adjoint(&self) -> Self::Adjoint<'_> {
        self.forward_op.clone()
    }
}

impl<'a, F, X, Ypre, ExpXpre, ExpYpre, S> BoundedLinear<Ypre, ExpYpre, ExpXpre, F>
    for PreadjointHelper<'a, S, X>
where
    ExpXpre: HasDualExponent,
    ExpYpre: HasDualExponent,
    F: Float,
    X: Space + Norm<ExpXpre::DualExp, F>,
    Ypre: Space + Norm<ExpYpre, F>,
    Self: Linear<Ypre>,
    S: 'a + Clone + BoundedLinear<X, ExpXpre::DualExp, ExpYpre::DualExp, F>,
{
    fn opnorm_bound(&self, expy: ExpYpre, expx: ExpXpre) -> DynResult<F> {
        self.forward_op
            .opnorm_bound(expx.dual_exponent(), expy.dual_exponent())
    }
}

mercurial