[][src]Struct ndarray::Zip

pub struct Zip<Parts, D> { /* fields omitted */ }

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: apply 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!() macro 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)
    .apply(|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.genrows())
    .apply(|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 apply_collect to make a new array

let mut totals2 = Zip::from(a.genrows()).apply_collect(|row| row.sum());

// Check the result against the previous example.
assert_eq!(totals, totals2);

Methods

impl<P, D> Zip<(P,), D> where
    D: Dimension,
    P: NdProducer<Dim = D>, 
[src]

pub fn from<IP>(p: IP) -> Self where
    IP: IntoNdProducer<Dim = D, Output = P, Item = P::Item>, 
[src]

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).

impl<P, D> Zip<(Indices<D>, P), D> where
    D: Dimension + Copy,
    P: NdProducer<Dim = D>, 
[src]

pub fn indexed<IP>(p: IP) -> Self where
    IP: IntoNdProducer<Dim = D, Output = P, Item = P::Item>, 
[src]

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.

impl<Parts, D> Zip<Parts, D> where
    D: Dimension
[src]

pub fn size(&self) -> usize[src]

Return a the number of element tuples in the Zip

impl<D, P1> Zip<(P1,), D> where
    D: Dimension,
    P1: NdProducer<Dim = D>, 
[src]

pub fn apply<F>(self, function: F) where
    F: FnMut(P1::Item), 
[src]

Apply a function to all elements of the input arrays, visiting elements in lock step.

pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
    F: FnMut(Acc, P1::Item) -> Acc, 
[src]

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);

pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
    F: FnMut(Acc, P1::Item) -> FoldWhile<Acc>, 
[src]

Apply a fold function to the input arrays while the return value is FoldWhile::Continue, visiting elements in lock step.

pub fn all<F>(self, predicate: F) -> bool where
    F: FnMut(P1::Item) -> bool
[src]

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));

pub fn and<P>(self, p: P) -> Zip<(P1, P::Output), D> where
    P: IntoNdProducer<Dim = D>, 
[src]

Include the producer p in the Zip.

Panics if p’s shape doesn’t match the Zip’s exactly.

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
[src]

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.

pub fn apply_collect<R>(self, f: impl FnMut(P1::Item) -> R) -> Array<R, D> where
    R: Copy
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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>, 
[src]

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.

pub fn split(self) -> (Self, Self)[src]

Split the Zip evenly in two.

It will be split in the way that best preserves element locality.

impl<D, P1, P2> Zip<(P1, P2), D> where
    D: Dimension,
    P1: NdProducer<Dim = D>,
    P2: NdProducer<Dim = D>, 
[src]

pub fn apply<F>(self, function: F) where
    F: FnMut(P1::Item, P2::Item), 
[src]

Apply a function to all elements of the input arrays, visiting elements in lock step.

pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
    F: FnMut(Acc, P1::Item, P2::Item) -> Acc, 
[src]

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);

pub fn fold_while<F, Acc>(self, acc: Acc, function: F) -> FoldWhile<Acc> where
    F: FnMut(Acc, P1::Item, P2::Item) -> FoldWhile<Acc>, 
[src]

Apply a fold function to the input arrays while the return value is FoldWhile::Continue, visiting elements in lock step.

pub fn all<F>(self, predicate: F) -> bool where
    F: FnMut(P1::Item, P2::Item) -> bool
[src]

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));

pub fn and<P>(self, p: P) -> Zip<(P1, P2, P::Output), D> where
    P: IntoNdProducer<Dim = D>, 
[src]

Include the producer p in the Zip.

Panics if p’s shape doesn’t match the Zip’s exactly.

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
[src]

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.

pub fn apply_collect<R>(
    self,
    f: impl FnMut(P1::Item, P2::Item) -> R
) -> Array<R, D> where
    R: Copy
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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>, 
[src]

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.

pub fn split(self) -> (Self, Self)[src]

Split the Zip evenly in two.

It will be split in the way that best preserves element locality.

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>, 
[src]

pub fn apply<F>(self, function: F) where
    F: FnMut(P1::Item, P2::Item, P3::Item), 
[src]

Apply a function to all elements of the input arrays, visiting elements in lock step.

pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
    F: FnMut(Acc, P1::Item, P2::Item, P3::Item) -> Acc, 
[src]

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);

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>, 
[src]

Apply a fold function to the input arrays while the return value is FoldWhile::Continue, visiting elements in lock step.

pub fn all<F>(self, predicate: F) -> bool where
    F: FnMut(P1::Item, P2::Item, P3::Item) -> bool
[src]

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));

pub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P::Output), D> where
    P: IntoNdProducer<Dim = D>, 
[src]

Include the producer p in the Zip.

Panics if p’s shape doesn’t match the Zip’s exactly.

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
[src]

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.

pub fn apply_collect<R>(
    self,
    f: impl FnMut(P1::Item, P2::Item, P3::Item) -> R
) -> Array<R, D> where
    R: Copy
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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>, 
[src]

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.

pub fn split(self) -> (Self, Self)[src]

Split the Zip evenly in two.

It will be split in the way that best preserves element locality.

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>, 
[src]

pub fn apply<F>(self, function: F) where
    F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item), 
[src]

Apply a function to all elements of the input arrays, visiting elements in lock step.

pub fn fold<F, Acc>(self, acc: Acc, function: F) -> Acc where
    F: FnMut(Acc, P1::Item, P2::Item, P3::Item, P4::Item) -> Acc, 
[src]

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);

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>, 
[src]

Apply a fold function to the input arrays while the return value is FoldWhile::Continue, visiting elements in lock step.

pub fn all<F>(self, predicate: F) -> bool where
    F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> bool
[src]

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));

pub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P4, P::Output), D> where
    P: IntoNdProducer<Dim = D>, 
[src]

Include the producer p in the Zip.

Panics if p’s shape doesn’t match the Zip’s exactly.

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
[src]

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.

pub fn apply_collect<R>(
    self,
    f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item) -> R
) -> Array<R, D> where
    R: Copy
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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>, 
[src]

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.

pub fn split(self) -> (Self, Self)[src]

Split the Zip evenly in two.

It will be split in the way that best preserves element locality.

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>, 
[src]

pub fn apply<F>(self, function: F) where
    F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item), 
[src]

Apply a function to all elements of the input arrays, visiting elements in lock step.

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, 
[src]

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);

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>, 
[src]

Apply a fold function to the input arrays while the return value is FoldWhile::Continue, visiting elements in lock step.

pub fn all<F>(self, predicate: F) -> bool where
    F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> bool
[src]

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));

pub fn and<P>(self, p: P) -> Zip<(P1, P2, P3, P4, P5, P::Output), D> where
    P: IntoNdProducer<Dim = D>, 
[src]

Include the producer p in the Zip.

Panics if p’s shape doesn’t match the Zip’s exactly.

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
[src]

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.

pub fn apply_collect<R>(
    self,
    f: impl FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) -> R
) -> Array<R, D> where
    R: Copy
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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>, 
[src]

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.

pub fn split(self) -> (Self, Self)[src]

Split the Zip evenly in two.

It will be split in the way that best preserves element locality.

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>, 
[src]

pub fn apply<F>(self, function: F) where
    F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item), 
[src]

Apply a function to all elements of the input arrays, visiting elements in lock step.

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, 
[src]

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);

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>, 
[src]

Apply a fold function to the input arrays while the return value is FoldWhile::Continue, visiting elements in lock step.

pub fn all<F>(self, predicate: F) -> bool where
    F: FnMut(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item) -> bool
[src]

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));

pub fn split(self) -> (Self, Self)[src]

Split the Zip evenly in two.

It will be split in the way that best preserves element locality.

impl<D, P1> Zip<(P1,), D> where
    P1::Item: Send,
    P1: Send,
    D: Dimension,
    P1: NdProducer<Dim = D>, 
[src]

pub fn par_apply<F>(self, function: F) where
    F: Fn(P1::Item) + Sync + Send
[src]

The par_apply method for Zip.

This is a shorthand for using .into_par_iter().for_each() on Zip.

Requires crate feature rayon.

pub fn par_apply_collect<R>(
    self,
    f: impl Fn(P1::Item) -> R + Sync + Send
) -> Array<R, D> where
    R: Copy + Send
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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
[src]

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.

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>, 
[src]

pub fn par_apply<F>(self, function: F) where
    F: Fn(P1::Item, P2::Item) + Sync + Send
[src]

The par_apply method for Zip.

This is a shorthand for using .into_par_iter().for_each() on Zip.

Requires crate feature rayon.

pub fn par_apply_collect<R>(
    self,
    f: impl Fn(P1::Item, P2::Item) -> R + Sync + Send
) -> Array<R, D> where
    R: Copy + Send
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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
[src]

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.

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>, 
[src]

pub fn par_apply<F>(self, function: F) where
    F: Fn(P1::Item, P2::Item, P3::Item) + Sync + Send
[src]

The par_apply method for Zip.

This is a shorthand for using .into_par_iter().for_each() on Zip.

Requires crate feature rayon.

pub fn par_apply_collect<R>(
    self,
    f: impl Fn(P1::Item, P2::Item, P3::Item) -> R + Sync + Send
) -> Array<R, D> where
    R: Copy + Send
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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
[src]

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.

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>, 
[src]

pub fn par_apply<F>(self, function: F) where
    F: Fn(P1::Item, P2::Item, P3::Item, P4::Item) + Sync + Send
[src]

The par_apply method for Zip.

This is a shorthand for using .into_par_iter().for_each() on Zip.

Requires crate feature rayon.

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: Copy + Send
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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
[src]

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.

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>, 
[src]

pub fn par_apply<F>(self, function: F) where
    F: Fn(P1::Item, P2::Item, P3::Item, P4::Item, P5::Item) + Sync + Send
[src]

The par_apply method for Zip.

This is a shorthand for using .into_par_iter().for_each() on Zip.

Requires crate feature rayon.

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: Copy + Send
[src]

Apply 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.

Restricted to functions that produce copyable results for technical reasons; other cases are not yet implemented.

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
[src]

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.

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>, 
[src]

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
[src]

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

impl<Parts: Clone, D: Clone> Clone for Zip<Parts, D>[src]

impl<Parts: Debug, D: Debug> Debug for Zip<Parts, D>[src]

impl<D, P1> IntoParallelIterator for Zip<(P1,), D> where
    P1::Item: Send,
    P1: Send,
    D: Dimension,
    P1: NdProducer<Dim = D>, 
[src]

Requires crate feature rayon.

type Item = (P1::Item,)

The type of item that the parallel iterator will produce.

type Iter = Parallel<Self>

The parallel iterator type that will be created.

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>, 
[src]

Requires crate feature rayon.

type Item = (P1::Item, P2::Item)

The type of item that the parallel iterator will produce.

type Iter = Parallel<Self>

The parallel iterator type that will be created.

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>, 
[src]

Requires crate feature rayon.

type Item = (P1::Item, P2::Item, P3::Item)

The type of item that the parallel iterator will produce.

type Iter = Parallel<Self>

The parallel iterator type that will be created.

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>, 
[src]

Requires crate feature rayon.

type Item = (P1::Item, P2::Item, P3::Item, P4::Item)

The type of item that the parallel iterator will produce.

type Iter = Parallel<Self>

The parallel iterator type that will be created.

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>, 
[src]

Requires crate feature rayon.

type Item = (P1::Item, P2::Item, P3::Item, P4::Item, P5::Item)

The type of item that the parallel iterator will produce.

type Iter = Parallel<Self>

The parallel iterator type that will be created.

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>, 
[src]

Requires crate feature rayon.

type Item = (P1::Item, P2::Item, P3::Item, P4::Item, P5::Item, P6::Item)

The type of item that the parallel iterator will produce.

type Iter = Parallel<Self>

The parallel iterator type that will be created.

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

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> IntoParallelIterator for T where
    T: ParallelIterator
[src]

type Iter = T

The parallel iterator type that will be created.

type Item = <T as ParallelIterator>::Item

The type of item that the parallel iterator will produce.

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.