56 template < GUM_Numeric GUM_SCALAR >
61 s << &(a.
type().variable()) <<
" - ";
62 s << i.
name() <<
"." << a.
safeName() <<
": input=" << i.
type().isInputNode(class_a);
63 s <<
" output=" << i.
type().isOutputNode(class_a)
64 <<
" inner=" << i.
type().isInnerNode(class_a);
68 template < GUM_Numeric GUM_SCALAR >
71 s << i.
name() << std::endl;
72 s <<
"Attributes: " << std::endl;
76 if (i.
type().slotChains().size()) {
77 s << std::endl <<
"SlotChains: " << std::endl;
78 for (
auto sc: i.
type().slotChains()) {
79 s << sc->name() <<
" ";
85 template < GUM_Numeric GUM_SCALAR >
87 std::stringstream str;
94 template <
typename LIST >
99 s << i->name() <<
" ";
105 template < GUM_Numeric GUM_SCALAR >
109 for (
auto var: pot.variablesSequence()) {
116 template <
typename SET >
127 template < GUM_Numeric GUM_SCALAR >
146 template < GUM_Numeric GUM_SCALAR >
158 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end(); ++child) {
159 if (!ignore.
exists(child->first)) {
167 }
else if (!eliminated.
exists(child->first)) {
169 delayedVars.
insert(iter.key());
178 std::vector< const DiscreteVariable* > elim_order;
182 for (
auto attr = query->
begin(); attr != query->
end(); ++attr) {
183 pool.
insert(&(
const_cast< Tensor< GUM_SCALAR >&
>((*(attr.val())).cpf())));
190 const auto& var = bn.
variable(var_id);
191 elim_order.push_back(&var);
204 while (!elim_list.
empty()) {
223 for (
const auto chain: query->
type().slotChains())
224 for (
const auto parent: query->
getInstances(chain->id()))
225 if (!ignore.
exists(parent))
229 template < GUM_Numeric GUM_SCALAR >
238 for (
const auto pot: pool)
239 if (pot->contains(*var)) {
244 for (
const auto pot: toRemove)
248 if (other != var) bucket->
add(*other);
250 Tensor< GUM_SCALAR >* bucket_pot =
new Tensor< GUM_SCALAR >(bucket);
252 pool.insert(bucket_pot);
256 template < GUM_Numeric GUM_SCALAR >
271 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end(); ++child) {
272 if (!ignore.exists(child->first)) {
274 }
else if (!eliminated.exists(child->first)) {
276 delayedVars.
insert(iter.key());
283 eliminated.insert(i);
286 for (
const auto node: my_list) {
288 if (!ignore.exists(node)) {
291 }
else if (node != from) {
292 elim_list.insert(node);
297 for (
const auto chain: i->
type().slotChains()) {
299 if (inst != from) { elim_list.insert(inst); }
304 template < GUM_Numeric GUM_SCALAR >
314 for (
const auto agg: i->
type().aggregates())
320 std::vector< const DiscreteVariable* > elim;
322 for (
const auto node: *(*p_eo)) {
323 const auto& var = bn.
variable(node);
324 if (delayedVars !=
nullptr) {
325 if (!delayedVars->
exists(node)) {
326 const auto& var = bn.
variable(node);
327 elim.push_back(&var);
330 elim.push_back(&var);
342 template < GUM_Numeric GUM_SCALAR >
354 for (
auto child = (*(iter.val())).begin(); child != (*(iter.val())).end(); ++child) {
355 if (!ignore.exists(child->first)) {
363 eliminated.insert(i);
367 while (!elim_list.empty()) {
369 if (!ignore.exists(elim_list.front())) {
379 tmp_list.
insert(elim_list.front());
382 elim_list.popFront();
386 for (
const auto chain: i->
type().slotChains()) {
388 if (!ignore.exists(parent)) {
395 template < GUM_Numeric GUM_SCALAR >
403 for (
const auto& elt: this->
evidence(i)) {
405 = i->
type().isInputNode(i->
get(elt.first)) || i->
type().isInnerNode(i->
get(elt.first));
407 if (inner) {
break; }
417 for (
const auto& elt: *i) {
418 tmp_pool.
insert(&(
const_cast< Tensor< GUM_SCALAR >&
>(elt.second->cpf())));
426 std::vector< const DiscreteVariable* > inner_elim_order;
427 std::vector< const DiscreteVariable* > output_elim_order;
429 for (
size_t idx = 0; idx < full_elim_order.size(); ++idx) {
430 auto var_id = full_elim_order[idx];
431 const auto& var = bn.
variable(var_id);
433 if (!i->type().isOutputNode(i->get(full_elim_order[idx]))) {
434 inner_elim_order.push_back(&var);
435 }
else if (delayedVars !=
nullptr) {
436 if (!delayedVars->
exists(full_elim_order[idx])) { output_elim_order.push_back(&var); }
438 output_elim_order.push_back(&var);
445 for (
const auto pot: tmp_pool)
448 if (!output_elim_order.empty())
eliminateNodes(output_elim_order, pool, trash);
455 for (
const auto agg: i->
type().aggregates())
461 std::vector< const DiscreteVariable* > elim;
463 for (
auto iter = (*p_eo2)->begin(); iter != (*p_eo2)->end(); ++iter) {
464 const auto& var = bn.
variable(*iter);
465 if (delayedVars !=
nullptr) {
466 if (!delayedVars->
exists(*iter)) { elim.push_back(&var); }
468 elim.push_back(&var);
477 template < GUM_Numeric GUM_SCALAR >
490 for (
const auto lifted_pot: *lifted_pool) {
497 template < GUM_Numeric GUM_SCALAR >
508 lifted_pool->
insert(
const_cast< Tensor< GUM_SCALAR >*
>(&(c.
get(node).cpf())));
534 for (
size_t idx = 0; idx < inners.
size(); ++idx)
547 template < GUM_Numeric GUM_SCALAR >
551 std::list< NodeId > l;
560 visited_node.
insert(l.front());
562 if (!class_elim_order.
exists(cdg.
get(l.front()).first)) {
563 class_elim_order.
insert(cdg.
get(l.front()).first);
567 if (!visited_node.
contains(child)) { l.push_back(child); }
574 for (
auto c: class_elim_order) {
575 std::string
name = c->name();
576 if (
auto pos =
name.find_first_of(
"<"); pos != std::string::npos) {
585 template < GUM_Numeric GUM_SCALAR >
593 std::vector< Tensor< GUM_SCALAR >* > result;
595 for (
const auto pot: pool) {
596 if (pot->contains(elt->
type().
variable())) { result.push_back(pot); }
599 while (result.size() > 1) {
600 auto& p1 = *(result.back());
602 auto& p2 = *(result.back());
604 auto mult =
new Tensor< GUM_SCALAR >(p1 * p2);
606 result.push_back(mult);
609 m = *(result.back());
612 for (
const auto pot: trash) {
617 template < GUM_Numeric GUM_SCALAR >
622 template < GUM_Numeric GUM_SCALAR >
625 GUM_CONSTRUCTOR(
SVE);
628 template < GUM_Numeric GUM_SCALAR >
630 for (
const auto& elt: this->
evidence(i))
631 pool.
insert(
const_cast< Tensor< GUM_SCALAR >*
>(elt.second));
634 template < GUM_Numeric GUM_SCALAR >
639 template < GUM_Numeric GUM_SCALAR >
641 if (
auto pos = s.find_first_of(
"<"); pos != std::string::npos) {
642 return std::string{s.substr(0, pos)};
644 return std::string{s};
647 template < GUM_Numeric GUM_SCALAR >
652 auto first_name =
_trim_(first->
type().name());
653 auto second_name =
_trim_(second->
type().name());
657 template < GUM_Numeric GUM_SCALAR >
660 return &(
const_cast< Tensor< GUM_SCALAR >&
>(i->
get(agg->
id()).cpf()));
663 template < GUM_Numeric GUM_SCALAR >
668 template < GUM_Numeric GUM_SCALAR >
673 template < GUM_Numeric GUM_SCALAR >
683 (*p_dv)->insert(&(j->
get(
id).type().variable()));
688 static std::string dot =
".";
690 auto key = j->
name() + dot + j->
get(
id).safeName();
698 template < GUM_Numeric GUM_SCALAR >
Headers of SVE (Structured Variable Elimination).
Headers of ClassDependencyGraph<GUM_SCALAR>.
const NodeSet & parents(NodeId id) const
returns the set of nodes with arc ingoing to a given node
NodeSet children(const NodeSet &ids) const
returns the set of nodes which consists in the node and its parents returns the set of children of a ...
UndiGraph moralGraph() const
The node's id are coherent with the variables and nodes of the topology.
The default triangulation algorithm used by aGrUM.
Exception : a similar element already exists.
Exception : fatal (unknown ?) error.
Generic doubly linked lists.
Val & front() const
Returns a reference to first element of a list, if any.
Val & push_back(Args &&... args)
An alias for pushBack used for STL compliance.
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
void popFront()
Removes the first element of a List, if any.
A multidim implementation for buckets.
const gum::VariableSet & allVariables() const
Returns the sequence of all the variables contained in the bucket.
void add(const MultiDimContainer< GUM_ELEMENT > &impl)
Add a MultiDimContainer in the bucket.
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
class for graph triangulations for which we enforce a given partial ordering on the nodes elimination...
void insert(const Key &k)
Insert an element at the end of the sequence.
bool exists(const Key &k) const
Check the existence of k in the sequence.
The generic class for storing (ordered) sequences of objects.
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
bool empty() const noexcept
Indicates whether the set is the empty set.
void insert(const Key &k)
Inserts a new element into the set.
void erase(const Key &k)
Erases an element from the set.
Size size() const noexcept
Returns the number of elements in the set.
const std::vector< NodeId > & eliminationOrder() override
returns an elimination ordering compatible with the triangulated graph
This class decorates a gum::prm::Class<GUM_SCALAR> has an IBaseBayesNet.
const NodeProperty< Size > & modalities() const
See gum::IBaseBayesNet::modalities().
This class represent the dependencies of all classes in a PRM<GUM_SCALAR>.
const EltPair & get(NodeId id) const
Returns a constant reference over the element assiociated with the node id in the ClassDependencyGrap...
const DAG & internalDag() const
Returns a constant reference over the graph of the DAG representing the ClassDependencyGraph<GUM_SCAL...
This class decorates an PRMInstance<GUM_SCALAR> as an IBaseBayesNet.
const NodeProperty< Size > & modalities() const
See gum::IBaseBayesNet::cpt().
const DiscreteVariable & variable(NodeId id) const override
See gum::IBaseBayesNet::variable().
PRMAttribute is a member of a Class in a PRM.
PRMType & type() override=0
See gum::PRMClassElement::type().
virtual const DAG & containerDag() const
Returns the gum::DAG of this PRMClassElementContainer.
virtual bool isInnerNode(const PRMClassElement< GUM_SCALAR > &elt) const
Returns true if the node is an inner node.
static INLINE bool isAggregate(const PRMClassElement< GUM_SCALAR > &elt)
Return true if obj is of type PRMAggregate.
static INLINE bool isAttribute(const PRMClassElement< GUM_SCALAR > &elt)
Returns true if obj_ptr is of type PRMAttribute.
NodeId id() const
Returns the NodeId of this element in it's class DAG.
const std::string & safeName() const
Returns the safe name of this PRMClassElement, if any.
A PRMClass is an object of a PRM representing a fragment of a Bayesian network which can be instantia...
PRMClassElement< GUM_SCALAR > & get(NodeId id) override
See gum::prm::PRMClassElementContainer<GUM_SCALAR>::get(NodeId).
bool isOutputNode(const PRMClassElement< GUM_SCALAR > &elt) const override
Returns true if elt is an output node.
PRMInference(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default constructor.
EMap & evidence(const PRMInstance< GUM_SCALAR > &i)
Returns EMap of evidences over i.
PRM< GUM_SCALAR > const * prm_
The PRM<GUM_SCALAR> on which inference is done.
bool hasEvidence(const PRMInstance< GUM_SCALAR > &i) const
Returns true if i has evidence.
An PRMInstance is a Bayesian network fragment defined by a Class and used in a PRMSystem.
const iterator & end()
Returns a reference over the iterator at the end of the list of gum::prm::PRMAttribute<GUM_SCALAR> in...
PRMAttribute< GUM_SCALAR > & get(NodeId id)
Getter on an PRMAttribute<GUM_SCALAR> of this PRMInstance<GUM_SCALAR>.
InvRefIterator beginInvRef()
Alias to iterate over the gum::prm::PRMAttribute<GUM_SCALAR> in this PRMInstance<GUM_SCALAR>.
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 InvRefIterator & endInvRef()
Alias to iterate over the gum::prm::PRMAttribute<GUM_SCALAR> in this PRMInstance<GUM_SCALAR>.
PRMClass< GUM_SCALAR > & type()
Returns the type of this instance.
iterator begin()
Returns an iterator at the begining of the list of gum::prm::PRMAttribute<GUM_SCALAR> in this PRMInst...
const Set< PRMInstance< GUM_SCALAR > * > & getInstances(NodeId id) const
Returns the Set of PRMInstance<GUM_SCALAR> referenced by id.
const std::string & name() const
Returns the name of this object.
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Sequence< std::string > * _class_elim_order_
Set< Tensor< GUM_SCALAR > * > BucketSet
Code alias.
void _eliminateNodesWithEvidence_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, Set< NodeId > *delayedVars=0)
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.
void _insertLiftedNodes_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
std::string _trim_(std::string_view s)
Returns true if second can be eliminated before first.
void _variableElimination_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, Set< NodeId > *delayedVars=0)
Returns true if second can be eliminated before first.
~SVE() override
Destructor.
HashTable< const PRMClass< GUM_SCALAR > *, std::vector< NodeId > * > _elim_orders_
void _eliminateNodes_(const PRMInstance< GUM_SCALAR > *query, NodeId id, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
std::string name() const override
Returns the name of the current inference algorithm.
bool _checkElimOrder_(const PRMInstance< GUM_SCALAR > *first, const PRMInstance< GUM_SCALAR > *second)
Returns true if second can be eliminated before first.
void joint_(const std::vector< Chain > &queries, Tensor< GUM_SCALAR > &j) override
See PRMInference<GUM_SCALAR>::joint_().
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.
void posterior_(const Chain &chain, Tensor< GUM_SCALAR > &m) override
See PRMInference<GUM_SCALAR>::posterior_().
void _initElimOrder_()
Returns true if second can be eliminated before first.
void evidenceRemoved_(const Chain &chain) override
See PRMInference<GUM_SCALAR>::evidenceRemoved_().
HashTable< std::string, Size > _delayedVariablesCounters_
Some variable must be delayed for more than one PRMInstance<GUM_SCALAR>, when the delayed variable co...
void _insertEvidence_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool)
Returns true if second can be eliminated before first.
void evidenceAdded_(const Chain &chain) override
See PRMInference<GUM_SCALAR>::evidenceAdded_().
typename PRMInference< GUM_SCALAR >::Chain Chain
Code alias.
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.
SVE(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default Constructor.
Tensor< GUM_SCALAR > * _getAggTensor_(const PRMInstance< GUM_SCALAR > *i, const PRMAggregate< GUM_SCALAR > *agg)
Returns true if second can be eliminated before first.
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...
HashTable< const PRMClass< GUM_SCALAR > *, BucketSet * > _lifted_pools_
std::vector< NodeId > & _getElimOrder_(const PRMClass< GUM_SCALAR > &c)
Returns true if second can be eliminated before first.
HashTable< const PRMInstance< GUM_SCALAR > *, gum::VariableSet * > _delayedVariables_
void _eliminateDelayedVariables_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
#define GUM_ERROR(type, msg)
Size NodeId
Type for node ids.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
namespace for all probabilistic relational models entities
std::string __print_attribute__(const PRMInstance< GUM_SCALAR > &i, const PRMAttribute< GUM_SCALAR > &a)
std::string __print_pot__(const Tensor< GUM_SCALAR > &pot)
void eliminateNode(const DiscreteVariable *var, Set< Tensor< GUM_SCALAR > * > &pool, Set< Tensor< GUM_SCALAR > * > &trash)
Proceeds with the elimination of var in pool.
std::string __print_instance__(const PRMInstance< GUM_SCALAR > &i)
std::string __print_set__(SET set)
std::string __print_list__(LIST l)
void eliminateNodes(const std::vector< const DiscreteVariable * > &elim_order, Set< Tensor< GUM_SCALAR > * > &pool, Set< Tensor< GUM_SCALAR > * > &trash)
Tensor< GUM_SCALAR > * copyTensor(const Bijection< const DiscreteVariable *, const DiscreteVariable * > &bij, const Tensor< GUM_SCALAR > &source)
Returns a copy of a Tensor after applying a bijection over the variables in source.
std::string __print_system__(const PRMSystem< GUM_SCALAR > &s)
gum is the global namespace for all aGrUM entities
Set< const DiscreteVariable * > VariableSet