Skip to content

Commit ac4cf44

Browse files
lchapelrflamary
andauthored
[MRG] MM algorithms for UOT (#362)
* bugfix * update refs partial OT * fixes small typos in plot_partial_wass_and_gromov * fix small bugs in partial.py * update README * pep8 bugfix * modif doctest * fix bugtests * update on test_partial and test on the numerical precision on ot/partial * resolve merge pb * Delete partial.py * update unbalanced: mm algo+plot * update unbalanced: mm algo+plot * update unbalanced: mm algo+plot * update unbalanced: mm algo+plot * update unbalanced: mm algo+plot * add test mm algo unbalanced OT * add test mm algo unbalanced OT * add test mm algo unbalanced OT * add test mm algo unbalanced OT * add test mm algo unbalanced OT * add test mm algo unbalanced OT * add test mm algo unbalanced OT * add test mm algo unbalanced OT * update unbalanced: mm algo+plot * update unbalanced: mm algo+plot * update releases.md with new MM UOT algorithms Co-authored-by: Rémi Flamary <[email protected]>
1 parent 0b223ff commit ac4cf44

File tree

8 files changed

+802
-224
lines changed

8 files changed

+802
-224
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ POT provides the following generic OT solvers (links to examples):
3535
Large-scale Optimal Transport (semi-dual problem [18] and dual problem [19])
3636
* [Sampled solver of Gromov Wasserstein](https://pythonot.github.io/auto_examples/gromov/plot_gromov.html) for large-scale problem with any loss functions [33]
3737
* Non regularized [free support Wasserstein barycenters](https://pythonot.github.io/auto_examples/barycenters/plot_free_support_barycenter.html) [20].
38-
* [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].
38+
* [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]
3939
* [Partial Wasserstein and Gromov-Wasserstein](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_partial_wass_and_gromov.html) (exact [29] and entropic [3]
4040
formulations).
4141
* [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].
@@ -309,4 +309,6 @@ Dictionary Learning](https://arxiv.org/pdf/2102.06555.pdf), International Confer
309309

310310
[39] Gozlan, N., Roberto, C., Samson, P. M., & Tetali, P. (2017). [Kantorovich duality for general transport costs and applications](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.712.1825&rep=rep1&type=pdf). Journal of Functional Analysis, 273(11), 3327-3405.
311311

312-
[40] Forrow, A., Hütter, J. C., Nitzan, M., Rigollet, P., Schiebinger, G., & Weed, J. (2019, April). [Statistical optimal transport via factored couplings](http://proceedings.mlr.press/v89/forrow19a/forrow19a.pdf). In The 22nd International Conference on Artificial Intelligence and Statistics (pp. 2454-2465). PMLR.
312+
[40] Forrow, A., Hütter, J. C., Nitzan, M., Rigollet, P., Schiebinger, G., & Weed, J. (2019, April). [Statistical optimal transport via factored couplings](http://proceedings.mlr.press/v89/forrow19a/forrow19a.pdf). In The 22nd International Conference on Artificial Intelligence and Statistics (pp. 2454-2465). PMLR.
313+
314+
[41] Chapel*, L., Flamary*, R., Wu, H., Févotte, C., Gasso, G. (2021). [Unbalanced Optimal Transport through Non-negative Penalized Linear Regression](https://proceedings.neurips.cc/paper/2021/file/c3c617a9b80b3ae1ebd868b0017cc349-Paper.pdf) Advances in Neural Information Processing Systems (NeurIPS), 2020. (Two first co-authors)

RELEASES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
- Add backend support for Domain Adaptation and Unbalanced solvers (PR #343).
2020
- Add (F)GW linear dictionary learning solvers + example (PR #319)
2121
- Add links to related PR and Issues in the doc release page (PR #350)
22+
- Add new minimization-maximization algorithms for solving exact Unbalanced OT + example (PR #362)
2223

2324
#### Closed issues
2425

docs/source/all.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ API and modules
2626
plot
2727
stochastic
2828
unbalanced
29+
regpath
2930
partial
3031
sliced
3132
weak
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
==============================================================
4+
2D examples of exact and entropic unbalanced optimal transport
5+
==============================================================
6+
This example is designed to show how to compute unbalanced and
7+
partial OT in POT.
8+
9+
UOT aims at solving the following optimization problem:
10+
11+
.. math::
12+
W = \min_{\gamma} <\gamma, \mathbf{M}>_F +
13+
\mathrm{reg}\cdot\Omega(\gamma) +
14+
\mathrm{reg_m} \cdot \mathrm{div}(\gamma \mathbf{1}, \mathbf{a}) +
15+
\mathrm{reg_m} \cdot \mathrm{div}(\gamma^T \mathbf{1}, \mathbf{b})
16+
17+
s.t.
18+
\gamma \geq 0
19+
20+
where :math:`\mathrm{div}` is a divergence.
21+
When using the entropic UOT, :math:`\mathrm{reg}>0` and :math:`\mathrm{div}`
22+
should be the Kullback-Leibler divergence.
23+
When solving exact UOT, :math:`\mathrm{reg}=0` and :math:`\mathrm{div}`
24+
can be either the Kullback-Leibler or the quadratic divergence.
25+
Using :math:`\ell_1` norm gives the so-called partial OT.
26+
"""
27+
28+
# Author: Laetitia Chapel <[email protected]>
29+
# License: MIT License
30+
31+
import numpy as np
32+
import matplotlib.pylab as pl
33+
import ot
34+
35+
##############################################################################
36+
# Generate data
37+
# -------------
38+
39+
# %% parameters and data generation
40+
41+
n = 40 # nb samples
42+
43+
mu_s = np.array([-1, -1])
44+
cov_s = np.array([[1, 0], [0, 1]])
45+
46+
mu_t = np.array([4, 4])
47+
cov_t = np.array([[1, -.8], [-.8, 1]])
48+
49+
np.random.seed(0)
50+
xs = ot.datasets.make_2D_samples_gauss(n, mu_s, cov_s)
51+
xt = ot.datasets.make_2D_samples_gauss(n, mu_t, cov_t)
52+
53+
n_noise = 10
54+
55+
xs = np.concatenate((xs, ((np.random.rand(n_noise, 2) - 4))), axis=0)
56+
xt = np.concatenate((xt, ((np.random.rand(n_noise, 2) + 6))), axis=0)
57+
58+
n = n + n_noise
59+
60+
a, b = np.ones((n,)) / n, np.ones((n,)) / n # uniform distribution on samples
61+
62+
# loss matrix
63+
M = ot.dist(xs, xt)
64+
M /= M.max()
65+
66+
67+
##############################################################################
68+
# Compute entropic kl-regularized UOT, kl- and l2-regularized UOT
69+
# -----------
70+
71+
reg = 0.005
72+
reg_m_kl = 0.05
73+
reg_m_l2 = 5
74+
mass = 0.7
75+
76+
entropic_kl_uot = ot.unbalanced.sinkhorn_unbalanced(a, b, M, reg, reg_m_kl)
77+
kl_uot = ot.unbalanced.mm_unbalanced(a, b, M, reg_m_kl, div='kl')
78+
l2_uot = ot.unbalanced.mm_unbalanced(a, b, M, reg_m_l2, div='l2')
79+
partial_ot = ot.partial.partial_wasserstein(a, b, M, m=mass)
80+
81+
##############################################################################
82+
# Plot the results
83+
# ----------------
84+
85+
pl.figure(2)
86+
transp = [partial_ot, l2_uot, kl_uot, entropic_kl_uot]
87+
title = ["partial OT \n m=" + str(mass), "$\ell_2$-UOT \n $\mathrm{reg_m}$=" +
88+
str(reg_m_l2), "kl-UOT \n $\mathrm{reg_m}$=" + str(reg_m_kl),
89+
"entropic kl-UOT \n $\mathrm{reg_m}$=" + str(reg_m_kl)]
90+
91+
for p in range(4):
92+
pl.subplot(2, 4, p + 1)
93+
P = transp[p]
94+
if P.sum() > 0:
95+
P = P / P.max()
96+
for i in range(n):
97+
for j in range(n):
98+
if P[i, j] > 0:
99+
pl.plot([xs[i, 0], xt[j, 0]], [xs[i, 1], xt[j, 1]], color='C2',
100+
alpha=P[i, j] * 0.3)
101+
pl.scatter(xs[:, 0], xs[:, 1], c='C0', alpha=0.2)
102+
pl.scatter(xt[:, 0], xt[:, 1], c='C1', alpha=0.2)
103+
pl.scatter(xs[:, 0], xs[:, 1], c='C0', s=P.sum(1).ravel() * (1 + p) * 2)
104+
pl.scatter(xt[:, 0], xt[:, 1], c='C1', s=P.sum(0).ravel() * (1 + p) * 2)
105+
pl.title(title[p])
106+
pl.yticks(())
107+
pl.xticks(())
108+
if p < 1:
109+
pl.ylabel("mappings")
110+
pl.subplot(2, 4, p + 5)
111+
pl.imshow(P, cmap='jet')
112+
pl.yticks(())
113+
pl.xticks(())
114+
if p < 1:
115+
pl.ylabel("transport plans")
116+
pl.show()

ot/partial.py

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
# License: MIT License
88

99
import numpy as np
10-
1110
from .lp import emd
1211

1312

@@ -29,7 +28,8 @@ def partial_wasserstein_lagrange(a, b, M, reg_m=None, nb_dummies=1, log=False,
2928
3029
\gamma &\geq 0
3130
32-
\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
31+
\mathbf{1}^T \gamma^T \mathbf{1} = m &
32+
\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
3333
3434
3535
or equivalently (see Chizat, L., Peyré, G., Schmitzer, B., & Vialard, F. X.
@@ -50,7 +50,8 @@ def partial_wasserstein_lagrange(a, b, M, reg_m=None, nb_dummies=1, log=False,
5050
- :math:`\lambda` is the lagrangian cost. Tuning its value allows attaining
5151
a given mass to be transported `m`
5252
53-
The formulation of the problem has been proposed in :ref:`[28] <references-partial-wasserstein-lagrange>`
53+
The formulation of the problem has been proposed in
54+
:ref:`[28] <references-partial-wasserstein-lagrange>`
5455
5556
5657
Parameters
@@ -261,7 +262,7 @@ def partial_wasserstein(a, b, M, m=None, nb_dummies=1, log=False, **kwargs):
261262
b_extended = np.append(b, [(np.sum(a) - m) / nb_dummies] * nb_dummies)
262263
a_extended = np.append(a, [(np.sum(b) - m) / nb_dummies] * nb_dummies)
263264
M_extended = np.zeros((len(a_extended), len(b_extended)))
264-
M_extended[-nb_dummies:, -nb_dummies:] = np.max(M) * 1e5
265+
M_extended[-nb_dummies:, -nb_dummies:] = np.max(M) * 2
265266
M_extended[:len(a), :len(b)] = M
266267

267268
gamma, log_emd = emd(a_extended, b_extended, M_extended, log=True,
@@ -455,7 +456,8 @@ def partial_gromov_wasserstein(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
455456
- :math:`\mathbf{a}` and :math:`\mathbf{b}` are the sample weights
456457
- `m` is the amount of mass to be transported
457458
458-
The formulation of the problem has been proposed in :ref:`[29] <references-partial-gromov-wasserstein>`
459+
The formulation of the problem has been proposed in
460+
:ref:`[29] <references-partial-gromov-wasserstein>`
459461
460462
461463
Parameters
@@ -469,7 +471,8 @@ def partial_gromov_wasserstein(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
469471
q : ndarray, shape (nt,)
470472
Distribution in the target space
471473
m : float, optional
472-
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
474+
Amount of mass to be transported
475+
(default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
473476
nb_dummies : int, optional
474477
Number of dummy points to add (avoid instabilities in the EMD solver)
475478
G0 : ndarray, shape (ns, nt), optional
@@ -623,16 +626,19 @@ def partial_gromov_wasserstein2(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
623626
624627
\gamma &\geq 0
625628
626-
\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
629+
\mathbf{1}^T \gamma^T \mathbf{1} = m
630+
&\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
627631
628632
where :
629633
630634
- :math:`\mathbf{M}` is the metric cost matrix
631-
- :math:`\Omega` is the entropic regularization term, :math:`\Omega(\gamma) = \sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
635+
- :math:`\Omega` is the entropic regularization term,
636+
:math:`\Omega(\gamma) = \sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
632637
- :math:`\mathbf{a}` and :math:`\mathbf{b}` are the sample weights
633638
- `m` is the amount of mass to be transported
634639
635-
The formulation of the problem has been proposed in :ref:`[29] <references-partial-gromov-wasserstein2>`
640+
The formulation of the problem has been proposed in
641+
:ref:`[29] <references-partial-gromov-wasserstein2>`
636642
637643
638644
Parameters
@@ -646,7 +652,8 @@ def partial_gromov_wasserstein2(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
646652
q : ndarray, shape (nt,)
647653
Distribution in the target space
648654
m : float, optional
649-
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
655+
Amount of mass to be transported
656+
(default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
650657
nb_dummies : int, optional
651658
Number of dummy points to add (avoid instabilities in the EMD solver)
652659
G0 : ndarray, shape (ns, nt), optional
@@ -728,21 +735,25 @@ def entropic_partial_wasserstein(a, b, M, reg, m=None, numItermax=1000,
728735
The function considers the following problem:
729736
730737
.. math::
731-
\gamma = \mathop{\arg \min}_\gamma \quad \langle \gamma, \mathbf{M} \rangle_F + \mathrm{reg} \cdot\Omega(\gamma)
738+
\gamma = \mathop{\arg \min}_\gamma \quad \langle \gamma,
739+
\mathbf{M} \rangle_F + \mathrm{reg} \cdot\Omega(\gamma)
732740
733741
s.t. \gamma \mathbf{1} &\leq \mathbf{a} \\
734742
\gamma^T \mathbf{1} &\leq \mathbf{b} \\
735743
\gamma &\geq 0 \\
736-
\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\} \\
744+
\mathbf{1}^T \gamma^T \mathbf{1} = m
745+
&\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\} \\
737746
738747
where :
739748
740749
- :math:`\mathbf{M}` is the metric cost matrix
741-
- :math:`\Omega` is the entropic regularization term, :math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
750+
- :math:`\Omega` is the entropic regularization term,
751+
:math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
742752
- :math:`\mathbf{a}` and :math:`\mathbf{b}` are the sample weights
743753
- `m` is the amount of mass to be transported
744754
745-
The formulation of the problem has been proposed in :ref:`[3] <references-entropic-partial-wasserstein>` (prop. 5)
755+
The formulation of the problem has been proposed in
756+
:ref:`[3] <references-entropic-partial-wasserstein>` (prop. 5)
746757
747758
748759
Parameters
@@ -829,12 +840,23 @@ def entropic_partial_wasserstein(a, b, M, reg, m=None, numItermax=1000,
829840
np.multiply(K, m / np.sum(K), out=K)
830841

831842
err, cpt = 1, 0
843+
q1 = np.ones(K.shape)
844+
q2 = np.ones(K.shape)
845+
q3 = np.ones(K.shape)
832846

833847
while (err > stopThr and cpt < numItermax):
834848
Kprev = K
849+
K = K * q1
835850
K1 = np.dot(np.diag(np.minimum(a / np.sum(K, axis=1), dx)), K)
851+
q1 = q1 * Kprev / K1
852+
K1prev = K1
853+
K1 = K1 * q2
836854
K2 = np.dot(K1, np.diag(np.minimum(b / np.sum(K1, axis=0), dy)))
855+
q2 = q2 * K1prev / K2
856+
K2prev = K2
857+
K2 = K2 * q3
837858
K = K2 * (m / np.sum(K2))
859+
q3 = q3 * K2prev / K
838860

839861
if np.any(np.isnan(K)) or np.any(np.isinf(K)):
840862
print('Warning: numerical errors at iteration', cpt)
@@ -861,7 +883,8 @@ def entropic_partial_gromov_wasserstein(C1, C2, p, q, reg, m=None, G0=None,
861883
numItermax=1000, tol=1e-7, log=False,
862884
verbose=False):
863885
r"""
864-
Returns the partial Gromov-Wasserstein transport between :math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`
886+
Returns the partial Gromov-Wasserstein transport between
887+
:math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`
865888
866889
The function solves the following optimization problem:
867890
@@ -877,18 +900,22 @@ def entropic_partial_gromov_wasserstein(C1, C2, p, q, reg, m=None, G0=None,
877900
878901
\gamma^T \mathbf{1} &\leq \mathbf{b}
879902
880-
\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
903+
\mathbf{1}^T \gamma^T \mathbf{1} = m
904+
&\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
881905
882906
where :
883907
884908
- :math:`\mathbf{C_1}` is the metric cost matrix in the source space
885909
- :math:`\mathbf{C_2}` is the metric cost matrix in the target space
886910
- :math:`\mathbf{p}` and :math:`\mathbf{q}` are the sample weights
887911
- `L`: quadratic loss function
888-
- :math:`\Omega` is the entropic regularization term, :math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
912+
- :math:`\Omega` is the entropic regularization term,
913+
:math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
889914
- `m` is the amount of mass to be transported
890915
891-
The formulation of the GW problem has been proposed in :ref:`[12] <references-entropic-partial-gromov-wassertein>` and the partial GW in :ref:`[29] <references-entropic-partial-gromov-wassertein>`
916+
The formulation of the GW problem has been proposed in
917+
:ref:`[12] <references-entropic-partial-gromov-wassertein>` and the
918+
partial GW in :ref:`[29] <references-entropic-partial-gromov-wassertein>`
892919
893920
Parameters
894921
----------
@@ -903,7 +930,8 @@ def entropic_partial_gromov_wasserstein(C1, C2, p, q, reg, m=None, G0=None,
903930
reg: float
904931
entropic regularization parameter
905932
m : float, optional
906-
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
933+
Amount of mass to be transported (default:
934+
:math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
907935
G0 : ndarray, shape (ns, nt), optional
908936
Initialisation of the transportation matrix
909937
numItermax : int, optional
@@ -1005,13 +1033,15 @@ def entropic_partial_gromov_wasserstein2(C1, C2, p, q, reg, m=None, G0=None,
10051033
numItermax=1000, tol=1e-7, log=False,
10061034
verbose=False):
10071035
r"""
1008-
Returns the partial Gromov-Wasserstein discrepancy between :math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`
1036+
Returns the partial Gromov-Wasserstein discrepancy between
1037+
:math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`
10091038
10101039
The function solves the following optimization problem:
10111040
10121041
.. math::
1013-
GW = \min_{\gamma} \quad \sum_{i,j,k,l} L(\mathbf{C_1}_{i,k}, \mathbf{C_2}_{j,l})\cdot
1014-
\gamma_{i,j}\cdot\gamma_{k,l} + \mathrm{reg} \cdot\Omega(\gamma)
1042+
GW = \min_{\gamma} \quad \sum_{i,j,k,l} L(\mathbf{C_1}_{i,k},
1043+
\mathbf{C_2}_{j,l})\cdot
1044+
\gamma_{i,j}\cdot\gamma_{k,l} + \mathrm{reg} \cdot\Omega(\gamma)
10151045
10161046
.. math::
10171047
s.t. \ \gamma &\geq 0
@@ -1028,10 +1058,13 @@ def entropic_partial_gromov_wasserstein2(C1, C2, p, q, reg, m=None, G0=None,
10281058
- :math:`\mathbf{C_2}` is the metric cost matrix in the target space
10291059
- :math:`\mathbf{p}` and :math:`\mathbf{q}` are the sample weights
10301060
- `L` : quadratic loss function
1031-
- :math:`\Omega` is the entropic regularization term, :math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
1061+
- :math:`\Omega` is the entropic regularization term,
1062+
:math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
10321063
- `m` is the amount of mass to be transported
10331064
1034-
The formulation of the GW problem has been proposed in :ref:`[12] <references-entropic-partial-gromov-wassertein2>` and the partial GW in :ref:`[29] <references-entropic-partial-gromov-wassertein2>`
1065+
The formulation of the GW problem has been proposed in
1066+
:ref:`[12] <references-entropic-partial-gromov-wassertein2>` and the
1067+
partial GW in :ref:`[29] <references-entropic-partial-gromov-wassertein2>`
10351068
10361069
10371070
Parameters
@@ -1047,7 +1080,8 @@ def entropic_partial_gromov_wasserstein2(C1, C2, p, q, reg, m=None, G0=None,
10471080
reg: float
10481081
entropic regularization parameter
10491082
m : float, optional
1050-
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
1083+
Amount of mass to be transported (default:
1084+
:math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
10511085
G0 : ndarray, shape (ns, nt), optional
10521086
Initialisation of the transportation matrix
10531087
numItermax : int, optional

0 commit comments

Comments
 (0)