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

The constants Monty's arithmetic agrees on.

Mirrors `tbp/monty/math.py`, which is little more than the tolerances every
geometric comparison uses. They live in one place because a tolerance that
differs between two modules is a disagreement about what "the same direction"
means, and that disagreement shows up as a hypothesis surviving in one module
and not in another.

Monty's type aliases (`VectorXYZ`, `EulerAnglesXYZ`, `QuaternionWXYZ`) have no
Elixir counterpart: a `[x, y, z]` is a list and a quaternion is a
`Monty.Geometry.Rotation`, so the aliases would only restate their own types.

# `clip`

```elixir
@spec clip(number(), number(), number()) :: number()
```

The value moved inside `[low, high]`, numpy's `np.clip`.

# `default_tolerance`

```elixir
@spec default_tolerance() :: float()
```

How close two lengths or dot products must be to count as equal.

Monty's `DEFAULT_TOLERANCE`. It is a distance, not a relative error: halves of
a metre compare at this scale, and comparisons of larger quantities scale it
by their own magnitude at the call site.

# `degrees`

```elixir
@spec degrees(number()) :: float()
```

An angle in degrees as radians.

Monty writes this conversion out at each use (`math.radians`, or `* pi / 180`
inside scipy calls); the arithmetic is the same either way, and having one
copy means a tolerance in degrees and a tolerance in radians cannot drift
apart.

# `identity_quaternion`

```elixir
@spec identity_quaternion() :: {float(), float(), float(), float()}
```

The quaternion `wxyz` of no rotation.

# `mean`

```elixir
@spec mean([number()]) :: float()
```

The average of a sample, or zero for an empty one.

numpy's `np.mean`, which Monty uses to summarise evidence and locations. The
empty case is Monty's own convention for a hypothesis space with nothing in
it: no observations, no average, and zero is the neutral value to add to.

# `ones_vector`

```elixir
@spec ones_vector() :: {float(), float(), float()}
```

The vector `(1, 1, 1)`.

# `population_std`

```elixir
@spec population_std([number()]) :: float()
```

The spread of a sample around its mean, dividing by `n`.

numpy's `np.std` — population standard deviation, not the sample estimate.
Monty uses it to decide whether one object stands out from the field: a wide
spread means there is something to discriminate between.

# `rotation_tolerance_radians`

```elixir
@spec rotation_tolerance_radians() :: float()
```

How small an angle (in radians) counts as no rotation.

# `zero_vector`

```elixir
@spec zero_vector() :: {float(), float(), float()}
```

The vector `(0, 0, 0)`.

---

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