public function det()
{
if (isset($this->det)) {
return $this->det;
}
if (!$this->isSquare()) {
throw new Exception\MatrixException('Not a sqaure matrix (required for determinant)');
}
$m = $this->m;
$n = $this->n;
$R = MatrixFactory::create($this->A);
/*
* 1x1 matrix
* A = [a]
*
* |A| = a
*/
if ($m === 1) {
$this->det = $R[0][0];
return $this->det;
}
/*
* 2x2 matrix
* [a b]
* A = [c d]
*
* |A| = ad - bc
*/
if ($m === 2) {
$a = $R[0][0];
$b = $R[0][1];
$c = $R[1][0];
$d = $R[1][1];
$ad = $a * $d;
$bc = $b * $c;
$this->det = $ad - $bc;
return $this->det;
}
/*
* 3x3 matrix
* [a b c]
* A = [d e f]
* [g h i]
*
* |A| = a(ei - fh) - b(di - fg) + c(dh - eg)
*/
if ($m === 3) {
$a = $R[0][0];
$b = $R[0][1];
$c = $R[0][2];
$d = $R[1][0];
$e = $R[1][1];
$f = $R[1][2];
$g = $R[2][0];
$h = $R[2][1];
$i = $R[2][2];
$ei = $e * $i;
$fh = $f * $h;
$di = $d * $i;
$fg = $f * $g;
$dh = $d * $h;
$eg = $e * $g;
$this->det = $a * ($ei - $fh) - $b * ($di - $fg) + $c * ($dh - $eg);
return $this->det;
}
/*
* nxn matrix 4x4 or larger
* Get row reduced echelon form, then compute determinant of rref.
* Then plug into formula with swaps and product of scaling factor.
* │A│ = (-1)ⁿ │rref(A)│ ∏1/k
*/
$rref⟮A⟯ = $this->rref ?? $this->rref();
$ⁿ = $this->rref_swaps;
$∏1/k = $this->rref_∏scaling_factor;
// Det(rref(A))
$│rref⟮A⟯│ = 1;
for ($i = 0; $i < $m; $i++) {
$│rref⟮A⟯│ *= $rref⟮A⟯[$i][$i];
}
// │A│ = (-1)ⁿ │rref(A)│ ∏1/k
$this->det = (-1) ** $ⁿ * ($│rref⟮A⟯│ / $∏1/k);
return $this->det;
}