Documentation
¶
Overview ¶
Package matrix is a pure-Go (CGO=0) reimplementation of Ruby's `matrix` standard library: Matrix and Vector with MRI-faithful behaviour.
Like MRI, arithmetic is exact wherever the input is exact. Entries flow through the Num numeric tower (Integer / Rational / Float), so Matrix#determinant of an Integer matrix stays an Integer and Matrix#inverse produces exact Rationals — `New([][]any{{1,2},{3,4}}).Inverse()` renders `Matrix[[(-2/1), (1/1)], [(3/2), (-1/2)]]`, exactly as `Matrix[[1,2],[3,4]].inverse` does under Ruby 4.0.
The formatting (ToS / Inspect), the error classes (ErrDimensionMismatch / ErrNotRegular / ErrOperationNotDefined) and the numeric promotion rules all track MRI so a binding (rbgo) can present this as the genuine `Matrix` class.
Index ¶
- Variables
- func Independent(vs ...*Vector) (bool, error)
- type Matrix
- func Build(r, c int, fn func(i, j int) any) (*Matrix, error)
- func ColumnVector(values []any) (*Matrix, error)
- func Columns(cols [][]any) (*Matrix, error)
- func Diagonal(values ...any) (*Matrix, error)
- func HStack(ms ...*Matrix) (*Matrix, error)
- func Identity(n int) *Matrix
- func New(rows [][]any) (*Matrix, error)
- func RowVector(values []any) (*Matrix, error)
- func Rows(rows [][]any) (*Matrix, error)
- func Scalar(n int, value any) (*Matrix, error)
- func VStack(ms ...*Matrix) (*Matrix, error)
- func Zero(r, c int) *Matrix
- func (m *Matrix) Add(other *Matrix) (*Matrix, error)
- func (m *Matrix) At(i, j int) (Num, bool)
- func (m *Matrix) Column(j int) (*Vector, bool)
- func (m *Matrix) ColumnCount() int
- func (m *Matrix) Determinant() (Num, error)
- func (m *Matrix) Div(other *Matrix) (*Matrix, error)
- func (m *Matrix) DivScalar(scalar any) (*Matrix, error)
- func (m *Matrix) Each(fn func(v Num))
- func (m *Matrix) EachWithIndex(fn func(v Num, i, j int))
- func (m *Matrix) Eql(other *Matrix) bool
- func (m *Matrix) FirstMinor(i, j int) (*Matrix, error)
- func (m *Matrix) Hash() uint64
- func (m *Matrix) Inspect() string
- func (m *Matrix) Inverse() (*Matrix, error)
- func (m *Matrix) IsDiagonal() bool
- func (m *Matrix) IsZero() bool
- func (m *Matrix) LowerTriangular() bool
- func (m *Matrix) Minor(r0, r1, c0, c1 int) (*Matrix, error)
- func (m *Matrix) Mul(other *Matrix) (*Matrix, error)
- func (m *Matrix) MulScalar(scalar any) (*Matrix, error)
- func (m *Matrix) MulVector(v *Vector) (*Vector, error)
- func (m *Matrix) Neg() *Matrix
- func (m *Matrix) Orthogonal() (bool, error)
- func (m *Matrix) Pow(p int) (*Matrix, error)
- func (m *Matrix) Rank() int
- func (m *Matrix) Regular() (bool, error)
- func (m *Matrix) RoundEntries(ndigits int) *Matrix
- func (m *Matrix) Row(i int) (*Vector, bool)
- func (m *Matrix) RowCount() int
- func (m *Matrix) Singular() (bool, error)
- func (m *Matrix) Square() bool
- func (m *Matrix) Sub(other *Matrix) (*Matrix, error)
- func (m *Matrix) Symmetric() bool
- func (m *Matrix) ToA() [][]Num
- func (m *Matrix) ToS() string
- func (m *Matrix) Trace() (Num, error)
- func (m *Matrix) Transpose() *Matrix
- func (m *Matrix) UpperTriangular() bool
- type Num
- func (a Num) Add(b Num) Num
- func (a Num) Div(b Num) Num
- func (a Num) Eql(b Num) bool
- func (a Num) IsZero() bool
- func (a Num) Mul(b Num) Num
- func (a Num) Neg() Num
- func (a Num) Quo(b Num) Num
- func (a Num) Round(ndigits int) Num
- func (a Num) Sqrt() Num
- func (a Num) String() string
- func (a Num) Sub(b Num) Num
- type Vector
- func (v *Vector) Add(other *Vector) (*Vector, error)
- func (v *Vector) Angle(other *Vector) (Num, error)
- func (v *Vector) At(i int) (Num, bool)
- func (v *Vector) CrossProduct(other *Vector) (*Vector, error)
- func (v *Vector) Each(fn func(n Num))
- func (v *Vector) Elements() []Num
- func (v *Vector) Eql(other *Vector) bool
- func (v *Vector) InnerProduct(other *Vector) (Num, error)
- func (v *Vector) Inspect() string
- func (v *Vector) Magnitude() Num
- func (v *Vector) Map(fn func(n Num) any) (*Vector, error)
- func (v *Vector) Mul(scalar any) (*Vector, error)
- func (v *Vector) Normalize() (*Vector, error)
- func (v *Vector) Size() int
- func (v *Vector) Sub(other *Vector) (*Vector, error)
- func (v *Vector) ToS() string
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDimensionMismatch corresponds to Matrix::ErrDimensionMismatch // ("Dimension mismatch"): operands whose shapes are incompatible. ErrDimensionMismatch = errors.New("Dimension mismatch") // ErrNotRegular corresponds to Matrix::ErrNotRegular ("Not Regular // Matrix"): inverting or dividing by a singular matrix. ErrNotRegular = errors.New("Not Regular Matrix") // ErrOperationNotDefined corresponds to Matrix::ErrOperationNotDefined: an // operation that is not defined for the given operand. ErrOperationNotDefined = errors.New("operation not defined") // ErrArgument corresponds to Ruby's ArgumentError. The concrete error // carries MRI's exact message (e.g. "wrong number of arguments (1 for 0)") // and wraps this sentinel so callers can match it with errors.Is. ErrArgument = errors.New("ArgumentError") )
These mirror the exceptions Ruby's matrix library raises under ExceptionForMatrix. The messages match MRI's so a binding can surface them verbatim.
Functions ¶
func Independent ¶
Independent reports whether the given vectors are linearly independent, like `Vector.independent?(*vs)`. Vectors of differing sizes are not independent (MRI raises ErrDimensionMismatch); this returns an error for that case.
Types ¶
type Matrix ¶
type Matrix struct {
// contains filtered or unexported fields
}
Matrix is an immutable r×c matrix of Num entries, stored row-major.
func Build ¶
Build returns an r×c matrix whose (i,j) entry is fn(i,j), like `Matrix.build(r, c) { |i, j| ... }`.
func ColumnVector ¶
ColumnVector returns an n×1 matrix from the values, like `Matrix.column_vector([...])`.
func Columns ¶
Columns builds a Matrix treating each inner slice as a column, like `Matrix.columns(...)`.
func Diagonal ¶
Diagonal returns a square matrix with the given values on the diagonal and Integer zeros elsewhere, like `Matrix.diagonal(*values)`.
func HStack ¶
HStack returns the matrices joined left-to-right; all must have equal row counts, like `Matrix.hstack(*matrices)`.
func Identity ¶
Identity returns the n×n identity matrix (Integer entries), like `Matrix.identity(n)`.
func New ¶
New builds a Matrix from rows of values (each value convertible via the Num tower: int kinds, *big.Int, *big.Rat, float kinds, or Num). All rows must have the same length; an empty input yields a 0×0 matrix. It mirrors `Matrix[[...],[...]]` / `Matrix.rows`.
func Rows ¶
Rows builds a Matrix treating each inner slice as a row. It is an alias of New matching `Matrix.rows(...)`.
func Scalar ¶
Scalar returns the n×n matrix with value on the diagonal and zeros elsewhere, like `Matrix.scalar(n, value)`.
func VStack ¶
VStack returns the matrices stacked top-to-bottom; all must have equal column counts, like `Matrix.vstack(*matrices)`.
func (*Matrix) At ¶
At returns the (i,j) entry. It returns false when the indices are out of range, matching `Matrix#[]` which returns nil there.
func (*Matrix) ColumnCount ¶
ColumnCount returns the number of columns.
func (*Matrix) Determinant ¶
Determinant returns the determinant; the matrix must be square, like `Matrix#determinant` / `#det`. It uses cofactor (Laplace) expansion with only +, − and ×, so an Integer matrix yields an Integer determinant exactly as MRI does (no Rational/Float drift).
func (*Matrix) DivScalar ¶
DivScalar returns m with each entry divided by scalar, like `Matrix#/` with a scalar. Division follows Ruby's `/` operator per operand kind: Integer/Integer floors to an Integer, any Rational stays Rational, and any Float yields a Float — see Num.Div.
func (*Matrix) EachWithIndex ¶
EachWithIndex calls fn(v, i, j) for every entry in row-major order, like `Matrix#each_with_index`.
func (*Matrix) Eql ¶
Eql reports whether two matrices have the same shape and numerically equal entries, like `Matrix#==`.
func (*Matrix) FirstMinor ¶
FirstMinor returns the matrix with row i and column j removed, like `Matrix#first_minor(i, j)`.
func (*Matrix) Hash ¶
Hash returns a hash of the matrix derived from its shape and entry values, consistent with Eql, like `Matrix#hash`.
func (*Matrix) Inspect ¶
Inspect is an alias of ToS, matching that MRI's Matrix#inspect and #to_s produce the same text.
func (*Matrix) Inverse ¶
Inverse returns the inverse matrix; the matrix must be square and regular, like `Matrix#inverse` / `#inv`. It reproduces MRI's `inverse_from` algorithm step for step — Gauss-Jordan with partial pivoting on the largest absolute pivot, dividing with the exact Num.Quo — so an Integer matrix inverts to exact Rationals (`[[1,2],[3,4]].inverse` → `[[(-2/1),(1/1)],[(3/2),(-1/2)]]`) and a Float matrix reproduces MRI's exact rounding, including the same elimination order that yields values like `-1.9999999999999998`.
func (*Matrix) IsDiagonal ¶
IsDiagonal reports whether the matrix is square with zeros off the diagonal, like `Matrix#diagonal?`.
func (*Matrix) LowerTriangular ¶
LowerTriangular reports whether all entries above the diagonal are zero, like `Matrix#lower_triangular?`.
func (*Matrix) Minor ¶
Minor returns the submatrix spanning rows [r0,r1) and columns [c0,c1), like `Matrix#minor(r0...r1, c0...c1)`. Bounds are clamped to the matrix as MRI does for ranges that overshoot; an empty span yields an empty matrix.
func (*Matrix) Mul ¶
Mul returns the matrix product m·other; m.cols must equal other.rows, like `Matrix#*` between matrices.
func (*Matrix) MulScalar ¶
MulScalar returns m scaled by a single value, like `Matrix#*` with a scalar.
func (*Matrix) MulVector ¶
MulVector returns the matrix-times-column-vector product m·v, returning a Vector, like `Matrix#*` with a Vector. m.cols must equal v.Size().
func (*Matrix) Orthogonal ¶
Orthogonal reports whether the matrix is square and its transpose is its inverse (mᵀ·m == I), like `Matrix#orthogonal?`.
func (*Matrix) Pow ¶
Pow returns m raised to an integer power. Positive powers multiply m by itself; m**0 is the identity; negative powers use the inverse. The matrix must be square. Mirrors `Matrix#**`.
func (*Matrix) Rank ¶
Rank returns the rank of the matrix (the number of linearly independent rows) computed by exact Gaussian elimination over the numeric tower, like `Matrix#rank`. It works for non-square matrices.
func (*Matrix) Regular ¶
Regular reports whether the matrix is square and non-singular (invertible), like `Matrix#regular?`.
func (*Matrix) RoundEntries ¶
RoundEntries returns the matrix with every entry rounded to ndigits decimal places, like `Matrix#round(ndigits)`. Per Ruby's per-kind round semantics, ndigits <= 0 (which includes the no-arg `Matrix#round`, called as RoundEntries(0)) produces Integer entries, while ndigits >= 1 keeps each entry's kind — see Num.Round.
func (*Matrix) Singular ¶
Singular reports whether the matrix is square and has determinant zero, like `Matrix#singular?`.
func (*Matrix) Symmetric ¶
Symmetric reports whether the matrix equals its transpose, like `Matrix#symmetric?`. Non-square matrices are not symmetric.
func (*Matrix) ToS ¶
ToS renders the matrix as `Matrix[[...], [...]]`, identical to MRI's `Matrix#to_s` and `#inspect` for populated matrices. An empty matrix renders as `Matrix.empty(r, c)`.
func (*Matrix) Trace ¶
Trace returns the sum of the diagonal entries; the matrix must be square, like `Matrix#trace` / `#tr`.
func (*Matrix) UpperTriangular ¶
UpperTriangular reports whether all entries below the diagonal are zero, like `Matrix#upper_triangular?`.
type Num ¶
type Num struct {
// contains filtered or unexported fields
}
Num is one entry of a Matrix or Vector. It models the slice of Ruby's numeric tower that the `matrix` stdlib actually depends on: Integer, Rational and Float. Keeping the three kinds distinct is what lets this package reproduce MRI's exact-arithmetic output byte for byte — `Matrix[[1,2],[3,4]].inverse` must print exact Rationals like `(-2/1)`, and `det` of an Integer matrix must stay an Integer, never silently degrade to Float.
The kinds promote following Ruby's coercion rules:
- Integer op Integer → Integer (except Quo, see below)
- any Rational, no Float → Rational (stays Rational even when whole)
- any Float → Float
Quo is exact "/": Integer.quo(Integer) yields a Rational, matching how MRI's Matrix#inverse and Vector#normalize divide. Plain Ruby Integer "/" floors, but the matrix library never uses it, so Num offers only the exact Quo.
func (Num) Div ¶
Div returns a/b following Ruby's `/` operator per operand kind, as used by `Matrix#/` with a scalar. Unlike the exact Quo, this reproduces Ruby's type-directed division:
- Integer / Integer → Integer, floor division (so 3/2 == 1, -3/2 == -2);
- Integer / Rational, Rational / anything (non-Float) → Rational;
- any Float involvement → Float.
b must be non-zero (callers guard against a zero divisor).
func (Num) Eql ¶
Eql reports numeric equality across kinds, matching Ruby's == (Rational(2,1) equals the Integer 2, and 2.0 equals 2).
func (Num) Quo ¶
Quo returns the exact quotient a/b. Integer/Integer yields a Rational (Ruby's Integer#quo), mirroring how Matrix#inverse divides; Float involvement yields a Float. b must be non-zero (callers guard against a zero pivot/divisor).
func (Num) Round ¶
Round returns a rounded to ndigits decimal places, following Ruby's Integer#round / Rational#round / Float#round, which `Matrix#round` maps over the entries. Two rules drive the result kind, exactly as in MRI:
- ndigits <= 0 always yields an Integer (this includes the no-arg form, called here as Round(0)), rounding half away from zero at the 10**(-ndigits) place;
- ndigits >= 1 keeps the operand's kind: an Integer stays itself, a Rational stays a (rounded) Rational, a Float stays a (rounded) Float.
All kinds round half away from zero, matching Ruby's default rounding mode.
func (Num) Sqrt ¶
Sqrt returns the Float square root of a (always a Float, like Ruby's Integer#** with 0.5 / Math.sqrt used by Vector#magnitude).
type Vector ¶
type Vector struct {
// contains filtered or unexported fields
}
Vector is an immutable sequence of Num entries, the analogue of Ruby's Vector. Like Matrix, arithmetic is exact where the input is exact; magnitude, normalisation and angle go through Float because they involve a square root.
func NewVector ¶
NewVector builds a Vector from values (each convertible via the Num tower), like `Vector[...]` / `Vector.elements([...])`.
func (*Vector) Angle ¶
Angle returns the angle in radians between v and other (a Float), like `Vector#angle_with`. Neither vector may be zero.
func (*Vector) At ¶
At returns the i-th entry, like `Vector#[]`. The second result is false when i is out of range (Ruby returns nil there).
func (*Vector) CrossProduct ¶
CrossProduct returns the cross product with one other vector, like the binary form of `Vector#cross_product`. It mirrors MRI exactly: the receiver must have dimension at least 2, and the cross product with a single argument is only defined when the receiver is 3-dimensional. MRI implements cross_product(*vs) requiring vs.size == size-2, so for a single argument any size other than 3 is the wrong number of arguments and raises ArgumentError; a sub-2 dimension instead raises ErrOperationNotDefined, and a dimension mismatch between the two vectors raises ErrDimensionMismatch.
func (*Vector) Eql ¶
Eql reports whether two vectors have the same size and numerically equal entries, like `Vector#==`.
func (*Vector) InnerProduct ¶
InnerProduct returns the dot product v·other; sizes must match, like `Vector#inner_product` / `#dot`.
func (*Vector) Magnitude ¶
Magnitude returns the Euclidean norm √(Σ vᵢ²) as a Float, like `Vector#magnitude` / `#norm` / `#r`.
func (*Vector) Normalize ¶
Normalize returns v scaled to unit magnitude; the zero vector cannot be normalised, like `Vector#normalize`.
