Skip to content

Commit 8b3927b

Browse files
authored
Merge pull request #90 from rtavenar/dev-doctests
[MRG] Have Travis actually execute doctests
2 parents a9b8af1 + 5b6eb56 commit 8b3927b

File tree

9 files changed

+203
-183
lines changed

9 files changed

+203
-183
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ before_script: # configure a headless display to test plot generation
2626
# command to install dependencies
2727
install:
2828
- pip install -r requirements.txt
29+
- pip install -U "numpy>=1.14" "scipy<1.3" # for numpy array formatting in doctests + scipy version: otherwise, pymanopt fails, cf <https://github.com/pymanopt/pymanopt/issues/77>
2930
- pip install flake8 pytest "pytest-cov<2.6"
3031
- pip install .
3132
# command to run tests + check syntax style
3233
script:
3334
- python setup.py develop
3435
- flake8 examples/ ot/ test/
35-
- python -m pytest -v test/ --cov=ot
36+
- python -m pytest -v test/ ot/ --doctest-modules --ignore ot/gpu/ --cov=ot
3637
# - py.test ot test

ot/bregman.py

Lines changed: 50 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
def sinkhorn(a, b, M, reg, method='sinkhorn', numItermax=1000,
1818
stopThr=1e-9, verbose=False, log=False, **kwargs):
19-
u"""
19+
r"""
2020
Solve the entropic regularization optimal transport problem and return the OT matrix
2121
2222
The function solves the following optimization problem:
@@ -73,12 +73,12 @@ def sinkhorn(a, b, M, reg, method='sinkhorn', numItermax=1000,
7373
--------
7474
7575
>>> import ot
76-
>>> a=[.5,.5]
77-
>>> b=[.5,.5]
78-
>>> M=[[0.,1.],[1.,0.]]
79-
>>> ot.sinkhorn(a,b,M,1)
80-
array([[ 0.36552929, 0.13447071],
81-
[ 0.13447071, 0.36552929]])
76+
>>> a=[.5, .5]
77+
>>> b=[.5, .5]
78+
>>> M=[[0., 1.], [1., 0.]]
79+
>>> ot.sinkhorn(a, b, M, 1)
80+
array([[0.36552929, 0.13447071],
81+
[0.13447071, 0.36552929]])
8282
8383
8484
References
@@ -131,7 +131,7 @@ def sink():
131131

132132
def sinkhorn2(a, b, M, reg, method='sinkhorn', numItermax=1000,
133133
stopThr=1e-9, verbose=False, log=False, **kwargs):
134-
u"""
134+
r"""
135135
Solve the entropic regularization optimal transport problem and return the loss
136136
137137
The function solves the following optimization problem:
@@ -188,11 +188,11 @@ def sinkhorn2(a, b, M, reg, method='sinkhorn', numItermax=1000,
188188
--------
189189
190190
>>> import ot
191-
>>> a=[.5,.5]
192-
>>> b=[.5,.5]
193-
>>> M=[[0.,1.],[1.,0.]]
194-
>>> ot.sinkhorn2(a,b,M,1)
195-
array([ 0.26894142])
191+
>>> a=[.5, .5]
192+
>>> b=[.5, .5]
193+
>>> M=[[0., 1.], [1., 0.]]
194+
>>> ot.sinkhorn2(a, b, M, 1)
195+
array([0.26894142])
196196
197197
198198
@@ -248,7 +248,7 @@ def sink():
248248

249249
def sinkhorn_knopp(a, b, M, reg, numItermax=1000,
250250
stopThr=1e-9, verbose=False, log=False, **kwargs):
251-
"""
251+
r"""
252252
Solve the entropic regularization optimal transport problem and return the OT matrix
253253
254254
The function solves the following optimization problem:
@@ -302,12 +302,12 @@ def sinkhorn_knopp(a, b, M, reg, numItermax=1000,
302302
--------
303303
304304
>>> import ot
305-
>>> a=[.5,.5]
306-
>>> b=[.5,.5]
307-
>>> M=[[0.,1.],[1.,0.]]
308-
>>> ot.sinkhorn(a,b,M,1)
309-
array([[ 0.36552929, 0.13447071],
310-
[ 0.13447071, 0.36552929]])
305+
>>> a=[.5, .5]
306+
>>> b=[.5, .5]
307+
>>> M=[[0., 1.], [1., 0.]]
308+
>>> ot.sinkhorn(a, b, M, 1)
309+
array([[0.36552929, 0.13447071],
310+
[0.13447071, 0.36552929]])
311311
312312
313313
References
@@ -422,7 +422,7 @@ def sinkhorn_knopp(a, b, M, reg, numItermax=1000,
422422

423423

424424
def greenkhorn(a, b, M, reg, numItermax=10000, stopThr=1e-9, verbose=False, log=False):
425-
"""
425+
r"""
426426
Solve the entropic regularization optimal transport problem and return the OT matrix
427427
428428
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=
481481
--------
482482
483483
>>> import ot
484-
>>> a=[.5,.5]
485-
>>> b=[.5,.5]
486-
>>> M=[[0.,1.],[1.,0.]]
487-
>>> ot.bregman.greenkhorn(a,b,M,1)
488-
array([[ 0.36552929, 0.13447071],
489-
[ 0.13447071, 0.36552929]])
484+
>>> a=[.5, .5]
485+
>>> b=[.5, .5]
486+
>>> M=[[0., 1.], [1., 0.]]
487+
>>> ot.bregman.greenkhorn(a, b, M, 1)
488+
array([[0.36552929, 0.13447071],
489+
[0.13447071, 0.36552929]])
490490
491491
492492
References
@@ -576,7 +576,7 @@ def greenkhorn(a, b, M, reg, numItermax=10000, stopThr=1e-9, verbose=False, log=
576576

577577
def sinkhorn_stabilized(a, b, M, reg, numItermax=1000, tau=1e3, stopThr=1e-9,
578578
warmstart=None, verbose=False, print_period=20, log=False, **kwargs):
579-
"""
579+
r"""
580580
Solve the entropic regularization OT problem with log stabilization
581581
582582
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,
639639
>>> b=[.5,.5]
640640
>>> M=[[0.,1.],[1.,0.]]
641641
>>> ot.bregman.sinkhorn_stabilized(a,b,M,1)
642-
array([[ 0.36552929, 0.13447071],
643-
[ 0.13447071, 0.36552929]])
642+
array([[0.36552929, 0.13447071],
643+
[0.13447071, 0.36552929]])
644644
645645
646646
References
@@ -796,7 +796,7 @@ def get_Gamma(alpha, beta, u, v):
796796

797797
def sinkhorn_epsilon_scaling(a, b, M, reg, numItermax=100, epsilon0=1e4, numInnerItermax=100,
798798
tau=1e3, stopThr=1e-9, warmstart=None, verbose=False, print_period=10, log=False, **kwargs):
799-
"""
799+
r"""
800800
Solve the entropic regularization optimal transport problem with log
801801
stabilization and epsilon scaling.
802802
@@ -862,12 +862,12 @@ def sinkhorn_epsilon_scaling(a, b, M, reg, numItermax=100, epsilon0=1e4, numInne
862862
--------
863863
864864
>>> import ot
865-
>>> a=[.5,.5]
866-
>>> b=[.5,.5]
867-
>>> M=[[0.,1.],[1.,0.]]
868-
>>> ot.bregman.sinkhorn_epsilon_scaling(a,b,M,1)
869-
array([[ 0.36552929, 0.13447071],
870-
[ 0.13447071, 0.36552929]])
865+
>>> a=[.5, .5]
866+
>>> b=[.5, .5]
867+
>>> M=[[0., 1.], [1., 0.]]
868+
>>> ot.bregman.sinkhorn_epsilon_scaling(a, b, M, 1)
869+
array([[0.36552929, 0.13447071],
870+
[0.13447071, 0.36552929]])
871871
872872
873873
References
@@ -989,7 +989,7 @@ def projC(gamma, q):
989989

990990
def barycenter(A, M, reg, weights=None, numItermax=1000,
991991
stopThr=1e-4, verbose=False, log=False):
992-
"""Compute the entropic regularized wasserstein barycenter of distributions A
992+
r"""Compute the entropic regularized wasserstein barycenter of distributions A
993993
994994
The function solves the following optimization problem:
995995
@@ -1084,7 +1084,7 @@ def barycenter(A, M, reg, weights=None, numItermax=1000,
10841084

10851085

10861086
def convolutional_barycenter2d(A, reg, weights=None, numItermax=10000, stopThr=1e-9, stabThr=1e-30, verbose=False, log=False):
1087-
"""Compute the entropic regularized wasserstein barycenter of distributions A
1087+
r"""Compute the entropic regularized wasserstein barycenter of distributions A
10881088
where A is a collection of 2D images.
10891089
10901090
The function solves the following optimization problem:
@@ -1195,7 +1195,7 @@ def K(x):
11951195

11961196
def unmix(a, D, M, M0, h0, reg, reg0, alpha, numItermax=1000,
11971197
stopThr=1e-3, verbose=False, log=False):
1198-
"""
1198+
r"""
11991199
Compute the unmixing of an observation with a given dictionary using Wasserstein distance
12001200
12011201
The function solve the following optimization problem:
@@ -1302,7 +1302,7 @@ def unmix(a, D, M, M0, h0, reg, reg0, alpha, numItermax=1000,
13021302

13031303

13041304
def empirical_sinkhorn(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numIterMax=10000, stopThr=1e-9, verbose=False, log=False, **kwargs):
1305-
'''
1305+
r'''
13061306
Solve the entropic regularization optimal transport problem and return the
13071307
OT matrix from empirical data
13081308
@@ -1360,10 +1360,9 @@ def empirical_sinkhorn(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numI
13601360
>>> reg = 0.1
13611361
>>> X_s = np.reshape(np.arange(n_s), (n_s, 1))
13621362
>>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1))
1363-
>>> emp_sinkhorn = empirical_sinkhorn(X_s, X_t, reg, verbose=False)
1364-
>>> print(emp_sinkhorn)
1365-
>>> [[4.99977301e-01 2.26989344e-05]
1366-
[2.26989344e-05 4.99977301e-01]]
1363+
>>> empirical_sinkhorn(X_s, X_t, reg, verbose=False) # doctest: +NORMALIZE_WHITESPACE
1364+
array([[4.99977301e-01, 2.26989344e-05],
1365+
[2.26989344e-05, 4.99977301e-01]])
13671366
13681367
13691368
References
@@ -1392,7 +1391,7 @@ def empirical_sinkhorn(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numI
13921391

13931392

13941393
def empirical_sinkhorn2(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', numIterMax=10000, stopThr=1e-9, verbose=False, log=False, **kwargs):
1395-
'''
1394+
r'''
13961395
Solve the entropic regularization optimal transport problem from empirical
13971396
data and return the OT loss
13981397
@@ -1451,9 +1450,8 @@ def empirical_sinkhorn2(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', num
14511450
>>> reg = 0.1
14521451
>>> X_s = np.reshape(np.arange(n_s), (n_s, 1))
14531452
>>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1))
1454-
>>> loss_sinkhorn = empirical_sinkhorn2(X_s, X_t, reg, verbose=False)
1455-
>>> print(loss_sinkhorn)
1456-
>>> [4.53978687e-05]
1453+
>>> empirical_sinkhorn2(X_s, X_t, reg, verbose=False)
1454+
array([4.53978687e-05])
14571455
14581456
14591457
References
@@ -1482,7 +1480,7 @@ def empirical_sinkhorn2(X_s, X_t, reg, a=None, b=None, metric='sqeuclidean', num
14821480

14831481

14841482
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):
1485-
'''
1483+
r'''
14861484
Compute the sinkhorn divergence loss from empirical data
14871485
14881486
The function solves the following optimization problems and return the
@@ -1560,9 +1558,8 @@ def empirical_sinkhorn_divergence(X_s, X_t, reg, a=None, b=None, metric='sqeucli
15601558
>>> reg = 0.1
15611559
>>> X_s = np.reshape(np.arange(n_s), (n_s, 1))
15621560
>>> X_t = np.reshape(np.arange(0, n_t), (n_t, 1))
1563-
>>> emp_sinkhorn_div = empirical_sinkhorn_divergence(X_s, X_t, reg)
1564-
>>> print(emp_sinkhorn_div)
1565-
>>> [2.99977435]
1561+
>>> empirical_sinkhorn_divergence(X_s, X_t, reg) # doctest: +ELLIPSIS
1562+
array([1.499...])
15661563
15671564
15681565
References

ot/gpu/bregman.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,6 @@ def sinkhorn_knopp(a, b, M, reg, numItermax=1000, stopThr=1e-9,
7070
log : dict
7171
log dictionary return only if log==True in parameters
7272
73-
Examples
74-
--------
75-
76-
>>> import ot
77-
>>> a=[.5,.5]
78-
>>> b=[.5,.5]
79-
>>> M=[[0.,1.],[1.,0.]]
80-
>>> ot.sinkhorn(a,b,M,1)
81-
array([[ 0.36552929, 0.13447071],
82-
[ 0.13447071, 0.36552929]])
83-
8473
8574
References
8675
----------

ot/lp/__init__.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626

2727
def emd(a, b, M, numItermax=100000, log=False):
28-
"""Solves the Earth Movers distance problem and returns the OT matrix
28+
r"""Solves the Earth Movers distance problem and returns the OT matrix
2929
3030
3131
.. math::
@@ -76,8 +76,8 @@ def emd(a, b, M, numItermax=100000, log=False):
7676
>>> b=[.5,.5]
7777
>>> M=[[0.,1.],[1.,0.]]
7878
>>> ot.emd(a,b,M)
79-
array([[ 0.5, 0. ],
80-
[ 0. , 0.5]])
79+
array([[0.5, 0. ],
80+
[0. , 0.5]])
8181
8282
References
8383
----------
@@ -117,7 +117,7 @@ def emd(a, b, M, numItermax=100000, log=False):
117117

118118
def emd2(a, b, M, processes=multiprocessing.cpu_count(),
119119
numItermax=100000, log=False, return_matrix=False):
120-
"""Solves the Earth Movers distance problem and returns the loss
120+
r"""Solves the Earth Movers distance problem and returns the loss
121121
122122
.. math::
123123
\gamma = arg\min_\gamma <\gamma,M>_F
@@ -315,7 +315,7 @@ def free_support_barycenter(measures_locations, measures_weights, X_init, b=None
315315

316316
def emd_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True,
317317
log=False):
318-
"""Solves the Earth Movers distance problem between 1d measures and returns
318+
r"""Solves the Earth Movers distance problem between 1d measures and returns
319319
the OT matrix
320320
321321
@@ -381,11 +381,11 @@ def emd_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True,
381381
>>> x_a = [2., 0.]
382382
>>> x_b = [0., 3.]
383383
>>> ot.emd_1d(x_a, x_b, a, b)
384-
array([[0. , 0.5],
385-
[0.5, 0. ]])
384+
array([[0. , 0.5],
385+
[0.5, 0. ]])
386386
>>> ot.emd_1d(x_a, x_b)
387-
array([[0. , 0.5],
388-
[0.5, 0. ]])
387+
array([[0. , 0.5],
388+
[0.5, 0. ]])
389389
390390
References
391391
----------
@@ -435,7 +435,7 @@ def emd_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True,
435435

436436
def emd2_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True,
437437
log=False):
438-
"""Solves the Earth Movers distance problem between 1d measures and returns
438+
r"""Solves the Earth Movers distance problem between 1d measures and returns
439439
the loss
440440
441441
@@ -530,7 +530,7 @@ def emd2_1d(x_a, x_b, a=None, b=None, metric='sqeuclidean', p=1., dense=True,
530530

531531

532532
def wasserstein_1d(x_a, x_b, a=None, b=None, p=1.):
533-
"""Solves the p-Wasserstein distance problem between 1d measures and returns
533+
r"""Solves the p-Wasserstein distance problem between 1d measures and returns
534534
the distance
535535
536536

0 commit comments

Comments
 (0)