Row Operations
Every row reduction algorithm — Gaussian elimination, Gauss-Jordan, LU decomposition — is built from three elementary row operations. In panchi, these are first-class objects, not implementation details.
The three operations
RowSwap — swap two rows:
from panchi.algorithms import RowSwap
import panchi as pan
m = pan.Matrix([[1, 2], [3, 4], [5, 6]])
op = RowSwap(0, 2)
print(op.apply(m))
# [[5, 6],
# [3, 4],
# [1, 2]]
RowScale — multiply a row by a non-zero scalar:
from panchi.algorithms import RowScale
op = RowScale(1, 3)
print(op.apply(m))
# [[1, 2],
# [9, 12],
# [5, 6]]
RowAdd — add a scalar multiple of one row to another:
from panchi.algorithms import RowAdd
m = pan.Matrix([[1, 2], [3, 4]])
op = RowAdd(target=1, source=0, scalar=-3)
print(op.apply(m))
# [[1, 2],
# [0, -2]]
This is the core step of Gaussian elimination: choosing a scalar that zeroes out an entry below the pivot.
Elementary matrices
Each row operation corresponds to an elementary matrix — the identity matrix with the operation applied to it. Multiplying a matrix on the left by an elementary matrix performs the row operation:
op = RowSwap(0, 1)
E = op.elementary_matrix(2)
print(E)
# [[0, 1],
# [1, 0]]
assert op.apply(m) == E @ m
This connection between row operations and matrix multiplication is a core idea in linear algebra, and panchi makes it explicit.
Inverses
Every row operation has an inverse that undoes it:
op = RowAdd(target=1, source=0, scalar=-3)
inv = op.inverse()
# RowAdd(target=1, source=0, scalar=3)
assert inv.apply(op.apply(m)) == m
Inverses are used internally when building the L matrix in LU decomposition.
String representation
Operations print in standard mathematical notation:
print(RowSwap(0, 2)) # R0 <-> R2
print(RowScale(1, 3)) # R1 -> 3 * R1
print(RowAdd(1, 0, -3)) # R1 -> R1 + (-3) * R0
This makes the step-by-step output from ref() and rref() readable without any translation.