Update to approx 0.2.

This commit is contained in:
sebcrozet 2018-05-19 15:41:58 +02:00 committed by Sébastien Crozet
parent 118227d6b9
commit 88055dfc45
10 changed files with 314 additions and 126 deletions

View File

@ -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<N, D, S> = Matrix<N, D, D, S>;
@ -80,7 +81,8 @@ pub struct Matrix<N: Scalar, R: Dim, C: Dim, S> {
impl<N: Scalar, R: Dim, C: Dim, S: fmt::Debug> fmt::Debug for Matrix<N, R, C, S> {
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<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// 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<R2, C2, SB>(
&self,
@ -233,7 +235,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
max_relative: N::Epsilon,
) -> bool
where
N: ApproxEq,
N: RelativeEq,
R2: Dim,
C2: Dim,
SB: Storage<N, R2, C2>,
@ -740,9 +742,9 @@ impl<N: Scalar + Zero, D: DimAdd<U1>, S: Storage<N, D>> Vector<N, D, S> {
}
}
impl<N, R: Dim, C: Dim, S> ApproxEq for Matrix<N, R, C, S>
impl<N, R: Dim, C: Dim, S> AbsDiffEq for Matrix<N, R, C, S>
where
N: Scalar + ApproxEq,
N: Scalar + AbsDiffEq,
S: Storage<N, R, C>,
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<N, R: Dim, C: Dim, S> RelativeEq for Matrix<N, R, C, S>
where
N: Scalar + RelativeEq,
S: Storage<N, R, C>,
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<N, R: Dim, C: Dim, S> UlpsEq for Matrix<N, R, C, S>
where
N: Scalar + UlpsEq,
S: Storage<N, R, C>,
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<N: Real, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
}
}
impl<N, R: Dim, C: Dim, S> ApproxEq for Unit<Matrix<N, R, C, S>>
impl<N, R: Dim, C: Dim, S> AbsDiffEq for Unit<Matrix<N, R, C, S>>
where
N: Scalar + ApproxEq,
N: Scalar + AbsDiffEq,
S: Storage<N, R, C>,
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<N, R: Dim, C: Dim, S> RelativeEq for Unit<Matrix<N, R, C, S>>
where
N: Scalar + RelativeEq,
S: Storage<N, R, C>,
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<N, R: Dim, C: Dim, S> UlpsEq for Unit<Matrix<N, R, C, S>>
where
N: Scalar + UlpsEq,
S: Storage<N, R, C>,
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 {

View File

@ -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<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Indicates if this is a square matrix.
@ -24,7 +24,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
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<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[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<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[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, R, C>,
N::Epsilon: Copy,
DefaultAllocator: Allocator<N, C, C>,

View File

@ -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<T> AsRef<T> for Unit<T> {
*/
impl<T: NormedSpace> SubsetOf<T> for Unit<T>
where
T::Field: ApproxEq,
T::Field: RelativeEq,
{
#[inline]
fn to_superset(&self) -> T {
@ -156,7 +156,7 @@ where
}
}
// impl<T: ApproxEq> ApproxEq for Unit<T> {
// impl<T: RelativeEq> RelativeEq for Unit<T> {
// type Epsilon = T::Epsilon;
//
// #[inline]

View File

@ -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<N, D>,
Owned<N, D>: serde::Serialize")))]
#[cfg_attr(feature = "serde-serialize",
serde(bound(deserialize = "R: serde::Deserialize<'de>,
Owned<N, D>: serde::Serialize"
)
)
)]
#[cfg_attr(
feature = "serde-serialize",
serde(
bound(
deserialize = "R: serde::Deserialize<'de>,
DefaultAllocator: Allocator<N, D>,
Owned<N, D>: serde::Deserialize<'de>")))]
Owned<N, D>: serde::Deserialize<'de>"
)
)
)]
pub struct Isometry<N: Real, D: DimName, R>
where
DefaultAllocator: Allocator<N, D>,
@ -201,9 +213,9 @@ where
}
}
impl<N: Real, D: DimName, R> ApproxEq for Isometry<N, D, R>
impl<N: Real, D: DimName, R> AbsDiffEq for Isometry<N, D, R>
where
R: Rotation<Point<N, D>> + ApproxEq<Epsilon = N::Epsilon>,
R: Rotation<Point<N, D>> + AbsDiffEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
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<N: Real, D: DimName, R> RelativeEq for Isometry<N, D, R>
where
R: Rotation<Point<N, D>> + RelativeEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
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<N: Real, D: DimName, R> UlpsEq for Isometry<N, D, R>
where
R: Rotation<Point<N, D>> + UlpsEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
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 {

View File

@ -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<N: Scalar + ApproxEq, D: DimName> ApproxEq for Point<N, D>
impl<N: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for Point<N, D>
where
DefaultAllocator: Allocator<N, D>,
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<N: Scalar + RelativeEq, D: DimName> RelativeEq for Point<N, D>
where
DefaultAllocator: Allocator<N, D>,
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<N: Scalar + UlpsEq, D: DimName> UlpsEq for Point<N, D>
where
DefaultAllocator: Allocator<N, D>,
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 {

View File

@ -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<N: Real> Quaternion<N> {
}
}
impl<N: Real + ApproxEq<Epsilon = N>> ApproxEq for Quaternion<N> {
impl<N: Real + AbsDiffEq<Epsilon = N>> AbsDiffEq for Quaternion<N> {
type Epsilon = N;
#[inline]
@ -289,16 +289,20 @@ impl<N: Real + ApproxEq<Epsilon = N>> ApproxEq for Quaternion<N> {
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<N: Real + RelativeEq<Epsilon = N>> RelativeEq for Quaternion<N> {
#[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<N: Real + ApproxEq<Epsilon = N>> ApproxEq for Quaternion<N> {
// 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<N: Real + UlpsEq<Epsilon = N>> UlpsEq for Quaternion<N> {
#[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<N: Real + fmt::Display> fmt::Display for UnitQuaternion<N> {
}
}
impl<N: Real + ApproxEq<Epsilon = N>> ApproxEq for UnitQuaternion<N> {
impl<N: Real + AbsDiffEq<Epsilon = N>> AbsDiffEq for UnitQuaternion<N> {
type Epsilon = N;
#[inline]
@ -621,16 +632,18 @@ impl<N: Real + ApproxEq<Epsilon = N>> ApproxEq for UnitQuaternion<N> {
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<N: Real + RelativeEq<Epsilon = N>> RelativeEq for UnitQuaternion<N> {
#[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<N: Real + ApproxEq<Epsilon = N>> ApproxEq for UnitQuaternion<N> {
self.as_ref()
.relative_eq(other.as_ref(), epsilon, max_relative)
}
}
impl<N: Real + UlpsEq<Epsilon = N>> UlpsEq for UnitQuaternion<N> {
#[inline]
fn default_max_ulps() -> u32 {
N::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {

View File

@ -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<N, D: DimName> ApproxEq for Rotation<N, D>
impl<N, D: DimName> AbsDiffEq for Rotation<N, D>
where
N: Scalar + ApproxEq,
N: Scalar + AbsDiffEq,
DefaultAllocator: Allocator<N, D, D>,
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<N, D: DimName> RelativeEq for Rotation<N, D>
where
N: Scalar + RelativeEq,
DefaultAllocator: Allocator<N, D, D>,
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<N, D: DimName> UlpsEq for Rotation<N, D>
where
N: Scalar + UlpsEq,
DefaultAllocator: Allocator<N, D, D>,
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 {

View File

@ -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<N, D>,
Owned<N, D>: serde::Serialize")))]
#[cfg_attr(feature = "serde-serialize",
serde(bound(deserialize = "N: serde::Deserialize<'de>,
Owned<N, D>: serde::Serialize"
)
)
)]
#[cfg_attr(
feature = "serde-serialize",
serde(
bound(
deserialize = "N: serde::Deserialize<'de>,
R: serde::Deserialize<'de>,
DefaultAllocator: Allocator<N, D>,
Owned<N, D>: serde::Deserialize<'de>")))]
Owned<N, D>: serde::Deserialize<'de>"
)
)
)]
pub struct Similarity<N: Real, D: DimName, R>
where
DefaultAllocator: Allocator<N, D>,
@ -276,9 +288,9 @@ where
}
}
impl<N: Real, D: DimName, R> ApproxEq for Similarity<N, D, R>
impl<N: Real, D: DimName, R> AbsDiffEq for Similarity<N, D, R>
where
R: Rotation<Point<N, D>> + ApproxEq<Epsilon = N::Epsilon>,
R: Rotation<Point<N, D>> + AbsDiffEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
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<N: Real, D: DimName, R> RelativeEq for Similarity<N, D, R>
where
R: Rotation<Point<N, D>> + RelativeEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
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<N: Real, D: DimName, R> UlpsEq for Similarity<N, D, R>
where
R: Rotation<Point<N, D>> + UlpsEq<Epsilon = N::Epsilon>,
DefaultAllocator: Allocator<N, D>,
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 {

View File

@ -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<N: Scalar + ApproxEq, D: DimName> ApproxEq for Translation<N, D>
impl<N: Scalar + AbsDiffEq, D: DimName> AbsDiffEq for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
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<N: Scalar + RelativeEq, D: DimName> RelativeEq for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
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<N: Scalar + UlpsEq, D: DimName> UlpsEq for Translation<N, D>
where
DefaultAllocator: Allocator<N, D>,
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 {

View File

@ -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<N: Real + fmt::Display> fmt::Display for UnitComplex<N> {
}
}
impl<N: Real> ApproxEq for UnitComplex<N> {
impl<N: Real> AbsDiffEq for UnitComplex<N> {
type Epsilon = N;
#[inline]
@ -137,16 +137,18 @@ impl<N: Real> ApproxEq for UnitComplex<N> {
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<N: Real> RelativeEq for UnitComplex<N> {
#[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<N: Real> ApproxEq for UnitComplex<N> {
self.re.relative_eq(&other.re, epsilon, max_relative)
&& self.im.relative_eq(&other.im, epsilon, max_relative)
}
}
impl<N: Real> UlpsEq for UnitComplex<N> {
#[inline]
fn default_max_ulps() -> u32 {
N::default_max_ulps()
}
#[inline]
fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {