Skip to content

[MRG] MM algorithms for UOT #362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
850d116
bugfix
lchapel Oct 13, 2020
573fbd5
Merge branch 'lchapel-partial-W-and-GW'
lchapel Oct 14, 2020
2b433d1
update refs partial OT
lchapel Oct 14, 2020
bf40e97
fixes small typos in plot_partial_wass_and_gromov
lchapel Oct 14, 2020
8bfdd43
fix small bugs in partial.py
lchapel Oct 14, 2020
096b878
Merge branch 'master' of https://github.com/PythonOT/POT
lchapel Oct 14, 2020
5302f6d
update README
lchapel Oct 14, 2020
5a1c998
pep8 bugfix
lchapel Oct 14, 2020
d136c8e
modif doctest
lchapel Oct 14, 2020
dcbd1b5
fix bugtests
lchapel Oct 14, 2020
eedf08d
update on test_partial and test on the numerical precision on ot/partial
lchapel Oct 15, 2020
26a843f
resolve merge pb
lchapel Oct 20, 2020
fc7bc8d
Merge branch 'master' into master
rflamary Oct 22, 2020
02b2c72
Delete partial.py
lchapel Mar 10, 2022
e4c50d5
Merge branch 'master' of https://github.com/PythonOT/POT into PythonO…
lchapel Mar 14, 2022
96500a4
Merge branch 'PythonOT-master'
lchapel Mar 14, 2022
63601c4
Merge branch 'PythonOT:master' into master
lchapel Apr 4, 2022
a33a994
update unbalanced: mm algo+plot
lchapel Apr 8, 2022
f37bcf2
update unbalanced: mm algo+plot
lchapel Apr 8, 2022
ef0d15c
update unbalanced: mm algo+plot
lchapel Apr 8, 2022
50ebbed
Merge branch 'master' into master
rflamary Apr 8, 2022
44d799d
update unbalanced: mm algo+plot
lchapel Apr 8, 2022
ecfbbcc
Merge branch 'master' of https://github.com/lchapel/POT
lchapel Apr 8, 2022
8fa78be
update unbalanced: mm algo+plot
lchapel Apr 8, 2022
f11caf2
add test mm algo unbalanced OT
lchapel Apr 11, 2022
b944132
add test mm algo unbalanced OT
lchapel Apr 11, 2022
97282df
add test mm algo unbalanced OT
lchapel Apr 11, 2022
adf0662
add test mm algo unbalanced OT
lchapel Apr 11, 2022
49a71a0
add test mm algo unbalanced OT
lchapel Apr 11, 2022
fc37e17
add test mm algo unbalanced OT
lchapel Apr 11, 2022
915a4c6
add test mm algo unbalanced OT
lchapel Apr 11, 2022
c574874
add test mm algo unbalanced OT
lchapel Apr 11, 2022
de19311
update unbalanced: mm algo+plot
lchapel Apr 11, 2022
4251357
update unbalanced: mm algo+plot
lchapel Apr 11, 2022
8385b6d
update releases.md with new MM UOT algorithms
lchapel Apr 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ POT provides the following generic OT solvers (links to examples):
Large-scale Optimal Transport (semi-dual problem [18] and dual problem [19])
* [Sampled solver of Gromov Wasserstein](https://pythonot.github.io/auto_examples/gromov/plot_gromov.html) for large-scale problem with any loss functions [33]
* Non regularized [free support Wasserstein barycenters](https://pythonot.github.io/auto_examples/barycenters/plot_free_support_barycenter.html) [20].
* [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].
* [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]
* [Partial Wasserstein and Gromov-Wasserstein](https://pythonot.github.io/auto_examples/unbalanced-partial/plot_partial_wass_and_gromov.html) (exact [29] and entropic [3]
formulations).
* [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].
Expand Down Expand Up @@ -309,4 +309,6 @@ Dictionary Learning](https://arxiv.org/pdf/2102.06555.pdf), International Confer

[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.

[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.
[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.

[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)
1 change: 1 addition & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- Add backend support for Domain Adaptation and Unbalanced solvers (PR #343).
- Add (F)GW linear dictionary learning solvers + example (PR #319)
- Add links to related PR and Issues in the doc release page (PR #350)
- Add new minimization-maximization algorithms for solving exact Unbalanced OT + example (PR #362)

#### Closed issues

Expand Down
1 change: 1 addition & 0 deletions docs/source/all.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ API and modules
plot
stochastic
unbalanced
regpath
partial
sliced
weak
Expand Down
116 changes: 116 additions & 0 deletions examples/unbalanced-partial/plot_unbalanced_OT.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
"""
==============================================================
2D examples of exact and entropic unbalanced optimal transport
==============================================================
This example is designed to show how to compute unbalanced and
partial OT in POT.

UOT aims at solving the following optimization problem:

.. math::
W = \min_{\gamma} <\gamma, \mathbf{M}>_F +
\mathrm{reg}\cdot\Omega(\gamma) +
\mathrm{reg_m} \cdot \mathrm{div}(\gamma \mathbf{1}, \mathbf{a}) +
\mathrm{reg_m} \cdot \mathrm{div}(\gamma^T \mathbf{1}, \mathbf{b})

s.t.
\gamma \geq 0

where :math:`\mathrm{div}` is a divergence.
When using the entropic UOT, :math:`\mathrm{reg}>0` and :math:`\mathrm{div}`
should be the Kullback-Leibler divergence.
When solving exact UOT, :math:`\mathrm{reg}=0` and :math:`\mathrm{div}`
can be either the Kullback-Leibler or the quadratic divergence.
Using :math:`\ell_1` norm gives the so-called partial OT.
"""

# Author: Laetitia Chapel <laetitia.chapel@univ-ubs.fr>
# License: MIT License

import numpy as np
import matplotlib.pylab as pl
import ot

##############################################################################
# Generate data
# -------------

# %% parameters and data generation

n = 40 # nb samples

mu_s = np.array([-1, -1])
cov_s = np.array([[1, 0], [0, 1]])

mu_t = np.array([4, 4])
cov_t = np.array([[1, -.8], [-.8, 1]])

np.random.seed(0)
xs = ot.datasets.make_2D_samples_gauss(n, mu_s, cov_s)
xt = ot.datasets.make_2D_samples_gauss(n, mu_t, cov_t)

n_noise = 10

xs = np.concatenate((xs, ((np.random.rand(n_noise, 2) - 4))), axis=0)
xt = np.concatenate((xt, ((np.random.rand(n_noise, 2) + 6))), axis=0)

n = n + n_noise

a, b = np.ones((n,)) / n, np.ones((n,)) / n # uniform distribution on samples

# loss matrix
M = ot.dist(xs, xt)
M /= M.max()


##############################################################################
# Compute entropic kl-regularized UOT, kl- and l2-regularized UOT
# -----------

reg = 0.005
reg_m_kl = 0.05
reg_m_l2 = 5
mass = 0.7

entropic_kl_uot = ot.unbalanced.sinkhorn_unbalanced(a, b, M, reg, reg_m_kl)
kl_uot = ot.unbalanced.mm_unbalanced(a, b, M, reg_m_kl, div='kl')
l2_uot = ot.unbalanced.mm_unbalanced(a, b, M, reg_m_l2, div='l2')
partial_ot = ot.partial.partial_wasserstein(a, b, M, m=mass)

##############################################################################
# Plot the results
# ----------------

pl.figure(2)
transp = [partial_ot, l2_uot, kl_uot, entropic_kl_uot]
title = ["partial OT \n m=" + str(mass), "$\ell_2$-UOT \n $\mathrm{reg_m}$=" +
str(reg_m_l2), "kl-UOT \n $\mathrm{reg_m}$=" + str(reg_m_kl),
"entropic kl-UOT \n $\mathrm{reg_m}$=" + str(reg_m_kl)]

for p in range(4):
pl.subplot(2, 4, p + 1)
P = transp[p]
if P.sum() > 0:
P = P / P.max()
for i in range(n):
for j in range(n):
if P[i, j] > 0:
pl.plot([xs[i, 0], xt[j, 0]], [xs[i, 1], xt[j, 1]], color='C2',
alpha=P[i, j] * 0.3)
pl.scatter(xs[:, 0], xs[:, 1], c='C0', alpha=0.2)
pl.scatter(xt[:, 0], xt[:, 1], c='C1', alpha=0.2)
pl.scatter(xs[:, 0], xs[:, 1], c='C0', s=P.sum(1).ravel() * (1 + p) * 2)
pl.scatter(xt[:, 0], xt[:, 1], c='C1', s=P.sum(0).ravel() * (1 + p) * 2)
pl.title(title[p])
pl.yticks(())
pl.xticks(())
if p < 1:
pl.ylabel("mappings")
pl.subplot(2, 4, p + 5)
pl.imshow(P, cmap='jet')
pl.yticks(())
pl.xticks(())
if p < 1:
pl.ylabel("transport plans")
pl.show()
84 changes: 59 additions & 25 deletions ot/partial.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# License: MIT License

import numpy as np

from .lp import emd


Expand All @@ -29,7 +28,8 @@ def partial_wasserstein_lagrange(a, b, M, reg_m=None, nb_dummies=1, log=False,

\gamma &\geq 0

\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
\mathbf{1}^T \gamma^T \mathbf{1} = m &
\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}


or equivalently (see Chizat, L., Peyré, G., Schmitzer, B., & Vialard, F. X.
Expand All @@ -50,7 +50,8 @@ def partial_wasserstein_lagrange(a, b, M, reg_m=None, nb_dummies=1, log=False,
- :math:`\lambda` is the lagrangian cost. Tuning its value allows attaining
a given mass to be transported `m`

The formulation of the problem has been proposed in :ref:`[28] <references-partial-wasserstein-lagrange>`
The formulation of the problem has been proposed in
:ref:`[28] <references-partial-wasserstein-lagrange>`


Parameters
Expand Down Expand Up @@ -261,7 +262,7 @@ def partial_wasserstein(a, b, M, m=None, nb_dummies=1, log=False, **kwargs):
b_extended = np.append(b, [(np.sum(a) - m) / nb_dummies] * nb_dummies)
a_extended = np.append(a, [(np.sum(b) - m) / nb_dummies] * nb_dummies)
M_extended = np.zeros((len(a_extended), len(b_extended)))
M_extended[-nb_dummies:, -nb_dummies:] = np.max(M) * 1e5
M_extended[-nb_dummies:, -nb_dummies:] = np.max(M) * 2
M_extended[:len(a), :len(b)] = M

gamma, log_emd = emd(a_extended, b_extended, M_extended, log=True,
Expand Down Expand Up @@ -455,7 +456,8 @@ def partial_gromov_wasserstein(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
- :math:`\mathbf{a}` and :math:`\mathbf{b}` are the sample weights
- `m` is the amount of mass to be transported

The formulation of the problem has been proposed in :ref:`[29] <references-partial-gromov-wasserstein>`
The formulation of the problem has been proposed in
:ref:`[29] <references-partial-gromov-wasserstein>`


Parameters
Expand All @@ -469,7 +471,8 @@ def partial_gromov_wasserstein(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
q : ndarray, shape (nt,)
Distribution in the target space
m : float, optional
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
Amount of mass to be transported
(default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
nb_dummies : int, optional
Number of dummy points to add (avoid instabilities in the EMD solver)
G0 : ndarray, shape (ns, nt), optional
Expand Down Expand Up @@ -623,16 +626,19 @@ def partial_gromov_wasserstein2(C1, C2, p, q, m=None, nb_dummies=1, G0=None,

\gamma &\geq 0

\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
\mathbf{1}^T \gamma^T \mathbf{1} = m
&\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}

where :

- :math:`\mathbf{M}` is the metric cost matrix
- :math:`\Omega` is the entropic regularization term, :math:`\Omega(\gamma) = \sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- :math:`\Omega` is the entropic regularization term,
:math:`\Omega(\gamma) = \sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- :math:`\mathbf{a}` and :math:`\mathbf{b}` are the sample weights
- `m` is the amount of mass to be transported

The formulation of the problem has been proposed in :ref:`[29] <references-partial-gromov-wasserstein2>`
The formulation of the problem has been proposed in
:ref:`[29] <references-partial-gromov-wasserstein2>`


Parameters
Expand All @@ -646,7 +652,8 @@ def partial_gromov_wasserstein2(C1, C2, p, q, m=None, nb_dummies=1, G0=None,
q : ndarray, shape (nt,)
Distribution in the target space
m : float, optional
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
Amount of mass to be transported
(default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
nb_dummies : int, optional
Number of dummy points to add (avoid instabilities in the EMD solver)
G0 : ndarray, shape (ns, nt), optional
Expand Down Expand Up @@ -728,21 +735,25 @@ def entropic_partial_wasserstein(a, b, M, reg, m=None, numItermax=1000,
The function considers the following problem:

.. math::
\gamma = \mathop{\arg \min}_\gamma \quad \langle \gamma, \mathbf{M} \rangle_F + \mathrm{reg} \cdot\Omega(\gamma)
\gamma = \mathop{\arg \min}_\gamma \quad \langle \gamma,
\mathbf{M} \rangle_F + \mathrm{reg} \cdot\Omega(\gamma)

s.t. \gamma \mathbf{1} &\leq \mathbf{a} \\
\gamma^T \mathbf{1} &\leq \mathbf{b} \\
\gamma &\geq 0 \\
\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\} \\
\mathbf{1}^T \gamma^T \mathbf{1} = m
&\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\} \\

where :

- :math:`\mathbf{M}` is the metric cost matrix
- :math:`\Omega` is the entropic regularization term, :math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- :math:`\Omega` is the entropic regularization term,
:math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- :math:`\mathbf{a}` and :math:`\mathbf{b}` are the sample weights
- `m` is the amount of mass to be transported

The formulation of the problem has been proposed in :ref:`[3] <references-entropic-partial-wasserstein>` (prop. 5)
The formulation of the problem has been proposed in
:ref:`[3] <references-entropic-partial-wasserstein>` (prop. 5)


Parameters
Expand Down Expand Up @@ -829,12 +840,23 @@ def entropic_partial_wasserstein(a, b, M, reg, m=None, numItermax=1000,
np.multiply(K, m / np.sum(K), out=K)

err, cpt = 1, 0
q1 = np.ones(K.shape)
q2 = np.ones(K.shape)
q3 = np.ones(K.shape)

while (err > stopThr and cpt < numItermax):
Kprev = K
K = K * q1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is all this? was the implementation false? why is there so much more steps?

K1 = np.dot(np.diag(np.minimum(a / np.sum(K, axis=1), dx)), K)
q1 = q1 * Kprev / K1
K1prev = K1
K1 = K1 * q2
K2 = np.dot(K1, np.diag(np.minimum(b / np.sum(K1, axis=0), dy)))
q2 = q2 * K1prev / K2
K2prev = K2
K2 = K2 * q3
K = K2 * (m / np.sum(K2))
q3 = q3 * K2prev / K

if np.any(np.isnan(K)) or np.any(np.isinf(K)):
print('Warning: numerical errors at iteration', cpt)
Expand All @@ -861,7 +883,8 @@ def entropic_partial_gromov_wasserstein(C1, C2, p, q, reg, m=None, G0=None,
numItermax=1000, tol=1e-7, log=False,
verbose=False):
r"""
Returns the partial Gromov-Wasserstein transport between :math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`
Returns the partial Gromov-Wasserstein transport between
:math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`

The function solves the following optimization problem:

Expand All @@ -877,18 +900,22 @@ def entropic_partial_gromov_wasserstein(C1, C2, p, q, reg, m=None, G0=None,

\gamma^T \mathbf{1} &\leq \mathbf{b}

\mathbf{1}^T \gamma^T \mathbf{1} = m &\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}
\mathbf{1}^T \gamma^T \mathbf{1} = m
&\leq \min\{\|\mathbf{a}\|_1, \|\mathbf{b}\|_1\}

where :

- :math:`\mathbf{C_1}` is the metric cost matrix in the source space
- :math:`\mathbf{C_2}` is the metric cost matrix in the target space
- :math:`\mathbf{p}` and :math:`\mathbf{q}` are the sample weights
- `L`: quadratic loss function
- :math:`\Omega` is the entropic regularization term, :math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- :math:`\Omega` is the entropic regularization term,
:math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- `m` is the amount of mass to be transported

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>`
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>`

Parameters
----------
Expand All @@ -903,7 +930,8 @@ def entropic_partial_gromov_wasserstein(C1, C2, p, q, reg, m=None, G0=None,
reg: float
entropic regularization parameter
m : float, optional
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
Amount of mass to be transported (default:
:math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
G0 : ndarray, shape (ns, nt), optional
Initialisation of the transportation matrix
numItermax : int, optional
Expand Down Expand Up @@ -1005,13 +1033,15 @@ def entropic_partial_gromov_wasserstein2(C1, C2, p, q, reg, m=None, G0=None,
numItermax=1000, tol=1e-7, log=False,
verbose=False):
r"""
Returns the partial Gromov-Wasserstein discrepancy between :math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`
Returns the partial Gromov-Wasserstein discrepancy between
:math:`(\mathbf{C_1}, \mathbf{p})` and :math:`(\mathbf{C_2}, \mathbf{q})`

The function solves the following optimization problem:

.. math::
GW = \min_{\gamma} \quad \sum_{i,j,k,l} L(\mathbf{C_1}_{i,k}, \mathbf{C_2}_{j,l})\cdot
\gamma_{i,j}\cdot\gamma_{k,l} + \mathrm{reg} \cdot\Omega(\gamma)
GW = \min_{\gamma} \quad \sum_{i,j,k,l} L(\mathbf{C_1}_{i,k},
\mathbf{C_2}_{j,l})\cdot
\gamma_{i,j}\cdot\gamma_{k,l} + \mathrm{reg} \cdot\Omega(\gamma)

.. math::
s.t. \ \gamma &\geq 0
Expand All @@ -1028,10 +1058,13 @@ def entropic_partial_gromov_wasserstein2(C1, C2, p, q, reg, m=None, G0=None,
- :math:`\mathbf{C_2}` is the metric cost matrix in the target space
- :math:`\mathbf{p}` and :math:`\mathbf{q}` are the sample weights
- `L` : quadratic loss function
- :math:`\Omega` is the entropic regularization term, :math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- :math:`\Omega` is the entropic regularization term,
:math:`\Omega=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- `m` is the amount of mass to be transported

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>`
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>`


Parameters
Expand All @@ -1047,7 +1080,8 @@ def entropic_partial_gromov_wasserstein2(C1, C2, p, q, reg, m=None, G0=None,
reg: float
entropic regularization parameter
m : float, optional
Amount of mass to be transported (default: :math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
Amount of mass to be transported (default:
:math:`\min\{\|\mathbf{p}\|_1, \|\mathbf{q}\|_1\}`)
G0 : ndarray, shape (ns, nt), optional
Initialisation of the transportation matrix
numItermax : int, optional
Expand Down
Loading