Initial draft for into_row_iter and into_column_iter
https://github.com/dimforge/nalgebra/issues/834
This commit is contained in:
parent
6ed6084745
commit
267eb01fe5
|
@ -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;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
114
src/base/iter.rs
114
src/base/iter.rs
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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>;
|
||||||
|
|
Loading…
Reference in New Issue