From a7ab61f9745dd21ea7dce5b713b0fcff36341fe8 Mon Sep 17 00:00:00 2001 From: sebcrozet Date: Tue, 29 Jan 2019 12:03:48 +0100 Subject: [PATCH] Add horizontal and vertical resizing for dynamic matrices and vectors. --- src/base/edition.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/base/edition.rs b/src/base/edition.rs index 0ae9c35f..74acd5d9 100644 --- a/src/base/edition.rs +++ b/src/base/edition.rs @@ -1,6 +1,7 @@ use num::{One, Zero}; use std::cmp; use std::ptr; +use std::mem; use base::allocator::{Allocator, Reallocator}; use base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; @@ -549,6 +550,29 @@ impl> Matrix { self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val) } + /// Resizes this matrix vertically, i.e., so that it contains `new_nrows` rows while keeping the same number of columns. + /// + /// 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: N) -> MatrixMN + where DefaultAllocator: Reallocator { + let ncols = self.data.shape().1; + self.resize_generic(Dynamic::new(new_nrows), ncols, val) + } + + /// Resizes this matrix horizontally, i.e., so that it contains `new_ncolumns` columns while keeping the same number of columns. + /// + /// 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: N) -> MatrixMN + where DefaultAllocator: Reallocator { + let nrows = self.data.shape().0; + self.resize_generic(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 @@ -626,6 +650,59 @@ impl> Matrix { } } +impl DMatrix { + /// Resizes this matrix in-place. + /// + /// 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`. + /// + /// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`. + #[cfg(any(feature = "std", feature = "alloc"))] + pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: N) + where DefaultAllocator: Reallocator { + let placeholder = unsafe { Self::new_uninitialized(0, 0) }; + let old = mem::replace(self, placeholder); + let new = old.resize(new_nrows, new_ncols, val); + let _ = mem::replace(self, new); + } +} + +impl MatrixMN + where DefaultAllocator: Allocator { + /// Changes the number of rows of this matrix in-place. + /// + /// 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`. + /// + /// Defined only for owned matrices with a dynamic number of rows (for example, `DVector`). + #[cfg(any(feature = "std", feature = "alloc"))] + pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: N) + where DefaultAllocator: Reallocator { + let placeholder = unsafe { Self::new_uninitialized_generic(Dynamic::new(0), self.data.shape().1) }; + let old = mem::replace(self, placeholder); + let new = old.resize_vertically(new_nrows, val); + let _ = mem::replace(self, new); + } +} + +impl MatrixMN + where DefaultAllocator: Allocator { + /// Changes the number of column of this matrix in-place. + /// + /// 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`. + /// + /// Defined only for owned matrices with a dynamic number of columns (for example, `DVector`). + #[cfg(any(feature = "std", feature = "alloc"))] + pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: N) + where DefaultAllocator: Reallocator { + let placeholder = unsafe { Self::new_uninitialized_generic(self.data.shape().0, Dynamic::new(0)) }; + let old = mem::replace(self, placeholder); + let new = old.resize_horizontally(new_ncols, val); + let _ = mem::replace(self, new); + } +} + unsafe fn compress_rows( data: &mut [N], nrows: usize,