torchpairwise


Nametorchpairwise JSON
Version 0.2.0 PyPI version JSON
download
home_pagehttps://github.com/inspiros/torchpairwise
SummaryPairwise Metrics for PyTorch
upload_time2025-01-19 23:34:49
maintainerNone
docs_urlNone
authorHoang-Nhat Tran (inspiros)
requires_python>=3.9
licenseMIT
keywords pairwise_metric pairwise_distance kernel_function
VCS
bugtrack_url
requirements torch
Travis-CI No Travis.
coveralls test coverage No coveralls.
            TorchPairwise [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/inspiros/torchpairwise/build_wheels.yml)](https://github.com/inspiros/torchpairwise/actions) [![PyPI - Version](https://img.shields.io/pypi/v/torchpairwise)](https://pypi.org/project/torchpairwise/) [![Downloads](https://static.pepy.tech/badge/torchpairwise)](https://pepy.tech/project/torchpairwise) [![GitHub - License](https://img.shields.io/github/license/inspiros/torchpairwise)](LICENSE.txt)
======

This package provides highly-efficient pairwise metrics for **PyTorch**.

## Highlights

``torchpairwise`` is a collection of **general purpose** pairwise metric functions that behave similar to
``torch.cdist`` (which only implements $L_p$ distance).
Instead, we offer a lot more metrics ported from other packages such as
``scipy.spatial.distance`` and ``sklearn.metrics.pairwise``.
For task-specific metrics (e.g. for evaluation of classification, regression, clustering, ...), you should be in the
wrong place, please head to the [TorchMetrics](https://github.com/Lightning-AI/torchmetrics) repo.

Written in ``torch``'s C++ API, the main differences are that our metrics:

- are all (_except some boolean distances_) **differentiable** with backward formulas manually derived, implemented,
  and verified with ``torch.autograd.gradcheck``.
- are **batched** and can exploit GPU parallelization.
- can be integrated seamlessly within **PyTorch**-based projects, all functions are ``torch.jit.script``-able.

### List of pairwise distance metrics

| ``torchpairwise`` ops            | Equivalences in other libraries                                                                                                                                              | Differentiable |
|:---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------:|
| ``euclidean_distances``          | [``sklearn.metrics.pairwise.euclidean_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.euclidean_distances.html)                      |       ✔️       |
| ``haversine_distances``          | [``sklearn.metrics.pairwise.haversine_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.haversine_distances.html)                      |       ✔️       |
| ``manhattan_distances``          | [``sklearn.metrics.pairwise.manhattan_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.manhattan_distances.html)                      |       ✔️       |
| ``cosine_distances``             | [``sklearn.metrics.pairwise.cosine_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_distances.html)                            |       ✔️       |
| ``l1_distances``                 | _(Alias of ``manhattan_distances``)_                                                                                                                                         |       ✔️       |
| ``l2_distances``                 | _(Alias of ``euclidean_distances``)_                                                                                                                                         |       ✔️       |
| ``lp_distances``                 | _(Alias of ``minkowski_distances``)_                                                                                                                                         |       ✔️       |
| ``linf_distances``               | _(Alias of ``chebyshev_distances``)_                                                                                                                                         |       ✔️       |
| ``directed_hausdorff_distances`` | [``scipy.spatial.distance.directed_hausdorff``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.directed_hausdorff.html) [^1]                    |       ✔️       |
| ``minkowski_distances``          | [``scipy.spatial.distance.minkowski``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html) [^1]                                      |       ✔️       |
| ``wminkowski_distances``         | [``scipy.spatial.distance.wminkowski``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.wminkowski.html) [^1]                                    |       ✔️       |
| ``sqeuclidean_distances``        | [``scipy.spatial.distance.sqeuclidean_distances``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.sqeuclidean_distances.html) [^1]              |       ✔️       |
| ``correlation_distances``        | [``scipy.spatial.distance.correlation``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.correlation.html) [^1]                                  |       ✔️       |
| ``hamming_distances``            | [``scipy.spatial.distance.hamming``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.hamming.html) [^1]                                          |     ❌[^2]      |
| ``jaccard_distances``            | [``scipy.spatial.distance.jaccard``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jaccard.html) [^1]                                          |     ❌[^2]      |
| ``kulsinski_distances``          | [``scipy.spatial.distance.kulsinski``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.kulsinski.html) [^1]                                      |     ❌[^2]      |
| ``kulczynski1_distances``        | [``scipy.spatial.distance.kulczynski1``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.kulczynski1.html) [^1]                                  |     ❌[^2]      |
| ``seuclidean_distances``         | [``scipy.spatial.distance.seuclidean``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.seuclidean.html) [^1]                                    |       ✔️       |
| ``cityblock_distances``          | [``scipy.spatial.distance.cityblock``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cityblock.html) [^1] _(Alias of ``manhattan_distances``)_ |       ✔️       |
| ``mahalanobis_distances``        | [``scipy.spatial.distance.mahalanobis``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.mahalanobis.html) [^1]                                  |       ✔️       |
| ``chebyshev_distances``          | [``scipy.spatial.distance.chebyshev``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.chebyshev.html) [^1]                                      |       ✔️       |
| ``braycurtis_distances``         | [``scipy.spatial.distance.braycurtis``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.braycurtis.html) [^1]                                    |       ✔️       |
| ``canberra_distances``           | [``scipy.spatial.distance.canberra``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.canberra.html) [^1]                                        |       ✔️       |
| ``jensenshannon_distances``      | [``scipy.spatial.distance.jensenshannon``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) [^1]                              |       ✔️       |
| ``yule_distances``               | [``scipy.spatial.distance.yule``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.yule.html) [^1]                                                |     ❌[^2]      |
| ``dice_distances``               | [``scipy.spatial.distance.dice``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.dice.html) [^1]                                                |     ❌[^2]      |
| ``rogerstanimoto_distances``     | [``scipy.spatial.distance.rogerstanimoto``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.rogerstanimoto.html) [^1]                            |     ❌[^2]      |
| ``russellrao_distances``         | [``scipy.spatial.distance.russellrao``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.russellrao.html) [^1]                                    |     ❌[^2]      |
| ``sokalmichener_distances``      | [``scipy.spatial.distance.sokalmichener``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.sokalmichener.html) [^1]                              |     ❌[^2]      |
| ``sokalsneath_distances``        | [``scipy.spatial.distance.sokalsneath``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.sokalsneath.html) [^1]                                  |     ❌[^2]      |
| ``snr_distances``                | [``pytorch_metric_learning.distances.SNRDistance``](https://kevinmusgrave.github.io/pytorch-metric-learning/distances/#snrdistance) [^1]                                     |       ✔️       |

[^1]: These metrics are not pairwise but a pairwise form can be computed by
calling ``scipy.spatial.distance.cdist(x1, x2, metric="[metric_name_or_callable]")``.

[^2]: These are boolean distances. ``hamming_distances`` can be applied for floating point inputs but involves
comparison.

### Other pairwise metrics or kernel functions

These metrics are usually used to compute kernel for machine learning algorithms.

| ``torchpairwise`` ops    | Equivalences in other libraries                                                                                                                           | Differentiable |
|:-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------:|
| ``linear_kernel``        | [``sklearn.metrics.pairwise.linear_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.linear_kernel.html)               |       ✔️       |
| ``polynomial_kernel``    | [``sklearn.metrics.pairwise.polynomial_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.polynomial_kernel.html)       |       ✔️       |
| ``sigmoid_kernel``       | [``sklearn.metrics.pairwise.sigmoid_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.sigmoid_kernel.html)             |       ✔️       |
| ``rbf_kernel``           | [``sklearn.metrics.pairwise.rbf_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.rbf_kernel.html)                     |       ✔️       |
| ``laplacian_kernel``     | [``sklearn.metrics.pairwise.laplacian_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.laplacian_kernel.html)         |       ✔️       |
| ``cosine_similarity``    | [``sklearn.metrics.pairwise.cosine_similarity``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_similarity.html)       |       ✔️       |
| ``additive_chi2_kernel`` | [``sklearn.metrics.pairwise.additive_chi2_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.additive_chi2_kernel.html) |       ✔️       |
| ``chi2_kernel``          | [``sklearn.metrics.pairwise.chi2_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.chi2_kernel.html)                   |       ✔️       |

### Custom ``cdist`` and ``pdist``

Furthermore, we provide a convenient wrapper function analoguous to ``torch.cdist`` excepts that it takes a string
``metric: str = "minkowski"`` indicating the desired metric to be used as the third argument,
and extra metric-specific arguments are passed as keywords.

```python
import torch, torchpairwise

# directed_hausdorff_distances is a pairwise 2d metric
x1 = torch.rand(10, 6, 3)
x2 = torch.rand(8, 5, 3)

generator = torch.Generator().manual_seed(1)
output = torchpairwise.cdist(x1, x2,
                             metric="directed_hausdorff",
                             shuffle=True,  # kwargs exclusive to directed_hausdorff
                             generator=generator)
```

Note that pairwise metrics on the second table are currently not allowed keys for ``cdist``
because they are not _dist_.
We have a similar plan for ``pdist`` (which is equivalent to calling ``cdist(x1, x1)`` but avoid storing duplicated
positions).
However, that requires a total overhaul of existing C++/Cuda kernels and won't be available soon.

## Future Improvements

- Add more metrics (contact me or create a feature request issue).
- Add memory-efficient ``argkmin`` for retrieving pairwise neighbors' distances and indices without storing the whole
  pairwise distance matrix.
- Add an equivalence of ``torch.pdist`` with ``metric: str = "minkowski"`` argument.
- (_Unlikely_) Support sparse layouts.

## Requirements

- Python 3.9+
- `torch>=2.5.0` (`torch>=1.9.0` if compiled from source)

## Installation

#### From PyPI:

To install prebuilt wheels from [torchpairwise](https://pypi.org/project/torchpairwise), simply run:

```console
pip install torchpairwise
```

Note that the Linux and Windows wheels in **PyPI** are compiled with ``torch==2.5.1`` and **Cuda 12.4**.
We only do a non-strict version checking and a warning will be raised if ``torch``'s and ``torchpairwise``'s
Cuda versions do not match.

#### From Source:

Make sure your machine has a C++17 and a Cuda compiler installed, then clone the repo and run:

```console
pip install .
```

## Usage

The basic usecase is very straight-forward if you are familiar with
``sklearn.metrics.pairwise`` and ``scipy.spatial.distance``:

<table>
<tr>
<th>scikit-learn / SciPy</th>
<th>TorchPairwise</th>
</tr>

<tr>
<td>
<sub>

```python
import numpy as np
import sklearn.metrics.pairwise as sklearn_pairwise

x1 = np.random.rand(10, 5)
x2 = np.random.rand(12, 5)

output = sklearn_pairwise.cosine_similarity(x1, x2)
print(output)
```

</sub>
<td>
<sub>

```python
import torch
import torchpairwise

x1 = torch.rand(10, 5, device='cuda')
x2 = torch.rand(12, 5, device='cuda')

output = torchpairwise.cosine_similarity(x1, x2)
print(output)
```

</sub>
</td>
</tr>

<tr>
<td>
<sub>

```python
import numpy as np
import scipy.spatial.distance as distance

x1 = np.random.binomial(
    1, p=0.6, size=(10, 5)).astype(np.bool_)
x2 = np.random.binomial(
    1, p=0.7, size=(12, 5)).astype(np.bool_)

output = distance.cdist(x1, x2, metric='jaccard')
print(output)
```

</sub>
<td>
<sub>

```python
import torch
import torchpairwise

x1 = torch.bernoulli(
    torch.full((10, 5), fill_value=0.6, device='cuda')).to(torch.bool)
x2 = torch.bernoulli(
    torch.full((12, 5), fill_value=0.7, device='cuda')).to(torch.bool)

output = torchpairwise.jaccard_distances(x1, x2)
print(output)
```

</sub>
</td>
</tr>

</table>

Please check the [tests](tests) folder where we will add more examples.

## License

The code is released under the MIT license. See [`LICENSE.txt`](LICENSE.txt) for details.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/inspiros/torchpairwise",
    "name": "torchpairwise",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "pairwise_metric, pairwise_distance, kernel_function",
    "author": "Hoang-Nhat Tran (inspiros)",
    "author_email": "hnhat.tran@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/58/19/327f32dccedc938e937ae6b8e2b4b4a040ba0b2a597d0f75d7f640f3fe7b/torchpairwise-0.2.0.tar.gz",
    "platform": null,
    "description": "TorchPairwise [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/inspiros/torchpairwise/build_wheels.yml)](https://github.com/inspiros/torchpairwise/actions) [![PyPI - Version](https://img.shields.io/pypi/v/torchpairwise)](https://pypi.org/project/torchpairwise/) [![Downloads](https://static.pepy.tech/badge/torchpairwise)](https://pepy.tech/project/torchpairwise) [![GitHub - License](https://img.shields.io/github/license/inspiros/torchpairwise)](LICENSE.txt)\n======\n\nThis package provides highly-efficient pairwise metrics for **PyTorch**.\n\n## Highlights\n\n``torchpairwise`` is a collection of **general purpose** pairwise metric functions that behave similar to\n``torch.cdist`` (which only implements $L_p$ distance).\nInstead, we offer a lot more metrics ported from other packages such as\n``scipy.spatial.distance`` and ``sklearn.metrics.pairwise``.\nFor task-specific metrics (e.g. for evaluation of classification, regression, clustering, ...), you should be in the\nwrong place, please head to the [TorchMetrics](https://github.com/Lightning-AI/torchmetrics) repo.\n\nWritten in ``torch``'s C++ API, the main differences are that our metrics:\n\n- are all (_except some boolean distances_) **differentiable** with backward formulas manually derived, implemented,\n  and verified with ``torch.autograd.gradcheck``.\n- are **batched** and can exploit GPU parallelization.\n- can be integrated seamlessly within **PyTorch**-based projects, all functions are ``torch.jit.script``-able.\n\n### List of pairwise distance metrics\n\n| ``torchpairwise`` ops            | Equivalences in other libraries                                                                                                                                              | Differentiable |\n|:---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------:|\n| ``euclidean_distances``          | [``sklearn.metrics.pairwise.euclidean_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.euclidean_distances.html)                      |       \u2714\ufe0f       |\n| ``haversine_distances``          | [``sklearn.metrics.pairwise.haversine_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.haversine_distances.html)                      |       \u2714\ufe0f       |\n| ``manhattan_distances``          | [``sklearn.metrics.pairwise.manhattan_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.manhattan_distances.html)                      |       \u2714\ufe0f       |\n| ``cosine_distances``             | [``sklearn.metrics.pairwise.cosine_distances``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_distances.html)                            |       \u2714\ufe0f       |\n| ``l1_distances``                 | _(Alias of ``manhattan_distances``)_                                                                                                                                         |       \u2714\ufe0f       |\n| ``l2_distances``                 | _(Alias of ``euclidean_distances``)_                                                                                                                                         |       \u2714\ufe0f       |\n| ``lp_distances``                 | _(Alias of ``minkowski_distances``)_                                                                                                                                         |       \u2714\ufe0f       |\n| ``linf_distances``               | _(Alias of ``chebyshev_distances``)_                                                                                                                                         |       \u2714\ufe0f       |\n| ``directed_hausdorff_distances`` | [``scipy.spatial.distance.directed_hausdorff``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.directed_hausdorff.html) [^1]                    |       \u2714\ufe0f       |\n| ``minkowski_distances``          | [``scipy.spatial.distance.minkowski``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.minkowski.html) [^1]                                      |       \u2714\ufe0f       |\n| ``wminkowski_distances``         | [``scipy.spatial.distance.wminkowski``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.wminkowski.html) [^1]                                    |       \u2714\ufe0f       |\n| ``sqeuclidean_distances``        | [``scipy.spatial.distance.sqeuclidean_distances``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.sqeuclidean_distances.html) [^1]              |       \u2714\ufe0f       |\n| ``correlation_distances``        | [``scipy.spatial.distance.correlation``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.correlation.html) [^1]                                  |       \u2714\ufe0f       |\n| ``hamming_distances``            | [``scipy.spatial.distance.hamming``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.hamming.html) [^1]                                          |     \u274c[^2]      |\n| ``jaccard_distances``            | [``scipy.spatial.distance.jaccard``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jaccard.html) [^1]                                          |     \u274c[^2]      |\n| ``kulsinski_distances``          | [``scipy.spatial.distance.kulsinski``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.kulsinski.html) [^1]                                      |     \u274c[^2]      |\n| ``kulczynski1_distances``        | [``scipy.spatial.distance.kulczynski1``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.kulczynski1.html) [^1]                                  |     \u274c[^2]      |\n| ``seuclidean_distances``         | [``scipy.spatial.distance.seuclidean``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.seuclidean.html) [^1]                                    |       \u2714\ufe0f       |\n| ``cityblock_distances``          | [``scipy.spatial.distance.cityblock``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cityblock.html) [^1] _(Alias of ``manhattan_distances``)_ |       \u2714\ufe0f       |\n| ``mahalanobis_distances``        | [``scipy.spatial.distance.mahalanobis``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.mahalanobis.html) [^1]                                  |       \u2714\ufe0f       |\n| ``chebyshev_distances``          | [``scipy.spatial.distance.chebyshev``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.chebyshev.html) [^1]                                      |       \u2714\ufe0f       |\n| ``braycurtis_distances``         | [``scipy.spatial.distance.braycurtis``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.braycurtis.html) [^1]                                    |       \u2714\ufe0f       |\n| ``canberra_distances``           | [``scipy.spatial.distance.canberra``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.canberra.html) [^1]                                        |       \u2714\ufe0f       |\n| ``jensenshannon_distances``      | [``scipy.spatial.distance.jensenshannon``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) [^1]                              |       \u2714\ufe0f       |\n| ``yule_distances``               | [``scipy.spatial.distance.yule``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.yule.html) [^1]                                                |     \u274c[^2]      |\n| ``dice_distances``               | [``scipy.spatial.distance.dice``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.dice.html) [^1]                                                |     \u274c[^2]      |\n| ``rogerstanimoto_distances``     | [``scipy.spatial.distance.rogerstanimoto``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.rogerstanimoto.html) [^1]                            |     \u274c[^2]      |\n| ``russellrao_distances``         | [``scipy.spatial.distance.russellrao``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.russellrao.html) [^1]                                    |     \u274c[^2]      |\n| ``sokalmichener_distances``      | [``scipy.spatial.distance.sokalmichener``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.sokalmichener.html) [^1]                              |     \u274c[^2]      |\n| ``sokalsneath_distances``        | [``scipy.spatial.distance.sokalsneath``](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.sokalsneath.html) [^1]                                  |     \u274c[^2]      |\n| ``snr_distances``                | [``pytorch_metric_learning.distances.SNRDistance``](https://kevinmusgrave.github.io/pytorch-metric-learning/distances/#snrdistance) [^1]                                     |       \u2714\ufe0f       |\n\n[^1]: These metrics are not pairwise but a pairwise form can be computed by\ncalling ``scipy.spatial.distance.cdist(x1, x2, metric=\"[metric_name_or_callable]\")``.\n\n[^2]: These are boolean distances. ``hamming_distances`` can be applied for floating point inputs but involves\ncomparison.\n\n### Other pairwise metrics or kernel functions\n\nThese metrics are usually used to compute kernel for machine learning algorithms.\n\n| ``torchpairwise`` ops    | Equivalences in other libraries                                                                                                                           | Differentiable |\n|:-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------:|\n| ``linear_kernel``        | [``sklearn.metrics.pairwise.linear_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.linear_kernel.html)               |       \u2714\ufe0f       |\n| ``polynomial_kernel``    | [``sklearn.metrics.pairwise.polynomial_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.polynomial_kernel.html)       |       \u2714\ufe0f       |\n| ``sigmoid_kernel``       | [``sklearn.metrics.pairwise.sigmoid_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.sigmoid_kernel.html)             |       \u2714\ufe0f       |\n| ``rbf_kernel``           | [``sklearn.metrics.pairwise.rbf_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.rbf_kernel.html)                     |       \u2714\ufe0f       |\n| ``laplacian_kernel``     | [``sklearn.metrics.pairwise.laplacian_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.laplacian_kernel.html)         |       \u2714\ufe0f       |\n| ``cosine_similarity``    | [``sklearn.metrics.pairwise.cosine_similarity``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_similarity.html)       |       \u2714\ufe0f       |\n| ``additive_chi2_kernel`` | [``sklearn.metrics.pairwise.additive_chi2_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.additive_chi2_kernel.html) |       \u2714\ufe0f       |\n| ``chi2_kernel``          | [``sklearn.metrics.pairwise.chi2_kernel``](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.chi2_kernel.html)                   |       \u2714\ufe0f       |\n\n### Custom ``cdist`` and ``pdist``\n\nFurthermore, we provide a convenient wrapper function analoguous to ``torch.cdist`` excepts that it takes a string\n``metric: str = \"minkowski\"`` indicating the desired metric to be used as the third argument,\nand extra metric-specific arguments are passed as keywords.\n\n```python\nimport torch, torchpairwise\n\n# directed_hausdorff_distances is a pairwise 2d metric\nx1 = torch.rand(10, 6, 3)\nx2 = torch.rand(8, 5, 3)\n\ngenerator = torch.Generator().manual_seed(1)\noutput = torchpairwise.cdist(x1, x2,\n                             metric=\"directed_hausdorff\",\n                             shuffle=True,  # kwargs exclusive to directed_hausdorff\n                             generator=generator)\n```\n\nNote that pairwise metrics on the second table are currently not allowed keys for ``cdist``\nbecause they are not _dist_.\nWe have a similar plan for ``pdist`` (which is equivalent to calling ``cdist(x1, x1)`` but avoid storing duplicated\npositions).\nHowever, that requires a total overhaul of existing C++/Cuda kernels and won't be available soon.\n\n## Future Improvements\n\n- Add more metrics (contact me or create a feature request issue).\n- Add memory-efficient ``argkmin`` for retrieving pairwise neighbors' distances and indices without storing the whole\n  pairwise distance matrix.\n- Add an equivalence of ``torch.pdist`` with ``metric: str = \"minkowski\"`` argument.\n- (_Unlikely_) Support sparse layouts.\n\n## Requirements\n\n- Python 3.9+\n- `torch>=2.5.0` (`torch>=1.9.0` if compiled from source)\n\n## Installation\n\n#### From PyPI:\n\nTo install prebuilt wheels from [torchpairwise](https://pypi.org/project/torchpairwise), simply run:\n\n```console\npip install torchpairwise\n```\n\nNote that the Linux and Windows wheels in **PyPI** are compiled with ``torch==2.5.1`` and **Cuda 12.4**.\nWe only do a non-strict version checking and a warning will be raised if ``torch``'s and ``torchpairwise``'s\nCuda versions do not match.\n\n#### From Source:\n\nMake sure your machine has a C++17 and a Cuda compiler installed, then clone the repo and run:\n\n```console\npip install .\n```\n\n## Usage\n\nThe basic usecase is very straight-forward if you are familiar with\n``sklearn.metrics.pairwise`` and ``scipy.spatial.distance``:\n\n<table>\n<tr>\n<th>scikit-learn / SciPy</th>\n<th>TorchPairwise</th>\n</tr>\n\n<tr>\n<td>\n<sub>\n\n```python\nimport numpy as np\nimport sklearn.metrics.pairwise as sklearn_pairwise\n\nx1 = np.random.rand(10, 5)\nx2 = np.random.rand(12, 5)\n\noutput = sklearn_pairwise.cosine_similarity(x1, x2)\nprint(output)\n```\n\n</sub>\n<td>\n<sub>\n\n```python\nimport torch\nimport torchpairwise\n\nx1 = torch.rand(10, 5, device='cuda')\nx2 = torch.rand(12, 5, device='cuda')\n\noutput = torchpairwise.cosine_similarity(x1, x2)\nprint(output)\n```\n\n</sub>\n</td>\n</tr>\n\n<tr>\n<td>\n<sub>\n\n```python\nimport numpy as np\nimport scipy.spatial.distance as distance\n\nx1 = np.random.binomial(\n    1, p=0.6, size=(10, 5)).astype(np.bool_)\nx2 = np.random.binomial(\n    1, p=0.7, size=(12, 5)).astype(np.bool_)\n\noutput = distance.cdist(x1, x2, metric='jaccard')\nprint(output)\n```\n\n</sub>\n<td>\n<sub>\n\n```python\nimport torch\nimport torchpairwise\n\nx1 = torch.bernoulli(\n    torch.full((10, 5), fill_value=0.6, device='cuda')).to(torch.bool)\nx2 = torch.bernoulli(\n    torch.full((12, 5), fill_value=0.7, device='cuda')).to(torch.bool)\n\noutput = torchpairwise.jaccard_distances(x1, x2)\nprint(output)\n```\n\n</sub>\n</td>\n</tr>\n\n</table>\n\nPlease check the [tests](tests) folder where we will add more examples.\n\n## License\n\nThe code is released under the MIT license. See [`LICENSE.txt`](LICENSE.txt) for details.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Pairwise Metrics for PyTorch",
    "version": "0.2.0",
    "project_urls": {
        "Homepage": "https://github.com/inspiros/torchpairwise",
        "Source": "https://github.com/inspiros/torchpairwise"
    },
    "split_keywords": [
        "pairwise_metric",
        " pairwise_distance",
        " kernel_function"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2627a597fbd7764154dd144723b3e943e98f574dd40a8f7b3afcf87397cc25ab",
                "md5": "5aefdf44490273a36288e116b78d1de7",
                "sha256": "5b48e64c2258b24a0f58f1c6988215c14641f9a3f91bd216116c21dea3b06928"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp310-cp310-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "5aefdf44490273a36288e116b78d1de7",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 670417,
            "upload_time": "2025-01-19T23:33:46",
            "upload_time_iso_8601": "2025-01-19T23:33:46.066123Z",
            "url": "https://files.pythonhosted.org/packages/26/27/a597fbd7764154dd144723b3e943e98f574dd40a8f7b3afcf87397cc25ab/torchpairwise-0.2.0-cp310-cp310-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3a362e4829188ade8505e1a61dbf3a05233e9824e909805c1d75ddafbcae4344",
                "md5": "a3b9b5cc7a1661f5aceec46f2976d766",
                "sha256": "3b6d958c72b61432b708d5ecdccfc12a62cb73a25e5ea895f40e4961ed40542c"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "a3b9b5cc7a1661f5aceec46f2976d766",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 48564689,
            "upload_time": "2025-01-19T23:33:50",
            "upload_time_iso_8601": "2025-01-19T23:33:50.366004Z",
            "url": "https://files.pythonhosted.org/packages/3a/36/2e4829188ade8505e1a61dbf3a05233e9824e909805c1d75ddafbcae4344/torchpairwise-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "423d8c3f18289faf812c886227e5854767c099be2ebdf73ab6a32d2be3c95836",
                "md5": "71511f550e4b4b721edbd36677025fbc",
                "sha256": "37cf0e988a74770de17588d1e781ae836ddeb51f1ac12431074f5311de916ab8"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "71511f550e4b4b721edbd36677025fbc",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.9",
            "size": 16504977,
            "upload_time": "2025-01-19T23:33:55",
            "upload_time_iso_8601": "2025-01-19T23:33:55.479122Z",
            "url": "https://files.pythonhosted.org/packages/42/3d/8c3f18289faf812c886227e5854767c099be2ebdf73ab6a32d2be3c95836/torchpairwise-0.2.0-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cf15f092c202d439c58c78d39c1ba1ce62ba19a74bd7fcb7176820410e2c0941",
                "md5": "3fdfd0b25e715a8b25dc5604b9ed21ad",
                "sha256": "888c8a276dd0548f52bf37b4baa705d7c1e73a1aa2e3a5f3d99460cda3118627"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp311-cp311-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "3fdfd0b25e715a8b25dc5604b9ed21ad",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 670422,
            "upload_time": "2025-01-19T23:33:58",
            "upload_time_iso_8601": "2025-01-19T23:33:58.328699Z",
            "url": "https://files.pythonhosted.org/packages/cf/15/f092c202d439c58c78d39c1ba1ce62ba19a74bd7fcb7176820410e2c0941/torchpairwise-0.2.0-cp311-cp311-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "20277d5784ffaa5582ffaab2bd9b8bd2057bfb779a385167dea0cab79a839344",
                "md5": "ccecde15addb16ee1d265bf27f26062b",
                "sha256": "d2559608ae6a43b5f37920949e99eb5588588fccc4eb272a61d44426fd9bb9a2"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "ccecde15addb16ee1d265bf27f26062b",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 48564901,
            "upload_time": "2025-01-19T23:34:02",
            "upload_time_iso_8601": "2025-01-19T23:34:02.497521Z",
            "url": "https://files.pythonhosted.org/packages/20/27/7d5784ffaa5582ffaab2bd9b8bd2057bfb779a385167dea0cab79a839344/torchpairwise-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "910f5fe0457b3856a572c9c58bbe49decae7d861bce14f6fe84ecabbd7c3773d",
                "md5": "b22d556d9a7fc4625d0e3b70b47854f1",
                "sha256": "0466b0aca97982c461a4e200df19d342f0177dfb5c8772862a3bb5b572ac056b"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "b22d556d9a7fc4625d0e3b70b47854f1",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.9",
            "size": 16505709,
            "upload_time": "2025-01-19T23:34:07",
            "upload_time_iso_8601": "2025-01-19T23:34:07.557066Z",
            "url": "https://files.pythonhosted.org/packages/91/0f/5fe0457b3856a572c9c58bbe49decae7d861bce14f6fe84ecabbd7c3773d/torchpairwise-0.2.0-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "107f5191c4b498edbf55852c5ad58ee2d7542cac3d43ba0279930cc0c1303a3b",
                "md5": "4acae1f2bc150909c605035d39b2a743",
                "sha256": "4b466ba1cd6a492d70341e24fb100580862e1b5dcfc9e126aa519fc7b494b870"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp312-cp312-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "4acae1f2bc150909c605035d39b2a743",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 670428,
            "upload_time": "2025-01-19T23:34:10",
            "upload_time_iso_8601": "2025-01-19T23:34:10.548977Z",
            "url": "https://files.pythonhosted.org/packages/10/7f/5191c4b498edbf55852c5ad58ee2d7542cac3d43ba0279930cc0c1303a3b/torchpairwise-0.2.0-cp312-cp312-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5abeadc41df91b4e95d3b503606c0ee03d50974664a6ffb83da3e1c8792a5ca4",
                "md5": "5931eb6068d1df11a385bd61bf88546a",
                "sha256": "730a94a9bd00b89cd9a2a0720a1492f59fee58af0708ab6425f1da0bb5dc056f"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "5931eb6068d1df11a385bd61bf88546a",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 48577529,
            "upload_time": "2025-01-19T23:34:14",
            "upload_time_iso_8601": "2025-01-19T23:34:14.747856Z",
            "url": "https://files.pythonhosted.org/packages/5a/be/adc41df91b4e95d3b503606c0ee03d50974664a6ffb83da3e1c8792a5ca4/torchpairwise-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "056afff0b11caacf234d6d8030227e3a22457e2f5823858eaa6720fe4255d75f",
                "md5": "e1c1a729869427f0c3f7fac3483e73ec",
                "sha256": "80238f46f730b4dbce71260c15d1fae446b9cffa49965ae78fa68be873653623"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "e1c1a729869427f0c3f7fac3483e73ec",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": ">=3.9",
            "size": 16505407,
            "upload_time": "2025-01-19T23:34:23",
            "upload_time_iso_8601": "2025-01-19T23:34:23.358912Z",
            "url": "https://files.pythonhosted.org/packages/05/6a/fff0b11caacf234d6d8030227e3a22457e2f5823858eaa6720fe4255d75f/torchpairwise-0.2.0-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a8bd13485ee416f0af9be4911703847522885fbcf130aad04a745a82743919a6",
                "md5": "9474fd17905b075853320c06de4d0f7f",
                "sha256": "734fecd504c1250c6681ae99b87c50aadbfa54ac0c95d44d424b9cb1fd2435c9"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "9474fd17905b075853320c06de4d0f7f",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": ">=3.9",
            "size": 48577852,
            "upload_time": "2025-01-19T23:34:29",
            "upload_time_iso_8601": "2025-01-19T23:34:29.572463Z",
            "url": "https://files.pythonhosted.org/packages/a8/bd/13485ee416f0af9be4911703847522885fbcf130aad04a745a82743919a6/torchpairwise-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "55c1a735a01e25c0c4c0ead3bccc48e57d1a4cc5f3b712608cc161e0a7fe8239",
                "md5": "1b690ff66c8ec62f4d436c16b0bb8ef5",
                "sha256": "76fb30b09d223d53c0878a523ca96e7e8a6014f8ba2907f5cab8e10370b76726"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp39-cp39-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "1b690ff66c8ec62f4d436c16b0bb8ef5",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 670361,
            "upload_time": "2025-01-19T23:34:34",
            "upload_time_iso_8601": "2025-01-19T23:34:34.339786Z",
            "url": "https://files.pythonhosted.org/packages/55/c1/a735a01e25c0c4c0ead3bccc48e57d1a4cc5f3b712608cc161e0a7fe8239/torchpairwise-0.2.0-cp39-cp39-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "34479f34c61e8fbef321d9b5832487b0149aef585562f0457285dedfbca4ba52",
                "md5": "69faf538d213ff7e2ad9f6fd431a45ad",
                "sha256": "a36a860faa29ebe8f2bb760b12ab138e923218fdcbe2e5476962771cedc08f2e"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "69faf538d213ff7e2ad9f6fd431a45ad",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 48564572,
            "upload_time": "2025-01-19T23:34:38",
            "upload_time_iso_8601": "2025-01-19T23:34:38.999764Z",
            "url": "https://files.pythonhosted.org/packages/34/47/9f34c61e8fbef321d9b5832487b0149aef585562f0457285dedfbca4ba52/torchpairwise-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8daff8a9b9c38165397178b93ebdbecf5f3618782029a0784256ed4a54f794a7",
                "md5": "2adb4c3f24dddb39ed4a43fdbcc79dab",
                "sha256": "5e6fc9443e8eb34d9c76968be54e7ce63888036805c47c72ed43856e879ae65c"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "2adb4c3f24dddb39ed4a43fdbcc79dab",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.9",
            "size": 16504906,
            "upload_time": "2025-01-19T23:34:46",
            "upload_time_iso_8601": "2025-01-19T23:34:46.233903Z",
            "url": "https://files.pythonhosted.org/packages/8d/af/f8a9b9c38165397178b93ebdbecf5f3618782029a0784256ed4a54f794a7/torchpairwise-0.2.0-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5819327f32dccedc938e937ae6b8e2b4b4a040ba0b2a597d0f75d7f640f3fe7b",
                "md5": "ef93afb449174f6e2db2b49d6ccbc4d8",
                "sha256": "d890d6647c10e6a3dcf752081adec2ab14a186c459cac13126d24aa122fa3fde"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "ef93afb449174f6e2db2b49d6ccbc4d8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 52141,
            "upload_time": "2025-01-19T23:34:49",
            "upload_time_iso_8601": "2025-01-19T23:34:49.779637Z",
            "url": "https://files.pythonhosted.org/packages/58/19/327f32dccedc938e937ae6b8e2b4b4a040ba0b2a597d0f75d7f640f3fe7b/torchpairwise-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-19 23:34:49",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "inspiros",
    "github_project": "torchpairwise",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "torch",
            "specs": [
                [
                    ">=",
                    "2.5.0"
                ]
            ]
        }
    ],
    "lcname": "torchpairwise"
}
        
Elapsed time: 1.41518s