def sinkhorn(a, b, C, reg=0.1, method='sinkhorn', maxIter=1000, tau=1000.0, stopThr=1e-09, verbose=True, log=True, warm_start=None, eval_freq=10, print_freq=200, **kwargs):
    "\n    Solve the entropic regularization optimal transport\n    The input should be PyTorch tensors\n    The function solves the following optimization problem:\n\n    .. math::\n        \\gamma = arg\\min_\\gamma <\\gamma,C>_F + reg\\cdot\\Omega(\\gamma)\n        s.t. \\gamma 1 = a\n             \\gamma^T 1= b\n             \\gamma\\geq 0\n    where :\n    - C is the (ns,nt) metric cost matrix\n    - :math:`\\Omega` is the entropic regularization term :math:`\\Omega(\\gamma)=\\sum_{i,j} \\gamma_{i,j}\\log(\\gamma_{i,j})`\n    - a and b are target and source measures (sum to 1)\n    The algorithm used for solving the problem is the Sinkhorn-Knopp matrix scaling algorithm as proposed in [1].\n\n    Parameters\n    ----------\n    a : torch.tensor (na,)\n        samples measure in the target domain\n    b : torch.tensor (nb,)\n        samples in the source domain\n    C : torch.tensor (na,nb)\n        loss matrix\n    reg : float\n        Regularization term > 0\n    method : str\n        method used for the solver either 'sinkhorn', 'greenkhorn', 'sinkhorn_stabilized' or\n        'sinkhorn_epsilon_scaling', see those function for specific parameters\n    maxIter : int, optional\n        Max number of iterations\n    stopThr : float, optional\n        Stop threshol on error ( > 0 )\n    verbose : bool, optional\n        Print information along iterations\n    log : bool, optional\n        record log if True\n\n    Returns\n    -------\n    gamma : (na x nb) torch.tensor\n        Optimal transportation matrix for the given parameters\n    log : dict\n        log dictionary return only if log==True in parameters\n\n    References\n    ----------\n    [1] M. Cuturi, Sinkhorn Distances : Lightspeed Computation of Optimal Transport, Advances in Neural Information Processing Systems (NIPS) 26, 2013\n    See Also\n    --------\n\n    "
    if (method.lower() == 'sinkhorn'):
        return sinkhorn_knopp(a, b, C, reg, maxIter=maxIter, stopThr=stopThr, verbose=verbose, log=log, warm_start=warm_start, eval_freq=eval_freq, print_freq=print_freq, **kwargs)
    elif (method.lower() == 'sinkhorn_stabilized'):
        return sinkhorn_stabilized(a, b, C, reg, maxIter=maxIter, tau=tau, stopThr=stopThr, verbose=verbose, log=log, warm_start=warm_start, eval_freq=eval_freq, print_freq=print_freq, **kwargs)
    elif (method.lower() == 'sinkhorn_epsilon_scaling'):
        return sinkhorn_epsilon_scaling(a, b, C, reg, maxIter=maxIter, maxInnerIter=100, tau=tau, scaling_base=0.75, scaling_coef=None, stopThr=stopThr, verbose=False, log=log, warm_start=warm_start, eval_freq=eval_freq, print_freq=print_freq, **kwargs)
    else:
        raise ValueError(("Unknown method '%s'." % method))
Solve the entropic regularization optimal transport
The input should be PyTorch tensors
The function solves the following optimization problem:

.. math::
    \gamma = arg\min_\gamma <\gamma,C>_F + reg\cdot\Omega(\gamma)
    s.t. \gamma 1 = a
         \gamma^T 1= b
         \gamma\geq 0
where :
- C is the (ns,nt) metric cost matrix
- :math:`\Omega` is the entropic regularization term :math:`\Omega(\gamma)=\sum_{i,j} \gamma_{i,j}\log(\gamma_{i,j})`
- a and b are target and source measures (sum to 1)
The algorithm used for solving the problem is the Sinkhorn-Knopp matrix scaling algorithm as proposed in [1].

Parameters
----------
a : torch.tensor (na,)
    samples measure in the target domain
b : torch.tensor (nb,)
    samples in the source domain
C : torch.tensor (na,nb)
    loss matrix
reg : float
    Regularization term > 0
method : str
    method used for the solver either 'sinkhorn', 'greenkhorn', 'sinkhorn_stabilized' or
    'sinkhorn_epsilon_scaling', see those function for specific parameters
maxIter : int, optional
    Max number of iterations
stopThr : float, optional
    Stop threshol on error ( > 0 )
verbose : bool, optional
    Print information along iterations
log : bool, optional
    record log if True

Returns
-------
gamma : (na x nb) torch.tensor
    Optimal transportation matrix for the given parameters
log : dict
    log dictionary return only if log==True in parameters

References
----------
[1] M. Cuturi, Sinkhorn Distances : Lightspeed Computation of Optimal Transport, Advances in Neural Information Processing Systems (NIPS) 26, 2013
See Also
--------
def sinkhorn(a, b, C, reg=0.1, method='sinkhorn', maxIter=1000, tau=1000.0, stopThr=1e-09, verbose=True, log=True, warm_start=None, eval_freq=10, print_freq=200, **kwargs):
    "\n    Solve the entropic regularization optimal transport\n    The input should be PyTorch tensors\n    The function solves the following optimization problem:\n\n    .. math::\n        \\gamma = arg\\min_\\gamma <\\gamma,C>_F + reg\\cdot\\Omega(\\gamma)\n        s.t. \\gamma 1 = a\n             \\gamma^T 1= b\n             \\gamma\\geq 0\n    where :\n    - C is the (ns,nt) metric cost matrix\n    - :math:`\\Omega` is the entropic regularization term :math:`\\Omega(\\gamma)=\\sum_{i,j} \\gamma_{i,j}\\log(\\gamma_{i,j})`\n    - a and b are target and source measures (sum to 1)\n    The algorithm used for solving the problem is the Sinkhorn-Knopp matrix scaling algorithm as proposed in [1].\n\n    Parameters\n    ----------\n    a : torch.tensor (na,)\n        samples measure in the target domain\n    b : torch.tensor (nb,)\n        samples in the source domain\n    C : torch.tensor (na,nb)\n        loss matrix\n    reg : float\n        Regularization term > 0\n    method : str\n        method used for the solver either 'sinkhorn', 'greenkhorn', 'sinkhorn_stabilized' or\n        'sinkhorn_epsilon_scaling', see those function for specific parameters\n    maxIter : int, optional\n        Max number of iterations\n    stopThr : float, optional\n        Stop threshol on error ( > 0 )\n    verbose : bool, optional\n        Print information along iterations\n    log : bool, optional\n        record log if True\n\n    Returns\n    -------\n    gamma : (na x nb) torch.tensor\n        Optimal transportation matrix for the given parameters\n    log : dict\n        log dictionary return only if log==True in parameters\n\n    References\n    ----------\n    [1] M. Cuturi, Sinkhorn Distances : Lightspeed Computation of Optimal Transport, Advances in Neural Information Processing Systems (NIPS) 26, 2013\n    See Also\n    --------\n\n    "
    if (method.lower() == 'sinkhorn'):
        return sinkhorn_knopp(a, b, C, reg, maxIter=maxIter, stopThr=stopThr, verbose=verbose, log=log, warm_start=warm_start, eval_freq=eval_freq, print_freq=print_freq, **kwargs)
    elif (method.lower() == 'sinkhorn_stabilized'):
        return sinkhorn_stabilized(a, b, C, reg, maxIter=maxIter, tau=tau, stopThr=stopThr, verbose=verbose, log=log, warm_start=warm_start, eval_freq=eval_freq, print_freq=print_freq, **kwargs)
    elif (method.lower() == 'sinkhorn_epsilon_scaling'):
        return sinkhorn_epsilon_scaling(a, b, C, reg, maxIter=maxIter, maxInnerIter=100, tau=tau, scaling_base=0.75, scaling_coef=None, stopThr=stopThr, verbose=False, log=log, warm_start=warm_start, eval_freq=eval_freq, print_freq=print_freq, **kwargs)
    else:
        raise ValueError(("Unknown method '%s'." % method))