# Dense Distances

> NumKong for C++

The dense spatial kernels cover the SciPy-style `sqeuclidean`, `euclidean`, and `angular` family.
The important difference is that storage type and output type are not forced to match.

```c
nk_f16_t a[768];
nk_f16_t b[768];
nk_f32_t sqeuclidean = 0, euclidean = 0, angular = 0;

// `_Float16` support varies across compilers, and
// auto-vectorization targets `f32` — not `f16`.
nk_sqeuclidean_f16_best(a, b, 768, &sqeuclidean, capabilities, NULL);
nk_euclidean_f16_best(a, b, 768, &euclidean, capabilities, NULL);
nk_angular_f16_best(a, b, 768, &angular, capabilities, NULL);
```

For `i8`, `u8`, `i4`, `u4`, and `u1`, the widening is even more important.
The output type is chosen to avoid the obvious overflow trap of same-width accumulation.

`#include <numkong/spatial.hpp>`

## euclidean

L₂ (Euclidean) distance: √Σ(aᵢ − bᵢ)²

```cpp
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::euclidean_result_t>
status_t euclidean(
    in_type_ const *a,
    in_type_ const *b,
    std::size_t d,
    result_type_ *r,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
```

```cpp
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::euclidean_result_t, vector_of<in_type_> a_type_, vector_of<in_type_> b_type_>
expected<result_type_> euclidean(
    a_type_ const & a,
    b_type_ const & b,
    nk_capability_t capabilities = default_capabilities()) noexcept;
```

Euclidean distance between two runs of `in_type_` with equal dimensions; [`unexpected_dimensions_k`](https://www.unum.cloud/docs/numkong/cpp/quickstart.md#unexpected_dimensions_k) when they differ or either run is strided or ends mid-value.

- `a` (in): First vector
- `b` (in): Second vector
- `d` (in): Counts dimensions, a multiple of the values per byte.
- `r` (out): Pointer to output distance value
- `capabilities` (in): Capabilities to pick from, or zero for the C++ template
- `stream` (in): Null on the CPU, or the stream of the device `capabilities` describes

## sqeuclidean

Squared L₂ distance: Σ(aᵢ − bᵢ)²

```cpp
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::sqeuclidean_result_t>
status_t sqeuclidean(
    in_type_ const *a,
    in_type_ const *b,
    std::size_t d,
    result_type_ *r,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
```

```cpp
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::sqeuclidean_result_t, vector_of<in_type_> a_type_, vector_of<in_type_> b_type_>
expected<result_type_> sqeuclidean(
    a_type_ const & a,
    b_type_ const & b,
    nk_capability_t capabilities = default_capabilities()) noexcept;
```

Squared Euclidean distance between two runs, failing like the concept [`euclidean`](#euclidean).

- `a` (in): First vector
- `b` (in): Second vector
- `d` (in): Counts dimensions, a multiple of the values per byte.
- `r` (out): Pointer to output distance value
- `capabilities` (in): Capabilities to pick from, or zero for the C++ template
- `stream` (in): Null on the CPU, or the stream of the device `capabilities` describes

## angular

Angular similarity (cosine): ⟨a,b⟩ / (‖a‖ × ‖b‖).

```cpp
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::angular_result_t>
status_t angular(
    in_type_ const *a,
    in_type_ const *b,
    std::size_t d,
    result_type_ *r,
    nk_capability_t capabilities = default_capabilities(),
    nk_stream_t stream = nullptr) noexcept;
```

```cpp
template <numeric_dtype in_type_, numeric_dtype result_type_ = typename in_type_::angular_result_t, vector_of<in_type_> a_type_, vector_of<in_type_> b_type_>
expected<result_type_> angular(
    a_type_ const & a,
    b_type_ const & b,
    nk_capability_t capabilities = default_capabilities()) noexcept;
```

Angular distance between two runs, failing like the concept [`euclidean`](#euclidean).

- `a` (in): First vector
- `b` (in): Second vector
- `d` (in): Counts dimensions, a multiple of the values per byte.
- `r` (out): Pointer to output distance value
- `capabilities` (in): Capabilities to pick from, or zero for the C++ template
- `stream` (in): Null on the CPU, or the stream of the device `capabilities` describes

