aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
multiDimImplementation_tpl.h
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
/**
23
* @file
24
* @brief Implementation of gum::MultiDimImplementation.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
*/
28
29
// to ease IDE parser
30
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimImplementation
.
h
>
31
32
namespace
gum
{
33
34
// Default constructor
35
36
template
<
typename
GUM_SCALAR >
37
INLINE MultiDimImplementation<
GUM_SCALAR
>::
MultiDimImplementation
() :
38
MultiDimContainer
<
GUM_SCALAR
>(),
_vars_
(),
_slaveInstantiations_
() {
39
GUM_CONSTRUCTOR
(
MultiDimImplementation
);
40
_internalChangeMethod_
=
_InternalChangeMethod_
::
DIRECT_CHANGE
;
41
_internalChangeState_
=
_InternalChangeState_
::
NO_CHANGE
;
42
_domainSize_
= 1;
43
}
44
45
// Copy constructor
46
47
template
<
typename
GUM_SCALAR
>
48
INLINE
MultiDimImplementation
<
GUM_SCALAR
>::
MultiDimImplementation
(
49
const
MultiDimImplementation
<
GUM_SCALAR
>&
from
) :
50
MultiDimContainer
<
GUM_SCALAR
>(
from
),
51
_vars_
(
from
.
_vars_
),
_internalChangeMethod_
(
from
.
_internalChangeMethod_
),
52
_internalChangeState_
(
from
.
_internalChangeState_
),
_domainSize_
(
from
.
_domainSize_
) {
53
GUM_CONS_CPY
(
MultiDimImplementation
);
54
GUM_ASSERT
(!
this
->
isCommitNeeded_
());
55
}
56
57
// destructor
58
59
template
<
typename
GUM_SCALAR
>
60
INLINE
MultiDimImplementation
<
GUM_SCALAR
>::~
MultiDimImplementation
() {
61
GUM_DESTRUCTOR
(
MultiDimImplementation
);
62
// unregister all remaining slave instantiations
63
64
for
(
List
<
Instantiation
* >::
iterator_safe
iter
=
_slaveInstantiations_
.
beginSafe
();
65
iter
!=
_slaveInstantiations_
.
endSafe
();
66
++
iter
)
67
(*
iter
)->
forgetMaster
();
68
}
69
70
// add a new var to the sequence of _vars_.
71
72
template
<
typename
GUM_SCALAR
>
73
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
add
(
const
DiscreteVariable
&
v
) {
74
// check if the variable already belongs to the tuple of variables
75
// of the Instantiation
76
if
(
_vars_
.
exists
(&
v
)) {
77
GUM_ERROR
(
DuplicateElement
,
"Var "
<<
v
.
name
() <<
" already exists in this instantiation"
)
78
}
79
for
(
const
auto
&
w
:
_vars_
) {
80
if
(
w
->
name
() ==
v
.
name
())
81
GUM_ERROR
(
DuplicateElement
,
82
"A var with name '"
<<
v
.
name
() <<
"' already exists in this instantiation"
);
83
}
84
85
_domainSize_
*=
v
.
domainSize
();
86
87
_vars_
.
insert
(&
v
);
88
89
// informs all the slaves that they have to update themselves
90
for
(
List
<
Instantiation
* >::
iterator_safe
iter
=
_slaveInstantiations_
.
beginSafe
();
91
iter
!=
_slaveInstantiations_
.
endSafe
();
92
++
iter
) {
93
(*
iter
)->
addWithMaster
(
this
,
v
);
94
}
95
96
if
(
isInMultipleChangeMethod_
())
_setNotCommitedChange_
();
97
}
98
99
// removes a var from the variables of the multidimensional matrix
100
101
template
<
typename
GUM_SCALAR
>
102
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
erase
(
const
DiscreteVariable
&
v
) {
103
// check that the variable does actually belong to the
104
// MultiDimImplementation
105
if
(!
_vars_
.
exists
(&
v
)) {
GUM_ERROR
(
NotFound
,
"Var does not exist in this implementation"
) }
106
107
_domainSize_
/=
v
.
domainSize
();
108
109
_vars_
.
erase
(&
v
);
110
111
// informs all the slaves that they have to update themselves
112
for
(
List
<
Instantiation
* >::
iterator_safe
iter
=
_slaveInstantiations_
.
beginSafe
();
113
iter
!=
_slaveInstantiations_
.
endSafe
();
114
++
iter
) {
115
(*
iter
)->
eraseWithMaster
(
this
,
v
);
116
}
117
118
if
(
isInMultipleChangeMethod_
())
_setNotCommitedChange_
();
119
}
120
121
// adds a new var to the sequence of _vars_
122
template
<
typename
GUM_SCALAR
>
123
INLINE
MultiDimImplementation
<
GUM_SCALAR
>&
124
operator
<<(
MultiDimImplementation
<
GUM_SCALAR
>&
array
,
const
DiscreteVariable
&
v
) {
125
array
.
add
(
v
);
126
return
array
;
127
}
128
129
// add a Instantiation to the list of slave instantiations
130
131
template
<
typename
GUM_SCALAR
>
132
INLINE
bool
MultiDimImplementation
<
GUM_SCALAR
>::
registerSlave
(
Instantiation
&
slave
) {
133
// check that the Instantiation has the same variables as this
134
if
(
slave
.
nbrDim
() !=
_vars_
.
size
())
return
false
;
135
136
for
(
Sequence
<
const
DiscreteVariable
* >::
iterator_safe
iter
=
_vars_
.
beginSafe
();
137
iter
!=
_vars_
.
endSafe
();
138
++
iter
)
139
if
(!
slave
.
contains
(*
iter
))
return
false
;
140
141
slave
.
synchronizeWithMaster
(
this
);
142
143
_slaveInstantiations_
+= (&
slave
);
144
145
return
true
;
146
}
147
148
// removes a Instantiation from the list of slave instantiations
149
150
template
<
typename
GUM_SCALAR
>
151
INLINE
bool
MultiDimImplementation
<
GUM_SCALAR
>::
unregisterSlave
(
Instantiation
&
slave
) {
152
_slaveInstantiations_
.
eraseByVal
(&
slave
);
153
return
true
;
154
}
155
156
template
<
typename
GUM_SCALAR
>
157
INLINE
Idx
MultiDimImplementation
<
GUM_SCALAR
>::
nbrDim
()
const
{
158
return
_vars_
.
size
();
159
}
160
161
template
<
typename
GUM_SCALAR
>
162
INLINE
Size
MultiDimImplementation
<
GUM_SCALAR
>::
domainSize
()
const
{
163
return
_domainSize_
;
164
}
165
166
template
<
typename
GUM_SCALAR
>
167
INLINE
const
DiscreteVariable
&
MultiDimImplementation
<
GUM_SCALAR
>::
variable
(
Idx
i
)
const
{
168
return
*(
_vars_
.
atPos
(
i
));
169
}
170
171
template
<
typename
GUM_SCALAR
>
172
INLINE
const
DiscreteVariable
&
173
MultiDimImplementation
<
GUM_SCALAR
>::
variable
(
const
std
::
string
&
name
)
const
{
174
for
(
const
auto
&
v
:
_vars_
) {
175
if
(
v
->
name
() ==
name
)
return
*
v
;
176
}
177
178
GUM_ERROR
(
NotFound
,
"'"
<<
name
<<
"' can not be found in the multidim structure."
)
179
}
180
181
template
<
typename
GUM_SCALAR
>
182
INLINE
Idx
MultiDimImplementation
<
GUM_SCALAR
>::
pos
(
const
DiscreteVariable
&
v
)
const
{
183
return
_vars_
.
pos
(&
v
);
184
}
185
186
template
<
typename
GUM_SCALAR
>
187
INLINE
bool
MultiDimImplementation
<
GUM_SCALAR
>::
contains
(
const
DiscreteVariable
&
v
)
const
{
188
return
_vars_
.
exists
(&
v
);
189
}
190
191
// returns a const ref to the sequence of DiscreteVariable*
192
193
template
<
typename
GUM_SCALAR
>
194
INLINE
const
Sequence
<
const
DiscreteVariable
* >&
195
MultiDimImplementation
<
GUM_SCALAR
>::
variablesSequence
()
const
{
196
return
_vars_
;
197
}
198
199
// is this empty ?
200
template
<
typename
GUM_SCALAR
>
201
INLINE
bool
MultiDimImplementation
<
GUM_SCALAR
>::
empty
()
const
{
202
GUM_ASSERT
(!
this
->
isCommitNeeded_
());
203
return
_vars_
.
empty
();
204
}
205
206
template
<
typename
GUM_SCALAR
>
207
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
beginMultipleChanges
() {
208
_internalChangeMethod_
=
_InternalChangeMethod_
::
MULTIPLE_CHANGE
;
209
}
210
211
template
<
typename
GUM_SCALAR
>
212
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
endMultipleChanges
() {
213
if
(
_internalChangeState_
==
_InternalChangeState_
::
NOT_COMMITTED_CHANGE
) {
214
commitMultipleChanges_
();
215
_internalChangeState_
=
_InternalChangeState_
::
NO_CHANGE
;
216
}
217
218
_internalChangeMethod_
=
_InternalChangeMethod_
::
DIRECT_CHANGE
;
219
}
220
221
template
<
typename
GUM_SCALAR
>
222
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
endMultipleChanges
(
const
GUM_SCALAR
&
x
) {
223
if
(
_internalChangeState_
==
_InternalChangeState_
::
NOT_COMMITTED_CHANGE
) {
224
commitMultipleChanges_
(
x
);
225
_internalChangeState_
=
_InternalChangeState_
::
NO_CHANGE
;
226
}
227
228
_internalChangeMethod_
=
_InternalChangeMethod_
::
DIRECT_CHANGE
;
229
}
230
231
template
<
typename
GUM_SCALAR
>
232
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
commitMultipleChanges_
() {
233
// empty!
234
}
235
236
template
<
typename
GUM_SCALAR
>
237
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
commitMultipleChanges_
(
const
GUM_SCALAR
&) {
238
// empty!
239
}
240
241
// get the actual change method of *this
242
template
<
typename
GUM_SCALAR
>
243
INLINE
bool
MultiDimImplementation
<
GUM_SCALAR
>::
isInMultipleChangeMethod_
()
const
{
244
return
(
_internalChangeMethod_
==
_InternalChangeMethod_
::
MULTIPLE_CHANGE
);
245
}
246
247
// get the actual state of *this
248
template
<
typename
GUM_SCALAR
>
249
INLINE
bool
MultiDimImplementation
<
GUM_SCALAR
>::
isCommitNeeded_
()
const
{
250
return
(
_internalChangeState_
==
_InternalChangeState_
::
NOT_COMMITTED_CHANGE
);
251
}
252
253
// Returns a constant reference over the list of slaved instantiations.
254
template
<
typename
GUM_SCALAR
>
255
INLINE
const
List
<
Instantiation
* >&
MultiDimImplementation
<
GUM_SCALAR
>::
slaves_
()
const
{
256
return
_slaveInstantiations_
;
257
}
258
259
// get the actual state of *this
260
template
<
typename
GUM_SCALAR
>
261
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
_setNotCommitedChange_
() {
262
_internalChangeState_
=
_InternalChangeState_
::
NOT_COMMITTED_CHANGE
;
263
}
264
265
// get the actual state of *this
266
template
<
typename
GUM_SCALAR
>
267
INLINE
float
MultiDimImplementation
<
GUM_SCALAR
>::
compressionRate
()
const
{
268
return
((
float
)1) - (
float
)
realSize
() / (
float
)
domainSize
();
269
}
270
271
// returns a basename to be used for default operators
272
template
<
typename
GUM_SCALAR
>
273
const
std
::
string
&
MultiDimImplementation
<
GUM_SCALAR
>::
basename
()
const
{
274
static
const
std
::
string
str
=
"MultiDimImplementation"
;
275
return
str
;
276
}
277
278
template
<
typename
GUM_SCALAR
>
279
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
replace_
(
const
DiscreteVariable
*
x
,
280
const
DiscreteVariable
*
y
) {
281
_vars_
.
setAtPos
(
_vars_
.
pos
(
x
),
y
);
282
283
for
(
List
<
Instantiation
* >::
iterator_safe
iter
=
_slaveInstantiations_
.
beginSafe
();
284
iter
!=
_slaveInstantiations_
.
endSafe
();
285
++
iter
) {
286
(**
iter
).
replace
(*
x
, *
y
);
287
}
288
}
289
290
template
<
typename
GUM_SCALAR
>
291
INLINE
void
MultiDimImplementation
<
GUM_SCALAR
>::
invert_
(
Idx
p1
,
Idx
p2
) {
292
_vars_
.
swap
(
p1
,
p2
);
293
}
294
295
// for friendly displaying the content of the array
296
template
<
typename
GUM_SCALAR
>
297
INLINE
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
298
const
MultiDimImplementation
<
GUM_SCALAR
>&
array
) {
299
return
out
<<
static_cast
<
const
MultiDimContainer
<
GUM_SCALAR
>& >(
array
);
300
}
301
302
303
// protected access to content_
304
template
<
typename
GUM_SCALAR
>
305
INLINE
MultiDimImplementation
<
GUM_SCALAR
>*
MultiDimImplementation
<
GUM_SCALAR
>::
content
() {
306
return
this
;
307
}
308
309
// protected access to content_
310
template
<
typename
GUM_SCALAR
>
311
INLINE
const
MultiDimImplementation
<
GUM_SCALAR
>*
312
MultiDimImplementation
<
GUM_SCALAR
>::
content
()
const
{
313
return
this
;
314
}
315
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643