32 template <
typename GUM_SCALAR >
39 <<
": input=" << i.
type().isInputNode(class_a);
40 s <<
" output=" << i.
type().isOutputNode(class_a)
41 <<
" inner=" << i.
type().isInnerNode(class_a);
45 template <
typename GUM_SCALAR >
48 s << i.
name() << std::endl;
49 s <<
"Attributes: " << std::endl;
53 if (i.type().slotChains().size()) {
54 s << std::endl <<
"SlotChains: " << std::endl;
55 for (
auto sc : i.type().slotChains()) {
56 s << sc->name() <<
" ";
62 template <
typename GUM_SCALAR >
64 std::stringstream str;
71 template <
typename LIST >
76 s << i->name() <<
" ";
82 template <
typename GUM_SCALAR >
93 template <
typename SET >
104 template <
typename GUM_SCALAR >
108 for (
const auto& elt : __elim_orders)
111 for (
const auto& elt : __lifted_pools)
114 if (__class_elim_order !=
nullptr)
delete __class_elim_order;
116 for (
const auto trash : __lifted_trash)
119 for (
auto set : __delayedVariables)
123 template <
typename GUM_SCALAR >
136 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end();
138 if (!ignore.
exists(child->first)) {
139 __eliminateNodesDownward(
140 query, child->first, pool, trash, elim_list, ignore, eliminated);
141 }
else if (!eliminated.
exists(child->first)) {
142 __addDelayedVariable(child->first, query, iter.key());
143 delayedVars.
insert(iter.key());
151 std::vector< const DiscreteVariable* > elim_order;
153 if (this->hasEvidence(query)) { __insertEvidence(query, pool); }
155 for (
auto attr = query->
begin(); attr != query->
end(); ++attr) {
164 const auto& var = bn.
variable(var_id);
165 elim_order.push_back(&var);
172 if (__delayedVariables.exists(query)) {
173 __eliminateDelayedVariables(query, pool, trash);
180 while (!elim_list.
empty()) {
181 if (__checkElimOrder(query, elim_list.
front())) {
183 __eliminateNodesDownward(query,
199 for (
const auto chain : query->
type().slotChains())
200 for (
const auto parent : query->
getInstances(chain->id()))
201 if (!ignore.
exists(parent))
202 __eliminateNodesUpward(
203 parent, pool, trash, tmp_list, ignore, eliminated);
206 template <
typename GUM_SCALAR >
211 for (
const auto var : *__delayedVariables[i]) {
214 for (
const auto pot : pool)
215 if (pot->contains(*var)) {
220 for (
const auto pot : toRemove)
224 if (other != var) bucket->
add(*other);
228 pool.insert(bucket_pot);
232 template <
typename GUM_SCALAR >
247 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end();
249 if (!ignore.exists(child->first)) {
250 __eliminateNodesDownward(
251 i, child->first, pool, trash, my_list, ignore, eliminated);
252 }
else if (!eliminated.exists(child->first)) {
253 __addDelayedVariable(child->first, i, iter.key());
254 delayedVars.
insert(iter.key());
260 __variableElimination(
261 i, pool, trash, (delayedVars.
empty() ? 0 : &delayedVars));
262 eliminated.insert(i);
265 for (
const auto node : my_list) {
266 if (__checkElimOrder(i, node) && (node != from)) {
267 if (!ignore.exists(node)) {
268 __eliminateNodesDownward(
269 i, node, pool, trash, elim_list, ignore, eliminated);
271 }
else if (node != from) {
272 elim_list.insert(node);
277 for (
const auto chain : i->
type().slotChains()) {
279 if (inst != from) { elim_list.insert(inst); }
284 template <
typename GUM_SCALAR >
290 if (this->hasEvidence(i)) {
291 __eliminateNodesWithEvidence(i, pool, trash, delayedVars);
293 __insertLiftedNodes(i, pool, trash);
295 for (
const auto agg : i->
type().aggregates())
296 pool.
insert(__getAggPotential(i, agg));
301 std::vector< const DiscreteVariable* > elim;
303 for (
const auto node : __getElimOrder(i->
type())) {
304 const auto& var = bn.
variable(node);
305 if (delayedVars !=
nullptr) {
306 if (!delayedVars->
exists(node)) {
307 const auto& var = bn.
variable(node);
308 elim.push_back(&var);
311 elim.push_back(&var);
322 if (__delayedVariables.exists(i)) {
323 __eliminateDelayedVariables(i, pool, trash);
327 template <
typename GUM_SCALAR >
339 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end();
341 if (!ignore.exists(child->first)) {
342 __eliminateNodesDownward(
343 i, child->first, pool, trash, elim_list, ignore, eliminated);
349 __variableElimination(i, pool, trash);
350 eliminated.insert(i);
354 while (!elim_list.empty()) {
355 if (__checkElimOrder(i, elim_list.front())) {
356 if (!ignore.exists(elim_list.front())) {
357 __eliminateNodesDownward(
358 i, elim_list.front(), pool, trash, elim_list, ignore, eliminated);
361 tmp_list.
insert(elim_list.front());
364 elim_list.popFront();
368 for (
const auto chain : i->
type().slotChains()) {
369 for (
const auto parent : i->
getInstances(chain->id())) {
370 if (!ignore.exists(parent)) {
371 __eliminateNodesUpward(
372 parent, pool, trash, tmp_list, ignore, eliminated);
378 template <
typename GUM_SCALAR >
387 for (
const auto& elt : this->evidence(i)) {
388 inner = i->
type().isInputNode(i->
get(elt.first))
389 || i->
type().isInnerNode(i->
get(elt.first));
391 if (inner) {
break; }
397 __insertEvidence(i, tmp_pool);
401 for (
const auto& elt : *i) {
410 std::vector< const DiscreteVariable* > inner_elim_order;
411 std::vector< const DiscreteVariable* > output_elim_order;
413 for (
size_t idx = 0; idx < full_elim_order.size(); ++idx) {
414 auto var_id = full_elim_order[idx];
415 const auto& var = bn.
variable(var_id);
417 if (!i->type().isOutputNode(i->get(full_elim_order[idx]))) {
418 inner_elim_order.push_back(&var);
419 }
else if (delayedVars !=
nullptr) {
420 if (!delayedVars->
exists(full_elim_order[idx])) {
421 output_elim_order.push_back(&var);
424 output_elim_order.push_back(&var);
431 for (
const auto pot : tmp_pool)
434 if (!output_elim_order.empty())
439 __insertEvidence(i, pool);
440 __insertLiftedNodes(i, pool, trash);
442 for (
const auto agg : i->
type().aggregates())
443 pool.
insert(__getAggPotential(i, agg));
446 std::vector< const DiscreteVariable* > elim;
448 for (
auto iter = __getElimOrder(i->
type()).begin();
449 iter != __getElimOrder(i->
type()).end();
451 const auto& var = bn.
variable(*iter);
452 if (delayedVars !=
nullptr) {
453 if (!delayedVars->
exists(*iter)) { elim.push_back(&var); }
455 elim.push_back(&var);
466 template <
typename GUM_SCALAR >
473 lifted_pool = __lifted_pools[&(i->
type())];
475 __initLiftedNodes(i->
type());
476 lifted_pool = __lifted_pools[&(i->
type())];
479 for (
const auto lifted_pot : *lifted_pool) {
486 template <
typename GUM_SCALAR >
489 __lifted_pools.insert(&c, lifted_pool);
496 else if (!outers.
exists(node))
526 for (
size_t idx = 0; idx < inners.
size(); ++idx)
533 __elim_orders.insert(
540 template <
typename GUM_SCALAR >
544 std::list< NodeId > l;
546 for (
const auto node : cdg.
dag().nodes()) {
547 if (cdg.
dag().parents(node).empty()) { l.push_back(node); }
553 visited_node.
insert(l.front());
555 if (!class_elim_order.
exists(cdg.
get(l.front()).first)) {
556 class_elim_order.
insert(cdg.
get(l.front()).first);
559 for (
const auto child : cdg.
dag().children(l.front())) {
560 if (!visited_node.
contains(child)) { l.push_back(child); }
567 for (
auto c : class_elim_order) {
568 std::string name = c->name();
569 auto pos = name.find_first_of(
"<");
570 if (pos != std::string::npos) { name = name.substr(0, pos); }
572 __class_elim_order->
insert(name);
577 template <
typename GUM_SCALAR >
584 __eliminateNodes(i, elt->
id(), pool, trash);
586 std::vector< Potential< GUM_SCALAR >* > result;
588 for (
const auto pot : pool) {
589 if (pot->contains(elt->
type().
variable())) { result.push_back(pot); }
592 while (result.size() > 1) {
593 auto& p1 = *(result.back());
595 auto& p2 = *(result.back());
599 result.push_back(mult);
602 m = *(result.back());
605 for (
const auto pot : trash) {
610 template <
typename GUM_SCALAR >
616 template <
typename GUM_SCALAR >
620 __class_elim_order(0) {
621 GUM_CONSTRUCTOR(
SVE);
624 template <
typename GUM_SCALAR >
628 for (
const auto& elt : this->
evidence(i))
632 template <
typename GUM_SCALAR >
633 INLINE std::vector< NodeId >&
638 template <
typename GUM_SCALAR >
640 auto pos = s.find_first_of(
"<");
641 if (pos != std::string::npos) {
return s.substr(0, pos); }
645 template <
typename GUM_SCALAR >
651 auto first_name =
__trim(first->
type().name());
652 auto second_name =
__trim(second->
type().name());
657 template <
typename GUM_SCALAR >
663 template <
typename GUM_SCALAR >
668 template <
typename GUM_SCALAR >
673 template <
typename GUM_SCALAR >
687 static std::string dot =
".";
697 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.
gum is the global namespace for all aGrUM entities
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.
Headers of ClassDependencyGraph<GUM_SCALAR>.
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)
Headers of SVE (Structured Variable Elimination).
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.