# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.


import itertools
import numpy as np



from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
    raise RuntimeError("Python 2.7 or later required")

# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _wasserstein
else:
    import _wasserstein

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

_swig_new_instance_method = _wasserstein.SWIG_PyInstanceMethod_New
_swig_new_static_method = _wasserstein.SWIG_PyStaticMethod_New

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "thisown":
            self.this.own(value)
        elif name == "this":
            set(self, name, value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


class SwigPyIterator(object):
    r"""Proxy of C++ swig::SwigPyIterator class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _wasserstein.delete_SwigPyIterator
    value = _swig_new_instance_method(_wasserstein.SwigPyIterator_value)
    incr = _swig_new_instance_method(_wasserstein.SwigPyIterator_incr)
    decr = _swig_new_instance_method(_wasserstein.SwigPyIterator_decr)
    distance = _swig_new_instance_method(_wasserstein.SwigPyIterator_distance)
    equal = _swig_new_instance_method(_wasserstein.SwigPyIterator_equal)
    copy = _swig_new_instance_method(_wasserstein.SwigPyIterator_copy)
    next = _swig_new_instance_method(_wasserstein.SwigPyIterator_next)
    __next__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___next__)
    previous = _swig_new_instance_method(_wasserstein.SwigPyIterator_previous)
    advance = _swig_new_instance_method(_wasserstein.SwigPyIterator_advance)
    __eq__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___eq__)
    __ne__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___ne__)
    __iadd__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___iadd__)
    __isub__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___isub__)
    __add__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___add__)
    __sub__ = _swig_new_instance_method(_wasserstein.SwigPyIterator___sub__)
    def __iter__(self):
        return self

# Register SwigPyIterator in _wasserstein:
_wasserstein.SwigPyIterator_swigregister(SwigPyIterator)

class vectorDouble(object):
    r"""Proxy of C++ std::vector< double > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    iterator = _swig_new_instance_method(_wasserstein.vectorDouble_iterator)
    def __iter__(self):
        return self.iterator()
    __nonzero__ = _swig_new_instance_method(_wasserstein.vectorDouble___nonzero__)
    __bool__ = _swig_new_instance_method(_wasserstein.vectorDouble___bool__)
    __len__ = _swig_new_instance_method(_wasserstein.vectorDouble___len__)
    __getslice__ = _swig_new_instance_method(_wasserstein.vectorDouble___getslice__)
    __setslice__ = _swig_new_instance_method(_wasserstein.vectorDouble___setslice__)
    __delslice__ = _swig_new_instance_method(_wasserstein.vectorDouble___delslice__)
    __delitem__ = _swig_new_instance_method(_wasserstein.vectorDouble___delitem__)
    __getitem__ = _swig_new_instance_method(_wasserstein.vectorDouble___getitem__)
    __setitem__ = _swig_new_instance_method(_wasserstein.vectorDouble___setitem__)
    pop = _swig_new_instance_method(_wasserstein.vectorDouble_pop)
    append = _swig_new_instance_method(_wasserstein.vectorDouble_append)
    empty = _swig_new_instance_method(_wasserstein.vectorDouble_empty)
    size = _swig_new_instance_method(_wasserstein.vectorDouble_size)
    swap = _swig_new_instance_method(_wasserstein.vectorDouble_swap)
    begin = _swig_new_instance_method(_wasserstein.vectorDouble_begin)
    end = _swig_new_instance_method(_wasserstein.vectorDouble_end)
    rbegin = _swig_new_instance_method(_wasserstein.vectorDouble_rbegin)
    rend = _swig_new_instance_method(_wasserstein.vectorDouble_rend)
    clear = _swig_new_instance_method(_wasserstein.vectorDouble_clear)
    get_allocator = _swig_new_instance_method(_wasserstein.vectorDouble_get_allocator)
    pop_back = _swig_new_instance_method(_wasserstein.vectorDouble_pop_back)
    erase = _swig_new_instance_method(_wasserstein.vectorDouble_erase)

    def __init__(self, *args):
        r"""
        __init__(vectorDouble self) -> vectorDouble
        __init__(vectorDouble self, vectorDouble other) -> vectorDouble
        __init__(vectorDouble self, std::vector< double >::size_type size) -> vectorDouble
        __init__(vectorDouble self, std::vector< double >::size_type size, std::vector< double >::value_type const & value) -> vectorDouble
        """
        _wasserstein.vectorDouble_swiginit(self, _wasserstein.new_vectorDouble(*args))
    push_back = _swig_new_instance_method(_wasserstein.vectorDouble_push_back)
    front = _swig_new_instance_method(_wasserstein.vectorDouble_front)
    back = _swig_new_instance_method(_wasserstein.vectorDouble_back)
    assign = _swig_new_instance_method(_wasserstein.vectorDouble_assign)
    resize = _swig_new_instance_method(_wasserstein.vectorDouble_resize)
    insert = _swig_new_instance_method(_wasserstein.vectorDouble_insert)
    reserve = _swig_new_instance_method(_wasserstein.vectorDouble_reserve)
    capacity = _swig_new_instance_method(_wasserstein.vectorDouble_capacity)
    __swig_destroy__ = _wasserstein.delete_vectorDouble

# Register vectorDouble in _wasserstein:
_wasserstein.vectorDouble_swigregister(vectorDouble)

class vectorString(object):
    r"""Proxy of C++ std::vector< std::string > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr
    iterator = _swig_new_instance_method(_wasserstein.vectorString_iterator)
    def __iter__(self):
        return self.iterator()
    __nonzero__ = _swig_new_instance_method(_wasserstein.vectorString___nonzero__)
    __bool__ = _swig_new_instance_method(_wasserstein.vectorString___bool__)
    __len__ = _swig_new_instance_method(_wasserstein.vectorString___len__)
    __getslice__ = _swig_new_instance_method(_wasserstein.vectorString___getslice__)
    __setslice__ = _swig_new_instance_method(_wasserstein.vectorString___setslice__)
    __delslice__ = _swig_new_instance_method(_wasserstein.vectorString___delslice__)
    __delitem__ = _swig_new_instance_method(_wasserstein.vectorString___delitem__)
    __getitem__ = _swig_new_instance_method(_wasserstein.vectorString___getitem__)
    __setitem__ = _swig_new_instance_method(_wasserstein.vectorString___setitem__)
    pop = _swig_new_instance_method(_wasserstein.vectorString_pop)
    append = _swig_new_instance_method(_wasserstein.vectorString_append)
    empty = _swig_new_instance_method(_wasserstein.vectorString_empty)
    size = _swig_new_instance_method(_wasserstein.vectorString_size)
    swap = _swig_new_instance_method(_wasserstein.vectorString_swap)
    begin = _swig_new_instance_method(_wasserstein.vectorString_begin)
    end = _swig_new_instance_method(_wasserstein.vectorString_end)
    rbegin = _swig_new_instance_method(_wasserstein.vectorString_rbegin)
    rend = _swig_new_instance_method(_wasserstein.vectorString_rend)
    clear = _swig_new_instance_method(_wasserstein.vectorString_clear)
    get_allocator = _swig_new_instance_method(_wasserstein.vectorString_get_allocator)
    pop_back = _swig_new_instance_method(_wasserstein.vectorString_pop_back)
    erase = _swig_new_instance_method(_wasserstein.vectorString_erase)

    def __init__(self, *args):
        r"""
        __init__(vectorString self) -> vectorString
        __init__(vectorString self, vectorString other) -> vectorString
        __init__(vectorString self, std::vector< std::string >::size_type size) -> vectorString
        __init__(vectorString self, std::vector< std::string >::size_type size, std::vector< std::string >::value_type const & value) -> vectorString
        """
        _wasserstein.vectorString_swiginit(self, _wasserstein.new_vectorString(*args))
    push_back = _swig_new_instance_method(_wasserstein.vectorString_push_back)
    front = _swig_new_instance_method(_wasserstein.vectorString_front)
    back = _swig_new_instance_method(_wasserstein.vectorString_back)
    assign = _swig_new_instance_method(_wasserstein.vectorString_assign)
    resize = _swig_new_instance_method(_wasserstein.vectorString_resize)
    insert = _swig_new_instance_method(_wasserstein.vectorString_insert)
    reserve = _swig_new_instance_method(_wasserstein.vectorString_reserve)
    capacity = _swig_new_instance_method(_wasserstein.vectorString_capacity)
    __swig_destroy__ = _wasserstein.delete_vectorString

# Register vectorString in _wasserstein:
_wasserstein.vectorString_swigregister(vectorString)

class pairVectorDouble(object):
    r"""Proxy of C++ std::pair< std::vector< double >,std::vector< double > > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(pairVectorDouble self) -> pairVectorDouble
        __init__(pairVectorDouble self, vectorDouble first, vectorDouble second) -> pairVectorDouble
        __init__(pairVectorDouble self, pairVectorDouble other) -> pairVectorDouble
        """
        _wasserstein.pairVectorDouble_swiginit(self, _wasserstein.new_pairVectorDouble(*args))
    first = property(_wasserstein.pairVectorDouble_first_get, _wasserstein.pairVectorDouble_first_set, doc=r"""first : std::vector<(double,std::allocator<(double)>)>""")
    second = property(_wasserstein.pairVectorDouble_second_get, _wasserstein.pairVectorDouble_second_set, doc=r"""second : std::vector<(double,std::allocator<(double)>)>""")
    def __len__(self):
        return 2
    def __repr__(self):
        return str((self.first, self.second))
    def __getitem__(self, index): 
        if not (index % 2):
            return self.first
        else:
            return self.second
    def __setitem__(self, index, val):
        if not (index % 2):
            self.first = val
        else:
            self.second = val
    __swig_destroy__ = _wasserstein.delete_pairVectorDouble

# Register pairVectorDouble in _wasserstein:
_wasserstein.pairVectorDouble_swigregister(pairVectorDouble)

EMDStatus_Success = _wasserstein.EMDStatus_Success

EMDStatus_Empty = _wasserstein.EMDStatus_Empty

EMDStatus_SupplyMismatch = _wasserstein.EMDStatus_SupplyMismatch

EMDStatus_Unbounded = _wasserstein.EMDStatus_Unbounded

EMDStatus_MaxIterReached = _wasserstein.EMDStatus_MaxIterReached

EMDStatus_Infeasible = _wasserstein.EMDStatus_Infeasible

ExtraParticle_Neither = _wasserstein.ExtraParticle_Neither

ExtraParticle_Zero = _wasserstein.ExtraParticle_Zero

ExtraParticle_One = _wasserstein.ExtraParticle_One

phi_fix = _wasserstein.phi_fix
check_emd_status = _wasserstein.check_emd_status
class ExternalEMDHandler(object):
    r"""Proxy of C++ emd::ExternalEMDHandler class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _wasserstein.delete_ExternalEMDHandler
    description = _swig_new_instance_method(_wasserstein.ExternalEMDHandler_description)
    __call__ = _swig_new_instance_method(_wasserstein.ExternalEMDHandler___call__)
    num_calls = _swig_new_instance_method(_wasserstein.ExternalEMDHandler_num_calls)

# Register ExternalEMDHandler in _wasserstein:
_wasserstein.ExternalEMDHandler_swigregister(ExternalEMDHandler)
cvar = _wasserstein.cvar
PI = cvar.PI
TWOPI = cvar.TWOPI

class EMDBaseDouble(object):
    r"""Proxy of C++ emd::EMDBase< double > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, norm=False, do_timing=False, external_dists=False):
        r"""__init__(EMDBaseDouble self, bool norm=False, bool do_timing=False, bool external_dists=False) -> EMDBaseDouble"""
        _wasserstein.EMDBaseDouble_swiginit(self, _wasserstein.new_EMDBaseDouble(norm, do_timing, external_dists))
    __swig_destroy__ = _wasserstein.delete_EMDBaseDouble
    norm = _swig_new_instance_method(_wasserstein.EMDBaseDouble_norm)
    set_norm = _swig_new_instance_method(_wasserstein.EMDBaseDouble_set_norm)
    do_timing = _swig_new_instance_method(_wasserstein.EMDBaseDouble_do_timing)
    set_do_timing = _swig_new_instance_method(_wasserstein.EMDBaseDouble_set_do_timing)
    external_dists = _swig_new_instance_method(_wasserstein.EMDBaseDouble_external_dists)
    set_external_dists = _swig_new_instance_method(_wasserstein.EMDBaseDouble_set_external_dists)
    n0 = _swig_new_instance_method(_wasserstein.EMDBaseDouble_n0)
    n1 = _swig_new_instance_method(_wasserstein.EMDBaseDouble_n1)
    extra = _swig_new_instance_method(_wasserstein.EMDBaseDouble_extra)
    emd = _swig_new_instance_method(_wasserstein.EMDBaseDouble_emd)
    status = _swig_new_instance_method(_wasserstein.EMDBaseDouble_status)
    weightdiff = _swig_new_instance_method(_wasserstein.EMDBaseDouble_weightdiff)
    scale = _swig_new_instance_method(_wasserstein.EMDBaseDouble_scale)
    duration = _swig_new_instance_method(_wasserstein.EMDBaseDouble_duration)

# Register EMDBaseDouble in _wasserstein:
_wasserstein.EMDBaseDouble_swigregister(EMDBaseDouble)

class Histogram1DHandler(ExternalEMDHandler):
    r"""
    Proxy of C++ emd::Histogram1DHandler< > class.
    Proxy of C++ emd::Histogram1DHandler< > class.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args):
        r"""
        __init__(Histogram1DHandler self, double axis_min, double axis_max, unsigned int nbins) -> Histogram1DHandler
        __init__(Histogram1DHandler self) -> Histogram1DHandler
        """
        _wasserstein.Histogram1DHandler_swiginit(self, _wasserstein.new_Histogram1DHandler(*args))
    __swig_destroy__ = _wasserstein.delete_Histogram1DHandler
    axis_min = _swig_new_instance_method(_wasserstein.Histogram1DHandler_axis_min)
    axis_max = _swig_new_instance_method(_wasserstein.Histogram1DHandler_axis_max)
    nbins = _swig_new_instance_method(_wasserstein.Histogram1DHandler_nbins)
    description = _swig_new_instance_method(_wasserstein.Histogram1DHandler_description)
    hist_vals_errs_vec = _swig_new_instance_method(_wasserstein.Histogram1DHandler_hist_vals_errs_vec)
    bin_centers_vec = _swig_new_instance_method(_wasserstein.Histogram1DHandler_bin_centers_vec)
    bin_edges_vec = _swig_new_instance_method(_wasserstein.Histogram1DHandler_bin_edges_vec)
    __str__ = _swig_new_instance_method(_wasserstein.Histogram1DHandler___str__)
    __repr__ = _swig_new_instance_method(_wasserstein.Histogram1DHandler___repr__)
    bin_centers = _swig_new_instance_method(_wasserstein.Histogram1DHandler_bin_centers)
    bin_edges = _swig_new_instance_method(_wasserstein.Histogram1DHandler_bin_edges)
    hist_vals_errs = _swig_new_instance_method(_wasserstein.Histogram1DHandler_hist_vals_errs)

# Register Histogram1DHandler in _wasserstein:
_wasserstein.Histogram1DHandler_swigregister(Histogram1DHandler)

class Histogram1DHandlerLog(ExternalEMDHandler):
    r"""Proxy of C++ emd::Histogram1DHandler< boost::histogram::axis::transform::log > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args):
        r"""
        __init__(Histogram1DHandlerLog self, double axis_min, double axis_max, unsigned int nbins) -> Histogram1DHandlerLog
        __init__(Histogram1DHandlerLog self) -> Histogram1DHandlerLog
        """
        _wasserstein.Histogram1DHandlerLog_swiginit(self, _wasserstein.new_Histogram1DHandlerLog(*args))
    __swig_destroy__ = _wasserstein.delete_Histogram1DHandlerLog
    axis_min = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_axis_min)
    axis_max = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_axis_max)
    nbins = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_nbins)
    description = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_description)
    hist_vals_errs_vec = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_hist_vals_errs_vec)
    bin_centers_vec = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_bin_centers_vec)
    bin_edges_vec = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_bin_edges_vec)
    __str__ = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog___str__)
    __repr__ = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog___repr__)
    bin_centers = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_bin_centers)
    bin_edges = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_bin_edges)
    hist_vals_errs = _swig_new_instance_method(_wasserstein.Histogram1DHandlerLog_hist_vals_errs)

# Register Histogram1DHandlerLog in _wasserstein:
_wasserstein.Histogram1DHandlerLog_swigregister(Histogram1DHandlerLog)

class CorrelationDimension(Histogram1DHandlerLog):
    r"""Proxy of C++ emd::CorrelationDimension class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args):
        r"""
        __init__(CorrelationDimension self, double axis_min, double axis_max, unsigned int nbins) -> CorrelationDimension
        __init__(CorrelationDimension self) -> CorrelationDimension
        """
        _wasserstein.CorrelationDimension_swiginit(self, _wasserstein.new_CorrelationDimension(*args))
    __swig_destroy__ = _wasserstein.delete_CorrelationDimension
    corrdims_vec = _swig_new_instance_method(_wasserstein.CorrelationDimension_corrdims_vec)
    corrdim_bins_vec = _swig_new_instance_method(_wasserstein.CorrelationDimension_corrdim_bins_vec)
    cumulative_vals_vars_vec = _swig_new_instance_method(_wasserstein.CorrelationDimension_cumulative_vals_vars_vec)
    __str__ = _swig_new_instance_method(_wasserstein.CorrelationDimension___str__)
    __repr__ = _swig_new_instance_method(_wasserstein.CorrelationDimension___repr__)
    corrdim_bins = _swig_new_instance_method(_wasserstein.CorrelationDimension_corrdim_bins)
    corrdims = _swig_new_instance_method(_wasserstein.CorrelationDimension_corrdims)
    cumulative_vals_vars = _swig_new_instance_method(_wasserstein.CorrelationDimension_cumulative_vals_vars)

# Register CorrelationDimension in _wasserstein:
_wasserstein.CorrelationDimension_swigregister(CorrelationDimension)

class EMD(EMDBaseDouble):
    r"""
    Proxy of C++ emd::EMD< emd::ArrayEvent< >,emd::EuclideanArrayDistance< > > class.
    Proxy of C++ emd::EMD< emd::ArrayEvent< >,emd::EuclideanArrayDistance< > > class.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, R=1, beta=1, norm=False, do_timing=False, external_dists=False, n_iter_max=100000, epsilon_large_factor=10000, epsilon_small_factor=1):
        r"""__init__(EMD self, emd::Value R=1, emd::Value beta=1, bool norm=False, bool do_timing=False, bool external_dists=False, unsigned int n_iter_max=100000, emd::Value epsilon_large_factor=10000, emd::Value epsilon_small_factor=1) -> EMD"""
        _wasserstein.EMD_swiginit(self, _wasserstein.new_EMD(R, beta, norm, do_timing, external_dists, n_iter_max, epsilon_large_factor, epsilon_small_factor))
    __swig_destroy__ = _wasserstein.delete_EMD
    R = _swig_new_instance_method(_wasserstein.EMD_R)
    beta = _swig_new_instance_method(_wasserstein.EMD_beta)
    set_R = _swig_new_instance_method(_wasserstein.EMD_set_R)
    set_beta = _swig_new_instance_method(_wasserstein.EMD_set_beta)
    set_network_simplex_params = _swig_new_instance_method(_wasserstein.EMD_set_network_simplex_params)
    description = _swig_new_instance_method(_wasserstein.EMD_description)
    clear = _swig_new_instance_method(_wasserstein.EMD_clear)
    dists_vec = _swig_new_instance_method(_wasserstein.EMD_dists_vec)
    flows_vec = _swig_new_instance_method(_wasserstein.EMD_flows_vec)
    flow = _swig_new_instance_method(_wasserstein.EMD_flow)
    __str__ = _swig_new_instance_method(_wasserstein.EMD___str__)
    __repr__ = _swig_new_instance_method(_wasserstein.EMD___repr__)
    flows = _swig_new_instance_method(_wasserstein.EMD_flows)
    dists = _swig_new_instance_method(_wasserstein.EMD_dists)
    __call__ = _swig_new_instance_method(_wasserstein.EMD___call__)

# Register EMD in _wasserstein:
_wasserstein.EMD_swigregister(EMD)

class PairwiseEMD(object):
    r"""
    Proxy of C++ emd::PairwiseEMD< emd::EMD< emd::ArrayEvent< >,emd::EuclideanArrayDistance< > > > class.
    Proxy of C++ emd::PairwiseEMD< emd::EMD< emd::ArrayEvent< >,emd::EuclideanArrayDistance< > > > class.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        r"""__init__(PairwiseEMD self, emd::Value R=1, emd::Value beta=1, bool norm=False, int num_threads=-1, long long print_every=-10, unsigned int verbose=1, bool store_sym_emds_flattened=True, bool throw_on_error=False, unsigned int n_iter_max=100000, emd::Value epsilon_large_factor=10000, emd::Value epsilon_small_factor=1, std::ostream & os=std::cout) -> PairwiseEMD"""
        _wasserstein.PairwiseEMD_swiginit(self, _wasserstein.new_PairwiseEMD(*args, **kwargs))
    __swig_destroy__ = _wasserstein.delete_PairwiseEMD
    R = _swig_new_instance_method(_wasserstein.PairwiseEMD_R)
    set_R = _swig_new_instance_method(_wasserstein.PairwiseEMD_set_R)
    beta = _swig_new_instance_method(_wasserstein.PairwiseEMD_beta)
    set_beta = _swig_new_instance_method(_wasserstein.PairwiseEMD_set_beta)
    norm = _swig_new_instance_method(_wasserstein.PairwiseEMD_norm)
    set_norm = _swig_new_instance_method(_wasserstein.PairwiseEMD_set_norm)
    set_network_simplex_params = _swig_new_instance_method(_wasserstein.PairwiseEMD_set_network_simplex_params)
    set_omp_dynamic_chunksize = _swig_new_instance_method(_wasserstein.PairwiseEMD_set_omp_dynamic_chunksize)
    omp_dynamic_chunksize = _swig_new_instance_method(_wasserstein.PairwiseEMD_omp_dynamic_chunksize)

    def set_external_emd_handler(self, handler):
        if not handler.thisown:
            raise RuntimeError('ExternalEMDHandler must own itself; perhaps it is already in use elsewhere')
        handler.thisown = 0
        _wasserstein.PairwiseEMD_set_external_emd_handler(self, handler)
        self.external_emd_handler = handler


    external_handler = _swig_new_instance_method(_wasserstein.PairwiseEMD_external_handler)
    description = _swig_new_instance_method(_wasserstein.PairwiseEMD_description)

    def clear(self):
        _wasserstein.PairwiseEMD_clear(self)
        self.event_arrs = []


    emds_vec = _swig_new_instance_method(_wasserstein.PairwiseEMD_emds_vec)
    emd = _swig_new_instance_method(_wasserstein.PairwiseEMD_emd)
    errored = _swig_new_instance_method(_wasserstein.PairwiseEMD_errored)
    error_messages = _swig_new_instance_method(_wasserstein.PairwiseEMD_error_messages)
    num_emds = _swig_new_instance_method(_wasserstein.PairwiseEMD_num_emds)
    nevA = _swig_new_instance_method(_wasserstein.PairwiseEMD_nevA)
    nevB = _swig_new_instance_method(_wasserstein.PairwiseEMD_nevB)
    duration = _swig_new_instance_method(_wasserstein.PairwiseEMD_duration)
    preprocess_back_event = _swig_new_instance_method(_wasserstein.PairwiseEMD_preprocess_back_event)
    init = _swig_new_instance_method(_wasserstein.PairwiseEMD_init)
    compute = _swig_new_instance_method(_wasserstein.PairwiseEMD_compute)
    __str__ = _swig_new_instance_method(_wasserstein.PairwiseEMD___str__)
    __repr__ = _swig_new_instance_method(_wasserstein.PairwiseEMD___repr__)
    emds = _swig_new_instance_method(_wasserstein.PairwiseEMD_emds)


        # ensure proper destruction of objects held by this instance
    def __del__(self):
        if hasattr(self, 'event_arrs'):
            del self.event_arrs
        if hasattr(self, 'external_emd_handler'):
            self.external_emd_handler.thisown = 1
            del self.external_emd_handler

    _add_event = _swig_new_instance_method(_wasserstein.PairwiseEMD__add_event)


    def __call__(self, eventsA, eventsB=None, gdim=None, mask=False):

        if eventsB is None:
            self.init(len(eventsA))
            eventsB = []
        else:
            self.init(len(eventsA), len(eventsB))

        if mask:
            R2 = self.R()*self.R()

        self.event_arrs = []
        for event in itertools.chain(eventsA, eventsB):

    # ensure event is 2d
            event = np.atleast_2d(event)

    # consider gdim
            if gdim is not None:
                event = event[:,:gdim+1]

    # consider mask
            if mask:
                event = event[np.sum(event**2, axis=1) <= R2]

    # extract weights and coords
            weights = np.ascontiguousarray(event[:,0], dtype=np.double)
            coords = np.ascontiguousarray(event[:,1:], dtype=np.double)

    # ensure that the lifetime of these arrays lasts through the computation
            self.event_arrs.append((weights, coords))

    # store individual event
            self._add_event(weights, coords)

    # run actual computation
        self.compute()


# Register PairwiseEMD in _wasserstein:
_wasserstein.PairwiseEMD_swigregister(PairwiseEMD)



