matrix

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: MIT Imports: 6 Imported by: 0

README

matrix

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

Go Reference Go Report Card codecov

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 .
Operation 10×10 100×100
Mul 1.9 µs / 1.1 KB 1.6 ms / 92 KB
LU 1.6 µs / 2.3 KB 466 µs / 186 KB
QR 2.5 µs / 3.3 KB 1.2 ms / 277 KB
Solve 2.4 µs / 3.2 KB 519 µs / 195 KB
Det 1.1 µs / 1.1 KB 645 µs / 92 KB

API Reference

Category Functions / Methods
Constructors New, MustNew, Identity, Zeros, Ones, Random
Accessors Shape, Rows, Cols, At, Set, Copy, Data, Row, Col, SubMatrix
Comparison Equals, ApproxEquals
Arithmetic Add, Sub, Mul, Scale, Transpose, HadamardProduct
Properties IsSquare, IsSymmetric, IsIdentity, IsZero, Trace, Norm, Det, Rank
Transforms REF, RREF, Inverse
Decompositions LU, LUP, QR, Eigen, SVD
Solve Solve
Printing String, 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.

Documentation

Overview

Package matrix provides a clean, generic matrix type with support for common linear algebra operations — creation, arithmetic, transformations, and decompositions.

Built with Go generics, it works with int, float32, float64, complex128, and other numeric types. Zero external dependencies.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrDimensionMismatch is returned when matrix dimensions are incompatible
	// for the requested operation (e.g., adding a 2x3 to a 3x2).
	ErrDimensionMismatch = errors.New("matrix: dimension mismatch")

	// ErrNotSquare is returned when an operation requires a square matrix
	// but receives a non-square one (e.g., determinant of a 2x3).
	ErrNotSquare = errors.New("matrix: matrix must be square")

	// ErrSingular is returned when a matrix is singular (determinant ≈ 0)
	// and the operation requires a non-singular matrix.
	ErrSingular = errors.New("matrix: matrix is singular")

	// ErrNotInvertible is returned when a matrix cannot be inverted.
	// This is typically because the matrix is singular.
	ErrNotInvertible = errors.New("matrix: matrix is not invertible")

	// ErrOutOfBounds is returned when an index is outside the valid range
	// for the matrix dimensions.
	ErrOutOfBounds = errors.New("matrix: index out of bounds")

	// ErrEmptyMatrix is returned when attempting to create or operate on
	// a matrix with zero rows or zero columns.
	ErrEmptyMatrix = errors.New("matrix: empty matrix")

	// ErrNotVector is returned when an operation expects a vector (n×1 or 1×n)
	// but receives a general matrix.
	ErrNotVector = errors.New("matrix: expected a vector (n×1)")

	// ErrNotImplemented is returned for operations that are planned but not
	// yet implemented (e.g., SVD in v1).
	ErrNotImplemented = errors.New("matrix: operation not yet implemented")

	// ErrNotConverged is returned when an iterative algorithm (e.g., QR
	// eigenvalue computation) fails to converge within the maximum number
	// of iterations.
	ErrNotConverged = errors.New("matrix: algorithm did not converge")
)

Sentinel errors for matrix operations. All operations that can fail return (result, error) — never panic.

View Source
var Epsilon = 1e-9

Epsilon is the tolerance used for floating-point comparisons. Operations like singularity checks compare against this value rather than testing exact equality to zero.

Functions

This section is empty.

Types

type Float

type Float interface {
	~float32 | ~float64
}

Float is a constraint for floating-point types only. Used for operations like Random that only make sense for floats.

type Matrix

type Matrix[T Numeric] struct {
	// contains filtered or unexported fields
}

Matrix is the core generic matrix type. It stores elements in row-major order as a 2D slice. All operations return new matrices — the original is never mutated (except Set, which operates on a pointer receiver).

func Add

func Add[T Numeric](a, b *Matrix[T]) (*Matrix[T], error)

Add performs element-wise addition of two matrices. Both matrices must have the same dimensions.

Mathematically: C[i][j] = A[i][j] + B[i][j]

func HadamardProduct

func HadamardProduct[T Numeric](a, b *Matrix[T]) (*Matrix[T], error)

HadamardProduct performs element-wise multiplication of two matrices. Both matrices must have the same dimensions. Also known as the Schur product.

Mathematically: C[i][j] = A[i][j] * B[i][j]

func Identity

func Identity[T Numeric](n int) *Matrix[T]

Identity returns an n×n identity matrix (1s on the diagonal, 0s elsewhere). Panics if n <= 0.

func Mul

func Mul[T Numeric](a, b *Matrix[T]) (*Matrix[T], error)

Mul performs matrix multiplication (dot product) of two matrices. Requires a.cols == b.rows. The result has dimensions (a.rows × b.cols).

Mathematically: C[i][j] = Σ(k=0..n-1) A[i][k] * B[k][j]

Uses the naive O(n³) algorithm. Fine for small-to-medium matrices. For large matrices, consider Strassen (planned for v2).

func MustNew

func MustNew[T Numeric](data [][]T) *Matrix[T]

MustNew is like New but panics on error. Useful for test code and literals where you know the input is valid.

func New

func New[T Numeric](data [][]T) (*Matrix[T], error)

New creates a Matrix from a 2D slice. It validates that the input is rectangular (all rows have the same length) and performs a deep copy so the caller's original slice is not aliased.

Returns nil and an error if the input is empty or jagged.

func Ones

func Ones[T Numeric](rows, cols int) *Matrix[T]

Ones returns a rows×cols matrix filled with ones. Panics if rows or cols <= 0.

func Random

func Random[T Float](rows, cols int) *Matrix[T]

Random returns a rows×cols matrix filled with random float values in [0, 1). Only available for float32 and float64 types. Panics if rows or cols <= 0.

func Scale

func Scale[T Numeric](m *Matrix[T], scalar T) *Matrix[T]

Scale multiplies every element of the matrix by a scalar value. Always succeeds — returns a new matrix.

Mathematically: C[i][j] = scalar * A[i][j]

func Solve

func Solve[T Numeric](A *Matrix[T], b *Matrix[T]) (*Matrix[float64], error)

Solve solves the linear system Ax = b using LU decomposition with forward and backward substitution.

Given:

  • A is an n×n coefficient matrix
  • b is an n×1 column vector (right-hand side)

Returns x such that Ax = b.

Algorithm:

  1. Decompose PA = LU (with partial pivoting)
  2. Permute b according to P → Pb
  3. Solve Ly = Pb (forward substitution)
  4. Solve Ux = y (backward substitution)

Returns ErrNotSquare if A isn't square. Returns ErrDimensionMismatch if b doesn't have the right dimensions. Returns ErrNotVector if b isn't a column vector. Returns ErrSingular if A is singular.

func Sub

func Sub[T Numeric](a, b *Matrix[T]) (*Matrix[T], error)

Sub performs element-wise subtraction of two matrices. Both matrices must have the same dimensions.

Mathematically: C[i][j] = A[i][j] - B[i][j]

func Transpose

func Transpose[T Numeric](m *Matrix[T]) *Matrix[T]

Transpose returns the transpose of the matrix. Rows become columns and columns become rows.

Mathematically: B[j][i] = A[i][j]

Properties:

  • (Aᵀ)ᵀ = A
  • (A + B)ᵀ = Aᵀ + Bᵀ
  • (AB)ᵀ = BᵀAᵀ

func Zeros

func Zeros[T Numeric](rows, cols int) *Matrix[T]

Zeros returns a rows×cols matrix filled with zeros. Panics if rows or cols <= 0.

func (*Matrix[T]) ApproxEquals added in v1.1.0

func (m *Matrix[T]) ApproxEquals(other *Matrix[T], eps float64) bool

ApproxEquals returns true if two matrices have the same shape and all corresponding elements differ by less than eps (in absolute value).

This is essential when comparing matrices that result from floating-point arithmetic, where exact equality (Equals) would produce false negatives.

func (*Matrix[T]) At

func (m *Matrix[T]) At(i, j int) (T, error)

At returns the element at row i, column j (0-indexed). Returns an error if the indices are out of bounds.

func (*Matrix[T]) Col added in v1.1.0

func (m *Matrix[T]) Col(j int) (*Matrix[T], error)

Col returns the j-th column as a new n×1 matrix (deep copy, 0-indexed). Returns ErrOutOfBounds if j is out of range.

func (*Matrix[T]) Cols

func (m *Matrix[T]) Cols() int

Cols returns the number of columns.

func (*Matrix[T]) Copy

func (m *Matrix[T]) Copy() *Matrix[T]

Copy returns a deep copy of the matrix.

func (*Matrix[T]) Data

func (m *Matrix[T]) Data() [][]T

Data returns a deep copy of the underlying 2D slice. The returned slice is safe to modify without affecting the matrix.

func (*Matrix[T]) Det

func (m *Matrix[T]) Det() (float64, error)

Det returns the determinant of a square matrix.

The determinant is computed via LU-style Gaussian elimination with partial pivoting. The determinant equals the product of the diagonal elements of the upper triangular form, adjusted for row swaps.

Properties:

  • det(I) = 1
  • det(AB) = det(A) * det(B)
  • det(Aᵀ) = det(A)
  • det(cA) = c^n * det(A) for n×n matrix
  • A is invertible ⟺ det(A) ≠ 0

Returns ErrNotSquare if the matrix isn't square.

func (*Matrix[T]) Eigen

func (m *Matrix[T]) Eigen() ([]complex128, error)

Eigen computes the eigenvalues of a square matrix using the QR algorithm with implicit shifts.

Eigenvalues λ satisfy: Av = λv for some non-zero vector v.

The QR algorithm iteratively decomposes A = QR, then forms A' = RQ. This converges to an upper triangular (Schur) form where the diagonal entries are the eigenvalues.

For real matrices, complex eigenvalues appear as 2×2 blocks on the diagonal.

Returns eigenvalues as complex128 (real eigenvalues have zero imaginary part). Returns ErrNotSquare if the matrix isn't square. Returns ErrNotConverged if the algorithm fails to converge.

Note: eigenvector computation is planned for v1.5.

func (*Matrix[T]) Equals

func (m *Matrix[T]) Equals(other *Matrix[T]) bool

Equals returns true if two matrices have the same shape and identical elements. For floating-point types, exact equality is used — use ApproxEquals for epsilon-based comparison.

func (*Matrix[T]) Inverse

func (m *Matrix[T]) Inverse() (*Matrix[float64], error)

Inverse returns the multiplicative inverse of a square matrix using Gauss-Jordan elimination on the augmented matrix [A | I].

The inverse A⁻¹ satisfies: A * A⁻¹ = A⁻¹ * A = I

Returns ErrNotSquare if the matrix isn't square. Returns ErrNotInvertible if the matrix is singular (det ≈ 0).

func (*Matrix[T]) IsIdentity

func (m *Matrix[T]) IsIdentity() bool

IsIdentity returns true if the matrix is the identity matrix (ones on diagonal, zeros elsewhere), within Epsilon tolerance.

func (*Matrix[T]) IsSquare

func (m *Matrix[T]) IsSquare() bool

IsSquare returns true if the matrix has the same number of rows and columns.

func (*Matrix[T]) IsSymmetric

func (m *Matrix[T]) IsSymmetric() bool

IsSymmetric returns true if the matrix equals its own transpose: A = Aᵀ. For floating-point types, comparisons use the package-level Epsilon tolerance. A non-square matrix is never symmetric.

func (*Matrix[T]) IsZero

func (m *Matrix[T]) IsZero() bool

IsZero returns true if all elements are zero (within Epsilon tolerance).

func (*Matrix[T]) LU

func (m *Matrix[T]) LU() (*Matrix[float64], *Matrix[float64], error)

LU performs LU decomposition with partial pivoting.

Decomposes the matrix A into a lower triangular matrix L and an upper triangular matrix U such that PA = LU, where P is an implicit permutation matrix from row swaps.

The Doolittle algorithm is used: L has ones on its diagonal.

Uses:

  • Solving linear systems (Ax = b → LUx = b)
  • Computing determinants efficiently
  • Matrix inversion

Returns (L, U, error). Returns ErrNotSquare if the matrix isn't square. Returns ErrSingular if a zero pivot is encountered.

func (*Matrix[T]) LUP added in v1.1.0

func (m *Matrix[T]) LUP() (*Matrix[float64], *Matrix[float64], *Matrix[float64], error)

LUP performs LU decomposition with partial pivoting and also returns the permutation matrix P.

Returns (L, U, P, error) such that P*A = L*U.

P is an n×n permutation matrix built from the row-swap history. Use this when you need to verify or reconstruct the decomposition.

func (*Matrix[T]) Norm

func (m *Matrix[T]) Norm() float64

Norm returns the Frobenius norm of the matrix.

Mathematically: ‖A‖_F = √(Σ |a[i][j]|²)

The Frobenius norm is the matrix analogue of the Euclidean vector norm. It's always non-negative and equals zero only for the zero matrix.

func (*Matrix[T]) Print

func (m *Matrix[T]) Print()

Print prints the matrix to stdout with default formatting.

func (*Matrix[T]) PrintWith

func (m *Matrix[T]) PrintWith(opts PrintOptions)

PrintWith prints the matrix to stdout with custom formatting options.

func (*Matrix[T]) QR

func (m *Matrix[T]) QR() (*Matrix[float64], *Matrix[float64], error)

QR performs QR decomposition using the Modified Gram-Schmidt process.

Decomposes the matrix A into an orthogonal matrix Q and an upper triangular matrix R such that A = QR.

Q has orthonormal columns: QᵀQ = I R is upper triangular

Uses:

  • Solving least-squares problems
  • Eigenvalue computation (QR algorithm)
  • Numerical stability improvements

The modified Gram-Schmidt process is more numerically stable than the classical version.

Returns (Q, R, error). Works on any m×n matrix where m ≥ n.

func (*Matrix[T]) REF

func (m *Matrix[T]) REF() (*Matrix[float64], error)

REF returns the Row Echelon Form of the matrix using Gaussian elimination with partial pivoting.

In REF:

  • All zero rows are at the bottom
  • The leading entry (pivot) of each non-zero row is to the right of the pivot in the row above
  • All entries below a pivot are zero

The result is always float64 regardless of the input type, since row reduction inherently produces fractions.

func (*Matrix[T]) RREF

func (m *Matrix[T]) RREF() (*Matrix[float64], error)

RREF returns the Reduced Row Echelon Form of the matrix using Gauss-Jordan elimination with partial pivoting.

In RREF (extends REF with):

  • Each pivot is exactly 1
  • Each pivot is the only non-zero entry in its column

RREF is unique for any given matrix — unlike REF, which depends on the elimination order.

func (*Matrix[T]) Rank

func (m *Matrix[T]) Rank() int

Rank returns the rank of the matrix — the number of linearly independent rows (equivalently, columns).

Computed by reducing to RREF and counting non-zero rows (pivots).

Properties:

  • 0 ≤ rank(A) ≤ min(rows, cols)
  • rank(A) = rank(Aᵀ)
  • A is full rank if rank(A) = min(rows, cols)

func (*Matrix[T]) Row added in v1.1.0

func (m *Matrix[T]) Row(i int) (*Matrix[T], error)

Row returns the i-th row as a new 1×n matrix (deep copy, 0-indexed). Returns ErrOutOfBounds if i is out of range.

func (*Matrix[T]) Rows

func (m *Matrix[T]) Rows() int

Rows returns the number of rows.

func (*Matrix[T]) SVD

func (m *Matrix[T]) SVD() (*Matrix[float64], *Matrix[float64], *Matrix[float64], error)

SVD performs Singular Value Decomposition (thin SVD).

Decomposes A = U * Σ * Vᵀ where:

  • U is an m×k orthogonal matrix (left singular vectors)
  • Σ is a k×k diagonal matrix (singular values, non-negative, descending)
  • V is an n×k orthogonal matrix (right singular vectors)
  • k = min(m, n)

Algorithm: One-sided Jacobi SVD. Iteratively applies Jacobi rotations to orthogonalize the columns of A, producing V and the singular values as column norms, then normalizes to get U.

Uses:

  • Principal Component Analysis (PCA)
  • Low-rank approximation
  • Pseudoinverse computation
  • Condition number estimation

Returns (U, Σ, V, error). Returns ErrEmptyMatrix for empty inputs.

func (*Matrix[T]) Set

func (m *Matrix[T]) Set(i, j int, val T) error

Set sets the element at row i, column j (0-indexed). This is the only mutating operation — it uses a pointer receiver. Returns an error if the indices are out of bounds.

func (*Matrix[T]) Shape

func (m *Matrix[T]) Shape() (int, int)

Shape returns the number of rows and columns in the matrix.

func (*Matrix[T]) String

func (m *Matrix[T]) String() string

String implements the fmt.Stringer interface, providing a clean default representation of the matrix.

Example output for a 2×3 matrix:

[ 1.0000   2.0000   3.0000 ]
[ 4.0000   5.0000   6.0000 ]

func (*Matrix[T]) SubMatrix added in v1.1.0

func (m *Matrix[T]) SubMatrix(r0, r1, c0, c1 int) (*Matrix[T], error)

SubMatrix extracts the submatrix spanning rows [r0, r1) and columns [c0, c1). Uses half-open ranges consistent with Go slice semantics. Returns a deep copy — modifying the result does not affect the original.

Returns ErrOutOfBounds if any index is out of range or if r0 >= r1 or c0 >= c1.

func (*Matrix[T]) Trace

func (m *Matrix[T]) Trace() (T, error)

Trace returns the sum of the diagonal elements. Also known as the "spur."

Mathematically: tr(A) = Σ a[i][i] for i = 0..n-1

Properties:

  • tr(A + B) = tr(A) + tr(B)
  • tr(cA) = c * tr(A)
  • tr(AB) = tr(BA)

Returns ErrNotSquare if the matrix isn't square.

type Numeric

type Numeric interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~float32 | ~float64 |
		~complex64 | ~complex128
}

Numeric is the type constraint for all matrix element types. It supports integers, floats, and complex numbers.

type PrintOptions

type PrintOptions struct {
	// Precision is the number of decimal places for floating-point values.
	// Default: 4. Ignored for integer types.
	Precision int

	// Padding is the minimum number of spaces between columns.
	// Default: 2.
	Padding int

	// Brackets controls the bracket style for the matrix.
	// Options: "square" (default), "round", "pipe", "none".
	Brackets string
}

PrintOptions controls how a matrix is formatted when using PrintWith.

type RealNumeric

type RealNumeric interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~float32 | ~float64
}

RealNumeric is a stricter constraint for operations that require ordered comparisons or real-valued math functions (Abs, Sqrt, etc.). Complex types are excluded because they lack a natural ordering.

Directories

Path Synopsis
examples
01_basics command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL