Skip to content

Commit 6e4b236

Browse files
Merge branch 'master' into low-rank-via-factor-relaxation
2 parents 4a44da2 + 8aed2d7 commit 6e4b236

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2754
-302
lines changed

CONTRIBUTORS.md

+3-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
## Creators and Maintainers
44

5-
This toolbox has been created by
5+
This toolbox has been created by [Rémi Flamary](https://remi.flamary.com/)
6+
and [Nicolas Courty](http://people.irisa.fr/Nicolas.Courty/).
67

7-
* [Rémi Flamary](https://remi.flamary.com/)
8-
* [Nicolas Courty](http://people.irisa.fr/Nicolas.Courty/)
9-
10-
It is currently maintained by
8+
It is currently maintained by :
119

1210
* [Rémi Flamary](https://remi.flamary.com/)
1311
* [Cédric Vincent-Cuaz](https://cedricvincentcuaz.github.io/)

README.md

+7-9
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ POT provides the following generic OT solvers (links to examples):
4040
* [Sampled solver of Gromov Wasserstein](https://pythonot.github.io/auto_examples/gromov/plot_gromov.html) for large-scale problem with any loss functions [33]
4141
* Non regularized [free support Wasserstein barycenters](https://pythonot.github.io/auto_examples/barycenters/plot_free_support_barycenter.html) [20].
4242
* [One dimensional Unbalanced OT](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_UOT_1D.html) with KL relaxation and [barycenter](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_UOT_barycenter_1D.html) [10, 25]. Also [exact unbalanced OT](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_unbalanced_ot.html) with KL and quadratic regularization and the [regularization path of UOT](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_regpath.html) [41]
43-
* [Partial Wasserstein and Gromov-Wasserstein](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_partial_wass_and_gromov.html) (exact [29] and entropic [3]
44-
formulations).
43+
* [Partial Wasserstein and Gromov-Wasserstein](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_partial_wass_and_gromov.html) and [Partial Fused Gromov-Wasserstein](https://pythonot.github.io/auto_examples/gromov/plot_partial_fgw.html) (exact [29] and entropic [3] formulations).
4544
* [Sliced Wasserstein](https://pythonot.github.io/auto_examples/sliced-wasserstein/plot_variance.html) [31, 32] and Max-sliced Wasserstein [35] that can be used for gradient flows [36].
4645
* [Wasserstein distance on the circle](https://pythonot.github.io/auto_examples/plot_compute_wasserstein_circle.html) [44, 45]
4746
* [Spherical Sliced Wasserstein](https://pythonot.github.io/auto_examples/sliced-wasserstein/plot_variance_ssw.html) [46]
@@ -203,12 +202,9 @@ The examples folder contain several examples and use case for the library. The f
203202

204203
## Acknowledgements
205204

206-
This toolbox has been created by
205+
This toolbox has been created by [Rémi Flamary](https://remi.flamary.com/) and [Nicolas Courty](http://people.irisa.fr/Nicolas.Courty/).
207206

208-
* [Rémi Flamary](https://remi.flamary.com/)
209-
* [Nicolas Courty](http://people.irisa.fr/Nicolas.Courty/)
210-
211-
It is currently maintained by
207+
It is currently maintained by :
212208

213209
* [Rémi Flamary](https://remi.flamary.com/)
214210
* [Cédric Vincent-Cuaz](https://cedricvincentcuaz.github.io/)
@@ -219,8 +215,6 @@ POT has benefited from the financing or manpower from the following partners:
219215

220216
<img src="https://pythonot.github.io/master/_static/images/logo_anr.jpg" alt="ANR" style="height:60px;"/><img src="https://pythonot.github.io/master/_static/images/logo_cnrs.jpg" alt="CNRS" style="height:60px;"/><img src="https://pythonot.github.io/master/_static/images/logo_3ia.jpg" alt="3IA" style="height:60px;"/><img src="https://pythonot.github.io/master/_static/images/logo_hiparis.png" alt="Hi!PARIS" style="height:60px;"/>
221217

222-
223-
224218
## Contributions and code of conduct
225219

226220
Every contribution is welcome and should respect the [contribution guidelines](https://pythonot.github.io/master/contributing.html). Each member of the project is expected to follow the [code of conduct](https://pythonot.github.io/master/code_of_conduct.html).
@@ -391,3 +385,7 @@ Artificial Intelligence.
391385
[72] Thibault Séjourné, François-Xavier Vialard, and Gabriel Peyré (2021). [The Unbalanced Gromov Wasserstein Distance: Conic Formulation and Relaxation](https://proceedings.neurips.cc/paper/2021/file/4990974d150d0de5e6e15a1454fe6b0f-Paper.pdf). Neural Information Processing Systems (NeurIPS).
392386

393387
[73] Séjourné, T., Vialard, F. X., & Peyré, G. (2022). [Faster Unbalanced Optimal Transport: Translation Invariant Sinkhorn and 1-D Frank-Wolfe](https://proceedings.mlr.press/v151/sejourne22a.html). In International Conference on Artificial Intelligence and Statistics (pp. 4995-5021). PMLR.
388+
389+
[74] Chewi, S., Maunu, T., Rigollet, P., & Stromme, A. J. (2020). [Gradient descent algorithms for Bures-Wasserstein barycenters](https://proceedings.mlr.press/v125/chewi20a.html). In Conference on Learning Theory (pp. 1276-1304). PMLR.
390+
391+
[75] Altschuler, J., Chewi, S., Gerber, P. R., & Stromme, A. (2021). [Averaging on the Bures-Wasserstein manifold: dimension-free convergence of gradient descent](https://papers.neurips.cc/paper_files/paper/2021/hash/b9acb4ae6121c941324b2b1d3fac5c30-Abstract.html). Advances in Neural Information Processing Systems, 34, 22132-22145.

RELEASES.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77
- Added feature `grad=last_step` for `ot.solvers.solve` (PR #693)
88
- Automatic PR labeling and release file update check (PR #704)
99
- Reorganize sub-module `ot/lp/__init__.py` into separate files (PR #714)
10+
- Fix warning raise when import the library (PR #716)
11+
- Implement projected gradient descent solvers for entropic partial FGW (PR #702)
1012
- Fix documentation in the module `ot.gaussian` (PR #718)
13+
- Refactored `ot.bregman._convolutional` to improve readability (PR #709)
14+
- Added `ot.gaussian.bures_barycenter_gradient_descent` (PR #680)
15+
- Added `ot.gaussian.bures_wasserstein_distance` (PR #680)
16+
- `ot.gaussian.bures_wasserstein_distance` can be batched (PR #680)
17+
- Backend implementation of `ot.dist` for (PR #701)
18+
- Updated documentation Quickstart guide and User guide with new API (PR #726)
1119
- Implement low rank through Factor Relaxation with Latent Coupling (PR #719)
1220

1321
#### Closed issues
@@ -16,6 +24,7 @@
1624
- Add version number to the documentation (PR #696)
1725
- Update doc for default regularization in `ot.unbalanced` sinkhorn solvers (Issue #691, PR #700)
1826
- Clean documentation for `gromov`, `lp` and `unbalanced` folders (PR #710)
27+
- Clean references in documentation (PR #722)
1928

2029
## 0.9.5
2130

@@ -44,7 +53,6 @@ This release also contains few bug fixes, concerning the support of any metric i
4453
- Notes before depreciating partial Gromov-Wasserstein function in `ot.partial` moved to ot.gromov (PR #663)
4554
- Create `ot.gromov._partial` add new features `loss_fun = "kl_loss"` and `symmetry=False` to all solvers while increasing speed + updating adequatly `ot.solvers` (PR #663)
4655
- Added `ot.unbalanced.sinkhorn_unbalanced_translation_invariant` (PR #676)
47-
- Refactored `ot.bregman._convolutional` to improve readability (PR #709)
4856

4957
#### Closed issues
5058
- Fixed `ot.gaussian` ignoring weights when computing means (PR #649, Issue #648)

docs/source/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ def __getattr__(cls, name):
347347
}
348348

349349
sphinx_gallery_conf = {
350-
"examples_dirs": ["../../examples", "../../examples/da"],
350+
"examples_dirs": ["../../examples"],
351351
"gallery_dirs": "auto_examples",
352352
"filename_pattern": "plot_", # (?!barycenter_fgw)
353353
"nested_sections": False,

docs/source/index.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ Contents
1717
:maxdepth: 1
1818

1919
self
20-
quickstart
21-
all
20+
auto_examples/plot_quickstart_guide
2221
auto_examples/index
22+
user_guide
23+
all
2324
releases
2425
contributors
2526
contributing

docs/source/quickstart.rst renamed to docs/source/user_guide.rst

+35-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

2-
Quick start guide
3-
=================
2+
User guide
3+
==========
44

55
In the following we provide some pointers about which functions and classes
66
to use for different problems related to optimal transport (OT) and machine
@@ -136,12 +136,12 @@ instance the memory cost for an OT problem is always :math:`\mathcal{O}(n^2)` in
136136
memory because the cost matrix has to be computed. The exact solver in of time
137137
complexity :math:`\mathcal{O}(n^3\log(n))` and the Sinkhorn solver has been
138138
proven to be nearly :math:`\mathcal{O}(n^2)` which is still too complex for very
139-
large scale solvers.
139+
large scale solvers. For all the generic solvers we need to compute the cost
140+
matrix and the OT matrix of memory size :math:`\mathcal{O}(n^2)` which can be
141+
prohibitive for very large scale problems.
140142

141-
142-
If you need to solve OT with large number of samples, we recommend to use
143-
entropic regularization and memory efficient implementation of Sinkhorn as
144-
proposed in `GeomLoss <https://www.kernel-operations.io/geomloss/>`_. This
143+
If you need to solve OT with large number of samples, we provide "lazy" memory efficient implementation of Sinkhorn in pure
144+
python and using `GeomLoss <https://www.kernel-operations.io/geomloss/>`_. This
145145
implementation is compatible with Pytorch and can handle large number of
146146
samples. Another approach to estimate the Wasserstein distance for very large
147147
number of sample is to use the trick from `Wasserstein GAN
@@ -193,15 +193,19 @@ that will return the optimal transport matrix :math:`\gamma^*`:
193193
194194
# a and b are 1D histograms (sum to 1 and positive)
195195
# M is the ground cost matrix
196+
197+
# unified API
198+
T = ot.solve(M, a, b).plan # exact linear program
199+
200+
# classical API
196201
T = ot.emd(a, b, M) # exact linear program
197202
198203
The method implemented for solving the OT problem is the network simplex. It is
199204
implemented in C from [1]_. It has a complexity of :math:`O(n^3)` but the
200205
solver is quite efficient and uses sparsity of the solution.
201206

202207

203-
204-
.. minigallery:: ot.emd
208+
.. minigallery:: ot.emd, ot.solve
205209
:add-heading: Examples of use for :any:`ot.emd`
206210
:heading-level: "
207211

@@ -226,7 +230,12 @@ It can computed from an already estimated OT matrix with
226230
227231
# a and b are 1D histograms (sum to 1 and positive)
228232
# M is the ground cost matrix
229-
W = ot.emd2(a, b, M) # Wasserstein distance / EMD value
233+
234+
# Wasserstein distance / EMD value with unified API
235+
W = ot.solve(M, a, b, return_matrix=False).value
236+
237+
# with classical API
238+
W = ot.emd2(a, b, M)
230239
231240
Note that the well known `Wasserstein distance
232241
<https://en.wikipedia.org/wiki/Wasserstein_metric>`_ between distributions a and
@@ -246,7 +255,7 @@ the :math:`W_1` Wasserstein distance can be done directly with :any:`ot.emd2`
246255
when providing :code:`M = ot.dist(xs, xt, metric='euclidean')` to use the Euclidean
247256
distance.
248257

249-
.. minigallery:: ot.emd2
258+
.. minigallery:: ot.emd2, ot.solve
250259
:add-heading: Examples of use for :any:`ot.emd2`
251260
:heading-level: "
252261

@@ -274,6 +283,10 @@ distributions. In the case when the finite sample dataset is supposed Gaussian,
274283
we provide :any:`ot.gaussian.bures_wasserstein_mapping` that returns the parameters for the
275284
Monge mapping.
276285

286+
All those special cases are accessible with the unified API of POT through the
287+
function :any:`ot.solve_sample` with the parameter :code:`method` that allows to
288+
choose the method used to solve the problem (with :code:`method='1D'` or :code:`method='gaussian'`).
289+
277290

278291
Regularized Optimal Transport
279292
-----------------------------
@@ -330,13 +343,15 @@ The Sinkhorn-Knopp algorithm is implemented in :any:`ot.sinkhorn` and
330343
linear term. Note that the regularization parameter :math:`\lambda` in the
331344
equation above is given to those functions with the parameter :code:`reg`.
332345

333-
>>> import ot
334-
>>> a = [.5, .5]
335-
>>> b = [.5, .5]
336-
>>> M = [[0., 1.], [1., 0.]]
337-
>>> ot.sinkhorn(a, b, M, 1)
338-
array([[ 0.36552929, 0.13447071],
339-
[ 0.13447071, 0.36552929]])
346+
.. code:: python
347+
348+
# unified API
349+
P = ot.solve(M, a, b, reg=1).plan # OT Sinkhorn matrix
350+
loss = ot.solve(M, a, b, reg=1).value # OT Sinkhorn value
351+
352+
# classical API
353+
P = ot.sinkhorn(a, b, M, reg=1) # OT Sinkhorn matrix
354+
loss = ot.sinkhorn2(a, b, M, reg=1) # OT Sinkhorn value
340355
341356
More details about the algorithms used are given in the following note.
342357

@@ -406,13 +421,10 @@ implementations are not optimized for speed but provide a robust implementation
406421
of algorithms in [18]_ [19]_.
407422

408423

409-
.. minigallery:: ot.sinkhorn
410-
:add-heading: Examples of use for :any:`ot.sinkhorn`
424+
.. minigallery:: ot.sinkhorn ot.sinkhorn2
425+
:add-heading: Examples of use for Sinkhorn algorithm
411426
:heading-level: "
412427

413-
.. minigallery:: ot.sinkhorn2
414-
:add-heading: Examples of use for :any:`ot.sinkhorn2`
415-
:heading-level: "
416428

417429

418430
Other regularizations
@@ -969,18 +981,6 @@ For instance, to disable TensorFlow, set `export POT_BACKEND_DISABLE_TENSORFLOW=
969981
It's important to note that the `numpy` backend cannot be disabled.
970982

971983

972-
List of compatible modules
973-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
974-
975-
This list will get longer for new releases and will hopefully disappear when POT
976-
become fully implemented with the backend.
977-
978-
- :any:`ot.bregman`
979-
- :any:`ot.gromov` (some functions use CPU only solvers with copy overhead)
980-
- :any:`ot.optim` (some functions use CPU only solvers with copy overhead)
981-
- :any:`ot.sliced`
982-
- :any:`ot.utils` (partial)
983-
984984

985985
FAQ
986986
---

examples/gromov/plot_barycenter_fgw.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def build_noisy_circular_graph(
9191
g = nx.Graph()
9292
g.add_nodes_from(list(range(N)))
9393
for i in range(N):
94-
noise = float(np.random.normal(mu, sigma, 1))
94+
noise = np.random.normal(mu, sigma, 1)[0]
9595
if with_noise:
9696
g.add_node(i, attr_name=math.sin((2 * i * math.pi / N)) + noise)
9797
else:
@@ -107,7 +107,7 @@ def build_noisy_circular_graph(
107107
if i == N - 1:
108108
g.add_edge(i, 1)
109109
g.add_edge(N, 0)
110-
noise = float(np.random.normal(mu, sigma, 1))
110+
noise = np.random.normal(mu, sigma, 1)[0]
111111
if with_noise:
112112
g.add_node(N, attr_name=math.sin((2 * N * math.pi / N)) + noise)
113113
else:
@@ -157,7 +157,7 @@ def graph_colors(nx_graph, vmin=0, vmax=7):
157157
plt.subplot(3, 3, i + 1)
158158
g = X0[i]
159159
pos = nx.kamada_kawai_layout(g)
160-
nx.draw(
160+
nx.draw_networkx(
161161
g,
162162
pos=pos,
163163
node_color=graph_colors(g, vmin=-1, vmax=1),
@@ -173,7 +173,7 @@ def graph_colors(nx_graph, vmin=0, vmax=7):
173173

174174
# %% We compute the barycenter using FGW. Structure matrices are computed using the shortest_path distance in the graph
175175
# Features distances are the euclidean distances
176-
Cs = [shortest_path(nx.adjacency_matrix(x).todense()) for x in X0]
176+
Cs = [shortest_path(nx.adjacency_matrix(x).toarray()) for x in X0]
177177
ps = [np.ones(len(x.nodes())) / len(x.nodes()) for x in X0]
178178
Ys = [
179179
np.array([v for (k, v) in nx.get_node_attributes(x, "attr_name").items()]).reshape(
@@ -199,7 +199,7 @@ def graph_colors(nx_graph, vmin=0, vmax=7):
199199

200200
# %%
201201
pos = nx.kamada_kawai_layout(bary)
202-
nx.draw(
202+
nx.draw_networkx(
203203
bary, pos=pos, node_color=graph_colors(bary, vmin=-1, vmax=1), with_labels=False
204204
)
205205
plt.suptitle("Barycenter", fontsize=20)

0 commit comments

Comments
 (0)