aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
multiDimWithOffset_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 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() : MultiDimImplementation< GUM_SCALAR >() {
41  // for debugging purposes
42  GUM_CONSTRUCTOR(MultiDimWithOffset);
43  }
44 
45  // copy constructor
46 
47  template < typename GUM_SCALAR >
51  gaps_(from.gaps_) {
52  // for debugging purposes
54  }
55 
56  // destructor
57 
58  template < typename GUM_SCALAR >
60  // for debugging purposes
62  // no need to unregister all slaves as it will be done by
63  // MultiDimImplementation
64  }
65 
66  // add a new dimension, needed for updating the offsets_ & gaps_
67 
68  template < typename GUM_SCALAR >
70  Size lg = this->domainSize();
71 
72  if (lg > std::numeric_limits< Idx >::max() / v.domainSize()) {
73  GUM_ERROR(OutOfBounds, "Out of bounds !")
74  }
75 
77  gaps_.insert(&v, lg);
78  }
79 
80  // removes a dimension, needed for updating the offsets_ & gaps_
81 
82  template < typename GUM_SCALAR >
85  Idx pos = variables.pos(&v); // throw a NotFound if necessary
86 
87  if (variables.size() == 1) {
88  gaps_.clear();
89  } else {
90  // update the gaps_
91  Size v_size = v.domainSize();
93 
94  for (Idx i = pos + 1; i < variables.size(); ++i) {
95  gaps_[variables[i]] /= v_size;
96  }
97  }
98 
100  }
101 
102  // listen to change in each recorded Instantiation.
103 
104  template < typename GUM_SCALAR >
105  INLINE void
107  const DiscreteVariable* const var,
108  Idx oldval,
109  Idx newval) {
111  GUM_ASSERT(offsets_[&i] < this->domainSize());
114 
115  if (newval >= oldval) {
116  offsets_[&i] += gaps_[var] * (newval - oldval);
117  GUM_ASSERT(offsets_[&i] < this->domainSize());
118  } else {
119  GUM_ASSERT(offsets_[&i] >= gaps_[var] * (oldval - newval));
120  offsets_[&i] -= gaps_[var] * (oldval - newval);
121  }
122  }
123 
124  // listen to an assignment of a value in a Instantiation
125 
126  template < typename GUM_SCALAR >
129  offsets_[&i] = getOffs_(i);
130  }
131 
132  // listen to setFirst in each recorded Instantiation.
133 
134  template < typename GUM_SCALAR >
137  offsets_[&i] = 0;
138  }
139 
140  // listen to setLast in each recorded Instantiation.
141 
142  template < typename GUM_SCALAR >
145  offsets_[&i] = this->domainSize() - 1;
146  }
147 
148  // listen to increment in each recorded Instantiation.
149 
150  template < typename GUM_SCALAR >
153  GUM_ASSERT(offsets_[&i] != this->domainSize() - 1);
154  ++offsets_[&i];
155  }
156 
157  // listen to increment in each recorded Instantiation.
158 
159  template < typename GUM_SCALAR >
162  GUM_ASSERT(offsets_[&i] != 0);
163  --offsets_[&i];
164  }
165 
166  // add a Instantiation as a slave
167 
168  template < typename GUM_SCALAR >
172  offsets_.insert(&i, getOffs_(i));
173  return true;
174  }
175 
176  return false;
177  }
178 
179  // remove a registered slave instantiation
180 
181  template < typename GUM_SCALAR >
184  offsets_.erase(&i);
185  return true;
186  }
187 
188  // Compute the offset of a Instantiation
189  /** If the instantiation is not fully compatible with the MultiDimWithOffset,
190  * no exception thrown
191  * but 0 is assumed for dimensions not present in the instantiation.
192  * for instance : M<<a<<b<<c; with i=b:1|c:2|d:1 then M.getOffs_(i) give the
193  * offset of a:0|b:1|c:2.
194  */
195 
196  template < typename GUM_SCALAR >
198  Idx off = 0;
199 
201  iter != gaps_.endSafe();
202  ++iter)
203  if (i.contains(iter.key()))
204  off += iter.val() * i.valFromPtr(iter.key());
205  else
206  GUM_ERROR(InvalidArgument, iter.key()->name() << " not present in the instantiation " << i)
207 
208  return off;
209  }
210 
211  // For a given indice of a value in the vector values_, this method computes
212  // the corresponding instantiation
213  /**
214  * @param result the result of this methods, we assume that the given
215  * instantiation already contains all the variables
216  * contained in the multidimarray (if V is the set of variables
217  * of this tab, V must be a subset of variables in
218  * result or the exact set)
219  * @param indice indice in the vector values_
220  */
221 
222  template < typename GUM_SCALAR >
224  Size indice) const {
225  for (Idx i = 0; i < this->nbrDim(); ++i) {
226  const DiscreteVariable& var = this->variable(i);
230  }
231 
232  GUM_ASSERT(indice == 0);
233  }
234 
235  // string representation of internal data about i in this.
236  template < typename GUM_SCALAR >
238  if (i->isMaster(this)) {
239  std::stringstream s;
240  s << offsets_[i];
241  std::string res;
242  s >> res;
243  return res;
244  } else {
245  return "--";
246  }
247  }
248 
249  template < typename GUM_SCALAR >
251  return getOffs_(i);
252  }
253 
254  // set the Instantiation to the values corresponding to the offset (in this
255  // array)
256  template < typename GUM_SCALAR >
258  Size offset) const {
260  return i;
261  }
262 
263 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643