numbt

NumPy-style numerical computing library for MoonBit

numpy
numerical
blas
matrix
moon add mizchi/numbt@0.2.4
Download zip
Author
Version
0.2.4
License
Apache-2.0
Last updated
19 hours ago
Downloads
1K

Dependencies

README

#numbt

NumPy-style numerical computing library for MoonBit.

Built on BLAS (Apple Accelerate framework on macOS) for high-performance matrix operations.

#Features

  • Vec/Mat views over Float arrays (zero-copy)
  • BLAS-accelerated matrix multiplication (cblas_sgemm)
  • LAPACK SVD decomposition
  • Element-wise operations
  • Softmax, ReLU activation functions

#Requirements

  • MoonBit native backend
  • BLAS/LAPACK library:
    • macOS: Apple Accelerate (built-in)
    • Linux: OpenBLAS + LAPACK (sudo apt-get install libopenblas-dev liblapack-dev)

#Platform Configuration

Add the appropriate link flags to your package's moon.pkg:

macOS:
options( link: { "native": { "cc-link-flags": "-framework Accelerate" } }, )

Linux:
options( link: { "native": { "cc-link-flags": "-lopenblas -llapack -lm" } }, )

#Installation

Add to moon.mod.json:

{ "deps": { "mizchi/numbt": "0.1.0" } }

Then run:

moon update

#Usage

// Create views over arrays
let data : Array[Float] = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
let mat = @numbt.mat_view(data, rows=2, cols=3)
let vec = @numbt.vec_view(data, offset=0, len=3)

// Matrix multiplication
let a = @numbt.mat_view([1.0, 2.0, 3.0, 4.0], 2, 2)
let b = @numbt.mat_view([5.0, 6.0, 7.0, 8.0], 2, 2)
let c = a.matmul(b)

// Softmax
let logits = @numbt.vec_view([1.0, 2.0, 3.0], 0, 3)
let probs = @numbt.vec_view(Array::make(3, 0.0), 0, 3)
@numbt.softmax_into(input=logits, output=probs)

#API

#Vec operations

  • vec_view(data, offset, len) - Create a view
  • vec_add_into(left, right, output~) - Element-wise addition
  • vec_sub_into(left, right, output~) - Element-wise subtraction
  • vec_mul_into(left, right, output~) - Element-wise multiplication
  • softmax_into(input~, output~) - Softmax activation
  • relu_into(input~, output~) - ReLU activation

#Mat operations

  • mat_view(data, rows, cols) - Create a view
  • mat_matmul(a, b) - Matrix multiplication
  • Mat::matmul(self, other) - Method syntax
  • matmul_vec_bias_into(weight, input, bias, output~) - Linear layer forward

#LAPACK (LapackMat)

LapackMat is the FixedArray[Byte]-backed matrix type. Its raw byte layout matches what BLAS / LAPACK / vDSP expect, so calls into the native side are zero-copy.

  • fmat_zeros(rows, cols) / fmat_eye(n) / fmat_randn(rows, cols) - constructors
  • fmat_from_mat(m) / fmat_to_mat(fm) - conversion to / from Mat
  • fmat_matmul(a, b) - BLAS sgemm (matrix multiply)
  • fmat_svd / fmat_eig / fmat_cholesky / fmat_qr / fmat_det / fmat_lstsq - LAPACK
  • fmat_inv / fmat_solve - LU-based linear solve

#LapackMat: Accelerate vDSP element-wise + reductions (SIMD)

Zero-copy SIMD via Apple Accelerate's vDSP. ~10-30x faster than the equivalent scalar implementation on the same storage:

  • fmat_add / fmat_sub / fmat_mul / fmat_div - element-wise binary ops
  • fmat_add_into / etc. - in-place variants (no allocation)
  • fmat_add_scalar / fmat_mul_scalar - broadcast scalar ops
  • fmat_sum / fmat_mean / fmat_max / fmat_min - reductions

Note: the equivalent ops on the Array[Float]-backed Vec / Mat types stay scalar by default. MoonBit's C FFI requires the buffer to be FixedArray[Byte], and the Array[Float] -> bytes round-trip cost erases the SIMD win even at N = 1M+. For hot inner loops, convert once with fmat_from_mat and stay on LapackMat.

#License

Apache-2.0

#
LapackMat

pub struct LapackMat {
data : FixedArray[Byte]
rows : Int
cols : Int
}

Matrix type optimized for LAPACK operations (SVD, eigenvalues, etc).

Uses FixedArray[Byte] for zero-copy interop with C LAPACK functions. Convert from Mat using fmat_from_mat, back to Mat using fmat_to_mat.

#
Mat

pub struct Mat {
data : Array[Float]
rows : Int
cols : Int
}

impl Add for Mat
impl Div for Mat
impl Mul for Mat
impl Neg for Mat
impl Sub for Mat

#
Mat::matmul

fn Mat::matmul(self : Mat, other : Mat) -> Mat

Matrix multiplication method: self @ other

Example: let c = a.matmul(b) is equivalent to mat_matmul(a, b)

#
Vec

pub struct Vec {
data : Array[Float]
offset : Int
len : Int
}

impl Add for Vec
impl Div for Vec
impl Mul for Vec
impl Neg for Vec
impl Sub for Vec

#
batch_matmul

fn batch_matmul(input : Array[Float], weight : Array[Float], out : Array[Float], batch : Int, in_dim : Int, out_dim : Int) -> Unit

Batch matrix multiply using BLAS sgemm: Out = Input @ Weight Input: batch x in_dim, Weight: in_dim x out_dim, Out: batch x out_dim

#
batch_matmul_bias

fn batch_matmul_bias(input : Array[Float], weight : Array[Float], bias : Array[Float], out : Array[Float], batch : Int, in_dim : Int, out_dim : Int) -> Unit

Batch matrix multiply + bias

#
batch_matmul_bias_relu

fn batch_matmul_bias_relu(input : Array[Float], weight : Array[Float], bias : Array[Float], out : Array[Float], batch : Int, in_dim : Int, out_dim : Int) -> Unit

Batch matrix multiply + bias + ReLU

#
cross_entropy_loss

fn cross_entropy_loss(probs : Vec, label : Int) -> Float

#
fmat_add

fn fmat_add(a : LapackMat, b : LapackMat) -> LapackMat

LapackMat add (C = A + B), backed by Accelerate vDSP_vadd. Zero-copy: FixedArray[Byte] storage is passed directly to the SIMD path.

#
fmat_add_into

fn fmat_add_into(a : LapackMat, b : LapackMat, out~ : LapackMat) -> Unit

In-place fmat add: out = a + b (zero allocation).

#
fmat_add_scalar

fn fmat_add_scalar(a : LapackMat, scalar : Float) -> LapackMat

Scalar add: out[i] = a[i] + scalar (Accelerate vDSP_vsadd).

#
fmat_cholesky

fn fmat_cholesky(a : LapackMat) -> LapackMat?

Cholesky decomposition: A = L @ L^T Returns lower triangular L or None if failed Note: input matrix must be symmetric positive definite

#
fmat_clone

fn fmat_clone(fm : LapackMat) -> LapackMat

#
fmat_cols

fn fmat_cols(fm : LapackMat) -> Int

#
fmat_det

fn fmat_det(a : LapackMat) -> Float?

Compute determinant of square matrix Returns determinant or None if failed

#
fmat_div

fn fmat_div(a : LapackMat, b : LapackMat) -> LapackMat

LapackMat element-wise div: C[i,j] = A[i,j] / B[i,j] (Accelerate vDSP_vdiv).

#
fmat_div_into

fn fmat_div_into(a : LapackMat, b : LapackMat, out~ : LapackMat) -> Unit

#
fmat_eig

fn fmat_eig(a : LapackMat) -> (Vec, LapackMat)?

Eigenvalue decomposition for symmetric matrix Returns (eigenvalues, eigenvectors) or None if failed Note: input matrix must be symmetric

#
fmat_eye

fn fmat_eye(n : Int) -> LapackMat

Create LapackMat identity matrix

#
fmat_from_mat

fn fmat_from_mat(m : Mat) -> LapackMat

#
fmat_inv

fn fmat_inv(fm : LapackMat) -> Bool

Matrix inverse on LapackMat (in-place, returns success)

#
fmat_lstsq

fn fmat_lstsq(a : LapackMat, b : Vec) -> Vec?

Least squares solution: minimize ||A @ x - b|| Returns solution x or None if failed

#
fmat_matmul

fn fmat_matmul(a : LapackMat, b : LapackMat) -> LapackMat

#
fmat_max

fn fmat_max(a : LapackMat) -> Float

Max of all elements (Accelerate vDSP_maxv).

#
fmat_mean

fn fmat_mean(a : LapackMat) -> Float

Mean of all elements (Accelerate vDSP_meanv).

#
fmat_min

fn fmat_min(a : LapackMat) -> Float

Min of all elements (Accelerate vDSP_minv).

#
fmat_mul

fn fmat_mul(a : LapackMat, b : LapackMat) -> LapackMat

LapackMat element-wise mul: C[i,j] = A[i,j] * B[i,j] (Accelerate vDSP_vmul). Not matrix-matrix multiply; for that use fmat_matmul.

#
fmat_mul_into

fn fmat_mul_into(a : LapackMat, b : LapackMat, out~ : LapackMat) -> Unit

#
fmat_mul_scalar

fn fmat_mul_scalar(a : LapackMat, scalar : Float) -> LapackMat

Scalar mul: out[i] = a[i] * scalar (Accelerate vDSP_vsmul).

#
fmat_qr

fn fmat_qr(a : LapackMat) -> (LapackMat, LapackMat)?

QR decomposition: A = Q @ R Returns (Q, R) or None if failed

#
fmat_randn

fn fmat_randn(rows : Int, cols : Int) -> LapackMat

Create LapackMat from random values

#
fmat_rows

fn fmat_rows(fm : LapackMat) -> Int

#
fmat_solve

fn fmat_solve(a : LapackMat, b : FixedArray[Byte]) -> Bool

Solve A @ x = b on LapackMat (modifies both a and b in-place) After call, b contains solution x

#
fmat_sub

fn fmat_sub(a : LapackMat, b : LapackMat) -> LapackMat

LapackMat sub: C = A - B (Accelerate vDSP_vsub).

#
fmat_sub_into

fn fmat_sub_into(a : LapackMat, b : LapackMat, out~ : LapackMat) -> Unit

#
fmat_sum

fn fmat_sum(a : LapackMat) -> Float

Sum of all elements (Accelerate vDSP_sve).

#
fmat_svd

fn fmat_svd(a : LapackMat) -> (LapackMat, Vec, LapackMat)?

SVD decomposition: A = U @ diag(S) @ Vt Returns (U, S, Vt) or None if failed

#
fmat_to_mat

fn fmat_to_mat(fm : LapackMat) -> Mat

#
fmat_transpose

fn fmat_transpose(a : LapackMat) -> LapackMat

LapackMat transpose

#
fmat_zeros

fn fmat_zeros(rows : Int, cols : Int) -> LapackMat

#
mat_add

fn mat_add(a : Mat, b : Mat) -> Mat

#
mat_add_into

fn mat_add_into(a : Mat, b : Mat, output~ : Mat) -> Unit

Element-wise matrix addition: output[i,j] = a[i,j] + b[i,j]

#
mat_add_scalar

fn mat_add_scalar(mat : Mat, scalar : Float) -> Mat

#
mat_allclose

fn mat_allclose(a : Mat, b : Mat, atol : Float) -> Bool

Check if all elements are equal within tolerance

#
mat_at

fn mat_at(mat : Mat, row : Int, col : Int) -> Float

#
mat_clone

fn mat_clone(mat : Mat) -> Mat

#
mat_cols

fn mat_cols(mat : Mat) -> Int

#
mat_diag

fn mat_diag(m : Mat) -> Vec

Extract diagonal elements from matrix

#
mat_div

fn mat_div(a : Mat, b : Mat) -> Mat

#
mat_div_into

fn mat_div_into(a : Mat, b : Mat, output~ : Mat) -> Unit

Element-wise matrix division: output[i,j] = a[i,j] / b[i,j]

#
mat_div_scalar

fn mat_div_scalar(mat : Mat, scalar : Float) -> Mat

#
mat_eye

fn mat_eye(n : Int) -> Mat

#
mat_fill

fn mat_fill(mat : Mat, value : Float) -> Unit

@deprecated Use mat_fill_inplace instead.

#
mat_fill_inplace

fn mat_fill_inplace(mat : Mat, value : Float) -> Unit

Fill all elements with a constant value (in-place modification).

#
mat_flatten

fn mat_flatten(mat : Mat) -> Vec

Flatten mat to vec (row-major order)

#
mat_hstack

fn mat_hstack(mats : Array[Mat]) -> Mat

Horizontal stack: stack matrices along columns (axis=1)

#
mat_inv

fn mat_inv(m : Mat) -> Mat?

Matrix inverse using LAPACK sgetrf/sgetri Returns None if matrix is singular

#
mat_matmul

fn mat_matmul(a : Mat, b : Mat) -> Mat

Matrix multiplication using BLAS: C = A @ B

Equivalent to NumPy's @ operator or np.matmul. Requires: a.cols == b.rows

#
mat_max

fn mat_max(mat : Mat) -> Float

Max of all elements

#
mat_mean

fn mat_mean(mat : Mat) -> Float

Mean of all elements

#
mat_mean_axis0

fn mat_mean_axis0(mat : Mat) -> Vec

Mean along axis 0

#
mat_mean_axis1

fn mat_mean_axis1(mat : Mat) -> Vec

Mean along axis 1

#
mat_min

fn mat_min(mat : Mat) -> Float

Min of all elements

#
mat_mul

fn mat_mul(a : Mat, b : Mat) -> Mat

#
mat_mul_into

fn mat_mul_into(a : Mat, b : Mat, output~ : Mat) -> Unit

Element-wise matrix multiplication: output[i,j] = a[i,j] * b[i,j]

#
mat_mul_scalar

fn mat_mul_scalar(mat : Mat, scalar : Float) -> Mat

#
mat_neg

fn mat_neg(mat : Mat) -> Mat

#
mat_new

fn mat_new(rows : Int, cols : Int, value : Float) -> Mat

#
mat_ones

fn mat_ones(rows : Int, cols : Int) -> Mat

#
mat_rand

fn mat_rand(rows : Int, cols : Int) -> Mat

Generate matrix of uniform random values in [0, 1)

#
mat_randn

fn mat_randn(rows : Int, cols : Int) -> Mat

Generate matrix of standard normal random values

#
mat_row

fn mat_row(mat : Mat, row : Int) -> Vec

Get row as Vec (view into original data)

#
mat_rows

fn mat_rows(mat : Mat) -> Int

#
mat_scale_inplace

fn mat_scale_inplace(mat : Mat, scalar : Float) -> Unit

#
mat_set

fn mat_set(mat : Mat, row : Int, col : Int, value : Float) -> Unit

#
mat_solve

fn mat_solve(a : Mat, b : Vec) -> Vec?

Solve linear system A @ x = b using LAPACK sgesv Returns None if system is singular

#
mat_sub

fn mat_sub(a : Mat, b : Mat) -> Mat

#
mat_sub_into

fn mat_sub_into(a : Mat, b : Mat, output~ : Mat) -> Unit

Element-wise matrix subtraction: output[i,j] = a[i,j] - b[i,j]

#
mat_sub_scalar

fn mat_sub_scalar(mat : Mat, scalar : Float) -> Mat

#
mat_sum

fn mat_sum(mat : Mat) -> Float

Sum of all elements

#
mat_sum_axis0

fn mat_sum_axis0(mat : Mat) -> Vec

Sum along axis 0 (columns): result[j] = sum_i(mat[i,j])

#
mat_sum_axis1

fn mat_sum_axis1(mat : Mat) -> Vec

Sum along axis 1 (rows): result[i] = sum_j(mat[i,j])

#
mat_tile

fn mat_tile(m : Mat, rows_repeat : Int, cols_repeat : Int) -> Mat

Tile matrix: repeat along rows and columns

#
mat_to_array

fn mat_to_array(mat : Mat) -> Array[Float]

#
mat_trace

fn mat_trace(m : Mat) -> Float

Trace of matrix (sum of diagonal elements)

#
mat_transpose

fn mat_transpose(mat : Mat) -> Mat

Transpose matrix (creates new matrix)

#
mat_view

fn mat_view(data : Array[Float], rows : Int, cols : Int) -> Mat

#
mat_vstack

fn mat_vstack(mats : Array[Mat]) -> Mat

Vertical stack: stack matrices along rows (axis=0)

#
mat_zeros

fn mat_zeros(rows : Int, cols : Int) -> Mat

#
matmul_vec_bias_blas_into

fn matmul_vec_bias_blas_into(weight : Mat, input : Vec, bias : Vec, output~ : Vec) -> Unit

Matrix-vector multiply + bias using BLAS: output = weight^T @ input + bias

Uses Accelerate framework's BLAS for optimal performance.

#
matmul_vec_bias_into

fn matmul_vec_bias_into(weight : Mat, input : Vec, bias : Vec, output~ : Vec) -> Unit

Matrix-vector multiply with bias: output = weight^T @ input + bias

Parameters:
  • weight: Matrix of shape (in_dim, out_dim)
  • input: Input vector of length in_dim
  • bias: Bias vector of length out_dim
  • output: Output buffer of length out_dim

Computes: output[j] = bias[j] + sum_i(input[i] * weight[i, j])

#
matmul_vec_bias_relu_blas_into

fn matmul_vec_bias_relu_blas_into(weight : Mat, input : Vec, bias : Vec, output~ : Vec) -> Unit

Matrix-vector multiply + bias + ReLU using BLAS

Computes: output = relu(weight^T @ input + bias) Uses Accelerate framework's BLAS for optimal performance.

#
matmul_vec_bias_relu_into

fn matmul_vec_bias_relu_into(weight : Mat, input : Vec, bias : Vec, output~ : Vec) -> Unit

Matrix-vector multiply with bias and ReLU: output = relu(weight^T @ input + bias)

Parameters:
  • weight: Matrix of shape (in_dim, out_dim)
  • input: Input vector of length in_dim
  • bias: Bias vector of length out_dim
  • output: Output buffer of length out_dim

Computes: output[j] = max(0, bias[j] + sum_i(input[i] * weight[i, j]))

#
matmul_vec_blas_into

fn matmul_vec_blas_into(weight : Mat, input : Vec, output~ : Vec) -> Unit

Matrix-vector multiply using BLAS sgemv: output = weight^T @ input

Uses Accelerate framework's BLAS for optimal performance.

#
matmul_vec_into

fn matmul_vec_into(weight : Mat, input : Vec, output~ : Vec) -> Unit

Matrix-vector multiply: output = weight^T @ input

Parameters:
  • weight: Matrix of shape (in_dim, out_dim)
  • input: Input vector of length in_dim
  • output: Output buffer of length out_dim

Computes: output[j] = sum_i(input[i] * weight[i, j])

#
random_seed

fn random_seed(seed : Int) -> Unit

Set random seed

#
relu

fn relu(value : Float) -> Float

#
relu_grad

fn relu_grad(value : Float) -> Float

#
softmax_into

fn softmax_into(input~ : Vec, output~ : Vec) -> Unit

Compute softmax probabilities from logits (writes to output buffer).

Parameters:
  • input: Raw logits (unnormalized scores)
  • output: Output buffer for normalized probabilities (same length as input)

The softmax is computed with numerical stability (subtracting max). Result: output[i] = exp(input[i] - max) / sum(exp(input - max))

#
vec_abs

fn vec_abs(input : Vec) -> Vec

#
vec_abs_into

fn vec_abs_into(input : Vec, output~ : Vec) -> Unit

Element-wise absolute value: output[i] = |input[i]|

#
vec_add

fn vec_add(left : Vec, right : Vec) -> Vec

#
vec_add_into

fn vec_add_into(left : Vec, right : Vec, output~ : Vec) -> Unit

Element-wise addition: output[i] = left[i] + right[i]

#
vec_add_scalar

fn vec_add_scalar(vec : Vec, scalar : Float) -> Vec

Add scalar to all elements: out = vec + scalar

#
vec_add_scalar_inplace

fn vec_add_scalar_inplace(vec : Vec, scalar : Float) -> Unit

In-place add scalar: vec = vec + scalar

#
vec_all

fn vec_all(v : Vec) -> Bool

Returns true if all elements are non-zero (truthy)

#
vec_allclose

fn vec_allclose(a : Vec, b : Vec, atol : Float) -> Bool

Check if all elements are equal within tolerance

#
vec_any

fn vec_any(v : Vec) -> Bool

Returns true if any element is non-zero (truthy)

#
vec_arange

fn vec_arange(start : Float, stop : Float, step : Float) -> Vec

Create vec like numpy.arange: [start, stop) with step

#
vec_argmax

fn vec_argmax(vec : Vec) -> Int

#
vec_argmin

fn vec_argmin(vec : Vec) -> Int

#
vec_argsort

fn vec_argsort(v : Vec) -> Array[Int]

Return indices that would sort the vector (ascending)

#
vec_argsort_desc

fn vec_argsort_desc(v : Vec) -> Array[Int]

Return indices that would sort the vector (descending)

#
vec_at

fn vec_at(vec : Vec, index : Int) -> Float

#
vec_axpy

fn vec_axpy(alpha : Float, x : Vec, y : Vec) -> Unit

AXPY: y = α*x + y

#
vec_ceil

fn vec_ceil(input : Vec) -> Vec

#
vec_ceil_into

fn vec_ceil_into(input : Vec, output~ : Vec) -> Unit

Element-wise ceiling: output[i] = ceil(input[i])

#
vec_clip

fn vec_clip(input : Vec, min : Float, max : Float) -> Vec

#
vec_clip_into

fn vec_clip_into(input : Vec, min : Float, max : Float, output~ : Vec) -> Unit

Clip values to [min, max] range: output[i] = clamp(input[i], min, max)

#
vec_concatenate

fn vec_concatenate(vecs : Array[Vec]) -> Vec

Concatenate multiple vectors into one

#
vec_cos

fn vec_cos(input : Vec) -> Vec

#
vec_cos_into

fn vec_cos_into(input : Vec, output~ : Vec) -> Unit

Element-wise cosine: output[i] = cos(input[i])

#
vec_cumprod

fn vec_cumprod(v : Vec) -> Vec

Cumulative product: out[i] = prod(v[0..i+1])

#
vec_cumsum

fn vec_cumsum(v : Vec) -> Vec

Cumulative sum: out[i] = sum(v[0..i+1])

#
vec_diag

fn vec_diag(v : Vec) -> Mat

Create diagonal matrix from vector

#
vec_diff

fn vec_diff(v : Vec) -> Vec

Difference between consecutive elements: out[i] = v[i+1] - v[i]

#
vec_div

fn vec_div(left : Vec, right : Vec) -> Vec

#
vec_div_into

fn vec_div_into(left : Vec, right : Vec, output~ : Vec) -> Unit

Element-wise division: output[i] = left[i] / right[i]

#
vec_div_scalar

fn vec_div_scalar(vec : Vec, scalar : Float) -> Vec

Divide all elements by scalar: out = vec / scalar

#
vec_div_scalar_inplace

fn vec_div_scalar_inplace(vec : Vec, scalar : Float) -> Unit

In-place div scalar: vec = vec / scalar

#
vec_dot

fn vec_dot(x : Vec, y : Vec) -> Float

Dot product: x · y

#
vec_exp

fn vec_exp(input : Vec) -> Vec

Uses vvexpf from Accelerate framework for optimal performance

#
vec_exp_into

fn vec_exp_into(output~ : Vec, input : Vec) -> Unit

Element-wise exponential: output[i] = exp(input[i])

Note: For BLAS-accelerated version, use vec_exp which uses vvexpf.

#
vec_fill

fn vec_fill(vec : Vec, value : Float) -> Unit

@deprecated Use vec_fill_inplace instead.

#
vec_fill_inplace

fn vec_fill_inplace(vec : Vec, value : Float) -> Unit

Fill all elements with a constant value (in-place modification).

Example: vec_fill_inplace(v, 0.0) sets all elements to zero.

#
vec_floor

fn vec_floor(input : Vec) -> Vec

#
vec_floor_into

fn vec_floor_into(input : Vec, output~ : Vec) -> Unit

Element-wise floor: output[i] = floor(input[i])

#
vec_from_array

fn vec_from_array(data : Array[Float]) -> Vec

#
vec_from_fn

fn vec_from_fn(len : Int, f : (Int) -> Float) -> Vec

Create vec from initializer function: out[i] = f(i)

#
vec_ge

fn vec_ge(v : Vec, threshold : Float) -> Vec

Element-wise greater than or equal

#
vec_gt

fn vec_gt(v : Vec, threshold : Float) -> Vec

Element-wise greater than: out[i] = 1.0 if v[i] > threshold else 0.0

#
vec_has_inf

fn vec_has_inf(v : Vec) -> Bool

Check if any element is infinite

#
vec_has_nan

fn vec_has_nan(v : Vec) -> Bool

Check if any element is NaN

#
vec_le

fn vec_le(v : Vec, threshold : Float) -> Vec

Element-wise less than or equal

#
vec_len

fn vec_len(vec : Vec) -> Int

#
vec_linspace

fn vec_linspace(start : Float, stop : Float, num : Int) -> Vec

Create vec like numpy.linspace: num evenly spaced values in [start, stop]

#
vec_log

fn vec_log(input : Vec) -> Vec

#
vec_log_into

fn vec_log_into(output~ : Vec, input : Vec) -> Unit

Element-wise natural logarithm: output[i] = ln(input[i])

#
vec_lt

fn vec_lt(v : Vec, threshold : Float) -> Vec

Element-wise less than

#
vec_max

fn vec_max(vec : Vec) -> Float

#
vec_maximum

fn vec_maximum(a : Vec, b : Vec) -> Vec

#
vec_maximum_into

fn vec_maximum_into(a : Vec, b : Vec, output~ : Vec) -> Unit

Element-wise maximum of two vectors: output[i] = max(a[i], b[i])

#
vec_mean

fn vec_mean(vec : Vec) -> Float

#
vec_median

fn vec_median(v : Vec) -> Float

Median of vector elements

#
vec_min

fn vec_min(vec : Vec) -> Float

#
vec_minimum

fn vec_minimum(a : Vec, b : Vec) -> Vec

#
vec_minimum_into

fn vec_minimum_into(a : Vec, b : Vec, output~ : Vec) -> Unit

Element-wise minimum of two vectors: output[i] = min(a[i], b[i])

#
vec_mul

fn vec_mul(left : Vec, right : Vec) -> Vec

#
vec_mul_into

fn vec_mul_into(left : Vec, right : Vec, output~ : Vec) -> Unit

Element-wise multiplication: output[i] = left[i] * right[i]

#
vec_mul_scalar

fn vec_mul_scalar(vec : Vec, scalar : Float) -> Vec

Multiply all elements by scalar: out = vec * scalar

#
vec_mul_scalar_inplace

fn vec_mul_scalar_inplace(vec : Vec, scalar : Float) -> Unit

In-place mul scalar: vec = vec * scalar

#
vec_neg

fn vec_neg(input : Vec) -> Vec

Negate all elements: out = -input

#
vec_neg_inplace

fn vec_neg_inplace(vec : Vec) -> Unit

In-place negate: vec = -vec

#
vec_new

fn vec_new(len : Int, value : Float) -> Vec

#
vec_nonzero

fn vec_nonzero(v : Vec) -> Array[Int]

Return indices of non-zero elements

#
vec_nrm2

fn vec_nrm2(x : Vec) -> Float

L2 norm: ||x||_2

#
vec_ones

fn vec_ones(len : Int) -> Vec

#
vec_outer

fn vec_outer(a : Vec, b : Vec) -> Mat

Outer product: out[i,j] = a[i] * b[j] Uses BLAS sger from Accelerate framework for optimal performance

#
vec_percentile

fn vec_percentile(v : Vec, p : Float) -> Float

Percentile (0-100) of vector elements

#
vec_pow

fn vec_pow(input : Vec, exp : Float) -> Vec

#
vec_pow_into

fn vec_pow_into(input : Vec, exp : Float, output~ : Vec) -> Unit

Element-wise power: output[i] = input[i]^exp

#
vec_prod

fn vec_prod(vec : Vec) -> Float

Product of all elements

#
vec_quantile

fn vec_quantile(v : Vec, q : Float) -> Float

Quantile (0-1) of vector elements

#
vec_rand

fn vec_rand(n : Int) -> Vec

Generate vector of uniform random values in [0, 1)

#
vec_randn

fn vec_randn(n : Int) -> Vec

Generate vector of standard normal random values (mean=0, std=1)

#
vec_repeat

fn vec_repeat(v : Vec, n : Int) -> Vec

Repeat vector n times

#
vec_reshape

fn vec_reshape(v : Vec, rows : Int, cols : Int) -> Mat

Reshape vec to mat (must have matching element count)

#
vec_round

fn vec_round(input : Vec) -> Vec

#
vec_round_into

fn vec_round_into(input : Vec, output~ : Vec) -> Unit

Element-wise rounding: output[i] = round(input[i])

#
vec_scale_inplace

fn vec_scale_inplace(vec : Vec, scale : Float) -> Unit

Multiply all elements by a scalar (in-place modification).

Example: vec_scale_inplace(v, 2.0) doubles all elements.

#
vec_searchsorted

fn vec_searchsorted(sorted : Vec, value : Float) -> Int

Binary search: find insertion point for value in sorted vector Returns index where value should be inserted to maintain sorted order

#
vec_searchsorted_right

fn vec_searchsorted_right(sorted : Vec, value : Float) -> Int

Binary search (right): find rightmost insertion point

#
vec_set

fn vec_set(vec : Vec, index : Int, value : Float) -> Unit

#
vec_shuffle

fn vec_shuffle(v : Vec) -> Vec

Shuffle vector elements in place

#
vec_sign

fn vec_sign(input : Vec) -> Vec

#
vec_sign_into

fn vec_sign_into(input : Vec, output~ : Vec) -> Unit

Element-wise sign: -1 for negative, 0 for zero, 1 for positive

#
vec_sin

fn vec_sin(input : Vec) -> Vec

#
vec_sin_into

fn vec_sin_into(input : Vec, output~ : Vec) -> Unit

Element-wise sine: output[i] = sin(input[i])

#
vec_slice

fn vec_slice(v : Vec, start : Int, end : Int) -> Vec

Create a slice of vec [start, end)

#
vec_sort

fn vec_sort(v : Vec) -> Vec

Sort vector in ascending order (returns new vector) Uses vDSP_vsort from Accelerate framework for optimal performance

#
vec_sort_desc

fn vec_sort_desc(v : Vec) -> Vec

Sort vector in descending order (returns new vector) Uses vDSP_vsort from Accelerate framework for optimal performance

#
vec_sqrt

fn vec_sqrt(input : Vec) -> Vec

#
vec_sqrt_into

fn vec_sqrt_into(input : Vec, output~ : Vec) -> Unit

Element-wise square root: output[i] = sqrt(input[i])

#
vec_std

fn vec_std(vec : Vec) -> Float

Standard deviation: sqrt(variance)

#
vec_sub

fn vec_sub(left : Vec, right : Vec) -> Vec

#
vec_sub_into

fn vec_sub_into(left : Vec, right : Vec, output~ : Vec) -> Unit

Element-wise subtraction: output[i] = left[i] - right[i]

#
vec_sub_scalar

fn vec_sub_scalar(vec : Vec, scalar : Float) -> Vec

Subtract scalar from all elements: out = vec - scalar

#
vec_sub_scalar_inplace

fn vec_sub_scalar_inplace(vec : Vec, scalar : Float) -> Unit

In-place sub scalar: vec = vec - scalar

#
vec_sum

fn vec_sum(vec : Vec) -> Float

#
vec_tanh

fn vec_tanh(input : Vec) -> Vec

#
vec_tanh_into

fn vec_tanh_into(input : Vec, output~ : Vec) -> Unit

Element-wise hyperbolic tangent: output[i] = tanh(input[i])

#
vec_to_array

fn vec_to_array(vec : Vec) -> Array[Float]

#
vec_unique

fn vec_unique(v : Vec) -> Vec

Return sorted unique elements

#
vec_var

fn vec_var(vec : Vec) -> Float

Variance: E[(X - mean)^2]

#
vec_view

fn vec_view(data : Array[Float], offset : Int, len : Int) -> Vec

#
vec_where

fn vec_where(mask : Vec, x : Vec, y : Vec) -> Vec

Select elements based on mask: out[i] = x[i] if mask[i] > 0 else y[i]

#
vec_where_scalar

fn vec_where_scalar(mask : Vec, x : Vec, y : Float) -> Vec

Select elements based on mask with scalar fallback

#
vec_zeros

fn vec_zeros(len : Int) -> Vec