diff --git a/.github/workflows/nalgebra-ci-build.yml b/.github/workflows/nalgebra-ci-build.yml index c00b6cbc..d7027127 100644 --- a/.github/workflows/nalgebra-ci-build.yml +++ b/.github/workflows/nalgebra-ci-build.yml @@ -50,7 +50,7 @@ jobs: runs-on: ubuntu-latest steps: # Needed because the --all-features build which enables cuda support. - - uses: Jimver/cuda-toolkit@v0.2.4 + - uses: Jimver/cuda-toolkit@v0.2.8 - uses: actions/checkout@v2 - run: cargo build --all-features; - run: cargo build -p nalgebra-glm --all-features; @@ -61,7 +61,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: test - run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests; + run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests,rkyv-safe-deser,rayon; test-nalgebra-glm: runs-on: ubuntu-latest steps: @@ -123,9 +123,9 @@ jobs: build-cuda: runs-on: ubuntu-latest steps: - - uses: Jimver/cuda-toolkit@v0.2.4 + - uses: Jimver/cuda-toolkit@v0.2.8 with: - cuda: '11.2.2' + cuda: '11.5.0' - name: Install nightly-2021-12-04 uses: actions-rs/toolchain@v1 with: @@ -136,4 +136,10 @@ jobs: - run: cargo build --no-default-features --features cuda - run: cargo build --no-default-features --features cuda --target=nvptx64-nvidia-cuda env: - CUDA_ARCH: "350" \ No newline at end of file + CUDA_ARCH: "350" + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Generate documentation + run: cargo doc diff --git a/CHANGELOG.md b/CHANGELOG.md index e035e084..71846f87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,43 @@ documented here. This project adheres to [Semantic Versioning](https://semver.org/). +## [0.32.0] (14 Jan. 2023) + +### Modified +- Renamed all `MatrixSlice` types to `MatrixView`. In general all occurrences of the world `Slice` or `slice` have been + replaced by `View` or `view`. +- Deprecated all the types involving `Slice` in its name, in favor of the word `View`. +- Make it so that most `nalgebra` objects archive as themselves (when using `rkyv` for serialization). +- Renamed `Dynamic` to `Dyn` and make `Dyn` a tuple struct. + +### Added +- Add `Cholesky::ln_determinant` to compute the natural logarithm of the determinant of a matrix decomposed + with Cholesky. This can be more numerically stable than computing the determinant itself when very small and/or + large values are involved. +- Added new methods `Matrix::as_view` and `Matrix::as_view_mut`, which are very useful when working with view-based APIs. +- Added parallel column iterator using `rayon`: `Matrix::par_column_iter` and `Matrix::par_column_iter_mut`. The `rayon` + feature must be enabled to access these methods. +- Implement `ReshapableStorage` for matrix slices (only for unit strides at the moment). +- Add `U0, U1, …` constants alongside the `U0, U1, …` types. This lets us write `U4` instead of `U4::name()` or + `Const::<4>` when we need const dimensions. + +### Fixed +- Fixed the implementation of `Rotation3::euler_angles` to return the angles in the documented order (roll, pitch, yaw). + +## [0.31.4] (13 Nov. 2022) + +### Added +- Add a `convert-glam022` feature to enable conversion between `nalgebra` and `glam v0.22`. + + +## [0.31.3] (30 Oct. 2022) + +### Added +- Add `Matrix::try_cast` to attempt casting the inner scalar types when that cast may fail. + +### Fixed +- Fixed the usage of `CheckBytes` with `rkyv`. + ## [0.31.2] (09 Oct. 2022) ### Modified diff --git a/Cargo.toml b/Cargo.toml index 89de73e5..03217548 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nalgebra" -version = "0.31.2" +version = "0.32.0" authors = [ "Sébastien Crozet " ] description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices." @@ -34,6 +34,7 @@ libm-force = [ "simba/libm_force" ] macros = [ "nalgebra-macros" ] cuda = [ "cust_core", "simba/cuda" ] + # Conversion convert-mint = [ "mint" ] convert-bytemuck = [ "bytemuck" ] @@ -45,6 +46,7 @@ convert-glam018 = [ "glam018" ] convert-glam019 = [ "glam019" ] convert-glam020 = [ "glam020" ] convert-glam021 = [ "glam021" ] +convert-glam022 = [ "glam022" ] # Serialization ## To use serde in a #[no-std] environment, enable the @@ -53,8 +55,8 @@ convert-glam021 = [ "glam021" ] ## `serde-serialize`. serde-serialize-no-std = [ "serde", "num-complex/serde" ] serde-serialize = [ "serde-serialize-no-std", "serde/std" ] -rkyv-serialize-no-std = [ "rkyv" ] -rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "bytecheck" ] +rkyv-serialize-no-std = [ "rkyv/size_32" ] +rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "rkyv/validation", "bytecheck" ] # Randomness ## To use rand in a #[no-std] environment, enable the @@ -66,6 +68,7 @@ rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand arbitrary = [ "quickcheck" ] proptest-support = [ "proptest" ] slow-tests = [] +rkyv-safe-deser = [ "rkyv-serialize", "rkyv/validation" ] [dependencies] nalgebra-macros = { version = "0.1", path = "nalgebra-macros", optional = true } @@ -75,12 +78,12 @@ num-traits = { version = "0.2", default-features = false } num-complex = { version = "0.4", default-features = false } num-rational = { version = "0.4", default-features = false } approx = { version = "0.5", default-features = false } -simba = { version = "0.7", default-features = false } +simba = { version = "0.8", default-features = false } 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.1", optional = true } +rkyv = { version = "0.7", default-features = false, optional = true } bytecheck = { version = "~0.6.1", optional = true } mint = { version = "0.5", optional = true } quickcheck = { version = "1", optional = true } @@ -97,14 +100,15 @@ glam018 = { package = "glam", version = "0.18", optional = true } 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 } cust_core = { version = "0.1", optional = true } - +rayon = { version = "1.6", optional = true } [dev-dependencies] serde_json = "1.0" rand_xorshift = "0.3" rand_isaac = "0.3" -criterion = { version = "0.3", features = ["html_reports"] } +criterion = { version = "0.4", features = ["html_reports"] } # For matrix comparison macro matrixcompare = "0.3.0" @@ -134,4 +138,5 @@ lto = true [package.metadata.docs.rs] # Enable all the features when building the docs on docs.rs all-features = true - +# define the configuration attribute `docsrs` +rustdoc-args = ["--cfg", "docsrs"] diff --git a/benches/core/matrix.rs b/benches/core/matrix.rs index 3c483c35..8f3d6305 100644 --- a/benches/core/matrix.rs +++ b/benches/core/matrix.rs @@ -53,7 +53,7 @@ fn mat_div_scalar(b: &mut criterion::Criterion) { b.bench_function("mat_div_scalar", move |bh| { bh.iter(|| { let mut aa = a.clone(); - let mut b = aa.slice_mut((0, 0), (1000, 1000)); + let mut b = aa.view_mut((0, 0), (1000, 1000)); b /= n }) }); diff --git a/examples/cargo/Cargo.toml b/examples/cargo/Cargo.toml index 63e70aab..2e9d4f23 100644 --- a/examples/cargo/Cargo.toml +++ b/examples/cargo/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" authors = [ "You" ] [dependencies] -nalgebra = "0.31.0" +nalgebra = "0.32.0" [[bin]] name = "example" diff --git a/examples/reshaping.rs b/examples/reshaping.rs index b2178e79..78f7bcd5 100644 --- a/examples/reshaping.rs +++ b/examples/reshaping.rs @@ -2,7 +2,7 @@ extern crate nalgebra as na; -use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const}; +use na::{DMatrix, Dyn, Matrix2x3, Matrix3x2, Const}; fn main() { // Matrices can be reshaped in-place without moving or copying values. @@ -46,9 +46,9 @@ fn main() { ], ); - let dm3 = dm1.reshape_generic(Dynamic::new(6), Dynamic::new(2)); + let dm3 = dm1.reshape_generic(Dyn(6), Dyn(2)); assert_eq!(dm3, dm2); // Invalid reshapings of dynamic matrices will panic at run-time. - //let dm4 = dm3.reshape_generic(Dynamic::new(6), Dynamic::new(6)); + //let dm4 = dm3.reshape_generic(Dyn(6), Dyn(6)); } diff --git a/nalgebra-glm/Cargo.toml b/nalgebra-glm/Cargo.toml index e700af37..3f9c4dd9 100644 --- a/nalgebra-glm/Cargo.toml +++ b/nalgebra-glm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nalgebra-glm" -version = "0.17.0" +version = "0.18.0" authors = ["sebcrozet "] description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library." @@ -35,5 +35,5 @@ convert-glam018 = [ "nalgebra/glam018" ] [dependencies] num-traits = { version = "0.2", default-features = false } approx = { version = "0.5", default-features = false } -simba = { version = "0.7", default-features = false } -nalgebra = { path = "..", version = "0.31", default-features = false } +simba = { version = "0.8", default-features = false } +nalgebra = { path = "..", version = "0.32", default-features = false } diff --git a/nalgebra-glm/src/gtx/quaternion.rs b/nalgebra-glm/src/gtx/quaternion.rs index f912c409..d4f82af2 100644 --- a/nalgebra-glm/src/gtx/quaternion.rs +++ b/nalgebra-glm/src/gtx/quaternion.rs @@ -93,6 +93,6 @@ pub fn mat3_to_quat(x: &TMat3) -> Qua { /// Converts a rotation matrix in homogeneous coordinates to a quaternion. pub fn to_quat(x: &TMat4) -> Qua { - let rot = x.fixed_slice::<3, 3>(0, 0).into_owned(); + let rot = x.fixed_view::<3, 3>(0, 0).into_owned(); mat3_to_quat(&rot) } diff --git a/nalgebra-glm/src/gtx/transform2.rs b/nalgebra-glm/src/gtx/transform2.rs index f389e4b1..56f736d7 100644 --- a/nalgebra-glm/src/gtx/transform2.rs +++ b/nalgebra-glm/src/gtx/transform2.rs @@ -7,7 +7,7 @@ pub fn proj2d(m: &TMat3, normal: &TVec2) -> TMat3 { let mut res = TMat3::identity(); { - let mut part = res.fixed_slice_mut::<2, 2>(0, 0); + let mut part = res.fixed_view_mut::<2, 2>(0, 0); part -= normal * normal.transpose(); } @@ -19,7 +19,7 @@ pub fn proj(m: &TMat4, normal: &TVec3) -> TMat4 { let mut res = TMat4::identity(); { - let mut part = res.fixed_slice_mut::<3, 3>(0, 0); + let mut part = res.fixed_view_mut::<3, 3>(0, 0); part -= normal * normal.transpose(); } @@ -31,7 +31,7 @@ pub fn reflect2d(m: &TMat3, normal: &TVec2) -> TMat3 { let mut res = TMat3::identity(); { - let mut part = res.fixed_slice_mut::<2, 2>(0, 0); + let mut part = res.fixed_view_mut::<2, 2>(0, 0); part -= (normal * T::from_subset(&2.0)) * normal.transpose(); } @@ -43,7 +43,7 @@ pub fn reflect(m: &TMat4, normal: &TVec3) -> TMat4 { let mut res = TMat4::identity(); { - let mut part = res.fixed_slice_mut::<3, 3>(0, 0); + let mut part = res.fixed_view_mut::<3, 3>(0, 0); part -= (normal * T::from_subset(&2.0)) * normal.transpose(); } diff --git a/nalgebra-lapack/Cargo.toml b/nalgebra-lapack/Cargo.toml index 91517a8d..7eb7265b 100644 --- a/nalgebra-lapack/Cargo.toml +++ b/nalgebra-lapack/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nalgebra-lapack" -version = "0.22.0" +version = "0.24.0" authors = [ "Sébastien Crozet ", "Andrew Straw " ] description = "Matrix decompositions using nalgebra matrices and Lapack bindings." @@ -29,18 +29,19 @@ accelerate = ["lapack-src/accelerate"] intel-mkl = ["lapack-src/intel-mkl"] [dependencies] -nalgebra = { version = "0.31", path = ".." } +nalgebra = { version = "0.32", path = ".." } num-traits = "0.2" num-complex = { version = "0.4", default-features = false } -simba = "0.7" +simba = "0.8" serde = { version = "1.0", features = [ "derive" ], optional = true } lapack = { version = "0.19", default-features = false } lapack-src = { version = "0.8", default-features = false } # clippy = "*" [dev-dependencies] -nalgebra = { version = "0.31", features = [ "arbitrary", "rand" ], path = ".." } +nalgebra = { version = "0.32", features = [ "arbitrary", "rand" ], path = ".." } proptest = { version = "1", default-features = false, features = ["std"] } quickcheck = "1" approx = "0.5" rand = "0.8" + diff --git a/nalgebra-lapack/src/eigen.rs b/nalgebra-lapack/src/eigen.rs index 8eab62d8..08f16115 100644 --- a/nalgebra-lapack/src/eigen.rs +++ b/nalgebra-lapack/src/eigen.rs @@ -7,13 +7,12 @@ use num_complex::Complex; use simba::scalar::RealField; use crate::ComplexHelper; -use na::allocator::Allocator; use na::dimension::{Const, Dim}; -use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar}; +use na::{allocator::Allocator, DefaultAllocator, Matrix, OMatrix, OVector, Scalar}; use lapack; -/// Eigendecomposition of a real square matrix with real eigenvalues. +/// Eigendecomposition of a real square matrix with real or complex eigenvalues. #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize", @@ -36,8 +35,10 @@ pub struct Eigen where DefaultAllocator: Allocator + Allocator, { - /// The eigenvalues of the decomposed matrix. - pub eigenvalues: OVector, + /// The real parts of eigenvalues of the decomposed matrix. + pub eigenvalues_re: OVector, + /// The imaginary parts of the eigenvalues of the decomposed matrix. + pub eigenvalues_im: OVector, /// The (right) eigenvectors of the decomposed matrix. pub eigenvectors: Option>, /// The left eigenvectors of the decomposed matrix. @@ -69,8 +70,8 @@ where "Unable to compute the eigenvalue decomposition of a non-square matrix." ); - let ljob = if left_eigenvectors { b'V' } else { b'T' }; - let rjob = if eigenvectors { b'V' } else { b'T' }; + let ljob = if left_eigenvectors { b'V' } else { b'N' }; + let rjob = if eigenvectors { b'V' } else { b'N' }; let (nrows, ncols) = m.shape_generic(); let n = nrows.value(); @@ -104,213 +105,232 @@ where lapack_check!(info); let mut work = vec![T::zero(); lwork as usize]; + let mut vl = if left_eigenvectors { + Some(Matrix::zeros_generic(nrows, ncols)) + } else { + None + }; + let mut vr = if eigenvectors { + Some(Matrix::zeros_generic(nrows, ncols)) + } else { + None + }; - match (left_eigenvectors, eigenvectors) { - (true, true) => { - // TODO: avoid the initializations? - let mut vl = Matrix::zeros_generic(nrows, ncols); - let mut vr = Matrix::zeros_generic(nrows, ncols); - - T::xgeev( - ljob, - rjob, - n as i32, - m.as_mut_slice(), - lda, - wr.as_mut_slice(), - wi.as_mut_slice(), - &mut vl.as_mut_slice(), - n as i32, - &mut vr.as_mut_slice(), - n as i32, - &mut work, - lwork, - &mut info, - ); - lapack_check!(info); - - if wi.iter().all(|e| e.is_zero()) { - return Some(Self { - eigenvalues: wr, - left_eigenvectors: Some(vl), - eigenvectors: Some(vr), - }); - } - } - (true, false) => { - // TODO: avoid the initialization? - let mut vl = Matrix::zeros_generic(nrows, ncols); - - T::xgeev( - ljob, - rjob, - n as i32, - m.as_mut_slice(), - lda, - wr.as_mut_slice(), - wi.as_mut_slice(), - &mut vl.as_mut_slice(), - n as i32, - &mut placeholder2, - 1 as i32, - &mut work, - lwork, - &mut info, - ); - lapack_check!(info); - - if wi.iter().all(|e| e.is_zero()) { - return Some(Self { - eigenvalues: wr, - left_eigenvectors: Some(vl), - eigenvectors: None, - }); - } - } - (false, true) => { - // TODO: avoid the initialization? - let mut vr = Matrix::zeros_generic(nrows, ncols); - - T::xgeev( - ljob, - rjob, - n as i32, - m.as_mut_slice(), - lda, - wr.as_mut_slice(), - wi.as_mut_slice(), - &mut placeholder1, - 1 as i32, - &mut vr.as_mut_slice(), - n as i32, - &mut work, - lwork, - &mut info, - ); - lapack_check!(info); - - if wi.iter().all(|e| e.is_zero()) { - return Some(Self { - eigenvalues: wr, - left_eigenvectors: None, - eigenvectors: Some(vr), - }); - } - } - (false, false) => { - T::xgeev( - ljob, - rjob, - n as i32, - m.as_mut_slice(), - lda, - wr.as_mut_slice(), - wi.as_mut_slice(), - &mut placeholder1, - 1 as i32, - &mut placeholder2, - 1 as i32, - &mut work, - lwork, - &mut info, - ); - lapack_check!(info); - - if wi.iter().all(|e| e.is_zero()) { - return Some(Self { - eigenvalues: wr, - left_eigenvectors: None, - eigenvectors: None, - }); - } - } - } - - None - } - - /// The complex eigenvalues of the given matrix. - /// - /// Panics if the eigenvalue computation does not converge. - pub fn complex_eigenvalues(mut m: OMatrix) -> OVector, D> - where - DefaultAllocator: Allocator, D>, - { - assert!( - m.is_square(), - "Unable to compute the eigenvalue decomposition of a non-square matrix." - ); - - let nrows = m.shape_generic().0; - let n = nrows.value(); - - let lda = n as i32; - - // TODO: avoid the initialization? - let mut wr = Matrix::zeros_generic(nrows, Const::<1>); - let mut wi = Matrix::zeros_generic(nrows, Const::<1>); - - let mut info = 0; - let mut placeholder1 = [T::zero()]; - let mut placeholder2 = [T::zero()]; - - let lwork = T::xgeev_work_size( - b'T', - b'T', - n as i32, - m.as_mut_slice(), - lda, - wr.as_mut_slice(), - wi.as_mut_slice(), - &mut placeholder1, - n as i32, - &mut placeholder2, - n as i32, - &mut info, - ); - - lapack_panic!(info); - - let mut work = vec![T::zero(); lwork as usize]; + let vl_ref = vl + .as_mut() + .map(|m| m.as_mut_slice()) + .unwrap_or(&mut placeholder1); + let vr_ref = vr + .as_mut() + .map(|m| m.as_mut_slice()) + .unwrap_or(&mut placeholder2); T::xgeev( - b'T', - b'T', + ljob, + rjob, n as i32, m.as_mut_slice(), lda, wr.as_mut_slice(), wi.as_mut_slice(), - &mut placeholder1, - 1 as i32, - &mut placeholder2, - 1 as i32, + vl_ref, + if left_eigenvectors { n as i32 } else { 1 }, + vr_ref, + if eigenvectors { n as i32 } else { 1 }, &mut work, lwork, &mut info, ); - lapack_panic!(info); + lapack_check!(info); - let mut res = Matrix::zeros_generic(nrows, Const::<1>); + Some(Self { + eigenvalues_re: wr, + eigenvalues_im: wi, + left_eigenvectors: vl, + eigenvectors: vr, + }) + } - for i in 0..res.len() { - res[i] = Complex::new(wr[i].clone(), wi[i].clone()); - } - - res + /// Returns `true` if all the eigenvalues are real. + pub fn eigenvalues_are_real(&self) -> bool { + self.eigenvalues_im.iter().all(|e| e.is_zero()) } /// The determinant of the decomposed matrix. #[inline] #[must_use] - pub fn determinant(&self) -> T { - let mut det = T::one(); - for e in self.eigenvalues.iter() { - det *= e.clone(); + pub fn determinant(&self) -> Complex { + let mut det: Complex = na::one(); + for (re, im) in self.eigenvalues_re.iter().zip(self.eigenvalues_im.iter()) { + det *= Complex::new(re.clone(), im.clone()); } det } + + /// Returns a tuple of vectors. The elements of the tuple are the real parts of the eigenvalues, left eigenvectors and right eigenvectors respectively. + pub fn get_real_elements( + &self, + ) -> ( + Vec, + Option>>, + Option>>, + ) + where + DefaultAllocator: Allocator, + { + let (number_of_elements, _) = self.eigenvalues_re.shape_generic(); + let number_of_elements_value = number_of_elements.value(); + let mut eigenvalues = Vec::::with_capacity(number_of_elements_value); + let mut eigenvectors = match self.eigenvectors.is_some() { + true => Some(Vec::>::with_capacity( + number_of_elements_value, + )), + false => None, + }; + let mut left_eigenvectors = match self.left_eigenvectors.is_some() { + true => Some(Vec::>::with_capacity( + number_of_elements_value, + )), + false => None, + }; + + let mut c = 0; + while c < number_of_elements_value { + eigenvalues.push(self.eigenvalues_re[c].clone()); + + if eigenvectors.is_some() { + eigenvectors.as_mut().unwrap().push( + (&self.eigenvectors.as_ref()) + .unwrap() + .column(c) + .into_owned(), + ); + } + + if left_eigenvectors.is_some() { + left_eigenvectors.as_mut().unwrap().push( + (&self.left_eigenvectors.as_ref()) + .unwrap() + .column(c) + .into_owned(), + ); + } + if self.eigenvalues_im[c] != T::zero() { + //skip next entry + c += 1; + } + c += 1; + } + (eigenvalues, left_eigenvectors, eigenvectors) + } + + /// Returns a tuple of vectors. The elements of the tuple are the complex eigenvalues, complex left eigenvectors and complex right eigenvectors respectively. + /// The elements appear as conjugate pairs within each vector, with the positive of the pair always being first. + pub fn get_complex_elements( + &self, + ) -> ( + Option>>, + Option, D>>>, + Option, D>>>, + ) + where + DefaultAllocator: Allocator, D>, + { + match self.eigenvalues_are_real() { + true => (None, None, None), + false => { + let (number_of_elements, _) = self.eigenvalues_re.shape_generic(); + let number_of_elements_value = number_of_elements.value(); + let number_of_complex_entries = + self.eigenvalues_im + .iter() + .fold(0, |acc, e| if !e.is_zero() { acc + 1 } else { acc }); + let mut eigenvalues = Vec::>::with_capacity(number_of_complex_entries); + let mut eigenvectors = match self.eigenvectors.is_some() { + true => Some(Vec::, D>>::with_capacity( + number_of_complex_entries, + )), + false => None, + }; + let mut left_eigenvectors = match self.left_eigenvectors.is_some() { + true => Some(Vec::, D>>::with_capacity( + number_of_complex_entries, + )), + false => None, + }; + + let mut c = 0; + while c < number_of_elements_value { + if self.eigenvalues_im[c] != T::zero() { + //Complex conjugate pairs of eigenvalues appear consecutively with the eigenvalue having the positive imaginary part first. + eigenvalues.push(Complex::::new( + self.eigenvalues_re[c].clone(), + self.eigenvalues_im[c].clone(), + )); + eigenvalues.push(Complex::::new( + self.eigenvalues_re[c + 1].clone(), + self.eigenvalues_im[c + 1].clone(), + )); + + if eigenvectors.is_some() { + let mut vec = OVector::, D>::zeros_generic( + number_of_elements, + Const::<1>, + ); + let mut vec_conj = OVector::, D>::zeros_generic( + number_of_elements, + Const::<1>, + ); + + for r in 0..number_of_elements_value { + vec[r] = Complex::::new( + (&self.eigenvectors.as_ref()).unwrap()[(r, c)].clone(), + (&self.eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(), + ); + vec_conj[r] = Complex::::new( + (&self.eigenvectors.as_ref()).unwrap()[(r, c)].clone(), + (&self.eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(), + ); + } + + eigenvectors.as_mut().unwrap().push(vec); + eigenvectors.as_mut().unwrap().push(vec_conj); + } + + if left_eigenvectors.is_some() { + let mut vec = OVector::, D>::zeros_generic( + number_of_elements, + Const::<1>, + ); + let mut vec_conj = OVector::, D>::zeros_generic( + number_of_elements, + Const::<1>, + ); + + for r in 0..number_of_elements_value { + vec[r] = Complex::::new( + (&self.left_eigenvectors.as_ref()).unwrap()[(r, c)].clone(), + (&self.left_eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(), + ); + vec_conj[r] = Complex::::new( + (&self.left_eigenvectors.as_ref()).unwrap()[(r, c)].clone(), + (&self.left_eigenvectors.as_ref()).unwrap()[(r, c + 1)].clone(), + ); + } + + left_eigenvectors.as_mut().unwrap().push(vec); + left_eigenvectors.as_mut().unwrap().push(vec_conj); + } + //skip next entry + c += 1; + } + c += 1; + } + (Some(eigenvalues), left_eigenvectors, eigenvectors) + } + } + } } /* diff --git a/nalgebra-lapack/src/qr.rs b/nalgebra-lapack/src/qr.rs index 895e34f3..ade2e452 100644 --- a/nalgebra-lapack/src/qr.rs +++ b/nalgebra-lapack/src/qr.rs @@ -126,7 +126,7 @@ where let mut q = self .qr - .generic_slice((0, 0), (nrows, min_nrows_ncols)) + .generic_view((0, 0), (nrows, min_nrows_ncols)) .into_owned(); let mut info = 0; diff --git a/nalgebra-lapack/src/svd.rs b/nalgebra-lapack/src/svd.rs index 972ffa1b..804284d9 100644 --- a/nalgebra-lapack/src/svd.rs +++ b/nalgebra-lapack/src/svd.rs @@ -157,7 +157,7 @@ macro_rules! svd_impl( let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols); { - let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols)); + let mut sres = res.generic_view_mut((0, 0), (min_nrows_ncols, ncols)); sres.copy_from(&self.vt.rows_generic(0, min_nrows_ncols)); for i in 0 .. min_nrows_ncols.value() { @@ -183,7 +183,7 @@ macro_rules! svd_impl( let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows); { - let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows)); + let mut sres = res.generic_view_mut((0, 0), (min_nrows_ncols, nrows)); self.u.columns_generic(0, min_nrows_ncols).transpose_to(&mut sres); for i in 0 .. min_nrows_ncols.value() { diff --git a/nalgebra-lapack/tests/linalg/cholesky.rs b/nalgebra-lapack/tests/linalg/cholesky.rs index 632347b8..0bf74dd4 100644 --- a/nalgebra-lapack/tests/linalg/cholesky.rs +++ b/nalgebra-lapack/tests/linalg/cholesky.rs @@ -58,8 +58,8 @@ proptest! { let sol1 = chol.solve(&b1).unwrap(); let sol2 = chol.solve(&b2).unwrap(); - prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-4)); + prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-4)); } } @@ -84,7 +84,7 @@ proptest! { let id1 = &m * &m1; let id2 = &m1 * &m; - prop_assert!(id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5)) + prop_assert!(id1.is_identity(1.0e-4) && id2.is_identity(1.0e-4)) } } } diff --git a/nalgebra-lapack/tests/linalg/complex_eigen.rs b/nalgebra-lapack/tests/linalg/complex_eigen.rs new file mode 100644 index 00000000..aa3474b9 --- /dev/null +++ b/nalgebra-lapack/tests/linalg/complex_eigen.rs @@ -0,0 +1,47 @@ +use na::Matrix3; +use nalgebra_lapack::Eigen; +use num_complex::Complex; + +#[test] +fn complex_eigen() { + let m = Matrix3::::new( + 4.0 / 5.0, + -3.0 / 5.0, + 0.0, + 3.0 / 5.0, + 4.0 / 5.0, + 0.0, + 1.0, + 2.0, + 2.0, + ); + let eigen = Eigen::new(m, true, true).expect("Eigen Creation Failed!"); + let (some_eigenvalues, some_left_vec, some_right_vec) = eigen.get_complex_elements(); + let eigenvalues = some_eigenvalues.expect("Eigenvalues Failed"); + let _left_eigenvectors = some_left_vec.expect("Left Eigenvectors Failed"); + let eigenvectors = some_right_vec.expect("Right Eigenvectors Failed"); + + assert_relative_eq!( + eigenvalues[0].re, + Complex::::new(4.0 / 5.0, 3.0 / 5.0).re + ); + assert_relative_eq!( + eigenvalues[0].im, + Complex::::new(4.0 / 5.0, 3.0 / 5.0).im + ); + assert_relative_eq!( + eigenvalues[1].re, + Complex::::new(4.0 / 5.0, -3.0 / 5.0).re + ); + assert_relative_eq!( + eigenvalues[1].im, + Complex::::new(4.0 / 5.0, -3.0 / 5.0).im + ); + + assert_relative_eq!(eigenvectors[0][0].re, -12.0 / 32.7871926215100059134410999); + assert_relative_eq!(eigenvectors[0][0].im, -9.0 / 32.7871926215100059134410999); + assert_relative_eq!(eigenvectors[0][1].re, -9.0 / 32.7871926215100059134410999); + assert_relative_eq!(eigenvectors[0][1].im, 12.0 / 32.7871926215100059134410999); + assert_relative_eq!(eigenvectors[0][2].re, 25.0 / 32.7871926215100059134410999); + assert_relative_eq!(eigenvectors[0][2].im, 0.0); +} diff --git a/nalgebra-lapack/tests/linalg/lu.rs b/nalgebra-lapack/tests/linalg/lu.rs index 9665964e..b9d45208 100644 --- a/nalgebra-lapack/tests/linalg/lu.rs +++ b/nalgebra-lapack/tests/linalg/lu.rs @@ -51,10 +51,10 @@ proptest! { let tr_sol1 = lup.solve_transpose(&b1).unwrap(); let tr_sol2 = lup.solve_transpose(&b2).unwrap(); - prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-5)); } #[test] @@ -68,10 +68,10 @@ proptest! { let tr_sol1 = lup.solve_transpose(&b1).unwrap(); let tr_sol2 = lup.solve_transpose(&b2).unwrap(); - prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-5)); } #[test] diff --git a/nalgebra-lapack/tests/linalg/mod.rs b/nalgebra-lapack/tests/linalg/mod.rs index 251bbe7b..92425293 100644 --- a/nalgebra-lapack/tests/linalg/mod.rs +++ b/nalgebra-lapack/tests/linalg/mod.rs @@ -1,4 +1,5 @@ mod cholesky; +mod complex_eigen; mod generalized_eigenvalues; mod lu; mod qr; diff --git a/nalgebra-lapack/tests/linalg/real_eigensystem.rs b/nalgebra-lapack/tests/linalg/real_eigensystem.rs index 3d1c91eb..599d1b2a 100644 --- a/nalgebra-lapack/tests/linalg/real_eigensystem.rs +++ b/nalgebra-lapack/tests/linalg/real_eigensystem.rs @@ -13,30 +13,36 @@ proptest! { let m = DMatrix::::new_random(n, n); if let Some(eig) = Eigen::new(m.clone(), true, true) { - let eigvals = DMatrix::from_diagonal(&eig.eigenvalues); - let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap(); - let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals; + // TODO: test the complex case too. + if eig.eigenvalues_are_real() { + let eigvals = DMatrix::from_diagonal(&eig.eigenvalues_re); + let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap(); + let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals; - let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap(); - let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals; + let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap(); + let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals; - prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-5)); + } } } #[test] fn eigensystem_static(m in matrix4()) { if let Some(eig) = Eigen::new(m, true, true) { - let eigvals = Matrix4::from_diagonal(&eig.eigenvalues); - let transformed_eigvectors = m * eig.eigenvectors.unwrap(); - let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals; + // TODO: test the complex case too. + if eig.eigenvalues_are_real() { + let eigvals = Matrix4::from_diagonal(&eig.eigenvalues_re); + let transformed_eigvectors = m * eig.eigenvectors.unwrap(); + let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals; - let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap(); - let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals; + let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap(); + let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals; - prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7)); - prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7)); + prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-5)); + prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-5)); + } } } } diff --git a/nalgebra-lapack/tests/linalg/schur.rs b/nalgebra-lapack/tests/linalg/schur.rs index 0fd1cc33..ee7bad90 100644 --- a/nalgebra-lapack/tests/linalg/schur.rs +++ b/nalgebra-lapack/tests/linalg/schur.rs @@ -11,14 +11,17 @@ proptest! { let n = cmp::max(1, cmp::min(n, 10)); let m = DMatrix::::new_random(n, n); - let (vecs, vals) = Schur::new(m.clone()).unpack(); - - prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)) + if let Some(schur) = Schur::try_new(m.clone()) { + let (vecs, vals) = schur.unpack(); + prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-5)) + } } #[test] fn schur_static(m in matrix4()) { - let (vecs, vals) = Schur::new(m.clone()).unpack(); - prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)) + if let Some(schur) = Schur::try_new(m.clone()) { + let (vecs, vals) = schur.unpack(); + prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-5)) + } } } diff --git a/nalgebra-macros/Cargo.toml b/nalgebra-macros/Cargo.toml index 6e35f9e9..041e36a7 100644 --- a/nalgebra-macros/Cargo.toml +++ b/nalgebra-macros/Cargo.toml @@ -21,5 +21,5 @@ quote = "1.0" proc-macro2 = "1.0" [dev-dependencies] -nalgebra = { version = "0.31.0", path = ".." } +nalgebra = { version = "0.32.0", path = ".." } trybuild = "1.0.42" diff --git a/nalgebra-macros/src/lib.rs b/nalgebra-macros/src/lib.rs index 0d7889ae..e12139d2 100644 --- a/nalgebra-macros/src/lib.rs +++ b/nalgebra-macros/src/lib.rs @@ -191,8 +191,8 @@ pub fn dmatrix(stream: TokenStream) -> TokenStream { let output = quote! { nalgebra::DMatrix::<_> ::from_vec_storage(nalgebra::VecStorage::new( - nalgebra::Dynamic::new(#row_dim), - nalgebra::Dynamic::new(#col_dim), + nalgebra::Dyn(#row_dim), + nalgebra::Dyn(#col_dim), vec!#array_tokens)) }; @@ -285,7 +285,7 @@ pub fn dvector(stream: TokenStream) -> TokenStream { let output = quote! { nalgebra::DVector::<_> ::from_vec_storage(nalgebra::VecStorage::new( - nalgebra::Dynamic::new(#len), + nalgebra::Dyn(#len), nalgebra::Const::<1>, vec!#array_tokens)) }; diff --git a/nalgebra-sparse/Cargo.toml b/nalgebra-sparse/Cargo.toml index b9c343e4..3a1bd20d 100644 --- a/nalgebra-sparse/Cargo.toml +++ b/nalgebra-sparse/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nalgebra-sparse" -version = "0.7.1" +version = "0.9.0" authors = [ "Andreas Longva", "Sébastien Crozet " ] edition = "2018" description = "Sparse matrix computation based on nalgebra." @@ -24,7 +24,7 @@ io = [ "pest", "pest_derive" ] slow-tests = [] [dependencies] -nalgebra = { version="0.31", path = "../" } +nalgebra = { version="0.32", path = "../" } num-traits = { version = "0.2", default-features = false } proptest = { version = "1.0", optional = true } matrixcompare-core = { version = "0.1.0", optional = true } @@ -35,7 +35,7 @@ serde = { version = "1.0", default-features = false, features = [ "derive" ], op [dev-dependencies] itertools = "0.10" matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] } -nalgebra = { version="0.31", path = "../", features = ["compare"] } +nalgebra = { version="0.32", path = "../", features = ["compare"] } tempfile = "3.3" serde_json = "1.0" diff --git a/nalgebra-sparse/src/coo.rs b/nalgebra-sparse/src/coo.rs index 25dc07fb..b71cb0b6 100644 --- a/nalgebra-sparse/src/coo.rs +++ b/nalgebra-sparse/src/coo.rs @@ -170,6 +170,16 @@ impl CooMatrix { .map(|((i, j), v)| (*i, *j, v)) } + /// A mutable iterator over triplets (i, j, v). + // TODO: Consider giving the iterator a concrete type instead of impl trait...? + pub fn triplet_iter_mut(&mut self) -> impl Iterator { + self.row_indices + .iter() + .zip(&self.col_indices) + .zip(self.values.iter_mut()) + .map(|((i, j), v)| (*i, *j, v)) + } + /// Reserves capacity for COO matrix by at least `additional` elements. /// /// This increase the capacities of triplet holding arrays by reserving more space to avoid diff --git a/nalgebra-sparse/src/csc.rs b/nalgebra-sparse/src/csc.rs index d926dafb..0cd89f5c 100644 --- a/nalgebra-sparse/src/csc.rs +++ b/nalgebra-sparse/src/csc.rs @@ -24,6 +24,7 @@ use std::slice::{Iter, IterMut}; /// # Usage /// /// ``` +/// use nalgebra_sparse::coo::CooMatrix; /// use nalgebra_sparse::csc::CscMatrix; /// use nalgebra::{DMatrix, Matrix3x4}; /// use matrixcompare::assert_matrix_eq; @@ -32,8 +33,9 @@ use std::slice::{Iter, IterMut}; /// // change the sparsity pattern of the matrix after it has been constructed. The easiest /// // way to construct a CSC matrix is to first incrementally construct a COO matrix, /// // and then convert it to CSC. -/// # use nalgebra_sparse::coo::CooMatrix; -/// # let coo = CooMatrix::::new(3, 3); +/// +/// let mut coo = CooMatrix::::new(3, 3); +/// coo.push(2, 0, 1.0); /// let csc = CscMatrix::from(&coo); /// /// // Alternatively, a CSC matrix can be constructed directly from raw CSC data. diff --git a/nalgebra-sparse/src/csr.rs b/nalgebra-sparse/src/csr.rs index 90be35f1..255e8404 100644 --- a/nalgebra-sparse/src/csr.rs +++ b/nalgebra-sparse/src/csr.rs @@ -25,6 +25,7 @@ use std::slice::{Iter, IterMut}; /// # Usage /// /// ``` +/// use nalgebra_sparse::coo::CooMatrix; /// use nalgebra_sparse::csr::CsrMatrix; /// use nalgebra::{DMatrix, Matrix3x4}; /// use matrixcompare::assert_matrix_eq; @@ -33,8 +34,9 @@ use std::slice::{Iter, IterMut}; /// // change the sparsity pattern of the matrix after it has been constructed. The easiest /// // way to construct a CSR matrix is to first incrementally construct a COO matrix, /// // and then convert it to CSR. -/// # use nalgebra_sparse::coo::CooMatrix; -/// # let coo = CooMatrix::::new(3, 3); +/// +/// let mut coo = CooMatrix::::new(3, 3); +/// coo.push(2, 0, 1.0); /// let csr = CsrMatrix::from(&coo); /// /// // Alternatively, a CSR matrix can be constructed directly from raw CSR data. diff --git a/nalgebra-sparse/src/factorization/cholesky.rs b/nalgebra-sparse/src/factorization/cholesky.rs index 1f653278..f84e621f 100644 --- a/nalgebra-sparse/src/factorization/cholesky.rs +++ b/nalgebra-sparse/src/factorization/cholesky.rs @@ -3,7 +3,7 @@ use crate::ops::serial::spsolve_csc_lower_triangular; use crate::ops::Op; use crate::pattern::SparsityPattern; use core::{iter, mem}; -use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, RealField}; +use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, RealField}; use std::fmt::{Display, Formatter}; /// A symbolic sparse Cholesky factorization of a CSC matrix. @@ -264,7 +264,7 @@ impl CscCholesky { /// /// Panics if `B` is not square. #[must_use = "Did you mean to use solve_mut()?"] - pub fn solve<'a>(&'a self, b: impl Into>) -> DMatrix { + pub fn solve<'a>(&'a self, b: impl Into>) -> DMatrix { let b = b.into(); let mut output = b.clone_owned(); self.solve_mut(&mut output); @@ -278,7 +278,7 @@ impl CscCholesky { /// # Panics /// /// Panics if `b` is not square. - pub fn solve_mut<'a>(&'a self, b: impl Into>) { + pub fn solve_mut<'a>(&'a self, b: impl Into>) { let expect_msg = "If the Cholesky factorization succeeded,\ then the triangular solve should never fail"; // Solve LY = B diff --git a/nalgebra-sparse/src/ops/impl_std_ops.rs b/nalgebra-sparse/src/ops/impl_std_ops.rs index 91b6574f..7363c9d9 100644 --- a/nalgebra-sparse/src/ops/impl_std_ops.rs +++ b/nalgebra-sparse/src/ops/impl_std_ops.rs @@ -10,7 +10,7 @@ use nalgebra::allocator::Allocator; use nalgebra::base::storage::RawStorage; use nalgebra::constraint::{DimEq, ShapeConstraint}; use nalgebra::{ - ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, OMatrix, + ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dyn, Matrix, OMatrix, Scalar, U1, }; use num_traits::{One, Zero}; @@ -273,8 +273,8 @@ macro_rules! impl_spmm_cs_dense { // Implement ref-ref impl_spmm_cs_dense!(&'a $matrix_type_name, &'a Matrix, $spmm_fn, |lhs, rhs| { let (_, ncols) = rhs.shape_generic(); - let nrows = Dynamic::new(lhs.nrows()); - let mut result = OMatrix::::zeros_generic(nrows, ncols); + let nrows = Dyn(lhs.nrows()); + let mut result = OMatrix::::zeros_generic(nrows, ncols); $spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs)); result }); @@ -302,21 +302,21 @@ macro_rules! impl_spmm_cs_dense { R: Dim, C: Dim, S: RawStorage, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, // TODO: Is it possible to simplify these bounds? ShapeConstraint: - // Bounds so that we can turn OMatrix into a DMatrixSliceMut - DimEq>::Buffer as RawStorage>::RStride> - + DimEq - + DimEq>::Buffer as RawStorage>::CStride> + // Bounds so that we can turn OMatrix into a DMatrixSliceMut + DimEq>::Buffer as RawStorage>::RStride> + + DimEq + + DimEq>::Buffer as RawStorage>::CStride> // Bounds so that we can turn &Matrix into a DMatrixSlice + DimEq - + DimEq - + DimEq + + DimEq + + DimEq { // We need the column dimension to be generic, so that if RHS is a vector, then // we also get a vector (and not a matrix) - type Output = OMatrix; + type Output = OMatrix; fn mul(self, rhs: $dense_matrix_type) -> Self::Output { let $lhs = self; diff --git a/nalgebra-sparse/src/ops/serial/cs.rs b/nalgebra-sparse/src/ops/serial/cs.rs index cc13c168..a2a132fc 100644 --- a/nalgebra-sparse/src/ops/serial/cs.rs +++ b/nalgebra-sparse/src/ops/serial/cs.rs @@ -2,7 +2,7 @@ use crate::cs::CsMatrix; use crate::ops::serial::{OperationError, OperationErrorKind}; use crate::ops::Op; use crate::SparseEntryMut; -use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar}; +use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar}; use num_traits::{One, Zero}; fn spmm_cs_unexpected_entry() -> OperationError { @@ -176,10 +176,10 @@ where /// the transposed operation must be specified for the CSC matrix. pub fn spmm_cs_dense( beta: T, - mut c: DMatrixSliceMut<'_, T>, + mut c: DMatrixViewMut<'_, T>, alpha: T, a: Op<&CsMatrix>, - b: Op>, + b: Op>, ) where T: Scalar + ClosedAdd + ClosedMul + Zero + One, { diff --git a/nalgebra-sparse/src/ops/serial/csc.rs b/nalgebra-sparse/src/ops/serial/csc.rs index 6a691ef9..5cf8ab23 100644 --- a/nalgebra-sparse/src/ops/serial/csc.rs +++ b/nalgebra-sparse/src/ops/serial/csc.rs @@ -4,7 +4,7 @@ use crate::ops::serial::cs::{ }; use crate::ops::serial::{OperationError, OperationErrorKind}; use crate::ops::Op; -use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, RealField, Scalar}; +use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, RealField, Scalar}; use num_traits::{One, Zero}; use std::borrow::Cow; @@ -16,10 +16,10 @@ use std::borrow::Cow; /// Panics if the dimensions of the matrices involved are not compatible with the expression. pub fn spmm_csc_dense<'a, T>( beta: T, - c: impl Into>, + c: impl Into>, alpha: T, a: Op<&CscMatrix>, - b: Op>>, + b: Op>>, ) where T: Scalar + ClosedAdd + ClosedMul + Zero + One, { @@ -29,10 +29,10 @@ pub fn spmm_csc_dense<'a, T>( fn spmm_csc_dense_( beta: T, - c: DMatrixSliceMut<'_, T>, + c: DMatrixViewMut<'_, T>, alpha: T, a: Op<&CscMatrix>, - b: Op>, + b: Op>, ) where T: Scalar + ClosedAdd + ClosedMul + Zero + One, { @@ -173,7 +173,7 @@ where /// Panics if `L` is not square, or if `L` and `B` are not dimensionally compatible. pub fn spsolve_csc_lower_triangular<'a, T: RealField>( l: Op<&CscMatrix>, - b: impl Into>, + b: impl Into>, ) -> Result<(), OperationError> { let b = b.into(); let l_matrix = l.into_inner(); @@ -195,7 +195,7 @@ pub fn spsolve_csc_lower_triangular<'a, T: RealField>( fn spsolve_csc_lower_triangular_no_transpose( l: &CscMatrix, - b: DMatrixSliceMut<'_, T>, + b: DMatrixViewMut<'_, T>, ) -> Result<(), OperationError> { let mut x = b; @@ -253,7 +253,7 @@ fn spsolve_encountered_zero_diagonal() -> Result<(), OperationError> { fn spsolve_csc_lower_triangular_transpose( l: &CscMatrix, - b: DMatrixSliceMut<'_, T>, + b: DMatrixViewMut<'_, T>, ) -> Result<(), OperationError> { let mut x = b; diff --git a/nalgebra-sparse/src/ops/serial/csr.rs b/nalgebra-sparse/src/ops/serial/csr.rs index 708c81a3..d69bc54c 100644 --- a/nalgebra-sparse/src/ops/serial/csr.rs +++ b/nalgebra-sparse/src/ops/serial/csr.rs @@ -4,17 +4,17 @@ use crate::ops::serial::cs::{ }; use crate::ops::serial::OperationError; use crate::ops::Op; -use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar}; +use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar}; use num_traits::{One, Zero}; use std::borrow::Cow; /// Sparse-dense matrix-matrix multiplication `C <- beta * C + alpha * op(A) * op(B)`. pub fn spmm_csr_dense<'a, T>( beta: T, - c: impl Into>, + c: impl Into>, alpha: T, a: Op<&CsrMatrix>, - b: Op>>, + b: Op>>, ) where T: Scalar + ClosedAdd + ClosedMul + Zero + One, { @@ -24,10 +24,10 @@ pub fn spmm_csr_dense<'a, T>( fn spmm_csr_dense_( beta: T, - c: DMatrixSliceMut<'_, T>, + c: DMatrixViewMut<'_, T>, alpha: T, a: Op<&CsrMatrix>, - b: Op>, + b: Op>, ) where T: Scalar + ClosedAdd + ClosedMul + Zero + One, { diff --git a/nalgebra-sparse/tests/unit_tests/coo.rs b/nalgebra-sparse/tests/unit_tests/coo.rs index d232b041..8d7f740b 100644 --- a/nalgebra-sparse/tests/unit_tests/coo.rs +++ b/nalgebra-sparse/tests/unit_tests/coo.rs @@ -87,6 +87,40 @@ fn coo_construction_for_valid_data() { } } +#[test] +fn coo_triplets_iter_mut() { + // Arbitrary matrix, with duplicates + let i = vec![0, 1, 0, 0, 0, 0, 2, 1]; + let j = vec![0, 2, 0, 1, 0, 3, 3, 2]; + let v = vec![2, 3, 4, 7, 1, 3, 1, 5]; + let mut coo = + CooMatrix::::try_from_triplets(3, 5, i.clone(), j.clone(), v.clone()).unwrap(); + + let actual_triplets: Vec<_> = coo.triplet_iter_mut().map(|(i, j, v)| (i, j, *v)).collect(); + + let expected_triplets: Vec<_> = i + .iter() + .zip(&j) + .zip(&v) + .map(|((i, j), v)| (*i, *j, *v)) + .collect(); + assert_eq!(expected_triplets, actual_triplets); + + for (_i, _j, v) in coo.triplet_iter_mut() { + *v += *v; + } + + let actual_triplets: Vec<_> = coo.triplet_iter_mut().map(|(i, j, v)| (i, j, *v)).collect(); + let v = vec![4, 6, 8, 14, 2, 6, 2, 10]; + let expected_triplets: Vec<_> = i + .iter() + .zip(&j) + .zip(&v) + .map(|((i, j), v)| (*i, *j, *v)) + .collect(); + assert_eq!(expected_triplets, actual_triplets); +} + #[test] fn coo_try_from_triplets_reports_out_of_bounds_indices() { { @@ -314,8 +348,8 @@ fn coo_push_matrix_valid_entries() { // Works with sliced { let source = nalgebra::SMatrix::::new(6, 7, 8, 9); - let sliced = source.fixed_slice::<2, 1>(0, 0); - coo.push_matrix(1, 0, &sliced); + let view = source.fixed_view::<2, 1>(0, 0); + coo.push_matrix(1, 0, &view); assert_eq!( coo.triplet_iter().collect::>(), diff --git a/nalgebra-sparse/tests/unit_tests/ops.rs b/nalgebra-sparse/tests/unit_tests/ops.rs index 0a335567..c8d80f32 100644 --- a/nalgebra-sparse/tests/unit_tests/ops.rs +++ b/nalgebra-sparse/tests/unit_tests/ops.rs @@ -14,7 +14,7 @@ use nalgebra_sparse::pattern::SparsityPattern; use nalgebra_sparse::proptest::{csc, csr, sparsity_pattern}; use nalgebra::proptest::{matrix, vector}; -use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, Scalar}; +use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, Scalar}; use proptest::prelude::*; @@ -333,10 +333,10 @@ fn csc_square_with_non_zero_diagonals() -> impl Strategy> /// Helper function to help us call dense GEMM with our `Op` type fn dense_gemm<'a>( beta: i32, - c: impl Into>, + c: impl Into>, alpha: i32, - a: Op>>, - b: Op>>, + a: Op>>, + b: Op>>, ) { let mut c = c.into(); let a = a.convert(); diff --git a/src/base/alias.rs b/src/base/alias.rs index 68829d9a..e3ac40b0 100644 --- a/src/base/alias.rs +++ b/src/base/alias.rs @@ -1,5 +1,5 @@ #[cfg(any(feature = "alloc", feature = "std"))] -use crate::base::dimension::Dynamic; +use crate::base::dimension::Dyn; use crate::base::dimension::{U1, U2, U3, U4, U5, U6}; use crate::base::storage::Owned; #[cfg(any(feature = "std", feature = "alloc"))] @@ -48,69 +48,69 @@ pub type SMatrix = /// /// **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 DMatrix = Matrix>; +pub type DMatrix = Matrix>; /// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 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 MatrixXx1 = Matrix>; +pub type MatrixXx1 = Matrix>; /// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 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 MatrixXx2 = Matrix>; +pub type MatrixXx2 = Matrix>; /// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 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 MatrixXx3 = Matrix>; +pub type MatrixXx3 = Matrix>; /// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 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 MatrixXx4 = Matrix>; +pub type MatrixXx4 = Matrix>; /// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 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 MatrixXx5 = Matrix>; +pub type MatrixXx5 = Matrix>; /// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 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 MatrixXx6 = Matrix>; +pub type MatrixXx6 = Matrix>; /// A heap-allocated, row-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>; +pub type Matrix1xX = Matrix>; /// A heap-allocated, row-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>; +pub type Matrix2xX = Matrix>; /// A heap-allocated, row-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>; +pub type Matrix3xX = Matrix>; /// A heap-allocated, row-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>; +pub type Matrix4xX = Matrix>; /// A heap-allocated, row-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>; +pub type Matrix5xX = Matrix>; /// A heap-allocated, row-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"))] -pub type Matrix6xX = Matrix>; +pub type Matrix6xX = Matrix>; /// A stack-allocated, column-major, 1x1 square matrix. /// @@ -276,7 +276,7 @@ pub type Matrix6x5 = Matrix>; */ /// A dynamically sized column vector. #[cfg(any(feature = "std", feature = "alloc"))] -pub type DVector = Matrix>; +pub type DVector = Matrix>; /// An owned D-dimensional column vector. pub type OVector = Matrix>; @@ -316,7 +316,7 @@ pub type Vector6 = Matrix>; */ /// A dynamically sized row vector. #[cfg(any(feature = "std", feature = "alloc"))] -pub type RowDVector = Matrix>; +pub type RowDVector = Matrix>; /// An owned D-dimensional row vector. pub type RowOVector = Matrix>; diff --git a/src/base/alias_slice.rs b/src/base/alias_slice.rs index 929d2f03..9c1a9a87 100644 --- a/src/base/alias_slice.rs +++ b/src/base/alias_slice.rs @@ -1,6 +1,7 @@ -use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6}; -use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; +use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6}; +use crate::base::matrix_view::{ViewStorage, ViewStorageMut}; use crate::base::{Const, Matrix}; +use crate::slice_deprecation_note; /* * @@ -13,286 +14,345 @@ use crate::base::{Const, Matrix}; /// A column-major matrix slice with dimensions known at compile-time. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(SMatrixView)] pub type SMatrixSlice<'a, T, const R: usize, const C: usize> = - Matrix, Const, SliceStorage<'a, T, Const, Const, Const<1>, Const>>; + Matrix, Const, ViewStorage<'a, T, Const, Const, Const<1>, Const>>; /// A column-major matrix slice dynamic numbers of rows and columns. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** -pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(DMatrixView)] +pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major 1x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView1)] pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 2x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView2)] pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 3x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView3)] pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 4x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView4)] pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 5x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView5)] pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 6x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView6)] pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 1x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView1x2)] pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView1x3)] pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView1x4)] pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView1x5)] pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView1x6)] pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 2x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView2x1)] pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView2x3)] pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView2x4)] pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView2x5)] pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView2x6)] pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 3x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView3x1)] pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView3x2)] pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView3x4)] pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView3x5)] pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView3x6)] pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 4x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView4x1)] pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView4x2)] pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView4x3)] pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView4x5)] pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView4x6)] pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 5x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView5x1)] pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView5x2)] pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView5x3)] pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView5x4)] pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView5x6)] pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 6x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView6x1)] pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView6x2)] pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView6x3)] pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView6x4)] pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixView6x5)] pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major matrix slice with 1 row and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixView1xX)] pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major matrix slice with 2 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixView2xX)] pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major matrix slice with 3 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixView3xX)] pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major matrix slice with 4 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixView4xX)] pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major matrix slice with 5 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixView5xX)] pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major matrix slice with 6 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixView6xX)] pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 1 column. -pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewXx1)] +pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 2 columns. -pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewXx2)] +pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 3 columns. -pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewXx3)] +pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 4 columns. -pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewXx4)] +pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 5 columns. -pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewXx5)] +pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 6 columns. -pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewXx6)] +pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column vector slice with dimensions known at compile-time. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView)] pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> = - Matrix>; + Matrix>; /// A column vector slice with dimensions known at compile-time. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(SVectorView)] pub type SVectorSlice<'a, T, const D: usize> = - Matrix, Const<1>, SliceStorage<'a, T, Const, Const<1>, Const<1>, Const>>; + Matrix, Const<1>, ViewStorage<'a, T, Const, Const<1>, Const<1>, Const>>; /// A column vector slice dynamic numbers of rows and columns. -pub type DVectorSlice<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(DVectorView)] +pub type DVectorSlice<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A 1D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView1)] pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A 2D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView2)] pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A 3D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView3)] pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A 4D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView4)] pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A 5D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView5)] pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A 6D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorView6)] pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /* * @@ -304,297 +364,358 @@ pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> = /// A column-major matrix slice with `R` rows and `C` columns. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = "Use MatrixViewMut instead, which has an identical definition."] pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> = - Matrix>; + Matrix>; /// A column-major matrix slice with `D` rows and columns. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = "Use MatrixViewMut instead."] pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> = - Matrix>; + Matrix>; /// A column-major matrix slice with dimensions known at compile-time. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(SMatrixViewMut)] pub type SMatrixSliceMut<'a, T, const R: usize, const C: usize> = - Matrix, Const, SliceStorageMut<'a, T, Const, Const, Const<1>, Const>>; + Matrix, Const, ViewStorageMut<'a, T, Const, Const, Const<1>, Const>>; /// A column-major matrix slice dynamic numbers of rows and columns. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** -pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(DMatrixViewMut)] +pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major 1x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut1)] pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 2x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut2)] pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 3x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut3)] pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 4x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut4)] pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 5x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut5)] pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 6x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut6)] pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 1x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut1x2)] pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut1x3)] pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut1x4)] pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut1x5)] pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 1x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut1x6)] pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major 2x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut2x1)] pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut2x3)] pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut2x4)] pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut2x5)] pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 2x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut2x6)] pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major 3x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut3x1)] pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut3x2)] pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut3x4)] pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut3x5)] pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 3x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut3x6)] pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major 4x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut4x1)] pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut4x2)] pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut4x3)] pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut4x5)] pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 4x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut4x6)] pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major 5x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut5x1)] pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut5x2)] pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut5x3)] pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut5x4)] pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 5x6 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut5x6)] pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major 6x1 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut6x1)] pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x2 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut6x2)] pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x3 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut6x3)] pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x4 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut6x4)] pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major 6x5 matrix slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(MatrixViewMut6x5)] pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major matrix slice with 1 row and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixViewMut1xX)] pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A column-major matrix slice with 2 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixViewMut2xX)] pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A column-major matrix slice with 3 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixViewMut3xX)] pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A column-major matrix slice with 4 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixViewMut4xX)] pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A column-major matrix slice with 5 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixViewMut5xX)] pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A column-major matrix slice with 6 rows and a number of columns chosen at runtime. +#[deprecated = slice_deprecation_note!(MatrixViewMut6xX)] pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 1 column. -pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewMutXx1)] +pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 2 columns. -pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewMutXx2)] +pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 3 columns. -pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewMutXx3)] +pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 4 columns. -pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewMutXx4)] +pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 5 columns. -pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewMutXx5)] +pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column-major matrix slice with a number of rows chosen at runtime and 6 columns. -pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(MatrixViewMutXx6)] +pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A column vector slice with dimensions known at compile-time. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut)] pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> = - Matrix>; + Matrix>; /// A column vector slice with dimensions known at compile-time. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(SVectorViewMut)] pub type SVectorSliceMut<'a, T, const D: usize> = - Matrix, Const<1>, SliceStorageMut<'a, T, Const, Const<1>, Const<1>, Const>>; + Matrix, Const<1>, ViewStorageMut<'a, T, Const, Const<1>, Const<1>, Const>>; /// A column vector slice dynamic numbers of rows and columns. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** -pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dynamic> = - Matrix>; +#[deprecated = slice_deprecation_note!(DVectorViewMut)] +pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; /// A 1D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut1)] pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> = - Matrix>; + Matrix>; /// A 2D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut2)] pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> = - Matrix>; + Matrix>; /// A 3D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut3)] pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> = - Matrix>; + Matrix>; /// A 4D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut4)] pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> = - Matrix>; + Matrix>; /// A 5D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut5)] pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> = - Matrix>; + Matrix>; /// A 6D column vector slice. /// /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +#[deprecated = slice_deprecation_note!(VectorViewMut6)] pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> = - Matrix>; + Matrix>; diff --git a/src/base/alias_view.rs b/src/base/alias_view.rs new file mode 100644 index 00000000..26da6f47 --- /dev/null +++ b/src/base/alias_view.rs @@ -0,0 +1,589 @@ +use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6}; +use crate::base::matrix_view::{ViewStorage, ViewStorageMut}; +use crate::base::{Const, Matrix}; + +/* + * + * + * Matrix view aliases. + * + * + */ +// NOTE: we can't provide defaults for the strides because it's not supported yet by min_const_generics. +/// A column-major matrix view with dimensions known at compile-time. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type SMatrixView<'a, T, const R: usize, const C: usize> = + Matrix, Const, ViewStorage<'a, T, Const, Const, Const<1>, Const>>; + +/// A column-major matrix view dynamic numbers of rows and columns. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type DMatrixView<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; + +/// A column-major 1x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView1<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 2x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView2<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 3x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView3<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 4x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView4<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 5x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView5<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 6x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView6<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/// A column-major 1x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView1x2<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView1x3<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView1x4<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView1x5<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView1x6<'a, T, RStride = U1, CStride = U1> = + Matrix>; + +/// A column-major 2x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView2x1<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView2x3<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView2x4<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView2x5<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView2x6<'a, T, RStride = U1, CStride = U2> = + Matrix>; + +/// A column-major 3x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView3x1<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView3x2<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView3x4<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView3x5<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView3x6<'a, T, RStride = U1, CStride = U3> = + Matrix>; + +/// A column-major 4x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView4x1<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView4x2<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView4x3<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView4x5<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView4x6<'a, T, RStride = U1, CStride = U4> = + Matrix>; + +/// A column-major 5x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView5x1<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView5x2<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView5x3<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView5x4<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView5x6<'a, T, RStride = U1, CStride = U5> = + Matrix>; + +/// A column-major 6x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView6x1<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView6x2<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView6x3<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView6x4<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixView6x5<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/// A column-major matrix view with 1 row and a number of columns chosen at runtime. +pub type MatrixView1xX<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major matrix view with 2 rows and a number of columns chosen at runtime. +pub type MatrixView2xX<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major matrix view with 3 rows and a number of columns chosen at runtime. +pub type MatrixView3xX<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major matrix view with 4 rows and a number of columns chosen at runtime. +pub type MatrixView4xX<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major matrix view with 5 rows and a number of columns chosen at runtime. +pub type MatrixView5xX<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major matrix view with 6 rows and a number of columns chosen at runtime. +pub type MatrixView6xX<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/// A column-major matrix view with a number of rows chosen at runtime and 1 column. +pub type MatrixViewXx1<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 2 columns. +pub type MatrixViewXx2<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 3 columns. +pub type MatrixViewXx3<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 4 columns. +pub type MatrixViewXx4<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 5 columns. +pub type MatrixViewXx5<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 6 columns. +pub type MatrixViewXx6<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; + +/// A column vector view with dimensions known at compile-time. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView<'a, T, D, RStride = U1, CStride = D> = + Matrix>; + +/// A column vector view with dimensions known at compile-time. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type SVectorView<'a, T, const D: usize> = + Matrix, Const<1>, ViewStorage<'a, T, Const, Const<1>, Const<1>, Const>>; + +/// A column vector view dynamic numbers of rows and columns. +pub type DVectorView<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; + +/// A 1D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView1<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A 2D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView2<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A 3D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView3<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A 4D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView4<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A 5D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView5<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A 6D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorView6<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/* + * + * + * Same thing, but for mutable views. + * + * + */ + +/// A column-major matrix view with dimensions known at compile-time. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type SMatrixViewMut<'a, T, const R: usize, const C: usize> = + Matrix, Const, ViewStorageMut<'a, T, Const, Const, Const<1>, Const>>; + +/// A column-major matrix view dynamic numbers of rows and columns. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type DMatrixViewMut<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; + +/// A column-major 1x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut1<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 2x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut2<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 3x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut3<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 4x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut4<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 5x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut5<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 6x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut6<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/// A column-major 1x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut1x2<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut1x3<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut1x4<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut1x5<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major 1x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut1x6<'a, T, RStride = U1, CStride = U1> = + Matrix>; + +/// A column-major 2x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut2x1<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut2x3<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut2x4<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut2x5<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major 2x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut2x6<'a, T, RStride = U1, CStride = U2> = + Matrix>; + +/// A column-major 3x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut3x1<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut3x2<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut3x4<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut3x5<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major 3x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut3x6<'a, T, RStride = U1, CStride = U3> = + Matrix>; + +/// A column-major 4x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut4x1<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut4x2<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut4x3<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut4x5<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major 4x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut4x6<'a, T, RStride = U1, CStride = U4> = + Matrix>; + +/// A column-major 5x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut5x1<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut5x2<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut5x3<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut5x4<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major 5x6 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut5x6<'a, T, RStride = U1, CStride = U5> = + Matrix>; + +/// A column-major 6x1 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut6x1<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x2 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut6x2<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x3 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut6x3<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x4 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut6x4<'a, T, RStride = U1, CStride = U6> = + Matrix>; +/// A column-major 6x5 matrix view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type MatrixViewMut6x5<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/// A column-major matrix view with 1 row and a number of columns chosen at runtime. +pub type MatrixViewMut1xX<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A column-major matrix view with 2 rows and a number of columns chosen at runtime. +pub type MatrixViewMut2xX<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A column-major matrix view with 3 rows and a number of columns chosen at runtime. +pub type MatrixViewMut3xX<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A column-major matrix view with 4 rows and a number of columns chosen at runtime. +pub type MatrixViewMut4xX<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A column-major matrix view with 5 rows and a number of columns chosen at runtime. +pub type MatrixViewMut5xX<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A column-major matrix view with 6 rows and a number of columns chosen at runtime. +pub type MatrixViewMut6xX<'a, T, RStride = U1, CStride = U6> = + Matrix>; + +/// A column-major matrix view with a number of rows chosen at runtime and 1 column. +pub type MatrixViewMutXx1<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 2 columns. +pub type MatrixViewMutXx2<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 3 columns. +pub type MatrixViewMutXx3<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 4 columns. +pub type MatrixViewMutXx4<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 5 columns. +pub type MatrixViewMutXx5<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; +/// A column-major matrix view with a number of rows chosen at runtime and 6 columns. +pub type MatrixViewMutXx6<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; + +/// A column vector view with dimensions known at compile-time. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut<'a, T, D, RStride = U1, CStride = D> = + Matrix>; + +/// A column vector view with dimensions known at compile-time. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type SVectorViewMut<'a, T, const D: usize> = + Matrix, Const<1>, ViewStorageMut<'a, T, Const, Const<1>, Const<1>, Const>>; + +/// A column vector view dynamic numbers of rows and columns. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type DVectorViewMut<'a, T, RStride = U1, CStride = Dyn> = + Matrix>; + +/// A 1D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut1<'a, T, RStride = U1, CStride = U1> = + Matrix>; +/// A 2D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut2<'a, T, RStride = U1, CStride = U2> = + Matrix>; +/// A 3D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut3<'a, T, RStride = U1, CStride = U3> = + Matrix>; +/// A 4D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut4<'a, T, RStride = U1, CStride = U4> = + Matrix>; +/// A 5D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut5<'a, T, RStride = U1, CStride = U5> = + Matrix>; +/// A 6D column vector view. +/// +/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** +pub type VectorViewMut6<'a, T, RStride = U1, CStride = U6> = + Matrix>; diff --git a/src/base/allocator.rs b/src/base/allocator.rs index bb227d3b..6458b8cb 100644 --- a/src/base/allocator.rs +++ b/src/base/allocator.rs @@ -15,7 +15,7 @@ use std::mem::MaybeUninit; /// /// An allocator is said to be: /// − static: if `R` and `C` both implement `DimName`. -/// − dynamic: if either one (or both) of `R` or `C` is equal to `Dynamic`. +/// − dynamic: if either one (or both) of `R` or `C` is equal to `Dyn`. /// /// Every allocator must be both static and dynamic. Though not all implementations may share the /// same `Buffer` type. diff --git a/src/base/array_storage.rs b/src/base/array_storage.rs index 3bc71e1a..5c165399 100644 --- a/src/base/array_storage.rs +++ b/src/base/array_storage.rs @@ -27,11 +27,18 @@ use std::mem; /// A array-based statically sized matrix data storage. #[repr(transparent)] #[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "ArrayStorage", + bound(archive = " + T: rkyv::Archive, + [[T; R]; C]: rkyv::Archive + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct ArrayStorage(pub [[T; R]; C]); diff --git a/src/base/blas.rs b/src/base/blas.rs index e65304b5..e5741568 100644 --- a/src/base/blas.rs +++ b/src/base/blas.rs @@ -7,11 +7,11 @@ use crate::base::blas_uninit::{axcpy_uninit, gemm_uninit, gemv_uninit}; use crate::base::constraint::{ AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, }; -use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4}; +use crate::base::dimension::{Const, Dim, Dyn, U1, U2, U3, U4}; use crate::base::storage::{Storage, StorageMut}; use crate::base::uninit::Init; use crate::base::{ - DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSlice, + DVectorView, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorView, }; /// # Dot/scalar product @@ -363,8 +363,8 @@ where x: &Vector, beta: T, dot: impl Fn( - &DVectorSlice<'_, T, SB::RStride, SB::CStride>, - &DVectorSlice<'_, T, SC::RStride, SC::CStride>, + &DVectorView<'_, T, SB::RStride, SB::CStride>, + &DVectorView<'_, T, SC::RStride, SC::CStride>, ) -> T, ) where T: One, @@ -393,7 +393,7 @@ where let col2 = a.column(0); let val = unsafe { x.vget_unchecked(0).clone() }; self.axpy(alpha.clone() * val, &col2, beta); - self[0] += alpha.clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..)); + self[0] += alpha.clone() * dot(&a.view_range(1.., 0), &x.rows_range(1..)); for j in 1..dim2 { let col2 = a.column(j); @@ -506,7 +506,7 @@ where a: &Matrix, x: &Vector, beta: T, - dot: impl Fn(&VectorSlice<'_, T, R2, SB::RStride, SB::CStride>, &Vector) -> T, + dot: impl Fn(&VectorView<'_, T, R2, SB::RStride, SB::CStride>, &Vector) -> T, ) where T: One, SB: Storage, @@ -890,9 +890,9 @@ where for j in 0..dim1 { let val = unsafe { conjugate(y.vget_unchecked(j).clone()) }; - let subdim = Dynamic::new(dim1 - j); + let subdim = Dyn(dim1 - j); // TODO: avoid bound checks. - self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy( + self.generic_view_mut((j, j), (subdim, Const::<1>)).axpy( alpha.clone() * val, &x.rows_range(j..), beta.clone(), diff --git a/src/base/blas_uninit.rs b/src/base/blas_uninit.rs index 7e449d7d..3fcfa6e1 100644 --- a/src/base/blas_uninit.rs +++ b/src/base/blas_uninit.rs @@ -18,7 +18,7 @@ use std::mem; use crate::base::constraint::{ AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, }; -use crate::base::dimension::{Dim, Dynamic, U1}; +use crate::base::dimension::{Dim, Dyn, U1}; use crate::base::storage::{RawStorage, RawStorageMut}; use crate::base::uninit::InitStatus; use crate::base::{Matrix, Scalar, Vector}; @@ -209,16 +209,16 @@ pub unsafe fn gemm_uninit< #[cfg(feature = "std")] { - // We assume large matrices will be Dynamic but small matrices static. + // We assume large matrices will be Dyn but small matrices static. // We could use matrixmultiply for large statically-sized matrices but the performance // threshold to activate it would be different from SMALL_DIM because our code optimizes // better for statically-sized matrices. - if R1::is::() - || C1::is::() - || R2::is::() - || C2::is::() - || R3::is::() - || C3::is::() + if R1::is::() + || C1::is::() + || R2::is::() + || C2::is::() + || R3::is::() + || C3::is::() { // matrixmultiply can be used only if the std feature is available. let nrows1 = y.nrows(); diff --git a/src/base/cg.rs b/src/base/cg.rs index ef3ad5b5..586c923e 100644 --- a/src/base/cg.rs +++ b/src/base/cg.rs @@ -59,7 +59,7 @@ where SB: Storage>, { let mut res = Self::identity(); - res.generic_slice_mut( + res.generic_view_mut( (0, D::dim() - 1), (DimNameDiff::::name(), Const::<1>), ) @@ -382,19 +382,19 @@ impl>, { let scale = self - .generic_slice( + .generic_view( (D::dim() - 1, 0), (Const::<1>, DimNameDiff::::name()), ) .tr_dot(shift); - let post_translation = self.generic_slice( + let post_translation = self.generic_view( (0, 0), (DimNameDiff::::name(), DimNameDiff::::name()), ) * shift; self[(D::dim() - 1, D::dim() - 1)] += scale; - let mut translation = self.generic_slice_mut( + let mut translation = self.generic_view_mut( (0, D::dim() - 1), (DimNameDiff::::name(), Const::<1>), ); @@ -415,11 +415,11 @@ where &self, v: &OVector>, ) -> OVector> { - let transform = self.generic_slice( + let transform = self.generic_view( (0, 0), (DimNameDiff::::name(), DimNameDiff::::name()), ); - let normalizer = self.generic_slice( + let normalizer = self.generic_view( (D::dim() - 1, 0), (Const::<1>, DimNameDiff::::name()), ); @@ -437,9 +437,9 @@ impl, Const<3>>> SquareMatrix, /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. #[inline] pub fn transform_point(&self, pt: &Point) -> Point { - let transform = self.fixed_slice::<2, 2>(0, 0); - let translation = self.fixed_slice::<2, 1>(0, 2); - let normalizer = self.fixed_slice::<1, 2>(2, 0); + let transform = self.fixed_view::<2, 2>(0, 0); + let translation = self.fixed_view::<2, 1>(0, 2); + let normalizer = self.fixed_view::<1, 2>(2, 0); let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() }; if !n.is_zero() { @@ -454,9 +454,9 @@ impl, Const<4>>> SquareMatrix, /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. #[inline] pub fn transform_point(&self, pt: &Point) -> Point { - let transform = self.fixed_slice::<3, 3>(0, 0); - let translation = self.fixed_slice::<3, 1>(0, 3); - let normalizer = self.fixed_slice::<1, 3>(3, 0); + let transform = self.fixed_view::<3, 3>(0, 0); + let translation = self.fixed_view::<3, 1>(0, 3); + let normalizer = self.fixed_view::<1, 3>(3, 0); let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() }; if !n.is_zero() { diff --git a/src/base/constraint.rs b/src/base/constraint.rs index b8febd03..5aecc279 100644 --- a/src/base/constraint.rs +++ b/src/base/constraint.rs @@ -1,6 +1,6 @@ //! Compatibility constraints between matrix shapes, e.g., for addition or multiplication. -use crate::base::dimension::{Dim, DimName, Dynamic}; +use crate::base::dimension::{Dim, DimName, Dyn}; /// A type used in `where` clauses for enforcing constraints. #[derive(Copy, Clone, Debug)] @@ -25,11 +25,11 @@ impl DimEq for ShapeConstraint { type Representative = D; } -impl DimEq for ShapeConstraint { +impl DimEq for ShapeConstraint { type Representative = D; } -impl DimEq for ShapeConstraint { +impl DimEq for ShapeConstraint { type Representative = D; } @@ -47,11 +47,11 @@ macro_rules! equality_trait_decl( type Representative = D; } - impl $Trait for ShapeConstraint { + impl $Trait for ShapeConstraint { type Representative = D; } - impl $Trait for ShapeConstraint { + impl $Trait for ShapeConstraint { type Representative = D; } )*} @@ -82,10 +82,10 @@ impl SameDimension for ShapeConstraint { type Representative = D; } -impl SameDimension for ShapeConstraint { +impl SameDimension for ShapeConstraint { type Representative = D; } -impl SameDimension for ShapeConstraint { +impl SameDimension for ShapeConstraint { type Representative = D; } diff --git a/src/base/construction.rs b/src/base/construction.rs index 009d8c76..aabe75d8 100644 --- a/src/base/construction.rs +++ b/src/base/construction.rs @@ -19,7 +19,7 @@ use typenum::{self, Cmp, Greater}; use simba::scalar::{ClosedAdd, ClosedMul}; use crate::base::allocator::Allocator; -use crate::base::dimension::{Dim, DimName, Dynamic, ToTypenum}; +use crate::base::dimension::{Dim, DimName, Dyn, ToTypenum}; use crate::base::storage::RawStorage; use crate::base::{ ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector, @@ -317,12 +317,12 @@ where /// /// # Example /// ``` - /// # use nalgebra::{Dynamic, DMatrix, Matrix, Const}; + /// # use nalgebra::{Dyn, DMatrix, Matrix, Const}; /// /// let vec = vec![0, 1, 2, 3, 4, 5]; /// let vec_ptr = vec.as_ptr(); /// - /// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), Const::<1>, vec); + /// let matrix = Matrix::from_vec_generic(Dyn(vec.len()), Const::<1>, vec); /// let matrix_storage_ptr = matrix.data.as_vec().as_ptr(); /// /// // `matrix` is backed by exactly the same `Vec` as it was constructed from. @@ -656,35 +656,35 @@ where } /// # Constructors of matrices with a dynamic number of columns -impl OMatrix +impl OMatrix where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { - impl_constructors!(R, Dynamic; + impl_constructors!(R, Dyn; => R: DimName; - R::name(), Dynamic::new(ncols); + R::name(), Dyn(ncols); ncols); } /// # Constructors of dynamic vectors and matrices with a dynamic number of rows -impl OMatrix +impl OMatrix where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { - impl_constructors!(Dynamic, C; + impl_constructors!(Dyn, C; => C: DimName; - Dynamic::new(nrows), C::name(); + Dyn(nrows), C::name(); nrows); } /// # Constructors of fully dynamic matrices -impl OMatrix +impl OMatrix where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { - impl_constructors!(Dynamic, Dynamic; + impl_constructors!(Dyn, Dyn; ; - Dynamic::new(nrows), Dynamic::new(ncols); + Dyn(nrows), Dyn(ncols); nrows, ncols); } @@ -790,19 +790,19 @@ impl_constructors_from_data!(data; R, C; // Arguments for Matri R::name(), C::name(); // Arguments for `_generic` constructors. ); // Arguments for non-generic constructors. -impl_constructors_from_data!(data; R, Dynamic; +impl_constructors_from_data!(data; R, Dyn; => R: DimName; -R::name(), Dynamic::new(data.len() / R::dim()); +R::name(), Dyn(data.len() / R::dim()); ); -impl_constructors_from_data!(data; Dynamic, C; +impl_constructors_from_data!(data; Dyn, C; => C: DimName; -Dynamic::new(data.len() / C::dim()), C::name(); +Dyn(data.len() / C::dim()), C::name(); ); -impl_constructors_from_data!(data; Dynamic, Dynamic; +impl_constructors_from_data!(data; Dyn, Dyn; ; - Dynamic::new(nrows), Dynamic::new(ncols); + Dyn(nrows), Dyn(ncols); nrows, ncols); /* diff --git a/src/base/construction_slice.rs b/src/base/construction_view.rs similarity index 69% rename from src/base/construction_slice.rs rename to src/base/construction_view.rs index 7094bdca..8584f5b2 100644 --- a/src/base/construction_slice.rs +++ b/src/base/construction_view.rs @@ -1,18 +1,18 @@ -use crate::base::dimension::{Const, Dim, DimName, Dynamic}; -use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; -use crate::base::{MatrixSlice, MatrixSliceMutMN, Scalar}; +use crate::base::dimension::{Const, Dim, DimName, Dyn}; +use crate::base::matrix_view::{ViewStorage, ViewStorageMut}; +use crate::base::{MatrixView, MatrixViewMut, Scalar}; use num_rational::Ratio; -/// # Creating matrix slices from `&[T]` +/// # Creating matrix views from `&[T]` impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> - MatrixSlice<'a, T, R, C, RStride, CStride> + MatrixView<'a, T, R, C, RStride, CStride> { - /// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances. + /// Creates, without bounds checking, a matrix view from an array and with dimensions and strides specified by generic types instances. /// /// # Safety /// This method is unsafe because the input data array is not checked to contain enough elements. - /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub unsafe fn from_slice_with_strides_generic_unchecked( data: &'a [T], @@ -22,7 +22,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> rstride: RStride, cstride: CStride, ) -> Self { - let data = SliceStorage::from_raw_parts( + let data = ViewStorage::from_raw_parts( data.as_ptr().add(start), (nrows, ncols), (rstride, cstride), @@ -30,10 +30,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Self::from_data(data) } - /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances. + /// Creates a matrix view from an array and with dimensions and strides specified by generic types instances. /// /// Panics if the input data array dose not contain enough elements. - /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub fn from_slice_with_strides_generic( data: &'a [T], @@ -48,7 +48,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> assert!( data.len() + cstride.value() + rstride.value() >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1, - "Matrix slice: input data buffer to small." + "Matrix view: input data buffer too small." ); unsafe { @@ -57,12 +57,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> } } -impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> { - /// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances. +impl<'a, T: Scalar, R: Dim, C: Dim> MatrixView<'a, T, R, C> { + /// Creates, without bound-checking, a matrix view from an array and with dimensions specified by generic types instances. /// /// # Safety /// This method is unsafe because the input data array is not checked to contain enough elements. - /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub unsafe fn from_slice_generic_unchecked( data: &'a [T], @@ -75,10 +75,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> { ) } - /// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances. + /// Creates a matrix view from an array and with dimensions and strides specified by generic types instances. /// /// Panics if the input data array dose not contain enough elements. - /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self { Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows) @@ -87,8 +87,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> { macro_rules! impl_constructors( ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { - impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSlice<'a, T, $($Dims),*> { - /// Creates a new matrix slice from the given data array. + impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixView<'a, T, $($Dims),*> { + /// Creates a new matrix view from the given data array. /// /// Panics if `data` does not contain enough elements. #[inline] @@ -96,26 +96,26 @@ macro_rules! impl_constructors( Self::from_slice_generic(data, $($gargs),*) } - /// Creates, without bound checking, a new matrix slice from the given data array. + /// Creates, without bound checking, a new matrix view from the given data array. #[inline] pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self { Self::from_slice_generic_unchecked(data, start, $($gargs),*) } } - impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSlice<'a, T, $($Dims,)* Dynamic, Dynamic> { - /// Creates a new matrix slice with the specified strides from the given data array. + impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixView<'a, T, $($Dims,)* Dyn, Dyn> { + /// Creates a new matrix view with the specified strides from the given data array. /// /// Panics if `data` does not contain enough elements. #[inline] pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self { - Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) + Self::from_slice_with_strides_generic(data, $($gargs,)* Dyn(rstride), Dyn(cstride)) } - /// Creates, without bound checking, a new matrix slice with the specified strides from the given data array. + /// Creates, without bound checking, a new matrix view with the specified strides from the given data array. #[inline] pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { - Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) + Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride)) } } } @@ -127,30 +127,30 @@ impl_constructors!(R, C; // Arguments for Matrix R: DimName; - R::name(), Dynamic::new(ncols); + R::name(), Dyn(ncols); ncols); -impl_constructors!(Dynamic, C; +impl_constructors!(Dyn, C; => C: DimName; - Dynamic::new(nrows), C::name(); + Dyn(nrows), C::name(); nrows); -impl_constructors!(Dynamic, Dynamic; +impl_constructors!(Dyn, Dyn; ; - Dynamic::new(nrows), Dynamic::new(ncols); + Dyn(nrows), Dyn(ncols); nrows, ncols); -/// # Creating mutable matrix slices from `&mut [T]` +/// # Creating mutable matrix views from `&mut [T]` impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> - MatrixSliceMutMN<'a, T, R, C, RStride, CStride> + MatrixViewMut<'a, T, R, C, RStride, CStride> { - /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. + /// Creates, without bound-checking, a mutable matrix view from an array and with dimensions and strides specified by generic types instances. /// /// # Safety /// This method is unsafe because the input data array is not checked to contain enough elements. - /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub unsafe fn from_slice_with_strides_generic_unchecked( data: &'a mut [T], @@ -160,7 +160,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> rstride: RStride, cstride: CStride, ) -> Self { - let data = SliceStorageMut::from_raw_parts( + let data = ViewStorageMut::from_raw_parts( data.as_mut_ptr().add(start), (nrows, ncols), (rstride, cstride), @@ -168,10 +168,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Self::from_data(data) } - /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. + /// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances. /// /// Panics if the input data array dose not contain enough elements. - /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub fn from_slice_with_strides_generic( data: &'a mut [T], @@ -186,7 +186,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> assert!( data.len() + cstride.value() + rstride.value() >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1, - "Matrix slice: input data buffer to small." + "Matrix view: input data buffer too small." ); assert!( @@ -208,7 +208,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> } } }, - "Matrix slice: dimensions and strides result in aliased indices." + "Matrix view: dimensions and strides result in aliased indices." ); unsafe { @@ -217,12 +217,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> } } -impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> { - /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances. +impl<'a, T: Scalar, R: Dim, C: Dim> MatrixViewMut<'a, T, R, C> { + /// Creates, without bound-checking, a mutable matrix view from an array and with dimensions specified by generic types instances. /// /// # Safety /// This method is unsafe because the input data array is not checked to contain enough elements. - /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub unsafe fn from_slice_generic_unchecked( data: &'a mut [T], @@ -235,10 +235,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> { ) } - /// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. + /// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances. /// /// Panics if the input data array dose not contain enough elements. - /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. + /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`. #[inline] pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self { Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows) @@ -247,8 +247,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> { macro_rules! impl_constructors_mut( ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { - impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, T, $($Dims),*> { - /// Creates a new mutable matrix slice from the given data array. + impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixViewMut<'a, T, $($Dims),*> { + /// Creates a new mutable matrix view from the given data array. /// /// Panics if `data` does not contain enough elements. #[inline] @@ -256,28 +256,28 @@ macro_rules! impl_constructors_mut( Self::from_slice_generic(data, $($gargs),*) } - /// Creates, without bound checking, a new mutable matrix slice from the given data array. + /// Creates, without bound checking, a new mutable matrix view from the given data array. #[inline] pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self { Self::from_slice_generic_unchecked(data, start, $($gargs),*) } } - impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, T, $($Dims,)* Dynamic, Dynamic> { - /// Creates a new mutable matrix slice with the specified strides from the given data array. + impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixViewMut<'a, T, $($Dims,)* Dyn, Dyn> { + /// Creates a new mutable matrix view with the specified strides from the given data array. /// /// Panics if `data` does not contain enough elements. #[inline] pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self { Self::from_slice_with_strides_generic( - data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) + data, $($gargs,)* Dyn(rstride), Dyn(cstride)) } - /// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array. + /// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array. #[inline] pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { Self::from_slice_with_strides_generic_unchecked( - data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) + data, start, $($gargs,)* Dyn(rstride), Dyn(cstride)) } } } @@ -289,17 +289,17 @@ impl_constructors_mut!(R, C; // Arguments for Matrix R: DimName; - R::name(), Dynamic::new(ncols); + R::name(), Dyn(ncols); ncols); -impl_constructors_mut!(Dynamic, C; +impl_constructors_mut!(Dyn, C; => C: DimName; - Dynamic::new(nrows), C::name(); + Dyn(nrows), C::name(); nrows); -impl_constructors_mut!(Dynamic, Dynamic; +impl_constructors_mut!(Dyn, Dyn; ; - Dynamic::new(nrows), Dynamic::new(ncols); + Dyn(nrows), Dyn(ncols); nrows, ncols); diff --git a/src/base/conversion.rs b/src/base/conversion.rs index dd71186f..22774287 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -9,21 +9,21 @@ use simba::simd::{PrimitiveSimdValue, SimdValue}; use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; #[cfg(any(feature = "std", feature = "alloc"))] -use crate::base::dimension::Dynamic; +use crate::base::dimension::Dyn; use crate::base::dimension::{ Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9, }; use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut}; use crate::base::{ - ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice, - MatrixSliceMut, OMatrix, Scalar, + ArrayStorage, DVectorView, DVectorViewMut, DefaultAllocator, Matrix, MatrixView, MatrixViewMut, + OMatrix, Scalar, }; #[cfg(any(feature = "std", feature = "alloc"))] use crate::base::{DVector, RowDVector, VecStorage}; -use crate::base::{SliceStorage, SliceStorageMut}; +use crate::base::{ViewStorage, ViewStorageMut}; use crate::constraint::DimEq; -use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorSlice, VectorSliceMut}; +use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut}; use std::mem::MaybeUninit; // TODO: too bad this won't work for slice conversions. @@ -126,19 +126,19 @@ impl From> for [T; D] { } impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize> - From, RStride, CStride>> for [T; D] + From, RStride, CStride>> for [T; D] { #[inline] - fn from(vec: VectorSlice<'a, T, Const, RStride, CStride>) -> Self { + fn from(vec: VectorView<'a, T, Const, RStride, CStride>) -> Self { vec.into_owned().into() } } impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize> - From, RStride, CStride>> for [T; D] + From, RStride, CStride>> for [T; D] { #[inline] - fn from(vec: VectorSliceMut<'a, T, Const, RStride, CStride>) -> Self { + fn from(vec: VectorViewMut<'a, T, Const, RStride, CStride>) -> Self { vec.into_owned().into() } } @@ -221,19 +221,19 @@ impl From> for [[T; } impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize> - From, Const, RStride, CStride>> for [[T; R]; C] + From, Const, RStride, CStride>> for [[T; R]; C] { #[inline] - fn from(mat: MatrixSlice<'a, T, Const, Const, RStride, CStride>) -> Self { + fn from(mat: MatrixView<'a, T, Const, Const, RStride, CStride>) -> Self { mat.into_owned().into() } } impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize> - From, Const, RStride, CStride>> for [[T; R]; C] + From, Const, RStride, CStride>> for [[T; R]; C] { #[inline] - fn from(mat: MatrixSliceMut<'a, T, Const, Const, RStride, CStride>) -> Self { + fn from(mat: MatrixViewMut<'a, T, Const, Const, RStride, CStride>) -> Self { mat.into_owned().into() } } @@ -289,192 +289,183 @@ impl_from_into_asref_borrow_2D!( ); impl<'a, T, RStride, CStride, const R: usize, const C: usize> - From, Const, RStride, CStride>> + From, Const, RStride, CStride>> for Matrix, Const, ArrayStorage> where T: Scalar, RStride: Dim, CStride: Dim, { - fn from(matrix_slice: MatrixSlice<'a, T, Const, Const, RStride, CStride>) -> Self { - matrix_slice.into_owned() + fn from(matrix_view: MatrixView<'a, T, Const, Const, RStride, CStride>) -> Self { + matrix_view.into_owned() } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T, C, RStride, CStride> From> - for Matrix> +impl<'a, T, C, RStride, CStride> From> + for Matrix> where T: Scalar, C: Dim, RStride: Dim, CStride: Dim, { - fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self { - matrix_slice.into_owned() + fn from(matrix_view: MatrixView<'a, T, Dyn, C, RStride, CStride>) -> Self { + matrix_view.into_owned() } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T, R, RStride, CStride> From> - for Matrix> +impl<'a, T, R, RStride, CStride> From> + for Matrix> where T: Scalar, R: DimName, RStride: Dim, CStride: Dim, { - fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self { - matrix_slice.into_owned() + fn from(matrix_view: MatrixView<'a, T, R, Dyn, RStride, CStride>) -> Self { + matrix_view.into_owned() } } impl<'a, T, RStride, CStride, const R: usize, const C: usize> - From, Const, RStride, CStride>> + From, Const, RStride, CStride>> for Matrix, Const, ArrayStorage> where T: Scalar, RStride: Dim, CStride: Dim, { - fn from(matrix_slice: MatrixSliceMut<'a, T, Const, Const, RStride, CStride>) -> Self { - matrix_slice.into_owned() + fn from(matrix_view: MatrixViewMut<'a, T, Const, Const, RStride, CStride>) -> Self { + matrix_view.into_owned() } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T, C, RStride, CStride> From> - for Matrix> +impl<'a, T, C, RStride, CStride> From> + for Matrix> where T: Scalar, C: Dim, RStride: Dim, CStride: Dim, { - fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self { - matrix_slice.into_owned() + fn from(matrix_view: MatrixViewMut<'a, T, Dyn, C, RStride, CStride>) -> Self { + matrix_view.into_owned() } } #[cfg(any(feature = "std", feature = "alloc"))] -impl<'a, T, R, RStride, CStride> From> - for Matrix> +impl<'a, T, R, RStride, CStride> From> + for Matrix> where T: Scalar, R: DimName, RStride: Dim, CStride: Dim, { - fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self { - matrix_slice.into_owned() + fn from(matrix_view: MatrixViewMut<'a, T, R, Dyn, RStride, CStride>) -> Self { + matrix_view.into_owned() } } -impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix> - for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride> +impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a Matrix> + for MatrixView<'a, T, RView, CView, RStride, CStride> where - T: Scalar, R: Dim, C: Dim, - RSlice: Dim, - CSlice: Dim, + RView: Dim, + CView: Dim, RStride: Dim, CStride: Dim, S: RawStorage, - ShapeConstraint: DimEq - + DimEq - + DimEq - + DimEq, + ShapeConstraint: + DimEq + DimEq + DimEq + DimEq, { fn from(m: &'a Matrix) -> Self { let (row, col) = m.shape_generic(); - let row_slice = RSlice::from_usize(row.value()); - let col_slice = CSlice::from_usize(col.value()); + let rows_result = RView::from_usize(row.value()); + let cols_result = CView::from_usize(col.value()); let (rstride, cstride) = m.strides(); - let rstride_slice = RStride::from_usize(rstride); - let cstride_slice = CStride::from_usize(cstride); + let rstride_result = RStride::from_usize(rstride); + let cstride_result = CStride::from_usize(cstride); unsafe { - let data = SliceStorage::from_raw_parts( + let data = ViewStorage::from_raw_parts( m.data.ptr(), - (row_slice, col_slice), - (rstride_slice, cstride_slice), + (rows_result, cols_result), + (rstride_result, cstride_result), ); Matrix::from_data_statically_unchecked(data) } } } -impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix> - for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride> +impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix> + for MatrixView<'a, T, RView, CView, RStride, CStride> where - T: Scalar, R: Dim, C: Dim, - RSlice: Dim, - CSlice: Dim, + RView: Dim, + CView: Dim, RStride: Dim, CStride: Dim, S: RawStorage, - ShapeConstraint: DimEq - + DimEq - + DimEq - + DimEq, + ShapeConstraint: + DimEq + DimEq + DimEq + DimEq, { fn from(m: &'a mut Matrix) -> Self { let (row, col) = m.shape_generic(); - let row_slice = RSlice::from_usize(row.value()); - let col_slice = CSlice::from_usize(col.value()); + let rows_result = RView::from_usize(row.value()); + let cols_result = CView::from_usize(col.value()); let (rstride, cstride) = m.strides(); - let rstride_slice = RStride::from_usize(rstride); - let cstride_slice = CStride::from_usize(cstride); + let rstride_result = RStride::from_usize(rstride); + let cstride_result = CStride::from_usize(cstride); unsafe { - let data = SliceStorage::from_raw_parts( + let data = ViewStorage::from_raw_parts( m.data.ptr(), - (row_slice, col_slice), - (rstride_slice, cstride_slice), + (rows_result, cols_result), + (rstride_result, cstride_result), ); Matrix::from_data_statically_unchecked(data) } } } -impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix> - for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride> +impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix> + for MatrixViewMut<'a, T, RView, CView, RStride, CStride> where - T: Scalar, R: Dim, C: Dim, - RSlice: Dim, - CSlice: Dim, + RView: Dim, + CView: Dim, RStride: Dim, CStride: Dim, S: RawStorageMut, - ShapeConstraint: DimEq - + DimEq - + DimEq - + DimEq, + ShapeConstraint: + DimEq + DimEq + DimEq + DimEq, { fn from(m: &'a mut Matrix) -> Self { let (row, col) = m.shape_generic(); - let row_slice = RSlice::from_usize(row.value()); - let col_slice = CSlice::from_usize(col.value()); + let rows_result = RView::from_usize(row.value()); + let cols_result = CView::from_usize(col.value()); let (rstride, cstride) = m.strides(); - let rstride_slice = RStride::from_usize(rstride); - let cstride_slice = CStride::from_usize(cstride); + let rstride_result = RStride::from_usize(rstride); + let cstride_result = CStride::from_usize(cstride); unsafe { - let data = SliceStorageMut::from_raw_parts( + let data = ViewStorageMut::from_raw_parts( m.data.ptr_mut(), - (row_slice, col_slice), - (rstride_slice, cstride_slice), + (rows_result, cols_result), + (rstride_result, cstride_result), ); Matrix::from_data_statically_unchecked(data) } @@ -515,28 +506,28 @@ impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: RawStorageMut + IsContigu } } -impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorSlice<'a, T> { +impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorView<'a, T> { #[inline] fn from(slice: &'a [T]) -> Self { Self::from_slice(slice, slice.len()) } } -impl<'a, T: Scalar> From> for &'a [T] { - fn from(vec: DVectorSlice<'a, T>) -> &'a [T] { +impl<'a, T: Scalar> From> for &'a [T] { + fn from(vec: DVectorView<'a, T>) -> &'a [T] { vec.data.into_slice() } } -impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorSliceMut<'a, T> { +impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorViewMut<'a, T> { #[inline] fn from(slice: &'a mut [T]) -> Self { Self::from_slice(slice, slice.len()) } } -impl<'a, T: Scalar> From> for &'a mut [T] { - fn from(vec: DVectorSliceMut<'a, T>) -> &'a mut [T] { +impl<'a, T: Scalar> From> for &'a mut [T] { + fn from(vec: DVectorViewMut<'a, T>) -> &'a mut [T] { vec.data.into_slice_mut() } } diff --git a/src/base/default_allocator.rs b/src/base/default_allocator.rs index 6aaadfc7..ff645d62 100644 --- a/src/base/default_allocator.rs +++ b/src/base/default_allocator.rs @@ -13,7 +13,7 @@ use super::Const; use crate::base::allocator::{Allocator, Reallocator}; use crate::base::array_storage::ArrayStorage; #[cfg(any(feature = "alloc", feature = "std"))] -use crate::base::dimension::Dynamic; +use crate::base::dimension::Dyn; use crate::base::dimension::{Dim, DimName}; use crate::base::storage::{RawStorage, RawStorageMut}; #[cfg(any(feature = "std", feature = "alloc"))] @@ -82,15 +82,15 @@ impl Allocator, Const> } } -// Dynamic - Static -// Dynamic - Dynamic +// Dyn - Static +// Dyn - Dyn #[cfg(any(feature = "std", feature = "alloc"))] -impl Allocator for DefaultAllocator { - type Buffer = VecStorage; - type BufferUninit = VecStorage, Dynamic, C>; +impl Allocator for DefaultAllocator { + type Buffer = VecStorage; + type BufferUninit = VecStorage, Dyn, C>; #[inline] - fn allocate_uninit(nrows: Dynamic, ncols: C) -> VecStorage, Dynamic, C> { + fn allocate_uninit(nrows: Dyn, ncols: C) -> VecStorage, Dyn, C> { let mut data = Vec::new(); let length = nrows.value() * ncols.value(); data.reserve_exact(length); @@ -99,9 +99,7 @@ impl Allocator for DefaultAllocator { } #[inline] - unsafe fn assume_init( - uninit: VecStorage, Dynamic, C>, - ) -> VecStorage { + unsafe fn assume_init(uninit: VecStorage, Dyn, C>) -> VecStorage { // Avoids a double-drop. let (nrows, ncols) = uninit.shape(); let vec: Vec<_> = uninit.into(); @@ -117,7 +115,7 @@ impl Allocator for DefaultAllocator { #[inline] fn allocate_from_iterator>( - nrows: Dynamic, + nrows: Dyn, ncols: C, iter: I, ) -> Self::Buffer { @@ -130,14 +128,14 @@ impl Allocator for DefaultAllocator { } } -// Static - Dynamic +// Static - Dyn #[cfg(any(feature = "std", feature = "alloc"))] -impl Allocator for DefaultAllocator { - type Buffer = VecStorage; - type BufferUninit = VecStorage, R, Dynamic>; +impl Allocator for DefaultAllocator { + type Buffer = VecStorage; + type BufferUninit = VecStorage, R, Dyn>; #[inline] - fn allocate_uninit(nrows: R, ncols: Dynamic) -> VecStorage, R, Dynamic> { + fn allocate_uninit(nrows: R, ncols: Dyn) -> VecStorage, R, Dyn> { let mut data = Vec::new(); let length = nrows.value() * ncols.value(); data.reserve_exact(length); @@ -147,9 +145,7 @@ impl Allocator for DefaultAllocator { } #[inline] - unsafe fn assume_init( - uninit: VecStorage, R, Dynamic>, - ) -> VecStorage { + unsafe fn assume_init(uninit: VecStorage, R, Dyn>) -> VecStorage { // Avoids a double-drop. let (nrows, ncols) = uninit.shape(); let vec: Vec<_> = uninit.into(); @@ -166,7 +162,7 @@ impl Allocator for DefaultAllocator { #[inline] fn allocate_from_iterator>( nrows: R, - ncols: Dynamic, + ncols: Dyn, iter: I, ) -> Self::Buffer { let it = iter.into_iter(); @@ -215,20 +211,20 @@ where } } -// Static × Static -> Dynamic × Any +// Static × Static -> Dyn × Any #[cfg(any(feature = "std", feature = "alloc"))] impl - Reallocator, Const, Dynamic, CTo> for DefaultAllocator + Reallocator, Const, Dyn, CTo> for DefaultAllocator where CTo: Dim, { #[inline] unsafe fn reallocate_copy( - rto: Dynamic, + rto: Dyn, cto: CTo, buf: ArrayStorage, - ) -> VecStorage, Dynamic, CTo> { - let mut res = >::allocate_uninit(rto, cto); + ) -> VecStorage, Dyn, CTo> { + let mut res = >::allocate_uninit(rto, cto); let (rfrom, cfrom) = buf.shape(); @@ -246,20 +242,20 @@ where } } -// Static × Static -> Static × Dynamic +// Static × Static -> Static × Dyn #[cfg(any(feature = "std", feature = "alloc"))] impl - Reallocator, Const, RTo, Dynamic> for DefaultAllocator + Reallocator, Const, RTo, Dyn> for DefaultAllocator where RTo: DimName, { #[inline] unsafe fn reallocate_copy( rto: RTo, - cto: Dynamic, + cto: Dyn, buf: ArrayStorage, - ) -> VecStorage, RTo, Dynamic> { - let mut res = >::allocate_uninit(rto, cto); + ) -> VecStorage, RTo, Dyn> { + let mut res = >::allocate_uninit(rto, cto); let (rfrom, cfrom) = buf.shape(); @@ -279,60 +275,58 @@ where // All conversion from a dynamic buffer to a dynamic buffer. #[cfg(any(feature = "std", feature = "alloc"))] -impl Reallocator - for DefaultAllocator -{ +impl Reallocator for DefaultAllocator { #[inline] unsafe fn reallocate_copy( - rto: Dynamic, + rto: Dyn, cto: CTo, - buf: VecStorage, - ) -> VecStorage, Dynamic, CTo> { + buf: VecStorage, + ) -> VecStorage, Dyn, CTo> { let new_buf = buf.resize(rto.value() * cto.value()); VecStorage::new(rto, cto, new_buf) } } #[cfg(any(feature = "std", feature = "alloc"))] -impl Reallocator +impl Reallocator for DefaultAllocator { #[inline] unsafe fn reallocate_copy( rto: RTo, - cto: Dynamic, - buf: VecStorage, - ) -> VecStorage, RTo, Dynamic> { + cto: Dyn, + buf: VecStorage, + ) -> VecStorage, RTo, Dyn> { let new_buf = buf.resize(rto.value() * cto.value()); VecStorage::new(rto, cto, new_buf) } } #[cfg(any(feature = "std", feature = "alloc"))] -impl Reallocator +impl Reallocator for DefaultAllocator { #[inline] unsafe fn reallocate_copy( - rto: Dynamic, + rto: Dyn, cto: CTo, - buf: VecStorage, - ) -> VecStorage, Dynamic, CTo> { + buf: VecStorage, + ) -> VecStorage, Dyn, CTo> { let new_buf = buf.resize(rto.value() * cto.value()); VecStorage::new(rto, cto, new_buf) } } #[cfg(any(feature = "std", feature = "alloc"))] -impl Reallocator +impl Reallocator for DefaultAllocator { #[inline] unsafe fn reallocate_copy( rto: RTo, - cto: Dynamic, - buf: VecStorage, - ) -> VecStorage, RTo, Dynamic> { + cto: Dyn, + buf: VecStorage, + ) -> VecStorage, RTo, Dyn> { let new_buf = buf.resize(rto.value() * cto.value()); VecStorage::new(rto, cto, new_buf) } diff --git a/src/base/dimension.rs b/src/base/dimension.rs index b1b700d7..97616129 100644 --- a/src/base/dimension.rs +++ b/src/base/dimension.rs @@ -13,54 +13,59 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Dim of dynamically-sized algebraic entities. #[derive(Clone, Copy, Eq, PartialEq, Debug)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr( + feature = "rkyv-serialize", + archive_attr(derive(bytecheck::CheckBytes)) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] -pub struct Dynamic { - value: usize, -} +pub struct Dyn(pub usize); -impl Dynamic { +#[deprecated(note = "use Dyn instead.")] +pub type Dynamic = Dyn; + +impl Dyn { /// A dynamic size equal to `value`. #[inline] + #[deprecated(note = "use Dyn(value) instead.")] pub const fn new(value: usize) -> Self { - Self { value } + Self(value) } } #[cfg(feature = "serde-serialize-no-std")] -impl Serialize for Dynamic { +impl Serialize for Dyn { fn serialize(&self, serializer: S) -> Result where S: Serializer, { - self.value.serialize(serializer) + self.0.serialize(serializer) } } #[cfg(feature = "serde-serialize-no-std")] -impl<'de> Deserialize<'de> for Dynamic { +impl<'de> Deserialize<'de> for Dyn { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - usize::deserialize(deserializer).map(|x| Dynamic { value: x }) + usize::deserialize(deserializer).map(|x| Dyn(x)) } } -/// Trait implemented by `Dynamic`. +/// Trait implemented by `Dyn`. pub trait IsDynamic {} -/// Trait implemented by `Dynamic` and type-level integers different from `U1`. +/// Trait implemented by `Dyn` and type-level integers different from `U1`. pub trait IsNotStaticOne {} -impl IsDynamic for Dynamic {} -impl IsNotStaticOne for Dynamic {} +impl IsDynamic for Dyn {} +impl IsNotStaticOne for Dyn {} /// Trait implemented by any type that can be used as a dimension. This includes type-level -/// integers and `Dynamic` (for dimensions not known at compile-time). +/// integers and `Dyn` (for dimensions not known at compile-time). pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync { #[inline(always)] fn is() -> bool { @@ -68,7 +73,7 @@ pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync { } /// Gets the compile-time value of `Self`. Returns `None` if it is not known, i.e., if `Self = - /// Dynamic`. + /// Dyn`. fn try_to_usize() -> Option; /// Gets the run-time value of `self`. For type-level integers, this is the same as @@ -80,7 +85,7 @@ pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync { fn from_usize(dim: usize) -> Self; } -unsafe impl Dim for Dynamic { +unsafe impl Dim for Dyn { #[inline] fn try_to_usize() -> Option { None @@ -88,30 +93,30 @@ unsafe impl Dim for Dynamic { #[inline] fn from_usize(dim: usize) -> Self { - Self::new(dim) + Self(dim) } #[inline] fn value(&self) -> usize { - self.value + self.0 } } -impl Add for Dynamic { - type Output = Dynamic; +impl Add for Dyn { + type Output = Dyn; #[inline] fn add(self, rhs: usize) -> Self { - Self::new(self.value + rhs) + Self(self.0 + rhs) } } -impl Sub for Dynamic { - type Output = Dynamic; +impl Sub for Dyn { + type Output = Dyn; #[inline] fn sub(self, rhs: usize) -> Self { - Self::new(self.value - rhs) + Self(self.0 - rhs) } } @@ -149,22 +154,22 @@ macro_rules! dim_ops( } } - impl $DimOp for Dynamic { - type Output = Dynamic; + impl $DimOp for Dyn { + type Output = Dyn; #[inline] - fn $op(self, other: D) -> Dynamic { - Dynamic::new($op_path(self.value, other.value())) + fn $op(self, other: D) -> Dyn { + Dyn($op_path(self.value(), other.value())) } } // TODO: use Const instead of D: DimName? - impl $DimOp for D { - type Output = Dynamic; + impl $DimOp for D { + type Output = Dyn; #[inline] - fn $op(self, other: Dynamic) -> Dynamic { - Dynamic::new($op_path(self.value(), other.value)) + fn $op(self, other: Dyn) -> Dyn { + Dyn($op_path(self.value(), other.value())) } } @@ -205,7 +210,8 @@ dim_ops!( #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive(as = "Self") )] #[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] @@ -306,6 +312,11 @@ macro_rules! from_to_typenum ( } impl IsNotStaticOne for $D { } + + /// The constant dimension + #[doc = stringify!($VAL)] + /// . + pub const $D: $D = Const::<$VAL>; )*} ); @@ -319,3 +330,7 @@ from_to_typenum!( U111, 111; U112, 112; U113, 113; U114, 114; U115, 115; U116, 116; U117, 117; U118, 118; U119, 119; U120, 120; U121, 121; U122, 122; U123, 123; U124, 124; U125, 125; U126, 126; U127, 127 ); + +/// The constant dimension 1. +// Note: We add U1 separately since it's not covered by the from_to_typenum! macro. +pub const U1: U1 = Const::<1>; diff --git a/src/base/edition.rs b/src/base/edition.rs index 760b3950..e482fa24 100644 --- a/src/base/edition.rs +++ b/src/base/edition.rs @@ -7,7 +7,7 @@ use std::ptr; use crate::base::allocator::{Allocator, Reallocator}; use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; #[cfg(any(feature = "std", feature = "alloc"))] -use crate::base::dimension::Dynamic; +use crate::base::dimension::Dyn; use crate::base::dimension::{Const, Dim, DimAdd, DimDiff, DimMin, DimMinimum, DimSub, DimSum, U1}; use crate::base::storage::{RawStorage, RawStorageMut, ReshapableStorage}; use crate::base::{DefaultAllocator, Matrix, OMatrix, RowVector, Scalar, Vector}; @@ -48,15 +48,15 @@ impl> Matrix { /// Creates a new matrix by extracting the given set of rows from `self`. #[cfg(any(feature = "std", feature = "alloc"))] #[must_use] - pub fn select_rows<'a, I>(&self, irows: I) -> OMatrix + pub fn select_rows<'a, I>(&self, irows: I) -> OMatrix where I: IntoIterator, I::IntoIter: ExactSizeIterator + Clone, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { let irows = irows.into_iter(); let ncols = self.shape_generic().1; - let mut res = Matrix::uninit(Dynamic::new(irows.len()), ncols); + let mut res = Matrix::uninit(Dyn(irows.len()), ncols); // First, check that all the indices from irows are valid. // This will allow us to use unchecked access in the inner loop. @@ -85,15 +85,15 @@ impl> Matrix { /// Creates a new matrix by extracting the given set of columns from `self`. #[cfg(any(feature = "std", feature = "alloc"))] #[must_use] - pub fn select_columns<'a, I>(&self, icols: I) -> OMatrix + pub fn select_columns<'a, I>(&self, icols: I) -> OMatrix where I: IntoIterator, I::IntoIter: ExactSizeIterator, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { let icols = icols.into_iter(); let nrows = self.shape_generic().0; - let mut res = Matrix::uninit(nrows, Dynamic::new(icols.len())); + let mut res = Matrix::uninit(nrows, Dyn(icols.len())); for (destination, source) in icols.enumerate() { // NOTE: this is basically a copy_frow but wrapping the values insnide of MaybeUninit. @@ -359,10 +359,10 @@ impl> Matrix { /// Removes all columns in `indices` #[cfg(any(feature = "std", feature = "alloc"))] - pub fn remove_columns_at(self, indices: &[usize]) -> OMatrix + pub fn remove_columns_at(self, indices: &[usize]) -> OMatrix where - C: DimSub, - DefaultAllocator: Reallocator, + C: DimSub, + DefaultAllocator: Reallocator, { let mut m = self.into_owned(); let (nrows, ncols) = m.shape_generic(); @@ -400,7 +400,7 @@ impl> Matrix { unsafe { let new_data = DefaultAllocator::reallocate_copy( nrows, - ncols.sub(Dynamic::from_usize(offset)), + ncols.sub(Dyn::from_usize(offset)), m.data, ); @@ -410,10 +410,10 @@ impl> Matrix { /// Removes all rows in `indices` #[cfg(any(feature = "std", feature = "alloc"))] - pub fn remove_rows_at(self, indices: &[usize]) -> OMatrix + pub fn remove_rows_at(self, indices: &[usize]) -> OMatrix where - R: DimSub, - DefaultAllocator: Reallocator, + R: DimSub, + DefaultAllocator: Reallocator, { let mut m = self.into_owned(); let (nrows, ncols) = m.shape_generic(); @@ -448,7 +448,7 @@ impl> Matrix { // be assumed to be initialized. unsafe { let new_data = DefaultAllocator::reallocate_copy( - nrows.sub(Dynamic::from_usize(offset / ncols.value())), + nrows.sub(Dyn::from_usize(offset / ncols.value())), ncols, m.data, ); @@ -474,12 +474,12 @@ impl> Matrix { /// Removes `n` consecutive columns from this matrix, starting with the `i`-th (included). #[inline] #[cfg(any(feature = "std", feature = "alloc"))] - pub fn remove_columns(self, i: usize, n: usize) -> OMatrix + pub fn remove_columns(self, i: usize, n: usize) -> OMatrix where - C: DimSub, - DefaultAllocator: Reallocator, + C: DimSub, + DefaultAllocator: Reallocator, { - self.remove_columns_generic(i, Dynamic::new(n)) + self.remove_columns_generic(i, Dyn(n)) } /// Removes `nremove.value()` columns from this matrix, starting with the `i`-th (included). @@ -569,12 +569,12 @@ impl> Matrix { /// Removes `n` consecutive rows from this matrix, starting with the `i`-th (included). #[inline] #[cfg(any(feature = "std", feature = "alloc"))] - pub fn remove_rows(self, i: usize, n: usize) -> OMatrix + pub fn remove_rows(self, i: usize, n: usize) -> OMatrix where - R: DimSub, - DefaultAllocator: Reallocator, + R: DimSub, + DefaultAllocator: Reallocator, { - self.remove_rows_generic(i, Dynamic::new(n)) + self.remove_rows_generic(i, Dyn(n)) } /// Removes `nremove.value()` rows from this matrix, starting with the `i`-th (included). @@ -659,12 +659,12 @@ impl> Matrix { /// Inserts `n` columns filled with `val` starting at the `i-th` position. #[inline] #[cfg(any(feature = "std", feature = "alloc"))] - pub fn insert_columns(self, i: usize, n: usize, val: T) -> OMatrix + pub fn insert_columns(self, i: usize, n: usize, val: T) -> OMatrix where - C: DimAdd, - DefaultAllocator: Reallocator, + C: DimAdd, + DefaultAllocator: Reallocator, { - let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) }; + let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dyn(n)) }; res.columns_mut(i, n) .fill_with(|| MaybeUninit::new(val.clone())); @@ -752,12 +752,12 @@ impl> Matrix { /// Inserts `n` rows filled with `val` starting at the `i-th` position. #[inline] #[cfg(any(feature = "std", feature = "alloc"))] - pub fn insert_rows(self, i: usize, n: usize, val: T) -> OMatrix + pub fn insert_rows(self, i: usize, n: usize, val: T) -> OMatrix where - R: DimAdd, - DefaultAllocator: Reallocator, + R: DimAdd, + DefaultAllocator: Reallocator, { - let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) }; + let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dyn(n)) }; res.rows_mut(i, n) .fill_with(|| MaybeUninit::new(val.clone())); @@ -815,11 +815,11 @@ impl> Matrix { /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// rows and/or columns than `self`, then the extra rows or columns are filled with `val`. #[cfg(any(feature = "std", feature = "alloc"))] - pub fn resize(self, new_nrows: usize, new_ncols: usize, val: T) -> OMatrix + pub fn resize(self, new_nrows: usize, new_ncols: usize, val: T) -> OMatrix where - DefaultAllocator: Reallocator, + DefaultAllocator: Reallocator, { - self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val) + self.resize_generic(Dyn(new_nrows), Dyn(new_ncols), val) } /// Resizes this matrix vertically, i.e., so that it contains `new_nrows` rows while keeping the same number of columns. @@ -827,12 +827,12 @@ impl> Matrix { /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// rows than `self`, then the extra rows are filled with `val`. #[cfg(any(feature = "std", feature = "alloc"))] - pub fn resize_vertically(self, new_nrows: usize, val: T) -> OMatrix + pub fn resize_vertically(self, new_nrows: usize, val: T) -> OMatrix where - DefaultAllocator: Reallocator, + DefaultAllocator: Reallocator, { let ncols = self.shape_generic().1; - self.resize_generic(Dynamic::new(new_nrows), ncols, val) + self.resize_generic(Dyn(new_nrows), ncols, val) } /// Resizes this matrix horizontally, i.e., so that it contains `new_ncolumns` columns while keeping the same number of columns. @@ -840,12 +840,12 @@ impl> Matrix { /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// columns than `self`, then the extra columns are filled with `val`. #[cfg(any(feature = "std", feature = "alloc"))] - pub fn resize_horizontally(self, new_ncols: usize, val: T) -> OMatrix + pub fn resize_horizontally(self, new_ncols: usize, val: T) -> OMatrix where - DefaultAllocator: Reallocator, + DefaultAllocator: Reallocator, { let nrows = self.shape_generic().0; - self.resize_generic(nrows, Dynamic::new(new_ncols), val) + self.resize_generic(nrows, Dyn(new_ncols), val) } /// Resizes this matrix so that it contains `R2::value()` rows and `C2::value()` columns. @@ -938,7 +938,7 @@ impl> Matrix { } if new_nrows.value() > nrows { - res.slice_range_mut(nrows.., ..cmp::min(ncols, new_ncols.value())) + res.view_range_mut(nrows.., ..cmp::min(ncols, new_ncols.value())) .fill_with(|| MaybeUninit::new(val.clone())); } @@ -962,7 +962,7 @@ impl> Matrix { /// # Examples /// /// ``` - /// # use nalgebra::{Matrix3x2, Matrix2x3, DMatrix, Const, Dynamic}; + /// # use nalgebra::{Matrix3x2, Matrix2x3, DMatrix, Const, Dyn}; /// /// let m1 = Matrix2x3::new( /// 1.1, 1.2, 1.3, @@ -998,7 +998,7 @@ impl> Matrix { /// 0.0, 0.0, /// ], /// ); - /// let reshaped = dm1.reshape_generic(Dynamic::new(6), Dynamic::new(2)); + /// let reshaped = dm1.reshape_generic(Dyn(6), Dyn(2)); /// assert_eq!(reshaped, dm2); /// ``` pub fn reshape_generic( @@ -1018,7 +1018,7 @@ impl> Matrix { /// # In-place resizing #[cfg(any(feature = "std", feature = "alloc"))] -impl OMatrix { +impl OMatrix { /// Resizes this matrix in-place. /// /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more @@ -1027,7 +1027,7 @@ impl OMatrix { /// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`. pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: T) where - DefaultAllocator: Reallocator, + DefaultAllocator: Reallocator, { // TODO: avoid the clone. *self = self.clone().resize(new_nrows, new_ncols, val); @@ -1035,9 +1035,9 @@ impl OMatrix { } #[cfg(any(feature = "std", feature = "alloc"))] -impl OMatrix +impl OMatrix where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { /// Changes the number of rows of this matrix in-place. /// @@ -1048,7 +1048,7 @@ where #[cfg(any(feature = "std", feature = "alloc"))] pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: T) where - DefaultAllocator: Reallocator, + DefaultAllocator: Reallocator, { // TODO: avoid the clone. *self = self.clone().resize_vertically(new_nrows, val); @@ -1056,9 +1056,9 @@ where } #[cfg(any(feature = "std", feature = "alloc"))] -impl OMatrix +impl OMatrix where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { /// Changes the number of column of this matrix in-place. /// @@ -1069,7 +1069,7 @@ where #[cfg(any(feature = "std", feature = "alloc"))] pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: T) where - DefaultAllocator: Reallocator, + DefaultAllocator: Reallocator, { // TODO: avoid the clone. *self = self.clone().resize_horizontally(new_ncols, val); @@ -1167,7 +1167,7 @@ unsafe fn extend_rows(data: &mut [T], nrows: usize, ncols: usize, i: usize, n /// Extend the number of columns of the `Matrix` with elements from /// a given iterator. #[cfg(any(feature = "std", feature = "alloc"))] -impl Extend for Matrix +impl Extend for Matrix where T: Scalar, R: Dim, @@ -1178,7 +1178,7 @@ where /// /// # Example /// ``` - /// # use nalgebra::{DMatrix, Dynamic, Matrix, OMatrix, Matrix3}; + /// # use nalgebra::{DMatrix, Dyn, Matrix, OMatrix, Matrix3}; /// /// let data = vec![0, 1, 2, // column 1 /// 3, 4, 5]; // column 2 @@ -1198,7 +1198,7 @@ where /// `Matrix`. /// /// ```should_panic - /// # use nalgebra::{DMatrix, Dynamic, OMatrix}; + /// # use nalgebra::{DMatrix, Dyn, OMatrix}; /// let data = vec![0, 1, 2, // column 1 /// 3, 4, 5]; // column 2 /// @@ -1215,7 +1215,7 @@ where /// Extend the number of rows of the `Vector` with elements from /// a given iterator. #[cfg(any(feature = "std", feature = "alloc"))] -impl Extend for Matrix +impl Extend for Matrix where T: Scalar, S: Extend, @@ -1236,7 +1236,7 @@ where } #[cfg(any(feature = "std", feature = "alloc"))] -impl Extend> for Matrix +impl Extend> for Matrix where T: Scalar, R: Dim, diff --git a/src/base/indexing.rs b/src/base/indexing.rs index 2c691bd1..48dd8fad 100644 --- a/src/base/indexing.rs +++ b/src/base/indexing.rs @@ -3,7 +3,7 @@ use crate::base::storage::{RawStorage, RawStorageMut}; use crate::base::{ - Const, Dim, DimDiff, DimName, DimSub, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1, + Const, Dim, DimDiff, DimName, DimSub, Dyn, Matrix, MatrixView, MatrixViewMut, Scalar, U1, }; use std::ops; @@ -49,7 +49,7 @@ fn dimrange_usize() { } impl DimRange for ops::Range { - type Length = Dynamic; + type Length = Dyn; #[inline(always)] fn lower(&self, _: D) -> usize { @@ -58,7 +58,7 @@ impl DimRange for ops::Range { #[inline(always)] fn length(&self, _: D) -> Self::Length { - Dynamic::new(self.end.saturating_sub(self.start)) + Dyn(self.end.saturating_sub(self.start)) } #[inline(always)] @@ -74,24 +74,24 @@ fn dimrange_range_usize() { assert!(DimRange::contained_by(&(0..1), Const::<1>)); assert!(DimRange::contained_by( &((usize::MAX - 1)..usize::MAX), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); assert_eq!( - DimRange::length(&((usize::MAX - 1)..usize::MAX), Dynamic::new(usize::MAX)), - Dynamic::new(1) + DimRange::length(&((usize::MAX - 1)..usize::MAX), Dyn(usize::MAX)), + Dyn(1) ); assert_eq!( - DimRange::length(&(usize::MAX..(usize::MAX - 1)), Dynamic::new(usize::MAX)), - Dynamic::new(0) + DimRange::length(&(usize::MAX..(usize::MAX - 1)), Dyn(usize::MAX)), + Dyn(0) ); assert_eq!( - DimRange::length(&(usize::MAX..usize::MAX), Dynamic::new(usize::MAX)), - Dynamic::new(0) + DimRange::length(&(usize::MAX..usize::MAX), Dyn(usize::MAX)), + Dyn(0) ); } impl DimRange for ops::RangeFrom { - type Length = Dynamic; + type Length = Dyn; #[inline(always)] fn lower(&self, _: D) -> usize { @@ -116,16 +116,13 @@ fn dimrange_rangefrom_usize() { assert!(DimRange::contained_by(&(0..), Const::<1>)); assert!(DimRange::contained_by( &((usize::MAX - 1)..), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); assert_eq!( - DimRange::length(&((usize::MAX - 1)..), Dynamic::new(usize::MAX)), - Dynamic::new(1) - ); - assert_eq!( - DimRange::length(&(usize::MAX..), Dynamic::new(usize::MAX)), - Dynamic::new(0) + DimRange::length(&((usize::MAX - 1)..), Dyn(usize::MAX)), + Dyn(1) ); + assert_eq!(DimRange::length(&(usize::MAX..), Dyn(usize::MAX)), Dyn(0)); } impl DimRange for ops::RangeFrom @@ -181,7 +178,7 @@ fn dimrange_rangefull() { } impl DimRange for ops::RangeInclusive { - type Length = Dynamic; + type Length = Dyn; #[inline(always)] fn lower(&self, _: D) -> usize { @@ -190,7 +187,7 @@ impl DimRange for ops::RangeInclusive { #[inline(always)] fn length(&self, _: D) -> Self::Length { - Dynamic::new(if self.end() < self.start() { + Dyn(if self.end() < self.start() { 0 } else { self.end().wrapping_sub(self.start().wrapping_sub(1)) @@ -209,33 +206,33 @@ fn dimrange_rangeinclusive_usize() { assert!(DimRange::contained_by(&(0..=0), Const::<1>)); assert!(!DimRange::contained_by( &(usize::MAX..=usize::MAX), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); assert!(!DimRange::contained_by( &((usize::MAX - 1)..=usize::MAX), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); assert!(DimRange::contained_by( &((usize::MAX - 1)..=(usize::MAX - 1)), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); - assert_eq!(DimRange::length(&(0..=0), Const::<1>), Dynamic::new(1)); + assert_eq!(DimRange::length(&(0..=0), Const::<1>), Dyn(1)); assert_eq!( - DimRange::length(&((usize::MAX - 1)..=usize::MAX), Dynamic::new(usize::MAX)), - Dynamic::new(2) + DimRange::length(&((usize::MAX - 1)..=usize::MAX), Dyn(usize::MAX)), + Dyn(2) ); assert_eq!( - DimRange::length(&(usize::MAX..=(usize::MAX - 1)), Dynamic::new(usize::MAX)), - Dynamic::new(0) + DimRange::length(&(usize::MAX..=(usize::MAX - 1)), Dyn(usize::MAX)), + Dyn(0) ); assert_eq!( - DimRange::length(&(usize::MAX..=usize::MAX), Dynamic::new(usize::MAX)), - Dynamic::new(1) + DimRange::length(&(usize::MAX..=usize::MAX), Dyn(usize::MAX)), + Dyn(1) ); } impl DimRange for ops::RangeTo { - type Length = Dynamic; + type Length = Dyn; #[inline(always)] fn lower(&self, _: D) -> usize { @@ -244,7 +241,7 @@ impl DimRange for ops::RangeTo { #[inline(always)] fn length(&self, _: D) -> Self::Length { - Dynamic::new(self.end) + Dyn(self.end) } #[inline(always)] @@ -260,20 +257,20 @@ fn dimrange_rangeto_usize() { assert!(DimRange::contained_by(&(..0), Const::<1>)); assert!(DimRange::contained_by( &(..(usize::MAX - 1)), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); assert_eq!( - DimRange::length(&(..(usize::MAX - 1)), Dynamic::new(usize::MAX)), - Dynamic::new(usize::MAX - 1) + DimRange::length(&(..(usize::MAX - 1)), Dyn(usize::MAX)), + Dyn(usize::MAX - 1) ); assert_eq!( - DimRange::length(&(..usize::MAX), Dynamic::new(usize::MAX)), - Dynamic::new(usize::MAX) + DimRange::length(&(..usize::MAX), Dyn(usize::MAX)), + Dyn(usize::MAX) ); } impl DimRange for ops::RangeToInclusive { - type Length = Dynamic; + type Length = Dyn; #[inline(always)] fn lower(&self, _: D) -> usize { @@ -282,7 +279,7 @@ impl DimRange for ops::RangeToInclusive { #[inline(always)] fn length(&self, _: D) -> Self::Length { - Dynamic::new(self.end + 1) + Dyn(self.end + 1) } #[inline(always)] @@ -296,17 +293,14 @@ fn dimrange_rangetoinclusive_usize() { assert!(!DimRange::contained_by(&(..=0), Const::<0>)); assert!(!DimRange::contained_by(&(..=1), Const::<0>)); assert!(DimRange::contained_by(&(..=0), Const::<1>)); - assert!(!DimRange::contained_by( - &(..=(usize::MAX)), - Dynamic::new(usize::MAX) - )); + assert!(!DimRange::contained_by(&(..=(usize::MAX)), Dyn(usize::MAX))); assert!(DimRange::contained_by( &(..=(usize::MAX - 1)), - Dynamic::new(usize::MAX) + Dyn(usize::MAX) )); assert_eq!( - DimRange::length(&(..=(usize::MAX - 1)), Dynamic::new(usize::MAX)), - Dynamic::new(usize::MAX) + DimRange::length(&(..=(usize::MAX - 1)), Dyn(usize::MAX)), + Dyn(usize::MAX) ); } @@ -378,7 +372,7 @@ pub trait MatrixIndexMut<'a, T, R: Dim, C: Dim, S: RawStorageMut>: } } -/// # Slicing based on ranges +/// # Views based on ranges /// ## Indices to Individual Elements /// ### Two-Dimensional Indices /// ``` @@ -669,7 +663,7 @@ macro_rules! impl_index_pair { $( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)* $( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),* { - type Output = MatrixSlice<'a, T, $ROut, $COut, S::RStride, S::CStride>; + type Output = MatrixView<'a, T, $ROut, $COut, S::RStride, S::CStride>; #[doc(hidden)] #[inline(always)] @@ -682,13 +676,13 @@ macro_rules! impl_index_pair { #[doc(hidden)] #[inline(always)] unsafe fn get_unchecked(self, matrix: &'a Matrix) -> Self::Output { - use crate::base::SliceStorage; + use crate::base::ViewStorage; let (rows, cols) = self; let (nrows, ncols) = matrix.shape_generic(); let data = - SliceStorage::new_unchecked(&matrix.data, + ViewStorage::new_unchecked(&matrix.data, (rows.lower(nrows), cols.lower(ncols)), (rows.length(nrows), cols.length(ncols))); @@ -705,18 +699,18 @@ macro_rules! impl_index_pair { $( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)* $( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),* { - type OutputMut = MatrixSliceMut<'a, T, $ROut, $COut, S::RStride, S::CStride>; + type OutputMut = MatrixViewMut<'a, T, $ROut, $COut, S::RStride, S::CStride>; #[doc(hidden)] #[inline(always)] unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix) -> Self::OutputMut { - use crate::base::SliceStorageMut; + use crate::base::ViewStorageMut; let (rows, cols) = self; let (nrows, ncols) = matrix.shape_generic(); let data = - SliceStorageMut::new_unchecked(&mut matrix.data, + ViewStorageMut::new_unchecked(&mut matrix.data, (rows.lower(nrows), cols.lower(ncols)), (rows.length(nrows), cols.length(ncols))); @@ -742,12 +736,12 @@ macro_rules! impl_index_pairs { impl_index_pairs! { index R with { [<> usize => U1], - [<> ops::Range => Dynamic], - [<> ops::RangeFrom => Dynamic], + [<> ops::Range => Dyn], + [<> ops::RangeFrom => Dyn], [<> ops::RangeFull => R], - [<> ops::RangeInclusive => Dynamic], - [<> ops::RangeTo => Dynamic], - [<> ops::RangeToInclusive => Dynamic], + [<> ops::RangeInclusive => Dyn], + [<> ops::RangeTo => Dyn], + [<> ops::RangeToInclusive => Dyn], [ ops::RangeFrom => DimDiff @@ -755,12 +749,12 @@ impl_index_pairs! { } index C with { [<> usize => U1], - [<> ops::Range => Dynamic], - [<> ops::RangeFrom => Dynamic], + [<> ops::Range => Dyn], + [<> ops::RangeFrom => Dyn], [<> ops::RangeFull => C], - [<> ops::RangeInclusive => Dynamic], - [<> ops::RangeTo => Dynamic], - [<> ops::RangeToInclusive => Dynamic], + [<> ops::RangeInclusive => Dyn], + [<> ops::RangeTo => Dyn], + [<> ops::RangeToInclusive => Dyn], [ ops::RangeFrom => DimDiff diff --git a/src/base/iter.rs b/src/base/iter.rs index b68e1051..0e4aa8d4 100644 --- a/src/base/iter.rs +++ b/src/base/iter.rs @@ -1,12 +1,18 @@ //! Matrix iterators. +// only enables the `doc_cfg` feature when +// the `docsrs` configuration attribute is defined +#![cfg_attr(docsrs, feature(doc_cfg))] + +use core::fmt::Debug; +use core::ops::Range; use std::iter::FusedIterator; use std::marker::PhantomData; use std::mem; use crate::base::dimension::{Dim, U1}; use crate::base::storage::{RawStorage, RawStorageMut}; -use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar}; +use crate::base::{Matrix, MatrixView, MatrixViewMut, Scalar}; macro_rules! iterator { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => { @@ -193,7 +199,7 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage> RowIter<'a, T, R, C, S> } impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage> Iterator for RowIter<'a, T, R, C, S> { - type Item = MatrixSlice<'a, T, U1, C, S::RStride, S::CStride>; + type Item = MatrixView<'a, T, U1, C, S::RStride, S::CStride>; #[inline] fn next(&mut self) -> Option { @@ -254,7 +260,7 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> RowIterMut<'a, T, R, impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> Iterator for RowIterMut<'a, T, R, C, S> { - type Item = MatrixSliceMut<'a, T, U1, C, S::RStride, S::CStride>; + type Item = MatrixViewMut<'a, T, U1, C, S::RStride, S::CStride>; #[inline] fn next(&mut self) -> Option { @@ -288,7 +294,6 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorageMut> ExactSizeIte } /* - * * Column iterators. * */ @@ -296,23 +301,45 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorageMut> ExactSizeIte /// An iterator through the columns of a matrix. pub struct ColumnIter<'a, T, R: Dim, C: Dim, S: RawStorage> { mat: &'a Matrix, - curr: usize, + range: Range, } impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage> ColumnIter<'a, T, R, C, S> { + /// a new column iterator covering all columns of the matrix pub(crate) fn new(mat: &'a Matrix) -> Self { - ColumnIter { mat, curr: 0 } + ColumnIter { + mat, + range: 0..mat.ncols(), + } + } + + pub(crate) fn split_at(self, index: usize) -> (Self, Self) { + // SAFETY: this makes sur the generated ranges are valid. + let split_pos = (self.range.start + index).min(self.range.end); + + let left_iter = ColumnIter { + mat: self.mat, + range: self.range.start..split_pos, + }; + + let right_iter = ColumnIter { + mat: self.mat, + range: split_pos..self.range.end, + }; + + (left_iter, right_iter) } } impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage> Iterator for ColumnIter<'a, T, R, C, S> { - type Item = MatrixSlice<'a, T, R, U1, S::RStride, S::CStride>; + type Item = MatrixView<'a, T, R, U1, S::RStride, S::CStride>; #[inline] fn next(&mut self) -> Option { - if self.curr < self.mat.ncols() { - let res = self.mat.column(self.curr); - self.curr += 1; + debug_assert!(self.range.start <= self.range.end); + if self.range.start < self.range.end { + let res = self.mat.column(self.range.start); + self.range.start += 1; Some(res) } else { None @@ -321,15 +348,29 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage> Iterator for ColumnIter #[inline] fn size_hint(&self) -> (usize, Option) { - ( - self.mat.ncols() - self.curr, - Some(self.mat.ncols() - self.curr), - ) + let hint = self.range.len(); + (hint, Some(hint)) } #[inline] fn count(self) -> usize { - self.mat.ncols() - self.curr + self.range.len() + } +} + +impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorage> DoubleEndedIterator + for ColumnIter<'a, T, R, C, S> +{ + fn next_back(&mut self) -> Option { + debug_assert!(self.range.start <= self.range.end); + if !self.range.is_empty() { + self.range.end -= 1; + debug_assert!(self.range.end < self.mat.ncols()); + debug_assert!(self.range.end >= self.range.start); + Some(self.mat.column(self.range.end)) + } else { + None + } } } @@ -338,7 +379,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorage> ExactSizeIterat { #[inline] fn len(&self) -> usize { - self.mat.ncols() - self.curr + self.range.end - self.range.start } } @@ -346,19 +387,39 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorage> ExactSizeIterat #[derive(Debug)] pub struct ColumnIterMut<'a, T, R: Dim, C: Dim, S: RawStorageMut> { mat: *mut Matrix, - curr: usize, + range: Range, phantom: PhantomData<&'a mut Matrix>, } impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> ColumnIterMut<'a, T, R, C, S> { pub(crate) fn new(mat: &'a mut Matrix) -> Self { + let range = 0..mat.ncols(); ColumnIterMut { mat, - curr: 0, - phantom: PhantomData, + range, + phantom: Default::default(), } } + pub(crate) fn split_at(self, index: usize) -> (Self, Self) { + // SAFETY: this makes sur the generated ranges are valid. + let split_pos = (self.range.start + index).min(self.range.end); + + let left_iter = ColumnIterMut { + mat: self.mat, + range: self.range.start..split_pos, + phantom: Default::default(), + }; + + let right_iter = ColumnIterMut { + mat: self.mat, + range: split_pos..self.range.end, + phantom: Default::default(), + }; + + (left_iter, right_iter) + } + fn ncols(&self) -> usize { unsafe { (*self.mat).ncols() } } @@ -367,13 +428,14 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> ColumnIterMut<'a, T, impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> Iterator for ColumnIterMut<'a, T, R, C, S> { - type Item = MatrixSliceMut<'a, T, R, U1, S::RStride, S::CStride>; + type Item = MatrixViewMut<'a, T, R, U1, S::RStride, S::CStride>; #[inline] - fn next(&mut self) -> Option { - if self.curr < self.ncols() { - let res = unsafe { (*self.mat).column_mut(self.curr) }; - self.curr += 1; + fn next(&'_ mut self) -> Option { + debug_assert!(self.range.start <= self.range.end); + if self.range.start < self.range.end { + let res = unsafe { (*self.mat).column_mut(self.range.start) }; + self.range.start += 1; Some(res) } else { None @@ -382,12 +444,13 @@ impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> Iterator #[inline] fn size_hint(&self) -> (usize, Option) { - (self.ncols() - self.curr, Some(self.ncols() - self.curr)) + let hint = self.range.len(); + (hint, Some(hint)) } #[inline] fn count(self) -> usize { - self.ncols() - self.curr + self.range.len() } } @@ -396,6 +459,22 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorageMut> ExactSizeIte { #[inline] fn len(&self) -> usize { - self.ncols() - self.curr + self.range.len() + } +} + +impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorageMut> DoubleEndedIterator + for ColumnIterMut<'a, T, R, C, S> +{ + fn next_back(&mut self) -> Option { + debug_assert!(self.range.start <= self.range.end); + if !self.range.is_empty() { + self.range.end -= 1; + debug_assert!(self.range.end < self.ncols()); + debug_assert!(self.range.end >= self.range.start); + Some(unsafe { (*self.mat).column_mut(self.range.end) }) + } else { + None + } } } diff --git a/src/base/matrix.rs b/src/base/matrix.rs index d9294c9e..d4875944 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -11,6 +11,11 @@ use std::mem; #[cfg(feature = "serde-serialize-no-std")] use serde::{Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "rkyv-serialize-no-std")] +use super::rkyv_wrappers::CustomPhantom; +#[cfg(feature = "rkyv-serialize-no-std")] +use rkyv::{with::With, Archive, Archived}; + use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field, SupersetOf}; use simba::simd::SimdPartialOrd; @@ -27,7 +32,7 @@ use crate::{ArrayStorage, SMatrix, SimdComplexField, Storage, UninitMatrix}; use crate::storage::IsContiguous; use crate::uninit::{Init, InitStatus, Uninit}; #[cfg(any(feature = "std", feature = "alloc"))] -use crate::{DMatrix, DVector, Dynamic, RowDVector, VecStorage}; +use crate::{DMatrix, DVector, Dyn, RowDVector, VecStorage}; use std::mem::MaybeUninit; /// A square matrix. @@ -96,16 +101,17 @@ pub type MatrixCross = /// /// #### Iteration, map, and fold /// - [Iteration on components, rows, and columns `iter`, `column_iter`…](#iteration-on-components-rows-and-columns) +/// - [Parallel iterators using rayon `par_column_iter`, `par_column_iter_mut`…](#parallel-iterators-using-rayon) /// - [Elementwise mapping and folding `map`, `fold`, `zip_map`…](#elementwise-mapping-and-folding) /// - [Folding or columns and rows `compress_rows`, `compress_columns`…](#folding-on-columns-and-rows) /// -/// #### Vector and matrix slicing -/// - [Creating matrix slices from `&[T]` `from_slice`, `from_slice_with_strides`…](#creating-matrix-slices-from-t) -/// - [Creating mutable matrix slices from `&mut [T]` `from_slice_mut`, `from_slice_with_strides_mut`…](#creating-mutable-matrix-slices-from-mut-t) -/// - [Slicing based on index and length `row`, `columns`, `slice`…](#slicing-based-on-index-and-length) -/// - [Mutable slicing based on index and length `row_mut`, `columns_mut`, `slice_mut`…](#mutable-slicing-based-on-index-and-length) -/// - [Slicing based on ranges `rows_range`, `columns_range`…](#slicing-based-on-ranges) -/// - [Mutable slicing based on ranges `rows_range_mut`, `columns_range_mut`…](#mutable-slicing-based-on-ranges) +/// #### Vector and matrix views +/// - [Creating matrix views from `&[T]` `from_slice`, `from_slice_with_strides`…](#creating-matrix-views-from-t) +/// - [Creating mutable matrix views from `&mut [T]` `from_slice_mut`, `from_slice_with_strides_mut`…](#creating-mutable-matrix-views-from-mut-t) +/// - [Views based on index and length `row`, `columns`, `view`…](#views-based-on-index-and-length) +/// - [Mutable views based on index and length `row_mut`, `columns_mut`, `view_mut`…](#mutable-views-based-on-index-and-length) +/// - [Views based on ranges `rows_range`, `columns_range`…](#views-based-on-ranges) +/// - [Mutable views based on ranges `rows_range_mut`, `columns_range_mut`…](#mutable-views-based-on-ranges) /// /// #### In-place modification of a single matrix or vector /// - [In-place filling `fill`, `fill_diagonal`, `fill_with_identity`…](#in-place-filling) @@ -140,21 +146,29 @@ pub type MatrixCross = /// - type-level unsigned integer constants (e.g. `U1024`, `U10000`) from the `typenum::` crate. /// Using those, you will not get error messages as nice as for numbers smaller than 128 defined on /// the `nalgebra::` module. -/// - the special value `Dynamic` from the `nalgebra::` root module. This indicates that the +/// - the special value `Dyn` from the `nalgebra::` root module. This indicates that the /// specified dimension is not known at compile-time. Note that this will generally imply that the /// matrix data storage `S` performs a dynamic allocation and contains extra metadata for the /// matrix shape. /// -/// Note that mixing `Dynamic` with type-level unsigned integers is allowed. Actually, a -/// dynamically-sized column vector should be represented as a `Matrix` (given +/// Note that mixing `Dyn` with type-level unsigned integers is allowed. Actually, a +/// dynamically-sized column vector should be represented as a `Matrix` (given /// some concrete types for `T` and a compatible data storage type `S`). #[repr(C)] #[derive(Clone, Copy)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Matrix", + bound(archive = " + T: Archive, + S: Archive, + With, CustomPhantom<(Archived, R, C)>>: Archive, R, C)>> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Matrix { /// The data storage that contains all the matrix components. Disappointed? @@ -192,6 +206,7 @@ pub struct Matrix { // of the `RawStorage` trait. However, because we don't have // specialization, this is not possible because these `T, R, C` // allows us to desambiguate a lot of configurations. + #[cfg_attr(feature = "rkyv-serialize-no-std", with(CustomPhantom<(T::Archived, R, C)>))] _phantoms: PhantomData<(T, R, C)>, } @@ -326,7 +341,7 @@ impl DMatrix { /// /// This method exists primarily as a workaround for the fact that `from_data` can not /// work in `const fn` contexts. - pub const fn from_vec_storage(storage: VecStorage) -> Self { + pub const fn from_vec_storage(storage: VecStorage) -> Self { // This is sound because the dimensions of the matrix and the storage are guaranteed // to be the same unsafe { Self::from_data_statically_unchecked(storage) } @@ -341,7 +356,7 @@ impl DVector { /// /// This method exists primarily as a workaround for the fact that `from_data` can not /// work in `const fn` contexts. - pub const fn from_vec_storage(storage: VecStorage) -> Self { + pub const fn from_vec_storage(storage: VecStorage) -> Self { // This is sound because the dimensions of the matrix and the storage are guaranteed // to be the same unsafe { Self::from_data_statically_unchecked(storage) } @@ -356,7 +371,7 @@ impl RowDVector { /// /// This method exists primarily as a workaround for the fact that `from_data` can not /// work in `const fn` contexts. - pub const fn from_vec_storage(storage: VecStorage) -> Self { + pub const fn from_vec_storage(storage: VecStorage) -> Self { // This is sound because the dimensions of the matrix and the storage are guaranteed // to be the same unsafe { Self::from_data_statically_unchecked(storage) } @@ -402,7 +417,7 @@ impl> Matrix { (nrows.value(), ncols.value()) } - /// The shape of this matrix wrapped into their representative types (`Const` or `Dynamic`). + /// The shape of this matrix wrapped into their representative types (`Const` or `Dyn`). #[inline] #[must_use] pub fn shape_generic(&self) -> (R, C) { @@ -443,7 +458,7 @@ impl> Matrix { /// ``` /// # use nalgebra::DMatrix; /// let mat = DMatrix::::zeros(10, 10); - /// let slice = mat.slice_with_steps((0, 0), (5, 3), (1, 2)); + /// let view = mat.view_with_steps((0, 0), (5, 3), (1, 2)); /// // The column strides is the number of steps (here 2) multiplied by the corresponding dimension. /// assert_eq!(mat.strides(), (1, 10)); /// ``` @@ -736,6 +751,24 @@ impl> Matrix { crate::convert(self) } + /// Attempts to cast the components of `self` to another type. + /// + /// # Example + /// ``` + /// # use nalgebra::Vector3; + /// let q = Vector3::new(1.0f64, 2.0, 3.0); + /// let q2 = q.try_cast::(); + /// assert_eq!(q2, Some(Vector3::new(1, 2, 3))); + /// ``` + pub fn try_cast(self) -> Option> + where + T: Scalar, + Self: SupersetOf>, + DefaultAllocator: Allocator, + { + crate::try_convert(self) + } + /// Similar to `self.iter().fold(init, f)` except that `init` is replaced by a closure. /// /// The initialization closure is given the first component of this matrix: @@ -1612,7 +1645,7 @@ impl + IsNotStaticOne, S: RawStorage::from_usize(self.nrows() + 1); let mut res = OMatrix::identity_generic(dim, dim); - res.generic_slice_mut::((0, 0), self.shape_generic()) + res.generic_view_mut::((0, 0), self.shape_generic()) .copy_from(self); res } @@ -1640,7 +1673,7 @@ impl, S: RawStorage> Vector { { if v[v.len() - 1].is_zero() { let nrows = D::from_usize(v.len() - 1); - Some(v.generic_slice((0, 0), (nrows, Const::<1>)).into_owned()) + Some(v.generic_view((0, 0), (nrows, Const::<1>)).into_owned()) } else { None } @@ -1660,7 +1693,7 @@ impl, S: RawStorage> Vector { let mut res = Matrix::uninit(hnrows, Const::<1>); // This is basically a copy_from except that we warp the copied // values into MaybeUninit. - res.generic_slice_mut((0, 0), self.shape_generic()) + res.generic_view_mut((0, 0), self.shape_generic()) .zip_apply(self, |out, e| *out = MaybeUninit::new(e)); res[(len, 0)] = MaybeUninit::new(element); diff --git a/src/base/matrix_slice.rs b/src/base/matrix_slice.rs deleted file mode 100644 index 5fbd4b01..00000000 --- a/src/base/matrix_slice.rs +++ /dev/null @@ -1,955 +0,0 @@ -use std::marker::PhantomData; -use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo}; -use std::slice; - -use crate::base::allocator::Allocator; -use crate::base::default_allocator::DefaultAllocator; -use crate::base::dimension::{Const, Dim, DimName, Dynamic, IsNotStaticOne, U1}; -use crate::base::iter::MatrixIter; -use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, Storage}; -use crate::base::{Matrix, Scalar}; - -macro_rules! slice_storage_impl( - ($doc: expr; $Storage: ident as $SRef: ty; $T: ident.$get_addr: ident ($Ptr: ty as $Ref: ty)) => { - #[doc = $doc] - #[derive(Debug)] - pub struct $T<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> { - ptr: $Ptr, - shape: (R, C), - strides: (RStride, CStride), - _phantoms: PhantomData<$Ref>, - } - - unsafe impl<'a, T: Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send - for $T<'a, T, R, C, RStride, CStride> - {} - - unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync - for $T<'a, T, R, C, RStride, CStride> - {} - - impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> { - /// Create a new matrix slice without bound checking and from a raw pointer. - #[inline] - pub unsafe fn from_raw_parts(ptr: $Ptr, - shape: (R, C), - strides: (RStride, CStride)) - -> Self - where RStride: Dim, - CStride: Dim { - - $T { - ptr, - shape, - strides, - _phantoms: PhantomData - } - } - } - - // Dynamic is arbitrary. It's just to be able to call the constructors with `Slice::` - impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dynamic, Dynamic> { - /// Create a new matrix slice without bound checking. - #[inline] - pub unsafe fn new_unchecked(storage: $SRef, start: (usize, usize), shape: (R, C)) - -> $T<'a, T, R, C, S::RStride, S::CStride> - where RStor: Dim, - CStor: Dim, - S: $Storage { - - let strides = storage.strides(); - $T::new_with_strides_unchecked(storage, start, shape, strides) - } - - /// Create a new matrix slice without bound checking. - #[inline] - pub unsafe fn new_with_strides_unchecked(storage: $SRef, - start: (usize, usize), - shape: (R, C), - strides: (RStride, CStride)) - -> $T<'a, T, R, C, RStride, CStride> - where RStor: Dim, - CStor: Dim, - S: $Storage, - RStride: Dim, - CStride: Dim { - $T::from_raw_parts(storage.$get_addr(start.0, start.1), shape, strides) - } - } - - impl <'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> - $T<'a, T, R, C, RStride, CStride> - where - Self: RawStorage + IsContiguous - { - /// Extracts the original slice from this storage - pub fn into_slice(self) -> &'a [T] { - let (nrows, ncols) = self.shape(); - if nrows.value() != 0 && ncols.value() != 0 { - let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); - unsafe { slice::from_raw_parts(self.ptr, sz + 1) } - } else { - unsafe { slice::from_raw_parts(self.ptr, 0) } - } - } - } - } -); - -slice_storage_impl!("A matrix data storage for a matrix slice. Only contains an internal reference \ - to another matrix data storage."; - RawStorage as &'a S; SliceStorage.get_address_unchecked(*const T as &'a T)); - -slice_storage_impl!("A mutable matrix data storage for mutable matrix slice. Only contains an \ - internal mutable reference to another matrix data storage."; - RawStorageMut as &'a mut S; SliceStorageMut.get_address_unchecked_mut(*mut T as &'a mut T) -); - -impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy - for SliceStorage<'a, T, R, C, RStride, CStride> -{ -} - -impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone - for SliceStorage<'a, T, R, C, RStride, CStride> -{ - #[inline] - fn clone(&self) -> Self { - Self { - ptr: self.ptr, - shape: self.shape, - strides: self.strides, - _phantoms: PhantomData, - } - } -} - -impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> - SliceStorageMut<'a, T, R, C, RStride, CStride> -where - Self: RawStorageMut + IsContiguous, -{ - /// Extracts the original slice from this storage - pub fn into_slice_mut(self) -> &'a mut [T] { - let (nrows, ncols) = self.shape(); - if nrows.value() != 0 && ncols.value() != 0 { - let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); - unsafe { slice::from_raw_parts_mut(self.ptr, sz + 1) } - } else { - unsafe { slice::from_raw_parts_mut(self.ptr, 0) } - } - } -} - -macro_rules! storage_impl( - ($($T: ident),* $(,)*) => {$( - unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorage - for $T<'a, T, R, C, RStride, CStride> { - - type RStride = RStride; - type CStride = CStride; - - #[inline] - fn ptr(&self) -> *const T { - self.ptr - } - - #[inline] - fn shape(&self) -> (R, C) { - self.shape - } - - #[inline] - fn strides(&self) -> (Self::RStride, Self::CStride) { - self.strides - } - - #[inline] - fn is_contiguous(&self) -> bool { - // Common cases that can be deduced at compile-time even if one of the dimensions - // is Dynamic. - if (RStride::is::() && C::is::()) || // Column vector. - (CStride::is::() && R::is::()) { // Row vector. - true - } - else { - let (nrows, _) = self.shape(); - let (srows, scols) = self.strides(); - - srows.value() == 1 && scols.value() == nrows.value() - } - } - - #[inline] - unsafe fn as_slice_unchecked(&self) -> &[T] { - let (nrows, ncols) = self.shape(); - if nrows.value() != 0 && ncols.value() != 0 { - let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); - slice::from_raw_parts(self.ptr, sz + 1) - } - else { - slice::from_raw_parts(self.ptr, 0) - } - } - } - - unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage - for $T<'a, T, R, C, RStride, CStride> { - #[inline] - fn into_owned(self) -> Owned - where DefaultAllocator: Allocator { - self.clone_owned() - } - - #[inline] - fn clone_owned(&self) -> Owned - where DefaultAllocator: Allocator { - let (nrows, ncols) = self.shape(); - let it = MatrixIter::new(self).cloned(); - DefaultAllocator::allocate_from_iterator(nrows, ncols, it) - } - } - )*} -); - -storage_impl!(SliceStorage, SliceStorageMut); - -unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorageMut - for SliceStorageMut<'a, T, R, C, RStride, CStride> -{ - #[inline] - fn ptr_mut(&mut self) -> *mut T { - self.ptr - } - - #[inline] - unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { - let (nrows, ncols) = self.shape(); - if nrows.value() != 0 && ncols.value() != 0 { - let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); - slice::from_raw_parts_mut(self.ptr, sz + 1) - } else { - slice::from_raw_parts_mut(self.ptr, 0) - } - } -} - -unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous for SliceStorage<'a, T, R, U1, U1, CStride> {} -unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous - for SliceStorageMut<'a, T, R, U1, U1, CStride> -{ -} - -unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous - for SliceStorage<'a, T, R, C, U1, R> -{ -} -unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous - for SliceStorageMut<'a, T, R, C, U1, R> -{ -} - -impl> Matrix { - #[inline] - fn assert_slice_index( - &self, - start: (usize, usize), - shape: (usize, usize), - steps: (usize, usize), - ) { - let my_shape = self.shape(); - // NOTE: we don't do any subtraction to avoid underflow for zero-sized matrices. - // - // Terms that would have been negative are moved to the other side of the inequality - // instead. - assert!( - start.0 + (steps.0 + 1) * shape.0 <= my_shape.0 + steps.0, - "Matrix slicing out of bounds." - ); - assert!( - start.1 + (steps.1 + 1) * shape.1 <= my_shape.1 + steps.1, - "Matrix slicing out of bounds." - ); - } -} - -macro_rules! matrix_slice_impl( - ($me: ident: $Me: ty, $MatrixSlice: ident, $SliceStorage: ident, $Storage: ident.$get_addr: ident (), $data: expr; - $row: ident, - $row_part: ident, - $rows: ident, - $rows_with_step: ident, - $fixed_rows: ident, - $fixed_rows_with_step: ident, - $rows_generic: ident, - $rows_generic_with_step: ident, - $column: ident, - $column_part: ident, - $columns: ident, - $columns_with_step: ident, - $fixed_columns: ident, - $fixed_columns_with_step: ident, - $columns_generic: ident, - $columns_generic_with_step: ident, - $slice: ident, - $slice_with_steps: ident, - $fixed_slice: ident, - $fixed_slice_with_steps: ident, - $generic_slice: ident, - $generic_slice_with_steps: ident, - $rows_range_pair: ident, - $columns_range_pair: ident) => { - /* - * - * Row slicing. - * - */ - /// Returns a slice containing the i-th row of this matrix. - #[inline] - pub fn $row($me: $Me, i: usize) -> $MatrixSlice<'_, T, U1, C, S::RStride, S::CStride> { - $me.$fixed_rows::<1>(i) - } - - /// Returns a slice containing the `n` first elements of the i-th row of this matrix. - #[inline] - pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<'_, T, U1, Dynamic, S::RStride, S::CStride> { - $me.$generic_slice((i, 0), (Const::<1>, Dynamic::new(n))) - } - - /// Extracts from this matrix a set of consecutive rows. - #[inline] - pub fn $rows($me: $Me, first_row: usize, nrows: usize) - -> $MatrixSlice<'_, T, Dynamic, C, S::RStride, S::CStride> { - - $me.$rows_generic(first_row, Dynamic::new(nrows)) - } - - /// Extracts from this matrix a set of consecutive rows regularly skipping `step` rows. - #[inline] - pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize) - -> $MatrixSlice<'_, T, Dynamic, C, Dynamic, S::CStride> { - - $me.$rows_generic_with_step(first_row, Dynamic::new(nrows), step) - } - - /// Extracts a compile-time number of consecutive rows from this matrix. - #[inline] - pub fn $fixed_rows($me: $Me, first_row: usize) - -> $MatrixSlice<'_, T, Const, C, S::RStride, S::CStride> { - - $me.$rows_generic(first_row, Const::) - } - - /// Extracts from this matrix a compile-time number of rows regularly skipping `step` - /// rows. - #[inline] - pub fn $fixed_rows_with_step($me: $Me, first_row: usize, step: usize) - -> $MatrixSlice<'_, T, Const, C, Dynamic, S::CStride> { - - $me.$rows_generic_with_step(first_row, Const::, step) - } - - /// Extracts from this matrix `nrows` rows regularly skipping `step` rows. Both - /// argument may or may not be values known at compile-time. - #[inline] - pub fn $rows_generic($me: $Me, row_start: usize, nrows: RSlice) - -> $MatrixSlice<'_, T, RSlice, C, S::RStride, S::CStride> { - - let my_shape = $me.shape_generic(); - $me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0)); - - let shape = (nrows, my_shape.1); - - unsafe { - let data = $SliceStorage::new_unchecked($data, (row_start, 0), shape); - Matrix::from_data_statically_unchecked(data) - } - } - - /// Extracts from this matrix `nrows` rows regularly skipping `step` rows. Both - /// argument may or may not be values known at compile-time. - #[inline] - pub fn $rows_generic_with_step($me: $Me, row_start: usize, nrows: RSlice, step: usize) - -> $MatrixSlice<'_, T, RSlice, C, Dynamic, S::CStride> - where RSlice: Dim { - - let my_shape = $me.shape_generic(); - let my_strides = $me.data.strides(); - $me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (step, 0)); - - let strides = (Dynamic::new((step + 1) * my_strides.0.value()), my_strides.1); - let shape = (nrows, my_shape.1); - - unsafe { - let data = $SliceStorage::new_with_strides_unchecked($data, (row_start, 0), shape, strides); - Matrix::from_data_statically_unchecked(data) - } - } - - /* - * - * Column slicing. - * - */ - /// Returns a slice containing the i-th column of this matrix. - #[inline] - pub fn $column($me: $Me, i: usize) -> $MatrixSlice<'_, T, R, U1, S::RStride, S::CStride> { - $me.$fixed_columns::<1>(i) - } - - /// Returns a slice containing the `n` first elements of the i-th column of this matrix. - #[inline] - pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<'_, T, Dynamic, U1, S::RStride, S::CStride> { - $me.$generic_slice((0, i), (Dynamic::new(n), Const::<1>)) - } - - /// Extracts from this matrix a set of consecutive columns. - #[inline] - pub fn $columns($me: $Me, first_col: usize, ncols: usize) - -> $MatrixSlice<'_, T, R, Dynamic, S::RStride, S::CStride> { - - $me.$columns_generic(first_col, Dynamic::new(ncols)) - } - - /// Extracts from this matrix a set of consecutive columns regularly skipping `step` - /// columns. - #[inline] - pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize) - -> $MatrixSlice<'_, T, R, Dynamic, S::RStride, Dynamic> { - - $me.$columns_generic_with_step(first_col, Dynamic::new(ncols), step) - } - - /// Extracts a compile-time number of consecutive columns from this matrix. - #[inline] - pub fn $fixed_columns($me: $Me, first_col: usize) - -> $MatrixSlice<'_, T, R, Const, S::RStride, S::CStride> { - - $me.$columns_generic(first_col, Const::) - } - - /// Extracts from this matrix a compile-time number of columns regularly skipping - /// `step` columns. - #[inline] - pub fn $fixed_columns_with_step($me: $Me, first_col: usize, step: usize) - -> $MatrixSlice<'_, T, R, Const, S::RStride, Dynamic> { - - $me.$columns_generic_with_step(first_col, Const::, step) - } - - /// Extracts from this matrix `ncols` columns. The number of columns may or may not be - /// known at compile-time. - #[inline] - pub fn $columns_generic($me: $Me, first_col: usize, ncols: CSlice) - -> $MatrixSlice<'_, T, R, CSlice, S::RStride, S::CStride> { - - let my_shape = $me.shape_generic(); - $me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0)); - let shape = (my_shape.0, ncols); - - unsafe { - let data = $SliceStorage::new_unchecked($data, (0, first_col), shape); - Matrix::from_data_statically_unchecked(data) - } - } - - - /// Extracts from this matrix `ncols` columns skipping `step` columns. Both argument may - /// or may not be values known at compile-time. - #[inline] - pub fn $columns_generic_with_step($me: $Me, first_col: usize, ncols: CSlice, step: usize) - -> $MatrixSlice<'_, T, R, CSlice, S::RStride, Dynamic> { - - let my_shape = $me.shape_generic(); - let my_strides = $me.data.strides(); - - $me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, step)); - - let strides = (my_strides.0, Dynamic::new((step + 1) * my_strides.1.value())); - let shape = (my_shape.0, ncols); - - unsafe { - let data = $SliceStorage::new_with_strides_unchecked($data, (0, first_col), shape, strides); - Matrix::from_data_statically_unchecked(data) - } - } - - /* - * - * General slicing. - * - */ - /// Slices this matrix starting at its component `(irow, icol)` and with `(nrows, ncols)` - /// consecutive elements. - #[inline] - pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize)) - -> $MatrixSlice<'_, T, Dynamic, Dynamic, S::RStride, S::CStride> { - - $me.assert_slice_index(start, shape, (0, 0)); - let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1)); - - unsafe { - let data = $SliceStorage::new_unchecked($data, start, shape); - Matrix::from_data_statically_unchecked(data) - } - } - - - /// Slices this matrix starting at its component `(start.0, start.1)` and with - /// `(shape.0, shape.1)` components. Each row (resp. column) of the sliced matrix is - /// separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of the - /// original matrix. - #[inline] - pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize)) - -> $MatrixSlice<'_, T, Dynamic, Dynamic, Dynamic, Dynamic> { - let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1)); - - $me.$generic_slice_with_steps(start, shape, steps) - } - - /// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(), - /// CSlice::dim())` consecutive components. - #[inline] - pub fn $fixed_slice($me: $Me, irow: usize, icol: usize) - -> $MatrixSlice<'_, T, Const, Const, S::RStride, S::CStride> { - - $me.assert_slice_index((irow, icol), (RSLICE, CSLICE), (0, 0)); - let shape = (Const::, Const::); - - unsafe { - let data = $SliceStorage::new_unchecked($data, (irow, icol), shape); - Matrix::from_data_statically_unchecked(data) - } - } - - /// Slices this matrix starting at its component `(start.0, start.1)` and with - /// `(RSLICE, CSLICE)` components. Each row (resp. column) of the sliced - /// matrix is separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of - /// the original matrix. - #[inline] - pub fn $fixed_slice_with_steps($me: $Me, start: (usize, usize), steps: (usize, usize)) - -> $MatrixSlice<'_, T, Const, Const, Dynamic, Dynamic> { - let shape = (Const::, Const::); - $me.$generic_slice_with_steps(start, shape, steps) - } - - /// Creates a slice that may or may not have a fixed size and stride. - #[inline] - pub fn $generic_slice($me: $Me, start: (usize, usize), shape: (RSlice, CSlice)) - -> $MatrixSlice<'_, T, RSlice, CSlice, S::RStride, S::CStride> - where RSlice: Dim, - CSlice: Dim { - - $me.assert_slice_index(start, (shape.0.value(), shape.1.value()), (0, 0)); - - unsafe { - let data = $SliceStorage::new_unchecked($data, start, shape); - Matrix::from_data_statically_unchecked(data) - } - } - - /// Creates a slice that may or may not have a fixed size and stride. - #[inline] - pub fn $generic_slice_with_steps($me: $Me, - start: (usize, usize), - shape: (RSlice, CSlice), - steps: (usize, usize)) - -> $MatrixSlice<'_, T, RSlice, CSlice, Dynamic, Dynamic> - where RSlice: Dim, - CSlice: Dim { - - $me.assert_slice_index(start, (shape.0.value(), shape.1.value()), steps); - - let my_strides = $me.data.strides(); - let strides = (Dynamic::new((steps.0 + 1) * my_strides.0.value()), - Dynamic::new((steps.1 + 1) * my_strides.1.value())); - - unsafe { - let data = $SliceStorage::new_with_strides_unchecked($data, start, shape, strides); - Matrix::from_data_statically_unchecked(data) - } - } - - /* - * - * Splitting. - * - */ - /// Splits this `NxM` matrix into two parts delimited by two ranges. - /// - /// Panics if the ranges overlap or if the first range is empty. - #[inline] - pub fn $rows_range_pair, Range2: SliceRange>($me: $Me, r1: Range1, r2: Range2) - -> ($MatrixSlice<'_, T, Range1::Size, C, S::RStride, S::CStride>, - $MatrixSlice<'_, T, Range2::Size, C, S::RStride, S::CStride>) { - - let (nrows, ncols) = $me.shape_generic(); - let strides = $me.data.strides(); - - let start1 = r1.begin(nrows); - let start2 = r2.begin(nrows); - - let end1 = r1.end(nrows); - let end2 = r2.end(nrows); - - let nrows1 = r1.size(nrows); - let nrows2 = r2.size(nrows); - - assert!(start2 >= end1 || start1 >= end2, "Rows range pair: the slice ranges must not overlap."); - assert!(end2 <= nrows.value(), "Rows range pair: index out of range."); - - unsafe { - let ptr1 = $data.$get_addr(start1, 0); - let ptr2 = $data.$get_addr(start2, 0); - - let data1 = $SliceStorage::from_raw_parts(ptr1, (nrows1, ncols), strides); - let data2 = $SliceStorage::from_raw_parts(ptr2, (nrows2, ncols), strides); - let slice1 = Matrix::from_data_statically_unchecked(data1); - let slice2 = Matrix::from_data_statically_unchecked(data2); - - (slice1, slice2) - } - } - - /// Splits this `NxM` matrix into two parts delimited by two ranges. - /// - /// Panics if the ranges overlap or if the first range is empty. - #[inline] - pub fn $columns_range_pair, Range2: SliceRange>($me: $Me, r1: Range1, r2: Range2) - -> ($MatrixSlice<'_, T, R, Range1::Size, S::RStride, S::CStride>, - $MatrixSlice<'_, T, R, Range2::Size, S::RStride, S::CStride>) { - - let (nrows, ncols) = $me.shape_generic(); - let strides = $me.data.strides(); - - let start1 = r1.begin(ncols); - let start2 = r2.begin(ncols); - - let end1 = r1.end(ncols); - let end2 = r2.end(ncols); - - let ncols1 = r1.size(ncols); - let ncols2 = r2.size(ncols); - - assert!(start2 >= end1 || start1 >= end2, "Columns range pair: the slice ranges must not overlap."); - assert!(end2 <= ncols.value(), "Columns range pair: index out of range."); - - unsafe { - let ptr1 = $data.$get_addr(0, start1); - let ptr2 = $data.$get_addr(0, start2); - - let data1 = $SliceStorage::from_raw_parts(ptr1, (nrows, ncols1), strides); - let data2 = $SliceStorage::from_raw_parts(ptr2, (nrows, ncols2), strides); - let slice1 = Matrix::from_data_statically_unchecked(data1); - let slice2 = Matrix::from_data_statically_unchecked(data2); - - (slice1, slice2) - } - } - } -); - -/// A matrix slice. -pub type MatrixSlice<'a, T, R, C, RStride = U1, CStride = R> = - Matrix>; -/// A mutable matrix slice. -pub type MatrixSliceMut<'a, T, R, C, RStride = U1, CStride = R> = - Matrix>; - -/// # Slicing based on index and length -impl> Matrix { - matrix_slice_impl!( - self: &Self, MatrixSlice, SliceStorage, RawStorage.get_address_unchecked(), &self.data; - row, - row_part, - rows, - rows_with_step, - fixed_rows, - fixed_rows_with_step, - rows_generic, - rows_generic_with_step, - column, - column_part, - columns, - columns_with_step, - fixed_columns, - fixed_columns_with_step, - columns_generic, - columns_generic_with_step, - slice, - slice_with_steps, - fixed_slice, - fixed_slice_with_steps, - generic_slice, - generic_slice_with_steps, - rows_range_pair, - columns_range_pair); -} - -/// # Mutable slicing based on index and length -impl> Matrix { - matrix_slice_impl!( - self: &mut Self, MatrixSliceMut, SliceStorageMut, RawStorageMut.get_address_unchecked_mut(), &mut self.data; - row_mut, - row_part_mut, - rows_mut, - rows_with_step_mut, - fixed_rows_mut, - fixed_rows_with_step_mut, - rows_generic_mut, - rows_generic_with_step_mut, - column_mut, - column_part_mut, - columns_mut, - columns_with_step_mut, - fixed_columns_mut, - fixed_columns_with_step_mut, - columns_generic_mut, - columns_generic_with_step_mut, - slice_mut, - slice_with_steps_mut, - fixed_slice_mut, - fixed_slice_with_steps_mut, - generic_slice_mut, - generic_slice_with_steps_mut, - rows_range_pair_mut, - columns_range_pair_mut); -} - -/// A range with a size that may be known at compile-time. -/// -/// This may be: -/// * A single `usize` index, e.g., `4` -/// * A left-open range `std::ops::RangeTo`, e.g., `.. 4` -/// * A right-open range `std::ops::RangeFrom`, e.g., `4 ..` -/// * A full range `std::ops::RangeFull`, e.g., `..` -pub trait SliceRange { - /// Type of the range size. May be a type-level integer. - type Size: Dim; - - /// The start index of the range. - fn begin(&self, shape: D) -> usize; - // NOTE: this is the index immediately after the last index. - /// The index immediately after the last index inside of the range. - fn end(&self, shape: D) -> usize; - /// The number of elements of the range, i.e., `self.end - self.begin`. - fn size(&self, shape: D) -> Self::Size; -} - -impl SliceRange for usize { - type Size = U1; - - #[inline(always)] - fn begin(&self, _: D) -> usize { - *self - } - - #[inline(always)] - fn end(&self, _: D) -> usize { - *self + 1 - } - - #[inline(always)] - fn size(&self, _: D) -> Self::Size { - Const::<1> - } -} - -impl SliceRange for Range { - type Size = Dynamic; - - #[inline(always)] - fn begin(&self, _: D) -> usize { - self.start - } - - #[inline(always)] - fn end(&self, _: D) -> usize { - self.end - } - - #[inline(always)] - fn size(&self, _: D) -> Self::Size { - Dynamic::new(self.end - self.start) - } -} - -impl SliceRange for RangeFrom { - type Size = Dynamic; - - #[inline(always)] - fn begin(&self, _: D) -> usize { - self.start - } - - #[inline(always)] - fn end(&self, dim: D) -> usize { - dim.value() - } - - #[inline(always)] - fn size(&self, dim: D) -> Self::Size { - Dynamic::new(dim.value() - self.start) - } -} - -impl SliceRange for RangeTo { - type Size = Dynamic; - - #[inline(always)] - fn begin(&self, _: D) -> usize { - 0 - } - - #[inline(always)] - fn end(&self, _: D) -> usize { - self.end - } - - #[inline(always)] - fn size(&self, _: D) -> Self::Size { - Dynamic::new(self.end) - } -} - -impl SliceRange for RangeFull { - type Size = D; - - #[inline(always)] - fn begin(&self, _: D) -> usize { - 0 - } - - #[inline(always)] - fn end(&self, dim: D) -> usize { - dim.value() - } - - #[inline(always)] - fn size(&self, dim: D) -> Self::Size { - dim - } -} - -impl SliceRange for RangeInclusive { - type Size = Dynamic; - - #[inline(always)] - fn begin(&self, _: D) -> usize { - *self.start() - } - - #[inline(always)] - fn end(&self, _: D) -> usize { - *self.end() + 1 - } - - #[inline(always)] - fn size(&self, _: D) -> Self::Size { - Dynamic::new(*self.end() + 1 - *self.start()) - } -} - -// TODO: see how much of this overlaps with the general indexing -// methods from indexing.rs. -impl> Matrix { - /// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed - /// by the range `cols`. - #[inline] - #[must_use] - pub fn slice_range( - &self, - rows: RowRange, - cols: ColRange, - ) -> MatrixSlice<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride> - where - RowRange: SliceRange, - ColRange: SliceRange, - { - let (nrows, ncols) = self.shape_generic(); - self.generic_slice( - (rows.begin(nrows), cols.begin(ncols)), - (rows.size(nrows), cols.size(ncols)), - ) - } - - /// Slice containing all the rows indexed by the range `rows`. - #[inline] - #[must_use] - pub fn rows_range>( - &self, - rows: RowRange, - ) -> MatrixSlice<'_, T, RowRange::Size, C, S::RStride, S::CStride> { - self.slice_range(rows, ..) - } - - /// Slice containing all the columns indexed by the range `rows`. - #[inline] - #[must_use] - pub fn columns_range>( - &self, - cols: ColRange, - ) -> MatrixSlice<'_, T, R, ColRange::Size, S::RStride, S::CStride> { - self.slice_range(.., cols) - } -} - -// TODO: see how much of this overlaps with the general indexing -// methods from indexing.rs. -impl> Matrix { - /// Slices a mutable sub-matrix containing the rows indexed by the range `rows` and the columns - /// indexed by the range `cols`. - pub fn slice_range_mut( - &mut self, - rows: RowRange, - cols: ColRange, - ) -> MatrixSliceMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride> - where - RowRange: SliceRange, - ColRange: SliceRange, - { - let (nrows, ncols) = self.shape_generic(); - self.generic_slice_mut( - (rows.begin(nrows), cols.begin(ncols)), - (rows.size(nrows), cols.size(ncols)), - ) - } - - /// Slice containing all the rows indexed by the range `rows`. - #[inline] - pub fn rows_range_mut>( - &mut self, - rows: RowRange, - ) -> MatrixSliceMut<'_, T, RowRange::Size, C, S::RStride, S::CStride> { - self.slice_range_mut(rows, ..) - } - - /// Slice containing all the columns indexed by the range `cols`. - #[inline] - pub fn columns_range_mut>( - &mut self, - cols: ColRange, - ) -> MatrixSliceMut<'_, T, R, ColRange::Size, S::RStride, S::CStride> { - self.slice_range_mut(.., cols) - } -} - -impl<'a, T, R, C, RStride, CStride> From> - for MatrixSlice<'a, T, R, C, RStride, CStride> -where - R: Dim, - C: Dim, - RStride: Dim, - CStride: Dim, -{ - fn from(slice_mut: MatrixSliceMut<'a, T, R, C, RStride, CStride>) -> Self { - let data = SliceStorage { - ptr: slice_mut.data.ptr, - shape: slice_mut.data.shape, - strides: slice_mut.data.strides, - _phantoms: PhantomData, - }; - - unsafe { Matrix::from_data_statically_unchecked(data) } - } -} diff --git a/src/base/matrix_view.rs b/src/base/matrix_view.rs new file mode 100644 index 00000000..fa6f8f00 --- /dev/null +++ b/src/base/matrix_view.rs @@ -0,0 +1,1233 @@ +use std::marker::PhantomData; +use std::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo}; +use std::slice; + +use crate::base::allocator::Allocator; +use crate::base::default_allocator::DefaultAllocator; +use crate::base::dimension::{Const, Dim, DimName, Dyn, IsNotStaticOne, U1}; +use crate::base::iter::MatrixIter; +use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, Storage}; +use crate::base::{Matrix, Scalar}; +use crate::constraint::{DimEq, ShapeConstraint}; +use crate::ReshapableStorage; + +macro_rules! view_storage_impl ( + ($doc: expr; $Storage: ident as $SRef: ty; $legacy_name:ident => $T: ident.$get_addr: ident ($Ptr: ty as $Ref: ty)) => { + #[doc = $doc] + #[derive(Debug)] + pub struct $T<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> { + ptr: $Ptr, + shape: (R, C), + strides: (RStride, CStride), + _phantoms: PhantomData<$Ref>, + } + + #[doc = $doc] + /// + /// This type alias exists only for legacy purposes and is deprecated. It will be removed + /// in a future release. Please use + /// [` + #[doc = stringify!($T)] + /// `] instead. See [issue #1076](https://github.com/dimforge/nalgebra/issues/1076) + /// for the rationale. + #[deprecated = "Use ViewStorage(Mut) instead."] + pub type $legacy_name<'a, T, R, C, RStride, CStride> = $T<'a, T, R, C, RStride, CStride>; + + unsafe impl<'a, T: Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send + for $T<'a, T, R, C, RStride, CStride> + {} + + unsafe impl<'a, T: Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync + for $T<'a, T, R, C, RStride, CStride> + {} + + impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> { + /// Create a new matrix view without bounds checking and from a raw pointer. + #[inline] + pub unsafe fn from_raw_parts(ptr: $Ptr, + shape: (R, C), + strides: (RStride, CStride)) + -> Self + where RStride: Dim, + CStride: Dim { + + $T { + ptr, + shape, + strides, + _phantoms: PhantomData + } + } + } + + // Dyn is arbitrary. It's just to be able to call the constructors with `Slice::` + impl<'a, T, R: Dim, C: Dim> $T<'a, T, R, C, Dyn, Dyn> { + /// Create a new matrix view without bounds checking. + #[inline] + pub unsafe fn new_unchecked(storage: $SRef, start: (usize, usize), shape: (R, C)) + -> $T<'a, T, R, C, S::RStride, S::CStride> + where RStor: Dim, + CStor: Dim, + S: $Storage { + + let strides = storage.strides(); + $T::new_with_strides_unchecked(storage, start, shape, strides) + } + + /// Create a new matrix view without bounds checking. + #[inline] + pub unsafe fn new_with_strides_unchecked(storage: $SRef, + start: (usize, usize), + shape: (R, C), + strides: (RStride, CStride)) + -> $T<'a, T, R, C, RStride, CStride> + where RStor: Dim, + CStor: Dim, + S: $Storage, + RStride: Dim, + CStride: Dim { + $T::from_raw_parts(storage.$get_addr(start.0, start.1), shape, strides) + } + } + + impl <'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> + $T<'a, T, R, C, RStride, CStride> + where + Self: RawStorage + IsContiguous + { + /// Extracts the original slice from this storage. + pub fn into_slice(self) -> &'a [T] { + let (nrows, ncols) = self.shape(); + if nrows.value() != 0 && ncols.value() != 0 { + let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); + unsafe { slice::from_raw_parts(self.ptr, sz + 1) } + } else { + unsafe { slice::from_raw_parts(self.ptr, 0) } + } + } + } + } +); + +view_storage_impl!("A matrix data storage for a matrix view. Only contains an internal reference \ + to another matrix data storage."; + RawStorage as &'a S; SliceStorage => ViewStorage.get_address_unchecked(*const T as &'a T)); + +view_storage_impl!("A mutable matrix data storage for mutable matrix view. Only contains an \ + internal mutable reference to another matrix data storage."; + RawStorageMut as &'a mut S; SliceStorageMut => ViewStorageMut.get_address_unchecked_mut(*mut T as &'a mut T) +); + +impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy + for ViewStorage<'a, T, R, C, RStride, CStride> +{ +} + +impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone + for ViewStorage<'a, T, R, C, RStride, CStride> +{ + #[inline] + fn clone(&self) -> Self { + Self { + ptr: self.ptr, + shape: self.shape, + strides: self.strides, + _phantoms: PhantomData, + } + } +} + +impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> + ViewStorageMut<'a, T, R, C, RStride, CStride> +where + Self: RawStorageMut + IsContiguous, +{ + /// Extracts the original slice from this storage + pub fn into_slice_mut(self) -> &'a mut [T] { + let (nrows, ncols) = self.shape(); + if nrows.value() != 0 && ncols.value() != 0 { + let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); + unsafe { slice::from_raw_parts_mut(self.ptr, sz + 1) } + } else { + unsafe { slice::from_raw_parts_mut(self.ptr, 0) } + } + } +} + +macro_rules! storage_impl( + ($($T: ident),* $(,)*) => {$( + unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorage + for $T<'a, T, R, C, RStride, CStride> { + + type RStride = RStride; + type CStride = CStride; + + #[inline] + fn ptr(&self) -> *const T { + self.ptr + } + + #[inline] + fn shape(&self) -> (R, C) { + self.shape + } + + #[inline] + fn strides(&self) -> (Self::RStride, Self::CStride) { + self.strides + } + + #[inline] + fn is_contiguous(&self) -> bool { + // Common cases that can be deduced at compile-time even if one of the dimensions + // is Dyn. + if (RStride::is::() && C::is::()) || // Column vector. + (CStride::is::() && R::is::()) { // Row vector. + true + } + else { + let (nrows, _) = self.shape(); + let (srows, scols) = self.strides(); + + srows.value() == 1 && scols.value() == nrows.value() + } + } + + #[inline] + unsafe fn as_slice_unchecked(&self) -> &[T] { + let (nrows, ncols) = self.shape(); + if nrows.value() != 0 && ncols.value() != 0 { + let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); + slice::from_raw_parts(self.ptr, sz + 1) + } + else { + slice::from_raw_parts(self.ptr, 0) + } + } + } + + unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage + for $T<'a, T, R, C, RStride, CStride> { + #[inline] + fn into_owned(self) -> Owned + where DefaultAllocator: Allocator { + self.clone_owned() + } + + #[inline] + fn clone_owned(&self) -> Owned + where DefaultAllocator: Allocator { + let (nrows, ncols) = self.shape(); + let it = MatrixIter::new(self).cloned(); + DefaultAllocator::allocate_from_iterator(nrows, ncols, it) + } + } + )*} +); + +storage_impl!(ViewStorage, ViewStorageMut); + +unsafe impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim> RawStorageMut + for ViewStorageMut<'a, T, R, C, RStride, CStride> +{ + #[inline] + fn ptr_mut(&mut self) -> *mut T { + self.ptr + } + + #[inline] + unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { + let (nrows, ncols) = self.shape(); + if nrows.value() != 0 && ncols.value() != 0 { + let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); + slice::from_raw_parts_mut(self.ptr, sz + 1) + } else { + slice::from_raw_parts_mut(self.ptr, 0) + } + } +} + +unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous for ViewStorage<'a, T, R, U1, U1, CStride> {} +unsafe impl<'a, T, R: Dim, CStride: Dim> IsContiguous + for ViewStorageMut<'a, T, R, U1, U1, CStride> +{ +} + +unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous + for ViewStorage<'a, T, R, C, U1, R> +{ +} +unsafe impl<'a, T, R: DimName, C: Dim + IsNotStaticOne> IsContiguous + for ViewStorageMut<'a, T, R, C, U1, R> +{ +} + +impl> Matrix { + #[inline] + fn assert_view_index( + &self, + start: (usize, usize), + shape: (usize, usize), + steps: (usize, usize), + ) { + let my_shape = self.shape(); + // NOTE: we don't do any subtraction to avoid underflow for zero-sized matrices. + // + // Terms that would have been negative are moved to the other side of the inequality + // instead. + assert!( + start.0 + (steps.0 + 1) * shape.0 <= my_shape.0 + steps.0, + "Matrix slicing out of bounds." + ); + assert!( + start.1 + (steps.1 + 1) * shape.1 <= my_shape.1 + steps.1, + "Matrix slicing out of bounds." + ); + } +} + +macro_rules! matrix_view_impl ( + ($me: ident: $Me: ty, $MatrixView: ident, $ViewStorage: ident, $Storage: ident.$get_addr: ident (), $data: expr; + $row: ident, + $row_part: ident, + $rows: ident, + $rows_with_step: ident, + $fixed_rows: ident, + $fixed_rows_with_step: ident, + $rows_generic: ident, + $rows_generic_with_step: ident, + $column: ident, + $column_part: ident, + $columns: ident, + $columns_with_step: ident, + $fixed_columns: ident, + $fixed_columns_with_step: ident, + $columns_generic: ident, + $columns_generic_with_step: ident, + $slice: ident => $view:ident, + $slice_with_steps: ident => $view_with_steps:ident, + $fixed_slice: ident => $fixed_view:ident, + $fixed_slice_with_steps: ident => $fixed_view_with_steps:ident, + $generic_slice: ident => $generic_view:ident, + $generic_slice_with_steps: ident => $generic_view_with_steps:ident, + $rows_range_pair: ident, + $columns_range_pair: ident) => { + /* + * + * Row slicing. + * + */ + /// Returns a view containing the i-th row of this matrix. + #[inline] + pub fn $row($me: $Me, i: usize) -> $MatrixView<'_, T, U1, C, S::RStride, S::CStride> { + $me.$fixed_rows::<1>(i) + } + + /// Returns a view containing the `n` first elements of the i-th row of this matrix. + #[inline] + pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixView<'_, T, U1, Dyn, S::RStride, S::CStride> { + $me.$generic_view((i, 0), (Const::<1>, Dyn(n))) + } + + /// Extracts from this matrix a set of consecutive rows. + #[inline] + pub fn $rows($me: $Me, first_row: usize, nrows: usize) + -> $MatrixView<'_, T, Dyn, C, S::RStride, S::CStride> { + + $me.$rows_generic(first_row, Dyn(nrows)) + } + + /// Extracts from this matrix a set of consecutive rows regularly skipping `step` rows. + #[inline] + pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize) + -> $MatrixView<'_, T, Dyn, C, Dyn, S::CStride> { + + $me.$rows_generic_with_step(first_row, Dyn(nrows), step) + } + + /// Extracts a compile-time number of consecutive rows from this matrix. + #[inline] + pub fn $fixed_rows($me: $Me, first_row: usize) + -> $MatrixView<'_, T, Const, C, S::RStride, S::CStride> { + + $me.$rows_generic(first_row, Const::) + } + + /// Extracts from this matrix a compile-time number of rows regularly skipping `step` + /// rows. + #[inline] + pub fn $fixed_rows_with_step($me: $Me, first_row: usize, step: usize) + -> $MatrixView<'_, T, Const, C, Dyn, S::CStride> { + + $me.$rows_generic_with_step(first_row, Const::, step) + } + + /// Extracts from this matrix `nrows` rows regularly skipping `step` rows. Both + /// argument may or may not be values known at compile-time. + #[inline] + pub fn $rows_generic($me: $Me, row_start: usize, nrows: RView) + -> $MatrixView<'_, T, RView, C, S::RStride, S::CStride> { + + let my_shape = $me.shape_generic(); + $me.assert_view_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0)); + + let shape = (nrows, my_shape.1); + + unsafe { + let data = $ViewStorage::new_unchecked($data, (row_start, 0), shape); + Matrix::from_data_statically_unchecked(data) + } + } + + /// Extracts from this matrix `nrows` rows regularly skipping `step` rows. Both + /// argument may or may not be values known at compile-time. + #[inline] + pub fn $rows_generic_with_step($me: $Me, row_start: usize, nrows: RView, step: usize) + -> $MatrixView<'_, T, RView, C, Dyn, S::CStride> + where RView: Dim { + + let my_shape = $me.shape_generic(); + let my_strides = $me.data.strides(); + $me.assert_view_index((row_start, 0), (nrows.value(), my_shape.1.value()), (step, 0)); + + let strides = (Dyn((step + 1) * my_strides.0.value()), my_strides.1); + let shape = (nrows, my_shape.1); + + unsafe { + let data = $ViewStorage::new_with_strides_unchecked($data, (row_start, 0), shape, strides); + Matrix::from_data_statically_unchecked(data) + } + } + + /* + * + * Column slicing. + * + */ + /// Returns a view containing the i-th column of this matrix. + #[inline] + pub fn $column($me: $Me, i: usize) -> $MatrixView<'_, T, R, U1, S::RStride, S::CStride> { + $me.$fixed_columns::<1>(i) + } + + /// Returns a view containing the `n` first elements of the i-th column of this matrix. + #[inline] + pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixView<'_, T, Dyn, U1, S::RStride, S::CStride> { + $me.$generic_view((0, i), (Dyn(n), Const::<1>)) + } + + /// Extracts from this matrix a set of consecutive columns. + #[inline] + pub fn $columns($me: $Me, first_col: usize, ncols: usize) + -> $MatrixView<'_, T, R, Dyn, S::RStride, S::CStride> { + + $me.$columns_generic(first_col, Dyn(ncols)) + } + + /// Extracts from this matrix a set of consecutive columns regularly skipping `step` + /// columns. + #[inline] + pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize) + -> $MatrixView<'_, T, R, Dyn, S::RStride, Dyn> { + + $me.$columns_generic_with_step(first_col, Dyn(ncols), step) + } + + /// Extracts a compile-time number of consecutive columns from this matrix. + #[inline] + pub fn $fixed_columns($me: $Me, first_col: usize) + -> $MatrixView<'_, T, R, Const, S::RStride, S::CStride> { + + $me.$columns_generic(first_col, Const::) + } + + /// Extracts from this matrix a compile-time number of columns regularly skipping + /// `step` columns. + #[inline] + pub fn $fixed_columns_with_step($me: $Me, first_col: usize, step: usize) + -> $MatrixView<'_, T, R, Const, S::RStride, Dyn> { + + $me.$columns_generic_with_step(first_col, Const::, step) + } + + /// Extracts from this matrix `ncols` columns. The number of columns may or may not be + /// known at compile-time. + #[inline] + pub fn $columns_generic($me: $Me, first_col: usize, ncols: CView) + -> $MatrixView<'_, T, R, CView, S::RStride, S::CStride> { + + let my_shape = $me.shape_generic(); + $me.assert_view_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0)); + let shape = (my_shape.0, ncols); + + unsafe { + let data = $ViewStorage::new_unchecked($data, (0, first_col), shape); + Matrix::from_data_statically_unchecked(data) + } + } + + + /// Extracts from this matrix `ncols` columns skipping `step` columns. Both argument may + /// or may not be values known at compile-time. + #[inline] + pub fn $columns_generic_with_step($me: $Me, first_col: usize, ncols: CView, step: usize) + -> $MatrixView<'_, T, R, CView, S::RStride, Dyn> { + + let my_shape = $me.shape_generic(); + let my_strides = $me.data.strides(); + + $me.assert_view_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, step)); + + let strides = (my_strides.0, Dyn((step + 1) * my_strides.1.value())); + let shape = (my_shape.0, ncols); + + unsafe { + let data = $ViewStorage::new_with_strides_unchecked($data, (0, first_col), shape, strides); + Matrix::from_data_statically_unchecked(data) + } + } + + /* + * + * General slicing. + * + */ + /// Slices this matrix starting at its component `(irow, icol)` and with `(nrows, ncols)` + /// consecutive elements. + #[inline] + #[deprecated = slice_deprecation_note!($view)] + pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize)) + -> $MatrixView<'_, T, Dyn, Dyn, S::RStride, S::CStride> { + $me.$view(start, shape) + } + + /// Return a view of this matrix starting at its component `(irow, icol)` and with `(nrows, ncols)` + /// consecutive elements. + #[inline] + pub fn $view($me: $Me, start: (usize, usize), shape: (usize, usize)) + -> $MatrixView<'_, T, Dyn, Dyn, S::RStride, S::CStride> { + + $me.assert_view_index(start, shape, (0, 0)); + let shape = (Dyn(shape.0), Dyn(shape.1)); + + unsafe { + let data = $ViewStorage::new_unchecked($data, start, shape); + Matrix::from_data_statically_unchecked(data) + } + } + + /// Slices this matrix starting at its component `(start.0, start.1)` and with + /// `(shape.0, shape.1)` components. Each row (resp. column) of the sliced matrix is + /// separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of the + /// original matrix. + #[inline] + #[deprecated = slice_deprecation_note!($view_with_steps)] + pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize)) + -> $MatrixView<'_, T, Dyn, Dyn, Dyn, Dyn> { + $me.$view_with_steps(start, shape, steps) + } + + /// Return a view of this matrix starting at its component `(start.0, start.1)` and with + /// `(shape.0, shape.1)` components. Each row (resp. column) of the matrix view is + /// separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of the + /// original matrix. + #[inline] + pub fn $view_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize)) + -> $MatrixView<'_, T, Dyn, Dyn, Dyn, Dyn> { + let shape = (Dyn(shape.0), Dyn(shape.1)); + $me.$generic_view_with_steps(start, shape, steps) + } + + /// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(), + /// CView::dim())` consecutive components. + #[inline] + #[deprecated = slice_deprecation_note!($fixed_view)] + pub fn $fixed_slice($me: $Me, irow: usize, icol: usize) + -> $MatrixView<'_, T, Const, Const, S::RStride, S::CStride> { + $me.$fixed_view(irow, icol) + } + + /// Return a view of this matrix starting at its component `(irow, icol)` and with `(R::dim(), + /// CView::dim())` consecutive components. + #[inline] + pub fn $fixed_view($me: $Me, irow: usize, icol: usize) + -> $MatrixView<'_, T, Const, Const, S::RStride, S::CStride> { + + $me.assert_view_index((irow, icol), (RVIEW, CVIEW), (0, 0)); + let shape = (Const::, Const::); + + unsafe { + let data = $ViewStorage::new_unchecked($data, (irow, icol), shape); + Matrix::from_data_statically_unchecked(data) + } + } + + /// Slices this matrix starting at its component `(start.0, start.1)` and with + /// `(RVIEW, CVIEW)` components. Each row (resp. column) of the sliced + /// matrix is separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of + /// the original matrix. + #[inline] + #[deprecated = slice_deprecation_note!($fixed_view_with_steps)] + pub fn $fixed_slice_with_steps($me: $Me, start: (usize, usize), steps: (usize, usize)) + -> $MatrixView<'_, T, Const, Const, Dyn, Dyn> { + $me.$fixed_view_with_steps(start, steps) + } + + /// Returns a view of this matrix starting at its component `(start.0, start.1)` and with + /// `(RVIEW, CVIEW)` components. Each row (resp. column) of the matrix view + /// is separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of + /// the original matrix. + #[inline] + pub fn $fixed_view_with_steps($me: $Me, start: (usize, usize), steps: (usize, usize)) + -> $MatrixView<'_, T, Const, Const, Dyn, Dyn> { + let shape = (Const::, Const::); + $me.$generic_view_with_steps(start, shape, steps) + } + + /// Creates a slice that may or may not have a fixed size and stride. + #[inline] + #[deprecated = slice_deprecation_note!($generic_view)] + pub fn $generic_slice($me: $Me, start: (usize, usize), shape: (RView, CView)) + -> $MatrixView<'_, T, RView, CView, S::RStride, S::CStride> + where RView: Dim, + CView: Dim { + $me.$generic_view(start, shape) + } + + /// Creates a matrix view that may or may not have a fixed size and stride. + #[inline] + pub fn $generic_view($me: $Me, start: (usize, usize), shape: (RView, CView)) + -> $MatrixView<'_, T, RView, CView, S::RStride, S::CStride> + where RView: Dim, + CView: Dim { + + $me.assert_view_index(start, (shape.0.value(), shape.1.value()), (0, 0)); + + unsafe { + let data = $ViewStorage::new_unchecked($data, start, shape); + Matrix::from_data_statically_unchecked(data) + } + } + + /// Creates a slice that may or may not have a fixed size and stride. + #[inline] + #[deprecated = slice_deprecation_note!($generic_view_with_steps)] + pub fn $generic_slice_with_steps($me: $Me, + start: (usize, usize), + shape: (RView, CView), + steps: (usize, usize)) + -> $MatrixView<'_, T, RView, CView, Dyn, Dyn> + where RView: Dim, + CView: Dim { + $me.$generic_view_with_steps(start, shape, steps) + } + + /// Creates a matrix view that may or may not have a fixed size and stride. + #[inline] + pub fn $generic_view_with_steps($me: $Me, + start: (usize, usize), + shape: (RView, CView), + steps: (usize, usize)) + -> $MatrixView<'_, T, RView, CView, Dyn, Dyn> + where RView: Dim, + CView: Dim { + + $me.assert_view_index(start, (shape.0.value(), shape.1.value()), steps); + + let my_strides = $me.data.strides(); + let strides = (Dyn((steps.0 + 1) * my_strides.0.value()), + Dyn((steps.1 + 1) * my_strides.1.value())); + + unsafe { + let data = $ViewStorage::new_with_strides_unchecked($data, start, shape, strides); + Matrix::from_data_statically_unchecked(data) + } + } + + /* + * + * Splitting. + * + */ + /// Splits this `NxM` matrix into two parts delimited by two ranges. + /// + /// Panics if the ranges overlap or if the first range is empty. + #[inline] + pub fn $rows_range_pair, Range2: DimRange>($me: $Me, r1: Range1, r2: Range2) + -> ($MatrixView<'_, T, Range1::Size, C, S::RStride, S::CStride>, + $MatrixView<'_, T, Range2::Size, C, S::RStride, S::CStride>) { + + let (nrows, ncols) = $me.shape_generic(); + let strides = $me.data.strides(); + + let start1 = r1.begin(nrows); + let start2 = r2.begin(nrows); + + let end1 = r1.end(nrows); + let end2 = r2.end(nrows); + + let nrows1 = r1.size(nrows); + let nrows2 = r2.size(nrows); + + assert!(start2 >= end1 || start1 >= end2, "Rows range pair: the ranges must not overlap."); + assert!(end2 <= nrows.value(), "Rows range pair: index out of range."); + + unsafe { + let ptr1 = $data.$get_addr(start1, 0); + let ptr2 = $data.$get_addr(start2, 0); + + let data1 = $ViewStorage::from_raw_parts(ptr1, (nrows1, ncols), strides); + let data2 = $ViewStorage::from_raw_parts(ptr2, (nrows2, ncols), strides); + let view1 = Matrix::from_data_statically_unchecked(data1); + let view2 = Matrix::from_data_statically_unchecked(data2); + + (view1, view2) + } + } + + /// Splits this `NxM` matrix into two parts delimited by two ranges. + /// + /// Panics if the ranges overlap or if the first range is empty. + #[inline] + pub fn $columns_range_pair, Range2: DimRange>($me: $Me, r1: Range1, r2: Range2) + -> ($MatrixView<'_, T, R, Range1::Size, S::RStride, S::CStride>, + $MatrixView<'_, T, R, Range2::Size, S::RStride, S::CStride>) { + + let (nrows, ncols) = $me.shape_generic(); + let strides = $me.data.strides(); + + let start1 = r1.begin(ncols); + let start2 = r2.begin(ncols); + + let end1 = r1.end(ncols); + let end2 = r2.end(ncols); + + let ncols1 = r1.size(ncols); + let ncols2 = r2.size(ncols); + + assert!(start2 >= end1 || start1 >= end2, "Columns range pair: the ranges must not overlap."); + assert!(end2 <= ncols.value(), "Columns range pair: index out of range."); + + unsafe { + let ptr1 = $data.$get_addr(0, start1); + let ptr2 = $data.$get_addr(0, start2); + + let data1 = $ViewStorage::from_raw_parts(ptr1, (nrows, ncols1), strides); + let data2 = $ViewStorage::from_raw_parts(ptr2, (nrows, ncols2), strides); + let view1 = Matrix::from_data_statically_unchecked(data1); + let view2 = Matrix::from_data_statically_unchecked(data2); + + (view1, view2) + } + } + } +); + +/// A matrix slice. +/// +/// This type alias exists only for legacy purposes and is deprecated. It will be removed +/// in a future release. Please use [`MatrixView`] instead. +/// See [issue #1076](https://github.com/dimforge/nalgebra/issues/1076) +/// for the rationale. +#[deprecated = "Use MatrixView instead."] +pub type MatrixSlice<'a, T, R, C, RStride = U1, CStride = R> = + MatrixView<'a, T, R, C, RStride, CStride>; + +/// A matrix view. +pub type MatrixView<'a, T, R, C, RStride = U1, CStride = R> = + Matrix>; + +/// A mutable matrix slice. +/// +/// This type alias exists only for legacy purposes and is deprecated. It will be removed +/// in a future release. Please use [`MatrixViewMut`] instead. +/// See [issue #1076](https://github.com/dimforge/nalgebra/issues/1076) +/// for the rationale. +#[deprecated = "Use MatrixViewMut instead."] +pub type MatrixSliceMut<'a, T, R, C, RStride = U1, CStride = R> = + MatrixViewMut<'a, T, R, C, RStride, CStride>; + +/// A mutable matrix view. +pub type MatrixViewMut<'a, T, R, C, RStride = U1, CStride = R> = + Matrix>; + +/// # Views based on index and length +impl> Matrix { + matrix_view_impl!( + self: &Self, MatrixView, ViewStorage, RawStorage.get_address_unchecked(), &self.data; + row, + row_part, + rows, + rows_with_step, + fixed_rows, + fixed_rows_with_step, + rows_generic, + rows_generic_with_step, + column, + column_part, + columns, + columns_with_step, + fixed_columns, + fixed_columns_with_step, + columns_generic, + columns_generic_with_step, + slice => view, + slice_with_steps => view_with_steps, + fixed_slice => fixed_view, + fixed_slice_with_steps => fixed_view_with_steps, + generic_slice => generic_view, + generic_slice_with_steps => generic_view_with_steps, + rows_range_pair, + columns_range_pair); +} + +/// # Mutable views based on index and length +impl> Matrix { + matrix_view_impl!( + self: &mut Self, MatrixViewMut, ViewStorageMut, RawStorageMut.get_address_unchecked_mut(), &mut self.data; + row_mut, + row_part_mut, + rows_mut, + rows_with_step_mut, + fixed_rows_mut, + fixed_rows_with_step_mut, + rows_generic_mut, + rows_generic_with_step_mut, + column_mut, + column_part_mut, + columns_mut, + columns_with_step_mut, + fixed_columns_mut, + fixed_columns_with_step_mut, + columns_generic_mut, + columns_generic_with_step_mut, + slice_mut => view_mut, + slice_with_steps_mut => view_with_steps_mut, + fixed_slice_mut => fixed_view_mut, + fixed_slice_with_steps_mut => fixed_view_with_steps_mut, + generic_slice_mut => generic_view_mut, + generic_slice_with_steps_mut => generic_view_with_steps_mut, + rows_range_pair_mut, + columns_range_pair_mut); +} + +/// A range with a size that may be known at compile-time. +/// +/// This may be: +/// * A single `usize` index, e.g., `4` +/// * A left-open range `std::ops::RangeTo`, e.g., `.. 4` +/// * A right-open range `std::ops::RangeFrom`, e.g., `4 ..` +/// * A full range `std::ops::RangeFull`, e.g., `..` +pub trait DimRange { + /// Type of the range size. May be a type-level integer. + type Size: Dim; + + /// The start index of the range. + fn begin(&self, shape: D) -> usize; + // NOTE: this is the index immediately after the last index. + /// The index immediately after the last index inside of the range. + fn end(&self, shape: D) -> usize; + /// The number of elements of the range, i.e., `self.end - self.begin`. + fn size(&self, shape: D) -> Self::Size; +} + +/// A range with a size that may be known at compile-time. +/// +/// This is merely a legacy trait alias to minimize breakage. Use the [`DimRange`] trait instead. +#[deprecated = slice_deprecation_note!(DimRange)] +pub trait SliceRange: DimRange {} + +#[allow(deprecated)] +impl, D: Dim> SliceRange for R {} + +impl DimRange for usize { + type Size = U1; + + #[inline(always)] + fn begin(&self, _: D) -> usize { + *self + } + + #[inline(always)] + fn end(&self, _: D) -> usize { + *self + 1 + } + + #[inline(always)] + fn size(&self, _: D) -> Self::Size { + Const::<1> + } +} + +impl DimRange for Range { + type Size = Dyn; + + #[inline(always)] + fn begin(&self, _: D) -> usize { + self.start + } + + #[inline(always)] + fn end(&self, _: D) -> usize { + self.end + } + + #[inline(always)] + fn size(&self, _: D) -> Self::Size { + Dyn(self.end - self.start) + } +} + +impl DimRange for RangeFrom { + type Size = Dyn; + + #[inline(always)] + fn begin(&self, _: D) -> usize { + self.start + } + + #[inline(always)] + fn end(&self, dim: D) -> usize { + dim.value() + } + + #[inline(always)] + fn size(&self, dim: D) -> Self::Size { + Dyn(dim.value() - self.start) + } +} + +impl DimRange for RangeTo { + type Size = Dyn; + + #[inline(always)] + fn begin(&self, _: D) -> usize { + 0 + } + + #[inline(always)] + fn end(&self, _: D) -> usize { + self.end + } + + #[inline(always)] + fn size(&self, _: D) -> Self::Size { + Dyn(self.end) + } +} + +impl DimRange for RangeFull { + type Size = D; + + #[inline(always)] + fn begin(&self, _: D) -> usize { + 0 + } + + #[inline(always)] + fn end(&self, dim: D) -> usize { + dim.value() + } + + #[inline(always)] + fn size(&self, dim: D) -> Self::Size { + dim + } +} + +impl DimRange for RangeInclusive { + type Size = Dyn; + + #[inline(always)] + fn begin(&self, _: D) -> usize { + *self.start() + } + + #[inline(always)] + fn end(&self, _: D) -> usize { + *self.end() + 1 + } + + #[inline(always)] + fn size(&self, _: D) -> Self::Size { + Dyn(*self.end() + 1 - *self.start()) + } +} + +// TODO: see how much of this overlaps with the general indexing +// methods from indexing.rs. +impl> Matrix { + /// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed + /// by the range `cols`. + #[inline] + #[must_use] + #[deprecated = slice_deprecation_note!(view_range)] + pub fn slice_range( + &self, + rows: RowRange, + cols: ColRange, + ) -> MatrixView<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride> + where + RowRange: DimRange, + ColRange: DimRange, + { + let (nrows, ncols) = self.shape_generic(); + self.generic_view( + (rows.begin(nrows), cols.begin(ncols)), + (rows.size(nrows), cols.size(ncols)), + ) + } + + /// Returns a view containing the rows indexed by the range `rows` and the columns indexed + /// by the range `cols`. + #[inline] + #[must_use] + pub fn view_range( + &self, + rows: RowRange, + cols: ColRange, + ) -> MatrixView<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride> + where + RowRange: DimRange, + ColRange: DimRange, + { + let (nrows, ncols) = self.shape_generic(); + self.generic_view( + (rows.begin(nrows), cols.begin(ncols)), + (rows.size(nrows), cols.size(ncols)), + ) + } + + /// View containing all the rows indexed by the range `rows`. + #[inline] + #[must_use] + pub fn rows_range>( + &self, + rows: RowRange, + ) -> MatrixView<'_, T, RowRange::Size, C, S::RStride, S::CStride> { + self.view_range(rows, ..) + } + + /// View containing all the columns indexed by the range `rows`. + #[inline] + #[must_use] + pub fn columns_range>( + &self, + cols: ColRange, + ) -> MatrixView<'_, T, R, ColRange::Size, S::RStride, S::CStride> { + self.view_range(.., cols) + } +} + +// TODO: see how much of this overlaps with the general indexing +// methods from indexing.rs. +impl> Matrix { + /// Slices a mutable sub-matrix containing the rows indexed by the range `rows` and the columns + /// indexed by the range `cols`. + #[deprecated = slice_deprecation_note!(view_range_mut)] + pub fn slice_range_mut( + &mut self, + rows: RowRange, + cols: ColRange, + ) -> MatrixViewMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride> + where + RowRange: DimRange, + ColRange: DimRange, + { + self.view_range_mut(rows, cols) + } + + /// Return a mutable view containing the rows indexed by the range `rows` and the columns + /// indexed by the range `cols`. + pub fn view_range_mut( + &mut self, + rows: RowRange, + cols: ColRange, + ) -> MatrixViewMut<'_, T, RowRange::Size, ColRange::Size, S::RStride, S::CStride> + where + RowRange: DimRange, + ColRange: DimRange, + { + let (nrows, ncols) = self.shape_generic(); + self.generic_view_mut( + (rows.begin(nrows), cols.begin(ncols)), + (rows.size(nrows), cols.size(ncols)), + ) + } + + /// Mutable view containing all the rows indexed by the range `rows`. + #[inline] + pub fn rows_range_mut>( + &mut self, + rows: RowRange, + ) -> MatrixViewMut<'_, T, RowRange::Size, C, S::RStride, S::CStride> { + self.view_range_mut(rows, ..) + } + + /// Mutable view containing all the columns indexed by the range `cols`. + #[inline] + pub fn columns_range_mut>( + &mut self, + cols: ColRange, + ) -> MatrixViewMut<'_, T, R, ColRange::Size, S::RStride, S::CStride> { + self.view_range_mut(.., cols) + } +} + +impl<'a, T, R, C, RStride, CStride> From> + for MatrixView<'a, T, R, C, RStride, CStride> +where + R: Dim, + C: Dim, + RStride: Dim, + CStride: Dim, +{ + fn from(view_mut: MatrixViewMut<'a, T, R, C, RStride, CStride>) -> Self { + let data = ViewStorage { + ptr: view_mut.data.ptr, + shape: view_mut.data.shape, + strides: view_mut.data.strides, + _phantoms: PhantomData, + }; + + unsafe { Matrix::from_data_statically_unchecked(data) } + } +} + +impl Matrix +where + R: Dim, + C: Dim, + S: RawStorage, +{ + /// Returns this matrix as a view. + /// + /// The returned view type is generally ambiguous unless specified. + /// This is particularly useful when working with functions or methods that take + /// matrix views as input. + /// + /// # Panics + /// Panics if the dimensions of the view and the matrix are not compatible and this cannot + /// be proven at compile-time. This might happen, for example, when constructing a static + /// view of size 3x3 from a dynamically sized matrix of dimension 5x5. + /// + /// # Examples + /// ``` + /// use nalgebra::{DMatrixSlice, SMatrixView}; + /// + /// fn consume_view(_: DMatrixSlice) {} + /// + /// let matrix = nalgebra::Matrix3::zeros(); + /// consume_view(matrix.as_view()); + /// + /// let dynamic_view: DMatrixSlice = matrix.as_view(); + /// let static_view_from_dyn: SMatrixView = dynamic_view.as_view(); + /// ``` + pub fn as_view( + &self, + ) -> MatrixView<'_, T, RView, CView, RViewStride, CViewStride> + where + RView: Dim, + CView: Dim, + RViewStride: Dim, + CViewStride: Dim, + ShapeConstraint: DimEq + + DimEq + + DimEq + + DimEq, + { + // Defer to (&matrix).into() + self.into() + } +} + +impl Matrix +where + R: Dim, + C: Dim, + S: RawStorageMut, +{ + /// Returns this matrix as a mutable view. + /// + /// The returned view type is generally ambiguous unless specified. + /// This is particularly useful when working with functions or methods that take + /// matrix views as input. + /// + /// # Panics + /// Panics if the dimensions of the view and the matrix are not compatible and this cannot + /// be proven at compile-time. This might happen, for example, when constructing a static + /// view of size 3x3 from a dynamically sized matrix of dimension 5x5. + /// + /// # Examples + /// ``` + /// use nalgebra::{DMatrixViewMut, SMatrixViewMut}; + /// + /// fn consume_view(_: DMatrixViewMut) {} + /// + /// let mut matrix = nalgebra::Matrix3::zeros(); + /// consume_view(matrix.as_view_mut()); + /// + /// let mut dynamic_view: DMatrixViewMut = matrix.as_view_mut(); + /// let static_view_from_dyn: SMatrixViewMut = dynamic_view.as_view_mut(); + /// ``` + pub fn as_view_mut( + &mut self, + ) -> MatrixViewMut<'_, T, RView, CView, RViewStride, CViewStride> + where + RView: Dim, + CView: Dim, + RViewStride: Dim, + CViewStride: Dim, + ShapeConstraint: DimEq + + DimEq + + DimEq + + DimEq, + { + // Defer to (&mut matrix).into() + self.into() + } +} + +// TODO: Arbitrary strides? +impl<'a, T, R1, C1, R2, C2> ReshapableStorage + for ViewStorage<'a, T, R1, C1, U1, R1> +where + T: Scalar, + R1: Dim, + C1: Dim, + R2: Dim, + C2: Dim, +{ + type Output = ViewStorage<'a, T, R2, C2, U1, R2>; + + fn reshape_generic(self, nrows: R2, ncols: C2) -> Self::Output { + let (r1, c1) = self.shape(); + assert_eq!(nrows.value() * ncols.value(), r1.value() * c1.value()); + let ptr = self.ptr(); + let new_shape = (nrows, ncols); + let strides = (U1::name(), nrows); + unsafe { ViewStorage::from_raw_parts(ptr, new_shape, strides) } + } +} + +// TODO: Arbitrary strides? +impl<'a, T, R1, C1, R2, C2> ReshapableStorage + for ViewStorageMut<'a, T, R1, C1, U1, R1> +where + T: Scalar, + R1: Dim, + C1: Dim, + R2: Dim, + C2: Dim, +{ + type Output = ViewStorageMut<'a, T, R2, C2, U1, R2>; + + fn reshape_generic(mut self, nrows: R2, ncols: C2) -> Self::Output { + let (r1, c1) = self.shape(); + assert_eq!(nrows.value() * ncols.value(), r1.value() * c1.value()); + let ptr = self.ptr_mut(); + let new_shape = (nrows, ncols); + let strides = (U1::name(), nrows); + unsafe { ViewStorageMut::from_raw_parts(ptr, new_shape, strides) } + } +} diff --git a/src/base/mod.rs b/src/base/mod.rs index c6279ba3..0f09cc33 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -12,18 +12,19 @@ pub mod storage; mod alias; mod alias_slice; +mod alias_view; mod array_storage; mod cg; mod componentwise; #[macro_use] mod construction; -mod construction_slice; +mod construction_view; mod conversion; mod edition; pub mod indexing; mod matrix; mod matrix_simba; -mod matrix_slice; +mod matrix_view; mod norm; mod properties; mod scalar; @@ -41,6 +42,12 @@ mod min_max; /// Mechanisms for working with values that may not be initialized. pub mod uninit; +#[cfg(feature = "rayon")] +pub mod par_iter; + +#[cfg(feature = "rkyv-serialize-no-std")] +mod rkyv_wrappers; + pub use self::matrix::*; pub use self::norm::*; pub use self::scalar::*; @@ -51,8 +58,9 @@ pub use self::dimension::*; pub use self::alias::*; pub use self::alias_slice::*; +pub use self::alias_view::*; pub use self::array_storage::*; -pub use self::matrix_slice::*; +pub use self::matrix_view::*; pub use self::storage::*; #[cfg(any(feature = "std", feature = "alloc"))] pub use self::vec_storage::*; diff --git a/src/base/ops.rs b/src/base/ops.rs index 6b6d0c45..d5cf3a51 100644 --- a/src/base/ops.rs +++ b/src/base/ops.rs @@ -11,10 +11,10 @@ use crate::base::blas_uninit::gemm_uninit; use crate::base::constraint::{ AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, }; -use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dynamic}; +use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dyn}; use crate::base::storage::{Storage, StorageMut}; use crate::base::uninit::Uninit; -use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar, VectorSlice}; +use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar, VectorView}; use crate::storage::IsContiguous; use crate::uninit::{Init, InitStatus}; use crate::{RawStorage, RawStorageMut, SimdComplexField}; @@ -374,10 +374,10 @@ where } } -impl iter::Sum for OMatrix +impl iter::Sum for OMatrix where T: Scalar + ClosedAdd + Zero, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { /// # Example /// ``` @@ -395,7 +395,7 @@ where /// # use nalgebra::DMatrix; /// iter::empty::>().sum::>(); // panics! /// ``` - fn sum>>(mut iter: I) -> OMatrix { + fn sum>>(mut iter: I) -> OMatrix { if let Some(first) = iter.next() { iter.fold(first, |acc, x| acc + x) } else { @@ -414,10 +414,10 @@ where } } -impl<'a, T, C: Dim> iter::Sum<&'a OMatrix> for OMatrix +impl<'a, T, C: Dim> iter::Sum<&'a OMatrix> for OMatrix where T: Scalar + ClosedAdd + Zero, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { /// # Example /// ``` @@ -435,7 +435,7 @@ where /// # use nalgebra::DMatrix; /// iter::empty::<&DMatrix>().sum::>(); // panics! /// ``` - fn sum>>(mut iter: I) -> OMatrix { + fn sum>>(mut iter: I) -> OMatrix { if let Some(first) = iter.next() { iter.fold(first.clone(), |acc, x| acc + x) } else { @@ -703,8 +703,8 @@ where rhs: &Matrix, out: &mut Matrix, dot: impl Fn( - &VectorSlice<'_, T, R1, SA::RStride, SA::CStride>, - &VectorSlice<'_, T, R2, SB::RStride, SB::CStride>, + &VectorView<'_, T, R1, SA::RStride, SA::CStride>, + &VectorView<'_, T, R2, SB::RStride, SB::CStride>, ) -> T, ) where Status: InitStatus, diff --git a/src/base/par_iter.rs b/src/base/par_iter.rs new file mode 100644 index 00000000..af5e1cb7 --- /dev/null +++ b/src/base/par_iter.rs @@ -0,0 +1,285 @@ +//! Parallel iterators for matrices compatible with rayon. + +// only enables the `doc_cfg` feature when +// the `docsrs` configuration attribute is defined +#![cfg_attr(docsrs, feature(doc_cfg))] + +use crate::{ + iter::{ColumnIter, ColumnIterMut}, + Dim, Matrix, MatrixView, MatrixViewMut, RawStorage, RawStorageMut, Scalar, U1, +}; +use rayon::iter::plumbing::Producer; +use rayon::{iter::plumbing::bridge, prelude::*}; + +/// A rayon parallel iterator over the colums of a matrix. It is created +/// using the [`par_column_iter`] method of [`Matrix`]. +/// +/// *Only available if compiled with the feature `rayon`.* +/// [`par_column_iter`]: crate::Matrix::par_column_iter +/// [`Matrix`]: crate::Matrix +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +pub struct ParColumnIter<'a, T, R: Dim, Cols: Dim, S: RawStorage> { + mat: &'a Matrix, +} + +impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> ParColumnIter<'a, T, R, Cols, S> { + /// Create a new parallel iterator for the given matrix. + fn new(matrix: &'a Matrix) -> Self { + Self { mat: matrix } + } +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> ParallelIterator + for ParColumnIter<'a, T, R, Cols, S> +where + T: Sync + Send + Scalar, + S: Sync, +{ + type Item = MatrixView<'a, T, R, U1, S::RStride, S::CStride>; + + fn drive_unindexed(self, consumer: Consumer) -> Consumer::Result + where + Consumer: rayon::iter::plumbing::UnindexedConsumer, + { + bridge(self, consumer) + } + + fn opt_len(&self) -> Option { + Some(self.mat.ncols()) + } +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// *Only available if compiled with the feature `rayon`.* +impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> IndexedParallelIterator + for ParColumnIter<'a, T, R, Cols, S> +where + T: Send + Sync + Scalar, + S: Sync, +{ + fn len(&self) -> usize { + self.mat.ncols() + } + + fn drive>(self, consumer: C) -> C::Result { + bridge(self, consumer) + } + + fn with_producer>( + self, + callback: CB, + ) -> CB::Output { + let producer = ColumnProducer(ColumnIter::new(self.mat)); + callback.callback(producer) + } +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// A rayon parallel iterator through the mutable columns of a matrix. +/// *Only available if compiled with the feature `rayon`.* +pub struct ParColumnIterMut< + 'a, + T, + R: Dim, + Cols: Dim, + S: RawStorage + RawStorageMut, +> { + mat: &'a mut Matrix, +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// *only availabe if compiled with the feature `rayon`* +impl<'a, T, R, Cols, S> ParColumnIterMut<'a, T, R, Cols, S> +where + R: Dim, + Cols: Dim, + S: RawStorage + RawStorageMut, +{ + /// create a new parallel iterator for the given matrix. + fn new(mat: &'a mut Matrix) -> Self { + Self { mat } + } +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// *Only available if compiled with the feature `rayon`* +impl<'a, T, R, Cols, S> ParallelIterator for ParColumnIterMut<'a, T, R, Cols, S> +where + R: Dim, + Cols: Dim, + S: RawStorage + RawStorageMut, + T: Send + Sync + Scalar, + S: Send + Sync, +{ + type Item = MatrixViewMut<'a, T, R, U1, S::RStride, S::CStride>; + fn drive_unindexed(self, consumer: C) -> C::Result + where + C: rayon::iter::plumbing::UnindexedConsumer, + { + bridge(self, consumer) + } + + fn opt_len(&self) -> Option { + Some(self.mat.ncols()) + } +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// *Only available if compiled with the feature `rayon`* +impl<'a, T, R, Cols, S> IndexedParallelIterator for ParColumnIterMut<'a, T, R, Cols, S> +where + R: Dim, + Cols: Dim, + S: RawStorage + RawStorageMut, + T: Send + Sync + Scalar, + S: Send + Sync, +{ + fn drive>(self, consumer: C) -> C::Result { + bridge(self, consumer) + } + + fn len(&self) -> usize { + self.mat.ncols() + } + + fn with_producer>( + self, + callback: CB, + ) -> CB::Output { + let producer = ColumnProducerMut(ColumnIterMut::new(self.mat)); + callback.callback(producer) + } +} + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// # Parallel iterators using `rayon` +/// *Only available if compiled with the feature `rayon`* +impl> Matrix +where + T: Send + Sync + Scalar, + S: Sync, +{ + /// Iterate through the columns of the matrix in parallel using rayon. + /// This iterates over *immutable* references ot the columns of the matrix, + /// if *mutable* access to the columns is required, use [`par_column_iter_mut`] + /// instead. + /// + /// # Example + /// Using parallel column iterators to calculate the sum of the maximum + /// elements in each column: + /// ``` + /// use nalgebra::{dmatrix, DMatrix}; + /// use rayon::prelude::*; + /// + /// let matrix : DMatrix = dmatrix![1.0, 0.0, 5.0; + /// 2.0, 4.0, 1.0; + /// 3.0, 2.0, 2.0; + /// ]; + /// let sum_of_max :f64 = matrix + /// .par_column_iter() + /// .map(|col| col.max()) + /// .sum(); + /// + /// assert_eq!(sum_of_max,3.0 + 4.0 + 5.0); + /// + /// ``` + /// + /// [`par_column_iter_mut`]: crate::Matrix::par_column_iter_mut + pub fn par_column_iter(&self) -> ParColumnIter<'_, T, R, Cols, S> { + ParColumnIter::new(self) + } + + /// Mutably iterate through the columns of this matrix in parallel using rayon. + /// Allows mutable access to the columns in parallel using mutable references. + /// If mutable access to the columns is not required rather use [`par_column_iter`] + /// instead. + /// + /// # Example + /// Normalize each column of a matrix with respect to its own maximum value. + /// + /// ``` + /// use nalgebra::{dmatrix, DMatrix}; + /// use rayon::prelude::*; + /// + /// let mut matrix : DMatrix = dmatrix![ + /// 2.0, 4.0, 6.0; + /// 1.0, 2.0, 3.0; + /// ]; + /// matrix.par_column_iter_mut().for_each(|mut col| col /= col.max()); + /// + /// assert_eq!(matrix, dmatrix![1.0, 1.0, 1.0; 0.5, 0.5, 0.5]); + /// ``` + /// + /// [`par_column_iter`]: crate::Matrix::par_column_iter + pub fn par_column_iter_mut(&mut self) -> ParColumnIterMut<'_, T, R, Cols, S> + where + S: RawStorageMut, + { + ParColumnIterMut::new(self) + } +} + +/// A private helper newtype that wraps the `ColumnIter` and implements +/// the rayon `Producer` trait. It's just here so we don't have to make the +/// rayon trait part of the public interface of the `ColumnIter`. +struct ColumnProducer<'a, T, R: Dim, C: Dim, S: RawStorage>(ColumnIter<'a, T, R, C, S>); + +#[cfg_attr(doc_cfg, doc(cfg(feature = "rayon")))] +/// *only available if compiled with the feature `rayon`* +impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> Producer + for ColumnProducer<'a, T, R, Cols, S> +where + T: Send + Sync + Scalar, + S: Sync, +{ + type Item = MatrixView<'a, T, R, U1, S::RStride, S::CStride>; + type IntoIter = ColumnIter<'a, T, R, Cols, S>; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.0 + } + + #[inline] + fn split_at(self, index: usize) -> (Self, Self) { + // The index is relative to the size of this current iterator. + // It will always start at zero so it serves as an offset. + let (left_iter, right_iter) = self.0.split_at(index); + (Self(left_iter), Self(right_iter)) + } +} + +/// See `ColumnProducer`. A private wrapper newtype that keeps the Producer +/// implementation private +struct ColumnProducerMut<'a, T, R: Dim, C: Dim, S: RawStorageMut>( + ColumnIterMut<'a, T, R, C, S>, +); + +impl<'a, T, R: Dim, C: Dim, S: 'a + RawStorageMut> Producer + for ColumnProducerMut<'a, T, R, C, S> +where + T: Send + Sync + Scalar, + S: Send + Sync, +{ + type Item = MatrixViewMut<'a, T, R, U1, S::RStride, S::CStride>; + type IntoIter = ColumnIterMut<'a, T, R, C, S>; + + fn into_iter(self) -> Self::IntoIter { + self.0 + } + + fn split_at(self, index: usize) -> (Self, Self) { + // The index is relative to the size of this current iterator + // it will always start at zero so it serves as an offset. + let (left_iter, right_iter) = self.0.split_at(index); + (Self(left_iter), Self(right_iter)) + } +} + +/// this implementation is safe because we are enforcing exclusive access +/// to the columns through the active range of the iterator +unsafe impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + RawStorageMut> Send + for ColumnIterMut<'a, T, R, C, S> +{ +} diff --git a/src/base/rkyv_wrappers.rs b/src/base/rkyv_wrappers.rs new file mode 100644 index 00000000..ce178674 --- /dev/null +++ b/src/base/rkyv_wrappers.rs @@ -0,0 +1,46 @@ +//! Wrapper that allows changing the generic type of a PhantomData +//! +//! Copied from https://github.com/rkyv/rkyv_contrib (MIT-Apache2 licences) which isn’t published yet. + +use rkyv::{ + with::{ArchiveWith, DeserializeWith, SerializeWith}, + Fallible, +}; +use std::marker::PhantomData; + +/// A wrapper that allows for changing the generic type of a PhantomData. +pub struct CustomPhantom { + _data: PhantomData<*const NT>, +} + +impl ArchiveWith> for CustomPhantom { + type Archived = PhantomData; + type Resolver = (); + + #[inline] + unsafe fn resolve_with( + _: &PhantomData, + _: usize, + _: Self::Resolver, + _: *mut Self::Archived, + ) { + } +} + +impl SerializeWith, S> + for CustomPhantom +{ + #[inline] + fn serialize_with(_: &PhantomData, _: &mut S) -> Result { + Ok(()) + } +} + +impl + DeserializeWith, PhantomData, D> for CustomPhantom +{ + #[inline] + fn deserialize_with(_: &PhantomData, _: &mut D) -> Result, D::Error> { + Ok(PhantomData) + } +} diff --git a/src/base/statistics.rs b/src/base/statistics.rs index 320cd12f..9f0e0ee6 100644 --- a/src/base/statistics.rs +++ b/src/base/statistics.rs @@ -1,6 +1,6 @@ use crate::allocator::Allocator; use crate::storage::RawStorage; -use crate::{Const, DefaultAllocator, Dim, Matrix, OVector, RowOVector, Scalar, VectorSlice, U1}; +use crate::{Const, DefaultAllocator, Dim, Matrix, OVector, RowOVector, Scalar, VectorView, U1}; use num::{One, Zero}; use simba::scalar::{ClosedAdd, ClosedMul, Field, SupersetOf}; use std::mem::MaybeUninit; @@ -13,7 +13,7 @@ impl> Matrix { #[must_use] pub fn compress_rows( &self, - f: impl Fn(VectorSlice<'_, T, R, S::RStride, S::CStride>) -> T, + f: impl Fn(VectorView<'_, T, R, S::RStride, S::CStride>) -> T, ) -> RowOVector where DefaultAllocator: Allocator, @@ -41,7 +41,7 @@ impl> Matrix { #[must_use] pub fn compress_rows_tr( &self, - f: impl Fn(VectorSlice<'_, T, R, S::RStride, S::CStride>) -> T, + f: impl Fn(VectorView<'_, T, R, S::RStride, S::CStride>) -> T, ) -> OVector where DefaultAllocator: Allocator, @@ -67,7 +67,7 @@ impl> Matrix { pub fn compress_columns( &self, init: OVector, - f: impl Fn(&mut OVector, VectorSlice<'_, T, R, S::RStride, S::CStride>), + f: impl Fn(&mut OVector, VectorView<'_, T, R, S::RStride, S::CStride>), ) -> OVector where DefaultAllocator: Allocator, diff --git a/src/base/storage.rs b/src/base/storage.rs index 76a60ce3..dd335014 100644 --- a/src/base/storage.rs +++ b/src/base/storage.rs @@ -122,7 +122,7 @@ pub unsafe trait RawStorage: Sized { /// # Safety /// The matrix components may not be stored in a contiguous way, depending on the strides. /// This method is unsafe because this can yield to invalid aliasing when called on some pairs - /// of matrix slices originating from the same matrix with strides. + /// of matrix views originating from the same matrix with strides. /// /// Call the safe alternative `matrix.as_slice()` instead. unsafe fn as_slice_unchecked(&self) -> &[T]; @@ -148,7 +148,7 @@ pub unsafe trait Storage: RawStorage { /// contains `MaybeUninit` elements. /// /// Note that a mutable access does not mean that the matrix owns its data. For example, a mutable -/// matrix slice can provide mutable access to its elements even if it does not own its data (it +/// matrix view can provide mutable access to its elements even if it does not own its data (it /// contains only an internal reference to them). pub unsafe trait RawStorageMut: RawStorage { /// The matrix mutable data pointer. diff --git a/src/base/unit.rs b/src/base/unit.rs index 6fc00092..2fc51107 100644 --- a/src/base/unit.rs +++ b/src/base/unit.rs @@ -21,11 +21,17 @@ use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealF /// in their documentation, read their dedicated pages directly. #[repr(transparent)] #[derive(Clone, Hash, Copy)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Unit", + bound(archive = " + T: rkyv::Archive, + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] // #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Unit { pub(crate) value: T, diff --git a/src/base/vec_storage.rs b/src/base/vec_storage.rs index 414354cd..4614598b 100644 --- a/src/base/vec_storage.rs +++ b/src/base/vec_storage.rs @@ -4,7 +4,7 @@ use alloc::vec::Vec; use crate::base::allocator::Allocator; use crate::base::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::base::default_allocator::DefaultAllocator; -use crate::base::dimension::{Dim, DimName, Dynamic, U1}; +use crate::base::dimension::{Dim, DimName, Dyn, U1}; use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, ReshapableStorage}; use crate::base::{Scalar, Vector}; @@ -188,13 +188,13 @@ impl From> for Vec { /* * - * Dynamic − Static - * Dynamic − Dynamic + * Dyn − Static + * Dyn − Dyn * */ -unsafe impl RawStorage for VecStorage { +unsafe impl RawStorage for VecStorage { type RStride = U1; - type CStride = Dynamic; + type CStride = Dyn; #[inline] fn ptr(&self) -> *const T { @@ -202,7 +202,7 @@ unsafe impl RawStorage for VecStorage { } #[inline] - fn shape(&self) -> (Dynamic, C) { + fn shape(&self) -> (Dyn, C) { (self.nrows, self.ncols) } @@ -222,28 +222,28 @@ unsafe impl RawStorage for VecStorage { } } -unsafe impl Storage for VecStorage +unsafe impl Storage for VecStorage where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { #[inline] - fn into_owned(self) -> Owned + fn into_owned(self) -> Owned where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { self } #[inline] - fn clone_owned(&self) -> Owned + fn clone_owned(&self) -> Owned where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { self.clone() } } -unsafe impl RawStorage for VecStorage { +unsafe impl RawStorage for VecStorage { type RStride = U1; type CStride = R; @@ -253,7 +253,7 @@ unsafe impl RawStorage for VecStorage (R, Dynamic) { + fn shape(&self) -> (R, Dyn) { (self.nrows, self.ncols) } @@ -273,22 +273,22 @@ unsafe impl RawStorage for VecStorage Storage for VecStorage +unsafe impl Storage for VecStorage where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { #[inline] - fn into_owned(self) -> Owned + fn into_owned(self) -> Owned where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { self } #[inline] - fn clone_owned(&self) -> Owned + fn clone_owned(&self) -> Owned where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { self.clone() } @@ -299,7 +299,7 @@ where * RawStorageMut, ContiguousStorage. * */ -unsafe impl RawStorageMut for VecStorage { +unsafe impl RawStorageMut for VecStorage { #[inline] fn ptr_mut(&mut self) -> *mut T { self.data.as_mut_ptr() @@ -313,15 +313,15 @@ unsafe impl RawStorageMut for VecStorage IsContiguous for VecStorage {} -impl ReshapableStorage for VecStorage +impl ReshapableStorage for VecStorage where T: Scalar, C1: Dim, C2: Dim, { - type Output = VecStorage; + type Output = VecStorage; - fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { + fn reshape_generic(self, nrows: Dyn, ncols: C2) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, @@ -331,15 +331,15 @@ where } } -impl ReshapableStorage for VecStorage +impl ReshapableStorage for VecStorage where T: Scalar, C1: Dim, R2: DimName, { - type Output = VecStorage; + type Output = VecStorage; - fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { + fn reshape_generic(self, nrows: R2, ncols: Dyn) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, @@ -349,7 +349,7 @@ where } } -unsafe impl RawStorageMut for VecStorage { +unsafe impl RawStorageMut for VecStorage { #[inline] fn ptr_mut(&mut self) -> *mut T { self.data.as_mut_ptr() @@ -361,15 +361,15 @@ unsafe impl RawStorageMut for VecStorage ReshapableStorage for VecStorage +impl ReshapableStorage for VecStorage where T: Scalar, R1: DimName, C2: Dim, { - type Output = VecStorage; + type Output = VecStorage; - fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { + fn reshape_generic(self, nrows: Dyn, ncols: C2) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, @@ -379,15 +379,15 @@ where } } -impl ReshapableStorage for VecStorage +impl ReshapableStorage for VecStorage where T: Scalar, R1: DimName, R2: DimName, { - type Output = VecStorage; + type Output = VecStorage; - fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { + fn reshape_generic(self, nrows: R2, ncols: Dyn) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, @@ -397,7 +397,7 @@ where } } -impl Extend for VecStorage { +impl Extend for VecStorage { /// Extends the number of columns of the `VecStorage` with elements /// from the given iterator. /// @@ -407,13 +407,13 @@ impl Extend for VecStorage { /// `VecStorage`. fn extend>(&mut self, iter: I) { self.data.extend(iter); - self.ncols = Dynamic::new(self.data.len() / self.nrows.value()); + self.ncols = Dyn(self.data.len() / self.nrows.value()); assert!(self.data.len() % self.nrows.value() == 0, "The number of elements produced by the given iterator was not a multiple of the number of rows."); } } -impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage { +impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage { /// Extends the number of columns of the `VecStorage` with elements /// from the given iterator. /// @@ -426,7 +426,7 @@ impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage { } } -impl Extend> for VecStorage +impl Extend> for VecStorage where T: Scalar, R: Dim, @@ -450,15 +450,15 @@ where assert_eq!(nrows, vector.shape().0); self.data.extend(vector.iter().cloned()); } - self.ncols = Dynamic::new(self.data.len() / nrows); + self.ncols = Dyn(self.data.len() / nrows); } } -impl Extend for VecStorage { +impl Extend for VecStorage { /// Extends the number of rows of the `VecStorage` with elements /// from the given iterator. fn extend>(&mut self, iter: I) { self.data.extend(iter); - self.nrows = Dynamic::new(self.data.len()); + self.nrows = Dyn(self.data.len()); } } diff --git a/src/debug/random_orthogonal.rs b/src/debug/random_orthogonal.rs index c9684238..18924fb2 100644 --- a/src/debug/random_orthogonal.rs +++ b/src/debug/random_orthogonal.rs @@ -4,7 +4,7 @@ use crate::base::storage::Owned; use quickcheck::{Arbitrary, Gen}; use crate::base::allocator::Allocator; -use crate::base::dimension::{Dim, Dynamic}; +use crate::base::dimension::{Dim, Dyn}; use crate::base::Scalar; use crate::base::{DefaultAllocator, OMatrix}; use crate::linalg::givens::GivensRotation; @@ -12,7 +12,7 @@ use simba::scalar::ComplexField; /// A random orthogonal matrix. #[derive(Clone, Debug)] -pub struct RandomOrthogonal +pub struct RandomOrthogonal where DefaultAllocator: Allocator, { diff --git a/src/debug/random_sdp.rs b/src/debug/random_sdp.rs index a915f2fc..278071a8 100644 --- a/src/debug/random_sdp.rs +++ b/src/debug/random_sdp.rs @@ -4,7 +4,7 @@ use crate::base::storage::Owned; use quickcheck::{Arbitrary, Gen}; use crate::base::allocator::Allocator; -use crate::base::dimension::{Dim, Dynamic}; +use crate::base::dimension::{Dim, Dyn}; use crate::base::Scalar; use crate::base::{DefaultAllocator, OMatrix}; use simba::scalar::ComplexField; @@ -13,7 +13,7 @@ use crate::debug::RandomOrthogonal; /// A random, well-conditioned, symmetric definite-positive matrix. #[derive(Clone, Debug)] -pub struct RandomSDP +pub struct RandomSDP where DefaultAllocator: Allocator, { diff --git a/src/geometry/dual_quaternion.rs b/src/geometry/dual_quaternion.rs index 6f1b7053..bae04f46 100644 --- a/src/geometry/dual_quaternion.rs +++ b/src/geometry/dual_quaternion.rs @@ -40,11 +40,18 @@ use simba::scalar::{ClosedNeg, RealField}; /// See #[repr(C)] #[derive(Debug, Copy, Clone)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "DualQuaternion", + bound(archive = " + T: rkyv::Archive, + Quaternion: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct DualQuaternion { /// The real component of the quaternion diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs index 92169742..e3f44075 100755 --- a/src/geometry/isometry.rs +++ b/src/geometry/isometry.rs @@ -21,6 +21,7 @@ use crate::geometry::{AbstractRotation, Point, Translation}; /// A 2D isometry is composed of: /// - A translation part of type [`Translation2`](crate::Translation2) /// - A rotation part which can either be a [`UnitComplex`](crate::UnitComplex) or a [`Rotation2`](crate::Rotation2). +/// /// A 3D isometry is composed of: /// - A translation part of type [`Translation3`](crate::Translation3) /// - A rotation part which can either be a [`UnitQuaternion`](crate::UnitQuaternion) or a [`Rotation3`](crate::Rotation3). @@ -66,11 +67,19 @@ use crate::geometry::{AbstractRotation, Point, Translation}; Owned>: Deserialize<'de>, T: Scalar")) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Isometry", + bound(archive = " + T: rkyv::Archive, + R: rkyv::Archive, + Translation: rkyv::Archive> + ") + ) )] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] pub struct Isometry { /// The pure rotational part of this isometry. pub rotation: R, @@ -425,7 +434,7 @@ impl Isometry { DefaultAllocator: Allocator, U1>, DimNameSum, U1>>, { let mut res: OMatrix = crate::convert_ref(&self.rotation); - res.fixed_slice_mut::(0, D) + res.fixed_view_mut::(0, D) .copy_from(&self.translation.vector); res diff --git a/src/geometry/isometry_conversion.rs b/src/geometry/isometry_conversion.rs index 627ea3ee..06507631 100644 --- a/src/geometry/isometry_conversion.rs +++ b/src/geometry/isometry_conversion.rs @@ -153,8 +153,8 @@ where #[inline] fn is_in_subset(m: &OMatrix, U1>, DimNameSum, U1>>) -> bool { - let rot = m.fixed_slice::(0, 0); - let bottom = m.fixed_slice::<1, D>(D, 0); + let rot = m.fixed_view::(0, 0); + let bottom = m.fixed_view::<1, D>(D, 0); // Scalar types agree. m.iter().all(|e| SupersetOf::::is_in_subset(e)) && @@ -168,7 +168,7 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let t = m.fixed_slice::(0, D).into_owned(); + let t = m.fixed_view::(0, D).into_owned(); let t = Translation { vector: crate::convert_unchecked(t), }; diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs index 7348f676..06d0b471 100644 --- a/src/geometry/orthographic.rs +++ b/src/geometry/orthographic.rs @@ -19,11 +19,18 @@ use crate::geometry::{Point3, Projective3}; /// A 3D orthographic projection stored as a homogeneous 4x4 matrix. #[repr(C)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Orthographic3", + bound(archive = " + T: rkyv::Archive, + Matrix4: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Orthographic3 { diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs index 351960bb..a5fc19a8 100644 --- a/src/geometry/perspective.rs +++ b/src/geometry/perspective.rs @@ -20,11 +20,18 @@ use crate::geometry::{Point3, Projective3}; /// A 3D perspective projection stored as a homogeneous 4x4 matrix. #[repr(C)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Perspective3", + bound(archive = " + T: rkyv::Archive, + Matrix4: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Perspective3 { diff --git a/src/geometry/point.rs b/src/geometry/point.rs index 306c18e5..71ace3a9 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -36,11 +36,20 @@ use std::mem::MaybeUninit; /// of said transformations for details. #[repr(C)] #[derive(Clone)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "OPoint", + bound(archive = " + T: rkyv::Archive, + T::Archived: Scalar, + OVector: rkyv::Archive>, + DefaultAllocator: Allocator, + ") + ) )] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] pub struct OPoint where DefaultAllocator: Allocator, @@ -204,7 +213,7 @@ where let mut res = crate::Matrix::uninit(DimNameSum::::name(), Const::<1>); // This is basically a copy_from except that we warp the copied // values into MaybeUninit. - res.generic_slice_mut((0, 0), self.coords.shape_generic()) + res.generic_view_mut((0, 0), self.coords.shape_generic()) .zip_apply(&self.coords, |out, e| *out = MaybeUninit::new(e)); res[(len, 0)] = MaybeUninit::new(T::one()); diff --git a/src/geometry/point_construction.rs b/src/geometry/point_construction.rs index 598cf4ed..04228cd2 100644 --- a/src/geometry/point_construction.rs +++ b/src/geometry/point_construction.rs @@ -113,7 +113,7 @@ where DefaultAllocator: Allocator>, { if !v[D::dim()].is_zero() { - let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone(); + let coords = v.generic_view((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone(); Some(Self::from(coords)) } else { None diff --git a/src/geometry/point_conversion.rs b/src/geometry/point_conversion.rs index ce1bd930..81870379 100644 --- a/src/geometry/point_conversion.rs +++ b/src/geometry/point_conversion.rs @@ -66,7 +66,7 @@ where #[inline] fn from_superset_unchecked(v: &OVector>) -> Self { - let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone(); + let coords = v.generic_view((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone(); Self { coords: crate::convert_unchecked(coords), } diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index f38dca6f..1b251b29 100755 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -14,7 +14,7 @@ use simba::simd::{SimdBool, SimdOption, SimdRealField}; use crate::base::dimension::{U1, U3, U4}; use crate::base::storage::{CStride, RStride}; use crate::base::{ - Matrix3, Matrix4, MatrixSlice, MatrixSliceMut, Normed, Scalar, Unit, Vector3, Vector4, + Matrix3, Matrix4, MatrixView, MatrixViewMut, Normed, Scalar, Unit, Vector3, Vector4, }; use crate::geometry::{Point3, Rotation}; @@ -23,11 +23,18 @@ use crate::geometry::{Point3, Rotation}; /// that may be used as a rotation. #[repr(C)] #[derive(Copy, Clone)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Quaternion", + bound(archive = " + T: rkyv::Archive, + Vector4: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Quaternion { /// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order. @@ -188,7 +195,7 @@ where /// ``` #[inline] #[must_use] - pub fn vector(&self) -> MatrixSlice<'_, T, U3, U1, RStride, CStride> { + pub fn vector(&self) -> MatrixView<'_, T, U3, U1, RStride, CStride> { self.coords.fixed_rows::<3>(0) } @@ -581,7 +588,7 @@ where #[inline] pub fn vector_mut( &mut self, - ) -> MatrixSliceMut<'_, T, U3, U1, RStride, CStride> { + ) -> MatrixViewMut<'_, T, U3, U1, RStride, CStride> { self.coords.fixed_rows_mut::<3>(0) } @@ -1320,7 +1327,7 @@ where } } - /// The rotation axis and angle in ]0, pi] of this unit quaternion. + /// The rotation axis and angle in (0, pi] of this unit quaternion. /// /// Returns `None` if the angle is zero. /// diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs index 2a8bf427..5eceec21 100755 --- a/src/geometry/rotation.rs +++ b/src/geometry/rotation.rs @@ -49,11 +49,18 @@ use crate::geometry::Point; /// * [Conversion to a matrix `matrix`, `to_homogeneous`…](#conversion-to-a-matrix) /// #[repr(C)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Rotation", + bound(archive = " + T: rkyv::Archive, + SMatrix: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Rotation { @@ -258,7 +265,7 @@ impl Rotation { // adding the additional traits `DimAdd` and `IsNotStaticOne`. Maybe // these things will get nicer once specialization lands in Rust. let mut res = OMatrix::, U1>, DimNameSum, U1>>::identity(); - res.fixed_slice_mut::(0, 0).copy_from(&self.matrix); + res.fixed_view_mut::(0, 0).copy_from(&self.matrix); res } diff --git a/src/geometry/rotation_conversion.rs b/src/geometry/rotation_conversion.rs index 517010a0..c37b5cdd 100644 --- a/src/geometry/rotation_conversion.rs +++ b/src/geometry/rotation_conversion.rs @@ -211,8 +211,8 @@ where #[inline] fn is_in_subset(m: &OMatrix, U1>, DimNameSum, U1>>) -> bool { - let rot = m.fixed_slice::(0, 0); - let bottom = m.fixed_slice::<1, D>(D, 0); + let rot = m.fixed_view::(0, 0); + let bottom = m.fixed_view::<1, D>(D, 0); // Scalar types agree. m.iter().all(|e| SupersetOf::::is_in_subset(e)) && @@ -226,7 +226,7 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let r = m.fixed_slice::(0, 0); + let r = m.fixed_view::(0, 0); Self::from_matrix_unchecked(crate::convert_unchecked(r.into_owned())) } } diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs index c9197fd6..1ea5cd92 100644 --- a/src/geometry/rotation_specialization.rs +++ b/src/geometry/rotation_specialization.rs @@ -877,7 +877,7 @@ impl Rotation3 { } } - /// The rotation axis and angle in ]0, pi] of this rotation matrix. + /// The rotation axis and angle in (0, pi] of this rotation matrix. /// /// Returns `None` if the angle is zero. /// @@ -956,13 +956,15 @@ impl Rotation3 { { // Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh // https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578 + // where roll, pitch, yaw angles are referred to as ψ, θ, ϕ, if self[(2, 0)].clone().abs() < T::one() { - let yaw = -self[(2, 0)].clone().asin(); - let roll = (self[(2, 1)].clone() / yaw.clone().cos()) - .atan2(self[(2, 2)].clone() / yaw.clone().cos()); - let pitch = (self[(1, 0)].clone() / yaw.clone().cos()) - .atan2(self[(0, 0)].clone() / yaw.clone().cos()); - (roll, yaw, pitch) + let pitch = -self[(2, 0)].clone().asin(); + let theta_cos = pitch.clone().cos(); + let roll = (self[(2, 1)].clone() / theta_cos.clone()) + .atan2(self[(2, 2)].clone() / theta_cos.clone()); + let yaw = + (self[(1, 0)].clone() / theta_cos.clone()).atan2(self[(0, 0)].clone() / theta_cos); + (roll, pitch, yaw) } else if self[(2, 0)].clone() <= -T::one() { ( self[(0, 1)].clone().atan2(self[(0, 2)].clone()), diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 37da1ef0..36a68066 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -17,11 +17,18 @@ use crate::geometry::Point; /// A scale which supports non-uniform scaling. #[repr(C)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Scale", + bound(archive = " + T: rkyv::Archive, + SVector: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Scale { diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 2dc670a1..2d807e3a 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -102,7 +102,7 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let v = m.fixed_slice::(0, 0).diagonal(); + let v = m.fixed_view::(0, 0).diagonal(); Self { vector: crate::convert_unchecked(v), } diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index 8c38ff1e..989b721b 100755 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -34,11 +34,19 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; DefaultAllocator: Allocator>, Owned>: Deserialize<'de>")) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Similarity", + bound(archive = " + T: rkyv::Archive, + R: rkyv::Archive, + Isometry: rkyv::Archive> + ") + ) )] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] pub struct Similarity { /// The part of this similarity that does not include the scaling factor. pub isometry: Isometry, @@ -301,7 +309,7 @@ impl Similarity { { let mut res = self.isometry.to_homogeneous(); - for e in res.fixed_slice_mut::(0, 0).iter_mut() { + for e in res.fixed_view_mut::(0, 0).iter_mut() { *e *= self.scaling.clone() } diff --git a/src/geometry/similarity_conversion.rs b/src/geometry/similarity_conversion.rs index 6bc12814..e5d28906 100644 --- a/src/geometry/similarity_conversion.rs +++ b/src/geometry/similarity_conversion.rs @@ -106,7 +106,7 @@ where #[inline] fn is_in_subset(m: &OMatrix, U1>, DimNameSum, U1>>) -> bool { - let mut rot = m.fixed_slice::(0, 0).clone_owned(); + let mut rot = m.fixed_view::(0, 0).clone_owned(); if rot .fixed_columns_mut::<1>(0) .try_normalize_mut(T2::zero()) @@ -128,7 +128,7 @@ where rot.fixed_columns_mut::<1>(2).neg_mut(); } - let bottom = m.fixed_slice::<1, D>(D, 0); + let bottom = m.fixed_view::<1, D>(D, 0); // Scalar types agree. m.iter().all(|e| SupersetOf::::is_in_subset(e)) && // The normalized block part is a rotation. @@ -145,22 +145,22 @@ where m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { let mut mm = m.clone_owned(); - let na = mm.fixed_slice_mut::(0, 0).normalize_mut(); - let nb = mm.fixed_slice_mut::(0, 1).normalize_mut(); - let nc = mm.fixed_slice_mut::(0, 2).normalize_mut(); + let na = mm.fixed_view_mut::(0, 0).normalize_mut(); + let nb = mm.fixed_view_mut::(0, 1).normalize_mut(); + let nc = mm.fixed_view_mut::(0, 2).normalize_mut(); let mut scale = (na + nb + nc) / crate::convert(3.0); // We take the mean, for robustness. // TODO: could we avoid the explicit computation of the determinant? // (its sign is needed to see if the scaling factor is negative). - if mm.fixed_slice::(0, 0).determinant() < T2::zero() { - mm.fixed_slice_mut::(0, 0).neg_mut(); - mm.fixed_slice_mut::(0, 1).neg_mut(); - mm.fixed_slice_mut::(0, 2).neg_mut(); + if mm.fixed_view::(0, 0).determinant() < T2::zero() { + mm.fixed_view_mut::(0, 0).neg_mut(); + mm.fixed_view_mut::(0, 1).neg_mut(); + mm.fixed_view_mut::(0, 2).neg_mut(); scale = -scale; } - let t = m.fixed_slice::(0, D).into_owned(); + let t = m.fixed_view::(0, D).into_owned(); let t = Translation { vector: crate::convert_unchecked(t), }; diff --git a/src/geometry/transform_ops.rs b/src/geometry/transform_ops.rs index 8a500676..4c6284d0 100644 --- a/src/geometry/transform_ops.rs +++ b/src/geometry/transform_ops.rs @@ -120,10 +120,10 @@ md_impl_all!( [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => { - let transform = self.matrix().fixed_slice::(0, 0); + let transform = self.matrix().fixed_view::(0, 0); if C::has_normalizer() { - let normalizer = self.matrix().fixed_slice::<1, D>(D, 0); + let normalizer = self.matrix().fixed_view::<1, D>(D, 0); let n = normalizer.tr_dot(rhs); if !n.is_zero() { @@ -148,11 +148,11 @@ md_impl_all!( [ref val] => self * &rhs; [val ref] => &self * rhs; [ref ref] => { - let transform = self.matrix().fixed_slice::(0, 0); - let translation = self.matrix().fixed_slice::(0, D); + let transform = self.matrix().fixed_view::(0, 0); + let translation = self.matrix().fixed_view::(0, D); if C::has_normalizer() { - let normalizer = self.matrix().fixed_slice::<1, D>(D, 0); + let normalizer = self.matrix().fixed_view::<1, D>(D, 0); #[allow(clippy::suspicious_arithmetic_impl)] let n = normalizer.tr_dot(&rhs.coords) + unsafe { self.matrix().get_unchecked((D, D)).clone() }; diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs index bef66f68..39fae3b6 100755 --- a/src/geometry/translation.rs +++ b/src/geometry/translation.rs @@ -17,11 +17,18 @@ use crate::geometry::Point; /// A translation. #[repr(C)] -#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr( feature = "rkyv-serialize-no-std", - derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), + archive( + as = "Translation", + bound(archive = " + T: rkyv::Archive, + SVector: rkyv::Archive> + ") + ) )] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Translation { @@ -147,7 +154,7 @@ impl Translation { DefaultAllocator: Allocator, U1>, DimNameSum, U1>>, { let mut res = OMatrix::, U1>, DimNameSum, U1>>::identity(); - res.fixed_slice_mut::(0, D).copy_from(&self.vector); + res.fixed_view_mut::(0, D).copy_from(&self.vector); res } diff --git a/src/geometry/translation_conversion.rs b/src/geometry/translation_conversion.rs index 70000efb..73646780 100644 --- a/src/geometry/translation_conversion.rs +++ b/src/geometry/translation_conversion.rs @@ -159,7 +159,7 @@ where #[inline] fn is_in_subset(m: &OMatrix, U1>, DimNameSum, U1>>) -> bool { - let id = m.generic_slice((0, 0), (DimNameSum::, U1>::name(), Const::)); + let id = m.generic_view((0, 0), (DimNameSum::, U1>::name(), Const::)); // Scalar types agree. m.iter().all(|e| SupersetOf::::is_in_subset(e)) && @@ -173,7 +173,7 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let t = m.fixed_slice::(0, D); + let t = m.fixed_view::(0, D); Self { vector: crate::convert_unchecked(t.into_owned()), } diff --git a/src/geometry/unit_complex.rs b/src/geometry/unit_complex.rs index efe0dac2..8e44f71a 100755 --- a/src/geometry/unit_complex.rs +++ b/src/geometry/unit_complex.rs @@ -132,7 +132,7 @@ where Vector1::new(self.angle()) } - /// The rotation axis and angle in ]0, pi] of this complex number. + /// The rotation axis and angle in (0, pi] of this complex number. /// /// This is generally used in the context of generic programming. Using /// the `.angle()` method instead is more common. diff --git a/src/lib.rs b/src/lib.rs index 86a5dc6b..93f05ff5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,20 +83,31 @@ an optimized set of tools for computer graphics and physics. Those features incl unused_variables, unused_mut, unused_parens, - unused_qualifications, rust_2018_idioms, rust_2018_compatibility, future_incompatible, missing_copy_implementations )] -#![cfg_attr(feature = "rkyv-serialize-no-std", warn(unused_results))] // TODO: deny this once bytecheck stops generating warnings. -#![cfg_attr(not(feature = "rkyv-serialize-no-std"), deny(unused_results))] +#![cfg_attr(not(feature = "rkyv-serialize-no-std"), deny(unused_results))] // TODO: deny this globally once bytecheck stops generating unused results. #![doc( html_favicon_url = "https://nalgebra.org/img/favicon.ico", html_root_url = "https://docs.rs/nalgebra/0.25.0" )] #![cfg_attr(not(feature = "std"), no_std)] +/// Generates an appropriate deprecation note with a suggestion for replacement. +/// +/// Used for deprecating slice types in various locations throughout the library. +/// See #1076 for more information. +macro_rules! slice_deprecation_note { + ($replacement:ident) => { + concat!("Use ", stringify!($replacement), + r###" instead. See [issue #1076](https://github.com/dimforge/nalgebra/issues/1076) for more information."###) + } +} + +pub(crate) use slice_deprecation_note; + #[cfg(feature = "rand-no-std")] extern crate rand_package as rand; diff --git a/src/linalg/bidiagonal.rs b/src/linalg/bidiagonal.rs index c6b02975..3036e9f1 100644 --- a/src/linalg/bidiagonal.rs +++ b/src/linalg/bidiagonal.rs @@ -202,7 +202,7 @@ where ); let start = self.axis_shift(); - res.slice_mut(start, (d.value() - 1, d.value() - 1)) + res.view_mut(start, (d.value() - 1, d.value() - 1)) .set_partial_diagonal( self.off_diagonal .iter() @@ -226,11 +226,11 @@ where let shift = self.axis_shift().0; for i in (0..dim - shift).rev() { - let axis = self.uv.slice_range(i + shift.., i); + let axis = self.uv.view_range(i + shift.., i); // TODO: sometimes, the axis might have a zero magnitude. let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); - let mut res_rows = res.slice_range_mut(i + shift.., i..); + let mut res_rows = res.view_range_mut(i + shift.., i..); let sign = if self.upper_diagonal { self.diagonal[i].clone().signum() @@ -260,13 +260,13 @@ where let shift = self.axis_shift().1; for i in (0..min_nrows_ncols.value() - shift).rev() { - let axis = self.uv.slice_range(i, i + shift..); + let axis = self.uv.view_range(i, i + shift..); let mut axis_packed = axis_packed.rows_range_mut(i + shift..); axis_packed.tr_copy_from(&axis); // TODO: sometimes, the axis might have a zero magnitude. let refl = Reflection::new(Unit::new_unchecked(axis_packed), T::zero()); - let mut res_rows = res.slice_range_mut(i.., i + shift..); + let mut res_rows = res.view_range_mut(i.., i + shift..); let sign = if self.upper_diagonal { self.off_diagonal[i].clone().signum() @@ -304,7 +304,7 @@ where } } -// impl + DimSub> Bidiagonal +// impl + DimSub> Bidiagonal // where DefaultAllocator: Allocator + // Allocator { // /// Solves the linear system `self * x = b`, where `x` is the unknown to be determined. @@ -346,7 +346,7 @@ where // *b.vget_unchecked_mut(i) = coeff; // } // -// b.rows_range_mut(.. i).axpy(-coeff, &self.uv.slice_range(.. i, i), T::one()); +// b.rows_range_mut(.. i).axpy(-coeff, &self.uv.view_range(.. i, i), T::one()); // } // } // } diff --git a/src/linalg/cholesky.rs b/src/linalg/cholesky.rs index f61a4e63..02101748 100644 --- a/src/linalg/cholesky.rs +++ b/src/linalg/cholesky.rs @@ -1,7 +1,7 @@ #[cfg(feature = "serde-serialize-no-std")] use serde::{Deserialize, Serialize}; -use num::One; +use num::{One, Zero}; use simba::scalar::ComplexField; use simba::simd::SimdComplexField; @@ -67,7 +67,7 @@ where *matrix.get_unchecked_mut((j, j)) = denom.clone(); } - let mut col = matrix.slice_range_mut(j + 1.., j); + let mut col = matrix.view_range_mut(j + 1.., j); col /= denom; } @@ -161,6 +161,27 @@ where } prod_diag.simd_modulus_squared() } + + /// Computes the natural logarithm of determinant of the decomposed matrix. + /// + /// This method is more robust than `.determinant()` to very small or very + /// large determinants since it returns the natural logarithm of the + /// determinant rather than the determinant itself. + #[must_use] + pub fn ln_determinant(&self) -> T::SimdRealField { + let dim = self.chol.nrows(); + let mut sum_diag = T::SimdRealField::zero(); + for i in 0..dim { + sum_diag += unsafe { + self.chol + .get_unchecked((i, i)) + .clone() + .simd_modulus_squared() + .simd_ln() + }; + } + sum_diag + } } impl Cholesky @@ -228,7 +249,7 @@ where *matrix.get_unchecked_mut((j, j)) = denom.clone(); } - let mut col = matrix.slice_range_mut(j + 1.., j); + let mut col = matrix.view_range_mut(j + 1.., j); col /= denom; continue; } @@ -283,17 +304,17 @@ where self.chol.shape_generic().0.add(Const::<1>), self.chol.shape_generic().1.add(Const::<1>), ); - chol.slice_range_mut(..j, ..j) - .copy_from(&self.chol.slice_range(..j, ..j)); - chol.slice_range_mut(..j, j + 1..) - .copy_from(&self.chol.slice_range(..j, j..)); - chol.slice_range_mut(j + 1.., ..j) - .copy_from(&self.chol.slice_range(j.., ..j)); - chol.slice_range_mut(j + 1.., j + 1..) - .copy_from(&self.chol.slice_range(j.., j..)); + chol.view_range_mut(..j, ..j) + .copy_from(&self.chol.view_range(..j, ..j)); + chol.view_range_mut(..j, j + 1..) + .copy_from(&self.chol.view_range(..j, j..)); + chol.view_range_mut(j + 1.., ..j) + .copy_from(&self.chol.view_range(j.., ..j)); + chol.view_range_mut(j + 1.., j + 1..) + .copy_from(&self.chol.view_range(j.., j..)); // update the jth row - let top_left_corner = self.chol.slice_range(..j, ..j); + let top_left_corner = self.chol.view_range(..j, ..j); let col_j = col[j].clone(); let (mut new_rowj_adjoint, mut new_colj) = col.rows_range_pair_mut(..j, j + 1..); @@ -302,14 +323,14 @@ where "Cholesky::insert_column : Unable to solve lower triangular system!" ); - new_rowj_adjoint.adjoint_to(&mut chol.slice_range_mut(j, ..j)); + new_rowj_adjoint.adjoint_to(&mut chol.view_range_mut(j, ..j)); // update the center element let center_element = T::sqrt(col_j - T::from_real(new_rowj_adjoint.norm_squared())); chol[(j, j)] = center_element.clone(); // update the jth column - let bottom_left_corner = self.chol.slice_range(j.., ..j); + let bottom_left_corner = self.chol.view_range(j.., ..j); // new_colj = (col_jplus - bottom_left_corner * new_rowj.adjoint()) / center_element; new_colj.gemm( -T::one() / center_element.clone(), @@ -317,10 +338,10 @@ where &new_rowj_adjoint, T::one() / center_element, ); - chol.slice_range_mut(j + 1.., j).copy_from(&new_colj); + chol.view_range_mut(j + 1.., j).copy_from(&new_colj); // update the bottom right corner - let mut bottom_right_corner = chol.slice_range_mut(j + 1.., j + 1..); + let mut bottom_right_corner = chol.view_range_mut(j + 1.., j + 1..); Self::xx_rank_one_update( &mut bottom_right_corner, &mut new_colj, @@ -348,17 +369,17 @@ where self.chol.shape_generic().0.sub(Const::<1>), self.chol.shape_generic().1.sub(Const::<1>), ); - chol.slice_range_mut(..j, ..j) - .copy_from(&self.chol.slice_range(..j, ..j)); - chol.slice_range_mut(..j, j..) - .copy_from(&self.chol.slice_range(..j, j + 1..)); - chol.slice_range_mut(j.., ..j) - .copy_from(&self.chol.slice_range(j + 1.., ..j)); - chol.slice_range_mut(j.., j..) - .copy_from(&self.chol.slice_range(j + 1.., j + 1..)); + chol.view_range_mut(..j, ..j) + .copy_from(&self.chol.view_range(..j, ..j)); + chol.view_range_mut(..j, j..) + .copy_from(&self.chol.view_range(..j, j + 1..)); + chol.view_range_mut(j.., ..j) + .copy_from(&self.chol.view_range(j + 1.., ..j)); + chol.view_range_mut(j.., j..) + .copy_from(&self.chol.view_range(j + 1.., j + 1..)); // updates the bottom right corner - let mut bottom_right_corner = chol.slice_range_mut(j.., j..); + let mut bottom_right_corner = chol.view_range_mut(j.., j..); let mut workspace = self.chol.column(j).clone_owned(); let mut old_colj = workspace.rows_range_mut(j + 1..); Self::xx_rank_one_update(&mut bottom_right_corner, &mut old_colj, T::RealField::one()); @@ -370,7 +391,7 @@ where /// performs a rank one update such that we end up with the decomposition of `M + sigma * (x * x.adjoint())`. /// /// This helper method is called by `rank_one_update` but also `insert_column` and `remove_column` - /// where it is used on a square slice of the decomposition + /// where it is used on a square view of the decomposition fn xx_rank_one_update( chol: &mut Matrix, x: &mut Vector, @@ -404,7 +425,7 @@ where beta += sigma_xj2 / diag2; // updates the terms of L let mut xjplus = x.rows_range_mut(j + 1..); - let mut col_j = chol.slice_range_mut(j + 1.., j); + let mut col_j = chol.view_range_mut(j + 1.., j); // temp_jplus -= (wj / T::from_real(diag)) * col_j; xjplus.axpy(-xj.clone() / T::from_real(diag.clone()), &col_j, T::one()); if gamma != crate::zero::() { diff --git a/src/linalg/col_piv_qr.rs b/src/linalg/col_piv_qr.rs index 822448e3..bd234b60 100644 --- a/src/linalg/col_piv_qr.rs +++ b/src/linalg/col_piv_qr.rs @@ -78,7 +78,7 @@ where let mut diag = Matrix::uninit(min_nrows_ncols, Const::<1>); for i in 0..min_nrows_ncols.value() { - let piv = matrix.slice_range(i.., i..).icamax_full(); + let piv = matrix.view_range(i.., i..).icamax_full(); let col_piv = piv.1 + i; matrix.swap_columns(i, col_piv); p.append_permutation(i, col_piv); @@ -144,11 +144,11 @@ where let dim = self.diag.len(); for i in (0..dim).rev() { - let axis = self.col_piv_qr.slice_range(i.., i); + let axis = self.col_piv_qr.view_range(i.., i); // TODO: sometimes, the axis might have a zero magnitude. let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); - let mut res_rows = res.slice_range_mut(i.., i..); + let mut res_rows = res.view_range_mut(i.., i..); refl.reflect_with_sign(&mut res_rows, self.diag[i].clone().signum()); } @@ -191,7 +191,7 @@ where let dim = self.diag.len(); for i in 0..dim { - let axis = self.col_piv_qr.slice_range(i.., i); + let axis = self.col_piv_qr.view_range(i.., i); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let mut rhs_rows = rhs.rows_range_mut(i..); @@ -281,7 +281,7 @@ where } b.rows_range_mut(..i) - .axpy(-coeff, &self.col_piv_qr.slice_range(..i, i), T::one()); + .axpy(-coeff, &self.col_piv_qr.view_range(..i, i), T::one()); } } diff --git a/src/linalg/eigen.rs b/src/linalg/eigen.rs index 37b5ddea..a1f6172e 100644 --- a/src/linalg/eigen.rs +++ b/src/linalg/eigen.rs @@ -8,7 +8,7 @@ use std::fmt::Display; use std::ops::MulAssign; use crate::allocator::Allocator; -use crate::base::dimension::{Dim, DimDiff, DimSub, Dynamic, U1, U2, U3}; +use crate::base::dimension::{Dim, DimDiff, DimSub, Dyn, U1, U2, U3}; use crate::base::storage::Storage; use crate::base::{ DefaultAllocator, Hessenberg, OMatrix, OVector, SquareMatrix, Unit, Vector2, Vector3, @@ -52,8 +52,8 @@ where impl Eigen where - D: DimSub, // For Hessenberg. - ShapeConstraint: DimEq>, // For Hessenberg. + D: DimSub, // For Hessenberg. + ShapeConstraint: DimEq>, // For Hessenberg. DefaultAllocator: Allocator> + Allocator> + Allocator diff --git a/src/linalg/full_piv_lu.rs b/src/linalg/full_piv_lu.rs index b11bf4d6..2037e285 100644 --- a/src/linalg/full_piv_lu.rs +++ b/src/linalg/full_piv_lu.rs @@ -64,7 +64,7 @@ where } for i in 0..min_nrows_ncols.value() { - let piv = matrix.slice_range(i.., i..).icamax_full(); + let piv = matrix.view_range(i.., i..).icamax_full(); let row_piv = piv.0 + i; let col_piv = piv.1 + i; let diag = matrix[(row_piv, col_piv)].clone(); diff --git a/src/linalg/hessenberg.rs b/src/linalg/hessenberg.rs index 2f85d462..0313a0bb 100644 --- a/src/linalg/hessenberg.rs +++ b/src/linalg/hessenberg.rs @@ -113,7 +113,7 @@ where let dim = self.hess.nrows(); self.hess.fill_lower_triangle(T::zero(), 2); self.hess - .slice_mut((1, 0), (dim - 1, dim - 1)) + .view_mut((1, 0), (dim - 1, dim - 1)) .set_partial_diagonal( self.subdiag .iter() @@ -132,7 +132,7 @@ where let dim = self.hess.nrows(); let mut res = self.hess.clone(); res.fill_lower_triangle(T::zero(), 2); - res.slice_mut((1, 0), (dim - 1, dim - 1)) + res.view_mut((1, 0), (dim - 1, dim - 1)) .set_partial_diagonal( self.subdiag .iter() diff --git a/src/linalg/householder.rs b/src/linalg/householder.rs index 688930a3..79d7c768 100644 --- a/src/linalg/householder.rs +++ b/src/linalg/householder.rs @@ -128,10 +128,10 @@ where let mut res = OMatrix::identity_generic(dim, dim); for i in (0..dim.value() - 1).rev() { - let axis = m.slice_range(i + 1.., i); + let axis = m.view_range(i + 1.., i); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); - let mut res_rows = res.slice_range_mut(i + 1.., i..); + let mut res_rows = res.view_range_mut(i + 1.., i..); refl.reflect_with_sign(&mut res_rows, signs[i].clone().signum()); } diff --git a/src/linalg/inverse.rs b/src/linalg/inverse.rs index f07be14a..91d45587 100644 --- a/src/linalg/inverse.rs +++ b/src/linalg/inverse.rs @@ -8,7 +8,11 @@ use crate::base::{DefaultAllocator, OMatrix, SquareMatrix}; use crate::linalg::lu; impl> SquareMatrix { - /// Attempts to invert this matrix. + /// Attempts to invert this square matrix. + /// + /// # Panics + /// + /// Panics if `self` isn’t a square matrix. #[inline] #[must_use = "Did you mean to use try_inverse_mut()?"] pub fn try_inverse(self) -> Option> @@ -25,8 +29,12 @@ impl> SquareMatrix { } impl> SquareMatrix { - /// Attempts to invert this matrix in-place. Returns `false` and leaves `self` untouched if + /// Attempts to invert this square matrix in-place. Returns `false` and leaves `self` untouched if /// inversion fails. + /// + /// # Panics + /// + /// Panics if `self` isn’t a square matrix. #[inline] pub fn try_inverse_mut(&mut self) -> bool where diff --git a/src/linalg/lu.rs b/src/linalg/lu.rs index 01ae46f0..a5e87072 100644 --- a/src/linalg/lu.rs +++ b/src/linalg/lu.rs @@ -64,7 +64,7 @@ where out.fill_with_identity(); for i in 0..dim { - let piv = matrix.slice_range(i.., i).icamax() + i; + let piv = matrix.view_range(i.., i).icamax() + i; let diag = matrix[(piv, i)].clone(); if diag.is_zero() { @@ -100,7 +100,7 @@ where } for i in 0..min_nrows_ncols.value() { - let piv = matrix.slice_range(i.., i).icamax() + i; + let piv = matrix.view_range(i.., i).icamax() + i; let diag = matrix[(piv, i)].clone(); if diag.is_zero() { @@ -338,7 +338,7 @@ where T: Scalar + Field, S: StorageMut, { - let mut submat = matrix.slice_range_mut(i.., i..); + let mut submat = matrix.view_range_mut(i.., i..); let inv_diag = T::one() / diag; @@ -368,7 +368,7 @@ pub fn gauss_step_swap( S: StorageMut, { let piv = piv - i; - let mut submat = matrix.slice_range_mut(i.., i..); + let mut submat = matrix.view_range_mut(i.., i..); let inv_diag = T::one() / diag; diff --git a/src/linalg/permutation_sequence.rs b/src/linalg/permutation_sequence.rs index f4521988..9e4eb37b 100644 --- a/src/linalg/permutation_sequence.rs +++ b/src/linalg/permutation_sequence.rs @@ -7,7 +7,7 @@ use simba::scalar::ClosedNeg; use crate::allocator::Allocator; use crate::base::{DefaultAllocator, Matrix, OVector, Scalar}; #[cfg(any(feature = "std", feature = "alloc"))] -use crate::dimension::Dynamic; +use crate::dimension::Dyn; use crate::dimension::{Const, Dim, DimName}; use crate::storage::StorageMut; @@ -51,14 +51,14 @@ where } #[cfg(any(feature = "std", feature = "alloc"))] -impl PermutationSequence +impl PermutationSequence where - DefaultAllocator: Allocator<(usize, usize), Dynamic>, + DefaultAllocator: Allocator<(usize, usize), Dyn>, { /// Creates a new dynamically-allocated sequence of `n` identity permutations. #[inline] pub fn identity(n: usize) -> Self { - Self::identity_generic(Dynamic::new(n)) + Self::identity_generic(Dyn(n)) } } diff --git a/src/linalg/qr.rs b/src/linalg/qr.rs index 1b06e34b..54921939 100644 --- a/src/linalg/qr.rs +++ b/src/linalg/qr.rs @@ -116,11 +116,11 @@ where let dim = self.diag.len(); for i in (0..dim).rev() { - let axis = self.qr.slice_range(i.., i); + let axis = self.qr.view_range(i.., i); // TODO: sometimes, the axis might have a zero magnitude. let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); - let mut res_rows = res.slice_range_mut(i.., i..); + let mut res_rows = res.view_range_mut(i.., i..); refl.reflect_with_sign(&mut res_rows, self.diag[i].clone().signum()); } @@ -161,7 +161,7 @@ where let dim = self.diag.len(); for i in 0..dim { - let axis = self.qr.slice_range(i.., i); + let axis = self.qr.view_range(i.., i); let refl = Reflection::new(Unit::new_unchecked(axis), T::zero()); let mut rhs_rows = rhs.rows_range_mut(i..); @@ -247,7 +247,7 @@ where } b.rows_range_mut(..i) - .axpy(-coeff, &self.qr.slice_range(..i, i), T::one()); + .axpy(-coeff, &self.qr.view_range(..i, i), T::one()); } } diff --git a/src/linalg/schur.rs b/src/linalg/schur.rs index c7753cee..3f734723 100644 --- a/src/linalg/schur.rs +++ b/src/linalg/schur.rs @@ -8,7 +8,7 @@ use simba::scalar::{ComplexField, RealField}; use std::cmp; use crate::allocator::Allocator; -use crate::base::dimension::{Const, Dim, DimDiff, DimSub, Dynamic, U1, U2}; +use crate::base::dimension::{Const, Dim, DimDiff, DimSub, Dyn, U1, U2}; use crate::base::storage::Storage; use crate::base::{DefaultAllocator, OMatrix, OVector, SquareMatrix, Unit, Vector2, Vector3}; @@ -174,19 +174,18 @@ where { let krows = cmp::min(k + 4, end + 1); let mut work = work.rows_mut(0, krows); - refl.reflect(&mut t.generic_slice_mut( - (k, k), - (Const::<3>, Dynamic::new(dim.value() - k)), - )); + refl.reflect( + &mut t.generic_view_mut((k, k), (Const::<3>, Dyn(dim.value() - k))), + ); refl.reflect_rows( - &mut t.generic_slice_mut((0, k), (Dynamic::new(krows), Const::<3>)), + &mut t.generic_view_mut((0, k), (Dyn(krows), Const::<3>)), &mut work, ); } if let Some(ref mut q) = q { refl.reflect_rows( - &mut q.generic_slice_mut((0, k), (dim, Const::<3>)), + &mut q.generic_view_mut((0, k), (dim, Const::<3>)), work, ); } @@ -211,38 +210,36 @@ where { let mut work = work.rows_mut(0, end + 1); - refl.reflect(&mut t.generic_slice_mut( - (m, m), - (Const::<2>, Dynamic::new(dim.value() - m)), - )); + refl.reflect( + &mut t.generic_view_mut((m, m), (Const::<2>, Dyn(dim.value() - m))), + ); refl.reflect_rows( - &mut t.generic_slice_mut((0, m), (Dynamic::new(end + 1), Const::<2>)), + &mut t.generic_view_mut((0, m), (Dyn(end + 1), Const::<2>)), &mut work, ); } if let Some(ref mut q) = q { - refl.reflect_rows( - &mut q.generic_slice_mut((0, m), (dim, Const::<2>)), - work, - ); + refl.reflect_rows(&mut q.generic_view_mut((0, m), (dim, Const::<2>)), work); } } } else { // Decouple the 2x2 block if it has real eigenvalues. - if let Some(rot) = compute_2x2_basis(&t.fixed_slice::<2, 2>(start, start)) { + if let Some(rot) = compute_2x2_basis(&t.fixed_view::<2, 2>(start, start)) { let inv_rot = rot.inverse(); - inv_rot.rotate(&mut t.generic_slice_mut( - (start, start), - (Const::<2>, Dynamic::new(dim.value() - start)), - )); + inv_rot.rotate( + &mut t.generic_view_mut( + (start, start), + (Const::<2>, Dyn(dim.value() - start)), + ), + ); rot.rotate_rows( - &mut t.generic_slice_mut((0, start), (Dynamic::new(end + 1), Const::<2>)), + &mut t.generic_view_mut((0, start), (Dyn(end + 1), Const::<2>)), ); t[(end, start)] = T::zero(); if let Some(ref mut q) = q { - rot.rotate_rows(&mut q.generic_slice_mut((0, start), (dim, Const::<2>))); + rot.rotate_rows(&mut q.generic_view_mut((0, start), (dim, Const::<2>))); } } @@ -427,9 +424,9 @@ where { let dim = m.shape_generic().0; let mut q = None; - match compute_2x2_basis(&m.fixed_slice::<2, 2>(0, 0)) { + match compute_2x2_basis(&m.fixed_view::<2, 2>(0, 0)) { Some(rot) => { - let mut m = m.fixed_slice_mut::<2, 2>(0, 0); + let mut m = m.fixed_view_mut::<2, 2>(0, 0); let inv_rot = rot.inverse(); inv_rot.rotate(&mut m); rot.rotate_rows(&mut m); @@ -530,7 +527,7 @@ where if self.nrows() == 2 { // TODO: can we avoid this slicing // (which is needed here just to transform D to U2)? - let me = self.fixed_slice::<2, 2>(0, 0); + let me = self.fixed_view::<2, 2>(0, 0); return match compute_2x2_eigvals(&me) { Some((a, b)) => { work[0] = a; diff --git a/src/linalg/solve.rs b/src/linalg/solve.rs index 7409e7fb..237986a8 100644 --- a/src/linalg/solve.rs +++ b/src/linalg/solve.rs @@ -5,7 +5,7 @@ use crate::base::allocator::Allocator; use crate::base::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::base::dimension::{Dim, U1}; use crate::base::storage::{Storage, StorageMut}; -use crate::base::{DVectorSlice, DefaultAllocator, Matrix, OMatrix, SquareMatrix, Vector}; +use crate::base::{DVectorView, DefaultAllocator, Matrix, OMatrix, SquareMatrix, Vector}; impl> SquareMatrix { /// Computes the solution of the linear system `self . x = b` where `x` is the unknown and only @@ -93,7 +93,7 @@ impl> SquareMatrix { } b.rows_range_mut(i + 1..) - .axpy(-coeff, &self.slice_range(i + 1.., i), T::one()); + .axpy(-coeff, &self.view_range(i + 1.., i), T::one()); } true @@ -125,7 +125,7 @@ impl> SquareMatrix { for i in 0..dim - 1 { let coeff = unsafe { bcol.vget_unchecked(i).clone() } / diag.clone(); bcol.rows_range_mut(i + 1..) - .axpy(-coeff, &self.slice_range(i + 1.., i), T::one()); + .axpy(-coeff, &self.view_range(i + 1.., i), T::one()); } } @@ -175,7 +175,7 @@ impl> SquareMatrix { } b.rows_range_mut(..i) - .axpy(-coeff, &self.slice_range(..i, i), T::one()); + .axpy(-coeff, &self.view_range(..i, i), T::one()); } true @@ -376,8 +376,8 @@ impl> SquareMatrix { b: &mut Vector, conjugate: impl Fn(T) -> T, dot: impl Fn( - &DVectorSlice<'_, T, S::RStride, S::CStride>, - &DVectorSlice<'_, T, S2::RStride, S2::CStride>, + &DVectorView<'_, T, S::RStride, S::CStride>, + &DVectorView<'_, T, S2::RStride, S2::CStride>, ) -> T, ) -> bool where @@ -387,7 +387,7 @@ impl> SquareMatrix { let dim = self.nrows(); for i in (0..dim).rev() { - let dot = dot(&self.slice_range(i + 1.., i), &b.slice_range(i + 1.., 0)); + let dot = dot(&self.view_range(i + 1.., i), &b.view_range(i + 1.., 0)); unsafe { let b_i = b.vget_unchecked_mut(i); @@ -411,8 +411,8 @@ impl> SquareMatrix { b: &mut Vector, conjugate: impl Fn(T) -> T, dot: impl Fn( - &DVectorSlice<'_, T, S::RStride, S::CStride>, - &DVectorSlice<'_, T, S2::RStride, S2::CStride>, + &DVectorView<'_, T, S::RStride, S::CStride>, + &DVectorView<'_, T, S2::RStride, S2::CStride>, ) -> T, ) -> bool where @@ -422,7 +422,7 @@ impl> SquareMatrix { let dim = self.nrows(); for i in 0..dim { - let dot = dot(&self.slice_range(..i, i), &b.slice_range(..i, 0)); + let dot = dot(&self.view_range(..i, i), &b.view_range(..i, 0)); unsafe { let b_i = b.vget_unchecked_mut(i); @@ -514,7 +514,7 @@ impl> SquareMatrix { } b.rows_range_mut(i + 1..) - .axpy(-coeff.clone(), &self.slice_range(i + 1.., i), T::one()); + .axpy(-coeff.clone(), &self.view_range(i + 1.., i), T::one()); } } @@ -539,7 +539,7 @@ impl> SquareMatrix { for i in 0..dim - 1 { let coeff = unsafe { bcol.vget_unchecked(i).clone() } / diag.clone(); bcol.rows_range_mut(i + 1..) - .axpy(-coeff, &self.slice_range(i + 1.., i), T::one()); + .axpy(-coeff, &self.view_range(i + 1.., i), T::one()); } } } @@ -575,7 +575,7 @@ impl> SquareMatrix { } b.rows_range_mut(..i) - .axpy(-coeff, &self.slice_range(..i, i), T::one()); + .axpy(-coeff, &self.view_range(..i, i), T::one()); } } @@ -734,8 +734,8 @@ impl> SquareMatrix { b: &mut Vector, conjugate: impl Fn(T) -> T, dot: impl Fn( - &DVectorSlice<'_, T, S::RStride, S::CStride>, - &DVectorSlice<'_, T, S2::RStride, S2::CStride>, + &DVectorView<'_, T, S::RStride, S::CStride>, + &DVectorView<'_, T, S2::RStride, S2::CStride>, ) -> T, ) where S2: StorageMut, @@ -744,7 +744,7 @@ impl> SquareMatrix { let dim = self.nrows(); for i in (0..dim).rev() { - let dot = dot(&self.slice_range(i + 1.., i), &b.slice_range(i + 1.., 0)); + let dot = dot(&self.view_range(i + 1.., i), &b.view_range(i + 1.., 0)); unsafe { let b_i = b.vget_unchecked_mut(i); @@ -760,15 +760,15 @@ impl> SquareMatrix { b: &mut Vector, conjugate: impl Fn(T) -> T, dot: impl Fn( - &DVectorSlice<'_, T, S::RStride, S::CStride>, - &DVectorSlice<'_, T, S2::RStride, S2::CStride>, + &DVectorView<'_, T, S::RStride, S::CStride>, + &DVectorView<'_, T, S2::RStride, S2::CStride>, ) -> T, ) where S2: StorageMut, ShapeConstraint: SameNumberOfRows, { for i in 0..self.nrows() { - let dot = dot(&self.slice_range(..i, i), &b.slice_range(..i, 0)); + let dot = dot(&self.view_range(..i, i), &b.view_range(..i, 0)); unsafe { let b_i = b.vget_unchecked_mut(i); diff --git a/src/proptest/mod.rs b/src/proptest/mod.rs index a7cbe549..6cb31521 100644 --- a/src/proptest/mod.rs +++ b/src/proptest/mod.rs @@ -53,11 +53,11 @@ //! with [matrix](fn.matrix.html) as follows: //! //! ``` -//! use nalgebra::{Dynamic, OMatrix, Const}; +//! use nalgebra::{Dyn, OMatrix, Const}; //! use nalgebra::proptest::matrix; //! use proptest::prelude::*; //! -//! type MyMatrix = OMatrix, Dynamic>; +//! type MyMatrix = OMatrix, Dyn>; //! //! /// Returns a strategy for pairs of matrices with `U3` rows and the same number of //! /// columns. @@ -93,7 +93,7 @@ //! If you don't care about the dimensions of matrices, you can write tests like these: //! //! ``` -//! use nalgebra::{DMatrix, DVector, Dynamic, Matrix3, OMatrix, Vector3, U3}; +//! use nalgebra::{DMatrix, DVector, Dyn, Matrix3, OMatrix, Vector3, U3}; //! use proptest::prelude::*; //! //! proptest! { @@ -108,7 +108,7 @@ //! # /* //! #[test] //! # */ -//! fn test_static_and_mixed(matrix: Matrix3, matrix2: OMatrix) { +//! fn test_static_and_mixed(matrix: Matrix3, matrix2: OMatrix) { //! // Test some property involving these matrices //! } //! @@ -141,7 +141,7 @@ //! PROPTEST_MAX_SHRINK_ITERS=100000 cargo test my_failing_test //! ``` use crate::allocator::Allocator; -use crate::{Const, DefaultAllocator, Dim, DimName, Dynamic, OMatrix, Scalar, U1}; +use crate::{Const, DefaultAllocator, Dim, DimName, Dyn, OMatrix, Scalar, U1}; use proptest::arbitrary::Arbitrary; use proptest::collection::vec; use proptest::strategy::{BoxedStrategy, Just, NewTree, Strategy, ValueTree}; @@ -167,9 +167,9 @@ pub struct MatrixParameters { /// of matrices with `proptest`. In most cases, you do not need to concern yourself with /// `DimRange` directly, as it supports conversion from other types such as `U3` or inclusive /// ranges such as `5 ..= 6`. The latter example corresponds to dimensions from (inclusive) -/// `Dynamic::new(5)` to `Dynamic::new(6)` (inclusive). +/// `Dyn(5)` to `Dyn(6)` (inclusive). #[derive(Debug, Clone, PartialEq, Eq)] -pub struct DimRange(RangeInclusive); +pub struct DimRange(RangeInclusive); impl DimRange { /// The lower bound for dimensions generated. @@ -195,9 +195,9 @@ impl From> for DimRange { } } -impl From> for DimRange { +impl From> for DimRange { fn from(range: RangeInclusive) -> Self { - DimRange::from(Dynamic::new(*range.start())..=Dynamic::new(*range.end())) + DimRange::from(Dyn(*range.start())..=Dyn(*range.end())) } } @@ -208,14 +208,14 @@ impl DimRange { } } -impl From for DimRange { +impl From for DimRange { fn from(dim: usize) -> Self { - DimRange::from(Dynamic::new(dim)) + DimRange::from(Dyn(dim)) } } -/// The default range used for Dynamic dimensions when generating arbitrary matrices. -fn dynamic_dim_range() -> DimRange { +/// The default range used for Dyn dimensions when generating arbitrary matrices. +fn dynamic_dim_range() -> DimRange { DimRange::from(0..=6) } @@ -225,7 +225,7 @@ fn dynamic_dim_range() -> DimRange { /// ## Examples /// ``` /// use nalgebra::proptest::matrix; -/// use nalgebra::{OMatrix, Const, Dynamic}; +/// use nalgebra::{OMatrix, Const, Dyn}; /// use proptest::prelude::*; /// /// proptest! { @@ -234,7 +234,7 @@ fn dynamic_dim_range() -> DimRange { /// # */ /// fn my_test(a in matrix(0 .. 5i32, Const::<3>, 0 ..= 5)) { /// // Let's make sure we've got the correct type first -/// let a: OMatrix<_, Const::<3>, Dynamic> = a; +/// let a: OMatrix<_, Const::<3>, Dyn> = a; /// prop_assert!(a.nrows() == 3); /// prop_assert!(a.ncols() <= 5); /// prop_assert!(a.iter().all(|x_ij| *x_ij >= 0 && *x_ij < 5)); @@ -347,7 +347,7 @@ where } } -impl Default for MatrixParameters +impl Default for MatrixParameters where NParameters: Default, R: DimName, @@ -361,7 +361,7 @@ where } } -impl Default for MatrixParameters +impl Default for MatrixParameters where NParameters: Default, C: DimName, @@ -375,7 +375,7 @@ where } } -impl Default for MatrixParameters +impl Default for MatrixParameters where NParameters: Default, { diff --git a/src/sparse/cs_matrix.rs b/src/sparse/cs_matrix.rs index 14f8d41e..5b63e537 100644 --- a/src/sparse/cs_matrix.rs +++ b/src/sparse/cs_matrix.rs @@ -7,7 +7,7 @@ use std::slice; use crate::allocator::Allocator; use crate::sparse::cs_utils; -use crate::{Const, DefaultAllocator, Dim, Dynamic, Matrix, OVector, Scalar, Vector, U1}; +use crate::{Const, DefaultAllocator, Dim, Dyn, Matrix, OVector, Scalar, Vector, U1}; pub struct ColumnEntries<'a, T> { curr: usize, @@ -236,16 +236,16 @@ impl CsStorageMut for CsVecStorage pub struct CsSliceStorage<'a, T: Scalar, R: Dim, C: DimAdd> { shape: (R, C), p: VectorSlice>, - i: VectorSlice, - vals: VectorSlice, + i: VectorSlice, + vals: VectorSlice, }*/ /// A compressed sparse column matrix. #[derive(Clone, Debug, PartialEq)] pub struct CsMatrix< T: Scalar, - R: Dim = Dynamic, - C: Dim = Dynamic, + R: Dim = Dyn, + C: Dim = Dyn, S: CsStorage = CsVecStorage, > { pub(crate) data: S, @@ -253,7 +253,7 @@ pub struct CsMatrix< } /// A column compressed sparse vector. -pub type CsVector> = CsMatrix; +pub type CsVector> = CsMatrix; impl CsMatrix where @@ -342,8 +342,8 @@ impl CsMatrix { vals: Vec, ) -> Self { - let nrows = Dynamic::new(nrows); - let ncols = Dynamic::new(ncols); + let nrows = Dyn(nrows); + let ncols = Dyn(ncols); let p = DVector::from_data(VecStorage::new(ncols, U1, p)); Self::from_parts_generic(nrows, ncols, p, i, vals) } diff --git a/src/sparse/cs_matrix_conversion.rs b/src/sparse/cs_matrix_conversion.rs index e7ff8c36..4154f452 100644 --- a/src/sparse/cs_matrix_conversion.rs +++ b/src/sparse/cs_matrix_conversion.rs @@ -5,7 +5,7 @@ use crate::allocator::Allocator; use crate::sparse::cs_utils; use crate::sparse::{CsMatrix, CsStorage}; use crate::storage::Storage; -use crate::{DefaultAllocator, Dim, Dynamic, Matrix, OMatrix, Scalar}; +use crate::{DefaultAllocator, Dim, Dyn, Matrix, OMatrix, Scalar}; impl<'a, T: Scalar + Zero + ClosedAdd> CsMatrix { /// Creates a column-compressed sparse matrix from a sparse matrix in triplet form. @@ -16,7 +16,7 @@ impl<'a, T: Scalar + Zero + ClosedAdd> CsMatrix { icols: &[usize], vals: &[T], ) -> Self { - Self::from_triplet_generic(Dynamic::new(nrows), Dynamic::new(ncols), irows, icols, vals) + Self::from_triplet_generic(Dyn(nrows), Dyn(ncols), irows, icols, vals) } } diff --git a/src/third_party/glam/mod.rs b/src/third_party/glam/mod.rs index 06bdcfb7..811e88b2 100644 --- a/src/third_party/glam/mod.rs +++ b/src/third_party/glam/mod.rs @@ -14,3 +14,5 @@ mod v019; mod v020; #[cfg(feature = "glam021")] mod v021; +#[cfg(feature = "glam022")] +mod v022; diff --git a/src/third_party/glam/v022/mod.rs b/src/third_party/glam/v022/mod.rs new file mode 100644 index 00000000..de27f929 --- /dev/null +++ b/src/third_party/glam/v022/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 glam022 as glam; diff --git a/tests/core/conversion.rs b/tests/core/conversion.rs index 5374c399..096f235b 100644 --- a/tests/core/conversion.rs +++ b/tests/core/conversion.rs @@ -7,7 +7,7 @@ use na::{ RowVector5, RowVector6, Similarity3, Transform3, UnitQuaternion, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, }; -use na::{DMatrix, DMatrixSlice, DMatrixSliceMut, MatrixSlice, MatrixSliceMut}; +use na::{DMatrix, DMatrixView, DMatrixViewMut, MatrixView, MatrixViewMut}; use na::{U1, U3, U4}; use crate::proptest::*; @@ -266,24 +266,24 @@ fn matrix_slice_from_matrix_ref() { // Note: these have to be macros, and not functions, because the input type is different // across the different tests. Moreover, the output type depends on the stride of the input, // which is different for static and dynamic matrices. - macro_rules! dynamic_slice { + macro_rules! dynamic_view { ($mref:expr) => { - DMatrixSlice::<_>::from($mref) + DMatrixView::<_>::from($mref) }; } - macro_rules! dynamic_slice_mut { + macro_rules! dynamic_view_mut { ($mref:expr) => { - DMatrixSliceMut::<_>::from($mref) + DMatrixViewMut::<_>::from($mref) }; } - macro_rules! fixed_slice { + macro_rules! fixed_view { ($mref:expr) => { - MatrixSlice::<_, U3, U4, U1, U3>::from($mref) + MatrixView::<_, U3, U4, U1, U3>::from($mref) }; } - macro_rules! fixed_slice_mut { + macro_rules! fixed_view_mut { ($mref:expr) => { - MatrixSliceMut::<_, U3, U4, U1, U3>::from($mref) + MatrixViewMut::<_, U3, U4, U1, U3>::from($mref) }; } @@ -291,66 +291,66 @@ fn matrix_slice_from_matrix_ref() { // Self and RHS. See issue #674. Once this is implemented, we can remove `into_owned` // from the below tests. - // Construct slices from reference to a + // Construct views from reference to a { - assert_eq!(a, fixed_slice!(&a).into_owned()); - assert_eq!(d, dynamic_slice!(&a).into_owned()); + assert_eq!(a, fixed_view!(&a).into_owned()); + assert_eq!(d, dynamic_view!(&a).into_owned()); } - // Construct slices from mutable reference to a + // Construct views from mutable reference to a { let mut a_clone = a.clone(); - assert_eq!(a, fixed_slice!(&mut a_clone).into_owned()); - assert_eq!(d, dynamic_slice!(&mut a_clone).into_owned()); + assert_eq!(a, fixed_view!(&mut a_clone).into_owned()); + assert_eq!(d, dynamic_view!(&mut a_clone).into_owned()); } // Construct mutable slices from mutable reference to a { let mut a_clone = a.clone(); - assert_eq!(a, fixed_slice_mut!(&mut a_clone).into_owned()); - assert_eq!(d, dynamic_slice_mut!(&mut a_clone).into_owned()); + assert_eq!(a, fixed_view_mut!(&mut a_clone).into_owned()); + assert_eq!(d, dynamic_view_mut!(&mut a_clone).into_owned()); } // Construct slices from reference to d { - assert_eq!(a, fixed_slice!(&d).into_owned()); - assert_eq!(d, dynamic_slice!(&d).into_owned()); + assert_eq!(a, fixed_view!(&d).into_owned()); + assert_eq!(d, dynamic_view!(&d).into_owned()); } // Construct slices from mutable reference to d { let mut d_clone = a.clone(); - assert_eq!(a, fixed_slice!(&mut d_clone).into_owned()); - assert_eq!(d, dynamic_slice!(&mut d_clone).into_owned()); + assert_eq!(a, fixed_view!(&mut d_clone).into_owned()); + assert_eq!(d, dynamic_view!(&mut d_clone).into_owned()); } // Construct mutable slices from mutable reference to d { let mut d_clone = d.clone(); - assert_eq!(a, fixed_slice_mut!(&mut d_clone).into_owned()); - assert_eq!(d, dynamic_slice_mut!(&mut d_clone).into_owned()); + assert_eq!(a, fixed_view_mut!(&mut d_clone).into_owned()); + assert_eq!(d, dynamic_view_mut!(&mut d_clone).into_owned()); } // Construct slices from a slice of a { - let mut a_slice = fixed_slice!(&a); - assert_eq!(a, fixed_slice!(&a_slice).into_owned()); - assert_eq!(a, fixed_slice!(&mut a_slice).into_owned()); - assert_eq!(d, dynamic_slice!(&a_slice).into_owned()); - assert_eq!(d, dynamic_slice!(&mut a_slice).into_owned()); + let mut a_slice = fixed_view!(&a); + assert_eq!(a, fixed_view!(&a_slice).into_owned()); + assert_eq!(a, fixed_view!(&mut a_slice).into_owned()); + assert_eq!(d, dynamic_view!(&a_slice).into_owned()); + assert_eq!(d, dynamic_view!(&mut a_slice).into_owned()); } // Construct slices from a slice mut of a { // Need a clone of a here, so that we can both have a mutable borrow and compare equality let mut a_clone = a.clone(); - let mut a_slice = fixed_slice_mut!(&mut a_clone); + let mut a_slice = fixed_view_mut!(&mut a_clone); - assert_eq!(a, fixed_slice!(&a_slice).into_owned()); - assert_eq!(a, fixed_slice!(&mut a_slice).into_owned()); - assert_eq!(d, dynamic_slice!(&a_slice).into_owned()); - assert_eq!(d, dynamic_slice!(&mut a_slice).into_owned()); - assert_eq!(a, fixed_slice_mut!(&mut a_slice).into_owned()); - assert_eq!(d, dynamic_slice_mut!(&mut a_slice).into_owned()); + assert_eq!(a, fixed_view!(&a_slice).into_owned()); + assert_eq!(a, fixed_view!(&mut a_slice).into_owned()); + assert_eq!(d, dynamic_view!(&a_slice).into_owned()); + assert_eq!(d, dynamic_view!(&mut a_slice).into_owned()); + assert_eq!(a, fixed_view_mut!(&mut a_slice).into_owned()); + assert_eq!(d, dynamic_view_mut!(&mut a_slice).into_owned()); } } diff --git a/tests/core/edition.rs b/tests/core/edition.rs index bd882652..f5a51874 100644 --- a/tests/core/edition.rs +++ b/tests/core/edition.rs @@ -2,7 +2,7 @@ use na::{ DMatrix, Matrix, Matrix3, Matrix3x4, Matrix3x5, Matrix4, Matrix4x3, Matrix4x5, Matrix5, Matrix5x3, Matrix5x4, }; -use na::{Dynamic, U3, U5}; +use na::{Dyn, U3, U5}; #[test] #[rustfmt::skip] @@ -257,7 +257,7 @@ fn remove_columns() { assert_eq!(m.remove_fixed_columns::<2>(2), expected_b3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, U3, Dynamic, _> = m.remove_columns(3, 2); + let computed: Matrix<_, U3, Dyn, _> = m.remove_columns(3, 2); assert!(computed.eq(&expected_b2)); /* @@ -391,7 +391,7 @@ fn remove_rows() { assert_eq!(m.remove_fixed_rows::<2>(2), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, Dynamic, U3, _> = m.remove_rows(3, 2); + let computed: Matrix<_, Dyn, U3, _> = m.remove_rows(3, 2); assert!(computed.eq(&expected2)); } @@ -508,7 +508,7 @@ fn insert_columns() { assert_eq!(m.insert_fixed_columns::<2>(2, 0), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, U5, Dynamic, _> = m.insert_columns(3, 2, 0); + let computed: Matrix<_, U5, Dyn, _> = m.insert_columns(3, 2, 0); assert!(computed.eq(&expected2)); } @@ -581,7 +581,7 @@ fn insert_rows() { assert_eq!(m.insert_fixed_rows::<2>(2, 0), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, Dynamic, U5, _> = m.insert_rows(3, 2, 0); + let computed: Matrix<_, Dyn, U5, _> = m.insert_rows(3, 2, 0); assert!(computed.eq(&expected2)); } diff --git a/tests/core/matrix.rs b/tests/core/matrix.rs index 8a545e97..27926a27 100644 --- a/tests/core/matrix.rs +++ b/tests/core/matrix.rs @@ -1066,43 +1066,43 @@ fn partial_eq_different_types() { let static_mat = Matrix2x4::new(1, 2, 3, 4, 5, 6, 7, 8); let mut typenum_static_mat = OMatrix::, Const<4>>::zeros(); - let mut slice = typenum_static_mat.slice_mut((0, 0), (2, 4)); - slice += static_mat; + let mut view = typenum_static_mat.view_mut((0, 0), (2, 4)); + view += static_mat; - let fslice_of_dmat = dynamic_mat.fixed_slice::<2, 2>(0, 0); - let dslice_of_dmat = dynamic_mat.slice((0, 0), (2, 2)); - let fslice_of_smat = static_mat.fixed_slice::<2, 2>(0, 0); - let dslice_of_smat = static_mat.slice((0, 0), (2, 2)); + let fview_of_dmat = dynamic_mat.fixed_view::<2, 2>(0, 0); + let dview_of_dmat = dynamic_mat.view((0, 0), (2, 2)); + let fview_of_smat = static_mat.fixed_view::<2, 2>(0, 0); + let dview_of_smat = static_mat.view((0, 0), (2, 2)); assert_eq!(dynamic_mat, static_mat); assert_eq!(static_mat, dynamic_mat); - assert_eq!(dynamic_mat, slice); - assert_eq!(slice, dynamic_mat); + assert_eq!(dynamic_mat, view); + assert_eq!(view, dynamic_mat); - assert_eq!(static_mat, slice); - assert_eq!(slice, static_mat); + assert_eq!(static_mat, view); + assert_eq!(view, static_mat); - assert_eq!(fslice_of_dmat, dslice_of_dmat); - assert_eq!(dslice_of_dmat, fslice_of_dmat); + assert_eq!(fview_of_dmat, dview_of_dmat); + assert_eq!(dview_of_dmat, fview_of_dmat); - assert_eq!(fslice_of_dmat, fslice_of_smat); - assert_eq!(fslice_of_smat, fslice_of_dmat); + assert_eq!(fview_of_dmat, fview_of_smat); + assert_eq!(fview_of_smat, fview_of_dmat); - assert_eq!(fslice_of_dmat, dslice_of_smat); - assert_eq!(dslice_of_smat, fslice_of_dmat); + assert_eq!(fview_of_dmat, dview_of_smat); + assert_eq!(dview_of_smat, fview_of_dmat); - assert_eq!(dslice_of_dmat, fslice_of_smat); - assert_eq!(fslice_of_smat, dslice_of_dmat); + assert_eq!(dview_of_dmat, fview_of_smat); + assert_eq!(fview_of_smat, dview_of_dmat); - assert_eq!(dslice_of_dmat, dslice_of_smat); - assert_eq!(dslice_of_smat, dslice_of_dmat); + assert_eq!(dview_of_dmat, dview_of_smat); + assert_eq!(dview_of_smat, dview_of_dmat); - assert_eq!(fslice_of_smat, dslice_of_smat); - assert_eq!(dslice_of_smat, fslice_of_smat); + assert_eq!(fview_of_smat, dview_of_smat); + assert_eq!(dview_of_smat, fview_of_smat); - assert_ne!(dynamic_mat, dslice_of_smat); - assert_ne!(dslice_of_smat, dynamic_mat); + assert_ne!(dynamic_mat, dview_of_smat); + assert_ne!(dview_of_smat, dynamic_mat); // TODO - implement those comparisons // assert_ne!(static_mat, typenum_static_mat); @@ -1136,3 +1136,153 @@ fn omatrix_to_string() { (svec.to_string(), smatr.to_string()) ); } + +#[test] +fn column_iteration() { + // dynamic matrix + let dmat = nalgebra::dmatrix![ + 13,14,15; + 23,24,25; + 33,34,35; + ]; + let mut col_iter = dmat.column_iter(); + assert_eq!(col_iter.next(), Some(dmat.column(0))); + assert_eq!(col_iter.next(), Some(dmat.column(1))); + assert_eq!(col_iter.next(), Some(dmat.column(2))); + assert_eq!(col_iter.next(), None); + + // statically sized matrix + let smat: nalgebra::SMatrix = nalgebra::matrix![1.0, 2.0; 3.0, 4.0]; + let mut col_iter = smat.column_iter(); + assert_eq!(col_iter.next(), Some(smat.column(0))); + assert_eq!(col_iter.next(), Some(smat.column(1))); + assert_eq!(col_iter.next(), None); +} + +#[test] +fn column_iteration_mut() { + let mut dmat = nalgebra::dmatrix![ + 13,14,15; + 23,24,25; + 33,34,35; + ]; + let mut cloned = dmat.clone(); + let mut col_iter = dmat.column_iter_mut(); + assert_eq!(col_iter.next(), Some(cloned.column_mut(0))); + assert_eq!(col_iter.next(), Some(cloned.column_mut(1))); + assert_eq!(col_iter.next(), Some(cloned.column_mut(2))); + assert_eq!(col_iter.next(), None); + + // statically sized matrix + let mut smat: nalgebra::SMatrix = nalgebra::matrix![1.0, 2.0; 3.0, 4.0]; + let mut cloned = smat.clone(); + let mut col_iter = smat.column_iter_mut(); + assert_eq!(col_iter.next(), Some(cloned.column_mut(0))); + assert_eq!(col_iter.next(), Some(cloned.column_mut(1))); + assert_eq!(col_iter.next(), None); +} + +#[test] +fn column_iteration_double_ended() { + let dmat = nalgebra::dmatrix![ + 13,14,15,16,17; + 23,24,25,26,27; + 33,34,35,36,37; + ]; + let mut col_iter = dmat.column_iter(); + assert_eq!(col_iter.next(), Some(dmat.column(0))); + assert_eq!(col_iter.next(), Some(dmat.column(1))); + assert_eq!(col_iter.next_back(), Some(dmat.column(4))); + assert_eq!(col_iter.next_back(), Some(dmat.column(3))); + assert_eq!(col_iter.next(), Some(dmat.column(2))); + assert_eq!(col_iter.next_back(), None); + assert_eq!(col_iter.next(), None); +} + +#[test] +fn column_iterator_double_ended_mut() { + let mut dmat = nalgebra::dmatrix![ + 13,14,15,16,17; + 23,24,25,26,27; + 33,34,35,36,37; + ]; + let mut cloned = dmat.clone(); + let mut col_iter_mut = dmat.column_iter_mut(); + assert_eq!(col_iter_mut.next(), Some(cloned.column_mut(0))); + assert_eq!(col_iter_mut.next(), Some(cloned.column_mut(1))); + assert_eq!(col_iter_mut.next_back(), Some(cloned.column_mut(4))); + assert_eq!(col_iter_mut.next_back(), Some(cloned.column_mut(3))); + assert_eq!(col_iter_mut.next(), Some(cloned.column_mut(2))); + assert_eq!(col_iter_mut.next_back(), None); + assert_eq!(col_iter_mut.next(), None); +} + +#[test] +#[cfg(feature = "rayon")] +fn parallel_column_iteration() { + use nalgebra::dmatrix; + use rayon::prelude::*; + let dmat: DMatrix = dmatrix![ + 13.,14.; + 23.,24.; + 33.,34.; + ]; + let cloned = dmat.clone(); + // test that correct columns are iterated over + dmat.par_column_iter().enumerate().for_each(|(idx, col)| { + assert_eq!(col, cloned.column(idx)); + }); + // test that a more complex expression produces the same + // result as the serial equivalent + let par_result: f64 = dmat.par_column_iter().map(|col| col.norm()).sum(); + let ser_result: f64 = dmat.column_iter().map(|col| col.norm()).sum(); + assert_eq!(par_result, ser_result); + + // repeat this test using mutable iterators + let mut dmat = dmat; + dmat.par_column_iter_mut() + .enumerate() + .for_each(|(idx, col)| { + assert_eq!(col, cloned.column(idx)); + }); + + let par_mut_result: f64 = dmat.par_column_iter_mut().map(|col| col.norm()).sum(); + assert_eq!(par_mut_result, ser_result); +} + +#[test] +#[cfg(feature = "rayon")] +fn column_iteration_mut_double_ended() { + let dmat = nalgebra::dmatrix![ + 13,14,15,16,17; + 23,24,25,26,27; + 33,34,35,36,37; + ]; + let cloned = dmat.clone(); + let mut col_iter = dmat.column_iter(); + assert_eq!(col_iter.next(), Some(cloned.column(0))); + assert_eq!(col_iter.next(), Some(cloned.column(1))); + assert_eq!(col_iter.next_back(), Some(cloned.column(4))); + assert_eq!(col_iter.next_back(), Some(cloned.column(3))); + assert_eq!(col_iter.next(), Some(cloned.column(2))); + assert_eq!(col_iter.next_back(), None); + assert_eq!(col_iter.next(), None); +} + +#[test] +#[cfg(feature = "rayon")] +fn parallel_column_iteration_mut() { + use rayon::prelude::*; + let mut first = DMatrix::::zeros(400, 300); + let mut second = DMatrix::::zeros(400, 300); + first + .column_iter_mut() + .enumerate() + .for_each(|(idx, mut col)| col[idx] = 1.); + second + .par_column_iter_mut() + .enumerate() + .for_each(|(idx, mut col)| col[idx] = 1.); + assert_eq!(first, second); + assert_eq!(second, DMatrix::identity(400, 300)); +} diff --git a/tests/core/matrix_slice.rs b/tests/core/matrix_view.rs similarity index 79% rename from tests/core/matrix_slice.rs rename to tests/core/matrix_view.rs index ada5297e..4ce49d02 100644 --- a/tests/core/matrix_slice.rs +++ b/tests/core/matrix_view.rs @@ -1,22 +1,22 @@ #![allow(non_snake_case)] use na::{ - DMatrix, DMatrixSlice, DMatrixSliceMut, Matrix2, Matrix2x3, Matrix2x4, Matrix2x6, Matrix3, - Matrix3x2, Matrix3x4, Matrix4x2, Matrix6x2, MatrixSlice2, MatrixSlice2x3, MatrixSlice2xX, - MatrixSlice3, MatrixSlice3x2, MatrixSliceMut2, MatrixSliceMut2x3, MatrixSliceMut2xX, - MatrixSliceMut3, MatrixSliceMut3x2, MatrixSliceMutXx3, MatrixSliceXx3, RowVector4, Vector3, + DMatrix, DMatrixView, DMatrixViewMut, Matrix2, Matrix2x3, Matrix2x4, Matrix2x6, Matrix3, + Matrix3x2, Matrix3x4, Matrix4x2, Matrix6x2, MatrixView2, MatrixView2x3, MatrixView2xX, + MatrixView3, MatrixView3x2, MatrixViewMut2, MatrixViewMut2x3, MatrixViewMut2xX, MatrixViewMut3, + MatrixViewMut3x2, MatrixViewMutXx3, MatrixViewXx3, RowVector4, Vector3, }; #[test] #[rustfmt::skip] -fn nested_fixed_slices() { +fn nested_fixed_views() { let a = Matrix3x4::new(11.0, 12.0, 13.0, 14.0, 21.0, 22.0, 23.0, 24.0, 31.0, 32.0, 33.0, 34.0); - let s1 = a.fixed_slice::<3, 3>(0, 1); // Simple slice. - let s2 = s1.fixed_slice::<2, 2>(1, 1); // Slice of slice. - let s3 = s1.fixed_slice_with_steps::<2, 2>((0, 0), (1, 1)); // Slice of slice with steps. + let s1 = a.fixed_view::<3, 3>(0, 1); // Simple view. + let s2 = s1.fixed_view::<2, 2>(1, 1); // View of view. + let s3 = s1.fixed_view_with_steps::<2, 2>((0, 0), (1, 1)); // View of view with steps. let expected_owned_s1 = Matrix3::new(12.0, 13.0, 14.0, 22.0, 23.0, 24.0, @@ -35,14 +35,14 @@ fn nested_fixed_slices() { #[test] #[rustfmt::skip] -fn nested_slices() { +fn nested_views() { let a = Matrix3x4::new(11.0, 12.0, 13.0, 14.0, 21.0, 22.0, 23.0, 24.0, 31.0, 32.0, 33.0, 34.0); - let s1 = a.slice((0, 1), (3, 3)); - let s2 = s1.slice((1, 1), (2, 2)); - let s3 = s1.slice_with_steps((0, 0), (2, 2), (1, 1)); + let s1 = a.view((0, 1), (3, 3)); + let s2 = s1.view((1, 1), (2, 2)); + let s3 = s1.view_with_steps((0, 0), (2, 2), (1, 1)); let expected_owned_s1 = DMatrix::from_row_slice(3, 3, &[ 12.0, 13.0, 14.0, 22.0, 23.0, 24.0, @@ -61,14 +61,14 @@ fn nested_slices() { #[test] #[rustfmt::skip] -fn slice_mut() { +fn view_mut() { let mut a = Matrix3x4::new(11.0, 12.0, 13.0, 14.0, 21.0, 22.0, 23.0, 24.0, 31.0, 32.0, 33.0, 34.0); { - // We modify `a` through the mutable slice. - let mut s1 = a.slice_with_steps_mut((0, 1), (2, 2), (1, 1)); + // We modify `a` through the mutable view. + let mut s1 = a.view_with_steps_mut((0, 1), (2, 2), (1, 1)); s1.fill(0.0); } @@ -81,7 +81,7 @@ fn slice_mut() { #[test] #[rustfmt::skip] -fn nested_row_slices() { +fn nested_row_views() { let a = Matrix6x2::new(11.0, 12.0, 21.0, 22.0, 31.0, 32.0, @@ -105,7 +105,7 @@ fn nested_row_slices() { #[test] #[rustfmt::skip] -fn row_slice_mut() { +fn row_view_mut() { let mut a = Matrix6x2::new(11.0, 12.0, 21.0, 22.0, 31.0, 32.0, @@ -113,7 +113,7 @@ fn row_slice_mut() { 51.0, 52.0, 61.0, 62.0); { - // We modify `a` through the mutable slice. + // We modify `a` through the mutable view. let mut s1 = a.rows_with_step_mut(1, 3, 1); s1.fill(0.0); } @@ -130,7 +130,7 @@ fn row_slice_mut() { #[test] #[rustfmt::skip] -fn nested_col_slices() { +fn nested_col_views() { let a = Matrix2x6::new(11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0); let s1 = a.fixed_columns::<4>(1); @@ -148,12 +148,12 @@ fn nested_col_slices() { #[test] #[rustfmt::skip] -fn col_slice_mut() { +fn col_view_mut() { let mut a = Matrix2x6::new(11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0); { - // We modify `a` through the mutable slice. + // We modify `a` through the mutable view. let mut s1 = a.columns_with_step_mut(1, 3, 1); s1.fill(0.0); } @@ -203,7 +203,7 @@ fn columns_range_pair() { #[test] #[rustfmt::skip] -fn new_slice() { +fn new_from_slice() { let data = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ]; @@ -214,13 +214,13 @@ fn new_slice() { let expected3x2 = Matrix3x2::from_column_slice(&data); { - let m2 = MatrixSlice2::from_slice(&data); - let m3 = MatrixSlice3::from_slice(&data); - let m2x3 = MatrixSlice2x3::from_slice(&data); - let m3x2 = MatrixSlice3x2::from_slice(&data); - let m2xX = MatrixSlice2xX::from_slice(&data, 3); - let mXx3 = MatrixSliceXx3::from_slice(&data, 2); - let mXxX = DMatrixSlice::from_slice(&data, 2, 3); + let m2 = MatrixView2::from_slice(&data); + let m3 = MatrixView3::from_slice(&data); + let m2x3 = MatrixView2x3::from_slice(&data); + let m3x2 = MatrixView3x2::from_slice(&data); + let m2xX = MatrixView2xX::from_slice(&data, 3); + let mXx3 = MatrixViewXx3::from_slice(&data, 2); + let mXxX = DMatrixView::from_slice(&data, 2, 3); assert!(m2.eq(&expected2)); assert!(m3.eq(&expected3)); @@ -234,7 +234,7 @@ fn new_slice() { #[test] #[rustfmt::skip] -fn new_slice_mut() { +fn new_from_slice_mut() { let data = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 ]; @@ -252,31 +252,31 @@ fn new_slice_mut() { 9.0, 10.0, 11.0, 12.0 ]; let mut data_mut = data.clone(); - MatrixSliceMut2::from_slice(&mut data_mut).fill(0.0); + MatrixViewMut2::from_slice(&mut data_mut).fill(0.0); assert!(data_mut == expected2); let mut data_mut = data.clone(); - MatrixSliceMut3::from_slice(&mut data_mut).fill(0.0); + MatrixViewMut3::from_slice(&mut data_mut).fill(0.0); assert!(data_mut == expected3); let mut data_mut = data.clone(); - MatrixSliceMut2x3::from_slice(&mut data_mut).fill(0.0); + MatrixViewMut2x3::from_slice(&mut data_mut).fill(0.0); assert!(data_mut == expected2x3); let mut data_mut = data.clone(); - MatrixSliceMut3x2::from_slice(&mut data_mut).fill(0.0); + MatrixViewMut3x2::from_slice(&mut data_mut).fill(0.0); assert!(data_mut == expected3x2); let mut data_mut = data.clone(); - MatrixSliceMut2xX::from_slice(&mut data_mut, 3).fill(0.0); + MatrixViewMut2xX::from_slice(&mut data_mut, 3).fill(0.0); assert!(data_mut == expected2x3); let mut data_mut = data.clone(); - MatrixSliceMutXx3::from_slice(&mut data_mut, 2).fill(0.0); + MatrixViewMutXx3::from_slice(&mut data_mut, 2).fill(0.0); assert!(data_mut == expected2x3); let mut data_mut = data.clone(); - DMatrixSliceMut::from_slice(&mut data_mut, 2, 3).fill(0.0); + DMatrixViewMut::from_slice(&mut data_mut, 2, 3).fill(0.0); assert!(data_mut == expected2x3); } @@ -324,14 +324,14 @@ fn columns_with_step_out_of_bounds() { #[test] #[should_panic] -fn slice_out_of_bounds() { +fn view_out_of_bounds() { let a = Matrix3x4::::zeros(); - a.slice((1, 2), (3, 1)); + a.view((1, 2), (3, 1)); } #[test] #[should_panic] -fn slice_with_steps_out_of_bounds() { +fn view_with_steps_out_of_bounds() { let a = Matrix3x4::::zeros(); - a.slice_with_steps((1, 2), (2, 2), (0, 1)); + a.view_with_steps((1, 2), (2, 2), (0, 1)); } diff --git a/tests/core/mod.rs b/tests/core/mod.rs index 5fb8c82b..0f7ee85b 100644 --- a/tests/core/mod.rs +++ b/tests/core/mod.rs @@ -4,9 +4,12 @@ mod conversion; mod edition; mod empty; mod matrix; -mod matrix_slice; +mod matrix_view; #[cfg(feature = "mint")] mod mint; +mod reshape; +#[cfg(feature = "rkyv-serialize-no-std")] +mod rkyv; mod serde; #[cfg(feature = "compare")] diff --git a/tests/core/reshape.rs b/tests/core/reshape.rs new file mode 100644 index 00000000..3873667f --- /dev/null +++ b/tests/core/reshape.rs @@ -0,0 +1,80 @@ +use na::{ + Const, DMatrix, DMatrixView, DMatrixViewMut, Dyn, Matrix, MatrixView, MatrixViewMut, SMatrix, + SMatrixView, SMatrixViewMut, VecStorage, U3, U4, +}; +use nalgebra_macros::matrix; +use simba::scalar::SupersetOf; + +const MATRIX: SMatrix = matrix![ + 1, 2, 3; + 4, 5, 6; + 7, 8, 9; + 10, 11, 12 +]; + +const RESHAPED_MATRIX: SMatrix = matrix![ + 1, 10, 8, 6; + 4, 2, 11, 9; + 7, 5, 3, 12 +]; + +// Helper alias for making it easier to specify dynamically allocated matrices with +// different dimension types (unlike DMatrix) +type GenericDMatrix = Matrix>; + +#[test] +fn reshape_owned() { + macro_rules! test_reshape { + ($in_matrix:ty => $out_matrix:ty, $rows:expr, $cols:expr) => {{ + // This is a pretty weird way to convert, but Matrix implements SubsetOf + let matrix: $in_matrix = MATRIX.to_subset().unwrap(); + let reshaped: $out_matrix = matrix.reshape_generic($rows, $cols); + assert_eq!(reshaped, RESHAPED_MATRIX); + }}; + } + + test_reshape!(SMatrix<_, 4, 3> => SMatrix<_, 3, 4>, U3, U4); + test_reshape!(GenericDMatrix<_, U4, Dyn> => GenericDMatrix<_, Dyn, Dyn>, Dyn(3), Dyn(4)); + test_reshape!(GenericDMatrix<_, U4, Dyn> => GenericDMatrix<_, U3, Dyn>, U3, Dyn(4)); + test_reshape!(GenericDMatrix<_, U4, Dyn> => GenericDMatrix<_, Dyn, U4>, Dyn(3), U4); + test_reshape!(DMatrix<_> => DMatrix<_>, Dyn(3), Dyn(4)); +} + +#[test] +fn reshape_slice() { + macro_rules! test_reshape { + ($in_slice:ty => $out_slice:ty, $rows:expr, $cols:expr) => { + // We test both that types check out by being explicit about types + // and the actual contents of the matrix + { + // By constructing the slice from a mutable reference we can obtain *either* + // an immutable slice or a mutable slice, which simplifies the testing of both + // types of mutability + let mut source_matrix = MATRIX.clone(); + let slice: $in_slice = Matrix::from(&mut source_matrix); + let reshaped: $out_slice = slice.reshape_generic($rows, $cols); + assert_eq!(reshaped, RESHAPED_MATRIX); + } + }; + } + + // Static "source slice" + test_reshape!(SMatrixView<_, 4, 3> => SMatrixView<_, 3, 4>, U3, U4); + test_reshape!(SMatrixView<_, 4, 3> => DMatrixView<_>, Dyn(3), Dyn(4)); + test_reshape!(SMatrixView<_, 4, 3> => MatrixView<_, Const<3>, Dyn>, U3, Dyn(4)); + test_reshape!(SMatrixView<_, 4, 3> => MatrixView<_, Dyn, Const<4>>, Dyn(3), U4); + test_reshape!(SMatrixViewMut<_, 4, 3> => SMatrixViewMut<_, 3, 4>, U3, U4); + test_reshape!(SMatrixViewMut<_, 4, 3> => DMatrixViewMut<_>, Dyn(3), Dyn(4)); + test_reshape!(SMatrixViewMut<_, 4, 3> => MatrixViewMut<_, Const<3>, Dyn>, U3, Dyn(4)); + test_reshape!(SMatrixViewMut<_, 4, 3> => MatrixViewMut<_, Dyn, Const<4>>, Dyn(3), U4); + + // Dyn "source slice" + test_reshape!(DMatrixView<_> => SMatrixView<_, 3, 4>, U3, U4); + test_reshape!(DMatrixView<_> => DMatrixView<_>, Dyn(3), Dyn(4)); + test_reshape!(DMatrixView<_> => MatrixView<_, Const<3>, Dyn>, U3, Dyn(4)); + test_reshape!(DMatrixView<_> => MatrixView<_, Dyn, Const<4>>, Dyn(3), U4); + test_reshape!(DMatrixViewMut<_> => SMatrixViewMut<_, 3, 4>, U3, U4); + test_reshape!(DMatrixViewMut<_> => DMatrixViewMut<_>, Dyn(3), Dyn(4)); + test_reshape!(DMatrixViewMut<_> => MatrixViewMut<_, Const<3>, Dyn>, U3, Dyn(4)); + test_reshape!(DMatrixViewMut<_> => MatrixViewMut<_, Dyn, Const<4>>, Dyn(3), U4); +} diff --git a/tests/core/rkyv.rs b/tests/core/rkyv.rs new file mode 100644 index 00000000..ffe9ed30 --- /dev/null +++ b/tests/core/rkyv.rs @@ -0,0 +1,62 @@ +#![cfg(feature = "rkyv-serialize")] + +use na::{ + Isometry3, IsometryMatrix2, IsometryMatrix3, Matrix3x4, Point2, Point3, Quaternion, Rotation2, + Rotation3, Similarity3, SimilarityMatrix2, SimilarityMatrix3, Translation2, Translation3, +}; +use rand; +use rkyv::{Deserialize, Infallible}; + +macro_rules! test_rkyv_same_type( + ($($test: ident, $ty: ident);* $(;)*) => {$( + #[test] + fn $test() { + let value: $ty = rand::random(); + let bytes = rkyv::to_bytes::<_, 256>(&value).unwrap(); + + let archived = rkyv::check_archived_root::<$ty>(&bytes[..]).unwrap(); + // Compare archived and non-archived + assert_eq!(archived, &value); + + // Make sure Debug implementations are the same for Archived and non-Archived versions. + assert_eq!(format!("{:?}", value), format!("{:?}", archived)); + } + )*} +); +macro_rules! test_rkyv_diff_type( + ($($test: ident, $ty: ident);* $(;)*) => {$( + #[test] + fn $test() { + let value: $ty = Default::default(); + let bytes = rkyv::to_bytes::<_, 256>(&value).unwrap(); + + let archived = rkyv::check_archived_root::<$ty>(&bytes[..]).unwrap(); + let deserialized: $ty = archived.deserialize(&mut Infallible).unwrap(); + assert_eq!(deserialized, value); + } + )*} +); + +// Tests to make sure +test_rkyv_same_type!( + rkyv_same_type_matrix3x4, Matrix3x4; + rkyv_same_type_point3, Point3; + rkyv_same_type_translation3, Translation3; + rkyv_same_type_rotation3, Rotation3; + rkyv_same_type_isometry3, Isometry3; + rkyv_same_type_isometry_matrix3, IsometryMatrix3; + rkyv_same_type_similarity3, Similarity3; + rkyv_same_type_similarity_matrix3, SimilarityMatrix3; + rkyv_same_type_quaternion, Quaternion; + rkyv_same_type_point2, Point2; + rkyv_same_type_translation2, Translation2; + rkyv_same_type_rotation2, Rotation2; + // rkyv_same_type_isometry2, Isometry2; + rkyv_same_type_isometry_matrix2, IsometryMatrix2; + // rkyv_same_type_similarity2, Similarity2; + rkyv_same_type_similarity_matrix2, SimilarityMatrix2; +); + +test_rkyv_diff_type! { + rkyv_diff_type_matrix3x4, Matrix3x4; +} diff --git a/tests/linalg/cholesky.rs b/tests/linalg/cholesky.rs index 891e54ca..a73fa947 100644 --- a/tests/linalg/cholesky.rs +++ b/tests/linalg/cholesky.rs @@ -15,7 +15,7 @@ macro_rules! gen_tests( ($module: ident, $scalar: ty) => { mod $module { use na::debug::RandomSDP; - use na::dimension::{Const, Dynamic}; + use na::dimension::{Const, Dyn}; use na::{DMatrix, DVector, Matrix4x3, Vector4}; use rand::random; use simba::scalar::ComplexField; @@ -28,7 +28,7 @@ macro_rules! gen_tests( proptest! { #[test] fn cholesky(n in PROPTEST_MATRIX_DIM) { - let m = RandomSDP::new(Dynamic::new(n), || random::<$scalar>().0).unwrap(); + let m = RandomSDP::new(Dyn(n), || random::<$scalar>().0).unwrap(); let l = m.clone().cholesky().unwrap().unpack(); prop_assert!(relative_eq!(m, &l * l.adjoint(), epsilon = 1.0e-7)); } @@ -44,7 +44,7 @@ macro_rules! gen_tests( #[test] fn cholesky_solve(n in PROPTEST_MATRIX_DIM, nb in PROPTEST_MATRIX_DIM) { - let m = RandomSDP::new(Dynamic::new(n), || random::<$scalar>().0).unwrap(); + let m = RandomSDP::new(Dyn(n), || random::<$scalar>().0).unwrap(); let chol = m.clone().cholesky().unwrap(); let b1 = DVector::<$scalar>::new_random(n).map(|e| e.0); @@ -73,7 +73,7 @@ macro_rules! gen_tests( #[test] fn cholesky_inverse(n in PROPTEST_MATRIX_DIM) { - let m = RandomSDP::new(Dynamic::new(n), || random::<$scalar>().0).unwrap(); + let m = RandomSDP::new(Dyn(n), || random::<$scalar>().0).unwrap(); let m1 = m.clone().cholesky().unwrap().inverse(); let id1 = &m * &m1; let id2 = &m1 * &m; @@ -93,7 +93,7 @@ macro_rules! gen_tests( #[test] fn cholesky_determinant(n in PROPTEST_MATRIX_DIM) { - let m = RandomSDP::new(Dynamic::new(n), || random::<$scalar>().0).unwrap(); + let m = RandomSDP::new(Dyn(n), || random::<$scalar>().0).unwrap(); let lu_det = m.clone().lu().determinant(); assert_relative_eq!(lu_det.imaginary(), 0., epsilon = 1.0e-7); let chol_det = m.cholesky().unwrap().determinant(); @@ -137,7 +137,7 @@ macro_rules! gen_tests( fn cholesky_insert_column(n in PROPTEST_MATRIX_DIM) { let n = n.max(1).min(10); let j = random::() % n; - let m_updated = RandomSDP::new(Dynamic::new(n), || random::<$scalar>().0).unwrap(); + let m_updated = RandomSDP::new(Dyn(n), || random::<$scalar>().0).unwrap(); // build m and col from m_updated let col = m_updated.column(j); @@ -154,7 +154,7 @@ macro_rules! gen_tests( fn cholesky_remove_column(n in PROPTEST_MATRIX_DIM) { let n = n.max(1).min(10); let j = random::() % n; - let m = RandomSDP::new(Dynamic::new(n), || random::<$scalar>().0).unwrap(); + let m = RandomSDP::new(Dyn(n), || random::<$scalar>().0).unwrap(); // remove column from cholesky decomposition and rebuild m let chol = m.clone().cholesky().unwrap().remove_column(j); diff --git a/tests/linalg/convolution.rs b/tests/linalg/convolution.rs index b2e151d3..eba8b84d 100644 --- a/tests/linalg/convolution.rs +++ b/tests/linalg/convolution.rs @@ -16,7 +16,7 @@ fn convolve_same_check() { assert!(relative_eq!(actual_s, expected_s, epsilon = 1.0e-7)); - // Dynamic Tests + // Dyn Tests let actual_d = DVector::from_vec(vec![1.0, 4.0, 7.0, 10.0]); let expected_d = DVector::from_vec(vec![1.0, 2.0, 3.0, 4.0]) .convolve_same(DVector::from_vec(vec![1.0, 2.0])); @@ -54,7 +54,7 @@ fn convolve_full_check() { assert!(relative_eq!(actual_s, expected_s, epsilon = 1.0e-7)); - // Dynamic Tests + // Dyn Tests let actual_d = DVector::from_vec(vec![1.0, 4.0, 7.0, 10.0, 8.0]); let expected_d = DVector::from_vec(vec![1.0, 2.0, 3.0, 4.0]) .convolve_full(DVector::from_vec(vec![1.0, 2.0])); @@ -90,7 +90,7 @@ fn convolve_valid_check() { assert!(relative_eq!(actual_s, expected_s, epsilon = 1.0e-7)); - // Dynamic Tests + // Dyn Tests let actual_d = DVector::from_vec(vec![4.0, 7.0, 10.0]); let expected_d = DVector::from_vec(vec![1.0, 2.0, 3.0, 4.0]) .convolve_valid(DVector::from_vec(vec![1.0, 2.0])); diff --git a/tests/linalg/full_piv_lu.rs b/tests/linalg/full_piv_lu.rs index 7ac95b0f..24e3bb48 100644 --- a/tests/linalg/full_piv_lu.rs +++ b/tests/linalg/full_piv_lu.rs @@ -253,7 +253,7 @@ fn remove_columns() { assert_eq!(m.remove_fixed_columns::(2), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, U3, Dynamic, _> = m.remove_columns(3, 2); + let computed: Matrix<_, U3, Dyn, _> = m.remove_columns(3, 2); assert!(computed.eq(&expected2)); } @@ -309,7 +309,7 @@ fn remove_rows() { assert_eq!(m.remove_fixed_rows::(2), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, Dynamic, U3, _> = m.remove_rows(3, 2); + let computed: Matrix<_, Dyn, U3, _> = m.remove_rows(3, 2); assert!(computed.eq(&expected2)); } @@ -374,7 +374,7 @@ fn insert_columns() { assert_eq!(m.insert_fixed_columns::(2, 0), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, U5, Dynamic, _> = m.insert_columns(3, 2, 0); + let computed: Matrix<_, U5, Dyn, _> = m.insert_columns(3, 2, 0); assert!(computed.eq(&expected2)); } @@ -434,7 +434,7 @@ fn insert_rows() { assert_eq!(m.insert_fixed_rows::<2>(2, 0), expected3); // The following is just to verify that the return type dimensions is correctly inferred. - let computed: Matrix<_, Dynamic, U5, _> = m.insert_rows(3, 2, 0); + let computed: Matrix<_, Dyn, U5, _> = m.insert_rows(3, 2, 0); assert!(computed.eq(&expected2)); } diff --git a/tests/proptest/mod.rs b/tests/proptest/mod.rs index ec2e2c7b..cedfae84 100644 --- a/tests/proptest/mod.rs +++ b/tests/proptest/mod.rs @@ -101,11 +101,11 @@ pub fn dvector() -> impl Strategy> { pub fn dmatrix_( scalar_strategy: ScalarStrategy, -) -> impl Strategy> +) -> impl Strategy> where ScalarStrategy: Strategy + Clone + 'static, ScalarStrategy::Value: Scalar, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { matrix(scalar_strategy, PROPTEST_MATRIX_DIM, PROPTEST_MATRIX_DIM) } @@ -114,7 +114,7 @@ where // where // RangeInclusive: Strategy, // T: Scalar + PartialEq + Copy, -// DefaultAllocator: Allocator, +// DefaultAllocator: Allocator, // { // vector(range, PROPTEST_MATRIX_DIM) // } @@ -213,9 +213,9 @@ fn test_matrix_output_types() { // Test that the dimension types are correct for the given inputs let _: MatrixStrategy<_, U3, U4> = matrix(-5..5, Const::<3>, Const::<4>); let _: MatrixStrategy<_, U3, U3> = matrix(-5..5, Const::<3>, Const::<3>); - let _: MatrixStrategy<_, U3, Dynamic> = matrix(-5..5, Const::<3>, 1..=5); - let _: MatrixStrategy<_, Dynamic, U3> = matrix(-5..5, 1..=5, Const::<3>); - let _: MatrixStrategy<_, Dynamic, Dynamic> = matrix(-5..5, 1..=5, 1..=5); + let _: MatrixStrategy<_, U3, Dyn> = matrix(-5..5, Const::<3>, 1..=5); + let _: MatrixStrategy<_, Dyn, U3> = matrix(-5..5, 1..=5, Const::<3>); + let _: MatrixStrategy<_, Dyn, Dyn> = matrix(-5..5, 1..=5, 1..=5); } // Below we have some tests to ensure that specific instances of OMatrix are usable @@ -225,10 +225,10 @@ proptest! { fn ensure_arbitrary_test_compiles_matrix3(_: Matrix3) {} #[test] - fn ensure_arbitrary_test_compiles_matrixmn_u3_dynamic(_: OMatrix) {} + fn ensure_arbitrary_test_compiles_matrixmn_u3_dynamic(_: OMatrix) {} #[test] - fn ensure_arbitrary_test_compiles_matrixmn_dynamic_u3(_: OMatrix) {} + fn ensure_arbitrary_test_compiles_matrixmn_dynamic_u3(_: OMatrix) {} #[test] fn ensure_arbitrary_test_compiles_dmatrix(_: DMatrix) {}