Skip to content

Add matrix commands - #18553

Merged
fdncred merged 6 commits into
nushell:mainfrom
fdncred:the_matrix
Jul 14, 2026
Merged

fdncred merged 6 commits into
nushell:mainfrom
fdncred:the_matrix

Conversation

@fdncred

@fdncred fdncred commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description

I've been thinking about this for a while. Trying to process data that's faster than nushell does but doesn't really need polars. This is what I came up with. The matrix family of commands.

This PR introduces a new matrix custom value type backed by the ndarray crate, providing high-performance n-dimensional array operations in Nushell. Modeled after the existing semver custom value pattern, all matrix operations operate directly on ndarray::ArrayD<f64> data with zero Value conversion overhead.

User-facing changes (Release notes)

Added matrix custom value and 21 subcommands

A new matrix custom value type enables high-performance matrix math in Nushell, backed by the ndarray library for Rust.

Constructors:

  • matrix zeros <dims> — create a matrix filled with zeros
  • matrix identity <n> — create an n×n identity matrix
  • into matrix — convert a table/list-of-lists/list-of-records into a matrix

Access:

  • matrix get-row <index> — extract a row as a list
  • matrix get-col <index> — extract a column as a list (2D only)
  • matrix set-row <index> <values> — replace a row
  • matrix set-col <index> <values> — replace a column (2D only)

Arithmetic:

  • matrix add <matrix|scalar> — element-wise addition with optional --broadcast
  • matrix subtract <matrix|scalar> — element-wise subtraction with optional --broadcast
  • matrix scale <scalar> — multiply all elements by a scalar
  • Matrix values also support <operator> expressions: $m + $n, $m * 2.0, $m == $n

Linear algebra:

  • matrix multiply <matrix> — dot product (supports 1D×1D, 2D×1D, 1D×2D, 2D×2D)
  • matrix transpose — swap rows and columns (nD reverses all axes)

Transforms:

  • matrix reshape <dims> — change dimensions
  • matrix reshape --flatten — flatten to 1D

Element-wise: (could rename this to matrix each if map is confusing)

  • matrix map { |e| ... } — apply a closure to each element, returning a new matrix

Reductions:

  • matrix sum / matrix sum --axis <n> — sum all or along an axis
  • matrix mean — arithmetic mean of all elements
  • matrix max / matrix max --axis <n> — maximum all or along an axis
  • matrix reduce --fold <init> { |acc e| ... } — fold all elements to a single value

Output:

  • matrix into-nu — convert to table (list of lists)
  • matrix into-nu --as-records — convert to table of records with auto-generated column names

Examples

# Create and manipulate matrices
[[1 2 3] [4 5 6]] | into matrix | matrix transpose | matrix into-nu | to nuon
# [[1.0, 4.0], [2.0, 5.0], [3.0, 6.0]]

matrix identity 3 | matrix scale 5 | matrix into-nu | to nuon
# [[5.0, 0.0, 0.0], [0.0, 5.0, 0.0], [0.0, 0.0, 5.0]]

# Matrix multiplication
[[1 2] [3 4]] | into matrix | matrix multiply ([[1 0] [0 1]] | into matrix) | matrix into-nu | to nuon
# [[1.0, 2.0], [3.0, 4.0]]

# Element-wise operations
[[1 2] [3 4]] | into matrix | matrix map { |e| $e * 2 } | matrix sum
# 20.0

# Broadcasting
matrix zeros 2 3 | matrix add --broadcast ([[1.0 2.0 3.0]] | into matrix) | matrix into-nu | to nuon
# [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]]

# Row/column access
matrix identity 2 | matrix get-row 1 | to nuon
# [0.0, 1.0]

# Shape metadata via cell path
matrix identity 2 | $in.shape
# ╭───┬───╮
# │ 0 │ 2 │
# │ 1 │ 2 │
# ╰───┴───╯
matrix identity 2 | $in.ndim   # 2
matrix identity 2 | $in.size   # 4

Standard iterator commands redirect to matrix-specific ones

  • each on a matrix → errors: "Use matrix map for element-wise operations"
  • par-each on a matrix → errors: "Use matrix map for element-wise operations"
  • reduce on a matrix → errors: "Use matrix reduce --fold <initial> { ... }"

Benchmarking

All benchmarks use std/bench with 100 rounds to eliminate outliers. Each benchmark compares a matrix command (backed by ndarray) against the equivalent operation using only nushell's built-in list/table commands.

Environment: release build, Apple Silicon M-series, 100×100 matrices (10,000 elements) for all except matrix multiply (50×50).


Results summary

Benchmark matrix nushell Speedup
Sum all elements 22µs 8,354µs 373×
Scale by scalar 223µs 18,723µs 84×
Transpose 374µs — Not sure how to do in nushell
Add two matrices 246µs — Does not complete in 2+ min
Matrix multiply (50×50) 81µs — O(n³) infeasible
Construct dense matrix 217µs 8,148µs 38×
Row-wise sum 26µs 8,640µs 328×
Map closure element-wise 9,929µs 20,496µs 2×

Additional notes

@fdncred
fdncred marked this pull request as ready for review July 10, 2026 21:06
@fdncred fdncred added notes:ready Indicates Ready for Release notes notes:additions Noted in "Additions" section labels Jul 14, 2026
@fdncred
fdncred merged commit addca5c into nushell:main Jul 14, 2026
15 checks passed
@fdncred
fdncred deleted the the_matrix branch July 14, 2026 20:04
@github-actions github-actions Bot added this to the v0.115.0 milestone Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

notes:additions Noted in "Additions" section notes:ready Indicates Ready for Release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant