aGrUM
0.20.3
a C++ library for (probabilistic) graphical models
multiDimArray_tpl.h
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 the MultiDimArray class.
25
*
26
* @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27
*/
28
29
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimArray
.
h
>
30
#
include
<
agrum
/
tools
/
multidim
/
implementations
/
multiDimWithOffset
.
h
>
31
32
namespace
gum
{
33
34
// Default constructor: creates an empty null dimensional matrix
35
template
<
typename
GUM_SCALAR >
36
MultiDimArray< GUM_SCALAR >::MultiDimArray() : MultiDimWithOffset< GUM_SCALAR >() {
37
// for debugging purposes
38
GUM_CONSTRUCTOR(MultiDimArray);
39
}
40
41
// copy constructor
42
template
<
typename
GUM_SCALAR
>
43
MultiDimArray
<
GUM_SCALAR
>::
MultiDimArray
(
const
MultiDimArray
<
GUM_SCALAR
>&
src
) :
44
MultiDimWithOffset
<
GUM_SCALAR
>(
src
),
values_
(
src
.
values_
) {
45
// for debugging purposes
46
GUM_CONS_CPY
(
MultiDimArray
);
47
}
48
49
// destructor
50
template
<
typename
GUM_SCALAR
>
51
MultiDimArray
<
GUM_SCALAR
>::~
MultiDimArray
() {
52
// for debugging purposes
53
GUM_DESTRUCTOR
(
MultiDimArray
);
54
// no need to unregister all slaves as it will be done by MultiDimWithOffset
55
}
56
57
template
<
typename
GUM_SCALAR
>
58
void
MultiDimArray
<
GUM_SCALAR
>::
copyFrom
(
const
MultiDimContainer
<
GUM_SCALAR
>&
src
)
const
{
59
auto
mda
=
dynamic_cast
<
const
MultiDimArray
<
GUM_SCALAR
>* >(&
src
);
60
61
if
(
mda
==
nullptr
) {
62
MultiDimContainer
<
GUM_SCALAR
>::
copyFrom
(
src
);
63
}
else
{
64
values_
=
mda
->
values_
;
65
}
66
}
67
68
template
<
typename
GUM_SCALAR
>
69
void
MultiDimArray
<
GUM_SCALAR
>::
apply
(
std
::
function
<
GUM_SCALAR
(
GUM_SCALAR
) >
f
)
const
{
70
std
::
transform
(
values_
.
begin
(),
values_
.
end
(),
values_
.
begin
(),
f
);
71
}
72
73
template
<
typename
GUM_SCALAR
>
74
GUM_SCALAR
75
MultiDimArray
<
GUM_SCALAR
>::
reduce
(
std
::
function
<
GUM_SCALAR
(
GUM_SCALAR
,
GUM_SCALAR
) >
f
,
76
GUM_SCALAR
base
)
const
{
77
return
std
::
accumulate
(
values_
.
begin
(),
values_
.
end
(),
base
,
f
);
78
}
79
80
81
// data access operator
82
template
<
typename
GUM_SCALAR
>
83
INLINE
GUM_SCALAR
&
MultiDimArray
<
GUM_SCALAR
>::
get_
(
const
Instantiation
&
i
)
const
{
84
if
(
i
.
isMaster
(
this
)) {
85
return
values_
[
this
->
offsets_
[&
i
]];
86
}
else
{
87
return
values_
[
this
->
getOffs_
(
i
)];
88
}
89
}
90
91
// add a new dimension, needed for updating the offsets_ & gaps_
92
template
<
typename
GUM_SCALAR
>
93
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
add
(
const
DiscreteVariable
&
v
) {
94
Size
lg
=
MultiDimWithOffset
<
GUM_SCALAR
>::
domainSize
();
95
MultiDimWithOffset
<
GUM_SCALAR
>::
add
(
v
);
96
97
if
(!
this
->
isInMultipleChangeMethod_
()) {
values_
.
resize
(
lg
*
v
.
domainSize
()); }
98
}
99
100
// removes a dimension, needed for updating the offsets_ & gaps_
101
template
<
typename
GUM_SCALAR
>
102
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
erase
(
const
DiscreteVariable
&
v
) {
103
Sequence
<
const
DiscreteVariable
* >
variables
=
this
->
variablesSequence
();
104
Idx
pos
=
variables
.
pos
(&
v
);
// throw a NotFound if necessary
105
106
if
(
variables
.
size
() == 1) {
107
if
(!
this
->
isInMultipleChangeMethod_
())
values_
.
clear
();
108
}
else
{
109
Size
v_size
=
v
.
domainSize
();
110
Size
size
=
this
->
domainSize
();
111
// here, the variable does belong to the array.
112
// => if pos = variables.size() - 1 then we just have to extract the
113
// beginning of the array (actually the first gap of variable v)
114
// if pos = 0, then copy every element whose index is a multiple of |v|
115
// Assume now that pos != 0 and pos != variables.size() - 1, then
116
// let w be the next variable in the set of variables of the array.
117
// Then we must copy |gap(v)| elements every |gap(w)| elements
118
119
if
(!
this
->
isInMultipleChangeMethod_
()) {
120
if
(
pos
!=
variables
.
size
() - 1) {
121
Size
gap_v
=
this
->
gaps_
[
variables
[
pos
]];
122
Size
gap_w
=
this
->
gaps_
[
variables
[
pos
+ 1]];
123
124
for
(
Idx
i
= 0,
j
= 0;
i
<
size
;
i
+=
gap_w
) {
125
Idx
last
=
i
+
gap_v
;
126
127
for
(
Idx
k
=
i
;
k
<
last
; ++
k
, ++
j
)
128
values_
[
j
] =
values_
[
k
];
129
}
130
}
131
132
// shrink values_
133
values_
.
resize
(
size
/
v_size
);
134
}
135
}
136
137
MultiDimWithOffset
<
GUM_SCALAR
>::
erase
(
v
);
138
}
139
140
template
<
typename
GUM_SCALAR
>
141
INLINE
Size
MultiDimArray
<
GUM_SCALAR
>::
realSize
()
const
{
142
return
this
->
domainSize
();
143
}
144
145
// synchronise content after MultipleChanges
146
template
<
typename
GUM_SCALAR
>
147
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
commitMultipleChanges_
() {
148
if
(
MultiDimWithOffset
<
GUM_SCALAR
>::
domainSize
() !=
values_
.
size
()) {
149
values_
.
resize
(
MultiDimWithOffset
<
GUM_SCALAR
>::
domainSize
());
150
}
151
}
152
153
// synchronise content after MultipleChanges
154
template
<
typename
GUM_SCALAR
>
155
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
commitMultipleChanges_
(
const
GUM_SCALAR
&
x
) {
156
if
(
MultiDimWithOffset
<
GUM_SCALAR
>::
domainSize
() !=
values_
.
size
()) {
157
values_
.
resize
(
MultiDimWithOffset
<
GUM_SCALAR
>::
domainSize
(),
x
);
158
}
159
}
160
161
// fill the array with the arg
162
template
<
typename
GUM_SCALAR
>
163
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
fill
(
const
GUM_SCALAR
&
d
)
const
{
164
if
(!
this
->
empty
())
std
::
fill
(
values_
.
begin
(),
values_
.
end
(),
d
);
165
}
166
167
// virtual constructor
168
template
<
typename
GUM_SCALAR
>
169
INLINE
MultiDimContainer
<
GUM_SCALAR
>*
MultiDimArray
<
GUM_SCALAR
>::
newFactory
()
const
{
170
return
new
MultiDimArray
<
GUM_SCALAR
>;
171
}
172
173
// returns the element stored in the multidimArray at a given offset
174
template
<
typename
GUM_SCALAR
>
175
INLINE
const
GUM_SCALAR
&
MultiDimArray
<
GUM_SCALAR
>::
unsafeGet
(
Idx
offset
)
const
{
176
return
values_
[
offset
];
177
}
178
179
template
<
typename
GUM_SCALAR
>
180
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
unsafeSet
(
Idx
offset
,
const
GUM_SCALAR
&
data
) {
181
values_
[
offset
] =
data
;
182
}
183
184
// returns the element stored in the multidimArray at a given offset
185
template
<
typename
GUM_SCALAR
>
186
INLINE
const
GUM_SCALAR
&
MultiDimArray
<
GUM_SCALAR
>::
getByOffset
(
Idx
offset
)
const
{
187
if
(
offset
>=
values_
.
size
()) {
GUM_ERROR
(
OutOfBounds
,
"offset too large"
) }
188
189
return
values_
[
offset
];
190
}
191
192
template
<
typename
GUM_SCALAR
>
193
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
setByOffset
(
Idx
offset
,
const
GUM_SCALAR
&
data
) {
194
if
(
offset
>=
values_
.
size
()) {
GUM_ERROR
(
OutOfBounds
,
"offset too large"
) }
195
196
values_
[
offset
] =
data
;
197
}
198
199
// returns the name of the implementation
200
template
<
typename
GUM_SCALAR
>
201
INLINE
const
std
::
string
&
MultiDimArray
<
GUM_SCALAR
>::
name
()
const
{
202
static
const
std
::
string
str
=
"MultiDimArray"
;
203
return
str
;
204
}
205
206
template
<
typename
GUM_SCALAR
>
207
INLINE
void
MultiDimArray
<
GUM_SCALAR
>::
replace_
(
const
DiscreteVariable
*
x
,
208
const
DiscreteVariable
*
y
) {
209
MultiDimImplementation
<
GUM_SCALAR
>::
replace_
(
x
,
y
);
210
}
211
}
/* namespace gum */
gum::Set::emplace
INLINE void emplace(Args &&... args)
Definition:
set_tpl.h:643