Skip to main content

faer/utils/
approx.rs

1use crate::internal_prelude::*;
2use core::ops::Mul;
3use faer_traits::Real;
4extern crate alloc;
5#[derive(Copy, Clone, Debug, PartialEq, Eq)]
6pub struct ApproxEq<T> {
7	pub abs_tol: T,
8	pub rel_tol: T,
9}
10pub struct CwiseMat<Cmp>(pub Cmp);
11impl<T: RealField> ApproxEq<T> {
12	#[inline]
13	pub fn eps() -> Self {
14		Self {
15			abs_tol: eps::<T>() * from_f64::<T>(128.0),
16			rel_tol: eps::<T>() * from_f64::<T>(128.0),
17		}
18	}
19}
20impl<T: RealField> Mul<T> for ApproxEq<T> {
21	type Output = ApproxEq<T>;
22
23	#[inline]
24	fn mul(self, rhs: Real<T>) -> Self::Output {
25		ApproxEq {
26			abs_tol: &self.abs_tol * &rhs,
27			rel_tol: &self.rel_tol * &rhs,
28		}
29	}
30}
31#[derive(Copy, Clone, Debug)]
32pub struct ApproxEqError;
33#[derive(Clone, Debug)]
34pub enum CwiseMatError<Rows: Shape, Cols: Shape, Error> {
35	DimMismatch,
36	Elements(alloc::vec::Vec<(crate::Idx<Rows>, crate::Idx<Cols>, Error)>),
37}
38#[derive(Clone, Debug)]
39pub enum CwiseColError<Rows: Shape, Error> {
40	DimMismatch,
41	Elements(alloc::vec::Vec<(crate::Idx<Rows>, Error)>),
42}
43#[derive(Clone, Debug)]
44pub enum CwiseRowError<Cols: Shape, Error> {
45	DimMismatch,
46	Elements(alloc::vec::Vec<(crate::Idx<Cols>, Error)>),
47}
48impl<R: RealField, T: ComplexField<Real = R>> equator::Cmp<T, T>
49	for ApproxEq<R>
50{
51	fn test(&self, lhs: &T, rhs: &T) -> bool {
52		let Self { abs_tol, rel_tol } = self;
53		let diff = (lhs - rhs).abs();
54		let max = lhs.abs().fmax(rhs.abs());
55		(max == zero() && diff <= *abs_tol)
56			|| (diff <= *abs_tol || diff <= rel_tol * max)
57	}
58}
59impl<
60	T: ComplexField,
61	Rows: Shape,
62	Cols: Shape,
63	L: AsMatRef<T = T, Rows = Rows, Cols = Cols>,
64	R: AsMatRef<T = T, Rows = Rows, Cols = Cols>,
65	Cmp: equator::Cmp<T, T>,
66> equator::Cmp<L, R> for CwiseMat<Cmp>
67{
68	fn test(&self, lhs: &L, rhs: &R) -> bool {
69		let lhs = lhs.as_mat_ref();
70		let rhs = rhs.as_mat_ref();
71		if lhs.nrows() != rhs.nrows() || lhs.ncols() != rhs.ncols() {
72			return false;
73		}
74		for j in 0..lhs.ncols().unbound() {
75			let j = lhs.ncols().checked_idx(j);
76			for i in 0..lhs.nrows().unbound() {
77				let i = lhs.nrows().checked_idx(i);
78				if !self.0.test(&lhs[(i, j)], &rhs[(i, j)]) {
79					return false;
80				}
81			}
82		}
83		true
84	}
85}