aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
structuredBayesBall_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 StructuredBayesBall.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 #include <agrum/PRM/inference/structuredBayesBall.h>
30 
31 namespace gum {
32  namespace prm {
33 
34  template < typename GUM_SCALAR >
37 
38  for (const auto& elt: _reqMap_)
39  delete elt.second.first;
40  }
41 
42  template < typename GUM_SCALAR >
44  for (const auto& elt: _reqMap_)
45  delete elt.second.first;
46 
47  _keyMap_.clear();
48  _reqMap_.clear();
49  }
50 
51  template < typename GUM_SCALAR >
53  NodeId n) {
54  try {
55  typename PRMInference< GUM_SCALAR >::Chain chain = std::make_pair(i, &(i->get(n)));
56 
57  if (_inf_->hasEvidence(chain)) {
58  const Potential< GUM_SCALAR >* e = _inf_->evidence(i)[n];
60  Size count = 0;
61 
62  for (inst.setFirst(); !inst.end(); inst.inc()) {
63  if ((e->get(inst) == (GUM_SCALAR)1.0))
64  ++count;
65  else if (e->get(inst) != (GUM_SCALAR)0.0)
66  return false;
67  }
68 
69  return (count == 1);
70  }
71 
72  return false;
73  } catch (NotFound&) { return false; }
74  }
75 
76  template < typename GUM_SCALAR >
78  NodeId n) {
79  _clean_();
80  /// Key = instance.PRMClassElement<GUM_DATA>
81  /// pair = <upper mark, lower mark>
83  _fromChild_(i, n, marks);
85 
86  for (const auto& elt: marks)
87  delete elt.second;
88  }
89 
90  template < typename GUM_SCALAR >
92  NodeId n,
93  InstanceMap& marks) {
95 
96  if (!marks[i]->exists(n)) { marks[i]->insert(n, std::pair< bool, bool >(false, false)); }
97 
98  // Sending message to parents
99  switch (i->type().get(n).elt_type()) {
101  if (!_getMark_(marks, i, n).first) {
102  _getMark_(marks, i, n).first = true;
103 
104  for (const auto inst: i->getInstances(n))
106  }
107 
108  if (!_getMark_(marks, i, n).second) {
109  _getMark_(marks, i, n).second = true;
110 
111  for (const auto chi: i->type().containerDag().children(n))
112  _fromParent_(i, chi, marks);
113  }
114 
115  break;
116  }
117 
120  if (!_getMark_(marks, i, n).first) {
121  _getMark_(marks, i, n).first = true;
122 
123  if (!_isHardEvidence_(i, n))
124  for (const auto par: i->type().containerDag().parents(n))
125  _fromChild_(i, par, marks);
126  }
127 
128  if (!_getMark_(marks, i, n).second) {
129  _getMark_(marks, i, n).second = true;
130 
131  // In i.
132  for (const auto chi: i->type().containerDag().children(n))
133  _fromParent_(i, chi, marks);
134 
135  // Out of i.
136  try {
137  const auto& refs = i->getRefAttr(n);
138 
139  for (auto iter = refs.begin(); iter != refs.end(); ++iter)
141  } catch (NotFound&) {
142  // Not an inverse sc
143  }
144  }
145 
146  break;
147  }
148 
149  default: {
150  // We shouldn't reach any other PRMClassElement<GUM_DATA> than
151  // PRMAttribute
152  // or
153  // PRMSlotChain<GUM_SCALAR>.
154  GUM_ERROR(FatalError, "This case is impossible.")
155  }
156  }
157  }
158 
159  template < typename GUM_SCALAR >
161  NodeId n,
162  InstanceMap& marks) {
164 
165  if (!marks[i]->exists(n)) { marks[i]->insert(n, std::pair< bool, bool >(false, false)); }
166 
167  // Concerns only PRMAttribute (because of the hard evidence)
168  if ((_isHardEvidence_(i, n)) && (!_getMark_(marks, i, n).first)) {
169  _getMark_(marks, i, n).first = true;
170 
171  for (const auto par: i->type().containerDag().parents(n))
172  _fromChild_(i, par, marks);
173  } else if (!_getMark_(marks, i, n).second) {
174  _getMark_(marks, i, n).second = true;
175 
176  // In i.
177  for (const auto chi: i->type().containerDag().children(n))
178  _fromParent_(i, chi, marks);
179 
180  // Out of i.
181  try {
182  for (auto iter = i->getRefAttr(n).begin(); iter != i->getRefAttr(n).end(); ++iter)
184  } catch (NotFound&) {
185  // Not an inverse sc
186  }
187  }
188  }
189 
190  template < typename GUM_SCALAR >
192  // First find for each instance it's requisite nodes
193  HashTable< const PRMInstance< GUM_SCALAR >*, Set< NodeId >* > req_map;
194 
195  for (const auto& elt: marks) {
196  Set< NodeId >* req_set = new Set< NodeId >();
197 
198  for (const auto& elt2: *elt.second)
200 
202  }
203 
204  // Remove all instances with 0 requisite nodes
205  Set< const PRMInstance< GUM_SCALAR >* > to_remove;
206 
207  for (const auto& elt: req_map)
208  if (elt.second->size() == 0) to_remove.insert(elt.first);
209 
210  for (const auto remo: to_remove) {
211  delete req_map[remo];
212  req_map.erase(remo);
213  }
214 
215  // Fill _reqMap_ and _keyMap_
216  for (const auto& elt: req_map) {
218 
219  if (_reqMap_.exists(key)) {
221  std::pair< std::string, Set< NodeId >* >(key, _reqMap_[key].first));
222  _reqMap_[key].second += 1;
223  delete elt.second;
224  req_map[elt.first] = 0;
225  } else {
226  _reqMap_.insert(key, std::pair< Set< NodeId >*, Size >(elt.second, 1));
228  }
229  }
230  }
231 
232  template < typename GUM_SCALAR >
233  std::string
235  Set< NodeId >& req_nodes) {
237  sBuff << i->type().name();
238 
239  for (const auto node: i->type().containerDag().nodes())
240  if (req_nodes.exists(node)) sBuff << "-" << node;
241 
242  return sBuff.str();
243  }
244 
245  template < typename GUM_SCALAR >
247  const PRMInference< GUM_SCALAR >& inference) :
248  _inf_(&inference) {
250  }
251 
252  template < typename GUM_SCALAR >
255  _inf_(0) {
257  GUM_ERROR(FatalError, "Not allowed.")
258  }
259 
260  template < typename GUM_SCALAR >
263  GUM_ERROR(FatalError, "Not allowed.")
264  }
265 
266  template < typename GUM_SCALAR >
267  INLINE const std::string&
269  return _keyMap_[i].first;
270  }
271 
272  template < typename GUM_SCALAR >
273  INLINE const std::string&
275  return _keyMap_[&i].first;
276  }
277 
278  template < typename GUM_SCALAR >
279  INLINE const Set< NodeId >&
281  return *(_keyMap_[i].second);
282  }
283 
284  template < typename GUM_SCALAR >
285  INLINE const Set< NodeId >&
287  return *(_keyMap_[&i].second);
288  }
289 
290  template < typename GUM_SCALAR >
292  return _reqMap_[key].second;
293  }
294 
295  template < typename GUM_SCALAR >
297  return ((float)_reqMap_.size()) / ((float)_keyMap_.size());
298  }
299 
300  template < typename GUM_SCALAR >
301  INLINE bool
303  return _keyMap_.exists(i);
304  }
305 
306  template < typename GUM_SCALAR >
307  INLINE bool
309  return _keyMap_.exists(&i);
310  }
311 
312  template < typename GUM_SCALAR >
314  NodeId n) {
315  _compute_(i, n);
316  }
317 
318  template < typename GUM_SCALAR >
320  NodeId n) {
321  _compute_(&i, n);
322  }
323 
324  template < typename GUM_SCALAR >
325  INLINE const PRMSlotChain< GUM_SCALAR >&
327  return static_cast< const PRMSlotChain< GUM_SCALAR >& >(i->type().get(n));
328  }
329 
330  template < typename GUM_SCALAR >
331  INLINE std::pair< bool, bool >&
333  const PRMInstance< GUM_SCALAR >* i,
334  NodeId n) {
335  return (*(marks[i]))[n];
336  }
337 
338  } /* namespace prm */
339 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)