std.ndarray

Dense numerical arrays, views, reductions, and matrix operations.

Importuse std.ndarray

Types

struct NdArray#

An N-dimensional numeric array (NdArray<T>) over dense native storage.

The element type parameter is the storage dtype: bool, an integer width, f32, or float. Produced by the std.ndarray constructors (zeros, ones, full, arange, linspace, from_array, from_nested, from_bytes); reshaped, transposed, and sliced in place; consumed by elementwise arithmetic and comparisons, reductions (sum, mean, min, max and their _axis forms), and the matrix products matmul and dot.

use std.ndarray
use std.ndarray.NdArray

fn main() {
  let grid: NdArray<i32> = ndarray.zeros<i32>([2, 3])
  grid.fill(2)
  println(grid.shape())
  println(grid.rank())
  println(grid.sum())
  println(grid.mean_axis(1).to_array())
  println(ndarray.arange(0, 4, 1).to_array())
}
struct NdSlice#

A contiguous rank-one view of an NdArray<T>'s elements (NdSlice<T>), returned by view_contiguous.

The view shares the array's storage rather than copying it: writes through either are visible to both, and the view borrows the array for as long as it is live. Its surface is the three operations an element loop needs — len, get and set — because everything else is a question for the NdArray it came from, which is still there and still the owner.

It exists so a loop over elements costs what a loop over [T] costs. The checker knows the rank is one and the dtype is T, so a read is one scalar index and a typed load, with no stride arithmetic, no contiguity test and no dtype switch in the loop body.

use std.ndarray

fn main() {
  let grid = ndarray.zeros<f32>([2, 3])
  match grid.view_contiguous() {
    ok(cells) => {
      for i in 0..cells.len() { cells.set(i, (i * 2) as f32) }
      println(cells.get(5))
    },
    err(e) => println(e),
  }
}

Functions

fn zeros<T>(shape: [int]) -> NdArray<T>#
fn ones<T>(shape: [int]) -> NdArray<T>#
fn full<T>(shape: [int], value: T) -> NdArray<T>#
fn arange(start: int, end: int, step: int = 1) -> NdArray<int>#
fn linspace(start: float, end: float, count: int) -> NdArray<float>#
fn from_array<T>(values: [T], shape: [int]) -> Result<NdArray<T>, Error>#
fn from_nested<T>(values: nested [T]) -> Result<NdArray<T>, Error>#
fn from_bytes<T>(data: string, shape: [int]) -> Result<NdArray<T>, Error>#
fn to_bytes<T>(array: NdArray<T>) -> string#
fn dot<T>(a: NdArray<T>, b: NdArray<T>) -> Result<T, Error>#
fn matmul<T>(a: NdArray<T>, b: NdArray<T>) -> Result<NdArray<T>, Error>#
fn rank<T>(self: NdArray<T>) -> int#
fn shape<T>(self: NdArray<T>) -> [int]#
fn strides<T>(self: NdArray<T>) -> [int]#
fn len<T>(self: NdArray<T>) -> int#
fn is_contiguous<T>(self: NdArray<T>) -> bool#
fn view_contiguous<T>(self: NdArray<T>) -> Result<NdSlice<T>, Error>#
fn dtype<T>(self: NdArray<T>) -> string#
fn to_array<T>(self: NdArray<T>) -> [T]#
fn astype<T, U>(self: NdArray<T>) -> Result<NdArray<U>, Error>#
fn copy<T>(self: NdArray<T>) -> NdArray<T>#
fn contiguous<T>(self: NdArray<T>) -> NdArray<T>#
fn get<T>(self: NdArray<T>, indices: [int]) -> T#
fn get_or_none<T>(self: NdArray<T>, indices: [int]) -> Optional<T>#
fn set<T>(self: NdArray<T>, indices: [int], value: T)#
fn slice<T>(self: NdArray<T>, starts: [int], ends: [int], steps: [int]) -> Result<NdArray<T>, Error>#
fn reshape<T>(self: NdArray<T>, shape: [int]) -> Result<NdArray<T>, Error>#
fn transpose<T>(self: NdArray<T>, axes: [int]) -> Result<NdArray<T>, Error>#
fn swap_axes<T>(self: NdArray<T>, a: int, b: int) -> Result<NdArray<T>, Error>#
fn squeeze<T>(self: NdArray<T>) -> NdArray<T>#
fn expand_dims<T>(self: NdArray<T>, axis: int) -> Result<NdArray<T>, Error>#
fn broadcast_to<T>(self: NdArray<T>, shape: [int]) -> Result<NdArray<T>, Error>#
fn transpose2<T>(self: NdArray<T>) -> Result<NdArray<T>, Error>#
fn iter<T>(self: NdArray<T>) -> Iterator<T>#
fn eq_elements<T>(self: NdArray<T>, other: T | NdArray<T>) -> NdArray<bool>#
fn ne_elements<T>(self: NdArray<T>, other: T | NdArray<T>) -> NdArray<bool>#
fn lt_elements<T>(self: NdArray<T>, other: T | NdArray<T>) -> NdArray<bool>#
fn le_elements<T>(self: NdArray<T>, other: T | NdArray<T>) -> NdArray<bool>#
fn gt_elements<T>(self: NdArray<T>, other: T | NdArray<T>) -> NdArray<bool>#
fn ge_elements<T>(self: NdArray<T>, other: T | NdArray<T>) -> NdArray<bool>#
fn add_in_place<T>(self: NdArray<T>, other: T | NdArray<T>)#
fn sub_in_place<T>(self: NdArray<T>, other: T | NdArray<T>)#
fn mul_in_place<T>(self: NdArray<T>, other: T | NdArray<T>)#
fn fill<T>(self: NdArray<T>, value: T)#
fn array_equal<T>(self: NdArray<T>, other: NdArray<T>) -> bool#
fn all_close<T>(self: NdArray<T>, other: NdArray<T>, rel: float = 1e-5, abs: float = 1e-8) -> bool#
fn sum<T>(self: NdArray<T>) -> T#
fn product<T>(self: NdArray<T>) -> T#
fn min<T>(self: NdArray<T>) -> Optional<T>#
fn max<T>(self: NdArray<T>) -> Optional<T>#
fn mean<T>(self: NdArray<T>) -> Optional<float>#
fn any(self: NdArray<bool>) -> bool#
fn all(self: NdArray<bool>) -> bool#
fn sum_axis<T>(self: NdArray<T>, axis: int, keep_dims: bool = false) -> NdArray<T>#
fn mean_axis<T>(self: NdArray<T>, axis: int, keep_dims: bool = false) -> NdArray<float>#
fn min_axis<T>(self: NdArray<T>, axis: int, keep_dims: bool = false) -> Result<NdArray<T>, Error>#
fn max_axis<T>(self: NdArray<T>, axis: int, keep_dims: bool = false) -> Result<NdArray<T>, Error>#