# -*- coding: utf-8 -*- """ Bregman projection for regularized Otimal transport """ import numpy as np def sinkhorn(a,b, M, reg,numItermax = 1000,stopThr=1e-9): """ Solve the entropic regularization optimal transport problem and return the OT matrix The function solves the following optimization problem: .. math:: \gamma = arg\min_\gamma <\gamma,M>_F + reg\cdot\Omega(\gamma) s.t. \gamma 1 = a \gamma^T 1= b \gamma\geq 0 where : - M 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 source and target weights (sum to 1) The algorithm used for solving the problem is the Sinkhorn-Knopp matrix scaling algorithm as proposed in [1]_ Parameters ---------- a : np.ndarray (ns,) samples weights in the source domain b : np.ndarray (nt,) samples in the target domain M : np.ndarray (ns,nt) loss matrix reg: float() Regularization term >0 Returns ------- gamma: (ns x nt) ndarray Optimal transportation matrix for the given parameters References ---------- .. [1] M. Cuturi, Sinkhorn Distances : Lightspeed Computation of Optimal Transport, Advances in Neural Information Processing Systems (NIPS) 26, 2013 See Also -------- ot.emd.emd : Unregularized optimal ransport """ # init data Nini = len(a) Nfin = len(b) cpt = 0 # we assume that no distances are null except those of the diagonal of distances u = np.ones(Nini)/Nini v = np.ones(Nfin)/Nfin uprev=np.zeros(Nini) vprev=np.zeros(Nini) #print reg K = np.exp(-M/reg) #print np.min(K) Kp = np.dot(np.diag(1/a),K) transp = K cpt = 0 err=1 while (err>stopThr and cpttol_error and cpttol_error and cpt