macro_rules! azip {
(@parse [index => $a:expr, $($aa:expr,)*] $t1:tt in $t2:tt) => { ... };
(@parse [$a:expr, $($aa:expr,)*] $t1:tt in $t2:tt) => { ... };
(@finish ($z:expr) [$($aa:expr,)*] [$($p:pat,)+] in { $($t:tt)*}) => { ... };
(@parse [] [] index $i:pat, $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] mut $x:ident ($e:expr) $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] mut $x:ident $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] , $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] ref $x:ident ($e:expr) $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] ref $x:ident $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] $x:ident ($e:expr) $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] $x:ident $($t:tt)*) => { ... };
(@parse [$($exprs:tt)*] [$($pats:tt)*] $($t:tt)*) => { ... };
($($t:tt)*) => { ... };
}
Expand description
Array zip macro: lock step function application across several arrays and producers.
This is a shorthand for Zip
.
This example:
ⓘ
azip!(mut a, b, c in { *a = b + c })
Is equivalent to:
ⓘ
Zip::from(&mut a).and(&b).and(&c).apply(|a, &b, &c| {
*a = b + c;
});
Explanation of the shorthand for captures:
mut a
: the producer is&mut a
and the variable pattern ismut a
.b
: the producer is&b
and the variable pattern is&b
(same forc
).
The syntax is azip!(
[ index
pattern ,
] capture [,
capture [,
…] ] in {
expression })
where the captures are a sequence of pattern-like items that indicate which
arrays are used for the zip. The expression is evaluated elementwise,
with the value of an element from each producer in their respective variable.
More capture rules:
ref c
: the producer is&c
and the variable pattern isc
.mut a (expr)
: the producer isexpr
and the variable pattern ismut a
.b (expr)
: the producer isexpr
and the variable pattern is&b
.ref c (expr)
: the producer isexpr
and the variable pattern isc
.
Special rule:
index i
: UseZip::indexed
instead.i
is a pattern – it can be a single variable name or something else that pattern matches the index. This rule must be the first if it is used, and it must be followed by at least one other rule.
Panics if any of the arrays are not of the same shape.
Examples
#[macro_use(azip)]
extern crate ndarray;
use ndarray::{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
b.fill(1.);
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!(mut a, b, c in { *a = b + c });
assert_eq!(a, &b + &c);
// Example 2: azip!() with index
azip!(index (i, j), b, c in {
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, captures must use the x (x) pattern
// to avoid the macro's default rule that autorefs the producer.
fn borrow_multiply(a: &mut M, b: &M, c: &M) {
azip!(mut a (a), b (b), c (c) in { *a = b * c });
}
// Example 4: using azip!() with a `ref` rule
//
// 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; use the 'ref' rule on the row, to avoid the
// default which is to dereference the produced item.
let mut totals = Array1::zeros(a.rows());
azip!(mut totals, ref row (a.genrows()) in {
*totals = row.sum();
});
// Check the result against the built in `.sum_axis()` along axis 1.
assert_eq!(totals, a.sum_axis(Axis(1)));
}