torchpairwise


Nametorchpairwise JSON
Version 0.1.1 PyPI version JSON
download
home_pagehttps://github.com/inspiros/torchpairwise
SummaryPairwise Metrics for PyTorch
upload_time2023-10-16 10:16:13
maintainer
docs_urlNone
authorHoang-Nhat Tran (inspiros)
requires_python>=3.8
licenseMIT
keywords pairwise_metric pairwise_distance kernel_function
VCS
bugtrack_url
requirements No requirements were recorded.
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**.

## News
- **v0.1.1:** Added **SNR** distance (``torchpairwise.snr_distances``) presented in https://arxiv.org/abs/1904.02616.

## 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

- `torch>=2.1.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.1.0`` and **Cuda 12.1**.
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": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "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/c3/a2/ab7a2ed4e179b681223ba43fb1cf4ab55b3970182f641ce49d4afe4a8594/torchpairwise-0.1.1.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## News\n- **v0.1.1:** Added **SNR** distance (``torchpairwise.snr_distances``) presented in https://arxiv.org/abs/1904.02616.\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- `torch>=2.1.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.1.0`` and **Cuda 12.1**.\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.1.1",
    "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": "1b0ca7a41fc8d421f13062a0b413ced31ed4ce320e237301c2a8e478615876e7",
                "md5": "430550290f199dc0bc19268458a9d677",
                "sha256": "1d104d18e02c6a5fe11bdc6751cd0aac6c597287f5dbb3b4ab1a17f528dbbb2b"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp310-cp310-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "430550290f199dc0bc19268458a9d677",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 757518,
            "upload_time": "2023-10-16T10:15:36",
            "upload_time_iso_8601": "2023-10-16T10:15:36.077607Z",
            "url": "https://files.pythonhosted.org/packages/1b/0c/a7a41fc8d421f13062a0b413ced31ed4ce320e237301c2a8e478615876e7/torchpairwise-0.1.1-cp310-cp310-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5031f3777fec5a33481a487d11799370450766d9ba4d85f720e5aee3896dc9c6",
                "md5": "c28887ba903236d37b5fe134e54624d4",
                "sha256": "ecbbe463f184dee1fba97d5820cec6cf8397ea38420d7ab9328036e8c78f27a8"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c28887ba903236d37b5fe134e54624d4",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 45416291,
            "upload_time": "2023-10-16T10:15:39",
            "upload_time_iso_8601": "2023-10-16T10:15:39.069293Z",
            "url": "https://files.pythonhosted.org/packages/50/31/f3777fec5a33481a487d11799370450766d9ba4d85f720e5aee3896dc9c6/torchpairwise-0.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fc58fce93960091c4c77f4ea05e3b2b8201c70116d2edcaada5d104771db1027",
                "md5": "967d4b565c94edc9b32248c2e21ced63",
                "sha256": "29f6171a0650522864aae5701b9234156ad197938679c0ead54e07c1b2835c7b"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "967d4b565c94edc9b32248c2e21ced63",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": ">=3.8",
            "size": 16449907,
            "upload_time": "2023-10-16T10:15:43",
            "upload_time_iso_8601": "2023-10-16T10:15:43.206707Z",
            "url": "https://files.pythonhosted.org/packages/fc/58/fce93960091c4c77f4ea05e3b2b8201c70116d2edcaada5d104771db1027/torchpairwise-0.1.1-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "95bbf3033c06c24a1158f04ed38b6900c354259ccc4c5a5b8dd89dd49365cad0",
                "md5": "4a75dce6adeb4c6f6fdba7f84e3ae437",
                "sha256": "7bad619bd7888e1a8561758f981af1fa9f447fdf453378dcc227f1e206567de5"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp311-cp311-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "4a75dce6adeb4c6f6fdba7f84e3ae437",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 757517,
            "upload_time": "2023-10-16T10:15:45",
            "upload_time_iso_8601": "2023-10-16T10:15:45.710166Z",
            "url": "https://files.pythonhosted.org/packages/95/bb/f3033c06c24a1158f04ed38b6900c354259ccc4c5a5b8dd89dd49365cad0/torchpairwise-0.1.1-cp311-cp311-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "24dfa68ee15e46d590872d3e7f2cb1cddcb04abdc79fc5438946a5cb352a11ed",
                "md5": "edefe85482e8a6dc2bdc03880aa539cf",
                "sha256": "62a45a155a56e2f46e89ac1870dae7ce87102f421c84d0ea0a2df2af6c2afd4f"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "edefe85482e8a6dc2bdc03880aa539cf",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 45417416,
            "upload_time": "2023-10-16T10:15:48",
            "upload_time_iso_8601": "2023-10-16T10:15:48.777033Z",
            "url": "https://files.pythonhosted.org/packages/24/df/a68ee15e46d590872d3e7f2cb1cddcb04abdc79fc5438946a5cb352a11ed/torchpairwise-0.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "214afd642ef680974691b3dbe4d2a8f2a906b074fabe1fd16dc5f77e6219e785",
                "md5": "f216630e014f077ca307b290cb99cecb",
                "sha256": "26a555ac644f45db2928fc3e3c685cf3bc379910cf524276656b576877c98d08"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "f216630e014f077ca307b290cb99cecb",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": ">=3.8",
            "size": 16449656,
            "upload_time": "2023-10-16T10:15:52",
            "upload_time_iso_8601": "2023-10-16T10:15:52.393278Z",
            "url": "https://files.pythonhosted.org/packages/21/4a/fd642ef680974691b3dbe4d2a8f2a906b074fabe1fd16dc5f77e6219e785/torchpairwise-0.1.1-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4ac6e604bfb200cf064eef4de6cf9872c3e7a1195e75829aa94ca7606cf93274",
                "md5": "c1caa28c8f0a7238f0dd22d29f395466",
                "sha256": "416d46a1b1e615d0fe31dfafadcec72cc8b4a2834ac9833288214870ba3ef1ba"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp38-cp38-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c1caa28c8f0a7238f0dd22d29f395466",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.8",
            "size": 757492,
            "upload_time": "2023-10-16T10:15:55",
            "upload_time_iso_8601": "2023-10-16T10:15:55.044677Z",
            "url": "https://files.pythonhosted.org/packages/4a/c6/e604bfb200cf064eef4de6cf9872c3e7a1195e75829aa94ca7606cf93274/torchpairwise-0.1.1-cp38-cp38-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8353f174de1762dfe70b3df61b5f3c08f2f62fcbee1ddb794cb5ae9b056729aa",
                "md5": "c246a1c18eb3d049d0f7a10fb64f9cd5",
                "sha256": "32fcb746485e4d139bd2b92fd3184287db0cb8421109ffe9e9c7285abf35bf28"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "c246a1c18eb3d049d0f7a10fb64f9cd5",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.8",
            "size": 45416137,
            "upload_time": "2023-10-16T10:15:57",
            "upload_time_iso_8601": "2023-10-16T10:15:57.442186Z",
            "url": "https://files.pythonhosted.org/packages/83/53/f174de1762dfe70b3df61b5f3c08f2f62fcbee1ddb794cb5ae9b056729aa/torchpairwise-0.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "834d1505accd1b931edac22b68047865b121135ecc83b341a06b73914be90504",
                "md5": "6a10cd26152598ee2ee3a922546dcdd0",
                "sha256": "42cac2c1b73496c7b7349197a68a52a3e36037f9ed20d4d0ab81ef8f19ef1e8a"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp38-cp38-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "6a10cd26152598ee2ee3a922546dcdd0",
            "packagetype": "bdist_wheel",
            "python_version": "cp38",
            "requires_python": ">=3.8",
            "size": 16450327,
            "upload_time": "2023-10-16T10:16:01",
            "upload_time_iso_8601": "2023-10-16T10:16:01.492384Z",
            "url": "https://files.pythonhosted.org/packages/83/4d/1505accd1b931edac22b68047865b121135ecc83b341a06b73914be90504/torchpairwise-0.1.1-cp38-cp38-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5e1825ba537df84b37b068bcd0c17d8b8fdf6fdf4a3876fe6bcf43522cc66d25",
                "md5": "b2575eee3330adfdf3e0aa84979ad90e",
                "sha256": "a568f0e7facb6c4034422f732d2a535563e78b43c4d292dbe5c964af6498b120"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp39-cp39-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "b2575eee3330adfdf3e0aa84979ad90e",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.8",
            "size": 757493,
            "upload_time": "2023-10-16T10:16:03",
            "upload_time_iso_8601": "2023-10-16T10:16:03.996438Z",
            "url": "https://files.pythonhosted.org/packages/5e/18/25ba537df84b37b068bcd0c17d8b8fdf6fdf4a3876fe6bcf43522cc66d25/torchpairwise-0.1.1-cp39-cp39-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bf2f00b28d4fe8a6297aca6e14cc9a96a0a37c7b46bd9b5f0f2a3e3cb2f694ee",
                "md5": "f8408827fdc4f7b1f7f614a2c455bc01",
                "sha256": "dd8c18c39b1d1301fd54fdb306b90e37dda6680441a8d5340b00501067762658"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "f8408827fdc4f7b1f7f614a2c455bc01",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.8",
            "size": 45416786,
            "upload_time": "2023-10-16T10:16:06",
            "upload_time_iso_8601": "2023-10-16T10:16:06.835622Z",
            "url": "https://files.pythonhosted.org/packages/bf/2f/00b28d4fe8a6297aca6e14cc9a96a0a37c7b46bd9b5f0f2a3e3cb2f694ee/torchpairwise-0.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7601136fbac0c6af1680c36d0fd8b3520d5de9c253cffff68a10cc962e107180",
                "md5": "d3a9637d3a800807643f019498f5ef7b",
                "sha256": "905cc6671cdd3641316d00a7c40c25d22988e49ec57a96a1236d16903ecc2038"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "d3a9637d3a800807643f019498f5ef7b",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": ">=3.8",
            "size": 16450062,
            "upload_time": "2023-10-16T10:16:11",
            "upload_time_iso_8601": "2023-10-16T10:16:11.034053Z",
            "url": "https://files.pythonhosted.org/packages/76/01/136fbac0c6af1680c36d0fd8b3520d5de9c253cffff68a10cc962e107180/torchpairwise-0.1.1-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c3a2ab7a2ed4e179b681223ba43fb1cf4ab55b3970182f641ce49d4afe4a8594",
                "md5": "e8e3bd32d6a0fcf5828592851ba5365e",
                "sha256": "ee8a766e361ec5364df84160748debd1da4c9ec9408d4a6b74060bfeeda78b8a"
            },
            "downloads": -1,
            "filename": "torchpairwise-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "e8e3bd32d6a0fcf5828592851ba5365e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 50444,
            "upload_time": "2023-10-16T10:16:13",
            "upload_time_iso_8601": "2023-10-16T10:16:13.263726Z",
            "url": "https://files.pythonhosted.org/packages/c3/a2/ab7a2ed4e179b681223ba43fb1cf4ab55b3970182f641ce49d4afe4a8594/torchpairwise-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-16 10:16:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "inspiros",
    "github_project": "torchpairwise",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "torchpairwise"
}
        
Elapsed time: 0.16120s