/// <summary>
/// Inverts the largest nonsingular submatrix in the matrix, excluding 2x2's that involve M13 or M31, and excluding 1x1's that include nondiagonal elements.
/// </summary>
/// <param name="matrix">Matrix to be inverted.</param>
/// <param name="result">Inverted matrix.</param>
public static void AdaptiveInvert(ref Matrix3x3 matrix, out Matrix3x3 result)
{
// Perform full Gauss-invert and return if successful
if (Invert(ref matrix, out result))
{
return;
}
int submatrix;
Fix64 determinantInverse = F64.C1 / matrix.AdaptiveDeterminant(out submatrix);
Fix64 m11, m12, m13, m21, m22, m23, m31, m32, m33;
switch (submatrix)
{
case 1: //Upper left matrix, m11, m12, m21, m22.
m11 = matrix.M22 * determinantInverse;
m12 = -matrix.M12 * determinantInverse;
m13 = F64.C0;
m21 = -matrix.M21 * determinantInverse;
m22 = matrix.M11 * determinantInverse;
m23 = F64.C0;
m31 = F64.C0;
m32 = F64.C0;
m33 = F64.C0;
break;
case 2: //Lower right matrix, m22, m23, m32, m33.
m11 = F64.C0;
m12 = F64.C0;
m13 = F64.C0;
m21 = F64.C0;
m22 = matrix.M33 * determinantInverse;
m23 = -matrix.M23 * determinantInverse;
m31 = F64.C0;
m32 = -matrix.M32 * determinantInverse;
m33 = matrix.M22 * determinantInverse;
break;
case 3: //Corners, m11, m31, m13, m33.
m11 = matrix.M33 * determinantInverse;
m12 = F64.C0;
m13 = -matrix.M13 * determinantInverse;
m21 = F64.C0;
m22 = F64.C0;
m23 = F64.C0;
m31 = -matrix.M31 * determinantInverse;
m32 = F64.C0;
m33 = matrix.M11 * determinantInverse;
break;
case 4: //M11
m11 = F64.C1 / matrix.M11;
m12 = F64.C0;
m13 = F64.C0;
m21 = F64.C0;
m22 = F64.C0;
m23 = F64.C0;
m31 = F64.C0;
m32 = F64.C0;
m33 = F64.C0;
break;
case 5: //M22
m11 = F64.C0;
m12 = F64.C0;
m13 = F64.C0;
m21 = F64.C0;
m22 = F64.C1 / matrix.M22;
m23 = F64.C0;
m31 = F64.C0;
m32 = F64.C0;
m33 = F64.C0;
break;
case 6: //M33
m11 = F64.C0;
m12 = F64.C0;
m13 = F64.C0;
m21 = F64.C0;
m22 = F64.C0;
m23 = F64.C0;
m31 = F64.C0;
m32 = F64.C0;
m33 = F64.C1 / matrix.M33;
break;
default: //Completely singular.
m11 = F64.C0; m12 = F64.C0; m13 = F64.C0; m21 = F64.C0; m22 = F64.C0; m23 = F64.C0; m31 = F64.C0; m32 = F64.C0; m33 = F64.C0;
break;
}
result.M11 = m11;
result.M12 = m12;
result.M13 = m13;
result.M21 = m21;
result.M22 = m22;
result.M23 = m23;
result.M31 = m31;
result.M32 = m32;
result.M33 = m33;
}