From 57123ed6aa0bf4265e711fbd1303c898a4a6dbbd Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Sun, 2 Dec 2018 15:00:08 -0500 Subject: [PATCH] Overloaded Indexing --- nalgebra-lapack/src/cholesky.rs | 2 +- src/base/blas.rs | 42 +- src/base/cg.rs | 2 +- src/base/componentwise.rs | 12 +- src/base/construction.rs | 12 +- src/base/conversion.rs | 4 +- src/base/edition.rs | 16 +- src/base/indexing.rs | 661 +++++++++++++++++++++++++++++++ src/base/matrix.rs | 81 ++-- src/base/mod.rs | 1 + src/base/ops.rs | 22 +- src/geometry/transform_ops.rs | 2 +- src/geometry/unit_complex_ops.rs | 16 +- src/linalg/cholesky.rs | 6 +- src/linalg/determinant.rs | 28 +- src/linalg/full_piv_lu.rs | 2 +- src/linalg/inverse.rs | 56 +-- src/linalg/lu.rs | 2 +- src/linalg/solve.rs | 8 +- 19 files changed, 808 insertions(+), 167 deletions(-) create mode 100644 src/base/indexing.rs diff --git a/nalgebra-lapack/src/cholesky.rs b/nalgebra-lapack/src/cholesky.rs index 7615a899..3976373d 100644 --- a/nalgebra-lapack/src/cholesky.rs +++ b/nalgebra-lapack/src/cholesky.rs @@ -160,7 +160,7 @@ where DefaultAllocator: Allocator // Copy lower triangle to upper triangle. for i in 0..dim { for j in i + 1..dim { - unsafe { *self.l.get_unchecked_mut(i, j) = *self.l.get_unchecked(j, i) }; + unsafe { *self.l.get_unchecked_mut((i, j)) = *self.l.get_unchecked((j, i)) }; } } diff --git a/src/base/blas.rs b/src/base/blas.rs index 073f519b..1379db19 100644 --- a/src/base/blas.rs +++ b/src/base/blas.rs @@ -142,12 +142,12 @@ impl> Matri pub fn iamax_full(&self) -> (usize, usize) { assert!(!self.is_empty(), "The input matrix must not be empty."); - let mut the_max = unsafe { self.get_unchecked(0, 0).abs() }; + let mut the_max = unsafe { self.get_unchecked((0, 0)).abs() }; let mut the_ij = (0, 0); for j in 0..self.ncols() { for i in 0..self.nrows() { - let val = unsafe { self.get_unchecked(i, j).abs() }; + let val = unsafe { self.get_unchecked((i, j)).abs() }; if val > the_max { the_max = val; @@ -197,27 +197,27 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul // because the `for` loop below won't be very efficient on those. if (R::is::() || R2::is::()) && (C::is::() || C2::is::()) { unsafe { - let a = *self.get_unchecked(0, 0) * *rhs.get_unchecked(0, 0); - let b = *self.get_unchecked(1, 0) * *rhs.get_unchecked(1, 0); + let a = *self.get_unchecked((0, 0)) * *rhs.get_unchecked((0, 0)); + let b = *self.get_unchecked((1, 0)) * *rhs.get_unchecked((1, 0)); return a + b; } } if (R::is::() || R2::is::()) && (C::is::() || C2::is::()) { unsafe { - let a = *self.get_unchecked(0, 0) * *rhs.get_unchecked(0, 0); - let b = *self.get_unchecked(1, 0) * *rhs.get_unchecked(1, 0); - let c = *self.get_unchecked(2, 0) * *rhs.get_unchecked(2, 0); + let a = *self.get_unchecked((0, 0)) * *rhs.get_unchecked((0, 0)); + let b = *self.get_unchecked((1, 0)) * *rhs.get_unchecked((1, 0)); + let c = *self.get_unchecked((2, 0)) * *rhs.get_unchecked((2, 0)); return a + b + c; } } if (R::is::() || R2::is::()) && (C::is::() || C2::is::()) { unsafe { - let mut a = *self.get_unchecked(0, 0) * *rhs.get_unchecked(0, 0); - let mut b = *self.get_unchecked(1, 0) * *rhs.get_unchecked(1, 0); - let c = *self.get_unchecked(2, 0) * *rhs.get_unchecked(2, 0); - let d = *self.get_unchecked(3, 0) * *rhs.get_unchecked(3, 0); + let mut a = *self.get_unchecked((0, 0)) * *rhs.get_unchecked((0, 0)); + let mut b = *self.get_unchecked((1, 0)) * *rhs.get_unchecked((1, 0)); + let c = *self.get_unchecked((2, 0)) * *rhs.get_unchecked((2, 0)); + let d = *self.get_unchecked((3, 0)) * *rhs.get_unchecked((3, 0)); a += c; b += d; @@ -257,14 +257,14 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul acc7 = N::zero(); while self.nrows() - i >= 8 { - acc0 += unsafe { *self.get_unchecked(i + 0, j) * *rhs.get_unchecked(i + 0, j) }; - acc1 += unsafe { *self.get_unchecked(i + 1, j) * *rhs.get_unchecked(i + 1, j) }; - acc2 += unsafe { *self.get_unchecked(i + 2, j) * *rhs.get_unchecked(i + 2, j) }; - acc3 += unsafe { *self.get_unchecked(i + 3, j) * *rhs.get_unchecked(i + 3, j) }; - acc4 += unsafe { *self.get_unchecked(i + 4, j) * *rhs.get_unchecked(i + 4, j) }; - acc5 += unsafe { *self.get_unchecked(i + 5, j) * *rhs.get_unchecked(i + 5, j) }; - acc6 += unsafe { *self.get_unchecked(i + 6, j) * *rhs.get_unchecked(i + 6, j) }; - acc7 += unsafe { *self.get_unchecked(i + 7, j) * *rhs.get_unchecked(i + 7, j) }; + acc0 += unsafe { *self.get_unchecked((i + 0, j)) * *rhs.get_unchecked((i + 0, j)) }; + acc1 += unsafe { *self.get_unchecked((i + 1, j)) * *rhs.get_unchecked((i + 1, j)) }; + acc2 += unsafe { *self.get_unchecked((i + 2, j)) * *rhs.get_unchecked((i + 2, j)) }; + acc3 += unsafe { *self.get_unchecked((i + 3, j)) * *rhs.get_unchecked((i + 3, j)) }; + acc4 += unsafe { *self.get_unchecked((i + 4, j)) * *rhs.get_unchecked((i + 4, j)) }; + acc5 += unsafe { *self.get_unchecked((i + 5, j)) * *rhs.get_unchecked((i + 5, j)) }; + acc6 += unsafe { *self.get_unchecked((i + 6, j)) * *rhs.get_unchecked((i + 6, j)) }; + acc7 += unsafe { *self.get_unchecked((i + 7, j)) * *rhs.get_unchecked((i + 7, j)) }; i += 8; } @@ -274,7 +274,7 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul res += acc3 + acc7; for k in i..self.nrows() { - res += unsafe { *self.get_unchecked(k, j) * *rhs.get_unchecked(k, j) } + res += unsafe { *self.get_unchecked((k, j)) * *rhs.get_unchecked((k, j)) } } } @@ -314,7 +314,7 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul for j in 0..self.nrows() { for i in 0..self.ncols() { - res += unsafe { *self.get_unchecked(j, i) * *rhs.get_unchecked(i, j) } + res += unsafe { *self.get_unchecked((j, i)) * *rhs.get_unchecked((i, j)) } } } diff --git a/src/base/cg.rs b/src/base/cg.rs index ba5dffa3..357e21bf 100644 --- a/src/base/cg.rs +++ b/src/base/cg.rs @@ -348,7 +348,7 @@ where DefaultAllocator: Allocator let translation = self.fixed_slice::, U1>(0, D::dim() - 1); let normalizer = self.fixed_slice::>(D::dim() - 1, 0); let n = normalizer.tr_dot(&pt.coords) - + unsafe { *self.get_unchecked(D::dim() - 1, D::dim() - 1) }; + + unsafe { *self.get_unchecked((D::dim() - 1, D::dim() - 1)) }; if !n.is_zero() { return transform * (pt / n) + translation; diff --git a/src/base/componentwise.rs b/src/base/componentwise.rs index 958feb0a..195bc29a 100644 --- a/src/base/componentwise.rs +++ b/src/base/componentwise.rs @@ -61,7 +61,7 @@ macro_rules! component_binop_impl( for j in 0 .. res.ncols() { for i in 0 .. res.nrows() { unsafe { - res.get_unchecked_mut(i, j).$op_assign(*rhs.get_unchecked(i, j)); + res.get_unchecked_mut((i, j)).$op_assign(*rhs.get_unchecked((i, j))); } } } @@ -89,8 +89,8 @@ macro_rules! component_binop_impl( for j in 0 .. self.ncols() { for i in 0 .. self.nrows() { unsafe { - let res = alpha * a.get_unchecked(i, j).$op(*b.get_unchecked(i, j)); - *self.get_unchecked_mut(i, j) = res; + let res = alpha * a.get_unchecked((i, j)).$op(*b.get_unchecked((i, j))); + *self.get_unchecked_mut((i, j)) = res; } } } @@ -99,8 +99,8 @@ macro_rules! component_binop_impl( for j in 0 .. self.ncols() { for i in 0 .. self.nrows() { unsafe { - let res = alpha * a.get_unchecked(i, j).$op(*b.get_unchecked(i, j)); - *self.get_unchecked_mut(i, j) = beta * *self.get_unchecked(i, j) + res; + let res = alpha * a.get_unchecked((i, j)).$op(*b.get_unchecked((i, j))); + *self.get_unchecked_mut((i, j)) = beta * *self.get_unchecked((i, j)) + res; } } } @@ -121,7 +121,7 @@ macro_rules! component_binop_impl( for j in 0 .. self.ncols() { for i in 0 .. self.nrows() { unsafe { - self.get_unchecked_mut(i, j).$op_assign(*rhs.get_unchecked(i, j)); + self.get_unchecked_mut((i, j)).$op_assign(*rhs.get_unchecked((i, j))); } } } diff --git a/src/base/construction.rs b/src/base/construction.rs index 7a12dc0f..8adc90c1 100644 --- a/src/base/construction.rs +++ b/src/base/construction.rs @@ -82,7 +82,7 @@ where DefaultAllocator: Allocator for i in 0..nrows.value() { for j in 0..ncols.value() { - unsafe { *res.get_unchecked_mut(i, j) = *iter.next().unwrap() } + unsafe { *res.get_unchecked_mut((i, j)) = *iter.next().unwrap() } } } @@ -105,7 +105,7 @@ where DefaultAllocator: Allocator for j in 0..ncols.value() { for i in 0..nrows.value() { - unsafe { *res.get_unchecked_mut(i, j) = f(i, j) } + unsafe { *res.get_unchecked_mut((i, j)) = f(i, j) } } } @@ -132,7 +132,7 @@ where DefaultAllocator: Allocator let mut res = Self::zeros_generic(nrows, ncols); for i in 0..::min(nrows.value(), ncols.value()) { - unsafe { *res.get_unchecked_mut(i, i) = elt } + unsafe { *res.get_unchecked_mut((i, i)) = elt } } res @@ -152,7 +152,7 @@ where DefaultAllocator: Allocator ); for (i, elt) in elts.iter().enumerate() { - unsafe { *res.get_unchecked_mut(i, i) = *elt } + unsafe { *res.get_unchecked_mut((i, i)) = *elt } } res @@ -313,7 +313,7 @@ where for i in 0..diag.len() { unsafe { - *res.get_unchecked_mut(i, i) = *diag.vget_unchecked(i); + *res.get_unchecked_mut((i, i)) = *diag.vget_unchecked(i); } } @@ -791,7 +791,7 @@ macro_rules! componentwise_constructors_impl( pub fn new($($args: N),*) -> Self { unsafe { let mut res = Self::new_uninitialized(); - $( *res.get_unchecked_mut($irow, $icol) = $args; )* + $( *res.get_unchecked_mut(($irow, $icol)) = $args; )* res } diff --git a/src/base/conversion.rs b/src/base/conversion.rs index b9acd66b..2e5ca9df 100644 --- a/src/base/conversion.rs +++ b/src/base/conversion.rs @@ -42,7 +42,7 @@ where let mut res = unsafe { MatrixMN::::new_uninitialized_generic(nrows2, ncols2) }; for i in 0..nrows { for j in 0..ncols { - unsafe { *res.get_unchecked_mut(i, j) = N2::from_subset(self.get_unchecked(i, j)) } + unsafe { *res.get_unchecked_mut((i, j)) = N2::from_subset(self.get_unchecked((i, j))) } } } @@ -63,7 +63,7 @@ where let mut res = Self::new_uninitialized_generic(nrows, ncols); for i in 0..nrows2 { for j in 0..ncols2 { - *res.get_unchecked_mut(i, j) = m.get_unchecked(i, j).to_subset_unchecked() + *res.get_unchecked_mut((i, j)) = m.get_unchecked((i, j)).to_subset_unchecked() } } diff --git a/src/base/edition.rs b/src/base/edition.rs index 445a4ffd..8b6581e8 100644 --- a/src/base/edition.rs +++ b/src/base/edition.rs @@ -58,7 +58,7 @@ impl> Matrix { let n = cmp::min(nrows, ncols); for i in 0..n { - unsafe { *self.get_unchecked_mut(i, i) = val } + unsafe { *self.get_unchecked_mut((i, i)) = val } } } @@ -67,7 +67,7 @@ impl> Matrix { pub fn fill_row(&mut self, i: usize, val: N) { assert!(i < self.nrows(), "Row index out of bounds."); for j in 0..self.ncols() { - unsafe { *self.get_unchecked_mut(i, j) = val } + unsafe { *self.get_unchecked_mut((i, j)) = val } } } @@ -76,7 +76,7 @@ impl> Matrix { pub fn fill_column(&mut self, j: usize, val: N) { assert!(j < self.ncols(), "Row index out of bounds."); for i in 0..self.nrows() { - unsafe { *self.get_unchecked_mut(i, j) = val } + unsafe { *self.get_unchecked_mut((i, j)) = val } } } @@ -93,7 +93,7 @@ impl> Matrix { assert_eq!(diag.len(), min_nrows_ncols, "Mismatched dimensions."); for i in 0..min_nrows_ncols { - unsafe { *self.get_unchecked_mut(i, i) = *diag.vget_unchecked(i) } + unsafe { *self.get_unchecked_mut((i, i)) = *diag.vget_unchecked(i) } } } @@ -128,7 +128,7 @@ impl> Matrix { pub fn fill_lower_triangle(&mut self, val: N, shift: usize) { for j in 0..self.ncols() { for i in (j + shift)..self.nrows() { - unsafe { *self.get_unchecked_mut(i, j) = val } + unsafe { *self.get_unchecked_mut((i, j)) = val } } } } @@ -146,7 +146,7 @@ impl> Matrix { // FIXME: is there a more efficient way to avoid the min ? // (necessary for rectangular matrices) for i in 0..cmp::min(j + 1 - shift, self.nrows()) { - unsafe { *self.get_unchecked_mut(i, j) = val } + unsafe { *self.get_unchecked_mut((i, j)) = val } } } } @@ -191,7 +191,7 @@ impl> Matrix { for j in 0..dim { for i in j + 1..dim { unsafe { - *self.get_unchecked_mut(i, j) = *self.get_unchecked(j, i); + *self.get_unchecked_mut((i, j)) = *self.get_unchecked((j, i)); } } } @@ -206,7 +206,7 @@ impl> Matrix { for j in 1..self.ncols() { for i in 0..j { unsafe { - *self.get_unchecked_mut(i, j) = *self.get_unchecked(j, i); + *self.get_unchecked_mut((i, j)) = *self.get_unchecked((j, i)); } } } diff --git a/src/base/indexing.rs b/src/base/indexing.rs new file mode 100644 index 00000000..f2715bf9 --- /dev/null +++ b/src/base/indexing.rs @@ -0,0 +1,661 @@ +//! Indexing + +use base::{Dim, Dynamic, Matrix, MatrixSlice, MatrixSliceMut, Scalar, U1}; +use base::storage::{Storage, StorageMut}; + +use std::ops; + +// N.B.: Not a public trait! +trait DimRange +{ + ///asdf + type Length: Dim; + + /// The lower bound of the range, inclusive. + fn lower(&self, dimension: D) -> usize; + + /// The number of elements included in the range. + fn length(&self, dimension: D) -> Self::Length; + + /// Produces true if `Self` is contained within `dimension`. + fn contained_by(&self, dimension: D) -> bool; +} + +impl DimRange for usize { + type Length = U1; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + *self + } + + #[inline(always)] + fn length(&self, _: D) -> Self::Length { + U1 + } + + #[inline(always)] + fn contained_by(&self, dimension: D) -> bool { + *self < dimension.value() + } +} + +#[test] +fn dimrange_usize() { + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&0, U0), false); + assert_eq!(DimRange::contained_by(&0, U1), true); +} + +impl DimRange for ops::Range { + type Length = Dynamic; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + self.start + } + + #[inline(always)] + fn length(&self, _: D) -> Self::Length { + Dynamic::new(self.end.saturating_sub(self.start)) + } + + #[inline(always)] + fn contained_by(&self, dimension: D) -> bool { + (self.start < dimension.value()) && (self.end <= dimension.value()) + } +} + +#[test] +fn dimrange_range_usize() { + use std::usize::MAX; + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&(0..0), U0), false); + assert_eq!(DimRange::contained_by(&(0..1), U0), false); + assert_eq!(DimRange::contained_by(&(0..1), U1), true); + assert_eq!(DimRange::contained_by(&((MAX - 1)..MAX), Dynamic::new(MAX)), true); + assert_eq!(DimRange::length(&((MAX - 1)..MAX), Dynamic::new(MAX)), Dynamic::new(1)); + assert_eq!(DimRange::length(&(MAX..(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(0)); + assert_eq!(DimRange::length(&(MAX..MAX), Dynamic::new(MAX)), Dynamic::new(0)); +} + +impl DimRange for ops::RangeFrom { + type Length = Dynamic; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + self.start + } + + #[inline(always)] + fn length(&self, dimension: D) -> Self::Length { + (self.start..dimension.value()).length(dimension) + } + + #[inline(always)] + fn contained_by(&self, dimension: D) -> bool { + self.start < dimension.value() + } +} + +#[test] +fn dimrange_rangefrom_usize() { + use std::usize::MAX; + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&(0..), U0), false); + assert_eq!(DimRange::contained_by(&(0..), U0), false); + assert_eq!(DimRange::contained_by(&(0..), U1), true); + assert_eq!(DimRange::contained_by(&((MAX - 1)..), Dynamic::new(MAX)), true); + assert_eq!(DimRange::length(&((MAX - 1)..), Dynamic::new(MAX)), Dynamic::new(1)); + assert_eq!(DimRange::length(&(MAX..), Dynamic::new(MAX)), Dynamic::new(0)); +} + +impl DimRange for ops::RangeFull { + type Length = D; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + 0 + } + + #[inline(always)] + fn length(&self, dimension: D) -> Self::Length { + dimension + } + + #[inline(always)] + fn contained_by(&self, _: D) -> bool { + true + } +} + +#[test] +fn dimrange_rangefull() { + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&(..), U0), true); + assert_eq!(DimRange::length(&(..), U1), U1); +} + +impl DimRange for ops::RangeInclusive { + type Length = Dynamic; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + *self.start() + } + + #[inline(always)] + fn length(&self, _: D) -> Self::Length { + Dynamic::new( + if self.end() < self.start() { + 0 + } else { + self.end().wrapping_sub(self.start().wrapping_sub(1)) + }) + } + + #[inline(always)] + fn contained_by(&self, dimension: D) -> bool { + (*self.start() < dimension.value()) && (*self.end() < dimension.value()) + } +} + +#[test] +fn dimrange_rangeinclusive_usize() { + use std::usize::MAX; + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&(0..=0), U0), false); + assert_eq!(DimRange::contained_by(&(0..=0), U1), true); + assert_eq!(DimRange::contained_by(&(MAX..=MAX), Dynamic::new(MAX)), false); + assert_eq!(DimRange::contained_by(&((MAX-1)..=MAX), Dynamic::new(MAX)), false); + assert_eq!(DimRange::contained_by(&((MAX-1)..=(MAX-1)), Dynamic::new(MAX)), true); + assert_eq!(DimRange::length(&(0..=0), U1), Dynamic::new(1)); + assert_eq!(DimRange::length(&((MAX - 1)..=MAX), Dynamic::new(MAX)), Dynamic::new(2)); + assert_eq!(DimRange::length(&(MAX..=(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(0)); + assert_eq!(DimRange::length(&(MAX..=MAX), Dynamic::new(MAX)), Dynamic::new(1)); +} + +impl DimRange for ops::RangeTo +{ + type Length = Dynamic; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + 0 + } + + #[inline(always)] + fn length(&self, _: D) -> Self::Length { + Dynamic::new(self.end) + } + + #[inline(always)] + fn contained_by(&self, dimension: D) -> bool { + self.end <= dimension.value() + } +} + +#[test] +fn dimrange_rangeto_usize() { + use std::usize::MAX; + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&(..0), U0), true); + assert_eq!(DimRange::contained_by(&(..1), U0), false); + assert_eq!(DimRange::contained_by(&(..0), U1), true); + assert_eq!(DimRange::contained_by(&(..(MAX - 1)), Dynamic::new(MAX)), true); + assert_eq!(DimRange::length(&(..(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(MAX - 1)); + assert_eq!(DimRange::length(&(..MAX), Dynamic::new(MAX)), Dynamic::new(MAX)); +} + +impl DimRange for ops::RangeToInclusive +{ + type Length = Dynamic; + + #[inline(always)] + fn lower(&self, _: D) -> usize { + 0 + } + + #[inline(always)] + fn length(&self, _: D) -> Self::Length { + Dynamic::new(self.end + 1) + } + + #[inline(always)] + fn contained_by(&self, dimension: D) -> bool { + self.end < dimension.value() + } +} + +#[test] +fn dimrange_rangetoinclusive_usize() { + use std::usize::MAX; + use base::dimension::U0; + assert_eq!(DimRange::contained_by(&(..=0), U0), false); + assert_eq!(DimRange::contained_by(&(..=1), U0), false); + assert_eq!(DimRange::contained_by(&(..=0), U1), true); + assert_eq!(DimRange::contained_by(&(..=(MAX)), Dynamic::new(MAX)), false); + assert_eq!(DimRange::contained_by(&(..=(MAX - 1)), Dynamic::new(MAX)), true); + assert_eq!(DimRange::length(&(..=(MAX - 1)), Dynamic::new(MAX)), Dynamic::new(MAX)); +} + +/// A helper trait used for indexing operations. +pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage>: Sized { + + /// The output type returned by methods. + type Output : 'a; + + /// Produces true if the given matrix is contained by this index. + #[doc(hidden)] + fn contained_by(&self, matrix: &Matrix) -> bool; + + /// Produces a shared view of the data at this location if in bounds, + /// or `None`, otherwise. + #[doc(hidden)] + #[inline(always)] + fn get(self, matrix: &'a Matrix) -> Option { + if self.contained_by(matrix) { + Some(unsafe{self.get_unchecked(matrix)}) + } else { + None + } + } + + /// Produces a shared view of the data at this location if in bounds + /// without any bounds checking. + #[doc(hidden)] + unsafe fn get_unchecked(self, matrix: &'a Matrix) -> Self::Output; + + /// Produces a shared view to the data at this location, or panics + /// if out of bounds. + #[doc(hidden)] + #[inline(always)] + fn index(self, matrix: &'a Matrix) -> Self::Output { + self.get(matrix).expect("Index out of bounds.") + } +} + +/// A helper trait used for indexing operations. +pub trait MutMatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut>: MatrixIndex<'a, N, R, C, S> { + /// The output type returned by methods. + type OutputMut : 'a; + + /// Produces a mutable view of the data at this location, without + /// performing any bounds checking. + #[doc(hidden)] + unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix) -> Self::OutputMut; + + /// Produces a mutable view of the data at this location, if in + /// bounds. + #[doc(hidden)] + #[inline(always)] + fn get_mut(self, matrix: &'a mut Matrix) -> Option { + if self.contained_by(matrix) { + Some(unsafe{self.get_unchecked_mut(matrix)}) + } else { + None + } + } + + /// Produces a mutable view of the data at this location, or panics + /// if out of bounds. + #[doc(hidden)] + #[inline(always)] + fn index_mut(self, matrix: &'a mut Matrix) -> Self::OutputMut { + self.get_mut(matrix).expect("Index out of bounds.") + } +} + +/// # Indexing Operations +/// ## Indicies to Individual Elements +/// ### Two-Dimensional Indicies +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix2::new(0, 2, +/// 1, 3); +/// +/// assert_eq!(matrix.index((0, 0)), &0); +/// assert_eq!(matrix.index((1, 0)), &1); +/// assert_eq!(matrix.index((0, 1)), &2); +/// assert_eq!(matrix.index((1, 1)), &3); +/// ``` +/// +/// ### Linear Address Indexing +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix2::new(0, 2, +/// 1, 3); +/// +/// assert_eq!(matrix.get(0), Some(&0)); +/// assert_eq!(matrix.get(1), Some(&1)); +/// assert_eq!(matrix.get(2), Some(&2)); +/// assert_eq!(matrix.get(3), Some(&3)); +/// ``` +/// +/// ## Indicies to Individual Rows and Columns +/// ### Index to a Row +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix2::new(0, 2, +/// 1, 3); +/// +/// assert!(matrix.index((0, ..)) +/// .eq(&Matrix1x2::new(0, 2))); +/// ``` +/// +/// ### Index to a Column +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix2::new(0, 2, +/// 1, 3); +/// +/// assert!(matrix.index((.., 0)) +/// .eq(&Matrix2x1::new(0, +/// 1))); +/// ``` +/// +/// ## Indicies to Parts of Individual Rows and Columns +/// ### Index to a Partial Row +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix3::new(0, 3, 6, +/// 1, 4, 7, +/// 2, 5, 8); +/// +/// assert!(matrix.index((0, ..2)) +/// .eq(&Matrix1x2::new(0, 3))); +/// ``` +/// +/// ### Index to a Partial Column +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix3::new(0, 3, 6, +/// 1, 4, 7, +/// 2, 5, 8); +/// +/// assert!(matrix.index((..2, 0)) +/// .eq(&Matrix2x1::new(0, +/// 1))); +/// ``` +/// ## Indicies to Ranges of Rows and Columns +/// ### Index to a Range of Rows +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix3::new(0, 3, 6, +/// 1, 4, 7, +/// 2, 5, 8); +/// +/// assert!(matrix.index((1..3, ..)) +/// .eq(&Matrix2x3::new(1, 4, 7, +/// 2, 5, 8))); +/// ``` +/// ### Index to a Range of Columns +/// ``` +/// # use nalgebra::*; +/// let matrix = Matrix3::new(0, 3, 6, +/// 1, 4, 7, +/// 2, 5, 8); +/// +/// assert!(matrix.index((.., 1..3)) +/// .eq(&Matrix3x2::new(3, 6, +/// 4, 7, +/// 5, 8))); +/// ``` +impl> Matrix +{ + /// Produces a view of the data at the given index, or + /// `None` if the index is out of bounds. + #[inline] + pub fn get<'a, I>(&'a self, index: I) -> Option + where + I: MatrixIndex<'a, N, R, C, S> + { + index.get(self) + } + + /// Produces a mutable view of the data at the given index, or + /// `None` if the index is out of bounds. + #[inline] + pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option + where + S: StorageMut, + I: MutMatrixIndex<'a, N, R, C, S> + { + index.get_mut(self) + } + + /// Produces a view of the data at the given index, or + /// panics if the index is out of bounds. + #[inline] + pub fn index<'a, I>(&'a self, index: I) -> I::Output + where + I: MatrixIndex<'a, N, R, C, S> + { + index.index(self) + } + + /// Produces a mutable view of the data at the given index, or + /// panics if the index is out of bounds. + #[inline] + pub fn index_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut + where + S: StorageMut, + I: MutMatrixIndex<'a, N, R, C, S> + { + index.index_mut(self) + } + + /// Produces a view of the data at the given index, without doing + /// any bounds checking. + #[inline] + pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output + where + I: MatrixIndex<'a, N, R, C, S> + { + index.get_unchecked(self) + } + + /// Returns a mutable view of the data at the given index, without doing + /// any bounds checking. + #[inline] + pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut + where + S: StorageMut, + I: MutMatrixIndex<'a, N, R, C, S> + { + index.get_unchecked_mut(self) + } +} + +// EXTRACT A SINGLE ELEMENT BY 1D LINEAR ADDRESS + +impl<'a, N, R, C, S> MatrixIndex<'a, N, R, C, S> for usize +where + N: Scalar, + R: Dim, + C: Dim, + S: Storage +{ + type Output = &'a N; + + #[doc(hidden)] + #[inline(always)] + fn contained_by(&self, matrix: &Matrix) -> bool { + *self < matrix.len() + } + + #[doc(hidden)] + #[inline(always)] + unsafe fn get_unchecked(self, matrix: &'a Matrix) -> Self::Output { + matrix.data.get_unchecked_linear(self) + } +} + +impl<'a, N, R, C, S> MutMatrixIndex<'a, N, R, C, S> for usize +where + N: Scalar, + R: Dim, + C: Dim, + S: StorageMut +{ + type OutputMut = &'a mut N; + + #[doc(hidden)] + #[inline(always)] + unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix) -> Self::OutputMut + where S: StorageMut, + { + matrix.data.get_unchecked_linear_mut(self) + } +} + +// EXTRACT A SINGLE ELEMENT BY 2D COORDINATES + +impl<'a, N, R, C, S> MatrixIndex<'a, N, R, C, S> for (usize, usize) +where + N: Scalar, + R: Dim, + C: Dim, + S: Storage +{ + type Output = &'a N; + + #[doc(hidden)] + #[inline(always)] + fn contained_by(&self, matrix: &Matrix) -> bool { + let (rows, cols) = self; + let (nrows, ncols) = matrix.data.shape(); + DimRange::contained_by(rows, nrows) && DimRange::contained_by(cols, ncols) + } + + #[doc(hidden)] + #[inline(always)] + unsafe fn get_unchecked(self, matrix: &'a Matrix) -> Self::Output { + let (row, col) = self; + matrix.data.get_unchecked(row, col) + } +} + +impl<'a, N, R, C, S> MutMatrixIndex<'a, N, R, C, S> for (usize, usize) +where + N: Scalar, + R: Dim, + C: Dim, + S: StorageMut +{ + type OutputMut = &'a mut N; + + #[doc(hidden)] + #[inline(always)] + unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix) -> Self::OutputMut + where S: StorageMut, + { + let (row, col) = self; + matrix.data.get_unchecked_mut(row, col) + } +} + +macro_rules! impl_usize_slice_index { + (index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> ($ROut: ty, ..)) => { + impl_usize_slice_index!{index Matrix<$R, $C> with [$RIdx, $CIdx] -> ($ROut, $C)} + }; + (index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> (.., $COut: ty)) => { + impl_usize_slice_index!{index Matrix<$R, $C> with [$RIdx, $CIdx] -> ($R, $COut)} + }; + (index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> (.., ..)) => { + impl_usize_slice_index!{index Matrix<$R, $C> with [$RIdx, $CIdx] -> ($R, $C)} + }; + (index Matrix<$R: ident, $C: ident> with [$RIdx: ty, $CIdx: ty] -> ($ROut: ty, $COut: ty)) => { + impl<'a, N, $R, $C, S> MatrixIndex<'a, N, $R, $C, S> for ($RIdx, $CIdx) + where + N: Scalar, + $R: Dim, + $C: Dim, + S: Storage + { + type Output = MatrixSlice<'a, N, $ROut, $COut, S::RStride, S::CStride>; + + #[doc(hidden)] + #[inline(always)] + fn contained_by(&self, matrix: &Matrix) -> bool { + let (rows, cols) = self; + let (nrows, ncols) = matrix.data.shape(); + DimRange::contained_by(rows, nrows) && DimRange::contained_by(cols, ncols) + } + + #[doc(hidden)] + #[inline(always)] + unsafe fn get_unchecked(self, matrix: &'a Matrix) -> Self::Output { + use base::SliceStorage; + + let (rows, cols) = self; + let (nrows, ncols) = matrix.data.shape(); + + let data = + SliceStorage::new_unchecked(&matrix.data, + (rows.lower(nrows), cols.lower(ncols)), + (rows.length(nrows), cols.length(ncols))); + + Matrix::from_data_statically_unchecked(data) + } + } + + impl<'a, N, $R, $C, S> MutMatrixIndex<'a, N, $R, $C, S> for ($RIdx, $CIdx) + where + N: Scalar, + $R: Dim, + $C: Dim, + S: StorageMut + { + type OutputMut = MatrixSliceMut<'a, N, $ROut, $COut, S::RStride, S::CStride>; + + #[doc(hidden)] + #[inline(always)] + unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix) -> Self::OutputMut { + use base::SliceStorageMut; + + let (rows, cols) = self; + let (nrows, ncols) = matrix.data.shape(); + + let data = + SliceStorageMut::new_unchecked(&mut matrix.data, + (rows.lower(nrows), cols.lower(ncols)), + (rows.length(nrows), cols.length(ncols))); + + Matrix::from_data_statically_unchecked(data) + } + } + } +} + +macro_rules! impl_slice_indices{ + (index Matrix<$R: ident, $C: ident> with) => {}; + + (index Matrix<$R: ident, $C: ident> with usize => U1, $($RI: ty => $RO: tt,)*) => + { + $(impl_usize_slice_index!{index Matrix<$R, $C> with [usize, $RI] -> (U1, $RO)})* + $(impl_usize_slice_index!{index Matrix<$R, $C> with [$RI, usize] -> ($RO, U1)})* + impl_slice_indices!{index Matrix<$R, $C> with $($RI => $RO,)*} + }; + + (index Matrix<$R: ident, $C: ident> with + $HI: ty => $HO: tt, + $($RI: ty => $RO: tt,)*) => + { + impl_usize_slice_index!{index Matrix<$R, $C> with [$HI, $HI] -> ($HO, $HO)} + $(impl_usize_slice_index!{index Matrix<$R, $C> with [$HI, $RI] -> ($HO, $RO)})* + $(impl_usize_slice_index!{index Matrix<$R, $C> with [$RI, $HI] -> ($RO, $HO)})* + impl_slice_indices!{index Matrix<$R, $C> with $($RI => $RO,)*} + }; +} + +impl_slice_indices!{ + index Matrix with + usize => U1, + ops::Range => Dynamic, + ops::RangeFrom => Dynamic, + ops::RangeFull => .., + ops::RangeInclusive => Dynamic, + ops::RangeTo => Dynamic, + ops::RangeToInclusive => Dynamic, +} \ No newline at end of file diff --git a/src/base/matrix.rs b/src/base/matrix.rs index 1d69d6e4..f63a07ba 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -264,17 +264,6 @@ impl> Matrix { } } - /// Gets a reference to the element of this matrix at row `irow` and column `icol` without - /// bound-checking. - #[inline] - pub unsafe fn get_unchecked(&self, irow: usize, icol: usize) -> &N { - debug_assert!( - irow < self.nrows() && icol < self.ncols(), - "Matrix index out of bounds." - ); - self.data.get_unchecked(irow, icol) - } - /// Tests whether `self` and `rhs` are equal up to a given epsilon. /// /// See `relative_eq` from the `RelativeEq` trait for more details. @@ -375,7 +364,7 @@ impl> Matrix { for j in 0..res.ncols() { for i in 0..res.nrows() { unsafe { - *res.get_unchecked_mut(i, j) = *self.get_unchecked(i, j); + *res.get_unchecked_mut((i, j)) = *self.get_unchecked((i, j)); } } } @@ -523,7 +512,7 @@ impl> Matrix { for i in 0..nrows { for j in 0..ncols { unsafe { - *out.get_unchecked_mut(j, i) = *self.get_unchecked(i, j); + *out.get_unchecked_mut((j, i)) = *self.get_unchecked((i, j)); } } } @@ -551,16 +540,6 @@ impl> Matrix { MatrixIterMut::new(&mut self.data) } - /// Gets a mutable reference to the i-th element of this matrix. - #[inline] - pub unsafe fn get_unchecked_mut(&mut self, irow: usize, icol: usize) -> &mut N { - debug_assert!( - irow < self.nrows() && icol < self.ncols(), - "Matrix index out of bounds." - ); - self.data.get_unchecked_mut(irow, icol) - } - /// Swaps two entries without bound-checking. #[inline] pub unsafe fn swap_unchecked(&mut self, row_cols1: (usize, usize), row_cols2: (usize, usize)) { @@ -599,7 +578,7 @@ impl> Matrix { for j in 0..ncols { for i in 0..nrows { unsafe { - *self.get_unchecked_mut(i, j) = *slice.get_unchecked(i + j * nrows); + *self.get_unchecked_mut((i, j)) = *slice.get_unchecked(i + j * nrows); } } } @@ -622,7 +601,7 @@ impl> Matrix { for j in 0..self.ncols() { for i in 0..self.nrows() { unsafe { - *self.get_unchecked_mut(i, j) = *other.get_unchecked(i, j); + *self.get_unchecked_mut((i, j)) = *other.get_unchecked((i, j)); } } } @@ -646,7 +625,7 @@ impl> Matrix { for j in 0..ncols { for i in 0..nrows { unsafe { - *self.get_unchecked_mut(i, j) = *other.get_unchecked(j, i); + *self.get_unchecked_mut((i, j)) = *other.get_unchecked((j, i)); } } } @@ -743,7 +722,7 @@ impl, R, C>> Matrix, R for i in 0..nrows { for j in 0..ncols { unsafe { - *out.get_unchecked_mut(j, i) = self.get_unchecked(i, j).conj(); + *out.get_unchecked_mut((j, i)) = self.get_unchecked((i, j)).conj(); } } } @@ -777,8 +756,8 @@ impl, D, D>> Matrix, D, D, for i in 1..dim { for j in 0..i { unsafe { - let ref_ij = self.get_unchecked_mut(i, j) as *mut Complex; - let ref_ji = self.get_unchecked_mut(j, i) as *mut Complex; + let ref_ij = self.get_unchecked_mut((i, j)) as *mut Complex; + let ref_ji = self.get_unchecked_mut((j, i)) as *mut Complex; let conj_ij = (*ref_ij).conj(); let conj_ji = (*ref_ji).conj(); *ref_ij = conj_ji; @@ -804,7 +783,7 @@ impl> SquareMatrix { for i in 0..dim.value() { unsafe { - *res.vget_unchecked_mut(i) = *self.get_unchecked(i, i); + *res.vget_unchecked_mut(i) = *self.get_unchecked((i, i)); } } @@ -824,7 +803,7 @@ impl> SquareMatrix { let mut res = N::zero(); for i in 0..dim.value() { - res += unsafe { *self.get_unchecked(i, i) }; + res += unsafe { *self.get_unchecked((i, i)) }; } res @@ -1140,8 +1119,8 @@ impl> Matrix { assert!(self.shape() == (2, 1), "2D perpendicular product "); unsafe { - *self.get_unchecked(0, 0) * *b.get_unchecked(1, 0) - - *self.get_unchecked(1, 0) * *b.get_unchecked(0, 0) + *self.get_unchecked((0, 0)) * *b.get_unchecked((1, 0)) + - *self.get_unchecked((1, 0)) * *b.get_unchecked((0, 0)) } } @@ -1176,17 +1155,17 @@ impl> Matrix { let ncols = SameShapeC::::from_usize(1); let mut res = Matrix::new_uninitialized_generic(nrows, ncols); - let ax = *self.get_unchecked(0, 0); - let ay = *self.get_unchecked(1, 0); - let az = *self.get_unchecked(2, 0); + let ax = *self.get_unchecked((0, 0)); + let ay = *self.get_unchecked((1, 0)); + let az = *self.get_unchecked((2, 0)); - let bx = *b.get_unchecked(0, 0); - let by = *b.get_unchecked(1, 0); - let bz = *b.get_unchecked(2, 0); + let bx = *b.get_unchecked((0, 0)); + let by = *b.get_unchecked((1, 0)); + let bz = *b.get_unchecked((2, 0)); - *res.get_unchecked_mut(0, 0) = ay * bz - az * by; - *res.get_unchecked_mut(1, 0) = az * bx - ax * bz; - *res.get_unchecked_mut(2, 0) = ax * by - ay * bx; + *res.get_unchecked_mut((0, 0)) = ay * bz - az * by; + *res.get_unchecked_mut((1, 0)) = az * bx - ax * bz; + *res.get_unchecked_mut((2, 0)) = ax * by - ay * bx; res } @@ -1197,17 +1176,17 @@ impl> Matrix { let ncols = SameShapeC::::from_usize(3); let mut res = Matrix::new_uninitialized_generic(nrows, ncols); - let ax = *self.get_unchecked(0, 0); - let ay = *self.get_unchecked(0, 1); - let az = *self.get_unchecked(0, 2); + let ax = *self.get_unchecked((0, 0)); + let ay = *self.get_unchecked((0, 1)); + let az = *self.get_unchecked((0, 2)); - let bx = *b.get_unchecked(0, 0); - let by = *b.get_unchecked(0, 1); - let bz = *b.get_unchecked(0, 2); + let bx = *b.get_unchecked((0, 0)); + let by = *b.get_unchecked((0, 1)); + let bz = *b.get_unchecked((0, 2)); - *res.get_unchecked_mut(0, 0) = ay * bz - az * by; - *res.get_unchecked_mut(0, 1) = az * bx - ax * bz; - *res.get_unchecked_mut(0, 2) = ax * by - ay * bx; + *res.get_unchecked_mut((0, 0)) = ay * bz - az * by; + *res.get_unchecked_mut((0, 1)) = az * bx - ax * bz; + *res.get_unchecked_mut((0, 2)) = ax * by - ay * bx; res } diff --git a/src/base/mod.rs b/src/base/mod.rs index 65a86032..e7240fb3 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -18,6 +18,7 @@ mod construction; mod construction_slice; mod conversion; mod edition; +pub mod indexing; mod matrix; mod matrix_alga; mod array_storage; diff --git a/src/base/ops.rs b/src/base/ops.rs index 14ec98f0..da81789f 100644 --- a/src/base/ops.rs +++ b/src/base/ops.rs @@ -45,7 +45,7 @@ where "Matrix index out of bounds." ); - unsafe { self.get_unchecked(ij.0, ij.1) } + unsafe { self.get_unchecked((ij.0, ij.1)) } } } @@ -71,7 +71,7 @@ where "Matrix index out of bounds." ); - unsafe { self.get_unchecked_mut(ij.0, ij.1) } + unsafe { self.get_unchecked_mut((ij.0, ij.1)) } } } @@ -172,8 +172,8 @@ macro_rules! componentwise_binop_impl( for j in 0 .. self.ncols() { for i in 0 .. self.nrows() { unsafe { - let val = self.get_unchecked(i, j).$method(*rhs.get_unchecked(i, j)); - *out.get_unchecked_mut(i, j) = val; + let val = self.get_unchecked((i, j)).$method(*rhs.get_unchecked((i, j))); + *out.get_unchecked_mut((i, j)) = val; } } } @@ -204,7 +204,7 @@ macro_rules! componentwise_binop_impl( for j in 0 .. rhs.ncols() { for i in 0 .. rhs.nrows() { unsafe { - self.get_unchecked_mut(i, j).$method_assign(*rhs.get_unchecked(i, j)) + self.get_unchecked_mut((i, j)).$method_assign(*rhs.get_unchecked((i, j))) } } } @@ -235,8 +235,8 @@ macro_rules! componentwise_binop_impl( for j in 0 .. self.ncols() { for i in 0 .. self.nrows() { unsafe { - let r = rhs.get_unchecked_mut(i, j); - *r = self.get_unchecked(i, j).$method(*r) + let r = rhs.get_unchecked_mut((i, j)); + *r = self.get_unchecked((i, j)).$method(*r) } } } @@ -448,7 +448,7 @@ macro_rules! componentwise_scalarop_impl( fn $method_assign(&mut self, rhs: N) { for j in 0 .. self.ncols() { for i in 0 .. self.nrows() { - unsafe { self.get_unchecked_mut(i, j).$method_assign(rhs) }; + unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs) }; } } } @@ -657,7 +657,7 @@ where for i in 0..ncols1 { for j in 0..ncols2 { let dot = self.column(i).dot(&rhs.column(j)); - unsafe { *out.get_unchecked_mut(i, j) = dot }; + unsafe { *out.get_unchecked_mut((i, j)) = dot }; } } } @@ -704,10 +704,10 @@ where for j2 in 0..ncols2.value() { for i1 in 0..nrows1.value() { unsafe { - let coeff = *self.get_unchecked(i1, j1); + let coeff = *self.get_unchecked((i1, j1)); for i2 in 0..nrows2.value() { - *data_res = coeff * *rhs.get_unchecked(i2, j2); + *data_res = coeff * *rhs.get_unchecked((i2, j2)); data_res = data_res.offset(1); } } diff --git a/src/geometry/transform_ops.rs b/src/geometry/transform_ops.rs index 1c95f3b0..2ede5c60 100644 --- a/src/geometry/transform_ops.rs +++ b/src/geometry/transform_ops.rs @@ -143,7 +143,7 @@ md_impl_all!( if C::has_normalizer() { let normalizer = self.matrix().fixed_slice::(D::dim(), 0); - let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked(D::dim(), D::dim()) }; + let n = normalizer.tr_dot(&rhs.coords) + unsafe { *self.matrix().get_unchecked((D::dim(), D::dim())) }; if !n.is_zero() { return (transform * rhs + translation) / n; diff --git a/src/geometry/unit_complex_ops.rs b/src/geometry/unit_complex_ops.rs index 0a8306d2..c9d31ad4 100644 --- a/src/geometry/unit_complex_ops.rs +++ b/src/geometry/unit_complex_ops.rs @@ -425,11 +425,11 @@ impl UnitComplex { for j in 0..rhs.ncols() { unsafe { - let a = *rhs.get_unchecked(0, j); - let b = *rhs.get_unchecked(1, j); + let a = *rhs.get_unchecked((0, j)); + let b = *rhs.get_unchecked((1, j)); - *rhs.get_unchecked_mut(0, j) = r * a - i * b; - *rhs.get_unchecked_mut(1, j) = i * a + r * b; + *rhs.get_unchecked_mut((0, j)) = r * a - i * b; + *rhs.get_unchecked_mut((1, j)) = i * a + r * b; } } } @@ -452,11 +452,11 @@ impl UnitComplex { // FIXME: can we optimize that to iterate on one column at a time ? for j in 0..lhs.nrows() { unsafe { - let a = *lhs.get_unchecked(j, 0); - let b = *lhs.get_unchecked(j, 1); + let a = *lhs.get_unchecked((j, 0)); + let b = *lhs.get_unchecked((j, 1)); - *lhs.get_unchecked_mut(j, 0) = r * a + i * b; - *lhs.get_unchecked_mut(j, 1) = -i * a + r * b; + *lhs.get_unchecked_mut((j, 0)) = r * a + i * b; + *lhs.get_unchecked_mut((j, 1)) = -i * a + r * b; } } } diff --git a/src/linalg/cholesky.rs b/src/linalg/cholesky.rs index c0868c1a..c1fd7b85 100644 --- a/src/linalg/cholesky.rs +++ b/src/linalg/cholesky.rs @@ -52,7 +52,7 @@ where DefaultAllocator: Allocator for j in 0..n { for k in 0..j { - let factor = unsafe { -*matrix.get_unchecked(j, k) }; + let factor = unsafe { -*matrix.get_unchecked((j, k)) }; let (mut col_j, col_k) = matrix.columns_range_pair_mut(j, k); let mut col_j = col_j.rows_range_mut(j..); @@ -61,11 +61,11 @@ where DefaultAllocator: Allocator col_j.axpy(factor, &col_k, N::one()); } - let diag = unsafe { *matrix.get_unchecked(j, j) }; + let diag = unsafe { *matrix.get_unchecked((j, j)) }; if diag > N::zero() { let denom = diag.sqrt(); unsafe { - *matrix.get_unchecked_mut(j, j) = denom; + *matrix.get_unchecked_mut((j, j)) = denom; } let mut col = matrix.slice_range_mut(j + 1.., j); diff --git a/src/linalg/determinant.rs b/src/linalg/determinant.rs index 100a21e7..6229da0e 100644 --- a/src/linalg/determinant.rs +++ b/src/linalg/determinant.rs @@ -23,27 +23,27 @@ impl, S: Storage> SquareMatrix N::one(), - 1 => *self.get_unchecked(0, 0), + 1 => *self.get_unchecked((0, 0)), 2 => { - let m11 = *self.get_unchecked(0, 0); - let m12 = *self.get_unchecked(0, 1); - let m21 = *self.get_unchecked(1, 0); - let m22 = *self.get_unchecked(1, 1); + let m11 = *self.get_unchecked((0, 0)); + let m12 = *self.get_unchecked((0, 1)); + let m21 = *self.get_unchecked((1, 0)); + let m22 = *self.get_unchecked((1, 1)); m11 * m22 - m21 * m12 } 3 => { - let m11 = *self.get_unchecked(0, 0); - let m12 = *self.get_unchecked(0, 1); - let m13 = *self.get_unchecked(0, 2); + let m11 = *self.get_unchecked((0, 0)); + let m12 = *self.get_unchecked((0, 1)); + let m13 = *self.get_unchecked((0, 2)); - let m21 = *self.get_unchecked(1, 0); - let m22 = *self.get_unchecked(1, 1); - let m23 = *self.get_unchecked(1, 2); + let m21 = *self.get_unchecked((1, 0)); + let m22 = *self.get_unchecked((1, 1)); + let m23 = *self.get_unchecked((1, 2)); - let m31 = *self.get_unchecked(2, 0); - let m32 = *self.get_unchecked(2, 1); - let m33 = *self.get_unchecked(2, 2); + let m31 = *self.get_unchecked((2, 0)); + let m32 = *self.get_unchecked((2, 1)); + let m33 = *self.get_unchecked((2, 2)); let minor_m12_m23 = m22 * m33 - m32 * m23; let minor_m11_m23 = m21 * m33 - m31 * m23; diff --git a/src/linalg/full_piv_lu.rs b/src/linalg/full_piv_lu.rs index 9bab4ee9..022152f4 100644 --- a/src/linalg/full_piv_lu.rs +++ b/src/linalg/full_piv_lu.rs @@ -251,7 +251,7 @@ where DefaultAllocator: Allocator + Allocator<(usize, usize), D> let mut res = self.lu[(dim - 1, dim - 1)]; if !res.is_zero() { for i in 0..dim - 1 { - res *= unsafe { *self.lu.get_unchecked(i, i) }; + res *= unsafe { *self.lu.get_unchecked((i, i)) }; } res * self.p.determinant() * self.q.determinant() diff --git a/src/linalg/inverse.rs b/src/linalg/inverse.rs index 08cebd2a..5748900f 100644 --- a/src/linalg/inverse.rs +++ b/src/linalg/inverse.rs @@ -35,46 +35,46 @@ impl> SquareMatrix { match dim { 0 => true, 1 => { - let determinant = self.get_unchecked(0, 0).clone(); + let determinant = self.get_unchecked((0, 0)).clone(); if determinant == N::zero() { false } else { - *self.get_unchecked_mut(0, 0) = N::one() / determinant; + *self.get_unchecked_mut((0, 0)) = N::one() / determinant; true } } 2 => { - let m11 = *self.get_unchecked(0, 0); - let m12 = *self.get_unchecked(0, 1); - let m21 = *self.get_unchecked(1, 0); - let m22 = *self.get_unchecked(1, 1); + let m11 = *self.get_unchecked((0, 0)); + let m12 = *self.get_unchecked((0, 1)); + let m21 = *self.get_unchecked((1, 0)); + let m22 = *self.get_unchecked((1, 1)); let determinant = m11 * m22 - m21 * m12; if determinant == N::zero() { false } else { - *self.get_unchecked_mut(0, 0) = m22 / determinant; - *self.get_unchecked_mut(0, 1) = -m12 / determinant; + *self.get_unchecked_mut((0, 0)) = m22 / determinant; + *self.get_unchecked_mut((0, 1)) = -m12 / determinant; - *self.get_unchecked_mut(1, 0) = -m21 / determinant; - *self.get_unchecked_mut(1, 1) = m11 / determinant; + *self.get_unchecked_mut((1, 0)) = -m21 / determinant; + *self.get_unchecked_mut((1, 1)) = m11 / determinant; true } } 3 => { - let m11 = *self.get_unchecked(0, 0); - let m12 = *self.get_unchecked(0, 1); - let m13 = *self.get_unchecked(0, 2); + let m11 = *self.get_unchecked((0, 0)); + let m12 = *self.get_unchecked((0, 1)); + let m13 = *self.get_unchecked((0, 2)); - let m21 = *self.get_unchecked(1, 0); - let m22 = *self.get_unchecked(1, 1); - let m23 = *self.get_unchecked(1, 2); + let m21 = *self.get_unchecked((1, 0)); + let m22 = *self.get_unchecked((1, 1)); + let m23 = *self.get_unchecked((1, 2)); - let m31 = *self.get_unchecked(2, 0); - let m32 = *self.get_unchecked(2, 1); - let m33 = *self.get_unchecked(2, 2); + let m31 = *self.get_unchecked((2, 0)); + let m32 = *self.get_unchecked((2, 1)); + let m33 = *self.get_unchecked((2, 2)); let minor_m12_m23 = m22 * m33 - m32 * m23; let minor_m11_m23 = m21 * m33 - m31 * m23; @@ -86,17 +86,17 @@ impl> SquareMatrix { if determinant == N::zero() { false } else { - *self.get_unchecked_mut(0, 0) = minor_m12_m23 / determinant; - *self.get_unchecked_mut(0, 1) = (m13 * m32 - m33 * m12) / determinant; - *self.get_unchecked_mut(0, 2) = (m12 * m23 - m22 * m13) / determinant; + *self.get_unchecked_mut((0, 0)) = minor_m12_m23 / determinant; + *self.get_unchecked_mut((0, 1)) = (m13 * m32 - m33 * m12) / determinant; + *self.get_unchecked_mut((0, 2)) = (m12 * m23 - m22 * m13) / determinant; - *self.get_unchecked_mut(1, 0) = -minor_m11_m23 / determinant; - *self.get_unchecked_mut(1, 1) = (m11 * m33 - m31 * m13) / determinant; - *self.get_unchecked_mut(1, 2) = (m13 * m21 - m23 * m11) / determinant; + *self.get_unchecked_mut((1, 0)) = -minor_m11_m23 / determinant; + *self.get_unchecked_mut((1, 1)) = (m11 * m33 - m31 * m13) / determinant; + *self.get_unchecked_mut((1, 2)) = (m13 * m21 - m23 * m11) / determinant; - *self.get_unchecked_mut(2, 0) = minor_m11_m22 / determinant; - *self.get_unchecked_mut(2, 1) = (m12 * m31 - m32 * m11) / determinant; - *self.get_unchecked_mut(2, 2) = (m11 * m22 - m21 * m12) / determinant; + *self.get_unchecked_mut((2, 0)) = minor_m11_m22 / determinant; + *self.get_unchecked_mut((2, 1)) = (m12 * m31 - m32 * m11) / determinant; + *self.get_unchecked_mut((2, 2)) = (m11 * m22 - m21 * m12) / determinant; true } diff --git a/src/linalg/lu.rs b/src/linalg/lu.rs index 66c2743e..67fae23f 100644 --- a/src/linalg/lu.rs +++ b/src/linalg/lu.rs @@ -290,7 +290,7 @@ where DefaultAllocator: Allocator + Allocator<(usize, usize), D> let mut res = N::one(); for i in 0..dim { - res *= unsafe { *self.lu.get_unchecked(i, i) }; + res *= unsafe { *self.lu.get_unchecked((i, i)) }; } res * self.p.determinant() diff --git a/src/linalg/solve.rs b/src/linalg/solve.rs index 904a1b29..4d2d103f 100644 --- a/src/linalg/solve.rs +++ b/src/linalg/solve.rs @@ -79,7 +79,7 @@ impl> SquareMatrix { let coeff; unsafe { - let diag = *self.get_unchecked(i, i); + let diag = *self.get_unchecked((i, i)); if diag.is_zero() { return false; @@ -161,7 +161,7 @@ impl> SquareMatrix { let coeff; unsafe { - let diag = *self.get_unchecked(i, i); + let diag = *self.get_unchecked((i, i)); if diag.is_zero() { return false; @@ -258,7 +258,7 @@ impl> SquareMatrix { unsafe { let b_i = b.vget_unchecked_mut(i); - let diag = *self.get_unchecked(i, i); + let diag = *self.get_unchecked((i, i)); if diag.is_zero() { return false; @@ -304,7 +304,7 @@ impl> SquareMatrix { unsafe { let b_i = b.vget_unchecked_mut(i); - let diag = *self.get_unchecked(i, i); + let diag = *self.get_unchecked((i, i)); if diag.is_zero() { return false;