From cb739f625921e7fc19113d6d758e27ac69eac24b Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 20 Mar 2018 15:05:57 +0100 Subject: add linear mapping function --- ot/da.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'ot/da.py') diff --git a/ot/da.py b/ot/da.py index c688654..63bee5a 100644 --- a/ot/da.py +++ b/ot/da.py @@ -10,6 +10,7 @@ Domain adaptation with optimal transport # License: MIT License import numpy as np +import scipy.linalg as linalg from .bregman import sinkhorn from .lp import emd @@ -633,6 +634,41 @@ def joint_OT_mapping_kernel(xs, xt, mu=1, eta=0.001, kerneltype='gaussian', return G, L +def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,log=False): + """ return OT linear operator between samples""" + + d=xs.shape[1] + + mxs=xs.mean(0,keepdims=True) + mxt=xt.mean(0,keepdims=True) + + + if ws is None: + ws=np.ones((xs.shape[0],1))/xs.shape[0] + + if wt is None: + wt=np.ones((xt.shape[0],1))/xt.shape[0] + + Cs=(xs*ws).T.dot(xs)/ws.sum()+reg*np.eye(d) + Ct=(xt*wt).T.dot(xt)/wt.sum()+reg*np.eye(d) + + + Cs12=linalg.sqrtm(Cs) + Cs_12=linalg.inv(Cs12) + + M0=linalg.sqrtm(Cs12.dot(Ct.dot(Cs12))) + + A=Cs_12.dot(M0.dot(Cs_12)).T + + b=mxt-mxs.dot(A) + + if log: + pass + else: + return A,b + + + @deprecated("The class OTDA is deprecated in 0.3.1 and will be " "removed in 0.5" "\n\tfor standard transport use class EMDTransport instead.") -- cgit v1.2.3 From 8fc9fce6c920c646ea7324ac0af54ad53e9aa1bf Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 20 Mar 2018 16:21:47 +0100 Subject: add class LinearTransport --- examples/plot_otda_linear_mapping.py | 35 ++++- ot/da.py | 239 ++++++++++++++++++++++++++++++++++- 2 files changed, 265 insertions(+), 9 deletions(-) (limited to 'ot/da.py') diff --git a/examples/plot_otda_linear_mapping.py b/examples/plot_otda_linear_mapping.py index eff2648..44aa9c5 100644 --- a/examples/plot_otda_linear_mapping.py +++ b/examples/plot_otda_linear_mapping.py @@ -9,7 +9,7 @@ Created on Tue Mar 20 14:31:15 2018 import numpy as np import pylab as pl import ot - +import scipy.linalg as linalg #%% @@ -19,11 +19,13 @@ n=1000 d=2 sigma=.1 +# source samples angles=np.random.rand(n,1)*2*np.pi xs=np.concatenate((np.sin(angles),np.cos(angles)),axis=1)+sigma*np.random.randn(n,2) - xs[:n//2,1]+=2 + +# target samples anglet=np.random.rand(n,1)*2*np.pi xt=np.concatenate((np.sin(anglet),np.cos(anglet)),axis=1)+sigma*np.random.randn(n,2) xt[:n//2,1]+=2 @@ -43,7 +45,33 @@ pl.plot(xt[:,0],xt[:,1],'o') Ae,be=ot.da.OT_mapping_linear(xs,xt) +Ae1=linalg.inv(Ae) +be1=-be.dot(Ae1) + xst=xs.dot(Ae)+be +xts=xt.dot(Ae1)+be1 + +##%% + +pl.figure(1,(5,5)) +pl.clf() +pl.plot(xs[:,0],xs[:,1],'+') +pl.plot(xt[:,0],xt[:,1],'o') +pl.plot(xst[:,0],xst[:,1],'+') +pl.plot(xts[:,0],xts[:,1],'o') + +pl.show() + + +#%% Example class with on images + +mapping=ot.da.LinearTransport() + +mapping.fit(Xs=xs,Xt=xt) + + +xst=mapping.transform(Xs=xs) +xts=mapping.inverse_transform(Xt=xt) ##%% @@ -51,4 +79,5 @@ pl.figure(1,(5,5)) pl.clf() pl.plot(xs[:,0],xs[:,1],'+') pl.plot(xt[:,0],xt[:,1],'o') -pl.plot(xst[:,0],xst[:,1],'+') \ No newline at end of file +pl.plot(xst[:,0],xst[:,1],'+') +pl.plot(xts[:,0],xts[:,1],'o') diff --git a/ot/da.py b/ot/da.py index 63bee5a..ab5f860 100644 --- a/ot/da.py +++ b/ot/da.py @@ -634,13 +634,76 @@ def joint_OT_mapping_kernel(xs, xt, mu=1, eta=0.001, kerneltype='gaussian', return G, L -def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,log=False): - """ return OT linear operator between samples""" +def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,bias=True,log=False): + """ return OT linear operator between samples + + The function estimate the optimal linear operator that align the two + empirical distributions. This is equivalent to estimating the closed + form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` + and :math:`N(\mu_t,\Sigma_t)` as proposed in [14]. + + The linear operator from source to target :math:`M` + + .. math:: + M(x)=Ax+b + + where : + + .. math:: + A=\Sigma_s^{-1/2}(\Sigma_s^{1/2}\Sigma_t\Sigma_s^{1/2})^{1/2} + \Sigma_s^{-1/2} + .. math:: + b=\mu_t-A\mu_s + + Parameters + ---------- + xs : np.ndarray (ns,d) + samples in the source domain + xt : np.ndarray (nt,d) + samples in the target domain + reg : float,optional + regularization added to the daigonals of convariances (>0) + ws : np.ndarray (ns,1), optional + weights for the source samples + wt : np.ndarray (ns,1), optional + weights for the target samples + bias: boolean, optional + estimate bias b else b=0 (default:True) + log : bool, optional + record log if True + + + Returns + ------- + A : (d x d) ndarray + Linear operator + b : (1 x d) ndarray + bias + log : dict + log dictionary return only if log==True in parameters + + + References + ---------- + + .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of + distributions", Journal of Optimization Theory and Applications + Vol 43, 1984 + + + """ d=xs.shape[1] - mxs=xs.mean(0,keepdims=True) - mxt=xt.mean(0,keepdims=True) + if bias: + mxs=xs.mean(0,keepdims=True) + mxt=xt.mean(0,keepdims=True) + + xs=xs-mxs + xt=xt-mxt + else: + mxs=np.zeros((1,d)) + mxt=np.zeros((1,d)) if ws is None: @@ -658,12 +721,17 @@ def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,log=False): M0=linalg.sqrtm(Cs12.dot(Ct.dot(Cs12))) - A=Cs_12.dot(M0.dot(Cs_12)).T + A=Cs_12.dot(M0.dot(Cs_12)) b=mxt-mxs.dot(A) if log: - pass + log={} + log['Cs']=Cs + log['Ct']=Ct + log['Cs12']=Cs12 + log['Cs_12']=Cs_12 + return A,b,log else: return A,b @@ -1216,6 +1284,165 @@ class BaseTransport(BaseEstimator): return transp_Xt +class LinearTransport(BaseTransport): + """ OT linear operator between empirical distributions + + The function estimate the optimal linear operator that align the two + empirical distributions. This is equivalent to estimating the closed + form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` + and :math:`N(\mu_t,\Sigma_t)` as proposed in [14]. + + The linear operator from source to target :math:`M` + + .. math:: + M(x)=Ax+b + + where : + + .. math:: + A=\Sigma_s^{-1/2}(\Sigma_s^{1/2}\Sigma_t\Sigma_s^{1/2})^{1/2} + \Sigma_s^{-1/2} + .. math:: + b=\mu_t-A\mu_s + + Parameters + ---------- + reg : float,optional + regularization added to the daigonals of convariances (>0) + bias: boolean, optional + estimate bias b else b=0 (default:True) + log : bool, optional + record log if True + + + """ + + def __init__(self, reg=1e-8,bias=True,log=False, + distribution_estimation=distribution_estimation_uniform): + + self.bias=bias + self.log=log + self.reg=reg + self.distribution_estimation=distribution_estimation + + def fit(self, Xs=None, ys=None, Xt=None, yt=None): + """Build a coupling matrix from source and target sets of samples + (Xs, ys) and (Xt, yt) + + Parameters + ---------- + Xs : array-like, shape (n_source_samples, n_features) + The training input samples. + ys : array-like, shape (n_source_samples,) + The class labels + Xt : array-like, shape (n_target_samples, n_features) + The training input samples. + yt : array-like, shape (n_target_samples,) + The class labels. If some target samples are unlabeled, fill the + yt's elements with -1. + + Warning: Note that, due to this convention -1 cannot be used as a + class label + + Returns + ------- + self : object + Returns self. + """ + + self.mu_s = self.distribution_estimation(Xs) + self.mu_t = self.distribution_estimation(Xt) + + + + # coupling estimation + returned_ = OT_mapping_linear(Xs,Xt,reg=self.reg, + ws=self.mu_s.reshape((-1,1)), + wt=self.mu_t.reshape((-1,1)), + bias=self.bias,log=self.log) + + # deal with the value of log + if self.log: + self.A_, self.B_, self.log_ = returned_ + else: + self.A_, self.B_, = returned_ + self.log_ = dict() + + # re compute inverse mapping + self.A1_=linalg.inv(self.A_) + self.B1_=-self.B_.dot(self.A1_) + + return self + + def transform(self, Xs=None, ys=None, Xt=None, yt=None, batch_size=128): + """Transports source samples Xs onto target ones Xt + + Parameters + ---------- + Xs : array-like, shape (n_source_samples, n_features) + The training input samples. + ys : array-like, shape (n_source_samples,) + The class labels + Xt : array-like, shape (n_target_samples, n_features) + The training input samples. + yt : array-like, shape (n_target_samples,) + The class labels. If some target samples are unlabeled, fill the + yt's elements with -1. + + Warning: Note that, due to this convention -1 cannot be used as a + class label + batch_size : int, optional (default=128) + The batch size for out of sample inverse transform + + Returns + ------- + transp_Xs : array-like, shape (n_source_samples, n_features) + The transport source samples. + """ + + # check the necessary inputs parameters are here + if check_params(Xs=Xs): + + transp_Xs= Xs.dot(self.A_)+self.B_ + + return transp_Xs + + def inverse_transform(self, Xs=None, ys=None, Xt=None, yt=None, + batch_size=128): + """Transports target samples Xt onto target samples Xs + + Parameters + ---------- + Xs : array-like, shape (n_source_samples, n_features) + The training input samples. + ys : array-like, shape (n_source_samples,) + The class labels + Xt : array-like, shape (n_target_samples, n_features) + The training input samples. + yt : array-like, shape (n_target_samples,) + The class labels. If some target samples are unlabeled, fill the + yt's elements with -1. + + Warning: Note that, due to this convention -1 cannot be used as a + class label + batch_size : int, optional (default=128) + The batch size for out of sample inverse transform + + Returns + ------- + transp_Xt : array-like, shape (n_source_samples, n_features) + The transported target samples. + """ + + # check the necessary inputs parameters are here + if check_params(Xt=Xt): + + transp_Xt= Xt.dot(self.A1_)+self.B1_ + + return transp_Xt + + + class SinkhornTransport(BaseTransport): """Domain Adapatation OT method based on Sinkhorn Algorithm -- cgit v1.2.3 From c1046238d826fe9cf1294f8ea60b8d44743fac78 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Tue, 20 Mar 2018 16:27:49 +0100 Subject: passing tests --- examples/plot_otda_linear_mapping.py | 74 +++++++++--------- ot/da.py | 147 +++++++++++++++++------------------ 2 files changed, 110 insertions(+), 111 deletions(-) (limited to 'ot/da.py') diff --git a/examples/plot_otda_linear_mapping.py b/examples/plot_otda_linear_mapping.py index 44aa9c5..143f129 100644 --- a/examples/plot_otda_linear_mapping.py +++ b/examples/plot_otda_linear_mapping.py @@ -15,69 +15,71 @@ import scipy.linalg as linalg #%% -n=1000 -d=2 -sigma=.1 +n = 1000 +d = 2 +sigma = .1 # source samples -angles=np.random.rand(n,1)*2*np.pi -xs=np.concatenate((np.sin(angles),np.cos(angles)),axis=1)+sigma*np.random.randn(n,2) -xs[:n//2,1]+=2 +angles = np.random.rand(n, 1) * 2 * np.pi +xs = np.concatenate((np.sin(angles), np.cos(angles)), + axis=1) + sigma * np.random.randn(n, 2) +xs[:n // 2, 1] += 2 # target samples -anglet=np.random.rand(n,1)*2*np.pi -xt=np.concatenate((np.sin(anglet),np.cos(anglet)),axis=1)+sigma*np.random.randn(n,2) -xt[:n//2,1]+=2 +anglet = np.random.rand(n, 1) * 2 * np.pi +xt = np.concatenate((np.sin(anglet), np.cos(anglet)), + axis=1) + sigma * np.random.randn(n, 2) +xt[:n // 2, 1] += 2 -A=np.array([[1.5,.7],[.7,1.5]]) -b=np.array([[4,2]]) -xt=xt.dot(A)+b +A = np.array([[1.5, .7], [.7, 1.5]]) +b = np.array([[4, 2]]) +xt = xt.dot(A) + b #%% -pl.figure(1,(5,5)) -pl.plot(xs[:,0],xs[:,1],'+') -pl.plot(xt[:,0],xt[:,1],'o') +pl.figure(1, (5, 5)) +pl.plot(xs[:, 0], xs[:, 1], '+') +pl.plot(xt[:, 0], xt[:, 1], 'o') #%% -Ae,be=ot.da.OT_mapping_linear(xs,xt) +Ae, be = ot.da.OT_mapping_linear(xs, xt) -Ae1=linalg.inv(Ae) -be1=-be.dot(Ae1) +Ae1 = linalg.inv(Ae) +be1 = -be.dot(Ae1) -xst=xs.dot(Ae)+be -xts=xt.dot(Ae1)+be1 +xst = xs.dot(Ae) + be +xts = xt.dot(Ae1) + be1 -##%% +# %% -pl.figure(1,(5,5)) +pl.figure(1, (5, 5)) pl.clf() -pl.plot(xs[:,0],xs[:,1],'+') -pl.plot(xt[:,0],xt[:,1],'o') -pl.plot(xst[:,0],xst[:,1],'+') -pl.plot(xts[:,0],xts[:,1],'o') +pl.plot(xs[:, 0], xs[:, 1], '+') +pl.plot(xt[:, 0], xt[:, 1], 'o') +pl.plot(xst[:, 0], xst[:, 1], '+') +pl.plot(xts[:, 0], xts[:, 1], 'o') pl.show() #%% Example class with on images -mapping=ot.da.LinearTransport() +mapping = ot.da.LinearTransport() -mapping.fit(Xs=xs,Xt=xt) +mapping.fit(Xs=xs, Xt=xt) -xst=mapping.transform(Xs=xs) -xts=mapping.inverse_transform(Xt=xt) +xst = mapping.transform(Xs=xs) +xts = mapping.inverse_transform(Xt=xt) -##%% +# %% -pl.figure(1,(5,5)) +pl.figure(1, (5, 5)) pl.clf() -pl.plot(xs[:,0],xs[:,1],'+') -pl.plot(xt[:,0],xt[:,1],'o') -pl.plot(xst[:,0],xst[:,1],'+') -pl.plot(xts[:,0],xts[:,1],'o') +pl.plot(xs[:, 0], xs[:, 1], '+') +pl.plot(xt[:, 0], xt[:, 1], 'o') +pl.plot(xst[:, 0], xst[:, 1], '+') +pl.plot(xts[:, 0], xts[:, 1], 'o') diff --git a/ot/da.py b/ot/da.py index ab5f860..f789396 100644 --- a/ot/da.py +++ b/ot/da.py @@ -357,7 +357,8 @@ def joint_OT_mapping_linear(xs, xt, mu=1, eta=0.001, bias=False, verbose=False, def loss(L, G): """Compute full loss""" - return np.sum((xs1.dot(L) - ns * G.dot(xt))**2) + mu * np.sum(G * M) + eta * np.sum(sel(L - I0)**2) + return np.sum((xs1.dot(L) - ns * G.dot(xt))**2) + mu * \ + np.sum(G * M) + eta * np.sum(sel(L - I0)**2) def solve_L(G): """ solve L problem with fixed G (least square)""" @@ -557,7 +558,8 @@ def joint_OT_mapping_kernel(xs, xt, mu=1, eta=0.001, kerneltype='gaussian', def loss(L, G): """Compute full loss""" - return np.sum((K1.dot(L) - ns * G.dot(xt))**2) + mu * np.sum(G * M) + eta * np.trace(L.T.dot(Kreg).dot(L)) + return np.sum((K1.dot(L) - ns * G.dot(xt))**2) + mu * \ + np.sum(G * M) + eta * np.trace(L.T.dot(Kreg).dot(L)) def solve_L_nobias(G): """ solve L problem with fixed G (least square)""" @@ -634,25 +636,26 @@ def joint_OT_mapping_kernel(xs, xt, mu=1, eta=0.001, kerneltype='gaussian', return G, L -def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,bias=True,log=False): +def OT_mapping_linear(xs, xt, reg=1e-6, ws=None, + wt=None, bias=True, log=False): """ return OT linear operator between samples The function estimate the optimal linear operator that align the two - empirical distributions. This is equivalent to estimating the closed - form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` + empirical distributions. This is equivalent to estimating the closed + form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` and :math:`N(\mu_t,\Sigma_t)` as proposed in [14]. - + The linear operator from source to target :math:`M` .. math:: M(x)=Ax+b - + where : - + .. math:: A=\Sigma_s^{-1/2}(\Sigma_s^{1/2}\Sigma_t\Sigma_s^{1/2})^{1/2} \Sigma_s^{-1/2} - .. math:: + .. math:: b=\mu_t-A\mu_s Parameters @@ -666,7 +669,7 @@ def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,bias=True,log=False): ws : np.ndarray (ns,1), optional weights for the source samples wt : np.ndarray (ns,1), optional - weights for the target samples + weights for the target samples bias: boolean, optional estimate bias b else b=0 (default:True) log : bool, optional @@ -686,55 +689,52 @@ def OT_mapping_linear(xs, xt, reg=1e-6,ws=None,wt=None,bias=True,log=False): References ---------- - .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of + .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of distributions", Journal of Optimization Theory and Applications Vol 43, 1984 """ - d=xs.shape[1] - + d = xs.shape[1] + if bias: - mxs=xs.mean(0,keepdims=True) - mxt=xt.mean(0,keepdims=True) - - xs=xs-mxs - xt=xt-mxt + mxs = xs.mean(0, keepdims=True) + mxt = xt.mean(0, keepdims=True) + + xs = xs - mxs + xt = xt - mxt else: - mxs=np.zeros((1,d)) - mxt=np.zeros((1,d)) + mxs = np.zeros((1, d)) + mxt = np.zeros((1, d)) - if ws is None: - ws=np.ones((xs.shape[0],1))/xs.shape[0] - + ws = np.ones((xs.shape[0], 1)) / xs.shape[0] + if wt is None: - wt=np.ones((xt.shape[0],1))/xt.shape[0] - - Cs=(xs*ws).T.dot(xs)/ws.sum()+reg*np.eye(d) - Ct=(xt*wt).T.dot(xt)/wt.sum()+reg*np.eye(d) - - - Cs12=linalg.sqrtm(Cs) - Cs_12=linalg.inv(Cs12) - - M0=linalg.sqrtm(Cs12.dot(Ct.dot(Cs12))) - - A=Cs_12.dot(M0.dot(Cs_12)) - - b=mxt-mxs.dot(A) - + wt = np.ones((xt.shape[0], 1)) / xt.shape[0] + + Cs = (xs * ws).T.dot(xs) / ws.sum() + reg * np.eye(d) + Ct = (xt * wt).T.dot(xt) / wt.sum() + reg * np.eye(d) + + Cs12 = linalg.sqrtm(Cs) + Cs_12 = linalg.inv(Cs12) + + M0 = linalg.sqrtm(Cs12.dot(Ct.dot(Cs12))) + + A = Cs_12.dot(M0.dot(Cs_12)) + + b = mxt - mxs.dot(A) + if log: - log={} - log['Cs']=Cs - log['Ct']=Ct - log['Cs12']=Cs12 - log['Cs_12']=Cs_12 - return A,b,log + log = {} + log['Cs'] = Cs + log['Ct'] = Ct + log['Cs12'] = Cs12 + log['Cs_12'] = Cs_12 + return A, b, log else: - return A,b - + return A, b @deprecated("The class OTDA is deprecated in 0.3.1 and will be " @@ -1288,42 +1288,42 @@ class LinearTransport(BaseTransport): """ OT linear operator between empirical distributions The function estimate the optimal linear operator that align the two - empirical distributions. This is equivalent to estimating the closed - form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` + empirical distributions. This is equivalent to estimating the closed + form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` and :math:`N(\mu_t,\Sigma_t)` as proposed in [14]. - + The linear operator from source to target :math:`M` .. math:: M(x)=Ax+b - + where : - + .. math:: A=\Sigma_s^{-1/2}(\Sigma_s^{1/2}\Sigma_t\Sigma_s^{1/2})^{1/2} \Sigma_s^{-1/2} - .. math:: + .. math:: b=\mu_t-A\mu_s Parameters ---------- reg : float,optional - regularization added to the daigonals of convariances (>0) + regularization added to the daigonals of convariances (>0) bias: boolean, optional estimate bias b else b=0 (default:True) log : bool, optional record log if True - - + + """ - - def __init__(self, reg=1e-8,bias=True,log=False, + + def __init__(self, reg=1e-8, bias=True, log=False, distribution_estimation=distribution_estimation_uniform): - - self.bias=bias - self.log=log - self.reg=reg - self.distribution_estimation=distribution_estimation + + self.bias = bias + self.log = log + self.reg = reg + self.distribution_estimation = distribution_estimation def fit(self, Xs=None, ys=None, Xt=None, yt=None): """Build a coupling matrix from source and target sets of samples @@ -1349,17 +1349,15 @@ class LinearTransport(BaseTransport): self : object Returns self. """ - + self.mu_s = self.distribution_estimation(Xs) self.mu_t = self.distribution_estimation(Xt) - - # coupling estimation - returned_ = OT_mapping_linear(Xs,Xt,reg=self.reg, - ws=self.mu_s.reshape((-1,1)), - wt=self.mu_t.reshape((-1,1)), - bias=self.bias,log=self.log) + returned_ = OT_mapping_linear(Xs, Xt, reg=self.reg, + ws=self.mu_s.reshape((-1, 1)), + wt=self.mu_t.reshape((-1, 1)), + bias=self.bias, log=self.log) # deal with the value of log if self.log: @@ -1367,10 +1365,10 @@ class LinearTransport(BaseTransport): else: self.A_, self.B_, = returned_ self.log_ = dict() - + # re compute inverse mapping - self.A1_=linalg.inv(self.A_) - self.B1_=-self.B_.dot(self.A1_) + self.A1_ = linalg.inv(self.A_) + self.B1_ = -self.B_.dot(self.A1_) return self @@ -1403,7 +1401,7 @@ class LinearTransport(BaseTransport): # check the necessary inputs parameters are here if check_params(Xs=Xs): - transp_Xs= Xs.dot(self.A_)+self.B_ + transp_Xs = Xs.dot(self.A_) + self.B_ return transp_Xs @@ -1437,12 +1435,11 @@ class LinearTransport(BaseTransport): # check the necessary inputs parameters are here if check_params(Xt=Xt): - transp_Xt= Xt.dot(self.A1_)+self.B1_ + transp_Xt = Xt.dot(self.A1_) + self.B1_ return transp_Xt - class SinkhornTransport(BaseTransport): """Domain Adapatation OT method based on Sinkhorn Algorithm -- cgit v1.2.3 From 1262563ef24c9ab0213f616ef01e1c80eb977176 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 21 Mar 2018 10:50:16 +0100 Subject: update readme + doc --- ot/da.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'ot/da.py') diff --git a/ot/da.py b/ot/da.py index f789396..5d62d43 100644 --- a/ot/da.py +++ b/ot/da.py @@ -643,7 +643,7 @@ def OT_mapping_linear(xs, xt, reg=1e-6, ws=None, The function estimate the optimal linear operator that align the two empirical distributions. This is equivalent to estimating the closed form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` - and :math:`N(\mu_t,\Sigma_t)` as proposed in [14]. + and :math:`N(\mu_t,\Sigma_t)` as proposed in [14] and discussed in remark 2.29 in [15]. The linear operator from source to target :math:`M` @@ -692,6 +692,9 @@ def OT_mapping_linear(xs, xt, reg=1e-6, ws=None, .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of distributions", Journal of Optimization Theory and Applications Vol 43, 1984 + + .. [15] Peyré, G., & Cuturi, M. (2017). "Computational Optimal + Transport", 2018. """ @@ -1290,7 +1293,8 @@ class LinearTransport(BaseTransport): The function estimate the optimal linear operator that align the two empirical distributions. This is equivalent to estimating the closed form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` - and :math:`N(\mu_t,\Sigma_t)` as proposed in [14]. + and :math:`N(\mu_t,\Sigma_t)` as proposed in [14] and discussed in + remark 2.29 in [15]. The linear operator from source to target :math:`M` @@ -1314,6 +1318,15 @@ class LinearTransport(BaseTransport): log : bool, optional record log if True + References + ---------- + + .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of + distributions", Journal of Optimization Theory and Applications + Vol 43, 1984 + + .. [15] Peyré, G., & Cuturi, M. (2017). "Computational Optimal + Transport", 2018. """ -- cgit v1.2.3 From 83c706cb6b1c9eb6ca033c58532b85c13b5d40f2 Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 21 Mar 2018 10:54:00 +0100 Subject: pep cleanup --- ot/da.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ot/da.py') diff --git a/ot/da.py b/ot/da.py index 5d62d43..cdebc91 100644 --- a/ot/da.py +++ b/ot/da.py @@ -692,8 +692,8 @@ def OT_mapping_linear(xs, xt, reg=1e-6, ws=None, .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of distributions", Journal of Optimization Theory and Applications Vol 43, 1984 - - .. [15] Peyré, G., & Cuturi, M. (2017). "Computational Optimal + + .. [15] Peyré, G., & Cuturi, M. (2017). "Computational Optimal Transport", 2018. @@ -1293,7 +1293,7 @@ class LinearTransport(BaseTransport): The function estimate the optimal linear operator that align the two empirical distributions. This is equivalent to estimating the closed form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` - and :math:`N(\mu_t,\Sigma_t)` as proposed in [14] and discussed in + and :math:`N(\mu_t,\Sigma_t)` as proposed in [14] and discussed in remark 2.29 in [15]. The linear operator from source to target :math:`M` @@ -1324,8 +1324,8 @@ class LinearTransport(BaseTransport): .. [14] Knott, M. and Smith, C. S. "On the optimal mapping of distributions", Journal of Optimization Theory and Applications Vol 43, 1984 - - .. [15] Peyré, G., & Cuturi, M. (2017). "Computational Optimal + + .. [15] Peyré, G., & Cuturi, M. (2017). "Computational Optimal Transport", 2018. """ -- cgit v1.2.3 From 0496e2b1b2c2f4ea2d7f313ccf58c612efaa70bf Mon Sep 17 00:00:00 2001 From: Rémi Flamary Date: Wed, 9 May 2018 13:12:06 +0200 Subject: doc typos in linear map function --- ot/da.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ot/da.py') diff --git a/ot/da.py b/ot/da.py index cdebc91..b83d67e 100644 --- a/ot/da.py +++ b/ot/da.py @@ -640,9 +640,9 @@ def OT_mapping_linear(xs, xt, reg=1e-6, ws=None, wt=None, bias=True, log=False): """ return OT linear operator between samples - The function estimate the optimal linear operator that align the two + The function estimates the optimal linear operator that aligns the two empirical distributions. This is equivalent to estimating the closed - form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` + form mapping between two Gaussian distributions :math:`N(\mu_s,\Sigma_s)` and :math:`N(\mu_t,\Sigma_t)` as proposed in [14] and discussed in remark 2.29 in [15]. The linear operator from source to target :math:`M` @@ -665,7 +665,7 @@ def OT_mapping_linear(xs, xt, reg=1e-6, ws=None, xt : np.ndarray (nt,d) samples in the target domain reg : float,optional - regularization added to the daigonals of convariances (>0) + regularization added to the diagonals of convariances (>0) ws : np.ndarray (ns,1), optional weights for the source samples wt : np.ndarray (ns,1), optional @@ -1290,9 +1290,9 @@ class BaseTransport(BaseEstimator): class LinearTransport(BaseTransport): """ OT linear operator between empirical distributions - The function estimate the optimal linear operator that align the two + The function estimates the optimal linear operator that aligns the two empirical distributions. This is equivalent to estimating the closed - form mapping between two Gaussian distribution :math:`N(\mu_s,\Sigma_s)` + form mapping between two Gaussian distributions :math:`N(\mu_s,\Sigma_s)` and :math:`N(\mu_t,\Sigma_t)` as proposed in [14] and discussed in remark 2.29 in [15]. -- cgit v1.2.3