34 template <
typename GUM_SCALAR >
38 for (
const auto& elt : __elim_orders)
41 if (__class_elim_order !=
nullptr)
delete __class_elim_order;
44 template <
typename GUM_SCALAR >
58 for (
const auto attr : attr_set) {
60 for (
auto iter = query->
getRefAttr(attr).begin();
63 if ((!ignore.
exists(iter->first)) && (__bb.exists(iter->first)))
64 __eliminateNodesDownward(
65 query, iter->first, pool, trash, elim_list, ignore);
74 std::vector< const DiscreteVariable* > elim_order;
76 if (this->hasEvidence(query)) __insertEvidence(query, pool);
78 for (
const auto attr : attr_set)
85 const auto& var = bn.
variable(var_id);
86 elim_order.push_back(&var);
93 __reduceElimList(query, elim_list, tmp_list, ignore, pool, trash);
95 while (!elim_list.
empty()) {
96 if (__checkElimOrder(query, elim_list.
front())) {
98 && (__bb.exists(elim_list.
front())))
99 __eliminateNodesDownward(
100 query, elim_list.
front(), pool, trash, elim_list, ignore);
101 }
else if (__bb.exists(elim_list.
front())) {
109 for (
const auto chain : sc_set)
111 if ((!ignore.
exists(parent)) && (__bb.exists(*parent)))
112 __eliminateNodesUpward(parent, pool, trash, tmp_list, ignore);
115 template <
typename GUM_SCALAR >
130 for (
const auto attr : attr_set) {
135 if ((!ignore.exists(iter->first)) && (__bb.exists(iter->first)))
136 __eliminateNodesDownward(
137 i, iter->first, pool, trash, my_list, ignore);
144 if (this->hasEvidence(i)) {
145 __eliminateNodesWithEvidence(i, pool, trash);
147 __insertLiftedNodes(i, pool, trash);
149 for (
const auto agg : i->
type().aggregates())
150 if (__bb.requisiteNodes(i).exists(agg->id()))
151 pool.
insert(__getAggPotential(i, agg));
155 std::vector< const DiscreteVariable* > elim_order;
157 for (
auto node : __getElimOrder(i->
type())) {
158 const auto& var = bn.
variable(node);
159 elim_order.push_back(&var);
169 while (!my_list.
empty()) {
170 if (__checkElimOrder(i, my_list.
front())) {
171 if ((!ignore.exists(my_list.
front())) && (__bb.exists(my_list.
front())))
172 __eliminateNodesDownward(
173 i, my_list.
front(), pool, trash, my_list, ignore);
174 }
else if (__bb.exists(my_list.
front())) {
175 elim_list.insert(my_list.
front());
182 for (
const auto chain : sc_set)
184 if ((!ignore.exists(parent)) && __bb.exists(parent) && (parent != from))
185 elim_list.insert(parent);
188 template <
typename GUM_SCALAR >
201 for (
const auto attr : attr_set) {
206 if ((!ignore.exists(iter->first)) && (__bb.exists(iter->first)))
207 __eliminateNodesDownward(
208 i, iter->first, pool, trash, elim_list, ignore);
215 if (this->hasEvidence(i)) {
216 __eliminateNodesWithEvidence(i, pool, trash);
218 __insertLiftedNodes(i, pool, trash);
220 for (
const auto agg : i->
type().aggregates())
221 if (__bb.requisiteNodes(i).exists(agg->id()))
222 pool.
insert(__getAggPotential(i, agg));
226 std::vector< const DiscreteVariable* > elim_order;
228 for (
auto node : __getElimOrder(i->
type())) {
229 const auto& var = bn.
variable(node);
230 elim_order.push_back(&var);
241 while (!elim_list.empty()) {
242 if (__checkElimOrder(i, elim_list.front())) {
243 if ((!ignore.exists(elim_list.front()))
244 && (__bb.exists(elim_list.front())))
245 __eliminateNodesDownward(
246 i, elim_list.front(), pool, trash, elim_list, ignore);
247 }
else if (__bb.exists(elim_list.front())) {
248 ignore.
insert(elim_list.front());
251 elim_list.popFront();
255 for (
const auto chain : sc_set)
257 if ((!ignore.exists(parent)) && (__bb.exists(parent)))
258 __eliminateNodesUpward(parent, pool, trash, tmp_list, ignore);
261 template <
typename GUM_SCALAR >
265 for (
const auto& elt : this->evidence(i))
266 if (__bb.requisiteNodes(i).exists(elt.first))
270 for (
const auto& a : *i)
271 if (__bb.requisiteNodes(i).exists(a.first))
278 for (
auto var = full_elim_order.begin(); var != full_elim_order.end(); ++var)
279 eliminateNode(&(i->get(*var).type().variable()), pool, trash);
282 template <
typename GUM_SCALAR >
288 lifted_pool = __lifted_pools[&(__bb.requisiteNodes(i))];
290 __initLiftedNodes(i, trash);
291 lifted_pool = __lifted_pools[&(__bb.requisiteNodes(i))];
294 for (
const auto lifted_pot : *lifted_pool) {
301 template <
typename GUM_SCALAR >
306 __lifted_pools.insert(&(__bb.requisiteNodes(i)), lifted_pool);
308 for (
const auto node : __bb.requisiteNodes(i))
313 NodeSet inners, outers, ignore;
315 for (
const auto& elt : *i) {
316 if (__bb.requisiteNodes(*i).exists(elt.first)) {
320 else if (!outers.
exists(elt.first))
329 for (
const auto par : c.
containerDag().parents(elt.first))
331 && i->
type().isInnerNode(i->type().get(par))
332 && __bb.requisiteNodes(i).exists(par)) {
352 GUM_ASSERT(inners.
size() || outers.
size());
356 for (
size_t idx = 0; idx < inners.
size(); ++idx)
363 __elim_orders.insert(
365 new std::vector< NodeId >(t.eliminationOrder().begin() + inners.
size(),
366 t.eliminationOrder().end()));
370 template <
typename GUM_SCALAR >
374 std::list< NodeId > l;
376 for (
const auto node : cdg.
dag().nodes()) {
377 if (cdg.
dag().parents(node).empty()) { l.push_back(node); }
383 visited_node.
insert(l.front());
385 if (!class_elim_order.
exists(cdg.
get(l.front()).first)) {
386 class_elim_order.
insert(cdg.
get(l.front()).first);
389 for (
const auto child : cdg.
dag().children(l.front())) {
390 if (!visited_node.
contains(child)) { l.push_back(child); }
397 for (
auto c : class_elim_order) {
398 std::string name = c->name();
399 auto pos = name.find_first_of(
"<");
400 if (pos != std::string::npos) { name = name.substr(0, pos); }
402 __class_elim_order->
insert(name);
407 template <
typename GUM_SCALAR >
413 __bb.compute(i, elt->
id());
414 __eliminateNodes(i, elt->
id(), pool, trash);
416 std::vector< const Potential< GUM_SCALAR >* > result;
417 for (
auto pot : pool) {
419 result.push_back(pot);
422 while (result.size() > 1) {
423 const auto& p1 = *(result.back());
425 const auto& p2 = *(result.back());
428 result.push_back(mult);
432 m = *(result.back());
438 for (
const auto pot : trash)
441 for (
const auto& elt : __lifted_pools)
444 __lifted_pools.clear();
446 for (
const auto& elt : __req_set) {
447 delete elt.second.first;
448 delete elt.second.second;
453 for (
const auto elt : __elim_orders)
456 __elim_orders.clear();
459 template <
typename GUM_SCALAR >
465 template <
typename GUM_SCALAR >
470 for (
const auto node : __bb.requisiteNodes(i)) {
471 switch (i->
type().get(node).elt_type()) {
485 "There should not be elements other" 486 " than PRMAttribute<GUM_SCALAR> and SlotChain.");
492 &(__bb.requisiteNodes(i)),
496 template <
typename GUM_SCALAR >
500 __class_elim_order(0), __bb(*this) {
501 GUM_CONSTRUCTOR(
SVED);
505 template <
typename GUM_SCALAR >
509 for (
const auto& elt : this->
evidence(i))
513 template <
typename GUM_SCALAR >
514 INLINE std::vector< NodeId >&
519 template <
typename GUM_SCALAR >
521 auto pos = s.find_first_of(
"<");
522 if (pos != std::string::npos) {
return s.substr(0, pos); }
526 template <
typename GUM_SCALAR >
532 auto first_name =
__trim(first->
type().name());
533 auto second_name =
__trim(second->
type().name());
538 template <
typename GUM_SCALAR >
545 template <
typename GUM_SCALAR >
551 template <
typename GUM_SCALAR >
557 template <
typename GUM_SCALAR >
568 template <
typename GUM_SCALAR >
579 template <
typename GUM_SCALAR >
587 while (!elim_list.empty()) {
589 if ((!ignore.exists(elim_list.front()))
590 && (
__bb.exists(elim_list.front()))) {
592 i, elim_list.front(), pool, trash, elim_list, ignore);
594 }
else if (
__bb.exists(elim_list.front())) {
595 reduced_list.insert(elim_list.front());
598 elim_list.popFront();
602 template <
typename GUM_SCALAR >
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
HashTable< const Set< NodeId > *, std::pair< Set< NodeId > *, Set< NodeId > *> > __req_set
First pair -> requisite Attributes Second pair -> requisite SlotChains.
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.
virtual std::string name() const
Returns the name of the current inference algorithm.
virtual Idx nbrDim() const final
Returns the number of vars in the multidimensional container.
Idx pos(const Key &key) const
Returns the position of the object passed in argument (if it exists).
void __insertEvidence(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool)
Returns true if second can be eliminated before first.
virtual void _marginal(const Chain &chain, Potential< GUM_SCALAR > &m)
See PRMInference::_marginal().
void __eliminateNodes(const PRMInstance< GUM_SCALAR > *query, NodeId id, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
const DAG & dag() const
Returns a constant reference over the graph of the DAG representing the ClassDependencyGraph<GUM_SCAL...
virtual const DiscreteVariable & variable(NodeId id) const
See gum::IBaseBayesNet::variable().
PRMAttribute< GUM_SCALAR > & get(NodeId id)
Getter on an PRMAttribute<GUM_SCALAR> of this PRMInstance<GUM_SCALAR>.
virtual void _evidenceRemoved(const Chain &chain)
See PRMInference::_evidenceRemoved().
SVED(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &model)
Default Constructor.
Set< NodeId > & __getSCSet(const PRMInstance< GUM_SCALAR > *i)
Returns true if second can be eliminated before first.
EMap & evidence(const PRMInstance< GUM_SCALAR > &i)
Returns EMap of evidences over i.
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
The generic class for storing (ordered) sequences of objects.
PRMClass< GUM_SCALAR > & type()
Returns the type of this instance.
void __initElimOrder()
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.
Potential< GUM_SCALAR > * __getAggPotential(const PRMInstance< GUM_SCALAR > *i, const PRMAggregate< GUM_SCALAR > *agg)
Returns true if second can be eliminated before first.
void __initReqSets(const PRMInstance< GUM_SCALAR > *i)
Returns true if second can be eliminated before first.
const EltPair & get(NodeId id) const
Returns a constant reference over the element assiociated with the node id in the ClassDependencyGrap...
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 popFront()
Removes the first element of a List, if any.
void __initLiftedNodes(const PRMInstance< GUM_SCALAR > *i, BucketSet &trash)
Returns true if second can be eliminated before first.
std::vector< std::pair< PRMInstance< GUM_SCALAR > *, std::string > > & getRefAttr(NodeId id)
Returns a vector of pairs of refering attributes of id.
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.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
PRMInference< GUM_SCALAR >::Chain Chain
Code alias.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
std::vector< NodeId > & __getElimOrder(const PRMClass< GUM_SCALAR > &c)
Returns true if second can be eliminated before first.
This class decorates a gum::prm::Class<GUM_SCALAR> has an IBaseBayesNet.
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.
This class is an implementation of the Structured Value Elimination algorithm on PRM<GUM_SCALAR>.
The default triangulation algorithm used by aGrUM.
Val & pushBack(const Val &val)
Inserts a new element (a copy) at the end of the chained list.
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).
Sequence< std::string > * __class_elim_order
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
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)
Returns true if second can be eliminated before first.
bool exists(const Key &k) const
Check the existence of k in the sequence.
StructuredBayesBall< GUM_SCALAR > __bb
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.
std::string __trim(const std::string &s)
Returns true if second can be eliminated before first.
This class represent the dependencies of all classes in a PRM<GUM_SCALAR>.
void eliminateNode(const DiscreteVariable *var, Set< Potential< GUM_SCALAR > * > &pool, Set< Potential< GUM_SCALAR > * > &trash)
Proceeds with the elimination of var in pool.
bool __checkElimOrder(const PRMInstance< GUM_SCALAR > *first, const PRMInstance< GUM_SCALAR > *second)
Returns true if second can be eliminated before first.
virtual PRMType & type()=0
Return a reference over the gum::PRMType of this class element.
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.
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.
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.
A PRMClass is an object of a PRM representing a fragment of a Bayesian Network which can be instantia...
virtual void _joint(const std::vector< Chain > &queries, Potential< GUM_SCALAR > &j)
See PRMInference::_joint().
void __eliminateNodesWithEvidence(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
This class decorates an PRMInstance<GUM_SCALAR> as an IBaseBayesNet.
HashTable< const PRMClass< GUM_SCALAR > *, std::vector< NodeId > *> __elim_orders
void __eliminateNodesUpward(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, List< const PRMInstance< GUM_SCALAR > * > &elim_list, Set< const PRMInstance< GUM_SCALAR > * > &ignore)
Returns true if second can be eliminated before first.
virtual void _evidenceAdded(const Chain &chain)
See PRMInference::_evidenceAdded().
PRMAttribute is a member of a Class in a PRM.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
virtual const Sequence< const DiscreteVariable *> & variablesSequence() const final
Returns a const ref to the sequence of DiscreteVariable*.
Set< NodeId > & __getAttrSet(const PRMInstance< GUM_SCALAR > *i)
Returns true if second can be eliminated before first.
Size size() const noexcept
Returns the number of elements in the set.
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
Size NodeId
Type for node ids.
void insert(const Key &k)
Inserts a new element into the set.
const NodeProperty< Size > & modalities() const
See gum::IBaseBayesNet::modalities().
#define GUM_ERROR(type, msg)
const Set< PRMInstance< GUM_SCALAR > *> & getInstances(NodeId id) const
Returns the Set of PRMInstance<GUM_SCALAR> referenced by id.
void __reduceElimList(const PRMInstance< GUM_SCALAR > *i, List< const PRMInstance< GUM_SCALAR > * > &elim_list, List< const PRMInstance< GUM_SCALAR > * > &reduced_list, Set< const PRMInstance< GUM_SCALAR > * > &ignore, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
void insert(const Key &k)
Insert an element at the end of the sequence.