From e5dd98730c3808d0e2e376d708caee5302b264fb Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Mon, 18 May 2020 14:18:04 -0700 Subject: [PATCH 1/3] Relax Float bound {Metric,Inner}Space and Matrix traits This makes the trait more flexible. This contributes to #496. --- src/structure.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/structure.rs b/src/structure.rs index 255449c1..f7375de2 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -195,7 +195,7 @@ where /// Examples are vectors, points, and quaternions. pub trait MetricSpace: Sized { /// The metric to be returned by the `distance` function. - type Metric: BaseFloat; + type Metric: Float; /// Returns the squared distance. /// @@ -219,19 +219,16 @@ pub trait MetricSpace: Sized { /// Examples include vectors and quaternions. pub trait InnerSpace: VectorSpace where + Self::Scalar: Float, // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 - ::Scalar: BaseFloat, - Self: MetricSpace::Scalar>, - // Self: approx::AbsDiffEq::Scalar>, - // Self: approx::RelativeEq::Scalar>, - Self: approx::UlpsEq::Scalar>, + Self: MetricSpace::Scalar> { /// Vector dot (or inner) product. fn dot(self, other: Self) -> Self::Scalar; /// Returns `true` if the vector is perpendicular (at right angles) to the /// other vector. - fn is_perpendicular(self, other: Self) -> bool { + fn is_perpendicular(self, other: Self) -> bool where Self::Scalar: approx::UlpsEq { ulps_eq!(Self::dot(self, other), &Self::Scalar::zero()) } @@ -252,7 +249,7 @@ where } /// Returns the angle between two vectors in radians. - fn angle(self, other: Self) -> Rad { + fn angle(self, other: Self) -> Rad where Self::Scalar: BaseFloat { Rad::acos(Self::dot(self, other) / (self.magnitude() * other.magnitude())) } @@ -427,14 +424,14 @@ where /// see `SquareMatrix`. pub trait Matrix: VectorSpace where - Self::Scalar: BaseFloat, + Self::Scalar: Float, // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: Index::Column>, Self: IndexMut::Column>, - Self: approx::AbsDiffEq::Scalar>, - Self: approx::RelativeEq::Scalar>, - Self: approx::UlpsEq::Scalar>, + //Self: approx::AbsDiffEq::Scalar>, + //Self: approx::RelativeEq::Scalar>, + //Self: approx::UlpsEq::Scalar>, { /// The row vector of the matrix. type Row: VectorSpace + Array; @@ -482,7 +479,7 @@ where /// A column-major major matrix where the rows and column vectors are of the same dimensions. pub trait SquareMatrix where - Self::Scalar: BaseFloat, + Self::Scalar: Float, Self: One, Self: iter::Product, @@ -543,14 +540,14 @@ where /// Test if this matrix is invertible. #[inline] - fn is_invertible(&self) -> bool { + fn is_invertible(&self) -> bool where Self::Scalar: approx::UlpsEq { ulps_ne!(self.determinant(), &Self::Scalar::zero()) } /// Test if this matrix is the identity matrix. That is, it is diagonal /// and every element in the diagonal is one. #[inline] - fn is_identity(&self) -> bool { + fn is_identity(&self) -> bool where Self: approx::UlpsEq { ulps_eq!(self, &Self::identity()) } From 8813d0b4ef009d530a1233011e668cc8c00c2f95 Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Thu, 21 May 2020 12:06:34 -0700 Subject: [PATCH 2/3] Further relax InnerSpace and is_finite BaseFloat bounds --- src/point.rs | 4 ++-- src/structure.rs | 2 +- src/vector.rs | 18 +++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/point.rs b/src/point.rs index d5aad795..5eb83c6a 100644 --- a/src/point.rs +++ b/src/point.rs @@ -17,7 +17,7 @@ //! distinguishes them from vectors, which have a length and direction, but do //! not have a fixed position. -use num_traits::{Bounded, NumCast}; +use num_traits::{Float, Bounded, NumCast}; use std::fmt; use std::mem; use std::ops::*; @@ -135,7 +135,7 @@ macro_rules! impl_point { fold_array!(mul, { $(self.$field),+ }) } - fn is_finite(&self) -> bool where S: BaseFloat { + fn is_finite(&self) -> bool where S: Float { $(self.$field.is_finite())&&+ } } diff --git a/src/structure.rs b/src/structure.rs index f7375de2..292bfb49 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -91,7 +91,7 @@ where /// Whether all elements of the array are finite fn is_finite(&self) -> bool where - Self::Element: BaseFloat; + Self::Element: Float; } /// Element-wise arithmetic operations. These are supplied for pragmatic diff --git a/src/vector.rs b/src/vector.rs index 5da7d444..40bf6c25 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use num_traits::{Bounded, NumCast}; +use num_traits::{Float, Bounded, NumCast}; #[cfg(feature = "rand")] use rand::{ distributions::{Distribution, Standard}, @@ -139,7 +139,7 @@ macro_rules! impl_vector { } } - impl MetricSpace for $VectorN { + impl MetricSpace for $VectorN { type Metric = S; #[inline] @@ -171,7 +171,7 @@ macro_rules! impl_vector { fold_array!(mul, { $(self.$field),+ }) } - fn is_finite(&self) -> bool where S: BaseFloat { + fn is_finite(&self) -> bool where S: Float { $(self.$field.is_finite())&&+ } } @@ -525,38 +525,38 @@ where V::dot(a, b) } -impl InnerSpace for Vector1 { +impl InnerSpace for Vector1 { #[inline] fn dot(self, other: Vector1) -> S { Vector1::mul_element_wise(self, other).sum() } } -impl InnerSpace for Vector2 { +impl InnerSpace for Vector2 { #[inline] fn dot(self, other: Vector2) -> S { Vector2::mul_element_wise(self, other).sum() } #[inline] - fn angle(self, other: Vector2) -> Rad { + fn angle(self, other: Vector2) -> Rad where S: BaseFloat { Rad::atan2(Self::perp_dot(self, other), Self::dot(self, other)) } } -impl InnerSpace for Vector3 { +impl InnerSpace for Vector3 { #[inline] fn dot(self, other: Vector3) -> S { Vector3::mul_element_wise(self, other).sum() } #[inline] - fn angle(self, other: Vector3) -> Rad { + fn angle(self, other: Vector3) -> Rad where S: BaseFloat { Rad::atan2(self.cross(other).magnitude(), Self::dot(self, other)) } } -impl InnerSpace for Vector4 { +impl InnerSpace for Vector4 { #[inline] fn dot(self, other: Vector4) -> S { Vector4::mul_element_wise(self, other).sum() From a92877c557b62042e2163b3d72dc95959ef09ef9 Mon Sep 17 00:00:00 2001 From: Egor Larionov Date: Fri, 22 May 2020 21:34:53 -0700 Subject: [PATCH 3/3] Remove unused commented out code --- src/structure.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/structure.rs b/src/structure.rs index 292bfb49..a5639642 100644 --- a/src/structure.rs +++ b/src/structure.rs @@ -429,9 +429,6 @@ where // FIXME: Ugly type signatures - blocked by rust-lang/rust#24092 Self: Index::Column>, Self: IndexMut::Column>, - //Self: approx::AbsDiffEq::Scalar>, - //Self: approx::RelativeEq::Scalar>, - //Self: approx::UlpsEq::Scalar>, { /// The row vector of the matrix. type Row: VectorSpace + Array;