diff options
author | Rémi Flamary <remi.flamary@gmail.com> | 2020-04-28 09:50:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-28 09:50:45 +0200 |
commit | afedeebf5bdd58ff92f52c73b9b41b8a8e66ca29 (patch) | |
tree | 60fafb54d66aa843965c000d48d249780afdcf75 | |
parent | b53fb23b538e0b7f6498bc217f02adac3c8f7d07 (diff) | |
parent | 3b0732b041d46df66cb182b17f6ece040c578722 (diff) |
Merge pull request #160 from PythonOT/doc_cov
[MRG] Update documentation and improve coverage
60 files changed, 647 insertions, 248 deletions
diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 1a4c173..be1719b 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -2,6 +2,9 @@ name: Build dist and wheels on: release: + push: + branches: + - "master" jobs: build_wheels: @@ -59,6 +59,11 @@ release_test : rdoc : pandoc --from=markdown --to=rst --output=docs/source/readme.rst README.md sed -i 's,https://pythonot.github.io/auto_examples/,auto_examples/,g' docs/source/readme.rst + pandoc --from=markdown --to=rst --output=docs/source/releases.rst RELEASES.md + sed -i 's,https://pot.readthedocs.io/en/latest/,,g' docs/source/releases.rst + sed -i 's,https://github.com/rflamary/POT/blob/master/notebooks/,auto_examples/,g' docs/source/releases.rst + sed -i 's,.ipynb,.html,g' docs/source/releases.rst + sed -i 's,https://pythonot.github.io/auto_examples/,auto_examples/,g' docs/source/releases.rst notebook : ipython notebook --matplotlib=inline --notebook-dir=notebooks/ @@ -22,29 +22,29 @@ POT provides the following generic OT solvers (links to examples): * [OT Network Simplex solver](https://pythonot.github.io/auto_examples/plot_OT_1D.html) for the linear program/ Earth Movers Distance [1] . * [Conditional gradient](https://pythonot.github.io/auto_examples/plot_optim_OTreg.html) [6] and [Generalized conditional gradient](https://pythonot.github.io/auto_examples/plot_optim_OTreg.html) for regularized OT [7]. * Entropic regularization OT solver with [Sinkhorn Knopp Algorithm](https://pythonot.github.io/auto_examples/plot_OT_1D.html) [2] , stabilized version [9] [10], greedy Sinkhorn [22] and [Screening Sinkhorn [26] ](https://pythonot.github.io/auto_examples/plot_screenkhorn_1D.html) with optional GPU implementation (requires cupy). -* Bregman projections for [Wasserstein barycenter](https://pythonot.github.io/auto_examples/plot_barycenter_lp_vs_entropic.html) [3], [convolutional barycenter](https://pythonot.github.io/auto_examples/plot_convolutional_barycenter.html) [21] and unmixing [4]. +* Bregman projections for [Wasserstein barycenter](https://pythonot.github.io/auto_examples/barycenters/plot_barycenter_lp_vs_entropic.html) [3], [convolutional barycenter](https://pythonot.github.io/auto_examples/barycenters/plot_convolutional_barycenter.html) [21] and unmixing [4]. * Sinkhorn divergence [23] and entropic regularization OT from empirical data. * [Smooth optimal transport solvers](https://pythonot.github.io/auto_examples/plot_OT_1D_smooth.html) (dual and semi-dual) for KL and squared L2 regularizations [17]. -* Non regularized [Wasserstein barycenters [16] ](https://pythonot.github.io/auto_examples/plot_barycenter_lp_vs_entropic.html)) with LP solver (only small scale). -* [Gromov-Wasserstein distances](https://pythonot.github.io/auto_examples/plot_gromov.html) and [GW barycenters](https://pythonot.github.io/auto_examples/plot_gromov_barycenter.html) (exact [13] and regularized [12]) - * [Fused-Gromov-Wasserstein distances solver](https://pythonot.github.io/auto_examples/plot_fgw.html#sphx-glr-auto-examples-plot-fgw-py) and [FGW barycenters](https://pythonot.github.io/auto_examples/plot_barycenter_fgw.html) [24] +* Non regularized [Wasserstein barycenters [16] ](https://pythonot.github.io/auto_examples/barycenters/plot_barycenter_lp_vs_entropic.html)) with LP solver (only small scale). +* [Gromov-Wasserstein distances](https://pythonot.github.io/auto_examples/gromov/plot_gromov.html) and [GW barycenters](https://pythonot.github.io/auto_examples/gromov/plot_gromov_barycenter.html) (exact [13] and regularized [12]) + * [Fused-Gromov-Wasserstein distances solver](https://pythonot.github.io/auto_examples/gromov/plot_fgw.html#sphx-glr-auto-examples-plot-fgw-py) and [FGW barycenters](https://pythonot.github.io/auto_examples/gromov/plot_barycenter_fgw.html) [24] * [Stochastic solver](https://pythonot.github.io/auto_examples/plot_stochastic.html) for Large-scale Optimal Transport (semi-dual problem [18] and dual problem [19]) -* Non regularized [free support Wasserstein barycenters](https://pythonot.github.io/auto_examples/plot_free_support_barycenter.html) [20]. -* [Unbalanced OT](https://pythonot.github.io/auto_examples/plot_UOT_1D.html) with KL relaxation and [barycenter](https://pythonot.github.io/auto_examples/plot_UOT_barycenter_1D.html) [10, 25]. -* [Partial Wasserstein and Gromov-Wasserstein](https://pythonot.github.io/auto_examples/plot_partial_wass_and_gromov.html) (exact [29] and entropic [3] +* Non regularized [free support Wasserstein barycenters](https://pythonot.github.io/auto_examples/barycenters/plot_free_support_barycenter.html) [20]. +* [Unbalanced OT](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_UOT_1D.html) with KL relaxation and [barycenter](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_UOT_barycenter_1D.html) [10, 25]. +* [Partial Wasserstein and Gromov-Wasserstein](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_partial_wass_and_gromov.html) (exact [29] and entropic [3] formulations). POT provides the following Machine Learning related solvers: * [Optimal transport for domain - adaptation](https://pythonot.github.io/auto_examples/plot_otda_classes.html) - with [group lasso regularization](https://pythonot.github.io/auto_examples/plot_otda_classes.html), [Laplacian regularization](https://pythonot.github.io/auto_examples/plot_otda_laplacian.html) [5] [30] and [semi - supervised setting](https://pythonot.github.io/auto_examples/plot_otda_semi_supervised.html). -* [Linear OT mapping](https://pythonot.github.io/auto_examples/plot_otda_linear_mapping.html) [14] and [Joint OT mapping estimation](https://pythonot.github.io/auto_examples/plot_otda_mapping.html) [8]. -* [Wasserstein Discriminant Analysis](https://pythonot.github.io/auto_examples/plot_WDA.html) [11] (requires autograd + pymanopt). -* [JCPOT algorithm for multi-source domain adaptation with target shift](https://pythonot.github.io/auto_examples/plot_otda_jcpot.html) [27]. + adaptation](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_classes.html) + with [group lasso regularization](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_classes.html), [Laplacian regularization](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_laplacian.html) [5] [30] and [semi + supervised setting](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_semi_supervised.html). +* [Linear OT mapping](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_linear_mapping.html) [14] and [Joint OT mapping estimation](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_mapping.html) [8]. +* [Wasserstein Discriminant Analysis](https://pythonot.github.io/auto_examples/others/plot_WDA.html) [11] (requires autograd + pymanopt). +* [JCPOT algorithm for multi-source domain adaptation with target shift](https://pythonot.github.io/auto_examples/domain-adaptation/plot_otda_jcpot.html) [27]. -Some demonstrations are available in the [documentation](https://pythonot.github.io/auto_examples/index.html). +Some other examples are available in the [documentation](https://pythonot.github.io/auto_examples/index.html). #### Using and citing the toolbox @@ -153,7 +153,7 @@ ba=ot.barycenter(A,M,reg) # reg is regularization parameter ### Examples and Notebooks -The examples folder contain several examples and use case for the library. The full documentation is available on [https://PythonOT.github.io/](https://PythonOT.github.io/). +The examples folder contain several examples and use case for the library. The full documentation with examples and output is available on [https://PythonOT.github.io/](https://PythonOT.github.io/). ## Acknowledgements diff --git a/RELEASES.md b/RELEASES.md index 66eee19..5fcf485 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,7 +1,9 @@ -# POT Releases +# Releases -## 0.6 Year 3 + + +## 0.6 *July 2019* This is the first official stable release of POT and this means a jump to 0.6! @@ -69,7 +71,7 @@ bring new features and solvers to the library. - Issue #72 Macosx build problem -## 0.5.0 Year 2 +## 0.5.0 *Sep 2018* POT is 2 years old! This release brings numerous new features to the @@ -127,7 +129,7 @@ Deprecated OTDA Classes were removed from ot.da and ot.gpu for version 0.5 * Issue #55 : UnicodeDecodeError: 'ascii' while installing with pip -## 0.4 Community edition +## 0.4 *15 Sep 2017* This release contains a lot of contribution from new contributors. @@ -152,7 +154,7 @@ This release contains a lot of contribution from new contributors. * Correct bug in emd on windows -## 0.3 Summer release +## 0.3 *7 Jul 2017* * emd* and sinkhorn* are now performed in parallel for multiple target distributions @@ -173,7 +175,7 @@ This release contains a lot of contribution from new contributors. -## V0.1.11 New years resolution +## 0.1.11 *5 Jan 2017* * Add sphinx gallery for better documentation @@ -181,24 +183,22 @@ This release contains a lot of contribution from new contributors. * Add simple tic() toc() functions for timing -## V0.1.10 +## 0.1.10 *7 Nov 2016* * numerical stabilization for sinkhorn (log domain and epsilon scaling) -## V0.1.9 DA classes and mapping +## 0.1.9 *4 Nov 2016* * Update classes and examples for domain adaptation * Joint OT matrix and mapping estimation -## V0.1.7 +## 0.1.7 *31 Oct 2016* * Original Domain adaptation classes - - -## PyPI version 0.1.3 +## 0.1.3 * pipy works diff --git a/docs/source/_templates/module.rst b/docs/source/_templates/module.rst new file mode 100644 index 0000000..5ad89be --- /dev/null +++ b/docs/source/_templates/module.rst @@ -0,0 +1,57 @@ +{{ fullname }} +{{ underline }} + +.. automodule:: {{ fullname }} + + {% block functions %} + {% if functions %} + + Functions + --------- + + {% for item in functions %} + + .. autofunction:: {{ item }} + + .. include:: backreferences/{{fullname}}.{{item}}.examples + + .. raw:: html + + <div class="sphx-glr-clear"></div> + + {%- endfor %} + {% endif %} + {% endblock %} + + {% block classes %} + {% if classes %} + + Classes + ------- + + {% for item in classes %} + .. autoclass:: {{ item }} + :members: + + .. include:: backreferences/{{fullname}}.{{item}}.examples + + .. raw:: html + + <div class="sphx-glr-clear"></div> + + {%- endfor %} + {% endif %} + {% endblock %} + + {% block exceptions %} + {% if exceptions %} + + Exceptions + ---------- + + .. autosummary:: + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %}
\ No newline at end of file diff --git a/docs/source/all.rst b/docs/source/all.rst index a6d9790..d7b878f 100644 --- a/docs/source/all.rst +++ b/docs/source/all.rst @@ -1,94 +1,36 @@ +.. _sphx_glr_api_reference: -Python modules -============== +API and modules +=============== -ot --- +.. currentmodule:: ot -.. automodule:: ot - :members: - -ot.lp ------ -.. automodule:: ot.lp - :members: - -ot.bregman ----------- - -.. automodule:: ot.bregman - :members: - -ot.smooth ------ -.. automodule:: ot.smooth - :members: - -ot.gromov ----------- - -.. automodule:: ot.gromov - :members: - - -ot.optim --------- - -.. automodule:: ot.optim - :members: - -ot.da --------- -.. automodule:: ot.da - :members: +:py:mod:`ot`: -ot.gpu --------- +.. autosummary:: + :toctree: gen_modules/ + :template: module.rst -.. automodule:: ot.gpu - :members: + lp + bregman + smooth + gromov + optim + da + gpu + dr + utils + datasets + plot + stochastic + unbalanced + partial -ot.dr --------- +.. autosummary:: + :toctree: ../modules/generated/ + :template: module.rst -.. automodule:: ot.dr - :members: - - -ot.utils --------- - -.. automodule:: ot.utils - :members: - -ot.datasets ------------ - -.. automodule:: ot.datasets - :members: - -ot.plot -------- - -.. automodule:: ot.plot - :members: - -ot.stochastic -------------- - -.. automodule:: ot.stochastic +.. automodule:: ot :members: - -ot.unbalanced -------------- - -.. automodule:: ot.unbalanced - :members: - -ot.partial -------------- - -.. automodule:: ot.partial - :members: diff --git a/docs/source/conf.py b/docs/source/conf.py index 880c71d..384bf40 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -36,9 +36,9 @@ class Mock(MagicMock): return MagicMock() -MOCK_MODULES = ['ot.lp.emd_wrap', 'autograd', 'pymanopt', 'cupy', 'autograd.numpy', 'pymanopt.manifolds', 'pymanopt.solvers'] +MOCK_MODULES = [ 'cupy'] # 'autograd.numpy','pymanopt.manifolds','pymanopt.solvers', -#sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) +sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) # !!!! # If extensions (or modules to document with autodoc) are in another directory, @@ -59,6 +59,7 @@ sys.path.insert(0, os.path.abspath("../..")) # ones. extensions = [ 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', @@ -70,6 +71,9 @@ extensions = [ 'sphinx_gallery.gen_gallery', ] +autosummary_generate = True + + napoleon_numpy_docstring = True # Add any paths that contain templates here, relative to this directory. @@ -88,7 +92,7 @@ master_doc = 'index' # General information about the project. project = u'POT Python Optimal Transport' -copyright = u'2016-2019, Rémi Flamary, Nicolas Courty' +copyright = u'2016-2020, Rémi Flamary, Nicolas Courty' author = u'Rémi Flamary, Nicolas Courty' # The version info for the project you're documenting, acts as replacement for @@ -297,7 +301,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'pot', u'POT Python Optimal Transport library Documentation', + (master_doc, 'pot', u'POT Python Optimal Transport', [author], 1) ] @@ -311,8 +315,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'POT', u'POT Python Optimal Transport library Documentation', - author, 'POT', 'Python Optimal Transport librar.', + (master_doc, 'POT', u'POT Python Optimal Transport', + author, 'POT', 'Python Optimal Transport', 'Miscellaneous'), ] @@ -333,13 +337,14 @@ texinfo_documents = [ intersphinx_mapping = {'python': ('https://docs.python.org/3', None), 'numpy': ('http://docs.scipy.org/doc/numpy/', None), 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), - 'matplotlib': ('http://matplotlib.sourceforge.net/', None)} + 'matplotlib': ('http://matplotlib.org/', None)} sphinx_gallery_conf = { 'examples_dirs': ['../../examples', '../../examples/da'], 'gallery_dirs': 'auto_examples', - 'backreferences_dir': '../modules/generated/', + 'backreferences_dir': 'gen_modules/backreferences', + 'inspect_global_variables' : True, + 'doc_module' : ('ot','numpy','scipy','pylab'), 'reference_url': { - 'numpy': 'http://docs.scipy.org/doc/numpy-1.9.1', - 'scipy': 'http://docs.scipy.org/doc/scipy-0.17.0/reference'} + 'ot': None} } diff --git a/docs/source/index.rst b/docs/source/index.rst index 9078d35..be01343 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,15 +10,17 @@ Contents -------- .. toctree:: - :maxdepth: 2 + :maxdepth: 1 self quickstart all auto_examples/index + releases .. include:: readme.rst - :start-line: 5 + :start-line: 2 + Indices and tables diff --git a/docs/source/readme.rst b/docs/source/readme.rst index b00d7b7..c96f191 100644 --- a/docs/source/readme.rst +++ b/docs/source/readme.rst @@ -1,8 +1,8 @@ POT: Python Optimal Transport ============================= -|PyPI version| |Anaconda Cloud| |Build Status| |Build Status| |Codecov -Status| |Downloads| |Anaconda downloads| |License| +|PyPI version| |Anaconda Cloud| |Build Status| |Codecov Status| +|Downloads| |Anaconda downloads| |License| This open source Python library provide several solvers for optimization problems related to Optimal Transport for signal, image processing and @@ -29,9 +29,9 @@ POT provides the following generic OT solvers (links to examples): [26] <auto_examples/plot_screenkhorn_1D.html>`__ with optional GPU implementation (requires cupy). - Bregman projections for `Wasserstein - barycenter <auto_examples/plot_barycenter_lp_vs_entropic.html>`__ + barycenter <auto_examples/barycenters/plot_barycenter_lp_vs_entropic.html>`__ [3], `convolutional - barycenter <auto_examples/plot_convolutional_barycenter.html>`__ + barycenter <auto_examples/barycenters/plot_convolutional_barycenter.html>`__ [21] and unmixing [4]. - Sinkhorn divergence [23] and entropic regularization OT from empirical data. @@ -39,68 +39,69 @@ POT provides the following generic OT solvers (links to examples): solvers <auto_examples/plot_OT_1D_smooth.html>`__ (dual and semi-dual) for KL and squared L2 regularizations [17]. - Non regularized `Wasserstein barycenters - [16] <auto_examples/plot_barycenter_lp_vs_entropic.html>`__) + [16] <auto_examples/barycenters/plot_barycenter_lp_vs_entropic.html>`__) with LP solver (only small scale). - `Gromov-Wasserstein - distances <auto_examples/plot_gromov.html>`__ + distances <auto_examples/gromov/plot_gromov.html>`__ and `GW - barycenters <auto_examples/plot_gromov_barycenter.html>`__ + barycenters <auto_examples/gromov/plot_gromov_barycenter.html>`__ (exact [13] and regularized [12]) - `Fused-Gromov-Wasserstein distances - solver <auto_examples/plot_fgw.html#sphx-glr-auto-examples-plot-fgw-py>`__ + solver <auto_examples/gromov/plot_fgw.html#sphx-glr-auto-examples-plot-fgw-py>`__ and `FGW - barycenters <auto_examples/plot_barycenter_fgw.html>`__ + barycenters <auto_examples/gromov/plot_barycenter_fgw.html>`__ [24] - `Stochastic solver <auto_examples/plot_stochastic.html>`__ for Large-scale Optimal Transport (semi-dual problem [18] and dual problem [19]) - Non regularized `free support Wasserstein - barycenters <auto_examples/plot_free_support_barycenter.html>`__ + barycenters <auto_examples/barycenters/plot_free_support_barycenter.html>`__ [20]. - `Unbalanced - OT <auto_examples/plot_UOT_1D.html>`__ + OT <auto_examples/unbalanced-partial/plot_UOT_1D.html>`__ with KL relaxation and - `barycenter <auto_examples/plot_UOT_barycenter_1D.html>`__ + `barycenter <auto_examples/unbalanced-partial/plot_UOT_barycenter_1D.html>`__ [10, 25]. - `Partial Wasserstein and - Gromov-Wasserstein <auto_examples/plot_partial_wass_and_gromov.html>`__ + Gromov-Wasserstein <auto_examples/unbalanced-partial/plot_partial_wass_and_gromov.html>`__ (exact [29] and entropic [3] formulations). POT provides the following Machine Learning related solvers: - `Optimal transport for domain - adaptation <auto_examples/plot_otda_classes.html>`__ + adaptation <auto_examples/domain-adaptation/plot_otda_classes.html>`__ with `group lasso - regularization <auto_examples/plot_otda_classes.html>`__, + regularization <auto_examples/domain-adaptation/plot_otda_classes.html>`__, `Laplacian - regularization <auto_examples/plot_otda_laplacian.html>`__ + regularization <auto_examples/domain-adaptation/plot_otda_laplacian.html>`__ [5] [30] and `semi supervised - setting <auto_examples/plot_otda_semi_supervised.html>`__. + setting <auto_examples/domain-adaptation/plot_otda_semi_supervised.html>`__. - `Linear OT - mapping <auto_examples/plot_otda_linear_mapping.html>`__ + mapping <auto_examples/domain-adaptation/plot_otda_linear_mapping.html>`__ [14] and `Joint OT mapping - estimation <auto_examples/plot_otda_mapping.html>`__ + estimation <auto_examples/domain-adaptation/plot_otda_mapping.html>`__ [8]. - `Wasserstein Discriminant - Analysis <auto_examples/plot_WDA.html>`__ + Analysis <auto_examples/others/plot_WDA.html>`__ [11] (requires autograd + pymanopt). - `JCPOT algorithm for multi-source domain adaptation with target - shift <auto_examples/plot_otda_jcpot.html>`__ + shift <auto_examples/domain-adaptation/plot_otda_jcpot.html>`__ [27]. -Some demonstrations are available in the +Some other examples are available in the `documentation <auto_examples/index.html>`__. Using and citing the toolbox ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you use this toolbox in your research and find it useful, please cite -POT using the following bibtex reference: +POT using the following reference: :: - Rémi Flamary and Nicolas Courty, POT Python Optimal Transport library, Website: https://pythonot.github.io/, 2017 + Rémi Flamary and Nicolas Courty, POT Python Optimal Transport library, + Website: https://pythonot.github.io/, 2017 In Bibtex format: @@ -141,11 +142,11 @@ You can install the toolbox through PyPI with: pip install POT -or get the very latest version by downloading it and then running: +or get the very latest version by running: :: - python setup.py install --user # for user install (no root) + pip install -U https://github.com/PythonOT/POT/archive/master.zip # with --user for user install (no root) Anaconda installation with conda-forge ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +233,7 @@ Examples and Notebooks ~~~~~~~~~~~~~~~~~~~~~~ The examples folder contain several examples and use case for the -library. The full documentation is available on +library. The full documentation with examples and output is available on https://PythonOT.github.io/. Acknowledgements @@ -245,7 +246,8 @@ This toolbox has been created and is maintained by The contributors to this library are -- `Alexandre Gramfort <http://alexandre.gramfort.net/>`__ (CI) +- `Alexandre Gramfort <http://alexandre.gramfort.net/>`__ (CI, + documentation) - `Laetitia Chapel <http://people.irisa.fr/Laetitia.Chapel/>`__ (Partial OT) - `Michael Perrot <http://perso.univ-st-etienne.fr/pem82055/>`__ @@ -452,8 +454,6 @@ NIPS Workshop on Optimal Transport and Machine Learning OTML, 2014. :target: https://badge.fury.io/py/POT .. |Anaconda Cloud| image:: https://anaconda.org/conda-forge/pot/badges/version.svg :target: https://anaconda.org/conda-forge/pot -.. |Build Status| image:: https://travis-ci.org/PythonOT/POT.svg?branch=master - :target: https://travis-ci.org/PythonOT/POT .. |Build Status| image:: https://github.com/PythonOT/POT/workflows/build/badge.svg :target: https://github.com/PythonOT/POT/actions .. |Codecov Status| image:: https://codecov.io/gh/PythonOT/POT/branch/master/graph/badge.svg diff --git a/docs/source/releases.rst b/docs/source/releases.rst new file mode 100644 index 0000000..075108f --- /dev/null +++ b/docs/source/releases.rst @@ -0,0 +1,260 @@ +Releases +======== + +0.6 +--- + +*July 2019* + +This is the first official stable release of POT and this means a jump +to 0.6! The library has been used in the wild for a while now and we +have reached a state where a lot of fundamental OT solvers are available +and tested. It has been quite stable in the last months but kept the +beta flag in its Pypi classifiers until now. + +Note that this release will be the last one supporting officially Python +2.7 (See https://python3statement.org/ for more reasons). For next +release we will keep the travis tests for Python 2 but will make them +non necessary for merge in 2020. + +The features are never complete in a toolbox designed for solving +mathematical problems and research but with the new contributions we now +implement algorithms and solvers from 24 scientific papers (listed in +the README.md file). New features include a direct implementation of the +`empirical Sinkhorn +divergence <all.html#ot.bregman.empirical_sinkhorn_divergence>`__ +, a new efficient (Cython implementation) solver for `EMD in +1D <all.html#ot.lp.emd_1d>`__ and +corresponding `Wasserstein +1D <all.html#ot.lp.wasserstein_1d>`__. +We now also have implementations for `Unbalanced +OT <auto_examples/plot_UOT_1D.html>`__ +and a solver for `Unbalanced OT +barycenters <auto_examples/plot_UOT_barycenter_1D.html>`__. +A new variant of Gromov-Wasserstein divergence called `Fused +Gromov-Wasserstein <all.html?highlight=fused_#ot.gromov.fused_gromov_wasserstein>`__ +has been also contributed with exemples of use on `structured +data <auto_examples/plot_fgw.html>`__ +and computing `barycenters of labeld +graphs <auto_examples/plot_barycenter_fgw.html>`__. + +A lot of work has been done on the documentation with several new +examples corresponding to the new features and a lot of corrections for +the docstrings. But the most visible change is a new `quick start +guide <quickstart.html>`__ for POT +that gives several pointers about which function or classes allow to +solve which specific OT problem. When possible a link is provided to +relevant examples. + +We will also provide with this release some pre-compiled Python wheels +for Linux 64bit on github and pip. This will simplify the install +process that before required a C compiler and numpy/cython already +installed. + +Finally we would like to acknowledge and thank the numerous contributors +of POT that has helped in the past build the foundation and are still +contributing to bring new features and solvers to the library. + +Features +^^^^^^^^ + +- Add compiled manylinux 64bits wheels to pip releases (PR #91) +- Add quick start guide (PR #88) +- Make doctest work on travis (PR #90) +- Update documentation (PR #79, PR #84) +- Solver for EMD in 1D (PR #89) +- Solvers for regularized unbalanced OT (PR #87, PR#99) +- Solver for Fused Gromov-Wasserstein (PR #86) +- Add empirical Sinkhorn and empirical Sinkhorn divergences (PR #80) + +Closed issues +^^^^^^^^^^^^^ + +- Issue #59 fail when using "pip install POT" (new details in doc+ + hopefully wheels) +- Issue #85 Cannot run gpu modules +- Issue #75 Greenkhorn do not return log (solved in PR #76) +- Issue #82 Gromov-Wasserstein fails when the cost matrices are + slightly different +- Issue #72 Macosx build problem + +0.5.0 +----- + +*Sep 2018* + +POT is 2 years old! This release brings numerous new features to the +toolbox as listed below but also several bug correction. + +| Among the new features, we can highlight a `non-regularized + Gromov-Wasserstein + solver <auto_examples/plot_gromov.html>`__, + a new `greedy variant of + sinkhorn <all.html#ot.bregman.greenkhorn>`__, +| `non-regularized <all.html#ot.lp.barycenter>`__, + `convolutional + (2D) <auto_examples/plot_convolutional_barycenter.html>`__ + and `free + support <auto_examples/plot_free_support_barycenter.html>`__ + Wasserstein barycenters and + `smooth <https://github.com/rflamary/POT/blob/prV0.5/notebooks/plot_OT_1D_smooth.html>`__ + and + `stochastic <all.html#ot.stochastic.sgd_entropic_regularization>`__ + implementation of entropic OT. + +POT 0.5 also comes with a rewriting of ot.gpu using the cupy framework +instead of the unmaintained cudamat. Note that while we tried to keed +changes to the minimum, the OTDA classes were deprecated. If you are +happy with the cudamat implementation, we recommend you stay with stable +release 0.4 for now. + +The code quality has also improved with 92% code coverage in tests that +is now printed to the log in the Travis builds. The documentation has +also been greatly improved with new modules and examples/notebooks. + +This new release is so full of new stuff and corrections thanks to the +old and new POT contributors (you can see the list in the +`readme <https://github.com/rflamary/POT/blob/master/README.md>`__). + +Features +^^^^^^^^ + +- Add non regularized Gromov-Wasserstein solver (PR #41) +- Linear OT mapping between empirical distributions and 90% test + coverage (PR #42) +- Add log parameter in class EMDTransport and SinkhornLpL1Transport (PR + #44) +- Add Markdown format for Pipy (PR #45) +- Test for Python 3.5 and 3.6 on Travis (PR #46) +- Non regularized Wasserstein barycenter with scipy linear solver + and/or cvxopt (PR #47) +- Rename dataset functions to be more sklearn compliant (PR #49) +- Smooth and sparse Optimal transport implementation with entropic and + quadratic regularization (PR #50) +- Stochastic OT in the dual and semi-dual (PR #52 and PR #62) +- Free support barycenters (PR #56) +- Speed-up Sinkhorn function (PR #57 and PR #58) +- Add convolutional Wassersein barycenters for 2D images (PR #64) +- Add Greedy Sinkhorn variant (Greenkhorn) (PR #66) +- Big ot.gpu update with cupy implementation (instead of un-maintained + cudamat) (PR #67) + +Deprecation +^^^^^^^^^^^ + +Deprecated OTDA Classes were removed from ot.da and ot.gpu for version +0.5 (PR #48 and PR #67). The deprecation message has been for a year +here since 0.4 and it is time to pull the plug. + +Closed issues +^^^^^^^^^^^^^ + +- Issue #35 : remove import plot from ot/\ **init**.py (See PR #41) +- Issue #43 : Unusable parameter log for EMDTransport (See PR #44) +- Issue #55 : UnicodeDecodeError: 'ascii' while installing with pip + +0.4 +--- + +*15 Sep 2017* + +This release contains a lot of contribution from new contributors. + +Features +^^^^^^^^ + +- Automatic notebooks and doc update (PR #27) +- Add gromov Wasserstein solver and Gromov Barycenters (PR #23) +- emd and emd2 can now return dual variables and have max\_iter (PR #29 + and PR #25) +- New domain adaptation classes compatible with scikit-learn (PR #22) +- Proper tests with pytest on travis (PR #19) +- PEP 8 tests (PR #13) + +Closed issues +^^^^^^^^^^^^^ + +- emd convergence problem du to fixed max iterations (#24) +- Semi supervised DA error (#26) + +0.3.1 +----- + +*11 Jul 2017* + +- Correct bug in emd on windows + +0.3 +--- + +*7 Jul 2017* + +- emd\* and sinkhorn\* are now performed in parallel for multiple + target distributions +- emd and sinkhorn are for OT matrix computation +- emd2 and sinkhorn2 are for OT loss computation +- new notebooks for emd computation and Wasserstein Discriminant + Analysis +- relocate notebooks +- update documentation +- clean\_zeros(a,b,M) for removimg zeros in sparse distributions +- GPU implementations for sinkhorn and group lasso regularization + +V0.2 +---- + +*7 Apr 2017* + +- New dimensionality reduction method (WDA) +- Efficient method emd2 returns only tarnsport (in paralell if several + histograms given) + +0.1.11 +------ + +*5 Jan 2017* + +- Add sphinx gallery for better documentation +- Small efficiency tweak in sinkhorn +- Add simple tic() toc() functions for timing + +0.1.10 +------ + +*7 Nov 2016* \* numerical stabilization for sinkhorn (log domain and +epsilon scaling) + +0.1.9 +----- + +*4 Nov 2016* + +- Update classes and examples for domain adaptation +- Joint OT matrix and mapping estimation + +0.1.7 +----- + +*31 Oct 2016* + +- Original Domain adaptation classes + +0.1.3 +----- + +- pipy works + +First pre-release +----------------- + +*28 Oct 2016* + +It provides the following solvers: \* OT solver for the linear program/ +Earth Movers Distance. \* Entropic regularization OT solver with +Sinkhorn Knopp Algorithm. \* Bregman projections for Wasserstein +barycenter [3] and unmixing. \* Optimal transport for domain adaptation +with group lasso regularization \* Conditional gradient and Generalized +conditional gradient for regularized OT. + +Some demonstrations (both in Python and Jupyter Notebook format) are +available in the examples folder. diff --git a/examples/README.txt b/examples/README.txt index b08d3f1..69a9f84 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1,4 +1,8 @@ -POT Examples -============ +Examples gallery +================ This is a gallery of all the POT example files. + + +OT and regularized OT +---------------------
\ No newline at end of file diff --git a/examples/barycenters/README.txt b/examples/barycenters/README.txt new file mode 100644 index 0000000..8461f7f --- /dev/null +++ b/examples/barycenters/README.txt @@ -0,0 +1,4 @@ + + +Wasserstein barycenters +-----------------------
\ No newline at end of file diff --git a/examples/plot_barycenter_1D.py b/examples/barycenters/plot_barycenter_1D.py index 6864301..63dc460 100644 --- a/examples/plot_barycenter_1D.py +++ b/examples/barycenters/plot_barycenter_1D.py @@ -18,6 +18,8 @@ SIAM Journal on Scientific Computing, 37(2), A1111-A1138. # # License: MIT License +# sphinx_gallery_thumbnail_number = 4 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_barycenter_lp_vs_entropic.py b/examples/barycenters/plot_barycenter_lp_vs_entropic.py index d7c72d0..57a6bac 100644 --- a/examples/plot_barycenter_lp_vs_entropic.py +++ b/examples/barycenters/plot_barycenter_lp_vs_entropic.py @@ -21,6 +21,8 @@ SIAM Journal on Scientific Computing, 37(2), A1111-A1138. # # License: MIT License +# sphinx_gallery_thumbnail_number = 4 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_convolutional_barycenter.py b/examples/barycenters/plot_convolutional_barycenter.py index e74db04..cbcd4a1 100644 --- a/examples/plot_convolutional_barycenter.py +++ b/examples/barycenters/plot_convolutional_barycenter.py @@ -26,10 +26,10 @@ import ot # The four distributions are constructed from 4 simple images -f1 = 1 - pl.imread('../data/redcross.png')[:, :, 2] -f2 = 1 - pl.imread('../data/duck.png')[:, :, 2] -f3 = 1 - pl.imread('../data/heart.png')[:, :, 2] -f4 = 1 - pl.imread('../data/tooth.png')[:, :, 2] +f1 = 1 - pl.imread('../../data/redcross.png')[:, :, 2] +f2 = 1 - pl.imread('../../data/duck.png')[:, :, 2] +f3 = 1 - pl.imread('../../data/heart.png')[:, :, 2] +f4 = 1 - pl.imread('../../data/tooth.png')[:, :, 2] A = [] f1 = f1 / np.sum(f1) diff --git a/examples/plot_free_support_barycenter.py b/examples/barycenters/plot_free_support_barycenter.py index 64b89e4..64b89e4 100644 --- a/examples/plot_free_support_barycenter.py +++ b/examples/barycenters/plot_free_support_barycenter.py diff --git a/examples/domain-adaptation/README.txt b/examples/domain-adaptation/README.txt new file mode 100644 index 0000000..81dd8d2 --- /dev/null +++ b/examples/domain-adaptation/README.txt @@ -0,0 +1,5 @@ + + + +Domain adaptation examples +--------------------------
\ No newline at end of file diff --git a/examples/plot_otda_classes.py b/examples/domain-adaptation/plot_otda_classes.py index f028022..f028022 100644 --- a/examples/plot_otda_classes.py +++ b/examples/domain-adaptation/plot_otda_classes.py diff --git a/examples/plot_otda_color_images.py b/examples/domain-adaptation/plot_otda_color_images.py index d9cbd2b..929365e 100644 --- a/examples/plot_otda_color_images.py +++ b/examples/domain-adaptation/plot_otda_color_images.py @@ -17,6 +17,8 @@ SIAM Journal on Imaging Sciences, 7(3), 1853-1882. # # License: MIT License +# sphinx_gallery_thumbnail_number = 2 + import numpy as np import matplotlib.pylab as pl import ot @@ -44,8 +46,8 @@ def minmax(I): # ------------- # Loading images -I1 = pl.imread('../data/ocean_day.jpg').astype(np.float64) / 256 -I2 = pl.imread('../data/ocean_sunset.jpg').astype(np.float64) / 256 +I1 = pl.imread('../../data/ocean_day.jpg').astype(np.float64) / 256 +I2 = pl.imread('../../data/ocean_sunset.jpg').astype(np.float64) / 256 X1 = im2mat(I1) X2 = im2mat(I2) diff --git a/examples/plot_otda_d2.py b/examples/domain-adaptation/plot_otda_d2.py index cf22c2f..f49a570 100644 --- a/examples/plot_otda_d2.py +++ b/examples/domain-adaptation/plot_otda_d2.py @@ -18,6 +18,8 @@ of what the transport methods are doing. # # License: MIT License +# sphinx_gallery_thumbnail_number = 2 + import matplotlib.pylab as pl import ot import ot.plot diff --git a/examples/plot_otda_jcpot.py b/examples/domain-adaptation/plot_otda_jcpot.py index c495690..c495690 100644 --- a/examples/plot_otda_jcpot.py +++ b/examples/domain-adaptation/plot_otda_jcpot.py diff --git a/examples/plot_otda_laplacian.py b/examples/domain-adaptation/plot_otda_laplacian.py index 67c8f67..67c8f67 100644 --- a/examples/plot_otda_laplacian.py +++ b/examples/domain-adaptation/plot_otda_laplacian.py diff --git a/examples/plot_otda_linear_mapping.py b/examples/domain-adaptation/plot_otda_linear_mapping.py index c65bd4f..dbf16b8 100644 --- a/examples/plot_otda_linear_mapping.py +++ b/examples/domain-adaptation/plot_otda_linear_mapping.py @@ -12,6 +12,8 @@ Linear OT mapping estimation # # License: MIT License +# sphinx_gallery_thumbnail_number = 2 + import numpy as np import pylab as pl import ot @@ -92,8 +94,8 @@ def minmax(I): # Loading images -I1 = pl.imread('../data/ocean_day.jpg').astype(np.float64) / 256 -I2 = pl.imread('../data/ocean_sunset.jpg').astype(np.float64) / 256 +I1 = pl.imread('../../data/ocean_day.jpg').astype(np.float64) / 256 +I2 = pl.imread('../../data/ocean_sunset.jpg').astype(np.float64) / 256 X1 = im2mat(I1) diff --git a/examples/plot_otda_mapping.py b/examples/domain-adaptation/plot_otda_mapping.py index 5880adf..ded2bdf 100644 --- a/examples/plot_otda_mapping.py +++ b/examples/domain-adaptation/plot_otda_mapping.py @@ -18,6 +18,8 @@ a linear or a kernelized mapping as introduced in [8]. # # License: MIT License +# sphinx_gallery_thumbnail_number = 2 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_otda_mapping_colors_images.py b/examples/domain-adaptation/plot_otda_mapping_colors_images.py index a0938a0..9d3a7c7 100644 --- a/examples/plot_otda_mapping_colors_images.py +++ b/examples/domain-adaptation/plot_otda_mapping_colors_images.py @@ -19,6 +19,8 @@ discrete optimal transport", Neural Information Processing Systems (NIPS), 2016. # # License: MIT License +# sphinx_gallery_thumbnail_number = 3 + import numpy as np import matplotlib.pylab as pl import ot @@ -45,8 +47,8 @@ def minmax(I): # ------------- # Loading images -I1 = pl.imread('../data/ocean_day.jpg').astype(np.float64) / 256 -I2 = pl.imread('../data/ocean_sunset.jpg').astype(np.float64) / 256 +I1 = pl.imread('../../data/ocean_day.jpg').astype(np.float64) / 256 +I2 = pl.imread('../../data/ocean_sunset.jpg').astype(np.float64) / 256 X1 = im2mat(I1) diff --git a/examples/plot_otda_semi_supervised.py b/examples/domain-adaptation/plot_otda_semi_supervised.py index 8a67720..478c3b8 100644 --- a/examples/plot_otda_semi_supervised.py +++ b/examples/domain-adaptation/plot_otda_semi_supervised.py @@ -18,6 +18,8 @@ of what the transport methods are doing. # # License: MIT License +# sphinx_gallery_thumbnail_number = 3 + import matplotlib.pylab as pl import ot diff --git a/examples/gromov/README.txt b/examples/gromov/README.txt new file mode 100644 index 0000000..9cc9c64 --- /dev/null +++ b/examples/gromov/README.txt @@ -0,0 +1,4 @@ + + +Gromov and Fused-Gromov-Wasserstein +-----------------------------------
\ No newline at end of file diff --git a/examples/plot_barycenter_fgw.py b/examples/gromov/plot_barycenter_fgw.py index 77b0370..77b0370 100644 --- a/examples/plot_barycenter_fgw.py +++ b/examples/gromov/plot_barycenter_fgw.py diff --git a/examples/plot_fgw.py b/examples/gromov/plot_fgw.py index cfdc33b..73e486e 100644 --- a/examples/plot_fgw.py +++ b/examples/gromov/plot_fgw.py @@ -17,6 +17,8 @@ This example illustrates the computation of FGW for 1D measures[18]. # # License: MIT License +# sphinx_gallery_thumbnail_number = 3 + import matplotlib.pyplot as pl import numpy as np import ot diff --git a/examples/plot_gromov.py b/examples/gromov/plot_gromov.py index deb2f86..deb2f86 100644 --- a/examples/plot_gromov.py +++ b/examples/gromov/plot_gromov.py diff --git a/examples/plot_gromov_barycenter.py b/examples/gromov/plot_gromov_barycenter.py index 6b29687..f6f031a 100755 --- a/examples/plot_gromov_barycenter.py +++ b/examples/gromov/plot_gromov_barycenter.py @@ -89,10 +89,10 @@ def im2mat(I): return I.reshape((I.shape[0] * I.shape[1], I.shape[2]))
-square = pl.imread('../data/square.png').astype(np.float64)[:, :, 2]
-cross = pl.imread('../data/cross.png').astype(np.float64)[:, :, 2]
-triangle = pl.imread('../data/triangle.png').astype(np.float64)[:, :, 2]
-star = pl.imread('../data/star.png').astype(np.float64)[:, :, 2]
+square = pl.imread('../../data/square.png').astype(np.float64)[:, :, 2]
+cross = pl.imread('../../data/cross.png').astype(np.float64)[:, :, 2]
+triangle = pl.imread('../../data/triangle.png').astype(np.float64)[:, :, 2]
+star = pl.imread('../../data/star.png').astype(np.float64)[:, :, 2]
shapes = [square, cross, triangle, star]
diff --git a/examples/others/README.txt b/examples/others/README.txt new file mode 100644 index 0000000..df4c697 --- /dev/null +++ b/examples/others/README.txt @@ -0,0 +1,5 @@ + + + +Other OT problems +-----------------
\ No newline at end of file diff --git a/examples/plot_WDA.py b/examples/others/plot_WDA.py index 93cc237..5e17433 100644 --- a/examples/plot_WDA.py +++ b/examples/others/plot_WDA.py @@ -16,6 +16,8 @@ Wasserstein Discriminant Analysis. # # License: MIT License +# sphinx_gallery_thumbnail_number = 2 + import numpy as np import matplotlib.pylab as pl diff --git a/examples/plot_OT_1D.py b/examples/plot_OT_1D.py index f33e2a4..15ead96 100644 --- a/examples/plot_OT_1D.py +++ b/examples/plot_OT_1D.py @@ -12,6 +12,7 @@ and their visualization. # Author: Remi Flamary <remi.flamary@unice.fr> # # License: MIT License +# sphinx_gallery_thumbnail_number = 3 import numpy as np import matplotlib.pylab as pl diff --git a/examples/plot_OT_1D_smooth.py b/examples/plot_OT_1D_smooth.py index b690751..75cd295 100644 --- a/examples/plot_OT_1D_smooth.py +++ b/examples/plot_OT_1D_smooth.py @@ -13,6 +13,8 @@ and their visualization. # # License: MIT License +# sphinx_gallery_thumbnail_number = 6 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_OT_2D_samples.py b/examples/plot_OT_2D_samples.py index 63126ba..1544e82 100644 --- a/examples/plot_OT_2D_samples.py +++ b/examples/plot_OT_2D_samples.py @@ -14,6 +14,8 @@ sum of diracs. The OT matrix is plotted with the samples. # # License: MIT License +# sphinx_gallery_thumbnail_number = 4 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_OT_L1_vs_L2.py b/examples/plot_OT_L1_vs_L2.py index 37b429f..60353ab 100644 --- a/examples/plot_OT_L1_vs_L2.py +++ b/examples/plot_OT_L1_vs_L2.py @@ -16,6 +16,8 @@ https://arxiv.org/pdf/1706.07650.pdf # # License: MIT License +# sphinx_gallery_thumbnail_number = 3 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_compute_emd.py b/examples/plot_compute_emd.py index 7ed2b01..3340115 100644 --- a/examples/plot_compute_emd.py +++ b/examples/plot_compute_emd.py @@ -14,6 +14,8 @@ ground metrics and plot their values for diffeent distributions. # # License: MIT License +# sphinx_gallery_thumbnail_number = 3 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_optim_OTreg.py b/examples/plot_optim_OTreg.py index 2c58def..51e2fdc 100644 --- a/examples/plot_optim_OTreg.py +++ b/examples/plot_optim_OTreg.py @@ -24,6 +24,7 @@ arXiv preprint arXiv:1510.06567. """ +# sphinx_gallery_thumbnail_number = 4 import numpy as np import matplotlib.pylab as pl diff --git a/examples/unbalanced-partial/README.txt b/examples/unbalanced-partial/README.txt new file mode 100644 index 0000000..2f404f0 --- /dev/null +++ b/examples/unbalanced-partial/README.txt @@ -0,0 +1,3 @@ + +Unbalanced and Partial OT +-------------------------
\ No newline at end of file diff --git a/examples/plot_UOT_1D.py b/examples/unbalanced-partial/plot_UOT_1D.py index 2ea8b05..2ea8b05 100644 --- a/examples/plot_UOT_1D.py +++ b/examples/unbalanced-partial/plot_UOT_1D.py diff --git a/examples/plot_UOT_barycenter_1D.py b/examples/unbalanced-partial/plot_UOT_barycenter_1D.py index acb5892..931798b 100644 --- a/examples/plot_UOT_barycenter_1D.py +++ b/examples/unbalanced-partial/plot_UOT_barycenter_1D.py @@ -16,6 +16,8 @@ as proposed in [10] for Unbalanced inputs. # # License: MIT License +# sphinx_gallery_thumbnail_number = 2 + import numpy as np import matplotlib.pylab as pl import ot diff --git a/examples/plot_partial_wass_and_gromov.py b/examples/unbalanced-partial/plot_partial_wass_and_gromov.py index 9f95a70..0c5cbf9 100755 --- a/examples/plot_partial_wass_and_gromov.py +++ b/examples/unbalanced-partial/plot_partial_wass_and_gromov.py @@ -11,6 +11,8 @@ distance computation in POT. # Author: Laetitia Chapel <laetitia.chapel@irisa.fr>
# License: MIT License
+# sphinx_gallery_thumbnail_number = 2
+
# necessary for 3d plot even if not used
from mpl_toolkits.mplot3d import Axes3D # noqa
import scipy as sp
diff --git a/ot/__init__.py b/ot/__init__.py index 1e57b78..2d23610 100644 --- a/ot/__init__.py +++ b/ot/__init__.py @@ -1,35 +1,5 @@ """ -This is the main module of the POT toolbox. It provides easy access to -a number of sub-modules and functions described below. - -.. note:: - - - Here is a list of the submodules and short description of what they contain. - - - :any:`ot.lp` contains OT solvers for the exact (Linear Program) OT problems. - - :any:`ot.bregman` contains OT solvers for the entropic OT problems using - Bregman projections. - - :any:`ot.lp` contains OT solvers for the exact (Linear Program) OT problems. - - :any:`ot.smooth` contains OT solvers for the regularized (l2 and kl) smooth OT - problems. - - :any:`ot.gromov` contains solvers for Gromov-Wasserstein and Fused Gromov - Wasserstein problems. - - :any:`ot.optim` contains generic solvers OT based optimization problems - - :any:`ot.da` contains classes and function related to Monge mapping - estimation and Domain Adaptation (DA). - - :any:`ot.gpu` contains GPU (cupy) implementation of some OT solvers - - :any:`ot.dr` contains Dimension Reduction (DR) methods such as Wasserstein - Discriminant Analysis. - - :any:`ot.utils` contains utility functions such as distance computation and - timing. - - :any:`ot.datasets` contains toy dataset generation functions. - - :any:`ot.plot` contains visualization functions - - :any:`ot.stochastic` contains stochastic solvers for regularized OT. - - :any:`ot.unbalanced` contains solvers for regularized unbalanced OT. - - :any:`ot.partial` contains solvers for partial OT. - .. warning:: The list of automatically imported sub-modules is as follows: :py:mod:`ot.lp`, :py:mod:`ot.bregman`, :py:mod:`ot.optim` diff --git a/ot/bregman.py b/ot/bregman.py index 543dbaa..f1f8437 100644 --- a/ot/bregman.py +++ b/ot/bregman.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Bregman projections for regularized OT +Bregman projections solvers for entropic regularized OT """ # Author: Remi Flamary <remi.flamary@unice.fr> @@ -909,11 +909,6 @@ def sinkhorn_epsilon_scaling(a, b, M, reg, numItermax=100, epsilon0=1e4, else: alpha, beta = warmstart - def get_K(alpha, beta): - """log space computation""" - return np.exp(-(M - alpha.reshape((dim_a, 1)) - - beta.reshape((1, dim_b))) / reg) - # print(np.min(K)) def get_reg(n): # exponential decreasing return (epsilon0 - reg) * np.exp(-n) + reg @@ -908,7 +908,8 @@ class BaseTransport(BaseEstimator): at the class level in their ``__init__`` as explicit keyword arguments (no ``*args`` or ``**kwargs``). - fit method should: + the fit method should: + - estimate a cost matrix and store it in a `cost_` attribute - estimate a coupling matrix and store it in a `coupling_` attribute @@ -933,7 +934,7 @@ class BaseTransport(BaseEstimator): Xs : array-like, shape (n_source_samples, n_features) The training input samples. ys : array-like, shape (n_source_samples,) - The class labels + The training class labels Xt : array-like, shape (n_target_samples, n_features) The training input samples. yt : array-like, shape (n_target_samples,) @@ -994,7 +995,7 @@ class BaseTransport(BaseEstimator): Xs : array-like, shape (n_source_samples, n_features) The training input samples. ys : array-like, shape (n_source_samples,) - The class labels + The class labels for training samples Xt : array-like, shape (n_target_samples, n_features) The training input samples. yt : array-like, shape (n_target_samples,) @@ -1018,13 +1019,13 @@ class BaseTransport(BaseEstimator): Parameters ---------- Xs : array-like, shape (n_source_samples, n_features) - The training input samples. + The source input samples. ys : array-like, shape (n_source_samples,) - The class labels + The class labels for source samples Xt : array-like, shape (n_target_samples, n_features) - The training input samples. + The target input samples. yt : array-like, shape (n_target_samples,) - The class labels. If some target samples are unlabeled, fill the + The class labels for target. If some target samples are unlabeled, fill the yt's elements with -1. Warning: Note that, due to this convention -1 cannot be used as a @@ -1085,7 +1086,7 @@ class BaseTransport(BaseEstimator): Parameters ---------- ys : array-like, shape (n_source_samples,) - The class labels + The source class labels Returns ------- @@ -1125,18 +1126,18 @@ class BaseTransport(BaseEstimator): def inverse_transform(self, Xs=None, ys=None, Xt=None, yt=None, batch_size=128): - """Transports target samples Xt onto target samples Xs + """Transports target samples Xt onto source samples Xs Parameters ---------- Xs : array-like, shape (n_source_samples, n_features) - The training input samples. + The source input samples. ys : array-like, shape (n_source_samples,) - The class labels + The source class labels Xt : array-like, shape (n_target_samples, n_features) - The training input samples. + The target input samples. yt : array-like, shape (n_target_samples,) - The class labels. If some target samples are unlabeled, fill the + The target class labels. If some target samples are unlabeled, fill the yt's elements with -1. Warning: Note that, due to this convention -1 cannot be used as a @@ -1227,7 +1228,6 @@ class BaseTransport(BaseEstimator): class LinearTransport(BaseTransport): - """ OT linear operator between empirical distributions The function estimates the optimal linear operator that aligns the two @@ -1438,6 +1438,9 @@ class SinkhornTransport(BaseTransport): .. [2] M. Cuturi, Sinkhorn Distances : Lightspeed Computation of Optimal Transport, Advances in Neural Information Processing Systems (NIPS) 26, 2013 + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. """ def __init__(self, reg_e=1., max_iter=1000, @@ -1536,6 +1539,9 @@ class EMDTransport(BaseTransport): .. [1] N. Courty; R. Flamary; D. Tuia; A. Rakotomamonjy, "Optimal Transport for Domain Adaptation," in IEEE Transactions on Pattern Analysis and Machine Intelligence , vol.PP, no.99, pp.1-1 + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. """ def __init__(self, metric="sqeuclidean", norm=None, log=False, @@ -1643,7 +1649,9 @@ class SinkhornLpl1Transport(BaseTransport): .. [2] Rakotomamonjy, A., Flamary, R., & Courty, N. (2015). Generalized conditional gradient: analysis of convergence and applications. arXiv preprint arXiv:1510.06567. - + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. """ def __init__(self, reg_e=1., reg_cl=0.1, @@ -1763,6 +1771,9 @@ class EMDLaplaceTransport(BaseTransport): .. [2] R. Flamary, N. Courty, D. Tuia, A. Rakotomamonjy, "Optimal transport with Laplacian regularization: Applications to domain adaptation and shape matching," in NIPS Workshop on Optimal Transport and Machine Learning OTML, 2014. + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. """ def __init__(self, reg_type='pos', reg_lap=1., reg_src=1., metric="sqeuclidean", @@ -1882,7 +1893,9 @@ class SinkhornL1l2Transport(BaseTransport): .. [2] Rakotomamonjy, A., Flamary, R., & Courty, N. (2015). Generalized conditional gradient: analysis of convergence and applications. arXiv preprint arXiv:1510.06567. - + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. """ def __init__(self, reg_e=1., reg_cl=0.1, @@ -2174,7 +2187,9 @@ class UnbalancedSinkhornTransport(BaseTransport): .. [1] Chizat, L., Peyré, G., Schmitzer, B., & Vialard, F. X. (2016). Scaling algorithms for unbalanced transport problems. arXiv preprint arXiv:1607.05816. - + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. """ def __init__(self, reg_e=1., reg_m=0.1, method='sinkhorn', @@ -2287,6 +2302,11 @@ class JCPOTTransport(BaseTransport): International Conference on Artificial Intelligence and Statistics (AISTATS), vol. 89, p.849-858, 2019. + .. [6] Ferradans, S., Papadakis, N., Peyré, G., & Aujol, J. F. (2014). + Regularized discrete optimal transport. SIAM Journal on Imaging + Sciences, 7(3), 1853-1882. + + """ def __init__(self, reg_e=.1, max_iter=10, diff --git a/ot/datasets.py b/ot/datasets.py index a1ca7b6..b86ef3b 100644 --- a/ot/datasets.py +++ b/ot/datasets.py @@ -1,5 +1,5 @@ """ -Simple example datasets for OT +Simple example datasets """ # Author: Remi Flamary <remi.flamary@unice.fr> @@ -147,8 +147,8 @@ def make_data_classif(dataset, n, nz=.5, theta=0, p=.5, random_state=None, **kwa n2 = np.sum(y == 2) x = np.zeros((n, 2)) - x[y == 1, :] = get_2D_samples_gauss(n1, m1, nz, random_state=generator) - x[y == 2, :] = get_2D_samples_gauss(n2, m2, nz, random_state=generator) + x[y == 1, :] = make_2D_samples_gauss(n1, m1, nz, random_state=generator) + x[y == 2, :] = make_2D_samples_gauss(n2, m2, nz, random_state=generator) x = x.dot(rot) @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- """ -Dimension reduction with optimal transport +Dimension reduction with OT .. warning:: - Note that by default the module is not import in :mod:`ot`. In order to + Note that by default the module is not imported in :mod:`ot`. In order to use it you need to explicitely import :mod:`ot.dr` """ diff --git a/ot/gpu/__init__.py b/ot/gpu/__init__.py index 1ab95bb..7478fb9 100644 --- a/ot/gpu/__init__.py +++ b/ot/gpu/__init__.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- """ +GPU implementation for several OT solvers and utility +functions. -This module provides GPU implementation for several OT solvers and utility -functions. The GPU backend in handled by `cupy +The GPU backend in handled by `cupy <https://cupy.chainer.org/>`_. .. warning:: diff --git a/ot/gromov.py b/ot/gromov.py index 43780a4..4427a96 100644 --- a/ot/gromov.py +++ b/ot/gromov.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*-
"""
-Gromov-Wasserstein transport method
+Gromov-Wasserstein and Fused-Gromov-Wasserstein solvers
"""
# Author: Erwan Vautier <erwan.vautier@gmail.com>
diff --git a/ot/lp/__init__.py b/ot/lp/__init__.py index ad390c5..50003ed 100644 --- a/ot/lp/__init__.py +++ b/ot/lp/__init__.py @@ -180,7 +180,9 @@ def emd(a, b, M, numItermax=100000, log=False, center_dual=True): \gamma = arg\min_\gamma <\gamma,M>_F s.t. \gamma 1 = a + \gamma^T 1= b + \gamma\geq 0 where : @@ -289,10 +291,12 @@ def emd2(a, b, M, processes=multiprocessing.cpu_count(), r"""Solves the Earth Movers distance problem and returns the loss .. math:: - \gamma = arg\min_\gamma <\gamma,M>_F + \min_\gamma <\gamma,M>_F s.t. \gamma 1 = a + \gamma^T 1= b + \gamma\geq 0 where : diff --git a/ot/optim.py b/ot/optim.py index 4012e0d..b9ca891 100644 --- a/ot/optim.py +++ b/ot/optim.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Optimization algorithms for OT +Generic solvers for regularized OT """ # Author: Remi Flamary <remi.flamary@unice.fr> diff --git a/ot/partial.py b/ot/partial.py index c03ec25..eb707d8 100755 --- a/ot/partial.py +++ b/ot/partial.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Partial OT +Partial OT solvers """ # Author: Laetitia Chapel <laetitia.chapel@irisa.fr> diff --git a/ot/smooth.py b/ot/smooth.py index 5a8e4b5..81f6a3e 100644 --- a/ot/smooth.py +++ b/ot/smooth.py @@ -26,7 +26,9 @@ # Remi Flamary <remi.flamary@unice.fr> """ -Implementation of +Smooth and Sparse Optimal Transport solvers (KL an L2 reg.) + +Implementation of : Smooth and Sparse Optimal Transport. Mathieu Blondel, Vivien Seguy, Antoine Rolet. In Proc. of AISTATS 2018. diff --git a/ot/unbalanced.py b/ot/unbalanced.py index 23f6607..e37f10c 100644 --- a/ot/unbalanced.py +++ b/ot/unbalanced.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -Regularized Unbalanced OT +Regularized Unbalanced OT solvers """ # Author: Hicham Janati <hicham.janati@inria.fr> diff --git a/test/test_bregman.py b/test/test_bregman.py index ec4388d..6aa4e08 100644 --- a/test/test_bregman.py +++ b/test/test_bregman.py @@ -57,6 +57,9 @@ def test_sinkhorn_empty(): np.testing.assert_allclose(u, G.sum(1), atol=1e-05) np.testing.assert_allclose(u, G.sum(0), atol=1e-05) + # test empty weights greenkhorn + ot.sinkhorn([], [], M, 1, method='greenkhorn', stopThr=1e-10, log=True) + def test_sinkhorn_variants(): # test sinkhorn @@ -124,7 +127,7 @@ def test_barycenter(method): # wasserstein reg = 1e-2 - bary_wass = ot.bregman.barycenter(A, M, reg, weights, method=method) + bary_wass, log = ot.bregman.barycenter(A, M, reg, weights, method=method, log=True) np.testing.assert_allclose(1, np.sum(bary_wass)) @@ -152,9 +155,9 @@ def test_barycenter_stabilization(): reg = 1e-2 bar_stable = ot.bregman.barycenter(A, M, reg, weights, method="sinkhorn_stabilized", - stopThr=1e-8) + stopThr=1e-8, verbose=True) bar = ot.bregman.barycenter(A, M, reg, weights, method="sinkhorn", - stopThr=1e-8) + stopThr=1e-8, verbose=True) np.testing.assert_allclose(bar, bar_stable) diff --git a/test/test_optim.py b/test/test_optim.py index aade36e..87b0268 100644 --- a/test/test_optim.py +++ b/test/test_optim.py @@ -38,7 +38,7 @@ def test_conditional_gradient(): def test_conditional_gradient2(): - n = 4000 # nb samples + n = 1000 # nb samples mu_s = np.array([0, 0]) cov_s = np.array([[1, 0], [0, 1]]) diff --git a/test/test_partial.py b/test/test_partial.py index 8b1ca89..510e081 100755 --- a/test/test_partial.py +++ b/test/test_partial.py @@ -8,6 +8,74 @@ import numpy as np import scipy as sp import ot +import pytest + + +def test_raise_errors(): + + n_samples = 20 # nb samples (gaussian) + n_noise = 20 # nb of samples (noise) + + mu = np.array([0, 0]) + cov = np.array([[1, 0], [0, 2]]) + + xs = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) + xs = np.append(xs, (np.random.rand(n_noise, 2) + 1) * 4).reshape((-1, 2)) + xt = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) + xt = np.append(xt, (np.random.rand(n_noise, 2) + 1) * -3).reshape((-1, 2)) + + M = ot.dist(xs, xt) + + p = ot.unif(n_samples + n_noise) + q = ot.unif(n_samples + n_noise) + + with pytest.raises(ValueError): + ot.partial.partial_wasserstein_lagrange(p + 1, q, M, 1, log=True) + + with pytest.raises(ValueError): + ot.partial.partial_wasserstein(p, q, M, m=2, log=True) + + with pytest.raises(ValueError): + ot.partial.partial_wasserstein(p, q, M, m=-1, log=True) + + with pytest.raises(ValueError): + ot.partial.entropic_partial_wasserstein(p, q, M, reg=1, m=2, log=True) + + with pytest.raises(ValueError): + ot.partial.entropic_partial_wasserstein(p, q, M, reg=1, m=-1, log=True) + + with pytest.raises(ValueError): + ot.partial.partial_gromov_wasserstein(M, M, p, q, m=2, log=True) + + with pytest.raises(ValueError): + ot.partial.partial_gromov_wasserstein(M, M, p, q, m=-1, log=True) + + with pytest.raises(ValueError): + ot.partial.entropic_partial_gromov_wasserstein(M, M, p, q, reg=1, m=2, log=True) + + with pytest.raises(ValueError): + ot.partial.entropic_partial_gromov_wasserstein(M, M, p, q, reg=1, m=-1, log=True) + + +def test_partial_wasserstein_lagrange(): + + n_samples = 20 # nb samples (gaussian) + n_noise = 20 # nb of samples (noise) + + mu = np.array([0, 0]) + cov = np.array([[1, 0], [0, 2]]) + + xs = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) + xs = np.append(xs, (np.random.rand(n_noise, 2) + 1) * 4).reshape((-1, 2)) + xt = ot.datasets.make_2D_samples_gauss(n_samples, mu, cov) + xt = np.append(xt, (np.random.rand(n_noise, 2) + 1) * -3).reshape((-1, 2)) + + M = ot.dist(xs, xt) + + p = ot.unif(n_samples + n_noise) + q = ot.unif(n_samples + n_noise) + + w0, log0 = ot.partial.partial_wasserstein_lagrange(p, q, M, 1, log=True) def test_partial_wasserstein(): @@ -32,7 +100,7 @@ def test_partial_wasserstein(): w0, log0 = ot.partial.partial_wasserstein(p, q, M, m=m, log=True) w, log = ot.partial.entropic_partial_wasserstein(p, q, M, reg=1, m=m, - log=True) + log=True, verbose=True) # check constratints np.testing.assert_equal( @@ -92,7 +160,7 @@ def test_partial_gromov_wasserstein(): m = 2 / 3 res0, log0 = ot.partial.partial_gromov_wasserstein(C1, C3, p, q, m=m, - log=True) + log=True, verbose=True) np.testing.assert_allclose(res0, 0, atol=1e-1, rtol=1e-1) C1 = sp.spatial.distance.cdist(xs, xs) diff --git a/test/test_stochastic.py b/test/test_stochastic.py index f0f3fc8..155622c 100644 --- a/test/test_stochastic.py +++ b/test/test_stochastic.py @@ -70,8 +70,8 @@ def test_stochastic_asgd(): M = ot.dist(x, x) - G = ot.stochastic.solve_semi_dual_entropic(u, u, M, reg, "asgd", - numItermax=numItermax) + G, log = ot.stochastic.solve_semi_dual_entropic(u, u, M, reg, "asgd", + numItermax=numItermax, log=True) # check constratints np.testing.assert_allclose( @@ -145,8 +145,8 @@ def test_stochastic_dual_sgd(): M = ot.dist(x, x) - G = ot.stochastic.solve_dual_entropic(u, u, M, reg, batch_size, - numItermax=numItermax) + G, log = ot.stochastic.solve_dual_entropic(u, u, M, reg, batch_size, + numItermax=numItermax, log=True) # check constratints np.testing.assert_allclose( diff --git a/test/test_unbalanced.py b/test/test_unbalanced.py index ca1efba..dfeaad9 100644 --- a/test/test_unbalanced.py +++ b/test/test_unbalanced.py @@ -31,9 +31,11 @@ def test_unbalanced_convergence(method): G, log = ot.unbalanced.sinkhorn_unbalanced(a, b, M, reg=epsilon, reg_m=reg_m, method=method, - log=True) + log=True, + verbose=True) loss = ot.unbalanced.sinkhorn_unbalanced2(a, b, M, epsilon, reg_m, - method=method) + method=method, + verbose=True) # check fixed point equations # in log-domain fi = reg_m / (reg_m + epsilon) @@ -73,7 +75,8 @@ def test_unbalanced_multiple_inputs(method): loss, log = ot.unbalanced.sinkhorn_unbalanced(a, b, M, reg=epsilon, reg_m=reg_m, method=method, - log=True) + log=True, + verbose=True) # check fixed point equations # in log-domain fi = reg_m / (reg_m + epsilon) |