Skip to content

Commit e52c2a3

Browse files
thibaut-germainosheasiennarflamary
authored
[MRG] Proximal point solver for batched optimal transport (#832)
* correction SGOT cost matrix, added to contributor list, move sgot example to other * updated graphs * fix plots * update example * fix releases.md * reformating * updating format * updated format * updated format * added PR and references * aligned usage of solve and solve_batch + added batch tests * fixed example * Apply suggestions from code review Co-authored-by: Rémi Flamary <remi.flamary@gmail.com> --------- Co-authored-by: Sienna O'Shea <osheasienna@gmail.com> Co-authored-by: Rémi Flamary <remi.flamary@gmail.com>
1 parent c836b97 commit e52c2a3

7 files changed

Lines changed: 423 additions & 129 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,4 +471,8 @@ Artificial Intelligence.
471471

472472
\[90] Genans, F., Godichon-Baggioni, A., Vialard, F. X., & Wintenberger, O. (2025). [Decreasing Entropic Regularization Averaged Gradient for Semi-Discrete Optimal Transport](https://proceedings.neurips.cc/paper_files/paper/2025/file/d7efa12e98f5e0dd8b4f48cd60b4e3aa-Paper-Conference.pdf). Advances in Neural Information Processing Systems, 38, 146913-146949.
473473

474-
\[91] Fatras, K., Zine, Y., Majewski, S., Flamary, R., Gribonval, R., & Courty, N. (2021). [Minibatch optimal transport distances; analysis and applications](https://arxiv.org/pdf/2101.01792). arXiv preprint arXiv:2101.01792.
474+
\[91] Fatras, K., Zine, Y., Majewski, S., Flamary, R., Gribonval, R., & Courty, N. (2021). [Minibatch optimal transport distances; analysis and applications](https://arxiv.org/pdf/2101.01792). arXiv preprint arXiv:2101.01792.
475+
476+
\[92] Xie, Y., Wang, X., Wang, R., & Zha, H. (2020, August).
477+
[A fast proximal point method for computing exact wasserstein distance.](https://proceedings.mlr.press/v115/xie20b/xie20b.pdf) In Uncertainty in artificial intelligence (pp. 433-453). PMLR.
478+

RELEASES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ This new release adds support for sparse cost matrices and a new lazy exact OT s
3030
- Add a numerically stable log-domain solver for entropic partial Wasserstein, selectable via the new `method` parameter of `entropic_partial_wasserstein` (`method='sinkhorn_log'`) or directly through `entropic_partial_wasserstein_logscale` (Issue #723)
3131
- Add cost functions between linear operators following
3232
[A Spectral-Grassmann Wasserstein metric for operator representations of dynamical systems](https://arxiv.org/pdf/2509.24920),
33-
implemented in `ot.sgot` (PR #792)
33+
implemented in `ot.sgot` (PR #792, PR #830)
3434
- Add batch FUGW loss to `ot.batch` and fix issues in some default parameters in the batch module (PR #775)
3535
- Wrapper for barycenter solvers with free support `ot.solvers.bary_free_support` (PR #730)
3636
- Build wheels on ubuntu ARM to avoid QEMU emulation (PR #818)
3737
- Add new methods to compute the linear transport map and the related 2-Wasserstein distance betweeen high-dimensional (HD) Gaussian distributions as described in [88], implemented in `ot.gaussian.bures_wasserstein_mapping_hd` and `ot.gaussian.bures_wasserstein_distance_hd`, respectively. Two additional methods estimate the same quantities from the source and destination observed data and are implemented in `ot.gaussian.empirical_bures_wasserstein_mapping_hd` and `ot.gaussian.empirical_bures_wasserstein_distance_hd`, respectively (PR #814)
3838
- Update the geomloss wrapper to the new version and API (PR #826)
3939
- Fix docstrings for `lowrank_gromov_wasserstein_samples` and `lowrank_sinkhorn` (PR #823)
4040
- Reorganize all tests per backend (PR #828)
41+
- Implemented batch proximal point solver for OT problems `ot.batch.proximal_bregman_log_plan_batch` function and updated wrapper functions `ot.batch.solve_batch` and `ot.batch.solve_sample_batch` (PR #832)
4142
- Implement debiased OT solvers in `ot.solve_sample`.
4243

4344

examples/backends/plot_ot_batch.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"""
1414

1515
# Author: Paul Krzakala <paul.krzakala@gmail.com>
16+
# Thibaut Germain <thibaut.germain.pro@gmail.com>
1617
# License: MIT License
1718

1819
# sphinx_gallery_thumbnail_number = 1
@@ -75,25 +76,52 @@
7576
# This is simple but inefficient for large batches.
7677
#
7778
# Instead, you can use :func:`ot.batch.solve_batch`, which solves all
78-
# problems in parallel.
79+
# problems in parallel. Several methods are available: ["sinkhorn", "log_sinkhorn"]
80+
# which solve regularized OT problems, and ["proximal"] which
81+
# solves regularized and unregularized OT problem using a proximal point scheme.
82+
# By default, the method is set to "auto" which automatically selects the appropriate
83+
# method based on the value of `reg`. If `reg` is None or 0, the proximal point method
84+
# is used. If `reg` is greater than 0, the Sinkhorn algorithm is used.
85+
86+
max_iter = 10000
87+
tol = 1e-4
88+
89+
# Classical OT problem
90+
## Naive approach
91+
results_values_list = []
92+
for i in range(n_problems):
93+
res = ot.solve(M_list[i], max_iter=max_iter, tol=tol)
94+
results_values_list.append(res.value_linear)
7995

80-
reg = 1.0
81-
max_iter = 100
82-
tol = 1e-3
96+
## Batched approach
97+
results_batch = ot.solve_batch(M=M_batch, max_iter=max_iter, tol=tol)
98+
results_values_batch = results_batch.value_linear
8399

84-
# Naive approach
100+
exact_validated = np.allclose(
101+
np.array(results_values_list), results_values_batch, atol=tol * 10
102+
)
103+
104+
# Entropic regularized OT problem
105+
## Naive approach
106+
reg = 1.0
85107
results_values_list = []
86108
for i in range(n_problems):
87109
res = ot.solve(M_list[i], reg=reg, max_iter=max_iter, tol=tol, reg_type="entropy")
88110
results_values_list.append(res.value_linear)
89111

90-
# Batched approach
112+
## Batched approach
91113
results_batch = ot.solve_batch(
92114
M=M_batch, reg=reg, max_iter=max_iter, tol=tol, reg_type="entropy"
93115
)
94116
results_values_batch = results_batch.value_linear
95117

96-
assert np.allclose(np.array(results_values_list), results_values_batch, atol=tol * 10)
118+
entropic_validated = np.allclose(
119+
np.array(results_values_list), results_values_batch, atol=tol * 10
120+
)
121+
122+
print(
123+
f"Exact solve vs proximal batch close: {exact_validated} \nSinkhorn solve vs Sinkhorn solve_batch close: {entropic_validated}"
124+
)
97125

98126
#############################################################################
99127
#

ot/batch/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
# Author: Remi Flamary <remi.flamary@unice.fr>
77
# Paul Krzakala <paul.krzakala@gmail.com>
8+
# Thibaut Germain <thibaut.germain.pro@gmail.com>
89
#
910
# License: MIT License
1011

@@ -25,6 +26,7 @@
2526
bregman_log_projection_batch,
2627
bregman_projection_batch,
2728
entropy_batch,
29+
proximal_bregman_log_plan_batch,
2830
)
2931

3032
__all__ = [
@@ -40,4 +42,5 @@
4042
"loss_quadratic_batch",
4143
"loss_quadratic_samples_batch",
4244
"tensor_batch",
45+
"proximal_bregman_log_plan_batch",
4346
]

0 commit comments

Comments
 (0)