aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
instantiation.cpp
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::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
) :
_master_
(0),
_overflow_
(
false
) {
68
// for debugging purposes
69
GUM_CONSTRUCTOR
(
Instantiation
);
70
_init_
(&
d
);
71
}
72
73
Instantiation
::
Instantiation
(
const
MultiDimAdressable
&
d
) :
_master_
(0),
_overflow_
(
false
) {
74
// for debugging purposes
75
GUM_CONSTRUCTOR
(
Instantiation
);
76
_init_
(
const_cast
<
MultiDimAdressable
* >(&
d
));
77
}
78
79
// constructor for a Instantiation contained into a MultiDimInterface
80
Instantiation
::
Instantiation
(
MultiDimAdressable
*
d
) :
_master_
(0),
_overflow_
(
false
) {
81
// for debugging purposes
82
GUM_CONSTRUCTOR
(
Instantiation
);
83
84
if
(
d
)
_init_
(
d
);
85
}
86
87
// constructor for a Instantiation contained into a MultiDimInterface this
88
// constructor is needed in order to allow creation of Instantiation(this) in
89
// MultiDimAdressable and below
90
Instantiation
::
Instantiation
(
const
MultiDimAdressable
*
const_d
) :
_master_
(0),
_overflow_
(
false
) {
91
// for debugging purposes
92
GUM_CONSTRUCTOR
(
Instantiation
);
93
94
if
(
const_d
)
_init_
(
const_cast
<
MultiDimAdressable
* >(
const_d
));
95
}
96
97
// copy constructor
98
Instantiation
::
Instantiation
(
const
Instantiation
&
aI
,
const
bool
notifyMaster
) :
99
MultiDimInterface
(),
_master_
(0),
_overflow_
(
false
) {
100
// for debugging purposes
101
GUM_CONS_CPY
(
Instantiation
);
102
// copy the content of aI
103
_vars_
=
aI
.
_vars_
;
104
_vals_
=
aI
.
_vals_
;
105
_overflow_
=
aI
.
_overflow_
;
106
107
if
(
aI
.
_master_
&&
notifyMaster
)
actAsSlave
(*
aI
.
_master_
);
108
}
109
110
// operator=
111
Instantiation
&
Instantiation
::
operator
=(
const
Instantiation
&
aI
) {
112
if
(
_master_
) {
113
if
(!
aI
.
isMaster
(
_master_
)) {
// aI as the same master.
114
if
(
nbrDim
() !=
aI
.
nbrDim
()) {
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
) }
115
116
for
(
Idx
i
= 0;
i
<
nbrDim
();
i
++) {
117
if
((!
contains
(
aI
.
variable
(
i
))) || (!
aI
.
contains
(
variable
(
i
)))) {
118
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
)
119
}
120
}
121
}
122
123
setVals
(
aI
);
124
}
else
{
125
// copy the content of aI
126
_vars_
=
aI
.
_vars_
;
127
_vals_
=
aI
.
_vals_
;
128
_overflow_
=
aI
.
_overflow_
;
129
130
if
(
aI
.
_master_
)
actAsSlave
(*
aI
.
_master_
);
131
}
132
133
return
*
this
;
134
}
135
136
// Gives a string version of a Instantiation
137
std
::
string
Instantiation
::
toString
()
const
{
138
std
::
stringstream
sstr
;
139
// check if the value of the instantiation is correct
140
141
if
(
_overflow_
) {
sstr
<<
"<invalid>"
; }
142
143
sstr
<<
"<"
;
144
145
bool
first
=
true
;
146
147
for
(
const
auto
var
:
_vars_
) {
148
if
(!
first
)
sstr
<<
"|"
;
149
150
first
=
false
;
151
sstr
<<
var
->
name
() <<
":"
<<
var
->
label
(
val
(*
var
));
152
}
153
154
sstr
<<
">"
;
155
156
return
sstr
.
str
();
157
}
158
159
// give a Id value for Hamming distance
160
Idx
Instantiation
::
hamming
()
const
{
161
Idx
res
= 0;
162
163
for
(
const
auto
var
:
_vars_
)
164
res
+=
val
(*
var
);
165
166
return
res
;
167
}
168
169
void
Instantiation
::
setValsFrom
(
170
const
HashTable
<
const
DiscreteVariable
*,
const
DiscreteVariable
* >&
map
,
171
const
Instantiation
&
external
) {
172
for
(
const
auto
&
elt
:
map
) {
173
const
DiscreteVariable
&
var
= *
elt
.
second
;
174
175
try
{
176
Idx
val
=
external
.
val
(*
elt
.
first
);
177
178
try
{
179
chgVal
(
var
,
val
);
180
}
catch
(
NotFound
&) {
181
GUM_ERROR
(
NotFound
,
var
.
name
() <<
" : missing variable in instantiation"
)
182
}
183
}
catch
(
NotFound
&) {
184
GUM_ERROR
(
NotFound
,
var
.
name
() <<
" : missing variable in external instantiation"
)
185
}
186
}
187
}
188
189
void
Instantiation
::
_masterChangeNotification_
(
Idx
varPos
,
Idx
newVal
,
Idx
oldVal
)
const
{
190
if
(
_master_
)
_master_
->
changeNotification
(*
this
,
_vars_
[
varPos
],
oldVal
,
newVal
);
191
}
192
193
void
Instantiation
::
_masterFirstNotification_
()
const
{
194
if
(
_master_
)
_master_
->
setFirstNotification
(*
this
);
195
}
196
197
void
Instantiation
::
_masterIncNotification_
()
const
{
198
if
(
_master_
)
_master_
->
setIncNotification
(*
this
);
199
}
200
void
Instantiation
::
_masterLastNotification_
()
const
{
201
if
(
_master_
)
_master_
->
setLastNotification
(*
this
);
202
}
203
void
Instantiation
::
_masterDecNotification_
()
const
{
204
if
(
_master_
)
_master_
->
setDecNotification
(*
this
);
205
}
206
207
// deassociate the master MultiDimAdressable, if any
208
bool
Instantiation
::
forgetMaster
() {
209
if
(
_master_
) {
210
_master_
->
unregisterSlave
(*
this
);
211
_master_
=
nullptr
;
212
}
213
return
true
;
214
}
215
// force the variables sequence order to be the same as the master one
216
void
Instantiation
::
synchronizeWithMaster
(
const
MultiDimAdressable
*
m
) {
217
if
(
m
!=
_master_
) {
GUM_ERROR
(
OperationNotAllowed
,
"only master can do this"
) }
218
219
_reorder_
(
_master_
->
variablesSequence
());
220
}
221
// erase new dim by master
222
void
Instantiation
::
eraseWithMaster
(
const
MultiDimAdressable
*
m
,
const
DiscreteVariable
&
v
) {
223
if
(
m
!=
_master_
) {
GUM_ERROR
(
OperationNotAllowed
,
"only master can do this"
) }
224
225
_erase_
(
v
);
226
227
if
(
_master_
)
_master_
->
setChangeNotification
(*
this
);
228
}
229
230
// tries to register the Instantiation to a MultiDimAdressable
231
bool
Instantiation
::
actAsSlave
(
MultiDimAdressable
&
aMD
) {
232
// if _master_ : not allowed
233
if
(
_master_
!=
nullptr
) {
GUM_ERROR
(
OperationNotAllowed
,
"in slave Instantiation"
) }
234
235
_master_
= &
aMD
;
236
237
// perform the registration
238
if
(
aMD
.
registerSlave
(*
this
)) {
239
return
true
;
240
}
else
{
241
_master_
=
nullptr
;
242
return
false
;
243
}
244
}
245
246
// an operator for user-friendly displaying the content of a Instantiation
247
std
::
ostream
&
operator
<<(
std
::
ostream
&
aStream
,
const
Instantiation
&
i
) {
248
aStream << i.toString();
249
return
aStream;
250
}
251
252
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643
gum::operator<<
std::ostream & operator<<(std::ostream &aStream, const Instantiation &i)
Print information of the instantiation in the stream.
Definition:
instantiation.cpp:247