aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
interfaceGraph_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::InterfaceGraph.
25  *
26  * @author Lionel TORTI and Pierre-Henri WUILLEMIN(@LIP6)
27  */
28 
29 namespace gum {
30  namespace prm {
31  namespace gspan {
32 
33  // NodeData
34 
35  template < typename GUM_SCALAR >
36  INLINE NodeData< GUM_SCALAR >::NodeData() : n(0), l(0) {
38  }
39 
40  template < typename GUM_SCALAR >
42  n(from.n), l(from.l) {
44  }
45 
46  template < typename GUM_SCALAR >
49  }
50 
51  template < typename GUM_SCALAR >
53  const NodeData< GUM_SCALAR >& from) const {
54  return (n == from.n) && (l == from.l);
55  }
56 
57  template < typename GUM_SCALAR >
59  const NodeData< GUM_SCALAR >& from) const {
60  return (n != from.n) && (l != from.l);
61  }
62 
63  // EdgeData<GUM_SCALAR>
64 
65  template < typename GUM_SCALAR >
66  INLINE EdgeData< GUM_SCALAR >::EdgeData() : u(0), v(0), l(0) {
68  }
69 
70  template < typename GUM_SCALAR >
72  u(from.u), v(from.v), l(from.l) {
74  }
75 
76  template < typename GUM_SCALAR >
79  }
80 
81  template < typename GUM_SCALAR >
83  const EdgeData< GUM_SCALAR >& from) const {
84  return (u == from.u) && (l_u == from.l_u) && (v == from.v)
85  && (l_v == from.l_v) && (l == from.l);
86  }
87 
88  template < typename GUM_SCALAR >
90  const EdgeData< GUM_SCALAR >& from) const {
91  return (u != from.u) && (l_u != from.l_u) && (v != from.v)
92  && (l_v != from.l_v) && (l != from.l);
93  }
94 
95  // InterfaceGraph
96 
97  template < typename GUM_SCALAR >
99  const PRMSystem< GUM_SCALAR >& sys) :
100  sys__(&sys),
101  labels__(new Bijection< Idx, LabelData* >()), counter__(0),
102  erase_flag__(true) {
105 
106  // We need to add each instance in graph__
107  for (auto iter = sys.begin(); iter != sys.end(); ++iter) {
108  NodeData< GUM_SCALAR >* node = new NodeData< GUM_SCALAR >();
109  node->n = iter.val();
112  idMap__.insert(node->n, iter.key());
113  nodes__.insert(iter.key(), node);
114  }
115 
116  NodeData< GUM_SCALAR >* u = nullptr;
117  NodeData< GUM_SCALAR >* v = nullptr;
118 
119  for (const auto& elt: nodes__) {
121 
122  for (const auto chain: data->n->type().slotChains()) {
123  for (const auto inst: data->n->getInstances(chain->id())) {
124  u = (nodes__[idMap__[inst]]->l < data->l) ? nodes__[idMap__[inst]]
125  : data;
126  v = (u != data) ? data : nodes__[idMap__[inst]];
127 
128  if (!graph__.existsEdge(idMap__[u->n], idMap__[v->n])) {
129  EdgeData< GUM_SCALAR >* edge = new EdgeData< GUM_SCALAR >();
130  edge->u = u->n;
131  edge->l_u = u->l;
132  edge->v = v->n;
133  edge->l_v = v->l;
137  }
138  }
139  }
140  }
141  }
142 
143  template < typename GUM_SCALAR >
145  const InterfaceGraph< GUM_SCALAR >& source) :
146  sys__(source.sys__),
153  }
154 
155  template < typename GUM_SCALAR >
158 
159  if (erase_flag__) {
160  for (const auto& elt: nodes__)
161  delete elt.second;
162 
163  for (const auto& elt: edges__)
164  delete elt.second;
165 
166  for (const auto& elt: nodeMap__) {
167  delete elt.first;
168  delete elt.second;
169  }
170 
171  for (const auto& elt: edgeMap__) {
172  delete elt.first;
173  delete elt.second;
174  }
175  }
176 
177  delete labels__;
178  }
179 
180  template < typename GUM_SCALAR >
182  const InterfaceGraph< GUM_SCALAR >& source) {
183  GUM_ERROR(FatalError, "not implemented");
184  }
185 
186  template < typename GUM_SCALAR >
190  Size size = Size(1);
192  sBuff << node->n->type().name();
193 
194  // First we search for multiple inputs
195  for (const auto chain: node->n->type().slotChains()) {
196  if (chain->isMultiple()) {
197  sBuff << "-" << node->n->getInstances(chain->id()).size();
198  sBuff << chain->name();
199  size *= node->n->getInstances(chain->id()).size()
200  * chain->lastElt().type().variable().domainSize();
201  } else {
203  }
204  }
205 
206  // Second we search for active outputs
207  for (const auto nn: node->n->type().containerDag().nodes()) {
208  if (node->n->type().isOutputNode(node->n->type().get(nn))) {
209  try {
210  sBuff << "-" << node->n->getRefAttr(nn).size()
211  << node->n->get(nn).name();
212  size *= node->n->get(nn).type().variable().domainSize();
213  } catch (NotFound&) {
214  // (nn) is an inactive output node
215  }
216  }
217  }
218 
219  // Label is ready
220  if (!label_map.exists(sBuff.str())) {
221  LabelData* label = new LabelData();
223  label->id = ++counter__;
224  label->tree_width = size;
225  label->l = sBuff.str();
227  nodeMap__.insert(label, new Set< NodeData< GUM_SCALAR >* >());
228  }
229 
230  node->l = label_map[sBuff.str()];
231  nodeMap__[node->l]->insert(node);
232  }
233 
234  template < typename GUM_SCALAR >
238  Size size = Size(1);
240  sBuff << edge->u->type().name() << "-" << edge->v->type().name();
241 
242  // First looking for edge->u output nodes in v
243  for (const auto chain: edge->u->type().slotChains()) {
244  if (edge->u->getInstances(chain->id()).exists(edge->v)) {
245  sBuff << "-" << edge->v->type().name() << "."
246  << chain->lastElt().name();
248  }
249  }
250 
251  // Second looking for edge->v output nodes in u
252  for (const auto chain: edge->v->type().slotChains())
253  if (edge->v->getInstances(chain->id()).exists(edge->u)) {
254  sBuff << "-" << edge->u->type().name() << "."
255  << chain->lastElt().name();
257  }
258 
259  // Label is ready
260  if (!label_map.exists(sBuff.str())) {
261  LabelData* label = new LabelData();
263  label->id = ++counter__;
264  label->l = sBuff.str();
265  label->tree_width = size;
267  edgeMap__.insert(label, new Set< EdgeData< GUM_SCALAR >* >());
268  }
269 
270  edge->l = label_map[sBuff.str()];
271  edgeMap__[edge->l]->insert(edge);
272  }
273 
274  template < typename GUM_SCALAR >
276  return graph__;
277  }
278 
279  template < typename GUM_SCALAR >
281  return graph__;
282  }
283 
284  template < typename GUM_SCALAR >
286  return *labels__;
287  }
288 
289  template < typename GUM_SCALAR >
290  INLINE const Bijection< Idx, LabelData* >&
292  return *labels__;
293  }
294 
295  template < typename GUM_SCALAR >
297  try {
298  return nodeMap__[const_cast< LabelData* >(l)]->size();
299  } catch (NotFound&) {
300  return edgeMap__[const_cast< LabelData* >(l)]->size();
301  }
302  }
303 
304  template < typename GUM_SCALAR >
305  INLINE Set< NodeData< GUM_SCALAR >* >&
307  return *(nodeMap__[const_cast< LabelData* >(l)]);
308  }
309 
310  template < typename GUM_SCALAR >
311  INLINE const Set< NodeData< GUM_SCALAR >* >&
313  return *(nodeMap__[const_cast< LabelData* >(l)]);
314  }
315 
316  template < typename GUM_SCALAR >
317  INLINE Set< EdgeData< GUM_SCALAR >* >&
319  return *(edgeMap__[const_cast< LabelData* >(l)]);
320  }
321 
322  template < typename GUM_SCALAR >
323  INLINE const Set< EdgeData< GUM_SCALAR >* >&
325  return *(edgeMap__[const_cast< LabelData* >(l)]);
326  }
327 
328  template < typename GUM_SCALAR >
330  return labels__->second(id);
331  }
332 
333  template < typename GUM_SCALAR >
335  const PRMInstance< GUM_SCALAR >& i) const {
336  return idMap__[const_cast< PRMInstance< GUM_SCALAR >* >(&i)];
337  }
338 
339  template < typename GUM_SCALAR >
341  const PRMInstance< GUM_SCALAR >* i) const {
342  return idMap__[const_cast< PRMInstance< GUM_SCALAR >* >(i)];
343  }
344 
345  template < typename GUM_SCALAR >
348  return node(id(i));
349  }
350 
351  template < typename GUM_SCALAR >
353  const PRMInstance< GUM_SCALAR >* i) const {
354  return node(id(i));
355  }
356 
357  template < typename GUM_SCALAR >
360  return *(nodes__[id]);
361  }
362 
363  template < typename GUM_SCALAR >
364  INLINE const NodeData< GUM_SCALAR >&
366  return *(nodes__[id]);
367  }
368 
369  template < typename GUM_SCALAR >
371  NodeId v) {
372  try {
373  return *(edges__[Edge(u, v)]);
374  } catch (NotFound&) { return *(edges__[Edge(v, u)]); }
375  }
376 
377  template < typename GUM_SCALAR >
378  INLINE const EdgeData< GUM_SCALAR >&
380  try {
381  return *(edges__[Edge(u, v)]);
382  } catch (NotFound&) { return *(edges__[Edge(v, u)]); }
383  }
384 
385  template < typename GUM_SCALAR >
387  const NodeData< GUM_SCALAR >& data) {
388  out << data.n->name() << "(" << data.l->l << ")";
389  return out;
390  }
391 
392  template < typename GUM_SCALAR >
394  const EdgeData< GUM_SCALAR >& data) {
395  out << data.u->name() << " -> " << data.v->name() << "(" << data.l->l
396  << ")";
397  return out;
398  }
399 
400  } /* namespace gspan */
401  } /* namespace prm */
402 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669
ParamScopeData(const std::string &s, const PRMReferenceSlot< GUM_SCALAR > &ref, Idx d)
INLINE std::ostream & operator<<(std::ostream &out, const EdgeData< GUM_SCALAR > &data)
Print a EdgeData<GUM_SCALAR> in out.