aGrUM  0.16.0
interfaceGraph_tpl.h
Go to the documentation of this file.
1 
30 namespace gum {
31  namespace prm {
32  namespace gspan {
33 
34  // NodeData
35 
36  template < typename GUM_SCALAR >
37  INLINE NodeData< GUM_SCALAR >::NodeData() : n(0), l(0) {
38  GUM_CONSTRUCTOR(NodeData);
39  }
40 
41  template < typename GUM_SCALAR >
43  n(from.n), l(from.l) {
44  GUM_CONS_CPY(NodeData);
45  }
46 
47  template < typename GUM_SCALAR >
49  GUM_DESTRUCTOR(NodeData);
50  }
51 
52  template < typename GUM_SCALAR >
53  INLINE bool NodeData< GUM_SCALAR >::
54  operator==(const NodeData< GUM_SCALAR >& from) const {
55  return (n == from.n) && (l == from.l);
56  }
57 
58  template < typename GUM_SCALAR >
59  INLINE bool NodeData< GUM_SCALAR >::
60  operator!=(const NodeData< GUM_SCALAR >& from) const {
61  return (n != from.n) && (l != from.l);
62  }
63 
64  // EdgeData<GUM_SCALAR>
65 
66  template < typename GUM_SCALAR >
67  INLINE EdgeData< GUM_SCALAR >::EdgeData() : u(0), v(0), l(0) {
68  GUM_CONSTRUCTOR(EdgeData);
69  }
70 
71  template < typename GUM_SCALAR >
73  u(from.u), v(from.v), l(from.l) {
74  GUM_CONS_CPY(EdgeData);
75  }
76 
77  template < typename GUM_SCALAR >
79  GUM_DESTRUCTOR(EdgeData);
80  }
81 
82  template < typename GUM_SCALAR >
83  INLINE bool EdgeData< GUM_SCALAR >::
84  operator==(const EdgeData< GUM_SCALAR >& from) const {
85  return (u == from.u) && (l_u == from.l_u) && (v == from.v)
86  && (l_v == from.l_v) && (l == from.l);
87  }
88 
89  template < typename GUM_SCALAR >
90  INLINE bool EdgeData< GUM_SCALAR >::
91  operator!=(const EdgeData< GUM_SCALAR >& from) const {
92  return (u != from.u) && (l_u != from.l_u) && (v != from.v)
93  && (l_v != from.l_v) && (l != from.l);
94  }
95 
96  // InterfaceGraph
97 
98  template < typename GUM_SCALAR >
100  const PRMSystem< GUM_SCALAR >& sys) :
101  __sys(&sys),
102  __labels(new Bijection< Idx, LabelData* >()), __counter(0),
103  __erase_flag(true) {
104  GUM_CONSTRUCTOR(InterfaceGraph);
106 
107  // We need to add each instance in __graph
108  for (auto iter = sys.begin(); iter != sys.end(); ++iter) {
110  node->n = iter.val();
111  __label(node, label_map);
112  __graph.addNodeWithId(iter.key());
113  __idMap.insert(node->n, iter.key());
114  __nodes.insert(iter.key(), node);
115  }
116 
117  NodeData< GUM_SCALAR >* u = nullptr;
118  NodeData< GUM_SCALAR >* v = nullptr;
119 
120  for (const auto& elt : __nodes) {
121  NodeData< GUM_SCALAR >* data = elt.second;
122 
123  for (const auto chain : data->n->type().slotChains()) {
124  for (const auto inst : data->n->getInstances(chain->id())) {
125  u = (__nodes[__idMap[inst]]->l < data->l) ? __nodes[__idMap[inst]]
126  : data;
127  v = (u != data) ? data : __nodes[__idMap[inst]];
128 
129  if (!__graph.existsEdge(__idMap[u->n], __idMap[v->n])) {
131  edge->u = u->n;
132  edge->l_u = u->l;
133  edge->v = v->n;
134  edge->l_v = v->l;
135  __label(edge, label_map);
136  __graph.addEdge(__idMap[u->n], __idMap[v->n]);
137  __edges.insert(Edge(__idMap[u->n], __idMap[v->n]), edge);
138  }
139  }
140  }
141  }
142  }
143 
144  template < typename GUM_SCALAR >
146  const InterfaceGraph< GUM_SCALAR >& source) :
147  __sys(source.__sys),
148  __graph(source.__graph), __nodes(source.__nodes),
149  __idMap(source.__idMap), __edges(source.__edges),
150  __labels(new Bijection< Idx, LabelData* >(*(source.__labels))),
151  __nodeMap(source.__nodeMap), __edgeMap(source.__edgeMap),
152  __counter(source.__counter), __erase_flag(false) {
153  GUM_CONS_CPY(InterfaceGraph);
154  }
155 
156  template < typename GUM_SCALAR >
158  GUM_DESTRUCTOR(InterfaceGraph);
159 
160  if (__erase_flag) {
161  for (const auto& elt : __nodes)
162  delete elt.second;
163 
164  for (const auto& elt : __edges)
165  delete elt.second;
166 
167  for (const auto& elt : __nodeMap) {
168  delete elt.first;
169  delete elt.second;
170  }
171 
172  for (const auto& elt : __edgeMap) {
173  delete elt.first;
174  delete elt.second;
175  }
176  }
177 
178  delete __labels;
179  }
180 
181  template < typename GUM_SCALAR >
184  GUM_ERROR(FatalError, "not implemented");
185  }
186 
187  template < typename GUM_SCALAR >
191  Size size = Size(1);
192  std::stringstream sBuff;
193  sBuff << node->n->type().name();
194 
195  // First we search for multiple inputs
196  for (const auto chain : node->n->type().slotChains()) {
197  if (chain->isMultiple()) {
198  sBuff << "-" << node->n->getInstances(chain->id()).size();
199  sBuff << chain->name();
200  size *= node->n->getInstances(chain->id()).size()
201  * chain->lastElt().type().variable().domainSize();
202  } else {
203  size *= chain->lastElt().type().variable().domainSize();
204  }
205  }
206 
207  // Second we search for active outputs
208  for (const auto nn : node->n->type().containerDag().nodes()) {
209  if (node->n->type().isOutputNode(node->n->type().get(nn))) {
210  try {
211  sBuff << "-" << node->n->getRefAttr(nn).size()
212  << node->n->get(nn).name();
213  size *= node->n->get(nn).type().variable().domainSize();
214  } catch (NotFound&) {
215  // (nn) is an inactive output node
216  }
217  }
218  }
219 
220  // Label is ready
221  if (!label_map.exists(sBuff.str())) {
222  LabelData* label = new LabelData();
223  label_map.insert(sBuff.str(), label);
224  label->id = ++__counter;
225  label->tree_width = size;
226  label->l = sBuff.str();
227  __labels->insert(label->id, label);
228  __nodeMap.insert(label, new Set< NodeData< GUM_SCALAR >* >());
229  }
230 
231  node->l = label_map[sBuff.str()];
232  __nodeMap[node->l]->insert(node);
233  }
234 
235  template < typename GUM_SCALAR >
239  Size size = Size(1);
240  std::stringstream sBuff;
241  sBuff << edge->u->type().name() << "-" << edge->v->type().name();
242 
243  // First looking for edge->u output nodes in v
244  for (const auto chain : edge->u->type().slotChains()) {
245  if (edge->u->getInstances(chain->id()).exists(edge->v)) {
246  sBuff << "-" << edge->v->type().name() << "."
247  << chain->lastElt().name();
248  size *= chain->lastElt().type().variable().domainSize();
249  }
250  }
251 
252  // Second looking for edge->v output nodes in u
253  for (const auto chain : edge->v->type().slotChains())
254  if (edge->v->getInstances(chain->id()).exists(edge->u)) {
255  sBuff << "-" << edge->u->type().name() << "."
256  << chain->lastElt().name();
257  size *= chain->lastElt().type().variable().domainSize();
258  }
259 
260  // Label is ready
261  if (!label_map.exists(sBuff.str())) {
262  LabelData* label = new LabelData();
263  label_map.insert(sBuff.str(), label);
264  label->id = ++__counter;
265  label->l = sBuff.str();
266  label->tree_width = size;
267  __labels->insert(label->id, label);
268  __edgeMap.insert(label, new Set< EdgeData< GUM_SCALAR >* >());
269  }
270 
271  edge->l = label_map[sBuff.str()];
272  __edgeMap[edge->l]->insert(edge);
273  }
274 
275  template < typename GUM_SCALAR >
277  return __graph;
278  }
279 
280  template < typename GUM_SCALAR >
282  return __graph;
283  }
284 
285  template < typename GUM_SCALAR >
287  return *__labels;
288  }
289 
290  template < typename GUM_SCALAR >
291  INLINE const Bijection< Idx, LabelData* >&
293  return *__labels;
294  }
295 
296  template < typename GUM_SCALAR >
298  try {
299  return __nodeMap[const_cast< LabelData* >(l)]->size();
300  } catch (NotFound&) {
301  return __edgeMap[const_cast< LabelData* >(l)]->size();
302  }
303  }
304 
305  template < typename GUM_SCALAR >
306  INLINE Set< NodeData< GUM_SCALAR >* >&
308  return *(__nodeMap[const_cast< LabelData* >(l)]);
309  }
310 
311  template < typename GUM_SCALAR >
312  INLINE const Set< NodeData< GUM_SCALAR >* >&
314  return *(__nodeMap[const_cast< LabelData* >(l)]);
315  }
316 
317  template < typename GUM_SCALAR >
318  INLINE Set< EdgeData< GUM_SCALAR >* >&
320  return *(__edgeMap[const_cast< LabelData* >(l)]);
321  }
322 
323  template < typename GUM_SCALAR >
324  INLINE const Set< EdgeData< GUM_SCALAR >* >&
326  return *(__edgeMap[const_cast< LabelData* >(l)]);
327  }
328 
329  template < typename GUM_SCALAR >
331  return __labels->second(id);
332  }
333 
334  template < typename GUM_SCALAR >
336  const PRMInstance< GUM_SCALAR >& i) const {
337  return __idMap[const_cast< PRMInstance< GUM_SCALAR >* >(&i)];
338  }
339 
340  template < typename GUM_SCALAR >
342  const PRMInstance< GUM_SCALAR >* i) const {
343  return __idMap[const_cast< PRMInstance< GUM_SCALAR >* >(i)];
344  }
345 
346  template < typename GUM_SCALAR >
347  INLINE NodeData< GUM_SCALAR >&
349  return node(id(i));
350  }
351 
352  template < typename GUM_SCALAR >
354  const PRMInstance< GUM_SCALAR >* i) const {
355  return node(id(i));
356  }
357 
358  template < typename GUM_SCALAR >
359  INLINE NodeData< GUM_SCALAR >&
361  return *(__nodes[id]);
362  }
363 
364  template < typename GUM_SCALAR >
365  INLINE const NodeData< GUM_SCALAR >&
367  return *(__nodes[id]);
368  }
369 
370  template < typename GUM_SCALAR >
372  NodeId v) {
373  try {
374  return *(__edges[Edge(u, v)]);
375  } catch (NotFound&) { return *(__edges[Edge(v, u)]); }
376  }
377 
378  template < typename GUM_SCALAR >
379  INLINE const EdgeData< GUM_SCALAR >&
381  try {
382  return *(__edges[Edge(u, v)]);
383  } catch (NotFound&) { return *(__edges[Edge(v, u)]); }
384  }
385 
386  template < typename GUM_SCALAR >
387  INLINE std::ostream& operator<<(std::ostream& out,
388  const NodeData< GUM_SCALAR >& data) {
389  out << data.n->name() << "(" << data.l->l << ")";
390  return out;
391  }
392 
393  template < typename GUM_SCALAR >
394  INLINE std::ostream& operator<<(std::ostream& out,
395  const EdgeData< GUM_SCALAR >& data) {
396  out << data.u->name() << " -> " << data.v->name() << "(" << data.l->l
397  << ")";
398  return out;
399  }
400 
401  } /* namespace gspan */
402  } /* namespace prm */
403 } /* namespace gum */
virtual void addNodeWithId(const NodeId id)
try to insert a node with the given id
std::ostream & operator<<(std::ostream &out, const DFSCode &code)
Print code in out.
Definition: DFSCode.cpp:40
Inner class to handle data about labels in this interface graph.
Bijection< Idx, LabelData *> & labels()
Returns the bijection between LabelData and their string representation.
PRMInstance< GUM_SCALAR > * u
One of the two instance represented by this edge.
PRMInstance< GUM_SCALAR > * n
The instance represented by this node.
iterator begin()
Returns an iterator over the instances in this system.
An PRMInstance is a Bayesian Network fragment defined by a Class and used in a PRMSystem.
Definition: PRMInstance.h:63
std::string l
The string version of this label.
virtual void addEdge(const NodeId first, const NodeId second)
insert a new edge into the undirected graph
Definition: undiGraph_inl.h:35
NodeProperty< NodeData< GUM_SCALAR > *> __nodes
Data associated with a node in __graph.
HashTable< LabelData *, Set< NodeData< GUM_SCALAR > *> *> __nodeMap
Mapping between a LabelData and the set of NodeData<GUM_SCALAR> with that label.
UndiGraph __graph
The interface graph.
LabelData * l_u
The label data of u.
NodeData< GUM_SCALAR > & node(const PRMInstance< GUM_SCALAR > *i)
Returns data about a node.
bool exists(const Key &key) const
Checks whether there exists an element with a given key in the hashtable.
Inner class to handle data about edges in __graph.
Idx __counter
A counter used of assigning ids to labels.
PRMInstance< GUM_SCALAR > * v
The other instance represented by thus edge.
This class represent the interface graph of a given gum::prm::PRMSystem<GUM_SCALAR>.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
bool operator==(const EdgeData< GUM_SCALAR > &from) const
Equality operator.
EdgeProperty< EdgeData< GUM_SCALAR > *> __edges
Data associated with edges in __graph.
The class for generic Hash Tables.
Definition: hashTable.h:679
LabelData * l
The labal data of this edge.
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:165
const PRMSystem< GUM_SCALAR > * __sys
The gum::prm::PRMSystem<GUM_SCALAR> represented by this interface graph.
UndiGraph & graph()
Returns the graph of this interface graph.
bool operator==(const NodeData< GUM_SCALAR > &from) const
Equality operator.
HashTable< LabelData *, Set< EdgeData< GUM_SCALAR > *> *> __edgeMap
Mapping between a LabelData and the set of EdgeData<GUM_SCALAR> with that label.
bool existsEdge(const Edge &edge) const
indicates whether a given edge exists
InterfaceGraph(const PRMSystem< GUM_SCALAR > &sys)
Default constructor.
bool operator!=(const EdgeData< GUM_SCALAR > &from) const
Difference operator.
A PRMSystem is a container of PRMInstance and describe a relational skeleton.
Definition: PRMObject.h:229
LabelData * l
The label of this node.
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1805
Set< EdgeData< GUM_SCALAR > *> & edges(const LabelData *l)
Returns the set of nodes labelled by l.
Inner class to handle data about nodes in __graph.
Idx id
An unique identifier for this label.
bool __erase_flag
For shallow copies.
LabelData * l_v
The label data of v.
NodeId id(const PRMInstance< GUM_SCALAR > &i) const
Returns the id of i in this interface graph.
The base class for all undirected edges.
HashTable< PRMInstance< GUM_SCALAR > *, NodeId > __idMap
Mapping between PRMInstance<GUM_SCALAR> dans their id in __graph.
LabelData * label(Idx id)
Returns a label given its id.
Bijection< Idx, LabelData *> * __labels
Bijection between labels and their ids.
Base class for undirected graphs.
Definition: undiGraph.h:109
void __label(NodeData< GUM_SCALAR > *node, HashTable< std::string, LabelData * > &label_map)
Compute the label of node and add it to __labels if it does not exists yet. Update node with the corr...
Size size(const LabelData *l) const
Returns the number of node or edges labelled by l.
Size Idx
Type for indexes.
Definition: types.h:53
Size tree_width
The size in terms of tree width of the given label.
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
const iterator & end()
Returns a iterator at the end of the set of PRMInstance in this PRMSystem.
value_type & insert(const Key &key, const Val &val)
Adds a new element (actually a copy of this element) into the hash table.
EdgeData< GUM_SCALAR > & edge(NodeId u, NodeId v)
Returns data about an edge.
Set< NodeData< GUM_SCALAR > *> & nodes(const LabelData *l)
Returns the set of nodes labelled by l.
Size NodeId
Type for node ids.
Definition: graphElements.h:98
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
InterfaceGraph & operator=(const InterfaceGraph &source)
Copy operator.
bool operator!=(const NodeData< GUM_SCALAR > &from) const
Difference operator.