src/forward_model/bias.rs

Mon, 05 Dec 2022 23:50:22 +0200

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 05 Dec 2022 23:50:22 +0200
changeset 56
3a784e6e475a
parent 49
6b0db7251ebe
permissions
-rw-r--r--

Zenodo packaging hacks

/*!
Simple parametric forward model.
 */

use super::{AdjointProductBoundedBy, AdjointProductPairBoundedBy, BoundedCurvature, ForwardModel};
use crate::measures::RNDM;
use alg_tools::direct_product::Pair;
use alg_tools::error::DynError;
use alg_tools::linops::{IdOp, Linear, RowOp, ZeroOp, AXPY};
use alg_tools::mapping::Space;
use alg_tools::norms::{Norm, NormExponent, PairNorm, L2};
use alg_tools::types::{ClosedAdd, Float};
use numeric_literals::replace_float_literals;

impl<Domain, F, A, E> ForwardModel<Pair<Domain, A::Observable>, F, PairNorm<E, L2, L2>>
    for RowOp<A, IdOp<A::Observable>>
where
    E: NormExponent,
    Domain: Space + Norm<F, E>,
    F: Float,
    A::Observable: ClosedAdd + Norm<F, L2> + 'static,
    A: ForwardModel<Domain, F, E> + 'static,
{
    type Observable = A::Observable;

    fn write_observable(&self, b: &Self::Observable, prefix: String) -> DynError {
        self.0.write_observable(b, prefix)
    }

    /// Returns a zero observable
    fn zero_observable(&self) -> Self::Observable {
        self.0.zero_observable()
    }
}

#[replace_float_literals(F::cast_from(literal))]
impl<Domain, F, A, D, Z> AdjointProductPairBoundedBy<Pair<Domain, Z>, D, IdOp<Z>>
    for RowOp<A, IdOp<Z>>
where
    Domain: Space,
    F: Float,
    Z: Clone + Space + ClosedAdd,
    A: AdjointProductBoundedBy<Domain, D, FloatType = F, Codomain = Z>,
    A::Codomain: ClosedAdd,
{
    type FloatType = F;

    fn adjoint_product_pair_bound(&self, d: &D, _: &IdOp<Z>) -> Option<(F, F)> {
        self.0.adjoint_product_bound(d).map(|l_0| {
            // [A_*; B_*][A, B] = [A_*A, A_* B; B_* A, B_* B] ≤ diag(2A_*A, 2B_*B)
            // ≤ diag(2l_A𝒟_A, 2l_B𝒟_B), where now 𝒟_B=Id and l_B=1.
            (2.0 * l_0, 2.0)
        })
    }
}

/*
/// This `impl` is bit of an abuse as the codomain of `Apre` is a [`Pair`] of a measure predual,
/// to which this `impl` applies, and another space.
impl<F, Apre, Z> LipschitzValues
for ColOp<Apre, IdOp<Z>>
where
    F : Float,
    Z : Clone + Space + ClosedAdd,
    Apre : LipschitzValues<FloatType = F>,
{
    type FloatType = F;
    /// Return (if one exists) a factor $L$ such that $A_*z$ is $L$-Lipschitz for all
    /// $z$ in the unit ball.
    fn value_unit_lipschitz_factor(&self) -> Option<Self::FloatType> {
        self.0.value_unit_lipschitz_factor()
    }

    /// Return (if one exists) a factor $L$ such that $∇A_*z$ is $L$-Lipschitz for all
    /// $z$ in the unit ball.
    fn value_diff_unit_lipschitz_factor(&self) -> Option<Self::FloatType> {
        self.0.value_diff_unit_lipschitz_factor()
    }
}
*/

impl<F, A, Z> BoundedCurvature for RowOp<A, IdOp<Z>>
where
    F: Float,
    Z: Clone + Space + ClosedAdd,
    A: BoundedCurvature<FloatType = F>,
{
    type FloatType = F;

    fn curvature_bound_components(&self) -> (Option<Self::FloatType>, Option<Self::FloatType>) {
        self.0.curvature_bound_components()
    }
}

#[replace_float_literals(F::cast_from(literal))]
impl<'a, F, D, XD, Y, const N: usize> AdjointProductBoundedBy<RNDM<F, N>, D>
    for ZeroOp<'a, RNDM<F, N>, XD, Y, F>
where
    F: Float,
    Y: AXPY<F> + Clone,
    D: Linear<RNDM<F, N>>,
{
    type FloatType = F;
    /// Return $L$ such that $A_*A ≤ L𝒟$ is bounded by some `other` operator $𝒟$.
    fn adjoint_product_bound(&self, _: &D) -> Option<F> {
        Some(0.0)
    }
}

mercurial