public function rref() : Matrix
{
if (isset($this->rref)) {
return $this->rref;
}
$m = $this->m;
$n = $this->n;
$R = MatrixFactory::create($this->A);
$swaps = 0;
$∏scaling_factor = 1;
$lead = 0;
for ($r = 0; $r < $m; $r++) {
if ($lead >= $n) {
break;
}
$i = $r;
while ($R[$i][$lead] == 0) {
$i++;
if ($i == $m) {
$i = $r;
$lead++;
if ($lead == $n) {
break 2;
// done; break out of outer loop and return.
}
}
}
// Swap rows i and r
if ($i !== $r) {
$R = $R->rowInterchange($i, $r);
$swaps++;
}
// Divide row $r by R[r][lead]
$lv = $R[$r][$lead];
$R = $R->rowDivide($r, $lv);
if ($lv != 0) {
$∏scaling_factor *= 1 / $lv;
}
// Subtract row r * R[r][lead] from row i
for ($i = 0; $i < $m; $i++) {
if ($i != $r) {
$R = $R->rowSubtract($r, $i, $R[$i][$lead]);
}
}
$lead++;
}
$this->rref = $R;
$this->rref_swaps = $swaps;
$this->rref_∏scaling_factor = $∏scaling_factor;
return $R;
}