Initial draft for into_row_iter and into_column_iter

https://github.com/dimforge/nalgebra/issues/834
This commit is contained in:
Linus Behrbohm 2021-02-22 00:47:33 +01:00
parent 6ed6084745
commit 267eb01fe5
6 changed files with 192 additions and 8 deletions

View File

@ -18,7 +18,7 @@ use crate::base::{DefaultAllocator, Scalar};
/// same `Buffer` type. /// same `Buffer` type.
pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized { pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
/// The type of buffer this allocator can instanciate. /// The type of buffer this allocator can instanciate.
type Buffer: ContiguousStorageMut<N, R, C> + Clone; type Buffer: ContiguousStorageMut<N, R, C> + Clone + IntoIterator<Item=N>;
/// Allocates a buffer with the given number of rows and columns without initializing its content. /// Allocates a buffer with the given number of rows and columns without initializing its content.
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer; unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer;

View File

@ -46,6 +46,20 @@ where
data: GenericArray<N, Prod<R::Value, C::Value>>, data: GenericArray<N, Prod<R::Value, C::Value>>,
} }
impl<N, R, C> IntoIterator for ArrayStorage<N, R, C>
where
R: DimName,
C: DimName,
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
{
type Item = N;
type IntoIter = <GenericArray<N, Prod<R::Value, C::Value>> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
#[deprecated(note = "renamed to `ArrayStorage`")] #[deprecated(note = "renamed to `ArrayStorage`")]
/// Renamed to [ArrayStorage]. /// Renamed to [ArrayStorage].
pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>; pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>;

View File

@ -21,7 +21,7 @@ use crate::base::dimension::{
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
}; };
use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut, Owned};
use crate::base::{ use crate::base::{
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixMN, MatrixSlice, ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixMN, MatrixSlice,
MatrixSliceMut, Scalar, MatrixSliceMut, Scalar,
@ -86,6 +86,17 @@ where
} }
} }
impl<N: Scalar, R: Dim, C: Dim> IntoIterator for Matrix<N, R, C, Owned<N, R, C>>
where DefaultAllocator: Allocator<N, R, C>
{
type Item = N;
type IntoIter = <Owned<N, R, C> as IntoIterator>::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
<Owned<N, R, C> as IntoIterator>::into_iter(self.data)
}
}
impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Matrix<N, R, C, S> { impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Matrix<N, R, C, S> {
type Item = &'a N; type Item = &'a N;
type IntoIter = MatrixIter<'a, N, R, C, S>; type IntoIter = MatrixIter<'a, N, R, C, S>;

View File

@ -3,9 +3,9 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use crate::base::dimension::{Dim, U1}; use crate::base::dimension::{Dim, U1, Dynamic};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut, Owned};
use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar}; use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar, Vector, RowVector};
macro_rules! iterator { macro_rules! iterator {
(struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
@ -237,6 +237,58 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
} }
} }
/// An owned iterator through the rows of a matrix.
pub struct OwnedRowIter<N: Scalar> {
rows: std::vec::IntoIter<RowVector<N, Dynamic, Owned<N, U1, Dynamic>>>,
}
impl<N: Scalar> OwnedRowIter<N> {
pub(crate) fn new(mat: Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>>) -> Self {
let ncols = mat.ncols();
let nrows = mat.nrows();
let mut rows: Vec<Vec<N>> = vec![Vec::with_capacity(ncols); nrows];
let mut i = 0;
for item in mat.into_iter() {
rows[i % nrows].push(item);
i += 1;
}
let rows: Vec<RowVector<N, Dynamic, Owned<N, U1, Dynamic>>> =
rows.into_iter()
.map(|row| RowVector::<N, Dynamic, Owned<N, U1, Dynamic>>::from_iterator_generic(
U1::from_usize(1), Dynamic::from_usize(ncols), row.into_iter()))
.collect();
OwnedRowIter { rows: rows.into_iter() }
}
}
impl<N: Scalar> Iterator for OwnedRowIter<N> {
type Item = RowVector<N, Dynamic, Owned<N, U1, Dynamic>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.rows.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.rows.size_hint()
}
#[inline]
fn count(self) -> usize {
self.rows.count()
}
}
impl<N: Scalar> ExactSizeIterator
for OwnedRowIter<N>
{
#[inline]
fn len(&self) -> usize {
self.rows.len()
}
}
/* /*
* *
* Column iterators. * Column iterators.
@ -350,3 +402,59 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
self.ncols() - self.curr self.ncols() - self.curr
} }
} }
/// An owned iterator through the rows of a matrix.
pub struct OwnedColumnIter<N: Scalar> {
cols: std::vec::IntoIter<Vector<N, Dynamic, Owned<N, Dynamic, U1>>>,
}
impl<N: Scalar> OwnedColumnIter<N> {
pub(crate) fn new(mat: Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>>) -> Self {
let ncols = mat.ncols();
let nrows = mat.nrows();
let mut cols: Vec<Vec<N>> = vec![Vec::with_capacity(nrows); ncols];
let mut i = 0;
for item in mat.into_iter() {
cols[i / nrows].push(item);
i += 1;
}
let cols: Vec<Vector<N, Dynamic, Owned<N, Dynamic, U1>>> =
cols.into_iter()
.map(|col|
Vector::<N, Dynamic, Owned<N, Dynamic, U1>>::from_iterator_generic(
Dynamic::from_usize(nrows),
U1::from_usize(1),
col.into_iter()
)
)
.collect();
OwnedColumnIter { cols: cols.into_iter() }
}
}
impl<N: Scalar> Iterator for OwnedColumnIter<N> {
type Item = Vector<N, Dynamic, Owned<N, Dynamic, U1>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.cols.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.cols.size_hint()
}
#[inline]
fn count(self) -> usize {
self.cols.count()
}
}
impl<N: Scalar> ExactSizeIterator
for OwnedColumnIter<N> {
#[inline]
fn len(&self) -> usize {
self.cols.len()
}
}

View File

@ -21,12 +21,12 @@ use simba::simd::SimdPartialOrd;
use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR}; use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR};
use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::base::dimension::{Dim, DimAdd, DimSum, IsNotStaticOne, U1, U2, U3}; use crate::base::dimension::{Dim, DimAdd, DimSum, IsNotStaticOne, U1, U2, U3, Dynamic};
use crate::base::iter::{ use crate::base::iter::{
ColumnIter, ColumnIterMut, MatrixIter, MatrixIterMut, RowIter, RowIterMut, ColumnIter, ColumnIterMut, OwnedColumnIter, MatrixIter, MatrixIterMut, RowIter, RowIterMut, OwnedRowIter,
}; };
use crate::base::storage::{ use crate::base::storage::{
ContiguousStorage, ContiguousStorageMut, Owned, SameShapeStorage, Storage, StorageMut, ContiguousStorage, ContiguousStorageMut, SameShapeStorage, Storage, StorageMut, Owned
}; };
use crate::base::{DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN}; use crate::base::{DefaultAllocator, MatrixMN, MatrixN, Scalar, Unit, VectorN};
use crate::SimdComplexField; use crate::SimdComplexField;
@ -859,6 +859,45 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
} }
impl<N: Scalar> Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>> {
/// Move rows of this matrix into an owned iterator.
///
/// # Example
/// ```
/// # use nalgebra::DMatrix;
/// let values = vec![1, 4, 2, 5, 3, 6].into_iter();
/// let mut a = DMatrix::from_iterator(2, 3, values);
/// let c = a.clone();
/// for (i, row) in a.into_row_iter().enumerate() {
/// for (v1, &v2) in row.into_iter().zip(c.row(i).iter()) {
/// assert_eq!(v1, v2)
/// }
/// }
/// ```
#[inline]
pub fn into_row_iter(self) -> OwnedRowIter<N> {
OwnedRowIter::new(self)
}
/// Move columns of this matrix into an owned iterator.
/// # Example
/// ```
/// # use nalgebra::DMatrix;
/// let values = vec![1, 4, 2, 5, 3, 6].into_iter();
/// let mut a = DMatrix::from_iterator(2, 3, values);
/// let c = a.clone();
/// for (i, column) in a.into_column_iter().enumerate() {
/// for (v1, &v2) in column.into_iter().zip(c.column(i).iter()) {
/// assert_eq!(v1, v2)
/// }
/// }
/// ```
#[inline]
pub fn into_column_iter(self) -> OwnedColumnIter<N> {
OwnedColumnIter::new(self)
}
}
/// # Iteration on components, rows, and columns /// # Iteration on components, rows, and columns
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: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Iterates through this matrix coordinates in column-major order. /// Iterates through this matrix coordinates in column-major order.

View File

@ -31,6 +31,18 @@ pub struct VecStorage<N, R: Dim, C: Dim> {
ncols: C, ncols: C,
} }
impl<N, R, C> IntoIterator for VecStorage<N, R, C>
where
R: Dim,
C: Dim,
{
type Item = N;
type IntoIter = <Vec<N> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.data.into_iter()
}
}
#[deprecated(note = "renamed to `VecStorage`")] #[deprecated(note = "renamed to `VecStorage`")]
/// Renamed to [VecStorage]. /// Renamed to [VecStorage].
pub type MatrixVec<N, R, C> = VecStorage<N, R, C>; pub type MatrixVec<N, R, C> = VecStorage<N, R, C>;