aGrUM  0.14.2
PRMInference_tpl.h
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
28 
29 namespace gum {
30  namespace prm {
31 
32  template < typename GUM_SCALAR >
34  for (const auto& elt : __evidences) {
35  for (const auto& elt2 : *elt.second)
36  delete elt2.second;
37 
38  delete elt.second;
39  }
40 
41  __evidences.clear();
42  }
43 
44  template < typename GUM_SCALAR >
46  const PRMInference< GUM_SCALAR >& source) :
47  _prm(source._prm),
48  _sys(source._sys) {
49  GUM_CONS_CPY(PRMInference);
50 
51  for (const auto& elt : source.__evidences) {
52  __evidences.insert(elt.first, new PRMInference< GUM_SCALAR >::EMap());
53 
54  for (const auto& elt2 : *elt.second) {
56  e->add(*(elt2.second->variablesSequence().front()));
57  Instantiation i(*e);
58 
59  for (i.setFirst(); !i.end(); i.inc())
60  e->set(i, elt2.second->get(i));
61 
62  __evidences[elt.first]->insert(elt2.first, e);
63  }
64  }
65  }
66 
67  template < typename GUM_SCALAR >
70  clearEvidence();
71  _prm = source._prm;
72  _sys = source._sys;
73 
74  for (const auto& elt : source.__evidences) {
75  __evidences.insert(elt.first, new PRMInference< GUM_SCALAR >::EMap());
76 
77  for (const auto& elt2 : *elt.second) {
79  e->add(*(elt2.second->variablesSequence().front()));
80  Instantiation i(*e);
81 
82  for (i.setFirst(); !i.end(); i.inc()) {
83  e->set(i, elt2.second->get(i));
84  }
85 
86  __evidences[elt.first]->insert(elt2.first, e);
87  }
88  }
89 
90  return *this;
91  }
92 
93  template < typename GUM_SCALAR >
96  if (__evidences.exists(i)) {
97  return *(__evidences[i]);
98  } else {
99  __evidences.insert(i, new PRMInference< GUM_SCALAR >::EMap());
100  return *(__evidences[i]);
101  }
102  }
103 
104  template < typename GUM_SCALAR >
105  void
107  const Potential< GUM_SCALAR >& p) {
108  if (chain.first->exists(chain.second->id())) {
109  if ((p.nbrDim() != 1) || (!p.contains(chain.second->type().variable())))
111  "illegal evidence for the given PRMAttribute.");
112 
114  e->add(chain.second->type().variable());
115  Instantiation i(*e);
116 
117  for (i.setFirst(); !i.end(); i.inc())
118  e->set(i, p.get(i));
119 
120  PRMInference< GUM_SCALAR >::EMap& emap = __EMap(chain.first);
121 
122  if (emap.exists(chain.second->id())) {
123  delete emap[chain.second->id()];
124  emap[chain.second->id()] = e;
125  } else {
126  emap.insert(chain.second->id(), e);
127  }
128 
129  _evidenceAdded(chain);
130  } else {
132  "the given PRMAttribute does not belong to this "
133  "Instance<GUM_SCALAR>.");
134  }
135  }
136 
137  template < typename GUM_SCALAR >
139  const PRM< GUM_SCALAR >& prm, const PRMSystem< GUM_SCALAR >& system) :
140  _prm(&prm),
141  _sys(&system) {
142  GUM_CONSTRUCTOR(PRMInference);
143  }
144 
145  template < typename GUM_SCALAR >
147  GUM_DESTRUCTOR(PRMInference);
148  clearEvidence();
149  }
150 
151  template < typename GUM_SCALAR >
152  INLINE typename PRMInference< GUM_SCALAR >::EMap&
154  try {
155  return *(__evidences[&i]);
156  } catch (NotFound&) {
157  GUM_ERROR(NotFound, "this instance has no evidence.");
158  }
159  }
160 
161  template < typename GUM_SCALAR >
162  INLINE const typename PRMInference< GUM_SCALAR >::EMap&
164  const PRMInstance< GUM_SCALAR >& i) const {
165  try {
166  return *(__evidences[&i]);
167  } catch (NotFound&) {
168  GUM_ERROR(NotFound, "this instance has no evidence.");
169  }
170  }
171 
172  template < typename GUM_SCALAR >
173  INLINE typename PRMInference< GUM_SCALAR >::EMap&
175  try {
176  return *(__evidences[i]);
177  } catch (NotFound&) {
178  GUM_ERROR(NotFound, "this instance has no evidence.");
179  }
180  }
181 
182  template < typename GUM_SCALAR >
183  INLINE const typename PRMInference< GUM_SCALAR >::EMap&
185  const PRMInstance< GUM_SCALAR >* i) const {
186  try {
187  return *(__evidences[i]);
188  } catch (NotFound&) {
189  GUM_ERROR(NotFound, "this instance has no evidence.");
190  }
191  }
192 
193  template < typename GUM_SCALAR >
195  const PRMInstance< GUM_SCALAR >& i) const {
196  return __evidences.exists(&i);
197  }
198 
199  template < typename GUM_SCALAR >
201  const PRMInstance< GUM_SCALAR >* i) const {
202  return __evidences.exists(i);
203  }
204 
205  template < typename GUM_SCALAR >
206  INLINE bool PRMInference< GUM_SCALAR >::hasEvidence(const Chain& chain) const {
207  return (hasEvidence(chain.first))
208  ? evidence(chain.first).exists(chain.second->id())
209  : false;
210  }
211 
212  template < typename GUM_SCALAR >
214  return (__evidences.size() != (Size)0);
215  }
216 
217  template < typename GUM_SCALAR >
219  try {
220  if (__EMap(chain.first).exists(chain.second->id())) {
221  _evidenceRemoved(chain);
222  delete __EMap(chain.first)[chain.second->id()];
223  __EMap(chain.first).erase(chain.second->id());
224  }
225  } catch (NotFound&) {
226  // Ok, we are only removing
227  }
228  }
229 
230  template < typename GUM_SCALAR >
232  const typename PRMInference< GUM_SCALAR >::Chain& chain,
234  if (m.nbrDim() > 0) {
235  GUM_ERROR(OperationNotAllowed, "the given Potential is not empty.");
236  }
237 
238  if (hasEvidence(chain)) {
239  m.add(chain.second->type().variable());
240  const Potential< GUM_SCALAR >& e =
241  *(evidence(chain.first)[chain.second->id()]);
242  Instantiation i(m), j(e);
243 
244  for (i.setFirst(), j.setFirst(); !i.end(); i.inc(), j.inc())
245  m.set(i, e.get(j));
246  } else {
247  if (chain.second != &(chain.first->get(chain.second->safeName()))) {
248  typename PRMInference< GUM_SCALAR >::Chain good_chain = std::make_pair(
249  chain.first, &(chain.first->get(chain.second->safeName())));
250  m.add(good_chain.second->type().variable());
251  _marginal(good_chain, m);
252  } else {
253  m.add(chain.second->type().variable());
254  _marginal(chain, m);
255  }
256  }
257  }
258 
259  template < typename GUM_SCALAR >
261  const std::vector< typename PRMInference< GUM_SCALAR >::Chain >& chains,
263  if (j.nbrDim() > 0) {
264  GUM_ERROR(OperationNotAllowed, "the given Potential is not empty.");
265  }
266 
267  for (auto chain = chains.begin(); chain != chains.end(); ++chain) {
268  j.add(chain->second->type().variable());
269  }
270 
271  _joint(chains, j);
272  }
273 
274  } /* namespace prm */
275 } /* namespace gum */
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:57
virtual Idx nbrDim() const final
Returns the number of vars in the multidimensional container.
virtual GUM_SCALAR get(const Instantiation &i) const final
Default implementation of MultiDimContainer::get().
HashTable< const PRMInstance< GUM_SCALAR > *, EMap *> __evidences
Mapping of evidence over PRMInstance<GUM_SCALAR>&#39;s nodes.
Definition: PRMInference.h:232
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Definition: PRMInstance.h:60
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
PRMInference(const PRM< GUM_SCALAR > &prm, const PRMSystem< GUM_SCALAR > &system)
Default constructor.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
PRM< GUM_SCALAR > const * _prm
The PRM<GUM_SCALAR> on which inference is done.
Definition: PRMInference.h:210
The class for generic Hash Tables.
Definition: hashTable.h:676
void inc()
Operator increment.
void clearEvidence()
Remove all evidences.
Headers of PRMInference.
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition: PRMObject.h:226
PRMSystem< GUM_SCALAR > const * _sys
The Model on which inference is done.
Definition: PRMInference.h:213
std::pair< const PRMInstance< double > *, const PRMAttribute< double > * > Chain
Code alias.
Definition: PRMInference.h:54
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
virtual void add(const DiscreteVariable &v) final
Adds a new var to the variables of the multidimensional matrix.
This abstract class is used as base class for all inference class on PRM<GUM_SCALAR>.
Definition: PRMInference.h:49
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:63
virtual void set(const Instantiation &i, const GUM_SCALAR &value) const final
Default implementation of MultiDimContainer::set().
void setFirst()
Assign the first values to the tuple of the Instantiation.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
virtual bool contains(const DiscreteVariable &var) const final
Returns true if var is in *this.
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
bool end() const
Returns true if the Instantiation reached the end.