matrix

May 20, 2026 · View on GitHub

A clean, generic, zero-dependency matrix math package for Go.

Go Reference Go Report Card codecov Go ≥1.21 License: MIT

Features

  • Generic — works with int, float32, float64, complex128, and more
  • Zero dependencies — pure Go stdlib only
  • Immutable by default — operations return new matrices, never mutate
  • Numerically stable — partial pivoting throughout, epsilon-based comparisons
  • Full decompositions — LU, QR, Eigen, and SVD out of the box
  • Well documented — every function explains the math, not just the code

Installation

go get github.com/Arceus-7/matrix

Requires Go 1.21+ (for generics stability).

Quick Start

package main

import (
    "fmt"
    "github.com/Arceus-7/matrix"
)

func main() {
    // Create from a 2D slice
    m := matrix.MustNew([][]float64{
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9},
    })
    m.Print()
    // [ 1.0000  2.0000  3.0000 ]
    // [ 4.0000  5.0000  6.0000 ]
    // [ 7.0000  8.0000  9.0000 ]

    // Special constructors
    identity := matrix.Identity[float64](3)     // 3×3 identity
    zeros    := matrix.Zeros[float64](3, 4)     // 3×4 zero matrix
    ones     := matrix.Ones[float64](2, 2)      // 2×2 ones matrix
    random   := matrix.Random[float64](3, 3)    // 3×3 random [0,1)

    _ = identity; _ = zeros; _ = ones; _ = random
}

Operations

Arithmetic

a := matrix.MustNew([][]float64{{1, 2}, {3, 4}})
b := matrix.MustNew([][]float64{{5, 6}, {7, 8}})

sum, _     := matrix.Add(a, b)        // element-wise addition
diff, _    := matrix.Sub(a, b)        // element-wise subtraction
product, _ := matrix.Mul(a, b)        // matrix multiplication
scaled     := matrix.Scale(a, 2.5)    // scalar multiplication
transposed := matrix.Transpose(a)     // transpose
hadamard,_ := matrix.HadamardProduct(a, b) // element-wise multiply

_, _, _, _ = sum, diff, product, scaled
_, _ = transposed, hadamard

Accessors

m := matrix.MustNew([][]float64{
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
})

row, _  := m.Row(0)                  // [ 1.0000  2.0000  3.0000 ] (1×3)
col, _  := m.Col(1)                  // [ 2.0000; 5.0000; 8.0000 ] (3×1)
sub, _  := m.SubMatrix(0, 2, 0, 2)   // top-left 2×2 block

_, _, _ = row, col, sub

Properties

m := matrix.MustNew([][]float64{
    {6, 1, 1},
    {4, -2, 5},
    {2, 8, 7},
})

rows, cols := m.Shape()           // (3, 3)
val, _     := m.At(0, 1)          // 1.0
det, _     := m.Det()             // -306.0
rank       := m.Rank()            // 3
trace, _   := m.Trace()           // 11.0
norm       := m.Norm()            // Frobenius norm
isSquare   := m.IsSquare()        // true
isSym      := m.IsSymmetric()     // false

_, _, _, _, _, _, _, _ = rows, cols, val, det, rank, trace, norm, isSquare
_ = isSym

Comparison

a := matrix.MustNew([][]float64{{1, 2}, {3, 4}})
b := matrix.MustNew([][]float64{{1.0000000001, 2}, {3, 4}})

exact := a.Equals(b)               // false (exact comparison)
approx := a.ApproxEquals(b, 1e-6)  // true  (within epsilon)

_, _ = exact, approx

Transformations

m := matrix.MustNew([][]float64{
    {2, 1, -1},
    {-3, -1, 2},
    {-2, 1, 2},
})

inv, _  := m.Inverse()     // matrix inverse (A⁻¹)
ref, _  := m.REF()         // Row Echelon Form
rref, _ := m.RREF()        // Reduced Row Echelon Form

_, _, _ = inv, ref, rref

Decompositions

m := matrix.MustNew([][]float64{
    {12, -51, 4},
    {6, 167, -68},
    {-4, 24, -41},
})

L, U, _      := m.LU()        // LU decomposition (PA = LU)
L, U, P, _   := m.LUP()       // LU with permutation matrix (P*A = L*U)
Q, R, _      := m.QR()        // QR decomposition (A = QR)
eigs, _      := m.Eigen()     // eigenvalues
U2, S, V, _  := m.SVD()       // singular value decomposition (A = U*Σ*Vᵀ)

_, _, _, _, _, _, _, _, _ = L, U, P, Q, R, eigs, U2, S, V

Solving Linear Systems

// Solve Ax = b
// System: 2x + y = 5, x + 3y = 7
// Solution: x = 1.6, y = 1.8
A := matrix.MustNew([][]float64{{2, 1}, {1, 3}})
b := matrix.MustNew([][]float64{{5}, {7}})

x, err := matrix.Solve(A, b)
if err != nil {
    panic(err)
}
x.Print()
// [ 1.6000 ]
// [ 1.8000 ]

Pretty Printing

m := matrix.MustNew([][]float64{{1.5, 2.7}, {3.14, 4.0}})

// Default formatting
fmt.Println(m)

// Custom formatting
m.PrintWith(matrix.PrintOptions{
    Precision: 2,      // 2 decimal places
    Padding:   3,      // 3 spaces between columns
    Brackets:  "round", // ( ) instead of [ ]
})

Generic Type Support

// Integer matrices
intM := matrix.MustNew([][]int{{1, 2}, {3, 4}})

// Float32
f32M := matrix.MustNew([][]float32{{1.5, 2.5}, {3.5, 4.5}})

// Complex numbers
cplxM := matrix.MustNew([][]complex128{{1+2i, 3+4i}, {5+6i, 7+8i}})

// Operations that produce fractional results (RREF, Inverse, LU, etc.)
// always return *Matrix[float64], even for integer inputs
inv, _ := intM.Inverse() // returns *Matrix[float64]

_, _, _ = f32M, cplxM, inv

Error Handling

All operations that can fail return (result, error) — never panic:

var (
    matrix.ErrDimensionMismatch  // incompatible matrix dimensions
    matrix.ErrNotSquare          // operation needs a square matrix
    matrix.ErrSingular           // matrix is singular (det ≈ 0)
    matrix.ErrNotInvertible      // matrix cannot be inverted
    matrix.ErrOutOfBounds        // index out of range
    matrix.ErrEmptyMatrix        // zero rows or columns
    matrix.ErrNotVector          // expected n×1 column vector
    matrix.ErrNotConverged       // iterative algorithm did not converge
)

Numerical Stability

Floating-point comparisons use an epsilon tolerance (default 1e-9):

// Adjust the global epsilon if needed
matrix.Epsilon = 1e-12

All elimination-based operations (REF, RREF, Inverse, LU) use partial pivoting — they swap rows to place the largest absolute value on the diagonal, reducing numerical error from catastrophic cancellation.

Benchmarks

Measured on Intel i5-11400F @ 2.60GHz, Go 1.21, Windows 11.

go test -bench . -benchmem -run NOMATCH .
Operation10×10100×100
Mul1.9 µs / 1.1 KB1.6 ms / 92 KB
LU1.6 µs / 2.3 KB466 µs / 186 KB
QR2.5 µs / 3.3 KB1.2 ms / 277 KB
Solve2.4 µs / 3.2 KB519 µs / 195 KB
Det1.1 µs / 1.1 KB645 µs / 92 KB

API Reference

CategoryFunctions / Methods
ConstructorsNew, MustNew, Identity, Zeros, Ones, Random
AccessorsShape, Rows, Cols, At, Set, Copy, Data, Row, Col, SubMatrix
ComparisonEquals, ApproxEquals
ArithmeticAdd, Sub, Mul, Scale, Transpose, HadamardProduct
PropertiesIsSquare, IsSymmetric, IsIdentity, IsZero, Trace, Norm, Det, Rank
TransformsREF, RREF, Inverse
DecompositionsLU, LUP, QR, Eigen, SVD
SolveSolve
PrintingString, Print, PrintWith

Roadmap

v1.0 ✅

  • Core matrix type with generics
  • Arithmetic operations
  • Determinant, rank, trace, norm
  • REF, RREF, inverse
  • LU and QR decomposition
  • Eigenvalue computation
  • Linear system solver
  • Pretty printing

v1.1 ✅

  • Epsilon-based comparison (ApproxEquals)
  • LU with permutation matrix (LUP)
  • SVD (Singular Value Decomposition)
  • Row, column, and submatrix extraction
  • Convergence error reporting for Eigen
  • Benchmark suite

v1.2 (planned)

  • Eigenvectors
  • Condition number
  • Matrix power (Pow)
  • Additional norms (1-norm, ∞-norm)
  • Kronecker product
  • Map / element-wise apply

License

MIT — see LICENSE for details.