forked from M-Labs/nalgebra
Merge pull request #797 from Recmo/remco/feat/double-ended-iter
impl DoubleEndedIterator for {MatrixIter, MatrixIterMut}
This commit is contained in:
commit
bc6faa22f3
@ -136,6 +136,30 @@ fn mat500_mul_mat500(bench: &mut criterion::Criterion) {
|
|||||||
bench.bench_function("mat500_mul_mat500", move |bh| bh.iter(|| &a * &b));
|
bench.bench_function("mat500_mul_mat500", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn iter(bench: &mut criterion::Criterion) {
|
||||||
|
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
|
|
||||||
|
bench.bench_function("iter", move |bh| {
|
||||||
|
bh.iter(|| {
|
||||||
|
for value in a.iter() {
|
||||||
|
criterion::black_box(value);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_rev(bench: &mut criterion::Criterion) {
|
||||||
|
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
|
|
||||||
|
bench.bench_function("iter_rev", move |bh| {
|
||||||
|
bh.iter(|| {
|
||||||
|
for value in a.iter().rev() {
|
||||||
|
criterion::black_box(value);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn copy_from(bench: &mut criterion::Criterion) {
|
fn copy_from(bench: &mut criterion::Criterion) {
|
||||||
let a = DMatrix::<f64>::new_random(1000, 1000);
|
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let mut b = DMatrix::<f64>::new_random(1000, 1000);
|
let mut b = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
@ -235,6 +259,8 @@ criterion_group!(
|
|||||||
mat10_mul_mat10_static,
|
mat10_mul_mat10_static,
|
||||||
mat100_mul_mat100,
|
mat100_mul_mat100,
|
||||||
mat500_mul_mat500,
|
mat500_mul_mat500,
|
||||||
|
iter,
|
||||||
|
iter_rev,
|
||||||
copy_from,
|
copy_from,
|
||||||
axpy,
|
axpy,
|
||||||
tr_mul_to,
|
tr_mul_to,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Matrix iterators.
|
//! Matrix iterators.
|
||||||
|
|
||||||
|
use std::iter::FusedIterator;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
@ -111,6 +112,46 @@ macro_rules! iterator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> DoubleEndedIterator
|
||||||
|
for $Name<'a, N, R, C, S>
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn next_back(&mut self) -> Option<$Ref> {
|
||||||
|
unsafe {
|
||||||
|
if self.size == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// Pre-decrement `size` such that it now counts to the
|
||||||
|
// element we want to return.
|
||||||
|
self.size -= 1;
|
||||||
|
|
||||||
|
// Fetch strides
|
||||||
|
let inner_stride = self.strides.0.value();
|
||||||
|
let outer_stride = self.strides.1.value();
|
||||||
|
|
||||||
|
// Compute number of rows
|
||||||
|
// Division should be exact
|
||||||
|
let inner_raw_size = self.inner_end.offset_from(self.inner_ptr) as usize;
|
||||||
|
let inner_size = inner_raw_size / inner_stride;
|
||||||
|
|
||||||
|
// Compute rows and cols remaining
|
||||||
|
let outer_remaining = self.size / inner_size;
|
||||||
|
let inner_remaining = self.size % inner_size;
|
||||||
|
|
||||||
|
// Compute pointer to last element
|
||||||
|
let last = self.ptr.offset(
|
||||||
|
(outer_remaining * outer_stride + inner_remaining * inner_stride)
|
||||||
|
as isize,
|
||||||
|
);
|
||||||
|
|
||||||
|
// We want either `& *last` or `&mut *last` here, depending
|
||||||
|
// on the mutability of `$Ref`.
|
||||||
|
Some(mem::transmute(last))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> ExactSizeIterator
|
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> ExactSizeIterator
|
||||||
for $Name<'a, N, R, C, S>
|
for $Name<'a, N, R, C, S>
|
||||||
{
|
{
|
||||||
@ -119,6 +160,11 @@ macro_rules! iterator {
|
|||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> FusedIterator
|
||||||
|
for $Name<'a, N, R, C, S>
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,24 @@ fn iter() {
|
|||||||
assert_eq!(*it.next().unwrap(), 6.0);
|
assert_eq!(*it.next().unwrap(), 6.0);
|
||||||
assert!(it.next().is_none());
|
assert!(it.next().is_none());
|
||||||
|
|
||||||
|
let mut it = a.iter();
|
||||||
|
assert_eq!(*it.next().unwrap(), 1.0);
|
||||||
|
assert_eq!(*it.next_back().unwrap(), 6.0);
|
||||||
|
assert_eq!(*it.next_back().unwrap(), 3.0);
|
||||||
|
assert_eq!(*it.next_back().unwrap(), 5.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 4.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 2.0);
|
||||||
|
assert!(it.next().is_none());
|
||||||
|
|
||||||
|
let mut it = a.iter().rev();
|
||||||
|
assert_eq!(*it.next().unwrap(), 6.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 3.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 5.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 2.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 4.0);
|
||||||
|
assert_eq!(*it.next().unwrap(), 1.0);
|
||||||
|
assert!(it.next().is_none());
|
||||||
|
|
||||||
let row = a.row(0);
|
let row = a.row(0);
|
||||||
let mut it = row.iter();
|
let mut it = row.iter();
|
||||||
assert_eq!(*it.next().unwrap(), 1.0);
|
assert_eq!(*it.next().unwrap(), 1.0);
|
||||||
|
Loading…
Reference in New Issue
Block a user