35 template <
typename GUM_SCALAR >
42 <<
": input=" << i.
type().isInputNode(class_a);
43 s <<
" output=" << i.
type().isOutputNode(class_a)
44 <<
" inner=" << i.
type().isInnerNode(class_a);
48 template <
typename GUM_SCALAR >
51 s << i.
name() << std::endl;
52 s <<
"Attributes: " << std::endl;
56 if (i.type().slotChains().size()) {
57 s << std::endl <<
"SlotChains: " << std::endl;
58 for (
auto sc : i.type().slotChains()) {
59 s << sc->name() <<
" ";
65 template <
typename GUM_SCALAR >
67 std::stringstream str;
74 template <
typename LIST >
79 s << i->name() <<
" ";
85 template <
typename GUM_SCALAR >
96 template <
typename SET >
107 template <
typename GUM_SCALAR >
111 for (
const auto& elt : __elim_orders)
114 for (
const auto& elt : __lifted_pools)
117 if (__class_elim_order !=
nullptr)
delete __class_elim_order;
119 for (
const auto trash : __lifted_trash)
122 for (
auto set : __delayedVariables)
126 template <
typename GUM_SCALAR >
139 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end();
141 if (!ignore.
exists(child->first)) {
142 __eliminateNodesDownward(
143 query, child->first, pool, trash, elim_list, ignore, eliminated);
144 }
else if (!eliminated.
exists(child->first)) {
145 __addDelayedVariable(child->first, query, iter.key());
146 delayedVars.
insert(iter.key());
154 std::vector< const DiscreteVariable* > elim_order;
156 if (this->hasEvidence(query)) { __insertEvidence(query, pool); }
158 for (
auto attr = query->
begin(); attr != query->
end(); ++attr) {
167 const auto& var = bn.
variable(var_id);
168 elim_order.push_back(&var);
175 if (__delayedVariables.exists(query)) {
176 __eliminateDelayedVariables(query, pool, trash);
183 while (!elim_list.
empty()) {
184 if (__checkElimOrder(query, elim_list.
front())) {
186 __eliminateNodesDownward(query,
202 for (
const auto chain : query->
type().slotChains())
203 for (
const auto parent : query->
getInstances(chain->id()))
204 if (!ignore.
exists(parent))
205 __eliminateNodesUpward(
206 parent, pool, trash, tmp_list, ignore, eliminated);
209 template <
typename GUM_SCALAR >
214 for (
const auto var : *__delayedVariables[i]) {
217 for (
const auto pot : pool)
218 if (pot->contains(*var)) {
223 for (
const auto pot : toRemove)
227 if (other != var) bucket->
add(*other);
231 pool.insert(bucket_pot);
235 template <
typename GUM_SCALAR >
250 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end();
252 if (!ignore.exists(child->first)) {
253 __eliminateNodesDownward(
254 i, child->first, pool, trash, my_list, ignore, eliminated);
255 }
else if (!eliminated.exists(child->first)) {
256 __addDelayedVariable(child->first, i, iter.key());
257 delayedVars.
insert(iter.key());
263 __variableElimination(
264 i, pool, trash, (delayedVars.
empty() ? 0 : &delayedVars));
265 eliminated.insert(i);
268 for (
const auto node : my_list) {
269 if (__checkElimOrder(i, node) && (node != from)) {
270 if (!ignore.exists(node)) {
271 __eliminateNodesDownward(
272 i, node, pool, trash, elim_list, ignore, eliminated);
274 }
else if (node != from) {
275 elim_list.insert(node);
280 for (
const auto chain : i->
type().slotChains()) {
282 if (inst != from) { elim_list.insert(inst); }
287 template <
typename GUM_SCALAR >
293 if (this->hasEvidence(i)) {
294 __eliminateNodesWithEvidence(i, pool, trash, delayedVars);
296 __insertLiftedNodes(i, pool, trash);
298 for (
const auto agg : i->
type().aggregates())
299 pool.
insert(__getAggPotential(i, agg));
304 std::vector< const DiscreteVariable* > elim;
306 for (
const auto node : __getElimOrder(i->
type())) {
307 const auto& var = bn.
variable(node);
308 if (delayedVars !=
nullptr) {
309 if (!delayedVars->
exists(node)) {
310 const auto& var = bn.
variable(node);
311 elim.push_back(&var);
314 elim.push_back(&var);
325 if (__delayedVariables.exists(i)) {
326 __eliminateDelayedVariables(i, pool, trash);
330 template <
typename GUM_SCALAR >
342 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end();
344 if (!ignore.exists(child->first)) {
345 __eliminateNodesDownward(
346 i, child->first, pool, trash, elim_list, ignore, eliminated);
352 __variableElimination(i, pool, trash);
353 eliminated.insert(i);
357 while (!elim_list.empty()) {
358 if (__checkElimOrder(i, elim_list.front())) {
359 if (!ignore.exists(elim_list.front())) {
360 __eliminateNodesDownward(
361 i, elim_list.front(), pool, trash, elim_list, ignore, eliminated);
364 tmp_list.
insert(elim_list.front());
367 elim_list.popFront();
371 for (
const auto chain : i->
type().slotChains()) {
372 for (
const auto parent : i->
getInstances(chain->id())) {
373 if (!ignore.exists(parent)) {
374 __eliminateNodesUpward(
375 parent, pool, trash, tmp_list, ignore, eliminated);
381 template <
typename GUM_SCALAR >
390 for (
const auto& elt : this->evidence(i)) {
391 inner = i->
type().isInputNode(i->
get(elt.first))
392 || i->
type().isInnerNode(i->
get(elt.first));
394 if (inner) {
break; }
400 __insertEvidence(i, tmp_pool);
404 for (
const auto& elt : *i) {
413 std::vector< const DiscreteVariable* > inner_elim_order;
414 std::vector< const DiscreteVariable* > output_elim_order;
416 for (
size_t idx = 0; idx < full_elim_order.size(); ++idx) {
417 auto var_id = full_elim_order[idx];
418 const auto& var = bn.
variable(var_id);
420 if (!i->type().isOutputNode(i->get(full_elim_order[idx]))) {
421 inner_elim_order.push_back(&var);
422 }
else if (delayedVars !=
nullptr) {
423 if (!delayedVars->
exists(full_elim_order[idx])) {
424 output_elim_order.push_back(&var);
427 output_elim_order.push_back(&var);
434 for (
const auto pot : tmp_pool)
437 if (!output_elim_order.empty())
442 __insertEvidence(i, pool);
443 __insertLiftedNodes(i, pool, trash);
445 for (
const auto agg : i->
type().aggregates())
446 pool.
insert(__getAggPotential(i, agg));
449 std::vector< const DiscreteVariable* > elim;
451 for (
auto iter = __getElimOrder(i->
type()).begin();
452 iter != __getElimOrder(i->
type()).end();
454 const auto& var = bn.
variable(*iter);
455 if (delayedVars !=
nullptr) {
456 if (!delayedVars->
exists(*iter)) { elim.push_back(&var); }
458 elim.push_back(&var);
469 template <
typename GUM_SCALAR >
476 lifted_pool = __lifted_pools[&(i->
type())];
478 __initLiftedNodes(i->
type());
479 lifted_pool = __lifted_pools[&(i->
type())];
482 for (
const auto lifted_pot : *lifted_pool) {
489 template <
typename GUM_SCALAR >
492 __lifted_pools.insert(&c, lifted_pool);
499 else if (!outers.
exists(node))
529 for (
size_t idx = 0; idx < inners.
size(); ++idx)
536 __elim_orders.insert(
543 template <
typename GUM_SCALAR >
547 std::list< NodeId > l;
549 for (
const auto node : cdg.
dag().nodes()) {
550 if (cdg.
dag().parents(node).empty()) { l.push_back(node); }
556 visited_node.
insert(l.front());
558 if (!class_elim_order.
exists(cdg.
get(l.front()).first)) {
559 class_elim_order.
insert(cdg.
get(l.front()).first);
562 for (
const auto child : cdg.
dag().children(l.front())) {
563 if (!visited_node.
contains(child)) { l.push_back(child); }
570 for (
auto c : class_elim_order) {
571 std::string name = c->name();
572 auto pos = name.find_first_of(
"<");
573 if (pos != std::string::npos) { name = name.substr(0, pos); }
575 __class_elim_order->
insert(name);
580 template <
typename GUM_SCALAR >
587 __eliminateNodes(i, elt->
id(), pool, trash);
589 std::vector< Potential< GUM_SCALAR >* > result;
591 for (
const auto pot : pool) {
592 if (pot->contains(elt->
type().
variable())) { result.push_back(pot); }
595 while (result.size() > 1) {
596 auto& p1 = *(result.back());
598 auto& p2 = *(result.back());
602 result.push_back(mult);
605 m = *(result.back());
608 for (
const auto pot : trash) {
613 template <
typename GUM_SCALAR >
619 template <
typename GUM_SCALAR >
623 __class_elim_order(0) {
624 GUM_CONSTRUCTOR(
SVE);
627 template <
typename GUM_SCALAR >
631 for (
const auto& elt : this->
evidence(i))
635 template <
typename GUM_SCALAR >
636 INLINE std::vector< NodeId >&
641 template <
typename GUM_SCALAR >
643 auto pos = s.find_first_of(
"<");
644 if (pos != std::string::npos) {
return s.substr(0, pos); }
648 template <
typename GUM_SCALAR >
654 auto first_name =
__trim(first->
type().name());
655 auto second_name =
__trim(second->
type().name());
660 template <
typename GUM_SCALAR >
666 template <
typename GUM_SCALAR >
671 template <
typename GUM_SCALAR >
676 template <
typename GUM_SCALAR >
690 static std::string dot =
".";
700 template <
typename GUM_SCALAR >
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
aGrUM's Potential is a multi-dimensional array with tensor operators.
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
Val & push_back(Args &&... args)
An alias for pushBack used for STL compliance.
void __addDelayedVariable(const PRMInstance< GUM_SCALAR > *i, const PRMInstance< GUM_SCALAR > *j, NodeId id)
When there is a loop in the references some variable elimination must be delayed, this methods add su...
bool empty() const noexcept
Indicates whether the set is the empty set.
const DAG & dag() const
Returns a constant reference over the graph of the DAG representing the ClassDependencyGraph<GUM_SCAL...
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
virtual const DiscreteVariable & variable(NodeId id) const
See gum::IBaseBayesNet::variable().
std::string __print_pot__(const Potential< GUM_SCALAR > &pot)
HashTable< std::string, Size > __delayedVariablesCounters
Some variable must be delayed for more than one PRMInstance<GUM_SCALAR>, when the delayed variable co...
PRMAttribute< GUM_SCALAR > & get(NodeId id)
Getter on an PRMAttribute<GUM_SCALAR> of this PRMInstance<GUM_SCALAR>.
void __insertEvidence(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool)
Returns true if second can be eliminated before first.
const std::string & name() const
Returns the name of this object.
std::vector< NodeId > & __getElimOrder(const PRMClass< GUM_SCALAR > &c)
Returns true if second can be eliminated before first.
void __initLiftedNodes(const PRMClass< GUM_SCALAR > &c)
Returns true if second can be eliminated before first.
EMap & evidence(const PRMInstance< GUM_SCALAR > &i)
Returns EMap of evidences over i.
virtual PRMType & type()=0
See gum::PRMClassElement::type().
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
const Potential< GUM_SCALAR > & normalize() const
normalisation of this do nothing if sum is 0
virtual bool isInnerNode(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if the node is an inner node.
std::string __print_list__(LIST l)
void __eliminateNodesUpward(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, List< const PRMInstance< GUM_SCALAR > * > &elim_list, Set< const PRMInstance< GUM_SCALAR > * > &ignore, Set< const PRMInstance< GUM_SCALAR > * > &eliminated)
Returns true if second can be eliminated before first.
virtual void _marginal(const Chain &chain, Potential< GUM_SCALAR > &m)
See PRMInference<GUM_SCALAR>::_marginal().
The generic class for storing (ordered) sequences of objects.
PRMClass< GUM_SCALAR > & type()
Returns the type of this instance.
bool __checkElimOrder(const PRMInstance< GUM_SCALAR > *first, const PRMInstance< GUM_SCALAR > *second)
Returns true if second can be eliminated before first.
const NodeProperty< Size > & modalities() const
See gum::IBaseBayesNet::cpt().
Abstract class representing an element of PRM class.
const EltPair & get(NodeId id) const
Returns a constant reference over the element assiociated with the node id in the ClassDependencyGrap...
A multidim implementation for buckets.
Sequence< std::string > * __class_elim_order
void erase(const Key &k)
Erases an element from the set.
Generic doubly linked lists.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
void __eliminateNodes(const PRMInstance< GUM_SCALAR > *query, NodeId id, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
void popFront()
Removes the first element of a List, if any.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Potential< GUM_SCALAR > * __getAggPotential(const PRMInstance< GUM_SCALAR > *i, const PRMAggregate< GUM_SCALAR > *agg)
Returns true if second can be eliminated before first.
HashTable< const PRMClass< GUM_SCALAR > *, std::vector< NodeId > *> __elim_orders
InvRefIterator beginInvRef()
Alias to iterate over the gum::prm::PRMAttribute<GUM_SCALAR> in this PRMInstance<GUM_SCALAR>.
Representation of a setA Set is a structure that contains arbitrary elements.
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
std::string __print_instance__(const PRMInstance< GUM_SCALAR > &i)
This class decorates a gum::prm::Class<GUM_SCALAR> has an IBaseBayesNet.
virtual void _evidenceRemoved(const Chain &chain)
See PRMInference<GUM_SCALAR>::_evidenceRemoved().
class for graph triangulations for which we enforce a given partial ordering on the nodes elimination...
void __insertLiftedNodes(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
SVE(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default Constructor.
The default triangulation algorithm used by aGrUM.
const Bijection< const DiscreteVariable *, const DiscreteVariable *> & bijection() const
Returns a mapping between DiscreteVariable used in this and the ones used in this PRMInstance<GUM_SCA...
const std::vector< NodeId > & eliminationOrder()
returns an elimination ordering compatible with the triangulated graph
PRMClassElement< GUM_SCALAR > & get(NodeId id)
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
void __variableElimination(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, Set< NodeId > *delayedVars=0)
Returns true if second can be eliminated before first.
void __eliminateNodesDownward(const PRMInstance< GUM_SCALAR > *from, const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, List< const PRMInstance< GUM_SCALAR > * > &elim_list, Set< const PRMInstance< GUM_SCALAR > * > &ignore, Set< const PRMInstance< GUM_SCALAR > * > &eliminated)
Returns true if second can be eliminated before first.
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
bool exists(const Key &k) const
Check the existence of k in the sequence.
void __initElimOrder()
Returns true if second can be eliminated before first.
Potential< GUM_SCALAR > * copyPotential(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bij, const Potential< GUM_SCALAR > &source)
Returns a copy of a Potential after applying a bijection over the variables in source.
virtual void _evidenceAdded(const Chain &chain)
See PRMInference<GUM_SCALAR>::_evidenceAdded().
This class represent the dependencies of all classes in a PRM<GUM_SCALAR>.
std::string __print_attribute__(const PRMInstance< GUM_SCALAR > &i, const PRMAttribute< GUM_SCALAR > &a)
void eliminateNode(const DiscreteVariable *var, Set< Potential< GUM_SCALAR > * > &pool, Set< Potential< GUM_SCALAR > * > &trash)
Proceeds with the elimination of var in pool.
virtual bool isOutputNode(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if elt is an output node.
void eliminateNodes(const std::vector< const DiscreteVariable * > &elim_order, Set< Potential< GUM_SCALAR > * > &pool, Set< Potential< GUM_SCALAR > * > &trash)
std::pair< const PRMInstance< GUM_SCALAR > *, const PRMAttribute< GUM_SCALAR > *> Chain
Code alias.
virtual std::string name() const
Returns the name of the current inference algorithm.
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
Val & front() const
Returns a reference to first element of a list, if any.
void __eliminateNodesWithEvidence(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, Set< NodeId > *delayedVars=0)
Returns true if second can be eliminated before first.
This abstract class is used as base class for all inference class on PRM<GUM_SCALAR>.
const UndiGraph & moralGraph(bool clear=true) const
The node's id are coherent with the variables and nodes of the topology.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
NodeId id() const
Returns the NodeId of this element in it's class DAG.
const iterator & end()
Returns a reference over the iterator at the end of the list of gum::prm::PRMAttribute<GUM_SCALAR> in...
void __eliminateDelayedVariables(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
This class decorates an PRMInstance<GUM_SCALAR> as an IBaseBayesNet.
std::string __trim(const std::string &s)
Returns true if second can be eliminated before first.
PRMAttribute is a member of a Class in a PRM.
virtual const Sequence< const DiscreteVariable *> & variablesSequence() const final
Returns a const ref to the sequence of DiscreteVariable*.
iterator begin()
Returns an iterator at the begining of the list of gum::prm::PRMAttribute<GUM_SCALAR> in this PRMInst...
std::string __print_system__(const PRMSystem< GUM_SCALAR > &s)
const Set< const DiscreteVariable *> & allVariables() const
Returns the sequence of all the variables contained in the bucket.
Size size() const noexcept
Returns the number of elements in the set.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
std::string __print_set__(SET set)
const InvRefIterator & endInvRef()
Alias to iterate over the gum::prm::PRMAttribute<GUM_SCALAR> in this PRMInstance<GUM_SCALAR>.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
void add(const MultiDimContainer< GUM_SCALAR > &impl)
Add a MultiDimContainer in the bucket.
Size NodeId
Type for node ids.
HashTable< const PRMInstance< GUM_SCALAR > *, Set< const DiscreteVariable *> *> __delayedVariables
void insert(const Key &k)
Inserts a new element into the set.
const NodeProperty< Size > & modalities() const
See gum::IBaseBayesNet::modalities().
virtual void _joint(const std::vector< Chain > &queries, Potential< GUM_SCALAR > &j)
See PRMInference<GUM_SCALAR>::_joint().
#define GUM_ERROR(type, msg)
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
This class is an implementation of the Structured Variable Elimination algorithm on PRM<GUM_SCALAR>...
const Set< PRMInstance< GUM_SCALAR > *> & getInstances(NodeId id) const
Returns the Set of PRMInstance<GUM_SCALAR> referenced by id.
void insert(const Key &k)
Insert an element at the end of the sequence.