# `Monty.Geometry`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/geometry.ex#L1)

Small 3×3 matrix arithmetic and pose helpers.

Mirrors `tbp/monty/geometry.py` where it matters for the messaging layer: the
pose-vector types live in `Monty.Geometry.*` and matrix products used to
transform them live here. Anything heavier (quaternions, alignment, batch
rotation) arrives with the numeric core and is tested against Monty's own
fixtures.

# `add`

```elixir
@spec add([number()], [number()]) :: [number()]
```

Adds two 3-vectors.

# `apply`

```elixir
@spec apply([[number()]], [number()]) :: [number()]
```

Multiplies a 3×3 matrix by a 3-vector.

Three dot products, written as three dot products — the map and its closure
were most of what this cost.

# `dot`

```elixir
@spec dot([number()], [number()]) :: number()
```

Dot product of two 3-vectors.

# `identity`

```elixir
@spec identity() :: [[float()]]
```

The 3×3 identity matrix.

# `mul`

```elixir
@spec mul([[number()]], [[number()]]) :: [[float()]]
```

Multiplies two 3×3 matrices.

`left * right`, row-major, the way `numpy.dot` reads.

Written out rather than built from `transpose/1` and a map of `dot/2` calls:
this is nine multiplications and six additions, and the general shape spent
six closures and three intermediate lists on them. In a step it is called once
per hypothesis to rotate a frame, so it is one of the few places where the
arithmetic has to be the whole function.

# `subtract`

```elixir
@spec subtract([number()], [number()]) :: [number()]
```

Subtracts two 3-vectors.

# `transpose`

```elixir
@spec transpose([[number()]]) :: [[number()]]
```

Transposes a 3×3 matrix.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
