# `ExMujoco.Tensor`
[🔗](https://github.com/d-led/ex.mujoco/blob/main/lib/ex_mujoco/tensor.ex#L1)

A field of an `mjModel` or `mjData`, as a value: the elements, their type, and
the shape MuJoCo declared them with.

    iex> model |> ExMujoco.Model.geom_pos() |> ExMujoco.Tensor.to_list()
    [[0.0, 0.0, 0.0], [0.0, 0.0, 0.05], ...]

The data is one binary of elements in the machine's native order — MuJoCo's own
layout, copied straight out of the struct — so `Nx.from_binary/2` takes it as it
is, and so does `<<x::float-64-native>>`.

A shape of `{3}` is a vector (MuJoCo's `(n × 1)`), `{n, 3}` is a matrix, and
`{}` is a single value. Reading a field copies it, so what you hold does not
change when the next step runs — which is the whole reason not to hand out a
binary that aliases live `mjData`.

# `element_type`

```elixir
@type element_type() :: :f64 | :f32 | :i32 | :u8
```

The element type, as MuJoCo declares it.

# `t`

```elixir
@type t() :: %ExMujoco.Tensor{data: binary(), shape: tuple(), type: element_type()}
```

# `size`

```elixir
@spec size(t()) :: non_neg_integer()
```

The number of elements, whatever the shape.

# `to_list`

```elixir
@spec to_list(t()) :: list()
```

The elements as an Elixir list, nested to the shape.

Convenient and slow: it allocates a term per element. For anything on a hot
path, keep the binary and read it with a bitstring pattern.

---

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