aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
orderedEliminationSequenceStrategy.cpp
Go to the documentation of this file.
1
/**
2
*
3
* Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4
* info_at_agrum_dot_org
5
*
6
* This library is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18
*
19
*/
20
21
22
/** @file
23
* @brief An Elimination sequence algorithm that imposes a given complete
24
*ordering
25
* on the nodes elimination sequence
26
*
27
* @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
28
*/
29
30
#
include
<
agrum
/
agrum
.
h
>
31
32
#
include
<
agrum
/
tools
/
graphs
/
algorithms
/
triangulations
/
eliminationStrategies
/
orderedEliminationSequenceStrategy
.
h
>
33
34
#
ifdef
GUM_NO_INLINE
35
#
include
<
agrum
/
tools
/
graphs
/
algorithms
/
triangulations
/
eliminationStrategies
/
orderedEliminationSequenceStrategy_inl
.
h
>
36
#
endif
// GUM_NOINLINE
37
38
namespace
gum
{
39
40
/// default constructor (uses an empty graph)
41
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
() {
42
GUM_CONSTRUCTOR
(
OrderedEliminationSequenceStrategy
);
43
}
44
45
/// constructor for an a priori non empty graph
46
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
(
47
UndiGraph
*
graph
,
48
const
NodeProperty
<
Size
>*
dom_sizes
,
49
const
std
::
vector
<
NodeId
>*
order
) :
50
EliminationSequenceStrategy
(
graph
,
dom_sizes
) {
51
// check that the user passed appropriate graphs and orders
52
if
(((
graph
==
nullptr
) && (
order
!=
nullptr
)) || ((
graph
!=
nullptr
) && (
order
==
nullptr
))) {
53
GUM_ERROR
(
GraphError
,
54
"OrderedEliminationSequenceStrategy needs either both nullptrs "
55
"or both non-nullptrs on graph and elimination ordering"
);
56
}
57
58
setOrder
(
order
);
59
60
GUM_CONSTRUCTOR
(
OrderedEliminationSequenceStrategy
);
61
}
62
63
/// copy constructor
64
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
(
65
const
OrderedEliminationSequenceStrategy
&
from
) :
66
EliminationSequenceStrategy
(
from
),
67
_order_
(
from
.
_order_
),
_order_index_
(
from
.
_order_index_
),
68
_order_needed_
(
from
.
_order_needed_
) {
69
GUM_CONS_CPY
(
OrderedEliminationSequenceStrategy
);
70
}
71
72
/// move constructor
73
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
(
74
OrderedEliminationSequenceStrategy
&&
from
) :
75
EliminationSequenceStrategy
(
std
::
move
(
from
)),
76
_order_
(
from
.
_order_
),
_order_index_
(
from
.
_order_index_
),
77
_order_needed_
(
from
.
_order_needed_
) {
78
GUM_CONS_MOV
(
OrderedEliminationSequenceStrategy
);
79
}
80
81
/// destructor
82
OrderedEliminationSequenceStrategy
::~
OrderedEliminationSequenceStrategy
() {
83
GUM_DESTRUCTOR
(
OrderedEliminationSequenceStrategy
);
84
}
85
86
/** @brief creates a new elimination sequence of the same type as the current
87
* object, but this sequence contains only an empty graph */
88
OrderedEliminationSequenceStrategy
*
OrderedEliminationSequenceStrategy
::
newFactory
()
const
{
89
return
new
OrderedEliminationSequenceStrategy
();
90
}
91
92
/// virtual copy constructor
93
OrderedEliminationSequenceStrategy
*
OrderedEliminationSequenceStrategy
::
copyFactory
()
const
{
94
return
new
OrderedEliminationSequenceStrategy
(*
this
);
95
}
96
97
/// sets a new graph to be triangulated
98
bool
OrderedEliminationSequenceStrategy
::
setGraph
(
UndiGraph
*
graph
,
99
const
NodeProperty
<
Size
>*
domain_sizes
) {
100
if
(
EliminationSequenceStrategy
::
setGraph
(
graph
,
domain_sizes
)) {
101
setOrder
(
_order_
);
102
return
true
;
103
}
104
105
return
false
;
106
}
107
108
/// indicates whether an order is compatible with the current graph
109
bool
110
OrderedEliminationSequenceStrategy
::
_isOrderNeeded_
(
const
std
::
vector
<
NodeId
>*
order
)
const
{
111
if
((
graph_
==
nullptr
) || (
order
==
nullptr
))
return
true
;
112
113
// determine the set of nodes in the order that belong to the graph
114
NodeSet
nodes_found
(
graph_
->
size
() / 2);
115
for
(
const
auto
node
: *
order
) {
116
if
(
graph_
->
existsNode
(
node
)) {
nodes_found
.
insert
(
node
); }
117
}
118
119
// check that the size of nodes_found is equal to that of the graph
120
return
nodes_found
.
size
() !=
graph_
->
size
();
121
}
122
123
/// sets a new complete order
124
bool
OrderedEliminationSequenceStrategy
::
setOrder
(
const
std
::
vector
<
NodeId
>*
order
) {
125
// check that the order contains all the nodes of the graph
126
_order_needed_
=
_isOrderNeeded_
(
order
);
127
128
if
(!
_order_needed_
) {
129
_order_
=
order
;
130
131
// determine the first element in order that belong to the graph
132
// here, note that we have the guarantee that _order_index_ will be
133
// lower than the size of _order_ since all the nodes in the graph
134
// belong to vector _order_
135
_order_index_
= 0;
136
while
(!
graph_
->
existsNode
((*
_order_
)[
_order_index_
]))
137
++
_order_index_
;
138
139
return
true
;
140
}
141
142
return
false
;
143
}
144
145
/// clears the order (to prepare, for instance, a new elimination sequence)
146
void
OrderedEliminationSequenceStrategy
::
clear
() {
147
EliminationSequenceStrategy
::
clear
();
148
_order_needed_
=
true
;
149
_order_index_
=
std
::
size_t
(0);
150
}
151
152
/// returns the new node to be eliminated within the triangulation algorithm
153
NodeId
OrderedEliminationSequenceStrategy
::
nextNodeToEliminate
() {
154
// check that we can return a nodeId
155
if
(
_order_needed_
|| (
_order_
->
size
() <=
_order_index_
)) {
156
GUM_ERROR
(
NotFound
,
"no node id can be returned"
)
157
}
158
159
return
(*
_order_
)[
_order_index_
];
160
}
161
162
/** @brief if the elimination sequence is able to compute fill-ins, we
163
* indicate whether we want this feature to be activated */
164
void
OrderedEliminationSequenceStrategy
::
askFillIns
(
bool
do_it
) {
165
// do nothing: we are not able to compute fill-ins
166
}
167
168
/** @brief indicates whether the fill-ins generated by the eliminated
169
* nodes, if needed, will be computed by the elimination sequence, or need be
170
* computed by the triangulation itself. */
171
bool
OrderedEliminationSequenceStrategy
::
providesFillIns
()
const
{
return
false
; }
172
173
/** @brief indicates whether the elimination sequence updates by itself the
174
* graph after a node has been eliminated */
175
bool
OrderedEliminationSequenceStrategy
::
providesGraphUpdate
()
const
{
return
false
; }
176
177
/// performs all the graph/fill-ins updates provided (if any)
178
void
OrderedEliminationSequenceStrategy
::
eliminationUpdate
(
const
NodeId
node
) {
179
// check whether there is something to update
180
if
(!
_order_needed_
) {
181
// check that node corresponds to the current index
182
if
((
_order_index_
>=
_order_
->
size
()) || ((*
_order_
)[
_order_index_
] !=
node
)) {
183
GUM_ERROR
(
OutOfBounds
,
184
"update impossible because node "
185
<<
node
<<
" does not correspond to the current elimination index"
);
186
}
187
188
// now perform the update: goto the next node that belongs to graph_
189
++
_order_index_
;
190
std
::
size_t
size
=
_order_
->
size
();
191
while
((
_order_index_
<
size
) && !
graph_
->
existsNode
((*
_order_
)[
_order_index_
]))
192
++
_order_index_
;
193
}
194
}
195
196
/** @brief in case fill-ins are provided, this function returns the fill-ins
197
* due to all the nodes eliminated so far */
198
const
EdgeSet
&
OrderedEliminationSequenceStrategy
::
fillIns
() {
199
return
EliminationSequenceStrategy
::
fillIns
();
200
}
201
202
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643