Add `assign` and generalize `map` to other return types.

The method assign replaces each components with the result of a closure (that takes the
corresponding component as parameter).
This commit is contained in:
Sébastien Crozet 2017-08-13 19:52:53 +02:00 committed by Sébastien Crozet
parent 053de0576f
commit 41f5231446
2 changed files with 57 additions and 2 deletions

View File

@ -284,8 +284,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Returns a matrix containing the result of `f` applied to each of its entries.
#[inline]
pub fn map<F: FnMut(N) -> N>(&self, mut f: F) -> MatrixMN<N, R, C>
where DefaultAllocator: Allocator<N, R, C> {
pub fn map<N2: Scalar, F: FnMut(N) -> N2>(&self, mut f: F) -> MatrixMN<N2, R, C>
where DefaultAllocator: Allocator<N2, R, C> {
let (nrows, ncols) = self.data.shape();
let mut res = unsafe { MatrixMN::new_uninitialized_generic(nrows, ncols) };
@ -440,6 +440,22 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
ShapeConstraint: SameNumberOfRows<R, R2> {
self.column_mut(i).copy_from(column);
}
/// Replaces each component of `self` by the result of a closure `f` applied on it.
#[inline]
pub fn apply<F: FnMut(N) -> N>(&mut self, mut f: F)
where DefaultAllocator: Allocator<N, R, C> {
let (nrows, ncols) = self.shape();
for j in 0 .. ncols {
for i in 0 .. nrows {
unsafe {
let e = self.data.get_unchecked_mut(i, j);
*e = f(*e)
}
}
}
}
}
impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {

View File

@ -1,4 +1,5 @@
use num::{Zero, One};
use num::Float;
use std::fmt::Display;
use alga::linear::FiniteDimInnerSpace;
@ -395,6 +396,44 @@ fn simple_scalar_conversion() {
assert_eq!(expected, a_u32);
}
#[test]
fn apply() {
let mut a = Matrix4::new(
1.1, 2.2, 3.3, 4.4,
5.5, 6.6, 7.7, 8.8,
9.9, 8.8, 7.7, 6.6,
5.5, 4.4, 3.3, 2.2);
let expected = Matrix4::new(
1.0, 2.0, 3.0, 4.0,
6.0, 7.0, 8.0, 9.0,
10.0, 9.0, 8.0, 7.0,
6.0, 4.0, 3.0, 2.0);
a.apply(|e| e.round());
assert_eq!(a, expected);
}
#[test]
fn map() {
let a = Matrix4::new(
1.1f64, 2.2, 3.3, 4.4,
5.5, 6.6, 7.7, 8.8,
9.9, 8.8, 7.7, 6.6,
5.5, 4.4, 3.3, 2.2);
let expected = Matrix4::new(
1, 2, 3, 4,
6, 7, 8, 9,
10, 9, 8, 7,
6, 4, 3, 2);
let computed = a.map(|e| e.round() as i64);
assert_eq!(computed, expected);
}
#[test]
#[should_panic]
fn trace_panic() {