aGrUM 3.1.1
a C++ library for (probabilistic) graphical models
SVE_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2026 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2026 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40
41#pragma once
42
43
52
53namespace gum {
54 namespace prm {
55
56 template < GUM_Numeric GUM_SCALAR >
59 std::stringstream s;
60 const auto& class_a = i.type().get(a.safeName());
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);
65 return s.str();
66 }
67
68 template < GUM_Numeric GUM_SCALAR >
70 std::stringstream s;
71 s << i.name() << std::endl;
72 s << "Attributes: " << std::endl;
73 for (auto a: i) {
74 s << __print_attribute__(i, *(a.second));
75 }
76 if (i.type().slotChains().size()) {
77 s << std::endl << "SlotChains: " << std::endl;
78 for (auto sc: i.type().slotChains()) {
79 s << sc->name() << " ";
80 }
81 }
82 return s.str();
83 }
84
85 template < GUM_Numeric GUM_SCALAR >
87 std::stringstream str;
88 for (auto i: s) {
89 str << __print_instance__(*(i.second)) << std::endl;
90 }
91 return str.str();
92 }
93
94 template < typename LIST >
95 std::string __print_list__(LIST l) {
96 std::stringstream s;
97 s << "[";
98 for (auto i: l) {
99 s << i->name() << " ";
100 }
101 s << "]";
102 return s.str();
103 }
104
105 template < GUM_Numeric GUM_SCALAR >
106 std::string __print_pot__(const Tensor< GUM_SCALAR >& pot) {
107 std::stringstream s;
108 s << "{";
109 for (auto var: pot.variablesSequence()) {
110 s << var << ", ";
111 }
112 s << "}";
113 return s.str();
114 }
115
116 template < typename SET >
117 std::string __print_set__(SET set) {
118 std::stringstream s;
119 s << "[";
120 for (auto p: set) {
121 s << __print_pot__(*p) << " ";
122 }
123 s << "]";
124 return s.str();
125 }
126
127 template < GUM_Numeric GUM_SCALAR >
129 GUM_DESTRUCTOR(SVE);
130
131 for (const auto& elt: _elim_orders_)
132 delete elt.second;
133
134 for (const auto& elt: _lifted_pools_)
135 delete elt.second;
136
137 if (_class_elim_order_ != nullptr) delete _class_elim_order_;
138
139 for (const auto trash: _lifted_trash_)
140 delete trash;
141
142 for (auto set: _delayedVariables_)
143 delete set.second;
144 }
145
146 template < GUM_Numeric GUM_SCALAR >
148 NodeId node,
149 BucketSet& pool,
150 BucketSet& trash) {
151 Set< const PRMInstance< GUM_SCALAR >* > ignore, eliminated;
152 Set< NodeId > delayedVars;
153 // Downward elimination
155 ignore.insert(query);
156
157 for (auto iter = query->beginInvRef(); iter != query->endInvRef(); ++iter) {
158 for (auto child = (*(iter.val())).begin(); child != (*(iter.val())).end(); ++child) {
159 if (!ignore.exists(child->first)) {
161 child->first,
162 pool,
163 trash,
164 elim_list,
165 ignore,
166 eliminated);
167 } else if (!eliminated.exists(child->first)) {
168 _addDelayedVariable_(child->first, query, iter.key());
169 delayedVars.insert(iter.key());
170 }
171 }
172 }
173
174 // Eliminating all nodes in query instance, except query
176 const auto moralg = bn.moralGraph();
177 DefaultTriangulation t(&moralg, &(bn.modalities()));
178 std::vector< const DiscreteVariable* > elim_order;
179
180 if (this->hasEvidence(query)) { _insertEvidence_(query, pool); }
181
182 for (auto attr = query->begin(); attr != query->end(); ++attr) {
183 pool.insert(&(const_cast< Tensor< GUM_SCALAR >& >((*(attr.val())).cpf())));
184 }
185
186 for (size_t idx = 0; idx < t.eliminationOrder().size(); ++idx) {
187 if ((t.eliminationOrder()[idx] != node)
188 && (!delayedVars.exists(t.eliminationOrder()[idx]))) {
189 auto var_id = t.eliminationOrder()[idx];
190 const auto& var = bn.variable(var_id);
191 elim_order.push_back(&var);
192 }
193 }
194
195 eliminateNodes(elim_order, pool, trash);
196
197 // Eliminating delayed variables, if any
198 if (_delayedVariables_.exists(query)) { _eliminateDelayedVariables_(query, pool, trash); }
199
200 eliminated.insert(query);
201 // Eliminating instance in elim_list
203
204 while (!elim_list.empty()) {
205 if (_checkElimOrder_(query, elim_list.front())) {
206 if (!ignore.exists(elim_list.front())) {
208 elim_list.front(),
209 pool,
210 trash,
211 elim_list,
212 ignore,
213 eliminated);
214 }
215 } else {
216 tmp_list.insert(elim_list.front());
217 }
218
219 elim_list.popFront();
220 }
221
222 // Upward elimination
223 for (const auto chain: query->type().slotChains())
224 for (const auto parent: query->getInstances(chain->id()))
225 if (!ignore.exists(parent))
226 _eliminateNodesUpward_(parent, pool, trash, tmp_list, ignore, eliminated);
227 }
228
229 template < GUM_Numeric GUM_SCALAR >
231 BucketSet& pool,
232 BucketSet& trash) {
233 Set< Tensor< GUM_SCALAR >* > toRemove;
234
235 for (const auto var: *_delayedVariables_[i]) {
237
238 for (const auto pot: pool)
239 if (pot->contains(*var)) {
240 bucket->add(*pot);
241 toRemove.insert(pot);
242 }
243
244 for (const auto pot: toRemove)
245 pool.erase(pot);
246
247 for (const auto other: bucket->allVariables())
248 if (other != var) bucket->add(*other);
249
250 Tensor< GUM_SCALAR >* bucket_pot = new Tensor< GUM_SCALAR >(bucket);
251 trash.insert(bucket_pot);
252 pool.insert(bucket_pot);
253 }
254 }
255
256 template < GUM_Numeric GUM_SCALAR >
258 const PRMInstance< GUM_SCALAR >* from,
260 BucketSet& pool,
261 BucketSet& trash,
262 List< const PRMInstance< GUM_SCALAR >* >& elim_list,
263 Set< const PRMInstance< GUM_SCALAR >* >& ignore,
264 Set< const PRMInstance< GUM_SCALAR >* >& eliminated) {
265 Set< NodeId > delayedVars;
266 ignore.insert(i);
267 // Calling elimination over child instance
269
270 for (auto iter = i->beginInvRef(); iter != i->endInvRef(); ++iter) {
271 for (auto child = (*(iter.val())).begin(); child != (*(iter.val())).end(); ++child) {
272 if (!ignore.exists(child->first)) {
273 _eliminateNodesDownward_(i, child->first, pool, trash, my_list, ignore, eliminated);
274 } else if (!eliminated.exists(child->first)) {
275 _addDelayedVariable_(child->first, i, iter.key());
276 delayedVars.insert(iter.key());
277 }
278 }
279 }
280
281 // Eliminating all nodes in current instance
282 _variableElimination_(i, pool, trash, (delayedVars.empty() ? 0 : &delayedVars));
283 eliminated.insert(i);
284
285 // Calling elimination over child's parents
286 for (const auto node: my_list) {
287 if (_checkElimOrder_(i, node) && (node != from)) {
288 if (!ignore.exists(node)) {
289 _eliminateNodesDownward_(i, node, pool, trash, elim_list, ignore, eliminated);
290 }
291 } else if (node != from) {
292 elim_list.insert(node);
293 }
294 }
295
296 // Adding parents instance to elim_list
297 for (const auto chain: i->type().slotChains()) {
298 for (const auto inst: i->getInstances(chain->id())) {
299 if (inst != from) { elim_list.insert(inst); }
300 }
301 }
302 }
303
304 template < GUM_Numeric GUM_SCALAR >
306 BucketSet& pool,
307 BucketSet& trash,
308 Set< NodeId >* delayedVars) {
309 if (this->hasEvidence(i)) {
310 _eliminateNodesWithEvidence_(i, pool, trash, delayedVars);
311 } else {
312 _insertLiftedNodes_(i, pool, trash);
313
314 for (const auto agg: i->type().aggregates())
315 pool.insert(_getAggTensor_(i, agg));
316
317 if (auto p_eo = _elim_orders_.tryGet(&(i->type()))) {
319
320 std::vector< const DiscreteVariable* > elim;
321
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);
328 }
329 } else {
330 elim.push_back(&var);
331 }
332 }
333
334 eliminateNodes(elim, pool, trash);
335 }
336 }
337
338 // Eliminating delayed variables, if any
339 if (_delayedVariables_.exists(i)) { _eliminateDelayedVariables_(i, pool, trash); }
340 }
341
342 template < GUM_Numeric GUM_SCALAR >
345 BucketSet& pool,
346 BucketSet& trash,
347 List< const PRMInstance< GUM_SCALAR >* >& elim_list,
348 Set< const PRMInstance< GUM_SCALAR >* >& ignore,
349 Set< const PRMInstance< GUM_SCALAR >* >& eliminated) {
350 // Downward elimination
351 ignore.insert(i);
352
353 for (auto iter = i->beginInvRef(); iter != i->endInvRef(); ++iter) {
354 for (auto child = (*(iter.val())).begin(); child != (*(iter.val())).end(); ++child) {
355 if (!ignore.exists(child->first)) {
356 _eliminateNodesDownward_(i, child->first, pool, trash, elim_list, ignore, eliminated);
357 }
358 }
359 }
360
361 // Eliminating all nodes in i instance
362 _variableElimination_(i, pool, trash);
363 eliminated.insert(i);
364 // Eliminating instance in elim_list
366
367 while (!elim_list.empty()) {
368 if (_checkElimOrder_(i, elim_list.front())) {
369 if (!ignore.exists(elim_list.front())) {
371 elim_list.front(),
372 pool,
373 trash,
374 elim_list,
375 ignore,
376 eliminated);
377 }
378 } else {
379 tmp_list.insert(elim_list.front());
380 }
381
382 elim_list.popFront();
383 }
384
385 // Upward elimination
386 for (const auto chain: i->type().slotChains()) {
387 for (const auto parent: i->getInstances(chain->id())) {
388 if (!ignore.exists(parent)) {
389 _eliminateNodesUpward_(parent, pool, trash, tmp_list, ignore, eliminated);
390 }
391 }
392 }
393 }
394
395 template < GUM_Numeric GUM_SCALAR >
397 BucketSet& pool,
398 BucketSet& trash,
399 Set< NodeId >* delayedVars) {
400 // First we check if evidences are on inner nodes
401 bool inner = false;
402
403 for (const auto& elt: this->evidence(i)) {
404 inner
405 = i->type().isInputNode(i->get(elt.first)) || i->type().isInnerNode(i->get(elt.first));
406
407 if (inner) { break; }
408 }
409
410 // Evidence on inner nodes
411 if (inner) {
412 BucketSet tmp_pool;
413 _insertEvidence_(i, tmp_pool);
414
415 // We need a local to not eliminate queried inner nodes of the same
416 // class
417 for (const auto& elt: *i) {
418 tmp_pool.insert(&(const_cast< Tensor< GUM_SCALAR >& >(elt.second->cpf())));
419 }
420
422 const auto moralg = bn.moralGraph();
423 DefaultTriangulation t(&moralg, &(bn.modalities()));
424 const std::vector< NodeId >& full_elim_order = t.eliminationOrder();
425 // Removing Output nodes of elimination order
426 std::vector< const DiscreteVariable* > inner_elim_order;
427 std::vector< const DiscreteVariable* > output_elim_order;
428
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);
432
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); }
437 } else {
438 output_elim_order.push_back(&var);
439 }
440 }
441
442 eliminateNodes(inner_elim_order, tmp_pool, trash);
443
444 // Now we add the new tensors in pool and eliminate output nodes
445 for (const auto pot: tmp_pool)
446 pool.insert(pot);
447
448 if (!output_elim_order.empty()) eliminateNodes(output_elim_order, pool, trash);
449
450 } else {
452 _insertEvidence_(i, pool);
453 _insertLiftedNodes_(i, pool, trash);
454
455 for (const auto agg: i->type().aggregates())
456 pool.insert(_getAggTensor_(i, agg));
457
458 if (auto p_eo2 = _elim_orders_.tryGet(&(i->type())); !p_eo2) {
459 GUM_ERROR(FatalError, "there should be at least one node here.")
460 } else {
461 std::vector< const DiscreteVariable* > elim;
462
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); }
467 } else {
468 elim.push_back(&var);
469 }
470 }
471
472 eliminateNodes(elim, pool, trash);
473 }
474 }
475 }
476
477 template < GUM_Numeric GUM_SCALAR >
479 BucketSet& pool,
480 BucketSet& trash) {
481 SVE< GUM_SCALAR >::BucketSet* lifted_pool = 0;
482
483 auto p_lp = _lifted_pools_.tryGet(&(i->type()));
484 if (!p_lp) {
486 p_lp = _lifted_pools_.tryGet(&(i->type()));
487 }
488 lifted_pool = *p_lp;
489
490 for (const auto lifted_pot: *lifted_pool) {
491 Tensor< GUM_SCALAR >* pot = copyTensor(i->bijection(), *lifted_pot);
492 pool.insert(pot);
493 trash.insert(pot);
494 }
495 }
496
497 template < GUM_Numeric GUM_SCALAR >
499 BucketSet* lifted_pool = new BucketSet();
500 _lifted_pools_.insert(&c, lifted_pool);
501 NodeSet inners, outers;
502
503 for (const auto node: c.containerDag().nodes())
505 if (c.isOutputNode(c.get(node))) outers.insert(node);
506 else if (!outers.exists(node)) inners.insert(node);
507
508 lifted_pool->insert(const_cast< Tensor< GUM_SCALAR >* >(&(c.get(node).cpf())));
510 outers.insert(node);
511
512 // We need to put in the output_elim_order aggregator's parents which
513 // are
514 // innner nodes
515 for (const auto par: c.containerDag().parents(node))
517 && c.isInnerNode(c.get(par))) {
518 inners.erase(par);
519 outers.insert(par);
520 }
521 }
522
523 // Now we proceed with the elimination of inner attributes
525 List< NodeSet > partial_ordering;
526
527 if (inners.size()) partial_ordering.push_back(inners);
528
529 if (outers.size()) partial_ordering.push_back(outers);
530
531 const auto moralg = bn.moralGraph();
532 PartialOrderedTriangulation t(&moralg, &(bn.modalities()), &partial_ordering);
533
534 for (size_t idx = 0; idx < inners.size(); ++idx)
535 eliminateNode(&(c.get(t.eliminationOrder()[idx]).type().variable()),
536 *lifted_pool,
538
539 // If there is not only inner and input Attributes
540 if (outers.size()) {
541 _elim_orders_.insert(&c,
542 new std::vector< NodeId >(t.eliminationOrder().begin() + inners.size(),
543 t.eliminationOrder().end()));
544 }
545 }
546
547 template < GUM_Numeric GUM_SCALAR >
551 std::list< NodeId > l;
552
553 for (const auto node: cdg.internalDag().nodes()) {
554 if (cdg.internalDag().parents(node).empty()) { l.push_back(node); }
555 }
556
557 Set< NodeId > visited_node;
558
559 while (!l.empty()) {
560 visited_node.insert(l.front());
561
562 if (!class_elim_order.exists(cdg.get(l.front()).first)) {
563 class_elim_order.insert(cdg.get(l.front()).first);
564 }
565
566 for (const auto child: cdg.internalDag().children(l.front())) {
567 if (!visited_node.contains(child)) { l.push_back(child); }
568 }
569
570 l.pop_front();
571 }
572
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) {
577 name = name.substr(0, pos);
578 }
579 try {
580 _class_elim_order_->insert(name);
581 } catch (DuplicateElement const&) {}
582 }
583 }
584
585 template < GUM_Numeric GUM_SCALAR >
586 void SVE< GUM_SCALAR >::posterior_(const Chain& chain, Tensor< GUM_SCALAR >& m) {
587 const PRMInstance< GUM_SCALAR >* i = chain.first;
588 const PRMAttribute< GUM_SCALAR >* elt = chain.second;
590
591 _eliminateNodes_(i, elt->id(), pool, trash);
592
593 std::vector< Tensor< GUM_SCALAR >* > result;
594
595 for (const auto pot: pool) {
596 if (pot->contains(elt->type().variable())) { result.push_back(pot); }
597 }
598
599 while (result.size() > 1) {
600 auto& p1 = *(result.back());
601 result.pop_back();
602 auto& p2 = *(result.back());
603 result.pop_back();
604 auto mult = new Tensor< GUM_SCALAR >(p1 * p2);
605 trash.insert(mult);
606 result.push_back(mult);
607 }
608
609 m = *(result.back());
610 m.normalize();
611
612 for (const auto pot: trash) {
613 delete pot;
614 }
615 }
616
617 template < GUM_Numeric GUM_SCALAR >
618 void SVE< GUM_SCALAR >::joint_(const std::vector< Chain >& queries, Tensor< GUM_SCALAR >& j) {
619 GUM_ERROR(FatalError, "Not implemented.")
620 }
621
622 template < GUM_Numeric GUM_SCALAR >
624 PRMInference< GUM_SCALAR >(prm, system), _class_elim_order_(0) {
625 GUM_CONSTRUCTOR(SVE);
626 }
627
628 template < GUM_Numeric GUM_SCALAR >
630 for (const auto& elt: this->evidence(i))
631 pool.insert(const_cast< Tensor< GUM_SCALAR >* >(elt.second));
632 }
633
634 template < GUM_Numeric GUM_SCALAR >
636 return *(_elim_orders_[&c]);
637 }
638
639 template < GUM_Numeric GUM_SCALAR >
640 std::string SVE< GUM_SCALAR >::_trim_(std::string_view s) {
641 if (auto pos = s.find_first_of("<"); pos != std::string::npos) {
642 return std::string{s.substr(0, pos)};
643 }
644 return std::string{s};
645 }
646
647 template < GUM_Numeric GUM_SCALAR >
649 const PRMInstance< GUM_SCALAR >* second) {
650 if (_class_elim_order_ == 0) { _initElimOrder_(); }
651
652 auto first_name = _trim_(first->type().name());
653 auto second_name = _trim_(second->type().name());
654 return (_class_elim_order_->pos(first_name) <= _class_elim_order_->pos(second_name));
655 }
656
657 template < GUM_Numeric GUM_SCALAR >
659 const PRMAggregate< GUM_SCALAR >* agg) {
660 return &(const_cast< Tensor< GUM_SCALAR >& >(i->get(agg->id()).cpf()));
661 }
662
663 template < GUM_Numeric GUM_SCALAR >
665 // Do nothing
666 }
667
668 template < GUM_Numeric GUM_SCALAR >
670 // Do nothing
671 }
672
673 template < GUM_Numeric GUM_SCALAR >
676 NodeId id) {
677 auto p_dv = _delayedVariables_.tryGet(i);
678 if (!p_dv) {
679 _delayedVariables_.insert(i, new gum::VariableSet());
680 p_dv = _delayedVariables_.tryGet(i);
681 }
682 try {
683 (*p_dv)->insert(&(j->get(id).type().variable()));
684 } catch (DuplicateElement const&) {
685 // happends if j->get(id) is parent of more than one variable in i
686 }
687
688 static std::string dot = ".";
689
690 auto key = j->name() + dot + j->get(id).safeName();
691 if (auto p_cnt = _delayedVariablesCounters_.tryGet(key)) {
692 *p_cnt += 1;
693 } else {
694 _delayedVariablesCounters_.insert(key, 1);
695 }
696 }
697
698 template < GUM_Numeric GUM_SCALAR >
699 std::string SVE< GUM_SCALAR >::name() const {
700 return "SVE";
701 }
702
703 } /* namespace prm */
704} /* namespace gum */
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.
Definition DAGmodel.cpp:81
The default triangulation algorithm used by aGrUM.
Exception : a similar element already exists.
Exception : fatal (unknown ?) error.
Generic doubly linked lists.
Definition list.h:378
Val & front() const
Returns a reference to first element of a list, if any.
Definition list_tpl.h:1694
Val & push_back(Args &&... args)
An alias for pushBack used for STL compliance.
Definition list_tpl.h:1494
Val & insert(const Val &val)
Inserts a new element at the end of the chained list (alias of pushBack).
Definition list_tpl.h:1508
bool empty() const noexcept
Returns a boolean indicating whether the chained list is empty.
Definition list_tpl.h:1822
void popFront()
Removes the first element of a List, if any.
Definition list_tpl.h:1816
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.
Definition sequence.h:994
Representation of a set.
Definition set.h:129
bool contains(const Key &k) const
Indicates whether a given elements belong to the set.
Definition set_tpl.h:468
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition set_tpl.h:504
bool empty() const noexcept
Indicates whether the set is the empty set.
Definition set_tpl.h:613
void insert(const Key &k)
Inserts a new element into the set.
Definition set_tpl.h:510
void erase(const Key &k)
Erases an element from the set.
Definition set_tpl.h:553
Size size() const noexcept
Returns the number of elements in the set.
Definition set_tpl.h:607
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...
Definition PRMClass.h:77
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.
Definition PRMInstance.h:79
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.
Definition PRMSystem.h:72
DiscreteVariable & variable()
Return a reference on the DiscreteVariable contained in this.
Definition PRMType_inl.h:65
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition PRM.h:74
Sequence< std::string > * _class_elim_order_
Definition SVE.h:131
Set< Tensor< GUM_SCALAR > * > BucketSet
Code alias.
Definition SVE.h:123
void _eliminateNodesWithEvidence_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, Set< NodeId > *delayedVars=0)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:396
void _initLiftedNodes_(const PRMClass< GUM_SCALAR > &c)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:498
void _insertLiftedNodes_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:478
std::string _trim_(std::string_view s)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:640
void _variableElimination_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash, Set< NodeId > *delayedVars=0)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:305
~SVE() override
Destructor.
Definition SVE_tpl.h:128
BucketSet _lifted_trash_
Definition SVE.h:142
HashTable< const PRMClass< GUM_SCALAR > *, std::vector< NodeId > * > _elim_orders_
Definition SVE.h:127
void _eliminateNodes_(const PRMInstance< GUM_SCALAR > *query, NodeId id, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:147
std::string name() const override
Returns the name of the current inference algorithm.
Definition SVE_tpl.h:699
bool _checkElimOrder_(const PRMInstance< GUM_SCALAR > *first, const PRMInstance< GUM_SCALAR > *second)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:648
void joint_(const std::vector< Chain > &queries, Tensor< GUM_SCALAR > &j) override
See PRMInference<GUM_SCALAR>::joint_().
Definition SVE_tpl.h:618
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.
Definition SVE_tpl.h:343
void posterior_(const Chain &chain, Tensor< GUM_SCALAR > &m) override
See PRMInference<GUM_SCALAR>::posterior_().
Definition SVE_tpl.h:586
void _initElimOrder_()
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:548
void evidenceRemoved_(const Chain &chain) override
See PRMInference<GUM_SCALAR>::evidenceRemoved_().
Definition SVE_tpl.h:669
HashTable< std::string, Size > _delayedVariablesCounters_
Some variable must be delayed for more than one PRMInstance<GUM_SCALAR>, when the delayed variable co...
Definition SVE.h:140
void _insertEvidence_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:629
void evidenceAdded_(const Chain &chain) override
See PRMInference<GUM_SCALAR>::evidenceAdded_().
Definition SVE_tpl.h:664
typename PRMInference< GUM_SCALAR >::Chain Chain
Code alias.
Definition SVE.h:105
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.
Definition SVE_tpl.h:257
SVE(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default Constructor.
Definition SVE_tpl.h:623
Tensor< GUM_SCALAR > * _getAggTensor_(const PRMInstance< GUM_SCALAR > *i, const PRMAggregate< GUM_SCALAR > *agg)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:658
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...
Definition SVE_tpl.h:674
HashTable< const PRMClass< GUM_SCALAR > *, BucketSet * > _lifted_pools_
Definition SVE.h:129
std::vector< NodeId > & _getElimOrder_(const PRMClass< GUM_SCALAR > &c)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:635
HashTable< const PRMInstance< GUM_SCALAR > *, gum::VariableSet * > _delayedVariables_
Definition SVE.h:133
void _eliminateDelayedVariables_(const PRMInstance< GUM_SCALAR > *i, BucketSet &pool, BucketSet &trash)
Returns true if second can be eliminated before first.
Definition SVE_tpl.h:230
#define GUM_ERROR(type, msg)
Definition exceptions.h:76
Size NodeId
Type for node ids.
Set< NodeId > NodeSet
Some typdefs and define for shortcuts ...
namespace for all probabilistic relational models entities
Definition agrum.h:68
std::string __print_attribute__(const PRMInstance< GUM_SCALAR > &i, const PRMAttribute< GUM_SCALAR > &a)
Definition SVE_tpl.h:57
std::string __print_pot__(const Tensor< GUM_SCALAR > &pot)
Definition SVE_tpl.h:106
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)
Definition SVE_tpl.h:69
std::string __print_set__(SET set)
Definition SVE_tpl.h:117
std::string __print_list__(LIST l)
Definition SVE_tpl.h:95
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)
Definition SVE_tpl.h:86
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Set< const DiscreteVariable * > VariableSet