Merge branch 'dimforge:dev' into dev

This commit is contained in:
Matteo Carnelos 2023-04-19 13:27:28 +02:00 committed by GitHub
commit 1d4d92edb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 47 additions and 34 deletions

View File

@ -7,24 +7,24 @@ use na::DefaultAllocator;
use crate::traits::{Alloc, Number, Dimension}; use crate::traits::{Alloc, Number, Dimension};
use crate::aliases::TVec; use crate::aliases::TVec;
/// Component-wise approximate equality beween two vectors. /// Component-wise approximate equality between two vectors.
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D> pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
where DefaultAllocator: Alloc<T, D> { where DefaultAllocator: Alloc<T, D> {
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
} }
/// Component-wise approximate equality beween two scalars. /// Component-wise approximate equality between two scalars.
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool { pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
abs_diff_eq!(x, y, epsilon = epsilon) abs_diff_eq!(x, y, epsilon = epsilon)
} }
/// Component-wise approximate non-equality beween two vectors. /// Component-wise approximate non-equality between two vectors.
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D> pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
where DefaultAllocator: Alloc<T, D> { where DefaultAllocator: Alloc<T, D> {
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
} }
/// Component-wise approximate non-equality beween two scalars. /// Component-wise approximate non-equality between two scalars.
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool { pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
abs_diff_ne!(x, y, epsilon = epsilon) abs_diff_ne!(x, y, epsilon = epsilon)
} }

View File

@ -80,7 +80,7 @@ pub fn quat_to_mat3<T: RealNumber>(x: &Qua<T>) -> TMat3<T> {
.into_inner() .into_inner()
} }
/// Converts a quaternion to a rotation matrix in homogenous coordinates. /// Converts a quaternion to a rotation matrix in homogeneous coordinates.
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> { pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
UnitQuaternion::new_unchecked(*x).to_homogeneous() UnitQuaternion::new_unchecked(*x).to_homogeneous()
} }

View File

@ -223,7 +223,7 @@ impl Parse for Vector {
elements: Vec::new(), elements: Vec::new(),
}) })
} else { } else {
let elements = MatrixRowSyntax::parse_separated_nonempty(input)? let elements = MatrixRowSyntax::parse_terminated(input)?
.into_iter() .into_iter()
.collect(); .collect();
Ok(Self { elements }) Ok(Self { elements })

View File

@ -94,6 +94,12 @@ fn dmatrix_small_dims_exhaustive() {
DMatrix::from_row_slice(4, 4, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])); DMatrix::from_row_slice(4, 4, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));
} }
#[test]
fn matrix_trailing_semi() {
matrix![1, 2;];
dmatrix![1, 2;];
}
// Skip rustfmt because it just makes the test bloated without making it more readable // Skip rustfmt because it just makes the test bloated without making it more readable
#[rustfmt::skip] #[rustfmt::skip]
#[test] #[test]
@ -151,6 +157,13 @@ fn dvector_small_dims_exhaustive() {
assert_eq_and_type!(dvector![1, 2, 3, 4, 5, 6], DVector::from_column_slice(&[1, 2, 3, 4, 5, 6])); assert_eq_and_type!(dvector![1, 2, 3, 4, 5, 6], DVector::from_column_slice(&[1, 2, 3, 4, 5, 6]));
} }
#[test]
fn vector_trailing_comma() {
vector![1, 2,];
point![1, 2,];
dvector![1, 2,];
}
#[test] #[test]
fn matrix_trybuild_tests() { fn matrix_trybuild_tests() {
let t = trybuild::TestCases::new(); let t = trybuild::TestCases::new();

View File

@ -494,7 +494,7 @@ where
assert_eq!(source_minor_indices.len(), values.len()); assert_eq!(source_minor_indices.len(), values.len());
let nnz = values.len(); let nnz = values.len();
// Count the number of occurences of each minor index // Count the number of occurrences of each minor index
let mut minor_counts = vec![0; minor_dim]; let mut minor_counts = vec![0; minor_dim];
for minor_idx in source_minor_indices { for minor_idx in source_minor_indices {
minor_counts[*minor_idx] += 1; minor_counts[*minor_idx] += 1;

View File

@ -98,7 +98,7 @@ where
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`. /// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
/// This will not return an error even if the patterns don't match. /// This will not return an error even if the patterns don't match.
/// Should be used for situations where pattern creation immediately preceeds multiplication. /// Should be used for situations where pattern creation immediately precedes multiplication.
/// ///
/// Panics if the dimensions of the matrices involved are not compatible with the expression. /// Panics if the dimensions of the matrices involved are not compatible with the expression.
pub fn spmm_csc_prealloc_unchecked<T>( pub fn spmm_csc_prealloc_unchecked<T>(

View File

@ -89,7 +89,7 @@ where
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`. /// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
/// This will not return an error even if the patterns don't match. /// This will not return an error even if the patterns don't match.
/// Should be used for situations where pattern creation immediately preceeds multiplication. /// Should be used for situations where pattern creation immediately precedes multiplication.
/// ///
/// Panics if the dimensions of the matrices involved are not compatible with the expression. /// Panics if the dimensions of the matrices involved are not compatible with the expression.
pub fn spmm_csr_prealloc_unchecked<T>( pub fn spmm_csr_prealloc_unchecked<T>(

View File

@ -20,9 +20,9 @@ use std::mem::MaybeUninit;
/// Every allocator must be both static and dynamic. Though not all implementations may share the /// Every allocator must be both static and dynamic. Though not all implementations may share the
/// same `Buffer` type. /// same `Buffer` type.
pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized { pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
/// The type of buffer this allocator can instanciate. /// The type of buffer this allocator can instantiate.
type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug; type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
/// The type of buffer with uninitialized components this allocator can instanciate. /// The type of buffer with uninitialized components this allocator can instantiate.
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous; type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
/// Allocates a buffer with the given number of rows and columns without initializing its content. /// Allocates a buffer with the given number of rows and columns without initializing its content.

View File

@ -5,7 +5,7 @@ use std::ops::Mul;
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::de::{Error, SeqAccess, Visitor}; use serde::de::{Error, SeqAccess, Visitor};
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::ser::SerializeSeq; use serde::ser::SerializeTuple;
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
@ -189,7 +189,7 @@ where
where where
S: Serializer, S: Serializer,
{ {
let mut serializer = serializer.serialize_seq(Some(R * C))?; let mut serializer = serializer.serialize_tuple(R * C)?;
for e in self.as_slice().iter() { for e in self.as_slice().iter() {
serializer.serialize_element(e)?; serializer.serialize_element(e)?;
@ -208,7 +208,7 @@ where
where where
D: Deserializer<'a>, D: Deserializer<'a>,
{ {
deserializer.deserialize_seq(ArrayStorageVisitor::new()) deserializer.deserialize_tuple(R * C, ArrayStorageVisitor::new())
} }
} }

View File

@ -1077,7 +1077,7 @@ where
} }
// Move the elements of `data` in such a way that the matrix with // Move the elements of `data` in such a way that the matrix with
// the rows `[i, i + nremove[` deleted is represented in a contigous // the rows `[i, i + nremove[` deleted is represented in a contiguous
// way in `data` after this method completes. // way in `data` after this method completes.
// Every deleted element are manually dropped by this method. // Every deleted element are manually dropped by this method.
unsafe fn compress_rows<T: Scalar>( unsafe fn compress_rows<T: Scalar>(

View File

@ -39,7 +39,7 @@ macro_rules! iterator {
let ptr = storage.$ptr(); let ptr = storage.$ptr();
// If we have a size of 0, 'ptr' must be // If we have a size of 0, 'ptr' must be
// dangling. Howver, 'inner_offset' might // dangling. However, 'inner_offset' might
// not be zero if only one dimension is zero, so // not be zero if only one dimension is zero, so
// we don't want to call 'offset'. // we don't want to call 'offset'.
// This pointer will never actually get used // This pointer will never actually get used

View File

@ -1860,14 +1860,14 @@ where
impl<T, R: Dim, C: Dim, S> Eq for Matrix<T, R, C, S> impl<T, R: Dim, C: Dim, S> Eq for Matrix<T, R, C, S>
where where
T: Scalar + Eq, T: Eq,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
{ {
} }
impl<T, R, R2, C, C2, S, S2> PartialEq<Matrix<T, R2, C2, S2>> for Matrix<T, R, C, S> impl<T, R, R2, C, C2, S, S2> PartialEq<Matrix<T, R2, C2, S2>> for Matrix<T, R, C, S>
where where
T: Scalar + PartialEq, T: PartialEq,
C: Dim, C: Dim,
C2: Dim, C2: Dim,
R: Dim, R: Dim,

View File

@ -11,7 +11,7 @@ use crate::{
use rayon::iter::plumbing::Producer; use rayon::iter::plumbing::Producer;
use rayon::{iter::plumbing::bridge, prelude::*}; use rayon::{iter::plumbing::bridge, prelude::*};
/// A rayon parallel iterator over the colums of a matrix. It is created /// A rayon parallel iterator over the columns of a matrix. It is created
/// using the [`par_column_iter`] method of [`Matrix`]. /// using the [`par_column_iter`] method of [`Matrix`].
/// ///
/// *Only available if compiled with the feature `rayon`.* /// *Only available if compiled with the feature `rayon`.*
@ -89,7 +89,7 @@ pub struct ParColumnIterMut<
} }
#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] #[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))]
/// *only availabe if compiled with the feature `rayon`* /// *only available if compiled with the feature `rayon`*
impl<'a, T, R, Cols, S> ParColumnIterMut<'a, T, R, Cols, S> impl<'a, T, R, Cols, S> ParColumnIterMut<'a, T, R, Cols, S>
where where
R: Dim, R: Dim,
@ -161,7 +161,7 @@ where
S: Sync, S: Sync,
{ {
/// Iterate through the columns of the matrix in parallel using rayon. /// Iterate through the columns of the matrix in parallel using rayon.
/// This iterates over *immutable* references ot the columns of the matrix, /// This iterates over *immutable* references to the columns of the matrix,
/// if *mutable* access to the columns is required, use [`par_column_iter_mut`] /// if *mutable* access to the columns is required, use [`par_column_iter_mut`]
/// instead. /// instead.
/// ///

View File

@ -34,7 +34,7 @@ pub unsafe trait InitStatus<T>: Copy {
/// A type implementing `InitStatus` indicating that the value is completely initialized. /// A type implementing `InitStatus` indicating that the value is completely initialized.
pub struct Init; pub struct Init;
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
/// A type implementing `InitStatus` indicating that the value is completely unitialized. /// A type implementing `InitStatus` indicating that the value is completely uninitialized.
pub struct Uninit; pub struct Uninit;
unsafe impl<T> InitStatus<T> for Init { unsafe impl<T> InitStatus<T> for Init {

View File

@ -148,7 +148,7 @@ impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
}; };
// Avoid double-free by forgetting `self` because its data buffer has // Avoid double-free by forgetting `self` because its data buffer has
// been transfered to `new_data`. // been transferred to `new_data`.
std::mem::forget(self); std::mem::forget(self);
new_data new_data
} }

View File

@ -42,7 +42,7 @@ impl<T: SimdRealField> Isometry3<T> {
/// Attempts to interpolate between two isometries using a linear interpolation for the translation part, /// Attempts to interpolate between two isometries using a linear interpolation for the translation part,
/// and a spherical interpolation for the rotation part. /// and a spherical interpolation for the rotation part.
/// ///
/// Retuns `None` if the angle between both rotations is 180 degrees (in which case the interpolation /// Returns `None` if the angle between both rotations is 180 degrees (in which case the interpolation
/// is not well-defined). /// is not well-defined).
/// ///
/// # Examples: /// # Examples:
@ -118,7 +118,7 @@ impl<T: SimdRealField> IsometryMatrix3<T> {
/// Attempts to interpolate between two isometries using a linear interpolation for the translation part, /// Attempts to interpolate between two isometries using a linear interpolation for the translation part,
/// and a spherical interpolation for the rotation part. /// and a spherical interpolation for the rotation part.
/// ///
/// Retuns `None` if the angle between both rotations is 180 degrees (in which case the interpolation /// Returns `None` if the angle between both rotations is 180 degrees (in which case the interpolation
/// is not well-defined). /// is not well-defined).
/// ///
/// # Examples: /// # Examples:

View File

@ -1577,7 +1577,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> { pub fn inverse_transform_point(&self, pt: &Point3<T>) -> Point3<T> {
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement // TODO: would it be useful performance-wise not to call inverse explicitly (i-e. implement
// the inverse transformation explicitly here) ? // the inverse transformation explicitly here) ?
self.inverse() * pt self.inverse() * pt
} }

View File

@ -122,7 +122,7 @@ macro_rules! category_mul_impl(
)*} )*}
); );
// We require stability uppon multiplication. // We require stability upon multiplication.
impl<T: TCategory> TCategoryMul<T> for T { impl<T: TCategory> TCategoryMul<T> for T {
type Representative = T; type Representative = T;
} }

View File

@ -347,7 +347,7 @@ where
#[inline] #[inline]
#[must_use] #[must_use]
pub fn inverse_transform_point(&self, pt: &Point2<T>) -> Point2<T> { pub fn inverse_transform_point(&self, pt: &Point2<T>) -> Point2<T> {
// TODO: would it be useful performancewise not to call inverse explicitly (i-e. implement // TODO: would it be useful performance-wise not to call inverse explicitly (i-e. implement
// the inverse transformation explicitly here) ? // the inverse transformation explicitly here) ?
self.inverse() * pt self.inverse() * pt
} }

View File

@ -724,7 +724,7 @@ where
/// Sort the estimated components of the SVD by its singular values in descending order. /// Sort the estimated components of the SVD by its singular values in descending order.
/// Such an ordering is often implicitly required when the decompositions are used for estimation or fitting purposes. /// Such an ordering is often implicitly required when the decompositions are used for estimation or fitting purposes.
/// Using this function is only required if `new_unordered` or `try_new_unorderd` were used and the specific sorting is required afterward. /// Using this function is only required if `new_unordered` or `try_new_unordered` were used and the specific sorting is required afterward.
pub fn sort_by_singular_values(&mut self) { pub fn sort_by_singular_values(&mut self) {
const VALUE_PROCESSED: usize = usize::MAX; const VALUE_PROCESSED: usize = usize::MAX;

View File

@ -498,7 +498,7 @@ where
} }
} }
// Remove dupliate entries on a sorted CsMatrix. // Remove duplicate entries on a sorted CsMatrix.
pub(crate) fn dedup(&mut self) pub(crate) fn dedup(&mut self)
where where
T: Zero + ClosedAdd, T: Zero + ClosedAdd,

View File

@ -123,7 +123,7 @@ fn symmetric_eigen_singular_24x24() {
// //
// /* // /*
// * NOTE: for the following tests, we use only upper-triangular matrices. // * NOTE: for the following tests, we use only upper-triangular matrices.
// * Thes ensures the schur decomposition will work, and allows use to test the eigenvector // * This ensures the schur decomposition will work, and allows use to test the eigenvector
// * computation. // * computation.
// */ // */
// fn eigen(n: usize) -> bool { // fn eigen(n: usize) -> bool {
@ -134,11 +134,11 @@ fn symmetric_eigen_singular_24x24() {
// verify_eigenvectors(m, eig) // verify_eigenvectors(m, eig)
// } // }
// //
// fn eigen_with_adjascent_duplicate_diagonals(n: usize) -> bool { // fn eigen_with_adjacent_duplicate_diagonals(n: usize) -> bool {
// let n = cmp::max(1, cmp::min(n, 10)); // let n = cmp::max(1, cmp::min(n, 10));
// let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle(); // let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle();
// //
// // Suplicate some adjascent diagonal elements. // // Suplicate some adjacent diagonal elements.
// for i in 0 .. n / 2 { // for i in 0 .. n / 2 {
// m[(i * 2 + 1, i * 2 + 1)] = m[(i * 2, i * 2)]; // m[(i * 2 + 1, i * 2 + 1)] = m[(i * 2, i * 2)];
// } // }
@ -147,7 +147,7 @@ fn symmetric_eigen_singular_24x24() {
// verify_eigenvectors(m, eig) // verify_eigenvectors(m, eig)
// } // }
// //
// fn eigen_with_nonadjascent_duplicate_diagonals(n: usize) -> bool { // fn eigen_with_nonadjacent_duplicate_diagonals(n: usize) -> bool {
// let n = cmp::max(3, cmp::min(n, 10)); // let n = cmp::max(3, cmp::min(n, 10));
// let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle(); // let mut m = DMatrix::<f64>::new_random(n, n).upper_triangle();
// //