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 ...@@ -81,6 +81,7 @@ apps/pyAgrum/notebooks/*.png
apps/pyAgrum/notebooks/WaterSprinkler.* apps/pyAgrum/notebooks/WaterSprinkler.*
apps/pyAgrum/notebooks/*.csv apps/pyAgrum/notebooks/*.csv
apps/pyAgrum/notebooks/*.html apps/pyAgrum/notebooks/*.html
.ipynb_checkpoints
apps/pyAgrum/samples/actuel.png apps/pyAgrum/samples/actuel.png
apps/pyAgrum/samples/alarm.csv apps/pyAgrum/samples/alarm.csv
......
...@@ -7,11 +7,11 @@ Welcome to aGrUM's contribution guide and thank you for helping us making aGrUM ...@@ -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 ! 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 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 ? ### 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 ## What to contribute
...@@ -23,7 +23,7 @@ You can contribute to aGrUM in the following domains: ...@@ -23,7 +23,7 @@ You can contribute to aGrUM in the following domains:
### Contributing to aGrUM's Code ### 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). 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 ...@@ -39,6 +39,6 @@ Packaging and distributing aGrUM or pyAgrum helps a lot by leting aGrUM users ea
## How to contribute ## 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 ...@@ -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. "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. "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 ...@@ -8,7 +8,7 @@ The purpose of this contributor agreement ("Agreement") is to clarify and docume
1. DEFINITIONS 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. "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. "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 { ...@@ -53,7 +53,7 @@ namespace gum {
} }
for ( const auto& child : __model.dag().children( __node ) ) { for ( const auto& child : __model.dag().children( __node ) ) {
__mb.addNode( child ); if ( !__mb.nodes().exists( child ) ) __mb.addNode( child );
__mb.addArc( __node, child ); __mb.addArc( __node, child );
for ( const auto& opar : __model.dag().parents( child ) ) { for ( const auto& opar : __model.dag().parents( child ) ) {
if ( opar != __node ) { if ( opar != __node ) {
......
...@@ -149,7 +149,7 @@ namespace gum { ...@@ -149,7 +149,7 @@ namespace gum {
/// Clear all the previously defined marginal targets /// Clear all the previously defined marginal targets
virtual void eraseAllMarginalTargets() final; 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 * @throw UndefinedElement if some node(s) do not belong to the Bayes net
*/ */
......
...@@ -91,11 +91,14 @@ namespace gum { ...@@ -91,11 +91,14 @@ namespace gum {
// Clear all previously defined targets (single targets and sets of targets) // Clear all previously defined targets (single targets and sets of targets)
template <typename GUM_SCALAR> template <typename GUM_SCALAR>
INLINE void JointTargetedInference<GUM_SCALAR>::eraseAllJointTargets() { INLINE void JointTargetedInference<GUM_SCALAR>::eraseAllJointTargets() {
if ( __joint_targets.size() > 0 ) {
// we already are in target mode. So no this->_setTargetedMode(); is needed
_onAllJointTargetsErased(); _onAllJointTargetsErased();
__joint_targets.clear(); __joint_targets.clear();
this->__state = this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure; BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
} }
}
// Clear all previously defined targets (single and joint targets) // Clear all previously defined targets (single and joint targets)
...@@ -141,6 +144,7 @@ namespace gum { ...@@ -141,6 +144,7 @@ namespace gum {
if ( iter->isSubsetOf( joint_target ) ) eraseJointTarget( *iter ); if ( iter->isSubsetOf( joint_target ) ) eraseJointTarget( *iter );
} }
this->_setTargetedMode(); // does nothing if already in targeted mode
__joint_targets.insert( joint_target ); __joint_targets.insert( joint_target );
_onJointTargetAdded( joint_target ); _onJointTargetAdded( joint_target );
this->__state = this->__state =
...@@ -169,6 +173,8 @@ namespace gum { ...@@ -169,6 +173,8 @@ namespace gum {
// check that the joint_target set does not contain the new target // check that the joint_target set does not contain the new target
if ( __joint_targets.contains( joint_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 ); _onJointTargetErased( joint_target );
__joint_targets.erase( joint_target ); __joint_targets.erase( joint_target );
this->__state = this->__state =
......
...@@ -50,7 +50,7 @@ namespace gum { ...@@ -50,7 +50,7 @@ namespace gum {
* the current state of the inference. Note that the MarginalTargetedInference * the current state of the inference. Note that the MarginalTargetedInference
* is designed to be used in incremental inference engines. * is designed to be used in incremental inference engines.
*/ */
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
class MarginalTargetedInference : public virtual BayesNetInference<GUM_SCALAR> { class MarginalTargetedInference : public virtual BayesNetInference<GUM_SCALAR> {
public: public:
// ############################################################################ // ############################################################################
...@@ -62,7 +62,7 @@ namespace gum { ...@@ -62,7 +62,7 @@ namespace gum {
/** @warning By default, all the nodes of the Bayes net are targets. /** @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 * @warning note that, by aGrUM's rule, the BN is not copied but only
* referenced by the inference algorithm. */ * referenced by the inference algorithm. */
MarginalTargetedInference(const IBayesNet<GUM_SCALAR> *bn); MarginalTargetedInference( const IBayesNet<GUM_SCALAR>* bn );
/// destructor /// destructor
virtual ~MarginalTargetedInference(); virtual ~MarginalTargetedInference();
...@@ -90,7 +90,7 @@ namespace gum { ...@@ -90,7 +90,7 @@ namespace gum {
* *
* @throw UndefinedElement if node is not in the set of targets * @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. /// Computes and returns the posterior of a node.
/** /**
...@@ -108,7 +108,7 @@ namespace gum { ...@@ -108,7 +108,7 @@ namespace gum {
* *
* @throw UndefinedElement if node is not in the set of targets * @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 { ...@@ -128,35 +128,35 @@ namespace gum {
/** /**
* @throw UndefinedElement if target is not a NodeId in the Bayes net * @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 /// Add a marginal target to the list of targets
/** /**
* @throw UndefinedElement if target is not a NodeId in the Bayes net * @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 /// removes an existing (marginal) target
/** @warning If the target does not already exist, the method does nothing. /** @warning If the target does not already exist, the method does nothing.
* In particular, it does not raise any exception. */ * 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 /// removes an existing (marginal) target
/** @warning If the target does not already exist, the method does nothing. /** @warning If the target does not already exist, the method does nothing.
* In particular, it does not raise any exception. */ * 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 /// 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 /// 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
virtual const Size nbrTargets() const noexcept final; virtual const Size nbrTargets() const noexcept final;
/// returns the list of marginal targets /// 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 { ...@@ -169,13 +169,13 @@ namespace gum {
* Compute Shanon's entropy of a node given the observation * Compute Shanon's entropy of a node given the observation
* @see http://en.wikipedia.org/wiki/Information_entropy * @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 /** Entropy
* Compute Shanon's entropy of a node given the observation * Compute Shanon's entropy of a node given the observation
* @see http://en.wikipedia.org/wiki/Information_entropy * @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 { ...@@ -191,8 +191,8 @@ namespace gum {
* @param evs the vector of nodeId of the observed variables * @param evs the vector of nodeId of the observed variables
* @return a Potential * @return a Potential
*/ */
Potential<GUM_SCALAR> evidenceImpact(NodeId target, Potential<GUM_SCALAR> evidenceImpact( NodeId target,
const std::vector<NodeId>& evs); const std::vector<NodeId>& evs );
/** /**
* Create a gum::Potential for P(target|evs) (for all instanciation of target * Create a gum::Potential for P(target|evs) (for all instanciation of target
...@@ -204,17 +204,17 @@ namespace gum { ...@@ -204,17 +204,17 @@ namespace gum {
* @param evs the nodeId of the observed variable * @param evs the nodeId of the observed variable
* @return a Potential * @return a Potential
*/ */
Potential<GUM_SCALAR> evidenceImpact(const std::string& target, Potential<GUM_SCALAR> evidenceImpact( const std::string& target,
const std::vector<std::string>& evs); const std::vector<std::string>& evs );
protected: protected:
/// fired after a new marginal target is inserted /// fired after a new marginal target is inserted
/** @param id The target variable's id. */ /** @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 /// fired before a marginal target is removed
/** @param id The target variable's id. */ /** @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 /// fired after all the nodes of the BN are added as marginal targets
virtual void _onAllMarginalTargetsAdded() = 0; virtual void _onAllMarginalTargetsAdded() = 0;
...@@ -223,16 +223,19 @@ namespace gum { ...@@ -223,16 +223,19 @@ namespace gum {
virtual void _onAllMarginalTargetsErased() = 0; virtual void _onAllMarginalTargetsErased() = 0;
/// fired after a new Bayes net has been assigned to the engine /// 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 /// asks derived classes for the posterior of a given variable
/** @param id The variable's id. */ /** @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 /// whether the actual targets are default
bool __defaultTargets; bool __targeted_mode;
/// the set of marginal targets /// the set of marginal targets
NodeSet __targets; NodeSet __targets;
......
...@@ -28,37 +28,37 @@ namespace gum { ...@@ -28,37 +28,37 @@ namespace gum {
// Default Constructor // Default Constructor
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
MarginalTargetedInference<GUM_SCALAR>::MarginalTargetedInference( MarginalTargetedInference<GUM_SCALAR>::MarginalTargetedInference(
const IBayesNet <GUM_SCALAR> *bn) const IBayesNet<GUM_SCALAR>* bn )
: BayesNetInference<GUM_SCALAR>(bn) { : BayesNetInference<GUM_SCALAR>( bn ) {
// assign a BN if this has not been done before (due to virtual inheritance) // assign a BN if this has not been done before (due to virtual inheritance)
if (this->__bn == nullptr) { if ( this->__bn == nullptr ) {
BayesNetInference<GUM_SCALAR>::__setBayesNetDuringConstruction(bn); BayesNetInference<GUM_SCALAR>::__setBayesNetDuringConstruction( bn );
} }
// sets all the nodes as targets // sets all the nodes as targets
if (bn != nullptr) { if ( bn != nullptr ) {
__defaultTargets=true; __targeted_mode = false;
__targets = bn->dag().asNodeSet(); __targets = bn->dag().asNodeSet();
} }
GUM_CONSTRUCTOR(MarginalTargetedInference); GUM_CONSTRUCTOR( MarginalTargetedInference );
} }
// Destructor // Destructor
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
MarginalTargetedInference<GUM_SCALAR>::~MarginalTargetedInference() { MarginalTargetedInference<GUM_SCALAR>::~MarginalTargetedInference() {
GUM_DESTRUCTOR(MarginalTargetedInference); GUM_DESTRUCTOR( MarginalTargetedInference );
} }
// fired when a new BN is assigned to the inference engine // fired when a new BN is assigned to the inference engine
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::_onBayesNetChanged( void MarginalTargetedInference<GUM_SCALAR>::_onBayesNetChanged(
const IBayesNet <GUM_SCALAR> *bn) { const IBayesNet<GUM_SCALAR>* bn ) {
__defaultTargets=true; __targeted_mode = true;
__setAllMarginalTargets(); __setAllMarginalTargets();
} }
...@@ -68,58 +68,60 @@ namespace gum { ...@@ -68,58 +68,60 @@ namespace gum {
// ############################################################################## // ##############################################################################
// return true if variable is a target // return true if variable is a target
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
INLINE bool 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 // check that the variable belongs to the bn
if (this->__bn == nullptr) GUM_ERROR(NullElement, if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the " "No Bayes net has been assigned to the "
"inference algorithm"); "inference algorithm" );
if (!this->__bn->dag().exists(var)) { if ( !this->__bn->dag().exists( var ) ) {
GUM_ERROR(UndefinedElement, var << " is not a NodeId in the bn"); 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 // Add a single target to the list of targets
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
INLINE bool MarginalTargetedInference<GUM_SCALAR>::isTarget( INLINE bool MarginalTargetedInference<GUM_SCALAR>::isTarget(
const std::string &nodeName) const { const std::string& nodeName ) const {
return isTarget(this->__bn->idFromName(nodeName)); return isTarget( this->__bn->idFromName( nodeName ) );
} }
// Clear all previously defined targets (single targets and sets of targets) // 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() { INLINE void MarginalTargetedInference<GUM_SCALAR>::eraseAllTargets() {
_onAllMarginalTargetsErased(); _onAllMarginalTargetsErased();
__targets.clear(); __targets.clear();
_setTargetedMode(); // does nothing if already in targeted mode
this->__state = this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure; BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
} }
// Add a single target to the list of targets // Add a single target to the list of targets
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::addTarget(NodeId target) { void MarginalTargetedInference<GUM_SCALAR>::addTarget( NodeId target ) {
// check if the node belongs to the Bayesian network // check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement, if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the " "No Bayes net has been assigned to the "
"inference algorithm"); "inference algorithm" );
if (!this->__bn->dag().exists(target)) { if ( !this->__bn->dag().exists( target ) ) {
GUM_ERROR(UndefinedElement, target << " is not a NodeId in the bn"); GUM_ERROR( UndefinedElement, target << " is not a NodeId in the bn" );
} }
if (__defaultTargets) { _setTargetedMode(); // does nothing if already in targeted mode
__defaultTargets=false;
eraseAllTargets();
}
// add the new target // add the new target
if (!__targets.contains(target)) { if ( !__targets.contains( target ) ) {
__targets.insert(target); __targets.insert( target );
_onMarginalTargetAdded(target); _onMarginalTargetAdded( target );
this->__state = this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure; BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
} }
...@@ -127,17 +129,20 @@ namespace gum { ...@@ -127,17 +129,20 @@ namespace gum {
// Add all nodes as targets // Add all nodes as targets
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::addAllTargets() { void MarginalTargetedInference<GUM_SCALAR>::addAllTargets() {
// check if the node belongs to the Bayesian network // check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement, if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the " "No Bayes net has been assigned to the "
"inference algorithm"); "inference algorithm" );
for (auto target : this->__bn->dag()) {
if (!__targets.contains(target)) { _setTargetedMode(); // does nothing if already in targeted mode
__targets.insert(target); for ( auto target : this->__bn->dag() ) {
_onMarginalTargetAdded(target); if ( !__targets.contains( target ) ) {
__targets.insert( target );
_onMarginalTargetAdded( target );
this->__state = this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure; BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
} }
...@@ -146,33 +151,38 @@ namespace gum { ...@@ -146,33 +151,38 @@ namespace gum {
// Add a single target to the list of targets // Add a single target to the list of targets
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
void 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 // check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement, if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the " "No Bayes net has been assigned to the "
"inference algorithm"); "inference algorithm" );
addTarget(this->__bn->idFromName(nodeName)); addTarget( this->__bn->idFromName( nodeName ) );
} }
// removes an existing target // removes an existing target
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::eraseTarget(const NodeId target) { void MarginalTargetedInference<GUM_SCALAR>::eraseTarget( const NodeId target ) {
// check if the node belongs to the Bayesian network // check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement, if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the " "No Bayes net has been assigned to the "
"inference algorithm"); "inference algorithm" );
if (!this->__bn->dag().exists(target)) { if ( !this->__bn->dag().exists( target ) ) {
GUM_ERROR(UndefinedElement, target << " is not a NodeId in the bn"); GUM_ERROR( UndefinedElement, target << " is not a NodeId in the bn" );
} }
if (__targets.contains(target)) {
_onMarginalTargetErased(target); if ( __targets.contains( target ) ) {
__targets.erase(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 = this->__state =
BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure; BayesNetInference<GUM_SCALAR>::StateOfInference::OutdatedBNStructure;
} }
...@@ -180,27 +190,28 @@ namespace gum { ...@@ -180,27 +190,28 @@ namespace gum {
// Add a single target to the list of targets // Add a single target to the list of targets
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
void MarginalTargetedInference<GUM_SCALAR>::eraseTarget( void MarginalTargetedInference<GUM_SCALAR>::eraseTarget(
const std::string &nodeName) { const std::string& nodeName ) {
// check if the node belongs to the Bayesian network // check if the node belongs to the Bayesian network
if (this->__bn == nullptr) GUM_ERROR(NullElement, if ( this->__bn == nullptr )
GUM_ERROR( NullElement,
"No Bayes net has been assigned to the " "No Bayes net has been assigned to the "
"inference algorithm"); "inference algorithm" );
eraseTarget(this->__bn->idFromName(nodeName)); eraseTarget( this->__bn->idFromName( nodeName ) );
} }
// returns the list of single targets // returns the list of single targets
template<typename GUM_SCALAR> template <typename GUM_SCALAR>
INLINE const NodeSet &MarginalTargetedInference<GUM_SCALAR>::targets() const INLINE const NodeSet& MarginalTargetedInference<GUM_SCALAR>::targets() const
noexcept {