aGrUM 3.1.1
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-2026 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-2026 *
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
41#pragma once
42
43
49
51#ifndef DOXYGEN_SHOULD_SKIP_THIS
52
53# include <sstream>
54# include <string>
55
57
58namespace gum {
59
60
62 template < typename TABLE >
64 if (_table_contained_ && (_table_ != nullptr)) delete _table_;
65 _table_ = nullptr;
66 }
67
69 template < typename TABLE >
70 ScheduleMultiDim< TABLE >::ScheduleMultiDim(const TABLE& table, const bool copy, const Idx id) :
72 if (copy) {
73 // copy the table
74 _table_ = new TABLE(table);
75 _table_contained_ = true;
76 } else {
77 _table_ = const_cast< TABLE* >(&table);
78 _table_contained_ = false;
79 }
80
81 _var_sequence_ = _table_->variablesSequence();
82 _domain_size_ = _table_->domainSize();
83
84 // for debugging purposes
85 GUM_CONSTRUCTOR(ScheduleMultiDim);
86 }
87
89 template < typename TABLE >
90 ScheduleMultiDim< TABLE >::ScheduleMultiDim(TABLE&& table, const Idx id) : IScheduleMultiDim(id) {
91 // move the table
92 _table_ = new TABLE(std::move(table));
93 _var_sequence_ = _table_->variablesSequence();
94 _domain_size_ = _table_->domainSize();
95
96 // for debugging purposes
97 GUM_CONSTRUCTOR(ScheduleMultiDim);
98 }
99
101 template < typename TABLE >
102 ScheduleMultiDim< TABLE >::ScheduleMultiDim(const Sequence< const DiscreteVariable* >& vars,
103 const Idx id) :
104 IScheduleMultiDim(id), _var_sequence_(vars) {
105 if (!_var_sequence_.empty()) {
106 // compute and store the domain size
107 _domain_size_ = Size(1);
108 for (const auto var: vars)
109 _domain_size_ *= var->domainSize();
110 }
111
112 // for debugging purposes
113 GUM_CONSTRUCTOR(ScheduleMultiDim);
114 }
115
117 template < typename TABLE >
118 ScheduleMultiDim< TABLE >::ScheduleMultiDim(const ScheduleMultiDim< TABLE >& from) :
119 IScheduleMultiDim(from), _table_contained_(from._table_contained_),
120 _var_sequence_(from._var_sequence_), _domain_size_(from._domain_size_) {
121 if (from._table_ != nullptr) {
122 if (from._table_contained_) {
123 // copy the table
124 _table_ = new TABLE(*(from._table_));
125 } else {
126 _table_ = from._table_;
127 }
128 }
129
130 // for debugging purposes
131 GUM_CONS_CPY(ScheduleMultiDim);
132 }
133
135 template < typename TABLE >
136 ScheduleMultiDim< TABLE >::ScheduleMultiDim(ScheduleMultiDim< TABLE >&& from) :
137 IScheduleMultiDim(from), _table_contained_(from._table_contained_),
138 _var_sequence_(from._var_sequence_), _domain_size_(from._domain_size_) {
139 if (from._table_ != nullptr) {
140 _table_ = from._table_;
141 from._table_ = nullptr;
142 }
143
144 // for debugging purposes
145 GUM_CONS_MOV(ScheduleMultiDim);
146 }
147
149 template < typename TABLE >
150 ScheduleMultiDim< TABLE >* ScheduleMultiDim< TABLE >::clone() const {
151 return new ScheduleMultiDim< TABLE >(*this);
152 }
153
155 template < typename TABLE >
156 ScheduleMultiDim< TABLE >* ScheduleMultiDim< TABLE >::clone(bool force_copy) const {
157 ScheduleMultiDim< TABLE >* new_sched;
158
159 if (!force_copy) new_sched = new ScheduleMultiDim< TABLE >(*this);
160 else {
161 if (!isAbstract()) new_sched = new ScheduleMultiDim< TABLE >(*_table_, true, this->id());
162 else {
163 new_sched = new ScheduleMultiDim< TABLE >(_var_sequence_, this->id());
164 new_sched->_table_contained_ = true;
165 }
166 }
167
168 return new_sched;
169 }
170
172 template < typename TABLE >
173 ScheduleMultiDim< TABLE >::~ScheduleMultiDim() {
174 _removeTable_();
175
176 // for debugging purposes
177 GUM_DESTRUCTOR(ScheduleMultiDim);
178 }
179
181 template < typename TABLE >
182 ScheduleMultiDim< TABLE >&
183 ScheduleMultiDim< TABLE >::operator=(const ScheduleMultiDim< TABLE >& from) {
184 // avoid self assignment
185 if (this != &from) {
186 // assign the table of from
187 if (from._table_ != nullptr) {
188 if (from._table_contained_) {
189 // if the ScheduleMultiDim does not contain its table, then make
190 // _table_ point to nullptr, so that we will allocate it
191 TABLE* old_table = _table_;
192 if (!_table_contained_) _table_ = nullptr;
193
194 if (_table_ == nullptr) {
195 try {
196 _table_ = new TABLE(*(from._table_));
197 } catch (...) {
198 _table_ = old_table;
199 throw;
200 }
201 } else {
202 // here, _table_ is not null and the ScheduleMultiDim contains
203 // it. So we should copy from's table into it.
204 *_table_ = *(from._table_);
205 }
206 _table_contained_ = true;
207 } else {
208 _removeTable_();
209 _table_ = from._table_;
210 _table_contained_ = false;
211 }
212 } else {
213 // here, we should make _table_ point to nullptr
214 _removeTable_();
215 _table_ = nullptr;
216 _table_contained_ = from._table_contained_;
217 }
218
219 _var_sequence_ = from._var_sequence_;
220 _domain_size_ = from._domain_size_;
221 IScheduleMultiDim::operator=(from);
222 }
223
224 return *this;
225 }
226
228 template < typename TABLE >
229 ScheduleMultiDim< TABLE >&
230 ScheduleMultiDim< TABLE >::operator=(ScheduleMultiDim< TABLE >&& from) {
231 // avoid self assignment
232 if (this != &from) {
233 // assign the table of from
234 _removeTable_();
235 _table_ = from._table_;
236 from._table_ = nullptr;
237 _table_contained_ = from._table_contained_;
238
239 _var_sequence_ = from._var_sequence_;
240 _domain_size_ = from._domain_size_;
241 IScheduleMultiDim::operator=(std::move(from));
242 }
243
244 return *this;
245 }
246
248 template < typename TABLE >
249 bool ScheduleMultiDim< TABLE >::operator==(const ScheduleMultiDim< TABLE >& m) const {
250 return IScheduleMultiDim::operator==(m);
251 }
252
254 template < typename TABLE >
255 bool ScheduleMultiDim< TABLE >::operator==(const IScheduleMultiDim& m) const {
256 try {
257 const ScheduleMultiDim< TABLE >& real_m = dynamic_cast< const ScheduleMultiDim< TABLE >& >(m);
258 return ScheduleMultiDim< TABLE >::operator==(real_m);
259 } catch (std::bad_cast&) { return false; }
260 }
261
263 template < typename TABLE >
264 bool ScheduleMultiDim< TABLE >::operator!=(const ScheduleMultiDim< TABLE >& m) const {
265 return !ScheduleMultiDim< TABLE >::operator==(m);
266 }
267
269 template < typename TABLE >
270 bool ScheduleMultiDim< TABLE >::operator!=(const IScheduleMultiDim& m) const {
271 return !ScheduleMultiDim< TABLE >::operator==(m);
272 }
273
275 template < typename TABLE >
276 bool ScheduleMultiDim< TABLE >::hasSameVariables(const ScheduleMultiDim< TABLE >& m) const {
277 return ((_domain_size_ == m._domain_size_) && (_var_sequence_ == m._var_sequence_));
278 }
279
281 template < typename TABLE >
282 bool ScheduleMultiDim< TABLE >::hasSameVariables(const IScheduleMultiDim& m) const {
283 try {
284 const ScheduleMultiDim< TABLE >& real_m = dynamic_cast< const ScheduleMultiDim< TABLE >& >(m);
285 return ScheduleMultiDim< TABLE >::hasSameVariables(real_m);
286 } catch (std::bad_cast&) { return false; }
287 }
288
290 template < typename TABLE >
291 bool ScheduleMultiDim< TABLE >::hasSameContent(const ScheduleMultiDim< TABLE >& m) const {
292 if (!hasSameVariables(m)) return false;
293
294 if (_table_ == nullptr) return (m._table_ == nullptr);
295 else {
296 if (m._table_ == nullptr) return false;
297 else { return (_table_ == m._table_) || (*_table_ == *(m._table_)); }
298 }
299 }
300
302 template < typename TABLE >
303 bool ScheduleMultiDim< TABLE >::hasSameContent(const IScheduleMultiDim& m) const {
304 try {
305 const ScheduleMultiDim< TABLE >& real_m = dynamic_cast< const ScheduleMultiDim< TABLE >& >(m);
306 return ScheduleMultiDim< TABLE >::hasSameContent(real_m);
307 } catch (std::bad_cast&) { return false; }
308 }
309
312 template < typename TABLE >
313 const TABLE& ScheduleMultiDim< TABLE >::multiDim() const {
314 if (_table_ == nullptr) {
316 "the ScheduleMultiDim is abstract, so its table " << "cannot be returned");
317 }
318 return *_table_;
319 }
320
322 template < typename TABLE >
323 bool ScheduleMultiDim< TABLE >::isAbstract() const {
324 return (_table_ == nullptr);
325 }
326
328 template < typename TABLE >
329 bool ScheduleMultiDim< TABLE >::containsMultiDim() const {
330 return _table_contained_ && (_table_ != nullptr);
331 }
332
334 template < typename TABLE >
335 void ScheduleMultiDim< TABLE >::makeAbstract() {
336 _removeTable_();
337 }
338
340 template < typename TABLE >
341 TABLE* ScheduleMultiDim< TABLE >::exportMultiDim() {
342 if (_table_ == nullptr) {
344 "The ScheduleMultiDim being abstract, " << "it is impossible to export its table");
345 }
346 if (!_table_contained_) {
348 "a ScheduleMultiDim cannot export a table it does not contain. "
349 "Use method multiDim() instead.");
350 }
351
352 auto table = _table_;
353 _table_ = nullptr;
354
355 return table;
356 }
357
359 template < typename TABLE >
360 const Sequence< const DiscreteVariable* >& ScheduleMultiDim< TABLE >::variablesSequence() const {
361 return _var_sequence_;
362 }
363
365 template < typename TABLE >
366 Size ScheduleMultiDim< TABLE >::domainSize() const {
367 return _domain_size_;
368 }
369
371 template < typename TABLE >
372 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:76
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