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