aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
multiDimContainer_tpl.h
Go to the documentation of this file.
1
/**
2
*
3
* Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) et Christophe GONZALES(@AMU)
4
* (@AMU) 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 the MultiDimContainer class.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
*/
28
29
#
include
<
agrum
/
agrum
.
h
>
30
#
include
<
algorithm
>
31
32
33
namespace
gum
{
34
35
template
<
typename
GUM_SCALAR >
36
INLINE MultiDimContainer<
GUM_SCALAR
>::
MultiDimContainer
(
37
MultiDimContainer
<
GUM_SCALAR
>&&
from
) :
38
MultiDimAdressable
(
std
::
forward
<
MultiDimAdressable
>(
from
)) {
39
GUM_CONS_MOV
(
MultiDimContainer
);
40
}
41
42
// Default constructor
43
template
<
typename
GUM_SCALAR
>
44
INLINE
MultiDimContainer
<
GUM_SCALAR
>::
MultiDimContainer
() :
45
MultiDimAdressable
() {
46
GUM_CONSTRUCTOR
(
MultiDimContainer
);
47
}
48
49
// Copy constructor
50
template
<
typename
GUM_SCALAR
>
51
INLINE
MultiDimContainer
<
GUM_SCALAR
>::
MultiDimContainer
(
52
const
MultiDimContainer
<
GUM_SCALAR
>&
src
) :
53
MultiDimAdressable
(
src
) {
54
GUM_CONS_CPY
(
MultiDimContainer
);
55
}
56
template
<
typename
GUM_SCALAR
>
57
INLINE
MultiDimContainer
<
GUM_SCALAR
>&
58
MultiDimContainer
<
GUM_SCALAR
>::
operator
=(
59
const
MultiDimContainer
<
GUM_SCALAR
>&
from
) {
60
MultiDimAdressable
::
operator
=(
from
);
61
return
*
this
;
62
}
63
template
<
typename
GUM_SCALAR
>
64
INLINE
MultiDimContainer
<
GUM_SCALAR
>&
65
MultiDimContainer
<
GUM_SCALAR
>::
operator
=(
66
MultiDimContainer
<
GUM_SCALAR
>&&
from
) {
67
GUM_OP_MOV
(
MultiDimContainer
);
68
MultiDimAdressable
::
operator
=(
std
::
forward
<
MultiDimAdressable
>(
from
));
69
return
*
this
;
70
}
71
72
// destructor
73
74
template
<
typename
GUM_SCALAR
>
75
INLINE
MultiDimContainer
<
GUM_SCALAR
>::~
MultiDimContainer
() {
76
GUM_DESTRUCTOR
(
MultiDimContainer
);
77
}
78
79
// an [] operator using a Instantiation as argument
80
81
template
<
typename
GUM_SCALAR
>
82
INLINE
GUM_SCALAR
83
MultiDimContainer
<
GUM_SCALAR
>::
operator
[](
const
Instantiation
&
i
)
const
{
84
return
get
(
i
);
85
}
86
87
// an [] operator using a Instantiation as argument
88
89
template
<
typename
GUM_SCALAR
>
90
INLINE
void
MultiDimContainer
<
GUM_SCALAR
>::
set
(
const
Instantiation
&
i
,
91
const
GUM_SCALAR
&
value
)
const
{
92
get_
(
i
) =
value
;
93
}
94
95
// an [] operator using a Instantiation as argument
96
97
template
<
typename
GUM_SCALAR
>
98
INLINE
GUM_SCALAR
99
MultiDimContainer
<
GUM_SCALAR
>::
get
(
const
Instantiation
&
i
)
const
{
100
return
get_
(
i
);
101
}
102
103
// display the content of an array
104
105
template
<
typename
GUM_SCALAR
>
106
std
::
string
MultiDimContainer
<
GUM_SCALAR
>::
toString
()
const
{
107
// we create a new instantiation and iterate over it to display the whole
108
// content of the array
109
if
(
this
->
nbrDim
() == 0) {
return
"[]"
; }
110
111
std
::
stringstream
ss
;
112
Instantiation
inst
(
const_cast
<
MultiDimContainer
* >(
this
));
113
114
bool
first
=
true
;
115
116
for
(
inst
.
setFirst
(); !
inst
.
end
(); ++
inst
) {
117
if
(!
first
) {
ss
<<
" /"
; }
118
first
=
false
;
119
120
ss
<<
inst
<<
" :: "
<<
get
(
inst
);
121
}
122
123
return
ss
.
str
();
124
}
125
126
// Test if this potential is equal to p.
127
128
template
<
typename
GUM_SCALAR
>
129
bool
MultiDimContainer
<
GUM_SCALAR
>::
operator
==(
130
const
MultiDimContainer
<
GUM_SCALAR
>&
p
)
const
{
131
if
((
nbrDim
() ==
p
.
nbrDim
()) && (
domainSize
() ==
p
.
domainSize
())) {
132
if
(
nbrDim
() == 0)
return
true
;
133
134
typedef
Sequence
<
const
DiscreteVariable
* >::
const_iterator_safe
135
var_iterator
;
136
137
for
(
var_iterator
iter
=
variablesSequence
().
beginSafe
();
138
iter
!=
variablesSequence
().
endSafe
();
139
++
iter
) {
140
if
(!
p
.
variablesSequence
().
exists
(*
iter
)) {
return
false
; }
141
}
142
}
else
{
143
return
false
;
144
}
145
146
Instantiation
i
(*
this
);
147
148
AlmostDifferent
<
GUM_SCALAR
>
cmp
;
149
150
for
(
i
.
setFirst
(); !
i
.
end
(); ++
i
) {
151
if
(
cmp
(
get
(
i
),
p
.
get
(
i
))) {
return
false
; }
152
}
153
154
return
true
;
155
}
156
157
// Test if this potential is different of p.
158
159
template
<
typename
GUM_SCALAR
>
160
INLINE
bool
MultiDimContainer
<
GUM_SCALAR
>::
operator
!=(
161
const
MultiDimContainer
<
GUM_SCALAR
>&
p
)
const
{
162
return
!
operator
==(
p
);
163
}
164
165
// automation fill with vector.
166
template
<
typename
GUM_SCALAR
>
167
void
MultiDimContainer
<
GUM_SCALAR
>::
populate
(
168
const
std
::
vector
<
GUM_SCALAR
>&
v
)
const
{
169
if
(
domainSize
() !=
v
.
size
()) {
170
GUM_ERROR
(
SizeError
,
171
"Sizes do not match : "
<<
domainSize
() <<
"!="
<<
v
.
size
());
172
}
173
174
Size
cpt
= 0;
175
176
Instantiation
i
(*
this
);
177
178
for
(
i
.
setFirst
(); !
i
.
end
(); ++
i
, ++
cpt
)
179
set
(
i
,
v
[
cpt
]);
180
}
181
182
template
<
typename
GUM_SCALAR
>
183
void
MultiDimContainer
<
GUM_SCALAR
>::
populate
(
184
std
::
initializer_list
<
GUM_SCALAR
>
l
)
const
{
185
if
(
domainSize
() !=
l
.
size
()) {
186
GUM_ERROR
(
SizeError
,
187
"Sizes do not match : "
<<
domainSize
() <<
"!="
<<
l
.
size
());
188
}
189
190
Instantiation
i
(*
this
);
191
// insert all the elements
192
for
(
const
auto
&
elt
:
l
) {
193
set
(
i
,
elt
);
194
++
i
;
195
}
196
}
197
198
template
<
typename
GUM_SCALAR
>
199
void
MultiDimContainer
<
GUM_SCALAR
>::
apply
(
200
std
::
function
<
GUM_SCALAR
(
GUM_SCALAR
) >
f
)
const
{
201
Instantiation
i
(*
this
);
202
for
(
i
.
setFirst
(); !
i
.
end
(); ++
i
) {
203
set
(
i
,
f
(
get
(
i
)));
204
}
205
}
206
207
template
<
typename
GUM_SCALAR
>
208
GUM_SCALAR
MultiDimContainer
<
GUM_SCALAR
>::
reduce
(
209
std
::
function
<
GUM_SCALAR
(
GUM_SCALAR
,
GUM_SCALAR
) >
f
,
210
GUM_SCALAR
base
)
const
{
211
GUM_SCALAR
tmp
=
base
;
212
Instantiation
i
(*
this
);
213
for
(
i
.
setFirst
(); !
i
.
end
(); ++
i
) {
214
tmp
=
f
(
tmp
,
get
(
i
));
215
}
216
return
tmp
;
217
}
218
219
220
template
<
typename
GUM_SCALAR
>
221
void
MultiDimContainer
<
GUM_SCALAR
>::
copyFrom
(
222
const
MultiDimContainer
<
GUM_SCALAR
>&
src
,
223
Instantiation
*
p_i
)
const
{
224
if
(
src
.
domainSize
() !=
domainSize
()) {
225
GUM_ERROR
(
OperationNotAllowed
,
226
"Domain sizes do not fit : "
<<
src
.
domainSize
()
227
<<
"!="
<<
domainSize
());
228
}
229
230
if
(
p_i
==
nullptr
) {
// if null, we just follow the same order
231
Instantiation
i
(
src
);
232
for
(
i
.
setFirst
(); !
i
.
end
(); ++
i
) {
233
set
(
i
,
src
[
i
]);
234
}
235
}
else
{
236
Instantiation
i_dest
(*
this
);
237
Instantiation
i_src
(
src
);
238
for
(
i_dest
.
setFirst
(),
i_src
.
setFirst
(); !
i_dest
.
end
();
239
i_dest
.
incIn
(*
p_i
), ++
i_src
) {
240
set
(
i_dest
,
src
[
i_src
]);
241
}
242
}
243
}
244
245
template
<
typename
GUM_SCALAR
>
246
void
MultiDimContainer
<
GUM_SCALAR
>::
extractFrom
(
247
const
MultiDimContainer
<
GUM_SCALAR
>&
src
,
248
const
Instantiation
&
imask
) {
249
this
->
beginMultipleChanges
();
250
251
Size
nbr
=
this
->
nbrDim
();
252
for
(
Idx
i
= 0;
i
<
nbr
;
i
++) {
253
this
->
erase
(
this
->
variable
(0));
254
}
255
256
for
(
Idx
i
= 0;
i
<
src
.
nbrDim
();
i
++) {
257
if
(!
imask
.
contains
(
src
.
variable
(
i
)))
this
->
add
(
src
.
variable
(
i
));
258
}
259
260
this
->
endMultipleChanges
();
261
262
if
(
this
->
nbrDim
() == 0) {
GUM_ERROR
(
FatalError
,
"Empty potential"
); }
263
264
Instantiation
inst
(
src
);
265
inst
.
setVals
(
imask
);
266
for
(
inst
.
setFirstOut
(
imask
); !
inst
.
end
();
inst
.
incOut
(
imask
))
267
set
(
inst
,
src
[
inst
]);
268
}
269
270
template
<
typename
GUM_SCALAR
>
271
void
MultiDimContainer
<
GUM_SCALAR
>::
copyFrom
(
272
const
MultiDimContainer
<
GUM_SCALAR
>&
src
)
const
{
273
if
(
src
.
domainSize
() !=
domainSize
()) {
274
GUM_ERROR
(
OperationNotAllowed
,
275
"Domain sizes do not fit : "
<<
src
.
domainSize
()
276
<<
"!="
<<
domainSize
());
277
}
278
279
Instantiation
i_dest
(*
this
);
280
Instantiation
i_src
(
src
);
281
282
for
(
i_dest
.
setFirst
(),
i_src
.
setFirst
(); !
i_dest
.
end
(); ++
i_dest
, ++
i_src
) {
283
set
(
i_dest
,
src
[
i_src
]);
284
}
285
}
286
287
// copy
288
289
template
<
typename
GUM_SCALAR
>
290
void
MultiDimContainer
<
GUM_SCALAR
>::
copy
(
291
const
MultiDimContainer
<
GUM_SCALAR
>&
src
) {
292
this
->
beginMultipleChanges
();
293
294
Size
nbr
=
this
->
nbrDim
();
295
296
for
(
Idx
i
= 0;
i
<
nbr
;
i
++) {
297
this
->
erase
(
this
->
variable
(0));
298
}
299
300
for
(
Idx
i
= 0;
i
<
src
.
nbrDim
();
i
++) {
301
this
->
add
(
src
.
variable
(
i
));
302
}
303
304
this
->
endMultipleChanges
();
305
this
->
copyFrom
(
src
);
306
}
307
308
template
<
typename
GUM_SCALAR
>
309
INLINE
MultiDimAdressable
&
MultiDimContainer
<
GUM_SCALAR
>::
getMasterRef
() {
310
return
static_cast
<
MultiDimAdressable
& >(*
content
());
311
}
312
313
template
<
typename
GUM_SCALAR
>
314
INLINE
const
MultiDimAdressable
&
315
MultiDimContainer
<
GUM_SCALAR
>::
getMasterRef
()
const
{
316
return
static_cast
<
const
MultiDimAdressable
& >(*
content
());
317
}
318
319
// display the content of an array
320
321
template
<
typename
GUM_SCALAR
>
322
std
::
ostream
&
operator
<<(
std
::
ostream
&
out
,
323
const
MultiDimContainer
<
GUM_SCALAR
>&
array
) {
324
out
<<
array
.
toString
();
325
return
out
;
326
}
327
328
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669