forked from M-Labs/nalgebra
Add documentation.
This commit is contained in:
parent
c258d13f98
commit
b22eb91a16
@ -586,7 +586,7 @@ where N: Scalar + Zero + One,
|
||||
#[inline]
|
||||
pub fn x() -> Self
|
||||
where R::Value: Cmp<typenum::U0, Output = Greater> {
|
||||
let mut res = Self::from_element(N::zero());
|
||||
let mut res = Self::zeros();
|
||||
unsafe { *res.vget_unchecked_mut(0) = N::one(); }
|
||||
|
||||
res
|
||||
@ -596,7 +596,7 @@ where N: Scalar + Zero + One,
|
||||
#[inline]
|
||||
pub fn y() -> Self
|
||||
where R::Value: Cmp<typenum::U1, Output = Greater> {
|
||||
let mut res = Self::from_element(N::zero());
|
||||
let mut res = Self::zeros();
|
||||
unsafe { *res.vget_unchecked_mut(1) = N::one(); }
|
||||
|
||||
res
|
||||
@ -606,7 +606,7 @@ where N: Scalar + Zero + One,
|
||||
#[inline]
|
||||
pub fn z() -> Self
|
||||
where R::Value: Cmp<typenum::U2, Output = Greater> {
|
||||
let mut res = Self::from_element(N::zero());
|
||||
let mut res = Self::zeros();
|
||||
unsafe { *res.vget_unchecked_mut(2) = N::one(); }
|
||||
|
||||
res
|
||||
@ -616,7 +616,7 @@ where N: Scalar + Zero + One,
|
||||
#[inline]
|
||||
pub fn w() -> Self
|
||||
where R::Value: Cmp<typenum::U3, Output = Greater> {
|
||||
let mut res = Self::from_element(N::zero());
|
||||
let mut res = Self::zeros();
|
||||
unsafe { *res.vget_unchecked_mut(3) = N::one(); }
|
||||
|
||||
res
|
||||
@ -626,7 +626,7 @@ where N: Scalar + Zero + One,
|
||||
#[inline]
|
||||
pub fn a() -> Self
|
||||
where R::Value: Cmp<typenum::U4, Output = Greater> {
|
||||
let mut res = Self::from_element(N::zero());
|
||||
let mut res = Self::zeros();
|
||||
unsafe { *res.vget_unchecked_mut(4) = N::one(); }
|
||||
|
||||
res
|
||||
@ -636,7 +636,7 @@ where N: Scalar + Zero + One,
|
||||
#[inline]
|
||||
pub fn b() -> Self
|
||||
where R::Value: Cmp<typenum::U5, Output = Greater> {
|
||||
let mut res = Self::from_element(N::zero());
|
||||
let mut res = Self::zeros();
|
||||
unsafe { *res.vget_unchecked_mut(5) = N::one(); }
|
||||
|
||||
res
|
||||
|
@ -438,21 +438,30 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
*
|
||||
*/
|
||||
|
||||
/// Resizes this matrix so that it contains `new_nrows` rows and `new_ncols` columns.
|
||||
///
|
||||
/// 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`.
|
||||
pub fn resize(self, new_nrows: usize, new_ncols: usize, val: N) -> DMatrix<N>
|
||||
where DefaultAllocator: Reallocator<N, R, C, Dynamic, Dynamic> {
|
||||
|
||||
self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val)
|
||||
}
|
||||
|
||||
/// Resizes this matrix so that it contains `R2::value()` rows and `C2::value()` columns.
|
||||
///
|
||||
/// 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`.
|
||||
pub fn fixed_resize<R2: DimName, C2: DimName>(self, val: N) -> MatrixMN<N, R2, C2>
|
||||
where DefaultAllocator: Reallocator<N, R, C, R2, C2> {
|
||||
|
||||
self.resize_generic(R2::name(), C2::name(), val)
|
||||
}
|
||||
|
||||
/// Resizes `self` such that it has dimensions `new_nrows × now_ncols`. 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`.
|
||||
/// Resizes `self` such that it has dimensions `new_nrows × now_ncols`.
|
||||
///
|
||||
/// 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`.
|
||||
#[inline]
|
||||
pub fn resize_generic<R2: Dim, C2: Dim>(self, new_nrows: R2, new_ncols: C2, val: N) -> MatrixMN<N, R2, C2>
|
||||
where DefaultAllocator: Reallocator<N, R, C, R2, C2> {
|
||||
|
@ -193,11 +193,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
#[inline]
|
||||
fn assert_slice_index(&self, start: (usize, usize), shape: (usize, usize), steps: (usize, usize)) {
|
||||
let my_shape = self.shape();
|
||||
// NOTE: we previously did: (shape.0 - 1) * steps.0
|
||||
// which was wrong because underflow may occur for zero-sized matrices.
|
||||
// Istead, we moved the subtraction into an addition on the right hand side.
|
||||
assert!(start.0 + shape.0 * steps.0 <= my_shape.0 + steps.0, "Matrix slicing out of bounds.");
|
||||
assert!(start.1 + shape.1 * steps.1 <= my_shape.1 + steps.1, "Matrix slicing out of bounds.");
|
||||
// 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.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,7 +291,7 @@ macro_rules! matrix_slice_impl(
|
||||
-> $MatrixSlice<N, RSlice, C, S::RStride, S::CStride> {
|
||||
|
||||
let my_shape = $me.data.shape();
|
||||
$me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (1, 1));
|
||||
$me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0));
|
||||
|
||||
let shape = (nrows, my_shape.1);
|
||||
|
||||
@ -309,7 +310,7 @@ macro_rules! matrix_slice_impl(
|
||||
|
||||
let my_shape = $me.data.shape();
|
||||
let my_strides = $me.data.strides();
|
||||
$me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (step, 1));
|
||||
$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);
|
||||
@ -378,7 +379,7 @@ macro_rules! matrix_slice_impl(
|
||||
-> $MatrixSlice<N, R, CSlice, S::RStride, S::CStride> {
|
||||
|
||||
let my_shape = $me.data.shape();
|
||||
$me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (1, 1));
|
||||
$me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0));
|
||||
let shape = (my_shape.0, ncols);
|
||||
|
||||
unsafe {
|
||||
@ -397,7 +398,7 @@ macro_rules! matrix_slice_impl(
|
||||
let my_shape = $me.data.shape();
|
||||
let my_strides = $me.data.strides();
|
||||
|
||||
$me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (1, step));
|
||||
$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);
|
||||
@ -419,7 +420,7 @@ macro_rules! matrix_slice_impl(
|
||||
pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize))
|
||||
-> $MatrixSlice<N, Dynamic, Dynamic, S::RStride, S::CStride> {
|
||||
|
||||
$me.assert_slice_index(start, shape, (1, 1));
|
||||
$me.assert_slice_index(start, shape, (0, 0));
|
||||
let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1));
|
||||
|
||||
unsafe {
|
||||
@ -449,7 +450,7 @@ macro_rules! matrix_slice_impl(
|
||||
where RSlice: DimName,
|
||||
CSlice: DimName {
|
||||
|
||||
$me.assert_slice_index((irow, icol), (RSlice::dim(), CSlice::dim()), (1, 1));
|
||||
$me.assert_slice_index((irow, icol), (RSlice::dim(), CSlice::dim()), (0, 0));
|
||||
let shape = (RSlice::name(), CSlice::name());
|
||||
|
||||
unsafe {
|
||||
@ -478,7 +479,7 @@ macro_rules! matrix_slice_impl(
|
||||
where RSlice: Dim,
|
||||
CSlice: Dim {
|
||||
|
||||
$me.assert_slice_index(start, (shape.0.value(), shape.1.value()), (1, 1));
|
||||
$me.assert_slice_index(start, (shape.0.value(), shape.1.value()), (0, 0));
|
||||
|
||||
unsafe {
|
||||
let data = $SliceStorage::new_unchecked($data, start, shape);
|
||||
@ -644,12 +645,23 @@ matrix_slice_impl!(
|
||||
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<D: Dim> {
|
||||
/// 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 immediatly after the last index.
|
||||
/// The index immediatly 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;
|
||||
}
|
||||
|
||||
@ -750,6 +762,8 @@ impl<D: Dim> SliceRange<D> for RangeFull {
|
||||
|
||||
|
||||
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
/// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed
|
||||
/// by the range `cols`.
|
||||
#[inline]
|
||||
pub fn slice_range<RowRange, ColRange>(&self, rows: RowRange, cols: ColRange)
|
||||
-> MatrixSlice<N, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
|
||||
@ -761,6 +775,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
(rows.size(nrows), cols.size(ncols)))
|
||||
}
|
||||
|
||||
/// Slice containing all the rows indexed by the range `rows`.
|
||||
#[inline]
|
||||
pub fn rows_range<RowRange: SliceRange<R>>(&self, rows: RowRange)
|
||||
-> MatrixSlice<N, RowRange::Size, C, S::RStride, S::CStride> {
|
||||
@ -768,6 +783,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
self.slice_range(rows, ..)
|
||||
}
|
||||
|
||||
/// Slice containing all the columns indexed by the range `rows`.
|
||||
#[inline]
|
||||
pub fn columns_range<ColRange: SliceRange<C>>(&self, cols: ColRange)
|
||||
-> MatrixSlice<N, R, ColRange::Size, S::RStride, S::CStride> {
|
||||
@ -777,6 +793,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
}
|
||||
|
||||
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
||||
/// 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<RowRange, ColRange>(&mut self, rows: RowRange, cols: ColRange)
|
||||
-> MatrixSliceMut<N, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
|
||||
where RowRange: SliceRange<R>,
|
||||
@ -787,6 +805,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
||||
(rows.size(nrows), cols.size(ncols)))
|
||||
}
|
||||
|
||||
/// Slice containing all the rows indexed by the range `rows`.
|
||||
#[inline]
|
||||
pub fn rows_range_mut<RowRange: SliceRange<R>>(&mut self, rows: RowRange)
|
||||
-> MatrixSliceMut<N, RowRange::Size, C, S::RStride, S::CStride> {
|
||||
@ -794,6 +813,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
||||
self.slice_range_mut(rows, ..)
|
||||
}
|
||||
|
||||
/// Slice containing all the columns indexed by the range `cols`.
|
||||
#[inline]
|
||||
pub fn columns_range_mut<ColRange: SliceRange<C>>(&mut self, cols: ColRange)
|
||||
-> MatrixSliceMut<N, R, ColRange::Size, S::RStride, S::CStride> {
|
||||
|
@ -7,6 +7,9 @@ use std::any::Any;
|
||||
/// This does not make any assumption on the algebraic properties of `Self`.
|
||||
pub trait Scalar: Copy + PartialEq + Debug + Any {
|
||||
#[inline]
|
||||
/// Tests if `Self` the the same as the type `T`
|
||||
///
|
||||
/// Typically used to test of `Self` is a f32 or a f64 with `N::is::<f32>()`.
|
||||
fn is<T: Scalar>() -> bool {
|
||||
TypeId::of::<Self>() == TypeId::of::<T>()
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ Simply add the following to your `Cargo.toml` file:
|
||||
|
||||
```.ignore
|
||||
[dependencies]
|
||||
nalgebra = "0.12"
|
||||
nalgebra = "0.13"
|
||||
```
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ an optimized set of tools for computer graphics and physics. Those features incl
|
||||
#![deny(non_upper_case_globals)]
|
||||
#![deny(unused_qualifications)]
|
||||
#![deny(unused_results)]
|
||||
//#![warn(missing_docs)]
|
||||
#![deny(missing_docs)]
|
||||
#![doc(html_root_url = "http://nalgebra.org/rustdoc")]
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
|
@ -189,3 +189,59 @@ fn columns_range_pair() {
|
||||
32.0, 33.0, 34.0);
|
||||
assert!(l.eq(&expected_l) && r.eq(&expected_r));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn row_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.row(3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn rows_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.rows(1, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn rows_with_step_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.rows_with_step(1, 2, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn column_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.column(4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn columns_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.columns(2, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn columns_with_step_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.columns_with_step(2, 2, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn slice_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.slice((1, 2), (3, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn slice_with_steps_out_of_bounds() {
|
||||
let a = Matrix3x4::<f32>::zeros();
|
||||
a.slice_with_steps((1, 2), (2, 2), (0, 1));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user