From 9e3bd9bcd803aa9a1b8c2aa7de12e9feb39dde7d Mon Sep 17 00:00:00 2001 From: Sean Olson Date: Fri, 22 Nov 2024 14:59:05 -0800 Subject: [PATCH] Upgrade non-integration dependencies. This change updates core dependencies to their latest versions at time of writing. This includes `ndarray`, which now provides more stable LAPACK builds on a larger variety of targets. --- Cargo.toml | 23 ++++++------ README.md | 3 +- src/adjunct.rs | 28 +++++++-------- src/integration/cgmath.rs | 15 ++++---- src/integration/mint.rs | 2 +- src/integration/nalgebra.rs | 5 +-- src/lapack.rs | 5 ++- src/lib.rs | 2 +- src/ops.rs | 2 +- src/query.rs | 71 +++++++++++++++++-------------------- src/space.rs | 6 ++-- 11 files changed, 80 insertions(+), 82 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7505afa..07491d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,11 +38,11 @@ lapack = [ ] [dependencies] -approx = "^0.3.0" -decorum = "^0.3.0" -itertools = "^0.9.0" -num = "^0.3.0" -typenum = "^1.10.0" +approx = "^0.5.0" +decorum = "^0.4.0" +itertools = "^0.13.0" +num = "^0.4.0" +typenum = "^1.17.0" # Integrations. @@ -68,16 +68,13 @@ optional = true # Platform-specific features. -[target.'cfg(target_os = "linux")'.dependencies.ndarray] -version = "^0.13.0" +[target.'cfg(target_arch = "x86_64")'.dependencies.ndarray] +version = "^0.15.0" optional = true -# LAPACK packages are difficult to distribute. MKL appears to build reliably on -# Linux, but does not support Windows and yields strange results on MacOS. The -# other supported packages require a more complex build environment. -[target.'cfg(target_os = "linux")'.dependencies.ndarray-linalg] -version = "^0.12.0" -features = ["intel-mkl"] +[target.'cfg(target_arch = "x86_64")'.dependencies.ndarray-linalg] +version = "^0.16.0" +features = ["intel-mkl-static"] optional = true [dev-dependencies] diff --git a/README.md b/README.md index 98124af..fe90401 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,8 @@ To support these queries, the `lapack` feature depends on [`ndarray`] and `lapack` feature and computes a best-fit plane using a singular value decomposition. -The `lapack` feature only supports Linux at this time. +The `lapack` feature can only be used with the `x86_64` architecture on Linux, +MacOS, and Windows. [space]: https://en.wikipedia.org/wiki/euclidean_space [lapack]: https://en.wikipedia.org/wiki/lapack diff --git a/src/adjunct.rs b/src/adjunct.rs index a943a24..9971a76 100644 --- a/src/adjunct.rs +++ b/src/adjunct.rs @@ -13,8 +13,8 @@ //! and other traits are provided for `nalgebra` types when the //! `geometry-nalgebra` feature is enabled. -use decorum::cmp::{self, IntrinsicOrd}; -use num::{Bounded, One, Zero}; +use decorum::cmp::{self, EmptyOrd}; +use num::traits::{Bounded, One, Zero}; use std::ops::{Add, Mul}; pub trait Adjunct: Sized { @@ -85,20 +85,20 @@ pub trait ZipMap::Item>: Adjunct { self.zip_map(other, |a, b| a * b) } - fn per_item_min_or_undefined(self, other: Self) -> Self::Output + fn per_item_min_or_empty(self, other: Self) -> Self::Output where Self: Adjunct, - T: IntrinsicOrd, + T: EmptyOrd, { - self.zip_map(other, cmp::min_or_undefined) + self.zip_map(other, cmp::min_or_empty) } - fn per_item_max_or_undefined(self, other: Self) -> Self::Output + fn per_item_max_or_empty(self, other: Self) -> Self::Output where Self: Adjunct, - T: IntrinsicOrd, + T: EmptyOrd, { - self.zip_map(other, cmp::max_or_undefined) + self.zip_map(other, cmp::max_or_empty) } } @@ -121,18 +121,18 @@ pub trait Fold: Adjunct { self.fold(One::one(), |product, n| product * n) } - fn min_or_undefined(self) -> Self::Item + fn min_or_empty(self) -> Self::Item where - Self::Item: Bounded + IntrinsicOrd, + Self::Item: Bounded + EmptyOrd, { - self.fold(Bounded::max_value(), cmp::min_or_undefined) + self.fold(Bounded::max_value(), cmp::min_or_empty) } - fn max_or_undefined(self) -> Self::Item + fn max_or_empty(self) -> Self::Item where - Self::Item: Bounded + IntrinsicOrd, + Self::Item: Bounded + EmptyOrd, { - self.fold(Bounded::min_value(), cmp::max_or_undefined) + self.fold(Bounded::min_value(), cmp::max_or_empty) } fn any(self, mut f: F) -> bool diff --git a/src/integration/cgmath.rs b/src/integration/cgmath.rs index eda821d..89c1a74 100644 --- a/src/integration/cgmath.rs +++ b/src/integration/cgmath.rs @@ -2,8 +2,9 @@ use approx::AbsDiffEq; use cgmath::{BaseFloat, BaseNum, Point2, Point3, Vector2, Vector3, Vector4}; -use decorum::{Real, R64}; -use num::{Num, NumCast}; +use decorum::R64; +use num::traits::real::Real; +use num::traits::{Num, NumCast}; use typenum::consts::{U2, U3, U4}; use crate::adjunct::{ @@ -319,11 +320,11 @@ where type ProjectiveSpace = Vector4; } -impl InnerSpace for Vector2 where T: BaseFloat + Real {} +impl InnerSpace for Vector2 where T: AbsDiffEq + BaseFloat + Real {} -impl InnerSpace for Vector3 where T: BaseFloat + Real {} +impl InnerSpace for Vector3 where T: AbsDiffEq + BaseFloat + Real {} -impl InnerSpace for Vector4 where T: BaseFloat + Real {} +impl InnerSpace for Vector4 where T: AbsDiffEq + BaseFloat + Real {} impl Interpolate for Vector2 where @@ -612,7 +613,7 @@ impl Extend> for Point2 { impl EuclideanSpace for Point2 where - T: BaseFloat + Real, + T: AbsDiffEq + BaseFloat + Real, { type CoordinateSpace = Vector2; @@ -623,7 +624,7 @@ where impl EuclideanSpace for Point3 where - T: BaseFloat + Real, + T: AbsDiffEq + BaseFloat + Real, { type CoordinateSpace = Vector3; diff --git a/src/integration/mint.rs b/src/integration/mint.rs index a1dd4fc..da07792 100644 --- a/src/integration/mint.rs +++ b/src/integration/mint.rs @@ -6,7 +6,7 @@ use decorum::R64; use mint::{Point2, Point3, Vector2, Vector3}; -use num::{Num, NumCast, One, Zero}; +use num::traits::{Num, NumCast, One, Zero}; use std::ops::Neg; use typenum::{U2, U3}; diff --git a/src/integration/nalgebra.rs b/src/integration/nalgebra.rs index b6c9ba6..2d76318 100644 --- a/src/integration/nalgebra.rs +++ b/src/integration/nalgebra.rs @@ -1,7 +1,7 @@ #![cfg(feature = "geometry-nalgebra")] use approx::AbsDiffEq; -use decorum::{Real, R64}; +use decorum::R64; use nalgebra::base::allocator::Allocator; use nalgebra::base::default_allocator::DefaultAllocator; use nalgebra::base::dimension::{ @@ -12,7 +12,8 @@ use nalgebra::base::{ Matrix2, Matrix3, MatrixMN, RowVector2, RowVector3, Scalar, Vector2, Vector3, Vector4, VectorN, }; use nalgebra::geometry::{Point, Point2, Point3}; -use num::{Num, NumCast, One, Zero}; +use num::traits::real::Real; +use num::traits::{Num, NumCast, One, Zero}; use std::ops::{AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use typenum::NonZero; diff --git a/src/lapack.rs b/src/lapack.rs index 650ef9f..b730feb 100644 --- a/src/lapack.rs +++ b/src/lapack.rs @@ -46,7 +46,10 @@ where let columns = columns.as_ref(); let n = columns.len(); convert::into_matrix( - MatrixLayout::F((n as i32, ::N::USIZE as i32)), + MatrixLayout::F { + col: n as i32, + lda: ::N::USIZE as i32, + }, columns .iter() .map(f) diff --git a/src/lib.rs b/src/lib.rs index d9402ef..4ea0037 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,7 @@ pub mod space; mod integration; use decorum::R64; -use num::{self, Num, NumCast, One, Zero}; +use num::traits::{Num, NumCast, One, Zero}; use crate::space::EuclideanSpace; diff --git a/src/ops.rs b/src/ops.rs index dab9652..ae5120b 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -16,7 +16,7 @@ pub trait Interpolate: Sized { fn lerp(self, other: T, f: R64) -> Self::Output; fn midpoint(self, other: T) -> Self::Output { - self.lerp(other, 0.5.into()) + self.lerp(other, R64::assert(0.5)) } } diff --git a/src/query.rs b/src/query.rs index 1083106..52340df 100644 --- a/src/query.rs +++ b/src/query.rs @@ -3,9 +3,10 @@ //! This module provides types and traits for performing spatial queries. use approx::abs_diff_eq; -use decorum::cmp::IntrinsicOrd; -use decorum::Infinite; -use num::{Bounded, Signed, Zero}; +use decorum::cmp::EmptyOrd; +use decorum::InfinityEncoding; +use num::traits::real::Real; +use num::traits::{Bounded, Signed, Zero}; use std::fmt::{self, Debug, Formatter}; use std::ops::Neg; use typenum::type_operators::Cmp; @@ -642,13 +643,13 @@ where pub fn from_points(points: I) -> Self where I: IntoIterator, - Scalar: IntrinsicOrd, + Scalar: EmptyOrd, { let mut min = S::origin(); let mut max = S::origin(); for point in points { - min = min.per_item_min_or_undefined(point); - max = max.per_item_max_or_undefined(point); + min = min.per_item_min_or_empty(point); + max = max.per_item_max_or_empty(point); } Aabb { origin: min, @@ -662,16 +663,16 @@ where pub fn upper_bound(&self) -> S where - Scalar: IntrinsicOrd, + Scalar: EmptyOrd, { - self.origin.per_item_max_or_undefined(self.endpoint()) + self.origin.per_item_max_or_empty(self.endpoint()) } pub fn lower_bound(&self) -> S where - Scalar: IntrinsicOrd, + Scalar: EmptyOrd, { - self.origin.per_item_min_or_undefined(self.endpoint()) + self.origin.per_item_min_or_empty(self.endpoint()) } /// Gets the Lebesgue measure ($n$-dimensional volume) of the bounding box. @@ -686,15 +687,10 @@ where pub fn union(&self, aabb: &Self) -> Self where - Scalar: IntrinsicOrd, + Scalar: EmptyOrd, { - let origin = self - .lower_bound() - .per_item_min_or_undefined(aabb.lower_bound()); - let extent = self - .upper_bound() - .per_item_max_or_undefined(aabb.upper_bound()) - - origin; + let origin = self.lower_bound().per_item_min_or_empty(aabb.lower_bound()); + let extent = self.upper_bound().per_item_max_or_empty(aabb.upper_bound()) - origin; Aabb { origin, extent } } } @@ -729,14 +725,14 @@ where impl Intersection for Aabb where S: EuclideanSpace, - Scalar: IntrinsicOrd + Signed, + Scalar: EmptyOrd + Signed, { type Output = Vector; fn intersection(&self, point: &S) -> Option { let aabb = self; - let lower = aabb.lower_bound().per_item_max_or_undefined(*point); - let upper = aabb.upper_bound().per_item_min_or_undefined(*point); + let lower = aabb.lower_bound().per_item_max_or_empty(*point); + let upper = aabb.upper_bound().per_item_min_or_empty(*point); if lower == upper { Some(*point - aabb.lower_bound()) } @@ -751,19 +747,19 @@ impl_symmetrical_intersection!(Aabb); impl Intersection> for Aabb where S: EuclideanSpace, - Scalar: IntrinsicOrd + Signed, + Scalar: EmptyOrd + Signed, { type Output = Self; fn intersection(&self, other: &Aabb) -> Option { let max_lower_bound = self .lower_bound() - .per_item_max_or_undefined(other.lower_bound()); + .per_item_max_or_empty(other.lower_bound()); let min_upper_bound = self .upper_bound() - .per_item_min_or_undefined(other.upper_bound()); + .per_item_min_or_empty(other.upper_bound()); let difference = min_upper_bound - max_lower_bound; - if difference.all(|x| (!x.is_undefined()) && x.is_positive()) { + if difference.all(|x| (!x.is_empty()) && x.is_positive()) { Some(Aabb { origin: max_lower_bound, extent: difference, @@ -779,7 +775,7 @@ where impl Intersection> for Aabb where S: EuclideanSpace, - Scalar: Bounded + Infinite + IntrinsicOrd + Signed, + Scalar: Bounded + EmptyOrd + InfinityEncoding + Signed, { /// The minimum and maximum _times of impact_ of the intersection. /// @@ -833,13 +829,9 @@ where let direction = *ray.direction.get(); let origin = (aabb.origin - ray.origin).zip_map(direction, pdiv); let endpoint = ((aabb.endpoint()) - ray.origin).zip_map(direction, pdiv); - let min = origin - .per_item_min_or_undefined(endpoint) - .max_or_undefined(); - let max = origin - .per_item_max_or_undefined(endpoint) - .min_or_undefined(); - if max.is_negative() || min > max || min.is_undefined() || max.is_undefined() { + let min = origin.per_item_min_or_empty(endpoint).max_or_empty(); + let max = origin.per_item_max_or_empty(endpoint).min_or_empty(); + if max.is_negative() || min > max || min.is_empty() || max.is_empty() { None } else { @@ -969,13 +961,16 @@ impl_symmetrical_intersection!(Plane, Ray); #[cfg(all(test, feature = "geometry-nalgebra"))] mod tests { - use decorum::N64; + use decorum::real::UnaryRealFunction; + use decorum::ExtendedReal; use nalgebra::{Point2, Point3}; use crate::adjunct::Converged; use crate::query::{Aabb, Intersection, Line, LineLine, Plane, PlaneRay, Ray, Unit}; use crate::space::{EuclideanSpace, Vector, VectorSpace}; + type X64 = ExtendedReal; + type E2 = Point2; type E3 = Point3; @@ -1051,15 +1046,15 @@ mod tests { // intersection of `Aabb` and `Ray`. #[test] fn aabb_ray_intersection_nan() { - let aabb = Aabb::> { + let aabb = Aabb::> { origin: EuclideanSpace::origin(), - extent: Converged::converged(1.0.into()), + extent: Converged::converged(X64::ONE), }; - let ray = Ray::> { + let ray = Ray::> { origin: EuclideanSpace::origin(), direction: Unit::x(), }; - assert_eq!(Some((0.0.into(), 1.0.into())), ray.intersection(&aabb)); + assert_eq!(Some((X64::ZERO, X64::ONE)), ray.intersection(&aabb)); } #[test] diff --git a/src/space.rs b/src/space.rs index bcb3b70..d3d0ce2 100644 --- a/src/space.rs +++ b/src/space.rs @@ -1,8 +1,8 @@ //! Vector and affine spaces. use approx::AbsDiffEq; -use decorum::Real; -use num::{NumCast, One, Zero}; +use num::traits::real::Real; +use num::traits::{NumCast, One, Zero}; use std::ops::{Add, Mul, Neg, Sub}; use typenum::consts::{U0, U1, U2, U3}; use typenum::type_operators::Cmp; @@ -95,7 +95,7 @@ pub trait VectorSpace: + Neg + ZipMap<::Scalar, Output = Self> { - type Scalar: AbsDiffEq + NumCast + Real; + type Scalar: AbsDiffEq + Copy + NumCast + Real; fn scalar_component(&self, index: usize) -> Option;