aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
scheduleMultiDim_tpl.h
Go to the documentation of this file.
1/****************************************************************************
2 * This file is part of the aGrUM/pyAgrum library. *
3 * *
4 * Copyright (c) 2005-2025 by *
5 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
6 * - Christophe GONZALES(_at_AMU) *
7 * *
8 * The aGrUM/pyAgrum library is free software; you can redistribute it *
9 * and/or modify it under the terms of either : *
10 * *
11 * - the GNU Lesser General Public License as published by *
12 * the Free Software Foundation, either version 3 of the License, *
13 * or (at your option) any later version, *
14 * - the MIT license (MIT), *
15 * - or both in dual license, as here. *
16 * *
17 * (see https://agrum.gitlab.io/articles/dual-licenses-lgplv3mit.html) *
18 * *
19 * This aGrUM/pyAgrum library is distributed in the hope that it will be *
20 * useful, but WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
21 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26 * OTHER DEALINGS IN THE SOFTWARE. *
27 * *
28 * See LICENCES for more details. *
29 * *
30 * SPDX-FileCopyrightText: Copyright 2005-2025 *
31 * - Pierre-Henri WUILLEMIN(_at_LIP6) *
32 * - Christophe GONZALES(_at_AMU) *
33 * SPDX-License-Identifier: LGPL-3.0-or-later OR MIT *
34 * *
35 * Contact : info_at_agrum_dot_org *
36 * homepage : http://agrum.gitlab.io *
37 * gitlab : https://gitlab.com/agrumery/agrum *
38 * *
39 ****************************************************************************/
40#pragma once
41
42
48
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
50
51# include <sstream>
52# include <string>
53
55
56namespace gum {
57
58
60 template < typename TABLE >
62 if (_table_contained_ && (_table_ != nullptr)) delete _table_;
63 _table_ = nullptr;
64 }
65
67 template < typename TABLE >
68 ScheduleMultiDim< TABLE >::ScheduleMultiDim(const TABLE& table, const bool copy, const Idx id) :
70 if (copy) {
71 // copy the table
72 _table_ = new TABLE(table);
73 _table_contained_ = true;
74 } else {
75 _table_ = const_cast< TABLE* >(&table);
76 _table_contained_ = false;
77 }
78
79 _var_sequence_ = _table_->variablesSequence();
80 _domain_size_ = _table_->domainSize();
81
82 // for debugging purposes
83 GUM_CONSTRUCTOR(ScheduleMultiDim);
84 }
85
87 template < typename TABLE >
88 ScheduleMultiDim< TABLE >::ScheduleMultiDim(TABLE&& table, const Idx id) : IScheduleMultiDim(id) {
89 // move the table
90 _table_ = new TABLE(std::move(table));
91 _var_sequence_ = _table_->variablesSequence();
92 _domain_size_ = _table_->domainSize();
93
94 // for debugging purposes
95 GUM_CONSTRUCTOR(ScheduleMultiDim);
96 }
97
99 template < typename TABLE >
100 ScheduleMultiDim< TABLE >::ScheduleMultiDim(const Sequence< const DiscreteVariable* >& vars,
101 const Idx id) :
102 IScheduleMultiDim(id), _var_sequence_(vars) {
103 if (!_var_sequence_.empty()) {
104 // compute and store the domain size
105 _domain_size_ = Size(1);
106 for (const auto var: vars)
107 _domain_size_ *= var->domainSize();
108 }
109
110 // for debugging purposes
111 GUM_CONSTRUCTOR(ScheduleMultiDim);
112 }
113
115 template < typename TABLE >
116 ScheduleMultiDim< TABLE >::ScheduleMultiDim(const ScheduleMultiDim< TABLE >& from) :
117 IScheduleMultiDim(from), _table_contained_(from._table_contained_),
118 _var_sequence_(from._var_sequence_), _domain_size_(from._domain_size_) {
119 if (from._table_ != nullptr) {
120 if (from._table_contained_) {
121 // copy the table
122 _table_ = new TABLE(*(from._table_));
123 } else {
124 _table_ = from._table_;
125 }
126 }
127
128 // for debugging purposes
129 GUM_CONS_CPY(ScheduleMultiDim);
130 }
131
133 template < typename TABLE >
134 ScheduleMultiDim< TABLE >::ScheduleMultiDim(ScheduleMultiDim< TABLE >&& from) :
135 IScheduleMultiDim(from), _table_contained_(from._table_contained_),
136 _var_sequence_(from._var_sequence_), _domain_size_(from._domain_size_) {
137 if (from._table_ != nullptr) {
138 _table_ = from._table_;
139 from._table_ = nullptr;
140 }
141
142 // for debugging purposes
143 GUM_CONS_MOV(ScheduleMultiDim);
144 }
145
147 template < typename TABLE >
148 INLINE ScheduleMultiDim< TABLE >* ScheduleMultiDim< TABLE >::clone() const {
149 return new ScheduleMultiDim< TABLE >(*this);
150 }
151
153 template < typename TABLE >
154 ScheduleMultiDim< TABLE >* ScheduleMultiDim< TABLE >::clone(bool force_copy) const {
155 ScheduleMultiDim< TABLE >* new_sched;
156
157 if (!force_copy) new_sched = new ScheduleMultiDim< TABLE >(*this);
158 else {
159 if (!isAbstract()) new_sched = new ScheduleMultiDim< TABLE >(*_table_, true, this->id());
160 else {
161 new_sched = new ScheduleMultiDim< TABLE >(_var_sequence_, this->id());
162 new_sched->_table_contained_ = true;
163 }
164 }
165
166 return new_sched;
167 }
168
170 template < typename TABLE >
171 ScheduleMultiDim< TABLE >::~ScheduleMultiDim() {
172 _removeTable_();
173
174 // for debugging purposes
175 GUM_DESTRUCTOR(ScheduleMultiDim);
176 }
177
179 template < typename TABLE >
180 ScheduleMultiDim< TABLE >&
181 ScheduleMultiDim< TABLE >::operator=(const ScheduleMultiDim< TABLE >& from) {
182 // avoid self assignment
183 if (this != &from) {
184 // assign the table of from
185 if (from._table_ != nullptr) {
186 if (from._table_contained_) {
187 // if the ScheduleMultiDim does not contain its table, then make
188 // _table_ point to nullptr, so that we will allocate it
189 TABLE* old_table = _table_;
190 if (!_table_contained_) _table_ = nullptr;
191
192 if (_table_ == nullptr) {
193 try {
194 _table_ = new TABLE(*(from._table_));
195 } catch (...) {
196 _table_ = old_table;
197 throw;
198 }
199 } else {
200 // here, _table_ is not null and the ScheduleMultiDim contains
201 // it. So we should copy from's table into it.
202 *_table_ = *(from._table_);
203 }
204 _table_contained_ = true;
205 } else {
206 _removeTable_();
207 _table_ = from._table_;
208 _table_contained_ = false;
209 }
210 } else {
211 // here, we should make _table_ point to nullptr
212 _removeTable_();
213 _table_ = nullptr;
214 _table_contained_ = from._table_contained_;
215 }
216
217 _var_sequence_ = from._var_sequence_;
218 _domain_size_ = from._domain_size_;
219 IScheduleMultiDim::operator=(from);
220 }
221
222 return *this;
223 }
224
226 template < typename TABLE >
227 ScheduleMultiDim< TABLE >&
228 ScheduleMultiDim< TABLE >::operator=(ScheduleMultiDim< TABLE >&& from) {
229 // avoid self assignment
230 if (this != &from) {
231 // assign the table of from
232 _removeTable_();
233 _table_ = from._table_;
234 from._table_ = nullptr;
235 _table_contained_ = from._table_contained_;
236
237 _var_sequence_ = from._var_sequence_;
238 _domain_size_ = from._domain_size_;
239 IScheduleMultiDim::operator=(std::move(from));
240 }
241
242 return *this;
243 }
244
246 template < typename TABLE >
247 INLINE bool ScheduleMultiDim< TABLE >::operator==(const ScheduleMultiDim< TABLE >& m) const {
248 return IScheduleMultiDim::operator==(m);
249 }
250
252 template < typename TABLE >
253 bool ScheduleMultiDim< TABLE >::operator==(const IScheduleMultiDim& m) const {
254 try {
255 const ScheduleMultiDim< TABLE >& real_m = dynamic_cast< const ScheduleMultiDim< TABLE >& >(m);
256 return ScheduleMultiDim< TABLE >::operator==(real_m);
257 } catch (std::bad_cast&) { return false; }
258 }
259
261 template < typename TABLE >
262 INLINE bool ScheduleMultiDim< TABLE >::operator!=(const ScheduleMultiDim< TABLE >& m) const {
263 return !ScheduleMultiDim< TABLE >::operator==(m);
264 }
265
267 template < typename TABLE >
268 INLINE bool ScheduleMultiDim< TABLE >::operator!=(const IScheduleMultiDim& m) const {
269 return !ScheduleMultiDim< TABLE >::operator==(m);
270 }
271
273 template < typename TABLE >
274 INLINE bool
275 ScheduleMultiDim< TABLE >::hasSameVariables(const ScheduleMultiDim< TABLE >& m) const {
276 return ((_domain_size_ == m._domain_size_) && (_var_sequence_ == m._var_sequence_));
277 }
278
280 template < typename TABLE >
281 bool ScheduleMultiDim< TABLE >::hasSameVariables(const IScheduleMultiDim& m) const {
282 try {
283 const ScheduleMultiDim< TABLE >& real_m = dynamic_cast< const ScheduleMultiDim< TABLE >& >(m);
284 return ScheduleMultiDim< TABLE >::hasSameVariables(real_m);
285 } catch (std::bad_cast&) { return false; }
286 }
287
289 template < typename TABLE >
290 bool ScheduleMultiDim< TABLE >::hasSameContent(const ScheduleMultiDim< TABLE >& m) const {
291 if (!hasSameVariables(m)) return false;
292
293 if (_table_ == nullptr) return (m._table_ == nullptr);
294 else {
295 if (m._table_ == nullptr) return false;
296 else { return (_table_ == m._table_) || (*_table_ == *(m._table_)); }
297 }
298 }
299
301 template < typename TABLE >
302 bool ScheduleMultiDim< TABLE >::hasSameContent(const IScheduleMultiDim& m) const {
303 try {
304 const ScheduleMultiDim< TABLE >& real_m = dynamic_cast< const ScheduleMultiDim< TABLE >& >(m);
305 return ScheduleMultiDim< TABLE >::hasSameContent(real_m);
306 } catch (std::bad_cast&) { return false; }
307 }
308
311 template < typename TABLE >
312 INLINE const TABLE& ScheduleMultiDim< TABLE >::multiDim() const {
313 if (_table_ == nullptr) {
315 "the ScheduleMultiDim is abstract, so its table " << "cannot be returned");
316 }
317 return *_table_;
318 }
319
321 template < typename TABLE >
322 INLINE bool ScheduleMultiDim< TABLE >::isAbstract() const {
323 return (_table_ == nullptr);
324 }
325
327 template < typename TABLE >
328 INLINE bool ScheduleMultiDim< TABLE >::containsMultiDim() const {
329 return _table_contained_ && (_table_ != nullptr);
330 }
331
333 template < typename TABLE >
334 INLINE void ScheduleMultiDim< TABLE >::makeAbstract() {
335 _removeTable_();
336 }
337
339 template < typename TABLE >
340 TABLE* ScheduleMultiDim< TABLE >::exportMultiDim() {
341 if (_table_ == nullptr) {
343 "The ScheduleMultiDim being abstract, " << "it is impossible to export its table");
344 }
345 if (!_table_contained_) {
347 "a ScheduleMultiDim cannot export a table it does not contain. "
348 "Use method multiDim() instead.");
349 }
350
351 auto table = _table_;
352 _table_ = nullptr;
353
354 return table;
355 }
356
358 template < typename TABLE >
359 INLINE const Sequence< const DiscreteVariable* >&
360 ScheduleMultiDim< TABLE >::variablesSequence() const {
361 return _var_sequence_;
362 }
363
365 template < typename TABLE >
366 INLINE Size ScheduleMultiDim< TABLE >::domainSize() const {
367 return _domain_size_;
368 }
369
371 template < typename TABLE >
372 INLINE double ScheduleMultiDim< TABLE >::sizeOfContent() const {
373 return double(sizeof(typename ElementType< TABLE >::value_type));
374 }
375
377 template < typename TABLE >
378 void ScheduleMultiDim< TABLE >::setMultiDim(const TABLE& table, const bool copy) {
379 if (copy) {
380 // if the ScheduleMultiDim does not contain its table, then make
381 // _table_ point to nullptr, so that we will allocate it
382 TABLE* old_table = _table_;
383 if (!_table_contained_) _table_ = nullptr;
384
385 if (_table_ == nullptr) {
386 try {
387 _table_ = new TABLE(table);
388 } catch (...) {
389 _table_ = old_table;
390 throw;
391 }
392 } else {
393 // here, _table_ is not null and the ScheduleMultiDim contains
394 // it. So we should copy table into it.
395 try {
396 *_table_ = table;
397 } catch (...) {
398 _table_ = old_table;
399 throw;
400 }
401 }
402 _table_contained_ = true;
403 } else {
404 _removeTable_();
405 _table_ = const_cast< TABLE* >(&table);
406 _table_contained_ = false;
407 }
408
409 _var_sequence_ = _table_->variablesSequence();
410 _domain_size_ = _table_->domainSize();
411 }
412
414 template < typename TABLE >
415 void ScheduleMultiDim< TABLE >::setMultiDim(TABLE&& table) {
416 // if the ScheduleMultiDim does not contain its table, then make
417 // _table_ point to nullptr, so that we will allocate it
418 TABLE* old_table = _table_;
419 if (!_table_contained_) _table_ = nullptr;
420
421 if (_table_ == nullptr) {
422 try {
423 _table_ = new TABLE(std::move(table));
424 } catch (...) {
425 _table_ = old_table;
426 throw;
427 }
428 } else {
429 // here, _table_ is not null and the ScheduleMultiDim contains
430 // it. Si we should copy table into it.
431 try {
432 *_table_ = std::move(table);
433 } catch (...) {
434 _table_ = old_table;
435 throw;
436 }
437 }
438 _table_contained_ = true;
439 _var_sequence_ = _table_->variablesSequence();
440 _domain_size_ = _table_->domainSize();
441 }
442
444 template < typename TABLE >
445 std::string ScheduleMultiDim< TABLE >::toString() const {
446 std::stringstream str;
447 str << "<id: " << this->id() << ", table: ";
448 if (_table_ == nullptr) str << "--";
449 else str << _table_->content();
450 str << ">";
451 return str.str();
452 }
453
454
455} /* namespace gum */
456
457#endif /* DOXYGEN_SHOULD_SKIP_THIS */
The Table-agnostic base class of scheduleMultiDim.
virtual const Sequence< const DiscreteVariable * > & variablesSequence() const =0
returns the set of variables involved in the ScheduleMultiDim
Exception : a pointer or a reference on a nullptr (0) object.
Exception : operation not allowed.
ScheduleMultiDim(const TABLE &table, const bool copy, const Idx id=0)
constructs a ScheduleMultiDim by copying/referencing table
void _removeTable_()
remove the table if it is contained in the ScheduleMultiDim
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
Size Idx
Type for indexes.
Definition types.h:79
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
a Wrapper for multi-dimensional tables used for scheduling inferences