#![allow(non_snake_case)]
#![allow(clippy::too_many_lines)]
use ndarray::{prelude::*, ScalarOperand, Zip};
use num_traits::{Float, One, Zero};
use std::{
fmt::Debug,
iter::Sum,
ops::{AddAssign, Mul, Neg, Sub},
};
pub trait Inverse<T: Float> {
fn det(&self) -> T;
fn inv(&self) -> Option<Self>
where
Self: Sized;
fn inv_diag(&self) -> Option<Self>
where
Self: Sized;
fn lu_inv(&self) -> Option<Self>
where
Self: Sized;
fn inv_lt(&self) -> Option<Self>
where
Self: Sized;
fn inv_ut(&self) -> Option<Self>
where
Self: Sized;
#[allow(clippy::return_self_not_must_use)]
fn cholesky(&self) -> Self
where
Self: Sized;
fn lu(&self) -> Option<(Self, Self, Self)>
where
Self: Sized;
}
impl<T> Inverse<T> for Array2<T>
where
T: Float + Debug + ScalarOperand + Sum<T> + AddAssign,
{
fn det(&self) -> T {
let s = self.raw_dim();
assert!(s[0] == s[1]);
let vm: Vec<T> = self.iter().copied().collect();
determinant(&vm, s[0])
}
fn inv(&self) -> Option<Self> {
fn submat<T: Float>(res: &mut [T], m: &Array2<T>, sr: usize, sc: usize) {
let s = m.raw_dim();
let mut i: usize = 0;
(0..s[0]).for_each(|r| {
(0..s[1]).for_each(|c| {
if r != sr && c != sc {
res[i] = m[(r, c)];
i += 1;
}
});
});
}
let s = self.raw_dim();
assert!(s[0] == s[1]);
let l = s[0];
let det = match l {
2..=4 => {
let d = self.det();
if d.is_zero() {
return None;
}
d
}
_ => T::zero(),
};
match l {
1 => Some(array![[self[(0, 0)].recip()]]),
2 => Some(array![
[self[(1, 1)] / det, -self[(0, 1)] / det],
[-self[(1, 0)] / det, self[(0, 0)] / det],
]),
3 => {
let m00 = self[(0, 0)];
let m01 = self[(0, 1)];
let m02 = self[(0, 2)];
let m10 = self[(1, 0)];
let m11 = self[(1, 1)];
let m12 = self[(1, 2)];
let m20 = self[(2, 0)];
let m21 = self[(2, 1)];
let m22 = self[(2, 2)];
let x00 = m11 * m22 - m21 * m12;
let x01 = m02 * m21 - m01 * m22;
let x02 = m01 * m12 - m02 * m11;
let x10 = m12 * m20 - m10 * m22;
let x11 = m00 * m22 - m02 * m20;
let x12 = m10 * m02 - m00 * m12;
let x20 = m10 * m21 - m20 * m11;
let x21 = m20 * m01 - m00 * m21;
let x22 = m00 * m11 - m10 * m01;
Some(array![
[x00 / det, x01 / det, x02 / det],
[x10 / det, x11 / det, x12 / det],
[x20 / det, x21 / det, x22 / det]
])
}
4 => {
let m00 = self[(0, 0)];
let m01 = self[(0, 1)];
let m02 = self[(0, 2)];
let m03 = self[(0, 3)];
let m10 = self[(1, 0)];
let m11 = self[(1, 1)];
let m12 = self[(1, 2)];
let m13 = self[(1, 3)];
let m20 = self[(2, 0)];
let m21 = self[(2, 1)];
let m22 = self[(2, 2)];
let m23 = self[(2, 3)];
let m30 = self[(3, 0)];
let m31 = self[(3, 1)];
let m32 = self[(3, 2)];
let m33 = self[(3, 3)];
let x00 = m11 * m22 * m33 - m11 * m32 * m23 - m12 * m21 * m33 + m12 * m31 * m23 + m13 * m21 * m32 - m13 * m31 * m22;
let x10 = -m10 * m22 * m33 + m10 * m32 * m23 + m12 * m20 * m33 - m12 * m30 * m23 - m13 * m20 * m32 + m13 * m30 * m22;
let x20 = m10 * m21 * m33 - m10 * m31 * m23 - m11 * m20 * m33 + m11 * m30 * m23 + m13 * m20 * m31 - m13 * m30 * m21;
let x30 = -m10 * m21 * m32 + m10 * m31 * m22 + m11 * m20 * m32 - m11 * m30 * m22 - m12 * m20 * m31 + m12 * m30 * m21;
let x01 = -m01 * m22 * m33 + m01 * m32 * m23 + m02 * m21 * m33 - m02 * m31 * m23 - m03 * m21 * m32 + m03 * m31 * m22;
let x11 = m00 * m22 * m33 - m00 * m32 * m23 - m02 * m20 * m33 + m02 * m30 * m23 + m03 * m20 * m32 - m03 * m30 * m22;
let x21 = -m00 * m21 * m33 + m00 * m31 * m23 + m01 * m20 * m33 - m01 * m30 * m23 - m03 * m20 * m31 + m03 * m30 * m21;
let x31 = m00 * m21 * m32 - m00 * m31 * m22 - m01 * m20 * m32 + m01 * m30 * m22 + m02 * m20 * m31 - m02 * m30 * m21;
let x02 = m01 * m12 * m33 - m01 * m32 * m13 - m02 * m11 * m33 + m02 * m31 * m13 + m03 * m11 * m32 - m03 * m31 * m12;
let x12 = -m00 * m12 * m33 + m00 * m32 * m13 + m02 * m10 * m33 - m02 * m30 * m13 - m03 * m10 * m32 + m03 * m30 * m12;
let x22 = m00 * m11 * m33 - m00 * m31 * m13 - m01 * m10 * m33 + m01 * m30 * m13 + m03 * m10 * m31 - m03 * m30 * m11;
let x03 = -m01 * m12 * m23 + m01 * m22 * m13 + m02 * m11 * m23 - m02 * m21 * m13 - m03 * m11 * m22 + m03 * m21 * m12;
let x32 = -m00 * m11 * m32 + m00 * m31 * m12 + m01 * m10 * m32 - m01 * m30 * m12 - m02 * m10 * m31 + m02 * m30 * m11;
let x13 = m00 * m12 * m23 - m00 * m22 * m13 - m02 * m10 * m23 + m02 * m20 * m13 + m03 * m10 * m22 - m03 * m20 * m12;
let x23 = -m00 * m11 * m23 + m00 * m21 * m13 + m01 * m10 * m23 - m01 * m20 * m13 - m03 * m10 * m21 + m03 * m20 * m11;
let x33 = m00 * m11 * m22 - m00 * m21 * m12 - m01 * m10 * m22 + m01 * m20 * m12 + m02 * m10 * m21 - m02 * m20 * m11;
Some(array![
[x00 / det, x01 / det, x02 / det, x03 / det],
[x10 / det, x11 / det, x12 / det, x13 / det],
[x20 / det, x21 / det, x22 / det, x23 / det],
[x30 / det, x31 / det, x32 / det, x33 / det]
])
}
_ => {
if let Some(res) = self.lu_inv() {
Some(res)
} else {
let det = self.det();
if det.is_zero() {
None
} else {
let mut cofactors: Array2<T> = Array2::zeros((l, l));
let mut res: Vec<T> = vec![T::zero(); (l - 1) * (l - 1)];
for r in 0..l {
for c in 0..l {
submat(&mut res, self, r, c);
let d = determinant(&res, l - 1);
cofactors[(c, r)] = if ((r + c) % 2) == 0 { d } else { -d };
}
}
Some(cofactors / det)
}
}
}
}
}
fn inv_diag(&self) -> Option<Self> {
let s = self.raw_dim();
assert!(s[0] == s[1]);
let mut res: Array2<T> = Array2::zeros(s);
for i in 0..s[0] {
res[(i, i)] = self[(i, i)].recip();
}
Some(res)
}
fn cholesky(&self) -> Self {
let s = self.raw_dim();
assert!(s[0] == s[1]);
let l = s[0];
let mut res: Array2<T> = Array2::zeros(s);
for i in 0..l {
for j in 0..=i {
let mut s = T::zero();
for k in 0..j {
if !res[(i, k)].is_zero() && !res[(j, k)].is_zero() {
s += res[(i, k)] * res[(j, k)];
}
}
res[(i, j)] = if i == j {
(self[(i, i)] - s).sqrt()
} else {
res[(j, j)].recip() * (self[(i, j)] - s)
};
}
}
res
}
fn lu(&self) -> Option<(Self, Self, Self)> {
fn pivot<T: Float>(A: &Array2<T>) -> Array2<T> {
let n = A.raw_dim()[0];
let mut P: Array2<T> = Array::eye(n);
for (idx, col) in A.axis_iter(Axis(1)).enumerate() {
let mut mp = idx;
for i in idx..n {
if col[mp].abs() < col[i].abs() {
mp = i;
}
}
if mp != idx {
let (l, r) = P.multi_slice_mut((s![idx, ..], s![mp, ..]));
Zip::from(l).and(r).for_each(std::mem::swap);
}
}
P
}
let d = self.raw_dim();
let n = d[0];
assert_eq!(n, d[1], "LU decomposition must take a square matrix.");
let P = pivot(self);
let pA = P.dot(self);
let mut L: Array2<T> = Array::eye(n);
let mut U: Array2<T> = Array::zeros((n, n));
for c in 0..n {
for r in 0..n {
let s = U.slice(s![0..r, c]).dot(&L.slice(s![r, 0..r]));
if s.is_nan() || s.is_infinite() {
return None;
}
let pAs = pA[[r, c]] - s;
if r < c + 1 {
U[[r, c]] = pAs;
} else {
L[[r, c]] = (pAs) / U[[c, c]];
}
}
}
Some((L, U, P))
}
fn lu_inv(&self) -> Option<Self> {
let d = self.raw_dim();
let n = d[0];
assert!(d[0] == d[1]);
if let Some((l, u, p)) = self.lu() {
let lt = linv(&l, n);
let ut = uinv(&u, n);
Some(ut.dot(<).dot(&p))
} else {
None
}
}
fn inv_lt(&self) -> Option<Self> {
let n = check_diag(self);
if n == 0 {
None
} else {
Some(linv(self, n))
}
}
fn inv_ut(&self) -> Option<Self> {
let n = check_diag(self);
if n == 0 {
None
} else {
Some(uinv(self, n))
}
}
}
fn determinant<T>(vm: &[T], l: usize) -> T
where
T: Copy + Debug + Zero + One + Mul + PartialEq + Sub<Output = T> + Neg<Output = T> + Sum<T>,
{
match l {
1 => vm[0],
2 => vm[0] * vm[3] - vm[2] * vm[1],
3 => {
let m00 = vm[0];
let m01 = vm[1];
let m02 = vm[2];
let m10 = vm[3];
let m11 = vm[4];
let m12 = vm[5];
let m20 = vm[6];
let m21 = vm[7];
let m22 = vm[8];
m00 * (m11 * m22 - m12 * m21) - m01 * (m10 * m22 - m12 * m20) + m02 * (m10 * m21 - m11 * m20)
}
4 => {
let m00 = vm[0];
let m01 = vm[1];
let m02 = vm[2];
let m03 = vm[3];
let m10 = vm[4];
let m11 = vm[5];
let m12 = vm[6];
let m13 = vm[7];
let m20 = vm[8];
let m21 = vm[9];
let m22 = vm[10];
let m23 = vm[11];
let m30 = vm[12];
let m31 = vm[13];
let m32 = vm[14];
let m33 = vm[15];
m00 * m21 * m32 * m13 - m00 * m21 * m33 * m12 - m00 * m22 * m31 * m13 + m00 * m22 * m33 * m11 + m00 * m23 * m31 * m12
- m00 * m23 * m32 * m11
- m21 * m30 * m02 * m13
+ m21 * m30 * m03 * m12
- m21 * m32 * m03 * m10
+ m21 * m33 * m02 * m10
+ m22 * m30 * m01 * m13
- m22 * m30 * m03 * m11
+ m22 * m31 * m03 * m10
- m22 * m33 * m01 * m10
- m23 * m30 * m01 * m12
+ m23 * m30 * m02 * m11
- m23 * m31 * m02 * m10
+ m23 * m32 * m01 * m10
+ m31 * m02 * m13 * m20
- m31 * m03 * m12 * m20
- m32 * m01 * m13 * m20
+ m32 * m03 * m11 * m20
+ m33 * m01 * m12 * m20
- m33 * m02 * m11 * m20
}
5 => {
let m00 = vm[0];
let m01 = vm[1];
let m02 = vm[2];
let m03 = vm[3];
let m04 = vm[4];
let m10 = vm[5];
let m11 = vm[6];
let m12 = vm[7];
let m13 = vm[8];
let m14 = vm[9];
let m20 = vm[10];
let m21 = vm[11];
let m22 = vm[12];
let m23 = vm[13];
let m24 = vm[14];
let m30 = vm[15];
let m31 = vm[16];
let m32 = vm[17];
let m33 = vm[18];
let m34 = vm[19];
let m40 = vm[20];
let m41 = vm[21];
let m42 = vm[22];
let m43 = vm[23];
let m44 = vm[24];
m00 * m11 * m22 * m33 * m44 - m00 * m11 * m22 * m34 * m43 - m00 * m11 * m23 * m32 * m44
+ m00 * m11 * m23 * m34 * m42
+ m00 * m11 * m24 * m32 * m43
- m00 * m11 * m24 * m33 * m42
- m00 * m12 * m21 * m33 * m44
+ m00 * m12 * m21 * m34 * m43
+ m00 * m12 * m23 * m31 * m44
- m00 * m12 * m23 * m34 * m41
- m00 * m12 * m24 * m31 * m43
+ m00 * m12 * m24 * m33 * m41
+ m00 * m13 * m21 * m32 * m44
- m00 * m13 * m21 * m34 * m42
- m00 * m13 * m22 * m31 * m44
+ m00 * m13 * m22 * m34 * m41
+ m00 * m13 * m24 * m31 * m42
- m00 * m13 * m24 * m32 * m41
- m00 * m14 * m21 * m32 * m43
+ m00 * m14 * m21 * m33 * m42
+ m00 * m14 * m22 * m31 * m43
- m00 * m14 * m22 * m33 * m41
- m00 * m14 * m23 * m31 * m42
+ m00 * m14 * m23 * m32 * m41
- m01 * m10 * m22 * m33 * m44
+ m01 * m10 * m22 * m34 * m43
+ m01 * m10 * m23 * m32 * m44
- m01 * m10 * m23 * m34 * m42
- m01 * m10 * m24 * m32 * m43
+ m01 * m10 * m24 * m33 * m42
+ m01 * m12 * m20 * m33 * m44
- m01 * m12 * m20 * m34 * m43
- m01 * m12 * m23 * m30 * m44
+ m01 * m12 * m23 * m34 * m40
+ m01 * m12 * m24 * m30 * m43
- m01 * m12 * m24 * m33 * m40
- m01 * m13 * m20 * m32 * m44
+ m01 * m13 * m20 * m34 * m42
+ m01 * m13 * m22 * m30 * m44
- m01 * m13 * m22 * m34 * m40
- m01 * m13 * m24 * m30 * m42
+ m01 * m13 * m24 * m32 * m40
+ m01 * m14 * m20 * m32 * m43
- m01 * m14 * m20 * m33 * m42
- m01 * m14 * m22 * m30 * m43
+ m01 * m14 * m22 * m33 * m40
+ m01 * m14 * m23 * m30 * m42
- m01 * m14 * m23 * m32 * m40
+ m02 * m10 * m21 * m33 * m44
- m02 * m10 * m21 * m34 * m43
- m02 * m10 * m23 * m31 * m44
+ m02 * m10 * m23 * m34 * m41
+ m02 * m10 * m24 * m31 * m43
- m02 * m10 * m24 * m33 * m41
- m02 * m11 * m20 * m33 * m44
+ m02 * m11 * m20 * m34 * m43
+ m02 * m11 * m23 * m30 * m44
- m02 * m11 * m23 * m34 * m40
- m02 * m11 * m24 * m30 * m43
+ m02 * m11 * m24 * m33 * m40
+ m02 * m13 * m20 * m31 * m44
- m02 * m13 * m20 * m34 * m41
- m02 * m13 * m21 * m30 * m44
+ m02 * m13 * m21 * m34 * m40
+ m02 * m13 * m24 * m30 * m41
- m02 * m13 * m24 * m31 * m40
- m02 * m14 * m20 * m31 * m43
+ m02 * m14 * m20 * m33 * m41
+ m02 * m14 * m21 * m30 * m43
- m02 * m14 * m21 * m33 * m40
- m02 * m14 * m23 * m30 * m41
+ m02 * m14 * m23 * m31 * m40
- m03 * m10 * m21 * m32 * m44
+ m03 * m10 * m21 * m34 * m42
+ m03 * m10 * m22 * m31 * m44
- m03 * m10 * m22 * m34 * m41
- m03 * m10 * m24 * m31 * m42
+ m03 * m10 * m24 * m32 * m41
+ m03 * m11 * m20 * m32 * m44
- m03 * m11 * m20 * m34 * m42
- m03 * m11 * m22 * m30 * m44
+ m03 * m11 * m22 * m34 * m40
+ m03 * m11 * m24 * m30 * m42
- m03 * m11 * m24 * m32 * m40
- m03 * m12 * m20 * m31 * m44
+ m03 * m12 * m20 * m34 * m41
+ m03 * m12 * m21 * m30 * m44
- m03 * m12 * m21 * m34 * m40
- m03 * m12 * m24 * m30 * m41
+ m03 * m12 * m24 * m31 * m40
+ m03 * m14 * m20 * m31 * m42
- m03 * m14 * m20 * m32 * m41
- m03 * m14 * m21 * m30 * m42
+ m03 * m14 * m21 * m32 * m40
+ m03 * m14 * m22 * m30 * m41
- m03 * m14 * m22 * m31 * m40
+ m04 * m10 * m21 * m32 * m43
- m04 * m10 * m21 * m33 * m42
- m04 * m10 * m22 * m31 * m43
+ m04 * m10 * m22 * m33 * m41
+ m04 * m10 * m23 * m31 * m42
- m04 * m10 * m23 * m32 * m41
- m04 * m11 * m20 * m32 * m43
+ m04 * m11 * m20 * m33 * m42
+ m04 * m11 * m22 * m30 * m43
- m04 * m11 * m22 * m33 * m40
- m04 * m11 * m23 * m30 * m42
+ m04 * m11 * m23 * m32 * m40
+ m04 * m12 * m20 * m31 * m43
- m04 * m12 * m20 * m33 * m41
- m04 * m12 * m21 * m30 * m43
+ m04 * m12 * m21 * m33 * m40
+ m04 * m12 * m23 * m30 * m41
- m04 * m12 * m23 * m31 * m40
- m04 * m13 * m20 * m31 * m42
+ m04 * m13 * m20 * m32 * m41
+ m04 * m13 * m21 * m30 * m42
- m04 * m13 * m21 * m32 * m40
- m04 * m13 * m22 * m30 * m41
+ m04 * m13 * m22 * m31 * m40
}
6 => {
let m00 = vm[0];
let m01 = vm[1];
let m02 = vm[2];
let m03 = vm[3];
let m04 = vm[4];
let m05 = vm[5];
let m10 = vm[6];
let m11 = vm[7];
let m12 = vm[8];
let m13 = vm[9];
let m14 = vm[10];
let m15 = vm[11];
let m20 = vm[12];
let m21 = vm[13];
let m22 = vm[14];
let m23 = vm[15];
let m24 = vm[16];
let m25 = vm[17];
let m30 = vm[18];
let m31 = vm[19];
let m32 = vm[20];
let m33 = vm[21];
let m34 = vm[22];
let m35 = vm[23];
let m40 = vm[24];
let m41 = vm[25];
let m42 = vm[26];
let m43 = vm[27];
let m44 = vm[28];
let m45 = vm[29];
let m50 = vm[30];
let m51 = vm[31];
let m52 = vm[32];
let m53 = vm[33];
let m54 = vm[34];
let m55 = vm[35];
m00 * m11 * m22 * m33 * m44 * m55 - m00 * m11 * m22 * m33 * m45 * m54 - m00 * m11 * m22 * m34 * m43 * m55
+ m00 * m11 * m22 * m34 * m45 * m53
+ m00 * m11 * m22 * m35 * m43 * m54
- m00 * m11 * m22 * m35 * m44 * m53
- m00 * m11 * m23 * m32 * m44 * m55
+ m00 * m11 * m23 * m32 * m45 * m54
+ m00 * m11 * m23 * m34 * m42 * m55
- m00 * m11 * m23 * m34 * m45 * m52
- m00 * m11 * m23 * m35 * m42 * m54
+ m00 * m11 * m23 * m35 * m44 * m52
+ m00 * m11 * m24 * m32 * m43 * m55
- m00 * m11 * m24 * m32 * m45 * m53
- m00 * m11 * m24 * m33 * m42 * m55
+ m00 * m11 * m24 * m33 * m45 * m52
+ m00 * m11 * m24 * m35 * m42 * m53
- m00 * m11 * m24 * m35 * m43 * m52
- m00 * m11 * m25 * m32 * m43 * m54
+ m00 * m11 * m25 * m32 * m44 * m53
+ m00 * m11 * m25 * m33 * m42 * m54
- m00 * m11 * m25 * m33 * m44 * m52
- m00 * m11 * m25 * m34 * m42 * m53
+ m00 * m11 * m25 * m34 * m43 * m52
- m00 * m12 * m21 * m33 * m44 * m55
+ m00 * m12 * m21 * m33 * m45 * m54
+ m00 * m12 * m21 * m34 * m43 * m55
- m00 * m12 * m21 * m34 * m45 * m53
- m00 * m12 * m21 * m35 * m43 * m54
+ m00 * m12 * m21 * m35 * m44 * m53
+ m00 * m12 * m23 * m31 * m44 * m55
- m00 * m12 * m23 * m31 * m45 * m54
- m00 * m12 * m23 * m34 * m41 * m55
+ m00 * m12 * m23 * m34 * m45 * m51
+ m00 * m12 * m23 * m35 * m41 * m54
- m00 * m12 * m23 * m35 * m44 * m51
- m00 * m12 * m24 * m31 * m43 * m55
+ m00 * m12 * m24 * m31 * m45 * m53
+ m00 * m12 * m24 * m33 * m41 * m55
- m00 * m12 * m24 * m33 * m45 * m51
- m00 * m12 * m24 * m35 * m41 * m53
+ m00 * m12 * m24 * m35 * m43 * m51
+ m00 * m12 * m25 * m31 * m43 * m54
- m00 * m12 * m25 * m31 * m44 * m53
- m00 * m12 * m25 * m33 * m41 * m54
+ m00 * m12 * m25 * m33 * m44 * m51
+ m00 * m12 * m25 * m34 * m41 * m53
- m00 * m12 * m25 * m34 * m43 * m51
+ m00 * m13 * m21 * m32 * m44 * m55
- m00 * m13 * m21 * m32 * m45 * m54
- m00 * m13 * m21 * m34 * m42 * m55
+ m00 * m13 * m21 * m34 * m45 * m52
+ m00 * m13 * m21 * m35 * m42 * m54
- m00 * m13 * m21 * m35 * m44 * m52
- m00 * m13 * m22 * m31 * m44 * m55
+ m00 * m13 * m22 * m31 * m45 * m54
+ m00 * m13 * m22 * m34 * m41 * m55
- m00 * m13 * m22 * m34 * m45 * m51
- m00 * m13 * m22 * m35 * m41 * m54
+ m00 * m13 * m22 * m35 * m44 * m51
+ m00 * m13 * m24 * m31 * m42 * m55
- m00 * m13 * m24 * m31 * m45 * m52
- m00 * m13 * m24 * m32 * m41 * m55
+ m00 * m13 * m24 * m32 * m45 * m51
+ m00 * m13 * m24 * m35 * m41 * m52
- m00 * m13 * m24 * m35 * m42 * m51
- m00 * m13 * m25 * m31 * m42 * m54
+ m00 * m13 * m25 * m31 * m44 * m52
+ m00 * m13 * m25 * m32 * m41 * m54
- m00 * m13 * m25 * m32 * m44 * m51
- m00 * m13 * m25 * m34 * m41 * m52
+ m00 * m13 * m25 * m34 * m42 * m51
- m00 * m14 * m21 * m32 * m43 * m55
+ m00 * m14 * m21 * m32 * m45 * m53
+ m00 * m14 * m21 * m33 * m42 * m55
- m00 * m14 * m21 * m33 * m45 * m52
- m00 * m14 * m21 * m35 * m42 * m53
+ m00 * m14 * m21 * m35 * m43 * m52
+ m00 * m14 * m22 * m31 * m43 * m55
- m00 * m14 * m22 * m31 * m45 * m53
- m00 * m14 * m22 * m33 * m41 * m55
+ m00 * m14 * m22 * m33 * m45 * m51
+ m00 * m14 * m22 * m35 * m41 * m53
- m00 * m14 * m22 * m35 * m43 * m51
- m00 * m14 * m23 * m31 * m42 * m55
+ m00 * m14 * m23 * m31 * m45 * m52
+ m00 * m14 * m23 * m32 * m41 * m55
- m00 * m14 * m23 * m32 * m45 * m51
- m00 * m14 * m23 * m35 * m41 * m52
+ m00 * m14 * m23 * m35 * m42 * m51
+ m00 * m14 * m25 * m31 * m42 * m53
- m00 * m14 * m25 * m31 * m43 * m52
- m00 * m14 * m25 * m32 * m41 * m53
+ m00 * m14 * m25 * m32 * m43 * m51
+ m00 * m14 * m25 * m33 * m41 * m52
- m00 * m14 * m25 * m33 * m42 * m51
+ m00 * m15 * m21 * m32 * m43 * m54
- m00 * m15 * m21 * m32 * m44 * m53
- m00 * m15 * m21 * m33 * m42 * m54
+ m00 * m15 * m21 * m33 * m44 * m52
+ m00 * m15 * m21 * m34 * m42 * m53
- m00 * m15 * m21 * m34 * m43 * m52
- m00 * m15 * m22 * m31 * m43 * m54
+ m00 * m15 * m22 * m31 * m44 * m53
+ m00 * m15 * m22 * m33 * m41 * m54
- m00 * m15 * m22 * m33 * m44 * m51
- m00 * m15 * m22 * m34 * m41 * m53
+ m00 * m15 * m22 * m34 * m43 * m51
+ m00 * m15 * m23 * m31 * m42 * m54
- m00 * m15 * m23 * m31 * m44 * m52
- m00 * m15 * m23 * m32 * m41 * m54
+ m00 * m15 * m23 * m32 * m44 * m51
+ m00 * m15 * m23 * m34 * m41 * m52
- m00 * m15 * m23 * m34 * m42 * m51
- m00 * m15 * m24 * m31 * m42 * m53
+ m00 * m15 * m24 * m31 * m43 * m52
+ m00 * m15 * m24 * m32 * m41 * m53
- m00 * m15 * m24 * m32 * m43 * m51
- m00 * m15 * m24 * m33 * m41 * m52
+ m00 * m15 * m24 * m33 * m42 * m51
- m01 * m10 * m22 * m33 * m44 * m55
+ m01 * m10 * m22 * m33 * m45 * m54
+ m01 * m10 * m22 * m34 * m43 * m55
- m01 * m10 * m22 * m34 * m45 * m53
- m01 * m10 * m22 * m35 * m43 * m54
+ m01 * m10 * m22 * m35 * m44 * m53
+ m01 * m10 * m23 * m32 * m44 * m55
- m01 * m10 * m23 * m32 * m45 * m54
- m01 * m10 * m23 * m34 * m42 * m55
+ m01 * m10 * m23 * m34 * m45 * m52
+ m01 * m10 * m23 * m35 * m42 * m54
- m01 * m10 * m23 * m35 * m44 * m52
- m01 * m10 * m24 * m32 * m43 * m55
+ m01 * m10 * m24 * m32 * m45 * m53
+ m01 * m10 * m24 * m33 * m42 * m55
- m01 * m10 * m24 * m33 * m45 * m52
- m01 * m10 * m24 * m35 * m42 * m53
+ m01 * m10 * m24 * m35 * m43 * m52
+ m01 * m10 * m25 * m32 * m43 * m54
- m01 * m10 * m25 * m32 * m44 * m53
- m01 * m10 * m25 * m33 * m42 * m54
+ m01 * m10 * m25 * m33 * m44 * m52
+ m01 * m10 * m25 * m34 * m42 * m53
- m01 * m10 * m25 * m34 * m43 * m52
+ m01 * m12 * m20 * m33 * m44 * m55
- m01 * m12 * m20 * m33 * m45 * m54
- m01 * m12 * m20 * m34 * m43 * m55
+ m01 * m12 * m20 * m34 * m45 * m53
+ m01 * m12 * m20 * m35 * m43 * m54
- m01 * m12 * m20 * m35 * m44 * m53
- m01 * m12 * m23 * m30 * m44 * m55
+ m01 * m12 * m23 * m30 * m45 * m54
+ m01 * m12 * m23 * m34 * m40 * m55
- m01 * m12 * m23 * m34 * m45 * m50
- m01 * m12 * m23 * m35 * m40 * m54
+ m01 * m12 * m23 * m35 * m44 * m50
+ m01 * m12 * m24 * m30 * m43 * m55
- m01 * m12 * m24 * m30 * m45 * m53
- m01 * m12 * m24 * m33 * m40 * m55
+ m01 * m12 * m24 * m33 * m45 * m50
+ m01 * m12 * m24 * m35 * m40 * m53
- m01 * m12 * m24 * m35 * m43 * m50
- m01 * m12 * m25 * m30 * m43 * m54
+ m01 * m12 * m25 * m30 * m44 * m53
+ m01 * m12 * m25 * m33 * m40 * m54
- m01 * m12 * m25 * m33 * m44 * m50
- m01 * m12 * m25 * m34 * m40 * m53
+ m01 * m12 * m25 * m34 * m43 * m50
- m01 * m13 * m20 * m32 * m44 * m55
+ m01 * m13 * m20 * m32 * m45 * m54
+ m01 * m13 * m20 * m34 * m42 * m55
- m01 * m13 * m20 * m34 * m45 * m52
- m01 * m13 * m20 * m35 * m42 * m54
+ m01 * m13 * m20 * m35 * m44 * m52
+ m01 * m13 * m22 * m30 * m44 * m55
- m01 * m13 * m22 * m30 * m45 * m54
- m01 * m13 * m22 * m34 * m40 * m55
+ m01 * m13 * m22 * m34 * m45 * m50
+ m01 * m13 * m22 * m35 * m40 * m54
- m01 * m13 * m22 * m35 * m44 * m50
- m01 * m13 * m24 * m30 * m42 * m55
+ m01 * m13 * m24 * m30 * m45 * m52
+ m01 * m13 * m24 * m32 * m40 * m55
- m01 * m13 * m24 * m32 * m45 * m50
- m01 * m13 * m24 * m35 * m40 * m52
+ m01 * m13 * m24 * m35 * m42 * m50
+ m01 * m13 * m25 * m30 * m42 * m54
- m01 * m13 * m25 * m30 * m44 * m52
- m01 * m13 * m25 * m32 * m40 * m54
+ m01 * m13 * m25 * m32 * m44 * m50
+ m01 * m13 * m25 * m34 * m40 * m52
- m01 * m13 * m25 * m34 * m42 * m50
+ m01 * m14 * m20 * m32 * m43 * m55
- m01 * m14 * m20 * m32 * m45 * m53
- m01 * m14 * m20 * m33 * m42 * m55
+ m01 * m14 * m20 * m33 * m45 * m52
+ m01 * m14 * m20 * m35 * m42 * m53
- m01 * m14 * m20 * m35 * m43 * m52
- m01 * m14 * m22 * m30 * m43 * m55
+ m01 * m14 * m22 * m30 * m45 * m53
+ m01 * m14 * m22 * m33 * m40 * m55
- m01 * m14 * m22 * m33 * m45 * m50
- m01 * m14 * m22 * m35 * m40 * m53
+ m01 * m14 * m22 * m35 * m43 * m50
+ m01 * m14 * m23 * m30 * m42 * m55
- m01 * m14 * m23 * m30 * m45 * m52
- m01 * m14 * m23 * m32 * m40 * m55
+ m01 * m14 * m23 * m32 * m45 * m50
+ m01 * m14 * m23 * m35 * m40 * m52
- m01 * m14 * m23 * m35 * m42 * m50
- m01 * m14 * m25 * m30 * m42 * m53
+ m01 * m14 * m25 * m30 * m43 * m52
+ m01 * m14 * m25 * m32 * m40 * m53
- m01 * m14 * m25 * m32 * m43 * m50
- m01 * m14 * m25 * m33 * m40 * m52
+ m01 * m14 * m25 * m33 * m42 * m50
- m01 * m15 * m20 * m32 * m43 * m54
+ m01 * m15 * m20 * m32 * m44 * m53
+ m01 * m15 * m20 * m33 * m42 * m54
- m01 * m15 * m20 * m33 * m44 * m52
- m01 * m15 * m20 * m34 * m42 * m53
+ m01 * m15 * m20 * m34 * m43 * m52
+ m01 * m15 * m22 * m30 * m43 * m54
- m01 * m15 * m22 * m30 * m44 * m53
- m01 * m15 * m22 * m33 * m40 * m54
+ m01 * m15 * m22 * m33 * m44 * m50
+ m01 * m15 * m22 * m34 * m40 * m53
- m01 * m15 * m22 * m34 * m43 * m50
- m01 * m15 * m23 * m30 * m42 * m54
+ m01 * m15 * m23 * m30 * m44 * m52
+ m01 * m15 * m23 * m32 * m40 * m54
- m01 * m15 * m23 * m32 * m44 * m50
- m01 * m15 * m23 * m34 * m40 * m52
+ m01 * m15 * m23 * m34 * m42 * m50
+ m01 * m15 * m24 * m30 * m42 * m53
- m01 * m15 * m24 * m30 * m43 * m52
- m01 * m15 * m24 * m32 * m40 * m53
+ m01 * m15 * m24 * m32 * m43 * m50
+ m01 * m15 * m24 * m33 * m40 * m52
- m01 * m15 * m24 * m33 * m42 * m50
+ m02 * m10 * m21 * m33 * m44 * m55
- m02 * m10 * m21 * m33 * m45 * m54
- m02 * m10 * m21 * m34 * m43 * m55
+ m02 * m10 * m21 * m34 * m45 * m53
+ m02 * m10 * m21 * m35 * m43 * m54
- m02 * m10 * m21 * m35 * m44 * m53
- m02 * m10 * m23 * m31 * m44 * m55
+ m02 * m10 * m23 * m31 * m45 * m54
+ m02 * m10 * m23 * m34 * m41 * m55
- m02 * m10 * m23 * m34 * m45 * m51
- m02 * m10 * m23 * m35 * m41 * m54
+ m02 * m10 * m23 * m35 * m44 * m51
+ m02 * m10 * m24 * m31 * m43 * m55
- m02 * m10 * m24 * m31 * m45 * m53
- m02 * m10 * m24 * m33 * m41 * m55
+ m02 * m10 * m24 * m33 * m45 * m51
+ m02 * m10 * m24 * m35 * m41 * m53
- m02 * m10 * m24 * m35 * m43 * m51
- m02 * m10 * m25 * m31 * m43 * m54
+ m02 * m10 * m25 * m31 * m44 * m53
+ m02 * m10 * m25 * m33 * m41 * m54
- m02 * m10 * m25 * m33 * m44 * m51
- m02 * m10 * m25 * m34 * m41 * m53
+ m02 * m10 * m25 * m34 * m43 * m51
- m02 * m11 * m20 * m33 * m44 * m55
+ m02 * m11 * m20 * m33 * m45 * m54
+ m02 * m11 * m20 * m34 * m43 * m55
- m02 * m11 * m20 * m34 * m45 * m53
- m02 * m11 * m20 * m35 * m43 * m54
+ m02 * m11 * m20 * m35 * m44 * m53
+ m02 * m11 * m23 * m30 * m44 * m55
- m02 * m11 * m23 * m30 * m45 * m54
- m02 * m11 * m23 * m34 * m40 * m55
+ m02 * m11 * m23 * m34 * m45 * m50
+ m02 * m11 * m23 * m35 * m40 * m54
- m02 * m11 * m23 * m35 * m44 * m50
- m02 * m11 * m24 * m30 * m43 * m55
+ m02 * m11 * m24 * m30 * m45 * m53
+ m02 * m11 * m24 * m33 * m40 * m55
- m02 * m11 * m24 * m33 * m45 * m50
- m02 * m11 * m24 * m35 * m40 * m53
+ m02 * m11 * m24 * m35 * m43 * m50
+ m02 * m11 * m25 * m30 * m43 * m54
- m02 * m11 * m25 * m30 * m44 * m53
- m02 * m11 * m25 * m33 * m40 * m54
+ m02 * m11 * m25 * m33 * m44 * m50
+ m02 * m11 * m25 * m34 * m40 * m53
- m02 * m11 * m25 * m34 * m43 * m50
+ m02 * m13 * m20 * m31 * m44 * m55
- m02 * m13 * m20 * m31 * m45 * m54
- m02 * m13 * m20 * m34 * m41 * m55
+ m02 * m13 * m20 * m34 * m45 * m51
+ m02 * m13 * m20 * m35 * m41 * m54
- m02 * m13 * m20 * m35 * m44 * m51
- m02 * m13 * m21 * m30 * m44 * m55
+ m02 * m13 * m21 * m30 * m45 * m54
+ m02 * m13 * m21 * m34 * m40 * m55
- m02 * m13 * m21 * m34 * m45 * m50
- m02 * m13 * m21 * m35 * m40 * m54
+ m02 * m13 * m21 * m35 * m44 * m50
+ m02 * m13 * m24 * m30 * m41 * m55
- m02 * m13 * m24 * m30 * m45 * m51
- m02 * m13 * m24 * m31 * m40 * m55
+ m02 * m13 * m24 * m31 * m45 * m50
+ m02 * m13 * m24 * m35 * m40 * m51
- m02 * m13 * m24 * m35 * m41 * m50
- m02 * m13 * m25 * m30 * m41 * m54
+ m02 * m13 * m25 * m30 * m44 * m51
+ m02 * m13 * m25 * m31 * m40 * m54
- m02 * m13 * m25 * m31 * m44 * m50
- m02 * m13 * m25 * m34 * m40 * m51
+ m02 * m13 * m25 * m34 * m41 * m50
- m02 * m14 * m20 * m31 * m43 * m55
+ m02 * m14 * m20 * m31 * m45 * m53
+ m02 * m14 * m20 * m33 * m41 * m55
- m02 * m14 * m20 * m33 * m45 * m51
- m02 * m14 * m20 * m35 * m41 * m53
+ m02 * m14 * m20 * m35 * m43 * m51
+ m02 * m14 * m21 * m30 * m43 * m55
- m02 * m14 * m21 * m30 * m45 * m53
- m02 * m14 * m21 * m33 * m40 * m55
+ m02 * m14 * m21 * m33 * m45 * m50
+ m02 * m14 * m21 * m35 * m40 * m53
- m02 * m14 * m21 * m35 * m43 * m50
- m02 * m14 * m23 * m30 * m41 * m55
+ m02 * m14 * m23 * m30 * m45 * m51
+ m02 * m14 * m23 * m31 * m40 * m55
- m02 * m14 * m23 * m31 * m45 * m50
- m02 * m14 * m23 * m35 * m40 * m51
+ m02 * m14 * m23 * m35 * m41 * m50
+ m02 * m14 * m25 * m30 * m41 * m53
- m02 * m14 * m25 * m30 * m43 * m51
- m02 * m14 * m25 * m31 * m40 * m53
+ m02 * m14 * m25 * m31 * m43 * m50
+ m02 * m14 * m25 * m33 * m40 * m51
- m02 * m14 * m25 * m33 * m41 * m50
+ m02 * m15 * m20 * m31 * m43 * m54
- m02 * m15 * m20 * m31 * m44 * m53
- m02 * m15 * m20 * m33 * m41 * m54
+ m02 * m15 * m20 * m33 * m44 * m51
+ m02 * m15 * m20 * m34 * m41 * m53
- m02 * m15 * m20 * m34 * m43 * m51
- m02 * m15 * m21 * m30 * m43 * m54
+ m02 * m15 * m21 * m30 * m44 * m53
+ m02 * m15 * m21 * m33 * m40 * m54
- m02 * m15 * m21 * m33 * m44 * m50
- m02 * m15 * m21 * m34 * m40 * m53
+ m02 * m15 * m21 * m34 * m43 * m50
+ m02 * m15 * m23 * m30 * m41 * m54
- m02 * m15 * m23 * m30 * m44 * m51
- m02 * m15 * m23 * m31 * m40 * m54
+ m02 * m15 * m23 * m31 * m44 * m50
+ m02 * m15 * m23 * m34 * m40 * m51
- m02 * m15 * m23 * m34 * m41 * m50
- m02 * m15 * m24 * m30 * m41 * m53
+ m02 * m15 * m24 * m30 * m43 * m51
+ m02 * m15 * m24 * m31 * m40 * m53
- m02 * m15 * m24 * m31 * m43 * m50
- m02 * m15 * m24 * m33 * m40 * m51
+ m02 * m15 * m24 * m33 * m41 * m50
- m03 * m10 * m21 * m32 * m44 * m55
+ m03 * m10 * m21 * m32 * m45 * m54
+ m03 * m10 * m21 * m34 * m42 * m55
- m03 * m10 * m21 * m34 * m45 * m52
- m03 * m10 * m21 * m35 * m42 * m54
+ m03 * m10 * m21 * m35 * m44 * m52
+ m03 * m10 * m22 * m31 * m44 * m55
- m03 * m10 * m22 * m31 * m45 * m54
- m03 * m10 * m22 * m34 * m41 * m55
+ m03 * m10 * m22 * m34 * m45 * m51
+ m03 * m10 * m22 * m35 * m41 * m54
- m03 * m10 * m22 * m35 * m44 * m51
- m03 * m10 * m24 * m31 * m42 * m55
+ m03 * m10 * m24 * m31 * m45 * m52
+ m03 * m10 * m24 * m32 * m41 * m55
- m03 * m10 * m24 * m32 * m45 * m51
- m03 * m10 * m24 * m35 * m41 * m52
+ m03 * m10 * m24 * m35 * m42 * m51
+ m03 * m10 * m25 * m31 * m42 * m54
- m03 * m10 * m25 * m31 * m44 * m52
- m03 * m10 * m25 * m32 * m41 * m54
+ m03 * m10 * m25 * m32 * m44 * m51
+ m03 * m10 * m25 * m34 * m41 * m52
- m03 * m10 * m25 * m34 * m42 * m51
+ m03 * m11 * m20 * m32 * m44 * m55
- m03 * m11 * m20 * m32 * m45 * m54
- m03 * m11 * m20 * m34 * m42 * m55
+ m03 * m11 * m20 * m34 * m45 * m52
+ m03 * m11 * m20 * m35 * m42 * m54
- m03 * m11 * m20 * m35 * m44 * m52
- m03 * m11 * m22 * m30 * m44 * m55
+ m03 * m11 * m22 * m30 * m45 * m54
+ m03 * m11 * m22 * m34 * m40 * m55
- m03 * m11 * m22 * m34 * m45 * m50
- m03 * m11 * m22 * m35 * m40 * m54
+ m03 * m11 * m22 * m35 * m44 * m50
+ m03 * m11 * m24 * m30 * m42 * m55
- m03 * m11 * m24 * m30 * m45 * m52
- m03 * m11 * m24 * m32 * m40 * m55
+ m03 * m11 * m24 * m32 * m45 * m50
+ m03 * m11 * m24 * m35 * m40 * m52
- m03 * m11 * m24 * m35 * m42 * m50
- m03 * m11 * m25 * m30 * m42 * m54
+ m03 * m11 * m25 * m30 * m44 * m52
+ m03 * m11 * m25 * m32 * m40 * m54
- m03 * m11 * m25 * m32 * m44 * m50
- m03 * m11 * m25 * m34 * m40 * m52
+ m03 * m11 * m25 * m34 * m42 * m50
- m03 * m12 * m20 * m31 * m44 * m55
+ m03 * m12 * m20 * m31 * m45 * m54
+ m03 * m12 * m20 * m34 * m41 * m55
- m03 * m12 * m20 * m34 * m45 * m51
- m03 * m12 * m20 * m35 * m41 * m54
+ m03 * m12 * m20 * m35 * m44 * m51
+ m03 * m12 * m21 * m30 * m44 * m55
- m03 * m12 * m21 * m30 * m45 * m54
- m03 * m12 * m21 * m34 * m40 * m55
+ m03 * m12 * m21 * m34 * m45 * m50
+ m03 * m12 * m21 * m35 * m40 * m54
- m03 * m12 * m21 * m35 * m44 * m50
- m03 * m12 * m24 * m30 * m41 * m55
+ m03 * m12 * m24 * m30 * m45 * m51
+ m03 * m12 * m24 * m31 * m40 * m55
- m03 * m12 * m24 * m31 * m45 * m50
- m03 * m12 * m24 * m35 * m40 * m51
+ m03 * m12 * m24 * m35 * m41 * m50
+ m03 * m12 * m25 * m30 * m41 * m54
- m03 * m12 * m25 * m30 * m44 * m51
- m03 * m12 * m25 * m31 * m40 * m54
+ m03 * m12 * m25 * m31 * m44 * m50
+ m03 * m12 * m25 * m34 * m40 * m51
- m03 * m12 * m25 * m34 * m41 * m50
+ m03 * m14 * m20 * m31 * m42 * m55
- m03 * m14 * m20 * m31 * m45 * m52
- m03 * m14 * m20 * m32 * m41 * m55
+ m03 * m14 * m20 * m32 * m45 * m51
+ m03 * m14 * m20 * m35 * m41 * m52
- m03 * m14 * m20 * m35 * m42 * m51
- m03 * m14 * m21 * m30 * m42 * m55
+ m03 * m14 * m21 * m30 * m45 * m52
+ m03 * m14 * m21 * m32 * m40 * m55
- m03 * m14 * m21 * m32 * m45 * m50
- m03 * m14 * m21 * m35 * m40 * m52
+ m03 * m14 * m21 * m35 * m42 * m50
+ m03 * m14 * m22 * m30 * m41 * m55
- m03 * m14 * m22 * m30 * m45 * m51
- m03 * m14 * m22 * m31 * m40 * m55
+ m03 * m14 * m22 * m31 * m45 * m50
+ m03 * m14 * m22 * m35 * m40 * m51
- m03 * m14 * m22 * m35 * m41 * m50
- m03 * m14 * m25 * m30 * m41 * m52
+ m03 * m14 * m25 * m30 * m42 * m51
+ m03 * m14 * m25 * m31 * m40 * m52
- m03 * m14 * m25 * m31 * m42 * m50
- m03 * m14 * m25 * m32 * m40 * m51
+ m03 * m14 * m25 * m32 * m41 * m50
- m03 * m15 * m20 * m31 * m42 * m54
+ m03 * m15 * m20 * m31 * m44 * m52
+ m03 * m15 * m20 * m32 * m41 * m54
- m03 * m15 * m20 * m32 * m44 * m51
- m03 * m15 * m20 * m34 * m41 * m52
+ m03 * m15 * m20 * m34 * m42 * m51
+ m03 * m15 * m21 * m30 * m42 * m54
- m03 * m15 * m21 * m30 * m44 * m52
- m03 * m15 * m21 * m32 * m40 * m54
+ m03 * m15 * m21 * m32 * m44 * m50
+ m03 * m15 * m21 * m34 * m40 * m52
- m03 * m15 * m21 * m34 * m42 * m50
- m03 * m15 * m22 * m30 * m41 * m54
+ m03 * m15 * m22 * m30 * m44 * m51
+ m03 * m15 * m22 * m31 * m40 * m54
- m03 * m15 * m22 * m31 * m44 * m50
- m03 * m15 * m22 * m34 * m40 * m51
+ m03 * m15 * m22 * m34 * m41 * m50
+ m03 * m15 * m24 * m30 * m41 * m52
- m03 * m15 * m24 * m30 * m42 * m51
- m03 * m15 * m24 * m31 * m40 * m52
+ m03 * m15 * m24 * m31 * m42 * m50
+ m03 * m15 * m24 * m32 * m40 * m51
- m03 * m15 * m24 * m32 * m41 * m50
+ m04 * m10 * m21 * m32 * m43 * m55
- m04 * m10 * m21 * m32 * m45 * m53
- m04 * m10 * m21 * m33 * m42 * m55
+ m04 * m10 * m21 * m33 * m45 * m52
+ m04 * m10 * m21 * m35 * m42 * m53
- m04 * m10 * m21 * m35 * m43 * m52
- m04 * m10 * m22 * m31 * m43 * m55
+ m04 * m10 * m22 * m31 * m45 * m53
+ m04 * m10 * m22 * m33 * m41 * m55
- m04 * m10 * m22 * m33 * m45 * m51
- m04 * m10 * m22 * m35 * m41 * m53
+ m04 * m10 * m22 * m35 * m43 * m51
+ m04 * m10 * m23 * m31 * m42 * m55
- m04 * m10 * m23 * m31 * m45 * m52
- m04 * m10 * m23 * m32 * m41 * m55
+ m04 * m10 * m23 * m32 * m45 * m51
+ m04 * m10 * m23 * m35 * m41 * m52
- m04 * m10 * m23 * m35 * m42 * m51
- m04 * m10 * m25 * m31 * m42 * m53
+ m04 * m10 * m25 * m31 * m43 * m52
+ m04 * m10 * m25 * m32 * m41 * m53
- m04 * m10 * m25 * m32 * m43 * m51
- m04 * m10 * m25 * m33 * m41 * m52
+ m04 * m10 * m25 * m33 * m42 * m51
- m04 * m11 * m20 * m32 * m43 * m55
+ m04 * m11 * m20 * m32 * m45 * m53
+ m04 * m11 * m20 * m33 * m42 * m55
- m04 * m11 * m20 * m33 * m45 * m52
- m04 * m11 * m20 * m35 * m42 * m53
+ m04 * m11 * m20 * m35 * m43 * m52
+ m04 * m11 * m22 * m30 * m43 * m55
- m04 * m11 * m22 * m30 * m45 * m53
- m04 * m11 * m22 * m33 * m40 * m55
+ m04 * m11 * m22 * m33 * m45 * m50
+ m04 * m11 * m22 * m35 * m40 * m53
- m04 * m11 * m22 * m35 * m43 * m50
- m04 * m11 * m23 * m30 * m42 * m55
+ m04 * m11 * m23 * m30 * m45 * m52
+ m04 * m11 * m23 * m32 * m40 * m55
- m04 * m11 * m23 * m32 * m45 * m50
- m04 * m11 * m23 * m35 * m40 * m52
+ m04 * m11 * m23 * m35 * m42 * m50
+ m04 * m11 * m25 * m30 * m42 * m53
- m04 * m11 * m25 * m30 * m43 * m52
- m04 * m11 * m25 * m32 * m40 * m53
+ m04 * m11 * m25 * m32 * m43 * m50
+ m04 * m11 * m25 * m33 * m40 * m52
- m04 * m11 * m25 * m33 * m42 * m50
+ m04 * m12 * m20 * m31 * m43 * m55
- m04 * m12 * m20 * m31 * m45 * m53
- m04 * m12 * m20 * m33 * m41 * m55
+ m04 * m12 * m20 * m33 * m45 * m51
+ m04 * m12 * m20 * m35 * m41 * m53
- m04 * m12 * m20 * m35 * m43 * m51
- m04 * m12 * m21 * m30 * m43 * m55
+ m04 * m12 * m21 * m30 * m45 * m53
+ m04 * m12 * m21 * m33 * m40 * m55
- m04 * m12 * m21 * m33 * m45 * m50
- m04 * m12 * m21 * m35 * m40 * m53
+ m04 * m12 * m21 * m35 * m43 * m50
+ m04 * m12 * m23 * m30 * m41 * m55
- m04 * m12 * m23 * m30 * m45 * m51
- m04 * m12 * m23 * m31 * m40 * m55
+ m04 * m12 * m23 * m31 * m45 * m50
+ m04 * m12 * m23 * m35 * m40 * m51
- m04 * m12 * m23 * m35 * m41 * m50
- m04 * m12 * m25 * m30 * m41 * m53
+ m04 * m12 * m25 * m30 * m43 * m51
+ m04 * m12 * m25 * m31 * m40 * m53
- m04 * m12 * m25 * m31 * m43 * m50
- m04 * m12 * m25 * m33 * m40 * m51
+ m04 * m12 * m25 * m33 * m41 * m50
- m04 * m13 * m20 * m31 * m42 * m55
+ m04 * m13 * m20 * m31 * m45 * m52
+ m04 * m13 * m20 * m32 * m41 * m55
- m04 * m13 * m20 * m32 * m45 * m51
- m04 * m13 * m20 * m35 * m41 * m52
+ m04 * m13 * m20 * m35 * m42 * m51
+ m04 * m13 * m21 * m30 * m42 * m55
- m04 * m13 * m21 * m30 * m45 * m52
- m04 * m13 * m21 * m32 * m40 * m55
+ m04 * m13 * m21 * m32 * m45 * m50
+ m04 * m13 * m21 * m35 * m40 * m52
- m04 * m13 * m21 * m35 * m42 * m50
- m04 * m13 * m22 * m30 * m41 * m55
+ m04 * m13 * m22 * m30 * m45 * m51
+ m04 * m13 * m22 * m31 * m40 * m55
- m04 * m13 * m22 * m31 * m45 * m50
- m04 * m13 * m22 * m35 * m40 * m51
+ m04 * m13 * m22 * m35 * m41 * m50
+ m04 * m13 * m25 * m30 * m41 * m52
- m04 * m13 * m25 * m30 * m42 * m51
- m04 * m13 * m25 * m31 * m40 * m52
+ m04 * m13 * m25 * m31 * m42 * m50
+ m04 * m13 * m25 * m32 * m40 * m51
- m04 * m13 * m25 * m32 * m41 * m50
+ m04 * m15 * m20 * m31 * m42 * m53
- m04 * m15 * m20 * m31 * m43 * m52
- m04 * m15 * m20 * m32 * m41 * m53
+ m04 * m15 * m20 * m32 * m43 * m51
+ m04 * m15 * m20 * m33 * m41 * m52
- m04 * m15 * m20 * m33 * m42 * m51
- m04 * m15 * m21 * m30 * m42 * m53
+ m04 * m15 * m21 * m30 * m43 * m52
+ m04 * m15 * m21 * m32 * m40 * m53
- m04 * m15 * m21 * m32 * m43 * m50
- m04 * m15 * m21 * m33 * m40 * m52
+ m04 * m15 * m21 * m33 * m42 * m50
+ m04 * m15 * m22 * m30 * m41 * m53
- m04 * m15 * m22 * m30 * m43 * m51
- m04 * m15 * m22 * m31 * m40 * m53
+ m04 * m15 * m22 * m31 * m43 * m50
+ m04 * m15 * m22 * m33 * m40 * m51
- m04 * m15 * m22 * m33 * m41 * m50
- m04 * m15 * m23 * m30 * m41 * m52
+ m04 * m15 * m23 * m30 * m42 * m51
+ m04 * m15 * m23 * m31 * m40 * m52
- m04 * m15 * m23 * m31 * m42 * m50
- m04 * m15 * m23 * m32 * m40 * m51
+ m04 * m15 * m23 * m32 * m41 * m50
- m05 * m10 * m21 * m32 * m43 * m54
+ m05 * m10 * m21 * m32 * m44 * m53
+ m05 * m10 * m21 * m33 * m42 * m54
- m05 * m10 * m21 * m33 * m44 * m52
- m05 * m10 * m21 * m34 * m42 * m53
+ m05 * m10 * m21 * m34 * m43 * m52
+ m05 * m10 * m22 * m31 * m43 * m54
- m05 * m10 * m22 * m31 * m44 * m53
- m05 * m10 * m22 * m33 * m41 * m54
+ m05 * m10 * m22 * m33 * m44 * m51
+ m05 * m10 * m22 * m34 * m41 * m53
- m05 * m10 * m22 * m34 * m43 * m51
- m05 * m10 * m23 * m31 * m42 * m54
+ m05 * m10 * m23 * m31 * m44 * m52
+ m05 * m10 * m23 * m32 * m41 * m54
- m05 * m10 * m23 * m32 * m44 * m51
- m05 * m10 * m23 * m34 * m41 * m52
+ m05 * m10 * m23 * m34 * m42 * m51
+ m05 * m10 * m24 * m31 * m42 * m53
- m05 * m10 * m24 * m31 * m43 * m52
- m05 * m10 * m24 * m32 * m41 * m53
+ m05 * m10 * m24 * m32 * m43 * m51
+ m05 * m10 * m24 * m33 * m41 * m52
- m05 * m10 * m24 * m33 * m42 * m51
+ m05 * m11 * m20 * m32 * m43 * m54
- m05 * m11 * m20 * m32 * m44 * m53
- m05 * m11 * m20 * m33 * m42 * m54
+ m05 * m11 * m20 * m33 * m44 * m52
+ m05 * m11 * m20 * m34 * m42 * m53
- m05 * m11 * m20 * m34 * m43 * m52
- m05 * m11 * m22 * m30 * m43 * m54
+ m05 * m11 * m22 * m30 * m44 * m53
+ m05 * m11 * m22 * m33 * m40 * m54
- m05 * m11 * m22 * m33 * m44 * m50
- m05 * m11 * m22 * m34 * m40 * m53
+ m05 * m11 * m22 * m34 * m43 * m50
+ m05 * m11 * m23 * m30 * m42 * m54
- m05 * m11 * m23 * m30 * m44 * m52
- m05 * m11 * m23 * m32 * m40 * m54
+ m05 * m11 * m23 * m32 * m44 * m50
+ m05 * m11 * m23 * m34 * m40 * m52
- m05 * m11 * m23 * m34 * m42 * m50
- m05 * m11 * m24 * m30 * m42 * m53
+ m05 * m11 * m24 * m30 * m43 * m52
+ m05 * m11 * m24 * m32 * m40 * m53
- m05 * m11 * m24 * m32 * m43 * m50
- m05 * m11 * m24 * m33 * m40 * m52
+ m05 * m11 * m24 * m33 * m42 * m50
- m05 * m12 * m20 * m31 * m43 * m54
+ m05 * m12 * m20 * m31 * m44 * m53
+ m05 * m12 * m20 * m33 * m41 * m54
- m05 * m12 * m20 * m33 * m44 * m51
- m05 * m12 * m20 * m34 * m41 * m53
+ m05 * m12 * m20 * m34 * m43 * m51
+ m05 * m12 * m21 * m30 * m43 * m54
- m05 * m12 * m21 * m30 * m44 * m53
- m05 * m12 * m21 * m33 * m40 * m54
+ m05 * m12 * m21 * m33 * m44 * m50
+ m05 * m12 * m21 * m34 * m40 * m53
- m05 * m12 * m21 * m34 * m43 * m50
- m05 * m12 * m23 * m30 * m41 * m54
+ m05 * m12 * m23 * m30 * m44 * m51
+ m05 * m12 * m23 * m31 * m40 * m54
- m05 * m12 * m23 * m31 * m44 * m50
- m05 * m12 * m23 * m34 * m40 * m51
+ m05 * m12 * m23 * m34 * m41 * m50
+ m05 * m12 * m24 * m30 * m41 * m53
- m05 * m12 * m24 * m30 * m43 * m51
- m05 * m12 * m24 * m31 * m40 * m53
+ m05 * m12 * m24 * m31 * m43 * m50
+ m05 * m12 * m24 * m33 * m40 * m51
- m05 * m12 * m24 * m33 * m41 * m50
+ m05 * m13 * m20 * m31 * m42 * m54
- m05 * m13 * m20 * m31 * m44 * m52
- m05 * m13 * m20 * m32 * m41 * m54
+ m05 * m13 * m20 * m32 * m44 * m51
+ m05 * m13 * m20 * m34 * m41 * m52
- m05 * m13 * m20 * m34 * m42 * m51
- m05 * m13 * m21 * m30 * m42 * m54
+ m05 * m13 * m21 * m30 * m44 * m52
+ m05 * m13 * m21 * m32 * m40 * m54
- m05 * m13 * m21 * m32 * m44 * m50
- m05 * m13 * m21 * m34 * m40 * m52
+ m05 * m13 * m21 * m34 * m42 * m50
+ m05 * m13 * m22 * m30 * m41 * m54
- m05 * m13 * m22 * m30 * m44 * m51
- m05 * m13 * m22 * m31 * m40 * m54
+ m05 * m13 * m22 * m31 * m44 * m50
+ m05 * m13 * m22 * m34 * m40 * m51
- m05 * m13 * m22 * m34 * m41 * m50
- m05 * m13 * m24 * m30 * m41 * m52
+ m05 * m13 * m24 * m30 * m42 * m51
+ m05 * m13 * m24 * m31 * m40 * m52
- m05 * m13 * m24 * m31 * m42 * m50
- m05 * m13 * m24 * m32 * m40 * m51
+ m05 * m13 * m24 * m32 * m41 * m50
- m05 * m14 * m20 * m31 * m42 * m53
+ m05 * m14 * m20 * m31 * m43 * m52
+ m05 * m14 * m20 * m32 * m41 * m53
- m05 * m14 * m20 * m32 * m43 * m51
- m05 * m14 * m20 * m33 * m41 * m52
+ m05 * m14 * m20 * m33 * m42 * m51
+ m05 * m14 * m21 * m30 * m42 * m53
- m05 * m14 * m21 * m30 * m43 * m52
- m05 * m14 * m21 * m32 * m40 * m53
+ m05 * m14 * m21 * m32 * m43 * m50
+ m05 * m14 * m21 * m33 * m40 * m52
- m05 * m14 * m21 * m33 * m42 * m50
- m05 * m14 * m22 * m30 * m41 * m53
+ m05 * m14 * m22 * m30 * m43 * m51
+ m05 * m14 * m22 * m31 * m40 * m53
- m05 * m14 * m22 * m31 * m43 * m50
- m05 * m14 * m22 * m33 * m40 * m51
+ m05 * m14 * m22 * m33 * m41 * m50
+ m05 * m14 * m23 * m30 * m41 * m52
- m05 * m14 * m23 * m30 * m42 * m51
- m05 * m14 * m23 * m31 * m40 * m52
+ m05 * m14 * m23 * m31 * m42 * m50
+ m05 * m14 * m23 * m32 * m40 * m51
- m05 * m14 * m23 * m32 * m41 * m50
}
_ =>
{
let l1 = l - 1;
let mut res: Vec<T> = vm.to_vec(); (0..l)
.map(|i| {
if vm[i].is_zero() {
T::zero()
} else {
for r in 0..l1 {
let d = r * l1;
let s = (r + 1) * l;
for c in 0..l1 {
res[d + c] = vm[s + c + usize::from(c >= i)];
}
}
let v = vm[i] * determinant(&res, l1);
if (i % 2) == 0 {
v
} else {
-v
}
}
})
.sum::<T>()
}
}
}
fn check_diag<T: Float>(m: &Array2<T>) -> usize {
let d = m.raw_dim();
assert!(d[0] == d[1]);
for i in 0..d[0] {
if m[(i, i)].is_zero() {
return 0;
}
}
d[0]
}
fn linv<T: Float>(l: &Array2<T>, n: usize) -> Array2<T> {
let mut m: Array2<T> = Array2::zeros((n, n));
for i in 0..n {
m[(i, i)] = l[(i, i)].recip();
for j in 0..i {
for k in j..i {
m[(i, j)] = m[(i, j)] + l[(i, k)] * m[(k, j)];
}
m[(i, j)] = -m[(i, j)] * m[(i, i)];
}
}
m
}
fn uinv<T: Float>(u: &Array2<T>, n: usize) -> Array2<T> {
linv(&u.t().to_owned(), n).t().to_owned()
}