Commit 4c06fc40 authored by Pierre-Henri Wuillemin's avatar Pierre-Henri Wuillemin

merging master

parents a1eb6a42 afc19c43
......@@ -22,10 +22,10 @@
* @brief Implementation of the BayesBall class.
*/
#include <agrum/BN/inference/BayesBall.h>
#include <agrum/BN/algorithms/BayesBall.h>
#ifdef GUM_NO_INLINE
#include <agrum/BN/inference/BayesBall_inl.h>
#include <agrum/BN/algorithms/BayesBall_inl.h>
#endif // GUM_NO_INLINE
namespace gum {
......
......@@ -92,9 +92,9 @@ namespace gum {
} /* namespace gum */
#ifndef GUM_NO_INLINE
#include <agrum/BN/inference/BayesBall_inl.h>
#include <agrum/BN/algorithms/BayesBall_inl.h>
#endif // GUM_NO_INLINE
#include <agrum/BN/inference/BayesBall_tpl.h>
#include <agrum/BN/algorithms/BayesBall_tpl.h>
#endif /* GUM_BAYESBALLS_H */
......@@ -23,7 +23,7 @@
*/
// to ease IDE parser
#include <agrum/BN/inference/BayesBall.h>
#include <agrum/BN/algorithms/BayesBall.h>
namespace gum {
......
/***************************************************************************
* Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
* {prenom.nom}_at_lip6.fr *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/** @file
* @brief Source implementation of the class building the Markov Blanket from a
* DAGmodel and a node (id or name)
*
* @author Pierre-Henri WUILLEMIN and Christophe GONZALES
*
*/
#include <agrum/BN/algorithms/MarkovBlanket.h>
#ifdef GUM_NO_INLINE
#include <agrum/BN/algorithms/MarkovBlanket_inl.h>
#endif // GUM_NOINLINE
namespace gum {
MarkovBlanket::MarkovBlanket( const DAGmodel& m, NodeId id )
: __model( m )
, __node( id ) {
__buildMarkovBlanket();
}
MarkovBlanket::MarkovBlanket( const DAGmodel& m, const std::string& name )
: MarkovBlanket( m, m.idFromName( name ) ) {}
MarkovBlanket::~MarkovBlanket() {}
void MarkovBlanket::__buildMarkovBlanket() {
if ( !__model.nodes().exists( __node ) )
GUM_ERROR( InvalidArgument, "Node " << __node << " does not exist." );
__mb.addNode( __node );
for ( const auto& parent : __model.dag().parents( __node ) ) {
__mb.addNode( parent );
__mb.addArc( parent, __node );
}
for ( const auto& child : __model.dag().children( __node ) ) {
__mb.addNode( child );
__mb.addArc( __node, child );
for ( const auto& opar : __model.dag().parents( child ) ) {
if ( opar != __node ) {
if ( !__mb.nodes().exists( opar ) ) __mb.addNode( opar );
__mb.addArc( opar, child );
}
}
}
// we add now some arcs that are between the nodes in __mb but are not part of
// the last ones.
// For instance, an arc between a parent and a parent of children
for ( const auto node : __mb.nodes() ) {
for ( const auto child : __model.dag().children( node ) ) {
if ( __mb.existsNode( child ) && !__mb.existsArc( Arc( node, child ) ) ) {
__mb.addArc( node, child );
__specialArcs.insert( Arc( node, child ) );
}
}
}
}
bool MarkovBlanket::hasSameStructure( const DAGmodel& other ) {
if ( size() != other.size() ) return false;
if ( sizeArcs() != other.sizeArcs() ) return false;
for ( const auto& nid : nodes() ) {
try {
other.idFromName( __model.variable( nid ).name() );
} catch ( NotFound ) {
return false;
}
}
for ( const auto& arc : arcs() ) {
if ( !other.arcs().exists(
Arc( other.idFromName( __model.variable( arc.tail() ).name() ),
other.idFromName( __model.variable( arc.head() ).name() ) ) ) )
return false;
}
return true;
}
std::string MarkovBlanket::toDot( void ) const {
std::stringstream output;
std::stringstream nodeStream;
std::stringstream arcStream;
List<NodeId> treatedNodes;
output << "digraph \""
<< "no_name\" {" << std::endl;
nodeStream << "node [shape = ellipse];" << std::endl;
std::string tab = " ";
for ( const auto node : __mb.nodes() ) {
nodeStream << tab << node << "[label=\"" << __model.variable( node ).name()
<< "\"";
if ( node == __node ) {
nodeStream << ", color=red";
}
nodeStream << "];" << std::endl;
for ( const auto chi : __mb.children( node ) ) {
arcStream << tab << node << " -> " << chi;
if ( __specialArcs.exists( Arc( node, chi ) ) ) {
arcStream << " [color=grey]";
}
arcStream << ";" << std::endl;
}
}
output << nodeStream.str() << std::endl
<< arcStream.str() << std::endl
<< "}" << std::endl;
return output.str();
}
} // namespace gum
/***************************************************************************
* Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
* {prenom.nom}_at_lip6.fr *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/**
* @file
* @brief Class building the markovBlanket from a DAGmodel and a node name
*
* @author Pierre-Henri WUILLEMIN and Christophe GONZALES
*
*/
#ifndef GUM_MARKOVBLANKET_H
#define GUM_MARKOVBLANKET_H
#include <agrum/graphicalModels/DAGmodel.h>
#include <agrum/graphs/diGraph.h>
#include <agrum/graphs/graphElements.h>
namespace gum {
/**
* @class MarkovBlanket MarkovBlanket.h <agrum/BN/algorithms/MarokovBlanket.h>
* @brief Class building the markov Blanket from a BN and a nodeName.
* @ingroup bn_group
* The main goal of this class is to build and to encapsulate the DiGraph which
represents the Markov Blanket.
*
*/
class MarkovBlanket {
public:
MarkovBlanket( const DAGmodel& m, NodeId n );
MarkovBlanket( const DAGmodel& m, const std::string& name );
~MarkovBlanket();
/// @return a copy of the mixed graph
DiGraph mb();
// @return a dot representation of this MarkovBlanket
// node of interest is in red
// special arcs (not used during the construction of the Markov Blanket) are in
// grey
std::string toDot( void ) const;
/// wrapping @ref DiGraph::parents(id)
const NodeSet& parents( const NodeId id ) const;
/// wrapping @ref DiGraph::parents(id)
const NodeSet& children( const NodeId id ) const;
/// wrapping @ref DiGraph::sizeArcs()
Size sizeArcs() const;
/// wrapping @ref DiGraph::arcs()
const ArcSet& arcs() const;
/// wrapping @ref DiGraph::sizeNodes()
Size sizeNodes() const;
/// wrapping @ref DiGraph::size()
Size size() const;
/// wrapping @ref DiGraph::nodes()
const NodeGraphPart& nodes() const;
/// @return true if all the named node are the same and all the named arcs are
/// the same
bool hasSameStructure( const DAGmodel& other );
private:
void __buildMarkovBlanket();
const DAGmodel& __model;
DiGraph __mb;
const NodeId __node;
ArcSet __specialArcs;
};
} // namespace gum
#ifndef GUM_NO_INLINE
#include <agrum/BN/algorithms/MarkovBlanket_inl.h>
#endif // GUM_NOINLINE
#endif // GUM_MARKOVBLANKET_H
/***************************************************************************
* Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
* {prenom.nom}_at_lip6.fr *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
/** @file
* @brief Inline implementation of the class building the essential Graph from a
* DAGmodel
* @author Pierre-Henri WUILLEMIN and Christophe GONZALES
*
*/
// to ease parsing by IDE
#include <agrum/BN/algorithms/MarkovBlanket.h>
namespace gum {
INLINE DiGraph MarkovBlanket::mb() { return __mb; }
INLINE const NodeSet& MarkovBlanket::parents( const NodeId id ) const {
return __mb.parents( id );
}
INLINE const NodeSet& MarkovBlanket::children( const NodeId id ) const {
return __mb.children( id );
}
INLINE Size MarkovBlanket::sizeArcs() const { return __mb.sizeArcs(); }
INLINE const ArcSet& MarkovBlanket::arcs() const { return __mb.arcs(); }
INLINE Size MarkovBlanket::sizeNodes() const { return __mb.sizeNodes(); }
INLINE Size MarkovBlanket::size() const { return __mb.size(); }
INLINE const NodeGraphPart& MarkovBlanket::nodes() const { return __mb.nodes(); }
} // namespace gum
......@@ -23,12 +23,12 @@
*/
#include <limits>
#include <agrum/BN/inference/barrenNodesFinder.h>
#include <agrum/BN/algorithms/barrenNodesFinder.h>
#include <agrum/core/list.h>
#include <agrum/core/sequence.h>
#ifdef GUM_NO_INLINE
#include <agrum/BN/inference/barrenNodesFinder_inl.h>
#include <agrum/BN/algorithms/barrenNodesFinder_inl.h>
#endif // GUM_NO_INLINE
namespace gum {
......
......@@ -121,11 +121,11 @@ namespace gum {
#ifndef GUM_NO_INLINE
#include <agrum/BN/inference/barrenNodesFinder_inl.h>
#include <agrum/BN/algorithms/barrenNodesFinder_inl.h>
#endif // GUM_NO_INLINE
#include <agrum/BN/inference/barrenNodesFinder_tpl.h>
#include <agrum/BN/algorithms/barrenNodesFinder_tpl.h>
#endif /* GUM_BARREN_NODES_FINDER_H */
......@@ -24,11 +24,11 @@
* @author Christophe GONZALES and Pierre-Henri WUILLEMIN
*/
#include <agrum/BN/inference/dSeparation.h>
#include <agrum/BN/algorithms/dSeparation.h>
#include <agrum/core/list.h>
#ifdef GUM_NO_INLINE
#include <agrum/BN/inference/dSeparation_inl.h>
#include <agrum/BN/algorithms/dSeparation_inl.h>
#endif // GUM_NO_INLINE
namespace gum {
......
......@@ -108,10 +108,10 @@ namespace gum {
#ifndef GUM_NO_INLINE
#include <agrum/BN/inference/dSeparation_inl.h>
#include <agrum/BN/algorithms/dSeparation_inl.h>
#endif // GUM_NO_INLINE
#include <agrum/BN/inference/dSeparation_tpl.h>
#include <agrum/BN/algorithms/dSeparation_tpl.h>
#endif /* GUM_D_SEPARATION_H */
......@@ -22,7 +22,7 @@
* @file
* @brief Class building the essential Graph from a DAGmodel
*
* @author Pierre-Henri WUILLEMIN and Lionel TORTI
* @author Pierre-Henri WUILLEMIN and Christophe GONZALES
*
*/
#ifndef GUM_ESSENTIALGRAPH_H
......@@ -42,19 +42,10 @@ namespace gum {
* Essential graph is a mixed graph (Chain Graph) that represents the class of
* markov equivalent Bayesian Networks (with the same independency model).
*
* The main goal of this class is
* - to nest the algorithm to build the essential graph form a BN
* - to enca
* - An arc A -> B represent a dependency between variables A and B, i.e. B
* conditional probability distribution is defined as \f$P(B| \pi(B)\f$.
* The main goal of this class is to nest the algorithm to build the essential graph
* from a BN and to encapsulate the representation (as a MixedGraph) of the essential
* graph.
*
* After a variable is added to the BN, if it's domain size changes, then the
* data in it's CPT is lost.
*
* You should look a the gum::BayesNetFactory class which can help build
* Bayesian Networks.
*
* You can print a BayesNet using
* gum::operator<<(std::ostream&, const BayesNet<GUM_SCALAR>&).
*/
class EssentialGraph {
......
......@@ -28,7 +28,7 @@
#include <cmath>
#include <utility>
#include <agrum/BN/inference/barrenNodesFinder.h>
#include <agrum/BN/algorithms/barrenNodesFinder.h>
#include <agrum/BN/inference/evidenceInference.h>
#include <agrum/BN/inference/jointTargetedInference.h>
#include <agrum/config.h>
......
......@@ -26,9 +26,9 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <agrum/BN/inference/ShaferShenoyInference.h>
#include <agrum/BN/inference/BayesBall.h>
#include <agrum/BN/inference/barrenNodesFinder.h>
#include <agrum/BN/inference/dSeparation.h>
#include <agrum/BN/algorithms/BayesBall.h>
#include <agrum/BN/algorithms/barrenNodesFinder.h>
#include <agrum/BN/algorithms/dSeparation.h>
#include <agrum/graphs/algorithms/binaryJoinTreeConverterDefault.h>
#include <agrum/multidim/instantiation.h>
#include <agrum/multidim/operators/multiDimCombineAndProjectDefault.h>
......@@ -346,7 +346,7 @@ namespace gum {
// however, note that the nodes that received hard evidence do not belong to
// the graph and, therefore, should not be taken into account
const auto& hard_ev_nodes = this->hardEvidenceNodes();
for ( const auto node : this->targets() ) {
for ( const auto node : this->allTargets() ) {
if ( !__graph.exists( node ) && !hard_ev_nodes.exists( node ) ) return true;
}
for ( const auto& nodes : this->jointTargets() ) {
......@@ -412,7 +412,7 @@ namespace gum {
// the BN without altering the inference output
if ( __barren_nodes_type == FindBarrenNodesType::FIND_BARREN_NODES ) {
// identify the barren nodes
NodeSet target_nodes = this->targets();
NodeSet target_nodes = this->allTargets();
for ( const auto& nodeset : this->jointTargets() ) {
target_nodes += nodeset;
}
......@@ -999,7 +999,7 @@ namespace gum {
void ShaferShenoyInference<GUM_SCALAR>::__computeJoinTreeRoots() {
// get the set of cliques in which we can find the targets and joint_targets
NodeSet clique_targets;
for ( const auto node : this->targets() ) {
for ( const auto node : this->allTargets() ) {
try {
clique_targets.insert( __node_to_clique[node] );
} catch ( Exception& ) {
......@@ -1288,7 +1288,7 @@ namespace gum {
template <typename GUM_SCALAR>
INLINE void ShaferShenoyInference<GUM_SCALAR>::_makeInference() {
// collect messages for all single targets
for ( const auto node : this->targets() ) {
for ( const auto node : this->allTargets() ) {
// perform only collects in the join tree for nodes that have
// not received hard evidence (those that received hard evidence were
// not included into the join tree for speed-up reasons)
......
......@@ -237,7 +237,7 @@ namespace gum {
template <typename GUM_SCALAR>
const Potential<GUM_SCALAR>&
JointTargetedInference<GUM_SCALAR>::posterior( const NodeId node ) {
if ( this->targets().contains( node ) )
if ( this->isTarget( node ) )
return MarginalTargetedInference<GUM_SCALAR>::posterior( node );
else
return jointPosterior( NodeSet{node} );
......
......@@ -30,7 +30,7 @@
#include <cmath>
#include <utility>
#include <agrum/BN/inference/barrenNodesFinder.h>
#include <agrum/BN/algorithms/barrenNodesFinder.h>
#include <agrum/BN/inference/evidenceInference.h>
#include <agrum/BN/inference/jointTargetedInference.h>
#include <agrum/BN/inference/relevantPotentialsFinderType.h>
......
......@@ -28,9 +28,9 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <algorithm>
#include <agrum/BN/inference/BayesBall.h>
#include <agrum/BN/inference/barrenNodesFinder.h>
#include <agrum/BN/inference/dSeparation.h>
#include <agrum/BN/algorithms/BayesBall.h>
#include <agrum/BN/algorithms/barrenNodesFinder.h>
#include <agrum/BN/algorithms/dSeparation.h>
#include <agrum/graphs/algorithms/binaryJoinTreeConverterDefault.h>
#include <agrum/multidim/instantiation.h>
#include <agrum/multidim/operators/multiDimCombineAndProjectDefault.h>
......@@ -385,7 +385,7 @@ namespace gum {
// however, note that the nodes that received hard evidence do not belong to
// the graph and, therefore, should not be taken into account
const auto& hard_ev_nodes = this->hardEvidenceNodes();
for ( const auto node : this->targets() ) {
for ( const auto node : this->allTargets() ) {
if ( !__graph.exists( node ) && !hard_ev_nodes.exists( node ) ) return true;
}
for ( const auto& nodes : this->jointTargets() ) {
......@@ -452,7 +452,7 @@ namespace gum {
// altering the inference output
if ( __barren_nodes_type == FindBarrenNodesType::FIND_BARREN_NODES ) {
// identify the barren nodes
NodeSet target_nodes = this->targets();
NodeSet target_nodes = this->allTargets();
for ( const auto& nodeset : this->jointTargets() ) {
target_nodes += nodeset;
}
......@@ -968,7 +968,7 @@ namespace gum {
void LazyPropagation<GUM_SCALAR>::__computeJoinTreeRoots() {
// get the set of cliques in which we can find the targets and joint_targets
NodeSet clique_targets;
for ( const auto node : this->targets() ) {
for ( const auto node : this->allTargets() ) {
try {
clique_targets.insert( __node_to_clique[node] );
} catch ( Exception& ) {
......@@ -1347,7 +1347,7 @@ namespace gum {
template <typename GUM_SCALAR>
INLINE void LazyPropagation<GUM_SCALAR>::_makeInference() {
// collect messages for all single targets
for ( const auto node : this->targets() ) {
for ( const auto node : this->allTargets() ) {
// perform only collects in the join tree for nodes that have
// not received hard evidence (those that received hard evidence were
// not included into the join tree for speed-up reasons)
......
......@@ -50,19 +50,21 @@ namespace gum {
* the current state of the inference. Note that the MarginalTargetedInference
* is designed to be used in incremental inference engines.
*/
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
class MarginalTargetedInference : public virtual BayesNetInference<GUM_SCALAR> {
public:
public:
// ############################################################################
/// @name Constructors / Destructors
// ############################################################################
/// @{
/// default constructor
/** @warning By default, all the nodes of the Bayes net are targets.
/** @warning By default (when the targets set is empty), all the nodes of
* the Bayes net are considered as targets. Once a first target is added to the
* set, the remaining nodes are not considered as default targets anymore.
* @warning note that, by aGrUM's rule, the BN is not copied but only
* referenced by the inference algorithm. */
MarginalTargetedInference(const IBayesNet<GUM_SCALAR> *bn);
MarginalTargetedInference( const IBayesNet<GUM_SCALAR>* bn );
/// destructor
virtual ~MarginalTargetedInference();
......@@ -90,7 +92,7 @@ namespace gum {
*
* @throw UndefinedElement if node is not in the set of targets
*/
virtual const Potential<GUM_SCALAR> &posterior(const NodeId node);
virtual const Potential<GUM_SCALAR>& posterior( const NodeId node );
/// Computes and returns the posterior of a node.
/**
......@@ -108,7 +110,7 @@ namespace gum {
*
* @throw UndefinedElement if node is not in the set of targets
*/
virtual const Potential<GUM_SCALAR> &posterior(const std::string &nodeName);
virtual const Potential<GUM_SCALAR>& posterior( const std::string& nodeName );
/// @}
......@@ -119,44 +121,62 @@ namespace gum {
/// @{
/// Clear all previously defined targets
/// @warning this means that every node is now a target by default
virtual void eraseAllTargets();
/// adds all nodes as targets
/// @warning due to the semantic of targets, this function is an alias of
/// eraseAllTargets()
virtual void addAllTargets() final;
/// Add a marginal target to the list of targets
/**
* @throw UndefinedElement if target is not a NodeId in the Bayes net
*/
virtual void addTarget(const NodeId target) final;
virtual void addTarget( const NodeId target ) final;
/// Add a marginal target to the list of targets
/**
* @throw UndefinedElement if target is not a NodeId in the Bayes net
*/
virtual void addTarget(const std::string &nodeName) final;
virtual void addTarget( const std::string& nodeName ) final;
/// removes an existing (marginal) target
/** @warning If the target does not already exist, the method does nothing.
* In particular, it does not raise any exception. */
virtual void eraseTarget(const NodeId target) final;
* In particular, it does not raise any exception.
* @warning Erasing the last target implies that every node is now a target by
* default.
* */
virtual void eraseTarget( const NodeId target ) final;
/// removes an existing (marginal) target
/** @warning If the target does not already exist, the method does nothing.
* In particular, it does not raise any exception. */
virtual void eraseTarget(const std::string &nodeName) final;
* In particular, it does not raise any exception.
* @warning Erasing the last target implies that every node is now a target by
* default.*/
virtual void eraseTarget( const std::string& nodeName ) final;
/// return true if variable is a (marginal) target
virtual bool isTarget(const NodeId variable) const final;
virtual bool isTarget( const NodeId variable ) const final;
/// return true if variable is a (marginal) target
virtual bool isTarget(const std::string &nodeName) const final;
virtual bool isTarget( const std::string& nodeName ) const final;
/// returns the number of marginal targets
/// returns the number of marginal targets.
//// @warning if the result is 0, it means that all the nodes are targets by
/// default.
virtual const Size nbrTargets() const noexcept final;
/// returns the list of marginal targets
virtual const NodeSet &targets() const noexcept final;
/// returns the set of marginal targets
//// @warning if the set is empty, it means that all the nodes are targets by
/// default.
virtual const NodeSet& targets() const noexcept final;
/// return all the marginal targets.
/** Particularly, if the targetSet is empty, allTargets will send a copy of the
* nodeSet of the BN
*/
virtual NodeSet allTargets() const noexcept final;
/// @}
......@@ -169,13 +189,13 @@ namespace gum {
* Compute Shanon's entropy of a node given the observation
* @see http://en.wikipedia.org/wiki/Information_entropy
*/
virtual GUM_SCALAR H(const NodeId X) final;
virtual GUM_SCALAR H( const NodeId X ) final;
/** Entropy
* Compute Shanon's entropy of a node given the observation
* @see http://en.wikipedia.org/wiki/Information_entropy
*/
virtual GUM_SCALAR H(const std::string &nodeName) final;
virtual GUM_SCALAR H( const std::string& nodeName ) final;
///@}
......@@ -191,8 +211,8 @@ namespace gum {
* @param evs the vector of nodeId of the observed variables
* @return a Potential
*/
Potential<GUM_SCALAR> evidenceImpact(NodeId target,
const std::vector<NodeId>& evs);
Potential<GUM_SCALAR> evidenceImpact( NodeId target,
const std::vector<NodeId>& evs );
/**
* Create a gum::Potential for P(target|evs) (for all instanciation of target
......@@ -204,17 +224,17 @@ namespace gum {
* @param evs the nodeId of the observed variable
* @return a Potential
*/
Potential<GUM_SCALAR> evidenceImpact(const std::string& target,
const std::vector<std::string>& evs);
Potential<GUM_SCALAR> evidenceImpact( const std::string& target,