From e610d685405f570f6269e1867cf965630bd6bfe7 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:20:24 +0100 Subject: travis 2 --- .travis.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .travis.yml (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c73bd8f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: python +python: + - "2.6" + - "2.7" + - "3.2" + - "3.3" + - "3.4" + # does not have headers provided, please ask https://launchpad.net/~pypy/+archive/ppa + # maintainers to fix their pypy-dev package. + - "pypy" +# command to install dependencies +install: + - pip install . + - pip install -r requirements.txt +# command to run tests +script: pytest -- cgit v1.2.3 From 9cc998f506a2530b7b13a8ecd932854cf09912a1 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:21:56 +0100 Subject: travis 3 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index c73bd8f..2e9fd85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: - "pypy" # command to install dependencies install: - - pip install . - pip install -r requirements.txt + - pip install . # command to run tests script: pytest -- cgit v1.2.3 From 6f328e065f6e8c877931609686bdfa10e7d29853 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:25:35 +0100 Subject: travis 4 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 2e9fd85..cf92ee8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: - "pypy" # command to install dependencies install: - - pip install -r requirements.txt - - pip install . + - pip install --user -r requirements.txt + - python setup.py install --user # command to run tests script: pytest -- cgit v1.2.3 From bb610ef0e23889efcc25cb25cc1852cc1de44ee4 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:27:05 +0100 Subject: travis 5 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index cf92ee8..0e0ab41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ python: - "pypy" # command to install dependencies install: - - pip install --user -r requirements.txt - - python setup.py install --user + - pip install -r requirements.txt + - python setup.py install # command to run tests script: pytest -- cgit v1.2.3 From 05959d1c570060fdbe44b37049077e28bdba40d8 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:34:29 +0100 Subject: travis 7 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 0e0ab41..26fb52a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ python: - "pypy" # command to install dependencies install: + - pip install --only-binary=numpy,scipy numpy scipy - pip install -r requirements.txt - python setup.py install # command to run tests -- cgit v1.2.3 From 3a65d6b3693c59d8273a6b8b96a2faafed6dd860 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:41:47 +0100 Subject: travis 8 --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 26fb52a..9ab8797 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,16 @@ language: python python: - - "2.6" + - "2.7" - - "3.2" - "3.3" - "3.4" # does not have headers provided, please ask https://launchpad.net/~pypy/+archive/ppa # maintainers to fix their pypy-dev package. - - "pypy" + # - "pypy" +before_install: + - sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev gfortran # command to install dependencies install: - - pip install --only-binary=numpy,scipy numpy scipy - pip install -r requirements.txt - python setup.py install # command to run tests -- cgit v1.2.3 From daffc937892da56aafbcd3607ed47e82b08b40e5 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 09:47:42 +0100 Subject: travis pytest --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 9ab8797..8acffbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ install: - pip install -r requirements.txt - python setup.py install # command to run tests -script: pytest +script: pytest -t test -- cgit v1.2.3 From 2e20a42897c59e2b0ab957982bacd2a5a1a1445a Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 10:07:49 +0100 Subject: travis pytest2 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 8acffbb..88f6517 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ install: - pip install -r requirements.txt - python setup.py install # command to run tests -script: pytest -t test +script: python test/test_load_module.py -v -- cgit v1.2.3 From 391a2d35bf3430bc02058f57bdf2dd765f2d81bf Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 8 Nov 2016 10:20:12 +0100 Subject: travis should work --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 88f6517..8547582 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: python python: - - "2.7" - - "3.3" - "3.4" # does not have headers provided, please ask https://launchpad.net/~pypy/+archive/ppa # maintainers to fix their pypy-dev package. -- cgit v1.2.3 From bb0047b374634a410ae3ded063784638a401b3f6 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 23 Jun 2017 09:12:20 +0200 Subject: test travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 8547582..244dbbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ python: # maintainers to fix their pypy-dev package. # - "pypy" before_install: - - sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev gfortran + - sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev #gfortran # command to install dependencies install: - pip install -r requirements.txt -- cgit v1.2.3 From 11239a9848e97201b3d4aa04224f3421b2c3974a Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 23 Jun 2017 13:10:27 +0200 Subject: add apt update tarvis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 244dbbb..ebdd225 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: # maintainers to fix their pypy-dev package. # - "pypy" before_install: + - sudo apt-get update -q - sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev #gfortran # command to install dependencies install: -- cgit v1.2.3 From a66807ee1fb45994cca7a2cc52b1cf06354e760d Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 7 Jul 2017 10:56:55 +0200 Subject: éadd macosxé MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index ebdd225..a741da4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,7 @@ language: python +os: + - linux + - osx python: - "2.7" - "3.4" @@ -6,8 +9,10 @@ python: # maintainers to fix their pypy-dev package. # - "pypy" before_install: - - sudo apt-get update -q - - sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev #gfortran + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get update -q ; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev; fi #gfortran + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python; fi # command to install dependencies install: - pip install -r requirements.txt -- cgit v1.2.3 From 6fe6020a336abf731defb75c3c908814429ad98c Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 7 Jul 2017 11:03:35 +0200 Subject: anotehr test --- .travis.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index a741da4..9b9efa2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,13 +9,26 @@ python: # maintainers to fix their pypy-dev package. # - "pypy" before_install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get update -q ; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev; fi #gfortran - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python; fi + - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get update -q ; fi' + - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev; fi #gfortran' + - 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi' + - 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python; fi' # command to install dependencies install: - pip install -r requirements.txt - python setup.py install # command to run tests +matrix: + include: + - os: linux + sudo: required + python: 3.2 + env: TOXENV=py32 + - os: linux + sudo: required + python: 3.3 + env: TOXENV=py33 + - os: osx + language: generic + env: TOXENV=py3 script: python test/test_load_module.py -v -- cgit v1.2.3 From d361e3f6b177506a54ce1e928a03d763ae59de98 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 7 Jul 2017 11:09:12 +0200 Subject: add before install script --- .travis.yml | 18 +++--------------- .travis/before_install.sh | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 15 deletions(-) create mode 100644 .travis/before_install.sh (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 9b9efa2..627e5cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: python os: - linux - - osx python: - "2.7" - "3.4" @@ -9,10 +8,7 @@ python: # maintainers to fix their pypy-dev package. # - "pypy" before_install: - - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get update -q ; fi' - - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev; fi #gfortran' - - 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi' - - 'if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python; fi' + - ./.travis/before_install.sh # command to install dependencies install: - pip install -r requirements.txt @@ -20,15 +16,7 @@ install: # command to run tests matrix: include: - - os: linux - sudo: required - python: 3.2 - env: TOXENV=py32 - - os: linux - sudo: required - python: 3.3 - env: TOXENV=py33 - os: osx - language: generic - env: TOXENV=py3 + language: python + script: python test/test_load_module.py -v diff --git a/.travis/before_install.sh b/.travis/before_install.sh new file mode 100644 index 0000000..cfa3fdc --- /dev/null +++ b/.travis/before_install.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +if [[ $TRAVIS_OS_NAME == 'osx' ]]; then + + # Install some custom requirements on OS X + # e.g. brew install pyenv-virtualenv + brew update + brew install python + + +else + # Install some custom requirements on Linux + sudo apt-get update -q + sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev +fi -- cgit v1.2.3 From e6887665538f437e9aa0b0cf44d54be2dff8cd74 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 7 Jul 2017 11:13:42 +0200 Subject: sudo required --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 627e5cd..ea809d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,5 +18,6 @@ matrix: include: - os: osx language: python - + - os: linux + sudo: required script: python test/test_load_module.py -v -- cgit v1.2.3 From 3867a1441f34bac5ac4270b903f9582a23fa2671 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 7 Jul 2017 11:18:49 +0200 Subject: better --- .travis.yml | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index ea809d9..f10131a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,16 @@ language: python -os: - - linux -python: - - "2.7" - - "3.4" - # does not have headers provided, please ask https://launchpad.net/~pypy/+archive/ppa - # maintainers to fix their pypy-dev package. - # - "pypy" +matrix: + allow_failures: + - os: osx + include: + - os: osx + language: python + - os: linux + sudo: required + python: 3.4 + - os: linux + sudo: required + python: 2.7 before_install: - ./.travis/before_install.sh # command to install dependencies @@ -14,10 +18,4 @@ install: - pip install -r requirements.txt - python setup.py install # command to run tests -matrix: - include: - - os: osx - language: python - - os: linux - sudo: required script: python test/test_load_module.py -v -- cgit v1.2.3 From 5cb196f0d9af2f100903e160807b58fddcfcaeed Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 7 Jul 2017 11:23:33 +0200 Subject: osx build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index f10131a..6126b3a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ matrix: - os: osx include: - os: osx - language: python + language: generic - os: linux sudo: required python: 3.4 -- cgit v1.2.3 From d0258f103946eb78f2fff6a3a82d85744ba27ec8 Mon Sep 17 00:00:00 2001 From: Alexandre Gramfort Date: Tue, 11 Jul 2017 21:32:41 +0200 Subject: add flake8 to travis + misc --- .gitignore | 3 +++ .travis.yml | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.gitignore b/.gitignore index 21be4c9..6edce05 100644 --- a/.gitignore +++ b/.gitignore @@ -97,3 +97,6 @@ ENV/ # Rope project settings .ropeproject + +# Mac stuff +.DS_Store diff --git a/.travis.yml b/.travis.yml index 6126b3a..8023ec5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,10 @@ before_install: # command to install dependencies install: - pip install -r requirements.txt + - pip install flake8 pytest - python setup.py install -# command to run tests -script: python test/test_load_module.py -v +# command to run tests + check syntax style +script: + - python test/test_load_module.py -v + - flake8 . + - py.test ot test -- cgit v1.2.3 From f15336be3bb91b619803bfbb58e7931997c46574 Mon Sep 17 00:00:00 2001 From: Alexandre Gramfort Date: Wed, 12 Jul 2017 23:57:11 +0200 Subject: update travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 8023ec5..050510b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,5 +21,5 @@ install: # command to run tests + check syntax style script: - python test/test_load_module.py -v - - flake8 . + - flake8 examples/ ot/ test/ - py.test ot test -- cgit v1.2.3 From cd9842dc2978cba757a51c32cce0272858c9a385 Mon Sep 17 00:00:00 2001 From: Alexandre Gramfort Date: Thu, 13 Jul 2017 00:04:49 +0200 Subject: more --- .travis.yml | 2 +- test/test_emd_multi.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 050510b..8a95d7c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,4 +22,4 @@ install: script: - python test/test_load_module.py -v - flake8 examples/ ot/ test/ - - py.test ot test + # - py.test ot test diff --git a/test/test_emd_multi.py b/test/test_emd_multi.py index 99173e9..2eef242 100644 --- a/test/test_emd_multi.py +++ b/test/test_emd_multi.py @@ -22,7 +22,7 @@ x = np.arange(n, dtype=np.float64) # Gaussian distributions a = gauss(n, m=20, s=5) # m= mean, s= std -ls = range(20, 1000, 10) +ls = np.arange(20, 1000, 10) nb = len(ls) b = np.zeros((n, nb)) for i in range(nb): -- cgit v1.2.3 From 5a6b5de9b2f28c93bef1a9db2e3b94693c05ff4f Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Mon, 24 Jul 2017 11:15:33 +0200 Subject: add proper testing --- .travis.yml | 2 +- Makefile | 13 ++++++---- docs/source/readme.rst | 52 +++++++++++++++++++++++++++++-------- test/test_emd_multi.py | 47 --------------------------------- test/test_gpu.py | 59 ++++++++++++++++++++++++++++++++++++++++++ test/test_gpu_sinkhorn.py | 28 -------------------- test/test_gpu_sinkhorn_lpl1.py | 29 --------------------- test/test_load_module.py | 10 ------- test/test_ot.py | 55 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 164 insertions(+), 131 deletions(-) delete mode 100644 test/test_emd_multi.py create mode 100644 test/test_gpu.py delete mode 100644 test/test_gpu_sinkhorn.py delete mode 100644 test/test_gpu_sinkhorn_lpl1.py delete mode 100644 test/test_load_module.py create mode 100644 test/test_ot.py (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 8a95d7c..1c3a18c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,6 @@ install: - python setup.py install # command to run tests + check syntax style script: - - python test/test_load_module.py -v - flake8 examples/ ot/ test/ + - python -m py.test -v # - py.test ot test diff --git a/Makefile b/Makefile index c6a83c8..ff03a63 100644 --- a/Makefile +++ b/Makefile @@ -31,22 +31,25 @@ sremove : tr '\n' '\0' < files.txt | sudo xargs -0 rm -f -- rm files.txt -clean : +clean : FORCE $(PYTHON) setup.py clean pep8 : flake8 examples/ ot/ test/ -test: - pytest +test : FORCE pep8 + python -m py.test -v -uploadpypi: +uploadpypi : #python setup.py register python setup.py sdist upload -r pypi -rdoc: +rdoc : pandoc --from=markdown --to=rst --output=docs/source/readme.rst README.md notebook : ipython notebook --matplotlib=inline --notebook-dir=notebooks/ + + +FORCE : diff --git a/docs/source/readme.rst b/docs/source/readme.rst index 611001b..c1e0017 100644 --- a/docs/source/readme.rst +++ b/docs/source/readme.rst @@ -28,8 +28,8 @@ available in the examples folder. Installation ------------ -The Library has been tested on Linux and MacOSX. It requires a C++ -compiler for using the EMD solver and rely on the following Python +The library has been tested on Linux, MacOSX and Windows. It requires a +C++ compiler for using the EMD solver and relies on the following Python modules: - Numpy (>=1.11) @@ -37,25 +37,34 @@ modules: - Cython (>=0.23) - Matplotlib (>=1.5) -Under debian based linux the dependencies can be installed with +Pip installation +^^^^^^^^^^^^^^^^ + +You can install the toolbox through PyPI with: :: - sudo apt-get install python-numpy python-scipy python-matplotlib cython + pip install POT -To install the library, you can install it locally (after downloading -it) on you machine using +or get the very latest version by downloading it and then running: :: python setup.py install --user # for user install (no root) -The toolbox is also available on PyPI with a possibly slightly older -version. You can install it with: +Anaconda installation with conda-forge +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you use the Anaconda python distribution, POT is available in +`conda-forge `__. To install it and the +required dependencies: :: - pip install POT + conda install -c conda-forge pot + +Post installation check +^^^^^^^^^^^^^^^^^^^^^^^ After a correct installation, you should be able to import the module without errors: @@ -109,6 +118,7 @@ Short examples # a,b are 1D histograms (sum to 1 and positive) # M is the ground cost matrix Wd=ot.emd2(a,b,M) # exact linear program + Wd_reg=ot.sinkhorn2(a,b,M,reg) # entropic regularized OT # if b is a matrix compute all distances to a and return a vector - Compute OT matrix @@ -117,8 +127,8 @@ Short examples # a,b are 1D histograms (sum to 1 and positive) # M is the ground cost matrix - Totp=ot.emd(a,b,M) # exact linear program - Totp_reg=ot.sinkhorn(a,b,M,reg) # entropic regularized OT + T=ot.emd(a,b,M) # exact linear program + T_reg=ot.sinkhorn(a,b,M,reg) # entropic regularized OT - Compute Wasserstein barycenter @@ -172,6 +182,7 @@ The contributors to this library are: - `Rémi Flamary `__ - `Nicolas Courty `__ +- `Alexandre Gramfort `__ - `Laetitia Chapel `__ - `Michael Perrot `__ (Mapping estimation) @@ -189,6 +200,25 @@ languages): - `Marco Cuturi `__ (Sinkhorn Knopp in Matlab/Cuda) +Contributions and code of conduct +--------------------------------- + +Every contribution is welcome and should respect the `contribution +guidelines `__. Each member of the project is expected +to follow the `code of conduct `__. + +Support +------- + +You can ask questions and join the development discussion: + +- On the `POT Slack channel `__ +- On the POT `mailing + list `__ + +You can also post bug reports and feature requests in Github issues. +Make sure to read our `guidelines `__ first. + References ---------- diff --git a/test/test_emd_multi.py b/test/test_emd_multi.py deleted file mode 100644 index 2eef242..0000000 --- a/test/test_emd_multi.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -""" -Created on Fri Mar 10 09:56:06 2017 - -@author: rflamary -""" - -import numpy as np - -import ot -from ot.datasets import get_1D_gauss as gauss -# reload(ot.lp) - -#%% parameters - -n = 5000 # nb bins - -# bin positions -x = np.arange(n, dtype=np.float64) - -# Gaussian distributions -a = gauss(n, m=20, s=5) # m= mean, s= std - -ls = np.arange(20, 1000, 10) -nb = len(ls) -b = np.zeros((n, nb)) -for i in range(nb): - b[:, i] = gauss(n, m=ls[i], s=10) - -# loss matrix -M = ot.dist(x.reshape((n, 1)), x.reshape((n, 1))) -# M/=M.max() - -#%% - -print('Computing {} EMD '.format(nb)) - -# emd loss 1 proc -ot.tic() -emd_loss4 = ot.emd2(a, b, M, 1) -ot.toc('1 proc : {} s') - -# emd loss multipro proc -ot.tic() -emd_loss4 = ot.emd2(a, b, M) -ot.toc('multi proc : {} s') diff --git a/test/test_gpu.py b/test/test_gpu.py new file mode 100644 index 0000000..312a2d4 --- /dev/null +++ b/test/test_gpu.py @@ -0,0 +1,59 @@ +import ot +import numpy as np +import time +import pytest + + +@pytest.mark.skip(reason="No way to test GPU on travis yet") +def test_gpu_sinkhorn(): + import ot.gpu + + def describeRes(r): + print("min:{:.3E}, max::{:.3E}, mean::{:.3E}, std::{:.3E}".format( + np.min(r), np.max(r), np.mean(r), np.std(r))) + + for n in [5000]: + print(n) + a = np.random.rand(n // 4, 100) + b = np.random.rand(n, 100) + time1 = time.time() + transport = ot.da.OTDA_sinkhorn() + transport.fit(a, b) + G1 = transport.G + time2 = time.time() + transport = ot.gpu.da.OTDA_sinkhorn() + transport.fit(a, b) + G2 = transport.G + time3 = time.time() + print("Normal sinkhorn, time: {:6.2f} sec ".format(time2 - time1)) + describeRes(G1) + print(" GPU sinkhorn, time: {:6.2f} sec ".format(time3 - time2)) + describeRes(G2) + + +@pytest.mark.skip(reason="No way to test GPU on travis yet") +def test_gpu_sinkhorn_lpl1(): + def describeRes(r): + print("min:{:.3E}, max:{:.3E}, mean:{:.3E}, std:{:.3E}" + .format(np.min(r), np.max(r), np.mean(r), np.std(r))) + + for n in [5000]: + print(n) + a = np.random.rand(n // 4, 100) + labels_a = np.random.randint(10, size=(n // 4)) + b = np.random.rand(n, 100) + time1 = time.time() + transport = ot.da.OTDA_lpl1() + transport.fit(a, labels_a, b) + G1 = transport.G + time2 = time.time() + transport = ot.gpu.da.OTDA_lpl1() + transport.fit(a, labels_a, b) + G2 = transport.G + time3 = time.time() + print("Normal sinkhorn lpl1, time: {:6.2f} sec ".format( + time2 - time1)) + describeRes(G1) + print(" GPU sinkhorn lpl1, time: {:6.2f} sec ".format( + time3 - time2)) + describeRes(G2) diff --git a/test/test_gpu_sinkhorn.py b/test/test_gpu_sinkhorn.py deleted file mode 100644 index 841f062..0000000 --- a/test/test_gpu_sinkhorn.py +++ /dev/null @@ -1,28 +0,0 @@ -import ot -import numpy as np -import time -import ot.gpu - - -def describeRes(r): - print("min:{:.3E}, max::{:.3E}, mean::{:.3E}, std::{:.3E}".format( - np.min(r), np.max(r), np.mean(r), np.std(r))) - - -for n in [5000, 10000, 15000, 20000]: - print(n) - a = np.random.rand(n // 4, 100) - b = np.random.rand(n, 100) - time1 = time.time() - transport = ot.da.OTDA_sinkhorn() - transport.fit(a, b) - G1 = transport.G - time2 = time.time() - transport = ot.gpu.da.OTDA_sinkhorn() - transport.fit(a, b) - G2 = transport.G - time3 = time.time() - print("Normal sinkhorn, time: {:6.2f} sec ".format(time2 - time1)) - describeRes(G1) - print(" GPU sinkhorn, time: {:6.2f} sec ".format(time3 - time2)) - describeRes(G2) diff --git a/test/test_gpu_sinkhorn_lpl1.py b/test/test_gpu_sinkhorn_lpl1.py deleted file mode 100644 index f0eb7e6..0000000 --- a/test/test_gpu_sinkhorn_lpl1.py +++ /dev/null @@ -1,29 +0,0 @@ -import ot -import numpy as np -import time -import ot.gpu - - -def describeRes(r): - print("min:{:.3E}, max:{:.3E}, mean:{:.3E}, std:{:.3E}" - .format(np.min(r), np.max(r), np.mean(r), np.std(r))) - - -for n in [5000, 10000, 15000, 20000]: - print(n) - a = np.random.rand(n // 4, 100) - labels_a = np.random.randint(10, size=(n // 4)) - b = np.random.rand(n, 100) - time1 = time.time() - transport = ot.da.OTDA_lpl1() - transport.fit(a, labels_a, b) - G1 = transport.G - time2 = time.time() - transport = ot.gpu.da.OTDA_lpl1() - transport.fit(a, labels_a, b) - G2 = transport.G - time3 = time.time() - print("Normal sinkhorn lpl1, time: {:6.2f} sec ".format(time2 - time1)) - describeRes(G1) - print(" GPU sinkhorn lpl1, time: {:6.2f} sec ".format(time3 - time2)) - describeRes(G2) diff --git a/test/test_load_module.py b/test/test_load_module.py deleted file mode 100644 index d77261e..0000000 --- a/test/test_load_module.py +++ /dev/null @@ -1,10 +0,0 @@ - - -import ot -import doctest - -# test lp solver -doctest.testmod(ot.lp, verbose=True) - -# test bregman solver -doctest.testmod(ot.bregman, verbose=True) diff --git a/test/test_ot.py b/test/test_ot.py new file mode 100644 index 0000000..51ee510 --- /dev/null +++ b/test/test_ot.py @@ -0,0 +1,55 @@ + + +import ot +import numpy as np + +#import pytest + + +def test_doctest(): + + import doctest + + # test lp solver + doctest.testmod(ot.lp, verbose=True) + + # test bregman solver + doctest.testmod(ot.bregman, verbose=True) + + +#@pytest.mark.skip(reason="Seems to be a conflict between pytest and multiprocessing") +def test_emd_multi(): + + from ot.datasets import get_1D_gauss as gauss + + n = 1000 # nb bins + + # bin positions + x = np.arange(n, dtype=np.float64) + + # Gaussian distributions + a = gauss(n, m=20, s=5) # m= mean, s= std + + ls = np.arange(20, 1000, 10) + nb = len(ls) + b = np.zeros((n, nb)) + for i in range(nb): + b[:, i] = gauss(n, m=ls[i], s=10) + + # loss matrix + M = ot.dist(x.reshape((n, 1)), x.reshape((n, 1))) + # M/=M.max() + + print('Computing {} EMD '.format(nb)) + + # emd loss 1 proc + ot.tic() + emd1 = ot.emd2(a, b, M, 1) + ot.toc('1 proc : {} s') + + # emd loss multipro proc + ot.tic() + emdn = ot.emd2(a, b, M) + ot.toc('multi proc : {} s') + + assert np.allclose(emd1, emdn) -- cgit v1.2.3 From beed8f49ee8d0bf828fc0b63f23254561d7566b0 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Mon, 24 Jul 2017 11:21:00 +0200 Subject: update test --- .travis.yml | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 1c3a18c..c5ca62b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,5 +21,5 @@ install: # command to run tests + check syntax style script: - flake8 examples/ ot/ test/ - - python -m py.test -v + - python -m py.test -v test/ # - py.test ot test diff --git a/Makefile b/Makefile index ff03a63..cabe6a9 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ pep8 : flake8 examples/ ot/ test/ test : FORCE pep8 - python -m py.test -v + python -m py.test -v test/ uploadpypi : #python setup.py register -- cgit v1.2.3 From 01f8c44d3e6dbe129b4b621af370bb6f015ab2b2 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Mon, 24 Jul 2017 11:29:25 +0200 Subject: try debug travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index c5ca62b..dc415a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,9 +17,10 @@ before_install: install: - pip install -r requirements.txt - pip install flake8 pytest - - python setup.py install + - pip install . # command to run tests + check syntax style script: + - python setup.py develop - flake8 examples/ ot/ test/ - python -m py.test -v test/ # - py.test ot test -- cgit v1.2.3 From 11f065237982516c08f91e7757dd7a81c9c525d6 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Mon, 24 Jul 2017 18:26:48 +0200 Subject: matplotlib travis --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index dc415a9..ec2b3d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,10 @@ matrix: python: 2.7 before_install: - ./.travis/before_install.sh +before_script: # configure a headless display to test plot generation + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + - sleep 3 # give xvfb some time to start # command to install dependencies install: - pip install -r requirements.txt -- cgit v1.2.3 From 17790802c6f3f31b30ad36f4a163eacf8eb6049e Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 9 May 2018 13:32:47 +0200 Subject: add several python 3 --- .travis.yml | 6 ++++++ .travis/before_install.sh | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index ec2b3d2..756b765 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,12 @@ matrix: - os: linux sudo: required python: 3.4 + - os: linux + sudo: required + python: 3.5 + - os: linux + sudo: required + python: 3.6 - os: linux sudo: required python: 2.7 diff --git a/.travis/before_install.sh b/.travis/before_install.sh index 60d1dcf..ce18f12 100755 --- a/.travis/before_install.sh +++ b/.travis/before_install.sh @@ -6,7 +6,7 @@ if [[ $TRAVIS_OS_NAME == 'osx' ]]; then # e.g. brew install pyenv-virtualenv #brew update #brew install python - echo do othing + echo do nothing else -- cgit v1.2.3 From 44fa4b82a0d1184369f7cfa87cac4f8c910ebe14 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 9 May 2018 13:52:32 +0200 Subject: wront travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 756b765..b45258a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,10 @@ matrix: python: 3.4 - os: linux sudo: required - python: 3.5 + python: 3.5 - os: linux sudo: required - python: 3.6 + python: 3.6 - os: linux sudo: required python: 2.7 -- cgit v1.2.3 From 04f0149e644e9231a3f2e66e3d2335d1465efe06 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 9 May 2018 13:53:57 +0200 Subject: space in travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index b45258a..b45330f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ matrix: - os: linux sudo: required python: 3.5 - - os: linux + - os: linux sudo: required python: 3.6 - os: linux -- cgit v1.2.3 From 58387b96cb2b4a417c84e729f0084be68fad731e Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 9 May 2018 14:05:58 +0200 Subject: switch to pytest --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index b45330f..56daada 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,5 +32,5 @@ install: script: - python setup.py develop - flake8 examples/ ot/ test/ - - python -m py.test -v test/ + - python -m pytest -v test/ # - py.test ot test -- cgit v1.2.3 From cc981610ba88e0222246aec2fdff903e8b83d918 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 9 May 2018 14:21:10 +0200 Subject: remove osx --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 56daada..d146395 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ language: python matrix: - allow_failures: - - os: osx +# allow_failures: +# - os: osx include: - - os: osx - language: generic +# - os: osx +# language: generic - os: linux sudo: required python: 3.4 -- cgit v1.2.3 From 5bb13e439578ad8952bece8f491ce68bb1efe47d Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Mon, 24 Sep 2018 15:47:29 +0200 Subject: do code coverage in travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index d146395..90a0ff4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,11 +26,11 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt - - pip install flake8 pytest + - pip install flake8 pytest pytest-cov - pip install . # command to run tests + check syntax style script: - python setup.py develop - flake8 examples/ ot/ test/ - - python -m pytest -v test/ + - python -m pytest -v test/ --cov=ot # - py.test ot test -- cgit v1.2.3 From fea0c38c4260788c0359547f7caf75a3d92a2b42 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Mon, 11 Mar 2019 10:51:10 +0100 Subject: pytest-cov workaronud --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 90a0ff4..50ff22c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt - - pip install flake8 pytest pytest-cov + - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style script: -- cgit v1.2.3 From 93a74fe4d477e1735e9ce21ee4113281f58b4dcf Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Mon, 1 Jul 2019 11:02:11 +0200 Subject: Explicit doctest call in travis + removed uneffective doctest in test_ot --- .travis.yml | 2 +- test/test_ot.py | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 50ff22c..d6b4232 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,5 +32,5 @@ install: script: - python setup.py develop - flake8 examples/ ot/ test/ - - python -m pytest -v test/ --cov=ot + - python -m pytest -v test/ ot/ --doctest-modules --cov=ot # - py.test ot test diff --git a/test/test_ot.py b/test/test_ot.py index 3c4ac11..ac86602 100644 --- a/test/test_ot.py +++ b/test/test_ot.py @@ -14,16 +14,6 @@ from ot.datasets import make_1D_gauss as gauss import pytest -def test_doctest(): - import doctest - - # test lp solver - doctest.testmod(ot.lp, verbose=True) - - # test bregman solver - doctest.testmod(ot.bregman, verbose=True) - - def test_emd_emd2(): # test emd and emd2 for simple identity n = 100 -- cgit v1.2.3 From 1fe13ed9cdda363c95c84f95fc70dcd95ac276f1 Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Mon, 1 Jul 2019 12:16:04 +0200 Subject: Fixed doctests --- .travis.yml | 2 +- ot/bregman.py | 17 +++++++--------- ot/stochastic.py | 59 +++++++++++++++++++++++--------------------------------- ot/utils.py | 6 +++--- 4 files changed, 35 insertions(+), 49 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index d6b4232..da68c96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,5 +32,5 @@ install: script: - python setup.py develop - flake8 examples/ ot/ test/ - - python -m pytest -v test/ ot/ --doctest-modules --cov=ot + - python -m pytest -v test/ ot/ --doctest-modules --ignore ot/gpu/ --cov=ot # - py.test ot test diff --git a/ot/bregman.py b/ot/bregman.py index 09716e6..8225967 100644 --- a/ot/bregman.py +++ b/ot/bregman.py @@ -1360,10 +1360,9 @@ def empirical_sinkhorn(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numI >>> reg = 0.1 >>> X_s = np.reshape(np.arange(n_s), (n_s, 1)) >>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1)) - >>> emp_sinkhorn = empirical_sinkhorn(X_s, X_t, reg, verbose=False) - >>> print(emp_sinkhorn) - >>> [[4.99977301e-01 2.26989344e-05] - [2.26989344e-05 4.99977301e-01]] + >>> empirical_sinkhorn(X_s, X_t, reg, verbose=False) # doctest: +NORMALIZE_WHITESPACE + array([[4.99977301e-01, 2.26989344e-05], + [2.26989344e-05, 4.99977301e-01]]) References @@ -1451,9 +1450,8 @@ def empirical_sinkhorn2(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', num >>> reg = 0.1 >>> X_s = np.reshape(np.arange(n_s), (n_s, 1)) >>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1)) - >>> loss_sinkhorn = empirical_sinkhorn2(X_s, X_t, reg, verbose=False) - >>> print(loss_sinkhorn) - >>> [4.53978687e-05] + >>> empirical_sinkhorn2(X_s, X_t, reg, verbose=False) + array([4.53978687e-05]) References @@ -1560,9 +1558,8 @@ def empirical_sinkhorn_divergence(X_s, X_t, reg, a=None, b=None, metric='sqeucli >>> reg = 0.1 >>> X_s = np.reshape(np.arange(n_s), (n_s, 1)) >>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1)) - >>> emp_sinkhorn_div = empirical_sinkhorn_divergence(X_s, X_t, reg) - >>> print(emp_sinkhorn_div) - >>> [2.99977435] + >>> empirical_sinkhorn_divergence(X_s, X_t, reg) + array([2.99977435]) References diff --git a/ot/stochastic.py b/ot/stochastic.py index 85c4230..762eb3e 100644 --- a/ot/stochastic.py +++ b/ot/stochastic.py @@ -11,7 +11,7 @@ import numpy as np def coordinate_grad_semi_dual(b, M, reg, beta, i): - ''' + r''' Compute the coordinate gradient update for regularized discrete distributions for (i, :) The function computes the gradient of the semi dual problem: @@ -51,7 +51,7 @@ def coordinate_grad_semi_dual(b, M, reg, beta, i): Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -63,8 +63,7 @@ def coordinate_grad_semi_dual(b, M, reg, beta, i): >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> method = "ASGD" - >>> asgd_pi = stochastic.solve_semi_dual_entropic(a, b, M, reg, - method, numItermax) + >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) >>> print(asgd_pi) References @@ -84,7 +83,7 @@ def coordinate_grad_semi_dual(b, M, reg, beta, i): def sag_entropic_transport(a, b, M, reg, numItermax=10000, lr=None): - ''' + r''' Compute the SAG algorithm to solve the regularized discrete measures optimal transport max problem @@ -133,7 +132,7 @@ def sag_entropic_transport(a, b, M, reg, numItermax=10000, lr=None): Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -145,8 +144,7 @@ def sag_entropic_transport(a, b, M, reg, numItermax=10000, lr=None): >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> method = "ASGD" - >>> asgd_pi = stochastic.solve_semi_dual_entropic(a, b, M, reg, - method, numItermax) + >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) >>> print(asgd_pi) References @@ -176,7 +174,7 @@ def sag_entropic_transport(a, b, M, reg, numItermax=10000, lr=None): def averaged_sgd_entropic_transport(a, b, M, reg, numItermax=300000, lr=None): - ''' + r''' Compute the ASGD algorithm to solve the regularized semi continous measures optimal transport max problem The function solves the following optimization problem: @@ -223,7 +221,7 @@ def averaged_sgd_entropic_transport(a, b, M, reg, numItermax=300000, lr=None): Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -235,8 +233,7 @@ def averaged_sgd_entropic_transport(a, b, M, reg, numItermax=300000, lr=None): >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> method = "ASGD" - >>> asgd_pi = stochastic.solve_semi_dual_entropic(a, b, M, reg, - method, numItermax) + >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) >>> print(asgd_pi) References @@ -264,7 +261,7 @@ def averaged_sgd_entropic_transport(a, b, M, reg, numItermax=300000, lr=None): def c_transform_entropic(b, M, reg, beta): - ''' + r''' The goal is to recover u from the c-transform. The function computes the c_transform of a dual variable from the other @@ -303,7 +300,7 @@ def c_transform_entropic(b, M, reg, beta): Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -315,8 +312,7 @@ def c_transform_entropic(b, M, reg, beta): >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> method = "ASGD" - >>> asgd_pi = stochastic.solve_semi_dual_entropic(a, b, M, reg, - method, numItermax) + >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) >>> print(asgd_pi) References @@ -340,7 +336,7 @@ def c_transform_entropic(b, M, reg, beta): def solve_semi_dual_entropic(a, b, M, reg, method, numItermax=10000, lr=None, log=False): - ''' + r''' Compute the transportation matrix to solve the regularized discrete measures optimal transport max problem @@ -398,7 +394,7 @@ def solve_semi_dual_entropic(a, b, M, reg, method, numItermax=10000, lr=None, Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -410,8 +406,7 @@ def solve_semi_dual_entropic(a, b, M, reg, method, numItermax=10000, lr=None, >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> method = "ASGD" - >>> asgd_pi = stochastic.solve_semi_dual_entropic(a, b, M, reg, - method, numItermax) + >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) >>> print(asgd_pi) References @@ -451,7 +446,7 @@ def solve_semi_dual_entropic(a, b, M, reg, method, numItermax=10000, lr=None, def batch_grad_dual(a, b, M, reg, alpha, beta, batch_size, batch_alpha, batch_beta): - ''' + r''' Computes the partial gradient of the dual optimal transport problem. For each (i,j) in a batch of coordinates, the partial gradients are : @@ -506,7 +501,7 @@ def batch_grad_dual(a, b, M, reg, alpha, beta, batch_size, batch_alpha, Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -520,9 +515,7 @@ def batch_grad_dual(a, b, M, reg, alpha, beta, batch_size, batch_alpha, >>> X_source = rng.randn(n_source, 2) >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> sgd_dual_pi, log = stochastic.solve_dual_entropic(a, b, M, reg, - batch_size, - numItermax, lr, log) + >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg, batch_size, numItermax, lr, log) >>> print(log['alpha'], log['beta']) >>> print(sgd_dual_pi) @@ -548,7 +541,7 @@ def batch_grad_dual(a, b, M, reg, alpha, beta, batch_size, batch_alpha, def sgd_entropic_regularization(a, b, M, reg, batch_size, numItermax, lr): - ''' + r''' Compute the sgd algorithm to solve the regularized discrete measures optimal transport dual problem @@ -597,7 +590,7 @@ def sgd_entropic_regularization(a, b, M, reg, batch_size, numItermax, lr): Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -611,9 +604,7 @@ def sgd_entropic_regularization(a, b, M, reg, batch_size, numItermax, lr): >>> X_source = rng.randn(n_source, 2) >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> sgd_dual_pi, log = stochastic.solve_dual_entropic(a, b, M, reg, - batch_size, - numItermax, lr, log) + >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg, batch_size, numItermax, lr, log) >>> print(log['alpha'], log['beta']) >>> print(sgd_dual_pi) @@ -644,7 +635,7 @@ def sgd_entropic_regularization(a, b, M, reg, batch_size, numItermax, lr): def solve_dual_entropic(a, b, M, reg, batch_size, numItermax=10000, lr=1, log=False): - ''' + r''' Compute the transportation matrix to solve the regularized discrete measures optimal transport dual problem @@ -695,7 +686,7 @@ def solve_dual_entropic(a, b, M, reg, batch_size, numItermax=10000, lr=1, Examples -------- - + >>> import ot >>> n_source = 7 >>> n_target = 4 >>> reg = 1 @@ -709,9 +700,7 @@ def solve_dual_entropic(a, b, M, reg, batch_size, numItermax=10000, lr=1, >>> X_source = rng.randn(n_source, 2) >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> sgd_dual_pi, log = stochastic.solve_dual_entropic(a, b, M, reg, - batch_size, - numItermax, lr, log) + >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg, batch_size, numItermax, lr, log) >>> print(log['alpha'], log['beta']) >>> print(sgd_dual_pi) diff --git a/ot/utils.py b/ot/utils.py index efd1288..f21ceb9 100644 --- a/ot/utils.py +++ b/ot/utils.py @@ -285,9 +285,9 @@ class deprecated(object): The optional extra argument will be appended to the deprecation message and the docstring. Note: to use this with the default value for extra, put in an empty of parentheses: - >>> from ot.deprecation import deprecated - >>> @deprecated() - ... def some_function(): pass + >>> from ot.deprecation import deprecated # doctest: +SKIP + >>> @deprecated() # doctest: +SKIP + ... def some_function(): pass # doctest: +SKIP Parameters ---------- -- cgit v1.2.3 From 3a84263ffe4bbf2ac055dfd5a84e1b65c14f9cda Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Mon, 1 Jul 2019 14:23:14 +0200 Subject: Set numpy array formatting version to post-1.13 --- .travis.yml | 2 ++ ot/bregman.py | 86 +++++++++++++++++++++++++++---------------------------- ot/lp/__init__.py | 22 +++++++------- ot/unbalanced.py | 10 +++---- 4 files changed, 61 insertions(+), 59 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index da68c96..f004a32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,8 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt + - pip install numpy>=1.14 # for numpy array formatting in doctests + - pip install scipy<1.3 # otherwise, pymanopt fails, cf - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style diff --git a/ot/bregman.py b/ot/bregman.py index 8225967..caf4024 100644 --- a/ot/bregman.py +++ b/ot/bregman.py @@ -16,7 +16,7 @@ from .utils import unif, dist def sinkhorn(a, b, M, reg, method='sinkhorn', numItermax=1000, stopThr=1e-9, verbose=False, log=False, **kwargs): - u""" + r""" Solve the entropic regularization optimal transport problem and return the OT matrix The function solves the following optimization problem: @@ -73,12 +73,12 @@ def sinkhorn(a, b, M, reg, method='sinkhorn', numItermax=1000, -------- >>> import ot - >>> a=[.5,.5] - >>> b=[.5,.5] - >>> M=[[0.,1.],[1.,0.]] - >>> ot.sinkhorn(a,b,M,1) - array([[ 0.36552929, 0.13447071], - [ 0.13447071, 0.36552929]]) + >>> a=[.5, .5] + >>> b=[.5, .5] + >>> M=[[0., 1.], [1., 0.]] + >>> ot.sinkhorn(a, b, M, 1) + array([[0.36552929, 0.13447071], + [0.13447071, 0.36552929]]) References @@ -131,7 +131,7 @@ def sinkhorn(a, b, M, reg, method='sinkhorn', numItermax=1000, def sinkhorn2(a, b, M, reg, method='sinkhorn', numItermax=1000, stopThr=1e-9, verbose=False, log=False, **kwargs): - u""" + r""" Solve the entropic regularization optimal transport problem and return the loss The function solves the following optimization problem: @@ -188,11 +188,11 @@ def sinkhorn2(a, b, M, reg, method='sinkhorn', numItermax=1000, -------- >>> import ot - >>> a=[.5,.5] - >>> b=[.5,.5] - >>> M=[[0.,1.],[1.,0.]] - >>> ot.sinkhorn2(a,b,M,1) - array([ 0.26894142]) + >>> a=[.5, .5] + >>> b=[.5, .5] + >>> M=[[0., 1.], [1., 0.]] + >>> ot.sinkhorn2(a, b, M, 1) + array([0.26894142]) @@ -248,7 +248,7 @@ def sinkhorn2(a, b, M, reg, method='sinkhorn', numItermax=1000, def sinkhorn_knopp(a, b, M, reg, numItermax=1000, stopThr=1e-9, verbose=False, log=False, **kwargs): - """ + r""" Solve the entropic regularization optimal transport problem and return the OT matrix The function solves the following optimization problem: @@ -302,12 +302,12 @@ def sinkhorn_knopp(a, b, M, reg, numItermax=1000, -------- >>> import ot - >>> a=[.5,.5] - >>> b=[.5,.5] - >>> M=[[0.,1.],[1.,0.]] - >>> ot.sinkhorn(a,b,M,1) - array([[ 0.36552929, 0.13447071], - [ 0.13447071, 0.36552929]]) + >>> a=[.5, .5] + >>> b=[.5, .5] + >>> M=[[0., 1.], [1., 0.]] + >>> ot.sinkhorn(a, b, M, 1) + array([[0.36552929, 0.13447071], + [0.13447071, 0.36552929]]) References @@ -422,7 +422,7 @@ def sinkhorn_knopp(a, b, M, reg, numItermax=1000, def greenkhorn(a, b, M, reg, numItermax=10000, stopThr=1e-9, verbose=False, log=False): - """ + r""" Solve the entropic regularization optimal transport problem and return the OT matrix The algorithm used is based on the paper @@ -481,12 +481,12 @@ def greenkhorn(a, b, M, reg, numItermax=10000, stopThr=1e-9, verbose=False, log= -------- >>> import ot - >>> a=[.5,.5] - >>> b=[.5,.5] - >>> M=[[0.,1.],[1.,0.]] - >>> ot.bregman.greenkhorn(a,b,M,1) - array([[ 0.36552929, 0.13447071], - [ 0.13447071, 0.36552929]]) + >>> a=[.5, .5] + >>> b=[.5, .5] + >>> M=[[0., 1.], [1., 0.]] + >>> ot.bregman.greenkhorn(a, b, M, 1) + array([[0.36552929, 0.13447071], + [0.13447071, 0.36552929]]) References @@ -576,7 +576,7 @@ def greenkhorn(a, b, M, reg, numItermax=10000, stopThr=1e-9, verbose=False, log= def sinkhorn_stabilized(a, b, M, reg, numItermax=1000, tau=1e3, stopThr=1e-9, warmstart=None, verbose=False, print_period=20, log=False, **kwargs): - """ + r""" Solve the entropic regularization OT problem with log stabilization The function solves the following optimization problem: @@ -639,8 +639,8 @@ def sinkhorn_stabilized(a, b, M, reg, numItermax=1000, tau=1e3, stopThr=1e-9, >>> b=[.5,.5] >>> M=[[0.,1.],[1.,0.]] >>> ot.bregman.sinkhorn_stabilized(a,b,M,1) - array([[ 0.36552929, 0.13447071], - [ 0.13447071, 0.36552929]]) + array([[0.36552929, 0.13447071], + [0.13447071, 0.36552929]]) References @@ -796,7 +796,7 @@ def sinkhorn_stabilized(a, b, M, reg, numItermax=1000, tau=1e3, stopThr=1e-9, def sinkhorn_epsilon_scaling(a, b, M, reg, numItermax=100, epsilon0=1e4, numInnerItermax=100, tau=1e3, stopThr=1e-9, warmstart=None, verbose=False, print_period=10, log=False, **kwargs): - """ + r""" Solve the entropic regularization optimal transport problem with log stabilization and epsilon scaling. @@ -862,12 +862,12 @@ def sinkhorn_epsilon_scaling(a, b, M, reg, numItermax=100, epsilon0=1e4, numInne -------- >>> import ot - >>> a=[.5,.5] - >>> b=[.5,.5] - >>> M=[[0.,1.],[1.,0.]] - >>> ot.bregman.sinkhorn_epsilon_scaling(a,b,M,1) - array([[ 0.36552929, 0.13447071], - [ 0.13447071, 0.36552929]]) + >>> a=[.5, .5] + >>> b=[.5, .5] + >>> M=[[0., 1.], [1., 0.]] + >>> ot.bregman.sinkhorn_epsilon_scaling(a, b, M, 1) + array([[0.36552929, 0.13447071], + [0.13447071, 0.36552929]]) References @@ -989,7 +989,7 @@ def projC(gamma, q): def barycenter(A, M, reg, weights=None, numItermax=1000, stopThr=1e-4, verbose=False, log=False): - """Compute the entropic regularized wasserstein barycenter of distributions A + r"""Compute the entropic regularized wasserstein barycenter of distributions A The function solves the following optimization problem: @@ -1084,7 +1084,7 @@ def barycenter(A, M, reg, weights=None, numItermax=1000, def convolutional_barycenter2d(A, reg, weights=None, numItermax=10000, stopThr=1e-9, stabThr=1e-30, verbose=False, log=False): - """Compute the entropic regularized wasserstein barycenter of distributions A + r"""Compute the entropic regularized wasserstein barycenter of distributions A where A is a collection of 2D images. The function solves the following optimization problem: @@ -1195,7 +1195,7 @@ def convolutional_barycenter2d(A, reg, weights=None, numItermax=10000, stopThr=1 def unmix(a, D, M, M0, h0, reg, reg0, alpha, numItermax=1000, stopThr=1e-3, verbose=False, log=False): - """ + r""" Compute the unmixing of an observation with a given dictionary using Wasserstein distance The function solve the following optimization problem: @@ -1302,7 +1302,7 @@ def unmix(a, D, M, M0, h0, reg, reg0, alpha, numItermax=1000, def empirical_sinkhorn(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numIterMax=10000, stopThr=1e-9, verbose=False, log=False, **kwargs): - ''' + r''' Solve the entropic regularization optimal transport problem and return the OT matrix from empirical data @@ -1391,7 +1391,7 @@ def empirical_sinkhorn(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numI def empirical_sinkhorn2(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numIterMax=10000, stopThr=1e-9, verbose=False, log=False, **kwargs): - ''' + r''' Solve the entropic regularization optimal transport problem from empirical data and return the OT loss @@ -1480,7 +1480,7 @@ def empirical_sinkhorn2(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', num def empirical_sinkhorn_divergence(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numIterMax=10000, stopThr=1e-9, verbose=False, log=False, **kwargs): - ''' + r''' Compute the sinkhorn divergence loss from empirical data The function solves the following optimization problems and return the diff --git a/ot/lp/__init__.py b/ot/lp/__init__.py index a3f5b8d..8ec286b 100644 --- a/ot/lp/__init__.py +++ b/ot/lp/__init__.py @@ -25,7 +25,7 @@ __all__=['emd', 'emd2', 'barycenter', 'free_support_barycenter', 'cvx', def emd(a, b, M, numItermax=100000, log=False): - """Solves the Earth Movers distance problem and returns the OT matrix + r"""Solves the Earth Movers distance problem and returns the OT matrix .. math:: @@ -76,8 +76,8 @@ def emd(a, b, M, numItermax=100000, log=False): >>> b=[.5,.5] >>> M=[[0.,1.],[1.,0.]] >>> ot.emd(a,b,M) - array([[ 0.5, 0. ], - [ 0. , 0.5]]) + array([[0.5, 0. ], + [0. , 0.5]]) References ---------- @@ -117,7 +117,7 @@ def emd(a, b, M, numItermax=100000, log=False): def emd2(a, b, M, processes=multiprocessing.cpu_count(), numItermax=100000, log=False, return_matrix=False): - """Solves the Earth Movers distance problem and returns the loss + r"""Solves the Earth Movers distance problem and returns the loss .. math:: \gamma = arg\min_\gamma <\gamma,M>_F @@ -315,7 +315,7 @@ def free_support_barycenter(measures_locations, measures_weights, X_init, b=None def emd_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True, log=False): - """Solves the Earth Movers distance problem between 1d measures and returns + r"""Solves the Earth Movers distance problem between 1d measures and returns the OT matrix @@ -381,11 +381,11 @@ def emd_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True, >>> x_a = [2., 0.] >>> x_b = [0., 3.] >>> ot.emd_1d(x_a, x_b, a, b) - array([[0. , 0.5], - [0.5, 0. ]]) + array([[0. , 0.5], + [0.5, 0. ]]) >>> ot.emd_1d(x_a, x_b) - array([[0. , 0.5], - [0.5, 0. ]]) + array([[0. , 0.5], + [0.5, 0. ]]) References ---------- @@ -435,7 +435,7 @@ def emd_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True, def emd2_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True, log=False): - """Solves the Earth Movers distance problem between 1d measures and returns + r"""Solves the Earth Movers distance problem between 1d measures and returns the loss @@ -530,7 +530,7 @@ def emd2_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True, def wasserstein_1d(x_a, x_b, a=None, b=None, p=1.): - """Solves the p-Wasserstein distance problem between 1d measures and returns + r"""Solves the p-Wasserstein distance problem between 1d measures and returns the distance diff --git a/ot/unbalanced.py b/ot/unbalanced.py index 484ce95..b2b7b10 100644 --- a/ot/unbalanced.py +++ b/ot/unbalanced.py @@ -13,7 +13,7 @@ import numpy as np def sinkhorn_unbalanced(a, b, M, reg, alpha, method='sinkhorn', numItermax=1000, stopThr=1e-9, verbose=False, log=False, **kwargs): - u""" + r""" Solve the unbalanced entropic regularization optimal transport problem and return the loss The function solves the following optimization problem: @@ -75,7 +75,7 @@ def sinkhorn_unbalanced(a, b, M, reg, alpha, method='sinkhorn', numItermax=1000, >>> M=[[0., 1.], [1., 0.]] >>> ot.sinkhorn_unbalanced(a, b, M, 1, 1) array([[0.51122823, 0.18807035], - [0.18807035, 0.51122823]]) + [0.18807035, 0.51122823]]) References @@ -122,7 +122,7 @@ def sinkhorn_unbalanced(a, b, M, reg, alpha, method='sinkhorn', numItermax=1000, def sinkhorn_unbalanced2(a, b, M, reg, alpha, method='sinkhorn', numItermax=1000, stopThr=1e-9, verbose=False, log=False, **kwargs): - u""" + r""" Solve the entropic regularization unbalanced optimal transport problem and return the loss The function solves the following optimization problem: @@ -233,7 +233,7 @@ def sinkhorn_unbalanced2(a, b, M, reg, alpha, method='sinkhorn', def sinkhorn_knopp_unbalanced(a, b, M, reg, alpha, numItermax=1000, stopThr=1e-9, verbose=False, log=False, **kwargs): - """ + r""" Solve the entropic regularization unbalanced optimal transport problem and return the loss The function solves the following optimization problem: @@ -401,7 +401,7 @@ def sinkhorn_knopp_unbalanced(a, b, M, reg, alpha, numItermax=1000, def barycenter_unbalanced(A, M, reg, alpha, weights=None, numItermax=1000, stopThr=1e-4, verbose=False, log=False): - """Compute the entropic regularized unbalanced wasserstein barycenter of distributions A + r"""Compute the entropic regularized unbalanced wasserstein barycenter of distributions A The function solves the following optimization problem: -- cgit v1.2.3 From 385d4a543898a7ddb842b983b5f174f8c80636fc Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Mon, 1 Jul 2019 14:28:11 +0200 Subject: Bug in syntax for old scipy version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index f004a32..275109c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ before_script: # configure a headless display to test plot generation install: - pip install -r requirements.txt - pip install numpy>=1.14 # for numpy array formatting in doctests - - pip install scipy<1.3 # otherwise, pymanopt fails, cf + - pip install "scipy<1.3" # otherwise, pymanopt fails, cf - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style -- cgit v1.2.3 From a08375c8dc7594e247e586fcc4d65a96771d25c7 Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Mon, 1 Jul 2019 15:36:55 +0200 Subject: Fixed all doctests assuming functions are working properly (actually tested in tests/) --- .travis.yml | 5 +- ot/bregman.py | 2 +- ot/stochastic.py | 155 +++++++++++++++++++++++++++++++++++-------------------- ot/unbalanced.py | 2 +- 4 files changed, 104 insertions(+), 60 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 275109c..2c6a5c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,9 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt - - pip install numpy>=1.14 # for numpy array formatting in doctests - - pip install "scipy<1.3" # otherwise, pymanopt fails, cf + - pip install numpy>=1.14 "scipy<1.3" # for numpy array formatting in doctests + # ^ scipy version: otherwise, pymanopt fails, cf + - python -c "import numpy; import scipy; print('numpy: ', numpy.__version__); print('scipy: ', scipy.__version__)" - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style diff --git a/ot/bregman.py b/ot/bregman.py index caf4024..50f8389 100644 --- a/ot/bregman.py +++ b/ot/bregman.py @@ -1559,7 +1559,7 @@ def empirical_sinkhorn_divergence(X_s, X_t, reg, a=None, b=None, metric='sqeucli >>> X_s = np.reshape(np.arange(n_s), (n_s, 1)) >>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1)) >>> empirical_sinkhorn_divergence(X_s, X_t, reg) - array([2.99977435]) + array([1.49988718]) References diff --git a/ot/stochastic.py b/ot/stochastic.py index 762eb3e..bf3e7a7 100644 --- a/ot/stochastic.py +++ b/ot/stochastic.py @@ -52,19 +52,23 @@ def coordinate_grad_semi_dual(b, M, reg, beta, i): Examples -------- >>> import ot + >>> np.random.seed(0) >>> n_source = 7 >>> n_target = 4 - >>> reg = 1 - >>> numItermax = 300000 >>> a = ot.utils.unif(n_source) >>> b = ot.utils.unif(n_target) - >>> rng = np.random.RandomState(0) - >>> X_source = rng.randn(n_source, 2) - >>> Y_target = rng.randn(n_target, 2) + >>> X_source = np.random.randn(n_source, 2) + >>> Y_target = np.random.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> method = "ASGD" - >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) - >>> print(asgd_pi) + >>> ot.stochastic.solve_semi_dual_entropic(a, b, M, reg=1, method="ASGD", numItermax=300000) + array([[2.53942342e-02, 9.98640673e-02, 1.75945647e-02, 4.27664307e-06], + [1.21556999e-01, 1.26350515e-02, 1.30491795e-03, 7.36017394e-03], + [3.54070702e-03, 7.63581358e-02, 6.29581672e-02, 1.32812798e-07], + [2.60578198e-02, 3.35916645e-02, 8.28023223e-02, 4.05336238e-04], + [9.86808864e-03, 7.59774324e-04, 1.08702729e-02, 1.21359007e-01], + [2.17218856e-02, 9.12931802e-04, 1.87962526e-03, 1.18342700e-01], + [4.14237512e-02, 2.67487857e-02, 7.23016955e-02, 2.38291052e-03]]) + References ---------- @@ -133,19 +137,22 @@ def sag_entropic_transport(a, b, M, reg, numItermax=10000, lr=None): Examples -------- >>> import ot + >>> np.random.seed(0) >>> n_source = 7 >>> n_target = 4 - >>> reg = 1 - >>> numItermax = 300000 >>> a = ot.utils.unif(n_source) >>> b = ot.utils.unif(n_target) - >>> rng = np.random.RandomState(0) - >>> X_source = rng.randn(n_source, 2) - >>> Y_target = rng.randn(n_target, 2) + >>> X_source = np.random.randn(n_source, 2) + >>> Y_target = np.random.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> method = "ASGD" - >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) - >>> print(asgd_pi) + >>> ot.stochastic.solve_semi_dual_entropic(a, b, M, reg=1, method="ASGD", numItermax=300000) + array([[2.53942342e-02, 9.98640673e-02, 1.75945647e-02, 4.27664307e-06], + [1.21556999e-01, 1.26350515e-02, 1.30491795e-03, 7.36017394e-03], + [3.54070702e-03, 7.63581358e-02, 6.29581672e-02, 1.32812798e-07], + [2.60578198e-02, 3.35916645e-02, 8.28023223e-02, 4.05336238e-04], + [9.86808864e-03, 7.59774324e-04, 1.08702729e-02, 1.21359007e-01], + [2.17218856e-02, 9.12931802e-04, 1.87962526e-03, 1.18342700e-01], + [4.14237512e-02, 2.67487857e-02, 7.23016955e-02, 2.38291052e-03]]) References ---------- @@ -222,19 +229,22 @@ def averaged_sgd_entropic_transport(a, b, M, reg, numItermax=300000, lr=None): Examples -------- >>> import ot + >>> np.random.seed(0) >>> n_source = 7 >>> n_target = 4 - >>> reg = 1 - >>> numItermax = 300000 >>> a = ot.utils.unif(n_source) >>> b = ot.utils.unif(n_target) - >>> rng = np.random.RandomState(0) - >>> X_source = rng.randn(n_source, 2) - >>> Y_target = rng.randn(n_target, 2) + >>> X_source = np.random.randn(n_source, 2) + >>> Y_target = np.random.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> method = "ASGD" - >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) - >>> print(asgd_pi) + >>> ot.stochastic.solve_semi_dual_entropic(a, b, M, reg=1, method="ASGD", numItermax=300000) + array([[2.53942342e-02, 9.98640673e-02, 1.75945647e-02, 4.27664307e-06], + [1.21556999e-01, 1.26350515e-02, 1.30491795e-03, 7.36017394e-03], + [3.54070702e-03, 7.63581358e-02, 6.29581672e-02, 1.32812798e-07], + [2.60578198e-02, 3.35916645e-02, 8.28023223e-02, 4.05336238e-04], + [9.86808864e-03, 7.59774324e-04, 1.08702729e-02, 1.21359007e-01], + [2.17218856e-02, 9.12931802e-04, 1.87962526e-03, 1.18342700e-01], + [4.14237512e-02, 2.67487857e-02, 7.23016955e-02, 2.38291052e-03]]) References ---------- @@ -301,19 +311,22 @@ def c_transform_entropic(b, M, reg, beta): Examples -------- >>> import ot + >>> np.random.seed(0) >>> n_source = 7 >>> n_target = 4 - >>> reg = 1 - >>> numItermax = 300000 >>> a = ot.utils.unif(n_source) >>> b = ot.utils.unif(n_target) - >>> rng = np.random.RandomState(0) - >>> X_source = rng.randn(n_source, 2) - >>> Y_target = rng.randn(n_target, 2) + >>> X_source = np.random.randn(n_source, 2) + >>> Y_target = np.random.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> method = "ASGD" - >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) - >>> print(asgd_pi) + >>> ot.stochastic.solve_semi_dual_entropic(a, b, M, reg=1, method="ASGD", numItermax=300000) + array([[2.53942342e-02, 9.98640673e-02, 1.75945647e-02, 4.27664307e-06], + [1.21556999e-01, 1.26350515e-02, 1.30491795e-03, 7.36017394e-03], + [3.54070702e-03, 7.63581358e-02, 6.29581672e-02, 1.32812798e-07], + [2.60578198e-02, 3.35916645e-02, 8.28023223e-02, 4.05336238e-04], + [9.86808864e-03, 7.59774324e-04, 1.08702729e-02, 1.21359007e-01], + [2.17218856e-02, 9.12931802e-04, 1.87962526e-03, 1.18342700e-01], + [4.14237512e-02, 2.67487857e-02, 7.23016955e-02, 2.38291052e-03]]) References ---------- @@ -395,19 +408,22 @@ def solve_semi_dual_entropic(a, b, M, reg, method, numItermax=10000, lr=None, Examples -------- >>> import ot + >>> np.random.seed(0) >>> n_source = 7 >>> n_target = 4 - >>> reg = 1 - >>> numItermax = 300000 >>> a = ot.utils.unif(n_source) >>> b = ot.utils.unif(n_target) - >>> rng = np.random.RandomState(0) - >>> X_source = rng.randn(n_source, 2) - >>> Y_target = rng.randn(n_target, 2) + >>> X_source = np.random.randn(n_source, 2) + >>> Y_target = np.random.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> method = "ASGD" - >>> asgd_pi = ot.stochastic.solve_semi_dual_entropic(a, b, M, reg, method, numItermax) - >>> print(asgd_pi) + >>> ot.stochastic.solve_semi_dual_entropic(a, b, M, reg=1, method="ASGD", numItermax=300000) + array([[2.53942342e-02, 9.98640673e-02, 1.75945647e-02, 4.27664307e-06], + [1.21556999e-01, 1.26350515e-02, 1.30491795e-03, 7.36017394e-03], + [3.54070702e-03, 7.63581358e-02, 6.29581672e-02, 1.32812798e-07], + [2.60578198e-02, 3.35916645e-02, 8.28023223e-02, 4.05336238e-04], + [9.86808864e-03, 7.59774324e-04, 1.08702729e-02, 1.21359007e-01], + [2.17218856e-02, 9.12931802e-04, 1.87962526e-03, 1.18342700e-01], + [4.14237512e-02, 2.67487857e-02, 7.23016955e-02, 2.38291052e-03]]) References ---------- @@ -502,22 +518,28 @@ def batch_grad_dual(a, b, M, reg, alpha, beta, batch_size, batch_alpha, Examples -------- >>> import ot + >>> np.random.seed(0) >>> n_source = 7 >>> n_target = 4 - >>> reg = 1 - >>> numItermax = 20000 - >>> lr = 0.1 - >>> batch_size = 3 - >>> log = True >>> a = ot.utils.unif(n_source) >>> b = ot.utils.unif(n_target) - >>> rng = np.random.RandomState(0) - >>> X_source = rng.randn(n_source, 2) - >>> Y_target = rng.randn(n_target, 2) + >>> X_source = np.random.randn(n_source, 2) + >>> Y_target = np.random.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) - >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg, batch_size, numItermax, lr, log) - >>> print(log['alpha'], log['beta']) - >>> print(sgd_dual_pi) + >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg=1, batch_size=3, numItermax=30000, lr=0.1, log=True) + >>> log['alpha'] + array([0.71759102, 1.57057384, 0.85576566, 0.1208211 , 0.59190466, + 1.197148 , 0.17805133]) + >>> log['beta'] + array([0.49741367, 0.57478564, 1.40075528, 2.75890102]) + >>> sgd_dual_pi + array([[2.09730063e-02, 8.38169324e-02, 7.50365455e-03, 8.72731415e-09], + [5.58432437e-03, 5.89881299e-04, 3.09558411e-05, 8.35469849e-07], + [3.26489515e-03, 7.15536035e-02, 2.99778211e-02, 3.02601593e-10], + [4.05390622e-02, 5.31085068e-02, 6.65191787e-02, 1.55812785e-06], + [7.82299812e-02, 6.12099102e-03, 4.44989098e-02, 2.37719187e-03], + [5.06266486e-02, 2.16230494e-03, 2.26215141e-03, 6.81514609e-04], + [6.06713990e-02, 3.98139808e-02, 5.46829338e-02, 8.62371424e-06]]) References ---------- @@ -526,7 +548,6 @@ def batch_grad_dual(a, b, M, reg, alpha, beta, batch_size, batch_alpha, International Conference on Learning Representation (2018), arXiv preprint arxiv:1711.02283. ''' - G = - (np.exp((alpha[batch_alpha, None] + beta[None, batch_beta] - M[batch_alpha, :][:, batch_beta]) / reg) * a[batch_alpha, None] * b[None, batch_beta]) @@ -605,8 +626,19 @@ def sgd_entropic_regularization(a, b, M, reg, batch_size, numItermax, lr): >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg, batch_size, numItermax, lr, log) - >>> print(log['alpha'], log['beta']) - >>> print(sgd_dual_pi) + >>> log['alpha'] + array([0.64171798, 1.27932201, 0.78132257, 0.15638935, 0.54888354, + 1.03663469, 0.20595781]) + >>> log['beta'] + array([0.51207194, 0.58033189, 1.28922676, 2.26859736]) + >>> sgd_dual_pi + array([[1.97276541e-02, 7.81248547e-02, 6.22136048e-03, 4.95442423e-09], + [4.23494310e-03, 4.43286263e-04, 2.06927079e-05, 3.82389139e-07], + [3.07542414e-03, 6.67897769e-02, 2.48904999e-02, 1.72030247e-10], + [4.26271990e-02, 5.53375455e-02, 6.16535024e-02, 9.88812650e-07], + [7.60423265e-02, 5.89585256e-03, 3.81267087e-02, 1.39458256e-03], + [4.37557504e-02, 1.85189176e-03, 1.72335760e-03, 3.55491279e-04], + [6.33096109e-02, 4.11683954e-02, 5.02962051e-02, 5.43097516e-06]]) References ---------- @@ -701,8 +733,19 @@ def solve_dual_entropic(a, b, M, reg, batch_size, numItermax=10000, lr=1, >>> Y_target = rng.randn(n_target, 2) >>> M = ot.dist(X_source, Y_target) >>> sgd_dual_pi, log = ot.stochastic.solve_dual_entropic(a, b, M, reg, batch_size, numItermax, lr, log) - >>> print(log['alpha'], log['beta']) - >>> print(sgd_dual_pi) + >>> log['alpha'] + array([0.64057733, 1.2683513 , 0.75610161, 0.16024284, 0.54926534, + 1.0514201 , 0.19958936]) + >>> log['beta'] + array([0.51372571, 0.58843489, 1.27993921, 2.24344807]) + >>> sgd_dual_pi + array([[1.97377795e-02, 7.86706853e-02, 6.15682001e-03, 4.82586997e-09], + [4.19566963e-03, 4.42016865e-04, 2.02777272e-05, 3.68823708e-07], + [3.00379244e-03, 6.56562018e-02, 2.40462171e-02, 1.63579656e-10], + [4.28626062e-02, 5.60031599e-02, 6.13193826e-02, 9.67977735e-07], + [7.61972739e-02, 5.94609051e-03, 3.77886693e-02, 1.36046648e-03], + [4.44810042e-02, 1.89476742e-03, 1.73285847e-03, 3.51826036e-04], + [6.30118293e-02, 4.12398660e-02, 4.95148998e-02, 5.26247246e-06]]) References ---------- diff --git a/ot/unbalanced.py b/ot/unbalanced.py index b2b7b10..4a2af8a 100644 --- a/ot/unbalanced.py +++ b/ot/unbalanced.py @@ -290,7 +290,7 @@ def sinkhorn_knopp_unbalanced(a, b, M, reg, alpha, numItermax=1000, >>> a=[.5, .15] >>> b=[.5, .5] >>> M=[[0., 1.],[1., 0.]] - >>> ot.sinkhorn_knopp_unbalanced(a, b, M, 1., 1.) + >>> ot.unbalanced.sinkhorn_knopp_unbalanced(a, b, M, 1., 1.) array([[0.52761554, 0.22392482], [0.10286295, 0.32257641]]) -- cgit v1.2.3 From d85f61683cbb94ca6c6cb91bbd7d82ea295dec3a Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Tue, 2 Jul 2019 09:26:32 +0200 Subject: Bug in syntax for new numpy version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 2c6a5c8..e61b577 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt - - pip install numpy>=1.14 "scipy<1.3" # for numpy array formatting in doctests + - pip install "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests # ^ scipy version: otherwise, pymanopt fails, cf - python -c "import numpy; import scipy; print('numpy: ', numpy.__version__); print('scipy: ', scipy.__version__)" - pip install flake8 pytest "pytest-cov<2.6" -- cgit v1.2.3 From cb919a30de5ebcbfcd8b15e0a5e7f90b36f4f7b3 Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Tue, 2 Jul 2019 09:29:06 +0200 Subject: Bug in syntax for new numpy version (cont'd) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index e61b577..8eaa202 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ install: - pip install -r requirements.txt - pip install "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests # ^ scipy version: otherwise, pymanopt fails, cf - - python -c "import numpy; import scipy; print('numpy: ', numpy.__version__); print('scipy: ', scipy.__version__)" + - python -c "import numpy; import scipy; print(\"numpy: \", numpy.__version__); print(\"scipy: \", scipy.__version__)" - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style -- cgit v1.2.3 From 36e9d8d8ada28e86833d9c7c0b441e3000800a31 Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Tue, 2 Jul 2019 09:29:48 +0200 Subject: Bug in syntax for new numpy version (cont'd) --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 8eaa202..3ed0e72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,7 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt - - pip install "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests - # ^ scipy version: otherwise, pymanopt fails, cf + - pip install "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests + scipy version: otherwise, pymanopt fails, cf - python -c "import numpy; import scipy; print(\"numpy: \", numpy.__version__); print(\"scipy: \", scipy.__version__)" - pip install flake8 pytest "pytest-cov<2.6" - pip install . -- cgit v1.2.3 From f7fbb57a96bc6c7fe7d6237292aa39516c2f614e Mon Sep 17 00:00:00 2001 From: Romain Tavenard Date: Tue, 2 Jul 2019 09:30:54 +0200 Subject: Bug in syntax for new numpy version (cont'd) --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 3ed0e72..5e5694b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,7 @@ before_script: # configure a headless display to test plot generation # command to install dependencies install: - pip install -r requirements.txt - - pip install "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests + scipy version: otherwise, pymanopt fails, cf - - python -c "import numpy; import scipy; print(\"numpy: \", numpy.__version__); print(\"scipy: \", scipy.__version__)" + - pip install -U "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests + scipy version: otherwise, pymanopt fails, cf - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style -- cgit v1.2.3 From 3a09a0ace10c184dc27a2fcc1f982208e4d9eb67 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 5 Jul 2019 11:44:02 +0200 Subject: add python 3.7 on travis --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 5e5694b..932f610 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,10 @@ matrix: python: 3.5 - os: linux sudo: required - python: 3.6 + python: 3.6 + - os: linux + sudo: required + python: 3.7 - os: linux sudo: required python: 2.7 -- cgit v1.2.3 From bfc84efcd94c03bebb80330aa1f2a92a4efb0ff9 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 5 Jul 2019 13:01:12 +0200 Subject: add xenial in travis pfor python 3.7 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 932f610..68b8ef1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: xenial # required for Python >= 3.7 language: python matrix: # allow_failures: -- cgit v1.2.3 From 0bc936f62430c98ecbb0f39c9508f29c6054a327 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 5 Jul 2019 13:06:07 +0200 Subject: travis xenial new --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 68b8ef1..67f0c43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,12 +21,13 @@ matrix: - os: linux sudo: required python: 2.7 + - name: "Python 3.7.3 on Windows" + os: windows # Windows 10.0.17134 N/A Build 17134 + language: shell # 'language: python' is an error on Travis CI Windows + before_install: choco install python + env: PATH=/c/Python37:/c/Python37/Scripts:$PATH before_install: - ./.travis/before_install.sh -before_script: # configure a headless display to test plot generation - - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - - sleep 3 # give xvfb some time to start # command to install dependencies install: - pip install -r requirements.txt -- cgit v1.2.3 From 7ac1b462d23ae0a396742bba4773e146e60e7502 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 5 Jul 2019 13:47:43 +0200 Subject: cleanup parmap on windows --- .travis.yml | 51 ++++++++++++++++++++++++++------------------------- ot/lp/__init__.py | 14 ++++++++++++-- ot/utils.py | 31 ++++++++++++++++++------------- requirements.txt | 1 + 4 files changed, 57 insertions(+), 40 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 67f0c43..cddf0e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,32 @@ dist: xenial # required for Python >= 3.7 language: python matrix: -# allow_failures: -# - os: osx - include: -# - os: osx -# language: generic - - os: linux - sudo: required - python: 3.4 - - os: linux - sudo: required - python: 3.5 - - os: linux - sudo: required - python: 3.6 - - os: linux - sudo: required - python: 3.7 - - os: linux - sudo: required - python: 2.7 - - name: "Python 3.7.3 on Windows" - os: windows # Windows 10.0.17134 N/A Build 17134 - language: shell # 'language: python' is an error on Travis CI Windows - before_install: choco install python - env: PATH=/c/Python37:/c/Python37/Scripts:$PATH + allow_failures: + - os: osx + - os: windows + include: + - os: osx + language: generic + - os: linux + sudo: required + python: 3.4 + - os: linux + sudo: required + python: 3.5 + - os: linux + sudo: required + python: 3.6 + - os: linux + sudo: required + python: 3.7 + - os: linux + sudo: required + python: 2.7 + - name: "Python 3.7.3 on Windows" + os: windows # Windows 10.0.17134 N/A Build 17134 + language: shell # 'language: python' is an error on Travis CI Windows + before_install: choco install python + env: PATH=/c/Python37:/c/Python37/Scripts:$PATH before_install: - ./.travis/before_install.sh # command to install dependencies diff --git a/ot/lp/__init__.py b/ot/lp/__init__.py index 17f1731..0c92810 100644 --- a/ot/lp/__init__.py +++ b/ot/lp/__init__.py @@ -11,7 +11,7 @@ Solvers for the original linear program OT problem # License: MIT License import multiprocessing - +import sys import numpy as np from scipy.sparse import coo_matrix @@ -151,6 +151,8 @@ def emd2(a, b, M, processes=multiprocessing.cpu_count(), Target histogram (uniform weight if empty list) M : (ns,nt) numpy.ndarray, float64 Loss matrix (c-order array with type float64) + processes : int, optional (default=nb cpu) + Nb of processes used for multiple emd computation (not used on windows) numItermax : int, optional (default=100000) The maximum number of iterations before stopping the optimization algorithm if it has not converged. @@ -200,6 +202,10 @@ def emd2(a, b, M, processes=multiprocessing.cpu_count(), b = np.asarray(b, dtype=np.float64) M = np.asarray(M, dtype=np.float64) + # problem with pikling Forks + if sys.platform.endswith('win32'): + processes=1 + # if empty array given then use uniform distributions if len(a) == 0: a = np.ones((M.shape[0],), dtype=np.float64) / M.shape[0] @@ -228,7 +234,11 @@ def emd2(a, b, M, processes=multiprocessing.cpu_count(), return f(b) nb = b.shape[1] - res = parmap(f, [b[:, i] for i in range(nb)], processes) + if processes>1: + res = parmap(f, [b[:, i] for i in range(nb)], processes) + else: + res = list(map(f, [b[:, i].copy() for i in range(nb)])) + return res diff --git a/ot/utils.py b/ot/utils.py index e8249ef..5707d9b 100644 --- a/ot/utils.py +++ b/ot/utils.py @@ -214,23 +214,28 @@ def fun(f, q_in, q_out): def parmap(f, X, nprocs=multiprocessing.cpu_count()): - """ paralell map for multiprocessing """ - q_in = multiprocessing.Queue(1) - q_out = multiprocessing.Queue() + """ paralell map for multiprocessing (only map on windows)""" - proc = [multiprocessing.Process(target=fun, args=(f, q_in, q_out)) - for _ in range(nprocs)] - for p in proc: - p.daemon = True - p.start() + if not sys.platform.endswith('win32'): - sent = [q_in.put((i, x)) for i, x in enumerate(X)] - [q_in.put((None, None)) for _ in range(nprocs)] - res = [q_out.get() for _ in range(len(sent))] + q_in = multiprocessing.Queue(1) + q_out = multiprocessing.Queue() - [p.join() for p in proc] + proc = [multiprocessing.Process(target=fun, args=(f, q_in, q_out)) + for _ in range(nprocs)] + for p in proc: + p.daemon = True + p.start() - return [x for i, x in sorted(res)] + sent = [q_in.put((i, x)) for i, x in enumerate(X)] + [q_in.put((None, None)) for _ in range(nprocs)] + res = [q_out.get() for _ in range(len(sent))] + + [p.join() for p in proc] + + return [x for i, x in sorted(res)] + else: + return list(map(f, X)) def check_params(**kwargs): diff --git a/requirements.txt b/requirements.txt index 97d165b..5a3432b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ matplotlib sphinx-gallery autograd pymanopt +cvxopt pytest -- cgit v1.2.3 From 41706d1c35bfe5f55f36041f511e2a42e36f6ab7 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 5 Jul 2019 14:03:15 +0200 Subject: remove test for python 3.4 --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index cddf0e0..57b961b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,8 @@ matrix: - os: windows include: - os: osx - language: generic - - os: linux sudo: required - python: 3.4 + language: generic - os: linux sudo: required python: 3.5 -- cgit v1.2.3 From 2873ba559bb6d3ccceeee326848d7216a139ed88 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Fri, 5 Jul 2019 14:14:52 +0200 Subject: remove windows and macosx tests, will add to master after release --- .travis.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 57b961b..0dfb0d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,10 @@ dist: xenial # required for Python >= 3.7 language: python matrix: - allow_failures: - - os: osx - - os: windows + # allow_failures: + # - os: osx + # - os: windows include: - - os: osx - sudo: required - language: generic - os: linux sudo: required python: 3.5 @@ -20,11 +17,14 @@ matrix: - os: linux sudo: required python: 2.7 - - name: "Python 3.7.3 on Windows" - os: windows # Windows 10.0.17134 N/A Build 17134 - language: shell # 'language: python' is an error on Travis CI Windows - before_install: choco install python - env: PATH=/c/Python37:/c/Python37/Scripts:$PATH + # - os: osx + # sudo: required + # language: generic + # - name: "Python 3.7.3 on Windows" + # os: windows # Windows 10.0.17134 N/A Build 17134 + # language: shell # 'language: python' is an error on Travis CI Windows + # before_install: choco install python + # env: PATH=/c/Python37:/c/Python37/Scripts:$PATH before_install: - ./.travis/before_install.sh # command to install dependencies -- cgit v1.2.3 From 9d4b786a036ac95989825beec819521089fb4feb Mon Sep 17 00:00:00 2001 From: ngayraud Date: Mon, 12 Aug 2019 16:37:58 -0400 Subject: fixes for travis, added test, minor nits --- .travis.yml | 5 ++-- ot/da.py | 2 +- ot/utils.py | 4 +++- test/test_da.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 4 deletions(-) (limited to '.travis.yml') diff --git a/.travis.yml b/.travis.yml index 5e5694b..72fd29a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ matrix: python: 3.5 - os: linux sudo: required - python: 3.6 + python: 3.6 - os: linux sudo: required python: 2.7 @@ -21,7 +21,6 @@ before_install: - ./.travis/before_install.sh before_script: # configure a headless display to test plot generation - "export DISPLAY=:99.0" - - "sh -e /etc/init.d/xvfb start" - sleep 3 # give xvfb some time to start # command to install dependencies install: @@ -30,6 +29,8 @@ install: - pip install flake8 pytest "pytest-cov<2.6" - pip install . # command to run tests + check syntax style +services: + - xvfb script: - python setup.py develop - flake8 examples/ ot/ test/ diff --git a/ot/da.py b/ot/da.py index c1d9849..2af855d 100644 --- a/ot/da.py +++ b/ot/da.py @@ -1852,7 +1852,7 @@ class UnbalancedSinkhornTransport(BaseTransport): """ def __init__(self, reg_e=1., reg_m=0.1, method='sinkhorn', - max_iter=10, tol=10e-9, verbose=False, log=False, + max_iter=10, tol=1e-9, verbose=False, log=False, metric="sqeuclidean", norm=None, distribution_estimation=distribution_estimation_uniform, out_of_sample_map='ferradans', limit_max=10): diff --git a/ot/utils.py b/ot/utils.py index be839f8..a334fea 100644 --- a/ot/utils.py +++ b/ot/utils.py @@ -178,7 +178,9 @@ def cost_normalization(C, norm=None): The input cost matrix normalized according to given norm. """ - if norm == "median": + if norm is None: + pass + elif norm == "median": C /= float(np.median(C)) elif norm == "max": C /= float(np.max(C)) diff --git a/test/test_da.py b/test/test_da.py index f7f3a9d..9efd2d9 100644 --- a/test/test_da.py +++ b/test/test_da.py @@ -245,6 +245,79 @@ def test_sinkhorn_transport_class(): assert len(otda.log_.keys()) != 0 +def test_unbalanced_sinkhorn_transport_class(): + """test_sinkhorn_transport + """ + + ns = 150 + nt = 200 + + Xs, ys = make_data_classif('3gauss', ns) + Xt, yt = make_data_classif('3gauss2', nt) + + otda = ot.da.UnbalancedSinkhornTransport() + + # test its computed + otda.fit(Xs=Xs, Xt=Xt) + assert hasattr(otda, "cost_") + assert hasattr(otda, "coupling_") + assert hasattr(otda, "log_") + + # test dimensions of coupling + assert_equal(otda.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + + # test margin constraints + mu_s = unif(ns) + mu_t = unif(nt) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + + # test transform + transp_Xs = otda.transform(Xs=Xs) + assert_equal(transp_Xs.shape, Xs.shape) + + Xs_new, _ = make_data_classif('3gauss', ns + 1) + transp_Xs_new = otda.transform(Xs_new) + + # check that the oos method is working + assert_equal(transp_Xs_new.shape, Xs_new.shape) + + # test inverse transform + transp_Xt = otda.inverse_transform(Xt=Xt) + assert_equal(transp_Xt.shape, Xt.shape) + + Xt_new, _ = make_data_classif('3gauss2', nt + 1) + transp_Xt_new = otda.inverse_transform(Xt=Xt_new) + + # check that the oos method is working + assert_equal(transp_Xt_new.shape, Xt_new.shape) + + # test fit_transform + transp_Xs = otda.fit_transform(Xs=Xs, Xt=Xt) + assert_equal(transp_Xs.shape, Xs.shape) + + # test unsupervised vs semi-supervised mode + otda_unsup = ot.da.SinkhornTransport() + otda_unsup.fit(Xs=Xs, Xt=Xt) + n_unsup = np.sum(otda_unsup.cost_) + + otda_semi = ot.da.SinkhornTransport() + otda_semi.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) + assert_equal(otda_semi.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + n_semisup = np.sum(otda_semi.cost_) + + # check that the cost matrix norms are indeed different + assert n_unsup != n_semisup, "semisupervised mode not working" + + # check everything runs well with log=True + otda = ot.da.SinkhornTransport(log=True) + otda.fit(Xs=Xs, ys=ys, Xt=Xt) + assert len(otda.log_.keys()) != 0 + + def test_emd_transport_class(): """test_sinkhorn_transport """ -- cgit v1.2.3