Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax BaseFloat bounds #503

Merged
merged 3 commits into from
May 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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())&&+
}
}
Expand Down
26 changes: 10 additions & 16 deletions src/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
///
Expand All @@ -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
<Self as VectorSpace>::Scalar: BaseFloat,
Self: MetricSpace<Metric = <Self as VectorSpace>::Scalar>,
// Self: approx::AbsDiffEq<Epsilon = <Self as VectorSpace>::Scalar>,
// Self: approx::RelativeEq<Epsilon = <Self as VectorSpace>::Scalar>,
Self: approx::UlpsEq<Epsilon = <Self as VectorSpace>::Scalar>,
Self: MetricSpace<Metric = <Self as VectorSpace>::Scalar>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks so much nicer!

{
/// 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 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great 👍

ulps_eq!(Self::dot(self, other), &Self::Scalar::zero())
}

Expand All @@ -252,7 +249,7 @@ where
}

/// Returns the angle between two vectors in radians.
fn angle(self, other: Self) -> Rad<Self::Scalar> {
fn angle(self, other: Self) -> Rad<Self::Scalar> where Self::Scalar: BaseFloat {
Rad::acos(Self::dot(self, other) / (self.magnitude() * other.magnitude()))
}

Expand Down Expand Up @@ -427,14 +424,11 @@ 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<usize, Output = <Self as Matrix>::Column>,
Self: IndexMut<usize, Output = <Self as Matrix>::Column>,
Self: approx::AbsDiffEq<Epsilon = <Self as VectorSpace>::Scalar>,
Self: approx::RelativeEq<Epsilon = <Self as VectorSpace>::Scalar>,
Self: approx::UlpsEq<Epsilon = <Self as VectorSpace>::Scalar>,
{
/// The row vector of the matrix.
type Row: VectorSpace<Scalar = Self::Scalar> + Array<Element = Self::Scalar>;
Expand Down Expand Up @@ -482,7 +476,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<Self>,
Expand Down Expand Up @@ -543,14 +537,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())
}

Expand Down
18 changes: 9 additions & 9 deletions src/vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -139,7 +139,7 @@ macro_rules! impl_vector {
}
}

impl<S: BaseFloat> MetricSpace for $VectorN<S> {
impl<S: BaseNum + Float> MetricSpace for $VectorN<S> {
type Metric = S;

#[inline]
Expand Down Expand Up @@ -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())&&+
}
}
Expand Down Expand Up @@ -525,38 +525,38 @@ where
V::dot(a, b)
}

impl<S: BaseFloat> InnerSpace for Vector1<S> {
impl<S: BaseNum + Float> InnerSpace for Vector1<S> {
#[inline]
fn dot(self, other: Vector1<S>) -> S {
Vector1::mul_element_wise(self, other).sum()
}
}

impl<S: BaseFloat> InnerSpace for Vector2<S> {
impl<S: BaseNum + Float> InnerSpace for Vector2<S> {
#[inline]
fn dot(self, other: Vector2<S>) -> S {
Vector2::mul_element_wise(self, other).sum()
}

#[inline]
fn angle(self, other: Vector2<S>) -> Rad<S> {
fn angle(self, other: Vector2<S>) -> Rad<S> where S: BaseFloat {
Rad::atan2(Self::perp_dot(self, other), Self::dot(self, other))
}
}

impl<S: BaseFloat> InnerSpace for Vector3<S> {
impl<S: BaseNum + Float> InnerSpace for Vector3<S> {
#[inline]
fn dot(self, other: Vector3<S>) -> S {
Vector3::mul_element_wise(self, other).sum()
}

#[inline]
fn angle(self, other: Vector3<S>) -> Rad<S> {
fn angle(self, other: Vector3<S>) -> Rad<S> where S: BaseFloat {
Rad::atan2(self.cross(other).magnitude(), Self::dot(self, other))
}
}

impl<S: BaseFloat> InnerSpace for Vector4<S> {
impl<S: BaseNum + Float> InnerSpace for Vector4<S> {
#[inline]
fn dot(self, other: Vector4<S>) -> S {
Vector4::mul_element_wise(self, other).sum()
Expand Down