from_row_iterator added
This commit is contained in:
parent
d0d88f1e82
commit
008511d96e
|
@ -41,6 +41,13 @@ pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
|
||||||
ncols: C,
|
ncols: C,
|
||||||
iter: I,
|
iter: I,
|
||||||
) -> Self::Buffer;
|
) -> Self::Buffer;
|
||||||
|
|
||||||
|
/// Allocates a buffer initialized with the content of the given row-major order iterator.
|
||||||
|
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
|
||||||
|
nrows: R,
|
||||||
|
ncols: C,
|
||||||
|
iter: I,
|
||||||
|
) -> Self::Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` ×
|
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` ×
|
||||||
|
|
|
@ -86,6 +86,17 @@ where
|
||||||
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a matrix with all its elements filled by an row-major order iterator.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_row_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = T>,
|
||||||
|
{
|
||||||
|
Self::from_data(DefaultAllocator::allocate_from_row_iterator(
|
||||||
|
nrows, ncols, iter,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a matrix with its elements filled with the components provided by a slice in
|
/// Creates a matrix with its elements filled with the components provided by a slice in
|
||||||
/// row-major order.
|
/// row-major order.
|
||||||
///
|
///
|
||||||
|
@ -479,6 +490,36 @@ macro_rules! impl_constructors(
|
||||||
Self::from_iterator_generic($($gargs, )* iter)
|
Self::from_iterator_generic($($gargs, )* iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a matrix or vector with all its elements filled by a row-major iterator.
|
||||||
|
///
|
||||||
|
/// The output matrix is filled row-by-row.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
|
||||||
|
/// # use std::iter;
|
||||||
|
///
|
||||||
|
/// let v = Vector3::from_row_iterator((0..3).into_iter());
|
||||||
|
/// // The additional argument represents the vector dimension.
|
||||||
|
/// let dv = DVector::from_row_iterator(3, (0..3).into_iter());
|
||||||
|
/// let m = Matrix2x3::from_row_iterator((0..6).into_iter());
|
||||||
|
/// // The two additional arguments represent the matrix dimensions.
|
||||||
|
/// let dm = DMatrix::from_row_iterator(2, 3, (0..6).into_iter());
|
||||||
|
///
|
||||||
|
/// // For Vectors from_row_iterator is identical to from_iterator
|
||||||
|
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
|
||||||
|
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
|
||||||
|
/// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
|
||||||
|
/// m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
|
||||||
|
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
|
||||||
|
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn from_row_iterator<I>($($args: usize,)* iter: I) -> Self
|
||||||
|
where I: IntoIterator<Item = T> {
|
||||||
|
Self::from_row_iterator_generic($($gargs, )* iter)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a matrix or vector filled with the results of a function applied to each of its
|
/// Creates a matrix or vector filled with the results of a function applied to each of its
|
||||||
/// component coordinates.
|
/// component coordinates.
|
||||||
///
|
///
|
||||||
|
|
|
@ -80,6 +80,40 @@ impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
|
||||||
// yielded enough elements to initialize our matrix.
|
// yielded enough elements to initialize our matrix.
|
||||||
unsafe { <Self as Allocator<T, Const<R>, Const<C>>>::assume_init(res) }
|
unsafe { <Self as Allocator<T, Const<R>, Const<C>>>::assume_init(res) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
|
||||||
|
nrows: Const<R>,
|
||||||
|
ncols: Const<C>,
|
||||||
|
iter: I,
|
||||||
|
) -> Self::Buffer {
|
||||||
|
#[cfg(feature = "no_unsound_assume_init")]
|
||||||
|
let mut res: Self::Buffer = unimplemented!();
|
||||||
|
#[cfg(not(feature = "no_unsound_assume_init"))]
|
||||||
|
let mut res = unsafe { Self::allocate_uninitialized(nrows, ncols).assume_init() };
|
||||||
|
let mut count = 0;
|
||||||
|
let res_ptr = res.as_mut_slice();
|
||||||
|
|
||||||
|
for (i, e) in iter
|
||||||
|
.into_iter()
|
||||||
|
.take(ncols.value() * nrows.value())
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
*res_ptr
|
||||||
|
.get_unchecked_mut((i % ncols.value()) * nrows.value() + i / ncols.value()) = e;
|
||||||
|
}
|
||||||
|
// res_ptr[(i % ncols.value()) * nrows.value() + i / ncols.value()] = e;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
count == nrows.value() * ncols.value(),
|
||||||
|
"Matrix init. from row iterator: iterator not long enough."
|
||||||
|
);
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic - Static
|
// Dynamic - Static
|
||||||
|
@ -128,6 +162,32 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
|
||||||
|
|
||||||
VecStorage::new(nrows, ncols, res)
|
VecStorage::new(nrows, ncols, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
|
||||||
|
nrows: Dynamic,
|
||||||
|
ncols: C,
|
||||||
|
iter: I,
|
||||||
|
) -> Self::Buffer {
|
||||||
|
let it = iter.into_iter().take(nrows.value() * ncols.value());
|
||||||
|
let mut res: Vec<T> = Vec::with_capacity(nrows.value() * ncols.value());
|
||||||
|
let res_ptr = res.as_mut_ptr();
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
for (i, e) in it.enumerate() {
|
||||||
|
*res_ptr.add((i % ncols.value()) * nrows.value() + i / ncols.value()) = e;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
res.set_len(nrows.value() * ncols.value());
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
count == nrows.value() * ncols.value(),
|
||||||
|
"Matrix init. from row iterator: iterator not long enough."
|
||||||
|
);
|
||||||
|
|
||||||
|
VecStorage::new(nrows, ncols, res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static - Dynamic
|
// Static - Dynamic
|
||||||
|
@ -176,6 +236,32 @@ impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
|
||||||
|
|
||||||
VecStorage::new(nrows, ncols, res)
|
VecStorage::new(nrows, ncols, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
|
||||||
|
nrows: R,
|
||||||
|
ncols: Dynamic,
|
||||||
|
iter: I,
|
||||||
|
) -> Self::Buffer {
|
||||||
|
let it = iter.into_iter().take(nrows.value() * ncols.value());
|
||||||
|
let mut res: Vec<T> = Vec::with_capacity(nrows.value() * ncols.value());
|
||||||
|
let res_ptr = res.as_mut_ptr();
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
for (i, e) in it.enumerate() {
|
||||||
|
*res_ptr.add((i % ncols.value()) * nrows.value() + i / ncols.value()) = e;
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
res.set_len(nrows.value() * ncols.value());
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
count == nrows.value() * ncols.value(),
|
||||||
|
"Matrix init. from row iterator: iterator not long enough."
|
||||||
|
);
|
||||||
|
|
||||||
|
VecStorage::new(nrows, ncols, res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue