Commit 6a18e957 authored by Pierre-Henri Wuillemin's avatar Pierre-Henri Wuillemin

Merge branch 'master' into documentation/swigDoc

parents 1a6577af b70b59d0
......@@ -81,6 +81,7 @@ apps/pyAgrum/notebooks/*.png
apps/pyAgrum/notebooks/WaterSprinkler.*
apps/pyAgrum/notebooks/*.csv
apps/pyAgrum/notebooks/*.html
.ipynb_checkpoints
apps/pyAgrum/samples/actuel.png
apps/pyAgrum/samples/alarm.csv
......
......@@ -7,11 +7,11 @@ Welcome to aGrUM's contribution guide and thank you for helping us making aGrUM
Before submitting your first contribution, please take the time to fill aGrUM's contribution agreement. We will not accept any contribution without it !
You can find the individual agreement [here](https://gitlab.com/agrumery/aGrUM/wikis/contribution/individual) and the entity agreement
[here](https://gitlab.com/agrumery/aGrUM/wikis/contribution/entity). Please send us your agreeemnt at agrum@lip6.fr.
[here](https://gitlab.com/agrumery/aGrUM/wikis/contribution/entity). Please send us your agreement at [info@agrum.org](mailto:info@agrum.org).
### Why a contribution agreement ?
We are planning to change aGrUM's licence, but don't worry aGrUM will always be Open Source. To do so, we need your agreement as one of aGrUM's contributor. There is also some legal consideration about how your contribution can be used and distributed with aGrUM. So please take your time and read the agreement before sending it to us. And if you have any question, feel free to ask us at agrum@lip6.fr.
We are planning to change aGrUM's licence, but don't worry aGrUM will always be Open Source. To do so, we need your agreement as one of aGrUM's contributor. There is also some legal consideration about how your contribution can be used and distributed with aGrUM. So please take your time and read the agreement before sending it to us. And if you have any question, feel free to ask us at [info@agrum.org](mailto:info@agrum.org).
## What to contribute
......@@ -23,7 +23,7 @@ You can contribute to aGrUM in the following domains:
### Contributing to aGrUM's Code
Before contributing to aGrUM's code you should ask us before hand at agrum@lip6.fr. This will prevent you from submiting code that we won't integrate: aGrUM's is still under heavy development and some featured modules like `bayesnet` or `learning` are refactored quite often.
Before contributing to aGrUM's code you should ask us before hand at [info@agrum.org](mailto:info@agrum.org). This will prevent you from submiting code that we won't integrate: aGrUM's is still under heavy development and some featured modules like `bayesnet` or `learning` are refactored quite often.
Outside of aGrUM's core code, you can help us [solve bugs](https://gitlab.com/agrumery/aGrUM/issues), write [new tests](https://gitlab.com/agrumery/aGrUM/tree/master/src/testunits/README.md) or contribute to one of aGrUM's [applications](https://gitlab.com/agrumery/aGrUM/tree/master/apps/README.md) or [wrappers](https://gitlab.com/agrumery/aGrUM/tree/master/wrappers/README.md).
......@@ -39,6 +39,6 @@ Packaging and distributing aGrUM or pyAgrum helps a lot by leting aGrUM users ea
## How to contribute
For your first contribution you should fork aGrUM, make your contribution and send us a merge request. Before contributing, please take the time to warn us at agrum@lip6.fr so we can help you out with your contribution.
For your first contribution you should fork aGrUM, make your contribution and send us a merge request. Before contributing, please take the time to warn us at [info@agrum.org](mailto:info@agrum.org) so we can help you out with your contribution.
......@@ -12,7 +12,7 @@ The purpose of this contributor agreement ("Agreement") is to clarify and docume
"Affiliate" means any other Legal Entity that controls, is controlled by, or under common control with that Legal Entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such Legal Entity, whether by contract or otherwise, (ii) ownership of fifty percent (50%) or more of the outstanding shares or securities that vote to elect the management or other persons who direct such Legal Entity or (iii) beneficial ownership of such entity.
"Contribution" means any original work of authorship (software and/or documentation) including any modifications or additions to an existing work, Submitted by You to Us, in which You own the Copyright. If You do not own the Copyright in the entire work of authorship, please contact Us at agrum@lip6.fr.
"Contribution" means any original work of authorship (software and/or documentation) including any modifications or additions to an existing work, Submitted by You to Us, in which You own the Copyright. If You do not own the Copyright in the entire work of authorship, please contact Us at info@agrum.org.
"Copyright" means all rights protecting works of authorship owned or controlled by You, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence including any extensions by You.
......
......@@ -8,7 +8,7 @@ The purpose of this contributor agreement ("Agreement") is to clarify and docume
1. DEFINITIONS
"You" means the Individual Copyright owner who submits a Contribution to Us. If You are an employee and submit the Contribution as part of your employment, You have had Your employer approve this Agreement or sign the Entity version of this document.
"Contribution" means any original work of authorship (software and/or documentation) including any modifications or additions to an existing work, Submitted by You to Us, in which You own the Copyright. If You do not own the Copyright in the entire work of authorship, please contact Us at agrum@lip6.fr.
"Contribution" means any original work of authorship (software and/or documentation) including any modifications or additions to an existing work, Submitted by You to Us, in which You own the Copyright. If You do not own the Copyright in the entire work of authorship, please contact Us at info@agrum.org.
"Copyright" means all rights protecting works of authorship owned or controlled by You, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence including any extensions by You.
......
......@@ -53,7 +53,7 @@ namespace gum {
}
for ( const auto& child : __model.dag().children( __node ) ) {
__mb.addNode( child );
if ( !__mb.nodes().exists( child ) ) __mb.addNode( child );
__mb.addArc( __node, child );
for ( const auto& opar : __model.dag().parents( child ) ) {
if ( opar != __node ) {
......
......@@ -149,7 +149,7 @@ namespace gum {
/// Clear all the previously defined marginal targets
virtual void eraseAllMarginalTargets() final;
/// Add a set of nodes as a new joint target
/// Add a set of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.
/**
* @throw UndefinedElement if some node(s) do not belong to the Bayes net
*/
......
......@@ -91,10 +91,13 @@ namespace gum {
// Clear all previously defined targets (single targets and sets of targets)
template <typename GUM_SCALAR>
INLINE void JointTargetedInference<GUM_SCALAR>::eraseAllJointTargets() {
_onAllJointTargetsErased();
__joint_targets.clear();
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
if ( __joint_targets.size() > 0 ) {
// we already are in target mode. So no this->_setTargetedMode(); is needed
_onAllJointTargetsErased();
__joint_targets.clear();
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
}
......@@ -141,6 +144,7 @@ namespace gum {
if ( iter->isSubsetOf( joint_target ) ) eraseJointTarget( *iter );
}
this->_setTargetedMode(); // does nothing if already in targeted mode
__joint_targets.insert( joint_target );
_onJointTargetAdded( joint_target );
this->__state =
......@@ -169,6 +173,8 @@ namespace gum {
// check that the joint_target set does not contain the new target
if ( __joint_targets.contains( joint_target ) ) {
// note that we have to be in target mode when we are here
// so, no this->_setTargetedMode(); is necessary
_onJointTargetErased( joint_target );
__joint_targets.erase( joint_target );
this->__state =
......
......@@ -50,9 +50,9 @@ 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
// ############################################################################
......@@ -62,7 +62,7 @@ namespace gum {
/** @warning By default, all the nodes of the Bayes net are targets.
* @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 +90,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 +108,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 );
/// @}
......@@ -128,35 +128,35 @@ namespace gum {
/**
* @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;
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;
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
virtual const Size nbrTargets() const noexcept final;
/// returns the list of marginal targets
virtual const NodeSet &targets() const noexcept final;
virtual const NodeSet& targets() const noexcept final;
/// @}
......@@ -169,13 +169,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 +191,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 +204,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,
const std::vector<std::string>& evs );
protected:
protected:
/// fired after a new marginal target is inserted
/** @param id The target variable's id. */
virtual void _onMarginalTargetAdded(const NodeId id) = 0;
virtual void _onMarginalTargetAdded( const NodeId id ) = 0;
/// fired before a marginal target is removed
/** @param id The target variable's id. */
virtual void _onMarginalTargetErased(const NodeId id) = 0;
virtual void _onMarginalTargetErased( const NodeId id ) = 0;
/// fired after all the nodes of the BN are added as marginal targets
virtual void _onAllMarginalTargetsAdded() = 0;
......@@ -223,16 +223,19 @@ namespace gum {
virtual void _onAllMarginalTargetsErased() = 0;
/// fired after a new Bayes net has been assigned to the engine
virtual void _onBayesNetChanged(const IBayesNet<GUM_SCALAR> *bn);
virtual void _onBayesNetChanged( const IBayesNet<GUM_SCALAR>* bn );
/// asks derived classes for the posterior of a given variable
/** @param id The variable's id. */
virtual const Potential<GUM_SCALAR> &_posterior(const NodeId id) = 0;
virtual const Potential<GUM_SCALAR>& _posterior( const NodeId id ) = 0;
protected:
void _setTargetedMode();
bool _isTargetedMode() const;
private:
private:
/// whether the actual targets are default
bool __defaultTargets;
bool __targeted_mode;
/// the set of marginal targets
NodeSet __targets;
......
......@@ -28,37 +28,37 @@ namespace gum {
// Default Constructor
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
MarginalTargetedInference<GUM_SCALAR>::MarginalTargetedInference(
const IBayesNet <GUM_SCALAR> *bn)
: BayesNetInference<GUM_SCALAR>(bn) {
const IBayesNet<GUM_SCALAR>* bn )
: BayesNetInference<GUM_SCALAR>( bn ) {
// assign a BN if this has not been done before (due to virtual inheritance)
if (this->__bn == nullptr) {
BayesNetInference<GUM_SCALAR>::__setBayesNetDuringConstruction(bn);
if ( this->__bn == nullptr ) {
BayesNetInference<GUM_SCALAR>::__setBayesNetDuringConstruction( bn );
}
// sets all the nodes as targets
if (bn != nullptr) {
__defaultTargets=true;
if ( bn != nullptr ) {
__targeted_mode = false;
__targets = bn->dag().asNodeSet();
}
GUM_CONSTRUCTOR(MarginalTargetedInference);
GUM_CONSTRUCTOR( MarginalTargetedInference );
}
// Destructor
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
MarginalTargetedInference<GUM_SCALAR>::~MarginalTargetedInference() {
GUM_DESTRUCTOR(MarginalTargetedInference);
GUM_DESTRUCTOR( MarginalTargetedInference );
}
// fired when a new BN is assigned to the inference engine
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::_onBayesNetChanged(
const IBayesNet <GUM_SCALAR> *bn) {
__defaultTargets=true;
const IBayesNet<GUM_SCALAR>* bn ) {
__targeted_mode = true;
__setAllMarginalTargets();
}
......@@ -68,150 +68,161 @@ namespace gum {
// ##############################################################################
// return true if variable is a target
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
INLINE bool
MarginalTargetedInference<GUM_SCALAR>::isTarget(const NodeId var) const {
MarginalTargetedInference<GUM_SCALAR>::isTarget( const NodeId var ) const {
// check that the variable belongs to the bn
if (this->__bn == nullptr) GUM_ERROR(NullElement,
"No Bayes net has been assigned to the "
"inference algorithm");
if (!this->__bn->dag().exists(var)) {
GUM_ERROR(UndefinedElement, var << " is not a NodeId in the bn");
if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
if ( !this->__bn->dag().exists( var ) ) {
GUM_ERROR( UndefinedElement, var << " is not a NodeId in the bn" );
}
return __targets.contains(var);
return __targets.contains( var );
}
// Add a single target to the list of targets
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
INLINE bool MarginalTargetedInference<GUM_SCALAR>::isTarget(
const std::string &nodeName) const {
return isTarget(this->__bn->idFromName(nodeName));
const std::string& nodeName ) const {
return isTarget( this->__bn->idFromName( nodeName ) );
}
// Clear all previously defined targets (single targets and sets of targets)
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
INLINE void MarginalTargetedInference<GUM_SCALAR>::eraseAllTargets() {
_onAllMarginalTargetsErased();
__targets.clear();
_setTargetedMode(); // does nothing if already in targeted mode
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
// Add a single target to the list of targets
template<typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::addTarget(NodeId target) {
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::addTarget( NodeId target ) {
// check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement,
"No Bayes net has been assigned to the "
"inference algorithm");
if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
if (!this->__bn->dag().exists(target)) {
GUM_ERROR(UndefinedElement, target << " is not a NodeId in the bn");
if ( !this->__bn->dag().exists( target ) ) {
GUM_ERROR( UndefinedElement, target << " is not a NodeId in the bn" );
}
if (__defaultTargets) {
__defaultTargets=false;
eraseAllTargets();
}
_setTargetedMode(); // does nothing if already in targeted mode
// add the new target
if (!__targets.contains(target)) {
__targets.insert(target);
_onMarginalTargetAdded(target);
if ( !__targets.contains( target ) ) {
__targets.insert( target );
_onMarginalTargetAdded( target );
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
}
// Add all nodes as targets
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::addAllTargets() {
// check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement,
"No Bayes net has been assigned to the "
"inference algorithm");
for (auto target : this->__bn->dag()) {
if (!__targets.contains(target)) {
__targets.insert(target);
_onMarginalTargetAdded(target);
if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
_setTargetedMode(); // does nothing if already in targeted mode
for ( auto target : this->__bn->dag() ) {
if ( !__targets.contains( target ) ) {
__targets.insert( target );
_onMarginalTargetAdded( target );
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
}
}
// Add a single target to the list of targets
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
void
MarginalTargetedInference<GUM_SCALAR>::addTarget(const std::string &nodeName) {
MarginalTargetedInference<GUM_SCALAR>::addTarget( const std::string& nodeName ) {
// check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement,
"No Bayes net has been assigned to the "
"inference algorithm");
if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
addTarget(this->__bn->idFromName(nodeName));
addTarget( this->__bn->idFromName( nodeName ) );
}
// removes an existing target
template<typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::eraseTarget(const NodeId target) {
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::eraseTarget( const NodeId target ) {
// check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement,
"No Bayes net has been assigned to the "
"inference algorithm");
if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
if (!this->__bn->dag().exists(target)) {
GUM_ERROR(UndefinedElement, target << " is not a NodeId in the bn");
if ( !this->__bn->dag().exists( target ) ) {
GUM_ERROR( UndefinedElement, target << " is not a NodeId in the bn" );
}
if (__targets.contains(target)) {
_onMarginalTargetErased(target);
__targets.erase(target);
if ( __targets.contains( target ) ) {
__targeted_mode = true; // we do not use _setTargetedMode because we do not
// want to clear the targets
_onMarginalTargetErased( target );
__targets.erase( target );
this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
}
}
// Add a single target to the list of targets
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::eraseTarget(
const std::string &nodeName) {
const std::string& nodeName ) {
// check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement,
"No Bayes net has been assigned to the "
"inference algorithm");
if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the "
"inference algorithm" );
eraseTarget(this->__bn->idFromName(nodeName));
eraseTarget( this->__bn->idFromName( nodeName ) );
}
// returns the list of single targets
template<typename GUM_SCALAR>
INLINE const NodeSet &MarginalTargetedInference<GUM_SCALAR>::targets() const
noexcept {
template <typename GUM_SCALAR>
INLINE const NodeSet& MarginalTargetedInference<GUM_SCALAR>::targets() const
noexcept {
return __targets;
}
// returns the list of single targets
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
INLINE const Size MarginalTargetedInference<GUM_SCALAR>::nbrTargets() const
noexcept {
noexcept {
return __targets.size();
}
/// sets all the nodes of the Bayes net as targets
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::__setAllMarginalTargets() {
__targets.clear();
if (this->__bn != nullptr) {
if ( this->__bn != nullptr ) {
__targets = this->__bn->dag().asNodeSet();
_onAllMarginalTargetsAdded();
}
......@@ -223,104 +234,115 @@ namespace gum {
// ##############################################################################
// Compute the posterior of a node.
template<typename GUM_SCALAR>
const Potential <GUM_SCALAR> &
MarginalTargetedInference<GUM_SCALAR>::posterior(const NodeId var) {
if (!isTarget(var)) {
template <typename GUM_SCALAR>
const Potential<GUM_SCALAR>&
MarginalTargetedInference<GUM_SCALAR>::posterior( const NodeId var ) {
if ( !isTarget( var ) ) {
// throws UndefinedElement if var is not a target
GUM_ERROR(UndefinedElement, var << " is not a target node");
GUM_ERROR( UndefinedElement, var << " is not a target node" );
}
if (!this->isDone()) {
if ( !this->isDone() ) {
this->makeInference();
}
return _posterior(var);
return _posterior( var );
}
// Compute the posterior of a node.
template<typename GUM_SCALAR>
const Potential <GUM_SCALAR> &
MarginalTargetedInference<GUM_SCALAR>::posterior(const std::string &nodeName) {
return posterior(this->BN().idFromName(nodeName));
template <typename GUM_SCALAR>
const Potential<GUM_SCALAR>&
MarginalTargetedInference<GUM_SCALAR>::posterior( const std::string& nodeName ) {
return posterior( this->BN().idFromName( nodeName ) );
}
/* Entropy
* Compute Shanon's entropy of a node given the observation
*/
template<typename GUM_SCALAR>
INLINE GUM_SCALAR MarginalTargetedInference<GUM_SCALAR>::H(const NodeId X) {
return posterior(X).entropy();
template <typename GUM_SCALAR>
INLINE GUM_SCALAR MarginalTargetedInference<GUM_SCALAR>::H( const NodeId X ) {
return posterior( X ).entropy();
}
/* Entropy
* Compute Shanon's entropy of a node given the observation
*/
template<typename GUM_SCALAR>
template <typename GUM_SCALAR>
INLINE GUM_SCALAR
MarginalTargetedInference<GUM_SCALAR>::H(const std::string &nodeName) {
return H(this->BN().idFromName(nodeName));
MarginalTargetedInference<GUM_SCALAR>::H( const std::string& nodeName ) {
return H( this->BN().idFromName( nodeName ) );
}
template<typename GUM_SCALAR>
Potential <GUM_SCALAR>
MarginalTargetedInference<GUM_SCALAR>::evidenceImpact(NodeId target,
const std::vector<NodeId>& evs) {
const auto &vtarget = this->BN().variable(target);
template <typename GUM_SCALAR>
Potential<GUM_SCALAR> MarginalTargetedInference<GUM_SCALAR>::evidenceImpact(
NodeId target, const std::vector<NodeId>& evs ) {
const auto& vtarget = this->BN().variable( target );
NodeSet soids(evs.size());
for (const auto &e : evs)
NodeSet soids( evs.size() );
for ( const auto& e : evs )
soids << e;
if (soids.contains(target)) {
GUM_ERROR(InvalidArgument,
"Target <" << vtarget.name() << "> (" << target
<< ") can not be in evs ("
<< evs
<< ").");
if ( soids.contains( target ) ) {
GUM_ERROR( InvalidArgument,
"Target <" << vtarget.name() << "> (" << target
<< ") can not be in evs ("
<< evs
<< ")." );
}
auto condset = this->BN().minimalCondSet(target, soids);
auto condset = this->BN().minimalCondSet( target, soids );
Potential<GUM_SCALAR> res;
this->eraseAllTargets();
this->eraseAllEvidence();
res.add(this->BN().variable(target));
this->addTarget(target);
for (const auto &n : condset) {
res.add(this->BN().variable(n));
this->addEvidence(n, 0);
res.add( this->BN().variable( target ) );
this->addTarget( target );
for ( const auto& n : condset ) {
res.add( this->BN().variable( n ) );
this->addEvidence( n, 0 );
}
Instantiation inst(res);
for (inst.setFirst(); !inst.end(); inst.incNotVar(vtarget)) {
Instantiation inst( res );
for ( inst.setFirst(); !inst.end(); inst.incNotVar( vtarget ) ) {
// inferring
for (const auto &n : condset)
this->chgEvidence(n, inst.val(this->BN().variable(n)));
for ( const auto& n : condset )
this->chgEvidence( n, inst.val( this->BN().variable( n ) ) );
this->makeInference();
// populate res
for (inst.setFirstVar(vtarget); !inst.end(); inst.incVar(vtarget)) {
res.set(inst, this->posterior(target)[inst]);
for ( inst.setFirstVar( vtarget ); !inst.end(); inst.incVar( vtarget ) ) {
res.set( inst, this->posterior( target )[inst] );
}
inst.setFirstVar(vtarget); // remove inst.end() flag
inst.setFirstVar( vtarget ); // remove inst.end() flag
}