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