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

"""
pyAgrum is a Python wrapper for the C++ aGrUM library. It provides a high-level
interface to the part of agrum allowing to create, handle and make computations
into Bayesian Networks. The module is mainly generated by the SWIG
interface generator.
"""


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')
def swig_import_helper():
    import importlib
    pkg = __name__.rpartition('.')[0]
    mname = '.'.join((pkg, '_pyAgrum')).lstrip('.')
    try:
        return importlib.import_module(mname)
    except ImportError:
        return importlib.import_module('_pyAgrum')
_pyAgrum = swig_import_helper()
del swig_import_helper
del _swig_python_version_info

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
    if name == "thisown":
        return self.this.own(value)
    if name == "this":
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name, None)
    if method:
        return method(self, value)
    if not static:
        object.__setattr__(self, name, value)
    else:
        raise AttributeError("You cannot add attributes to %s" % self)


def _swig_setattr(self, class_type, name, value):
    return _swig_setattr_nondynamic(self, class_type, name, value, 0)


def _swig_getattr(self, class_type, name):
    if name == "thisown":
        return self.this.own()
    method = class_type.__swig_getmethods__.get(name, None)
    if method:
        return method(self)
    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))


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__)


import weakref

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__ = _pyAgrum.delete_SwigPyIterator

    def value(self):
        r"""value(self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator_value(self)


    def incr(self, n=1):
        r"""
        incr(self, n=1) -> SwigPyIterator
        incr(self) -> SwigPyIterator
        """
        return _pyAgrum.SwigPyIterator_incr(self, n)


    def decr(self, n=1):
        r"""
        decr(self, n=1) -> SwigPyIterator
        decr(self) -> SwigPyIterator
        """
        return _pyAgrum.SwigPyIterator_decr(self, n)


    def distance(self, x):
        r"""distance(self, x) -> ptrdiff_t"""
        return _pyAgrum.SwigPyIterator_distance(self, x)


    def equal(self, x):
        r"""equal(self, x) -> bool"""
        return _pyAgrum.SwigPyIterator_equal(self, x)


    def copy(self):
        r"""copy(self) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator_copy(self)


    def next(self):
        r"""next(self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator_next(self)


    def __next__(self):
        r"""__next__(self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator___next__(self)


    def previous(self):
        r"""previous(self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator_previous(self)


    def advance(self, n):
        r"""advance(self, n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator_advance(self, n)


    def __eq__(self, x):
        r"""__eq__(self, x) -> bool"""
        return _pyAgrum.SwigPyIterator___eq__(self, x)


    def __ne__(self, x):
        r"""__ne__(self, x) -> bool"""
        return _pyAgrum.SwigPyIterator___ne__(self, x)


    def __iadd__(self, n):
        r"""__iadd__(self, n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator___iadd__(self, n)


    def __isub__(self, n):
        r"""__isub__(self, n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator___isub__(self, n)


    def __add__(self, n):
        r"""__add__(self, n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator___add__(self, n)


    def __sub__(self, *args):
        r"""
        __sub__(self, n) -> SwigPyIterator
        __sub__(self, x) -> ptrdiff_t
        """
        return _pyAgrum.SwigPyIterator___sub__(self, *args)

    def __iter__(self):
        return self

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


import numpy

class JTGenerator(object):
    r"""

    JTGenerator is use to generate junction tree or binary junction tree from bayesian networks.

    Available constructors:
    	``JTGenerator() -> JTGenerator``

    """

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

    def junctionTree(self, *args):
        r"""
        junctionTree(self, g) -> CliqueGraph
        junctionTree(self, bn) -> CliqueGraph

        Parameters
        ----------
        g : pyAgrum.UndiGraph
        	an Undirected graph
        bn : pyAgrum.BayesNet
        	a Bayesian network

        Returns
        -------
        pyAgrum.CliqueGraph
        	the current junction tree

        """
        return _pyAgrum.JTGenerator_junctionTree(self, *args)


    def binaryJoinTree(self, *args):
        r"""
        binaryJoinTree(self, g) -> CliqueGraph
        binaryJoinTree(self, bn) -> CliqueGraph

        Parameters
        ----------
        g : pyAgrum.UndiGraph
        	an Undirected graph
        bn : pyAgrum.BayesNet
        	a Bayesian network

        Returns
        -------
        pyAgrum.CliqueGraph
        	the binary join tree

        """
        return _pyAgrum.JTGenerator_binaryJoinTree(self, *args)


    def __init__(self):
        r"""
        __init__(self) -> JTGenerator

        JTGenerator is use to generate junction tree or binary junction tree from bayesian networks.

        Available constructors:
        	``JTGenerator() -> JTGenerator``

        """
        this = _pyAgrum.new_JTGenerator()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_JTGenerator

# Register JTGenerator in _pyAgrum:
_pyAgrum.JTGenerator_swigregister(JTGenerator)

class PythonBNListener(object):
    r"""Proxy of C++ PythonBNListener 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, g, vnm):
        r"""__init__(self, g, vnm) -> PythonBNListener"""
        this = _pyAgrum.new_PythonBNListener(g, vnm)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_PythonBNListener

    def whenNodeAdded(self, source, id):
        r"""whenNodeAdded(self, source, id)"""
        return _pyAgrum.PythonBNListener_whenNodeAdded(self, source, id)


    def whenNodeDeleted(self, arg2, id):
        r"""whenNodeDeleted(self, arg2, id)"""
        return _pyAgrum.PythonBNListener_whenNodeDeleted(self, arg2, id)


    def whenArcAdded(self, arg2, src, dst):
        r"""whenArcAdded(self, arg2, src, dst)"""
        return _pyAgrum.PythonBNListener_whenArcAdded(self, arg2, src, dst)


    def whenArcDeleted(self, arg2, src, dst):
        r"""whenArcDeleted(self, arg2, src, dst)"""
        return _pyAgrum.PythonBNListener_whenArcDeleted(self, arg2, src, dst)


    def setWhenArcAdded(self, pyfunc):
        r"""
        setWhenArcAdded(self, pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenArcAdded(self, pyfunc)


    def setWhenArcDeleted(self, pyfunc):
        r"""
        setWhenArcDeleted(self, pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenArcDeleted(self, pyfunc)


    def setWhenNodeAdded(self, pyfunc):
        r"""
        setWhenNodeAdded(self, pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenNodeAdded(self, pyfunc)


    def setWhenNodeDeleted(self, pyfunc):
        r"""
        setWhenNodeDeleted(self, pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenNodeDeleted(self, pyfunc)


# Register PythonBNListener in _pyAgrum:
_pyAgrum.PythonBNListener_swigregister(PythonBNListener)

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

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

    def whenLoading(self, buffer, percent):
        r"""whenLoading(self, buffer, percent)"""
        return _pyAgrum.PythonLoadListener_whenLoading(self, buffer, percent)


    def setPythonListener(self, l):
        r"""
        setPythonListener(self, l) -> bool



        """
        return _pyAgrum.PythonLoadListener_setPythonListener(self, l)


    def __init__(self):
        r"""__init__(self) -> PythonLoadListener"""
        this = _pyAgrum.new_PythonLoadListener()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_PythonLoadListener

# Register PythonLoadListener in _pyAgrum:
_pyAgrum.PythonLoadListener_swigregister(PythonLoadListener)


def __fillLoadListeners(py_listener, l):
    r"""__fillLoadListeners(py_listener, l) -> int"""
    return _pyAgrum.__fillLoadListeners(py_listener, l)
class PythonApproximationListener(object):
    r"""

    Parameters
    ----------
    algo : IApproximationSchemeConfiguration
    	an approxmation scheme

    """

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

    def __init__(self, algo):
        r"""
        __init__(self, algo) -> PythonApproximationListener

        Parameters
        ----------
        algo : IApproximationSchemeConfiguration
        	an approxmation scheme

        """
        this = _pyAgrum.new_PythonApproximationListener(algo)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_PythonApproximationListener

    def whenProgress(self, src, step, error, duration):
        r"""whenProgress(self, src, step, error, duration)"""
        return _pyAgrum.PythonApproximationListener_whenProgress(self, src, step, error, duration)


    def whenStop(self, src, message):
        r"""whenStop(self, src, message)"""
        return _pyAgrum.PythonApproximationListener_whenStop(self, src, message)


    def setWhenProgress(self, pyfunc):
        r"""
        setWhenProgress(self, pyfunc)

        Parameters
        ----------
        pyfunc
        	the function to execute

        """
        return _pyAgrum.PythonApproximationListener_setWhenProgress(self, pyfunc)


    def setWhenStop(self, pyfunc):
        r"""
        setWhenStop(self, pyfunc)

        Parameters
        ----------
        pyfunc
        	the function to execute

        """
        return _pyAgrum.PythonApproximationListener_setWhenStop(self, pyfunc)


# Register PythonApproximationListener in _pyAgrum:
_pyAgrum.PythonApproximationListener_swigregister(PythonApproximationListener)

class PythonDatabaseGeneratorListener(object):
    r"""Proxy of C++ PythonDatabaseGeneratorListener 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, notif):
        r"""__init__(self, notif) -> PythonDatabaseGeneratorListener"""
        this = _pyAgrum.new_PythonDatabaseGeneratorListener(notif)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_PythonDatabaseGeneratorListener

    def whenProgress(self, src, step, duration):
        r"""whenProgress(self, src, step, duration)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_whenProgress(self, src, step, duration)


    def whenStop(self, src, message):
        r"""whenStop(self, src, message)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_whenStop(self, src, message)


    def setWhenProgress(self, pyfunc):
        r"""setWhenProgress(self, pyfunc)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_setWhenProgress(self, pyfunc)


    def setWhenStop(self, pyfunc):
        r"""setWhenStop(self, pyfunc)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_setWhenStop(self, pyfunc)


# Register PythonDatabaseGeneratorListener in _pyAgrum:
_pyAgrum.PythonDatabaseGeneratorListener_swigregister(PythonDatabaseGeneratorListener)

class BNGenerator(object):
    r"""

    BNGenerator is used to easily generate Bayesian networks.

    Available constructors:

        ``BNGenerator() -> BNGenerator``

    """

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

    def generate(self, n_nodes=10, n_arcs=15, n_modmax=4):
        r"""
        generate(self, n_nodes=10, n_arcs=15, n_modmax=4) -> BayesNet
        generate(self, n_nodes=10, n_arcs=15) -> BayesNet
        generate(self, n_nodes=10) -> BayesNet
        generate(self) -> BayesNet

        Generate a new Bayesian network 

        Parameters
        ----------
        n_nodes : int
        	the number of nodes (default=10)
        n_arcs : int
        	the number of arcs (default=15)
        n_nodmax : int
        	the max number of modalities for a node (default=4)

        Returns
        -------
        pyAgrum.BayesNet
        	the generated Bayesian network

        Raises
        ------
        gum.OperationNotAllowed
        	If n_modmax < 2
        gum.OperationNotAllowed
        	If n_arcs is incompatible with n_nodes (not enough arcs)

        """
        return _pyAgrum.BNGenerator_generate(self, n_nodes, n_arcs, n_modmax)


    def __init__(self):
        r"""
        __init__(self) -> BNGenerator

        BNGenerator is used to easily generate Bayesian networks.

        Available constructors:

            ``BNGenerator() -> BNGenerator``

        """
        this = _pyAgrum.new_BNGenerator()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_BNGenerator

# Register BNGenerator in _pyAgrum:
_pyAgrum.BNGenerator_swigregister(BNGenerator)

class IDGenerator(object):
    r"""

    IDGenerator is used to easily generate influence diagrams.

    Available constructors:

        ``IDGenerator() -> IDGenerator``

    """

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

    def generate(self, nbrNodes=10, arcDensity=0.2, chanceNodeDensity=0.8, utilityNodeDensity=0.1, max_modality=2):
        r"""
        generate(self, nbrNodes=10, arcDensity=0.2, chanceNodeDensity=0.8, utilityNodeDensity=0.1, max_modality=2) -> InfluenceDiagram
        generate(self, nbrNodes=10, arcDensity=0.2, chanceNodeDensity=0.8, utilityNodeDensity=0.1) -> InfluenceDiagram
        generate(self, nbrNodes=10, arcDensity=0.2, chanceNodeDensity=0.8) -> InfluenceDiagram
        generate(self, nbrNodes=10, arcDensity=0.2) -> InfluenceDiagram
        generate(self, nbrNodes=10) -> InfluenceDiagram
        generate(self) -> InfluenceDiagram

        Generate a new influence diagram given the parameters.

        Parameters
        ----------
        nbrNodes : int
        	the number of node
        arcDensity : double
        	the density of arc (1 for a complete graph)
        chanceNodeDensity : double
        	the density of chance node
        utilityNodeDensity : double
        	the density of utility node
        max_modality : int
        	the maximum value for modalities

        Returns
        -------
        pyAgrum.InfluenceDiagram
        	the generated influence diagram

        """
        return _pyAgrum.IDGenerator_generate(self, nbrNodes, arcDensity, chanceNodeDensity, utilityNodeDensity, max_modality)


    def __init__(self):
        r"""
        __init__(self) -> IDGenerator

        IDGenerator is used to easily generate influence diagrams.

        Available constructors:

            ``IDGenerator() -> IDGenerator``

        """
        this = _pyAgrum.new_IDGenerator()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_IDGenerator

# Register IDGenerator in _pyAgrum:
_pyAgrum.IDGenerator_swigregister(IDGenerator)

class PRMexplorer(object):
    r"""

    PRMexplorer helps navigate through probabilistic relational models.

    Available constructors:
    	``JTGenerator() -> JTGenerator``

    """

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

    def __init__(self):
        r"""
        __init__(self) -> PRMexplorer

        PRMexplorer helps navigate through probabilistic relational models.

        Available constructors:
        	``JTGenerator() -> JTGenerator``

        """
        this = _pyAgrum.new_PRMexplorer()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_PRMexplorer

    def load(self, *args):
        r"""
        load(self, filename, classpath, verbose=False)
        load(self, filename, classpath)
        load(self, filename)

        Load a PRM into the explorer.

        Parameters
        ----------
        filename : str
        	the name of the o3prm file
        classpath : str
        	the classpath of the PRM

        Raises
        ------
        gum.FatalError
        	If file not found

        """
        return _pyAgrum.PRMexplorer_load(self, *args)


    def isType(self, name):
        r"""
        isType(self, name) -> PyObject *

        Parameters
        ----------
        name : str
        	an element name

        Returns
        -------
        bool
        	True if the parameter correspond to a type in the PRM

        """
        return _pyAgrum.PRMexplorer_isType(self, name)


    def isClass(self, name):
        r"""
        isClass(self, name) -> PyObject *

        Parameters
        ----------
        name : str
        	an element name

        Returns
        -------
        bool
        	True if the parameter correspond to a class in the PRM

        """
        return _pyAgrum.PRMexplorer_isClass(self, name)


    def isInterface(self, name):
        r"""
        isInterface(self, name) -> PyObject *

        Parameters
        ----------
        name : str
        	an element name

        Returns
        -------
        bool
        	True if the parameter correspond to an interface in the PRM

        """
        return _pyAgrum.PRMexplorer_isInterface(self, name)


    def classes(self):
        r"""
        classes(self) -> PyObject *

        Returns
        -------
        list
        	the list of classes

        """
        return _pyAgrum.PRMexplorer_classes(self)


    def classAttributes(self, class_name):
        r"""
        classAttributes(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of attributes

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classAttributes(self, class_name)


    def isAttribute(self, class_name, att_name):
        r"""
        isAttribute(self, class_name, att_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name
        att_name : str
        	the name of the attribute to be tested

        Returns
        -------
        bool
        	True if att_name is an attribute of class_name

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM
        gum.IndexError
        	If att_name is not an element of class_name

        """
        return _pyAgrum.PRMexplorer_isAttribute(self, class_name, att_name)


    def classReferences(self, class_name):
        r"""
        classReferences(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of references

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classReferences(self, class_name)


    def classParameters(self, class_name):
        r"""
        classParameters(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of parameters

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classParameters(self, class_name)


    def classImplements(self, class_name):
        r"""
        classImplements(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of interfaces implemented by the class

        """
        return _pyAgrum.PRMexplorer_classImplements(self, class_name)

    aggType = property(_pyAgrum.PRMexplorer_aggType_get, _pyAgrum.PRMexplorer_aggType_set)

    def classAggregates(self, class_name):
        r"""
        classAggregates(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of aggregates in the class

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classAggregates(self, class_name)


    def classSlotChains(self, class_name):
        r"""
        classSlotChains(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of class slot chains

        Raises
        ------
        gum.IndexError 
        	if the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classSlotChains(self, class_name)


    def classDag(self, class_name):
        r"""
        classDag(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        tuple
        	a description of the DAG

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classDag(self, class_name)


    def getalltheSystems(self):
        r"""
        getalltheSystems(self) -> PyObject *

        Returns
        -------
        list
        	the list of all the systems and their components

        """
        return _pyAgrum.PRMexplorer_getalltheSystems(self)


    def getSuperClass(self, class_name):
        r"""
        getSuperClass(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        str
        	the class extended by class_name

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getSuperClass(self, class_name)


    def getDirectSubClass(self, class_name):
        r"""
        getDirectSubClass(self, class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of direct subclasses

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getDirectSubClass(self, class_name)


    def cpf(self, class_name, attribute):
        r"""
        cpf(self, class_name, attribute) -> Potential

        Parameters
        ----------
        class_name : str
        	a class name

        attribute : str
        	an attribute

        Returns
        -------
        pyAgrum.Potential
        	the potential of the attribute

        Raises
        ------
        gum.OperationNotAllowed
        	If the class element doesn't have any gum::Potential (like a gum::PRMReferenceSlot). 
        gum.IndexError
        	If the class is not in the PRM
        gum.IndexError
        	If the attribute in parameters does not exist 

        """
        return _pyAgrum.PRMexplorer_cpf(self, class_name, attribute)


    def types(self):
        r"""
        types(self) -> PyObject *

        Returns
        -------
        list
        	the list of the custom types in the PRM 

        """
        return _pyAgrum.PRMexplorer_types(self)


    def getSuperType(self, type_name):
        r"""
        getSuperType(self, type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        str
        	the type extended by type_name

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getSuperType(self, type_name)


    def getDirectSubTypes(self, type_name):
        r"""
        getDirectSubTypes(self, type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        list
        	the list of direct subtypes

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getDirectSubTypes(self, type_name)


    def getLabels(self, type_name):
        r"""
        getLabels(self, type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        list
        	the list of type labels

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getLabels(self, type_name)


    def getLabelMap(self, type_name):
        r"""
        getLabelMap(self, type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        dict
        	a dict containing pairs of label and their values 

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getLabelMap(self, type_name)


    def interfaces(self):
        r"""
        interfaces(self) -> PyObject *

        Returns
        -------
        list
        	the list of interfaces in the PRM 

        """
        return _pyAgrum.PRMexplorer_interfaces(self)


    def interAttributes(self, interface_name, allAttributes=False):
        r"""
        interAttributes(self, interface_name, allAttributes=False) -> PyObject
        interAttributes(self, interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface

        allAttributes : bool
        	True if supertypes of a custom type should be indicated

        Returns
        -------
        list
        	the list of (<type>,<attribute_name>) for the given interface

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_interAttributes(self, interface_name, allAttributes)


    def interReferences(self, interface_name):
        r"""
        interReferences(self, interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface

        Returns
        -------
        list
        	the list of (<reference_type>,<reference_name>,<True if the reference is an array>) for the given interface

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_interReferences(self, interface_name)


    def getSuperInterface(self, interface_name):
        r"""
        getSuperInterface(self, interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface name

        Returns
        -------
        str
        	the interace extended by interface_name

        Raises
        ------
        gum.IndexError
        	If the interface is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getSuperInterface(self, interface_name)


    def getDirectSubInterfaces(self, interface_name):
        r"""
        getDirectSubInterfaces(self, interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface name

        Returns
        -------
        list
        	the list of direct subinterfaces

        Raises
        ------
        gum.IndexError
        	If the interface is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getDirectSubInterfaces(self, interface_name)


    def getImplementations(self, interface_name):
        r"""
        getImplementations(self, interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface name

        Returns
        -------
        str
        	the list of classes implementing the interface 

        Raises
        ------
        gum.IndexError
        	If the interface is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getImplementations(self, interface_name)


# Register PRMexplorer in _pyAgrum:
_pyAgrum.PRMexplorer_swigregister(PRMexplorer)

class Vector(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

    def iterator(self):
        r"""iterator(self) -> SwigPyIterator"""
        return _pyAgrum.Vector_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        r"""__nonzero__(self) -> bool"""
        return _pyAgrum.Vector___nonzero__(self)


    def __bool__(self):
        r"""__bool__(self) -> bool"""
        return _pyAgrum.Vector___bool__(self)


    def __len__(self):
        r"""__len__(self) -> std::vector< double >::size_type"""
        return _pyAgrum.Vector___len__(self)


    def __getslice__(self, i, j):
        r"""__getslice__(self, i, j) -> Vector"""
        return _pyAgrum.Vector___getslice__(self, i, j)


    def __setslice__(self, *args):
        r"""
        __setslice__(self, i, j)
        __setslice__(self, i, j, v)
        """
        return _pyAgrum.Vector___setslice__(self, *args)


    def __delslice__(self, i, j):
        r"""__delslice__(self, i, j)"""
        return _pyAgrum.Vector___delslice__(self, i, j)


    def __delitem__(self, *args):
        r"""
        __delitem__(self, i)
        __delitem__(self, slice)
        """
        return _pyAgrum.Vector___delitem__(self, *args)


    def __getitem__(self, *args):
        r"""
        __getitem__(self, slice) -> Vector
        __getitem__(self, i) -> std::vector< double >::value_type const &
        """
        return _pyAgrum.Vector___getitem__(self, *args)


    def __setitem__(self, *args):
        r"""
        __setitem__(self, slice, v)
        __setitem__(self, slice)
        __setitem__(self, i, x)
        """
        return _pyAgrum.Vector___setitem__(self, *args)


    def pop(self):
        r"""pop(self) -> std::vector< double >::value_type"""
        return _pyAgrum.Vector_pop(self)


    def append(self, x):
        r"""append(self, x)"""
        return _pyAgrum.Vector_append(self, x)


    def empty(self):
        r"""empty(self) -> bool"""
        return _pyAgrum.Vector_empty(self)


    def size(self):
        r"""size(self) -> std::vector< double >::size_type"""
        return _pyAgrum.Vector_size(self)


    def swap(self, v):
        r"""swap(self, v)"""
        return _pyAgrum.Vector_swap(self, v)


    def begin(self):
        r"""begin(self) -> std::vector< double >::iterator"""
        return _pyAgrum.Vector_begin(self)


    def end(self):
        r"""end(self) -> std::vector< double >::iterator"""
        return _pyAgrum.Vector_end(self)


    def rbegin(self):
        r"""rbegin(self) -> std::vector< double >::reverse_iterator"""
        return _pyAgrum.Vector_rbegin(self)


    def rend(self):
        r"""rend(self) -> std::vector< double >::reverse_iterator"""
        return _pyAgrum.Vector_rend(self)


    def clear(self):
        r"""clear(self)"""
        return _pyAgrum.Vector_clear(self)


    def get_allocator(self):
        r"""get_allocator(self) -> std::vector< double >::allocator_type"""
        return _pyAgrum.Vector_get_allocator(self)


    def pop_back(self):
        r"""pop_back(self)"""
        return _pyAgrum.Vector_pop_back(self)


    def erase(self, *args):
        r"""
        erase(self, pos) -> std::vector< double >::iterator
        erase(self, first, last) -> std::vector< double >::iterator
        """
        return _pyAgrum.Vector_erase(self, *args)


    def __init__(self, *args):
        r"""
        __init__(self) -> Vector
        __init__(self, arg2) -> Vector
        __init__(self, size) -> Vector
        __init__(self, size, value) -> Vector
        """
        this = _pyAgrum.new_Vector(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def push_back(self, x):
        r"""push_back(self, x)"""
        return _pyAgrum.Vector_push_back(self, x)


    def front(self):
        r"""front(self) -> std::vector< double >::value_type const &"""
        return _pyAgrum.Vector_front(self)


    def back(self):
        r"""back(self) -> std::vector< double >::value_type const &"""
        return _pyAgrum.Vector_back(self)


    def assign(self, n, x):
        r"""assign(self, n, x)"""
        return _pyAgrum.Vector_assign(self, n, x)


    def resize(self, *args):
        r"""
        resize(self, new_size)
        resize(self, new_size, x)
        """
        return _pyAgrum.Vector_resize(self, *args)


    def insert(self, *args):
        r"""
        insert(self, pos, x) -> std::vector< double >::iterator
        insert(self, pos, n, x)
        """
        return _pyAgrum.Vector_insert(self, *args)


    def reserve(self, n):
        r"""reserve(self, n)"""
        return _pyAgrum.Vector_reserve(self, n)


    def capacity(self):
        r"""capacity(self) -> std::vector< double >::size_type"""
        return _pyAgrum.Vector_capacity(self)

    __swig_destroy__ = _pyAgrum.delete_Vector

# Register Vector in _pyAgrum:
_pyAgrum.Vector_swigregister(Vector)

class Vector_int(object):
    r"""Proxy of C++ std::vector< unsigned int > class."""

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

    def iterator(self):
        r"""iterator(self) -> SwigPyIterator"""
        return _pyAgrum.Vector_int_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        r"""__nonzero__(self) -> bool"""
        return _pyAgrum.Vector_int___nonzero__(self)


    def __bool__(self):
        r"""__bool__(self) -> bool"""
        return _pyAgrum.Vector_int___bool__(self)


    def __len__(self):
        r"""__len__(self) -> std::vector< unsigned int >::size_type"""
        return _pyAgrum.Vector_int___len__(self)


    def __getslice__(self, i, j):
        r"""__getslice__(self, i, j) -> Vector_int"""
        return _pyAgrum.Vector_int___getslice__(self, i, j)


    def __setslice__(self, *args):
        r"""
        __setslice__(self, i, j)
        __setslice__(self, i, j, v)
        """
        return _pyAgrum.Vector_int___setslice__(self, *args)


    def __delslice__(self, i, j):
        r"""__delslice__(self, i, j)"""
        return _pyAgrum.Vector_int___delslice__(self, i, j)


    def __delitem__(self, *args):
        r"""
        __delitem__(self, i)
        __delitem__(self, slice)
        """
        return _pyAgrum.Vector_int___delitem__(self, *args)


    def __getitem__(self, *args):
        r"""
        __getitem__(self, slice) -> Vector_int
        __getitem__(self, i) -> std::vector< unsigned int >::value_type const &
        """
        return _pyAgrum.Vector_int___getitem__(self, *args)


    def __setitem__(self, *args):
        r"""
        __setitem__(self, slice, v)
        __setitem__(self, slice)
        __setitem__(self, i, x)
        """
        return _pyAgrum.Vector_int___setitem__(self, *args)


    def pop(self):
        r"""pop(self) -> std::vector< unsigned int >::value_type"""
        return _pyAgrum.Vector_int_pop(self)


    def append(self, x):
        r"""append(self, x)"""
        return _pyAgrum.Vector_int_append(self, x)


    def empty(self):
        r"""empty(self) -> bool"""
        return _pyAgrum.Vector_int_empty(self)


    def size(self):
        r"""size(self) -> std::vector< unsigned int >::size_type"""
        return _pyAgrum.Vector_int_size(self)


    def swap(self, v):
        r"""swap(self, v)"""
        return _pyAgrum.Vector_int_swap(self, v)


    def begin(self):
        r"""begin(self) -> std::vector< unsigned int >::iterator"""
        return _pyAgrum.Vector_int_begin(self)


    def end(self):
        r"""end(self) -> std::vector< unsigned int >::iterator"""
        return _pyAgrum.Vector_int_end(self)


    def rbegin(self):
        r"""rbegin(self) -> std::vector< unsigned int >::reverse_iterator"""
        return _pyAgrum.Vector_int_rbegin(self)


    def rend(self):
        r"""rend(self) -> std::vector< unsigned int >::reverse_iterator"""
        return _pyAgrum.Vector_int_rend(self)


    def clear(self):
        r"""clear(self)"""
        return _pyAgrum.Vector_int_clear(self)


    def get_allocator(self):
        r"""get_allocator(self) -> std::vector< unsigned int >::allocator_type"""
        return _pyAgrum.Vector_int_get_allocator(self)


    def pop_back(self):
        r"""pop_back(self)"""
        return _pyAgrum.Vector_int_pop_back(self)


    def erase(self, *args):
        r"""
        erase(self, pos) -> std::vector< unsigned int >::iterator
        erase(self, first, last) -> std::vector< unsigned int >::iterator
        """
        return _pyAgrum.Vector_int_erase(self, *args)


    def __init__(self, *args):
        r"""
        __init__(self) -> Vector_int
        __init__(self, arg2) -> Vector_int
        __init__(self, size) -> Vector_int
        __init__(self, size, value) -> Vector_int
        """
        this = _pyAgrum.new_Vector_int(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def push_back(self, x):
        r"""push_back(self, x)"""
        return _pyAgrum.Vector_int_push_back(self, x)


    def front(self):
        r"""front(self) -> std::vector< unsigned int >::value_type const &"""
        return _pyAgrum.Vector_int_front(self)


    def back(self):
        r"""back(self) -> std::vector< unsigned int >::value_type const &"""
        return _pyAgrum.Vector_int_back(self)


    def assign(self, n, x):
        r"""assign(self, n, x)"""
        return _pyAgrum.Vector_int_assign(self, n, x)


    def resize(self, *args):
        r"""
        resize(self, new_size)
        resize(self, new_size, x)
        """
        return _pyAgrum.Vector_int_resize(self, *args)


    def insert(self, *args):
        r"""
        insert(self, pos, x) -> std::vector< unsigned int >::iterator
        insert(self, pos, n, x)
        """
        return _pyAgrum.Vector_int_insert(self, *args)


    def reserve(self, n):
        r"""reserve(self, n)"""
        return _pyAgrum.Vector_int_reserve(self, n)


    def capacity(self):
        r"""capacity(self) -> std::vector< unsigned int >::size_type"""
        return _pyAgrum.Vector_int_capacity(self)

    __swig_destroy__ = _pyAgrum.delete_Vector_int

# Register Vector_int in _pyAgrum:
_pyAgrum.Vector_int_swigregister(Vector_int)

class Vector_string(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

    def iterator(self):
        r"""iterator(self) -> SwigPyIterator"""
        return _pyAgrum.Vector_string_iterator(self)

    def __iter__(self):
        return self.iterator()

    def __nonzero__(self):
        r"""__nonzero__(self) -> bool"""
        return _pyAgrum.Vector_string___nonzero__(self)


    def __bool__(self):
        r"""__bool__(self) -> bool"""
        return _pyAgrum.Vector_string___bool__(self)


    def __len__(self):
        r"""__len__(self) -> std::vector< std::string >::size_type"""
        return _pyAgrum.Vector_string___len__(self)


    def __getslice__(self, i, j):
        r"""__getslice__(self, i, j) -> Vector_string"""
        return _pyAgrum.Vector_string___getslice__(self, i, j)


    def __setslice__(self, *args):
        r"""
        __setslice__(self, i, j)
        __setslice__(self, i, j, v)
        """
        return _pyAgrum.Vector_string___setslice__(self, *args)


    def __delslice__(self, i, j):
        r"""__delslice__(self, i, j)"""
        return _pyAgrum.Vector_string___delslice__(self, i, j)


    def __delitem__(self, *args):
        r"""
        __delitem__(self, i)
        __delitem__(self, slice)
        """
        return _pyAgrum.Vector_string___delitem__(self, *args)


    def __getitem__(self, *args):
        r"""
        __getitem__(self, slice) -> Vector_string
        __getitem__(self, i) -> std::vector< std::string >::value_type const &
        """
        return _pyAgrum.Vector_string___getitem__(self, *args)


    def __setitem__(self, *args):
        r"""
        __setitem__(self, slice, v)
        __setitem__(self, slice)
        __setitem__(self, i, x)
        """
        return _pyAgrum.Vector_string___setitem__(self, *args)


    def pop(self):
        r"""pop(self) -> std::vector< std::string >::value_type"""
        return _pyAgrum.Vector_string_pop(self)


    def append(self, x):
        r"""append(self, x)"""
        return _pyAgrum.Vector_string_append(self, x)


    def empty(self):
        r"""empty(self) -> bool"""
        return _pyAgrum.Vector_string_empty(self)


    def size(self):
        r"""size(self) -> std::vector< std::string >::size_type"""
        return _pyAgrum.Vector_string_size(self)


    def swap(self, v):
        r"""swap(self, v)"""
        return _pyAgrum.Vector_string_swap(self, v)


    def begin(self):
        r"""begin(self) -> std::vector< std::string >::iterator"""
        return _pyAgrum.Vector_string_begin(self)


    def end(self):
        r"""end(self) -> std::vector< std::string >::iterator"""
        return _pyAgrum.Vector_string_end(self)


    def rbegin(self):
        r"""rbegin(self) -> std::vector< std::string >::reverse_iterator"""
        return _pyAgrum.Vector_string_rbegin(self)


    def rend(self):
        r"""rend(self) -> std::vector< std::string >::reverse_iterator"""
        return _pyAgrum.Vector_string_rend(self)


    def clear(self):
        r"""clear(self)"""
        return _pyAgrum.Vector_string_clear(self)


    def get_allocator(self):
        r"""get_allocator(self) -> std::vector< std::string >::allocator_type"""
        return _pyAgrum.Vector_string_get_allocator(self)


    def pop_back(self):
        r"""pop_back(self)"""
        return _pyAgrum.Vector_string_pop_back(self)


    def erase(self, *args):
        r"""
        erase(self, pos) -> std::vector< std::string >::iterator
        erase(self, first, last) -> std::vector< std::string >::iterator
        """
        return _pyAgrum.Vector_string_erase(self, *args)


    def __init__(self, *args):
        r"""
        __init__(self) -> Vector_string
        __init__(self, arg2) -> Vector_string
        __init__(self, size) -> Vector_string
        __init__(self, size, value) -> Vector_string
        """
        this = _pyAgrum.new_Vector_string(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def push_back(self, x):
        r"""push_back(self, x)"""
        return _pyAgrum.Vector_string_push_back(self, x)


    def front(self):
        r"""front(self) -> std::vector< std::string >::value_type const &"""
        return _pyAgrum.Vector_string_front(self)


    def back(self):
        r"""back(self) -> std::vector< std::string >::value_type const &"""
        return _pyAgrum.Vector_string_back(self)


    def assign(self, n, x):
        r"""assign(self, n, x)"""
        return _pyAgrum.Vector_string_assign(self, n, x)


    def resize(self, *args):
        r"""
        resize(self, new_size)
        resize(self, new_size, x)
        """
        return _pyAgrum.Vector_string_resize(self, *args)


    def insert(self, *args):
        r"""
        insert(self, pos, x) -> std::vector< std::string >::iterator
        insert(self, pos, n, x)
        """
        return _pyAgrum.Vector_string_insert(self, *args)


    def reserve(self, n):
        r"""reserve(self, n)"""
        return _pyAgrum.Vector_string_reserve(self, n)


    def capacity(self):
        r"""capacity(self) -> std::vector< std::string >::size_type"""
        return _pyAgrum.Vector_string_capacity(self)

    __swig_destroy__ = _pyAgrum.delete_Vector_string

# Register Vector_string in _pyAgrum:
_pyAgrum.Vector_string_swigregister(Vector_string)

class SetIteratorStaticEnd(object):
    r"""Proxy of C++ gum::SetIteratorStaticEnd 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):
        r"""__init__(self) -> SetIteratorStaticEnd"""
        this = _pyAgrum.new_SetIteratorStaticEnd()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_SetIteratorStaticEnd

# Register SetIteratorStaticEnd in _pyAgrum:
_pyAgrum.SetIteratorStaticEnd_swigregister(SetIteratorStaticEnd)

class GumException(Exception):
    r"""Proxy of C++ gum::Exception 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"""
        Exception(aMsg, aType) -> GumException
        Exception(aMsg) -> GumException
        Exception() -> GumException
        __init__(self, e) -> GumException
        """
        this = _pyAgrum.new_GumException(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_GumException

    def what(self):
        r"""what(self) -> std::string const"""
        return _pyAgrum.GumException_what(self)


    def errorContent(self):
        r"""
        errorContent(self) -> std::string const

        Returns
        -------
        str
        	the error content

        """
        return _pyAgrum.GumException_errorContent(self)


    def errorType(self):
        r"""
        errorType(self) -> std::string const

        Returns
        -------
        str
        	the error type

        """
        return _pyAgrum.GumException_errorType(self)


    def errorCallStack(self):
        r"""
        errorCallStack(self) -> std::string const

        Returns
        -------
        str
        	the error call stack

        """
        return _pyAgrum.GumException_errorCallStack(self)


# Register GumException in _pyAgrum:
_pyAgrum.GumException_swigregister(GumException)


def __createMsg(filename, function, line, msg):
    r"""__createMsg(filename, function, line, msg) -> std::string const"""
    return _pyAgrum.__createMsg(filename, function, line, msg)
class IdError(GumException):
    r"""Proxy of C++ gum::IdError 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__(self, aMsg, aType) -> IdError
        __init__(self, aMsg) -> IdError
        __init__(self, src) -> IdError
        """
        this = _pyAgrum.new_IdError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_IdError

# Register IdError in _pyAgrum:
_pyAgrum.IdError_swigregister(IdError)

class FatalError(GumException):
    r"""Proxy of C++ gum::FatalError 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__(self, aMsg, aType) -> FatalError
        __init__(self, aMsg) -> FatalError
        __init__(self, src) -> FatalError
        """
        this = _pyAgrum.new_FatalError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_FatalError

# Register FatalError in _pyAgrum:
_pyAgrum.FatalError_swigregister(FatalError)

class NotImplementedYet(GumException):
    r"""Proxy of C++ gum::NotImplementedYet 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__(self, aMsg, aType) -> NotImplementedYet
        __init__(self, aMsg) -> NotImplementedYet
        __init__(self, src) -> NotImplementedYet
        """
        this = _pyAgrum.new_NotImplementedYet(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_NotImplementedYet

# Register NotImplementedYet in _pyAgrum:
_pyAgrum.NotImplementedYet_swigregister(NotImplementedYet)

class UndefinedIteratorValue(GumException):
    r"""Proxy of C++ gum::UndefinedIteratorValue 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__(self, aMsg, aType) -> UndefinedIteratorValue
        __init__(self, aMsg) -> UndefinedIteratorValue
        __init__(self, src) -> UndefinedIteratorValue
        """
        this = _pyAgrum.new_UndefinedIteratorValue(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_UndefinedIteratorValue

# Register UndefinedIteratorValue in _pyAgrum:
_pyAgrum.UndefinedIteratorValue_swigregister(UndefinedIteratorValue)

class UndefinedIteratorKey(GumException):
    r"""Proxy of C++ gum::UndefinedIteratorKey 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__(self, aMsg, aType) -> UndefinedIteratorKey
        __init__(self, aMsg) -> UndefinedIteratorKey
        __init__(self, src) -> UndefinedIteratorKey
        """
        this = _pyAgrum.new_UndefinedIteratorKey(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_UndefinedIteratorKey

# Register UndefinedIteratorKey in _pyAgrum:
_pyAgrum.UndefinedIteratorKey_swigregister(UndefinedIteratorKey)

class NullElement(GumException):
    r"""Proxy of C++ gum::NullElement 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__(self, aMsg, aType) -> NullElement
        __init__(self, aMsg) -> NullElement
        __init__(self, src) -> NullElement
        """
        this = _pyAgrum.new_NullElement(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_NullElement

# Register NullElement in _pyAgrum:
_pyAgrum.NullElement_swigregister(NullElement)

class UndefinedElement(GumException):
    r"""Proxy of C++ gum::UndefinedElement 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__(self, aMsg, aType) -> UndefinedElement
        __init__(self, aMsg) -> UndefinedElement
        __init__(self, src) -> UndefinedElement
        """
        this = _pyAgrum.new_UndefinedElement(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_UndefinedElement

# Register UndefinedElement in _pyAgrum:
_pyAgrum.UndefinedElement_swigregister(UndefinedElement)

class SizeError(GumException):
    r"""Proxy of C++ gum::SizeError 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__(self, aMsg, aType) -> SizeError
        __init__(self, aMsg) -> SizeError
        __init__(self, src) -> SizeError
        """
        this = _pyAgrum.new_SizeError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_SizeError

# Register SizeError in _pyAgrum:
_pyAgrum.SizeError_swigregister(SizeError)

class EmptySet(GumException):
    r"""Proxy of C++ gum::EmptySet 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__(self, aMsg, aType) -> EmptySet
        __init__(self, aMsg) -> EmptySet
        __init__(self, src) -> EmptySet
        """
        this = _pyAgrum.new_EmptySet(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_EmptySet

# Register EmptySet in _pyAgrum:
_pyAgrum.EmptySet_swigregister(EmptySet)

class InvalidArgumentsNumber(GumException):
    r"""Proxy of C++ gum::InvalidArgumentsNumber 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__(self, aMsg, aType) -> InvalidArgumentsNumber
        __init__(self, aMsg) -> InvalidArgumentsNumber
        __init__(self, src) -> InvalidArgumentsNumber
        """
        this = _pyAgrum.new_InvalidArgumentsNumber(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InvalidArgumentsNumber

# Register InvalidArgumentsNumber in _pyAgrum:
_pyAgrum.InvalidArgumentsNumber_swigregister(InvalidArgumentsNumber)

class InvalidArgument(GumException):
    r"""Proxy of C++ gum::InvalidArgument 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__(self, aMsg, aType) -> InvalidArgument
        __init__(self, aMsg) -> InvalidArgument
        __init__(self, src) -> InvalidArgument
        """
        this = _pyAgrum.new_InvalidArgument(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InvalidArgument

# Register InvalidArgument in _pyAgrum:
_pyAgrum.InvalidArgument_swigregister(InvalidArgument)

class IOError(GumException):
    r"""Proxy of C++ gum::IOError 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__(self, aMsg, aType) -> IOError
        __init__(self, aMsg) -> IOError
        __init__(self, src) -> IOError
        """
        this = _pyAgrum.new_IOError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_IOError

# Register IOError in _pyAgrum:
_pyAgrum.IOError_swigregister(IOError)

class FormatNotFound(IOError):
    r"""Proxy of C++ gum::FormatNotFound 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__(self, aMsg, aType) -> FormatNotFound
        __init__(self, aMsg) -> FormatNotFound
        __init__(self, src) -> FormatNotFound
        """
        this = _pyAgrum.new_FormatNotFound(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_FormatNotFound

# Register FormatNotFound in _pyAgrum:
_pyAgrum.FormatNotFound_swigregister(FormatNotFound)

class OperationNotAllowed(GumException):
    r"""Proxy of C++ gum::OperationNotAllowed 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__(self, aMsg, aType) -> OperationNotAllowed
        __init__(self, aMsg) -> OperationNotAllowed
        __init__(self, src) -> OperationNotAllowed
        """
        this = _pyAgrum.new_OperationNotAllowed(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_OperationNotAllowed

# Register OperationNotAllowed in _pyAgrum:
_pyAgrum.OperationNotAllowed_swigregister(OperationNotAllowed)

class NotFound(GumException):
    r"""Proxy of C++ gum::NotFound 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__(self, aMsg, aType) -> NotFound
        __init__(self, aMsg) -> NotFound
        __init__(self, src) -> NotFound
        """
        this = _pyAgrum.new_NotFound(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_NotFound

# Register NotFound in _pyAgrum:
_pyAgrum.NotFound_swigregister(NotFound)

class ReferenceError(GumException):
    r"""Proxy of C++ gum::ReferenceError 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__(self, aMsg, aType) -> ReferenceError
        __init__(self, aMsg) -> ReferenceError
        __init__(self, src) -> ReferenceError
        """
        this = _pyAgrum.new_ReferenceError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_ReferenceError

# Register ReferenceError in _pyAgrum:
_pyAgrum.ReferenceError_swigregister(ReferenceError)

class OutOfBounds(ReferenceError):
    r"""Proxy of C++ gum::OutOfBounds 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__(self, aMsg, aType) -> OutOfBounds
        __init__(self, aMsg) -> OutOfBounds
        __init__(self, src) -> OutOfBounds
        """
        this = _pyAgrum.new_OutOfBounds(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_OutOfBounds

# Register OutOfBounds in _pyAgrum:
_pyAgrum.OutOfBounds_swigregister(OutOfBounds)

class OutOfLowerBound(OutOfBounds):
    r"""Proxy of C++ gum::OutOfLowerBound 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__(self, aMsg, aType) -> OutOfLowerBound
        __init__(self, aMsg) -> OutOfLowerBound
        __init__(self, src) -> OutOfLowerBound
        """
        this = _pyAgrum.new_OutOfLowerBound(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_OutOfLowerBound

# Register OutOfLowerBound in _pyAgrum:
_pyAgrum.OutOfLowerBound_swigregister(OutOfLowerBound)

class OutOfUpperBound(OutOfBounds):
    r"""Proxy of C++ gum::OutOfUpperBound 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__(self, aMsg, aType) -> OutOfUpperBound
        __init__(self, aMsg) -> OutOfUpperBound
        __init__(self, src) -> OutOfUpperBound
        """
        this = _pyAgrum.new_OutOfUpperBound(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_OutOfUpperBound

# Register OutOfUpperBound in _pyAgrum:
_pyAgrum.OutOfUpperBound_swigregister(OutOfUpperBound)

class DuplicateElement(ReferenceError):
    r"""Proxy of C++ gum::DuplicateElement 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__(self, aMsg, aType) -> DuplicateElement
        __init__(self, aMsg) -> DuplicateElement
        __init__(self, src) -> DuplicateElement
        """
        this = _pyAgrum.new_DuplicateElement(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DuplicateElement

# Register DuplicateElement in _pyAgrum:
_pyAgrum.DuplicateElement_swigregister(DuplicateElement)

class DuplicateLabel(ReferenceError):
    r"""Proxy of C++ gum::DuplicateLabel 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__(self, aMsg, aType) -> DuplicateLabel
        __init__(self, aMsg) -> DuplicateLabel
        __init__(self, src) -> DuplicateLabel
        """
        this = _pyAgrum.new_DuplicateLabel(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DuplicateLabel

# Register DuplicateLabel in _pyAgrum:
_pyAgrum.DuplicateLabel_swigregister(DuplicateLabel)

class GraphError(GumException):
    r"""Proxy of C++ gum::GraphError 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__(self, aMsg, aType) -> GraphError
        __init__(self, aMsg) -> GraphError
        __init__(self, src) -> GraphError
        """
        this = _pyAgrum.new_GraphError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_GraphError

# Register GraphError in _pyAgrum:
_pyAgrum.GraphError_swigregister(GraphError)

class NoNeighbour(GraphError):
    r"""Proxy of C++ gum::NoNeighbour 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__(self, aMsg, aType) -> NoNeighbour
        __init__(self, aMsg) -> NoNeighbour
        __init__(self, src) -> NoNeighbour
        """
        this = _pyAgrum.new_NoNeighbour(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_NoNeighbour

# Register NoNeighbour in _pyAgrum:
_pyAgrum.NoNeighbour_swigregister(NoNeighbour)

class NoParent(GraphError):
    r"""Proxy of C++ gum::NoParent 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__(self, aMsg, aType) -> NoParent
        __init__(self, aMsg) -> NoParent
        __init__(self, src) -> NoParent
        """
        this = _pyAgrum.new_NoParent(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_NoParent

# Register NoParent in _pyAgrum:
_pyAgrum.NoParent_swigregister(NoParent)

class NoChild(GraphError):
    r"""Proxy of C++ gum::NoChild 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__(self, aMsg, aType) -> NoChild
        __init__(self, aMsg) -> NoChild
        __init__(self, src) -> NoChild
        """
        this = _pyAgrum.new_NoChild(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_NoChild

# Register NoChild in _pyAgrum:
_pyAgrum.NoChild_swigregister(NoChild)

class InvalidEdge(GraphError):
    r"""Proxy of C++ gum::InvalidEdge 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__(self, aMsg, aType) -> InvalidEdge
        __init__(self, aMsg) -> InvalidEdge
        __init__(self, src) -> InvalidEdge
        """
        this = _pyAgrum.new_InvalidEdge(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InvalidEdge

# Register InvalidEdge in _pyAgrum:
_pyAgrum.InvalidEdge_swigregister(InvalidEdge)

class InvalidArc(GraphError):
    r"""Proxy of C++ gum::InvalidArc 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__(self, aMsg, aType) -> InvalidArc
        __init__(self, aMsg) -> InvalidArc
        __init__(self, src) -> InvalidArc
        """
        this = _pyAgrum.new_InvalidArc(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InvalidArc

# Register InvalidArc in _pyAgrum:
_pyAgrum.InvalidArc_swigregister(InvalidArc)

class InvalidNode(GraphError):
    r"""Proxy of C++ gum::InvalidNode 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__(self, aMsg, aType) -> InvalidNode
        __init__(self, aMsg) -> InvalidNode
        __init__(self, src) -> InvalidNode
        """
        this = _pyAgrum.new_InvalidNode(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InvalidNode

# Register InvalidNode in _pyAgrum:
_pyAgrum.InvalidNode_swigregister(InvalidNode)

class EmptyBSTree(GraphError):
    r"""Proxy of C++ gum::EmptyBSTree 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__(self, aMsg, aType) -> EmptyBSTree
        __init__(self, aMsg) -> EmptyBSTree
        __init__(self, src) -> EmptyBSTree
        """
        this = _pyAgrum.new_EmptyBSTree(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_EmptyBSTree

# Register EmptyBSTree in _pyAgrum:
_pyAgrum.EmptyBSTree_swigregister(EmptyBSTree)

class DefaultInLabel(GraphError):
    r"""Proxy of C++ gum::DefaultInLabel 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__(self, aMsg, aType) -> DefaultInLabel
        __init__(self, aMsg) -> DefaultInLabel
        __init__(self, src) -> DefaultInLabel
        """
        this = _pyAgrum.new_DefaultInLabel(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DefaultInLabel

# Register DefaultInLabel in _pyAgrum:
_pyAgrum.DefaultInLabel_swigregister(DefaultInLabel)

class InvalidDirectedCycle(GraphError):
    r"""Proxy of C++ gum::InvalidDirectedCycle 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__(self, aMsg, aType) -> InvalidDirectedCycle
        __init__(self, aMsg) -> InvalidDirectedCycle
        __init__(self, src) -> InvalidDirectedCycle
        """
        this = _pyAgrum.new_InvalidDirectedCycle(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InvalidDirectedCycle

# Register InvalidDirectedCycle in _pyAgrum:
_pyAgrum.InvalidDirectedCycle_swigregister(InvalidDirectedCycle)

class CPTError(GumException):
    r"""Proxy of C++ gum::CPTError 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__(self, aMsg, aType) -> CPTError
        __init__(self, aMsg) -> CPTError
        __init__(self, src) -> CPTError
        """
        this = _pyAgrum.new_CPTError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_CPTError

# Register CPTError in _pyAgrum:
_pyAgrum.CPTError_swigregister(CPTError)

class CPTNoSumTo1(CPTError):
    r"""Proxy of C++ gum::CPTNoSumTo1 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__(self, aMsg, aType) -> CPTNoSumTo1
        __init__(self, aMsg) -> CPTNoSumTo1
        __init__(self, src) -> CPTNoSumTo1
        """
        this = _pyAgrum.new_CPTNoSumTo1(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_CPTNoSumTo1

# Register CPTNoSumTo1 in _pyAgrum:
_pyAgrum.CPTNoSumTo1_swigregister(CPTNoSumTo1)

class IncompatibleEvidence(GumException):
    r"""Proxy of C++ gum::IncompatibleEvidence 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__(self, aMsg, aType) -> IncompatibleEvidence
        __init__(self, aMsg) -> IncompatibleEvidence
        __init__(self, src) -> IncompatibleEvidence
        """
        this = _pyAgrum.new_IncompatibleEvidence(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_IncompatibleEvidence

# Register IncompatibleEvidence in _pyAgrum:
_pyAgrum.IncompatibleEvidence_swigregister(IncompatibleEvidence)

class FactoryError(GumException):
    r"""Proxy of C++ gum::FactoryError 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__(self, aMsg, aType) -> FactoryError
        __init__(self, aMsg) -> FactoryError
        __init__(self, src) -> FactoryError
        """
        this = _pyAgrum.new_FactoryError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_FactoryError

# Register FactoryError in _pyAgrum:
_pyAgrum.FactoryError_swigregister(FactoryError)

class FactoryInvalidState(FactoryError):
    r"""Proxy of C++ gum::FactoryInvalidState 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__(self, aMsg, aType) -> FactoryInvalidState
        __init__(self, aMsg) -> FactoryInvalidState
        __init__(self, src) -> FactoryInvalidState
        """
        this = _pyAgrum.new_FactoryInvalidState(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_FactoryInvalidState

# Register FactoryInvalidState in _pyAgrum:
_pyAgrum.FactoryInvalidState_swigregister(FactoryInvalidState)

class WrongType(FactoryError):
    r"""Proxy of C++ gum::WrongType 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__(self, aMsg, aType) -> WrongType
        __init__(self, aMsg) -> WrongType
        __init__(self, src) -> WrongType
        """
        this = _pyAgrum.new_WrongType(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_WrongType

# Register WrongType in _pyAgrum:
_pyAgrum.WrongType_swigregister(WrongType)

class WrongClassElement(FactoryError):
    r"""Proxy of C++ gum::WrongClassElement 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__(self, aMsg, aType) -> WrongClassElement
        __init__(self, aMsg) -> WrongClassElement
        __init__(self, src) -> WrongClassElement
        """
        this = _pyAgrum.new_WrongClassElement(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_WrongClassElement

# Register WrongClassElement in _pyAgrum:
_pyAgrum.WrongClassElement_swigregister(WrongClassElement)

class TypeError(FactoryError):
    r"""Proxy of C++ gum::TypeError 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__(self, aMsg, aType) -> TypeError
        __init__(self, aMsg) -> TypeError
        __init__(self, src) -> TypeError
        """
        this = _pyAgrum.new_TypeError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_TypeError

# Register TypeError in _pyAgrum:
_pyAgrum.TypeError_swigregister(TypeError)

class LearningError(GumException):
    r"""Proxy of C++ gum::LearningError 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__(self, aMsg, aType) -> LearningError
        __init__(self, aMsg) -> LearningError
        __init__(self, src) -> LearningError
        """
        this = _pyAgrum.new_LearningError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_LearningError

# Register LearningError in _pyAgrum:
_pyAgrum.LearningError_swigregister(LearningError)

class IncompatibleScoreApriori(LearningError):
    r"""Proxy of C++ gum::IncompatibleScoreApriori 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__(self, aMsg, aType) -> IncompatibleScoreApriori
        __init__(self, aMsg) -> IncompatibleScoreApriori
        __init__(self, src) -> IncompatibleScoreApriori
        """
        this = _pyAgrum.new_IncompatibleScoreApriori(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_IncompatibleScoreApriori

# Register IncompatibleScoreApriori in _pyAgrum:
_pyAgrum.IncompatibleScoreApriori_swigregister(IncompatibleScoreApriori)

class PossiblyIncompatibleScoreApriori(LearningError):
    r"""Proxy of C++ gum::PossiblyIncompatibleScoreApriori 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__(self, aMsg, aType) -> PossiblyIncompatibleScoreApriori
        __init__(self, aMsg) -> PossiblyIncompatibleScoreApriori
        __init__(self, src) -> PossiblyIncompatibleScoreApriori
        """
        this = _pyAgrum.new_PossiblyIncompatibleScoreApriori(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_PossiblyIncompatibleScoreApriori

# Register PossiblyIncompatibleScoreApriori in _pyAgrum:
_pyAgrum.PossiblyIncompatibleScoreApriori_swigregister(PossiblyIncompatibleScoreApriori)

class DatabaseError(LearningError):
    r"""Proxy of C++ gum::DatabaseError 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__(self, aMsg, aType) -> DatabaseError
        __init__(self, aMsg) -> DatabaseError
        __init__(self, src) -> DatabaseError
        """
        this = _pyAgrum.new_DatabaseError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DatabaseError

# Register DatabaseError in _pyAgrum:
_pyAgrum.DatabaseError_swigregister(DatabaseError)

class MissingVariableInDatabase(LearningError):
    r"""Proxy of C++ gum::MissingVariableInDatabase 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__(self, aMsg, aType) -> MissingVariableInDatabase
        __init__(self, aMsg) -> MissingVariableInDatabase
        __init__(self, src) -> MissingVariableInDatabase
        """
        this = _pyAgrum.new_MissingVariableInDatabase(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_MissingVariableInDatabase

# Register MissingVariableInDatabase in _pyAgrum:
_pyAgrum.MissingVariableInDatabase_swigregister(MissingVariableInDatabase)

class MissingValueInDatabase(LearningError):
    r"""Proxy of C++ gum::MissingValueInDatabase 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__(self, aMsg, aType) -> MissingValueInDatabase
        __init__(self, aMsg) -> MissingValueInDatabase
        __init__(self, src) -> MissingValueInDatabase
        """
        this = _pyAgrum.new_MissingValueInDatabase(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_MissingValueInDatabase

# Register MissingValueInDatabase in _pyAgrum:
_pyAgrum.MissingValueInDatabase_swigregister(MissingValueInDatabase)

class UnknownLabelInDatabase(LearningError):
    r"""Proxy of C++ gum::UnknownLabelInDatabase 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__(self, aMsg, aType) -> UnknownLabelInDatabase
        __init__(self, aMsg) -> UnknownLabelInDatabase
        __init__(self, src) -> UnknownLabelInDatabase
        """
        this = _pyAgrum.new_UnknownLabelInDatabase(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_UnknownLabelInDatabase

# Register UnknownLabelInDatabase in _pyAgrum:
_pyAgrum.UnknownLabelInDatabase_swigregister(UnknownLabelInDatabase)

class SyntaxError(IOError):
    r"""Proxy of C++ gum::SyntaxError 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__(self, aMsg, nol, noc, aType) -> SyntaxError
        __init__(self, aMsg, nol, noc) -> SyntaxError
        """
        this = _pyAgrum.new_SyntaxError(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def col(self):
        r"""
        col(self) -> gum::Size

        Returns
        -------
        int
        	the indice of the colonne of the error

        """
        return _pyAgrum.SyntaxError_col(self)


    def line(self):
        r"""
        line(self) -> gum::Size

        Returns
        -------
        int
        	the indice of the line of the error

        """
        return _pyAgrum.SyntaxError_line(self)

    __swig_destroy__ = _pyAgrum.delete_SyntaxError

# Register SyntaxError in _pyAgrum:
_pyAgrum.SyntaxError_swigregister(SyntaxError)


def randomValue(max=2):
    r"""
    randomValue(max=2) -> gum::Idx
    randomValue() -> gum::Idx

    Returns
    -------
    int
      a value randomly drawn (0 or 1)

    """
    return _pyAgrum.randomValue(max)

def randomProba():
    r"""
    randomProba() -> double

    Returns
    -------
    double
        a random number between 0 and 1 included (i.e. a proba). 

    """
    return _pyAgrum.randomProba()

def randomGeneratorSeed():
    r"""
    randomGeneratorSeed() -> unsigned int

    Returns
    -------
    int
      a randomly generated seed

    """
    return _pyAgrum.randomGeneratorSeed()

def initRandom(seed=0):
    r"""
    initRandom(seed=0)
    initRandom()

    Initialize random generator seed.

    Parameters
    ----------
    seed : int
      the seed used to initialize the random generator

    """
    return _pyAgrum.initRandom(seed)

def getRandomGenerator(seed=0):
    r"""
    getRandomGenerator(seed=0) -> std::default_random_engine
    getRandomGenerator() -> std::default_random_engine

    Returns
    -------
    tbw
      the random generator

    """
    return _pyAgrum.getRandomGenerator(seed)

def isOMP():
    r"""
    isOMP() -> bool

    Returns
    -------
    bool
      True if OMP has been set at compilation, False otherwise

    """
    return _pyAgrum.isOMP()

def setNumberOfThreads(number):
    r"""
    setNumberOfThreads(number)

    To avoid spare cycles (less then 100% CPU occupied), use more threads than logical processors (x2 is a good all-around value). 

    Returns
    -------
    number : int
      the number of threads to be used

    """
    return _pyAgrum.setNumberOfThreads(number)

def getMaxNumberOfThreads():
    r"""
    getMaxNumberOfThreads() -> unsigned int

    Returns
    -------
    int
      the max number of threads

    """
    return _pyAgrum.getMaxNumberOfThreads()

def getThreadNumber():
    r"""
    getThreadNumber() -> unsigned int

    Returns
    -------
    int
      the number of thread

    """
    return _pyAgrum.getThreadNumber()

def getNumberOfRunningThreads():
    r"""
    getNumberOfRunningThreads() -> unsigned int

    Returns
    -------
    int
      the number of running threads

    """
    return _pyAgrum.getNumberOfRunningThreads()

def getNumberOfLogicalProcessors():
    r"""
    getNumberOfLogicalProcessors() -> unsigned int

    Returns
    -------
    int
      the number of logical processors

    """
    return _pyAgrum.getNumberOfLogicalProcessors()

def setNestedParallelism(value):
    r"""
    setNestedParallelism(value)

    Parameters
    ----------
    value : bool
      True if nested parallelism should be activated

    """
    return _pyAgrum.setNestedParallelism(value)

def getNestedParallelism():
    r"""
    getNestedParallelism() -> bool

    Returns
    -------
    bool
      True if nested parallelism is enabled

    """
    return _pyAgrum.getNestedParallelism()

def setDynamicThreadsNumber(value):
    r"""
    setDynamicThreadsNumber(value)

    Parameters
    ----------
    value : bool
      True if the number of threads should be dynamic

    """
    return _pyAgrum.setDynamicThreadsNumber(value)

def getDynamicThreadsNumber():
    r"""
    getDynamicThreadsNumber() -> bool

    Returns
    -------
    bool
      True if dynamic threads number is enabled

    """
    return _pyAgrum.getDynamicThreadsNumber()
VarType_Discretized = _pyAgrum.VarType_Discretized

VarType_Labelized = _pyAgrum.VarType_Labelized

VarType_Range = _pyAgrum.VarType_Range

VarType_Continuous = _pyAgrum.VarType_Continuous

class Variable(object):
    r"""

    Abstract class used by DiscreteVariable.

    """

    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__ = _pyAgrum.delete_Variable

    def clone(self):
        r"""
        clone(self) -> Variable

        Copy factory

        Returns
        -------
        pyAgrum.DiscreteVariable
        	a pointer on a new copy of this

        """
        return _pyAgrum.Variable_clone(self)


    def __eq__(self, aRV):
        r"""__eq__(self, aRV) -> bool"""
        return _pyAgrum.Variable___eq__(self, aRV)


    def __ne__(self, aRV):
        r"""__ne__(self, aRV) -> bool"""
        return _pyAgrum.Variable___ne__(self, aRV)


    def setName(self, theValue):
        r"""
        setName(self, theValue)

        sets the name of the variable.

        Parameters
        ----------
        theValue : str
        	the new description of the variable

        """
        return _pyAgrum.Variable_setName(self, theValue)


    def name(self):
        r"""
        name(self) -> std::string const &

        Returns
        -------
        str
        	the name of the variable

        """
        return _pyAgrum.Variable_name(self)


    def setDescription(self, theValue):
        r"""
        setDescription(self, theValue)

        set the description of the variable.

        Parameters
        ----------
        theValue : str
        	the new description of the variable

        """
        return _pyAgrum.Variable_setDescription(self, theValue)


    def description(self):
        r"""
        description(self) -> std::string const &

        Returns
        -------
        str
        	the description of the variable

        """
        return _pyAgrum.Variable_description(self)


    def varType(self):
        r"""varType(self) -> gum::VarType"""
        return _pyAgrum.Variable_varType(self)


# Register Variable in _pyAgrum:
_pyAgrum.Variable_swigregister(Variable)

class DiscreteVariable(Variable):
    r"""

    DiscreteVariable is the base class for discrete random variable.

    Available constructors:

        ``DiscreteVariable(aName, aDesc='') -> DiscreteVariable``

        ``DiscreteVariable(aDRV) -> DiscreteVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    aDRV: pyAgrum.DiscreteVariable
      Another `DiscreteVariable` that will be copied

    """

    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")
    __swig_destroy__ = _pyAgrum.delete_DiscreteVariable

    def clone(self):
        r"""
        clone(self) -> DiscreteVariable

        Returns
        -------
        pyAgrum.DiscreteVariable
        	a copy of the DiscreteVariable

        """
        return _pyAgrum.DiscreteVariable_clone(self)


    def empty(self):
        r"""
        empty(self) -> bool

        Returns
        -------
        bool
        	True if the domain size < 2

        """
        return _pyAgrum.DiscreteVariable_empty(self)


    def domainSize(self):
        r"""
        domainSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.DiscreteVariable_domainSize(self)


    def labels(self):
        r"""
        labels(self) -> Vector_string

        Returns
        -------
        tuple
        	a tuple containing the labels

        """
        return _pyAgrum.DiscreteVariable_labels(self)


    def numerical(self, indice):
        r"""
        numerical(self, indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.DiscreteVariable_numerical(self, indice)


    def varType(self):
        r"""
        varType(self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.DiscreteVariable_varType(self)


    def __eq__(self, aRV):
        r"""__eq__(self, aRV) -> bool"""
        return _pyAgrum.DiscreteVariable___eq__(self, aRV)


    def __ne__(self, aRV):
        r"""__ne__(self, aRV) -> bool"""
        return _pyAgrum.DiscreteVariable___ne__(self, aRV)


    def index(self, label):
        r"""
        index(self, label) -> gum::Idx

        Parameters
        ----------
        label : str
        	a label

        Returns
        -------
        int
        	the indice of the label

        """
        return _pyAgrum.DiscreteVariable_index(self, label)


    def label(self, i):
        r"""
        label(self, i) -> std::string

        Parameters
        ----------
        i : int
        	the index of the label we wish to return

        Returns
        -------
        str
        	the indice-th label

        Raises
        ------
        gum.OutOfBound
        	If the variable does not contain the label

        """
        return _pyAgrum.DiscreteVariable_label(self, i)


    def toStringWithDescription(self):
        r"""
        toStringWithDescription(self) -> std::string const

        Returns
        -------
        str
        	a description of the variable

        """
        return _pyAgrum.DiscreteVariable_toStringWithDescription(self)


    def domain(self):
        r"""
        domain(self) -> std::string const

        Returns
        -------
        str
        	the domain of the variable

        """
        return _pyAgrum.DiscreteVariable_domain(self)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.DiscreteVariable___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.DiscreteVariable___str__(self)


    def __getitem__(self,label):   # adding the y() function here
        return self.index(label)


    def toLabelizedVar(self):
        r"""
        toLabelizedVar(self) -> LabelizedVariable

        Returns
        -------
        pyAgrum.LabelizedVariable
        	the labelized variable

        Raises
        ------
        gum.RuntimeError
        	If the variable is not a LabelizedVariable

        """
        return _pyAgrum.DiscreteVariable_toLabelizedVar(self)


    def toRangeVar(self):
        r"""
        toRangeVar(self) -> RangeVariable

        Returns
        -------
        pyAgrum.RangeVariable
        	the range variable

        Raises
        ------
        gum.RuntimeError
        	If the variable is not a RangeVariable

        """
        return _pyAgrum.DiscreteVariable_toRangeVar(self)


    def toDiscretizedVar(self):
        r"""
        toDiscretizedVar(self) -> DiscretizedVariable

        Returns
        -------
        pyAgrum.DiscretizedVariable
        	the discretized variable

        Raises
        ------
        gum.RuntimeError 
        	If the variable is not a DiscretizedVariable

        """
        return _pyAgrum.DiscreteVariable_toDiscretizedVar(self)


# Register DiscreteVariable in _pyAgrum:
_pyAgrum.DiscreteVariable_swigregister(DiscreteVariable)

class LabelizedVariable(DiscreteVariable):
    r"""

    LabelizedVariable is a discrete random variable with a customizable sequence of labels.

    Available constructors:

        ``LabelizedVariable(aName, aDesc='', nbrLabel=2) -> LabelizedVariable``

        ``LabelizedVariable(aName, aDesc='') -> LabelizedVariable``

        ``LabelizedVariable(aLDRV) -> LabelizedVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    nbrLabel: int
      The number of labels to create (2 by default)
    aLDRV: pyAgrum.LabelizedVariable
      Another `LabelizedVariable` that will be copied

    Examples
    --------
    >>> import pyAgrum as gum
    >>>
    >>> # creating a variable with 3 labels : '0', '1' and '2'
    >>> va=gum.LabelizedVariable('a','a labelized variable',3)
    >>> print(va)
    >>> ## a<0,1,2>
    >>>
    >>> va.addLabel('foo')
    >>> print(va)
    >>> ## a<0,1,2,foo>
    >>>
    >>> va.chgLabel(1,'bar')
    >>> print(va)
    >>> a<0,bar,2,foo>
    >>>
    >>> vb=gum.LabelizedVariable('b','b',0).addLabel('A').addLabel('B').addLabel('C')
    >>> print(vb)
    >>> ## b<A,B,C>
    >>> 
    >>> vb.labels()
    >>> ## ('A', 'B', 'C')
    >>> 
    >>> vb.isLabel('E')
    >>> ## False
    >>> 
    >>> vb.label(2)
    >>> ## 'B'

    """

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

    def __init__(self, *args):
        r"""
        __init__(self, aName, aDesc, nbrLabel=2) -> LabelizedVariable
        __init__(self, aName, aDesc) -> LabelizedVariable
        __init__(self, aName) -> LabelizedVariable
        __init__(self, aName, aDesc, labels) -> LabelizedVariable
        __init__(self, aLDRV) -> LabelizedVariable
        """
        this = _pyAgrum.new_LabelizedVariable(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_LabelizedVariable

    def clone(self):
        r"""
        clone(self) -> LabelizedVariable

        Returns
        -------
        pyAgrum.LabelizedVariable
        	a copy of the LabelizedVariable

        """
        return _pyAgrum.LabelizedVariable_clone(self)


    def index(self, label):
        r"""
        index(self, label) -> gum::Idx

        Parameters
        ----------
        label : str
        	a label

        Returns
        -------
        int
        	the indice of the label

        """
        return _pyAgrum.LabelizedVariable_index(self, label)


    def isLabel(self, aLabel):
        r"""
        isLabel(self, aLabel) -> bool

        Indicates whether the variable already has the label passed in argument

        Parameters
        ----------
        aLabel : str
        	the label to be tested

        Returns
        -------
        bool
        	True if the label already exists

        """
        return _pyAgrum.LabelizedVariable_isLabel(self, aLabel)


    def addLabel(self,*args):
        """
        Add a label with a new index (we assume that we will NEVER remove a label).

        Parameters
        ----------
        aLabel : str
            the label to be added to the labelized variable

        Returns
        -------
        pyAgrum.LabelizedVariable
            the labelized variable

        Raises
        ------
        gum.DuplicateElement
            If the variable already contains the label
        """
        _pyAgrum.LabelizedVariable_addLabel(self,*args)
        return self



    def changeLabel(self, pos, aLabel):
        r"""
        changeLabel(self, pos, aLabel)

        Change the label at the specified index

        Parameters
        ----------
        pos : int
        	the index of the label to be changed
        aLabel : str
        	the label to be added to the labelized variable

        Raises
        ------
        gum.DuplicatedElement
          If the variable already contains the new label
        gum.OutOfBounds
          If the index is greater than the size of the variable

        """
        return _pyAgrum.LabelizedVariable_changeLabel(self, pos, aLabel)


    def eraseLabels(self):
        r"""
        eraseLabels(self)

        Erase all the labels from the variable.

        """
        return _pyAgrum.LabelizedVariable_eraseLabels(self)


    def label(self, i):
        r"""
        label(self, i) -> std::string

        Parameters
        ----------
        i : int
        	the index of the label we wish to return

        Returns
        -------
        str
        	the indice-th label

        Raises
        ------
        gum.OutOfBound
        	If the variable does not contain the label

        """
        return _pyAgrum.LabelizedVariable_label(self, i)


    def posLabel(self, label):
        r"""posLabel(self, label) -> gum::Idx"""
        return _pyAgrum.LabelizedVariable_posLabel(self, label)


    def numerical(self, indice):
        r"""
        numerical(self, indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.LabelizedVariable_numerical(self, indice)


    def domainSize(self):
        r"""
        domainSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.LabelizedVariable_domainSize(self)


    def varType(self):
        r"""
        varType(self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.LabelizedVariable_varType(self)


    def domain(self):
        r"""
        domain(self) -> std::string const

        Returns
        -------
        str
            the domain of the variable as a string

        """
        return _pyAgrum.LabelizedVariable_domain(self)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.LabelizedVariable___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.LabelizedVariable___str__(self)


# Register LabelizedVariable in _pyAgrum:
_pyAgrum.LabelizedVariable_swigregister(LabelizedVariable)

class RangeVariable(DiscreteVariable):
    r"""

    RangeVariable represents a variable with a range of integers as domain.

    Available constructors:

    	``RangeVariable(aName, aDesc='',minVal, maxVal) -> RangeVariable``

    	``RangeVariable(aName, aDesc='',minVal) -> RangeVariable``

      ``RangeVariable(aName, aDesc='') -> RangeVariable``

      ``RangeVariable(aRV) -> RangeVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    minVal : int
      The minimal integer of the interval
    maxVal : int
      The maximal integer of the interval
    aDV: pyAgrum.RangeVariable
      Another `RangeVariable` that will be copied

    Examples
    --------
    >>> import pyAgrum as gum
    >>>
    >>> vI=gum.gum.RangeVariable('I','I in [4,10]',4,10)
    >>> print(vI)
    >>> ## I[4-10]
    >>> 
    >>> vX.maxVal()
    >>> ## 10
    >>> 
    >>> vX.belongs(1)
    >>> ## False
    >>> 
    >>> # where is the value 5 ?
    >>> vX.index('5')
    >>> ## 1
    >>> 
    >>> vi.labels()
    >>> ## ('4', '5', '6', '7', '8', '9', '10')

    """

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

    def __init__(self, *args):
        r"""
        __init__(self, aName, aDesc, minVal=0, maxVal=1) -> RangeVariable
        __init__(self, aName, aDesc, minVal=0) -> RangeVariable
        __init__(self, aName, aDesc) -> RangeVariable
        __init__(self, aDRV) -> RangeVariable
        """
        this = _pyAgrum.new_RangeVariable(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_RangeVariable

    def clone(self):
        r"""
        clone(self) -> DiscreteVariable

        Returns
        -------
        pyAgrum.RangeVariable
        	a copy of the RangeVariable

        """
        return _pyAgrum.RangeVariable_clone(self)


    def domainSize(self):
        r"""
        domainSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.RangeVariable_domainSize(self)


    def varType(self):
        r"""
        varType(self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.RangeVariable_varType(self)


    def label(self, indice):
        r"""
        label(self, indice) -> std::string

        Parameters
        ----------
        indice : int
          the index of the label we wish to return

        Returns
        -------
        str
          the indice-th label

        Raises
        ------
        gum.OutOfBound
          If the variable does not contain the label

        """
        return _pyAgrum.RangeVariable_label(self, indice)


    def numerical(self, indice):
        r"""
        numerical(self, indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.RangeVariable_numerical(self, indice)


    def minVal(self):
        r"""
        minVal(self) -> long

        Returns
        -------
        long :
          the lower bound of the variable

        """
        return _pyAgrum.RangeVariable_minVal(self)


    def setMinVal(self, minVal):
        r"""
        setMinVal(self, minVal)

        Set a new value of the lower bound

        Parameters
        ----------
        minVal : long
          The new value of the lower bound

        Warnings
        --------
        An error should be raised if the value is higher than the upper bound.

        """
        return _pyAgrum.RangeVariable_setMinVal(self, minVal)


    def maxVal(self):
        r"""
        maxVal(self) -> long

        Returns
        -------
        long :
          the upper bound of the variable.

        """
        return _pyAgrum.RangeVariable_maxVal(self)


    def setMaxVal(self, maxVal):
        r"""
        setMaxVal(self, maxVal)

        Set a new value of the upper bound

        Parameters
        ----------
        maxVal : long
          The new value of the upper bound

        Warnings
        --------
        An error should be raised if the value is lower than the lower bound.

        """
        return _pyAgrum.RangeVariable_setMaxVal(self, maxVal)


    def belongs(self, val):
        r"""
        belongs(self, val) -> bool

        Parameters
        ----------
        val : long
          the value to be tested

        Returns
        -------
        bool:
          True if the value in parameters belongs to the variable's interval.

        """
        return _pyAgrum.RangeVariable_belongs(self, val)


    def index(self, arg2):
        r"""
        index(self, arg2) -> gum::Idx

        Parameters
        ----------
        arg2 : str
          a label

        Returns
        -------
        int
          the indice of the label

        """
        return _pyAgrum.RangeVariable_index(self, arg2)


    def domain(self):
        r"""
        domain(self) -> std::string const

        Returns
        -------
        str
        	the domain of the variable

        """
        return _pyAgrum.RangeVariable_domain(self)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.RangeVariable___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.RangeVariable___str__(self)


# Register RangeVariable in _pyAgrum:
_pyAgrum.RangeVariable_swigregister(RangeVariable)

class IDiscretizedVariable(DiscreteVariable):
    r"""Proxy of C++ gum::IDiscretizedVariable 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__ = _pyAgrum.delete_IDiscretizedVariable

    def clone(self):
        r"""
        clone(self) -> IDiscretizedVariable

        Returns
        -------
        pyAgrum.DiscreteVariable
        	a copy of the DiscreteVariable

        """
        return _pyAgrum.IDiscretizedVariable_clone(self)


# Register IDiscretizedVariable in _pyAgrum:
_pyAgrum.IDiscretizedVariable_swigregister(IDiscretizedVariable)

class Edge(object):
    r"""

    pyAgrum.Edge is the representation of an arc between two nodes represented by int : the first and the second.

    Available constructors :
        ``Edge(aN1,aN2) -> Edge``

        ``Edge(src) -> Edge``

    Parameters
    ----------
    aN1 : int
      the nodeId of the first node
    aN2 : int
      the nodeId of the secondnode
    src: pyAgrum.Edge
      the Edge to copy

    """

    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__(self, aN1, aN2) -> Edge
        __init__(self, src) -> Edge
        """
        this = _pyAgrum.new_Edge(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_Edge

    def other(self, id):
        r"""
        other(self, id) -> gum::NodeId

        Parameters
        ----------
        id : int
          the nodeId of one of the nodes of the Edge


        Returns
        ------
        int
          the nodeId of the other node

        """
        return _pyAgrum.Edge_other(self, id)


    def first(self):
        r"""
        first(self) -> gum::NodeId

        Returns
        ------
        int
          the nodeId of the first node of the arc (the tail)

        """
        return _pyAgrum.Edge_first(self)


    def second(self):
        r"""
        second(self) -> gum::NodeId

        Returns
        ------
        int
          the nodeId of the second node of the arc (the head)

        """
        return _pyAgrum.Edge_second(self)


    def __eq__(self, src):
        r"""__eq__(self, src) -> bool"""
        return _pyAgrum.Edge___eq__(self, src)


    def __ne__(self, src):
        r"""__ne__(self, src) -> bool"""
        return _pyAgrum.Edge___ne__(self, src)


# Register Edge in _pyAgrum:
_pyAgrum.Edge_swigregister(Edge)

class Arc(object):
    r"""

    pyAgrum.Arc is the representation of an arc between two nodes represented by int : the head and the tail.

    Available constructors:
        ``Arc(tail, head) -> Arc``

        ``Arc(src) -> Arc``

    Parameters
    ----------
    tail : int
      the tail
    head : int
      the head
    src : :class: Arc
      the Arc to copy


    """

    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__(self, tail, head) -> Arc
        __init__(self, src) -> Arc
        """
        this = _pyAgrum.new_Arc(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_Arc

    def tail(self):
        r"""
        tail(self) -> gum::NodeId

        Returns
        -------
        int
          the id of the tail node

        """
        return _pyAgrum.Arc_tail(self)


    def head(self):
        r"""
        head(self) -> gum::NodeId

        Returns
        ------
        int
          the id of the head node

        """
        return _pyAgrum.Arc_head(self)


    def other(self, id):
        r"""
        other(self, id) -> gum::NodeId

        Parameters
        ----------
        id : int
          the nodeId of the head or the tail


        Returns
        -------
        int
          the nodeId of the other node

        """
        return _pyAgrum.Arc_other(self, id)


    def first(self):
        r"""
        first(self) -> gum::NodeId

        Returns
        -------
        int
          the nodeId of the first node of the arc (the tail)

        """
        return _pyAgrum.Arc_first(self)


    def second(self):
        r"""
        second(self) -> gum::NodeId

        Returns
        -------
        int
          the nodeId of the second node of the arc (the head)

        """
        return _pyAgrum.Arc_second(self)


    def __eq__(self, src):
        r"""__eq__(self, src) -> bool"""
        return _pyAgrum.Arc___eq__(self, src)


    def __ne__(self, src):
        r"""__ne__(self, src) -> bool"""
        return _pyAgrum.Arc___ne__(self, src)


# Register Arc in _pyAgrum:
_pyAgrum.Arc_swigregister(Arc)

class DiGraph(object):
    r"""

    DiGraph represents a Directed Graph.

    Available constructors:
        ``DiGraph() -> DiGraph``

        ``DiGraph(src) -> DiGraph``

    Parameters
    ----------
    src : pyAgrum.DiGraph
      the digraph to copy


    """

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

    def __init__(self, *args):
        r"""
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size, arcs_resize_policy=True) -> DiGraph
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size) -> DiGraph
        __init__(self, nodes_size, nodes_resize_policy=True) -> DiGraph
        __init__(self, nodes_size) -> DiGraph
        __init__(self) -> DiGraph
        __init__(self, g) -> DiGraph
        """
        this = _pyAgrum.new_DiGraph(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DiGraph

    def __eq__(self, g):
        r"""__eq__(self, g) -> bool"""
        return _pyAgrum.DiGraph___eq__(self, g)


    def __ne__(self, g):
        r"""__ne__(self, g) -> bool"""
        return _pyAgrum.DiGraph___ne__(self, g)


    def eraseNode(self, id):
        r"""
        eraseNode(self, id)

        Erase the node and all the related arcs.

        Parameters
        ----------
        id : int
        	the id of the node

        """
        return _pyAgrum.DiGraph_eraseNode(self, id)


    def clear(self):
        r"""
        clear(self)

        Remove all the nodes and arcs from the graph.

        """
        return _pyAgrum.DiGraph_clear(self)


    def toDot(self):
        r"""
        toDot(self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format 

        """
        return _pyAgrum.DiGraph_toDot(self)


    def topologicalOrder(self, clear=True):
        r"""
        topologicalOrder(self, clear=True) -> gum::Sequence< gum::NodeId > const
        topologicalOrder(self) -> gum::Sequence< gum::NodeId > const &

        Returns
        -------
        List
            the list of the nodes Ids in a topological order

        Raises
        ------
        gum.InvalidDirectedCycle
          If this graph contains cycles

        """
        return _pyAgrum.DiGraph_topologicalOrder(self, clear)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.DiGraph___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.DiGraph___str__(self)


    def nodes(self):
        r"""
        nodes(self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.DiGraph_nodes(self)


    def addNodes(self, n):
        r"""
        addNodes(self, n) -> PyObject *

        Add n nodes.

        Parameters
        ----------
        n : int
          the number of nodes to add.

        Returns
        -------
        Set of int
          the new ids

        """
        return _pyAgrum.DiGraph_addNodes(self, n)


    def arcs(self):
        r"""
        arcs(self) -> PyObject *

        Returns
        -------
        List
        	the list of the arcs

        """
        return _pyAgrum.DiGraph_arcs(self)


    def parents(self, id):
        r"""
        parents(self, id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.DiGraph_parents(self, id)


    def children(self, id):
        r"""
        children(self, id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.DiGraph_children(self, id)


    def addNode(self):
        r"""
        addNode(self) -> gum::NodeId

        Returns
        -------
        int
          the new NodeId

        """
        return _pyAgrum.DiGraph_addNode(self)


    def addNodeWithId(self, id):
        r"""
        addNodeWithId(self, id)

        Add a node by choosing a new NodeId.

        Parameters
        ----------
        id : int
          The id of the new node

        Raises
        ------
        gum.DuplicateElement
          If the given id is already used

        """
        return _pyAgrum.DiGraph_addNodeWithId(self, id)


    def existsNode(self, id):
        r"""
        existsNode(self, id) -> bool

        Check if a node with a certain id exists in the graph.

        Parameters
        ----------
        id : int
            the checked id

        Returns
        -------
        bool
            True if the node exists

        """
        return _pyAgrum.DiGraph_existsNode(self, id)


    def size(self):
        r"""
        size(self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.DiGraph_size(self)


    def empty(self):
        r"""
        empty(self) -> bool

        Check if the graph is empty.

        Returns
        -------
        bool
            True if the graph is empty

        """
        return _pyAgrum.DiGraph_empty(self)


    def addArc(self, *args):
        r"""
        addArc(self, tail, head)
        addArc(self, n1, n2)

        Add an arc from tail to head.

        Parameters
        ----------
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        Raises
        ------
        gum.InvalidNode
          If head or tail does not belong to the graph nodes.

        """
        return _pyAgrum.DiGraph_addArc(self, *args)


    def eraseArc(self, n1, n2):
        r"""
        eraseArc(self, n1, n2)

        Erase the arc between n1 and n2.

        Parameters
        ----------
        n1 : int
        	the id of the tail node
        n2 : int
        	the id of the head node

        """
        return _pyAgrum.DiGraph_eraseArc(self, n1, n2)


    def existsArc(self, n1, n2):
        r"""
        existsArc(self, n1, n2) -> bool

        Check if an arc exists bewteen n1 and n2.

        Parameters
        ----------
        n1 : int
        	the id of the tail node
        n2 : int
        	the id of the head node

        Returns
        -------
        bool
            True if the arc exists

        """
        return _pyAgrum.DiGraph_existsArc(self, n1, n2)


    def eraseParents(self, n):
        r"""
        eraseParents(self, n)

        Erase the arcs coming to the node.

        Parameters
        ----------
        n : int
        	the id of the child node

        """
        return _pyAgrum.DiGraph_eraseParents(self, n)


    def eraseChildren(self, n):
        r"""
        eraseChildren(self, n)

        Erase the arcs heading through the node's children.

        Parameters
        ----------
        n : int
        	the id of the parent node

        """
        return _pyAgrum.DiGraph_eraseChildren(self, n)


    def sizeArcs(self):
        r"""
        sizeArcs(self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.DiGraph_sizeArcs(self)


    def emptyArcs(self):
        r"""
        emptyArcs(self) -> bool

        Check if the graph doesn't contains arcs.

        Returns
        -------
        bool
            True if the graph doesn't contains arcs

        """
        return _pyAgrum.DiGraph_emptyArcs(self)


# Register DiGraph in _pyAgrum:
_pyAgrum.DiGraph_swigregister(DiGraph)

class DAG(DiGraph):
    r"""

    DAG represents a Directed Acyclic Graph.

    Available constructors:
        ``DAG() -> DAG``

        ``DAG(src) -> DAG``

    Parameters
    ----------
    src : :class: DAG
      the DAG to copy

    """

    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__(self, nodes_size, nodes_resize_policy=True, arcs_size, arcs_resize_policy=True) -> DAG
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size) -> DAG
        __init__(self, nodes_size, nodes_resize_policy=True) -> DAG
        __init__(self, nodes_size) -> DAG
        __init__(self) -> DAG
        __init__(self, g) -> DAG
        """
        this = _pyAgrum.new_DAG(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DAG

    def addNodes(self, n):
        r"""addNodes(self, n) -> PyObject *"""
        return _pyAgrum.DAG_addNodes(self, n)


    def addArc(self, *args):
        r"""
        addArc(self, tail, head)
        addArc(self, n1, n2)

        Add an arc from tail to head.

        Parameters
        ----------
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        Raises
        ------
        gum.InvalidDirectedCircle
        	If any (directed) cycle is created by this arc
        gum.InvalidNode
        	If head or tail does not belong to the graph nodes

        """
        return _pyAgrum.DAG_addArc(self, *args)


# Register DAG in _pyAgrum:
_pyAgrum.DAG_swigregister(DAG)

class UndiGraph(object):
    r"""

    UndiGraph represents an Undirected Graph.

    Available constructors:
        ``UndiGraph() -> UndiGraph``

        ``UndiGraph(src) -> UndiGraph``

    Parameters
    ----------
    src : :class: UndiGraph
      the UndiGraph to copy


    """

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

    def __init__(self, *args):
        r"""
        __init__(self, nodes_size, nodes_resize_policy=True, edges_size, edges_resize_policy=True) -> UndiGraph
        __init__(self, nodes_size, nodes_resize_policy=True, edges_size) -> UndiGraph
        __init__(self, nodes_size, nodes_resize_policy=True) -> UndiGraph
        __init__(self, nodes_size) -> UndiGraph
        __init__(self) -> UndiGraph
        __init__(self, g) -> UndiGraph
        """
        this = _pyAgrum.new_UndiGraph(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_UndiGraph

    def __eq__(self, g):
        r"""__eq__(self, g) -> bool"""
        return _pyAgrum.UndiGraph___eq__(self, g)


    def __ne__(self, g):
        r"""__ne__(self, g) -> bool"""
        return _pyAgrum.UndiGraph___ne__(self, g)


    def eraseNode(self, id):
        r"""
        eraseNode(self, id)

        Erase the node and all the adjacent edges.

        Parameters
        ----------
        id : int
          the id of the node

        """
        return _pyAgrum.UndiGraph_eraseNode(self, id)


    def clear(self):
        r"""
        clear(self)

        Remove all the nodes and edges from the graph.

        """
        return _pyAgrum.UndiGraph_clear(self)


    def toDot(self):
        r"""
        toDot(self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.UndiGraph_toDot(self)


    def hasUndirectedCycle(self):
        r"""
        hasUndirectedCycle(self) -> bool

        Checks whether the graph contains cycles.

        Returns
        -------
        bool
            True if the graph contains a cycle

        """
        return _pyAgrum.UndiGraph_hasUndirectedCycle(self)


    def partialUndiGraph(self, nodesSet):
        r"""
        partialUndiGraph(self, nodesSet) -> UndiGraph

        Parameters
        ----------
        nodesSet : Set
            The set of nodes composing the partial graph

        Returns
        -------
        pyAgrum.UndiGraph
            The partial graph formed by the nodes given in parameter

        """
        return _pyAgrum.UndiGraph_partialUndiGraph(self, nodesSet)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.UndiGraph___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.UndiGraph___str__(self)


    def nodes(self):
        r"""
        nodes(self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.UndiGraph_nodes(self)


    def addNodes(self, n):
        r"""
        addNodes(self, n) -> PyObject *

        Add n nodes.

        Parameters
        ----------
        n : int
          the number of nodes to add.

        Returns
        -------
        Set of int
          the new ids

        """
        return _pyAgrum.UndiGraph_addNodes(self, n)


    def edges(self):
        r"""
        edges(self) -> PyObject *

        Returns
        -------
        List
          the list of the edges

        """
        return _pyAgrum.UndiGraph_edges(self)


    def neighbours(self, id):
        r"""
        neighbours(self, id) -> PyObject *

        Parameters
        ----------
        id : int
            the id of the checked node

        Returns
        -------
        Set
            The set of edges adjacent to the given node

        """
        return _pyAgrum.UndiGraph_neighbours(self, id)


    def addNode(self):
        r"""
        addNode(self) -> gum::NodeId

        Returns
        -------
        int
          the new NodeId

        """
        return _pyAgrum.UndiGraph_addNode(self)


    def addNodeWithId(self, id):
        r"""
        addNodeWithId(self, id)

        Add a node by choosing a new NodeId.

        Parameters
        ----------
        id : int
          The id of the new node

        Raises
        ------
        gum.DuplicateElement
          If the given id is already used

        """
        return _pyAgrum.UndiGraph_addNodeWithId(self, id)


    def existsNode(self, id):
        r"""
        existsNode(self, id) -> bool

        Check if a node with a certain id exists in the graph.

        Parameters
        ----------
        id : int
            the checked id

        Returns
        -------
        bool
            True if the node exists

        """
        return _pyAgrum.UndiGraph_existsNode(self, id)


    def size(self):
        r"""
        size(self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.UndiGraph_size(self)


    def empty(self):
        r"""
        empty(self) -> bool

        Check if the graph is empty.

        Returns
        -------
        bool
            True if the graph is empty

        """
        return _pyAgrum.UndiGraph_empty(self)


    def addEdge(self, n1, n2):
        r"""
        addEdge(self, n1, n2)

        Insert a new edge into the graph.

        Parameters
        ----------
        n1 : int
          the id of one node of the new inserted edge
        n2 : int
          the id of the other node of the new inserted edge

        Raises
        ------
        gum.InvalidNode
          If n1 or n2 does not belong to the graph nodes.

        """
        return _pyAgrum.UndiGraph_addEdge(self, n1, n2)


    def eraseEdge(self, n1, n2):
        r"""
        eraseEdge(self, n1, n2)

        Erase the edge between n1 and n2.

        Parameters
        ----------
        n1 : int
          the id of the tail node
        n2 : int
          the id of the head node

        """
        return _pyAgrum.UndiGraph_eraseEdge(self, n1, n2)


    def existsEdge(self, n1, n2):
        r"""
        existsEdge(self, n1, n2) -> bool

        Check if an edge exists bewteen n1 and n2.

        Parameters
        ----------
        n1 : int
          the id of one extremity of the edge
        n2 : int
          the id of the other extremity if tge edge

        Returns
        -------
        bool
            True if the arc exists

        """
        return _pyAgrum.UndiGraph_existsEdge(self, n1, n2)


    def sizeEdges(self):
        r"""
        sizeEdges(self) -> gum::Size

        Returns
        -------
        int
            the number of edges in the graph

        """
        return _pyAgrum.UndiGraph_sizeEdges(self)


    def emptyEdges(self):
        r"""
        emptyEdges(self) -> bool

        Check if the graph doesn't contains edges.

        Returns
        -------
        bool
            True if the graph doesn't contains edges

        """
        return _pyAgrum.UndiGraph_emptyEdges(self)


    def eraseNeighbours(self, n):
        r"""
        eraseNeighbours(self, n)

        Erase all the edges adjacent to a given node.

        Parameters
        ----------
        n : int
          the id of the node

        """
        return _pyAgrum.UndiGraph_eraseNeighbours(self, n)


# Register UndiGraph in _pyAgrum:
_pyAgrum.UndiGraph_swigregister(UndiGraph)

class MixedGraph(UndiGraph, DiGraph):
    r"""

    MixedGraph represents a Clique Graph.

    Available constructors:
        ``MixedGraph() -> MixedGraph``

        ``MixedGraph(src) -> MixedGraph``

    Parameters
    ----------
    src : pyAgrum.MixedGraph
      the MixedGraph to copy

    """

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

    def __init__(self, *args):
        r"""
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size, arcs_resize_policy=True, edges_size, edges_resize_policy=True) -> MixedGraph
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size, arcs_resize_policy=True, edges_size) -> MixedGraph
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size, arcs_resize_policy=True) -> MixedGraph
        __init__(self, nodes_size, nodes_resize_policy=True, arcs_size) -> MixedGraph
        __init__(self, nodes_size, nodes_resize_policy=True) -> MixedGraph
        __init__(self, nodes_size) -> MixedGraph
        __init__(self) -> MixedGraph
        __init__(self, g) -> MixedGraph
        """
        this = _pyAgrum.new_MixedGraph(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_MixedGraph

    def __eq__(self, g):
        r"""__eq__(self, g) -> bool"""
        return _pyAgrum.MixedGraph___eq__(self, g)


    def __ne__(self, g):
        r"""__ne__(self, g) -> bool"""
        return _pyAgrum.MixedGraph___ne__(self, g)


    def eraseNode(self, id):
        r"""
        eraseNode(self, id)

        Erase the node and all the adjacent edges.

        Parameters
        ----------
        id : int
          the id of the node

        """
        return _pyAgrum.MixedGraph_eraseNode(self, id)


    def clear(self):
        r"""
        clear(self)

        Remove all the nodes and edges from the graph.

        """
        return _pyAgrum.MixedGraph_clear(self)


    def mixedOrientedPath(self, node1, node2):
        r"""
        mixedOrientedPath(self, node1, node2) -> Vector_int

        Parameters
        ----------
        node1 : int
        	the id form which the path begins
        node2 : int
        	the id to witch the path ends

        Returns
        -------
        List
        	 a path from node1 to node2, using edges and/or arcs (following the direction of the arcs)

        Raises
        ------
        gum.NotFound
        	If no path can be found between the two nodes

        """
        return _pyAgrum.MixedGraph_mixedOrientedPath(self, node1, node2)


    def mixedUnorientedPath(self, node1, node2):
        r"""
        mixedUnorientedPath(self, node1, node2) -> Vector_int

        Parameters
        ----------
        node1 : int
        	the id from which the path begins
        node2 : int
        	the id to which the path ends

        Returns
        -------
        List
        	 a path from node1 to node2, using edges and/or arcs (not necessarily following the direction of the arcs)

        Raises
        ------
        gum.NotFound
        	If no path can be found between the two nodes

        """
        return _pyAgrum.MixedGraph_mixedUnorientedPath(self, node1, node2)


    def toDot(self):
        r"""
        toDot(self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.MixedGraph_toDot(self)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.MixedGraph___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.MixedGraph___str__(self)


# Register MixedGraph in _pyAgrum:
_pyAgrum.MixedGraph_swigregister(MixedGraph)

class CliqueGraph(UndiGraph):
    r"""

    CliqueGraph represents a Clique Graph.

    Available constructors:
        ``CliqueGraph() -> CliqueGraph``

        ``CliqueGraph(src) -> CliqueGraph``

    Parameters
    ----------
    src : pyAgrum.CliqueGraph
      the CliqueGraph to copy

    """

    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__(self, nodes_size, nodes_resize_policy=True, edges_size, edges_resize_policy=True) -> CliqueGraph
        __init__(self, nodes_size, nodes_resize_policy=True, edges_size) -> CliqueGraph
        __init__(self, nodes_size, nodes_resize_policy=True) -> CliqueGraph
        __init__(self, nodes_size) -> CliqueGraph
        __init__(self) -> CliqueGraph
        __init__(self, arg2) -> CliqueGraph
        """
        this = _pyAgrum.new_CliqueGraph(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_CliqueGraph

    def addEdge(self, first, second):
        r"""
        addEdge(self, first, second)

        Insert a new edge into the graph.

        Parameters
        ----------
        n1 : int
          the id of one node of the new inserted edge
        n2 : int
          the id of the other node of the new inserted edge

        Raises
        ------
        gum.InvalidNode
          If n1 or n2 does not belong to the graph nodes.

        """
        return _pyAgrum.CliqueGraph_addEdge(self, first, second)


    def eraseEdge(self, edge):
        r"""
        eraseEdge(self, edge)

        Erase the edge between n1 and n2.

        Parameters
        ----------
        n1 : int
          the id of the tail node
        n2 : int
          the id of the head node

        """
        return _pyAgrum.CliqueGraph_eraseEdge(self, edge)


    def clearEdges(self):
        r"""
        clearEdges(self)

        Remove all edges and their separators 

        """
        return _pyAgrum.CliqueGraph_clearEdges(self)


    def addNode(self, *args):
        r"""
        addNode(self, clique) -> gum::NodeId
        addNode(self) -> gum::NodeId
        addNode(self, id, clique)
        addNode(self, id)

        Returns
        -------
        int
          the new NodeId

        """
        return _pyAgrum.CliqueGraph_addNode(self, *args)


    def eraseNode(self, node):
        r"""
        eraseNode(self, node)

        Erase the node and all the adjacent edges.

        Parameters
        ----------
        id : int
          the id of the node

        """
        return _pyAgrum.CliqueGraph_eraseNode(self, node)


    def clear(self):
        r"""
        clear(self)

        Remove all the nodes and edges from the graph.

        """
        return _pyAgrum.CliqueGraph_clear(self)


    def container(self, idNode):
        r"""
        container(self, idNode) -> gum::NodeId

        Parameters
        ----------
        idNode : int
          the id of the node

        Returns
        -------
        int
          the id of a clique containing the node

        Raises
        ------
        gum.NotFound
          If no clique contains idNode  

        """
        return _pyAgrum.CliqueGraph_container(self, idNode)


    def setClique(self, idClique, new_clique):
        r"""
        setClique(self, idClique, new_clique)

        changes the set of nodes included into a given clique

        Parameters
        ----------
        idClique : int
          the id of the clique
        new_clique : Set
          the new set of nodes to be included in the clique

        Raises
        ------
        gum.NotFound
          If idClique is not a clique of the graph

        """
        return _pyAgrum.CliqueGraph_setClique(self, idClique, new_clique)


    def addToClique(self, clique_id, node_id):
        r"""
        addToClique(self, clique_id, node_id)

        Change the set of nodes included into a given clique and returns the new set 

        Parameters
        ----------
        clique_id : int
          the id of the clique
        node_id : int
          the id of the node

        Raises
        ------
        gum.NotFound
          If clique_id does not exist
        gum.DuplicateElement
          If clique_id set already contains the ndoe

        """
        return _pyAgrum.CliqueGraph_addToClique(self, clique_id, node_id)


    def eraseFromClique(self, clique_id, node_id):
        r"""
        eraseFromClique(self, clique_id, node_id)

        Remove a node from a clique

        Parameters
        ----------
        clique_id : int
          the id of the clique
        node_id : int
          the id of the node

        Raises
        ------
        gum.NotFound
          If clique_id does not exist

        """
        return _pyAgrum.CliqueGraph_eraseFromClique(self, clique_id, node_id)


    def separator(self, *args):
        r"""
        separator(self, edge) -> gum::NodeSet const
        separator(self, clique1, clique) -> gum::NodeSet const &

        Parameters
        ----------
        edge : pyAgrum.Edge
          the edge to be checked
        clique1 : int 
          one extremity of the edge
        clique : int 
          the other extremity of the edge

        Returns
        -------
        Set
          the separator included in a given edge

        Raises
        ------
        gum.NotFound
          If the edge does not belong to the clique graph

        """
        return _pyAgrum.CliqueGraph_separator(self, *args)


    def containerPath(self, node1, node2):
        r"""
        containerPath(self, node1, node2) -> Vector_int

        Parameters
        ----------
        node1 : int
          the id of one node
        node2 : int
          the id of the other node

        Returns
        -------
        List
          a path from a clique containing node1 to a clique containing node2

        Raises
        ------
        gum.NotFound 
          If such path cannot be found

        """
        return _pyAgrum.CliqueGraph_containerPath(self, node1, node2)


    def hasRunningIntersection(self):
        r"""
        hasRunningIntersection(self) -> bool

        Returns
        -------
        bool
          True if the running intersection property holds 

        """
        return _pyAgrum.CliqueGraph_hasRunningIntersection(self)


    def isJoinTree(self):
        r"""
        isJoinTree(self) -> bool

        Returns
        -------
        bool
          True if the graph is a join tree 

        """
        return _pyAgrum.CliqueGraph_isJoinTree(self)


    def toDot(self):
        r"""
        toDot(self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.CliqueGraph_toDot(self)


    def __ne__(self, arg2):
        r"""__ne__(self, arg2) -> bool"""
        return _pyAgrum.CliqueGraph___ne__(self, arg2)


    def __eq__(self, arg2):
        r"""__eq__(self, arg2) -> bool"""
        return _pyAgrum.CliqueGraph___eq__(self, arg2)


    def clique(self, clique):
        r"""
        clique(self, clique) -> PyObject *

        Parameters
        ----------
        idClique : int
          the id of the clique

        Returns
        -------
        Set
          The set of nodes included in the clique

        Raises
        ------
        gum.NotFound
          If the clique does not belong to the clique graph

        """
        return _pyAgrum.CliqueGraph_clique(self, clique)


    def toDotWithNames(self,bn):
        """
        Parameters
        ----------
        bn : pyAgrum.BayesNet
        a Bayesian network

        Returns
        -------
        str
          a friendly display of the graph in DOT format where ids have been changed according to their correspondance in the BN
        """
        def nameFromId(m):
          return " ".join([bn.variable(int(n)).name()
                           for n in m.group().split("-")])
        import re
        m = re.compile('(?<=label=\")\d+[\-\d+]*')
        return m.sub(nameFromId,self.toDot())


# Register CliqueGraph in _pyAgrum:
_pyAgrum.CliqueGraph_swigregister(CliqueGraph)

class Instantiation(object):
    r"""

    Class for assigning/browsing values to tuples of discrete variables.

    Instantiation is designed to assign values to tuples of variables and to efficiently loop over values of subsets of variables.

    Available constructors:

    	``Instantiation() -> Instantiation``

    	``Instantiation(aI) -> Instantiation``

    Parameters
    ----------
    aI: pyAgrum.Instantiation
      The Instantiation we copy

    Returns
    -------
    pyAgrum.Instantiation
    	An empty tuple or a copy of the one in parameters

    Instantiation is subscriptable therefore values can be easily accessed/modified.

    Examples
    --------
    >>> ## Access the value of A in an instantiation aI
    >>> valueOfA = aI['A']
    >>> ## Modify the value
    >>> aI['A'] = newValueOfA

    """

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

    def __init__(self, *args):
        r"""
        __init__(self) -> Instantiation
        __init__(self, aI, notifyMaster=True) -> Instantiation
        __init__(self, aI) -> Instantiation
        __init__(self, aMD) -> Instantiation
        __init__(self, aMD) -> Instantiation
        __init__(self, aMD) -> Instantiation
        __init__(self, aMD) -> Instantiation
        """
        this = _pyAgrum.new_Instantiation(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_Instantiation

    def nbrDim(self):
        r"""
        nbrDim(self) -> gum::Idx

        Returns
        -------
        int
            The number of variables in the Instantiation.

        """
        return _pyAgrum.Instantiation_nbrDim(self)


    def add(self, v):
        r"""
        add(self, v)

        Adds a new variable in the Instantiation.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The new variable added to the Instantiation

        Raises
        ------
        DuplicateElement
          If the variable is already in this Instantiation


        """
        return _pyAgrum.Instantiation_add(self, v)


    def erase(self, v):
        r"""
        erase(self, v)

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable to be removed from this Instantiation.

        Raises
        ------
        NotFound
          If v does not belong to this Instantiation.

        """
        return _pyAgrum.Instantiation_erase(self, v)


    def clear(self):
        r"""
        clear(self)

        Erase all variables from an Instantiation.

        """
        return _pyAgrum.Instantiation_clear(self)


    def domainSize(self):
        r"""
        domainSize(self) -> gum::Size

        Returns
        -------
        int
            The product of the variable's domain size in the Instantiation.

        """
        return _pyAgrum.Instantiation_domainSize(self)


    def pos(self, v):
        r"""
        pos(self, v) -> gum::Idx

        Returns
        -------
        int
           the position of the variable v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            the variable for which its position is return.

        Raises
        ------
        NotFound
          If v does not belong to the instantiation.

        """
        return _pyAgrum.Instantiation_pos(self, v)


    def val(self, *args):
        r"""
        val(self, i) -> gum::Idx
        val(self, var) -> gum::Idx

        Parameters
        ----------
        i : int
        	The index of the variable.
        var : pyAgrum.DiscreteVariable
        	The variable the value of which we wish to know

        Returns
        -------
        int
        	the current value of the variable.

        Raises
        ------
        NotFound
          If the element cannot be found.

        """
        return _pyAgrum.Instantiation_val(self, *args)


    def variable(self, *args):
        r"""
        variable(self, i) -> DiscreteVariable
        variable(self, name) -> DiscreteVariable

        Parameters
        ----------
        i : int
          The index of the variable

        Returns
        -------
        pyAgrum.DiscreteVariable
          the variable at position i in the tuple.

        Raises
        ------
        NotFound
          If the element cannot be found.

        """
        return _pyAgrum.Instantiation_variable(self, *args)


    def chgVal(self, *args):
        r"""
        chgVal(self, v, newval) -> Instantiation
        chgVal(self, v, newval) -> Instantiation
        chgVal(self, varPos, newval) -> Instantiation
        chgVal(self, var, newval) -> Instantiation
        chgVal(self, var, newval) -> Instantiation

        Assign newval to v (or to the variable at position varPos) in the Instantiation.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable or string
          The variable whose value is assigned (or its name)
        varPos : int
          The index of the variable whose value is assigned in the tuple of variables of the Instantiation
        newval : int or string
          The index of the value assigned (or its name)

        Returns
        -------
        pyAgrum.Instantiation
            The modified instantiation

        Raises
        ------
        NotFound
          If variable v does not belong to the instantiation.
        OutOfBound
          If newval is not a possible value for the variable.

        """
        return _pyAgrum.Instantiation_chgVal(self, *args)


    def setVals(self, i):
        r"""
        setVals(self, i) -> Instantiation

        Assign the values from i in the Instantiation.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          An Instantiation in which the new values are searched

        Returns
        -------
        pyAgrum.Instantiation
          a reference to the instantiation

        """
        return _pyAgrum.Instantiation_setVals(self, i)


    def contains(self, *args):
        r"""
        contains(self, v) -> bool
        contains(self, v) -> bool

        Indicates whether a given variable belongs to the Instantiation.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable for which the test is made.

        Returns
        -------
        bool :
            True if the variable is in the Instantiation.

        """
        return _pyAgrum.Instantiation_contains(self, *args)


    def variablesSequence(self):
        r"""
        variablesSequence(self) -> gum::Sequence< gum::DiscreteVariable const * > const &

        Returns
        -------
        List
            the sequence of DiscreteVariable of this instantiation.

        """
        return _pyAgrum.Instantiation_variablesSequence(self)


    def empty(self):
        r"""
        empty(self) -> bool

        Returns
        -------
        bool
            True if the instantiation is empty.

        """
        return _pyAgrum.Instantiation_empty(self)


    def inOverflow(self):
        r"""
        inOverflow(self) -> bool

        Returns
        -------
        bool
          True if the current value of the tuple is correct

        """
        return _pyAgrum.Instantiation_inOverflow(self)


    def unsetOverflow(self):
        r"""
        unsetOverflow(self)

        Removes the flag overflow.

        """
        return _pyAgrum.Instantiation_unsetOverflow(self)


    def unsetEnd(self):
        r"""
        unsetEnd(self)

        Alias for unsetOverflow().

        """
        return _pyAgrum.Instantiation_unsetEnd(self)


    def end(self):
        r"""
        end(self) -> bool

        Returns
        -------
        bool
            True if the Instantiation reached the end.

        """
        return _pyAgrum.Instantiation_end(self)


    def rend(self):
        r"""
        rend(self) -> bool

        Returns
        -------
        bool:
          True if the Instantiation reached the rend.

        """
        return _pyAgrum.Instantiation_rend(self)


    def inc(self):
        r"""
        inc(self)

        Operator ++.

        """
        return _pyAgrum.Instantiation_inc(self)


    def dec(self):
        r"""
        dec(self)

        Operator --.

        """
        return _pyAgrum.Instantiation_dec(self)


    def incIn(self, i):
        r"""
        incIn(self, i)

        Operator ++ for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The set of variables to increment in this Instantiation.

        """
        return _pyAgrum.Instantiation_incIn(self, i)


    def decIn(self, i):
        r"""
        decIn(self, i)

        Operator -- for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The set of variables to decrement in this Instantiation

        """
        return _pyAgrum.Instantiation_decIn(self, i)


    def incOut(self, i):
        r"""
        incOut(self, i)

        Operator ++ for the variables not in i.

        Parameters
        ----------
        i : Instantiation
            The set of variable to not increment in this Instantiation.

        """
        return _pyAgrum.Instantiation_incOut(self, i)


    def decOut(self, i):
        r"""
        decOut(self, i)

        Operator -- for the variables not in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The set of variables to not decrement in this Instantiation.

        """
        return _pyAgrum.Instantiation_decOut(self, i)


    def incNotVar(self, v):
        r"""
        incNotVar(self, v)

        Operator ++ for vars which are not v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable not to increment in this Instantiation.

        """
        return _pyAgrum.Instantiation_incNotVar(self, v)


    def decNotVar(self, v):
        r"""
        decNotVar(self, v)

        Operator -- for vars which are not v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable not to decrement in this Instantiation.

        """
        return _pyAgrum.Instantiation_decNotVar(self, v)


    def incVar(self, v):
        r"""
        incVar(self, v)

        Operator ++ for variable v only.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable to increment in this Instantiation.

        Raises
        ------
        NotFound
          If variable v does not belong to the Instantiation.

        """
        return _pyAgrum.Instantiation_incVar(self, v)


    def decVar(self, v):
        r"""
        decVar(self, v)

        Operator -- for variable v only.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
         The variable to decrement in this Instantiation.

        Raises
        ------
        NotFound
          If variable v does not belong to the Instantiation.

        """
        return _pyAgrum.Instantiation_decVar(self, v)


    def setFirst(self):
        r"""
        setFirst(self)

        Assign the first values to the tuple of the Instantiation.

        """
        return _pyAgrum.Instantiation_setFirst(self)


    def setLast(self):
        r"""
        setLast(self)

        Assign the last values in the Instantiation.

        """
        return _pyAgrum.Instantiation_setLast(self)


    def setFirstIn(self, i):
        r"""
        setFirstIn(self, i)

        Assign the first values in the Instantiation for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The variables to which their first value is assigned in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstIn(self, i)


    def setLastIn(self, i):
        r"""
        setLastIn(self, i)

        Assign the last values in the Instantiation for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The variables to which their last value is assigned in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastIn(self, i)


    def setFirstOut(self, i):
        r"""
        setFirstOut(self, i)

        Assign the first values in the Instantiation for the variables not in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The variable that will not be set to their first value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstOut(self, i)


    def setLastOut(self, i):
        r"""
        setLastOut(self, i)

        Assign the last values in the Instantiation for the variables not in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The variables that will not be set to their last value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastOut(self, i)


    def setFirstNotVar(self, v):
        r"""
        setFirstNotVar(self, v)

        Assign the first values to variables different of v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable that will not be set to its first value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstNotVar(self, v)


    def setLastNotVar(self, v):
        r"""
        setLastNotVar(self, v)

        Assign the last values to variables different of v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable that will not be set to its last value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastNotVar(self, v)


    def setFirstVar(self, v):
        r"""
        setFirstVar(self, v)

        Assign the first value in the Instantiation for var v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable that will be set to its first value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstVar(self, v)


    def setLastVar(self, v):
        r"""
        setLastVar(self, v)

        Assign the last value in the Instantiation for var v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable that will be set to its last value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastVar(self, v)


    def __eq__(self, other):
        r"""__eq__(self, other) -> bool"""
        return _pyAgrum.Instantiation___eq__(self, other)


    def __iadd__(self, depl):
        r"""__iadd__(self, depl) -> Instantiation"""
        return _pyAgrum.Instantiation___iadd__(self, depl)


    def __isub__(self, depl):
        r"""__isub__(self, depl) -> Instantiation"""
        return _pyAgrum.Instantiation___isub__(self, depl)


    def hamming(self):
        r"""
        hamming(self) -> gum::Idx

        Returns
        -------
        int
          the hamming distance of this instantiation.

        """
        return _pyAgrum.Instantiation_hamming(self)


    def reorder(self, *args):
        r"""
        reorder(self, v)
        reorder(self, i)

        Reorder vars of this instantiation giving the order in v (or i).

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The sequence of variables with which to reorder this Instantiation.
        v : list
            The new order of variables for this Instantiation.

        """
        return _pyAgrum.Instantiation_reorder(self, *args)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.Instantiation___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.Instantiation___str__(self)


    def todict(self, withLabels=False):
        r"""
        todict(self, withLabels=False) -> PyObject
        todict(self) -> PyObject *

        Create a dict (variable_name:value) from an instantiation

        Parameters
        ----------
        withLabels : boolean
        	The value will be a label (string) if True. It will be a position (int) if False.

        Returns
        -------
        Dict
            The dictionary

        """
        return _pyAgrum.Instantiation_todict(self, withLabels)


    def fromdict(self, dict):
        r"""
        fromdict(self, dict)

        Change the values in an instantiation from a dict (variable_name:value) where value can be a position (int) or a label (string).

        If a variable_name does not occur in the instantiation, nothing is done.

        Warnings
        --------
            OutOfBounds raised if a value cannot be found.

        """
        return _pyAgrum.Instantiation_fromdict(self, dict)


    def __setitem__(self,key,item):
      self.chgVal(key,item)

    def __getitem__(self,key):
      return self.val(self.variable(key))


# Register Instantiation in _pyAgrum:
_pyAgrum.Instantiation_swigregister(Instantiation)

GUM_DEFAULT_ITERATOR_NUMBER = _pyAgrum.GUM_DEFAULT_ITERATOR_NUMBER

class DAGmodel(object):
    r"""

    Abstract class used by IBayesNet and InfluenceDiagram.

    """

    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__ = _pyAgrum.delete_DAGmodel

    def property(self, name):
        r"""
        property(self, name) -> std::string const &

        Warnings
        --------
        Unreferenced function

        """
        return _pyAgrum.DAGmodel_property(self, name)


    def propertyWithDefault(self, name, byDefault):
        r"""
        propertyWithDefault(self, name, byDefault) -> std::string const &

        Warnings
        --------
        Unreferenced function

        """
        return _pyAgrum.DAGmodel_propertyWithDefault(self, name, byDefault)


    def setProperty(self, name, value):
        r"""
        setProperty(self, name, value)

        Warnings
        --------
        Unreferenced function

        """
        return _pyAgrum.DAGmodel_setProperty(self, name, value)


    def dag(self):
        r"""
        dag(self) -> DAG

        Returns
        -------
        pyAgrum.DAG
        	a constant reference to the dag of this BayesNet.

        """
        return _pyAgrum.DAGmodel_dag(self)


    def variableNodeMap(self):
        r"""
        variableNodeMap(self) -> VariableNodeMap

        Returns
        -------
        pyAgrum.variableNodeMap
        	the variable node map

        """
        return _pyAgrum.DAGmodel_variableNodeMap(self)


    def size(self):
        r"""
        size(self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.DAGmodel_size(self)


    def sizeArcs(self):
        r"""
        sizeArcs(self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.DAGmodel_sizeArcs(self)


    def empty(self):
        r"""
        empty(self) -> bool

        Returns
        -------
        bool
        	True if the model is empty

        """
        return _pyAgrum.DAGmodel_empty(self)


    def nodes(self):
        r"""
        nodes(self) -> NodeGraphPart

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.DAGmodel_nodes(self)


    def variable(self, id):
        r"""
        variable(self, id) -> DiscreteVariable

        Parameters
        ----------
        id : int
        	a variable's id
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.DAGmodel_variable(self, id)


    def nodeId(self, var):
        r"""
        nodeId(self, var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.DAGmodel_nodeId(self, var)


    def idFromName(self, name):
        r"""
        idFromName(self, name) -> gum::NodeId

        Returns a variable's id given its name in the graph.

        Parameters
        ----------
        name : str
        	The variable's name from which the id is returned.

        Returns
        -------
        int :
        	The variable's node id.

        Raises
        ------
        gum.NotFound
        	If name does not match a variable in the graph

        """
        return _pyAgrum.DAGmodel_idFromName(self, name)


    def variableFromName(self, name):
        r"""
        variableFromName(self, name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.DAGmodel_variableFromName(self, name)


    def completeInstantiation(self):
        r"""
        completeInstantiation(self) -> Instantiation

        Get an instantiation over all the variables of the model.

        Returns
        ----------
        pyAgrum.instantiation
        	the complete instantiation

        """
        return _pyAgrum.DAGmodel_completeInstantiation(self)


    def arcs(self):
        r"""
        arcs(self) -> gum::ArcSet const &

        Returns
        -------
        list
        	The lisf of arcs in the graph

        """
        return _pyAgrum.DAGmodel_arcs(self)


    def parents(self, *args):
        r"""
        parents(self, id) -> gum::NodeSet const
        parents(self, name) -> gum::NodeSet const &
        """
        return _pyAgrum.DAGmodel_parents(self, *args)


    def children(self, *args):
        r"""
        children(self, id) -> gum::NodeSet const
        children(self, name) -> gum::NodeSet const &
        """
        return _pyAgrum.DAGmodel_children(self, *args)


    def moralGraph(self, clear=True):
        r"""
        moralGraph(self, clear=True) -> UndiGraph
        moralGraph(self) -> UndiGraph

        Returns the moral graph of the BayesNet, formed by adding edges between all pairs of nodes that have a common child, and then making all edges in the graph undirected.

        Returns
        -------
        pyAgrum.UndiGraph
        	The moral graph

        """
        return _pyAgrum.DAGmodel_moralGraph(self, clear)


    def topologicalOrder(self, clear=True):
        r"""
        topologicalOrder(self, clear=True) -> gum::Sequence< gum::NodeId > const
        topologicalOrder(self) -> gum::Sequence< gum::NodeId > const &

        Returns
        -------
        List
            the list of the nodes Ids in a topological order

        Raises
        ------
        gum.InvalidDirectedCycle
        	If this graph contains cycles

        """
        return _pyAgrum.DAGmodel_topologicalOrder(self, clear)


    def log10DomainSize(self):
        r"""
        log10DomainSize(self) -> double

        Returns
        -------
        double
        	The log10 domain size of the joint probability for the model.

        """
        return _pyAgrum.DAGmodel_log10DomainSize(self)


    def hasSameStructure(self, other):
        r"""
        hasSameStructure(self, other) -> bool

        Parameters
        ----------
        pyAgrum.DAGmodel
        	a direct acyclic model

        Returns
        -------
        bool
            True if all the named node are the same and all the named arcs are the same

        """
        return _pyAgrum.DAGmodel_hasSameStructure(self, other)


# Register DAGmodel in _pyAgrum:
_pyAgrum.DAGmodel_swigregister(DAGmodel)
cvar = _pyAgrum.cvar
__list_end_safe = cvar.__list_end_safe
__list_end = cvar.__list_end

class EssentialGraph(object):
    r"""Proxy of C++ gum::EssentialGraph 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__(self) -> EssentialGraph
        __init__(self, m) -> EssentialGraph
        __init__(self, m, mg) -> EssentialGraph
        __init__(self, g) -> EssentialGraph
        """
        this = _pyAgrum.new_EssentialGraph(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_EssentialGraph

    def mixedGraph(self):
        r"""
        mixedGraph(self) -> MixedGraph

        Returns
        -------
        pyAgrum.MixedGraph
        	the mixed graph

        """
        return _pyAgrum.EssentialGraph_mixedGraph(self)


    def toDot(self):
        r"""
        toDot(self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format 

        """
        return _pyAgrum.EssentialGraph_toDot(self)


    def sizeArcs(self):
        r"""
        sizeArcs(self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.EssentialGraph_sizeArcs(self)


    def sizeEdges(self):
        r"""
        sizeEdges(self) -> gum::Size

        Returns
        -------
        int
            the number of edges in the graph

        """
        return _pyAgrum.EssentialGraph_sizeEdges(self)


    def sizeNodes(self):
        r"""
        sizeNodes(self) -> gum::Size

        Returns
        -------
        int
        	the number of nodes in the graph

        """
        return _pyAgrum.EssentialGraph_sizeNodes(self)


    def size(self):
        r"""
        size(self) -> gum::Size

        Returns
        -------
        int
        	the number of nodes in the graph

        """
        return _pyAgrum.EssentialGraph_size(self)


    def nodes(self):
        r"""nodes(self) -> PyObject *"""
        return _pyAgrum.EssentialGraph_nodes(self)


    def arcs(self):
        r"""
        arcs(self) -> PyObject *

        Returns
        -------
        list
        	The lisf of arcs in the EssentialGraph

        """
        return _pyAgrum.EssentialGraph_arcs(self)


    def parents(self, id):
        r"""
        parents(self, id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.EssentialGraph_parents(self, id)


    def children(self, id):
        r"""
        children(self, id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.EssentialGraph_children(self, id)


    def edges(self):
        r"""
        edges(self) -> PyObject *

        Returns
        -------
        List
          the list of the edges

        """
        return _pyAgrum.EssentialGraph_edges(self)


    def neighbours(self, id):
        r"""
        neighbours(self, id) -> PyObject *

        Parameters
        ----------
        id : int
            the id of the checked node

        Returns
        -------
        Set
            The set of edges adjacent to the given node 

        """
        return _pyAgrum.EssentialGraph_neighbours(self, id)


# Register EssentialGraph in _pyAgrum:
_pyAgrum.EssentialGraph_swigregister(EssentialGraph)

class MarkovBlanket(object):
    r"""Proxy of C++ gum::MarkovBlanket 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__(self, m, n) -> MarkovBlanket
        __init__(self, m, name) -> MarkovBlanket
        """
        this = _pyAgrum.new_MarkovBlanket(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_MarkovBlanket

    def mb(self):
        r"""
        mb(self) -> DiGraph

        Returns
        -------
        pyAgrum.DiGraph
          a copy of the directed graph

        """
        return _pyAgrum.MarkovBlanket_mb(self)


    def toDot(self):
        r"""
        toDot(self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format 

        """
        return _pyAgrum.MarkovBlanket_toDot(self)


    def sizeArcs(self):
        r"""
        sizeArcs(self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.MarkovBlanket_sizeArcs(self)


    def sizeNodes(self):
        r"""
        sizeNodes(self) -> gum::Size

        Returns
        -------
        int
        	the number of nodes in the graph

        """
        return _pyAgrum.MarkovBlanket_sizeNodes(self)


    def size(self):
        r"""
        size(self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.MarkovBlanket_size(self)


    def hasSameStructure(self, other):
        r"""
        hasSameStructure(self, other) -> bool

        Parameters
        ----------
        pyAgrum.DAGmodel
        	a direct acyclic model

        Returns
        -------
        bool
            True if all the named node are the same and all the named arcs are the same 

        """
        return _pyAgrum.MarkovBlanket_hasSameStructure(self, other)


    def nodes(self):
        r"""
        nodes(self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.MarkovBlanket_nodes(self)


    def arcs(self):
        r"""
        arcs(self) -> PyObject *

        Returns
        -------
        List
        	the list of the arcs

        """
        return _pyAgrum.MarkovBlanket_arcs(self)


    def parents(self, id):
        r"""
        parents(self, id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.MarkovBlanket_parents(self, id)


    def children(self, id):
        r"""
        children(self, id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.MarkovBlanket_children(self, id)


# Register MarkovBlanket in _pyAgrum:
_pyAgrum.MarkovBlanket_swigregister(MarkovBlanket)

class StructuralComparator(object):
    r"""Proxy of C++ gum::StructuralComparator 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):
        r"""__init__(self) -> StructuralComparator"""
        this = _pyAgrum.new_StructuralComparator()
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_StructuralComparator

    def compare(self, *args):
        r"""
        compare(self, ref, test)
        compare(self, ref, test)
        compare(self, ref, test)

        Use to compare the edges/arcs of two structure of the same type and same sizes (either DiGraph, UndiGraph or MixedGraph).

        Could be use to compare a BN and its learned version.

        Parameters
        ----------
        ref :
        	the structure of reference
        test :
        	the structure we want to test

        """
        return _pyAgrum.StructuralComparator_compare(self, *args)


    def precision_skeleton(self):
        r"""
        precision_skeleton(self) -> double

        Rate of true postive over labelized edges.

        Returns
        -------
        double
        	the precision of the tested graph skeleton

        """
        return _pyAgrum.StructuralComparator_precision_skeleton(self)


    def recall_skeleton(self):
        r"""
        recall_skeleton(self) -> double

        Rate of true postive over labelized edges.

        Returns
        -------
        double
        	the recall of the tested graph skeleton

        """
        return _pyAgrum.StructuralComparator_recall_skeleton(self)


    def f_score_skeleton(self):
        r"""
        f_score_skeleton(self) -> double

        Harmonic mean between recall and precision.

        Returns
        -------
        double
        	the tarmonic mean of the tested graph skeleton

        """
        return _pyAgrum.StructuralComparator_f_score_skeleton(self)


    def precision(self):
        r"""
        precision(self) -> double

        Rate of true postive over postively labelized arcs/edges.

        Returns
        -------
        double
        	the precision of the tested graph

        """
        return _pyAgrum.StructuralComparator_precision(self)


    def recall(self):
        r"""
        recall(self) -> double

        Rate of true postive over labelized arcs/edges.

        Returns
        -------
        double
        	the recall of the tested graph

        """
        return _pyAgrum.StructuralComparator_recall(self)


    def f_score(self):
        r"""
        f_score(self) -> double

        Harmonic mean between recall and precision.

        Returns
        -------
        double
        	the harmonic mean of the tested graph

        """
        return _pyAgrum.StructuralComparator_f_score(self)


# Register StructuralComparator in _pyAgrum:
_pyAgrum.StructuralComparator_swigregister(StructuralComparator)

class ApproximationScheme(object):
    r"""

    Used to parametrize stopping criteria in approximate inference or learning algorithm.

    Available constructors:
    	``ApproximationScheme() -> ApproximationScheme``

    	``ApproximationScheme(v) -> ApproximationScheme``

    Parameters
    ----------
    v : bool

    """

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

    def __init__(self, v=False):
        r"""
        __init__(self, v=False) -> ApproximationScheme
        __init__(self) -> ApproximationScheme
        """
        this = _pyAgrum.new_ApproximationScheme(v)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_ApproximationScheme

    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.ApproximationScheme_setEpsilon(self, eps)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.ApproximationScheme_epsilon(self)


    def disableEpsilon(self):
        r"""
        disableEpsilon(self)

        Disable epsilon as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableEpsilon(self)


    def enableEpsilon(self):
        r"""
        enableEpsilon(self)

        Enable epsilon as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableEpsilon(self)


    def isEnabledEpsilon(self):
        r"""
        isEnabledEpsilon(self) -> bool

        Returns
        -------
        bool
          True if epsilon is used as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_isEnabledEpsilon(self)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.ApproximationScheme_setMinEpsilonRate(self, rate)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.ApproximationScheme_minEpsilonRate(self)


    def disableMinEpsilonRate(self):
        r"""
        disableMinEpsilonRate(self)

        Disable a min epsilon rate as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableMinEpsilonRate(self)


    def enableMinEpsilonRate(self):
        r"""
        enableMinEpsilonRate(self)

        Enable a min epsilon rate as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableMinEpsilonRate(self)


    def isEnabledMinEpsilonRate(self):
        r"""
        isEnabledMinEpsilonRate(self) -> bool

        Returns
        -------
        bool
          True if epsilon rate is used as a stopping criterion

        """
        return _pyAgrum.ApproximationScheme_isEnabledMinEpsilonRate(self)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.ApproximationScheme_setMaxIter(self, max)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.ApproximationScheme_maxIter(self)


    def disableMaxIter(self):
        r"""
        disableMaxIter(self)

        Disable max iterations as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableMaxIter(self)


    def enableMaxIter(self):
        r"""
        enableMaxIter(self)

        Enable max iterations as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableMaxIter(self)


    def isEnabledMaxIter(self):
        r"""
        isEnabledMaxIter(self) -> bool

        Returns
        -------
        bool
          True if max iterations is used as a stopping criterion

        """
        return _pyAgrum.ApproximationScheme_isEnabledMaxIter(self)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.ApproximationScheme_setMaxTime(self, timeout)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.ApproximationScheme_maxTime(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.ApproximationScheme_currentTime(self)


    def disableMaxTime(self):
        r"""
        disableMaxTime(self)

        Disable max time as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableMaxTime(self)


    def enableMaxTime(self):
        r"""
        enableMaxTime(self)

        Enable max time as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableMaxTime(self)


    def isEnabledMaxTime(self):
        r"""
        isEnabledMaxTime(self) -> bool

        Returns
        -------
        bool
          True if max time is used as a stopping criterion

        """
        return _pyAgrum.ApproximationScheme_isEnabledMaxTime(self)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ApproximationScheme_setPeriodSize(self, p)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ApproximationScheme_periodSize(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.ApproximationScheme_setVerbosity(self, v)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.ApproximationScheme_verbosity(self)


    def stateApproximationScheme(self):
        r"""
        stateApproximationScheme(self) -> gum::IApproximationSchemeConfiguration::ApproximationSchemeSTATE

        Returns
        -------
        int
          the state of the approximation scheme

        """
        return _pyAgrum.ApproximationScheme_stateApproximationScheme(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.ApproximationScheme_nbrIterations(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.ApproximationScheme_history(self)


    def initApproximationScheme(self):
        r"""
        initApproximationScheme(self)

        Initiate the approximation scheme.

        """
        return _pyAgrum.ApproximationScheme_initApproximationScheme(self)


    def startOfPeriod(self):
        r"""
        startOfPeriod(self) -> bool

        Returns
        -------
        bool
          True if it is a start of a period

        """
        return _pyAgrum.ApproximationScheme_startOfPeriod(self)


    def updateApproximationScheme(self, incr=1):
        r"""
        updateApproximationScheme(self, incr=1)
        updateApproximationScheme(self)

        Update the approximation scheme.

        """
        return _pyAgrum.ApproximationScheme_updateApproximationScheme(self, incr)


    def remainingBurnIn(self):
        r"""
        remainingBurnIn(self) -> gum::Size

        Returns
        -------
        int
          the number of remaining burn in

        """
        return _pyAgrum.ApproximationScheme_remainingBurnIn(self)


    def stopApproximationScheme(self):
        r"""
        stopApproximationScheme(self)

        Stop the approximation scheme.

        """
        return _pyAgrum.ApproximationScheme_stopApproximationScheme(self)


    def continueApproximationScheme(self, error):
        r"""
        continueApproximationScheme(self, error) -> bool

        Continue the approximation scheme.

        Parameters
        ----------
        error : double

        """
        return _pyAgrum.ApproximationScheme_continueApproximationScheme(self, error)


# Register ApproximationScheme in _pyAgrum:
_pyAgrum.ApproximationScheme_swigregister(ApproximationScheme)

FindBarrenNodesType_FIND_NO_BARREN_NODES = _pyAgrum.FindBarrenNodesType_FIND_NO_BARREN_NODES

FindBarrenNodesType_FIND_BARREN_NODES = _pyAgrum.FindBarrenNodesType_FIND_BARREN_NODES


def randomDistribution(n):
    r"""
    randomDistribution(n) -> Vector

    Parameters
    ----------
    n : int
      The number of modalities for the ditribution.

    Returns
    -------
    a random discrete distribution. 

    """
    return _pyAgrum.randomDistribution(n)
class DiscretizedVariable(IDiscretizedVariable):
    r"""



    DiscretizedVariable is a discrete random variable with a set of ``ticks`` defining intervalls.

    Available constructors:

        ``DiscretizedVariable(aName, aDesc='') -> DiscretizedVariable``

        ``DiscretizedVariable(aDDRV) -> DiscretizedVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    aDDRV: pyAgrum.DiscretizedVariable
      Another `DiscretizedVariable` that will be copied

    Examples
    --------
    >>> import pyAgrum as gum
    >>>
    >>> vX=gum.DiscretizedVariable('X','X has been discretized')
    >>> vX.addTick(1).addTick(2).addTick(3).addTick(3.1415) #doctest: +ELLIPSIS
    >>> ## <pyAgrum.pyAgrum.DiscretizedVariable;...>
    >>> print(vX)
    >>> ## X<[1;2[,[2;3[,[3;3.1415]>
    >>>
    >>> vX.isTick(4)
    >>> ## False
    >>>
    >>> vX.labels()
    >>> ## ('[1;2[', '[2;3[', '[3;3.1415]')
    >>>
    >>> # where is the real value 2.5 ?
    >>> vX.index('2.5')
    >>> ## 1

    """

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

    def __init__(self, *args):
        r"""
        __init__(self, aName, aDesc) -> DiscretizedVariable
        __init__(self, aName, aDesc, ticks) -> DiscretizedVariable
        __init__(self, aDRV) -> DiscretizedVariable
        """
        this = _pyAgrum.new_DiscretizedVariable(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_DiscretizedVariable

    def clone(self):
        r"""
        clone(self) -> DiscretizedVariable

        Returns
        -------
        pyAgrum.DiscretizedVariable
        	a copy of the DiscretizedVariable

        """
        return _pyAgrum.DiscretizedVariable_clone(self)


    def varType(self):
        r"""
        varType(self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.DiscretizedVariable_varType(self)


    def isTick(self, aTick):
        r"""
        isTick(self, aTick) -> bool

        Parameters
        ----------
        aTick : double
        	the Tick to be tested

        Returns
        -------
        bool :
        	True if the Tick already exists

        """
        return _pyAgrum.DiscretizedVariable_isTick(self, aTick)


    def addTick(self,*args):
        """
        Parameters
        ----------
        aTick : double
            the Tick to be added

        Returns
        -------
        pyAgrum.DiscretizedVariable
            the discretized variable

        Raises
        ------
        gum.DefaultInLabel
            If the tick is already defined
        """
        _pyAgrum.DiscretizedVariable_addTick(self,*args)
        return self



    def eraseTicks(self):
        r"""
        eraseTicks(self)

        erase all the Ticks 

        """
        return _pyAgrum.DiscretizedVariable_eraseTicks(self)


    def label(self, i):
        r"""
        label(self, i) -> std::string

        Parameters
        ----------
        i : int
        	the index of the label we wish to return

        Returns
        -------
        str
        	the indice-th label

        Raises
        ------
        gum.OutOfBound
        	If the variable does not contain the label

        """
        return _pyAgrum.DiscretizedVariable_label(self, i)


    def numerical(self, indice):
        r"""
        numerical(self, indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.DiscretizedVariable_numerical(self, indice)


    def index(self, label):
        r"""
        index(self, label) -> gum::Idx

        Parameters
        ----------
        label : str
        	a label

        Returns
        -------
        int
        	the indice of the label

        """
        return _pyAgrum.DiscretizedVariable_index(self, label)


    def domainSize(self):
        r"""
        domainSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.DiscretizedVariable_domainSize(self)


    def domain(self):
        r"""
        domain(self) -> std::string const

        Returns
        -------
        str
            the domain of the variable as a string

        """
        return _pyAgrum.DiscretizedVariable_domain(self)


    def tick(self, i):
        r"""
        tick(self, i) -> double const &

        Indicate the index of the Tick

        Parameters
        ----------
        i : int
        	the index of the Tick

        Returns
        -------
        aTick : double
        	the index-th Tick

        Raises
        ------
        gum.NotFound
        	If the index is greater than the number of Ticks

        """
        return _pyAgrum.DiscretizedVariable_tick(self, i)


    def ticks(self):
        r"""
        ticks(self) -> Vector

        Returns
        -------
        tuple :
        	a tuple containing all the Ticks

        """
        return _pyAgrum.DiscretizedVariable_ticks(self)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.DiscretizedVariable___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.DiscretizedVariable___str__(self)


# Register DiscretizedVariable in _pyAgrum:
_pyAgrum.DiscretizedVariable_swigregister(DiscretizedVariable)

class MultiDimContainer(object):
    r"""
    Proxy of C++ gum::MultiDimContainer< double > class.
    Proxy of C++ gum::MultiDimContainer< double > 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__ = _pyAgrum.delete_MultiDimContainer

    def set(self, i, value):
        r"""set(self, i, value)"""
        return _pyAgrum.MultiDimContainer_set(self, i, value)


    def get(self, i):
        r"""get(self, i) -> double"""
        return _pyAgrum.MultiDimContainer_get(self, i)


    def fill(self, d):
        r"""fill(self, d)"""
        return _pyAgrum.MultiDimContainer_fill(self, d)


    def populate(self, *args):
        r"""
        populate(self, v)
        populate(self, l)
        """
        return _pyAgrum.MultiDimContainer_populate(self, *args)


    def copyFrom(self, *args):
        r"""
        copyFrom(self, src)
        copyFrom(self, src, p_i)
        """
        return _pyAgrum.MultiDimContainer_copyFrom(self, *args)


    def extractFrom(self, src, mask):
        r"""extractFrom(self, src, mask)"""
        return _pyAgrum.MultiDimContainer_extractFrom(self, src, mask)


    def content(self, *args):
        r"""
        content(self) -> gum::MultiDimImplementation< double > const
        content(self) -> gum::MultiDimImplementation< double > *
        """
        return _pyAgrum.MultiDimContainer_content(self, *args)


    def getMasterRef(self, *args):
        r"""
        getMasterRef(self) -> MultiDimAdressable
        getMasterRef(self) -> MultiDimAdressable
        """
        return _pyAgrum.MultiDimContainer_getMasterRef(self, *args)


    def copy(self, src):
        r"""copy(self, src)"""
        return _pyAgrum.MultiDimContainer_copy(self, src)


    def newFactory(self):
        r"""newFactory(self) -> MultiDimContainer"""
        return _pyAgrum.MultiDimContainer_newFactory(self)


    def toString(self, *args):
        r"""
        toString(self) -> std::string const
        toString(self, i) -> std::string const
        """
        return _pyAgrum.MultiDimContainer_toString(self, *args)


    def __eq__(self, p):
        r"""__eq__(self, p) -> bool"""
        return _pyAgrum.MultiDimContainer___eq__(self, p)


    def __ne__(self, p):
        r"""__ne__(self, p) -> bool"""
        return _pyAgrum.MultiDimContainer___ne__(self, p)


    def apply(self, f):
        r"""apply(self, f)"""
        return _pyAgrum.MultiDimContainer_apply(self, f)


    def reduce(self, f, base):
        r"""reduce(self, f, base) -> double"""
        return _pyAgrum.MultiDimContainer_reduce(self, f, base)


    def beginMultipleChanges(self):
        r"""beginMultipleChanges(self)"""
        return _pyAgrum.MultiDimContainer_beginMultipleChanges(self)


    def endMultipleChanges(self, *args):
        r"""
        endMultipleChanges(self)
        endMultipleChanges(self, v)
        """
        return _pyAgrum.MultiDimContainer_endMultipleChanges(self, *args)


# Register MultiDimContainer in _pyAgrum:
_pyAgrum.MultiDimContainer_swigregister(MultiDimContainer)

class Potential(object):
    r"""



    Class representing a potential.

    Available constructors:

      ``Potential() -> Potential``

      ``Potential(src) -> Potential``

    Parameters
    ----------
    src: pyAgrum.Potential
      The Potential to copy

    Returns
    -------
    pyAgrum.Potential
      The new Potential


    """

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

    def __init__(self, *args):
        r"""
        __init__(self) -> Potential
        __init__(self, aContent) -> Potential
        __init__(self, aContent, src) -> Potential
        __init__(self, src) -> Potential
        __init__(self, arg2) -> Potential
        """
        this = _pyAgrum.new_Potential(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._notSync=True
        self._list_vars=list()



    __swig_destroy__ = _pyAgrum.delete_Potential

    def newFactory(self):
        r"""
        newFactory(self) -> Potential

        Erase the Potential content and create a new empty one.

        Returns
        -------
        pyAgrum.Potential
         a reference to the new Potential

        """
        return _pyAgrum.Potential_newFactory(self)


    def isNonZeroMap(self):
        r"""
        isNonZeroMap(self) -> Potential

        Returns
        -------
        pyAgrum.Potential
          a boolean-like potential using the predicate isNonZero

        """
        return _pyAgrum.Potential_isNonZeroMap(self)


    def sum(self):
        r"""
        sum(self) -> double

        Returns
        -------
        double :
          the sum of all elements in the Potential

        """
        return _pyAgrum.Potential_sum(self)


    def product(self):
        r"""
        product(self) -> double

        Returns
        -------
        double
          the product of all elements in the Potential

        """
        return _pyAgrum.Potential_product(self)


    def max(self):
        r"""
        max(self) -> double

        Returns
        -------
        double
          the maximum of all elements in the Potential

        """
        return _pyAgrum.Potential_max(self)


    def min(self):
        r"""
        min(self) -> double

        Returns
        -------
        double
          the min of all elements in the Potential

        """
        return _pyAgrum.Potential_min(self)


    def maxNonOne(self):
        r"""
        maxNonOne(self) -> double

        Returns
        -------
        double
          the maximum of non one elements in the Potential

        Raises
        ------
        gum.NotFound
          If all value == 1.0

        """
        return _pyAgrum.Potential_maxNonOne(self)


    def minNonZero(self):
        r"""
        minNonZero(self) -> double

        Returns
        -------
        double
          the min of non zero elements in the Potential

        Raises
        ------
        gum.NotFound
          If all value == 0.0

        """
        return _pyAgrum.Potential_minNonZero(self)


    def findAll(self, v):
        r"""findAll(self, v) -> gum::Set< gum::Instantiation >"""
        return _pyAgrum.Potential_findAll(self, v)


    def argmax(self):
        r"""argmax(self) -> gum::Set< gum::Instantiation >"""
        return _pyAgrum.Potential_argmax(self)


    def argmin(self):
        r"""argmin(self) -> gum::Set< gum::Instantiation >"""
        return _pyAgrum.Potential_argmin(self)


    def entropy(self):
        r"""
        entropy(self) -> double

        Returns
        -------
        double
          the entropy of the potential

        """
        return _pyAgrum.Potential_entropy(self)


    def fillWith(self, *args):
        r"""
        fillWith(self, src) -> Potential
        fillWith(self, src, mapSrc) -> Potential
        fillWith(self, v) -> Potential
        fillWith(self, v) -> Potential

        Automatically fills the potential with v.

        Parameters
        ----------
        v : number or list or pyAgrum.Potential the number of parameters of the Potential
            a value or a list/pyAgrum.Potential containing the values to fill the Potential with.

        Warning
        -------
            if v is a list, the size of the list must be the
            if v is a pyAgrum.Potential. It must to contain variables with exactly the same names and labels but not necessarily the same variables.

        Returns
        -------
        pyAgrum.Potential
              a reference to the modified potentia

        Raises
        ------
        gum.SizeError
          If v size's does not matches the domain size. 

        """
        val = _pyAgrum.Potential_fillWith(self, *args)

        self._notSync=True
        return self


        return val


    def abs(self):
        r"""
        abs(self) -> Potential

        Apply abs on every element of the container

        Returns
        -------
        pyAgrum.Potential
            a reference to the modified potential.

        """
        val = _pyAgrum.Potential_abs(self)

        self._notSync=True
        return self


        return val


    def normalize(self):
        r"""
        normalize(self) -> Potential

        Normalize the Potential (do nothing if sum is 0)

        Returns
        -------
        pyAgrum.Potential
          a reference to the normalized Potential

        """
        val = _pyAgrum.Potential_normalize(self)

        self._notSync=True
        return self


        return val


    def sq(self):
        r"""
        sq(self) -> Potential

        Square all the values in the Potential

        """
        val = _pyAgrum.Potential_sq(self)

        self._notSync=True
        return self


        return val


    def KL(self, p):
        r"""
        KL(self, p) -> double

        Check the compatibility and compute the Kullback-Leibler divergence between the potential and.

        Parameters
        ----------
        p : pyAgrum.Potential
          the potential from which we want to calculate the divergence.

        Returns
        -------
        float
          The value of the divergence

        Raises
        ------
        gum.InvalidArgument
          If p is not compatible with the potential (dimension, variables)
        gum.FatalError
          If a zero is found in p or the potential and not in the other. 

        """
        return _pyAgrum.Potential_KL(self, p)


    def normalizeAsCPT(self):
        r"""
        normalizeAsCPT(self)

        Normalize the Potential as a CPT

        Returns
        -------
        pyAgrum.Potential
          a reference to the normalized Potential

        Raises
        ------
        gum.FatalError
          If some distribution sums to 0

        """
        val = _pyAgrum.Potential_normalizeAsCPT(self)

        self._notSync=True
        return self


        return val


    def scale(self, v):
        r"""
        scale(self, v) -> Potential

        Create a new potential multiplied by v.

        Parameters
        ----------
        v : double
          a multiplier

        Returns
        -------
          a reference to the modified potential

        """
        val = _pyAgrum.Potential_scale(self, v)

        self._notSync=True
        return self


        return val


    def translate(self, v):
        r"""
        translate(self, v) -> Potential

        Create a new potential added with v.

        Parameters
        ----------
        v : double
          The value to be added

        Returns
        -------
          a reference to the modified potential

        """
        val = _pyAgrum.Potential_translate(self, v)

        self._notSync=True
        return self


        return val


    def draw(self):
        r"""
        draw(self) -> gum::Idx

        draw a value using the potential as a probability table.

        Returns
        -------
        int
          the index of the drawn value

        """
        return _pyAgrum.Potential_draw(self)


    def __add__(self, p2):
        r"""__add__(self, p2) -> Potential"""
        return _pyAgrum.Potential___add__(self, p2)


    def __sub__(self, p2):
        r"""__sub__(self, p2) -> Potential"""
        return _pyAgrum.Potential___sub__(self, p2)


    def __mul__(self, p2):
        r"""__mul__(self, p2) -> Potential"""
        return _pyAgrum.Potential___mul__(self, p2)


    def __iadd__(self, r):
        r"""__iadd__(self, r) -> Potential"""
        return _pyAgrum.Potential___iadd__(self, r)


    def __imul__(self, r):
        r"""__imul__(self, r) -> Potential"""
        return _pyAgrum.Potential___imul__(self, r)


    def __isub__(self, r):
        r"""__isub__(self, r) -> Potential"""
        return _pyAgrum.Potential___isub__(self, r)


    def __itruediv__(self, *args):
        return _pyAgrum.Potential___itruediv__(self, *args)
    __idiv__ = __itruediv__



    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.Potential___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.Potential___str__(self)


    def extract(self, *args):
        r"""
        extract(self, inst) -> Potential
        extract(self, dict) -> Potential

        create a new Potential extracted from self given a partial instantiation.

        Parameters
        ----------
        inst : pyAgrum.instantiation
          a partial instantiation
        dict : dict
          a dictionnary containing discrete variables (?)

        Returns
        -------
        pyAgrum.Potential
          the new Potential

        """
        return _pyAgrum.Potential_extract(self, *args)


    def reorganize(self, *args):
        r"""
        reorganize(self, vars) -> Potential
        reorganize(self, varnames) -> Potential

        Create a new Potential with another order.

        Returns
        -------
        varnames : list
          a list of the var names in the new order

        Returns
        -------
        pyAgrum.Potential
          a reference to the modified potential

        """
        return _pyAgrum.Potential_reorganize(self, *args)


    def putFirst(self, varname):
        r"""
        putFirst(self, varname) -> Potential

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable for which the index should be 0.

        Returns
        -------
        pyAgrum.Potential
          a reference to the modified potential

        Raises
        ------
        gum.InvalidArgument
          If the var is not in the potential 

        """
        return _pyAgrum.Potential_putFirst(self, varname)


    def margSumOut(self, varnames):
        r"""
        margSumOut(self, varnames) -> Potential

        Projection using sum as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Raises
        ------
        gum.InvalidArgument 
          If varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margSumOut(self, varnames)


    def margProdOut(self, varnames):
        r"""
        margProdOut(self, varnames) -> Potential

        Projection using multiplication as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Raises
        ------
        gum.InvalidArgument
          If varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margProdOut(self, varnames)


    def margMaxOut(self, varnames):
        r"""
        margMaxOut(self, varnames) -> Potential

        Projection using max as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Raises
        ------
        gum.InvalidArgument
          If varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margMaxOut(self, varnames)


    def margMinOut(self, varnames):
        r"""
        margMinOut(self, varnames) -> Potential

        Projection using min as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Warnings
        --------
        InvalidArgument raised if varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margMinOut(self, varnames)


    def margSumIn(self, varnames):
        r"""
        margSumIn(self, varnames) -> Potential

        Projection using sum as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margSumIn(self, varnames)


    def margProdIn(self, varnames):
        r"""
        margProdIn(self, varnames) -> Potential

        Projection using multiplication as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margProdIn(self, varnames)


    def margMaxIn(self, varnames):
        r"""
        margMaxIn(self, varnames) -> Potential

        Projection using max as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margMaxIn(self, varnames)


    def margMinIn(self, varnames):
        r"""
        margMinIn(self, varnames) -> Potential

        Projection using min as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margMinIn(self, varnames)


    def __truediv__(self, *args):
        r"""
        __truediv__(self, p2) -> Potential
        __truediv__(self, b) -> Potential
        """
        return _pyAgrum.Potential___truediv__(self, *args)


    def __div__(self, b):
        r"""__div__(self, b) -> Potential"""
        return _pyAgrum.Potential___div__(self, b)


    def __eq__(self, *args):
        r"""
        __eq__(self, r) -> bool
        __eq__(self, b) -> bool
        """
        return _pyAgrum.Potential___eq__(self, *args)


    def __ne__(self, *args):
        r"""
        __ne__(self, r) -> bool
        __ne__(self, b) -> bool
        """
        return _pyAgrum.Potential___ne__(self, *args)



    def variablesSequence(self):
        """
        Returns
        -------
        list
            a list containing the sequence of variables
        """
        varlist = []
        for i in range(0, self.nbrDim()):
            varlist.append(self.variable(i))
        return varlist


    def __fill_distrib__(self):
      if not hasattr(self,'_notSync'):
        self._notSync=True

      if self._notSync:
        self._notSync=False
        self._var_names = []
        self._var_dims = []
        if self.empty():
            i = Instantiation(self)
            content = [self.get(i)]
            self.__distrib__ = numpy.array(content, dtype=numpy.float64) #M
            return

        content = []
        i = Instantiation(self)
        i.setFirst()
        while not i.end():
            content.append(self.get(i))
            i.inc()
        self.__distrib__ = numpy.array(content, dtype=numpy.float64) #M
        for var in self.variablesSequence():
            self._var_names.append(var.name())
            self._var_dims.append(var.domainSize())
        self._var_names.reverse()
        self._var_dims.reverse()
        self.__distrib__.shape = tuple(self._var_dims)



    def __indexfromdict__(self, id_dict):
        index = []
        for name, dim in zip(self._var_names, self._var_dims):
            if name in id_dict:
                id_value = id_dict[name]
                if isinstance(id_value, str):
    # id_value is a label of a LabelizedVar
                    i = self._var_names.index(name)
                    var = self.variable(len(self._var_names) - 1 - i)
                    id_value = var[id_value]
                if id_value >= dim:
                    raise IndexError("\"%s\" size is %d !"%(name, dim))
                index.append(id_value)
            else:
                index.append(slice(None, None, None)) # equivalent to ':'
        return tuple(index)



    def tolist(self):
        """
        Returns
        -------
        list
            the potential as a list
        """
        self.__fill_distrib__()
        return self.__distrib__.tolist()



    def toarray(self):
        """
        Returns
        -------
        array
            the potential as an array
        """
        return numpy.array(self.tolist())



    def __getitem__(self, id):
        self.__fill_distrib__()
        if self.empty():
            return self.__distrib__[0]

        if isinstance(id, dict):
            id_slice = self.__indexfromdict__(id)
        else:
            id_slice = id
        return self.__distrib__[id_slice]



    def __setitem__(self, id, value):
        self.__fill_distrib__()
        if self.empty():
            self.fill(value)
            self.__distrib__= numpy.array([value], dtype=numpy.float64) #M
            return

        if isinstance(id, dict):
            id_slice = self.__indexfromdict__(id)
        else:
            id_slice = id
        self.__distrib__[id_slice] = value
        self.fillWith(self.__distrib__.reshape(self.__distrib__.size).tolist())



    @property
    def var_names(self):
        """
        Returns
        -------
        list
            a list containing the name of each variables in the potential

        Warnings
        --------
            Listed in reverse from the variable enumeration order
        """
        self.__fill_distrib__()
        return self._var_names



    @property
    def var_dims(self):
        """
        Returns
        -------
        list
            a list containing the dimensions of each variables in the potential
        """
        self.__fill_distrib__()
        return self._var_dims



    def get(self, i):
        r"""
        get(self, i) -> double

        Parameters
        ----------
        i : pyAgrum.Instantiation
          an Instantiation

        Returns
        -------
        double
          the value in the Potential at the position given by the instantiation

        """
        return _pyAgrum.Potential_get(self, i)


    def set(self, i, value):
        r"""
        set(self, i, value)

        Change the value pointed by i

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The Instantiation to be changed
        value : double
          The new value of the Instantiation

        """
        val = _pyAgrum.Potential_set(self, i, value)

        self._notSync=True


        return val


    def empty(self):
        r"""
        empty(self) -> bool

        Returns
        -------
        bool
            Returns true if no variable is in the potential. 

        """
        return _pyAgrum.Potential_empty(self)


    def pos(self, v):
        r"""
        pos(self, v) -> gum::Idx

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable for which the index is returned.

        Returns
        -------
            Returns the index of a variable. 

        Raises
        ------
        gum.NotFound 
          If v is not in this multidimensional matrix. 

        """
        return _pyAgrum.Potential_pos(self, v)


    def contains(self, v):
        r"""
        contains(self, v) -> bool

        Parameters
        ----------
        v : pyAgrum.Potential
            a DiscreteVariable.

        Returns
        -------
        bool
            True if the var is in the potential

        """
        return _pyAgrum.Potential_contains(self, v)


    def nbrDim(self):
        r"""
        nbrDim(self) -> gum::Idx

        Returns
        -------
        int
          the number of vars in the multidimensional container. 

        """
        return _pyAgrum.Potential_nbrDim(self)


    def variable(self, *args):
        r"""
        variable(self, i) -> DiscreteVariable
        variable(self, name) -> DiscreteVariable

        Parameters
        ----------
        i : int 
          An index of this multidimensional matrix.

        Returns
        -------
          the varible at the ith index 

        Raises
        ------
        gum.NotFound
          If i does not reference a variable in this multidimensional matrix. 

        """
        return _pyAgrum.Potential_variable(self, *args)


    def remove(self, var):
        r"""
        remove(self, var)

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable to be removed

        Returns
        -------
        pyAgrum.Potential
          a reference to the modified potential

        Warnings
        --------
        IndexError raised if the var is not in the potential 

        """
        val = _pyAgrum.Potential_remove(self, var)

        self._list_vars.remove(var)
        self._notSync=True


        return val


    def add(self, v):
        r"""
        add(self, v)

        Add a discrete variable to the potential.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          the var to be added

        Raises
        ------
        DuplicateElement
          If the variable is already in this Potential.
        InvalidArgument
          If the variable is empty.

        """
        val = _pyAgrum.Potential_add(self, v)

        self._list_vars.append(v)
        self._notSync=True
        return self


        return val


# Register Potential in _pyAgrum:
_pyAgrum.Potential_swigregister(Potential)

class IBayesNet(DAGmodel):
    r"""



    Abstract class used by BayesNet.

    """

    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")
    __swig_destroy__ = _pyAgrum.delete_IBayesNet

    def cpt(self, varId):
        r"""
        cpt(self, varId) -> Potential

        Returns the CPT of a variable.

        Parameters
        ----------
        VarId : int
        	A variable's id in the pyAgrum.IBayesNet.
        name : str
        	A variable's name in the pyAgrum.IBayesNet.

        Returns
        -------
        pyAgrum.Potential
        	The variable's CPT. 

        Raises
        ------
        gum.NotFound 
        	If no variable's id matches varId. 

        """
        return _pyAgrum.IBayesNet_cpt(self, varId)


    def variableNodeMap(self):
        r"""
        variableNodeMap(self) -> VariableNodeMap

        Returns
        -------
        pyAgrum.variableNodeMap
        	the variable node map

        """
        return _pyAgrum.IBayesNet_variableNodeMap(self)


    def variable(self, id):
        r"""
        variable(self, id) -> DiscreteVariable

        Parameters
        ----------
        id : int
        	a variable's id
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.IBayesNet_variable(self, id)


    def nodeId(self, var):
        r"""
        nodeId(self, var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.IBayesNet_nodeId(self, var)


    def idFromName(self, name):
        r"""
        idFromName(self, name) -> gum::NodeId

        Returns a variable's id given its name in the graph.

        Parameters
        ----------
        name : str
        	The variable's name from which the id is returned.

        Returns
        -------
        int :
        	The variable's node id.

        Raises
        ------
        gum.NotFound
        	If name does not match a variable in the graph

        """
        return _pyAgrum.IBayesNet_idFromName(self, name)


    def variableFromName(self, name):
        r"""
        variableFromName(self, name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.IBayesNet_variableFromName(self, name)


    def jointProbability(self, i):
        r"""
        jointProbability(self, i) -> double

        Parameters
        ----------
        i : pyAgrum.instantiation
        	an instantiation of the variables

        Returns
        -------
        double
        	a parameter of the joint probability for the BayesNet

        Warnings
        --------
        a variable not present in the instantiation is assumed to be instantiated to 0

        """
        return _pyAgrum.IBayesNet_jointProbability(self, i)


    def log2JointProbability(self, i):
        r"""
        log2JointProbability(self, i) -> double

        Parameters
        ----------
        i : pyAgrum.instantiation
        	an instantiation of the variables

        Returns
        -------
        double
        	a parameter of the log joint probability for the BayesNet

        Warnings
        --------
        a variable not present in the instantiation is assumed to be instantiated to 0

        """
        return _pyAgrum.IBayesNet_log2JointProbability(self, i)


    def __eq__(self, arg2):
        r"""__eq__(self, arg2) -> bool"""
        return _pyAgrum.IBayesNet___eq__(self, arg2)


    def __ne__(self, arg2):
        r"""__ne__(self, arg2) -> bool"""
        return _pyAgrum.IBayesNet___ne__(self, arg2)


    def dim(self):
        r"""
        dim(self) -> gum::Size

        Returns the dimension (the number of free parameters) in this BayesNet.

        Returns
        -------
        int
        	the dimension of the BayesNet

        """
        return _pyAgrum.IBayesNet_dim(self)


    def maxVarDomainSize(self):
        r"""
        maxVarDomainSize(self) -> gum::Size

        Returns
        -------
        int
        	the biggest domain size among the variables of the BayesNet

        """
        return _pyAgrum.IBayesNet_maxVarDomainSize(self)


    def minParam(self):
        r"""
        minParam(self) -> double

        Returns
        -------
        double
            the smallest value in the CPTs of the IBayesNet

        """
        return _pyAgrum.IBayesNet_minParam(self)


    def maxParam(self):
        r"""
        maxParam(self) -> double

        Returns
        -------
        double
            the biggest value in the CPTs of the BayesNet

        """
        return _pyAgrum.IBayesNet_maxParam(self)


    def minNonZeroParam(self):
        r"""
        minNonZeroParam(self) -> double

        Returns
        -------
        double
            the smallest value (not equal to 0) in the CPTs of the IBayesNet

        """
        return _pyAgrum.IBayesNet_minNonZeroParam(self)


    def maxNonOneParam(self):
        r"""
        maxNonOneParam(self) -> double

        Returns
        -------
        double
        	The biggest value (not equal to 1) in the CPTs of the BayesNet

        """
        return _pyAgrum.IBayesNet_maxNonOneParam(self)


    def toDot(self):
        r"""
        toDot(self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.IBayesNet_toDot(self)


    def nodes(self):
        r"""
        nodes(self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.IBayesNet_nodes(self)


    def names(self):
        r"""
        names(self) -> PyObject *

        Returns
        -------
        list
        	The names of the graph variables

        """
        return _pyAgrum.IBayesNet_names(self)


    def minimalCondSet(self, *args):
        r"""
        minimalCondSet(self, target, soids) -> gum::NodeSet
        minimalCondSet(self, targets, soids) -> gum::NodeSet
        minimalCondSet(self, target, list) -> PyObject
        minimalCondSet(self, targets, list) -> PyObject *

        Returns, given one or many targets and a list of variables, the minimal set of those needed to calculate the target/targets.

        Parameters
        ----------
        target : int
        	The id of the target
        targets : list
        	The ids of the targets
        list : list
        	The list of available variables

        Returns
        -------
        Set
        	The minimal set of variables

        """
        return _pyAgrum.IBayesNet_minimalCondSet(self, *args)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.IBayesNet___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.IBayesNet___str__(self)


    def arcs(self):
        r"""
        arcs(self) -> PyObject *

        Returns
        -------
        list
        	The lisf of arcs in the IBayesNet

        """
        return _pyAgrum.IBayesNet_arcs(self)


    def parents(self, id):
        r"""
        parents(self, id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.IBayesNet_parents(self, id)


    def children(self, id):
        r"""
        children(self, id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.IBayesNet_children(self, id)


# Register IBayesNet in _pyAgrum:
_pyAgrum.IBayesNet_swigregister(IBayesNet)

class BayesNet(IBayesNet):
    r"""



    BayesNet represents a Bayesian Network.

    Available constructors:
    	``BayesNet(name='') -> BayesNet``

    	``BayesNet(source) -> BayesNet``


    Parameters
    ----------
    name: str
    	the name of the Bayes Net (optional)
    source : pyAgrum.BayesNet
    	the Bayesian network to copy

    """

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

    def fastPrototype(dotlike, domainSize=2):
        r"""
        fastPrototype(dotlike, domainSize=2) -> BayesNet
        fastPrototype(dotlike) -> BayesNet

        Create a bn with a dotlike syntax : 'a->b->c;b->d;'.

        The domain size maybe specified using 'a[10]'.

        Note that if the dotlike string contains such a specification for an already defined variable, the first specification will be used.

        Parameters
        ----------
        dotlike : str
        	the string containing the specification
        domainSize : int
        	the default domain size for variables

        Returns
        -------
        pyAgrum.BayesNet
        	the resulting bayesian network 

        """
        return _pyAgrum.BayesNet_fastPrototype(dotlike, domainSize)

    fastPrototype = staticmethod(fastPrototype)
    __swig_destroy__ = _pyAgrum.delete_BayesNet

    def __init__(self, *args):
        r"""
        __init__(self) -> BayesNet
        __init__(self, name) -> BayesNet
        __init__(self, source) -> BayesNet
        """
        this = _pyAgrum.new_BayesNet(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def cpt(self, *args):
        r"""
        cpt(self, varId) -> Potential
        cpt(self, name) -> Potential

        Returns the CPT of a variable.

        Parameters
        ----------
        VarId : int
        	A variable's id in the pyAgrum.BayesNet.
        name : str
        	A variable's name in the pyAgrum.BayesNet.

        Returns
        -------
        pyAgrum.Potential
        	The variable's CPT. 

        Raises
        ------
        gum.NotFound
            If no variable's id matches varId.

        """
        val = _pyAgrum.BayesNet_cpt(self, *args)

        val.__fill_distrib__()


        return val


    def variableNodeMap(self):
        r"""
        variableNodeMap(self) -> VariableNodeMap

        Returns
        -------
        pyAgrum.variableNodeMap
        	the variable node map

        """
        return _pyAgrum.BayesNet_variableNodeMap(self)


    def add(self, *args):
        r"""
        add(self, var) -> gum::NodeId
        add(self, name, nbrmod) -> gum::NodeId
        add(self, var, aContent) -> gum::NodeId
        add(self, var, id) -> gum::NodeId
        add(self, var, aContent, id) -> gum::NodeId

        Add a variable to the pyAgrum.BayesNet. 

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added
        name : str 
        	the variable name
        nbrmod : int
        	the numbre of modalities for the new variable
        id : int
        	the variable forced id in the pyAgrum.BayesNet

        Returns
        -------
        int 
        	the id of the new node

        Raises
        ------
        gum.DuplicateLabel
            If variable.name() is already used in this pyAgrum.BayesNet.
        gum.NotAllowed
            If nbrmod<2
        gum.DuplicateElement
            If id is already used.

        """
        return _pyAgrum.BayesNet_add(self, *args)


    def erase(self, *args):
        r"""
        erase(self, varId)
        erase(self, name)
        erase(self, var)

        Remove a variable from the gum::BayesNet.

        Removes the corresponding variable from the gum::BayesNet and from all of it's children gum::Potential.

        If no variable matches the given id, then nothing is done.

        Parameters
        ----------
        id : int
        	The variable's id to remove. 
        name : str
        	The variable's name to remove.
        var : pyAgrum.DiscreteVariable
        	A reference on the variable to remove. 

        """
        return _pyAgrum.BayesNet_erase(self, *args)


    def variable(self, *args):
        r"""
        variable(self, id) -> DiscreteVariable
        variable(self, name) -> DiscreteVariable

        Parameters
        ----------
        id : int
        	a variable's id
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.BayesNet_variable(self, *args)


    def changeVariableName(self, *args):
        r"""
        changeVariableName(self, id, new_name)
        changeVariableName(self, name, new_name)

        Changes a variable's name in the gum::BayesNet.

        This will change the gum::DiscreteVariable names in the gum::BayesNet.

        Parameters
        ----------
        new_name : str
        	the new name of the variable
        NodeId : int
        	the id of the node
        name : str
        	the name of the variable

        Raises
        ------
        gum.DuplicateLabel
            If new_name is already used in this BayesNet.
        gum.NotFound
            If no variable matches id.

        """
        return _pyAgrum.BayesNet_changeVariableName(self, *args)


    def changeVariableLabel(self, *args):
        r"""
        changeVariableLabel(self, id, old_label, new_label)
        changeVariableLabel(self, name, old_label, new_label)

        change the label of the variable associated to nodeId to the new value.

        Parameters
        ----------
        id : int
        	the id of the node
        name : str
        	the name of the variable
        old_label : str
        	the new label
        new_label : str
        	the new label

        Raises
        ------
        gum.NotFound
            if id/name is not a variable or if old_label does not exist.

        """
        return _pyAgrum.BayesNet_changeVariableLabel(self, *args)


    def nodeId(self, var):
        r"""
        nodeId(self, var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.BayesNet_nodeId(self, var)


    def idFromName(self, name):
        r"""
        idFromName(self, name) -> gum::NodeId

        Returns a variable's id given its name in the graph.

        Parameters
        ----------
        name : str
        	The variable's name from which the id is returned.

        Returns
        -------
        int :
        	The variable's node id.

        Raises
        ------
        gum.NotFound
        	If name does not match a variable in the graph

        """
        return _pyAgrum.BayesNet_idFromName(self, name)


    def variableFromName(self, name):
        r"""
        variableFromName(self, name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.BayesNet_variableFromName(self, name)


    def addArc(self, *args):
        r"""
        addArc(self, tail, head)
        addArc(self, tail, head)

        Add an arc in the BN, and update arc.head's CPT.

        Parameters
        ----------
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        Raises
        ------
        gum.InvalidEdge
            If arc.tail and/or arc.head are not in the BN.

        """
        return _pyAgrum.BayesNet_addArc(self, *args)


    def eraseArc(self, *args):
        r"""
        eraseArc(self, arc)
        eraseArc(self, tail, head)
        eraseArc(self, tail, head)

        Removes an arc in the BN, and update head's CTP.

        If (tail, head) doesn't exist, the nothing happens.

        Parameters
        ----------
        arc : pyAgrum.Arc 
        	The arc to be removed.
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        """
        return _pyAgrum.BayesNet_eraseArc(self, *args)


    def beginTopologyTransformation(self):
        r"""
        beginTopologyTransformation(self)

        When inserting/removing arcs, node CPTs change their dimension with a cost in time.
        begin Multiple Change for all CPTs
        These functions delay the CPTs change to be done just once at the end of a sequence of topology modification, begins a sequence of insertions/deletions of arcs without changing the dimensions of the CPTs.

        """
        return _pyAgrum.BayesNet_beginTopologyTransformation(self)


    def endTopologyTransformation(self):
        r"""
        endTopologyTransformation(self)

        Terminates a sequence of insertions/deletions of arcs by adjusting all CPTs dimensions.
        End Multiple Change for all CPTs.

        Returns
        -------
        pyAgrum.BayesNet

        """
        return _pyAgrum.BayesNet_endTopologyTransformation(self)


    def reverseArc(self, *args):
        r"""
        reverseArc(self, tail, head)
        reverseArc(self, tail, head)
        reverseArc(self, arc)

        Reverses an arc while preserving the same joint distribution. 

        Parameters
        ----------
        tail
        	(int) the id of the tail variable
        head
        	(int) the id of the head variable
        tail
        	(str) the name of the tail variable
        head
        	(str) the name of the head variable
        arc : pyAgrum.Arc
        	an arc 

        Raises
        ------
        gum.InvalidArc
            If the arc does not exsit or if its reversal would induce a directed cycle.

        """
        return _pyAgrum.BayesNet_reverseArc(self, *args)


    def addNoisyOR(self, *args):
        r"""
        addNoisyOR(self, var, external_weight) -> gum::NodeId
        addNoisyOR(self, var, external_weight, id) -> gum::NodeId

        Add a variable, it's associate node and a noisyOR implementation.

        Since it seems that the 'classical' noisyOR is the Compound noisyOR, we keep the addNoisyOR as an alias for addNoisyORCompound.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable. 

        Raises
        --------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addNoisyOR(self, *args)


    def addNoisyORNet(self, *args):
        r"""
        addNoisyORNet(self, var, external_weight) -> gum::NodeId
        addNoisyORNet(self, var, external_weight, id) -> gum::NodeId

        Add a variable, its associate node and a noisyOR implementation.

        Since it seems that the 'classical' noisyOR is the Compound noisyOR, we keep the addNoisyOR as an alias for addNoisyORCompound.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable.

        """
        return _pyAgrum.BayesNet_addNoisyORNet(self, *args)


    def addNoisyORCompound(self, *args):
        r"""
        addNoisyORCompound(self, var, external_weight) -> gum::NodeId
        addNoisyORCompound(self, var, external_weight, id) -> gum::NodeId

        Add a variable, it's associate node and a noisyOR implementation.

        Since it seems that the 'classical' noisyOR is the Compound noisyOR, we keep the addNoisyOR as an alias for addNoisyORCompound.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable.

        Raises
        --------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addNoisyORCompound(self, *args)


    def addNoisyAND(self, *args):
        r"""
        addNoisyAND(self, var, external_weight, id) -> gum::NodeId
        addNoisyAND(self, var, external_weight) -> gum::NodeId

        Add a variable, its associate node and a noisyAND implementation.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable.

        Raises
        ------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addNoisyAND(self, *args)


    def addLogit(self, *args):
        r"""
        addLogit(self, var, external_weight, id) -> gum::NodeId
        addLogit(self, var, external_weight) -> gum::NodeId

        Add a variable, its associate node and a Logit implementation.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.
        Returns
        -------
        int
        	the id of the added variable.

        Raises
        ------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addLogit(self, *args)


    def addOR(self, var):
        r"""
        addOR(self, var) -> gum::NodeId

        Add a variable, it's associate node and an OR implementation.

        The id of the new variable is automatically generated.

        Warnings
        --------
        	If parents are not boolean, all value>1 is True

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy

        Returns
        -------
        int
        	the id of the added variable.

        Raises
        ------
        gum.SizeError
            If variable.domainSize()>2

        """
        return _pyAgrum.BayesNet_addOR(self, var)


    def addAND(self, var):
        r"""
        addAND(self, var) -> gum::NodeId

        Add a variable, it's associate node and an AND implementation.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy.

        Returns
        -------
        int
        	the id of the added variable. 

        Raises
        ------
        gum.SizeError
            If variable.domainSize()>2

        """
        return _pyAgrum.BayesNet_addAND(self, var)


    def addAMPLITUDE(self, var):
        r"""
        addAMPLITUDE(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addAMPLITUDE(self, var)


    def addCOUNT(self, var, value=1):
        r"""
        addCOUNT(self, var, value=1) -> gum::NodeId
        addCOUNT(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addCOUNT(self, var, value)


    def addEXISTS(self, var, value=1):
        r"""
        addEXISTS(self, var, value=1) -> gum::NodeId
        addEXISTS(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addEXISTS(self, var, value)


    def addFORALL(self, var, value=1):
        r"""
        addFORALL(self, var, value=1) -> gum::NodeId
        addFORALL(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added variable.

        """
        return _pyAgrum.BayesNet_addFORALL(self, var, value)


    def addMAX(self, var):
        r"""
        addMAX(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addMAX(self, var)


    def addMEDIAN(self, var):
        r"""
        addMEDIAN(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addMEDIAN(self, var)


    def addMIN(self, var):
        r"""
        addMIN(self, var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addMIN(self, var)


    def addWeightedArc(self, *args):
        r"""
        addWeightedArc(self, tail, head, causalWeight)
        addWeightedArc(self, tail, head, causalWeight)

        Add an arc in the BN, and update arc.head's CPT.

        Parameters
        ----------
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)
        causalWeight : double
        	the added causal weight

        Raises
        ------
        gum.InvalidArc
            If arc.tail and/or arc.head are not in the BN.
        gum.InvalidArc
            If variable in arc.head is not a NoisyOR variable.

        """
        return _pyAgrum.BayesNet_addWeightedArc(self, *args)


    def generateCPTs(self):
        r"""
        generateCPTs(self)

        Randomly generates CPTs for a given structure.

        """
        return _pyAgrum.BayesNet_generateCPTs(self)


    def generateCPT(self, *args):
        r"""
        generateCPT(self, node)
        generateCPT(self, name)

        Randomly generate CPT for a given node in a given structure.

        Parameters
        ----------
        node : int
        	The variable's id.
        name : str 
        	The variable's name.

        """
        return _pyAgrum.BayesNet_generateCPT(self, *args)


    def changePotential(self, *args):
        r"""
        changePotential(self, id, newPot)
        changePotential(self, name, newPot)

        change the CPT associated to nodeId to newPot delete the old CPT associated to nodeId.

        Parameters
        ----------
        newPot : pyAgrum.Potential
        	the new potential
        NodeId : int
        	the id of the node
        name : str
        	the name of the variable

        Raises
        ------
        gum.NotAllowed
            If newPot has not the same signature as __probaMap[NodeId]

        """
        return _pyAgrum.BayesNet_changePotential(self, *args)


    def dag(self):
        r"""
        dag(self) -> DAG

        Returns
        -------
        pyAgrum.DAG
        	a constant reference to the dag of this BayesNet.

        """
        return _pyAgrum.BayesNet_dag(self)


    def size(self):
        r"""
        size(self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.BayesNet_size(self)


    def log10DomainSize(self):
        r"""
        log10DomainSize(self) -> double

        Returns
        -------
        double
        	The log10 domain size of the joint probability for the model.

        """
        return _pyAgrum.BayesNet_log10DomainSize(self)


    def addStructureListener(self,whenNodeAdded=None,whenNodeDeleted=None,whenArcAdded=None,whenArcDeleted=None):
        """
        Add the listeners in parameters to the list of existing ones.

        Parameters
        ----------
        whenNodeAdded : lambda expression
          a function for when a node is added
        whenNodeDeleted : lambda expression
          a function for when a node is removed
        whenArcAdded : lambda expression
          a function for when an arc is added
        whenArcDeleted : lambda expression
          a function for when an arc is removed
        """
        if [whenNodeAdded,whenNodeDeleted,whenArcAdded,whenArcDeleted]==[None,None,None,None]:
          return

        if not hasattr(self,"_listeners"):
          self._listeners=[]

        nl = PythonBNListener(self.dag(), self.variableNodeMap())
        if whenNodeAdded is not None:
          nl.setWhenNodeAdded(whenNodeAdded)
        if whenNodeDeleted is not None:
          nl.setWhenNodeDeleted(whenNodeDeleted)
        if whenArcAdded is not None:
          nl.setWhenArcAdded(whenArcAdded)
        if whenArcDeleted is not None:
          nl.setWhenArcDeleted(whenArcDeleted)

        self._listeners.append(nl)


    def loadBIF(self, *args):
        r"""
        loadBIF(self, name, l) -> std::string
        loadBIF(self, name) -> std::string

        Load a BIF file.

        Parameters
        ----------
        name : str
        	the file's name
        l : list
        	list of functions to execute

        Raises
        --------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadBIF(self, *args)


    def saveBIF(self, name):
        r"""
        saveBIF(self, name)

        Save the BayesNet in a BIF file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveBIF(self, name)


    def loadDSL(self, *args):
        r"""
        loadDSL(self, name, l) -> std::string
        loadDSL(self, name) -> std::string

        Load a DSL file.

        Parameters
        ----------
        name : str
        	the file's name
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadDSL(self, *args)


    def saveDSL(self, name):
        r"""
        saveDSL(self, name)

        Save the BayesNet in a DSL file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveDSL(self, name)


    def loadNET(self, *args):
        r"""
        loadNET(self, name, l) -> std::string
        loadNET(self, name) -> std::string

        Load a NET file.

        Parameters
        ----------
        name : str
        	the name's file
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadNET(self, *args)


    def saveNET(self, name):
        r"""
        saveNET(self, name)

        Save the BayesNet in a NET file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveNET(self, name)


    def loadO3PRM(self, *args):
        r"""
        loadO3PRM(self, name, system, classpath, l) -> std::string
        loadO3PRM(self, name, system, classpath) -> std::string
        loadO3PRM(self, name, system) -> std::string
        loadO3PRM(self, name) -> std::string

        Load an O3PRM file.

        Warnings
        --------
        The O3PRM language is the only language allowing to manipulate not only DiscretizedVariable but also RangeVariable and LabelizedVariable.

        Parameters
        ----------
        name : str
        	the file's name
        system : str
        	the system's name
        classpath : str
        	the classpath
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadO3PRM(self, *args)


    def saveO3PRM(self, name):
        r"""
        saveO3PRM(self, name)

        Save the BayesNet in an O3PRM file.

        Warnings
        --------
        The O3PRM language is the only language allowing to manipulate not only DiscretizedVariable but also RangeVariable and LabelizedVariable.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveO3PRM(self, name)


    def loadBIFXML(self, *args):
        r"""
        loadBIFXML(self, name, l) -> std::string
        loadBIFXML(self, name) -> std::string

        Load a BIFXML file.

        Parameters
        ----------
        name : str
        	the name's file
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadBIFXML(self, *args)


    def saveBIFXML(self, name):
        r"""
        saveBIFXML(self, name)

        Save the BayesNet in a BIFXML file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveBIFXML(self, name)


    def loadUAI(self, *args):
        r"""
        loadUAI(self, name, l) -> std::string
        loadUAI(self, name) -> std::string

        Load an UAI file.

        Parameters
        ----------
        name : str
        	the name's file
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadUAI(self, *args)


    def saveUAI(self, name):
        r"""
        saveUAI(self, name)

        Save the BayesNet in an UAI file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveUAI(self, name)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.BayesNet___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.BayesNet___str__(self)


# Register BayesNet in _pyAgrum:
_pyAgrum.BayesNet_swigregister(BayesNet)

def BayesNet_fastPrototype(dotlike, domainSize=2):
    r"""
    fastPrototype(dotlike, domainSize=2) -> BayesNet
    BayesNet_fastPrototype(dotlike) -> BayesNet

    Create a bn with a dotlike syntax : 'a->b->c;b->d;'.

    The domain size maybe specified using 'a[10]'.

    Note that if the dotlike string contains such a specification for an already defined variable, the first specification will be used.

    Parameters
    ----------
    dotlike : str
    	the string containing the specification
    domainSize : int
    	the default domain size for variables

    Returns
    -------
    pyAgrum.BayesNet
    	the resulting bayesian network 

    """
    return _pyAgrum.BayesNet_fastPrototype(dotlike, domainSize)

class BayesNetInference(object):
    r"""
    Proxy of C++ gum::BayesNetInference< double > class.
    Proxy of C++ gum::BayesNetInference< double > 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
    StateOfInference_OutdatedBNStructure = _pyAgrum.BayesNetInference_StateOfInference_OutdatedBNStructure
    
    StateOfInference_OutdatedBNPotentials = _pyAgrum.BayesNetInference_StateOfInference_OutdatedBNPotentials
    
    StateOfInference_ReadyForInference = _pyAgrum.BayesNetInference_StateOfInference_ReadyForInference
    
    StateOfInference_Done = _pyAgrum.BayesNetInference_StateOfInference_Done
    
    __swig_destroy__ = _pyAgrum.delete_BayesNetInference

    def setBN(self, bn):
        r"""setBN(self, bn)"""
        return _pyAgrum.BayesNetInference_setBN(self, bn)


    def BN(self):
        r"""BN(self) -> IBayesNet"""
        return _pyAgrum.BayesNetInference_BN(self)


    def domainSizes(self):
        r"""domainSizes(self) -> gum::NodeProperty< gum::Size > const &"""
        return _pyAgrum.BayesNetInference_domainSizes(self)


    def isInferenceReady(self):
        r"""isInferenceReady(self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceReady(self)


    def isInferenceOutdatedBNStructure(self):
        r"""isInferenceOutdatedBNStructure(self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceOutdatedBNStructure(self)


    def isInferenceOutdatedBNPotentials(self):
        r"""isInferenceOutdatedBNPotentials(self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceOutdatedBNPotentials(self)


    def isInferenceDone(self):
        r"""isInferenceDone(self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceDone(self)


    def isDone(self):
        r"""isDone(self) -> bool"""
        return _pyAgrum.BayesNetInference_isDone(self)


    def prepareInference(self):
        r"""prepareInference(self)"""
        return _pyAgrum.BayesNetInference_prepareInference(self)


    def makeInference(self):
        r"""makeInference(self)"""
        return _pyAgrum.BayesNetInference_makeInference(self)


    def clear(self):
        r"""clear(self)"""
        return _pyAgrum.BayesNetInference_clear(self)


    def state(self):
        r"""state(self) -> gum::BayesNetInference< double >::StateOfInference"""
        return _pyAgrum.BayesNetInference_state(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, label)
        addEvidence(self, nodeName, label)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)
        addEvidence(self, pot)
        addEvidence(self, pot)
        """
        return _pyAgrum.BayesNetInference_addEvidence(self, *args)


    def addSetOfEvidence(self, potset):
        r"""addSetOfEvidence(self, potset)"""
        return _pyAgrum.BayesNetInference_addSetOfEvidence(self, potset)


    def addListOfEvidence(self, potlist):
        r"""addListOfEvidence(self, potlist)"""
        return _pyAgrum.BayesNetInference_addListOfEvidence(self, potlist)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, label)
        chgEvidence(self, nodeName, label)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)
        chgEvidence(self, pot)
        """
        return _pyAgrum.BayesNetInference_chgEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""eraseAllEvidence(self)"""
        return _pyAgrum.BayesNetInference_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)
        """
        return _pyAgrum.BayesNetInference_eraseEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self) -> bool
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool
        """
        return _pyAgrum.BayesNetInference_hasEvidence(self, *args)


    def hasHardEvidence(self, *args):
        r"""
        hasHardEvidence(self, id) -> bool
        hasHardEvidence(self, nodeName) -> bool
        """
        return _pyAgrum.BayesNetInference_hasHardEvidence(self, *args)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool
        """
        return _pyAgrum.BayesNetInference_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""nbrEvidence(self) -> gum::Size"""
        return _pyAgrum.BayesNetInference_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""nbrHardEvidence(self) -> gum::Size"""
        return _pyAgrum.BayesNetInference_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""nbrSoftEvidence(self) -> gum::Size"""
        return _pyAgrum.BayesNetInference_nbrSoftEvidence(self)


    def evidence(self):
        r"""evidence(self) -> gum::NodeProperty< gum::Potential< double > const * > const &"""
        return _pyAgrum.BayesNetInference_evidence(self)


    def softEvidenceNodes(self):
        r"""softEvidenceNodes(self) -> gum::NodeSet const &"""
        return _pyAgrum.BayesNetInference_softEvidenceNodes(self)


    def hardEvidenceNodes(self):
        r"""hardEvidenceNodes(self) -> gum::NodeSet const &"""
        return _pyAgrum.BayesNetInference_hardEvidenceNodes(self)


    def hardEvidence(self):
        r"""hardEvidence(self) -> gum::NodeProperty< gum::Idx > const &"""
        return _pyAgrum.BayesNetInference_hardEvidence(self)


# Register BayesNetInference in _pyAgrum:
_pyAgrum.BayesNetInference_swigregister(BayesNetInference)

class LazyPropagation(object):
    r"""



    Class used for Lazy Propagation

    Available constructors:
    	``LazyPropagation(bn) -> LazyPropagation``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    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__(self, BN, arg3, arg4, use_binary_join_tree=True) -> LazyPropagation
        __init__(self, BN, arg3, arg4) -> LazyPropagation
        __init__(self, BN, arg3) -> LazyPropagation
        __init__(self, BN) -> LazyPropagation
        """
        this = _pyAgrum.new_LazyPropagation(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=args[0]#BN



    __swig_destroy__ = _pyAgrum.delete_LazyPropagation

    def setTriangulation(self, new_triangulation):
        r"""setTriangulation(self, new_triangulation)"""
        return _pyAgrum.LazyPropagation_setTriangulation(self, new_triangulation)


    def setRelevantPotentialsFinderType(self, type):
        r"""
        setRelevantPotentialsFinderType(self, type)

        sets how we determine the relevant potentials to combine

        When a clique sends a message to a separator, it first constitute the set of the potentials it contains and of the potentials contained in the messages it received. If RelevantPotentialsFinderType = FIND_ALL, all these potentials are combined and projected to produce the message sent to the separator. If RelevantPotentialsFinderType = DSEP_BAYESBALL_NODES, then only the set of potentials d-connected to the variables of the separator are kept for combination and projection.

        0 = FIND_ALL
        1 = DSEP_BAYESBALL_NODES
        2 = DSEP_BAYESBALL_POTENTIALS
        3 = DSEP_KOLLER_FRIEDMAN_2009

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.LazyPropagation_setRelevantPotentialsFinderType(self, type)


    def setFindBarrenNodesType(self, type):
        r"""
        setFindBarrenNodesType(self, type)

        sets how we determine barren nodes

        Barren nodes are unnecessary for probability inference, so they can be safely discarded in this case (type = FIND_BARREN_NODES). This speeds-up inference. However, there are some cases in which we do not want to remove barren nodes, typically when we want to answer queries such as Most Probable Explanations (MPE).

        0 = FIND_NO_BARREN_NODES
        1 = FIND_BARREN_NODES

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.LazyPropagation_setFindBarrenNodesType(self, type)


    def joinTree(self):
        r"""
        joinTree(self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current join tree used

        """
        return _pyAgrum.LazyPropagation_joinTree(self)


    def junctionTree(self):
        r"""
        junctionTree(self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current junction tree

        """
        return _pyAgrum.LazyPropagation_junctionTree(self)


    def evidenceProbability(self):
        r"""
        evidenceProbability(self) -> double

        Returns
        -------
        double
          the probability of evidence

        """
        return _pyAgrum.LazyPropagation_evidenceProbability(self)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LazyPropagation_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LazyPropagation_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LazyPropagation_targets(self)


    def jointPosterior(self, list):
        r"""
        jointPosterior(self, list) -> Potential

        Compute the joint posterior of a set of nodes.

        Parameters
        ----------
        list :
          the list of nodes whose posterior joint probability is wanted


        Warnings
        --------
        The order of the variables given by the list here or when the jointTarget is declared can not be assumed to be used bu the Potential.

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior joint probability of the set of nodes.

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LazyPropagation_jointPosterior(self, list)


    def addJointTarget(self, list):
        r"""
        addJointTarget(self, list)

        Add a list of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.

        Parameters
        ----------
        list
          a list of names of nodes

        Raises
        ------
        gum.UndefinedElement
          If some node(s) do not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_addJointTarget(self, list)


    def eraseJointTarget(self, list):
        r"""
        eraseJointTarget(self, list)

        Remove, if existing, the joint target.

        Parameters
        ----------
        list
          a list of names or Ids of nodes

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_eraseJointTarget(self, list)


    def isJointTarget(self, list):
        r"""
        isJointTarget(self, list) -> bool

        Parameters
        ----------
        list
          a list of nodes ids or names.

        Returns
        -------
        bool
          True if target is a joint target.

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_isJointTarget(self, list)


    def jointTargets(self):
        r"""
        jointTargets(self) -> PyObject *

        Returns
        -------
        list
          the list of target sets

        """
        return _pyAgrum.LazyPropagation_jointTargets(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LazyPropagation_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LazyPropagation_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LazyPropagation_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LazyPropagation_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LazyPropagation_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LazyPropagation_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LazyPropagation_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LazyPropagation_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LazyPropagation_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LazyPropagation_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LazyPropagation_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LazyPropagation_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LazyPropagation_evidenceImpact(self, *args)


    def eraseAllJointTargets(self):
        r"""
        eraseAllJointTargets(self)

        Clear all previously defined joint targets.

        """
        return _pyAgrum.LazyPropagation_eraseAllJointTargets(self)


    def eraseAllMarginalTargets(self):
        r"""
        eraseAllMarginalTargets(self)

        Clear all the previously defined marginal targets.

        """
        return _pyAgrum.LazyPropagation_eraseAllMarginalTargets(self)


    def nbrJointTargets(self):
        r"""
        nbrJointTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of joint targets

        """
        return _pyAgrum.LazyPropagation_nbrJointTargets(self)


    def I(self, X, Y):
        r"""
        I(self, X, Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LazyPropagation_I(self, X, Y)


    def VI(self, X, Y):
        r"""
        VI(self, X, Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          variation of information between X and Y

        """
        return _pyAgrum.LazyPropagation_VI(self, X, Y)


    def evidenceJointImpact(self, *args):
        r"""
        evidenceJointImpact(self, targets, evs) -> Potential
        evidenceJointImpact(self, targets, evs) -> Potential

        Create a pyAgrum.Potential for P(joint targets|evs) (for all instanciation of targets and evs)

        Parameters
        ----------
        targets :
          (int) a node Id
        targets :
          (str) a node name
        evs : set
          a set of nodes ids or names.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(target|evs)

        Raises
        ------
        gum.Exception
          If some evidene entered into the Bayes net are incompatible (their joint proba = 0)

        """
        return _pyAgrum.LazyPropagation_evidenceJointImpact(self, *args)


# Register LazyPropagation in _pyAgrum:
_pyAgrum.LazyPropagation_swigregister(LazyPropagation)

class ShaferShenoyInference(object):
    r"""



    Class used for Shafer-Shenoy inferences.

    Available constructors:
    	``ShaferShenoyInference(bn) -> ShaferShenoyInference``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    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__(self, BN, barren_type, use_binary_join_tree=True) -> ShaferShenoyInference
        __init__(self, BN, barren_type) -> ShaferShenoyInference
        __init__(self, BN) -> ShaferShenoyInference
        """
        this = _pyAgrum.new_ShaferShenoyInference(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=args[0]#BN



    __swig_destroy__ = _pyAgrum.delete_ShaferShenoyInference

    def setTriangulation(self, new_triangulation):
        r"""setTriangulation(self, new_triangulation)"""
        return _pyAgrum.ShaferShenoyInference_setTriangulation(self, new_triangulation)


    def setFindBarrenNodesType(self, type):
        r"""
        setFindBarrenNodesType(self, type)

        sets how we determine barren nodes

        Barren nodes are unnecessary for probability inference, so they can be safely discarded in this case (type = FIND_BARREN_NODES). This speeds-up inference. However, there are some cases in which we do not want to remove barren nodes, typically when we want to answer queries such as Most Probable Explanations (MPE).

        0 = FIND_NO_BARREN_NODES
        1 = FIND_BARREN_NODES

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.ShaferShenoyInference_setFindBarrenNodesType(self, type)


    def joinTree(self):
        r"""
        joinTree(self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current join tree used

        """
        return _pyAgrum.ShaferShenoyInference_joinTree(self)


    def junctionTree(self):
        r"""
        junctionTree(self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current junction tree

        """
        return _pyAgrum.ShaferShenoyInference_junctionTree(self)


    def evidenceProbability(self):
        r"""
        evidenceProbability(self) -> double

        Returns
        -------
        double
          the probability of evidence

        """
        return _pyAgrum.ShaferShenoyInference_evidenceProbability(self)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.ShaferShenoyInference_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.ShaferShenoyInference_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.ShaferShenoyInference_targets(self)


    def jointPosterior(self, list):
        r"""
        jointPosterior(self, list) -> Potential

        Compute the joint posterior of a set of nodes.

        Parameters
        ----------
        list :
          the list of nodes whose posterior joint probability is wanted


        Warnings
        --------
        The order of the variables given by the list here or when the jointTarget is declared can not be assumed to be used bu the Potential.

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior joint probability of the set of nodes.

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ShaferShenoyInference_jointPosterior(self, list)


    def addJointTarget(self, list):
        r"""
        addJointTarget(self, list)

        Add a list of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.

        Parameters
        ----------
        list
          a list of names of nodes

        Raises
        ------
        gum.UndefinedElement
          If some node(s) do not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_addJointTarget(self, list)


    def eraseJointTarget(self, list):
        r"""
        eraseJointTarget(self, list)

        Remove, if existing, the joint target.

        Parameters
        ----------
        list
          a list of names or Ids of nodes

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_eraseJointTarget(self, list)


    def isJointTarget(self, list):
        r"""
        isJointTarget(self, list) -> bool

        Parameters
        ----------
        list
          a list of nodes ids or names.

        Returns
        -------
        bool
          True if target is a joint target.

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_isJointTarget(self, list)


    def jointTargets(self):
        r"""
        jointTargets(self) -> PyObject *

        Returns
        -------
        list
          the list of target sets

        """
        return _pyAgrum.ShaferShenoyInference_jointTargets(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.ShaferShenoyInference_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ShaferShenoyInference_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.ShaferShenoyInference_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.ShaferShenoyInference_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.ShaferShenoyInference_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.ShaferShenoyInference_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.ShaferShenoyInference_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.ShaferShenoyInference_evidenceImpact(self, *args)


    def eraseAllJointTargets(self):
        r"""
        eraseAllJointTargets(self)

        Clear all previously defined joint targets.

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllJointTargets(self)


    def eraseAllMarginalTargets(self):
        r"""
        eraseAllMarginalTargets(self)

        Clear all the previously defined marginal targets.

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllMarginalTargets(self)


    def nbrJointTargets(self):
        r"""
        nbrJointTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of joint targets

        """
        return _pyAgrum.ShaferShenoyInference_nbrJointTargets(self)


    def I(self, X, Y):
        r"""
        I(self, X, Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.ShaferShenoyInference_I(self, X, Y)


    def VI(self, X, Y):
        r"""
        VI(self, X, Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          variation of information between X and Y

        """
        return _pyAgrum.ShaferShenoyInference_VI(self, X, Y)


    def evidenceJointImpact(self, *args):
        r"""
        evidenceJointImpact(self, targets, evs) -> Potential
        evidenceJointImpact(self, targets, evs) -> Potential

        Create a pyAgrum.Potential for P(joint targets|evs) (for all instanciation of targets and evs)

        Parameters
        ----------
        targets :
          (int) a node Id
        targets :
          (str) a node name
        evs : set
          a set of nodes ids or names.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(target|evs)

        Raises
        ------
        gum.Exception
          If some evidene entered into the Bayes net are incompatible (their joint proba = 0)

        """
        return _pyAgrum.ShaferShenoyInference_evidenceJointImpact(self, *args)


# Register ShaferShenoyInference in _pyAgrum:
_pyAgrum.ShaferShenoyInference_swigregister(ShaferShenoyInference)

class VariableElimination(object):
    r"""



    Class used for Variable Elimination inference algorithm.

    Available constructors:
    	``VariableElimination(bn) -> VariableElimination``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    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__(self, BN, relevant_type, arg4) -> VariableElimination
        __init__(self, BN, relevant_type) -> VariableElimination
        __init__(self, BN) -> VariableElimination
        """
        this = _pyAgrum.new_VariableElimination(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=args[0]#BN



    __swig_destroy__ = _pyAgrum.delete_VariableElimination

    def setTriangulation(self, new_triangulation):
        r"""setTriangulation(self, new_triangulation)"""
        return _pyAgrum.VariableElimination_setTriangulation(self, new_triangulation)


    def setRelevantPotentialsFinderType(self, type):
        r"""
        setRelevantPotentialsFinderType(self, type)

        sets how we determine the relevant potentials to combine

        When a clique sends a message to a separator, it first constitute the set of the potentials it contains and of the potentials contained in the messages it received. If RelevantPotentialsFinderType = FIND_ALL, all these potentials are combined and projected to produce the message sent to the separator. If RelevantPotentialsFinderType = DSEP_BAYESBALL_NODES, then only the set of potentials d-connected to the variables of the separator are kept for combination and projection.

        0 = FIND_ALL
        1 = DSEP_BAYESBALL_NODES
        2 = DSEP_BAYESBALL_POTENTIALS
        3 = DSEP_KOLLER_FRIEDMAN_2009

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.VariableElimination_setRelevantPotentialsFinderType(self, type)


    def setFindBarrenNodesType(self, type):
        r"""
        setFindBarrenNodesType(self, type)

        sets how we determine barren nodes

        Barren nodes are unnecessary for probability inference, so they can be safely discarded in this case (type = FIND_BARREN_NODES). This speeds-up inference. However, there are some cases in which we do not want to remove barren nodes, typically when we want to answer queries such as Most Probable Explanations (MPE).

        0 = FIND_NO_BARREN_NODES
        1 = FIND_BARREN_NODES

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.VariableElimination_setFindBarrenNodesType(self, type)


    def junctionTree(self, id):
        r"""
        junctionTree(self, id) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current junction tree

        """
        return _pyAgrum.VariableElimination_junctionTree(self, id)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.VariableElimination_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.VariableElimination_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.VariableElimination_targets(self)


    def jointPosterior(self, list):
        r"""
        jointPosterior(self, list) -> Potential

        Compute the joint posterior of a set of nodes.

        Parameters
        ----------
        list :
          the list of nodes whose posterior joint probability is wanted


        Warnings
        --------
        The order of the variables given by the list here or when the jointTarget is declared can not be assumed to be used bu the Potential.

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior joint probability of the set of nodes.

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.VariableElimination_jointPosterior(self, list)


    def addJointTarget(self, list):
        r"""
        addJointTarget(self, list)

        Add a list of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.

        Parameters
        ----------
        list
          a list of names of nodes

        Raises
        ------
        gum.UndefinedElement
          If some node(s) do not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_addJointTarget(self, list)


    def eraseJointTarget(self, list):
        r"""
        eraseJointTarget(self, list)

        Remove, if existing, the joint target.

        Parameters
        ----------
        list
          a list of names or Ids of nodes

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_eraseJointTarget(self, list)


    def isJointTarget(self, list):
        r"""
        isJointTarget(self, list) -> bool

        Parameters
        ----------
        list
          a list of nodes ids or names.

        Returns
        -------
        bool
          True if target is a joint target.

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_isJointTarget(self, list)


    def jointTargets(self):
        r"""
        jointTargets(self) -> PyObject *

        Returns
        -------
        list
          the list of target sets

        """
        return _pyAgrum.VariableElimination_jointTargets(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.VariableElimination_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.VariableElimination_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.VariableElimination_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.VariableElimination_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.VariableElimination_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.VariableElimination_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.VariableElimination_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.VariableElimination_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.VariableElimination_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.VariableElimination_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.VariableElimination_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.VariableElimination_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.VariableElimination_evidenceImpact(self, *args)


# Register VariableElimination in _pyAgrum:
_pyAgrum.VariableElimination_swigregister(VariableElimination)

class GibbsSampling(object):
    r"""



    Class for making Gibbs sampling inference in bayesian networks.

    Available constructors:
    	``GibbsSampling(bn) -> GibbsSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> GibbsSampling"""
        this = _pyAgrum.new_GibbsSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_GibbsSampling

    def setBurnIn(self, b):
        r"""
        setBurnIn(self, b)

        Parameters
        ----------
        b : int
          size of burn in on number of iteration

        """
        return _pyAgrum.GibbsSampling_setBurnIn(self, b)


    def burnIn(self):
        r"""
        burnIn(self) -> gum::Size

        Returns
        -------
        int
          size of burn in on number of iteration

        """
        return _pyAgrum.GibbsSampling_burnIn(self)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.GibbsSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.GibbsSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.GibbsSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.GibbsSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.GibbsSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.GibbsSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.GibbsSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.GibbsSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.GibbsSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.GibbsSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.GibbsSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.GibbsSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.GibbsSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.GibbsSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.GibbsSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.GibbsSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.GibbsSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.GibbsSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.GibbsSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.GibbsSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.GibbsSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.GibbsSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.GibbsSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.GibbsSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.GibbsSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.GibbsSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.GibbsSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.GibbsSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.GibbsSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.GibbsSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.GibbsSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.GibbsSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.GibbsSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.GibbsSampling_currentPosterior(self, *args)


    def nbrDrawnVar(self):
        r"""
        nbrDrawnVar(self) -> gum::Size

        Returns
        -------
        int
          the number of variable drawn at each iteration

        """
        return _pyAgrum.GibbsSampling_nbrDrawnVar(self)


    def setNbrDrawnVar(self, _nbr):
        r"""
        setNbrDrawnVar(self, _nbr)

        Parameters
        ----------
        _nbr : int
          the number of variables to be drawn at each iteration

        """
        return _pyAgrum.GibbsSampling_setNbrDrawnVar(self, _nbr)


    def isDrawnAtRandom(self):
        r"""
        isDrawnAtRandom(self) -> bool

        Returns
        -------
        bool
          True if variables are drawn at random

        """
        return _pyAgrum.GibbsSampling_isDrawnAtRandom(self)


    def setDrawnAtRandom(self, _atRandom):
        r"""
        setDrawnAtRandom(self, _atRandom)

        Parameters
        ----------
        _atRandom : bool
          indicates if variables should be drawn at random

        """
        return _pyAgrum.GibbsSampling_setDrawnAtRandom(self, _atRandom)


# Register GibbsSampling in _pyAgrum:
_pyAgrum.GibbsSampling_swigregister(GibbsSampling)

class ImportanceSampling(object):
    r"""



    Class used for inferences using the Importance Sampling algorithm.

    Available constructors:
    	``ImportanceSampling(bn) -> ImportanceSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> ImportanceSampling"""
        this = _pyAgrum.new_ImportanceSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_ImportanceSampling

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.ImportanceSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.ImportanceSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.ImportanceSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.ImportanceSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.ImportanceSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.ImportanceSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.ImportanceSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.ImportanceSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ImportanceSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.ImportanceSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.ImportanceSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.ImportanceSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.ImportanceSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.ImportanceSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ImportanceSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.ImportanceSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.ImportanceSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.ImportanceSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.ImportanceSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.ImportanceSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.ImportanceSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ImportanceSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.ImportanceSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.ImportanceSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.ImportanceSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.ImportanceSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.ImportanceSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.ImportanceSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.ImportanceSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.ImportanceSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ImportanceSampling_currentPosterior(self, *args)


# Register ImportanceSampling in _pyAgrum:
_pyAgrum.ImportanceSampling_swigregister(ImportanceSampling)

class WeightedSampling(object):
    r"""



    Class used for Weighted sampling inference algorithm.

    Available constructors:
    	``WeightedSampling(bn) -> WeightedSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> WeightedSampling"""
        this = _pyAgrum.new_WeightedSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_WeightedSampling

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.WeightedSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.WeightedSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.WeightedSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.WeightedSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.WeightedSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.WeightedSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.WeightedSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.WeightedSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.WeightedSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.WeightedSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.WeightedSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.WeightedSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.WeightedSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.WeightedSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.WeightedSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.WeightedSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.WeightedSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.WeightedSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.WeightedSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.WeightedSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.WeightedSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.WeightedSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.WeightedSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.WeightedSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.WeightedSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.WeightedSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.WeightedSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.WeightedSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.WeightedSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.WeightedSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.WeightedSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.WeightedSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.WeightedSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.WeightedSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.WeightedSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.WeightedSampling_currentPosterior(self, *args)


# Register WeightedSampling in _pyAgrum:
_pyAgrum.WeightedSampling_swigregister(WeightedSampling)

class MonteCarloSampling(object):
    r"""



    Class used for Monte Carlo sampling inference algorithm.

    Available constructors:
    	``MonteCarloSampling(bn) -> MonteCarloSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> MonteCarloSampling"""
        this = _pyAgrum.new_MonteCarloSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_MonteCarloSampling

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.MonteCarloSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.MonteCarloSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.MonteCarloSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.MonteCarloSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.MonteCarloSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.MonteCarloSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.MonteCarloSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.MonteCarloSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.MonteCarloSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.MonteCarloSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.MonteCarloSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.MonteCarloSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.MonteCarloSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.MonteCarloSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.MonteCarloSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.MonteCarloSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.MonteCarloSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.MonteCarloSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.MonteCarloSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.MonteCarloSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.MonteCarloSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.MonteCarloSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.MonteCarloSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.MonteCarloSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.MonteCarloSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.MonteCarloSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.MonteCarloSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.MonteCarloSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.MonteCarloSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.MonteCarloSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.MonteCarloSampling_currentPosterior(self, *args)


# Register MonteCarloSampling in _pyAgrum:
_pyAgrum.MonteCarloSampling_swigregister(MonteCarloSampling)

class LoopyImportanceSampling(object):
    r"""

    Class used for inferences using a loopy version of importance sampling.

    Available constructors:
    	``LoopyImportanceSampling(bn) -> LoopyImportanceSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> LoopyImportanceSampling"""
        this = _pyAgrum.new_LoopyImportanceSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyImportanceSampling

    def _makeInference(self):
        r"""_makeInference(self)"""
        return _pyAgrum.LoopyImportanceSampling__makeInference(self)


    def setVirtualLBPSize(self, vlbpsize):
        r"""
        setVirtualLBPSize(self, vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyImportanceSampling_setVirtualLBPSize(self, vlbpsize)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyImportanceSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyImportanceSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyImportanceSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyImportanceSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyImportanceSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyImportanceSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyImportanceSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyImportanceSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyImportanceSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyImportanceSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyImportanceSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyImportanceSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyImportanceSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyImportanceSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyImportanceSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyImportanceSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyImportanceSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyImportanceSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyImportanceSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.LoopyImportanceSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyImportanceSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyImportanceSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyImportanceSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyImportanceSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyImportanceSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyImportanceSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyImportanceSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyImportanceSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyImportanceSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyImportanceSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyImportanceSampling_currentPosterior(self, *args)


# Register LoopyImportanceSampling in _pyAgrum:
_pyAgrum.LoopyImportanceSampling_swigregister(LoopyImportanceSampling)

class LoopyWeightedSampling(object):
    r"""

    Class used for inferences using a loopy version of weighted sampling.

    Available constructors:
    	``LoopyWeightedSampling(bn) -> LoopyWeightedSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> LoopyWeightedSampling"""
        this = _pyAgrum.new_LoopyWeightedSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyWeightedSampling

    def _makeInference(self):
        r"""_makeInference(self)"""
        return _pyAgrum.LoopyWeightedSampling__makeInference(self)


    def setVirtualLBPSize(self, vlbpsize):
        r"""
        setVirtualLBPSize(self, vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyWeightedSampling_setVirtualLBPSize(self, vlbpsize)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyWeightedSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyWeightedSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyWeightedSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyWeightedSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyWeightedSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyWeightedSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyWeightedSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyWeightedSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyWeightedSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyWeightedSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyWeightedSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyWeightedSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyWeightedSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyWeightedSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyWeightedSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyWeightedSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyWeightedSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyWeightedSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyWeightedSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.LoopyWeightedSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyWeightedSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyWeightedSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyWeightedSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyWeightedSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyWeightedSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyWeightedSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyWeightedSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyWeightedSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyWeightedSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyWeightedSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyWeightedSampling_currentPosterior(self, *args)


# Register LoopyWeightedSampling in _pyAgrum:
_pyAgrum.LoopyWeightedSampling_swigregister(LoopyWeightedSampling)

class LoopyGibbsSampling(object):
    r"""

    Class used for inferences using a loopy version of Gibbs sampling.

    Available constructors:
    	``LoopyGibbsSampling(bn) -> LoopyGibbsSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> LoopyGibbsSampling"""
        this = _pyAgrum.new_LoopyGibbsSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyGibbsSampling

    def _makeInference(self):
        r"""_makeInference(self)"""
        return _pyAgrum.LoopyGibbsSampling__makeInference(self)


    def setVirtualLBPSize(self, vlbpsize):
        r"""
        setVirtualLBPSize(self, vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyGibbsSampling_setVirtualLBPSize(self, vlbpsize)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyGibbsSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyGibbsSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyGibbsSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyGibbsSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyGibbsSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyGibbsSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyGibbsSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyGibbsSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyGibbsSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyGibbsSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyGibbsSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyGibbsSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyGibbsSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyGibbsSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyGibbsSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyGibbsSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyGibbsSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyGibbsSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyGibbsSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.LoopyGibbsSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyGibbsSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyGibbsSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyGibbsSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyGibbsSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyGibbsSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyGibbsSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyGibbsSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyGibbsSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyGibbsSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyGibbsSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyGibbsSampling_currentPosterior(self, *args)


    def nbrDrawnVar(self):
        r"""
        nbrDrawnVar(self) -> gum::Size

        Returns
        -------
        int
          the number of variable drawn at each iteration

        """
        return _pyAgrum.LoopyGibbsSampling_nbrDrawnVar(self)


    def setNbrDrawnVar(self, _nbr):
        r"""
        setNbrDrawnVar(self, _nbr)

        Parameters
        ----------
        _nbr : int
          the number of variables to be drawn at each iteration

        """
        return _pyAgrum.LoopyGibbsSampling_setNbrDrawnVar(self, _nbr)


    def isDrawnAtRandom(self):
        r"""
        isDrawnAtRandom(self) -> bool

        Returns
        -------
        bool
          True if variables are drawn at random

        """
        return _pyAgrum.LoopyGibbsSampling_isDrawnAtRandom(self)


    def setDrawnAtRandom(self, _atRandom):
        r"""
        setDrawnAtRandom(self, _atRandom)

        Parameters
        ----------
        _atRandom : bool
          indicates if variables should be drawn at random

        """
        return _pyAgrum.LoopyGibbsSampling_setDrawnAtRandom(self, _atRandom)


    def burnIn(self):
        r"""
        burnIn(self) -> gum::Size

        Returns
        -------
        int
          size of burn in on number of iteration

        """
        return _pyAgrum.LoopyGibbsSampling_burnIn(self)


    def setBurnIn(self, b):
        r"""
        setBurnIn(self, b)

        Parameters
        ----------
        b : int
          size of burn in on number of iteration

        """
        return _pyAgrum.LoopyGibbsSampling_setBurnIn(self, b)


# Register LoopyGibbsSampling in _pyAgrum:
_pyAgrum.LoopyGibbsSampling_swigregister(LoopyGibbsSampling)

class LoopyMonteCarloSampling(object):
    r"""Proxy of C++ gum::LoopySamplingInference< double,gum::MonteCarloSampling > 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, bn):
        r"""__init__(self, bn) -> LoopyMonteCarloSampling"""
        this = _pyAgrum.new_LoopyMonteCarloSampling(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyMonteCarloSampling

    def _makeInference(self):
        r"""_makeInference(self)"""
        return _pyAgrum.LoopyMonteCarloSampling__makeInference(self)


    def setVirtualLBPSize(self, vlbpsize):
        r"""
        setVirtualLBPSize(self, vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyMonteCarloSampling_setVirtualLBPSize(self, vlbpsize)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyMonteCarloSampling_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyMonteCarloSampling_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyMonteCarloSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyMonteCarloSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyMonteCarloSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyMonteCarloSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyMonteCarloSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyMonteCarloSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyMonteCarloSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyMonteCarloSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyMonteCarloSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyMonteCarloSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyMonteCarloSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyMonteCarloSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyMonteCarloSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyMonteCarloSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyMonteCarloSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.LoopyMonteCarloSampling_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyMonteCarloSampling_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyMonteCarloSampling_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyMonteCarloSampling_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyMonteCarloSampling_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyMonteCarloSampling_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyMonteCarloSampling_evidenceImpact(self, *args)


    def currentPosterior(self, *args):
        r"""
        currentPosterior(self, id) -> Potential
        currentPosterior(self, name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_currentPosterior(self, *args)


# Register LoopyMonteCarloSampling in _pyAgrum:
_pyAgrum.LoopyMonteCarloSampling_swigregister(LoopyMonteCarloSampling)

class LoopyBeliefPropagation(object):
    r"""



    Class used for inferences using loopy belief propagation algorithm.

    Available constructors:
    	``LoopyBeliefPropagation(bn) -> LoopyBeliefPropagation``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

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

    def __init__(self, bn):
        r"""__init__(self, bn) -> LoopyBeliefPropagation"""
        this = _pyAgrum.new_LoopyBeliefPropagation(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyBeliefPropagation

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net 
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self):
        r"""
        hardEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyBeliefPropagation_hardEvidenceNodes(self)


    def softEvidenceNodes(self):
        r"""
        softEvidenceNodes(self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyBeliefPropagation_softEvidenceNodes(self)


    def targets(self):
        r"""
        targets(self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyBeliefPropagation_targets(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyBeliefPropagation_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyBeliefPropagation_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyBeliefPropagation_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyBeliefPropagation_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyBeliefPropagation_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyBeliefPropagation_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyBeliefPropagation_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyBeliefPropagation_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyBeliefPropagation_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyBeliefPropagation_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyBeliefPropagation_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyBeliefPropagation_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyBeliefPropagation_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyBeliefPropagation_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyBeliefPropagation_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.LoopyBeliefPropagation_asIApproximationSchemeConfiguration(self)


    def makeInference(self):
        r"""
        makeInference(self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyBeliefPropagation_makeInference(self)


    def posterior(self, *args):
        r"""
        posterior(self, var) -> Potential
        posterior(self, nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyBeliefPropagation_posterior(self, *args)


    def BN(self):
        r"""
        BN(self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyBeliefPropagation_BN(self)


    def addEvidence(self, *args):
        r"""
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, val)
        addEvidence(self, nodeName, val)
        addEvidence(self, id, vals)
        addEvidence(self, nodeName, vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_addEvidence(self, *args)


    def chgEvidence(self, *args):
        r"""
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, val)
        chgEvidence(self, nodeName, val)
        chgEvidence(self, id, vals)
        chgEvidence(self, nodeName, vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_chgEvidence(self, *args)


    def hasEvidence(self, *args):
        r"""
        hasEvidence(self, id) -> bool
        hasEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_hasEvidence(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseAllEvidence(self)


    def eraseEvidence(self, *args):
        r"""
        eraseEvidence(self, id)
        eraseEvidence(self, nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseEvidence(self, *args)


    def hasHardEvidence(self, nodeName):
        r"""
        hasHardEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_hasHardEvidence(self, nodeName)


    def hasSoftEvidence(self, *args):
        r"""
        hasSoftEvidence(self, id) -> bool
        hasSoftEvidence(self, nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_hasSoftEvidence(self, *args)


    def nbrEvidence(self):
        r"""
        nbrEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrEvidence(self)


    def nbrHardEvidence(self):
        r"""
        nbrHardEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrHardEvidence(self)


    def nbrSoftEvidence(self):
        r"""
        nbrSoftEvidence(self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrSoftEvidence(self)


    def eraseAllTargets(self):
        r"""
        eraseAllTargets(self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseAllTargets(self)


    def addAllTargets(self):
        r"""
        addAllTargets(self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyBeliefPropagation_addAllTargets(self)


    def addTarget(self, *args):
        r"""
        addTarget(self, target)
        addTarget(self, nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyBeliefPropagation_addTarget(self, *args)


    def eraseTarget(self, *args):
        r"""
        eraseTarget(self, target)
        eraseTarget(self, nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseTarget(self, *args)


    def isTarget(self, *args):
        r"""
        isTarget(self, variable) -> bool
        isTarget(self, nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_isTarget(self, *args)


    def nbrTargets(self):
        r"""
        nbrTargets(self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrTargets(self)


    def H(self, *args):
        r"""
        H(self, X) -> double
        H(self, nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyBeliefPropagation_H(self, *args)


    def evidenceImpact(self, *args):
        r"""
        evidenceImpact(self, target, evs) -> Potential
        evidenceImpact(self, target, evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyBeliefPropagation_evidenceImpact(self, *args)


# Register LoopyBeliefPropagation in _pyAgrum:
_pyAgrum.LoopyBeliefPropagation_swigregister(LoopyBeliefPropagation)

class BruteForceKL(object):
    r"""



    Class representing an exact KL-divergence

    Available constructors :

    	``BruteForceKL(P,Q) -> BruteForceKL``

    	``BruteForceKL(kl) -> BruteForceKL``

    Parameters
    ----------
    P : pyAgrum.IBayesNet
    	a Bayesian network
    Q : pyAgrum.IBayesNet
    	anotre Bayesian network
    kl : pyAgrum.KL
    	the KL to copy

    Raises
    ------
    gum.OperationNotAllowed
    	If the 2BNs have not the same domain size of compatible node sets

    """

    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__(self, P, Q) -> BruteForceKL
        __init__(self, kl) -> BruteForceKL
        """
        this = _pyAgrum.new_BruteForceKL(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_BruteForceKL

    def compute(self):
        r"""
        compute(self) -> PyObject *

        Returns
        -------
        dict
        	a dictionnary containing the different values after the computation.

        """
        return _pyAgrum.BruteForceKL_compute(self)


# Register BruteForceKL in _pyAgrum:
_pyAgrum.BruteForceKL_swigregister(BruteForceKL)

class GibbsKL(ApproximationScheme):
    r"""



    Class representing a Gibbs-Approximated KL-divergence 

    Available constructors :

    	``GibbsKL(P,Q) -> GibbsKL``

    	``GibbsKL(kl) -> GibbsKL``

    Parameters
    ----------
    P : pyAgrum.IBayesNet
    	a Bayesian network
    Q : pyAgrum.IBayesNet
    	anotre Bayesian network
    kl : pyAgrum.KL
    	the KL to copy

    Raises
    ------
    gum.OperationNotAllowed 
    	If the 2BNs have not the same domain size of compatible node sets

    """

    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__(self, P, Q) -> GibbsKL
        __init__(self, kl) -> GibbsKL
        """
        this = _pyAgrum.new_GibbsKL(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_GibbsKL

    def setBurnIn(self, b):
        r"""
        setBurnIn(self, b)

        Parameters
        ----------
        b : int
        	size of burn in on number of iteration

        """
        return _pyAgrum.GibbsKL_setBurnIn(self, b)


    def burnIn(self):
        r"""
        burnIn(self) -> gum::Size

        Returns
        -------
        int
        	size of burn in on number of iteration

        """
        return _pyAgrum.GibbsKL_burnIn(self)


    def compute(self):
        r"""
        compute(self) -> PyObject *

        Returns
        -------
        dict
        	a dictionnary containing the different values after the computation.

        """
        return _pyAgrum.GibbsKL_compute(self)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.GibbsKL_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.GibbsKL_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.GibbsKL_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.GibbsKL_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.GibbsKL_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsKL_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.GibbsKL_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.GibbsKL_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.GibbsKL_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.GibbsKL_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.GibbsKL_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsKL_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.GibbsKL_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.GibbsKL_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.GibbsKL_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.GibbsKL_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.GibbsKL_asIApproximationSchemeConfiguration(self)


    def nbrDrawnVar(self):
        r"""
        nbrDrawnVar(self) -> gum::Size

        Returns
        -------
        int
          the number of variable drawn at each iteration

        """
        return _pyAgrum.GibbsKL_nbrDrawnVar(self)


    def setNbrDrawnVar(self, _nbr):
        r"""
        setNbrDrawnVar(self, _nbr)

        Parameters
        ----------
        _nbr : int
          the number of variables to be drawn at each iteration

        """
        return _pyAgrum.GibbsKL_setNbrDrawnVar(self, _nbr)


    def isDrawnAtRandom(self):
        r"""
        isDrawnAtRandom(self) -> bool

        Returns
        -------
        bool
          True if variables are drawn at random

        """
        return _pyAgrum.GibbsKL_isDrawnAtRandom(self)


    def setDrawnAtRandom(self, _atRandom):
        r"""
        setDrawnAtRandom(self, _atRandom)

        Parameters
        ----------
        _atRandom : bool
          indicates if variables should be drawn at random

        """
        return _pyAgrum.GibbsKL_setDrawnAtRandom(self, _atRandom)


# Register GibbsKL in _pyAgrum:
_pyAgrum.GibbsKL_swigregister(GibbsKL)

class CredalNet(object):
    r"""



    Constructor used to create a CredalNet (step by step or with two BayesNet)

    Available constructors:
        ``CredalNet() -> CredalNet``

        ``CredalNet(src_min_num,src_max_den) -> CredalNet``

        ``CredalNet(src_min_num,src_max_den) -> CredalNet``

    Parameters
    ----------
    src_min_num
    	(str) the path to a BayesNet which contains lower probabilities.
    src_max_den
    	(str) the (optional) path to a BayesNet which contains upper probabilities.
    src_min_num
    	(pyAgrum.BayesNet) the BayesNet which contains lower probabilities.
    src_max_den
    	(pyAgrum.BayesNet) the (optional) BayesNet which contains upper probabilities. 

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    NodeType_Precise = _pyAgrum.CredalNet_NodeType_Precise
    
    NodeType_Credal = _pyAgrum.CredalNet_NodeType_Credal
    
    NodeType_Vacuous = _pyAgrum.CredalNet_NodeType_Vacuous
    
    NodeType_Indic = _pyAgrum.CredalNet_NodeType_Indic
    

    def __init__(self, *args):
        r"""
        __init__(self) -> CredalNet
        __init__(self, src_min_num, src_max_den) -> CredalNet
        __init__(self, src_min_num) -> CredalNet
        __init__(self, src_min_num, src_max_den) -> CredalNet
        __init__(self, src_min_num) -> CredalNet
        """
        this = _pyAgrum.new_CredalNet(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_CredalNet

    def addVariable(self, name, card):
        r"""
        addVariable(self, name, card) -> gum::NodeId

        Parameters
        ----------
        name : str
        	the name of the new variable
        card: int
            the domainSize of the new variable

        Returns
        -------
        int
        	the id of the new node

        """
        return _pyAgrum.CredalNet_addVariable(self, name, card)


    def addArc(self, tail, head):
        r"""
        addArc(self, tail, head)

        Adds an arc between two nodes

        Parameters
        ----------
        tail :
        	the id of the tail node
        head : int 
        	the id of the head node

        Raises
        ------
        gum.InvalidDirectedCircle
        	If any (directed) cycle is created by this arc
        gum.InvalidNode
        	If head or tail does not belong to the graph nodes
        gum.DuplicateElement
        	If one of the arc already exists

        """
        return _pyAgrum.CredalNet_addArc(self, tail, head)


    def setCPTs(self, id, cpt):
        r"""
        setCPTs(self, id, cpt)

        Warnings
        --------
        (experimental function) - Parameters to be wrapped


        Set the vertices of the credal sets (all of the conditionals) of a given node

        Parameters
        ----------
        id : int
        	the NodeId of the node
        cpt	: tbw 
        	the vertices of every credal set (for each instantiation of the parents)

        Warning
        -------
        DOES not change the BayesNet (s) associated to this credal net !

        """
        return _pyAgrum.CredalNet_setCPTs(self, id, cpt)


    def setCPT(self, *args):
        r"""
        setCPT(self, id, entry, cpt)
        setCPT(self, id, ins, cpt)

        Warnings
        --------
        (experimental function) - Parameters to be wrapped


        Set the vertices of one credal set of a given node (any instantiation index)

        Parameters
        ----------
        id : int
        	the Id of the node
        entry : int
        	the index of the instantiation (from 0 to K - 1) excluding the given node (only the parents are used to compute the index of the credal set)
        ins : pyAgrum.Instantiation
        	the Instantiation (only the parents matter to find the credal set index) 
        cpt	: tbw
        	the vertices of every credal set (for each instantiation of the parents)

        Warnings
        --------
        DOES not change the BayesNet(s) associated to this credal net !

        """
        return _pyAgrum.CredalNet_setCPT(self, *args)


    def fillConstraints(self, id, lower, upper):
        r"""
        fillConstraints(self, id, lower, upper)

        Set the interval constraints of the credal sets of a given node (all instantiations) 

        Parameters
        ----------
        id : int 
        	The id of the node
        lower : list
        	The lower value for each probability in correct order
        upper : list
        	The upper value for each probability in correct order

        Warnings
        --------
        You need to call intervalToCredal when done filling all constraints.

        Warning
        -------
        DOES change the BayesNet (s) associated to this credal net !

        """
        return _pyAgrum.CredalNet_fillConstraints(self, id, lower, upper)


    def fillConstraint(self, *args):
        r"""
        fillConstraint(self, id, entry, lower, upper)
        fillConstraint(self, id, ins, lower, upper)

        Set the interval constraints of a credal set of a given node (from an instantiation index)

        Parameters
        ----------
        id : int 
        	The id of the node
        entry : int
        	The index of the instantiation excluding the given node (only the parents are used to compute the index of the credal set)
        ins : pyAgrum.Instantiation
        	The Instantiation
        lower : list
        	The lower value for each probability in correct order
        upper : list
        	The upper value for each probability in correct order

        Warnings
        --------
        You need to call intervalToCredal when done filling all constraints.

        Warning
        -------
        DOES change the BayesNet (s) associated to this credal net ! 

        """
        return _pyAgrum.CredalNet_fillConstraint(self, *args)


    def instantiation(self, id):
        r"""
        instantiation(self, id) -> Instantiation

        Get an Instantiation from a node id, usefull to fill the constraints of the network.

        bnet accessors / shortcuts.

        Parameters
        ----------
        id : int
        	the id of the node we want an instantiation from

        Returns
        -------
        pyAgrum.Instantiation
            the instantiation 

        """
        return _pyAgrum.CredalNet_instantiation(self, id)


    def domainSize(self, id):
        r"""
        domainSize(self, id) -> gum::Size

        Parameters
        ----------
        id : int
        	The id of the node

        Returns
        -------
        int
            The cardinality of the node 

        """
        return _pyAgrum.CredalNet_domainSize(self, id)


    def bnToCredal(self, beta, oneNet, keepZeroes=False):
        r"""
        bnToCredal(self, beta, oneNet, keepZeroes=False)
        bnToCredal(self, beta, oneNet)

        Perturbates the BayesNet provided as input for this CredalNet by generating intervals instead of point probabilities and then computes each vertex of each credal set.

        Parameters
        ----------
        beta : double
        	The beta used to perturbate the network
        oneNet : bool
        	used as a flag. Set to True if one BayesNet if provided with counts, to False if two BayesNet are provided; one with probabilities (the lower net) and one with denominators over the first modalities (the upper net)
        keepZeroes : bool
        	used as a flag as whether or not - respectively True or False - we keep zeroes as zeroes. Default is False, i.e. zeroes are not kept

        """
        return _pyAgrum.CredalNet_bnToCredal(self, beta, oneNet, keepZeroes)


    def intervalToCredalWithFiles(self):
        r"""
        intervalToCredalWithFiles(self)

        Warnings
        --------
        Deprecated : use intervalToCredal (lrsWrapper with no input / output files needed).


        Computes the vertices of each credal set according to their interval definition (uses lrs).

        Use this method when using a single BayesNet storing counts of events. 

        """
        return _pyAgrum.CredalNet_intervalToCredalWithFiles(self)


    def intervalToCredal(self):
        r"""
        intervalToCredal(self)

        Computes the vertices of each credal set according to their interval definition (uses lrs).

        Use this method when using two BayesNet, one with lower probabilities and one with upper probabilities.

        """
        return _pyAgrum.CredalNet_intervalToCredal(self)


    def lagrangeNormalization(self):
        r"""
        lagrangeNormalization(self)

        Normalize counts of a BayesNet storing counts of each events such that no probability is 0.

        Use this method when using a single BayesNet storing counts of events. Lagrange normalization. This call is irreversible and modify counts stored by __src_bn.

        Doest not performs computations of the parameters but keeps normalized counts of events only. Call idmLearning to compute the probabilities (with any parameter value). 

        """
        return _pyAgrum.CredalNet_lagrangeNormalization(self)


    def idmLearning(self, s=0, keepZeroes=False):
        r"""
        idmLearning(self, s=0, keepZeroes=False)
        idmLearning(self, s=0)
        idmLearning(self)

        Learns parameters from a BayesNet storing counts of events.

        Use this method when using a single BayesNet storing counts of events. IDM model if s > 0, standard point probability if s = 0 (default value if none precised).

        Parameters
        ----------
        s : int
        	the IDM parameter.
        keepZeroes : bool
        	used as a flag as whether or not - respectively True or False - we keep zeroes as zeroes. Default is False, i.e. zeroes are not kept. 

        """
        return _pyAgrum.CredalNet_idmLearning(self, s, keepZeroes)


    def approximatedBinarization(self):
        r"""
        approximatedBinarization(self)

        Approximate binarization.

        Each bit has a lower and upper probability which is the lowest - resp. highest - over all vertices of the credal set. Enlarge the orignal credal sets and may induce huge imprecision.

        Warnings
        --------
        Enlarge the orignal credal sets and therefor induce huge imprecision by propagation. Not recommended, use MCSampling or something else instead

        """
        return _pyAgrum.CredalNet_approximatedBinarization(self)


    def saveBNsMinMax(self, min_path, max_path):
        r"""
        saveBNsMinMax(self, min_path, max_path)

        If this CredalNet was built over a perturbed BayesNet, one can save the intervals as two BayesNet.

        to call after bnToCredal(GUM_SCALAR beta) save a BN with lower probabilities and a BN with upper ones

        Parameters
        ----------
        min_path : str
        	the path to save the BayesNet which contains the lower probabilities of each node X.
        max_path : str
        	the path to save the BayesNet which contains the upper probabilities of each node X.

        """
        return _pyAgrum.CredalNet_saveBNsMinMax(self, min_path, max_path)


    def computeCPTMinMax(self):
        r"""
        computeCPTMinMax(self)

        Used with binary networks to speed-up L2U inference.

        Store the lower and upper probabilities of each node X over the 'True' modality.

        """
        return _pyAgrum.CredalNet_computeCPTMinMax(self)


    def src_bn(self):
        r"""
        src_bn(self) -> BayesNet

        Returns
        -------
        pyAgrum.BayesNet
            Returns a constant reference to the original BayesNet (used as a DAG, it's CPTs does not matter). 

        """
        return _pyAgrum.CredalNet_src_bn(self)


    def current_bn(self):
        r"""
        current_bn(self) -> BayesNet

        Returns
        -------
        pyAgrum.BayesNet
            Returs a constant reference to the actual BayesNet (used as a DAG, it's CPTs does not matter). 

        """
        return _pyAgrum.CredalNet_current_bn(self)


    def credalNet_currentCpt(self):
        r"""
        credalNet_currentCpt(self) -> gum::NodeProperty< std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
            a constant reference to the (up-to-date) CredalNet CPTs.

        """
        return _pyAgrum.CredalNet_credalNet_currentCpt(self)


    def credalNet_srcCpt(self):
        r"""
        credalNet_srcCpt(self) -> gum::NodeProperty< std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
            a constant reference to the (up-to-date) CredalNet CPTs.

        """
        return _pyAgrum.CredalNet_credalNet_srcCpt(self)


    def currentNodeType(self, id):
        r"""
        currentNodeType(self, id) -> gum::credal::CredalNet< double >::NodeType

        Parameters
        ----------
        id : int 
        	The constant reference to the choosen NodeId

        Returns
        -------
        pyAgrum.CredalNet
            the type of the choosen node in the (up-to-date) CredalNet __current_bn if any, __src_bn otherwise. 

        """
        return _pyAgrum.CredalNet_currentNodeType(self, id)


    def nodeType(self, id):
        r"""
        nodeType(self, id) -> gum::credal::CredalNet< double >::NodeType

        Parameters
        ----------
        id : int
        	the constant reference to the choosen NodeId

        Returns
        -------
        pyAgrum.CredalNet
        	the type of the choosen node in the (up-to-date) CredalNet in __src_bn. 

        """
        return _pyAgrum.CredalNet_nodeType(self, id)


    def epsilonMin(self):
        r"""
        epsilonMin(self) -> double const &

        Returns
        -------
        double
            a constant reference to the lowest perturbation of the BayesNet provided as input for this CredalNet. 

        """
        return _pyAgrum.CredalNet_epsilonMin(self)


    def epsilonMax(self):
        r"""
        epsilonMax(self) -> double const &

        Returns
        -------
        double
            a constant reference to the highest perturbation of the BayesNet provided as input for this CredalNet. 

        """
        return _pyAgrum.CredalNet_epsilonMax(self)


    def epsilonMean(self):
        r"""
        epsilonMean(self) -> double const &

        Returns
        -------
        double
            a constant reference to the average perturbation of the BayesNet provided as input for this CredalNet. 

        """
        return _pyAgrum.CredalNet_epsilonMean(self)


    def isSeparatelySpecified(self):
        r"""
        isSeparatelySpecified(self) -> bool const

        Returns
        -------
        bool
        	True if this CredalNet is separately and interval specified, False otherwise. 

        """
        return _pyAgrum.CredalNet_isSeparatelySpecified(self)


    def hasComputedCPTMinMax(self):
        r"""
        hasComputedCPTMinMax(self) -> bool const

        Returns
        -------
        bool
            True this CredalNet has called computeCPTMinMax() to speed-up inference with binary networks and L2U.

        """
        return _pyAgrum.CredalNet_hasComputedCPTMinMax(self)


    def get_CPT_min(self):
        r"""
        get_CPT_min(self) -> std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
        	a constant reference to the lower probabilities of each node X over the 'True' modality

        """
        return _pyAgrum.CredalNet_get_CPT_min(self)


    def get_CPT_max(self):
        r"""
        get_CPT_max(self) -> std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
        	a constant reference to the upper probabilities of each node X over the 'True' modality

        """
        return _pyAgrum.CredalNet_get_CPT_max(self)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.CredalNet___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.CredalNet___str__(self)


# Register CredalNet in _pyAgrum:
_pyAgrum.CredalNet_swigregister(CredalNet)

class CNMonteCarloSampling(object):
    r"""



    Class used for inferences in credal networks with Monte Carlo sampling algorithm.

    Available constructors:

        ``CNMonteCarloSampling(cn) -> CNMonteCarloSampling``

    Parameters
    ----------
    cn: pyAgrum.CredalNet
      a Credal network

    """

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

    def __init__(self, credalNet):
        r"""__init__(self, credalNet) -> CNMonteCarloSampling"""
        this = _pyAgrum.new_CNMonteCarloSampling(credalNet)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_CNMonteCarloSampling

    def makeInference(self):
        r"""
        makeInference(self)

        Starts the inference.

        """
        return _pyAgrum.CNMonteCarloSampling_makeInference(self)


    def insertEvidenceFile(self, path):
        r"""
        insertEvidenceFile(self, path)

        Insert evidence from file.

        Parameters
        ----------
        path : str
        	the path to the evidence file. 

        """
        return _pyAgrum.CNMonteCarloSampling_insertEvidenceFile(self, path)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.CNMonteCarloSampling_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.CNMonteCarloSampling_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.CNMonteCarloSampling_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.CNMonteCarloSampling_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.CNMonteCarloSampling_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNMonteCarloSampling_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.CNMonteCarloSampling_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.CNMonteCarloSampling_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.CNMonteCarloSampling_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.CNMonteCarloSampling_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.CNMonteCarloSampling_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNMonteCarloSampling_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.CNMonteCarloSampling_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.CNMonteCarloSampling_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.CNMonteCarloSampling_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.CNMonteCarloSampling_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.CNMonteCarloSampling_asIApproximationSchemeConfiguration(self)


    def setRepetitiveInd(self, flag):
        r"""
        setRepetitiveInd(self, flag)

        Parameters
        ----------
        flag : bool
        	True if repetitive independence is to be used, false otherwise. Only usefull with dynamic networks. 

        """
        return _pyAgrum.CNMonteCarloSampling_setRepetitiveInd(self, flag)


    def marginalMax(self, *args):
        r"""
        marginalMax(self, id) -> Vector
        marginalMax(self, name) -> Vector

        Get the upper marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which upper marginals we want.
        varName : str
        	the variable name which upper marginals we want. 

        Returns
        -------
        list
            a constant reference to this node upper marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNMonteCarloSampling_marginalMax(self, *args)


    def marginalMin(self, *args):
        r"""
        marginalMin(self, id) -> Vector
        marginalMin(self, name) -> Vector

        Get the lower marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which lower marginals we want.
        varName : str
        	the variable name which lower marginals we want. 

        Returns
        -------
        list
            a constant reference to this node lower marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNMonteCarloSampling_marginalMin(self, *args)


    def insertModalsFile(self, path):
        r"""
        insertModalsFile(self, path)

        Insert variables modalities from file to compute expectations.

        Parameters
        ----------
        path : str
        	The path to the modalities file. 

        """
        return _pyAgrum.CNMonteCarloSampling_insertModalsFile(self, path)


    def dynamicExpMax(self, varName):
        r"""
        dynamicExpMax(self, varName) -> Vector

        Get the upper dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which upper expectation we want.

        Returns
        -------
        double
            a constant reference to the variable upper expectation over all time steps. 

        """
        return _pyAgrum.CNMonteCarloSampling_dynamicExpMax(self, varName)


    def dynamicExpMin(self, varName):
        r"""
        dynamicExpMin(self, varName) -> Vector

        Get the lower dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which lower expectation we want.

        Returns
        -------
        double
            a constant reference to the variable lower expectation over all time steps. 

        """
        return _pyAgrum.CNMonteCarloSampling_dynamicExpMin(self, varName)


# Register CNMonteCarloSampling in _pyAgrum:
_pyAgrum.CNMonteCarloSampling_swigregister(CNMonteCarloSampling)

class CNLoopyPropagation(object):
    r"""



    Class used for inferences in credal networks with Loopy Propagation algorithm.

    Available constructors:

        ``CNLoopyPropagation(cn) -> CNLoopyPropagation``

    Parameters
    ----------
    cn: pyAgrum.CredalNet
      a Credal network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr
    InferenceType_nodeToNeighbours = _pyAgrum.CNLoopyPropagation_InferenceType_nodeToNeighbours
    
    InferenceType_ordered = _pyAgrum.CNLoopyPropagation_InferenceType_ordered
    
    InferenceType_randomOrder = _pyAgrum.CNLoopyPropagation_InferenceType_randomOrder
    

    def makeInference(self):
        r"""
        makeInference(self)

        Starts the inference.

        """
        return _pyAgrum.CNLoopyPropagation_makeInference(self)


    def inferenceType(self, *args):
        r"""
        inferenceType(self, inft)
        inferenceType(self) -> gum::credal::CNLoopyPropagation< double >::InferenceType

        Returns
        -------
        int
        	the inference type

        """
        return _pyAgrum.CNLoopyPropagation_inferenceType(self, *args)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Erase all inference related data to perform another one.

        You need to insert evidence again if needed but modalities are kept. You can insert new ones by using the appropriate method which will delete the old ones.

        """
        return _pyAgrum.CNLoopyPropagation_eraseAllEvidence(self)


    def saveInference(self, path):
        r"""
        saveInference(self, path)

        Saves marginals.

        Parameters
        ----------
        path : str
        	The path to the file to save marginals. 

        """
        return _pyAgrum.CNLoopyPropagation_saveInference(self, path)


    def __init__(self, cnet):
        r"""__init__(self, cnet) -> CNLoopyPropagation"""
        this = _pyAgrum.new_CNLoopyPropagation(cnet)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_CNLoopyPropagation

    def insertEvidenceFile(self, path):
        r"""
        insertEvidenceFile(self, path)

        Insert evidence from file.

        Parameters
        ----------
        path : str
        	the path to the evidence file. 

        """
        return _pyAgrum.CNLoopyPropagation_insertEvidenceFile(self, path)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.CNLoopyPropagation_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.CNLoopyPropagation_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.CNLoopyPropagation_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.CNLoopyPropagation_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.CNLoopyPropagation_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNLoopyPropagation_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.CNLoopyPropagation_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.CNLoopyPropagation_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.CNLoopyPropagation_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.CNLoopyPropagation_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.CNLoopyPropagation_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNLoopyPropagation_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.CNLoopyPropagation_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.CNLoopyPropagation_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.CNLoopyPropagation_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.CNLoopyPropagation_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.CNLoopyPropagation_asIApproximationSchemeConfiguration(self)


    def setRepetitiveInd(self, flag):
        r"""
        setRepetitiveInd(self, flag)

        Parameters
        ----------
        flag : bool
        	True if repetitive independence is to be used, false otherwise. Only usefull with dynamic networks. 

        """
        return _pyAgrum.CNLoopyPropagation_setRepetitiveInd(self, flag)


    def marginalMax(self, *args):
        r"""
        marginalMax(self, id) -> Vector
        marginalMax(self, name) -> Vector

        Get the upper marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which upper marginals we want.
        varName : str
        	the variable name which upper marginals we want. 

        Returns
        -------
        list
            a constant reference to this node upper marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNLoopyPropagation_marginalMax(self, *args)


    def marginalMin(self, *args):
        r"""
        marginalMin(self, id) -> Vector
        marginalMin(self, name) -> Vector

        Get the lower marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which lower marginals we want.
        varName : str
        	the variable name which lower marginals we want. 

        Returns
        -------
        list
            a constant reference to this node lower marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNLoopyPropagation_marginalMin(self, *args)


    def insertModalsFile(self, path):
        r"""
        insertModalsFile(self, path)

        Insert variables modalities from file to compute expectations.

        Parameters
        ----------
        path : str
        	The path to the modalities file. 

        """
        return _pyAgrum.CNLoopyPropagation_insertModalsFile(self, path)


    def dynamicExpMax(self, varName):
        r"""
        dynamicExpMax(self, varName) -> Vector

        Get the upper dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which upper expectation we want.

        Returns
        -------
        double
            a constant reference to the variable upper expectation over all time steps. 

        """
        return _pyAgrum.CNLoopyPropagation_dynamicExpMax(self, varName)


    def dynamicExpMin(self, varName):
        r"""
        dynamicExpMin(self, varName) -> Vector

        Get the lower dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which lower expectation we want.

        Returns
        -------
        double
            a constant reference to the variable lower expectation over all time steps. 

        """
        return _pyAgrum.CNLoopyPropagation_dynamicExpMin(self, varName)


# Register CNLoopyPropagation in _pyAgrum:
_pyAgrum.CNLoopyPropagation_swigregister(CNLoopyPropagation)

class InfluenceDiagram(DAGmodel):
    r"""



    InfluenceDiagram represents an Influence Diagram.

    Available constructors:
        ``InfluenceDiagram() -> InfluenceDiagram``

        ``InfluenceDiagram(source) -> InfluenceDiagram``

    Parameters
    ----------
    source : pyAgrum.InfluenceDiagram
      the InfluenceDiagram to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __swig_destroy__ = _pyAgrum.delete_InfluenceDiagram

    def __init__(self, *args):
        r"""
        __init__(self) -> InfluenceDiagram
        __init__(self, source) -> InfluenceDiagram
        """
        this = _pyAgrum.new_InfluenceDiagram(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this

    def toDot(self):
        r"""
        toDot(self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.InfluenceDiagram_toDot(self)


    def cpt(self, varId):
        r"""
        cpt(self, varId) -> Potential

        Returns the CPT of a variable.

        Parameters
        ----------
        VarId : int
        	A variable's id in the pyAgrum.BayesNet.

        Returns
        -------
        pyAgrum.Potential
        	The variable's CPT. 

        Raises
        ------
        gum.NotFound
        	If no variable's id matches varId. 

        """
        val = _pyAgrum.InfluenceDiagram_cpt(self, varId)

        val.__fill_distrib__()


        return val


    def utility(self, varId):
        r"""
        utility(self, varId) -> Potential

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        pyAgrum.Potential
        	the utility table of the node

        Raises
        ------
        gum.IndexError
        	If the InfluenceDiagram does not contain the variable

        """
        val = _pyAgrum.InfluenceDiagram_utility(self, varId)

        val.__fill_distrib__()


        return val


    def isUtilityNode(self, varId):
        r"""
        isUtilityNode(self, varId) -> bool

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        bool
        	true if node is an utility node

        """
        return _pyAgrum.InfluenceDiagram_isUtilityNode(self, varId)


    def isDecisionNode(self, varId):
        r"""
        isDecisionNode(self, varId) -> bool

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        bool
        	true if node is a decision node

        """
        return _pyAgrum.InfluenceDiagram_isDecisionNode(self, varId)


    def isChanceNode(self, varId):
        r"""
        isChanceNode(self, varId) -> bool

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        bool
        	true if node is a chance node

        """
        return _pyAgrum.InfluenceDiagram_isChanceNode(self, varId)


    def utilityNodeSize(self):
        r"""
        utilityNodeSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of utility nodes

        """
        return _pyAgrum.InfluenceDiagram_utilityNodeSize(self)


    def chanceNodeSize(self):
        r"""
        chanceNodeSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of chance nodes. 

        """
        return _pyAgrum.InfluenceDiagram_chanceNodeSize(self)


    def decisionNodeSize(self):
        r"""
        decisionNodeSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of decision nodes

        """
        return _pyAgrum.InfluenceDiagram_decisionNodeSize(self)


    def variable(self, id):
        r"""
        variable(self, id) -> DiscreteVariable

        Parameters
        ----------
        id : int
         	the node id

        Returns
        ------
        pyAgrum.DiscreteVariable
        	a constant reference over a variabe given it's node id

        Raises
        ------
        gum.NotFound
        	If no variable's id matches the parameter 

        """
        return _pyAgrum.InfluenceDiagram_variable(self, id)


    def nodeId(self, var):
        r"""
        nodeId(self, var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the InfluenceDiagram does not contain the variable

        """
        return _pyAgrum.InfluenceDiagram_nodeId(self, var)


    def idFromName(self, name):
        r"""
        idFromName(self, name) -> gum::NodeId

        Returns a variable's id given its name.

        Parameters
        ----------
        name : str
        	the variable's name from which the id is returned.

        Returns
        -------
        int
        	the variable's node id. 

        Raises
        ------
        gum.NotFound
        	If no such name exists in the graph. 

        """
        return _pyAgrum.InfluenceDiagram_idFromName(self, name)


    def variableFromName(self, name):
        r"""
        variableFromName(self, name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the InfluenceDiagram does not contain the variable

        """
        return _pyAgrum.InfluenceDiagram_variableFromName(self, name)


    def add(self, variable, id=0):
        r"""
        add(self, variable, id=0) -> gum::NodeId
        add(self, variable) -> gum::NodeId

        Add a chance variable, it's associate node and it's CPT.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy.
        id : int
        	The chosen id. If 0, the NodeGraphPart will choose.

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_add(self, variable, id)


    def addDecisionNode(self, variable, id=0):
        r"""
        addDecisionNode(self, variable, id=0) -> gum::NodeId
        addDecisionNode(self, variable) -> gum::NodeId

        Add a decision variable.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added by copy.
        id : int
        	the chosen id. If 0, the NodeGraphPart will choose.

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_addDecisionNode(self, variable, id)


    def addChanceNode(self, *args):
        r"""
        addChanceNode(self, variable, id=0) -> gum::NodeId
        addChanceNode(self, variable) -> gum::NodeId
        addChanceNode(self, variable, aContent, id=0) -> gum::NodeId
        addChanceNode(self, variable, aContent) -> gum::NodeId

        Add a chance variable, it's associate node and it's CPT.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added by copy.
        id : int
        	the chosen id. If 0, the NodeGraphPart will choose.

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_addChanceNode(self, *args)


    def addUtilityNode(self, *args):
        r"""
        addUtilityNode(self, variable, id=0) -> gum::NodeId
        addUtilityNode(self, variable) -> gum::NodeId
        addUtilityNode(self, variable, aContent, id=0) -> gum::NodeId
        addUtilityNode(self, variable, aContent) -> gum::NodeId

        Add a utility variable, it's associate node and it's UT. 

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added by copy
        id : int
        	the chosen id. If 0, the NodeGraphPart will choose

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.InvalidArgument
        	If variable has more than one label
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_addUtilityNode(self, *args)


    def erase(self, *args):
        r"""
        erase(self, id)
        erase(self, var)

        Erase a Variable from the network and remove the variable from all his childs.

        If no variable matches the id, then nothing is done.

        Parameters
        ----------
        id : int
        	The id of the variable to erase.
        var : pyAgrum.DiscreteVariable
        	The reference on the variable to remove. 

        """
        return _pyAgrum.InfluenceDiagram_erase(self, *args)


    def changeVariableName(self, id, new_name):
        r"""
        changeVariableName(self, id, new_name)

        Parameters
        ----------
        id : int
        	the node Id
        new_name : str
        	the name of the variable 

        Raises
        ------
        gum.DuplicateLabel
        	If this name already exists
        gum.NotFound
        	If no nodes matches id. 

        """
        return _pyAgrum.InfluenceDiagram_changeVariableName(self, id, new_name)


    def addArc(self, tail, head):
        r"""
        addArc(self, tail, head)

        Add an arc in the ID, and update diagram's potential nodes cpt if necessary.

        Parameters
        ----------
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        Raises
        ------
        gum.InvalidEdge
        	If arc.tail and/or arc.head are not in the ID.
        gum.InvalidEdge
        	If tail is a utility node 

        """
        return _pyAgrum.InfluenceDiagram_addArc(self, tail, head)


    def eraseArc(self, *args):
        r"""
        eraseArc(self, arc)
        eraseArc(self, tail, head)

        Removes an arc in the ID, and update diagram's potential nodes cpt if necessary.

        If (tail, head) doesn't exist, the nothing happens.

        Parameters
        ----------
        arc : pyAgrum.Arc
        	The arc to be removed.
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        """
        return _pyAgrum.InfluenceDiagram_eraseArc(self, *args)


    def decisionOrderExists(self):
        r"""
        decisionOrderExists(self) -> bool

        Returns
        -------
        bool
        	True if a directed path exist with all decision node

        """
        return _pyAgrum.InfluenceDiagram_decisionOrderExists(self)


    def getDecisionGraph(self):
        r"""
        getDecisionGraph(self) -> DAG

        Returns
        -------
        pyAgrum.DAG
        	the temporal Graph. 

        """
        return _pyAgrum.InfluenceDiagram_getDecisionGraph(self)


    def getDecisionOrder(self):
        r"""
        getDecisionOrder(self) -> Vector_int

        Returns
        -------
        list
        	the sequence of decision nodes in the directed path.

        Raises
        ------
        NotFound
        	If such a path does not exist 

        """
        return _pyAgrum.InfluenceDiagram_getDecisionOrder(self)


    def existsPathBetween(self, src, dest):
        r"""
        existsPathBetween(self, src, dest) -> bool

        Returns
        -------
        bool
        	true if a path exists between two nodes. 

        """
        return _pyAgrum.InfluenceDiagram_existsPathBetween(self, src, dest)


    def names(self):
        r"""
        names(self) -> PyObject *

        Returns
        -------
        list
        	The names of the InfluenceDiagram variables

        """
        return _pyAgrum.InfluenceDiagram_names(self)


    def ids(self):
        r"""
        ids(self) -> PyObject *

        .. note:: Deprecated in pyAgrum>0.13.0
            Please use nodes() instead

        """
        return _pyAgrum.InfluenceDiagram_ids(self)


    def arcs(self):
        r"""
        arcs(self) -> PyObject *

        Returns
        -------
        list:
        	the list of all the arcs in the Influence Diagram.

        """
        return _pyAgrum.InfluenceDiagram_arcs(self)


    def parents(self, id):
        r"""
        parents(self, id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        set
            the set of the parents ids.

        """
        return _pyAgrum.InfluenceDiagram_parents(self, id)


    def children(self, id):
        r"""
        children(self, id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.InfluenceDiagram_children(self, id)


    def loadBIFXML(self, *args):
        r"""
        loadBIFXML(self, name, l) -> bool
        loadBIFXML(self, name) -> bool

        Load a BIFXML file.

        Parameters
        ----------
        name : str
        	the name's file

        Raises
        ------
        gum.IOError
        	If file not found
        gum.FatalError
        	If file is not valid

        """
        return _pyAgrum.InfluenceDiagram_loadBIFXML(self, *args)


    def saveBIFXML(self, name):
        r"""
        saveBIFXML(self, name)

        Save the BayesNet in a BIFXML file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.InfluenceDiagram_saveBIFXML(self, name)


    def __repr__(self):
        r"""__repr__(self) -> std::string"""
        return _pyAgrum.InfluenceDiagram___repr__(self)


    def __str__(self):
        r"""__str__(self) -> std::string"""
        return _pyAgrum.InfluenceDiagram___str__(self)


# Register InfluenceDiagram in _pyAgrum:
_pyAgrum.InfluenceDiagram_swigregister(InfluenceDiagram)

class InfluenceDiagramInference(object):
    r"""
    Proxy of C++ gum::InfluenceDiagramInference< double > class.
    Proxy of C++ gum::InfluenceDiagramInference< 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, infDiag):
        r"""__init__(self, infDiag) -> InfluenceDiagramInference"""
        this = _pyAgrum.new_InfluenceDiagramInference(infDiag)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_InfluenceDiagramInference

    def makeInference(self):
        r"""
        makeInference(self)

        Makes the inference. 

        """
        return _pyAgrum.InfluenceDiagramInference_makeInference(self)


    def getMEU(self):
        r"""
        getMEU(self) -> double

        Returns maximum expected utility obtained from inference.

        Raises
        ------
        gum.OperationNotAllowed
        	If no inference have yet been made 

        """
        return _pyAgrum.InfluenceDiagramInference_getMEU(self)


    def getBestDecisionChoice(self, decisionId):
        r"""
        getBestDecisionChoice(self, decisionId) -> gum::Idx

        Returns best choice for decision variable given in parameter ( based upon MEU criteria )

        Parameters
        ----------
        decisionId : int
        	the id of the decision variable

        Raises
        ------
        gum.OperationNotAllowed
        	If no inference have yet been made
        gum.InvalidNode
        	If node given in parmaeter is not a decision node 

        """
        return _pyAgrum.InfluenceDiagramInference_getBestDecisionChoice(self, decisionId)


    def displayResult(self):
        r"""
        displayResult(self) -> std::string

        Displays the result of an inference.

        """
        return _pyAgrum.InfluenceDiagramInference_displayResult(self)


    def insertEvidence(self, evidenceList):
        r"""
        insertEvidence(self, evidenceList)

        Insert new evidence in the graph.

        Parameters
        ----------
        evidenceList : list
        	a list of potentials as evidences

        Warnings
        --------
        If an evidence already w.r.t. a given node and a new evidence w.r.t. this node is onserted, the old evidence is removed

        Raises
        ------
        gum.OperationNotAllowed
        	If an evidence is over more than one variable

        """
        return _pyAgrum.InfluenceDiagramInference_insertEvidence(self, evidenceList)


    def eraseEvidence(self, evidence):
        r"""
        eraseEvidence(self, evidence)

        Parameters
        ----------
        evidence : pyAgrum.Potential
        	the evidence to remove

        Raises
        ------
        gum.IndexError
        	If the evidence does not belong to the influence diagram

        """
        return _pyAgrum.InfluenceDiagramInference_eraseEvidence(self, evidence)


    def eraseAllEvidence(self):
        r"""
        eraseAllEvidence(self)

        Removes all the evidence entered into the diagram.

        """
        return _pyAgrum.InfluenceDiagramInference_eraseAllEvidence(self)


    def displayStrongJunctionTree(self, *args):
        r"""
        displayStrongJunctionTree(self, stream)

        Displays on terminal the result of strong junction tree computation for test purpose only.

        Parameters
        ----------
        args : TBW

        """
        return _pyAgrum.InfluenceDiagramInference_displayStrongJunctionTree(self, *args)


    def influenceDiagram(self):
        r"""
        influenceDiagram(self) -> InfluenceDiagram

        Returns a constant reference over the InfluenceDiagram on which this class work.

        Returns
        -------
        pyAgrum.InfluenceDiagram
        	the InfluenceDiagram on which this class work

        """
        return _pyAgrum.InfluenceDiagramInference_influenceDiagram(self)


    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be dict, not %s"%(type(evidces)))
        bn = self.influenceDiagram()

    # set evidences
        self.list_pot = []

        try:
          items=evidces.iteritems()
        except AttributeError:
          items=evidces.items()

        for var_name, evidce in items:
            pot = Potential()

            if isinstance(var_name, int):
                var = bn.variable(var_name)
            elif isinstance(var_name, str):
                var = bn.variableFromName(var_name)
            else:
                raise TypeError('values of the dict must be int or string')

            pot.add(var)
            if isinstance(evidce, (int, float, str)):
                pot[:] = 0
    # determine the var type
                try:
                    cast_var = var.toLabelizedVar()
                    if isinstance(evidce, int):
                        index = evidce
                    elif isinstance(evidce, str):
                        index = cast_var[evidce]
                    else:
                        raise TypeError('values of the dict must be int or string')
                except RuntimeError:
                    try:
                        cast_var = var.toRangeVar()
                        if isinstance(evidce, int):
                            index = cast_var[str(evidce)]
                        elif isinstance(evidce, str):
                            index = cast_var[evidce]
                        else:
                            raise TypeError('values of the dict must be int or string')
                    except RuntimeError:
                        cast_var = var.toDiscretizedVar()
                        if isinstance(evidce, float):
                            index = cast_var.index(evidce)
                        elif isinstance(evidce, str):
                            index = cast_var.index(float(evidce))
                        else:
                            raise TypeError('values of the dict must be float or string')
                pot[index] = 1
            elif isinstance(evidce, (list, tuple)):
                pot[:] = evidce
            else:
                raise TypeError('dict values must be number, string or sequence')
            self.list_pot.append(pot)

        self.eraseAllEvidence()
        self._setEvidence(self.list_pot)



    def _setEvidence(self, evidences):
        r"""_setEvidence(self, evidences)"""
        return _pyAgrum.InfluenceDiagramInference__setEvidence(self, evidences)


    def junctionTreeToDot(self):
        r"""
        junctionTreeToDot(self) -> std::string const

        Returns
        -------
        str
        	the result of strong junction tree computation for test purpose only.

        """
        return _pyAgrum.InfluenceDiagramInference_junctionTreeToDot(self)


# Register InfluenceDiagramInference in _pyAgrum:
_pyAgrum.InfluenceDiagramInference_swigregister(InfluenceDiagramInference)

class BNLearner(object):
    r"""



    Available constructors:
    	``BNLearner(filename) -> BNLearner``

    	``BNLearner(filename,src,parse_database=false) -> BNLearner``

    	``BNLearner(learner) -> BNLearner``

    Parameters
    ----------
    filename: str
    	the file to learn from
    src : pyAgrum.BayesNet
    	the Bayesian network used to find thoes modalities
    parse_database : bool
    	if true, the modalities specified by the user will be considered as a superset of the modalities of the variables.
    learner : pyAgrum.BNLearner
    	the BNLearner to copy

    """

    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__(self, filename, missing_symbols) -> BNLearner
        __init__(self, filename) -> BNLearner
        __init__(self, db) -> BNLearner
        __init__(self, filename, src, missing_symbols) -> BNLearner
        __init__(self, filename, src) -> BNLearner
        __init__(self, arg2) -> BNLearner
        __init__(self, arg2) -> BNLearner
        """
        this = _pyAgrum.new_BNLearner(*args)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_BNLearner

    def learnBN(self):
        r"""
        learnBN(self) -> BayesNet

        learn a BayesNet from a file (must have read the db before)

        Returns
        -------
        pyAgrum.BayesNet
        	the learned BayesNet

        """
        return _pyAgrum.BNLearner_learnBN(self)


    def learnParameters(self, *args):
        r"""
        learnParameters(self, dag, take_into_account_score=True) -> BayesNet
        learnParameters(self, dag) -> BayesNet
        learnParameters(self, take_into_account_score=True) -> BayesNet
        learnParameters(self) -> BayesNet

        learns a BN (its parameters) when its structure is known.

        Parameters
        ----------
        dag : pyAgrum.DAG
        bn : pyAgrum.BayesNet
        take_into_account_score : bool
        	The dag passed in argument may have been learnt from a structure learning. In this case, if the score used to learn the structure has an implicit apriori (like K2 which has a 1-smoothing apriori), it is important to also take into account this implicit apriori for parameter learning. By default, if a score exists, we will learn parameters by taking into account the apriori specified by methods useAprioriXXX () + the implicit apriori of the score, else we just take into account the apriori specified by useAprioriXXX ()

        Returns
        -------
        pyAgrum.BayesNet
        	the learned BayesNet

        Raises
        ------
        gum.MissingVariableInDatabase
        	If a variable of the BN is not found in the database
        gum.UnknownLabelInDatabase
        	If a label is found in the database that do not correspond to the variable

        """
        return _pyAgrum.BNLearner_learnParameters(self, *args)


    def setVerbosity(self, v):
        r"""
        setVerbosity(self, v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.BNLearner_setVerbosity(self, v)


    def setEpsilon(self, eps):
        r"""
        setEpsilon(self, eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.BNLearner_setEpsilon(self, eps)


    def setMinEpsilonRate(self, rate):
        r"""
        setMinEpsilonRate(self, rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.BNLearner_setMinEpsilonRate(self, rate)


    def setMaxIter(self, max):
        r"""
        setMaxIter(self, max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.BNLearner_setMaxIter(self, max)


    def setMaxTime(self, timeout):
        r"""
        setMaxTime(self, timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.BNLearner_setMaxTime(self, timeout)


    def setPeriodSize(self, p):
        r"""
        setPeriodSize(self, p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.BNLearner_setPeriodSize(self, p)


    def verbosity(self):
        r"""
        verbosity(self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.BNLearner_verbosity(self)


    def epsilon(self):
        r"""
        epsilon(self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.BNLearner_epsilon(self)


    def minEpsilonRate(self):
        r"""
        minEpsilonRate(self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.BNLearner_minEpsilonRate(self)


    def maxIter(self):
        r"""
        maxIter(self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.BNLearner_maxIter(self)


    def maxTime(self):
        r"""
        maxTime(self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.BNLearner_maxTime(self)


    def periodSize(self):
        r"""
        periodSize(self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.BNLearner_periodSize(self)


    def nbrIterations(self):
        r"""
        nbrIterations(self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.BNLearner_nbrIterations(self)


    def currentTime(self):
        r"""
        currentTime(self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.BNLearner_currentTime(self)


    def messageApproximationScheme(self):
        r"""
        messageApproximationScheme(self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.BNLearner_messageApproximationScheme(self)


    def history(self):
        r"""
        history(self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.BNLearner_history(self)


    def asIApproximationSchemeConfiguration(self):
        r"""
        asIApproximationSchemeConfiguration(self) -> IApproximationSchemeConfiguration

        Returns
        -------
        asIApproximationSchemeConfiguration

        """
        return _pyAgrum.BNLearner_asIApproximationSchemeConfiguration(self)


    def learnDAG(self):
        r"""learnDAG(self) -> DAG"""
        return _pyAgrum.BNLearner_learnDAG(self)


    def names(self):
        r"""names(self) -> Vector_string"""
        return _pyAgrum.BNLearner_names(self)


    def modalities(self):
        r"""modalities(self) -> std::vector< gum::Size,std::allocator< gum::Size > > const &"""
        return _pyAgrum.BNLearner_modalities(self)


    def idFromName(self, var_name):
        r"""idFromName(self, var_name) -> gum::NodeId"""
        return _pyAgrum.BNLearner_idFromName(self, var_name)


    def nameFromId(self, id):
        r"""nameFromId(self, id) -> std::string const &"""
        return _pyAgrum.BNLearner_nameFromId(self, id)


    def useScoreAIC(self):
        r"""useScoreAIC(self)"""
        return _pyAgrum.BNLearner_useScoreAIC(self)


    def useScoreBD(self):
        r"""useScoreBD(self)"""
        return _pyAgrum.BNLearner_useScoreBD(self)


    def useScoreBDeu(self):
        r"""useScoreBDeu(self)"""
        return _pyAgrum.BNLearner_useScoreBDeu(self)


    def useScoreBIC(self):
        r"""useScoreBIC(self)"""
        return _pyAgrum.BNLearner_useScoreBIC(self)


    def useScoreK2(self):
        r"""useScoreK2(self)"""
        return _pyAgrum.BNLearner_useScoreK2(self)


    def useScoreLog2Likelihood(self):
        r"""useScoreLog2Likelihood(self)"""
        return _pyAgrum.BNLearner_useScoreLog2Likelihood(self)


    def setAprioriWeight(self, weight):
        r"""setAprioriWeight(self, weight)"""
        return _pyAgrum.BNLearner_setAprioriWeight(self, weight)


    def useNoApriori(self):
        r"""useNoApriori(self)"""
        return _pyAgrum.BNLearner_useNoApriori(self)


    def useAprioriSmoothing(self, *args):
        r"""
        useAprioriSmoothing(self, weight=-1)
        useAprioriSmoothing(self)
        """
        return _pyAgrum.BNLearner_useAprioriSmoothing(self, *args)


    def useAprioriDirichlet(self, filename):
        r"""useAprioriDirichlet(self, filename)"""
        return _pyAgrum.BNLearner_useAprioriDirichlet(self, filename)


    def useGreedyHillClimbing(self):
        r"""useGreedyHillClimbing(self)"""
        return _pyAgrum.BNLearner_useGreedyHillClimbing(self)


    def useLocalSearchWithTabuList(self, *args):
        r"""
        useLocalSearchWithTabuList(self, tabu_size=100, nb_decrease=2)
        useLocalSearchWithTabuList(self, tabu_size=100)
        useLocalSearchWithTabuList(self)
        """
        return _pyAgrum.BNLearner_useLocalSearchWithTabuList(self, *args)


    def useK2(self, *args):
        r"""
        useK2(self, l)
        useK2(self, order)
        useK2(self, order)
        """
        return _pyAgrum.BNLearner_useK2(self, *args)


    def setMaxIndegree(self, max_indegree):
        r"""setMaxIndegree(self, max_indegree)"""
        return _pyAgrum.BNLearner_setMaxIndegree(self, max_indegree)


    def setSliceOrder(self, *args):
        r"""
        setSliceOrder(self, l)
        setSliceOrder(self, slice_order)
        setSliceOrder(self, slices)
        """
        return _pyAgrum.BNLearner_setSliceOrder(self, *args)


    def addForbiddenArc(self, *args):
        r"""
        addForbiddenArc(self, arc)
        addForbiddenArc(self, tail, head)
        addForbiddenArc(self, tail, head)
        """
        return _pyAgrum.BNLearner_addForbiddenArc(self, *args)


    def eraseForbiddenArc(self, *args):
        r"""
        eraseForbiddenArc(self, arc)
        eraseForbiddenArc(self, tail, head)
        eraseForbiddenArc(self, tail, head)
        """
        return _pyAgrum.BNLearner_eraseForbiddenArc(self, *args)


    def addMandatoryArc(self, *args):
        r"""
        addMandatoryArc(self, arc)
        addMandatoryArc(self, tail, head)
        addMandatoryArc(self, tail, head)
        """
        return _pyAgrum.BNLearner_addMandatoryArc(self, *args)


    def eraseMandatoryArc(self, *args):
        r"""
        eraseMandatoryArc(self, arc)
        eraseMandatoryArc(self, tail, head)
        eraseMandatoryArc(self, tail, head)
        """
        return _pyAgrum.BNLearner_eraseMandatoryArc(self, *args)


    def setInitialDAG(self, g):
        r"""
        setInitialDAG(self, g)

        Parameters
        ----------
        dag : pyAgrum.DAG
        	an initial DAG structure

        """
        return _pyAgrum.BNLearner_setInitialDAG(self, g)


    def use3off2(self):
        r"""
        use3off2(self)

        Indicate that we wish to use 3off2.

        """
        return _pyAgrum.BNLearner_use3off2(self)


    def useMIIC(self):
        r"""
        useMIIC(self)

        Indicate that we wish to use MIIC.

        """
        return _pyAgrum.BNLearner_useMIIC(self)


    def useNML(self):
        r"""
        useNML(self)

        Indicate that we wish to use the NML correction for 3off2 or MIIC

        """
        return _pyAgrum.BNLearner_useNML(self)


    def useMDL(self):
        r"""
        useMDL(self)

        Indicate that we wish to use the MDL correction for 3off2 or MIIC

        """
        return _pyAgrum.BNLearner_useMDL(self)


    def useNoCorr(self):
        r"""
        useNoCorr(self)

        Indicate that we wish to use the NoCorr correction for 3off2 or MIIC

        """
        return _pyAgrum.BNLearner_useNoCorr(self)


    def latentVariables(self, *args):
        r"""
        latentVariables(self) -> PyObject
        latentVariables(self) -> std::vector< gum::Arc,std::allocator< gum::Arc > > const

        Warnings
        --------
        learner must be using 3off2 or MIIC algorithm

        Returns
        -------
        list
        	the list of latent variables

        """
        return _pyAgrum.BNLearner_latentVariables(self, *args)


    def learnMixedStructure(self):
        r"""
        learnMixedStructure(self) -> MixedGraph

        Warnings
        --------
        learner must be using 3off2 or MIIC algorithm

        Returns
        -------
        pyAgrum.EssentialGraph
        	the learned structure as an EssentialGraph

        """
        val = _pyAgrum.BNLearner_learnMixedStructure(self)

        bn=BayesNet()
        for i in range(len(self.names())):
          bn.add(self.nameFromId(i),2)
        ge=EssentialGraph(bn,val)
        ge._bn=bn
        return ge


        return val


# Register BNLearner in _pyAgrum:
_pyAgrum.BNLearner_swigregister(BNLearner)

class BNDatabaseGenerator(object):
    r"""
    Proxy of C++ gum::learning::BNDatabaseGenerator< double > class.
    Proxy of C++ gum::learning::BNDatabaseGenerator< 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, bn):
        r"""__init__(self, bn) -> BNDatabaseGenerator"""
        this = _pyAgrum.new_BNDatabaseGenerator(bn)
        try:
            self.this.append(this)
        except __builtin__.Exception:
            self.this = this
    __swig_destroy__ = _pyAgrum.delete_BNDatabaseGenerator

    def drawSamples(self, nbSamples):
        r"""drawSamples(self, nbSamples) -> double"""
        return _pyAgrum.BNDatabaseGenerator_drawSamples(self, nbSamples)


    def toCSV(self, *args):
        r"""
        toCSV(self, csvFileURL, useLabels=True, append=False, csvSeparator, checkOnAppend=False)
        toCSV(self, csvFileURL, useLabels=True, append=False, csvSeparator)
        toCSV(self, csvFileURL, useLabels=True, append=False)
        toCSV(self, csvFileURL, useLabels=True)
        toCSV(self, csvFileURL)
        """
        return _pyAgrum.BNDatabaseGenerator_toCSV(self, *args)


    def toDatabaseTable(self, useLabels=True):
        r"""
        toDatabaseTable(self, useLabels=True) -> gum::learning::DatabaseTable< >
        toDatabaseTable(self) -> gum::learning::DatabaseTable< >
        """
        return _pyAgrum.BNDatabaseGenerator_toDatabaseTable(self, useLabels)


    def database(self):
        r"""database(self) -> std::vector< std::vector< gum::Idx,std::allocator< gum::Idx > >,std::allocator< std::vector< gum::Idx,std::allocator< gum::Idx > > > >"""
        return _pyAgrum.BNDatabaseGenerator_database(self)


    def setVarOrder(self, *args):
        r"""
        setVarOrder(self, varOrder)
        setVarOrder(self, varOrder)
        """
        return _pyAgrum.BNDatabaseGenerator_setVarOrder(self, *args)


    def setVarOrderFromCSV(self, *args):
        r"""
        setVarOrderFromCSV(self, csvFileURL, csvSeparator)
        setVarOrderFromCSV(self, csvFileURL)
        """
        return _pyAgrum.BNDatabaseGenerator_setVarOrderFromCSV(self, *args)


    def setTopologicalVarOrder(self):
        r"""setTopologicalVarOrder(self)"""
        return _pyAgrum.BNDatabaseGenerator_setTopologicalVarOrder(self)


    def setAntiTopologicalVarOrder(self):
        r"""setAntiTopologicalVarOrder(self)"""
        return _pyAgrum.BNDatabaseGenerator_setAntiTopologicalVarOrder(self)


    def setRandomVarOrder(self):
        r"""setRandomVarOrder(self)"""
        return _pyAgrum.BNDatabaseGenerator_setRandomVarOrder(self)


    def varOrder(self):
        r"""varOrder(self) -> std::vector< gum::Idx,std::allocator< gum::Idx > >"""
        return _pyAgrum.BNDatabaseGenerator_varOrder(self)


    def varOrderNames(self):
        r"""varOrderNames(self) -> Vector_string"""
        return _pyAgrum.BNDatabaseGenerator_varOrderNames(self)


    def log2likelihood(self):
        r"""log2likelihood(self) -> double"""
        return _pyAgrum.BNDatabaseGenerator_log2likelihood(self)


# Register BNDatabaseGenerator in _pyAgrum:
_pyAgrum.BNDatabaseGenerator_swigregister(BNDatabaseGenerator)


def statsObj():
    r"""statsObj()"""
    return _pyAgrum.statsObj()


