Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inverting a 4x4 matrix with try_inverse_mut doesn't leave self unchanged if the inversion fails. #1384

Merged
merged 8 commits into from
May 5, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
193 changes: 97 additions & 96 deletions src/linalg/inverse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,124 +145,127 @@ where
{
let m = m.as_slice();

out[(0, 0)] = m[5].clone() * m[10].clone() * m[15].clone()
let cofactor00 = m[5].clone() * m[10].clone() * m[15].clone()
- m[5].clone() * m[11].clone() * m[14].clone()
- m[9].clone() * m[6].clone() * m[15].clone()
+ m[9].clone() * m[7].clone() * m[14].clone()
+ m[13].clone() * m[6].clone() * m[11].clone()
- m[13].clone() * m[7].clone() * m[10].clone();

out[(1, 0)] = -m[1].clone() * m[10].clone() * m[15].clone()
+ m[1].clone() * m[11].clone() * m[14].clone()
+ m[9].clone() * m[2].clone() * m[15].clone()
- m[9].clone() * m[3].clone() * m[14].clone()
- m[13].clone() * m[2].clone() * m[11].clone()
+ m[13].clone() * m[3].clone() * m[10].clone();

out[(2, 0)] = m[1].clone() * m[6].clone() * m[15].clone()
- m[1].clone() * m[7].clone() * m[14].clone()
- m[5].clone() * m[2].clone() * m[15].clone()
+ m[5].clone() * m[3].clone() * m[14].clone()
+ m[13].clone() * m[2].clone() * m[7].clone()
- m[13].clone() * m[3].clone() * m[6].clone();

out[(3, 0)] = -m[1].clone() * m[6].clone() * m[11].clone()
+ m[1].clone() * m[7].clone() * m[10].clone()
+ m[5].clone() * m[2].clone() * m[11].clone()
- m[5].clone() * m[3].clone() * m[10].clone()
- m[9].clone() * m[2].clone() * m[7].clone()
+ m[9].clone() * m[3].clone() * m[6].clone();

out[(0, 1)] = -m[4].clone() * m[10].clone() * m[15].clone()
let cofactor01 = -m[4].clone() * m[10].clone() * m[15].clone()
+ m[4].clone() * m[11].clone() * m[14].clone()
+ m[8].clone() * m[6].clone() * m[15].clone()
- m[8].clone() * m[7].clone() * m[14].clone()
- m[12].clone() * m[6].clone() * m[11].clone()
+ m[12].clone() * m[7].clone() * m[10].clone();

out[(1, 1)] = m[0].clone() * m[10].clone() * m[15].clone()
- m[0].clone() * m[11].clone() * m[14].clone()
- m[8].clone() * m[2].clone() * m[15].clone()
+ m[8].clone() * m[3].clone() * m[14].clone()
+ m[12].clone() * m[2].clone() * m[11].clone()
- m[12].clone() * m[3].clone() * m[10].clone();

out[(2, 1)] = -m[0].clone() * m[6].clone() * m[15].clone()
+ m[0].clone() * m[7].clone() * m[14].clone()
+ m[4].clone() * m[2].clone() * m[15].clone()
- m[4].clone() * m[3].clone() * m[14].clone()
- m[12].clone() * m[2].clone() * m[7].clone()
+ m[12].clone() * m[3].clone() * m[6].clone();

out[(3, 1)] = m[0].clone() * m[6].clone() * m[11].clone()
- m[0].clone() * m[7].clone() * m[10].clone()
- m[4].clone() * m[2].clone() * m[11].clone()
+ m[4].clone() * m[3].clone() * m[10].clone()
+ m[8].clone() * m[2].clone() * m[7].clone()
- m[8].clone() * m[3].clone() * m[6].clone();

out[(0, 2)] = m[4].clone() * m[9].clone() * m[15].clone()
let cofactor02 = m[4].clone() * m[9].clone() * m[15].clone()
- m[4].clone() * m[11].clone() * m[13].clone()
- m[8].clone() * m[5].clone() * m[15].clone()
+ m[8].clone() * m[7].clone() * m[13].clone()
+ m[12].clone() * m[5].clone() * m[11].clone()
- m[12].clone() * m[7].clone() * m[9].clone();

out[(1, 2)] = -m[0].clone() * m[9].clone() * m[15].clone()
+ m[0].clone() * m[11].clone() * m[13].clone()
+ m[8].clone() * m[1].clone() * m[15].clone()
- m[8].clone() * m[3].clone() * m[13].clone()
- m[12].clone() * m[1].clone() * m[11].clone()
+ m[12].clone() * m[3].clone() * m[9].clone();

out[(2, 2)] = m[0].clone() * m[5].clone() * m[15].clone()
- m[0].clone() * m[7].clone() * m[13].clone()
- m[4].clone() * m[1].clone() * m[15].clone()
+ m[4].clone() * m[3].clone() * m[13].clone()
+ m[12].clone() * m[1].clone() * m[7].clone()
- m[12].clone() * m[3].clone() * m[5].clone();

out[(0, 3)] = -m[4].clone() * m[9].clone() * m[14].clone()
let cofactor03 = -m[4].clone() * m[9].clone() * m[14].clone()
+ m[4].clone() * m[10].clone() * m[13].clone()
+ m[8].clone() * m[5].clone() * m[14].clone()
- m[8].clone() * m[6].clone() * m[13].clone()
- m[12].clone() * m[5].clone() * m[10].clone()
+ m[12].clone() * m[6].clone() * m[9].clone();

out[(3, 2)] = -m[0].clone() * m[5].clone() * m[11].clone()
+ m[0].clone() * m[7].clone() * m[9].clone()
+ m[4].clone() * m[1].clone() * m[11].clone()
- m[4].clone() * m[3].clone() * m[9].clone()
- m[8].clone() * m[1].clone() * m[7].clone()
+ m[8].clone() * m[3].clone() * m[5].clone();

out[(1, 3)] = m[0].clone() * m[9].clone() * m[14].clone()
- m[0].clone() * m[10].clone() * m[13].clone()
- m[8].clone() * m[1].clone() * m[14].clone()
+ m[8].clone() * m[2].clone() * m[13].clone()
+ m[12].clone() * m[1].clone() * m[10].clone()
- m[12].clone() * m[2].clone() * m[9].clone();

out[(2, 3)] = -m[0].clone() * m[5].clone() * m[14].clone()
+ m[0].clone() * m[6].clone() * m[13].clone()
+ m[4].clone() * m[1].clone() * m[14].clone()
- m[4].clone() * m[2].clone() * m[13].clone()
- m[12].clone() * m[1].clone() * m[6].clone()
+ m[12].clone() * m[2].clone() * m[5].clone();

out[(3, 3)] = m[0].clone() * m[5].clone() * m[10].clone()
- m[0].clone() * m[6].clone() * m[9].clone()
- m[4].clone() * m[1].clone() * m[10].clone()
+ m[4].clone() * m[2].clone() * m[9].clone()
+ m[8].clone() * m[1].clone() * m[6].clone()
- m[8].clone() * m[2].clone() * m[5].clone();

let det = m[0].clone() * out[(0, 0)].clone()
+ m[1].clone() * out[(0, 1)].clone()
+ m[2].clone() * out[(0, 2)].clone()
+ m[3].clone() * out[(0, 3)].clone();

if !det.is_zero() {
let det = m[0].clone() * cofactor00.clone()
+ m[1].clone() * cofactor01.clone()
+ m[2].clone() * cofactor02.clone()
+ m[3].clone() * cofactor03.clone();

if det.is_zero() {
return false;
} else {
Ralith marked this conversation as resolved.
Show resolved Hide resolved
out[(0, 0)] = cofactor00;

out[(2, 0)] = m[1].clone() * m[6].clone() * m[15].clone()
- m[1].clone() * m[7].clone() * m[14].clone()
- m[5].clone() * m[2].clone() * m[15].clone()
+ m[5].clone() * m[3].clone() * m[14].clone()
+ m[13].clone() * m[2].clone() * m[7].clone()
- m[13].clone() * m[3].clone() * m[6].clone();

out[(3, 0)] = -m[1].clone() * m[6].clone() * m[11].clone()
+ m[1].clone() * m[7].clone() * m[10].clone()
+ m[5].clone() * m[2].clone() * m[11].clone()
- m[5].clone() * m[3].clone() * m[10].clone()
- m[9].clone() * m[2].clone() * m[7].clone()
+ m[9].clone() * m[3].clone() * m[6].clone();

out[(0, 1)] = cofactor01;

out[(1, 1)] = m[0].clone() * m[10].clone() * m[15].clone()
- m[0].clone() * m[11].clone() * m[14].clone()
- m[8].clone() * m[2].clone() * m[15].clone()
+ m[8].clone() * m[3].clone() * m[14].clone()
+ m[12].clone() * m[2].clone() * m[11].clone()
- m[12].clone() * m[3].clone() * m[10].clone();

out[(2, 1)] = -m[0].clone() * m[6].clone() * m[15].clone()
+ m[0].clone() * m[7].clone() * m[14].clone()
+ m[4].clone() * m[2].clone() * m[15].clone()
- m[4].clone() * m[3].clone() * m[14].clone()
- m[12].clone() * m[2].clone() * m[7].clone()
+ m[12].clone() * m[3].clone() * m[6].clone();

out[(3, 1)] = m[0].clone() * m[6].clone() * m[11].clone()
- m[0].clone() * m[7].clone() * m[10].clone()
- m[4].clone() * m[2].clone() * m[11].clone()
+ m[4].clone() * m[3].clone() * m[10].clone()
+ m[8].clone() * m[2].clone() * m[7].clone()
- m[8].clone() * m[3].clone() * m[6].clone();

out[(0, 2)] = cofactor02;

out[(1, 2)] = -m[0].clone() * m[9].clone() * m[15].clone()
+ m[0].clone() * m[11].clone() * m[13].clone()
+ m[8].clone() * m[1].clone() * m[15].clone()
- m[8].clone() * m[3].clone() * m[13].clone()
- m[12].clone() * m[1].clone() * m[11].clone()
+ m[12].clone() * m[3].clone() * m[9].clone();

out[(2, 2)] = m[0].clone() * m[5].clone() * m[15].clone()
- m[0].clone() * m[7].clone() * m[13].clone()
- m[4].clone() * m[1].clone() * m[15].clone()
+ m[4].clone() * m[3].clone() * m[13].clone()
+ m[12].clone() * m[1].clone() * m[7].clone()
- m[12].clone() * m[3].clone() * m[5].clone();

out[(0, 3)] = cofactor03;

out[(3, 2)] = -m[0].clone() * m[5].clone() * m[11].clone()
+ m[0].clone() * m[7].clone() * m[9].clone()
+ m[4].clone() * m[1].clone() * m[11].clone()
- m[4].clone() * m[3].clone() * m[9].clone()
- m[8].clone() * m[1].clone() * m[7].clone()
+ m[8].clone() * m[3].clone() * m[5].clone();

out[(1, 3)] = m[0].clone() * m[9].clone() * m[14].clone()
- m[0].clone() * m[10].clone() * m[13].clone()
- m[8].clone() * m[1].clone() * m[14].clone()
+ m[8].clone() * m[2].clone() * m[13].clone()
+ m[12].clone() * m[1].clone() * m[10].clone()
- m[12].clone() * m[2].clone() * m[9].clone();

out[(2, 3)] = -m[0].clone() * m[5].clone() * m[14].clone()
+ m[0].clone() * m[6].clone() * m[13].clone()
+ m[4].clone() * m[1].clone() * m[14].clone()
- m[4].clone() * m[2].clone() * m[13].clone()
- m[12].clone() * m[1].clone() * m[6].clone()
+ m[12].clone() * m[2].clone() * m[5].clone();

out[(3, 3)] = m[0].clone() * m[5].clone() * m[10].clone()
- m[0].clone() * m[6].clone() * m[9].clone()
- m[4].clone() * m[1].clone() * m[10].clone()
+ m[4].clone() * m[2].clone() * m[9].clone()
+ m[8].clone() * m[1].clone() * m[6].clone()
- m[8].clone() * m[2].clone() * m[5].clone();

let inv_det = T::one() / det;

for j in 0..4 {
Expand All @@ -271,7 +274,5 @@ where
}
}
true
} else {
false
}
}