From 8e5e54d196dab11c20553fc8c51e29f24b1d9eb9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sat, 14 Jan 2023 17:55:05 +0100
Subject: [PATCH 01/33] Bump version of nalgebra-macros
---
Cargo.toml | 4 ++--
nalgebra-macros/Cargo.toml | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 03217548..47895b58 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nalgebra"
-version = "0.32.0"
+version = "0.32.1"
authors = [ "Sébastien Crozet " ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
@@ -71,7 +71,7 @@ slow-tests = []
rkyv-safe-deser = [ "rkyv-serialize", "rkyv/validation" ]
[dependencies]
-nalgebra-macros = { version = "0.1", path = "nalgebra-macros", optional = true }
+nalgebra-macros = { version = "0.2", path = "nalgebra-macros", optional = true }
typenum = "1.12"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false }
diff --git a/nalgebra-macros/Cargo.toml b/nalgebra-macros/Cargo.toml
index 041e36a7..a6a2d14c 100644
--- a/nalgebra-macros/Cargo.toml
+++ b/nalgebra-macros/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nalgebra-macros"
-version = "0.1.0"
+version = "0.2.0"
authors = [ "Andreas Longva", "Sébastien Crozet " ]
edition = "2018"
description = "Procedural macros for nalgebra"
From 52e6db99c6e3615512801d5f43d9f9c8399627d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sat, 14 Jan 2023 17:57:31 +0100
Subject: [PATCH 02/33] Release v0.32.1
---
CHANGELOG.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 71846f87..90e304a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,11 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
+## [0.32.1] (14 Jan. 2023)
+
+### Modified
+- Updated `nalgebra-macros` to use the new `Dyn`, avoiding macro-generated deprecation warnings.
+
## [0.32.0] (14 Jan. 2023)
### Modified
From fd97a82926d30f06c06029ea5bed7ecace52208a Mon Sep 17 00:00:00 2001
From: Chris Ohk
Date: Wed, 1 Feb 2023 15:48:06 +0900
Subject: [PATCH 03/33] fix: Correct minor typos
---
nalgebra-glm/src/gtc/epsilon.rs | 8 ++++----
nalgebra-glm/src/gtx/quaternion.rs | 2 +-
nalgebra-sparse/src/cs.rs | 2 +-
nalgebra-sparse/src/ops/serial/csc.rs | 2 +-
nalgebra-sparse/src/ops/serial/csr.rs | 2 +-
src/base/allocator.rs | 4 ++--
src/base/edition.rs | 2 +-
src/base/iter.rs | 2 +-
src/base/par_iter.rs | 6 +++---
src/base/uninit.rs | 2 +-
src/base/vec_storage.rs | 2 +-
src/geometry/isometry_interpolation.rs | 4 ++--
src/geometry/quaternion.rs | 2 +-
src/geometry/transform.rs | 2 +-
src/geometry/unit_complex.rs | 2 +-
src/linalg/svd.rs | 2 +-
src/sparse/cs_matrix.rs | 2 +-
tests/linalg/eigen.rs | 8 ++++----
18 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/nalgebra-glm/src/gtc/epsilon.rs b/nalgebra-glm/src/gtc/epsilon.rs
index fae29981..efe6ddd6 100644
--- a/nalgebra-glm/src/gtc/epsilon.rs
+++ b/nalgebra-glm/src/gtc/epsilon.rs
@@ -7,24 +7,24 @@ use na::DefaultAllocator;
use crate::traits::{Alloc, Number, Dimension};
use crate::aliases::TVec;
-/// Component-wise approximate equality beween two vectors.
+/// Component-wise approximate equality between two vectors.
pub fn epsilon_equal(x: &TVec, y: &TVec, epsilon: T) -> TVec
where DefaultAllocator: Alloc {
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>(x: T, y: T, epsilon: T) -> bool {
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(x: &TVec, y: &TVec, epsilon: T) -> TVec
where DefaultAllocator: Alloc {
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>(x: T, y: T, epsilon: T) -> bool {
abs_diff_ne!(x, y, epsilon = epsilon)
}
diff --git a/nalgebra-glm/src/gtx/quaternion.rs b/nalgebra-glm/src/gtx/quaternion.rs
index d4f82af2..736d3bbb 100644
--- a/nalgebra-glm/src/gtx/quaternion.rs
+++ b/nalgebra-glm/src/gtx/quaternion.rs
@@ -80,7 +80,7 @@ pub fn quat_to_mat3(x: &Qua) -> TMat3 {
.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(x: &Qua) -> TMat4 {
UnitQuaternion::new_unchecked(*x).to_homogeneous()
}
diff --git a/nalgebra-sparse/src/cs.rs b/nalgebra-sparse/src/cs.rs
index 474eb2c0..e000e2de 100644
--- a/nalgebra-sparse/src/cs.rs
+++ b/nalgebra-sparse/src/cs.rs
@@ -494,7 +494,7 @@ where
assert_eq!(source_minor_indices.len(), 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];
for minor_idx in source_minor_indices {
minor_counts[*minor_idx] += 1;
diff --git a/nalgebra-sparse/src/ops/serial/csc.rs b/nalgebra-sparse/src/ops/serial/csc.rs
index 5cf8ab23..a18cca3c 100644
--- a/nalgebra-sparse/src/ops/serial/csc.rs
+++ b/nalgebra-sparse/src/ops/serial/csc.rs
@@ -98,7 +98,7 @@ where
/// 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.
-/// 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.
pub fn spmm_csc_prealloc_unchecked(
diff --git a/nalgebra-sparse/src/ops/serial/csr.rs b/nalgebra-sparse/src/ops/serial/csr.rs
index d69bc54c..6384f26d 100644
--- a/nalgebra-sparse/src/ops/serial/csr.rs
+++ b/nalgebra-sparse/src/ops/serial/csr.rs
@@ -89,7 +89,7 @@ where
/// 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.
-/// 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.
pub fn spmm_csr_prealloc_unchecked(
diff --git a/src/base/allocator.rs b/src/base/allocator.rs
index 6458b8cb..10c4bd31 100644
--- a/src/base/allocator.rs
+++ b/src/base/allocator.rs
@@ -20,9 +20,9 @@ use std::mem::MaybeUninit;
/// Every allocator must be both static and dynamic. Though not all implementations may share the
/// same `Buffer` type.
pub trait Allocator: Any + Sized {
- /// The type of buffer this allocator can instanciate.
+ /// The type of buffer this allocator can instantiate.
type Buffer: StorageMut + 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, R, C> + IsContiguous;
/// Allocates a buffer with the given number of rows and columns without initializing its content.
diff --git a/src/base/edition.rs b/src/base/edition.rs
index e482fa24..8994eed7 100644
--- a/src/base/edition.rs
+++ b/src/base/edition.rs
@@ -1077,7 +1077,7 @@ where
}
// 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.
// Every deleted element are manually dropped by this method.
unsafe fn compress_rows(
diff --git a/src/base/iter.rs b/src/base/iter.rs
index 0e4aa8d4..b396b271 100644
--- a/src/base/iter.rs
+++ b/src/base/iter.rs
@@ -39,7 +39,7 @@ macro_rules! iterator {
let ptr = storage.$ptr();
// 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
// we don't want to call 'offset'.
// This pointer will never actually get used
diff --git a/src/base/par_iter.rs b/src/base/par_iter.rs
index af5e1cb7..c4af719a 100644
--- a/src/base/par_iter.rs
+++ b/src/base/par_iter.rs
@@ -11,7 +11,7 @@ use crate::{
use rayon::iter::plumbing::Producer;
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`].
///
/// *Only available if compiled with the feature `rayon`.*
@@ -89,7 +89,7 @@ pub struct ParColumnIterMut<
}
#[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>
where
R: Dim,
@@ -161,7 +161,7 @@ where
S: Sync,
{
/// 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`]
/// instead.
///
diff --git a/src/base/uninit.rs b/src/base/uninit.rs
index ad2759eb..401e3336 100644
--- a/src/base/uninit.rs
+++ b/src/base/uninit.rs
@@ -34,7 +34,7 @@ pub unsafe trait InitStatus: Copy {
/// A type implementing `InitStatus` indicating that the value is completely initialized.
pub struct Init;
#[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;
unsafe impl InitStatus for Init {
diff --git a/src/base/vec_storage.rs b/src/base/vec_storage.rs
index 4614598b..42c4511b 100644
--- a/src/base/vec_storage.rs
+++ b/src/base/vec_storage.rs
@@ -148,7 +148,7 @@ impl VecStorage {
};
// 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);
new_data
}
diff --git a/src/geometry/isometry_interpolation.rs b/src/geometry/isometry_interpolation.rs
index 90f2c7ae..d6c20503 100644
--- a/src/geometry/isometry_interpolation.rs
+++ b/src/geometry/isometry_interpolation.rs
@@ -42,7 +42,7 @@ impl Isometry3 {
/// Attempts to interpolate between two isometries using a linear interpolation for the translation 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).
///
/// # Examples:
@@ -118,7 +118,7 @@ impl IsometryMatrix3 {
/// Attempts to interpolate between two isometries using a linear interpolation for the translation 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).
///
/// # Examples:
diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs
index 1b251b29..bb86a6e1 100755
--- a/src/geometry/quaternion.rs
+++ b/src/geometry/quaternion.rs
@@ -1577,7 +1577,7 @@ where
#[inline]
#[must_use]
pub fn inverse_transform_point(&self, pt: &Point3) -> Point3 {
- // 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) ?
self.inverse() * pt
}
diff --git a/src/geometry/transform.rs b/src/geometry/transform.rs
index 2a7ca112..73dc8d8a 100755
--- a/src/geometry/transform.rs
+++ b/src/geometry/transform.rs
@@ -122,7 +122,7 @@ macro_rules! category_mul_impl(
)*}
);
-// We require stability uppon multiplication.
+// We require stability upon multiplication.
impl TCategoryMul for T {
type Representative = T;
}
diff --git a/src/geometry/unit_complex.rs b/src/geometry/unit_complex.rs
index 8e44f71a..d6c0ade5 100755
--- a/src/geometry/unit_complex.rs
+++ b/src/geometry/unit_complex.rs
@@ -347,7 +347,7 @@ where
#[inline]
#[must_use]
pub fn inverse_transform_point(&self, pt: &Point2) -> Point2 {
- // 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) ?
self.inverse() * pt
}
diff --git a/src/linalg/svd.rs b/src/linalg/svd.rs
index 06bae4a3..39283e24 100644
--- a/src/linalg/svd.rs
+++ b/src/linalg/svd.rs
@@ -724,7 +724,7 @@ where
/// 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.
- /// 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) {
const VALUE_PROCESSED: usize = usize::MAX;
diff --git a/src/sparse/cs_matrix.rs b/src/sparse/cs_matrix.rs
index 5b63e537..9a240ff6 100644
--- a/src/sparse/cs_matrix.rs
+++ b/src/sparse/cs_matrix.rs
@@ -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)
where
T: Zero + ClosedAdd,
diff --git a/tests/linalg/eigen.rs b/tests/linalg/eigen.rs
index 162aad6a..a5dcf835 100644
--- a/tests/linalg/eigen.rs
+++ b/tests/linalg/eigen.rs
@@ -123,7 +123,7 @@ fn symmetric_eigen_singular_24x24() {
//
// /*
// * 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.
// */
// fn eigen(n: usize) -> bool {
@@ -134,11 +134,11 @@ fn symmetric_eigen_singular_24x24() {
// 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 mut m = DMatrix::::new_random(n, n).upper_triangle();
//
-// // Suplicate some adjascent diagonal elements.
+// // Suplicate some adjacent diagonal elements.
// for i in 0 .. n / 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)
// }
//
-// 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 mut m = DMatrix::::new_random(n, n).upper_triangle();
//
From 171e92bc202424294ea4cd1c5105c9149522dd8b Mon Sep 17 00:00:00 2001
From: Edgar Geier
Date: Mon, 6 Mar 2023 23:39:38 +0100
Subject: [PATCH 04/33] Remove unnecessary parentheses
---
src/linalg/convolution.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/linalg/convolution.rs b/src/linalg/convolution.rs
index 2402bb3d..b0abe994 100644
--- a/src/linalg/convolution.rs
+++ b/src/linalg/convolution.rs
@@ -47,11 +47,11 @@ impl> Vector {
let u_f = cmp::min(i, vec - 1);
if u_i == u_f {
- conv[i] += self[u_i].clone() * kernel[(i - u_i)].clone();
+ conv[i] += self[u_i].clone() * kernel[i - u_i].clone();
} else {
for u in u_i..(u_f + 1) {
if i - u < ker {
- conv[i] += self[u].clone() * kernel[(i - u)].clone();
+ conv[i] += self[u].clone() * kernel[i - u].clone();
}
}
}
From 24dab117112dbf33478304993b77d2a6752ca72a Mon Sep 17 00:00:00 2001
From: Marijn Suijten
Date: Mon, 27 Feb 2023 11:22:27 +0100
Subject: [PATCH 05/33] Support conversion for glam 0.23
---
Cargo.toml | 2 ++
src/third_party/glam/mod.rs | 2 ++
src/third_party/glam/v023/mod.rs | 18 ++++++++++++++++++
3 files changed, 22 insertions(+)
create mode 100644 src/third_party/glam/v023/mod.rs
diff --git a/Cargo.toml b/Cargo.toml
index 47895b58..bcc8f0cd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,6 +47,7 @@ convert-glam019 = [ "glam019" ]
convert-glam020 = [ "glam020" ]
convert-glam021 = [ "glam021" ]
convert-glam022 = [ "glam022" ]
+convert-glam023 = [ "glam023" ]
# Serialization
## To use serde in a #[no-std] environment, enable the
@@ -101,6 +102,7 @@ glam019 = { package = "glam", version = "0.19", optional = true }
glam020 = { package = "glam", version = "0.20", optional = true }
glam021 = { package = "glam", version = "0.21", optional = true }
glam022 = { package = "glam", version = "0.22", optional = true }
+glam023 = { package = "glam", version = "0.23", optional = true }
cust_core = { version = "0.1", optional = true }
rayon = { version = "1.6", optional = true }
diff --git a/src/third_party/glam/mod.rs b/src/third_party/glam/mod.rs
index 811e88b2..8c250bbf 100644
--- a/src/third_party/glam/mod.rs
+++ b/src/third_party/glam/mod.rs
@@ -16,3 +16,5 @@ mod v020;
mod v021;
#[cfg(feature = "glam022")]
mod v022;
+#[cfg(feature = "glam023")]
+mod v023;
diff --git a/src/third_party/glam/v023/mod.rs b/src/third_party/glam/v023/mod.rs
new file mode 100644
index 00000000..45b1ad47
--- /dev/null
+++ b/src/third_party/glam/v023/mod.rs
@@ -0,0 +1,18 @@
+#[path = "../common/glam_isometry.rs"]
+mod glam_isometry;
+#[path = "../common/glam_matrix.rs"]
+mod glam_matrix;
+#[path = "../common/glam_point.rs"]
+mod glam_point;
+#[path = "../common/glam_quaternion.rs"]
+mod glam_quaternion;
+#[path = "../common/glam_rotation.rs"]
+mod glam_rotation;
+#[path = "../common/glam_similarity.rs"]
+mod glam_similarity;
+#[path = "../common/glam_translation.rs"]
+mod glam_translation;
+#[path = "../common/glam_unit_complex.rs"]
+mod glam_unit_complex;
+
+pub(self) use glam023 as glam;
From 4a5183ae590ba17a28803480b911eabb1690f461 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Tue, 7 Mar 2023 10:13:14 +0100
Subject: [PATCH 06/33] Release v0.32.2
---
CHANGELOG.md | 6 ++++++
Cargo.toml | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 90e304a2..cf0253aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
+
+## [0.32.2] (07 March 2023)
+
+### Added
+- Add the `glam-0.23` to enable conversion from/to type from `glam` v0.23.
+
## [0.32.1] (14 Jan. 2023)
### Modified
diff --git a/Cargo.toml b/Cargo.toml
index bcc8f0cd..1d36aeb1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nalgebra"
-version = "0.32.1"
+version = "0.32.2"
authors = [ "Sébastien Crozet " ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
From 181291cb2da581a851632aaba649ca69a7e2b51e Mon Sep 17 00:00:00 2001
From: Roland Fredenhagen
Date: Thu, 9 Mar 2023 12:41:08 +0100
Subject: [PATCH 07/33] Allow trailing punctuation in macros
---
nalgebra-macros/src/lib.rs | 2 +-
nalgebra-macros/tests/tests.rs | 13 +++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/nalgebra-macros/src/lib.rs b/nalgebra-macros/src/lib.rs
index e12139d2..827d6080 100644
--- a/nalgebra-macros/src/lib.rs
+++ b/nalgebra-macros/src/lib.rs
@@ -223,7 +223,7 @@ impl Parse for Vector {
elements: Vec::new(),
})
} else {
- let elements = MatrixRowSyntax::parse_separated_nonempty(input)?
+ let elements = MatrixRowSyntax::parse_terminated(input)?
.into_iter()
.collect();
Ok(Self { elements })
diff --git a/nalgebra-macros/tests/tests.rs b/nalgebra-macros/tests/tests.rs
index 0e52da1f..ed6353d0 100644
--- a/nalgebra-macros/tests/tests.rs
+++ b/nalgebra-macros/tests/tests.rs
@@ -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]));
}
+#[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
#[rustfmt::skip]
#[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]));
}
+#[test]
+fn vector_trailing_comma() {
+ vector![1, 2,];
+ point![1, 2,];
+ dvector![1, 2,];
+}
+
#[test]
fn matrix_trybuild_tests() {
let t = trybuild::TestCases::new();
From 5c0e773242f1c971fefe5e6be8232b5b6d4cf200 Mon Sep 17 00:00:00 2001
From: Benjamin Saunders
Date: Mon, 13 Mar 2023 22:45:27 -0700
Subject: [PATCH 08/33] Serialize statically sized matrices as tuples
Breaking change. Consistent with how serde serializes plain arrays.
---
src/base/array_storage.rs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/base/array_storage.rs b/src/base/array_storage.rs
index 5c165399..dbc5e1d5 100644
--- a/src/base/array_storage.rs
+++ b/src/base/array_storage.rs
@@ -5,7 +5,7 @@ use std::ops::Mul;
#[cfg(feature = "serde-serialize-no-std")]
use serde::de::{Error, SeqAccess, Visitor};
#[cfg(feature = "serde-serialize-no-std")]
-use serde::ser::SerializeSeq;
+use serde::ser::SerializeTuple;
#[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")]
@@ -189,7 +189,7 @@ where
where
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() {
serializer.serialize_element(e)?;
@@ -208,7 +208,7 @@ where
where
D: Deserializer<'a>,
{
- deserializer.deserialize_seq(ArrayStorageVisitor::new())
+ deserializer.deserialize_tuple(R * C, ArrayStorageVisitor::new())
}
}
From 705051f639ef438339936f094b5cfca3e6e561d3 Mon Sep 17 00:00:00 2001
From: hqurve
Date: Sat, 8 Apr 2023 10:23:20 -0400
Subject: [PATCH 09/33] fix: remove Scalar trait bound for Matrix PartialEq and
Eq
---
src/base/matrix.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/base/matrix.rs b/src/base/matrix.rs
index d4875944..418522d2 100644
--- a/src/base/matrix.rs
+++ b/src/base/matrix.rs
@@ -1859,14 +1859,14 @@ where
impl Eq for Matrix
where
- T: Scalar + Eq,
+ T: Eq,
S: RawStorage,
{
}
impl PartialEq> for Matrix
where
- T: Scalar + PartialEq,
+ T: PartialEq,
C: Dim,
C2: Dim,
R: Dim,
From 889cf2f71d37b11140ac629f6999a6a8b74a536b Mon Sep 17 00:00:00 2001
From: Zach Kozar
Date: Sat, 22 Apr 2023 11:00:29 -0400
Subject: [PATCH 10/33] Add euler_angles_ordered function on Rotation
---
src/geometry/rotation_specialization.rs | 107 ++++++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs
index 1ea5cd92..b1ee8c82 100644
--- a/src/geometry/rotation_specialization.rs
+++ b/src/geometry/rotation_specialization.rs
@@ -979,6 +979,113 @@ impl Rotation3 {
)
}
}
+
+ /// Represent this rotation as Euler angles.
+ ///
+ /// Returns the angles produced in the order provided by seq parameter, along with the
+ /// observability flag. If the rotation is gimbal locked, then the observability flag is false.
+ ///
+ /// Algorithm based on:
+ /// Malcolm D. Shuster, F. Landis Markley, “General formula for extraction the Euler
+ /// angles”, Journal of guidance, control, and dynamics, vol. 29.1, pp. 215-221. 2006,
+ /// and modified to be able to produce extrinsic rotations.
+ #[must_use]
+ pub fn euler_angles_ordered(
+ &self,
+ mut seq: [Unit>; 3],
+ extrinsic: bool,
+ ) -> (Vector3, bool)
+ where
+ T: RealField + Copy,
+ {
+ let mut angles = Vector3::zeros();
+ let eps = T::from_subset(&1e-7);
+ let _2 = T::from_subset(&2.0);
+
+ if extrinsic {
+ seq.reverse();
+ }
+
+ let [n1, n2, n3] = &seq;
+
+ let n1_c_n2 = n1.cross(n2);
+ let s1 = n1_c_n2.dot(n3);
+ let c1 = n1.dot(n3);
+ let lambda = s1.atan2(c1);
+
+ let mut c = Matrix3::zeros();
+ c.column_mut(0).copy_from(n2);
+ c.column_mut(1).copy_from(&n1_c_n2);
+ c.column_mut(2).copy_from(n1);
+ c.transpose_mut();
+
+ let r1l = Matrix3::new(
+ T::one(), T::zero(), T::zero(),
+ T::zero(), c1, s1,
+ T::zero(), -s1, c1,
+ );
+ let o_t = &c * self.matrix() * (c.transpose() * r1l);
+ angles.y = o_t.m33.acos();
+
+ let safe1 = angles.y.abs() >= eps;
+ let safe2 = (angles.y - T::pi()).abs() >= eps;
+ let observable = safe1 && safe2;
+ angles.y += lambda;
+
+ if observable {
+ angles.x = o_t.m13.atan2(-o_t.m23);
+ angles.z = o_t.m31.atan2(o_t.m32);
+ } else {
+ // gimbal lock detected
+ if extrinsic {
+ // angle1 is initialized to zero
+ if !safe1 {
+ angles.z = (o_t.m12 - o_t.m21).atan2(o_t.m11 + o_t.m22);
+ } else {
+ angles.z = -(o_t.m12 + o_t.m21).atan2(o_t.m11 - o_t.m22);
+ };
+ } else {
+ // angle3 is initialized to zero
+ if !safe1 {
+ angles.x = (o_t.m12 - o_t.m21).atan2(o_t.m11 + o_t.m22);
+ } else {
+ angles.x = (o_t.m12 + o_t.m21).atan2(o_t.m11 - o_t.m22);
+ };
+ };
+ };
+
+ let adjust = if seq[0] == seq[2] {
+ // lambda = 0, so ensure angle2 -> [0, pi]
+ angles.y < T::zero() || angles.y > T::pi()
+ } else {
+ // lamda = + or - pi/2, so ensure angle2 -> [-pi/2, pi/2]
+ angles.y < -T::frac_pi_2() || angles.y > T::frac_pi_2()
+ };
+
+ // dont adjust gimbal locked rotation
+ if adjust && observable {
+ angles.x += T::pi();
+ angles.y = _2 * lambda - angles.y;
+ angles.z -= T::pi();
+ }
+
+ // ensure all angles are within [-pi, pi]
+ for angle in angles.as_mut_slice().iter_mut() {
+ if *angle < -T::pi() {
+ *angle += T::two_pi();
+ } else if *angle > T::pi() {
+ *angle -= T::two_pi();
+ }
+ }
+
+ if extrinsic {
+ let tmp = angles.x;
+ angles.x = angles.z;
+ angles.z = tmp;
+ }
+
+ (angles, observable)
+ }
}
#[cfg(feature = "rand-no-std")]
From d9af8650bbf31eab8d0d10e974eb9ff2f2c15ed4 Mon Sep 17 00:00:00 2001
From: julianknodt
Date: Wed, 12 Apr 2023 22:48:31 -0700
Subject: [PATCH 11/33] Add `.*_scalar()` to `Matrix1`
Allows for converting a `Matrix1` to a scalar without having to index.
---
src/base/matrix.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
diff --git a/src/base/matrix.rs b/src/base/matrix.rs
index d4875944..39dd3467 100644
--- a/src/base/matrix.rs
+++ b/src/base/matrix.rs
@@ -2244,3 +2244,102 @@ where
Unit::new_unchecked(crate::convert_ref(self.as_ref()))
}
}
+
+impl Matrix
+where
+ S: RawStorage,
+{
+ /// Returns a reference to the single element in this matrix.
+ ///
+ /// As opposed to indexing, using this provides type-safety
+ /// when flattening dimensions.
+ ///
+ /// # Example
+ /// ```
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let inner_product: f32 = *(v.transpose() * v).as_scalar();
+ /// ```
+ ///
+ ///```compile_fail
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let inner_product = (v * v.transpose()).item(); // Typo, does not compile.
+ ///```
+ pub fn as_scalar(&self) -> &T {
+ &self[(0, 0)]
+ }
+ /// Get a mutable reference to the single element in this matrix
+ ///
+ /// As opposed to indexing, using this provides type-safety
+ /// when flattening dimensions.
+ ///
+ /// # Example
+ /// ```
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let mut inner_product = (v.transpose() * v);
+ /// *inner_product.as_scalar_mut() = 3.;
+ /// ```
+ ///
+ ///```compile_fail
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let mut inner_product = (v * v.transpose());
+ /// *inner_product.as_scalar_mut() = 3.;
+ ///```
+ pub fn as_scalar_mut(&mut self) -> &mut T
+ where
+ S: RawStorageMut,
+ {
+ &mut self[(0, 0)]
+ }
+ /// Convert this 1x1 matrix by reference into a scalar.
+ ///
+ /// As opposed to indexing, using this provides type-safety
+ /// when flattening dimensions.
+ ///
+ /// # Example
+ /// ```
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let mut inner_product: f32 = (v.transpose() * v).to_scalar();
+ /// ```
+ ///
+ ///```compile_fail
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let mut inner_product: f32 = (v * v.transpose()).to_scalar();
+ ///```
+ pub fn to_scalar(&self) -> T
+ where
+ T: Clone,
+ {
+ self.as_scalar().clone()
+ }
+}
+
+impl super::alias::Matrix1 {
+ /// Convert this 1x1 matrix into a scalar.
+ ///
+ /// As opposed to indexing, using this provides type-safety
+ /// when flattening dimensions.
+ ///
+ /// # Example
+ /// ```
+ /// # use nalgebra::{Vector3, Matrix2, U1};
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let inner_product: f32 = (v.transpose() * v).into_scalar();
+ /// assert_eq!(inner_product, 1.);
+ /// ```
+ ///
+ ///```compile_fail
+ /// # use nalgebra::Vector3;
+ /// let v = Vector3::new(0., 0., 1.);
+ /// let mut inner_product: f32 = (v * v.transpose()).into_scalar();
+ ///```
+ pub fn into_scalar(self) -> T {
+ let [[scalar]] = self.data.0;
+ scalar
+ }
+}
From 029bbc9ecccef33842486c664208b55aa8ea9979 Mon Sep 17 00:00:00 2001
From: Vasil Nikolov
Date: Mon, 24 Apr 2023 00:46:06 +0300
Subject: [PATCH 12/33] add unit test for variance
---
src/base/mod.rs | 2 ++
src/base/variance_test.rs | 7 +++++++
2 files changed, 9 insertions(+)
create mode 100644 src/base/variance_test.rs
diff --git a/src/base/mod.rs b/src/base/mod.rs
index 0f09cc33..1eabbfcf 100644
--- a/src/base/mod.rs
+++ b/src/base/mod.rs
@@ -64,3 +64,5 @@ pub use self::matrix_view::*;
pub use self::storage::*;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::vec_storage::*;
+
+mod variance_test;
diff --git a/src/base/variance_test.rs b/src/base/variance_test.rs
new file mode 100644
index 00000000..eec5f7e4
--- /dev/null
+++ b/src/base/variance_test.rs
@@ -0,0 +1,7 @@
+#[cfg(test)]
+use crate::DVector;
+#[test]
+fn test_variance_new() {
+ let v = DVector::repeat(10_000, 100000000.1234);
+ assert_eq!(v.variance(), 0.0)
+}
From 032002dce964391e016bf880c894993246aec6eb Mon Sep 17 00:00:00 2001
From: Vasil Nikolov
Date: Mon, 24 Apr 2023 01:22:57 +0300
Subject: [PATCH 13/33] initial, unoptimized algoritm
---
src/base/statistics.rs | 27 +++++++++++++++++++++------
src/base/variance_test.rs | 2 +-
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/src/base/statistics.rs b/src/base/statistics.rs
index 9f0e0ee6..bf2c40d8 100644
--- a/src/base/statistics.rs
+++ b/src/base/statistics.rs
@@ -335,12 +335,27 @@ impl> Matrix {
if self.is_empty() {
T::zero()
} else {
- let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
- (a.0 + b.clone() * b.clone(), a.1 + b)
- });
- let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
- let vd = val.1 * denom.clone();
- val.0 * denom - vd.clone() * vd
+ // let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
+ // (a.0 + b.clone() * b.clone(), a.1 + b)
+ // });
+ // let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
+ // let vd = val.1 * denom.clone();
+ // val.0 * denom - vd.clone() * vd
+ // let mean: T = self.iter().map(|&entry| entry).sum::();
+ //
+ // let x: Vec = (0..1000).map(|_| T::zero()).collect();
+ // let s: T = x.iter().cloned().fold(T::zero(), |a, b| a + b);
+
+ // cannot use sum since `T` is not `Sum` by trait bounds
+ let total_sum = self.iter().cloned().fold(T::zero(), |a, b| a + b);
+ let n_elements = crate::convert::<_, T>(self.len() as f64);
+ let mean = total_sum / n_elements.clone();
+
+ let variance = self.iter().cloned().fold(T::zero(), |acc, x| {
+ acc + (x.clone() - mean.clone()) * (x.clone() - mean.clone())
+ }) / n_elements.clone();
+
+ variance
}
}
diff --git a/src/base/variance_test.rs b/src/base/variance_test.rs
index eec5f7e4..af5d22af 100644
--- a/src/base/variance_test.rs
+++ b/src/base/variance_test.rs
@@ -2,6 +2,6 @@
use crate::DVector;
#[test]
fn test_variance_new() {
- let v = DVector::repeat(10_000, 100000000.1234);
+ let v = DVector::repeat(10_000, 100000000.0);
assert_eq!(v.variance(), 0.0)
}
From fc56abe4816d6d00a9db4914c568698b4ed5754b Mon Sep 17 00:00:00 2001
From: vasil
Date: Mon, 24 Apr 2023 23:22:32 +0300
Subject: [PATCH 14/33] add simple test, remove comment from old variance impl
---
src/base/statistics.rs | 17 +++--------------
src/base/variance_test.rs | 7 +++++--
2 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/src/base/statistics.rs b/src/base/statistics.rs
index bf2c40d8..ebefb49d 100644
--- a/src/base/statistics.rs
+++ b/src/base/statistics.rs
@@ -335,25 +335,14 @@ impl> Matrix {
if self.is_empty() {
T::zero()
} else {
- // let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
- // (a.0 + b.clone() * b.clone(), a.1 + b)
- // });
- // let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
- // let vd = val.1 * denom.clone();
- // val.0 * denom - vd.clone() * vd
- // let mean: T = self.iter().map(|&entry| entry).sum::();
- //
- // let x: Vec = (0..1000).map(|_| T::zero()).collect();
- // let s: T = x.iter().cloned().fold(T::zero(), |a, b| a + b);
-
// cannot use sum since `T` is not `Sum` by trait bounds
- let total_sum = self.iter().cloned().fold(T::zero(), |a, b| a + b);
+ let sum_of_elements = self.iter().cloned().fold(T::zero(), |a, b| a + b);
let n_elements = crate::convert::<_, T>(self.len() as f64);
- let mean = total_sum / n_elements.clone();
+ let mean = sum_of_elements / n_elements.clone();
let variance = self.iter().cloned().fold(T::zero(), |acc, x| {
acc + (x.clone() - mean.clone()) * (x.clone() - mean.clone())
- }) / n_elements.clone();
+ }) / n_elements;
variance
}
diff --git a/src/base/variance_test.rs b/src/base/variance_test.rs
index af5d22af..4319e156 100644
--- a/src/base/variance_test.rs
+++ b/src/base/variance_test.rs
@@ -2,6 +2,9 @@
use crate::DVector;
#[test]
fn test_variance_new() {
- let v = DVector::repeat(10_000, 100000000.0);
- assert_eq!(v.variance(), 0.0)
+ let long_repeating_vector = DVector::repeat(10_000, 100000000.0);
+ assert_eq!(long_repeating_vector.variance(), 0.0);
+
+ let short_vec = DVector::from_vec(vec![1., 2., 3.]);
+ assert_eq!(short_vec.variance(), 2.0 / 3.0)
}
From 75405b1e24ed71561b3fb9e210dfab3f4c3e0d39 Mon Sep 17 00:00:00 2001
From: vasil
Date: Tue, 25 Apr 2023 01:25:36 +0300
Subject: [PATCH 15/33] fix bug, add test in tests folder
---
src/base/mod.rs | 2 --
src/base/statistics.rs | 12 ++++--------
tests/core/mod.rs | 1 +
src/base/variance_test.rs => tests/core/variance.rs | 6 +++---
4 files changed, 8 insertions(+), 13 deletions(-)
rename src/base/variance_test.rs => tests/core/variance.rs (72%)
diff --git a/src/base/mod.rs b/src/base/mod.rs
index 1eabbfcf..0f09cc33 100644
--- a/src/base/mod.rs
+++ b/src/base/mod.rs
@@ -64,5 +64,3 @@ pub use self::matrix_view::*;
pub use self::storage::*;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::vec_storage::*;
-
-mod variance_test;
diff --git a/src/base/statistics.rs b/src/base/statistics.rs
index ebefb49d..6007f8c7 100644
--- a/src/base/statistics.rs
+++ b/src/base/statistics.rs
@@ -335,16 +335,12 @@ impl> Matrix {
if self.is_empty() {
T::zero()
} else {
- // cannot use sum since `T` is not `Sum` by trait bounds
- let sum_of_elements = self.iter().cloned().fold(T::zero(), |a, b| a + b);
- let n_elements = crate::convert::<_, T>(self.len() as f64);
- let mean = sum_of_elements / n_elements.clone();
+ let n_elements: T = crate::convert(self.len() as f64);
+ let mean = self.mean();
- let variance = self.iter().cloned().fold(T::zero(), |acc, x| {
+ self.iter().cloned().fold(T::zero(), |acc, x| {
acc + (x.clone() - mean.clone()) * (x.clone() - mean.clone())
- }) / n_elements;
-
- variance
+ }) / n_elements
}
}
diff --git a/tests/core/mod.rs b/tests/core/mod.rs
index 0f7ee85b..f0484e4d 100644
--- a/tests/core/mod.rs
+++ b/tests/core/mod.rs
@@ -11,6 +11,7 @@ mod reshape;
#[cfg(feature = "rkyv-serialize-no-std")]
mod rkyv;
mod serde;
+mod variance;
#[cfg(feature = "compare")]
mod matrixcompare;
diff --git a/src/base/variance_test.rs b/tests/core/variance.rs
similarity index 72%
rename from src/base/variance_test.rs
rename to tests/core/variance.rs
index 4319e156..c643ea3f 100644
--- a/src/base/variance_test.rs
+++ b/tests/core/variance.rs
@@ -1,10 +1,10 @@
-#[cfg(test)]
-use crate::DVector;
+use nalgebra::DVector;
#[test]
fn test_variance_new() {
let long_repeating_vector = DVector::repeat(10_000, 100000000.0);
assert_eq!(long_repeating_vector.variance(), 0.0);
let short_vec = DVector::from_vec(vec![1., 2., 3.]);
- assert_eq!(short_vec.variance(), 2.0 / 3.0)
+
+ assert_eq!(short_vec.variance(), 2.0 / 3.0);
}
From 6c241a3200d4c8879bbe6fc0c8a3f432cfb05c6f Mon Sep 17 00:00:00 2001
From: Vasil Nikolov
Date: Fri, 28 Apr 2023 00:03:28 +0300
Subject: [PATCH 16/33] add features needed to run tests with only `cargo test`
---
Cargo.toml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Cargo.toml b/Cargo.toml
index 1d36aeb1..f5c67d15 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -111,6 +111,7 @@ serde_json = "1.0"
rand_xorshift = "0.3"
rand_isaac = "0.3"
criterion = { version = "0.4", features = ["html_reports"] }
+nalgebra = { path = ".", features = ["debug", "compare", "rand", "macros"]}
# For matrix comparison macro
matrixcompare = "0.3.0"
From 151084d6448bbfbffc05d036a4743c34e3f3dc86 Mon Sep 17 00:00:00 2001
From: wisp3rwind <17089248+wisp3rwind@users.noreply.github.com>
Date: Fri, 28 Apr 2023 13:35:54 +0200
Subject: [PATCH 17/33] docs: correct row-major -> column-major for
Matrix{1-6}xX storage
cf. Github discussion https://github.com/dimforge/nalgebra/discussions/1225
---
src/base/alias.rs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/base/alias.rs b/src/base/alias.rs
index e3ac40b0..a07ea9e7 100644
--- a/src/base/alias.rs
+++ b/src/base/alias.rs
@@ -81,32 +81,32 @@ pub type MatrixXx5 = Matrix>;
#[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx6 = Matrix>;
-/// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns.
+/// A heap-allocated, column-major, matrix with 1 rows and a dynamic number of columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix1xX = Matrix>;
-/// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns.
+/// A heap-allocated, column-major, matrix with 2 rows and a dynamic number of columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix2xX = Matrix>;
-/// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns.
+/// A heap-allocated, column-major, matrix with 3 rows and a dynamic number of columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix3xX = Matrix>;
-/// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns.
+/// A heap-allocated, column-major, matrix with 4 rows and a dynamic number of columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix4xX = Matrix>;
-/// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns.
+/// A heap-allocated, column-major, matrix with 5 rows and a dynamic number of columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix5xX = Matrix>;
-/// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns.
+/// A heap-allocated, column-major, matrix with 6 rows and a dynamic number of columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))]
From 2521fd9851726797df54965c202a17c9748fd555 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sun, 30 Apr 2023 14:53:12 +0200
Subject: [PATCH 18/33] Add a couple of additional catastrophic cancellation
variance checks
---
tests/core/variance.rs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/tests/core/variance.rs b/tests/core/variance.rs
index c643ea3f..eb08ea0f 100644
--- a/tests/core/variance.rs
+++ b/tests/core/variance.rs
@@ -1,10 +1,18 @@
use nalgebra::DVector;
+
#[test]
-fn test_variance_new() {
+fn test_variance_catastrophic_cancellation() {
let long_repeating_vector = DVector::repeat(10_000, 100000000.0);
assert_eq!(long_repeating_vector.variance(), 0.0);
let short_vec = DVector::from_vec(vec![1., 2., 3.]);
-
assert_eq!(short_vec.variance(), 2.0 / 3.0);
+
+ let short_vec =
+ DVector::::from_vec(vec![1.0e8 + 4.0, 1.0e8 + 7.0, 1.0e8 + 13.0, 1.0e8 + 16.0]);
+ assert_eq!(short_vec.variance(), 22.5);
+
+ let short_vec =
+ DVector::::from_vec(vec![1.0e9 + 4.0, 1.0e9 + 7.0, 1.0e9 + 13.0, 1.0e9 + 16.0]);
+ assert_eq!(short_vec.variance(), 22.5);
}
From 41cfbdbf6249c06508a7cb74e6d8b7ef602fc2d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sun, 30 Apr 2023 14:53:59 +0200
Subject: [PATCH 19/33] Update Changelog
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf0253aa..971c5173 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
+## Unreleased
+
+### Fixed
+- Fixed severe catastrophic cancellation issue in variance calculation.
## [0.32.2] (07 March 2023)
From 033f722d4f8c931688cfeee024ba49ac69a7093d Mon Sep 17 00:00:00 2001
From: Zach Kozar
Date: Fri, 5 May 2023 00:00:25 -0400
Subject: [PATCH 20/33] Return angles as array, add requirements and examples
to doc
---
src/geometry/rotation_specialization.rs | 111 +++++++++++++++++++-----
1 file changed, 87 insertions(+), 24 deletions(-)
diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs
index b1ee8c82..ae954dd2 100644
--- a/src/geometry/rotation_specialization.rs
+++ b/src/geometry/rotation_specialization.rs
@@ -983,7 +983,64 @@ impl Rotation3 {
/// Represent this rotation as Euler angles.
///
/// Returns the angles produced in the order provided by seq parameter, along with the
- /// observability flag. If the rotation is gimbal locked, then the observability flag is false.
+ /// observability flag. The Euler axes passed to seq must form an orthonormal basis. If the
+ /// rotation is gimbal locked, then the observability flag is false.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the Euler axes in `seq` are not orthonormal.
+ ///
+ /// # Example 1:
+ /// ```
+ /// use std::f64::consts::PI;
+ /// use approx::assert_relative_eq;
+ /// use nalgebra::{Matrix3, Rotation3, Unit, Vector3};
+ ///
+ /// // 3-1-2
+ /// let n = [
+ /// Unit::new_unchecked(Vector3::new(0.0, 0.0, 1.0)),
+ /// Unit::new_unchecked(Vector3::new(1.0, 0.0, 0.0)),
+ /// Unit::new_unchecked(Vector3::new(0.0, 1.0, 0.0)),
+ /// ];
+ ///
+ /// let r1 = Rotation3::from_axis_angle(&n[2], 20.0 * PI / 180.0);
+ /// let r2 = Rotation3::from_axis_angle(&n[1], 30.0 * PI / 180.0);
+ /// let r3 = Rotation3::from_axis_angle(&n[0], 45.0 * PI / 180.0);
+ ///
+ /// let d = r3 * r2 * r1;
+ ///
+ /// let (angles, observable) = d.euler_angles_ordered(n, false);
+ /// assert!(observable);
+ /// assert_relative_eq!(angles[0] * 180.0 / PI, 45.0, epsilon = 1e-12);
+ /// assert_relative_eq!(angles[1] * 180.0 / PI, 30.0, epsilon = 1e-12);
+ /// assert_relative_eq!(angles[2] * 180.0 / PI, 20.0, epsilon = 1e-12);
+ /// ```
+ ///
+ /// # Example 2:
+ /// ```
+ /// use std::f64::consts::PI;
+ /// use approx::assert_relative_eq;
+ /// use nalgebra::{Matrix3, Rotation3, Unit, Vector3};
+ ///
+ /// let sqrt_2 = 2.0_f64.sqrt();
+ /// let n = [
+ /// Unit::new_unchecked(Vector3::new(1.0 / sqrt_2, 1.0 / sqrt_2, 0.0)),
+ /// Unit::new_unchecked(Vector3::new(1.0 / sqrt_2, -1.0 / sqrt_2, 0.0)),
+ /// Unit::new_unchecked(Vector3::new(0.0, 0.0, 1.0)),
+ /// ];
+ ///
+ /// let r1 = Rotation3::from_axis_angle(&n[2], 20.0 * PI / 180.0);
+ /// let r2 = Rotation3::from_axis_angle(&n[1], 30.0 * PI / 180.0);
+ /// let r3 = Rotation3::from_axis_angle(&n[0], 45.0 * PI / 180.0);
+ ///
+ /// let d = r3 * r2 * r1;
+ ///
+ /// let (angles, observable) = d.euler_angles_ordered(n, false);
+ /// assert!(observable);
+ /// assert_relative_eq!(angles[0] * 180.0 / PI, 45.0, epsilon = 1e-12);
+ /// assert_relative_eq!(angles[1] * 180.0 / PI, 30.0, epsilon = 1e-12);
+ /// assert_relative_eq!(angles[2] * 180.0 / PI, 20.0, epsilon = 1e-12);
+ /// ```
///
/// Algorithm based on:
/// Malcolm D. Shuster, F. Landis Markley, “General formula for extraction the Euler
@@ -994,11 +1051,11 @@ impl Rotation3 {
&self,
mut seq: [Unit>; 3],
extrinsic: bool,
- ) -> (Vector3, bool)
+ ) -> ([T; 3], bool)
where
T: RealField + Copy,
{
- let mut angles = Vector3::zeros();
+ let mut angles = [T::zero(); 3];
let eps = T::from_subset(&1e-7);
let _2 = T::from_subset(&2.0);
@@ -1007,6 +1064,8 @@ impl Rotation3 {
}
let [n1, n2, n3] = &seq;
+ assert_relative_eq!(n1.dot(n2), T::zero(), epsilon = eps);
+ assert_relative_eq!(n3.dot(n1), T::zero(), epsilon = eps);
let n1_c_n2 = n1.cross(n2);
let s1 = n1_c_n2.dot(n3);
@@ -1020,53 +1079,59 @@ impl Rotation3 {
c.transpose_mut();
let r1l = Matrix3::new(
- T::one(), T::zero(), T::zero(),
- T::zero(), c1, s1,
- T::zero(), -s1, c1,
+ T::one(),
+ T::zero(),
+ T::zero(),
+ T::zero(),
+ c1,
+ s1,
+ T::zero(),
+ -s1,
+ c1,
);
let o_t = &c * self.matrix() * (c.transpose() * r1l);
- angles.y = o_t.m33.acos();
+ angles[1] = o_t.m33.acos();
- let safe1 = angles.y.abs() >= eps;
- let safe2 = (angles.y - T::pi()).abs() >= eps;
+ let safe1 = angles[1].abs() >= eps;
+ let safe2 = (angles[1] - T::pi()).abs() >= eps;
let observable = safe1 && safe2;
- angles.y += lambda;
+ angles[1] += lambda;
if observable {
- angles.x = o_t.m13.atan2(-o_t.m23);
- angles.z = o_t.m31.atan2(o_t.m32);
+ angles[0] = o_t.m13.atan2(-o_t.m23);
+ angles[2] = o_t.m31.atan2(o_t.m32);
} else {
// gimbal lock detected
if extrinsic {
// angle1 is initialized to zero
if !safe1 {
- angles.z = (o_t.m12 - o_t.m21).atan2(o_t.m11 + o_t.m22);
+ angles[2] = (o_t.m12 - o_t.m21).atan2(o_t.m11 + o_t.m22);
} else {
- angles.z = -(o_t.m12 + o_t.m21).atan2(o_t.m11 - o_t.m22);
+ angles[2] = -(o_t.m12 + o_t.m21).atan2(o_t.m11 - o_t.m22);
};
} else {
// angle3 is initialized to zero
if !safe1 {
- angles.x = (o_t.m12 - o_t.m21).atan2(o_t.m11 + o_t.m22);
+ angles[0] = (o_t.m12 - o_t.m21).atan2(o_t.m11 + o_t.m22);
} else {
- angles.x = (o_t.m12 + o_t.m21).atan2(o_t.m11 - o_t.m22);
+ angles[0] = (o_t.m12 + o_t.m21).atan2(o_t.m11 - o_t.m22);
};
};
};
let adjust = if seq[0] == seq[2] {
// lambda = 0, so ensure angle2 -> [0, pi]
- angles.y < T::zero() || angles.y > T::pi()
+ angles[1] < T::zero() || angles[1] > T::pi()
} else {
// lamda = + or - pi/2, so ensure angle2 -> [-pi/2, pi/2]
- angles.y < -T::frac_pi_2() || angles.y > T::frac_pi_2()
+ angles[1] < -T::frac_pi_2() || angles[1] > T::frac_pi_2()
};
// dont adjust gimbal locked rotation
if adjust && observable {
- angles.x += T::pi();
- angles.y = _2 * lambda - angles.y;
- angles.z -= T::pi();
+ angles[0] += T::pi();
+ angles[1] = _2 * lambda - angles[1];
+ angles[2] -= T::pi();
}
// ensure all angles are within [-pi, pi]
@@ -1079,9 +1144,7 @@ impl Rotation3 {
}
if extrinsic {
- let tmp = angles.x;
- angles.x = angles.z;
- angles.z = tmp;
+ angles.reverse();
}
(angles, observable)
From 06782da13ef3f57ed58ec2f64c75169058696021 Mon Sep 17 00:00:00 2001
From: Doug Roeper
Date: Thu, 25 May 2023 08:10:57 -0400
Subject: [PATCH 21/33] Adds support for glam 024
---
Cargo.toml | 2 ++
src/third_party/glam/mod.rs | 2 ++
src/third_party/glam/v024/mod.rs | 18 ++++++++++++++++++
3 files changed, 22 insertions(+)
create mode 100644 src/third_party/glam/v024/mod.rs
diff --git a/Cargo.toml b/Cargo.toml
index f5c67d15..dfdc0250 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -48,6 +48,7 @@ convert-glam020 = [ "glam020" ]
convert-glam021 = [ "glam021" ]
convert-glam022 = [ "glam022" ]
convert-glam023 = [ "glam023" ]
+convert-glam024 = [ "glam024" ]
# Serialization
## To use serde in a #[no-std] environment, enable the
@@ -103,6 +104,7 @@ glam020 = { package = "glam", version = "0.20", optional = true }
glam021 = { package = "glam", version = "0.21", optional = true }
glam022 = { package = "glam", version = "0.22", optional = true }
glam023 = { package = "glam", version = "0.23", optional = true }
+glam024 = { package = "glam", version = "0.24", optional = true }
cust_core = { version = "0.1", optional = true }
rayon = { version = "1.6", optional = true }
diff --git a/src/third_party/glam/mod.rs b/src/third_party/glam/mod.rs
index 8c250bbf..b868817a 100644
--- a/src/third_party/glam/mod.rs
+++ b/src/third_party/glam/mod.rs
@@ -18,3 +18,5 @@ mod v021;
mod v022;
#[cfg(feature = "glam023")]
mod v023;
+#[cfg(feature = "glam024")]
+mod v024;
diff --git a/src/third_party/glam/v024/mod.rs b/src/third_party/glam/v024/mod.rs
new file mode 100644
index 00000000..3dae276f
--- /dev/null
+++ b/src/third_party/glam/v024/mod.rs
@@ -0,0 +1,18 @@
+#[path = "../common/glam_isometry.rs"]
+mod glam_isometry;
+#[path = "../common/glam_matrix.rs"]
+mod glam_matrix;
+#[path = "../common/glam_point.rs"]
+mod glam_point;
+#[path = "../common/glam_quaternion.rs"]
+mod glam_quaternion;
+#[path = "../common/glam_rotation.rs"]
+mod glam_rotation;
+#[path = "../common/glam_similarity.rs"]
+mod glam_similarity;
+#[path = "../common/glam_translation.rs"]
+mod glam_translation;
+#[path = "../common/glam_unit_complex.rs"]
+mod glam_unit_complex;
+
+pub(self) use glam024 as glam;
From a1fcd1cb733ef3d2b180a863540ffeb7100d364f Mon Sep 17 00:00:00 2001
From: +merlan #flirora
Date: Sat, 3 Jun 2023 03:55:36 -0400
Subject: [PATCH 22/33] Add OPoint::lerp
---
src/base/interpolation.rs | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/base/interpolation.rs b/src/base/interpolation.rs
index 81b1a374..056bea1c 100644
--- a/src/base/interpolation.rs
+++ b/src/base/interpolation.rs
@@ -1,6 +1,7 @@
use crate::storage::Storage;
use crate::{
- Allocator, DefaultAllocator, Dim, OVector, One, RealField, Scalar, Unit, Vector, Zero,
+ Allocator, DefaultAllocator, Dim, DimName, OPoint, OVector, One, RealField, Scalar, Unit,
+ Vector, Zero,
};
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
@@ -58,6 +59,30 @@ impl OPoint
+where
+ DefaultAllocator: Allocator,
+{
+ /// Returns `self * (1.0 - t) + rhs.coords * t`, i.e., the linear blend of the points x and y using the scalar value a.
+ ///
+ /// The value for a is not restricted to the range `[0, 1]`.
+ ///
+ /// # Examples:
+ ///
+ /// ```
+ /// # use nalgebra::Point3;
+ /// let x = Point3::new(1.0, 2.0, 3.0);
+ /// let y = Point3::new(10.0, 20.0, 30.0);
+ /// assert_eq!(x.lerp(&y, 0.1), Point3::new(1.9, 3.8, 5.7));
+ /// ```
+ #[must_use]
+ pub fn lerp(&self, rhs: &OPoint, t: T) -> OPoint {
+ OPoint {
+ coords: self.coords.lerp(&rhs.coords, t),
+ }
+ }
+}
+
/// # Interpolation between two unit vectors
impl> Unit> {
/// Computes the spherical linear interpolation between two unit vectors.
From f7cd897fd651fd85e080c767c4193796c2fd3b00 Mon Sep 17 00:00:00 2001
From: +merlan #flirora
Date: Sat, 3 Jun 2023 04:02:05 -0400
Subject: [PATCH 23/33] Add doc comment for new impl block
---
src/base/interpolation.rs | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/base/interpolation.rs b/src/base/interpolation.rs
index 056bea1c..e0f855e1 100644
--- a/src/base/interpolation.rs
+++ b/src/base/interpolation.rs
@@ -59,6 +59,7 @@ impl OPoint
where
DefaultAllocator: Allocator,
From 860899cd6df7a477af1a7a4c86c3ac5baaa7d06a Mon Sep 17 00:00:00 2001
From: Alexander Ekdahl
Date: Mon, 19 Jun 2023 15:20:01 +0200
Subject: [PATCH 24/33] Remove unnecessary normalization in
`Rotation3::face_towards`
`zaxis` and `xaxis` are already normalized which means `zaxis.cross(&xaxis)` should already be normalized.
---
src/geometry/rotation_specialization.rs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs
index 1ea5cd92..17001d1a 100644
--- a/src/geometry/rotation_specialization.rs
+++ b/src/geometry/rotation_specialization.rs
@@ -478,9 +478,10 @@ where
SB: Storage,
SC: Storage,
{
+ // Gram–Schmidt process
let zaxis = dir.normalize();
let xaxis = up.cross(&zaxis).normalize();
- let yaxis = zaxis.cross(&xaxis).normalize();
+ let yaxis = zaxis.cross(&xaxis);
Self::from_matrix_unchecked(SMatrix::::new(
xaxis.x.clone(),
From 0754bd28f332c271c5f62633d5a4c46a32beaf5c Mon Sep 17 00:00:00 2001
From: Hennadii Chernyshchyk
Date: Tue, 27 Jun 2023 14:02:20 +0300
Subject: [PATCH 25/33] Add `Clone` to `MatrixIter` and `MatrixIterMut`
---
src/base/iter.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/base/iter.rs b/src/base/iter.rs
index b396b271..a076bd99 100644
--- a/src/base/iter.rs
+++ b/src/base/iter.rs
@@ -17,7 +17,7 @@ use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar};
macro_rules! iterator {
(struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
/// An iterator through a dense matrix with arbitrary strides matrix.
- #[derive(Debug)]
+ #[derive(Clone, Debug)]
pub struct $Name<'a, T, R: Dim, C: Dim, S: 'a + $Storage> {
ptr: $Ptr,
inner_ptr: $Ptr,
From 1e38e6f59534ce77201515c07960a314d08341a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sat, 8 Jul 2023 14:55:16 +0200
Subject: [PATCH 26/33] Mote Point::lerp to the point.rs file.
---
src/base/interpolation.rs | 28 +---------------------------
src/geometry/point.rs | 28 +++++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/src/base/interpolation.rs b/src/base/interpolation.rs
index e0f855e1..81b1a374 100644
--- a/src/base/interpolation.rs
+++ b/src/base/interpolation.rs
@@ -1,7 +1,6 @@
use crate::storage::Storage;
use crate::{
- Allocator, DefaultAllocator, Dim, DimName, OPoint, OVector, One, RealField, Scalar, Unit,
- Vector, Zero,
+ Allocator, DefaultAllocator, Dim, OVector, One, RealField, Scalar, Unit, Vector, Zero,
};
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
@@ -59,31 +58,6 @@ impl OPoint
-where
- DefaultAllocator: Allocator,
-{
- /// Returns `self * (1.0 - t) + rhs.coords * t`, i.e., the linear blend of the points x and y using the scalar value a.
- ///
- /// The value for a is not restricted to the range `[0, 1]`.
- ///
- /// # Examples:
- ///
- /// ```
- /// # use nalgebra::Point3;
- /// let x = Point3::new(1.0, 2.0, 3.0);
- /// let y = Point3::new(10.0, 20.0, 30.0);
- /// assert_eq!(x.lerp(&y, 0.1), Point3::new(1.9, 3.8, 5.7));
- /// ```
- #[must_use]
- pub fn lerp(&self, rhs: &OPoint, t: T) -> OPoint {
- OPoint {
- coords: self.coords.lerp(&rhs.coords, t),
- }
- }
-}
-
/// # Interpolation between two unit vectors
impl> Unit> {
/// Computes the spherical linear interpolation between two unit vectors.
diff --git a/src/geometry/point.rs b/src/geometry/point.rs
index 71ace3a9..8e950816 100644
--- a/src/geometry/point.rs
+++ b/src/geometry/point.rs
@@ -1,5 +1,5 @@
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
-use num::One;
+use num::{One, Zero};
use std::cmp::Ordering;
use std::fmt;
use std::hash;
@@ -13,6 +13,7 @@ use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1};
use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::{Const, DefaultAllocator, OVector, Scalar};
+use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
use std::mem::MaybeUninit;
/// A point in an euclidean space.
@@ -221,6 +222,31 @@ where
unsafe { res.assume_init() }
}
+ /// Linear interpolation between two points.
+ ///
+ /// Returns `self * (1.0 - t) + rhs.coords * t`, i.e., the linear blend of the points
+ /// `self` and `rhs` using the scalar value `t`.
+ ///
+ /// The value for a is not restricted to the range `[0, 1]`.
+ ///
+ /// # Examples:
+ ///
+ /// ```
+ /// # use nalgebra::Point3;
+ /// let a = Point3::new(1.0, 2.0, 3.0);
+ /// let b = Point3::new(10.0, 20.0, 30.0);
+ /// assert_eq!(a.lerp(&b, 0.1), Point3::new(1.9, 3.8, 5.7));
+ /// ```
+ #[must_use]
+ pub fn lerp(&self, rhs: &OPoint, t: T) -> OPoint
+ where
+ T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul,
+ {
+ OPoint {
+ coords: self.coords.lerp(&rhs.coords, t),
+ }
+ }
+
/// Creates a new point with the given coordinates.
#[deprecated(note = "Use Point::from(vector) instead.")]
#[inline]
From 922b0dbfa3b623e8362a599985eda7cc8ab851e0 Mon Sep 17 00:00:00 2001
From: Hennadii Chernyshchyk
Date: Sat, 8 Jul 2023 17:47:53 +0300
Subject: [PATCH 27/33] Derive Clone only on non-mutable version
---
src/base/iter.rs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/base/iter.rs b/src/base/iter.rs
index a076bd99..ebffdb07 100644
--- a/src/base/iter.rs
+++ b/src/base/iter.rs
@@ -15,9 +15,9 @@ use crate::base::storage::{RawStorage, RawStorageMut};
use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar};
macro_rules! iterator {
- (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
+ (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty, $($derives:ident),* $(,)?) => {
/// An iterator through a dense matrix with arbitrary strides matrix.
- #[derive(Clone, Debug)]
+ #[derive($($derives),*)]
pub struct $Name<'a, T, R: Dim, C: Dim, S: 'a + $Storage> {
ptr: $Ptr,
inner_ptr: $Ptr,
@@ -177,8 +177,8 @@ macro_rules! iterator {
};
}
-iterator!(struct MatrixIter for RawStorage.ptr -> *const T, &'a T, &'a S);
-iterator!(struct MatrixIterMut for RawStorageMut.ptr_mut -> *mut T, &'a mut T, &'a mut S);
+iterator!(struct MatrixIter for RawStorage.ptr -> *const T, &'a T, &'a S, Clone, Debug);
+iterator!(struct MatrixIterMut for RawStorageMut.ptr_mut -> *mut T, &'a mut T, &'a mut S, Debug);
/*
*
From c63503de04d905d6a8df8dc3c41a2e080ba060d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sun, 9 Jul 2023 11:36:44 +0200
Subject: [PATCH 28/33] chore: remove explicit bytecheck dependency
---
Cargo.toml | 5 ++---
src/base/array_storage.rs | 3 +++
src/base/dimension.rs | 2 ++
src/base/matrix.rs | 2 ++
src/base/unit.rs | 3 +++
src/geometry/dual_quaternion.rs | 3 +++
src/geometry/isometry.rs | 3 +++
src/geometry/orthographic.rs | 3 +++
src/geometry/perspective.rs | 3 +++
src/geometry/point.rs | 2 ++
src/geometry/quaternion.rs | 3 +++
src/geometry/rotation.rs | 3 +++
src/geometry/scale.rs | 3 +++
src/geometry/similarity.rs | 3 +++
src/geometry/translation.rs | 3 +++
15 files changed, 41 insertions(+), 3 deletions(-)
mode change 100755 => 100644 src/geometry/isometry.rs
mode change 100755 => 100644 src/geometry/quaternion.rs
mode change 100755 => 100644 src/geometry/rotation.rs
mode change 100755 => 100644 src/geometry/scale.rs
mode change 100755 => 100644 src/geometry/similarity.rs
mode change 100755 => 100644 src/geometry/translation.rs
diff --git a/Cargo.toml b/Cargo.toml
index dfdc0250..4839cd2e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -58,7 +58,7 @@ convert-glam024 = [ "glam024" ]
serde-serialize-no-std = [ "serde", "num-complex/serde" ]
serde-serialize = [ "serde-serialize-no-std", "serde/std" ]
rkyv-serialize-no-std = [ "rkyv/size_32" ]
-rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "rkyv/validation", "bytecheck" ]
+rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "rkyv/validation" ]
# Randomness
## To use rand in a #[no-std] environment, enable the
@@ -85,8 +85,7 @@ alga = { version = "0.9", default-features = false, optional = true }
rand_distr = { version = "0.4", default-features = false, optional = true }
matrixmultiply = { version = "0.3", optional = true }
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
-rkyv = { version = "0.7", default-features = false, optional = true }
-bytecheck = { version = "~0.6.1", optional = true }
+rkyv = { version = "0.7.41", default-features = false, optional = true }
mint = { version = "0.5", optional = true }
quickcheck = { version = "1", optional = true }
pest = { version = "2", optional = true }
diff --git a/src/base/array_storage.rs b/src/base/array_storage.rs
index dbc5e1d5..56e88d47 100644
--- a/src/base/array_storage.rs
+++ b/src/base/array_storage.rs
@@ -11,6 +11,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")]
use std::marker::PhantomData;
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Const, ToTypenum};
diff --git a/src/base/dimension.rs b/src/base/dimension.rs
index 97616129..11743dd8 100644
--- a/src/base/dimension.rs
+++ b/src/base/dimension.rs
@@ -8,6 +8,8 @@ use std::fmt::Debug;
use std::ops::{Add, Div, Mul, Sub};
use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
#[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
diff --git a/src/base/matrix.rs b/src/base/matrix.rs
index dcac7423..af5609df 100644
--- a/src/base/matrix.rs
+++ b/src/base/matrix.rs
@@ -13,6 +13,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "rkyv-serialize-no-std")]
use super::rkyv_wrappers::CustomPhantom;
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
#[cfg(feature = "rkyv-serialize-no-std")]
use rkyv::{with::With, Archive, Archived};
diff --git a/src/base/unit.rs b/src/base/unit.rs
index 2fc51107..12c70963 100644
--- a/src/base/unit.rs
+++ b/src/base/unit.rs
@@ -9,6 +9,9 @@ use crate::base::DefaultAllocator;
use crate::storage::RawStorage;
use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealField};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A wrapper that ensures the underlying algebraic entity has a unit norm.
///
/// **It is likely that the only piece of documentation that you need in this page are:**
diff --git a/src/geometry/dual_quaternion.rs b/src/geometry/dual_quaternion.rs
index bae04f46..2272b622 100644
--- a/src/geometry/dual_quaternion.rs
+++ b/src/geometry/dual_quaternion.rs
@@ -1,6 +1,9 @@
// The macros break if the references are taken out, for some reason.
#![allow(clippy::op_ref)]
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
use crate::{
Isometry3, Matrix4, Normed, OVector, Point3, Quaternion, Scalar, SimdRealField, Translation3,
Unit, UnitQuaternion, Vector3, Zero, U8,
diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs
old mode 100755
new mode 100644
index e3f44075..376af06f
--- a/src/geometry/isometry.rs
+++ b/src/geometry/isometry.rs
@@ -14,6 +14,9 @@ use crate::base::storage::Owned;
use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar, Unit};
use crate::geometry::{AbstractRotation, Point, Translation};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A direct isometry, i.e., a rotation followed by a translation (aka. a rigid-body motion).
///
/// This is also known as an element of a Special Euclidean (SE) group.
diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs
index 06d0b471..2d809fe4 100644
--- a/src/geometry/orthographic.rs
+++ b/src/geometry/orthographic.rs
@@ -17,6 +17,9 @@ use crate::base::{Matrix4, Vector, Vector3};
use crate::geometry::{Point3, Projective3};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A 3D orthographic projection stored as a homogeneous 4x4 matrix.
#[repr(C)]
#[cfg_attr(
diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs
index a5fc19a8..383c99b9 100644
--- a/src/geometry/perspective.rs
+++ b/src/geometry/perspective.rs
@@ -18,6 +18,9 @@ use crate::base::{Matrix4, Vector, Vector3};
use crate::geometry::{Point3, Projective3};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A 3D perspective projection stored as a homogeneous 4x4 matrix.
#[repr(C)]
#[cfg_attr(
diff --git a/src/geometry/point.rs b/src/geometry/point.rs
index 8e950816..e936c3da 100644
--- a/src/geometry/point.rs
+++ b/src/geometry/point.rs
@@ -4,6 +4,8 @@ use std::cmp::Ordering;
use std::fmt;
use std::hash;
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
#[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs
old mode 100755
new mode 100644
index bb86a6e1..7dcbce51
--- a/src/geometry/quaternion.rs
+++ b/src/geometry/quaternion.rs
@@ -19,6 +19,9 @@ use crate::base::{
use crate::geometry::{Point3, Rotation};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A quaternion. See the type alias `UnitQuaternion = Unit` for a quaternion
/// that may be used as a rotation.
#[repr(C)]
diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs
old mode 100755
new mode 100644
index 5eceec21..67a242cb
--- a/src/geometry/rotation.rs
+++ b/src/geometry/rotation.rs
@@ -17,6 +17,9 @@ use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{Const, DefaultAllocator, OMatrix, SMatrix, SVector, Scalar, Unit};
use crate::geometry::Point;
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A rotation matrix.
///
/// This is also known as an element of a Special Orthogonal (SO) group.
diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs
old mode 100755
new mode 100644
index 36a68066..c95c0967
--- a/src/geometry/scale.rs
+++ b/src/geometry/scale.rs
@@ -15,6 +15,9 @@ use crate::ClosedMul;
use crate::geometry::Point;
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A scale which supports non-uniform scaling.
#[repr(C)]
#[cfg_attr(
diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs
old mode 100755
new mode 100644
index 989b721b..4d931947
--- a/src/geometry/similarity.rs
+++ b/src/geometry/similarity.rs
@@ -15,6 +15,9 @@ use crate::base::storage::Owned;
use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar};
use crate::geometry::{AbstractRotation, Isometry, Point, Translation};
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation.
#[repr(C)]
#[derive(Debug, Copy, Clone)]
diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs
old mode 100755
new mode 100644
index 39fae3b6..4fc50777
--- a/src/geometry/translation.rs
+++ b/src/geometry/translation.rs
@@ -15,6 +15,9 @@ use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar};
use crate::geometry::Point;
+#[cfg(feature = "rkyv-serialize")]
+use rkyv::bytecheck;
+
/// A translation.
#[repr(C)]
#[cfg_attr(
From a6b3700473e938119252d32e0e9f1d3f91436e47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sun, 9 Jul 2023 12:03:39 +0200
Subject: [PATCH 29/33] Release v0.32.3
---
CHANGELOG.md | 13 +++++++++++++
Cargo.toml | 4 ++--
README.md | 19 -------------------
3 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 971c5173..4e9aa18f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,19 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## Unreleased
+### Modified
+- Statically sized matrices are now serialized as tuples to match how serde
+ serialized plain arrays.
+- Don’t require `Scalar` for matrix `PartialEq` and `Eq`.
+
+### Added
+- Allow trailing punctuation in macros `vector!`, `matrix!`, `point!`, etc.
+- Add the methods `Matrix1::as_scalar`, `::as_scalar_mut`, `::to_scalar`, `::into_scalar`.
+- Add `Rotation3::euler_angles_ordered`, a generalized euler angles calculation.
+- Add the `glam-0.24` feature to enable conversion from/to types from `glam` v0.24.
+- Add the `lerp` method to points.
+- Implement `Clone` for `MatrixIter`.
+
### Fixed
- Fixed severe catastrophic cancellation issue in variance calculation.
diff --git a/Cargo.toml b/Cargo.toml
index 4839cd2e..8e4a8cc9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nalgebra"
-version = "0.32.2"
+version = "0.32.3"
authors = [ "Sébastien Crozet " ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
@@ -73,7 +73,7 @@ slow-tests = []
rkyv-safe-deser = [ "rkyv-serialize", "rkyv/validation" ]
[dependencies]
-nalgebra-macros = { version = "0.2", path = "nalgebra-macros", optional = true }
+nalgebra-macros = { version = "0.2.1", path = "nalgebra-macros", optional = true }
typenum = "1.12"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false }
diff --git a/README.md b/README.md
index 62ab4759..857c84f2 100644
--- a/README.md
+++ b/README.md
@@ -29,22 +29,3 @@
-----
-
-## Acknowledgements
-nalgebra is supported by our **platinum** sponsors:
-
-
-
-
-
-
-And our gold sponsors:
-
-
-
-
-
-
-
-
-
\ No newline at end of file
From e977ad8774d5a6dbd62f0542ffbc32f345494fc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sun, 9 Jul 2023 12:04:59 +0200
Subject: [PATCH 30/33] Release nalgebra-macro v0.2.1
---
nalgebra-macros/Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nalgebra-macros/Cargo.toml b/nalgebra-macros/Cargo.toml
index a6a2d14c..8124ec78 100644
--- a/nalgebra-macros/Cargo.toml
+++ b/nalgebra-macros/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nalgebra-macros"
-version = "0.2.0"
+version = "0.2.1"
authors = [ "Andreas Longva", "Sébastien Crozet " ]
edition = "2018"
description = "Procedural macros for nalgebra"
From 706caf52c3a9648e1012999ea313169eb9980206 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Sun, 9 Jul 2023 12:35:05 +0200
Subject: [PATCH 31/33] Update CHANGELOG
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e9aa18f..b73ea701 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
-## Unreleased
+## [0.32.3] (09 July 2023)
### Modified
- Statically sized matrices are now serialized as tuples to match how serde
From 980dd68e6870fb85de575eed51ccab95dadcd352 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Mon, 19 Feb 2024 10:53:08 +0100
Subject: [PATCH 32/33] Support Glam 0.25 type conversion
---
CHANGELOG.md | 3 +++
Cargo.toml | 2 ++
src/third_party/glam/mod.rs | 2 ++
src/third_party/glam/v025/mod.rs | 18 ++++++++++++++++++
4 files changed, 25 insertions(+)
create mode 100644 src/third_party/glam/v025/mod.rs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b73ea701..e5b81265 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,9 @@ documented here.
This project adheres to [Semantic Versioning](https://semver.org/).
+## [0.32.4] (19 Feb 2023)
+- Add the `glam-0.25` feature to enable conversion from/to types from `glam` v0.25.
+
## [0.32.3] (09 July 2023)
### Modified
diff --git a/Cargo.toml b/Cargo.toml
index 8e4a8cc9..7efa660d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -49,6 +49,7 @@ convert-glam021 = [ "glam021" ]
convert-glam022 = [ "glam022" ]
convert-glam023 = [ "glam023" ]
convert-glam024 = [ "glam024" ]
+convert-glam025 = [ "glam025" ]
# Serialization
## To use serde in a #[no-std] environment, enable the
@@ -104,6 +105,7 @@ glam021 = { package = "glam", version = "0.21", optional = true }
glam022 = { package = "glam", version = "0.22", optional = true }
glam023 = { package = "glam", version = "0.23", optional = true }
glam024 = { package = "glam", version = "0.24", optional = true }
+glam025 = { package = "glam", version = "0.25", optional = true }
cust_core = { version = "0.1", optional = true }
rayon = { version = "1.6", optional = true }
diff --git a/src/third_party/glam/mod.rs b/src/third_party/glam/mod.rs
index b868817a..680e65e5 100644
--- a/src/third_party/glam/mod.rs
+++ b/src/third_party/glam/mod.rs
@@ -20,3 +20,5 @@ mod v022;
mod v023;
#[cfg(feature = "glam024")]
mod v024;
+#[cfg(feature = "glam025")]
+mod v025;
diff --git a/src/third_party/glam/v025/mod.rs b/src/third_party/glam/v025/mod.rs
new file mode 100644
index 00000000..b9f41e34
--- /dev/null
+++ b/src/third_party/glam/v025/mod.rs
@@ -0,0 +1,18 @@
+#[path = "../common/glam_isometry.rs"]
+mod glam_isometry;
+#[path = "../common/glam_matrix.rs"]
+mod glam_matrix;
+#[path = "../common/glam_point.rs"]
+mod glam_point;
+#[path = "../common/glam_quaternion.rs"]
+mod glam_quaternion;
+#[path = "../common/glam_rotation.rs"]
+mod glam_rotation;
+#[path = "../common/glam_similarity.rs"]
+mod glam_similarity;
+#[path = "../common/glam_translation.rs"]
+mod glam_translation;
+#[path = "../common/glam_unit_complex.rs"]
+mod glam_unit_complex;
+
+pub(self) use glam025 as glam;
From e726b65fd7c85c2578a2f39e2634b601af3bedd1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Crozet?=
Date: Mon, 19 Feb 2024 10:55:01 +0100
Subject: [PATCH 33/33] Release v0.32.4
---
Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Cargo.toml b/Cargo.toml
index 7efa660d..b62c4579 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nalgebra"
-version = "0.32.3"
+version = "0.32.4"
authors = [ "Sébastien Crozet " ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."