aGrUM
0.20.2
a C++ library for (probabilistic) graphical models
instantiation.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
/**
23
* @file
24
* @brief Implementation of gum::Instantiation.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
*/
28
29
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimAdressable
.
h
>
30
#
include
<
agrum
/
tools
/
multidim
/
instantiation
.
h
>
31
32
#
ifdef
GUM_NO_INLINE
33
#
include
<
agrum
/
tools
/
multidim
/
instantiation_inl
.
h
>
34
#
endif
/* GUM_NO_INLINE */
35
36
namespace
gum
{
37
38
// Default constructor
39
Instantiation
::
Instantiation
() :
master__
(
nullptr
),
overflow__
(
false
) {
40
GUM_CONSTRUCTOR
(
Instantiation
);
41
}
42
43
// destructor
44
Instantiation
::~
Instantiation
() {
45
GUM_DESTRUCTOR
(
Instantiation
);
46
// unregister the Instantiation from its master__
47
48
if
(
master__
)
master__
->
unregisterSlave
(*
this
);
49
}
50
51
void
Instantiation
::
init__
(
MultiDimAdressable
*
master
) {
52
// for speed issues
53
GUM_ASSERT
(
master
!=
nullptr
);
54
55
const
Sequence
<
const
DiscreteVariable
* >&
v
=
master
->
variablesSequence
();
56
vars__
.
resize
(
v
.
size
());
57
vals__
.
reserve
(
v
.
size
());
58
// fill the instantiation
59
60
for
(
const
auto
var
:
v
)
61
add__
(*
var
);
62
63
actAsSlave
(
master
->
getMasterRef
());
64
}
65
66
// constructor for a Instantiation contained into a MultiDimInterface
67
Instantiation
::
Instantiation
(
MultiDimAdressable
&
d
) :
68
master__
(0),
overflow__
(
false
) {
69
// for debugging purposes
70
GUM_CONSTRUCTOR
(
Instantiation
);
71
init__
(&
d
);
72
}
73
74
Instantiation
::
Instantiation
(
const
MultiDimAdressable
&
d
) :
75
master__
(0),
overflow__
(
false
) {
76
// for debugging purposes
77
GUM_CONSTRUCTOR
(
Instantiation
);
78
init__
(
const_cast
<
MultiDimAdressable
* >(&
d
));
79
}
80
81
// constructor for a Instantiation contained into a MultiDimInterface
82
Instantiation
::
Instantiation
(
MultiDimAdressable
*
d
) :
83
master__
(0),
overflow__
(
false
) {
84
// for debugging purposes
85
GUM_CONSTRUCTOR
(
Instantiation
);
86
87
if
(
d
)
init__
(
d
);
88
}
89
90
// constructor for a Instantiation contained into a MultiDimInterface this
91
// constructor is needed in order to allow creation of Instantiation(this) in
92
// MultiDimAdressable and below
93
Instantiation
::
Instantiation
(
const
MultiDimAdressable
*
const_d
) :
94
master__
(0),
overflow__
(
false
) {
95
// for debugging purposes
96
GUM_CONSTRUCTOR
(
Instantiation
);
97
98
if
(
const_d
)
init__
(
const_cast
<
MultiDimAdressable
* >(
const_d
));
99
}
100
101
// copy constructor
102
Instantiation
::
Instantiation
(
const
Instantiation
&
aI
,
const
bool
notifyMaster
) :
103
MultiDimInterface
(),
master__
(0),
overflow__
(
false
) {
104
// for debugging purposes
105
GUM_CONS_CPY
(
Instantiation
);
106
// copy the content of aI
107
vars__
=
aI
.
vars__
;
108
vals__
=
aI
.
vals__
;
109
overflow__
=
aI
.
overflow__
;
110
111
if
(
aI
.
master__
&&
notifyMaster
)
actAsSlave
(*
aI
.
master__
);
112
}
113
114
// operator=
115
Instantiation
&
Instantiation
::
operator
=(
const
Instantiation
&
aI
) {
116
if
(
master__
) {
117
if
(!
aI
.
isMaster
(
master__
)) {
// aI as the same master.
118
if
(
nbrDim
() !=
aI
.
nbrDim
()) {
119
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
);
120
}
121
122
for
(
Idx
i
= 0;
i
<
nbrDim
();
i
++) {
123
if
((!
contains
(
aI
.
variable
(
i
))) || (!
aI
.
contains
(
variable
(
i
)))) {
124
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
);
125
}
126
}
127
}
128
129
setVals
(
aI
);
130
}
else
{
131
// copy the content of aI
132
vars__
=
aI
.
vars__
;
133
vals__
=
aI
.
vals__
;
134
overflow__
=
aI
.
overflow__
;
135
136
if
(
aI
.
master__
)
actAsSlave
(*
aI
.
master__
);
137
}
138
139
return
*
this
;
140
}
141
142
// Gives a string version of a Instantiation
143
std
::
string
Instantiation
::
toString
()
const
{
144
std
::
stringstream
sstr
;
145
// check if the value of the instantiation is correct
146
147
if
(
overflow__
) {
sstr
<<
"<invalid>"
; }
148
149
sstr
<<
"<"
;
150
151
bool
first
=
true
;
152
153
for
(
const
auto
var
:
vars__
) {
154
if
(!
first
)
sstr
<<
"|"
;
155
156
first
=
false
;
157
sstr
<<
var
->
name
() <<
":"
<<
var
->
label
(
val
(*
var
));
158
}
159
160
sstr
<<
">"
;
161
162
return
sstr
.
str
();
163
}
164
165
// give a Id value for Hamming distance
166
Idx
Instantiation
::
hamming
()
const
{
167
Idx
res
= 0;
168
169
for
(
const
auto
var
:
vars__
)
170
res
+=
val
(*
var
);
171
172
return
res
;
173
}
174
175
void
Instantiation
::
setValsFrom
(
176
const
HashTable
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >&
map
,
177
const
Instantiation
&
external
) {
178
for
(
const
auto
&
elt
:
map
) {
179
const
DiscreteVariable
&
var
= *
elt
.
second
;
180
181
try
{
182
Idx
val
=
external
.
val
(*
elt
.
first
);
183
184
try
{
185
chgVal
(
var
,
val
);
186
}
catch
(
NotFound
&) {
187
GUM_ERROR
(
NotFound
,
188
var
.
name
() <<
" : missing variable in instantiation"
);
189
}
190
}
catch
(
NotFound
&) {
191
GUM_ERROR
(
NotFound
,
192
var
.
name
() <<
" : missing variable in external instantiation"
);
193
}
194
}
195
}
196
197
void
Instantiation
::
masterChangeNotification__
(
Idx
varPos
,
198
Idx
newVal
,
199
Idx
oldVal
)
const
{
200
if
(
master__
)
201
master__
->
changeNotification
(*
this
,
vars__
[
varPos
],
oldVal
,
newVal
);
202
}
203
204
void
Instantiation
::
masterFirstNotification__
()
const
{
205
if
(
master__
)
master__
->
setFirstNotification
(*
this
);
206
}
207
208
void
Instantiation
::
masterIncNotification__
()
const
{
209
if
(
master__
)
master__
->
setIncNotification
(*
this
);
210
}
211
void
Instantiation
::
masterLastNotification__
()
const
{
212
if
(
master__
)
master__
->
setLastNotification
(*
this
);
213
}
214
void
Instantiation
::
masterDecNotification__
()
const
{
215
if
(
master__
)
master__
->
setDecNotification
(*
this
);
216
}
217
218
// deassociate the master MultiDimAdressable, if any
219
bool
Instantiation
::
forgetMaster
() {
220
if
(
master__
) {
221
master__
->
unregisterSlave
(*
this
);
222
master__
=
nullptr
;
223
}
224
return
true
;
225
}
226
// force the variables sequence order to be the same as the master one
227
void
Instantiation
::
synchronizeWithMaster
(
const
MultiDimAdressable
*
m
) {
228
if
(
m
!=
master__
) {
229
GUM_ERROR
(
OperationNotAllowed
,
"only master can do this"
);
230
}
231
232
reorder__
(
master__
->
variablesSequence
());
233
}
234
// erase new dim by master
235
void
Instantiation
::
eraseWithMaster
(
const
MultiDimAdressable
*
m
,
236
const
DiscreteVariable
&
v
) {
237
if
(
m
!=
master__
) {
238
GUM_ERROR
(
OperationNotAllowed
,
"only master can do this"
);
239
}
240
241
erase__
(
v
);
242
243
if
(
master__
)
master__
->
setChangeNotification
(*
this
);
244
}
245
246
// tries to register the Instantiation to a MultiDimAdressable
247
bool
Instantiation
::
actAsSlave
(
MultiDimAdressable
&
aMD
) {
248
// if master__ : not allowed
249
if
(
master__
!=
nullptr
) {
250
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
);
251
}
252
253
master__
= &
aMD
;
254
255
// perform the registration
256
if
(
aMD
.
registerSlave
(*
this
)) {
257
return
true
;
258
}
else
{
259
master__
=
nullptr
;
260
return
false
;
261
}
262
}
263
264
// an operator for user-friendly displaying the content of a Instantiation
265
std
::
ostream
&
operator
<<(
std
::
ostream
&
aStream
,
const
Instantiation
&
i
) {
266
aStream << i.toString();
267
return
aStream;
268
}
269
270
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:669
gum::operator<<
std::ostream & operator<<(std::ostream &aStream, const Instantiation &i)
Print information of the instantiation in the stream.
Definition:
instantiation.cpp:265