Update to approx 0.2.
This commit is contained in:
parent
118227d6b9
commit
88055dfc45
|
@ -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 {
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue