# `Scholar.Metrics.Distance`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L1)

Distance metrics between multi-dimensional tensors.
They all support distance calculations between any subset of axes.

# `chebyshev`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L274)

Chebyshev or $L_{\infty}$ distance.

$$
D(x, y) = \max_i |x_i - y_i|
$$

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([3, 2])
    iex> Scholar.Metrics.Distance.chebyshev(x, y)
    #Nx.Tensor<
      f32
      2.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2])
    iex> Scholar.Metrics.Distance.chebyshev(x, y)
    #Nx.Tensor<
      f32
      0.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.chebyshev(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 5], [3, 4, 3]])
    iex> y = Nx.tensor([[8, 3, 1], [2, 5, 2]])
    iex> Scholar.Metrics.Distance.chebyshev(x, y, axes: [1])
    #Nx.Tensor<
      f32[2]
      [7.0, 1.0]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.chebyshev(x, y)
    #Nx.Tensor<
      f32
      8.0
    >

# `cosine`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L440)

Cosine distance.

$$
D(u, v) = 1 - \frac{u \cdot v}{\|u\|_2 \|v\|_2}
$$

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([5, 2])
    iex> Scholar.Metrics.Distance.cosine(x, y)
    #Nx.Tensor<
      f32
      0.25259071588516235
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.cosine(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 3], [0, 0, 0], [5, 2, 4]])
    iex> y = Nx.tensor([[1, 5, 2], [2, 4, 1], [0, 0, 0]])
    iex> Scholar.Metrics.Distance.cosine(x, y, axes: [1])
    #Nx.Tensor<
      f32[3]
      [0.1704850196838379, 1.0, 1.0]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.cosine(x, y)
    #Nx.Tensor<
      f32
      0.10575336217880249
    >

# `euclidean`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L85)

Standard euclidean distance ($L_{2}$ distance).

$$
D(x, y) = \sqrt{\sum_i (x_i - y_i)^2}
$$

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([3, 2])
    iex> Scholar.Metrics.Distance.euclidean(x, y)
    #Nx.Tensor<
      f32
      2.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2])
    iex> Scholar.Metrics.Distance.euclidean(x, y)
    #Nx.Tensor<
      f32
      0.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.euclidean(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 5], [3, 4, 3]])
    iex> y = Nx.tensor([[8, 3, 1], [2, 5, 2]])
    iex> Scholar.Metrics.Distance.euclidean(x, y, axes: [0])
    #Nx.Tensor<
      f32[3]
      [7.071067810058594, 1.4142135381698608, 4.123105525970459]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.euclidean(x, y)
    #Nx.Tensor<
      f32
      10.630146026611328
    >

# `hamming`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L533)

Hamming distance.

$$
hamming(x, y) = \frac{\left \lvert x\_{i, j, ...} \neq y\_{i, j, ...}\right \rvert}{\left \lvert x\_{i, j, ...}\right \rvert}
$$
where $i, j, ...$ are the aggregation axes

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 0, 0])
    iex> y = Nx.tensor([0, 1, 0])
    iex> Scholar.Metrics.Distance.hamming(x, y)
    #Nx.Tensor<
      f32
      0.6666666865348816
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.hamming(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 3], [0, 0, 0], [5, 2, 4]])
    iex> y = Nx.tensor([[1, 5, 2], [2, 4, 1], [0, 0, 0]])
    iex> Scholar.Metrics.Distance.hamming(x, y, axes: [1])
    #Nx.Tensor<
      f32[3]
      [0.6666666865348816, 1.0, 1.0]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.hamming(x, y)
    #Nx.Tensor<
      f32
      1.0
    >

# `hamming`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L569)

Hamming distance in weighted version.

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 0, 0])
    iex> y = Nx.tensor([0, 1, 0])
    iex> weights = Nx.tensor([1, 0.5, 0.5])
    iex> Scholar.Metrics.Distance.hamming(x, y, weights)
    #Nx.Tensor<
      f32
      0.75
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> weights = Nx.tensor([1, 0.5, 0.5])
    iex> Scholar.Metrics.Distance.hamming(x, y, weights, axes: [1])
    #Nx.Tensor<
      f32[2]
      [1.0, 1.0]
    >

# `manhattan`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L211)

Manhattan, Taxicab, or $L_{1}$ distance.

$$
D(x, y) = \sum_i |x_i - y_i|
$$

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([3, 2])
    iex> Scholar.Metrics.Distance.manhattan(x, y)
    #Nx.Tensor<
      f32
      2.0
    >

    iex> x = Nx.tensor([1.0, 2.0])
    iex> y = Nx.tensor([1, 2])
    iex> Scholar.Metrics.Distance.manhattan(x, y)
    #Nx.Tensor<
      f32
      0.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.manhattan(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 5], [3, 4, 3]])
    iex> y = Nx.tensor([[8, 3, 1], [2, 5, 2]])
    iex> Scholar.Metrics.Distance.manhattan(x, y, axes: [0])
    #Nx.Tensor<
      f32[3]
      [8.0, 2.0, 5.0]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.manhattan(x, y)
    #Nx.Tensor<
      f32
      21.0
    >

# `minkowski`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L337)

Minkowski distance.

$$
D(x, y) = \left(\sum_i |x_i - y_i|^p\right)^{\frac{1}{p}}
$$

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

* `:p` - A positive parameter of Minkowski distance or :infinity (then Chebyshev metric computed). The default value is `2.0`.

## Examples

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([5, 2])
    iex> Scholar.Metrics.Distance.minkowski(x, y)
    #Nx.Tensor<
      f32
      4.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2])
    iex> Scholar.Metrics.Distance.minkowski(x, y)
    #Nx.Tensor<
      f32
      0.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.minkowski(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 5], [3, 4, 3]])
    iex> y = Nx.tensor([[8, 3, 1], [2, 5, 2]])
    iex> Scholar.Metrics.Distance.minkowski(x, y, p: 2.5, axes: [0])
    #Nx.Tensor<
      f32[3]
      [7.021548271179199, 1.3195079565048218, 4.049539089202881]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.minkowski(x, y, p: 2.5)
    #Nx.Tensor<
      f32
      9.621805191040039
    >

# `pairwise_cosine`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L729)

Pairwise cosine distance. It is equivalent to
Scholar.Metrics.Distance.pairwise_euclidean(x, x)

## Examples

    iex> x = Nx.iota({6, 6})
    iex> Scholar.Metrics.Distance.pairwise_cosine(x)
    #Nx.Tensor<
      f32[6][6]
      [
        [0.0, 0.0793418288230896, 0.1139642596244812, 0.13029760122299194, 0.1397092342376709, 0.14581435918807983],
        [0.0793418288230896, 0.0, 0.0032819509506225586, 0.006624102592468262, 0.008954286575317383, 0.01060718297958374],
        [0.1139642596244812, 0.0032819509506225586, 0.0, 5.82277774810791e-4, 0.0013980269432067871, 0.0020949840545654297],
        [0.13029760122299194, 0.006624102592468262, 5.82277774810791e-4, 0.0, 1.7595291137695312e-4, 4.686713218688965e-4],
        [0.1397092342376709, 0.008954286575317383, 0.0013980269432067871, 1.7595291137695312e-4, 0.0, 7.027387619018555e-5],
        [0.14581435918807983, 0.01060718297958374, 0.0020949840545654297, 4.686713218688965e-4, 7.027387619018555e-5, 0.0]
      ]
    >

# `pairwise_cosine`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L703)

Pairwise cosine distance.

## Examples

    iex> x = Nx.iota({6, 6})
    iex> y = Nx.reverse(x)
    iex> Scholar.Metrics.Distance.pairwise_cosine(x, y)
    #Nx.Tensor<
      f32[6][6]
      [
        [0.2050153613090515, 0.21226388216018677, 0.22395789623260498, 0.24592703580856323, 0.30156970024108887, 0.6363636255264282],
        [0.03128105401992798, 0.03429150581359863, 0.039331674575805664, 0.049365341663360596, 0.07760530710220337, 0.30156970024108887],
        [0.014371514320373535, 0.01644366979598999, 0.020004630088806152, 0.02736520767211914, 0.049365341663360596, 0.24592703580856323],
        [0.0091819167137146, 0.010854601860046387, 0.013785064220428467, 0.020004630088806152, 0.039331674575805664, 0.22395789623260498],
        [0.006820023059844971, 0.008272230625152588, 0.010854601860046387, 0.01644366979598999, 0.03429150581359863, 0.21226388216018677],
        [0.005507469177246094, 0.006820023059844971, 0.0091819167137146, 0.014371514320373535, 0.03128105401992798, 0.2050153613090515]
      ]
    >

# `pairwise_euclidean`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L679)

Pairwise euclidean distance. It is equivalent to
Scholar.Metrics.Distance.pairwise_euclidean(x, x)

## Examples

    iex> x = Nx.iota({6, 6})
    iex> Scholar.Metrics.Distance.pairwise_euclidean(x)
    #Nx.Tensor<
      f32[6][6]
      [
        [0.0, 14.696938514709473, 29.393877029418945, 44.090816497802734, 58.78775405883789, 73.48469543457031],
        [14.696938514709473, 0.0, 14.696938514709473, 29.393877029418945, 44.090816497802734, 58.78775405883789],
        [29.393877029418945, 14.696938514709473, 0.0, 14.696938514709473, 29.393877029418945, 44.090816497802734],
        [44.090816497802734, 29.393877029418945, 14.696938514709473, 0.0, 14.696938514709473, 29.393877029418945],
        [58.78775405883789, 44.090816497802734, 29.393877029418945, 14.696938514709473, 0.0, 14.696938514709473],
        [73.48469543457031, 58.78775405883789, 44.090816497802734, 29.393877029418945, 14.696938514709473, 0.0]
      ]
    >

# `pairwise_euclidean`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L655)

Pairwise euclidean distance.

## Examples

    iex> x = Nx.iota({2, 3})
    iex> y = Nx.reverse(x)
    iex> Scholar.Metrics.Distance.pairwise_euclidean(x, y)
    #Nx.Tensor<
      f32[2][2]
      [
        [5.916079998016357, 2.8284270763397217],
        [2.8284270763397217, 5.916079998016357]
      ]
    >

# `pairwise_minkowski`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L380)

Computes the pairwise Minkowski distance.

## Examples

    iex> x = Nx.iota({2, 3})
    iex> y = Nx.reverse(x)
    iex> Scholar.Metrics.Distance.pairwise_minkowski(x, y)
    #Nx.Tensor<
      f32[2][2]
      [
        [5.916079998016357, 2.8284270763397217],
        [2.8284270763397217, 5.916079998016357]
      ]
    >

# `pairwise_squared_euclidean`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L633)

Pairwise squared euclidean distance. It is equivalent to
Scholar.Metrics.Distance.pairwise_squared_euclidean(x, x)

## Examples

    iex> x = Nx.iota({6, 6})
    iex> Scholar.Metrics.Distance.pairwise_squared_euclidean(x)
    #Nx.Tensor<
      s32[6][6]
      [
        [0, 216, 864, 1944, 3456, 5400],
        [216, 0, 216, 864, 1944, 3456],
        [864, 216, 0, 216, 864, 1944],
        [1944, 864, 216, 0, 216, 864],
        [3456, 1944, 864, 216, 0, 216],
        [5400, 3456, 1944, 864, 216, 0]
      ]
    >

# `pairwise_squared_euclidean`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L607)

Pairwise squared euclidean distance.

## Examples

    iex> x = Nx.iota({6, 6})
    iex> y = Nx.reverse(x)
    iex> Scholar.Metrics.Distance.pairwise_squared_euclidean(x, y)
    #Nx.Tensor<
      s32[6][6]
      [
        [5470, 3526, 2014, 934, 286, 70],
        [3526, 2014, 934, 286, 70, 286],
        [2014, 934, 286, 70, 286, 934],
        [934, 286, 70, 286, 934, 2014],
        [286, 70, 286, 934, 2014, 3526],
        [70, 286, 934, 2014, 3526, 5470]
      ]
    >

# `squared_euclidean`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/metrics/distance.ex#L148)

Squared euclidean distance.

$$
D(x, y) = \sum_i (x_i - y_i)^2
$$

## Options

* `:axes` - Axes to calculate the distance over. By default the distance
  is calculated between the whole tensors.

## Examples

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([3, 2])
    iex> Scholar.Metrics.Distance.squared_euclidean(x, y)
    #Nx.Tensor<
      f32
      4.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1.0, 2.0])
    iex> Scholar.Metrics.Distance.squared_euclidean(x, y)
    #Nx.Tensor<
      f32
      0.0
    >

    iex> x = Nx.tensor([1, 2])
    iex> y = Nx.tensor([1, 2, 3])
    iex> Scholar.Metrics.Distance.squared_euclidean(x, y)
    ** (ArgumentError) tensors must be broadcast compatible, got tensors with shapes {2} and {3}

    iex> x = Nx.tensor([[1, 2, 5], [3, 4, 3]])
    iex> y = Nx.tensor([[8, 3, 1], [2, 5, 2]])
    iex> Scholar.Metrics.Distance.squared_euclidean(x, y, axes: [0])
    #Nx.Tensor<
      f32[3]
      [50.0, 2.0, 17.0]
    >

    iex> x = Nx.tensor([[6, 2, 9], [2, 5, 3]])
    iex> y = Nx.tensor([[8, 3, 1]])
    iex> Scholar.Metrics.Distance.squared_euclidean(x, y)
    #Nx.Tensor<
      f32
      113.0
    >

---

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