Skip to content

Commit 1e11dc3

Browse files
committed
Merge branch 'release/0.6.0' into main
2 parents e9fb657 + bada206 commit 1e11dc3

28 files changed

+495
-454
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: [wmayner]

.github/workflows/build_wheels.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Build wheels & run tests
2+
3+
on: ['push', 'pull_request']
4+
5+
jobs:
6+
build_wheels:
7+
name: Build wheels on ${{ matrix.os }}
8+
runs-on: ${{ matrix.os }}
9+
strategy:
10+
matrix:
11+
os: [ubuntu-20.04, windows-2019, macos-11]
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
with:
16+
fetch-depth: 0
17+
18+
- name: Build wheels
19+
uses: pypa/cibuildwheel@v2.12.0
20+
with:
21+
package-dir: .
22+
output-dir: wheelhouse
23+
config-file: "{package}/pyproject.toml"
24+
25+
- uses: actions/upload-artifact@v3
26+
with:
27+
path: ./wheelhouse/*.whl

.github/workflows/make_sdist.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Make source distribution
2+
3+
on: ['push', 'pull_request']
4+
5+
jobs:
6+
make_sdist:
7+
name: Make source distribution
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
with:
12+
fetch-depth: 0
13+
14+
- name: Build source distribution
15+
run: pipx run build --sdist
16+
17+
- uses: actions/upload-artifact@v3
18+
with:
19+
path: dist/*.tar.gz

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
__pycache__
22
.gitconfig
33
.cache
4+
.pytest_cache
45
.tox
56
.env
67
.ropeproject
78
*.so
89
*.pyc
910
MANIFEST
1011
*.egg*
12+
src/pyemd/emd.cpp
13+
src/pyemd/_version.py
1114
build
1215
dist
13-
pyemd/emd.cpp
16+
wheelhouse
17+
ignore

.travis.yml

Lines changed: 0 additions & 20 deletions
This file was deleted.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2014-2017 Will Mayner
1+
Copyright (c) 2014-2023 Will Mayner
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy
44
of this software and associated documentation files (the "Software"), to deal

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
graft pyemd
1+
graft src/pyemd
22
graft test
33

44
include README.rst

Makefile

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,49 @@
1-
.PHONY: default test build clean dist test-dist check-dist build-dist clean-dist
1+
.PHONY: default clean develop test dist-clean build-local build dist-upload dist-test-upload dist-sign dist-check
22

3-
src = pyemd
4-
dist_dir = dist
3+
src = src/pyemd
4+
test = test
5+
dist = dist
6+
wheelhouse = wheelhouse
57

6-
default: build
8+
default: test
79

8-
test: build
10+
test: develop
911
py.test
1012

11-
build: clean
12-
python setup.py build_ext -b .
13+
develop: clean
14+
python -m pip install -e ".[test,dist]"
1315

1416
clean:
15-
rm -f pyemd/*.so
17+
rm -rf $(shell find . -name '__pycache__')
18+
rm -rf $(shell find . -name '*.so')
19+
rm -rf .eggs
20+
rm -rf pyemd.egg-info
21+
rm -rf build
1622

17-
dist: build-dist check-dist
18-
twine upload $(dist_dir)/*
23+
dist-build-local:
24+
python -m build
1925

20-
test-dist: build-dist check-dist
21-
twine upload --repository-url https://test.pypi.org/legacy/ $(dist_dir)/*
26+
dist-build-wheels:
27+
cibuildwheel --platform linux --config-file pyproject.toml
2228

23-
check-dist:
24-
python setup.py check --restructuredtext --strict
29+
dist-upload: dist-sign
30+
twine upload $(dist)/*
31+
twine upload $(wheelhouse)/*
2532

26-
build-dist: clean-dist
27-
python setup.py sdist bdist_wheel --dist-dir=$(dist_dir)
33+
dist-test-upload: dist-check
34+
twine upload --repository-url https://test.pypi.org/simple/ testpypi $(dist)/*
35+
twine upload --repository-url https://test.pypi.org/simple/ testpypi $(wheelhouse)/*
2836

29-
clean-dist:
30-
rm -rf $(dist_dir)
37+
dist-sign: dist-check
38+
gpg --detach-sign -a $(dist)/*.tar.gz
39+
gpg --detach-sign -a $(wheelhouse)/*.whl
40+
41+
dist-check:
42+
twine check --strict $(dist)/*
43+
twine check --strict $(wheelhouse)/*
44+
45+
dist-clean:
46+
rm -rf $(dist)
47+
48+
dist-test-install:
49+
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple pyemd

README.rst

Lines changed: 46 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
.. image:: https://img.shields.io/travis/wmayner/pyemd/develop.svg?style=flat-square&maxAge=3600
2-
:target: https://travis-ci.org/wmayner/pyemd
1+
.. image:: https://img.shields.io/github/actions/workflow/status/wmayner/pyemd/build_wheels.yml?style=flat-square&maxAge=86400
2+
:target: https://github.com/wmayner/pyemd/actions/workflows/build_wheels.yml
3+
:alt: Build status badge
34
.. image:: https://img.shields.io/pypi/pyversions/pyemd.svg?style=flat-square&maxAge=86400
4-
:target: https://wiki.python.org/moin/Python2orPython3
5+
:target: https://pypi.org/project/pyemd/
56
:alt: Python versions badge
67

78
PyEMD: Fast EMD for Python
89
==========================
910

1011
PyEMD is a Python wrapper for `Ofir Pele and Michael Werman's implementation
11-
<http://ofirpele.droppages.com/>`_ of the `Earth Mover's
12-
Distance <http://en.wikipedia.org/wiki/Earth_mover%27s_distance>`_ that allows
12+
<https://ofirpele.droppages.com/>`_ of the `Earth Mover's
13+
Distance <https://en.wikipedia.org/wiki/Earth_mover%27s_distance>`_ that allows
1314
it to be used with NumPy. **If you use this code, please cite the papers listed
1415
at the end of this document.**
1516

@@ -54,8 +55,9 @@ You can also calculate the EMD directly from two arrays of observations:
5455
>>> emd_samples(first_array, second_array, bins=2)
5556
0.5
5657
57-
Documentation
58-
-------------
58+
59+
API Documentation
60+
-----------------
5961

6062
emd()
6163
~~~~~
@@ -75,17 +77,17 @@ emd()
7577
*N*.
7678
- ``distance_matrix`` *(np.ndarray)*: A 2D array of ``np.float64,`` of size at
7779
least *N* × *N*. This defines the underlying metric, or ground distance, by
78-
giving the pairwise distances between the histogram bins. It must represent a
79-
metric; there is no warning if it doesn't.
80+
giving the pairwise distances between the histogram bins.
81+
**NOTE: It must represent a metric; there is no warning if it doesn't.**
8082

8183
*Keyword Arguments:*
8284

8385
- ``extra_mass_penalty`` *(float)*: The penalty for extra mass. If you want the
8486
resulting distance to be a metric, it should be at least half the diameter of
8587
the space (maximum possible distance between any two points). If you want
8688
partial matching you can set it to zero (but then the resulting distance is
87-
not guaranteed to be a metric). The default value is ``-1.0``, which means the
88-
maximum value in the distance matrix is used.
89+
not guaranteed to be a metric). The default value is ``-1.0``, which means
90+
the maximum value in the distance matrix is used.
8991

9092
*Returns:* *(float)* The EMD value.
9193

@@ -123,18 +125,18 @@ emd_samples()
123125
124126
*Arguments:*
125127

126-
- ``first_array`` *(Iterable)*: A 1D array of samples used to generate a
128+
- ``first_array`` *(Iterable)*: An array of samples used to generate a
127129
histogram.
128-
- ``second_array`` *(Iterable)*: A 1D array of samples used to generate a
130+
- ``second_array`` *(Iterable)*: An array of samples used to generate a
129131
histogram.
130132

131133
*Keyword Arguments:*
132134

133135
- ``extra_mass_penalty`` *(float)*: Same as for ``emd()``.
134136
- ``distance`` *(string or function)*: A string or function implementing
135-
a metric on a 1D ``np.ndarray``. Defaults to the Euclidean distance. Currently
136-
limited to 'euclidean' or your own function, which must take a 1D array and
137-
return a square 2D array of pairwise distances.
137+
a metric on a 1D ``np.ndarray``. Defaults to the Euclidean distance.
138+
Currently limited to 'euclidean' or your own function, which must take
139+
a 1D array and return a square 2D array of pairwise distances.
138140
- ``normalized`` (*boolean*): If true (default), treat histograms as fractions
139141
of the dataset. If false, treat histograms as counts. In the latter case the
140142
EMD will vary greatly by array length.
@@ -147,11 +149,12 @@ emd_samples()
147149
``first_array`` and ``second_array``. Note: if the given range is not a
148150
superset of the default range, no warning will be given.
149151

150-
*Returns:* *(float)* The EMD value between the histograms of ``first_array`` and
151-
``second_array``.
152+
*Returns:* *(float)* The EMD value between the histograms of ``first_array``
153+
and ``second_array``.
152154

153155
----
154156

157+
155158
Limitations and Caveats
156159
-----------------------
157160

@@ -163,66 +166,36 @@ Limitations and Caveats
163166
- The histograms and distance matrix must be numpy arrays of type
164167
``np.float64``. The original C++ template function can accept any numerical
165168
C++ type, but this wrapper only instantiates the template with ``double``
166-
(Cython converts ``np.float64`` to ``double``). If there's demand, I can add
167-
support for other types.
169+
(Cython converts ``np.float64`` to ``double``). If there's demand, I can
170+
add support for other types.
168171

169172
- ``emd_with_flow()``:
170173

171174
- The flow matrix does not contain the flows to/from the extra mass bin.
172175

173176
- ``emd_samples()``:
174177

175-
- Using the default ``bins='auto'`` results in an extra call to
176-
``np.histogram()`` to determine the bin lengths, since `the NumPy
177-
bin-selectors are not exposed in the public API
178+
- With ``numpy < 1.15.0``, using the default ``bins='auto'`` results in an
179+
extra call to ``np.histogram()`` to determine the bin lengths, since `the
180+
NumPy bin-selectors are not exposed in the public API
178181
<https://github.com/numpy/numpy/issues/10183>`_. For performance, you may
179-
want to set the bins yourself.
180-
181-
182-
Contributing
183-
------------
184-
185-
To help develop PyEMD, fork the project on GitHub and install the requirements
186-
with ``pip install -r requirements.txt``.
187-
188-
The ``Makefile`` defines some tasks to help with development:
189-
190-
- ``test``: Run the test suite
191-
- ``build`` Generate and compile the Cython extension
192-
- ``clean``: Remove the compiled Cython extension
193-
- ``default``: Run ``build``
194-
195-
Tests for different Python environments can be run with ``tox``.
182+
want to set the bins yourself. If ``numpy >= 1.15`` is available,
183+
``np.histogram_bin_edges()`` is called instead, which is more efficient.
196184

197185

198186
Credit
199187
------
200188

201189
- All credit for the actual algorithm and implementation goes to `Ofir Pele
202-
<http://www.ariel.ac.il/sites/ofirpele/>`_ and `Michael Werman
203-
<http://www.cs.huji.ac.il/~werman/>`_. See the `relevant paper
204-
<http://www.seas.upenn.edu/~ofirpele/publications/ICCV2009.pdf>`_.
190+
<https://ofirpele.droppages.com/>`_ and `Michael Werman
191+
<https://www.cs.huji.ac.il/~werman/>`_. See the `relevant paper
192+
<https://doi.org/10.1109/ICCV.2009.5459199>`_.
205193
- Thanks to the Cython developers for making this kind of wrapper relatively
206194
easy to write.
207195

208196
Please cite these papers if you use this code:
209197
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
210198

211-
Ofir Pele and Michael Werman. A linear time histogram metric for improved SIFT
212-
matching. *Computer Vision - ECCV 2008*, Marseille, France, 2008, pp. 495-508.
213-
214-
.. code-block:: latex
215-
216-
@INPROCEEDINGS{pele2008,
217-
title={A linear time histogram metric for improved sift matching},
218-
author={Pele, Ofir and Werman, Michael},
219-
booktitle={Computer Vision--ECCV 2008},
220-
pages={495--508},
221-
year={2008},
222-
month={October},
223-
publisher={Springer}
224-
}
225-
226199
Ofir Pele and Michael Werman. Fast and robust earth mover's distances. *Proc.
227200
2009 IEEE 12th Int. Conf. on Computer Vision*, Kyoto, Japan, 2009, pp. 460-467.
228201

@@ -237,3 +210,18 @@ Ofir Pele and Michael Werman. Fast and robust earth mover's distances. *Proc.
237210
month={September},
238211
organization={IEEE}
239212
}
213+
214+
Ofir Pele and Michael Werman. A linear time histogram metric for improved SIFT
215+
matching. *Computer Vision - ECCV 2008*, Marseille, France, 2008, pp. 495-508.
216+
217+
.. code-block:: latex
218+
219+
@INPROCEEDINGS{pele2008,
220+
title={A linear time histogram metric for improved sift matching},
221+
author={Pele, Ofir and Werman, Michael},
222+
booktitle={Computer Vision--ECCV 2008},
223+
pages={495--508},
224+
year={2008},
225+
month={October},
226+
publisher={Springer}
227+
}

conftest.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)