Mon, 08 Sep 2025 19:22:13 -0500
Pair L2 norms and distances
| src/direct_product.rs | file | annotate | diff | comparison | revisions |
--- a/src/direct_product.rs Sun Sep 07 10:00:14 2025 -0500 +++ b/src/direct_product.rs Mon Sep 08 19:22:13 2025 -0500 @@ -10,7 +10,7 @@ use crate::linops::{VectorSpace, AXPY}; use crate::loc::Loc; use crate::mapping::Space; -use crate::norms::{HasDual, Norm, NormExponent, Normed, PairNorm, L2}; +use crate::norms::{Dist, HasDual, Norm, NormExponent, Normed, PairNorm, L2}; use crate::types::{Float, Num}; use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use serde::{Deserialize, Serialize}; @@ -568,6 +568,51 @@ } } +impl<F, A, B, ExpA, ExpB, ExpJ> Dist<PairNorm<ExpA, ExpB, ExpJ>, F> for Pair<A, B> +where + F: Num, + ExpA: NormExponent, + ExpB: NormExponent, + ExpJ: NormExponent, + A: Dist<ExpA, F>, + B: Dist<ExpB, F>, + Loc<2, F>: Norm<ExpJ, F>, +{ + fn dist<I: Instance<Self>>( + &self, + x: I, + PairNorm(expa, expb, expj): PairNorm<ExpA, ExpB, ExpJ>, + ) -> F { + x.eval_decompose(|Pair(x1, x2)| { + Loc([self.0.dist(x1, expa), self.1.dist(x2, expb)]).norm(expj) + }) + } +} + +impl<F, A, B> Norm<L2, F> for Pair<A, B> +where + F: Num, + A: Norm<L2, F>, + B: Norm<L2, F>, + Loc<2, F>: Norm<L2, F>, +{ + fn norm(&self, _: L2) -> F { + Loc([self.0.norm(L2), self.1.norm(L2)]).norm(L2) + } +} + +impl<F, A, B> Dist<L2, F> for Pair<A, B> +where + F: Num, + A: Dist<L2, F>, + B: Dist<L2, F>, + Loc<2, F>: Norm<L2, F>, +{ + fn dist<I: Instance<Self>>(&self, x: I, _: L2) -> F { + x.eval_decompose(|Pair(x1, x2)| Loc([self.0.dist(x1, L2), self.1.dist(x2, L2)]).norm(L2)) + } +} + impl<F: Float, A, B> Normed<F> for Pair<A, B> where A: Normed<F>,