aGrUM 2.3.2
a C++ library for (probabilistic) graphical models
scheduleStorage_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 <agrum/agrum.h>
52
54
55namespace gum {
56
57 namespace ScheduleStorageMethod {
58
59 // storing tables into a Set<Table*>
60 template < typename TABLE >
61 INLINE void Execution< TABLE, TABLE*, Set >::execute(TABLE& table, Set< TABLE* >& container) {
62 container.insert(&table);
63 }
64
65 // storing tables into a vector<Table>
66 template < typename TABLE >
67 INLINE void Execution< TABLE, TABLE, std::vector >::execute(TABLE& table,
68 std::vector< TABLE >& container) {
69 container.push_back(std::move(table));
70 }
71
72 } // namespace ScheduleStorageMethod
73
75 template < typename TABLE, template < typename... > class CONTAINER >
76 ScheduleStorage< TABLE, CONTAINER >::ScheduleStorage(const IScheduleMultiDim& table,
77 CONTAINER< TABLE >& container) :
78 ScheduleOperator(ScheduleOperatorType::STORE_MULTIDIM, true, false), _container_(&container) {
79 // checks that table is a ScheduleMultiDim<T>, where either TABLE=T or
80 // TABLE = T*. If this is not the case, then we won't be able to perform the
81 // operator, hence we should raise an exception now, i.e., before performing
82 // all the computations within the schedule
83 try {
84 _arg_ = dynamic_cast< ScheduleMultiDim< SCHED_TABLE >* >(
85 const_cast< IScheduleMultiDim* >(&table));
86 } catch (std::bad_cast&) {
87 GUM_ERROR(TypeError,
88 "The ScheduleMultiDim cannot be stored in the container "
89 "because their types are incompatible.");
90 }
91
92 // save the arg into _args_ (no need to update _results_)
93 _args_ << _arg_;
94
95 // for debugging purposes
96 GUM_CONSTRUCTOR(ScheduleStorage);
97 }
98
100 template < typename TABLE, template < typename... > class CONTAINER >
101 ScheduleStorage< TABLE, CONTAINER >::ScheduleStorage(
102 const ScheduleStorage< TABLE, CONTAINER >& from) :
103 ScheduleOperator(from), _arg_(from._arg_), _container_(from._container_),
104 _is_executed_(from._is_executed_) {
105 // save the arg into _args_ (no need to update _results_)
106 _args_ << _arg_;
107
108 // for debugging purposes
109 GUM_CONS_CPY(ScheduleStorage);
110 }
111
113 template < typename TABLE, template < typename... > class CONTAINER >
114 ScheduleStorage< TABLE, CONTAINER >::ScheduleStorage(ScheduleStorage< TABLE, CONTAINER >&& from) :
115 ScheduleOperator(std::move(from)), _arg_(from._arg_), _container_(from._container_),
116 _is_executed_(from._is_executed_) {
117 // save the arg into _args_ (no need to update _results_)
118 _args_ << _arg_;
119
120 // for debugging purposes
121 GUM_CONS_MOV(ScheduleStorage);
122 }
123
125 template < typename TABLE, template < typename... > class CONTAINER >
126 INLINE ScheduleStorage< TABLE, CONTAINER >* ScheduleStorage< TABLE, CONTAINER >::clone() const {
127 return new ScheduleStorage< TABLE, CONTAINER >(*this);
128 }
129
131 template < typename TABLE, template < typename... > class CONTAINER >
132 ScheduleStorage< TABLE, CONTAINER >::~ScheduleStorage() {
133 // for debugging purposes
134 GUM_DESTRUCTOR(ScheduleStorage);
135 }
136
138 template < typename TABLE, template < typename... > class CONTAINER >
141 if (this != &from) {
142 _arg_ = from._arg_;
143 _args_.clear();
144 _args_ << _arg_;
145 _container_ = from._container_;
146 _is_executed_ = from._is_executed_;
148 }
149 return *this;
150 }
151
153 template < typename TABLE, template < typename... > class CONTAINER >
154 ScheduleStorage< TABLE, CONTAINER >&
156 if (this != &from) {
157 _arg_ = from._arg_;
158 _args_.clear();
159 _args_ << _arg_;
160 _container_ = from._container_;
161 _is_executed_ = from._is_executed_;
162 ScheduleOperator::operator=(std::move(from));
163 }
164 return *this;
165 }
166
168 template < typename TABLE, template < typename... > class CONTAINER >
169 INLINE bool ScheduleStorage< TABLE, CONTAINER >::operator==(
170 const ScheduleStorage< TABLE, CONTAINER >& op) const {
171 return (_container_ == op._container_) && (*_arg_ == *op._arg_);
172 }
173
175 template < typename TABLE, template < typename... > class CONTAINER >
176 bool ScheduleStorage< TABLE, CONTAINER >::operator==(const ScheduleOperator& op) const {
177 try {
178 const ScheduleStorage< TABLE, CONTAINER >& real_op
179 = dynamic_cast< const ScheduleStorage< TABLE, CONTAINER >& >(op);
180 return ScheduleStorage< TABLE, CONTAINER >::operator==(real_op);
181 } catch (std::bad_cast&) { return false; }
182 }
183
185 template < typename TABLE, template < typename... > class CONTAINER >
186 INLINE bool ScheduleStorage< TABLE, CONTAINER >::operator!=(
187 const ScheduleStorage< TABLE, CONTAINER >& op) const {
188 return !ScheduleStorage< TABLE, CONTAINER >::operator==(op);
189 }
190
192 template < typename TABLE, template < typename... > class CONTAINER >
193 INLINE bool ScheduleStorage< TABLE, CONTAINER >::operator!=(const ScheduleOperator& op) const {
194 return !ScheduleStorage< TABLE, CONTAINER >::operator==(op);
195 }
196
198 template < typename TABLE, template < typename... > class CONTAINER >
199 INLINE bool ScheduleStorage< TABLE, CONTAINER >::hasSimilarArguments(
200 const ScheduleStorage< TABLE, CONTAINER >& op) const {
201 return _arg_->hasSameVariables(*op._arg_);
202 }
203
205 template < typename TABLE, template < typename... > class CONTAINER >
206 bool ScheduleStorage< TABLE, CONTAINER >::hasSimilarArguments(const ScheduleOperator& op) const {
207 try {
208 const ScheduleStorage< TABLE, CONTAINER >& real_op
209 = dynamic_cast< const ScheduleStorage< TABLE, CONTAINER >& >(op);
210 return ScheduleStorage< TABLE, CONTAINER >::hasSimilarArguments(real_op);
211 } catch (std::bad_cast&) { return false; }
212 }
213
215 template < typename TABLE, template < typename... > class CONTAINER >
216 INLINE bool ScheduleStorage< TABLE, CONTAINER >::hasSameArguments(
217 const ScheduleStorage< TABLE, CONTAINER >& op) const {
218 return (_container_ == op._container_) && _arg_->hasSameVariables(*op._arg_)
219 && _arg_->hasSameContent(*op._arg_);
220 }
221
223 template < typename TABLE, template < typename... > class CONTAINER >
224 bool ScheduleStorage< TABLE, CONTAINER >::hasSameArguments(const ScheduleOperator& op) const {
225 try {
226 const ScheduleStorage< TABLE, CONTAINER >& real_op
227 = dynamic_cast< const ScheduleStorage< TABLE, CONTAINER >& >(op);
228 return ScheduleStorage< TABLE, CONTAINER >::hasSameArguments(real_op);
229 } catch (std::bad_cast&) { return false; }
230 }
231
233 template < typename TABLE, template < typename... > class CONTAINER >
234 INLINE bool ScheduleStorage< TABLE, CONTAINER >::isSameOperator(
235 const ScheduleStorage< TABLE, CONTAINER >& op) const {
236 return true;
237 }
238
240 template < typename TABLE, template < typename... > class CONTAINER >
241 bool ScheduleStorage< TABLE, CONTAINER >::isSameOperator(const ScheduleOperator& op) const {
242 try {
243 const ScheduleStorage< TABLE, CONTAINER >& real_op
244 = dynamic_cast< const ScheduleStorage< TABLE, CONTAINER >& >(op);
245 return ScheduleStorage< TABLE, CONTAINER >::isSameOperator(real_op);
246 } catch (std::bad_cast&) { return false; }
247 }
248
250 template < typename TABLE, template < typename... > class CONTAINER >
251 INLINE const ScheduleMultiDim< typename std::remove_pointer< TABLE >::type >&
252 ScheduleStorage< TABLE, CONTAINER >::arg() const {
253 return *_arg_;
254 }
255
257 template < typename TABLE, template < typename... > class CONTAINER >
259 return _args_;
260 }
261
263 template < typename TABLE, template < typename... > class CONTAINER >
265 return _results_;
266 }
267
269 template < typename TABLE, template < typename... > class CONTAINER >
270 void ScheduleStorage< TABLE, CONTAINER >::execute() {
271 if (_arg_->isAbstract()) {
272 GUM_ERROR(NullElement,
273 "It is impossible to store an abstract ScheduleMultiDim"
274 "into a container.");
275 }
276
277 // if the container contains tables, not pointers to tables, we will move
278 // directly the table contained within the ScheduleMultiDim into it, else
279 // we will allocate a new table and pass this newly allocated tables to
280 // the container
281 if (std::is_same< SCHED_TABLE, TABLE >::value) {
282 // here, the container contains tables, not pointers to tables
283 if (_arg_->containsMultiDim()) {
284 // here, the ScheduleMultiDim owns the table, so it can pass directly
285 // its table to the container
286 ScheduleStorageMethod::Execution< SCHED_TABLE, TABLE, CONTAINER >::execute(
287 const_cast< SCHED_TABLE& >(_arg_->multiDim()),
288 *_container_);
289 } else {
290 // here, the container just contains a reference on the table, hence
291 // we should first copy it and this is this copy that will be inserted
292 // into the container
293 SCHED_TABLE table = _arg_->multiDim();
294 ScheduleStorageMethod::Execution< SCHED_TABLE, TABLE, CONTAINER >::execute(table,
295 *_container_);
296 }
297 } else {
298 // here, the container contains pointers to tables. So we should first
299 // allocate the table that will be stored into the container
300 SCHED_TABLE* table;
301
302 // if the ScheduleMultiDim owns the table, we just have to initialize
303 // it by moving the ScheduleMultiDim's table, else we should copy it
304 if (_arg_->containsMultiDim()) {
305 table = new SCHED_TABLE(std::move(const_cast< SCHED_TABLE& >(_arg_->multiDim())));
306 } else {
307 table = new SCHED_TABLE(const_cast< SCHED_TABLE& >(_arg_->multiDim()));
308 }
309
310 ScheduleStorageMethod::Execution< SCHED_TABLE, TABLE, CONTAINER >::execute(*table,
311 *_container_);
312 }
313
314 // be sure that the ScheduleMultiDim becomes abstract
315 _arg_->makeAbstract();
316 _is_executed_ = true;
317 }
318
320 template < typename TABLE, template < typename... > class CONTAINER >
321 INLINE bool ScheduleStorage< TABLE, CONTAINER >::isExecuted() const {
322 return _is_executed_;
323 }
324
326 template < typename TABLE, template < typename... > class CONTAINER >
327 void ScheduleStorage< TABLE, CONTAINER >::undo() {
328 GUM_ERROR(OperationNotAllowed, "ScheduleStorage cannot be undone.");
329 }
330
332 template < typename TABLE, template < typename... > class CONTAINER >
333 void ScheduleStorage< TABLE, CONTAINER >::updateArgs(
334 const Sequence< const IScheduleMultiDim* >& new_args) {
335 // check that there is exactly one argument in new_args and that its type
336 // is compatible with TABLE
337 if (new_args.size() != Size(1)) {
338 GUM_ERROR(SizeError,
339 "Method ScheduleStorage::updateArgs expects 1 new "
340 << "argument, but " << new_args.size() << " were passed.");
341 }
342 ScheduleMultiDim< SCHED_TABLE >* arg;
343 try {
344 arg = dynamic_cast< ScheduleMultiDim< SCHED_TABLE >* >(
345 const_cast< IScheduleMultiDim* >(new_args[0]));
346 } catch (std::bad_cast&) {
347 GUM_ERROR(TypeError,
348 "The type of the argument passed to "
349 << "ScheduleStorage::updateArgs does not match what "
350 << "the ScheduleOperator expects");
351 }
352
353 // save the new argument
354 _arg_ = (ScheduleMultiDim< SCHED_TABLE >*)arg;
355 _args_.clear();
356 _args_ << _arg_;
357 _is_executed_ = false;
358 }
359
362 template < typename TABLE, template < typename... > class CONTAINER >
363 INLINE double ScheduleStorage< TABLE, CONTAINER >::nbOperations() const {
364 return 1.0;
365 }
366
368 template < typename TABLE, template < typename... > class CONTAINER >
369 INLINE std::pair< double, double > ScheduleStorage< TABLE, CONTAINER >::memoryUsage() const {
370 const double size_table = double(_arg_->domainSize()) * _arg_->sizeOfContent() + sizeof(TABLE);
371 return {-size_table, -size_table};
372 }
373
375 template < typename TABLE, template < typename... > class CONTAINER >
376 std::string ScheduleStorage< TABLE, CONTAINER >::toString() const {
377 return "store ( " + _arg_->toString() + " )";
378 }
379
380} // namespace gum
381
382#endif /* DOXYGEN_SHOULD_SKIP_THIS */
The Table-agnostic base class of scheduleMultiDim.
a Wrapper for multi-dimensional tables used for scheduling inferences
the base class for "low-level" operators used to schedule inferences
ScheduleOperator & operator=(const ScheduleOperator &from)
copy operator
Class for storing multidimensional tables into containers (sets, etc.).
ScheduleStorage< TABLE, CONTAINER > * clone() const final
virtual copy constructor
std::string toString() const final
displays the content of the operator
const Sequence< const IScheduleMultiDim * > & args() const final
returns the sequence of arguments passed to the operator
ScheduleStorage< TABLE, CONTAINER > & operator=(const ScheduleStorage< TABLE, CONTAINER > &)
copy operator
const Sequence< const IScheduleMultiDim * > & results() const final
returns the sequence of ScheduleMultidim output by the operator
The generic class for storing (ordered) sequences of objects.
Definition sequence.h:972
#define GUM_ERROR(type, msg)
Definition exceptions.h:72
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition types.h:74
gum is the global namespace for all aGrUM entities
Definition agrum.h:46
Class for storing multidimensional tables in scheduling inferences.