Domain adaptation Classes by Slasnista · Pull Request #22 · PythonOT/POT

Here is a bit of code you can add for a simple EMD transport. I hope I have it right.
Also from what I remember, if we set log = true, the methods return the log as well. So we need an "If log statement (see code below)

class EMDTransport(BaseTransport):
    """Domain Adapatation OT method based on Earth Mover's Distance
    Parameters
    ----------
    mode : string, optional (default="unsupervised")
        The DA mode. If "unsupervised" no target labels are taken into account
        to modify the cost matrix. If "semisupervised" the target labels
        are taken into account to set coefficients of the pairwise distance
        matrix to 0 for row and columns indices that correspond to source and
        target samples which share the same labels.
    mapping : string, optional (default="barycentric")
        The kind of mapping to apply to transport samples from a domain into
        another one.
        if "barycentric" only the samples used to estimate the coupling can
        be transported from a domain to another one.
    metric : string, optional (default="sqeuclidean")
        The ground metric for the Wasserstein problem
    distribution : string, optional (default="uniform")
        The kind of distribution estimation to employ
    verbose : int, optional (default=0)
        Controls the verbosity of the optimization algorithm
    log : int, optional (default=0)
        Controls the logs of the optimization algorithm
    Attributes
    ----------
    References
    ----------
    .. [1] N. Courty; R. Flamary; D. Tuia; A. Rakotomamonjy,
           "Optimal Transport for Domain Adaptation," in IEEE Transactions
           on Pattern Analysis and Machine Intelligence , vol.PP, no.99, pp.1-1
    """

    def __init__(self, mode="unsupervised", verbose=False, 
                 log=False, metric="sqeuclidean",
                 distribution_estimation=distribution_estimation_uniform,
                 out_of_sample_map='ferradans'):

        self.mode = mode
        self.verbose = verbose
        self.log = log
        self.metric = metric
        self.distribution_estimation = distribution_estimation
        self.out_of_sample_map = out_of_sample_map

    def fit(self, Xs, 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 of shape = [n_source_samples, n_features]
            The training input samples.
        ys : array-like, shape = [n_source_samples]
            The class labels
        Xt : array-like of shape = [n_target_samples, n_features]
            The training input samples.
        yt : array-like, shape = [n_labeled_target_samples]
            The class labels
        Returns
        -------
        self : object
            Returns self.
        """

        self = super(EMDTransport, self).fit(Xs, ys, Xt, yt)

        # coupling estimation
        if self.log:
                    self.gamma_, self.log_ = emd(
                        a=self.mu_s, b=self.mu_t, M=self.Cost, 
                        verbose=self.verbose, log=self.log)
        else:
                    self.gamma_= emd(
                        a=self.mu_s, b=self.mu_t, M=self.Cost, 
                        verbose=self.verbose, log=self.log)