RowReduce¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
RowReduce[m]
gives the row-reduced form of the matrix m.
RowReduce[m, Method -> "<name>"]
runs a specific elimination algorithm. Accepted method names:
"Automatic" — alias for "DivisionFreeRowReduction" (default)
"DivisionFreeRowReduction" — Bareiss-like fraction-free Gauss-Jordan
"OneStepRowReduction" — classical Gauss-Jordan with division per pivot
"CofactorExpansion" — identity-if-invertible via Laplace cofactor
Det[m] (singular / rectangular m falls back
to "DivisionFreeRowReduction")
Examples¶
All examples below are verified against the current Mathilda build.
In[1]:= RowReduce[{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}]
Out[1]= {{1, 0, -1}, {0, 1, 2}, {0, 0, 0}}
In[2]:= RowReduce[{{a, b, c}, {d, e, f}, {a+d, b+e, c+f}}]
Out[2]= {{1, 0, (c e)/(-b d + a e) - (b f)/(-b d + a e)}, {0, 1, -(c d)/(-b d + a e) + (a f)/(-b d + a e)}, {0, 0, 0}}
In[3]:= RowReduce[{{2, 1, 0}, {0, 3, 1}, {1, 0, 2}}, Method -> "CofactorExpansion"]
Out[3]= {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
In[4]:= RowReduce[{{a, b}, {c, d}}, Method -> "OneStepRowReduction"]
Out[4]= {{1, 0}, {0, 1}}
Implementation notes¶
Algorithm. builtin_rowreduce reduces m to reduced row-echelon form, dispatching on an optional Method option (matsol_parse_method_option):
DivisionFreeRowReduction(the default /Automatic):rowreduce_divfree, a Bareiss-like fraction-free Gauss-Jordan. Per pivot column it picks the first structurally non-zero pivot (is_zero_poly), eliminates every other row with the Bareiss updateM[i,j] ← (pivot·M[i,j] − M[i,c]·M[r,j]) / PwherePis the previous pivot and the division is exact (exact_div_wrapper), keeping all intermediates polynomial/integer with no GCD blow-up. A final pass scales each pivot row to a leading 1, reducing each entry by itsPolynomialGCDwith the leading coefficient andexpand-ing.OneStepRowReduction:rowreduce_onestep, textbook Gauss-Jordan — normalise the pivot row by dividing by the pivot (matsol_div_entry, which prefers exact division and canonicalises withTogether), then subtract multiples from every other row. Result is already RREF.CofactorExpansion:rowreduce_cofactorreturns identity-if-invertible for a non-singular square matrix, otherwise warns (RowReduce::cofnsq) and falls back to the fraction-free path.
Data structures. A flat row-major Expr** of size m·n; all arithmetic (Times, Plus, Power, PolynomialGCD, Together) is driven through the evaluator via eval_and_free, so integer, rational, complex, and free-symbolic matrices share one code path. Pivot detection is purely structural (is_zero_poly), so a Real cancellation of magnitude ~1e-18 is not treated as zero. Bad Method values emit RowReduce::method and leave the call unevaluated.
Protected.- Uses fraction-free division logic to perform exact algorithmic reduction across numerical, rational, and symbolics expressions natively avoiding division errors.
- Lives in
src/linalg/linsolve.c; the helper primitives (Laplace cofactor determinant, exact polynomial division, tensor flatten / dimensions) are exposed fromsrc/linalg/util.candsrc/linalg/det.c. - Accepts an optional
Method -> "<name>"argument: Method -> AutomaticorMethod -> "Automatic"(default) — alias for"DivisionFreeRowReduction".Method -> "DivisionFreeRowReduction"— Bareiss-like fraction-free Gauss-Jordan. Best for exact integer / rational / symbolic input — never produces a denominator larger than necessary.Method -> "OneStepRowReduction"— classical Gauss-Jordan with one division per pivot per element. Each entry is canonicalised viaTogetherso symbolic cancellations are still detected. Fast on numeric matrices.Method -> "CofactorExpansion"— for a non-singular square matrix, returns the identity (verified viaDet[m] != 0computed by Laplace cofactor expansion). On singular or rectangular input, falls back to"DivisionFreeRowReduction"and emitsRowReduce::cofnsq.- Unknown method names emit
RowReduce::methodand the call remains unevaluated.
Attributes: Protected.
Implementation status¶
Stable — documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
References¶
- E. H. Bareiss, "Sylvester's Identity and Multistep Integer-Preserving Gaussian Elimination", Math. Comp. 22 (1968).
- Source:
src/linalg/linsolve.c - Specification:
docs/spec/builtins/linear-algebra.md
Notes & additional examples¶
Worked examples¶
A 4x4 Vandermonde matrix is nonsingular, so it reduces to the identity:
In[1]:= RowReduce[{{1, 1, 1, 1}, {1, 2, 4, 8}, {1, 3, 9, 27}, {1, 4, 16, 64}}]
Out[1]= {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}
Reducing an augmented matrix [A | b] reads off the unique solution of A x = b
in the last column:
In[1]:= RowReduce[{{2, 1, -1, 8}, {-3, -1, 2, -11}, {-2, 1, 2, -3}}]
Out[1]= {{1, 0, 0, 2}, {0, 1, 0, 3}, {0, 0, 1, -1}}
A symbolic 2x2 matrix reduces to the identity, certifying generic invertibility:
Notes¶
RowReduce[m] returns the reduced row-echelon form of m. The default method is
a Bareiss-like fraction-free Gauss-Jordan elimination ("DivisionFreeRowReduction"),
which avoids intermediate-coefficient swell; pass Method -> "OneStepRowReduction"
for classical division-per-pivot, or Method -> "CofactorExpansion" to certify
invertibility via the determinant. The pivot columns of the result identify a basis
for the row space, and a zero bottom row (as in the 3x3 magic-style example) signals
linear dependence.