aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
multiDimWithOffset_tpl.h
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 Headers of the MultiDimWithOffset class.
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
27  */
28 
29 #include <limits>
30 
31 // to ease IDE parsers...
32 #include <agrum/tools/multidim/implementations/multiDimImplementation.h>
33 #include <agrum/tools/multidim/implementations/multiDimWithOffset.h>
34 
35 namespace gum {
36 
37  // Default constructor: creates an empty null dimensional matrix
38 
39  template < typename GUM_SCALAR >
40  MultiDimWithOffset< GUM_SCALAR >::MultiDimWithOffset() :
41  MultiDimImplementation< GUM_SCALAR >() {
42  // for debugging purposes
43  GUM_CONSTRUCTOR(MultiDimWithOffset);
44  }
45 
46  // copy constructor
47 
48  template < typename GUM_SCALAR >
52  gaps_(from.gaps_) {
53  // for debugging purposes
55  }
56 
57  // destructor
58 
59  template < typename GUM_SCALAR >
61  // for debugging purposes
63  // no need to unregister all slaves as it will be done by
64  // MultiDimImplementation
65  }
66 
67  // add a new dimension, needed for updating the offsets_ & gaps_
68 
69  template < typename GUM_SCALAR >
71  Size lg = this->domainSize();
72 
73  if (lg > std::numeric_limits< Idx >::max() / v.domainSize()) {
74  GUM_ERROR(OutOfBounds, "Out of bounds !");
75  }
76 
78  gaps_.insert(&v, lg);
79  }
80 
81  // removes a dimension, needed for updating the offsets_ & gaps_
82 
83  template < typename GUM_SCALAR >
86  Idx pos = variables.pos(&v); // throw a NotFound if necessary
87 
88  if (variables.size() == 1) {
89  gaps_.clear();
90  } else {
91  // update the gaps_
92  Size v_size = v.domainSize();
94 
95  for (Idx i = pos + 1; i < variables.size(); ++i) {
96  gaps_[variables[i]] /= v_size;
97  }
98  }
99 
101  }
102 
103  // listen to change in each recorded Instantiation.
104 
105  template < typename GUM_SCALAR >
107  const Instantiation& i,
108  const DiscreteVariable* const var,
109  Idx oldval,
110  Idx newval) {
112  GUM_ASSERT(offsets_[&i] < this->domainSize());
115 
116  if (newval >= oldval) {
117  offsets_[&i] += gaps_[var] * (newval - oldval);
118  GUM_ASSERT(offsets_[&i] < this->domainSize());
119  } else {
120  GUM_ASSERT(offsets_[&i] >= gaps_[var] * (oldval - newval));
121  offsets_[&i] -= gaps_[var] * (oldval - newval);
122  }
123  }
124 
125  // listen to an assignment of a value in a Instantiation
126 
127  template < typename GUM_SCALAR >
129  const Instantiation& i) {
131  offsets_[&i] = getOffs_(i);
132  }
133 
134  // listen to setFirst in each recorded Instantiation.
135 
136  template < typename GUM_SCALAR >
138  const Instantiation& i) {
140  offsets_[&i] = 0;
141  }
142 
143  // listen to setLast in each recorded Instantiation.
144 
145  template < typename GUM_SCALAR >
147  const Instantiation& i) {
149  offsets_[&i] = this->domainSize() - 1;
150  }
151 
152  // listen to increment in each recorded Instantiation.
153 
154  template < typename GUM_SCALAR >
155  INLINE void
158  GUM_ASSERT(offsets_[&i] != this->domainSize() - 1);
159  ++offsets_[&i];
160  }
161 
162  // listen to increment in each recorded Instantiation.
163 
164  template < typename GUM_SCALAR >
165  INLINE void
168  GUM_ASSERT(offsets_[&i] != 0);
169  --offsets_[&i];
170  }
171 
172  // add a Instantiation as a slave
173 
174  template < typename GUM_SCALAR >
178  offsets_.insert(&i, getOffs_(i));
179  return true;
180  }
181 
182  return false;
183  }
184 
185  // remove a registered slave instantiation
186 
187  template < typename GUM_SCALAR >
190  offsets_.erase(&i);
191  return true;
192  }
193 
194  // Compute the offset of a Instantiation
195  /** If the instantiation is not fully compatible with the MultiDimWithOffset,
196  * no exception thrown
197  * but 0 is assumed for dimensions not present in the instantiation.
198  * for instance : M<<a<<b<<c; with i=b:1|c:2|d:1 then M.getOffs_(i) give the
199  * offset of a:0|b:1|c:2.
200  */
201 
202  template < typename GUM_SCALAR >
203  INLINE Size
205  Idx off = 0;
206 
208  = gaps_.beginSafe();
209  iter != gaps_.endSafe();
210  ++iter)
211  if (i.contains(iter.key()))
212  off += iter.val() * i.valFromPtr(iter.key());
213  else
215  iter.key()->name() << " not present in the instantiation " << i);
216 
217  return off;
218  }
219 
220  // For a given indice of a value in the vector values_, this method computes
221  // the corresponding instantiation
222  /**
223  * @param result the result of this methods, we assume that the given
224  * instantiation already contains all the variables
225  * contained in the multidimarray (if V is the set of variables
226  * of this tab, V must be a subset of variables in
227  * result or the exact set)
228  * @param indice indice in the vector values_
229  */
230 
231  template < typename GUM_SCALAR >
234  Size indice) const {
235  for (Idx i = 0; i < this->nbrDim(); ++i) {
236  const DiscreteVariable& var = this->variable(i);
240  }
241 
242  GUM_ASSERT(indice == 0);
243  }
244 
245  // string representation of internal data about i in this.
246  template < typename GUM_SCALAR >
247  INLINE std::string
249  if (i->isMaster(this)) {
250  std::stringstream s;
251  s << offsets_[i];
252  std::string res;
253  s >> res;
254  return res;
255  } else {
256  return "--";
257  }
258  }
259 
260  template < typename GUM_SCALAR >
261  INLINE Size
263  return getOffs_(i);
264  }
265 
266  // set the Instantiation to the values corresponding to the offset (in this
267  // array)
268  template < typename GUM_SCALAR >
271  Size offset) const {
273  return i;
274  }
275 
276 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669