31 template <
typename GUM_SCALAR >
35 for (
const auto& elt : __elim_orders)
38 if (__class_elim_order !=
nullptr)
delete __class_elim_order;
41 template <
typename GUM_SCALAR >
55 for (
const auto attr : attr_set) {
57 for (
auto iter = query->
getRefAttr(attr).begin();
60 if ((!ignore.
exists(iter->first)) && (__bb.exists(iter->first)))
61 __eliminateNodesDownward(
62 query, iter->first, pool, trash, elim_list, ignore);
71 std::vector< const DiscreteVariable* > elim_order;
73 if (this->hasEvidence(query)) __insertEvidence(query, pool);
75 for (
const auto attr : attr_set)
82 const auto& var = bn.
variable(var_id);
83 elim_order.push_back(&var);
90 __reduceElimList(query, elim_list, tmp_list, ignore, pool, trash);
92 while (!elim_list.
empty()) {
93 if (__checkElimOrder(query, elim_list.
front())) {
95 && (__bb.exists(elim_list.
front())))
96 __eliminateNodesDownward(
97 query, elim_list.
front(), pool, trash, elim_list, ignore);
98 }
else if (__bb.exists(elim_list.
front())) {
106 for (
const auto chain : sc_set)
108 if ((!ignore.
exists(parent)) && (__bb.exists(*parent)))
109 __eliminateNodesUpward(parent, pool, trash, tmp_list, ignore);
112 template <
typename GUM_SCALAR >
127 for (
const auto attr : attr_set) {
132 if ((!ignore.exists(iter->first)) && (__bb.exists(iter->first)))
133 __eliminateNodesDownward(
134 i, iter->first, pool, trash, my_list, ignore);
141 if (this->hasEvidence(i)) {
142 __eliminateNodesWithEvidence(i, pool, trash);
144 __insertLiftedNodes(i, pool, trash);
146 for (
const auto agg : i->
type().aggregates())
147 if (__bb.requisiteNodes(i).exists(agg->id()))
148 pool.
insert(__getAggPotential(i, agg));
152 std::vector< const DiscreteVariable* > elim_order;
154 for (
auto node : __getElimOrder(i->
type())) {
155 const auto& var = bn.
variable(node);
156 elim_order.push_back(&var);
166 while (!my_list.
empty()) {
167 if (__checkElimOrder(i, my_list.
front())) {
168 if ((!ignore.exists(my_list.
front())) && (__bb.exists(my_list.
front())))
169 __eliminateNodesDownward(
170 i, my_list.
front(), pool, trash, my_list, ignore);
171 }
else if (__bb.exists(my_list.
front())) {
172 elim_list.insert(my_list.
front());
179 for (
const auto chain : sc_set)
181 if ((!ignore.exists(parent)) && __bb.exists(parent) && (parent != from))
182 elim_list.insert(parent);
185 template <
typename GUM_SCALAR >
198 for (
const auto attr : attr_set) {
203 if ((!ignore.exists(iter->first)) && (__bb.exists(iter->first)))
204 __eliminateNodesDownward(
205 i, iter->first, pool, trash, elim_list, ignore);
212 if (this->hasEvidence(i)) {
213 __eliminateNodesWithEvidence(i, pool, trash);
215 __insertLiftedNodes(i, pool, trash);
217 for (
const auto agg : i->
type().aggregates())
218 if (__bb.requisiteNodes(i).exists(agg->id()))
219 pool.
insert(__getAggPotential(i, agg));
223 std::vector< const DiscreteVariable* > elim_order;
225 for (
auto node : __getElimOrder(i->
type())) {
226 const auto& var = bn.
variable(node);
227 elim_order.push_back(&var);
238 while (!elim_list.empty()) {
239 if (__checkElimOrder(i, elim_list.front())) {
240 if ((!ignore.exists(elim_list.front()))
241 && (__bb.exists(elim_list.front())))
242 __eliminateNodesDownward(
243 i, elim_list.front(), pool, trash, elim_list, ignore);
244 }
else if (__bb.exists(elim_list.front())) {
245 ignore.
insert(elim_list.front());
248 elim_list.popFront();
252 for (
const auto chain : sc_set)
254 if ((!ignore.exists(parent)) && (__bb.exists(parent)))
255 __eliminateNodesUpward(parent, pool, trash, tmp_list, ignore);
258 template <
typename GUM_SCALAR >
262 for (
const auto& elt : this->evidence(i))
263 if (__bb.requisiteNodes(i).exists(elt.first))
267 for (
const auto& a : *i)
268 if (__bb.requisiteNodes(i).exists(a.first))
275 for (
auto var = full_elim_order.begin(); var != full_elim_order.end(); ++var)
276 eliminateNode(&(i->get(*var).type().variable()), pool, trash);
279 template <
typename GUM_SCALAR >
285 lifted_pool = __lifted_pools[&(__bb.requisiteNodes(i))];
287 __initLiftedNodes(i, trash);
288 lifted_pool = __lifted_pools[&(__bb.requisiteNodes(i))];
291 for (
const auto lifted_pot : *lifted_pool) {
298 template <
typename GUM_SCALAR >
303 __lifted_pools.insert(&(__bb.requisiteNodes(i)), lifted_pool);
305 for (
const auto node : __bb.requisiteNodes(i))
310 NodeSet inners, outers, ignore;
312 for (
const auto& elt : *i) {
313 if (__bb.requisiteNodes(*i).exists(elt.first)) {
317 else if (!outers.
exists(elt.first))
326 for (
const auto par : c.
containerDag().parents(elt.first))
328 && i->
type().isInnerNode(i->type().get(par))
329 && __bb.requisiteNodes(i).exists(par)) {
349 GUM_ASSERT(inners.
size() || outers.
size());
353 for (
size_t idx = 0; idx < inners.
size(); ++idx)
360 __elim_orders.insert(
362 new std::vector< NodeId >(t.eliminationOrder().begin() + inners.
size(),
363 t.eliminationOrder().end()));
367 template <
typename GUM_SCALAR >
371 std::list< NodeId > l;
373 for (
const auto node : cdg.
dag().nodes()) {
374 if (cdg.
dag().parents(node).empty()) { l.push_back(node); }
380 visited_node.
insert(l.front());
382 if (!class_elim_order.
exists(cdg.
get(l.front()).first)) {
383 class_elim_order.
insert(cdg.
get(l.front()).first);
386 for (
const auto child : cdg.
dag().children(l.front())) {
387 if (!visited_node.
contains(child)) { l.push_back(child); }
394 for (
auto c : class_elim_order) {
395 std::string name = c->name();
396 auto pos = name.find_first_of(
"<");
397 if (pos != std::string::npos) { name = name.substr(0, pos); }
399 __class_elim_order->
insert(name);
404 template <
typename GUM_SCALAR >
410 __bb.compute(i, elt->
id());
411 __eliminateNodes(i, elt->
id(), pool, trash);
413 std::vector< const Potential< GUM_SCALAR >* > result;
414 for (
auto pot : pool) {
416 result.push_back(pot);
419 while (result.size() > 1) {
420 const auto& p1 = *(result.back());
422 const auto& p2 = *(result.back());
425 result.push_back(mult);
429 m = *(result.back());
435 for (
const auto pot : trash)
438 for (
const auto& elt : __lifted_pools)
441 __lifted_pools.clear();
443 for (
const auto& elt : __req_set) {
444 delete elt.second.first;
445 delete elt.second.second;
450 for (
const auto elt : __elim_orders)
453 __elim_orders.clear();
456 template <
typename GUM_SCALAR >
462 template <
typename GUM_SCALAR >
467 for (
const auto node : __bb.requisiteNodes(i)) {
468 switch (i->
type().get(node).elt_type()) {
482 "There should not be elements other" 483 " than PRMAttribute<GUM_SCALAR> and SlotChain.");
489 &(__bb.requisiteNodes(i)),
493 template <
typename GUM_SCALAR >
497 __class_elim_order(0), __bb(*this) {
498 GUM_CONSTRUCTOR(
SVED);
502 template <
typename GUM_SCALAR >
506 for (
const auto& elt : this->
evidence(i))
510 template <
typename GUM_SCALAR >
511 INLINE std::vector< NodeId >&
516 template <
typename GUM_SCALAR >
518 auto pos = s.find_first_of(
"<");
519 if (pos != std::string::npos) {
return s.substr(0, pos); }
523 template <
typename GUM_SCALAR >
529 auto first_name =
__trim(first->
type().name());
530 auto second_name =
__trim(second->
type().name());
535 template <
typename GUM_SCALAR >
542 template <
typename GUM_SCALAR >
548 template <
typename GUM_SCALAR >
554 template <
typename GUM_SCALAR >
565 template <
typename GUM_SCALAR >
576 template <
typename GUM_SCALAR >
584 while (!elim_list.empty()) {
586 if ((!ignore.exists(elim_list.front()))
587 && (
__bb.exists(elim_list.front()))) {
589 i, elim_list.front(), pool, trash, elim_list, ignore);
591 }
else if (
__bb.exists(elim_list.front())) {
592 reduced_list.insert(elim_list.front());
595 elim_list.popFront();
599 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.
gum is the global namespace for all aGrUM entities
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.
Headers of SVED (Structured Value Elimination with d-seperation).
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.