aGrUM  0.14.2
structuredBayesBall_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  GUM_DESTRUCTOR(StructuredBayesBall);
35 
36  for (const auto& elt : __reqMap)
37  delete elt.second.first;
38  }
39 
40  template < typename GUM_SCALAR >
42  for (const auto& elt : __reqMap)
43  delete elt.second.first;
44 
45  __keyMap.clear();
46  __reqMap.clear();
47  }
48 
49  template < typename GUM_SCALAR >
51  const PRMInstance< GUM_SCALAR >* i, NodeId n) {
52  try {
53  typename PRMInference< GUM_SCALAR >::Chain chain =
54  std::make_pair(i, &(i->get(n)));
55 
56  if (__inf->hasEvidence(chain)) {
57  const Potential< GUM_SCALAR >* e = __inf->evidence(i)[n];
58  Instantiation inst(e);
59  Size count = 0;
60 
61  for (inst.setFirst(); !inst.end(); inst.inc()) {
62  if ((e->get(inst) == (GUM_SCALAR)1.0))
63  ++count;
64  else if (e->get(inst) != (GUM_SCALAR)0.0)
65  return false;
66  }
67 
68  return (count == 1);
69  }
70 
71  return false;
72  } catch (NotFound&) { return false; }
73  }
74 
75  template < typename GUM_SCALAR >
77  const PRMInstance< GUM_SCALAR >* i, NodeId n) {
78  __clean();
82  __fromChild(i, n, marks);
83  __fillMaps(marks);
84 
85  for (const auto& elt : marks)
86  delete elt.second;
87  }
88 
89  template < typename GUM_SCALAR >
91  const PRMInstance< GUM_SCALAR >* i, NodeId n, InstanceMap& marks) {
92  if (!marks.exists(i)) {
94  }
95 
96  if (!marks[i]->exists(n)) {
97  marks[i]->insert(n, std::pair< bool, bool >(false, false));
98  }
99 
100  // Sending message to parents
101  switch (i->type().get(n).elt_type()) {
103  if (!__getMark(marks, i, n).first) {
104  __getMark(marks, i, n).first = true;
105 
106  for (const auto inst : i->getInstances(n))
107  __fromChild(
108  inst, inst->get(__getSC(i, n).lastElt().safeName()).id(), marks);
109  }
110 
111  if (!__getMark(marks, i, n).second) {
112  __getMark(marks, i, n).second = true;
113 
114  for (const auto chi : i->type().containerDag().children(n))
115  __fromParent(i, chi, marks);
116  }
117 
118  break;
119  }
120 
123  if (!__getMark(marks, i, n).first) {
124  __getMark(marks, i, n).first = true;
125 
126  if (!__isHardEvidence(i, n))
127  for (const auto par : i->type().containerDag().parents(n))
128  __fromChild(i, par, marks);
129  }
130 
131  if (!__getMark(marks, i, n).second) {
132  __getMark(marks, i, n).second = true;
133 
134  // In i.
135  for (const auto chi : i->type().containerDag().children(n))
136  __fromParent(i, chi, marks);
137 
138  // Out of i.
139  try {
140  const auto& refs = i->getRefAttr(n);
141 
142  for (auto iter = refs.begin(); iter != refs.end(); ++iter)
143  __fromParent(
144  iter->first, iter->first->type().get(iter->second).id(), marks);
145  } catch (NotFound&) {
146  // Not an inverse sc
147  }
148  }
149 
150  break;
151  }
152 
153  default: {
154  // We shouldn't reach any other PRMClassElement<GUM_DATA> than
155  // PRMAttribute
156  // or
157  // PRMSlotChain<GUM_SCALAR>.
158  GUM_ERROR(FatalError, "This case is impossible.");
159  }
160  }
161  }
162 
163  template < typename GUM_SCALAR >
165  const PRMInstance< GUM_SCALAR >* i, NodeId n, InstanceMap& marks) {
166  if (!marks.exists(i)) {
168  }
169 
170  if (!marks[i]->exists(n)) {
171  marks[i]->insert(n, std::pair< bool, bool >(false, false));
172  }
173 
174  // Concerns only PRMAttribute (because of the hard evidence)
175  if ((__isHardEvidence(i, n)) && (!__getMark(marks, i, n).first)) {
176  __getMark(marks, i, n).first = true;
177 
178  for (const auto par : i->type().containerDag().parents(n))
179  __fromChild(i, par, marks);
180  } else if (!__getMark(marks, i, n).second) {
181  __getMark(marks, i, n).second = true;
182 
183  // In i.
184  for (const auto chi : i->type().containerDag().children(n))
185  __fromParent(i, chi, marks);
186 
187  // Out of i.
188  try {
189  for (auto iter = i->getRefAttr(n).begin();
190  iter != i->getRefAttr(n).end();
191  ++iter)
192  __fromParent(
193  iter->first, iter->first->type().get(iter->second).id(), marks);
194  } catch (NotFound&) {
195  // Not an inverse sc
196  }
197  }
198  }
199 
200  template < typename GUM_SCALAR >
202  // First find for each instance it's requisite nodes
204 
205  for (const auto& elt : marks) {
206  Set< NodeId >* req_set = new Set< NodeId >();
207 
208  for (const auto& elt2 : *elt.second)
209  if (elt2.second.first) req_set->insert(elt2.first);
210 
211  req_map.insert(elt.first, req_set);
212  }
213 
214  // Remove all instances with 0 requisite nodes
216 
217  for (const auto& elt : req_map)
218  if (elt.second->size() == 0) to_remove.insert(elt.first);
219 
220  for (const auto remo : to_remove) {
221  delete req_map[remo];
222  req_map.erase(remo);
223  }
224 
225  // Fill __reqMap and __keyMap
226  for (const auto& elt : req_map) {
227  std::string key = __buildHashKey(elt.first, *elt.second);
228 
229  if (__reqMap.exists(key)) {
230  __keyMap.insert(
231  elt.first,
232  std::pair< std::string, Set< NodeId >* >(key, __reqMap[key].first));
233  __reqMap[key].second += 1;
234  delete elt.second;
235  req_map[elt.first] = 0;
236  } else {
237  __reqMap.insert(key, std::pair< Set< NodeId >*, Size >(elt.second, 1));
238  __keyMap.insert(
239  elt.first, std::pair< std::string, Set< NodeId >* >(key, elt.second));
240  }
241  }
242  }
243 
244  template < typename GUM_SCALAR >
246  const PRMInstance< GUM_SCALAR >* i, Set< NodeId >& req_nodes) {
247  std::stringstream sBuff;
248  sBuff << i->type().name();
249 
250  for (const auto node : i->type().containerDag().nodes())
251  if (req_nodes.exists(node)) sBuff << "-" << node;
252 
253  return sBuff.str();
254  }
255 
256  template < typename GUM_SCALAR >
258  const PRMInference< GUM_SCALAR >& inference) :
259  __inf(&inference) {
260  GUM_CONSTRUCTOR(StructuredBayesBall);
261  }
262 
263  template < typename GUM_SCALAR >
265  const StructuredBayesBall< GUM_SCALAR >& source) :
266  __inf(0) {
267  GUM_CONS_CPY(StructuredBayesBall);
268  GUM_ERROR(FatalError, "Not allowed.");
269  }
270 
271  template < typename GUM_SCALAR >
274  GUM_ERROR(FatalError, "Not allowed.");
275  }
276 
277  template < typename GUM_SCALAR >
278  INLINE const std::string& StructuredBayesBall< GUM_SCALAR >::key(
279  const PRMInstance< GUM_SCALAR >* i) const {
280  return __keyMap[i].first;
281  }
282 
283  template < typename GUM_SCALAR >
284  INLINE const std::string& StructuredBayesBall< GUM_SCALAR >::key(
285  const PRMInstance< GUM_SCALAR >& i) const {
286  return __keyMap[&i].first;
287  }
288 
289  template < typename GUM_SCALAR >
291  const PRMInstance< GUM_SCALAR >* i) const {
292  return *(__keyMap[i].second);
293  }
294 
295  template < typename GUM_SCALAR >
297  const PRMInstance< GUM_SCALAR >& i) const {
298  return *(__keyMap[&i].second);
299  }
300 
301  template < typename GUM_SCALAR >
303  const std::string& key) const {
304  return __reqMap[key].second;
305  }
306 
307  template < typename GUM_SCALAR >
309  return ((float)__reqMap.size()) / ((float)__keyMap.size());
310  }
311 
312  template < typename GUM_SCALAR >
314  const PRMInstance< GUM_SCALAR >* i) const {
315  return __keyMap.exists(i);
316  }
317 
318  template < typename GUM_SCALAR >
320  const PRMInstance< GUM_SCALAR >& i) const {
321  return __keyMap.exists(&i);
322  }
323 
324  template < typename GUM_SCALAR >
326  const PRMInstance< GUM_SCALAR >* i, NodeId n) {
327  __compute(i, n);
328  }
329 
330  template < typename GUM_SCALAR >
332  const PRMInstance< GUM_SCALAR >& i, NodeId n) {
333  __compute(&i, n);
334  }
335 
336  template < typename GUM_SCALAR >
337  INLINE const PRMSlotChain< GUM_SCALAR >&
339  const PRMInstance< GUM_SCALAR >* i, NodeId n) {
340  return static_cast< const PRMSlotChain< GUM_SCALAR >& >(i->type().get(n));
341  }
342 
343  template < typename GUM_SCALAR >
344  INLINE std::pair< bool, bool >& StructuredBayesBall< GUM_SCALAR >::__getMark(
345  InstanceMap& marks, const PRMInstance< GUM_SCALAR >* i, NodeId n) {
346  return (*(marks[i]))[n];
347  }
348 
349  } /* namespace prm */
350 } /* namespace gum */
aGrUM&#39;s Potential is a multi-dimensional array with tensor operators.
Definition: potential.h:57
<agrum/PRM/structuredBayesBall.h>
PRMAttribute< GUM_SCALAR > & get(NodeId id)
Getter on an PRMAttribute<GUM_SCALAR> of this PRMInstance<GUM_SCALAR>.
virtual GUM_SCALAR get(const Instantiation &i) const final
Default implementation of MultiDimContainer::get().
const Set< NodeId > & requisiteNodes(const PRMInstance< GUM_SCALAR > *i) const
Returns the set of requisite nodes w.r.t. d-separation for i.
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Definition: PRMInstance.h:60
PRMClass< GUM_SCALAR > & type()
Returns the type of this instance.
Abstract class representing an element of PRM class.
std::pair< bool, bool > & __getMark(InstanceMap &marks, const PRMInstance< GUM_SCALAR > *i, NodeId n)
Code alias.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
void compute(const PRMInstance< GUM_SCALAR > *i, NodeId n)
Compute the set or requisite nodes for each required instance given the current set of observations...
bool __isHardEvidence(const PRMInstance< GUM_SCALAR > *i, NodeId n)
Returns true if there is a hard evidence on i->get(n).
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
HashTable< const PRMInstance< GUM_SCALAR > *, std::pair< std::string, Set< NodeId > *> > __keyMap
Associate an PRMInstance<GUM_SCALAR> with a unique key w.r.t. d-separation and the set of requisite n...
The class for generic Hash Tables.
Definition: hashTable.h:676
HashTable< std::string, std::pair< Set< NodeId > *, Size > > __reqMap
Associate a Key with the set of requisite nodes associated with it. The Size value is the number of i...
void __fillMaps(InstanceMap &marks)
Fill __keyMap and __reqMap.
bool exists(const PRMInstance< GUM_SCALAR > *i) const
Returns true if i has requisite nodes.
std::vector< std::pair< PRMInstance< GUM_SCALAR > *, std::string > > & getRefAttr(NodeId id)
Returns a vector of pairs of refering attributes of id.
bool exists(const Key &k) const
Indicates whether a given elements belong to the set.
Definition: set_tpl.h:604
void inc()
Operator increment.
void __fromChild(const PRMInstance< GUM_SCALAR > *i, NodeId n, InstanceMap &marks)
When the ball is received on i->get(n) from a child.
Size occurrence(const std::string &key) const
Returns the number of occurrence of the given key, which is the number of PRMInstance<GUM_SCALAR> sha...
Headers of StructuredBayesBall.
StructuredBayesBall & operator=(const StructuredBayesBall &source)
Copy operator.
std::string __buildHashKey(const PRMInstance< GUM_SCALAR > *i, Set< NodeId > &req_nodes)
Builds the HashKey for the given instance and requisite nodes set.
A PRMSlotChain represents a sequence of gum::prm::PRMClassElement<GUM_SCALAR> where the n-1 first gum...
Definition: PRMObject.h:218
const std::string & key(const PRMInstance< GUM_SCALAR > *i) const
Returns a unique key w.r.t. d-separation for i.
void __clean()
Cleans this before a new computation.
const PRMSlotChain< GUM_SCALAR > & __getSC(const PRMInstance< GUM_SCALAR > *i, NodeId n)
Code alias.
std::pair< const PRMInstance< GUM_SCALAR > *, const PRMAttribute< GUM_SCALAR > *> Chain
Code alias.
Definition: PRMInference.h:54
Class for assigning/browsing values to tuples of discrete variables.
Definition: instantiation.h:80
This abstract class is used as base class for all inference class on PRM<GUM_SCALAR>.
Definition: PRMInference.h:49
StructuredBayesBall(const PRMInference< GUM_SCALAR > &inference)
Default Constructor.
void setFirst()
Assign the first values to the tuple of the Instantiation.
const PRMInference< GUM_SCALAR > * __inf
The PRM at which __model belongs.
void __compute(const PRMInstance< GUM_SCALAR > *i, NodeId n)
The real compute method.
float liftRatio() const
Returns the ratio between the total number of instances and the number of instances with the same con...
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.
void __fromParent(const PRMInstance< GUM_SCALAR > *i, NodeId n, InstanceMap &marks)
When the ball is receive on i->get(n) from a parent.
Size NodeId
Type for node ids.
Definition: graphElements.h:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
const Set< PRMInstance< GUM_SCALAR > *> & getInstances(NodeId id) const
Returns the Set of PRMInstance<GUM_SCALAR> referenced by id.
bool end() const
Returns true if the Instantiation reached the end.