aGrUM  0.14.2
interfaceGraph_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  ***************************************************************************/
27 namespace gum {
28  namespace prm {
29  namespace gspan {
30 
31  // NodeData
32 
33  template < typename GUM_SCALAR >
34  INLINE NodeData< GUM_SCALAR >::NodeData() : n(0), l(0) {
35  GUM_CONSTRUCTOR(NodeData);
36  }
37 
38  template < typename GUM_SCALAR >
40  n(from.n), l(from.l) {
41  GUM_CONS_CPY(NodeData);
42  }
43 
44  template < typename GUM_SCALAR >
46  GUM_DESTRUCTOR(NodeData);
47  }
48 
49  template < typename GUM_SCALAR >
50  INLINE bool NodeData< GUM_SCALAR >::
51  operator==(const NodeData< GUM_SCALAR >& from) const {
52  return (n == from.n) && (l == from.l);
53  }
54 
55  template < typename GUM_SCALAR >
56  INLINE bool NodeData< GUM_SCALAR >::
57  operator!=(const NodeData< GUM_SCALAR >& from) const {
58  return (n != from.n) && (l != from.l);
59  }
60 
61  // EdgeData<GUM_SCALAR>
62 
63  template < typename GUM_SCALAR >
64  INLINE EdgeData< GUM_SCALAR >::EdgeData() : u(0), v(0), l(0) {
65  GUM_CONSTRUCTOR(EdgeData);
66  }
67 
68  template < typename GUM_SCALAR >
70  u(from.u), v(from.v), l(from.l) {
71  GUM_CONS_CPY(EdgeData);
72  }
73 
74  template < typename GUM_SCALAR >
76  GUM_DESTRUCTOR(EdgeData);
77  }
78 
79  template < typename GUM_SCALAR >
80  INLINE bool EdgeData< GUM_SCALAR >::
81  operator==(const EdgeData< GUM_SCALAR >& from) const {
82  return (u == from.u) && (l_u == from.l_u) && (v == from.v)
83  && (l_v == from.l_v) && (l == from.l);
84  }
85 
86  template < typename GUM_SCALAR >
87  INLINE bool EdgeData< GUM_SCALAR >::
88  operator!=(const EdgeData< GUM_SCALAR >& from) const {
89  return (u != from.u) && (l_u != from.l_u) && (v != from.v)
90  && (l_v != from.l_v) && (l != from.l);
91  }
92 
93  // InterfaceGraph
94 
95  template < typename GUM_SCALAR >
97  const PRMSystem< GUM_SCALAR >& sys) :
98  __sys(&sys),
99  __labels(new Bijection< Idx, LabelData* >()), __counter(0),
100  __erase_flag(true) {
101  GUM_CONSTRUCTOR(InterfaceGraph);
103 
104  // We need to add each instance in __graph
105  for (auto iter = sys.begin(); iter != sys.end(); ++iter) {
107  node->n = iter.val();
108  __label(node, label_map);
109  __graph.addNodeWithId(iter.key());
110  __idMap.insert(node->n, iter.key());
111  __nodes.insert(iter.key(), node);
112  }
113 
114  NodeData< GUM_SCALAR >* u = nullptr;
115  NodeData< GUM_SCALAR >* v = nullptr;
116 
117  for (const auto& elt : __nodes) {
118  NodeData< GUM_SCALAR >* data = elt.second;
119 
120  for (const auto chain : data->n->type().slotChains()) {
121  for (const auto inst : data->n->getInstances(chain->id())) {
122  u = (__nodes[__idMap[inst]]->l < data->l) ? __nodes[__idMap[inst]]
123  : data;
124  v = (u != data) ? data : __nodes[__idMap[inst]];
125 
126  if (!__graph.existsEdge(__idMap[u->n], __idMap[v->n])) {
128  edge->u = u->n;
129  edge->l_u = u->l;
130  edge->v = v->n;
131  edge->l_v = v->l;
132  __label(edge, label_map);
133  __graph.addEdge(__idMap[u->n], __idMap[v->n]);
134  __edges.insert(Edge(__idMap[u->n], __idMap[v->n]), edge);
135  }
136  }
137  }
138  }
139  }
140 
141  template < typename GUM_SCALAR >
143  const InterfaceGraph< GUM_SCALAR >& source) :
144  __sys(source.__sys),
145  __graph(source.__graph), __nodes(source.__nodes),
146  __idMap(source.__idMap), __edges(source.__edges),
147  __labels(new Bijection< Idx, LabelData* >(*(source.__labels))),
148  __nodeMap(source.__nodeMap), __edgeMap(source.__edgeMap),
149  __counter(source.__counter), __erase_flag(false) {
150  GUM_CONS_CPY(InterfaceGraph);
151  }
152 
153  template < typename GUM_SCALAR >
155  GUM_DESTRUCTOR(InterfaceGraph);
156 
157  if (__erase_flag) {
158  for (const auto& elt : __nodes)
159  delete elt.second;
160 
161  for (const auto& elt : __edges)
162  delete elt.second;
163 
164  for (const auto& elt : __nodeMap) {
165  delete elt.first;
166  delete elt.second;
167  }
168 
169  for (const auto& elt : __edgeMap) {
170  delete elt.first;
171  delete elt.second;
172  }
173  }
174 
175  delete __labels;
176  }
177 
178  template < typename GUM_SCALAR >
181  GUM_ERROR(FatalError, "not implemented");
182  }
183 
184  template < typename GUM_SCALAR >
188  Size size = Size(1);
189  std::stringstream sBuff;
190  sBuff << node->n->type().name();
191 
192  // First we search for multiple inputs
193  for (const auto chain : node->n->type().slotChains()) {
194  if (chain->isMultiple()) {
195  sBuff << "-" << node->n->getInstances(chain->id()).size();
196  sBuff << chain->name();
197  size *= node->n->getInstances(chain->id()).size()
198  * chain->lastElt().type().variable().domainSize();
199  } else {
200  size *= chain->lastElt().type().variable().domainSize();
201  }
202  }
203 
204  // Second we search for active outputs
205  for (const auto nn : node->n->type().containerDag().nodes()) {
206  if (node->n->type().isOutputNode(node->n->type().get(nn))) {
207  try {
208  sBuff << "-" << node->n->getRefAttr(nn).size()
209  << node->n->get(nn).name();
210  size *= node->n->get(nn).type().variable().domainSize();
211  } catch (NotFound&) {
212  // (nn) is an inactive output node
213  }
214  }
215  }
216 
217  // Label is ready
218  if (!label_map.exists(sBuff.str())) {
219  LabelData* label = new LabelData();
220  label_map.insert(sBuff.str(), label);
221  label->id = ++__counter;
222  label->tree_width = size;
223  label->l = sBuff.str();
224  __labels->insert(label->id, label);
225  __nodeMap.insert(label, new Set< NodeData< GUM_SCALAR >* >());
226  }
227 
228  node->l = label_map[sBuff.str()];
229  __nodeMap[node->l]->insert(node);
230  }
231 
232  template < typename GUM_SCALAR >
236  Size size = Size(1);
237  std::stringstream sBuff;
238  sBuff << edge->u->type().name() << "-" << edge->v->type().name();
239 
240  // First looking for edge->u output nodes in v
241  for (const auto chain : edge->u->type().slotChains()) {
242  if (edge->u->getInstances(chain->id()).exists(edge->v)) {
243  sBuff << "-" << edge->v->type().name() << "."
244  << chain->lastElt().name();
245  size *= chain->lastElt().type().variable().domainSize();
246  }
247  }
248 
249  // Second looking for edge->v output nodes in u
250  for (const auto chain : edge->v->type().slotChains())
251  if (edge->v->getInstances(chain->id()).exists(edge->u)) {
252  sBuff << "-" << edge->u->type().name() << "."
253  << chain->lastElt().name();
254  size *= chain->lastElt().type().variable().domainSize();
255  }
256 
257  // Label is ready
258  if (!label_map.exists(sBuff.str())) {
259  LabelData* label = new LabelData();
260  label_map.insert(sBuff.str(), label);
261  label->id = ++__counter;
262  label->l = sBuff.str();
263  label->tree_width = size;
264  __labels->insert(label->id, label);
265  __edgeMap.insert(label, new Set< EdgeData< GUM_SCALAR >* >());
266  }
267 
268  edge->l = label_map[sBuff.str()];
269  __edgeMap[edge->l]->insert(edge);
270  }
271 
272  template < typename GUM_SCALAR >
274  return __graph;
275  }
276 
277  template < typename GUM_SCALAR >
279  return __graph;
280  }
281 
282  template < typename GUM_SCALAR >
284  return *__labels;
285  }
286 
287  template < typename GUM_SCALAR >
288  INLINE const Bijection< Idx, LabelData* >&
290  return *__labels;
291  }
292 
293  template < typename GUM_SCALAR >
295  try {
296  return __nodeMap[const_cast< LabelData* >(l)]->size();
297  } catch (NotFound&) {
298  return __edgeMap[const_cast< LabelData* >(l)]->size();
299  }
300  }
301 
302  template < typename GUM_SCALAR >
303  INLINE Set< NodeData< GUM_SCALAR >* >&
305  return *(__nodeMap[const_cast< LabelData* >(l)]);
306  }
307 
308  template < typename GUM_SCALAR >
309  INLINE const Set< NodeData< GUM_SCALAR >* >&
311  return *(__nodeMap[const_cast< LabelData* >(l)]);
312  }
313 
314  template < typename GUM_SCALAR >
315  INLINE Set< EdgeData< GUM_SCALAR >* >&
317  return *(__edgeMap[const_cast< LabelData* >(l)]);
318  }
319 
320  template < typename GUM_SCALAR >
321  INLINE const Set< EdgeData< GUM_SCALAR >* >&
323  return *(__edgeMap[const_cast< LabelData* >(l)]);
324  }
325 
326  template < typename GUM_SCALAR >
328  return __labels->second(id);
329  }
330 
331  template < typename GUM_SCALAR >
333  const PRMInstance< GUM_SCALAR >& i) const {
334  return __idMap[const_cast< PRMInstance< GUM_SCALAR >* >(&i)];
335  }
336 
337  template < typename GUM_SCALAR >
339  const PRMInstance< GUM_SCALAR >* i) const {
340  return __idMap[const_cast< PRMInstance< GUM_SCALAR >* >(i)];
341  }
342 
343  template < typename GUM_SCALAR >
344  INLINE NodeData< GUM_SCALAR >&
346  return node(id(i));
347  }
348 
349  template < typename GUM_SCALAR >
351  const PRMInstance< GUM_SCALAR >* i) const {
352  return node(id(i));
353  }
354 
355  template < typename GUM_SCALAR >
356  INLINE NodeData< GUM_SCALAR >&
358  return *(__nodes[id]);
359  }
360 
361  template < typename GUM_SCALAR >
362  INLINE const NodeData< GUM_SCALAR >&
364  return *(__nodes[id]);
365  }
366 
367  template < typename GUM_SCALAR >
369  NodeId v) {
370  try {
371  return *(__edges[Edge(u, v)]);
372  } catch (NotFound&) { return *(__edges[Edge(v, u)]); }
373  }
374 
375  template < typename GUM_SCALAR >
376  INLINE const EdgeData< GUM_SCALAR >&
378  try {
379  return *(__edges[Edge(u, v)]);
380  } catch (NotFound&) { return *(__edges[Edge(v, u)]); }
381  }
382 
383  template < typename GUM_SCALAR >
384  INLINE std::ostream& operator<<(std::ostream& out,
385  const NodeData< GUM_SCALAR >& data) {
386  out << data.n->name() << "(" << data.l->l << ")";
387  return out;
388  }
389 
390  template < typename GUM_SCALAR >
391  INLINE std::ostream& operator<<(std::ostream& out,
392  const EdgeData< GUM_SCALAR >& data) {
393  out << data.u->name() << " -> " << data.v->name() << "(" << data.l->l
394  << ")";
395  return out;
396  }
397 
398  } /* namespace gspan */
399  } /* namespace prm */
400 } /* 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:37
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:60
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:32
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>.
gum is the global namespace for all aGrUM entities
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:676
LabelData * l
The labal data of this edge.
Representation of a setA Set is a structure that contains arbitrary elements.
Definition: set.h:162
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:226
LabelData * l
The label of this node.
Set of pairs of elements with fast search for both elements.
Definition: bijection.h:1803
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:106
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:50
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:45
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:97
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
InterfaceGraph & operator=(const InterfaceGraph &source)
Copy operator.
bool operator!=(const NodeData< GUM_SCALAR > &from) const
Difference operator.