diff --git a/src/core/matrix.rs b/src/core/matrix.rs index ec6f458b..949ef043 100644 --- a/src/core/matrix.rs +++ b/src/core/matrix.rs @@ -1,12 +1,12 @@ use num::Zero; use num_complex::Complex; -use std::cmp::Ordering; -use std::marker::PhantomData; -use std::fmt; +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use std::any::TypeId; +use std::cmp::Ordering; +use std::fmt; +use std::marker::PhantomData; use std::mem; -use approx::ApproxEq; #[cfg(feature = "serde-serialize")] use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -16,13 +16,14 @@ use abomonation::Abomonation; use alga::general::{Real, Ring}; -use core::{DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN}; -use core::dimension::{Dim, DimAdd, DimSum, U1, U2, U3}; -use core::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; -use core::iter::{MatrixIter, MatrixIterMut}; use core::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR}; -use core::storage::{ContiguousStorage, ContiguousStorageMut, Owned, SameShapeStorage, Storage, - StorageMut}; +use core::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; +use core::dimension::{Dim, DimAdd, DimSum, U1, U2, U3}; +use core::iter::{MatrixIter, MatrixIterMut}; +use core::storage::{ + ContiguousStorage, ContiguousStorageMut, Owned, SameShapeStorage, Storage, StorageMut, +}; +use core::{DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN}; /// A square matrix. pub type SquareMatrix = Matrix; @@ -80,7 +81,8 @@ pub struct Matrix { impl fmt::Debug for Matrix { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - formatter.debug_struct("Matrix") + formatter + .debug_struct("Matrix") .field("data", &self.data) .finish() } @@ -224,7 +226,7 @@ impl> Matrix { /// Tests whether `self` and `rhs` are equal up to a given epsilon. /// - /// See `relative_eq` from the `ApproxEq` trait for more details. + /// See `relative_eq` from the `RelativeEq` trait for more details. #[inline] pub fn relative_eq( &self, @@ -233,7 +235,7 @@ impl> Matrix { max_relative: N::Epsilon, ) -> bool where - N: ApproxEq, + N: RelativeEq, R2: Dim, C2: Dim, SB: Storage, @@ -740,9 +742,9 @@ impl, S: Storage> Vector { } } -impl ApproxEq for Matrix +impl AbsDiffEq for Matrix where - N: Scalar + ApproxEq, + N: Scalar + AbsDiffEq, S: Storage, N::Epsilon: Copy, { @@ -753,16 +755,25 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.iter() + .zip(other.iter()) + .all(|(a, b)| a.abs_diff_eq(b, epsilon)) + } +} + +impl RelativeEq for Matrix +where + N: Scalar + RelativeEq, + S: Storage, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -772,6 +783,18 @@ where ) -> bool { self.relative_eq(other, epsilon, max_relative) } +} + +impl UlpsEq for Matrix +where + N: Scalar + UlpsEq, + S: Storage, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { @@ -1165,9 +1188,9 @@ impl> Matrix { } } -impl ApproxEq for Unit> +impl AbsDiffEq for Unit> where - N: Scalar + ApproxEq, + N: Scalar + AbsDiffEq, S: Storage, N::Epsilon: Copy, { @@ -1178,16 +1201,23 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.as_ref().abs_diff_eq(other.as_ref(), epsilon) + } +} + +impl RelativeEq for Unit> +where + N: Scalar + RelativeEq, + S: Storage, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -1198,6 +1228,18 @@ where self.as_ref() .relative_eq(other.as_ref(), epsilon, max_relative) } +} + +impl UlpsEq for Unit> +where + N: Scalar + UlpsEq, + S: Storage, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/core/properties.rs b/src/core/properties.rs index 335e9ba1..5a77e8f3 100644 --- a/src/core/properties.rs +++ b/src/core/properties.rs @@ -1,13 +1,13 @@ // Matrix properties checks. +use approx::RelativeEq; use num::{One, Zero}; -use approx::ApproxEq; use alga::general::{ClosedAdd, ClosedMul, Real}; -use core::{DefaultAllocator, Matrix, Scalar, SquareMatrix}; +use core::allocator::Allocator; use core::dimension::{Dim, DimMin}; use core::storage::Storage; -use core::allocator::Allocator; +use core::{DefaultAllocator, Matrix, Scalar, SquareMatrix}; impl> Matrix { /// Indicates if this is a square matrix. @@ -24,7 +24,7 @@ impl> Matrix { nrows == ncols } - // FIXME: ApproxEq prevents us from using those methods on integer matrices… + // FIXME: RelativeEq prevents us from using those methods on integer matrices… /// Indicated if this is the identity matrix within a relative error of `eps`. /// /// If the matrix is diagonal, this checks that diagonal elements (i.e. at coordinates `(i, i)` @@ -32,7 +32,7 @@ impl> Matrix { #[inline] pub fn is_identity(&self, eps: N::Epsilon) -> bool where - N: Zero + One + ApproxEq, + N: Zero + One + RelativeEq, N::Epsilon: Copy, { let (nrows, ncols) = self.shape(); @@ -90,7 +90,7 @@ impl> Matrix { #[inline] pub fn is_orthogonal(&self, eps: N::Epsilon) -> bool where - N: Zero + One + ClosedAdd + ClosedMul + ApproxEq, + N: Zero + One + ClosedAdd + ClosedMul + RelativeEq, S: Storage, N::Epsilon: Copy, DefaultAllocator: Allocator, diff --git a/src/core/unit.rs b/src/core/unit.rs index 24d5382b..d8df3e82 100644 --- a/src/core/unit.rs +++ b/src/core/unit.rs @@ -1,6 +1,6 @@ +use approx::RelativeEq; use std::mem; use std::ops::{Deref, Neg}; -use approx::ApproxEq; #[cfg(feature = "serde-serialize")] use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -138,7 +138,7 @@ impl AsRef for Unit { */ impl SubsetOf for Unit where - T::Field: ApproxEq, + T::Field: RelativeEq, { #[inline] fn to_superset(&self) -> T { @@ -156,7 +156,7 @@ where } } -// impl ApproxEq for Unit { +// impl RelativeEq for Unit { // type Epsilon = T::Epsilon; // // #[inline] diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs index 8c582275..86aca469 100644 --- a/src/geometry/isometry.rs +++ b/src/geometry/isometry.rs @@ -1,7 +1,7 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use std::fmt; use std::hash; use std::marker::PhantomData; -use approx::ApproxEq; #[cfg(feature = "serde-serialize")] use serde; @@ -12,24 +12,36 @@ use abomonation::Abomonation; use alga::general::{Real, SubsetOf}; use alga::linear::Rotation; -use core::{DefaultAllocator, MatrixN}; +use core::allocator::Allocator; use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use core::storage::Owned; -use core::allocator::Allocator; +use core::{DefaultAllocator, MatrixN}; use geometry::{Point, Translation}; /// A direct isometry, i.e., a rotation followed by a translation. #[repr(C)] #[derive(Debug)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde-serialize", - serde(bound(serialize = "R: serde::Serialize, +#[cfg_attr( + feature = "serde-serialize", + serde( + bound( + serialize = "R: serde::Serialize, DefaultAllocator: Allocator, - Owned: serde::Serialize")))] -#[cfg_attr(feature = "serde-serialize", - serde(bound(deserialize = "R: serde::Deserialize<'de>, + Owned: serde::Serialize" + ) + ) +)] +#[cfg_attr( + feature = "serde-serialize", + serde( + bound( + deserialize = "R: serde::Deserialize<'de>, DefaultAllocator: Allocator, - Owned: serde::Deserialize<'de>")))] + Owned: serde::Deserialize<'de>" + ) + ) +)] pub struct Isometry where DefaultAllocator: Allocator, @@ -201,9 +213,9 @@ where } } -impl ApproxEq for Isometry +impl AbsDiffEq for Isometry where - R: Rotation> + ApproxEq, + R: Rotation> + AbsDiffEq, DefaultAllocator: Allocator, N::Epsilon: Copy, { @@ -214,16 +226,24 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.translation.abs_diff_eq(&other.translation, epsilon) + && self.rotation.abs_diff_eq(&other.rotation, epsilon) + } +} + +impl RelativeEq for Isometry +where + R: Rotation> + RelativeEq, + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -236,6 +256,18 @@ where && self.rotation .relative_eq(&other.rotation, epsilon, max_relative) } +} + +impl UlpsEq for Isometry +where + R: Rotation> + UlpsEq, + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/geometry/point.rs b/src/geometry/point.rs index f12f0f8f..0f167a6d 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -1,8 +1,8 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use num::One; -use std::hash; -use std::fmt; use std::cmp::Ordering; -use approx::ApproxEq; +use std::fmt; +use std::hash; #[cfg(feature = "serde-serialize")] use serde; @@ -10,10 +10,10 @@ use serde; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; -use core::{DefaultAllocator, Scalar, VectorN}; -use core::iter::{MatrixIter, MatrixIterMut}; -use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use core::allocator::Allocator; +use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; +use core::iter::{MatrixIter, MatrixIterMut}; +use core::{DefaultAllocator, Scalar, VectorN}; /// A point in a n-dimensional euclidean space. #[repr(C)] @@ -183,7 +183,7 @@ where } } -impl ApproxEq for Point +impl AbsDiffEq for Point where DefaultAllocator: Allocator, N::Epsilon: Copy, @@ -195,16 +195,22 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.coords.abs_diff_eq(&other.coords, epsilon) + } +} + +impl RelativeEq for Point +where + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -215,6 +221,17 @@ where self.coords .relative_eq(&other.coords, epsilon, max_relative) } +} + +impl UlpsEq for Point +where + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index b1cba752..72fe0790 100644 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -1,21 +1,21 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; +use num::Zero; use std::fmt; use std::hash; -use num::Zero; -use approx::ApproxEq; -#[cfg(feature = "serde-serialize")] -use serde; #[cfg(feature = "serde-serialize")] use core::storage::Owned; +#[cfg(feature = "serde-serialize")] +use serde; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; use alga::general::Real; -use core::{Matrix3, MatrixN, MatrixSlice, MatrixSliceMut, Unit, Vector3, Vector4}; use core::dimension::{U1, U3, U4}; use core::storage::{CStride, RStride}; +use core::{Matrix3, MatrixN, MatrixSlice, MatrixSliceMut, Unit, Vector3, Vector4}; use geometry::Rotation; @@ -281,7 +281,7 @@ impl Quaternion { } } -impl> ApproxEq for Quaternion { +impl> AbsDiffEq for Quaternion { type Epsilon = N; #[inline] @@ -289,16 +289,20 @@ impl> ApproxEq for Quaternion { N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.as_vector().abs_diff_eq(other.as_vector(), epsilon) || + // Account for the double-covering of S², i.e. q = -q + self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.abs_diff_eq(&-*b, epsilon)) + } +} + +impl> RelativeEq for Quaternion { #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -310,6 +314,13 @@ impl> ApproxEq for Quaternion { // Account for the double-covering of S², i.e. q = -q self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative)) } +} + +impl> UlpsEq for Quaternion { + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { @@ -613,7 +624,7 @@ impl fmt::Display for UnitQuaternion { } } -impl> ApproxEq for UnitQuaternion { +impl> AbsDiffEq for UnitQuaternion { type Epsilon = N; #[inline] @@ -621,16 +632,18 @@ impl> ApproxEq for UnitQuaternion { N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.as_ref().abs_diff_eq(other.as_ref(), epsilon) + } +} + +impl> RelativeEq for UnitQuaternion { #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -641,6 +654,13 @@ impl> ApproxEq for UnitQuaternion { self.as_ref() .relative_eq(other.as_ref(), epsilon, max_relative) } +} + +impl> UlpsEq for UnitQuaternion { + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs index b956d093..7d0a9416 100644 --- a/src/geometry/rotation.rs +++ b/src/geometry/rotation.rs @@ -1,7 +1,7 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use num::{One, Zero}; -use std::hash; use std::fmt; -use approx::ApproxEq; +use std::hash; #[cfg(feature = "serde-serialize")] use serde; @@ -14,9 +14,9 @@ use abomonation::Abomonation; use alga::general::Real; -use core::{DefaultAllocator, MatrixN, Scalar}; -use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use core::allocator::Allocator; +use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; +use core::{DefaultAllocator, MatrixN, Scalar}; /// A rotation matrix. #[repr(C)] @@ -201,9 +201,9 @@ where } } -impl ApproxEq for Rotation +impl AbsDiffEq for Rotation where - N: Scalar + ApproxEq, + N: Scalar + AbsDiffEq, DefaultAllocator: Allocator, N::Epsilon: Copy, { @@ -214,16 +214,23 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.matrix.abs_diff_eq(&other.matrix, epsilon) + } +} + +impl RelativeEq for Rotation +where + N: Scalar + RelativeEq, + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -234,6 +241,18 @@ where self.matrix .relative_eq(&other.matrix, epsilon, max_relative) } +} + +impl UlpsEq for Rotation +where + N: Scalar + UlpsEq, + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index 177be162..ef8fd95d 100644 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -1,6 +1,6 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use std::fmt; use std::hash; -use approx::ApproxEq; #[cfg(feature = "serde-serialize")] use serde; @@ -11,26 +11,38 @@ use abomonation::Abomonation; use alga::general::{Real, SubsetOf}; use alga::linear::Rotation; -use core::{DefaultAllocator, MatrixN}; +use core::allocator::Allocator; use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use core::storage::Owned; -use core::allocator::Allocator; +use core::{DefaultAllocator, MatrixN}; use geometry::{Isometry, Point, Translation}; /// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation. #[repr(C)] #[derive(Debug)] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde-serialize", - serde(bound(serialize = "N: serde::Serialize, +#[cfg_attr( + feature = "serde-serialize", + serde( + bound( + serialize = "N: serde::Serialize, R: serde::Serialize, DefaultAllocator: Allocator, - Owned: serde::Serialize")))] -#[cfg_attr(feature = "serde-serialize", - serde(bound(deserialize = "N: serde::Deserialize<'de>, + Owned: serde::Serialize" + ) + ) +)] +#[cfg_attr( + feature = "serde-serialize", + serde( + bound( + deserialize = "N: serde::Deserialize<'de>, R: serde::Deserialize<'de>, DefaultAllocator: Allocator, - Owned: serde::Deserialize<'de>")))] + Owned: serde::Deserialize<'de>" + ) + ) +)] pub struct Similarity where DefaultAllocator: Allocator, @@ -276,9 +288,9 @@ where } } -impl ApproxEq for Similarity +impl AbsDiffEq for Similarity where - R: Rotation> + ApproxEq, + R: Rotation> + AbsDiffEq, DefaultAllocator: Allocator, N::Epsilon: Copy, { @@ -289,16 +301,24 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.isometry.abs_diff_eq(&other.isometry, epsilon) + && self.scaling.abs_diff_eq(&other.scaling, epsilon) + } +} + +impl RelativeEq for Similarity +where + R: Rotation> + RelativeEq, + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -311,6 +331,18 @@ where && self.scaling .relative_eq(&other.scaling, epsilon, max_relative) } +} + +impl UlpsEq for Similarity +where + R: Rotation> + UlpsEq, + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs index 09e3cbfb..e19acbdb 100644 --- a/src/geometry/translation.rs +++ b/src/geometry/translation.rs @@ -1,7 +1,7 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use num::{One, Zero}; -use std::hash; use std::fmt; -use approx::ApproxEq; +use std::hash; #[cfg(feature = "serde-serialize")] use serde; @@ -11,10 +11,10 @@ use abomonation::Abomonation; use alga::general::{ClosedNeg, Real}; -use core::{DefaultAllocator, MatrixN, Scalar, VectorN}; +use core::allocator::Allocator; use core::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use core::storage::Owned; -use core::allocator::Allocator; +use core::{DefaultAllocator, MatrixN, Scalar, VectorN}; /// A translation. #[repr(C)] @@ -167,7 +167,7 @@ where } } -impl ApproxEq for Translation +impl AbsDiffEq for Translation where DefaultAllocator: Allocator, N::Epsilon: Copy, @@ -179,16 +179,22 @@ where N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.vector.abs_diff_eq(&other.vector, epsilon) + } +} + +impl RelativeEq for Translation +where + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -199,6 +205,17 @@ where self.vector .relative_eq(&other.vector, epsilon, max_relative) } +} + +impl UlpsEq for Translation +where + DefaultAllocator: Allocator, + N::Epsilon: Copy, +{ + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { diff --git a/src/geometry/unit_complex.rs b/src/geometry/unit_complex.rs index 07c7cdca..2ffe369b 100644 --- a/src/geometry/unit_complex.rs +++ b/src/geometry/unit_complex.rs @@ -1,6 +1,6 @@ -use std::fmt; -use approx::ApproxEq; +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; use num_complex::Complex; +use std::fmt; use alga::general::Real; use core::{Matrix2, Matrix3, Unit, Vector1}; @@ -129,7 +129,7 @@ impl fmt::Display for UnitComplex { } } -impl ApproxEq for UnitComplex { +impl AbsDiffEq for UnitComplex { type Epsilon = N; #[inline] @@ -137,16 +137,18 @@ impl ApproxEq for UnitComplex { N::default_epsilon() } + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.re.abs_diff_eq(&other.re, epsilon) && self.im.abs_diff_eq(&other.im, epsilon) + } +} + +impl RelativeEq for UnitComplex { #[inline] fn default_max_relative() -> Self::Epsilon { N::default_max_relative() } - #[inline] - fn default_max_ulps() -> u32 { - N::default_max_ulps() - } - #[inline] fn relative_eq( &self, @@ -157,6 +159,13 @@ impl ApproxEq for UnitComplex { self.re.relative_eq(&other.re, epsilon, max_relative) && self.im.relative_eq(&other.im, epsilon, max_relative) } +} + +impl UlpsEq for UnitComplex { + #[inline] + fn default_max_ulps() -> u32 { + N::default_max_ulps() + } #[inline] fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {