---
title: "Invert a matrix in C#"
url: https://recursiveai.org/onemath/cookbook/invert-matrix/
description: "Invert a matrix in C# with a complete runnable example, real output and the behavior to check before using the result. Free, open-source .NET code."
version: "1.0.0"
---

# Invert a matrix in C#

**OneMath** is a free, open-source deterministic math library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneMath) · [GitHub](https://github.com/recursive-ai-oss/onemath-csharp) · [Docs](https://recursiveai.org/onemath/docs/) · [Download example (.zip)](https://recursiveai.org/onemath/cookbook/invert-matrix/invert-matrix.zip)

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.

```shell
dotnet add package RecursiveAI.OneMath
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
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);
```

```text
3
```

Unzip [the example](https://recursiveai.org/onemath/cookbook/invert-matrix/invert-matrix.zip), 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.

```csharp
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:

```text
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:

```csharp
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}");
```

```text
0.5, 0.25
```

## Related recipes

- [Vector and quaternion math](https://recursiveai.org/onemath/cookbook/vector-and-quaternion-math/)
- [Convert System.Numerics conventions](https://recursiveai.org/onemath/cookbook/port-from-system-numerics/)

## 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](https://recursiveai.org/onemath/docs/evaluation-order/) 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.
