macro_rules! s { (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr;$s:expr) => { ... }; (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr) => { ... }; (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr;$s:expr ,) => { ... }; (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr ,) => { ... }; (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr;$s:expr, $($t:tt)*) => { ... }; (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr, $($t:tt)*) => { ... }; (@parse ::core::marker::PhantomData::<$crate::Ix0>, ::core::marker::PhantomData::<$crate::Ix0>, []) => { ... }; (@parse $($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/new-axes, 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![
[ elem [, elem [ , … ] ] ] ]
, where elem 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 aSlice
instance, multiplying the step size by step, to use for slicing that axis. - new-axis: a
NewAxis
instance that represents the creation of a new axis. (Except for.slice_collapse()
, which panics onNewAxis
elements.)
The number of elem, not including new-axis, must match the
number of axes in the array. index, range, slice, step, and
new-axis 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, NewAxis]
is a slice of the first axis
for 0..4 with step size 2, a subview of the second axis at index 6, a slice
of the third axis for 1..5 with default step size 1, and a new axis of
length 1 at the end of the shape. The input array must have 3 dimensions.
The resulting slice would have shape [2, 4, 1]
for .slice()
,
.slice_mut()
, and .slice_move()
, while .slice_collapse()
would
panic. Without the NewAxis
, i.e. s![0..4;2, 6, 1..5]
,
.slice_collapse()
would result in an array of shape [2, 1, 4]
.
See also Slicing.
Example
use ndarray::{s, 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:
-
First, perform a slice with range.
-
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]);