Macro ndarray::s

source ·
macro_rules! s {
    (@parse $dim:expr, [$($stack:tt)*] $r:expr;$s:expr) => { ... };
    (@parse $dim:expr, [$($stack:tt)*] $r:expr) => { ... };
    (@parse $dim:expr, [$($stack:tt)*] $r:expr;$s:expr ,) => { ... };
    (@parse $dim:expr, [$($stack:tt)*] $r:expr ,) => { ... };
    (@parse $dim:expr, [$($stack:tt)*] $r:expr;$s:expr, $($t:tt)*) => { ... };
    (@parse $dim:expr, [$($stack:tt)*] $r:expr, $($t:tt)*) => { ... };
    (@convert $r:expr) => { ... };
    (@convert $r:expr, $s:expr) => { ... };
    ($($t:tt)*) => { ... };
}
Expand description

Slice argument constructor.

s![] takes a list of ranges/slices/indices, separated by comma, with optional step sizes that are separated from the range by a semicolon. It is converted into a &SliceInfo instance.

Each range/slice/index uses signed indices, where a negative value is counted from the end of the axis. Step sizes are also signed and may be negative, but must not be zero.

The syntax is s![ [ axis-slice-or-index [, axis-slice-or-index [ , … ] ] ] ], where axis-slice-or-index is any of the following:

  • index: an index to use for taking a subview with respect to that axis. (The index is selected. The axis is removed except with .slice_collapse().)
  • range: a range with step size 1 to use for slicing that axis.
  • range ; step: a range with step size step to use for slicing that axis.
  • slice: a Slice instance to use for slicing that axis.
  • slice ; step: a range constructed from the start and end of a Slice instance, with new step size step, to use for slicing that axis.

The number of axis-slice-or-index must match the number of axes in the array. index, range, slice, and step can be expressions. index must be of type isize, usize, or i32. range must be of type Range<I>, RangeTo<I>, RangeFrom<I>, or RangeFull where I is isize, usize, or i32. step must be a type that can be converted to isize with the as keyword.

For example s![0..4;2, 6, 1..5] is a slice of the first axis for 0..4 with step size 2, a subview of the second axis at index 6, and a slice of the third axis for 1..5 with default step size 1. The input array must have 3 dimensions. The resulting slice would have shape [2, 4] for .slice(), .slice_mut(), and .slice_move(), and shape [2, 1, 4] for .slice_collapse().

See also Slicing.

Example

#[macro_use]
extern crate ndarray;

use ndarray::{Array2, ArrayView2};

fn laplacian(v: &ArrayView2<f32>) -> Array2<f32> {
    -4. * &v.slice(s![1..-1, 1..-1])
    + v.slice(s![ ..-2, 1..-1])
    + v.slice(s![1..-1,  ..-2])
    + v.slice(s![1..-1, 2..  ])
    + v.slice(s![2..  , 1..-1])
}

Negative step

The behavior of negative step arguments is most easily understood with slicing as a two-step process:

  1. First, perform a slice with range.

  2. If step is positive, start with the front of the slice; if step is negative, start with the back of the slice. Then, add step until reaching the other end of the slice (inclusive).

An equivalent way to think about step 2 is, “If step is negative, reverse the slice. Start at the front of the (possibly reversed) slice, and add step.abs() until reaching the back of the slice (inclusive).”

For example,

let arr = array![0, 1, 2, 3];
assert_eq!(arr.slice(s![1..3;-1]), array![2, 1]);
assert_eq!(arr.slice(s![1..;-2]), array![3, 1]);
assert_eq!(arr.slice(s![0..4;-2]), array![3, 1]);
assert_eq!(arr.slice(s![0..;-2]), array![3, 1]);
assert_eq!(arr.slice(s![..;-2]), array![3, 1]);