85 lines
4.4 KiB
Go
85 lines
4.4 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Package linalg is the dense and sparse linear algebra of the library:
|
|
// the factorisations, the solvers, the eigensolvers, the matrix
|
|
// functions and the Krylov methods, over the array types the core
|
|
// provides. Every symbol here is re-exported by the root package, so
|
|
// user code may import that facade alone and write tensor.Solve.
|
|
//
|
|
// # Dense
|
|
//
|
|
// The dense surface takes a 2-D array and answers arrays. Solve, Inv
|
|
// and Det run one LU decomposition with partial pivoting; Cholesky,
|
|
// QR, LeastSquares, RRQR and the tridiagonal pair SolveTridiagonal and
|
|
// SolveCyclicTridiagonal are the other factorisations and their solves.
|
|
// Eigen, EigenComplex, EigenGeneral, EigenGeneralised, SVD, SVDComplex
|
|
// and SchurComplex are the spectral decompositions, and Pinverse,
|
|
// MatrixRank and Cond read the singular spectrum that SVD produces.
|
|
// SolveTikhonov, SolveTruncated and SolveRRQR answer a system whose
|
|
// data does not determine the solution. MatrixExp, MatrixSqrt and
|
|
// MatrixLog are the matrix functions; FitPolynomial, PolynomialRoots
|
|
// and CubicSpline carry the polynomial work; GMRES solves a system
|
|
// presented as an operator rather than as a matrix.
|
|
//
|
|
// # Sparse
|
|
//
|
|
// The sparse surface starts from a COO matrix (the root package's
|
|
// tensor.SparseCOO) and converts it once into the compressed view the
|
|
// algorithm wants: SparseCSR for the iterative solvers, the Lanczos
|
|
// eigensolver and the row-wise products, SparseCSC for the direct
|
|
// factorisations and the column-wise scatter. The direct route is
|
|
// NewSparseCholesky for a symmetric positive definite matrix, under a
|
|
// fill-reducing SparseOrdering, and NewSparseLU for a general square
|
|
// matrix; NewSparseILU builds the incomplete factorisation the Krylov
|
|
// solvers take as a preconditioner. SpSolve and SpSolveBiCGSTAB, with
|
|
// their two complex counterparts, are the iterative solves; SpLSQR and
|
|
// SpLSMR are the least-squares iterations; SpEigen, SpEigenGeneral and
|
|
// the two complex forms are the Krylov eigensolvers; SpExpApply
|
|
// applies a matrix exponential to a vector without forming the matrix.
|
|
//
|
|
// # The pipeline
|
|
//
|
|
// Pipe and Pipeline read a sequence of array transformations as one
|
|
// expression. The evaluation is eager and each step allocates a new
|
|
// array. There is no lazy graph, no autograd and no backpropagation
|
|
// here: a failed step is recorded, the steps after it become no-ops,
|
|
// and Result returns the first error alongside the array.
|
|
//
|
|
// # Conventions
|
|
//
|
|
// The dense routines compute in float64 and complex128: int and float32
|
|
// inputs promote on the way in, and one complex operand promotes the
|
|
// whole call. A sparse routine with no complex form refuses a complex
|
|
// input instead of promoting it, and the four complex entry points name
|
|
// their element type in the name: SpSolveComplexCG,
|
|
// SpSolveComplexBiCGSTAB, SpEigenComplex and SpEigenGeneralComplex.
|
|
//
|
|
// Symmetry is checked where the algorithm depends on it, within a
|
|
// scale-relative 1e-12 tolerance by Eigen, EigenComplex, SpEigen,
|
|
// SpEigenComplex, SpSolve, SpSolveComplexCG and SpExpApply. It is not
|
|
// checked where the algorithm does not need it: EigenGeneralised
|
|
// requires a symmetric a and does not verify it, and the two general
|
|
// sparse eigensolvers do not screen for non-finite entries, which come
|
|
// back as NaN Ritz pairs.
|
|
//
|
|
// A shape mismatch, a singular matrix, a rank-deficient system, a
|
|
// matrix that leaves the positive definite cone during a rank-one
|
|
// update, and a Krylov iteration that exhausts its budget with the
|
|
// tolerance unmet are all errors naming themselves. An unconverged
|
|
// iterative solve returns no estimate, never a silent approximation.
|
|
//
|
|
// Results are reproducible: the kernels that dispatch over workers
|
|
// split the output space rather than the reduction, so an element is
|
|
// computed by the same arithmetic sequence whatever the worker count.
|
|
//
|
|
// # Constructors
|
|
//
|
|
// The array type belongs to the core, and its general constructors are
|
|
// re-exported by the root package as tensor.FromFloats, tensor.Zeros,
|
|
// tensor.Identity and their neighbours. A caller that imports this
|
|
// package on its own, without the root facade, has ArrayFromFloatsSafe
|
|
// for building the input to a call: it copies the slice it is given,
|
|
// so the caller keeps ownership of the values it passed in.
|
|
package linalg
|