[][src]Macro ndarray::azip

macro_rules! azip {
    (@build $apply:ident (index $index:pat, $first_pat:pat in $first_prod:expr $(,)?) $body:expr) => { ... };
    (@build $apply:ident (index $index:pat, $first_pat:pat in $first_prod:expr, $($pat:pat in $prod:expr),* $(,)?) $body:expr) => { ... };
    (@build $apply:ident ($first_pat:pat in $first_prod:expr $(,)?) $body:expr) => { ... };
    (@build $apply:ident ($first_pat:pat in $first_prod:expr, $($pat:pat in $prod:expr),* $(,)?) $body:expr) => { ... };
    (@build $($t:tt)*) => { ... };
    ($($t:tt)*) => { ... };

Array zip macro: lock step function application across several arrays and producers.

This is a shorthand for Zip.

This example:

This example is not tested
azip!((a in &mut a, &b in &b, &c in &c) *a = b + c);

Is equivalent to:

This example is not tested
Zip::from(&mut a).and(&b).and(&c).apply(|a, &b, &c| {
    *a = b + c

The syntax is either

azip!(( pat in expr , [ pat in expr , ... ] ) body_expr )

or, to use Zip::indexed instead of Zip::from,

azip!((index pat , pat in expr , [ pat in expr , ... ] ) body_expr )

The expr are expressions whose types must implement IntoNdProducer, the pat are the patterns of the parameters to the closure called by Zip::apply, and body_expr is the body of the closure called by Zip::apply. You can think of each pat in expr as being analogous to the pat in expr of a normal loop for pat in expr { statements }: a pattern, followed by in, followed by an expression that implements IntoNdProducer (analogous to IntoIterator for a for loop).

Panics if any of the arrays are not of the same shape.


extern crate ndarray;

use ndarray::{azip, Array1, Array2, Axis};

type M = Array2<f32>;

fn main() {
    // Setup example arrays
    let mut a = M::zeros((16, 16));
    let mut b = M::zeros(a.dim());
    let mut c = M::zeros(a.dim());

    // assign values
    for ((i, j), elt) in c.indexed_iter_mut() {
        *elt = (i + 10 * j) as f32;

    // Example 1: Compute a simple ternary operation:
    // elementwise addition of b and c, stored in a
    azip!((a in &mut a, &b in &b, &c in &c) *a = b + c);

    assert_eq!(a, &b + &c);

    // Example 2: azip!() with index
    azip!((index (i, j), &b in &b, &c in &c) {
        a[[i, j]] = b - c;

    assert_eq!(a, &b - &c);

    // Example 3: azip!() on references
    // See the definition of the function below
    borrow_multiply(&mut a, &b, &c);

    assert_eq!(a, &b * &c);

    // Since this function borrows its inputs, the `IntoNdProducer`
    // expressions don't need to explicitly include `&mut` or `&`.
    fn borrow_multiply(a: &mut M, b: &M, c: &M) {
        azip!((a in a, &b in b, &c in c) *a = b * c);

    // Example 4: using azip!() without dereference in pattern.
    // Create a new array `totals` with one entry per row of `a`.
    // Use azip to traverse the rows of `a` and assign to the corresponding
    // entry in `totals` with the sum across each row.
    // The row is an array view; it doesn't need to be dereferenced.
    let mut totals = Array1::zeros(a.rows());
    azip!((totals in &mut totals, row in a.genrows()) *totals = row.sum());

    // Check the result against the built in `.sum_axis()` along axis 1.
    assert_eq!(totals, a.sum_axis(Axis(1)));