Help us shape the future of Go! Take the 2026 Go Developer Survey

linalg

package
v0.18.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: BSD-3-Clause Imports: 10 Imported by: 0

Documentation

Overview

Package linalg is numpy.linalg for ndarray arrays, in pure Go: solving, inverting, determinants, the Cholesky, QR, singular-value and eigenvalue decompositions, least squares, pseudo-inverses, ranks, norms and condition numbers.

Every function takes arrays of any dtype and treats the last two axes as the matrix, so a (..., M, N) input is a stack of matrices processed one by one (in parallel), as numpy's gufuncs do. As in numpy, the computation is always in double precision: float64 and complex128 natively, integers and bools after promotion to float64, float32 and complex64 after widening — their results are rounded back to float32 or complex64, as numpy's are.

Decompositions follow LAPACK's algorithms (the ones numpy calls) and its sign and ordering conventions: LU with partial pivoting, Householder QR, Cholesky, Householder tridiagonalisation with implicit QL/QR for Hermitian eigenproblems, Golub–Kahan bidiagonalisation with implicit-shift QR for the SVD, and balancing, Hessenberg reduction, Francis QR and back-substitution for general eigenproblems. Large blocks are updated with the ndarray package's packed SIMD GEMM. docs/linalg.md describes the algorithms, their accuracy and their speed against numpy.

Errors: numerical failures — a singular matrix, a matrix that is not positive definite, an iteration that does not converge — wrap ErrLinAlg, numpy's LinAlgError. Operands of the wrong rank or shape give ErrShape, and invalid options ErrArgs.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrSingular      = fmt.Errorf("%w: singular matrix", ErrLinAlg)
	ErrNotPosDef     = fmt.Errorf("%w: matrix is not positive definite", ErrLinAlg)
	ErrNoConvergence = fmt.Errorf("%w: did not converge", ErrLinAlg)
)

The numerical failures, each wrapping ErrLinAlg.

View Source
var (
	Fro = Ord{/* contains filtered or unexported fields */} // the Frobenius norm
	Nuc = Ord{/* contains filtered or unexported fields */} // the nuclear norm, the sum of the singular values
)

The named matrix norms.

View Source
var ErrArgs = errors.New("linalg: invalid argument")

ErrArgs is returned for invalid options: an unknown norm order, repeated or out-of-range axes, too few arrays.

View Source
var ErrLinAlg = errors.New("linalg: LinAlgError")

ErrLinAlg is numpy's LinAlgError: the computation failed numerically. The more specific ErrSingular, ErrNotPosDef and ErrNoConvergence wrap it.

View Source
var ErrShape = errors.New("linalg: invalid shape")

ErrShape is returned for operands whose rank or shape the operation cannot take: fewer than two dimensions, a non-square matrix where a square one is needed, mismatched or non-broadcastable dimensions, or an empty matrix where numpy refuses one. (numpy raises LinAlgError for some of these and ValueError for others.)

Functions

func Cholesky

func Cholesky(a *ndarray.Array, uplo UPLO) (*ndarray.Array, error)

Cholesky is numpy.linalg.cholesky: for each Hermitian positive definite matrix A of a (..., M, M), the lower triangular L with A = L·Lᴴ (uplo Lower), or the upper triangular U with A = Uᴴ·U (uplo Upper, numpy's upper=True). Only that triangle of A is read. A matrix that is not positive definite gives ErrNotPosDef.

func Cond

func Cond(x *ndarray.Array, p Ord) (*ndarray.Array, error)

Cond is numpy.linalg.cond: the condition number of each matrix of x in the norm p. The default P2 (or the zero Ord, numpy's None) and its negative are the ratio of the extreme singular values and take any (..., M, N); the other orders (Fro, Nuc, ±1, ±Inf) are norm(x)·norm(x⁻¹) and need square matrices. A singular matrix has condition number +Inf.

func Det

func Det(a *ndarray.Array) (*ndarray.Array, error)

Det is numpy.linalg.det: the determinant of each square matrix of a (..., M, M), shaped (...). It is computed from the LU factors, with the product of the pivots accumulated as a mantissa and an exponent, so it neither overflows nor underflows before the final result does. A singular matrix has determinant 0, not an error.

func Eig

func Eig(a *ndarray.Array) (w, v *ndarray.Array, err error)

Eig is numpy.linalg.eig: the eigenvalues w (..., M) and right eigenvectors v (..., M, M), as columns, of each square matrix of a. As in numpy 2, both are always complex (complex64 for single-precision inputs). Each vector has Euclidean norm 1 and its largest component real; for a real matrix, conjugate eigenvalues have conjugate vectors. The algorithm is LAPACK geev's: balancing, Hessenberg reduction, Francis double-shift QR (single-shift for complex input), back-substitution. An input with Inf or NaN gives an error wrapping ErrLinAlg, as in numpy.

func Eigh

func Eigh(a *ndarray.Array, uplo UPLO) (w, v *ndarray.Array, err error)

Eigh is numpy.linalg.eigh: the eigenvalues, ascending, and the orthonormal eigenvectors (as columns) of each Hermitian matrix of a (..., M, M), read from the triangle uplo selects. w is (..., M) and real (float32 for single-precision inputs); v is (..., M, M) in a's precision. Eigenvectors are unique only up to a unit factor (a sign, or a phase), and within an eigenspace of a repeated eigenvalue only up to a unitary mix: compare A·v = λ·v, not the vectors themselves.

func Eigvals

func Eigvals(a *ndarray.Array) (*ndarray.Array, error)

Eigvals is numpy.linalg.eigvals: the eigenvalues of Eig only.

func Eigvalsh

func Eigvalsh(a *ndarray.Array, uplo UPLO) (*ndarray.Array, error)

Eigvalsh is numpy.linalg.eigvalsh: the eigenvalues of Eigh only, which costs a fraction of the vectors.

func Inv

func Inv(a *ndarray.Array) (*ndarray.Array, error)

Inv is numpy.linalg.inv: the inverse of each square matrix of a (..., M, M). An exactly singular matrix gives ErrSingular.

func MatrixPower

func MatrixPower(a *ndarray.Array, n int) (*ndarray.Array, error)

MatrixPower is numpy.linalg.matrix_power: each square matrix of a (..., M, M) raised to the integer power n, by repeated squaring in numpy's order. n = 0 gives identities of a's dtype; a negative n inverts first (so the result is floating point, and a singular matrix gives ErrSingular). Integer matrices stay integer for n >= 0.

func MatrixRank

func MatrixRank(a *ndarray.Array) (*ndarray.Array, error)

MatrixRank is numpy.linalg.matrix_rank(A) with its default tolerance: the number of singular values of each matrix of a greater than S.max()·max(M, N)·eps, eps being the machine epsilon of the singular values' dtype (float32's for single-precision inputs). The result is Int64, shaped like a's batch dimensions. As in numpy, an array of fewer than two dimensions has rank 1 unless all its elements are zero.

func MatrixRankTol

func MatrixRankTol(a *ndarray.Array, tol float64) (*ndarray.Array, error)

MatrixRankTol is numpy.linalg.matrix_rank(A, tol): singular values greater than the absolute threshold tol count.

func MultiDot

func MultiDot(arrays ...*ndarray.Array) (*ndarray.Array, error)

MultiDot is numpy.linalg.multi_dot: the product of two or more arrays, evaluated in the order of fewest scalar multiplications (the classic matrix-chain dynamic programme, as numpy does). The first and last arrays may be vectors — a row and a column vector — the others must be 2-D. Two vectors give a 0-d result, one gives a vector.

func Norm

func Norm(x *ndarray.Array, ord Ord, axes []int, keepdims bool) (*ndarray.Array, error)

Norm is numpy.linalg.norm(x, ord, axis, keepdims).

With axes nil: the default ord is the 2-norm of all of x flattened, whatever its rank; another ord takes x as a vector (1-D) or a matrix (2-D). With one axis, vector norms are taken along it; with two, matrix norms over them (the first indexes rows). keepdims keeps the reduced axes with length one. The result is float64, or float32 for float32 and complex64 inputs.

The sums are accumulated in double precision, and the 2-norms are rescaled when the sum of squares would overflow or underflow, so a float32 norm, or a norm of huge or tiny values, can be more accurate than numpy's (which overflows to Inf where this returns the norm).

func Pinv

func Pinv(a *ndarray.Array) (*ndarray.Array, error)

Pinv is numpy.linalg.pinv(a) with numpy's default cutoff: the Moore–Penrose pseudo-inverse (..., N, M) of each matrix of a (..., M, N), from its SVD, singular values at most 1e-15 times the largest being treated as zero.

func PinvRcond

func PinvRcond(a *ndarray.Array, rcond float64) (*ndarray.Array, error)

PinvRcond is Pinv with numpy's rcond: singular values at most rcond times the largest are treated as zero. numpy's rtol=None is PinvRcond(a, max(M, N)·eps).

func QR

func QR(a *ndarray.Array, mode QRMode) (q, r *ndarray.Array, err error)

QR is numpy.linalg.qr: the factorization A = Q·R of each matrix of a (..., M, N), Q with orthonormal columns and R upper triangular, by Householder reflections as LAPACK's geqrf computes it (R's diagonal may be negative, as in numpy). See QRMode for what is returned.

func SVD

func SVD(a *ndarray.Array, fullMatrices bool) (u, s, vh *ndarray.Array, err error)

SVD is numpy.linalg.svd: A = U·diag(S)·Vh for each matrix of a (..., M, N), the singular values S (..., K), K = min(M, N), real and decreasing. With fullMatrices U is (..., M, M) and Vh (..., N, N), as numpy's default; otherwise (..., M, K) and (..., K, N). Singular vectors are unique only up to a unit factor per pair (and a unitary mix within repeated singular values). It is Golub–Kahan bidiagonalisation followed by implicit-shift QR (LAPACK gesvd's algorithm); numpy calls gesdd, whose divide and conquer agrees to rounding.

func SVDVals

func SVDVals(a *ndarray.Array) (*ndarray.Array, error)

SVDVals is numpy.linalg.svdvals (svd with compute_uv=False): the singular values of each matrix of a, decreasing, without the vectors.

func Slogdet

func Slogdet(a *ndarray.Array) (sign, logabsdet *ndarray.Array, err error)

Slogdet is numpy.linalg.slogdet: the sign and the natural logarithm of the absolute value of the determinant of each matrix of a (..., M, M), so that det = sign·exp(logabsdet) without overflow. For a complex input sign is the complex unit det/|det|. A singular matrix has sign 0 and logabsdet -Inf. sign has a's (promoted) dtype, logabsdet the matching real dtype.

func Solve

func Solve(a, b *ndarray.Array) (*ndarray.Array, error)

Solve is numpy.linalg.solve: the solution X of A·X = B for square A.

a is (..., M, M). b is either a vector (M,), solved against every matrix of a, giving (..., M); or a stack (..., M, K), whose leading dimensions broadcast against a's, giving (..., M, K). As in numpy 2, a b of two or more dimensions is always a stack of matrices. An exactly singular matrix gives ErrSingular.

Types

type LstsqResult

type LstsqResult struct {
	// X is the least-squares solution, (N,) for a vector b and (N, K) for a
	// matrix b; the minimum-norm one when a is rank deficient.
	X *ndarray.Array
	// Residuals holds the squared Euclidean norm of each column of b - a·X,
	// (K,) — (1,) for a vector b, as in numpy — when the rank is N and
	// M > N; otherwise it is empty, (0,).
	Residuals *ndarray.Array
	// Rank is the effective rank of a.
	Rank int
	// S holds a's singular values, decreasing, (min(M, N),).
	S *ndarray.Array
}

LstsqResult is numpy.linalg.lstsq's result.

func Lstsq

func Lstsq(a, b *ndarray.Array) (LstsqResult, error)

Lstsq is numpy.linalg.lstsq(a, b) with numpy 2's default cutoff: the X minimizing ‖b - a·X‖ for an (M, N) a and a b of shape (M,) or (M, K). Singular values at most eps·max(M, N) times the largest are treated as zero (eps = 2⁻⁵²).

func LstsqRcond

func LstsqRcond(a, b *ndarray.Array, rcond float64) (LstsqResult, error)

LstsqRcond is Lstsq with numpy's rcond: singular values at most rcond times the largest are treated as zero. As in LAPACK's gelsd, which numpy calls, an rcond outside (0, 1) means the machine precision 2⁻⁵³.

type Ord

type Ord struct {
	// contains filtered or unexported fields
}

Ord is a norm order, numpy's ord argument. The zero value is numpy's None: the 2-norm of vectors and the Frobenius norm of matrices. Make a numeric order with P (P(math.Inf(1)) is numpy's inf); Fro and Nuc are numpy's 'fro' and 'nuc'.

func P

func P(p float64) Ord

P is the numeric norm order p: for vectors (Σ|x|^p)^(1/p), with 0 the count of nonzeros and ±Inf the largest and smallest |x|; for matrices ±1, ±2 and ±Inf only.

func (Ord) String

func (o Ord) String() string

type QRMode

type QRMode uint8

QRMode selects what QR returns, as numpy.linalg.qr's mode does.

const (
	// ModeReduced (numpy 'reduced', the default) returns Q (..., M, K) and
	// R (..., K, N).
	ModeReduced QRMode = iota
	// ModeComplete returns Q (..., M, M) and R (..., M, N).
	ModeComplete
	// ModeR returns only R (..., K, N); q is nil.
	ModeR
	// ModeRaw returns LAPACK's compact form, as numpy's 'raw': h
	// (..., N, M), the transpose of the factored matrix with R in its upper
	// part and the Householder vectors below, and tau (..., K).
	ModeRaw
)

The modes. With M×N matrices and K = min(M, N):

type UPLO

type UPLO uint8

UPLO selects which triangle of a Hermitian matrix is read.

const (
	Lower UPLO = iota
	Upper
)

The two triangles. Lower is numpy's default.

Jump to

Keyboard shortcuts

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