pub struct Zip<Parts, D> { /* private fields */ }
Expand description
Lock step function application across several arrays or other producers.
Zip allows matching several producers to each other elementwise and applying a function over all tuples of elements (one item from each input at a time).
In general, the zip uses a tuple of producers
(NdProducer
trait) that all have to be of the
same shape. The NdProducer implementation defines what its item type is
(for example if it’s a shared reference, mutable reference or an array
view etc).
If all the input arrays are of the same memory layout the zip performs much better and the compiler can usually vectorize the loop (if applicable).
The order elements are visited is not specified. The producers don’t have to have the same item type.
The Zip
has two methods for function application: for_each
and
fold_while
. The zip object can be split, which allows parallelization.
A read-only zip object (no mutable producers) can be cloned.
See also the azip!()
which offers a convenient shorthand
to common ways to use Zip
.
use ndarray::Zip;
use ndarray::Array2;
type M = Array2<f64>;
// Create four 2d arrays of the same size
let mut a = M::zeros((64, 32));
let b = M::from_elem(a.dim(), 1.);
let c = M::from_elem(a.dim(), 2.);
let d = M::from_elem(a.dim(), 3.);
// Example 1: Perform an elementwise arithmetic operation across
// the four arrays a, b, c, d.
Zip::from(&mut a)
.and(&b)
.and(&c)
.and(&d)
.for_each(|w, &x, &y, &z| {
*w += x + y * z;
});
// Example 2: Create a new array `totals` with one entry per row of `a`.
// Use Zip to traverse the rows of `a` and assign to the corresponding
// entry in `totals` with the sum across each row.
// This is possible because the producer for `totals` and the row producer
// for `a` have the same shape and dimensionality.
// The rows producer yields one array view (`row`) per iteration.
use ndarray::{Array1, Axis};
let mut totals = Array1::zeros(a.nrows());
Zip::from(&mut totals)
.and(a.rows())
.for_each(|totals, row| *totals = row.sum());
// Check the result against the built in `.sum_axis()` along axis 1.
assert_eq!(totals, a.sum_axis(Axis(1)));
// Example 3: Recreate Example 2 using map_collect to make a new array
let totals2 = Zip::from(a.rows()).map_collect(|row| row.sum());
// Check the result against the previous example.
assert_eq!(totals, totals2);
Implementations
sourceimpl<P, D> Zip<(P,), D> where
D: Dimension,
P: NdProducer<Dim = D>,
impl<P, D> Zip<(P,), D> where
D: Dimension,
P: NdProducer<Dim = D>,
sourcepub fn from<IP>(p: IP) -> Self where
IP: IntoNdProducer<Dim = D, Output = P, Item = P::Item>,
pub fn from<IP>(p: IP) -> Self where
IP: IntoNdProducer<Dim = D, Output = P, Item = P::Item>,
Create a new Zip
from the input array or other producer p
.
The Zip will take the exact dimension of p
and all inputs
must have the same dimensions (or be broadcast to them).
sourceimpl<P, D> Zip<(Indices<D>, P), D> where
D: Dimension + Copy,
P: NdProducer<Dim = D>,
impl<P, D> Zip<(Indices<D>, P), D> where
D: Dimension + Copy,
P: NdProducer<Dim = D>,
sourcepub fn indexed<IP>(p: IP) -> Self where
IP: IntoNdProducer<Dim = D, Output = P, Item = P::Item>,
pub fn indexed<IP>(p: IP) -> Self where
IP: IntoNdProducer<Dim = D, Output = P, Item = P::Item>,
Create a new Zip
with an index producer and the producer p
.
The Zip will take the exact dimension of p
and all inputs
must have the same dimensions (or be broadcast to them).
Note: Indexed zip has overhead.
sourceimpl<D, P1> Zip<(P1,), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
impl<D, P1> Zip<(P1,), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
sourcepub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item),
pub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item),
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn apply<F>(self, function: F) where
F: FnMut(P1::Item),
👎 Deprecated since 0.15.0: Renamed to .for_each()
pub fn apply<F>(self, function: F) where
F: FnMut(P1::Item),
Renamed to .for_each()
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item) -> Acc,
pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item) -> Acc,
Apply a fold function to all elements of the input arrays, visiting elements in lock step.
Example
The expression tr(AᵀB)
can be more efficiently computed as
the equivalent expression ∑ᵢⱼ(A∘B)ᵢⱼ
(i.e. the sum of the
elements of the entry-wise product). It would be possible to
evaluate this expression by first computing the entry-wise
product, A∘B
, and then computing the elementwise sum of that
product, but it’s possible to do this in a single loop (and
avoid an extra heap allocation if A
and B
can’t be
consumed) by using Zip
:
use ndarray::{array, Zip};
let a = array![[1, 5], [3, 7]];
let b = array![[2, 4], [8, 6]];
// Without using `Zip`. This involves two loops and an extra
// heap allocation for the result of `&a * &b`.
let sum_prod_nonzip = (&a * &b).sum();
// Using `Zip`. This is a single loop without any heap allocations.
let sum_prod_zip = Zip::from(&a).and(&b).fold(0, |acc, a, b| acc + a * b);
assert_eq!(sum_prod_nonzip, sum_prod_zip);
sourcepub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item) -> FoldWhile<Acc>,
pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item) -> FoldWhile<Acc>,
Apply a fold function to the input arrays while the return
value is FoldWhile::Continue
, visiting elements in lock step.
sourcepub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item) -> bool,
pub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item) -> bool,
Tests if every element of the iterator matches a predicate.
Returns true
if predicate
evaluates to true
for all elements.
Returns true
if the input arrays are empty.
Example:
use ndarray::{array, Zip};
let a = array![1, 2, 3];
let b = array![1, 4, 9];
assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b));
sourcepub fn and<P>(self, p: P) -> Zip<(P1, P::Output), D> where
P: IntoNdProducer<Dim = D>,
pub fn and<P>(self, p: P) -> Zip<(P1, P::Output), D> where
P: IntoNdProducer<Dim = D>,
Include the producer p
in the Zip.
Panics if p
’s shape doesn’t match the Zip’s exactly.
sourcepub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
pub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
Include the producer p
in the Zip, broadcasting if needed.
If their shapes disagree, rhs
is broadcast to the shape of self
.
Panics if broadcasting isn’t possible.
sourcepub fn map_collect<R>(self, f: impl FnMut(P1::Item) -> R) -> Array<R, D>
pub fn map_collect<R>(self, f: impl FnMut(P1::Item) -> R) -> Array<R, D>
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn apply_collect<R>(self, f: impl FnMut(P1::Item) -> R) -> Array<R, D>
👎 Deprecated since 0.15.0: Renamed to .map_collect()
pub fn apply_collect<R>(self, f: impl FnMut(P1::Item) -> R) -> Array<R, D>
Renamed to .map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn map_assign_into<R, Q>(self, into: Q, f: impl FnMut(P1::Item) -> R) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
pub fn map_assign_into<R, Q>(self, into: Q, f: impl FnMut(P1::Item) -> R) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn apply_assign_into<R, Q>(self, into: Q, f: impl FnMut(P1::Item) -> R) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
👎 Deprecated since 0.15.0: Renamed to .map_assign_into()
pub fn apply_assign_into<R, Q>(self, into: Q, f: impl FnMut(P1::Item) -> R) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Renamed to .map_assign_into()
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn split(self) -> (Self, Self)
pub fn split(self) -> (Self, Self)
Split the Zip
evenly in two.
It will be split in the way that best preserves element locality.
sourceimpl<D, P1, P2> Zip<(P1, P2), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
impl<D, P1, P2> Zip<(P1, P2), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
sourcepub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item),
pub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item),
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item),
👎 Deprecated since 0.15.0: Renamed to .for_each()
pub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item),
Renamed to .for_each()
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item) -> Acc,
pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item) -> Acc,
Apply a fold function to all elements of the input arrays, visiting elements in lock step.
Example
The expression tr(AᵀB)
can be more efficiently computed as
the equivalent expression ∑ᵢⱼ(A∘B)ᵢⱼ
(i.e. the sum of the
elements of the entry-wise product). It would be possible to
evaluate this expression by first computing the entry-wise
product, A∘B
, and then computing the elementwise sum of that
product, but it’s possible to do this in a single loop (and
avoid an extra heap allocation if A
and B
can’t be
consumed) by using Zip
:
use ndarray::{array, Zip};
let a = array![[1, 5], [3, 7]];
let b = array![[2, 4], [8, 6]];
// Without using `Zip`. This involves two loops and an extra
// heap allocation for the result of `&a * &b`.
let sum_prod_nonzip = (&a * &b).sum();
// Using `Zip`. This is a single loop without any heap allocations.
let sum_prod_zip = Zip::from(&a).and(&b).fold(0, |acc, a, b| acc + a * b);
assert_eq!(sum_prod_nonzip, sum_prod_zip);
sourcepub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item) -> FoldWhile<Acc>,
pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item) -> FoldWhile<Acc>,
Apply a fold function to the input arrays while the return
value is FoldWhile::Continue
, visiting elements in lock step.
sourcepub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item) -> bool,
pub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item) -> bool,
Tests if every element of the iterator matches a predicate.
Returns true
if predicate
evaluates to true
for all elements.
Returns true
if the input arrays are empty.
Example:
use ndarray::{array, Zip};
let a = array![1, 2, 3];
let b = array![1, 4, 9];
assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b));
sourcepub fn and<P>(self, p: P) -> Zip<(P1, P2, P::Output), D> where
P: IntoNdProducer<Dim = D>,
pub fn and<P>(self, p: P) -> Zip<(P1, P2, P::Output), D> where
P: IntoNdProducer<Dim = D>,
Include the producer p
in the Zip.
Panics if p
’s shape doesn’t match the Zip’s exactly.
sourcepub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
pub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
Include the producer p
in the Zip, broadcasting if needed.
If their shapes disagree, rhs
is broadcast to the shape of self
.
Panics if broadcasting isn’t possible.
sourcepub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item) -> R
) -> Array<R, D>
pub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item) -> R
) -> Array<R, D>
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item) -> R
) -> Array<R, D>
👎 Deprecated since 0.15.0: Renamed to .map_collect()
pub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item) -> R
) -> Array<R, D>
Renamed to .map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
pub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
👎 Deprecated since 0.15.0: Renamed to .map_assign_into()
pub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Renamed to .map_assign_into()
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn split(self) -> (Self, Self)
pub fn split(self) -> (Self, Self)
Split the Zip
evenly in two.
It will be split in the way that best preserves element locality.
sourceimpl<D, P1, P2, P3> Zip<(P1, P2, P3), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
impl<D, P1, P2, P3> Zip<(P1, P2, P3), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
sourcepub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item),
pub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item),
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item),
👎 Deprecated since 0.15.0: Renamed to .for_each()
pub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item),
Renamed to .for_each()
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item) -> Acc,
pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item) -> Acc,
Apply a fold function to all elements of the input arrays, visiting elements in lock step.
Example
The expression tr(AᵀB)
can be more efficiently computed as
the equivalent expression ∑ᵢⱼ(A∘B)ᵢⱼ
(i.e. the sum of the
elements of the entry-wise product). It would be possible to
evaluate this expression by first computing the entry-wise
product, A∘B
, and then computing the elementwise sum of that
product, but it’s possible to do this in a single loop (and
avoid an extra heap allocation if A
and B
can’t be
consumed) by using Zip
:
use ndarray::{array, Zip};
let a = array![[1, 5], [3, 7]];
let b = array![[2, 4], [8, 6]];
// Without using `Zip`. This involves two loops and an extra
// heap allocation for the result of `&a * &b`.
let sum_prod_nonzip = (&a * &b).sum();
// Using `Zip`. This is a single loop without any heap allocations.
let sum_prod_zip = Zip::from(&a).and(&b).fold(0, |acc, a, b| acc + a * b);
assert_eq!(sum_prod_nonzip, sum_prod_zip);
sourcepub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item) -> FoldWhile<Acc>,
pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item) -> FoldWhile<Acc>,
Apply a fold function to the input arrays while the return
value is FoldWhile::Continue
, visiting elements in lock step.
sourcepub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item) -> bool,
pub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item) -> bool,
Tests if every element of the iterator matches a predicate.
Returns true
if predicate
evaluates to true
for all elements.
Returns true
if the input arrays are empty.
Example:
use ndarray::{array, Zip};
let a = array![1, 2, 3];
let b = array![1, 4, 9];
assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b));
sourcepub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P::Output), D> where
P: IntoNdProducer<Dim = D>,
pub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P::Output), D> where
P: IntoNdProducer<Dim = D>,
Include the producer p
in the Zip.
Panics if p
’s shape doesn’t match the Zip’s exactly.
sourcepub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, P3, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
pub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, P3, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
Include the producer p
in the Zip, broadcasting if needed.
If their shapes disagree, rhs
is broadcast to the shape of self
.
Panics if broadcasting isn’t possible.
sourcepub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) -> Array<R, D>
pub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) -> Array<R, D>
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) -> Array<R, D>
👎 Deprecated since 0.15.0: Renamed to .map_collect()
pub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) -> Array<R, D>
Renamed to .map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
pub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
👎 Deprecated since 0.15.0: Renamed to .map_assign_into()
pub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Renamed to .map_assign_into()
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn split(self) -> (Self, Self)
pub fn split(self) -> (Self, Self)
Split the Zip
evenly in two.
It will be split in the way that best preserves element locality.
sourceimpl<D, P1, P2, P3, P4> Zip<(P1, P2, P3, P4), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4> Zip<(P1, P2, P3, P4), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
sourcepub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item),
pub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item),
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item),
👎 Deprecated since 0.15.0: Renamed to .for_each()
pub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item),
Renamed to .for_each()
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item) -> Acc,
pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item) -> Acc,
Apply a fold function to all elements of the input arrays, visiting elements in lock step.
Example
The expression tr(AᵀB)
can be more efficiently computed as
the equivalent expression ∑ᵢⱼ(A∘B)ᵢⱼ
(i.e. the sum of the
elements of the entry-wise product). It would be possible to
evaluate this expression by first computing the entry-wise
product, A∘B
, and then computing the elementwise sum of that
product, but it’s possible to do this in a single loop (and
avoid an extra heap allocation if A
and B
can’t be
consumed) by using Zip
:
use ndarray::{array, Zip};
let a = array![[1, 5], [3, 7]];
let b = array![[2, 4], [8, 6]];
// Without using `Zip`. This involves two loops and an extra
// heap allocation for the result of `&a * &b`.
let sum_prod_nonzip = (&a * &b).sum();
// Using `Zip`. This is a single loop without any heap allocations.
let sum_prod_zip = Zip::from(&a).and(&b).fold(0, |acc, a, b| acc + a * b);
assert_eq!(sum_prod_nonzip, sum_prod_zip);
sourcepub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item) -> FoldWhile<Acc>,
pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item) -> FoldWhile<Acc>,
Apply a fold function to the input arrays while the return
value is FoldWhile::Continue
, visiting elements in lock step.
sourcepub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> bool,
pub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> bool,
Tests if every element of the iterator matches a predicate.
Returns true
if predicate
evaluates to true
for all elements.
Returns true
if the input arrays are empty.
Example:
use ndarray::{array, Zip};
let a = array![1, 2, 3];
let b = array![1, 4, 9];
assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b));
sourcepub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P4, P::Output), D> where
P: IntoNdProducer<Dim = D>,
pub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P4, P::Output), D> where
P: IntoNdProducer<Dim = D>,
Include the producer p
in the Zip.
Panics if p
’s shape doesn’t match the Zip’s exactly.
sourcepub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, P3, P4, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
pub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, P3, P4, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
Include the producer p
in the Zip, broadcasting if needed.
If their shapes disagree, rhs
is broadcast to the shape of self
.
Panics if broadcasting isn’t possible.
sourcepub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) -> Array<R, D>
pub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) -> Array<R, D>
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) -> Array<R, D>
👎 Deprecated since 0.15.0: Renamed to .map_collect()
pub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) -> Array<R, D>
Renamed to .map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
pub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
👎 Deprecated since 0.15.0: Renamed to .map_assign_into()
pub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Renamed to .map_assign_into()
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn split(self) -> (Self, Self)
pub fn split(self) -> (Self, Self)
Split the Zip
evenly in two.
It will be split in the way that best preserves element locality.
sourceimpl<D, P1, P2, P3, P4, P5> Zip<(P1, P2, P3, P4, P5), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4, P5> Zip<(P1, P2, P3, P4, P5), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
sourcepub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item),
pub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item),
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item),
👎 Deprecated since 0.15.0: Renamed to .for_each()
pub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item),
Renamed to .for_each()
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> Acc,
pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> Acc,
Apply a fold function to all elements of the input arrays, visiting elements in lock step.
Example
The expression tr(AᵀB)
can be more efficiently computed as
the equivalent expression ∑ᵢⱼ(A∘B)ᵢⱼ
(i.e. the sum of the
elements of the entry-wise product). It would be possible to
evaluate this expression by first computing the entry-wise
product, A∘B
, and then computing the elementwise sum of that
product, but it’s possible to do this in a single loop (and
avoid an extra heap allocation if A
and B
can’t be
consumed) by using Zip
:
use ndarray::{array, Zip};
let a = array![[1, 5], [3, 7]];
let b = array![[2, 4], [8, 6]];
// Without using `Zip`. This involves two loops and an extra
// heap allocation for the result of `&a * &b`.
let sum_prod_nonzip = (&a * &b).sum();
// Using `Zip`. This is a single loop without any heap allocations.
let sum_prod_zip = Zip::from(&a).and(&b).fold(0, |acc, a, b| acc + a * b);
assert_eq!(sum_prod_nonzip, sum_prod_zip);
sourcepub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> FoldWhile<Acc>,
pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> FoldWhile<Acc>,
Apply a fold function to the input arrays while the return
value is FoldWhile::Continue
, visiting elements in lock step.
sourcepub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> bool,
pub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> bool,
Tests if every element of the iterator matches a predicate.
Returns true
if predicate
evaluates to true
for all elements.
Returns true
if the input arrays are empty.
Example:
use ndarray::{array, Zip};
let a = array![1, 2, 3];
let b = array![1, 4, 9];
assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b));
sourcepub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P4, P5, P::Output), D> where
P: IntoNdProducer<Dim = D>,
pub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P4, P5, P::Output), D> where
P: IntoNdProducer<Dim = D>,
Include the producer p
in the Zip.
Panics if p
’s shape doesn’t match the Zip’s exactly.
sourcepub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, P3, P4, P5, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
pub fn and_broadcast<'a, P, D2, Elem>(
self,
p: P
) -> Zip<(P1, P2, P3, P4, P5, ArrayView<'a, Elem, D>), D> where
P: IntoNdProducer<Dim = D2, Output = ArrayView<'a, Elem, D2>, Item = &'a Elem>,
D2: Dimension,
Include the producer p
in the Zip, broadcasting if needed.
If their shapes disagree, rhs
is broadcast to the shape of self
.
Panics if broadcasting isn’t possible.
sourcepub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) -> Array<R, D>
pub fn map_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) -> Array<R, D>
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) -> Array<R, D>
👎 Deprecated since 0.15.0: Renamed to .map_collect()
pub fn apply_collect<R>(
self,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) -> Array<R, D>
Renamed to .map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
pub fn map_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
👎 Deprecated since 0.15.0: Renamed to .map_assign_into()
pub fn apply_assign_into<R, Q>(
self,
into: Q,
f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R>,
Renamed to .map_assign_into()
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn split(self) -> (Self, Self)
pub fn split(self) -> (Self, Self)
Split the Zip
evenly in two.
It will be split in the way that best preserves element locality.
sourceimpl<D, P1, P2, P3, P4, P5, P6> Zip<(P1, P2, P3, P4, P5, P6), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
P6: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4, P5, P6> Zip<(P1, P2, P3, P4, P5, P6), D> where
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
P6: NdProducer<Dim = D>,
sourcepub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item),
pub fn for_each<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item),
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item),
👎 Deprecated since 0.15.0: Renamed to .for_each()
pub fn apply<F>(self, function: F) where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item),
Renamed to .for_each()
Apply a function to all elements of the input arrays, visiting elements in lock step.
sourcepub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> Acc,
pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> Acc,
Apply a fold function to all elements of the input arrays, visiting elements in lock step.
Example
The expression tr(AᵀB)
can be more efficiently computed as
the equivalent expression ∑ᵢⱼ(A∘B)ᵢⱼ
(i.e. the sum of the
elements of the entry-wise product). It would be possible to
evaluate this expression by first computing the entry-wise
product, A∘B
, and then computing the elementwise sum of that
product, but it’s possible to do this in a single loop (and
avoid an extra heap allocation if A
and B
can’t be
consumed) by using Zip
:
use ndarray::{array, Zip};
let a = array![[1, 5], [3, 7]];
let b = array![[2, 4], [8, 6]];
// Without using `Zip`. This involves two loops and an extra
// heap allocation for the result of `&a * &b`.
let sum_prod_nonzip = (&a * &b).sum();
// Using `Zip`. This is a single loop without any heap allocations.
let sum_prod_zip = Zip::from(&a).and(&b).fold(0, |acc, a, b| acc + a * b);
assert_eq!(sum_prod_nonzip, sum_prod_zip);
sourcepub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> FoldWhile<Acc>,
pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> FoldWhile<Acc>,
Apply a fold function to the input arrays while the return
value is FoldWhile::Continue
, visiting elements in lock step.
sourcepub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> bool,
pub fn all<F>(self, predicate: F) -> bool where
F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> bool,
Tests if every element of the iterator matches a predicate.
Returns true
if predicate
evaluates to true
for all elements.
Returns true
if the input arrays are empty.
Example:
use ndarray::{array, Zip};
let a = array![1, 2, 3];
let b = array![1, 4, 9];
assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b));
sourcepub fn split(self) -> (Self, Self)
pub fn split(self) -> (Self, Self)
Split the Zip
evenly in two.
It will be split in the way that best preserves element locality.
sourceimpl<D, P1> Zip<(P1,), D> where
P1::Item: Send,
P1: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
impl<D, P1> Zip<(P1,), D> where
P1::Item: Send,
P1: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
sourcepub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item) + Sync + Send,
pub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item) + Sync + Send,
The par_for_each
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item) + Sync + Send,
👎 Deprecated since 0.15.0: Renamed to .par_for_each()
pub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item) + Sync + Send,
Renamed to .par_for_each()
The par_apply
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
pub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_collect()
pub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Renamed to .par_map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
pub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_assign_into()
pub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Renamed to .par_map_assign_into()
Apply and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
pub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
Parallel version of fold
.
Splits the producer in multiple tasks which each accumulate a single value
using the fold
closure. Those tasks are executed in parallel and their results
are then combined to a single value using the reduce
closure.
The identity
closure provides the initial values for each of the tasks and
for the final reduction.
This is a shorthand for calling self.into_par_iter().fold(...).reduce(...)
.
Note that it is often more efficient to parallelize not per-element but rather based on larger chunks of an array like generalized rows and operating on each chunk using a sequential variant of the accumulation. For example, sum each row sequentially and in parallel, taking advantage of locality and vectorization within each task, and then reduce their sums to the sum of the matrix.
Also note that the splitting of the producer into multiple tasks is not deterministic which needs to be considered when the accuracy of such an operation is analyzed.
Examples
use ndarray::{Array, Zip};
let a = Array::<usize, _>::ones((128, 1024));
let b = Array::<usize, _>::ones(128);
let weighted_sum = Zip::from(a.rows()).and(&b).par_fold(
|| 0,
|sum, row, factor| sum + row.sum() * factor,
|sum, other_sum| sum + other_sum,
);
assert_eq!(weighted_sum, a.len());
sourceimpl<D, P1, P2> Zip<(P1, P2), D> where
P1::Item: Send,
P2::Item: Send,
P1: Send,
P2: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
impl<D, P1, P2> Zip<(P1, P2), D> where
P1::Item: Send,
P2::Item: Send,
P1: Send,
P2: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
sourcepub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item) + Sync + Send,
pub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item) + Sync + Send,
The par_for_each
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item) + Sync + Send,
👎 Deprecated since 0.15.0: Renamed to .par_for_each()
pub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item) + Sync + Send,
Renamed to .par_for_each()
The par_apply
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
pub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_collect()
pub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Renamed to .par_map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
pub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_assign_into()
pub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Renamed to .par_map_assign_into()
Apply and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
pub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
Parallel version of fold
.
Splits the producer in multiple tasks which each accumulate a single value
using the fold
closure. Those tasks are executed in parallel and their results
are then combined to a single value using the reduce
closure.
The identity
closure provides the initial values for each of the tasks and
for the final reduction.
This is a shorthand for calling self.into_par_iter().fold(...).reduce(...)
.
Note that it is often more efficient to parallelize not per-element but rather based on larger chunks of an array like generalized rows and operating on each chunk using a sequential variant of the accumulation. For example, sum each row sequentially and in parallel, taking advantage of locality and vectorization within each task, and then reduce their sums to the sum of the matrix.
Also note that the splitting of the producer into multiple tasks is not deterministic which needs to be considered when the accuracy of such an operation is analyzed.
Examples
use ndarray::{Array, Zip};
let a = Array::<usize, _>::ones((128, 1024));
let b = Array::<usize, _>::ones(128);
let weighted_sum = Zip::from(a.rows()).and(&b).par_fold(
|| 0,
|sum, row, factor| sum + row.sum() * factor,
|sum, other_sum| sum + other_sum,
);
assert_eq!(weighted_sum, a.len());
sourceimpl<D, P1, P2, P3> Zip<(P1, P2, P3), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P1: Send,
P2: Send,
P3: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
impl<D, P1, P2, P3> Zip<(P1, P2, P3), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P1: Send,
P2: Send,
P3: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
sourcepub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item) + Sync + Send,
pub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item) + Sync + Send,
The par_for_each
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item) + Sync + Send,
👎 Deprecated since 0.15.0: Renamed to .par_for_each()
pub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item) + Sync + Send,
Renamed to .par_for_each()
The par_apply
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
pub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_collect()
pub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Renamed to .par_map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
pub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_assign_into()
pub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Renamed to .par_map_assign_into()
Apply and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item, P3::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
pub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item, P3::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
Parallel version of fold
.
Splits the producer in multiple tasks which each accumulate a single value
using the fold
closure. Those tasks are executed in parallel and their results
are then combined to a single value using the reduce
closure.
The identity
closure provides the initial values for each of the tasks and
for the final reduction.
This is a shorthand for calling self.into_par_iter().fold(...).reduce(...)
.
Note that it is often more efficient to parallelize not per-element but rather based on larger chunks of an array like generalized rows and operating on each chunk using a sequential variant of the accumulation. For example, sum each row sequentially and in parallel, taking advantage of locality and vectorization within each task, and then reduce their sums to the sum of the matrix.
Also note that the splitting of the producer into multiple tasks is not deterministic which needs to be considered when the accuracy of such an operation is analyzed.
Examples
use ndarray::{Array, Zip};
let a = Array::<usize, _>::ones((128, 1024));
let b = Array::<usize, _>::ones(128);
let weighted_sum = Zip::from(a.rows()).and(&b).par_fold(
|| 0,
|sum, row, factor| sum + row.sum() * factor,
|sum, other_sum| sum + other_sum,
);
assert_eq!(weighted_sum, a.len());
sourceimpl<D, P1, P2, P3, P4> Zip<(P1, P2, P3, P4), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4> Zip<(P1, P2, P3, P4), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
sourcepub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item) + Sync + Send,
pub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item) + Sync + Send,
The par_for_each
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item) + Sync + Send,
👎 Deprecated since 0.15.0: Renamed to .par_for_each()
pub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item) + Sync + Send,
Renamed to .par_for_each()
The par_apply
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
pub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_collect()
pub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Renamed to .par_map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
pub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_assign_into()
pub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Renamed to .par_map_assign_into()
Apply and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item, P3::Item, P4::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
pub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item, P3::Item, P4::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
Parallel version of fold
.
Splits the producer in multiple tasks which each accumulate a single value
using the fold
closure. Those tasks are executed in parallel and their results
are then combined to a single value using the reduce
closure.
The identity
closure provides the initial values for each of the tasks and
for the final reduction.
This is a shorthand for calling self.into_par_iter().fold(...).reduce(...)
.
Note that it is often more efficient to parallelize not per-element but rather based on larger chunks of an array like generalized rows and operating on each chunk using a sequential variant of the accumulation. For example, sum each row sequentially and in parallel, taking advantage of locality and vectorization within each task, and then reduce their sums to the sum of the matrix.
Also note that the splitting of the producer into multiple tasks is not deterministic which needs to be considered when the accuracy of such an operation is analyzed.
Examples
use ndarray::{Array, Zip};
let a = Array::<usize, _>::ones((128, 1024));
let b = Array::<usize, _>::ones(128);
let weighted_sum = Zip::from(a.rows()).and(&b).par_fold(
|| 0,
|sum, row, factor| sum + row.sum() * factor,
|sum, other_sum| sum + other_sum,
);
assert_eq!(weighted_sum, a.len());
sourceimpl<D, P1, P2, P3, P4, P5> Zip<(P1, P2, P3, P4, P5), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4, P5> Zip<(P1, P2, P3, P4, P5), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
sourcepub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) + Sync + Send,
pub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) + Sync + Send,
The par_for_each
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) + Sync + Send,
👎 Deprecated since 0.15.0: Renamed to .par_for_each()
pub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) + Sync + Send,
Renamed to .par_for_each()
The par_apply
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
pub fn par_map_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_collect()
pub fn par_apply_collect<R>(
self,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) -> Array<R, D> where
R: Send,
Renamed to .par_map_collect()
Map and collect the results into a new array, which has the same size as the inputs.
If all inputs are c- or f-order respectively, that is preserved in the output.
sourcepub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
pub fn par_map_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Map and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
👎 Deprecated since 0.15.0: Renamed to .par_map_assign_into()
pub fn par_apply_assign_into<R, Q>(
self,
into: Q,
f: impl Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R + Sync + Send
) where
Q: IntoNdProducer<Dim = D>,
Q::Item: AssignElem<R> + Send,
Q::Output: Send,
Renamed to .par_map_assign_into()
Apply and assign the results into the producer into
, which should have the same
size as the other inputs.
The producer should have assignable items as dictated by the AssignElem
trait,
for example &mut R
.
sourcepub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
pub fn par_fold<ID, F, R, T>(self, identity: ID, fold: F, reduce: R) -> T where
ID: Fn() -> T + Send + Sync + Clone,
F: Fn(T, P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> T + Send + Sync,
R: Fn(T, T) -> T + Send + Sync,
T: Send,
Parallel version of fold
.
Splits the producer in multiple tasks which each accumulate a single value
using the fold
closure. Those tasks are executed in parallel and their results
are then combined to a single value using the reduce
closure.
The identity
closure provides the initial values for each of the tasks and
for the final reduction.
This is a shorthand for calling self.into_par_iter().fold(...).reduce(...)
.
Note that it is often more efficient to parallelize not per-element but rather based on larger chunks of an array like generalized rows and operating on each chunk using a sequential variant of the accumulation. For example, sum each row sequentially and in parallel, taking advantage of locality and vectorization within each task, and then reduce their sums to the sum of the matrix.
Also note that the splitting of the producer into multiple tasks is not deterministic which needs to be considered when the accuracy of such an operation is analyzed.
Examples
use ndarray::{Array, Zip};
let a = Array::<usize, _>::ones((128, 1024));
let b = Array::<usize, _>::ones(128);
let weighted_sum = Zip::from(a.rows()).and(&b).par_fold(
|| 0,
|sum, row, factor| sum + row.sum() * factor,
|sum, other_sum| sum + other_sum,
);
assert_eq!(weighted_sum, a.len());
sourceimpl<D, P1, P2, P3, P4, P5, P6> Zip<(P1, P2, P3, P4, P5, P6), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P6::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
P6: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
P6: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4, P5, P6> Zip<(P1, P2, P3, P4, P5, P6), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P6::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
P6: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
P6: NdProducer<Dim = D>,
sourcepub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) + Sync + Send,
pub fn par_for_each<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) + Sync + Send,
The par_for_each
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
sourcepub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) + Sync + Send,
👎 Deprecated since 0.15.0: Renamed to .par_for_each()
pub fn par_apply<F>(self, function: F) where
F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) + Sync + Send,
Renamed to .par_for_each()
The par_apply
method for Zip
.
This is a shorthand for using .into_par_iter().for_each()
on
Zip
.
Requires crate feature rayon
.
Trait Implementations
sourceimpl<D, P1, P2, P3, P4, P5, P6> IntoParallelIterator for Zip<(P1, P2, P3, P4, P5, P6), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P6::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
P6: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
P6: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4, P5, P6> IntoParallelIterator for Zip<(P1, P2, P3, P4, P5, P6), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P6::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
P6: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
P6: NdProducer<Dim = D>,
Requires crate feature rayon
.
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item, <P4 as NdProducer>::Item, <P5 as NdProducer>::Item, <P6 as NdProducer>::Item)
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item, <P4 as NdProducer>::Item, <P5 as NdProducer>::Item, <P6 as NdProducer>::Item)
The type of item that the parallel iterator will produce.
type Iter = Parallel<Zip<(P1, P2, P3, P4, P5, P6), D>>
type Iter = Parallel<Zip<(P1, P2, P3, P4, P5, P6), D>>
The parallel iterator type that will be created.
sourcefn into_par_iter(self) -> Self::Iter
fn into_par_iter(self) -> Self::Iter
Converts self
into a parallel iterator. Read more
sourceimpl<D, P1, P2, P3, P4, P5> IntoParallelIterator for Zip<(P1, P2, P3, P4, P5), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4, P5> IntoParallelIterator for Zip<(P1, P2, P3, P4, P5), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P5::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
P5: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
P5: NdProducer<Dim = D>,
Requires crate feature rayon
.
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item, <P4 as NdProducer>::Item, <P5 as NdProducer>::Item)
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item, <P4 as NdProducer>::Item, <P5 as NdProducer>::Item)
The type of item that the parallel iterator will produce.
type Iter = Parallel<Zip<(P1, P2, P3, P4, P5), D>>
type Iter = Parallel<Zip<(P1, P2, P3, P4, P5), D>>
The parallel iterator type that will be created.
sourcefn into_par_iter(self) -> Self::Iter
fn into_par_iter(self) -> Self::Iter
Converts self
into a parallel iterator. Read more
sourceimpl<D, P1, P2, P3, P4> IntoParallelIterator for Zip<(P1, P2, P3, P4), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
impl<D, P1, P2, P3, P4> IntoParallelIterator for Zip<(P1, P2, P3, P4), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P4::Item: Send,
P1: Send,
P2: Send,
P3: Send,
P4: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
P4: NdProducer<Dim = D>,
Requires crate feature rayon
.
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item, <P4 as NdProducer>::Item)
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item, <P4 as NdProducer>::Item)
The type of item that the parallel iterator will produce.
type Iter = Parallel<Zip<(P1, P2, P3, P4), D>>
type Iter = Parallel<Zip<(P1, P2, P3, P4), D>>
The parallel iterator type that will be created.
sourcefn into_par_iter(self) -> Self::Iter
fn into_par_iter(self) -> Self::Iter
Converts self
into a parallel iterator. Read more
sourceimpl<D, P1, P2, P3> IntoParallelIterator for Zip<(P1, P2, P3), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P1: Send,
P2: Send,
P3: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
impl<D, P1, P2, P3> IntoParallelIterator for Zip<(P1, P2, P3), D> where
P1::Item: Send,
P2::Item: Send,
P3::Item: Send,
P1: Send,
P2: Send,
P3: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
P3: NdProducer<Dim = D>,
Requires crate feature rayon
.
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item)
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item, <P3 as NdProducer>::Item)
The type of item that the parallel iterator will produce.
type Iter = Parallel<Zip<(P1, P2, P3), D>>
type Iter = Parallel<Zip<(P1, P2, P3), D>>
The parallel iterator type that will be created.
sourcefn into_par_iter(self) -> Self::Iter
fn into_par_iter(self) -> Self::Iter
Converts self
into a parallel iterator. Read more
sourceimpl<D, P1, P2> IntoParallelIterator for Zip<(P1, P2), D> where
P1::Item: Send,
P2::Item: Send,
P1: Send,
P2: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
impl<D, P1, P2> IntoParallelIterator for Zip<(P1, P2), D> where
P1::Item: Send,
P2::Item: Send,
P1: Send,
P2: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
P2: NdProducer<Dim = D>,
Requires crate feature rayon
.
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item)
type Item = (<P1 as NdProducer>::Item, <P2 as NdProducer>::Item)
The type of item that the parallel iterator will produce.
sourcefn into_par_iter(self) -> Self::Iter
fn into_par_iter(self) -> Self::Iter
Converts self
into a parallel iterator. Read more
sourceimpl<D, P1> IntoParallelIterator for Zip<(P1,), D> where
P1::Item: Send,
P1: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
impl<D, P1> IntoParallelIterator for Zip<(P1,), D> where
P1::Item: Send,
P1: Send,
D: Dimension,
P1: NdProducer<Dim = D>,
Requires crate feature rayon
.
Auto Trait Implementations
impl<Parts, D> RefUnwindSafe for Zip<Parts, D> where
D: RefUnwindSafe,
Parts: RefUnwindSafe,
impl<Parts, D> Send for Zip<Parts, D> where
D: Send,
Parts: Send,
impl<Parts, D> Sync for Zip<Parts, D> where
D: Sync,
Parts: Sync,
impl<Parts, D> Unpin for Zip<Parts, D> where
D: Unpin,
Parts: Unpin,
impl<Parts, D> UnwindSafe for Zip<Parts, D> where
D: UnwindSafe,
Parts: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more