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}