aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
orderedEliminationSequenceStrategy.cpp
Go to the documentation of this file.
1
/**
2
*
3
* Copyright 2005-2020 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
// for debugging purposes
43
GUM_CONSTRUCTOR
(
OrderedEliminationSequenceStrategy
);
44
}
45
46
/// constructor for an a priori non empty graph
47
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
(
48
UndiGraph
*
graph
,
49
const
NodeProperty
<
Size
>*
dom_sizes
,
50
const
std
::
vector
<
NodeId
>*
order
) :
51
EliminationSequenceStrategy
(
graph
,
dom_sizes
) {
52
// check that the user passed appropriate graphs and orders
53
if
(((
graph
==
nullptr
) && (
order
!=
nullptr
))
54
|| ((
graph
!=
nullptr
) && (
order
==
nullptr
))) {
55
GUM_ERROR
(
GraphError
,
56
"OrderedEliminationSequenceStrategy needs either both nullptrs "
57
"or both non-nullptrs on graph and elimination ordering"
);
58
}
59
60
setOrder
(
order
);
61
62
// for debugging purposes
63
GUM_CONSTRUCTOR
(
OrderedEliminationSequenceStrategy
);
64
}
65
66
/// copy constructor
67
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
(
68
const
OrderedEliminationSequenceStrategy
&
from
) :
69
EliminationSequenceStrategy
(
from
),
70
order__
(
from
.
order__
),
order_index__
(
from
.
order_index__
),
71
order_needed__
(
from
.
order_needed__
) {
72
// for debugging purposes
73
GUM_CONS_CPY
(
OrderedEliminationSequenceStrategy
);
74
}
75
76
/// move constructor
77
OrderedEliminationSequenceStrategy
::
OrderedEliminationSequenceStrategy
(
78
OrderedEliminationSequenceStrategy
&&
from
) :
79
EliminationSequenceStrategy
(
std
::
move
(
from
)),
80
order__
(
from
.
order__
),
order_index__
(
from
.
order_index__
),
81
order_needed__
(
from
.
order_needed__
) {
82
// for debugging purposes
83
GUM_CONS_MOV
(
OrderedEliminationSequenceStrategy
);
84
}
85
86
/// destructor
87
OrderedEliminationSequenceStrategy
::~
OrderedEliminationSequenceStrategy
() {
88
// for debugging purposes
89
GUM_DESTRUCTOR
(
OrderedEliminationSequenceStrategy
);
90
}
91
92
/** @brief creates a new elimination sequence of the same type as the current
93
* object, but this sequence contains only an empty graph */
94
OrderedEliminationSequenceStrategy
*
95
OrderedEliminationSequenceStrategy
::
newFactory
()
const
{
96
return
new
OrderedEliminationSequenceStrategy
();
97
}
98
99
/// virtual copy constructor
100
OrderedEliminationSequenceStrategy
*
101
OrderedEliminationSequenceStrategy
::
copyFactory
()
const
{
102
return
new
OrderedEliminationSequenceStrategy
(*
this
);
103
}
104
105
/// sets a new graph to be triangulated
106
bool
OrderedEliminationSequenceStrategy
::
setGraph
(
107
UndiGraph
*
graph
,
108
const
NodeProperty
<
Size
>*
domain_sizes
) {
109
if
(
EliminationSequenceStrategy
::
setGraph
(
graph
,
domain_sizes
)) {
110
setOrder
(
order__
);
111
return
true
;
112
}
113
114
return
false
;
115
}
116
117
/// indicates whether an order is compatible with the current graph
118
bool
OrderedEliminationSequenceStrategy
::
isOrderNeeded__
(
119
const
std
::
vector
<
NodeId
>*
order
)
const
{
120
if
((
graph_
==
nullptr
) || (
order
==
nullptr
))
return
true
;
121
122
// determine the set of nodes in the order that belong to the graph
123
NodeSet
nodes_found
(
graph_
->
size
() / 2);
124
for
(
const
auto
node
: *
order
) {
125
if
(
graph_
->
existsNode
(
node
)) {
nodes_found
.
insert
(
node
); }
126
}
127
128
// check that the size of nodes_found is equal to that of the graph
129
return
nodes_found
.
size
() !=
graph_
->
size
();
130
}
131
132
/// sets a new complete order
133
bool
OrderedEliminationSequenceStrategy
::
setOrder
(
134
const
std
::
vector
<
NodeId
>*
order
) {
135
// check that the order contains all the nodes of the graph
136
order_needed__
=
isOrderNeeded__
(
order
);
137
138
if
(!
order_needed__
) {
139
order__
=
order
;
140
141
// determine the first element in order that belong to the graph
142
// here, note that we have the guarantee that order_index__ will be
143
// lower than the size of order__ since all the nodes in the graph
144
// belong to vector order__
145
order_index__
= 0;
146
while
(!
graph_
->
existsNode
((*
order__
)[
order_index__
]))
147
++
order_index__
;
148
149
return
true
;
150
}
151
152
return
false
;
153
}
154
155
/// clears the order (to prepare, for instance, a new elimination sequence)
156
void
OrderedEliminationSequenceStrategy
::
clear
() {
157
EliminationSequenceStrategy
::
clear
();
158
order_needed__
=
true
;
159
order_index__
=
std
::
size_t
(0);
160
}
161
162
/// returns the new node to be eliminated within the triangulation algorithm
163
NodeId
OrderedEliminationSequenceStrategy
::
nextNodeToEliminate
() {
164
// check that we can return a nodeId
165
if
(
order_needed__
|| (
order__
->
size
() <=
order_index__
)) {
166
GUM_ERROR
(
NotFound
,
"no node id can be returned"
);
167
}
168
169
return
(*
order__
)[
order_index__
];
170
}
171
172
/** @brief if the elimination sequence is able to compute fill-ins, we
173
* indicate whether we want this feature to be activated */
174
void
OrderedEliminationSequenceStrategy
::
askFillIns
(
bool
do_it
) {
175
// do nothing: we are not able to compute fill-ins
176
}
177
178
/** @brief indicates whether the fill-ins generated by the eliminated
179
* nodes, if needed, will be computed by the elimination sequence, or need be
180
* computed by the triangulation itself. */
181
bool
OrderedEliminationSequenceStrategy
::
providesFillIns
()
const
{
182
return
false
;
183
}
184
185
/** @brief indicates whether the elimination sequence updates by itself the
186
* graph after a node has been eliminated */
187
bool
OrderedEliminationSequenceStrategy
::
providesGraphUpdate
()
const
{
188
return
false
;
189
}
190
191
/// performs all the graph/fill-ins updates provided (if any)
192
void
OrderedEliminationSequenceStrategy
::
eliminationUpdate
(
const
NodeId
node
) {
193
// check whether there is something to update
194
if
(!
order_needed__
) {
195
// check that node corresponds to the current index
196
if
((
order_index__
>=
order__
->
size
())
197
|| ((*
order__
)[
order_index__
] !=
node
)) {
198
GUM_ERROR
(
OutOfBounds
,
199
"update impossible because node "
200
<<
node
201
<<
" does not correspond to the current elimination index"
);
202
}
203
204
// now perform the update: goto the next node that belongs to graph_
205
++
order_index__
;
206
std
::
size_t
size
=
order__
->
size
();
207
while
((
order_index__
<
size
)
208
&& !
graph_
->
existsNode
((*
order__
)[
order_index__
]))
209
++
order_index__
;
210
}
211
}
212
213
/** @brief in case fill-ins are provided, this function returns the fill-ins
214
* due to all the nodes eliminated so far */
215
const
EdgeSet
&
OrderedEliminationSequenceStrategy
::
fillIns
() {
216
return
EliminationSequenceStrategy
::
fillIns
();
217
}
218
219
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669