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