ndarray is a Rust library providing an n-dimensional array. It has been in furious development, and now we are ready to release the next version which has many improvements.

One of the most fundamental additions, contributed by @vbarrielle, is better support for chunking and splitting array views. ArrayView and ArrayViewMut learned the new method .split_at(Axis, Ix) that splits the view, modelled on .split_at(_mut) for slices.

Creating a 3 × 5 × 5 array with ndarray looks like this:

use ndarray::OwnedArray;

let mut a = OwnedArray::range(0., 3. * 5. * 5., 1.).into_shape((3, 5, 5)).unwrap();

This uses the new constructor range (contributed by @palango), and calls .unwrap() which will panic if the array does not have the correct number of elements for the new shape.

Splitting the array along an axis looks like this:

use ndarray::Axis;

let (first, second) = a.view_mut().split_at(Axis(2), 2);

// print out the shapes of the parts
println!("first={:?}, second={:?}", first.shape(), second.shape());
// Output: first=[3, 5, 2], second=[3, 5, 3]

.split_at() uses the new newtype Axis for the first argument, which all axis arguments now use in version 0.4. The split views borrow from the original array, but can be sent to separate threads. (Naturally we have an eye on integration with rayon!)

split-at

Easier to be Generic

Version 0.4 adds the trait NdFloat, defined for only f32 and f64, which makes it easy to include the extra trait bounds needed for some operations. Any is used for old school type-based specialization for linear algebra (only .dot() implemented so far), and ScalarOperand is needed for technical reasons to implement both array + array and array + scalar at the same time.

ArrayView and ArrayViewMut now implement From, so that you can convert from slices and array references into array views. These conversion implementations are wrapped up into an even simpler form in trait AsArray.

use ndarray::{AsArray, NdFloat};

/// Return the element sum of a slice or an array of floats
pub fn sum<'a, F: NdFloat, V: AsArray<'a, F>>(data: V) -> F {
    data.into().scalar_sum()
}

ndarray’s .scalar_sum() uses a manually unrolled loop so that it can be autovectorized by the compiler, despite the float accuracy rules that prevent a simple summation loop to be optimized that way, so this function may be a drop in win.

Change Log

There were a lot more improvements, some breaking changes and some deprecations. See the full change log for more information!

Future

Furious development will hopefully continue. Rust 1.8 is around the corner, and with it the assignment operators (+=, *= etc) are finally stable. We will deprecate our old equivalent methods (iadd, imul etc) at that point.