aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
idCondSet_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 /** @file
23  * @brief Template implementation of idSets
24  *
25  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
26  */
27 
28 #ifndef DOXYGEN_SHOULD_SKIP_THIS
29 
30 
31 namespace gum {
32 
33  namespace learning {
34 
35 
36  /// default constructor
37  template < template < typename > class ALLOC >
38  INLINE IdCondSetIterator< ALLOC >::IdCondSetIterator() {
40  }
41 
42 
43  /// Constructor for a begin
44  template < template < typename > class ALLOC >
46  _seq_(&(idset.ids())) {
48  }
49 
50 
51  /// Copy constructor.
52  template < template < typename > class ALLOC >
56  }
57 
58 
59  /// move constructor
60  template < template < typename > class ALLOC >
64  }
65 
66 
67  /// destructor
68  template < template < typename > class ALLOC >
71  }
72 
73 
74  /// places the index to the end of the sequence
75  template < template < typename > class ALLOC >
77  if (_seq_ != nullptr)
78  _index_ = _seq_->size();
79  else
80  _index_ = std::size_t(0);
81  }
82 
83 
84  /// copy operator
85  template < template < typename > class ALLOC >
88  _seq_ = from._seq_;
90  return *this;
91  }
92 
93 
94  /// move operator
95  template < template < typename > class ALLOC >
98  _seq_ = from._seq_;
100  return *this;
101  }
102 
103 
104  /// Gives access to the content of the iterator.
105  template < template < typename > class ALLOC >
107  return _seq_->operator[](_index_);
108  }
109 
110 
111  /// Checks whether two iterators point toward different elements.
112  template < template < typename > class ALLOC >
113  INLINE bool
115  return (_index_ != from._index_) || (_seq_ != from._seq_);
116  }
117 
118 
119  /// Checks whether two iterators point toward the same elements.
120  template < template < typename > class ALLOC >
121  INLINE bool
123  return !operator!=(from);
124  }
125 
126 
127  /// Makes the iterator point to the next element in the IdCondSet
128  template < template < typename > class ALLOC >
130  ++_index_;
131  return *this;
132  }
133 
134 
135  /// Makes the iterator point to i elements further in the IdCondSet
136  template < template < typename > class ALLOC >
138  _index_ += i;
139  return *this;
140  }
141 
142 
143  /// Returns a new iterator pointing to i further elements in the IdCondSet
144  template < template < typename > class ALLOC >
146  IdCondSetIterator< ALLOC > res(*this);
147  res += i;
148  return res;
149  }
150 
151 
152  /// Returns the position of the iterator in the IdCondSet
153  template < template < typename > class ALLOC >
154  std::size_t IdCondSetIterator< ALLOC >::pos() const {
155  if (_seq_ == nullptr)
157  "The IdCondSet is empty, so its iterators have no position")
158  if (_index_ >= _seq_->size())
160  "the IdCondSet iterator has no position because it reached "
161  "the set's end.");
162  return _index_;
163  }
164 
165 
166  /// ==========================================================================
167  /// ==========================================================================
168 
169 
170  /// returns the allocator used by the translator
171  template < template < typename > class ALLOC >
172  INLINE typename IdCondSet< ALLOC >::allocator_type IdCondSet< ALLOC >::getAllocator() const {
173  return *this;
174  }
175 
176 
177  /// default constructor
178  template < template < typename > class ALLOC >
180  ALLOC< NodeId >(alloc), _end_safe_(*this) {
182  }
183 
184 
185  /// default constructor with no variable on the left side
186  template < template < typename > class ALLOC >
188  const bool rhs_ids,
189  const bool ordered_ids,
190  const typename IdCondSet< ALLOC >::allocator_type& alloc) :
191  ALLOC< NodeId >(alloc),
192  _end_safe_(*this) {
193  _ids_.resize(ids.size());
194 
195  // if the rhs_ids should be considered as unordered, we sort them by
196  // increasing order so that we can compare easily two different rhs_ids
197  if (!ordered_ids) {
198  std::vector< NodeId, ALLOC< NodeId > > vect(ids);
199  std::sort(vect.begin(), vect.end());
200  for (const auto id: vect)
201  _ids_ << id;
202  } else {
203  for (const auto id: ids)
204  _ids_ << id;
205  }
206 
207  if (!rhs_ids) _nb_lhs_ids_ = _ids_.size();
208 
209  // update the end iterator
211 
213  }
214 
215 
216  /// default constructor with one variable on the left side
217  template < template < typename > class ALLOC >
219  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids,
220  const bool ordered_rhs_ids,
221  const typename IdCondSet< ALLOC >::allocator_type& alloc) :
222  ALLOC< NodeId >(alloc),
223  _nb_lhs_ids_(std::size_t(1)), _end_safe_(*this) {
224  _ids_.resize(rhs_ids.size() + std::size_t(1));
225  _ids_ << var1;
226 
227  // if the rhs_ids should be considered as unordered, we sort them by
228  // increasing order so that we can compare easily two different rhs_ids
229  if (!ordered_rhs_ids) {
231  std::sort(vect.begin(), vect.end());
232  for (const auto id: vect)
233  _ids_ << id;
234  } else {
235  for (const auto id: rhs_ids)
236  _ids_ << id;
237  }
238 
239  // update the end iterator
241 
243  }
244 
245 
246  /// default constructor with two variables on the left side
247  template < template < typename > class ALLOC >
249  NodeId var2,
250  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids,
251  const bool ordered_lhs_vars,
252  const bool ordered_rhs_ids,
253  const typename IdCondSet< ALLOC >::allocator_type& alloc) :
254  ALLOC< NodeId >(alloc),
255  _nb_lhs_ids_(std::size_t(2)), _end_safe_(*this) {
256  _ids_.resize(rhs_ids.size() + std::size_t(2));
257 
258  // if the variables on the left side are unordered, sort them by
259  // increasing order
260  if (!ordered_lhs_vars && (var1 > var2)) std::swap(var1, var2);
261  _ids_ << var1;
262  _ids_ << var2;
263 
264  // if the rhs_ids should be considered as unordered, we sort them by
265  // increasing order so that we can compare easily two different rhs_ids
266  if (!ordered_rhs_ids) {
268  std::sort(vect.begin(), vect.end());
269  for (const auto id: vect)
270  _ids_ << id;
271  } else {
272  for (const auto id: rhs_ids)
273  _ids_ << id;
274  }
275 
276  // update the end iterator
278 
280  }
281 
282 
283  /// default constructor with three variables on the left side
284  template < template < typename > class ALLOC >
286  NodeId var2,
287  NodeId var3,
288  const std::vector< NodeId, ALLOC< NodeId > >& rhs_ids,
289  const bool ordered_lhs_vars,
290  const bool ordered_rhs_ids,
291  const typename IdCondSet< ALLOC >::allocator_type& alloc) :
292  ALLOC< NodeId >(alloc),
293  _nb_lhs_ids_(std::size_t(3)), _end_safe_(*this) {
294  _ids_.resize(rhs_ids.size() + std::size_t(3));
295 
296  // if the variables on the left side are unordered, sort them by
297  // increasing order
298  if (!ordered_lhs_vars) {
299  if (var1 > var2) std::swap(var1, var2);
300  if (var1 > var3) std::swap(var1, var3);
301  if (var2 > var3) std::swap(var2, var3);
302  }
303  _ids_ << var1;
304  _ids_ << var2;
305  _ids_ << var3;
306 
307  // if the rhs_ids should be considered as unordered, we sort them by
308  // increasing order so that we can compare easily two different rhs_ids
309  if (!ordered_rhs_ids) {
311  std::sort(vect.begin(), vect.end());
312  for (const auto id: vect)
313  _ids_ << id;
314  } else {
315  for (const auto id: rhs_ids)
316  _ids_ << id;
317  }
318 
319  // update the end iterator
321 
323  }
324 
325 
326  /// copy constructor with a given allocator
327  template < template < typename > class ALLOC >
329  const typename IdCondSet< ALLOC >::allocator_type& alloc) :
330  ALLOC< NodeId >(alloc),
334  }
335 
336 
337  /// copy constructor
338  template < template < typename > class ALLOC >
341 
342 
343  /// move constructor with a given allocator
344  template < template < typename > class ALLOC >
346  const typename IdCondSet< ALLOC >::allocator_type& alloc) :
347  ALLOC< NodeId >(alloc),
351  }
352 
353 
354  /// move constructor
355  template < template < typename > class ALLOC >
358 
359 
360  /// virtual copy constructor with a given allocator
361  template < template < typename > class ALLOC >
362  IdCondSet< ALLOC >*
363  IdCondSet< ALLOC >::clone(const typename IdCondSet< ALLOC >::allocator_type& alloc) const {
366  try {
367  allocator.construct(new_set, *this, alloc);
368  } catch (...) {
370  throw;
371  }
372 
373  return new_set;
374  }
375 
376 
377  /// virtual copy constructor
378  template < template < typename > class ALLOC >
379  IdCondSet< ALLOC >* IdCondSet< ALLOC >::clone() const {
380  return clone(this->getAllocator());
381  }
382 
383 
384  /// destructor
385  template < template < typename > class ALLOC >
388  }
389 
390 
391  /// copy operator
392  template < template < typename > class ALLOC >
394  if (this != &from) {
395  _ids_ = from._ids_;
398  }
399  return *this;
400  }
401 
402 
403  /// move operator
404  template < template < typename > class ALLOC >
406  if (this != &from) {
407  _ids_ = std::move(from._ids_);
410  }
411  return *this;
412  }
413 
414 
415  /// returns the id stored at a given index
416  template < template < typename > class ALLOC >
417  INLINE NodeId IdCondSet< ALLOC >::operator[](const std::size_t index) const {
418  return _ids_.atPos(index);
419  }
420 
421 
422  /// returns true if both sets are equal
423  template < template < typename > class ALLOC >
424  INLINE bool IdCondSet< ALLOC >::operator==(const IdCondSet< ALLOC >& from) const {
425  if (_nb_lhs_ids_ != from._nb_lhs_ids_) return false;
426 
427  const std::size_t size = _ids_.size();
428 
429  if (size != from._ids_.size()) return false;
430 
431  for (std::size_t i = std::size_t(0); i < size; ++i) {
432  if (_ids_[i] != from._ids_[i]) return false;
433  }
434 
435  return true;
436  }
437 
438 
439  /// returns true if the sets differ
440  template < template < typename > class ALLOC >
441  INLINE bool IdCondSet< ALLOC >::operator!=(const IdCondSet< ALLOC >& from) const {
442  return !operator==(from);
443  }
444 
445 
446  /// Returns a safe begin iterator.
447  template < template < typename > class ALLOC >
448  INLINE typename IdCondSet< ALLOC >::iterator_safe IdCondSet< ALLOC >::beginSafe() const {
449  return IdCondSetIterator< ALLOC >(*this);
450  }
451 
452 
453  /// Returns the safe end iterator.
454  template < template < typename > class ALLOC >
455  INLINE const typename IdCondSet< ALLOC >::iterator_safe& IdCondSet< ALLOC >::endSafe() const {
456  return _end_safe_;
457  }
458 
459 
460  /// Returns an unsafe begin iterator.
461  template < template < typename > class ALLOC >
462  INLINE typename IdCondSet< ALLOC >::iterator IdCondSet< ALLOC >::begin() const {
463  return IdCondSetIterator< ALLOC >(*this);
464  }
465 
466 
467  /// Returns the unsafe end iterator.
468  template < template < typename > class ALLOC >
469  INLINE const typename IdCondSet< ALLOC >::iterator& IdCondSet< ALLOC >::end() const {
470  return _end_safe_;
471  }
472 
473 
474  /// returns the set of ids contained in the object
475  template < template < typename > class ALLOC >
476  INLINE const Sequence< NodeId, ALLOC< NodeId > >& IdCondSet< ALLOC >::ids() const {
477  return _ids_;
478  }
479 
480 
481  /// returns the idSet at the right hand side of the conditioning bar
482  template < template < typename > class ALLOC >
484  IdCondSet< ALLOC > set(this->getAllocator());
485  const std::size_t size = _ids_.size();
486  for (std::size_t i = _nb_lhs_ids_; i < size; ++i)
487  set._ids_ << _ids_[i];
489  return set;
490  }
491 
492 
493  /// erase a node in the idset
494  template < template < typename > class ALLOC >
495  void IdCondSet< ALLOC >::erase(const NodeId id) {
496  // search for id in Sequence _ids_
497  const std::size_t size = _ids_.size();
498  std::size_t pos = std::size_t(0);
499  for (; pos < size; ++pos) {
500  if (_ids_[pos] == id) break;
501  }
502 
503  // if we found the id, remove it
504  if (pos < size) {
506  if (pos < _nb_lhs_ids_) --_nb_lhs_ids_;
508  }
509  }
510 
511 
512  /// returns the content of the set as a string
513  template < template < typename > class ALLOC >
514  std::string IdCondSet< ALLOC >::toString() const {
516 
517  str << '{';
518  bool deja = false;
519 
520  for (std::size_t i = std::size_t(0); i < _nb_lhs_ids_; ++i) {
521  if (deja)
522  str << " , ";
523  else
524  deja = true;
525  str << _ids_[i];
526  }
527 
528  deja = false;
529  for (auto iter = _ids_.begin() + _nb_lhs_ids_; iter != _ids_.end(); ++iter) {
530  if (deja)
531  str << " , ";
532  else {
533  deja = true;
534  str << " | ";
535  }
536  str << *iter;
537  }
538 
539  str << '}';
540 
541  return str.str();
542  }
543 
544 
545  /// returns the number of left hand side ids
546  template < template < typename > class ALLOC >
547  INLINE std::size_t IdCondSet< ALLOC >::nbLHSIds() const {
548  return _nb_lhs_ids_;
549  }
550 
551 
552  /// returns the number of right hand side ids
553  template < template < typename > class ALLOC >
554  INLINE std::size_t IdCondSet< ALLOC >::nbRHSIds() const {
555  return _ids_.size() - _nb_lhs_ids_;
556  }
557 
558 
559  /// indicates whether the IdCondSet contains the IdCondSet passed in argument
560  template < template < typename > class ALLOC >
561  bool IdCondSet< ALLOC >::contains(const IdCondSet< ALLOC >& set) const {
562  if (set._ids_.size() > _ids_.size()) return false;
563  for (const auto node: set._ids_) {
564  if (!_ids_.exists(node)) return false;
565  }
566  return true;
567  }
568 
569 
570  /// removes all the nodes from the IdCondSet
571  template < template < typename > class ALLOC >
572  INLINE void IdCondSet< ALLOC >::clear() {
573  _ids_.clear();
574  _nb_lhs_ids_ = std::size_t(0);
576  }
577 
578 
579  /// returns the number of variables (both left and right hand side)
580  template < template < typename > class ALLOC >
581  INLINE std::size_t IdCondSet< ALLOC >::size() const {
582  return _ids_.size();
583  }
584 
585 
586  /// returns the position of a given node in the IdCondSet
587  template < template < typename > class ALLOC >
588  INLINE std::size_t IdCondSet< ALLOC >::pos(const NodeId id) const {
589  return _ids_.pos(id);
590  }
591 
592 
593  /// indicates whether a given id is contained in the IdCondSet
594  template < template < typename > class ALLOC >
595  INLINE bool IdCondSet< ALLOC >::exists(const NodeId id) const {
596  return _ids_.exists(id);
597  }
598 
599 
600  /// indicates whether the idset contains a non-empty conditioning set
601  template < template < typename > class ALLOC >
602  INLINE bool IdCondSet< ALLOC >::hasConditioningSet() const {
603  return _nb_lhs_ids_ != _ids_.size();
604  }
605 
606 
607  /// indicates whether the IdCondSet contains some nodes or not
608  template < template < typename > class ALLOC >
609  INLINE bool IdCondSet< ALLOC >::empty() const {
610  return _ids_.empty();
611  }
612 
613 
614  // the display operator
615  template < template < typename > class ALLOC >
617  return stream << idset.toString();
618  }
619 
620  } /* namespace learning */
621 
622 
623  // Returns the value of a key as a Size.
624  template < template < typename > class ALLOC >
625  Size
626  HashFunc< learning::IdCondSet< ALLOC > >::castToSize(const learning::IdCondSet< ALLOC >& key) {
627  Size h = Size(key.nbLHSIds());
628  const Sequence< NodeId, ALLOC< NodeId > >& vect = key.ids();
629  const std::size_t size = vect.size();
630 
631  std::size_t i = std::size_t(0);
632  while (i < size) {
633  const Size id = Size(vect[i]);
634  ++i;
635  h += Size(i) * id;
636  }
637 
638  return h;
639  }
640 
641 
642  // the hash function for idSets
643  template < template < typename > class ALLOC >
644  INLINE Size HashFunc< learning::IdCondSet< ALLOC > >::operator()(
645  const learning::IdCondSet< ALLOC >& key) const {
646  return (castToSize(key) * HashFuncConst::gold) & this->hash_mask_;
647  }
648 
649 } /* namespace gum */
650 
651 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
Database(const std::string &filename, const BayesNet< GUM_SCALAR > &bn, const std::vector< std::string > &missing_symbols)