aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
PRMInstance_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 /**
23  * @file
24  * @brief Inline implementation of gum::PRMInstance
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #include <agrum/PRM/elements/PRMInstance.h>
30 
31 #include <agrum/tools/multidim/implementations/multiDimSparse.h>
32 
33 namespace gum {
34  namespace prm {
35  template < typename GUM_SCALAR >
36  PRMInstance< GUM_SCALAR >::PRMInstance(const std::string& name, PRMClass< GUM_SCALAR >& type) :
37  PRMObject(name), _instantiated_(false), _type_(&type) {
38  GUM_CONSTRUCTOR(PRMInstance);
39 
40  // First we create attributes for each aggregate in type
41  for (const auto agg: _type_->aggregates())
42  _copyAggregates_(agg);
43 
44  // We add attributes in type by reference for inner ones and by copy for
45  // output ones
46  for (const auto attr: _type_->attributes())
47  _copyAttribute_(attr);
48  }
49 
50  template < typename GUM_SCALAR >
53 
54  for (const auto& elt: _nodeIdMap_)
55  delete elt.second;
56 
57  for (const auto& elt: _referenceMap_)
58  delete elt.second;
59 
60  for (const auto& elt: _referingAttr_)
61  delete elt.second;
62  }
63 
64  template < typename GUM_SCALAR >
66  if (!_instantiated_) {
67  _instantiated_ = true;
69  }
70  }
71 
72  template < typename GUM_SCALAR >
74  // First retrieving any referenced instance
75  for (const auto chain: type().slotChains()) {
77  }
78 
79  // Now we need to add referred instance to each input node
80  // For Attributes we first add parents, then we initialize CPF
81  for (const auto attr: type().attributes()) {
83  }
84 
85  // For PRMAggregate<GUM_SCALAR> we add parents
86  for (const auto agg: type().aggregates()) {
88 
89  for (const auto node: type().containerDag().parents(agg->id())) {
90  try {
92  } catch (NotFound&) {
93  auto elt = &(type().get(node));
94  auto sc = static_cast< PRMSlotChain< GUM_SCALAR >* >(elt);
95 
96  try {
97  const auto& instances = getInstances(sc->id());
98 
99  for (const auto inst: instances) {
101  }
102  } catch (NotFound&) { // there is no parents for this agg
103  }
104  }
105  }
106  }
107  }
108 
109  template < typename GUM_SCALAR >
111  auto first_id = sc->chain()[0]->id();
112  if (!_referenceMap_.exists(first_id)) { return; }
113  auto set = new Set< PRMInstance< GUM_SCALAR >* >(*(_referenceMap_[first_id]));
114  // We proceed with a width-first run of the slot chain
115  for (Size idx = 1; idx < sc->chain().size() - 1; ++idx) {
116  auto temp = new Set< PRMInstance< GUM_SCALAR >* >();
117  for (auto current: *set) {
118  auto& ref = current->type().get(sc->chain()[idx]->name());
119  for (auto next: *(current->_referenceMap_[ref.id()])) {
120  temp->insert(next);
121  }
122  }
123  delete set;
124  set = temp;
125  }
126 
127  GUM_ASSERT(set->size() > 0);
128  // set contains all the instances references by sc
129  if (_referenceMap_.exists(sc->id())) {
130  delete _referenceMap_[sc->id()];
131  _referenceMap_[sc->id()] = set;
132  } else {
134  }
135 
136  // Add refering instances
137  for (auto i: *set) {
139  }
140 
141  // If sc is not multiple so it can be added as a parent of an attribute
142  if (!sc->isMultiple()) {
143  // We should have only one instance
144  // Less ugly way to get the single instance in set
145  for (auto instance: *set) {
146  auto& attr = instance->get(sc->lastElt().safeName());
147  _bijection_.insert(&(sc->type().variable()), &(attr.type().variable()));
148  }
149  }
150  }
151 
152  template < typename GUM_SCALAR >
155 
156  try {
157  elt = &(type().get(id));
158  } catch (NotFound&) {
159  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> matches the given id")
160  }
161 
162  switch (elt->elt_type()) {
164  PRMReferenceSlot< GUM_SCALAR >* ref = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(elt);
165 
166  // Checking if instance's type is legal
167  if (!instance.type().isSubTypeOf(ref->slotType())) {
169  "given Instance type is not a proper "
170  "subclass of the ReferenceSlot<GUM_SCALAR> slot type");
171  }
172 
173  // Checking the reference's size limit
175  && (!static_cast< PRMReferenceSlot< GUM_SCALAR >& >(type().get(id)).isArray())
176  && (_referenceMap_[id]->size() == 1)) {
177  GUM_ERROR(OutOfUpperBound, "ReferenceSlot<GUM_SCALAR> size limit reached")
178  }
179 
180  break;
181  }
182 
185  = static_cast< PRMSlotChain< GUM_SCALAR >& >(type().get(id));
186 
187  // Checking if instance's type is legal
188  if (!instance.type().isSubTypeOf(sc.end())) {
190  "given Instance type is not a proper "
191  "subclass of the ClassElementContainer pointed"
192  " by the SlotChain<GUM_SCALAR>");
193  }
194 
195  // Checking the reference's size limit
197  && (!static_cast< PRMSlotChain< GUM_SCALAR >& >(type().get(id)).isMultiple())
198  && (_referenceMap_[id]->size() == 1)) {
199  GUM_ERROR(OutOfUpperBound, "SlotChain<GUM_SCALAR> size limit reached")
200  }
201 
202  break;
203  }
204 
205  default: {
206  if (!type().isOutputNode(*elt)) {
207  GUM_ERROR(WrongClassElement, "given ClassElement<GUM_SCALAR> is not an output node")
208  }
209  }
210  }
211 
212  if (!_referenceMap_.exists(id)) {
214  }
215 
217  }
218 
219  template < typename GUM_SCALAR >
221  return _nodeIdMap_.size();
222  }
223 
224  template < typename GUM_SCALAR >
226  auto attr = new PRMScalarAttribute< GUM_SCALAR >(source->name(),
227  source->type(),
228  source->buildImpl());
229  GUM_ASSERT(&(attr->type().variable()) != &(source->type().variable()));
230  attr->setId(source->id());
233  }
234 
235  template < typename GUM_SCALAR >
237  auto attr = new PRMScalarAttribute< GUM_SCALAR >(source->name(), source->type());
238  GUM_ASSERT(&(attr->type().variable()) != &(source->type().variable()));
239  // The potential is copied when instantiate() is called
240  attr->cpf().fill((GUM_SCALAR)0);
241  attr->setId(source->id());
244  }
245 
246  template < typename GUM_SCALAR >
250  GUM_ERROR(FatalError, "do not copy Instance")
251  }
252 
253  template < typename GUM_SCALAR >
254  INLINE PRMInstance< GUM_SCALAR >& /**/
256  GUM_ERROR(FatalError, "do not copy Instance")
257  }
258 
259  template < typename GUM_SCALAR >
261  return PRMObject::prm_type::INSTANCE;
262  }
263 
264  template < typename GUM_SCALAR >
266  return *_type_;
267  }
268 
269  template < typename GUM_SCALAR >
271  return *_type_;
272  }
273 
274  template < typename GUM_SCALAR >
276  return _nodeIdMap_.exists(id);
277  }
278 
279  template < typename GUM_SCALAR >
280  INLINE bool PRMInstance< GUM_SCALAR >::exists(const std::string& name) const {
281  return _type_->exists(name) && exists(_type_->get(name).id());
282  }
283 
284  template < typename GUM_SCALAR >
286  try {
287  return *(_nodeIdMap_[id]);
288  } catch (NotFound&) {
289  GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given NodeId")
290  }
291  }
292 
293  template < typename GUM_SCALAR >
295  try {
296  return *(_nodeIdMap_[id]);
297  } catch (NotFound&) {
298  GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given NodeId")
299  }
300  }
301 
302  template < typename GUM_SCALAR >
304  try {
305  return *(_nodeIdMap_[type().get(name).id()]);
306  } catch (NotFound&) { GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given name") }
307  }
308 
309  template < typename GUM_SCALAR >
310  INLINE const PRMAttribute< GUM_SCALAR >&
311  PRMInstance< GUM_SCALAR >::get(const std::string& name) const {
312  try {
313  return *(_nodeIdMap_[type().get(name).id()]);
314  } catch (NotFound&) { GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given name") }
315  }
316 
317  template < typename GUM_SCALAR >
319  PRMInstance< GUM_SCALAR >* i) {
320  NodeId id = i->get(sc->lastElt().safeName()).id();
321  std::string name = sc->lastElt().safeName();
322 
323  try {
324  i->_referenceMap_[id]->insert(this);
326  } catch (NotFound&) {
328  i->_referenceMap_[id]->insert(this);
329  i->_referingAttr_.insert(id, new std::vector< pair >());
331  }
332  }
333 
334  template < typename GUM_SCALAR >
335  INLINE const Bijection< const DiscreteVariable*, const DiscreteVariable* >&
337  return _bijection_;
338  }
339 
340  template < typename GUM_SCALAR >
341  INLINE const PRMInstance< GUM_SCALAR >&
343  try {
344  if (_referenceMap_[id]->size() > 0) {
345  return **(_referenceMap_[id]->begin());
346  } else {
347  GUM_ERROR(UndefinedElement, "no Instance associated with the given NodeId")
348  }
349  } catch (NotFound&) {
351  "no ReferenceSlot<GUM_SCALAR> or SlotChain<GUM_SCALAR> "
352  "matches the given NodeId");
353  }
354  }
355 
356  template < typename GUM_SCALAR >
357  INLINE const Set< PRMInstance< GUM_SCALAR >* >&
359  try {
360  return *(_referenceMap_[id]);
361  } catch (NotFound&) {
363  "no ReferenceSlot<GUM_SCALAR> or SlotChain<GUM_SCALAR> "
364  "matches the given NodeId");
365  }
366  }
367 
368  template < typename GUM_SCALAR >
370  return _nodeIdMap_.begin();
371  }
372 
373  template < typename GUM_SCALAR >
375  return _nodeIdMap_.end();
376  }
377 
378  template < typename GUM_SCALAR >
381  return _nodeIdMap_.begin();
382  }
383 
384  template < typename GUM_SCALAR >
385  INLINE const typename PRMInstance< GUM_SCALAR >::const_iterator&
386  PRMInstance< GUM_SCALAR >::end() const {
387  return _nodeIdMap_.end();
388  }
389 
390  template < typename GUM_SCALAR >
393  try {
395  } catch (NotFound&) { GUM_ERROR(NotFound, "no referred instances from this NodeId") }
396  }
397 
398  template < typename GUM_SCALAR >
401  try {
403  } catch (NotFound&) { GUM_ERROR(NotFound, "no referred instances from this NodeId") }
404  }
405 
406  template < typename GUM_SCALAR >
407  INLINE
409  _set_(set),
410  _iter_(set.begin()) {
412  }
413 
414  template < typename GUM_SCALAR >
416  _set_(const_cast< Set< PRMInstance< GUM_SCALAR >* >& >(from._set_)), _iter_(from._iter_) {
418  }
419 
420  template < typename GUM_SCALAR >
423  }
424 
425  template < typename GUM_SCALAR >
428  _iter_ = from._iter_;
429  return *this;
430  }
431 
432  template < typename GUM_SCALAR >
435  ++_iter_;
436  return *this;
437  }
438 
439  template < typename GUM_SCALAR >
441  return _iter_ == _set_.end();
442  }
443 
444  template < typename GUM_SCALAR >
446  return _iter_ != from._iter_;
447  }
448 
449  template < typename GUM_SCALAR >
451  return _iter_ == from._iter_;
452  }
453 
454  template < typename GUM_SCALAR >
456  return **_iter_;
457  }
458 
459  template < typename GUM_SCALAR >
461  return *_iter_;
462  }
463 
464  template < typename GUM_SCALAR >
466  const Set< PRMInstance< GUM_SCALAR >* >& set) :
467  _set_(set),
468  _iter_(set.begin()) {
470  }
471 
472  template < typename GUM_SCALAR >
473  INLINE
475  _set_(from._set_),
476  _iter_(from._iter_) {
478  }
479 
480  template < typename GUM_SCALAR >
483  }
484 
485  template < typename GUM_SCALAR >
488  _iter_ = from._iter_;
489  return *this;
490  }
491 
492  template < typename GUM_SCALAR >
495  ++_iter_;
496  return *this;
497  }
498 
499  template < typename GUM_SCALAR >
501  return _iter_ == _set_.end();
502  }
503 
504  template < typename GUM_SCALAR >
505  INLINE bool
507  return _iter_ != from._iter_;
508  }
509 
510  template < typename GUM_SCALAR >
511  INLINE bool
513  return _iter_ == from._iter_;
514  }
515 
516  template < typename GUM_SCALAR >
517  INLINE const PRMInstance< GUM_SCALAR >&
519  return **_iter_;
520  }
521 
522  template < typename GUM_SCALAR >
523  INLINE const PRMInstance< GUM_SCALAR >*
525  return *_iter_;
526  }
527 
528  template < typename GUM_SCALAR >
531  return _referingAttr_.begin();
532  }
533 
534  template < typename GUM_SCALAR >
535  INLINE const typename PRMInstance< GUM_SCALAR >::InvRefIterator&
537  return _referingAttr_.end();
538  }
539 
540  template < typename GUM_SCALAR >
543  return _referingAttr_.begin();
544  }
545 
546  template < typename GUM_SCALAR >
549  return _referingAttr_.end();
550  }
551 
552  template < typename GUM_SCALAR >
555  return *(_referingAttr_[id]);
556  }
557 
558  template < typename GUM_SCALAR >
559  INLINE const std::vector< std::pair< PRMInstance< GUM_SCALAR >*, std::string > >&
561  return *(_referingAttr_[id]);
562  }
563 
564  template < typename GUM_SCALAR >
566  return _referingAttr_.exists(id) && (!_referingAttr_[id]->empty());
567  }
568 
569  template < typename GUM_SCALAR >
571  const auto& type_attr
572  = static_cast< const PRMAttribute< GUM_SCALAR >& >(type().get(attr->safeName()));
575  }
576 
577  } /* namespace prm */
578 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)