# `BB.Math.Covariance3`
[🔗](https://github.com/beam-bots/bb/blob/main/lib/bb/math/covariance3.ex#L5)

A 3x3 covariance matrix, backed by an Nx tensor.

Used to express uncertainty over a 3-vector quantity such as an
accelerometer reading, an angular velocity, or a position. The matrix
is mathematically expected to be symmetric and positive semi-definite;
this module does not enforce those invariants on construction (zero
matrices, in particular, are legitimate "unknown variance" placeholders
and must remain constructible).

Follows the same typed-Nx-wrapper pattern as `BB.Math.Vec3`,
`BB.Math.Quaternion`, and `BB.Math.Transform`.

## Examples

    iex> c = BB.Math.Covariance3.diagonal([0.01, 0.01, 0.02])
    iex> BB.Math.Covariance3.get(c, 0, 0)
    0.01

# `t`

```elixir
@type t() :: %BB.Math.Covariance3{tensor: Nx.Tensor.t()}
```

# `diagonal`

```elixir
@spec diagonal([number()] | Nx.Tensor.t()) :: t()
```

Builds a diagonal covariance from a list of three variances or a
`{3}` tensor.

## Examples

    iex> c = BB.Math.Covariance3.diagonal([0.1, 0.2, 0.3])
    iex> {BB.Math.Covariance3.get(c, 0, 0), BB.Math.Covariance3.get(c, 1, 1), BB.Math.Covariance3.get(c, 2, 2)}
    {0.1, 0.2, 0.3}

# `from_tensor`

```elixir
@spec from_tensor(Nx.Tensor.t()) :: t()
```

Wraps an existing `{3, 3}` tensor without validation. Convenience
alias for `new/1` matching the convention used by `BB.Math.Transform`.

# `get`

```elixir
@spec get(t(), 0..2, 0..2) :: float()
```

Reads a scalar element at row/column `(i, j)`.

## Examples

    iex> c = BB.Math.Covariance3.diagonal([0.5, 1.5, 2.5])
    iex> BB.Math.Covariance3.get(c, 2, 2)
    2.5

# `identity`

```elixir
@spec identity() :: t()
```

Returns the 3x3 identity matrix as a covariance.

## Examples

    iex> c = BB.Math.Covariance3.identity()
    iex> {BB.Math.Covariance3.get(c, 0, 0), BB.Math.Covariance3.get(c, 0, 1)}
    {1.0, 0.0}

# `new`

```elixir
@spec new(Nx.Tensor.t()) :: t()
```

Creates a covariance from a `{3, 3}` tensor.

## Examples

    iex> tensor = Nx.tensor([[1.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 3.0]])
    iex> c = BB.Math.Covariance3.new(tensor)
    iex> BB.Math.Covariance3.get(c, 1, 1)
    2.0

# `to_tensor`

```elixir
@spec to_tensor(t()) :: Nx.Tensor.t()
```

Returns the underlying tensor.

# `zero`

```elixir
@spec zero() :: t()
```

Returns the zero covariance - all variances and correlations zero.

## Examples

    iex> c = BB.Math.Covariance3.zero()
    iex> BB.Math.Covariance3.get(c, 0, 0)
    0.0

---

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