aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
PRMInstance_tpl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 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,
37  PRMClass< GUM_SCALAR >& type) :
38  PRMObject(name),
39  instantiated__(false), type__(&type) {
40  GUM_CONSTRUCTOR(PRMInstance);
41 
42  // First we create attributes for each aggregate in type
43  for (const auto agg: type__->aggregates())
44  copyAggregates__(agg);
45 
46  // We add attributes in type by reference for inner ones and by copy for
47  // output ones
48  for (const auto attr: type__->attributes())
49  copyAttribute__(attr);
50  }
51 
52  template < typename GUM_SCALAR >
55 
56  for (const auto& elt: nodeIdMap__)
57  delete elt.second;
58 
59  for (const auto& elt: referenceMap__)
60  delete elt.second;
61 
62  for (const auto& elt: referingAttr__)
63  delete elt.second;
64  }
65 
66  template < typename GUM_SCALAR >
68  if (!instantiated__) {
69  instantiated__ = true;
71  }
72  }
73 
74  template < typename GUM_SCALAR >
76  // First retrieving any referenced instance
77  for (const auto chain: type().slotChains()) {
79  }
80 
81  // Now we need to add referred instance to each input node
82  // For Attributes we first add parents, then we initialize CPF
83  for (const auto attr: type().attributes()) {
85  }
86 
87  // For PRMAggregate<GUM_SCALAR> we add parents
88  for (const auto agg: type().aggregates()) {
90 
91  for (const auto node: type().containerDag().parents(agg->id())) {
92  try {
94  } catch (NotFound&) {
95  auto elt = &(type().get(node));
96  auto sc = static_cast< PRMSlotChain< GUM_SCALAR >* >(elt);
97 
98  try {
99  const auto& instances = getInstances(sc->id());
100 
101  for (const auto inst: instances) {
103  }
104  } catch (NotFound&) { // there is no parents for this agg
105  }
106  }
107  }
108  }
109  }
110 
111  template < typename GUM_SCALAR >
113  PRMSlotChain< GUM_SCALAR >* sc) {
114  auto first_id = sc->chain()[0]->id();
115  if (!referenceMap__.exists(first_id)) { return; }
116  auto set
118  // We proceed with a width-first run of the slot chain
119  for (Size idx = 1; idx < sc->chain().size() - 1; ++idx) {
120  auto temp = new Set< PRMInstance< GUM_SCALAR >* >();
121  for (auto current: *set) {
122  auto& ref = current->type().get(sc->chain()[idx]->name());
123  for (auto next: *(current->referenceMap__[ref.id()])) {
124  temp->insert(next);
125  }
126  }
127  delete set;
128  set = temp;
129  }
130 
131  GUM_ASSERT(set->size() > 0);
132  // set contains all the instances references by sc
133  if (referenceMap__.exists(sc->id())) {
134  delete referenceMap__[sc->id()];
135  referenceMap__[sc->id()] = set;
136  } else {
138  }
139 
140  // Add refering instances
141  for (auto i: *set) {
143  }
144 
145  // If sc is not multiple so it can be added as a parent of an attribute
146  if (!sc->isMultiple()) {
147  // We should have only one instance
148  // Less ugly way to get the single instance in set
149  for (auto instance: *set) {
150  auto& attr = instance->get(sc->lastElt().safeName());
151  bijection__.insert(&(sc->type().variable()), &(attr.type().variable()));
152  }
153  }
154  }
155 
156  template < typename GUM_SCALAR >
160 
161  try {
162  elt = &(type().get(id));
163  } catch (NotFound&) {
164  GUM_ERROR(NotFound, "no ClassElement<GUM_SCALAR> matches the given id");
165  }
166 
167  switch (elt->elt_type()) {
170  = static_cast< PRMReferenceSlot< GUM_SCALAR >* >(elt);
171 
172  // Checking if instance's type is legal
173  if (!instance.type().isSubTypeOf(ref->slotType())) {
175  "given Instance type is not a proper "
176  "subclass of the ReferenceSlot<GUM_SCALAR> slot type");
177  }
178 
179  // Checking the reference's size limit
181  && (!static_cast< PRMReferenceSlot< GUM_SCALAR >& >(type().get(id))
182  .isArray())
183  && (referenceMap__[id]->size() == 1)) {
185  "ReferenceSlot<GUM_SCALAR> size limit reached");
186  }
187 
188  break;
189  }
190 
193  = static_cast< PRMSlotChain< GUM_SCALAR >& >(type().get(id));
194 
195  // Checking if instance's type is legal
196  if (!instance.type().isSubTypeOf(sc.end())) {
198  "given Instance type is not a proper "
199  "subclass of the ClassElementContainer pointed"
200  " by the SlotChain<GUM_SCALAR>");
201  }
202 
203  // Checking the reference's size limit
205  && (!static_cast< PRMSlotChain< GUM_SCALAR >& >(type().get(id))
206  .isMultiple())
207  && (referenceMap__[id]->size() == 1)) {
208  GUM_ERROR(OutOfUpperBound, "SlotChain<GUM_SCALAR> size limit reached");
209  }
210 
211  break;
212  }
213 
214  default: {
215  if (!type().isOutputNode(*elt)) {
217  "given ClassElement<GUM_SCALAR> is not an output node");
218  }
219  }
220  }
221 
222  if (!referenceMap__.exists(id)) {
224  }
225 
227  }
228 
229  template < typename GUM_SCALAR >
231  return nodeIdMap__.size();
232  }
233 
234  template < typename GUM_SCALAR >
237  auto attr = new PRMScalarAttribute< GUM_SCALAR >(source->name(),
238  source->type(),
239  source->buildImpl());
240  GUM_ASSERT(&(attr->type().variable()) != &(source->type().variable()));
241  attr->setId(source->id());
244  }
245 
246  template < typename GUM_SCALAR >
249  auto attr
251  GUM_ASSERT(&(attr->type().variable()) != &(source->type().variable()));
252  // The potential is copied when instantiate() is called
253  attr->cpf().fill((GUM_SCALAR)0);
254  attr->setId(source->id());
257  }
258 
259  template < typename GUM_SCALAR >
261  const PRMInstance< GUM_SCALAR >& source) :
262  PRMObject(source),
263  type__(source.type__) {
265  GUM_ERROR(FatalError, "do not copy Instance");
266  }
267 
268  template < typename GUM_SCALAR >
269  INLINE PRMInstance< GUM_SCALAR >& /**/
271  GUM_ERROR(FatalError, "do not copy Instance");
272  }
273 
274  template < typename GUM_SCALAR >
276  return PRMObject::prm_type::INSTANCE;
277  }
278 
279  template < typename GUM_SCALAR >
281  return *type__;
282  }
283 
284  template < typename GUM_SCALAR >
286  return *type__;
287  }
288 
289  template < typename GUM_SCALAR >
291  return nodeIdMap__.exists(id);
292  }
293 
294  template < typename GUM_SCALAR >
295  INLINE bool PRMInstance< GUM_SCALAR >::exists(const std::string& name) const {
296  return type__->exists(name) && exists(type__->get(name).id());
297  }
298 
299  template < typename GUM_SCALAR >
301  try {
302  return *(nodeIdMap__[id]);
303  } catch (NotFound&) {
304  GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given NodeId");
305  }
306  }
307 
308  template < typename GUM_SCALAR >
309  INLINE const PRMAttribute< GUM_SCALAR >&
311  try {
312  return *(nodeIdMap__[id]);
313  } catch (NotFound&) {
314  GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given NodeId");
315  }
316  }
317 
318  template < typename GUM_SCALAR >
321  try {
322  return *(nodeIdMap__[type().get(name).id()]);
323  } catch (NotFound&) {
324  GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given name");
325  }
326  }
327 
328  template < typename GUM_SCALAR >
329  INLINE const PRMAttribute< GUM_SCALAR >&
330  PRMInstance< GUM_SCALAR >::get(const std::string& name) const {
331  try {
332  return *(nodeIdMap__[type().get(name).id()]);
333  } catch (NotFound&) {
334  GUM_ERROR(NotFound, "no PRMAttribute<GUM_SCALAR> with the given name");
335  }
336  }
337 
338  template < typename GUM_SCALAR >
341  PRMInstance< GUM_SCALAR >* i) {
342  NodeId id = i->get(sc->lastElt().safeName()).id();
343  std::string name = sc->lastElt().safeName();
344 
345  try {
346  i->referenceMap__[id]->insert(this);
348  std::make_pair(this, sc->lastElt().safeName()));
349  } catch (NotFound&) {
351  i->referenceMap__[id]->insert(this);
352  i->referingAttr__.insert(id, new std::vector< pair >());
354  std::make_pair(this, sc->lastElt().safeName()));
355  }
356  }
357 
358  template < typename GUM_SCALAR >
359  INLINE const Bijection< const DiscreteVariable*, const DiscreteVariable* >&
361  return bijection__;
362  }
363 
364  template < typename GUM_SCALAR >
365  INLINE const PRMInstance< GUM_SCALAR >&
367  try {
368  if (referenceMap__[id]->size() > 0) {
369  return **(referenceMap__[id]->begin());
370  } else {
372  "no Instance associated with the given NodeId");
373  }
374  } catch (NotFound&) {
376  "no ReferenceSlot<GUM_SCALAR> or SlotChain<GUM_SCALAR> "
377  "matches the given NodeId");
378  }
379  }
380 
381  template < typename GUM_SCALAR >
382  INLINE const Set< PRMInstance< GUM_SCALAR >* >&
384  try {
385  return *(referenceMap__[id]);
386  } catch (NotFound&) {
388  "no ReferenceSlot<GUM_SCALAR> or SlotChain<GUM_SCALAR> "
389  "matches the given NodeId");
390  }
391  }
392 
393  template < typename GUM_SCALAR >
396  return nodeIdMap__.begin();
397  }
398 
399  template < typename GUM_SCALAR >
400  INLINE const typename PRMInstance< GUM_SCALAR >::iterator&
402  return nodeIdMap__.end();
403  }
404 
405  template < typename GUM_SCALAR >
408  return nodeIdMap__.begin();
409  }
410 
411  template < typename GUM_SCALAR >
412  INLINE const typename PRMInstance< GUM_SCALAR >::const_iterator&
413  PRMInstance< GUM_SCALAR >::end() const {
414  return nodeIdMap__.end();
415  }
416 
417  template < typename GUM_SCALAR >
420  try {
422  } catch (NotFound&) {
423  GUM_ERROR(NotFound, "no referred instances from this NodeId");
424  }
425  }
426 
427  template < typename GUM_SCALAR >
430  try {
432  } catch (NotFound&) {
433  GUM_ERROR(NotFound, "no referred instances from this NodeId");
434  }
435  }
436 
437  template < typename GUM_SCALAR >
439  Set< PRMInstance< GUM_SCALAR >* >& set) :
440  set__(set),
441  iter__(set.begin()) {
443  }
444 
445  template < typename GUM_SCALAR >
447  const RefIterator& from) :
448  set__(const_cast< Set< PRMInstance< GUM_SCALAR >* >& >(from.set__)),
449  iter__(from.iter__) {
451  }
452 
453  template < typename GUM_SCALAR >
456  }
457 
458  template < typename GUM_SCALAR >
461  iter__ = from.iter__;
462  return *this;
463  }
464 
465  template < typename GUM_SCALAR >
468  ++iter__;
469  return *this;
470  }
471 
472  template < typename GUM_SCALAR >
474  return iter__ == set__.end();
475  }
476 
477  template < typename GUM_SCALAR >
479  const RefIterator& from) const {
480  return iter__ != from.iter__;
481  }
482 
483  template < typename GUM_SCALAR >
485  const RefIterator& from) const {
486  return iter__ == from.iter__;
487  }
488 
489  template < typename GUM_SCALAR >
492  return **iter__;
493  }
494 
495  template < typename GUM_SCALAR >
498  return *iter__;
499  }
500 
501  template < typename GUM_SCALAR >
503  const Set< PRMInstance< GUM_SCALAR >* >& set) :
504  set__(set),
505  iter__(set.begin()) {
507  }
508 
509  template < typename GUM_SCALAR >
511  const RefConstIterator& from) :
512  set__(from.set__),
513  iter__(from.iter__) {
515  }
516 
517  template < typename GUM_SCALAR >
520  }
521 
522  template < typename GUM_SCALAR >
525  const RefConstIterator& from) {
526  iter__ = from.iter__;
527  return *this;
528  }
529 
530  template < typename GUM_SCALAR >
533  ++iter__;
534  return *this;
535  }
536 
537  template < typename GUM_SCALAR >
539  return iter__ == set__.end();
540  }
541 
542  template < typename GUM_SCALAR >
544  const RefConstIterator& from) const {
545  return iter__ != from.iter__;
546  }
547 
548  template < typename GUM_SCALAR >
550  const RefConstIterator& from) const {
551  return iter__ == from.iter__;
552  }
553 
554  template < typename GUM_SCALAR >
555  INLINE const PRMInstance< GUM_SCALAR >&
557  return **iter__;
558  }
559 
560  template < typename GUM_SCALAR >
561  INLINE const PRMInstance< GUM_SCALAR >*
563  return *iter__;
564  }
565 
566  template < typename GUM_SCALAR >
569  return referingAttr__.begin();
570  }
571 
572  template < typename GUM_SCALAR >
573  INLINE const typename PRMInstance< GUM_SCALAR >::InvRefIterator&
575  return referingAttr__.end();
576  }
577 
578  template < typename GUM_SCALAR >
581  return referingAttr__.begin();
582  }
583 
584  template < typename GUM_SCALAR >
587  return referingAttr__.end();
588  }
589 
590  template < typename GUM_SCALAR >
593  return *(referingAttr__[id]);
594  }
595 
596  template < typename GUM_SCALAR >
597  INLINE const
600  return *(referingAttr__[id]);
601  }
602 
603  template < typename GUM_SCALAR >
605  return referingAttr__.exists(id) && (!referingAttr__[id]->empty());
606  }
607 
608  template < typename GUM_SCALAR >
611  const auto& type_attr = static_cast< const PRMAttribute< GUM_SCALAR >& >(
612  type().get(attr->safeName()));
615  }
616 
617  } /* namespace prm */
618 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)