An inverse transform takes a point back to its original coordinates. OneMath has fixed 2×2, 3×3 and 4×4 matrix types in double (D) and float (F) precision, not arbitrary N×N double[,] arrays. Its math is deterministic: the same inputs give the same result bits across platforms.
dotnet add package RecursiveAI.OneMathRequires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using RecursiveAI.OneMath; var matrix = Matrix4x4D.CreateScale( new Vector3D(2, 4, 8)); if (!matrix.TryInvert(out var inverse)) throw new InvalidOperationException( "No inverse."); Console.WriteLine(inverse.TransformPoint( new Vector3D(2, 8, 24)).Z);
3Unzip the example, then dotnet run.
The full program
The full program combines translation and scale, transforms a point, and applies the inverse. It also checks a zero scale and a NaN input. TryInvert returns false and a zero matrix when the determinant is zero or non-finite.
using RecursiveAI.OneMath; var matrix = Matrix4x4D.CreateTranslation(new Vector3D(10, 20, 30)) * Matrix4x4D.CreateScale(new Vector3D(2, 4, 8)); if (!matrix.TryInvert(out var inverse)) throw new InvalidOperationException("Matrix cannot be inverted."); var point = new Vector3D(1, 2, 3); var transformed = matrix.TransformPoint(point); var restored = inverse.TransformPoint(transformed); Console.WriteLine($"Transformed: {transformed.X}, {transformed.Y}, {transformed.Z}"); Console.WriteLine($"Restored: {restored.X}, {restored.Y}, {restored.Z}"); var singular = Matrix4x4D.CreateScale(new Vector3D(1, 0, 1)); Console.WriteLine($"Singular invertible: {singular.TryInvert(out _)}"); var nonFinite = Matrix4x4D.CreateScale(new Vector3D(double.NaN, 1, 1)); Console.WriteLine($"NaN invertible: {nonFinite.TryInvert(out _)}");
dotnet run prints:
Transformed: 12, 28, 54 Restored: 1, 2, 3 Singular invertible: False NaN invertible: False
Variations
Invert a 2×2 matrix with the same failure check:
using RecursiveAI.OneMath; var matrix = new Matrix2x2D(2, 0, 0, 4); if (!matrix.TryInvert(out var inverse)) throw new InvalidOperationException( "No inverse."); Console.WriteLine($"{inverse.M11}, {inverse.M22}");
0.5, 0.25Related recipes
The short answer
Call matrix.TryInvert(out var inverse) and use the result only when it returns true. For a transform matrix, apply the inverse to a transformed point with inverse.TransformPoint(point). The full program uses a 4×4 double-precision matrix and recovers (1, 2, 3) from (12, 28, 54).
This recipe is for OneMath’s fixed-size matrix types, not arbitrary-size double[,] arrays. Choose the dimension and precision that match your data: Matrix2x2D, Matrix3x3D and Matrix4x4D use doubles, and the corresponding F types use floats. Converting an array into a matrix still requires arranging its entries according to the intended transform.
How do I invert a matrix?
An inverse undoes the matrix operation. For a transform, a practical check is to transform a known point and then transform it back with the inverse. For general floating-point input, a round-trip can contain rounding error; it should not be turned into an unconditional exact-equality test.
OneMath stores row-major fields named Mrc, but uses column vectors: transforming a vector means M * v. Translation is in M14, M24 and M34. In the expression translation * scale, scale is applied first and translation second. That is why the original point (1, 2, 3) becomes (12, 28, 54) in the example. Storage layout and vector convention are separate choices.
The inverse is a new matrix; it does not modify the original. Keep both when your application needs local-to-world and world-to-local transforms. When exchanging matrices with a row-vector API, use the provided representation conversions rather than copying the same named fields. The evaluation-order documentation describes composition and FromSystemNumerics / ToSystemNumerics.
How do I invert a 2×2 matrix?
Use Matrix2x2D.TryInvert, as in the variation. Its determinant is M11*M22 - M12*M21. For a nonzero finite determinant, the inverse uses the swapped diagonal and negated off-diagonal entries divided by that determinant. The diagonal example therefore produces reciprocals of 2 and 4.
A zero scale destroys a coordinate, so there is no unique original point to recover. OneMath reports failure when the determinant is zero or not finite, and puts the zero matrix in the output. Do not use that output as a fallback transform: it is not an identity matrix and does not undo anything.
A successful return is not a numerical conditioning test. A determinant that is finite and nonzero passes even when the matrix is close to singular. If your application is sensitive to error, examine residuals or impose application-specific acceptance criteria as well.