$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
line_graph.hh
1 // Copyright (C) 2008, 2009, 2010, 2012 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena 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 GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_UTIL_LINE_GRAPH_HH
28 # define MLN_UTIL_LINE_GRAPH_HH
29 
33 
34 # include <mln/util/internal/graph_base.hh>
35 # include <mln/util/internal/graph_iter.hh>
36 # include <mln/util/internal/graph_nbh_iter.hh>
37 # include <mln/util/ord_pair.hh>
38 
39 namespace mln
40 {
41 
42  namespace util
43  {
45  template <typename G>
46  class line_graph;
47  }
48 
49 
50  namespace internal
51  {
52 
57  template <typename G>
58  struct data< util::line_graph<G> >
59  {
60  typedef util::line_graph<G> lg_t;
61  typedef std::vector<std::vector<util::edge_id_t> > vertices_t;
62  typedef std::vector<util::ord_pair<util::vertex_id_t> > edges_t;
63 
64  data();
65  data(const G& g);
66  ~data();
67 
68  G g_;
70  vertices_t vertices_;
72  edges_t edges_;
73  };
74 
75  } // end of namespace mln::internal
76 
77 
78  namespace util
79  {
80 
84  template <typename G>
85  class line_graph : public internal::graph_base< line_graph<G> >
86  {
89 
90  typedef typename super::vertex_t vertex_t;
91  typedef typename super::edge_t edge_t;
92 
93  typedef typename super::vertex_data_t vertex_data_t;
94  typedef typename super::edge_data_t edge_data_t;
95 
96  public:
98  typedef std::vector<vertex_data_t> vertices_t;
99 
101  typedef std::vector<edge_data_t> edges_t;
102 
113 
122 
131 
140 
150 
151  line_graph();
152  line_graph(const G& g);
153 
160  vertex_t vertex(const vertex_id_t& id_v) const;
162 
164  // FIXME: Rename as nvertices.
165  size_t v_nmax() const;
166 
168  // FIXME: Is the `_v' suffix really needed?
169  bool has_v(const vertex_id_t& id_v) const;
170 
172  template <typename G2>
173  bool has(const util::vertex<G2>& v) const;
174 
175 
177  size_t v_nmax_nbh_edges(const vertex_id_t& id_v) const;
178 
180  edge_id_t v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const;
181 
183  size_t v_nmax_nbh_vertices(const vertex_id_t& id_v) const;
184 
186  vertex_id_t v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const;
188 
189 
190 
191 
195  edge_t edge(const edge_id_t& e) const;
196 
198  // FIXME: Rename as nedges.
199  size_t e_nmax() const;
200 
202  // FIXME: Is the `_e' suffix really needed?
203  bool has_e(const util::edge_id_t& id_e) const;
204 
206  template <typename G2>
207  bool has(const util::edge<G2>& e) const;
208 
209 
211  vertex_id_t v1(const edge_id_t& id_e) const;
212 
214  vertex_id_t v2(const edge_id_t& id_e) const;
215 
217  size_t e_nmax_nbh_edges(const edge_id_t& id_e) const;
218 
220  edge_id_t e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const;
221 
224  template <typename G2>
225  bool is_subgraph_of(const G2& g) const;
226 
228  const G& graph() const;
230 
231  protected:
232  using super::data_;
233  };
234 
235  template <typename G>
236  std::ostream&
237  operator<<(std::ostream& ostr, const line_graph<G>& g);
238 
239  } // end of namespace mln::util
240 
241 } // end of namespace mln
242 
243 # ifndef MLN_INCLUDE_ONLY
244 
245 namespace mln
246 {
247 
248  namespace internal
249  {
250 
251  template <typename G>
252  inline
254  {
255  }
256 
257  template <typename G>
258  inline
259  data< util::line_graph<G> >::data(const G& g)
260  {
261  g_ = g;
262 
263  // Initialize vertices and edges.
264  // FIXME: use an adjacency matrix!!
265  std::set<util::ord_pair<util::vertex_id_t> > edges_set;
266 
267  vertices_.resize(g.e_nmax());
268  mln_edge_iter(G) e(g);
269  mln_edge_nbh_edge_iter(G) ne(e);
270 
271  for_all(e)
272  {
273  util::vertex_id_t v1(e.id().value());
274  for_all(ne)
275  {
276  util::vertex_id_t v2(ne.id().value());
277  util::ord_pair<util::vertex_id_t> edge(v1, v2);
278  if (edges_set.find(edge) == edges_set.end())
279  {
280  vertices_[v1].push_back(edges_.size());
281  vertices_[v2].push_back(edges_.size());
282  edges_set.insert(edge);
283  edges_.push_back(edge);
284  }
285  }
286  }
287  }
288 
289  template <typename G>
290  inline
291  data< util::line_graph<G> >::~data()
292  {
293  }
294 
295  } // end of namespace mln::internal
296 
297  namespace util
298  {
299 
300  template <typename G>
301  inline
303  {
304  this->data_ = new mln::internal::data< util::line_graph<G> >();
305  }
306 
307  template <typename G>
308  inline
309  line_graph<G>::line_graph(const G& g)
310  {
311  this->data_ = new mln::internal::data< util::line_graph<G> >(g);
312  }
313 
314  /*---------------.
315  | Vertex related |
316  `---------------*/
317 
318  template <typename G>
319  inline
320  typename line_graph<G>::vertex_t
321  line_graph<G>::vertex(const vertex_id_t& id_v) const
322  {
323  mln_assertion(has_v(id_v));
324  return vertex_t(*this, id_v);
325  }
326 
327 
328  template <typename G>
329  inline
330  size_t
331  line_graph<G>::v_nmax() const
332  {
333  return data_->g_.e_nmax();
334  }
335 
336  template <typename G>
337  inline
338  bool
339  line_graph<G>::has_v(const vertex_id_t& id_v) const
340  {
341  return data_->g_.has_v(id_v);
342  }
343 
344  template <typename G>
345  template <typename G2>
346  inline
347  bool
348  line_graph<G>::has(const util::vertex<G2>& v) const
349  {
350  // FIXME: not sure...
351  return v.graph().is_subgraph_of(*this) && has_v(v.id());
352  }
353 
354  template <typename G>
355  inline
356  size_t
358  {
359  mln_precondition(has_v(id_v));
360  return data_->vertices_[id_v].size();
361  }
362 
363  template <typename G>
364  inline
365  edge_id_t
366  line_graph<G>::v_ith_nbh_edge(const vertex_id_t& id_v, unsigned i) const
367  {
368  mln_precondition(has_v(id_v));
369  if (i >= v_nmax_nbh_edges(id_v))
370  return v_nmax();
371  return data_->vertices_[id_v][i];
372  }
373 
374  template <typename G>
375  inline
376  size_t
378  {
379  mln_precondition(has_v(id_v));
380  return v_nmax_nbh_edges(id_v);
381  }
382 
383  template <typename G>
384  inline
386  line_graph<G>::v_ith_nbh_vertex(const vertex_id_t& id_v, unsigned i) const
387  {
388  mln_precondition(has_v(id_v));
389 
390  unsigned id_e = this->v_ith_nbh_edge(id_v, i);
391  return this->v_other(id_e, id_v);
392  }
393 
394 
395  /*--------------.
396  | Edges related |
397  `---------------*/
398 
399  template <typename G>
400  inline
401  typename line_graph<G>::edge_t
402  line_graph<G>::edge(const edge_id_t& e) const
403  {
404  mln_assertion(e < e_nmax());
405  return edge_t(*this, e);
406  }
407 
408  template <typename G>
409  inline
410  size_t
411  line_graph<G>::e_nmax() const
412  {
413  return data_->edges_.size();
414  }
415 
416  template <typename G>
417  inline
418  bool
419  line_graph<G>::has_e(const edge_id_t& id_e) const
420  {
421  return id_e < data_->edges_.size();
422  }
423 
424  template <typename G>
425  template <typename G2>
426  inline
427  bool
428  line_graph<G>::has(const util::edge<G2>& e) const
429  {
430  return e.graph().is_subgraph_of(*this) && has_e(e.id());
431  }
432 
433  template <typename G>
434  inline
436  line_graph<G>::v1(const edge_id_t& id_e) const
437  {
438  mln_precondition(has_e(id_e));
439  return data_->edges_[id_e].first();
440  }
441 
442  template <typename G>
443  inline
445  line_graph<G>::v2(const edge_id_t& id_e) const
446  {
447  mln_precondition(has_e(id_e));
448  return data_->edges_[id_e].second();
449  }
450 
451  template <typename G>
452  inline
453  size_t
454  line_graph<G>::e_nmax_nbh_edges(const edge_id_t& id_e) const
455  {
456  mln_precondition(has_e(id_e));
457  return v_nmax_nbh_edges(v1(id_e)) + v_nmax_nbh_edges(v2(id_e));
458  }
459 
460  template <typename G>
461  inline
462  edge_id_t
463  line_graph<G>::e_ith_nbh_edge(const edge_id_t& id_e, unsigned i) const
464  {
465  mln_precondition(has_e(id_e));
466  if (i >= e_nmax_nbh_edges(id_e))
467  return e_nmax();
468 
469  unsigned v1_nmax = v_nmax_nbh_edges(v1(id_e));
470  if (i < v1_nmax)
471  return v_ith_nbh_edge(v1(id_e), i);
472  return v_ith_nbh_edge(v2(id_e), i - v1_nmax);
473  }
474 
475 
476  template <typename G>
477  template <typename G2>
478  inline
479  bool
480  line_graph<G>::is_subgraph_of(const G2& g) const
481  {
482  return g.id() == this->id();
483  }
484 
485  template <typename G>
486  inline
487  const G&
488  line_graph<G>::graph() const
489  {
490  return this->data_->g_;
491  }
492 
493  // FIXME: move to graph_base
494  template <typename G>
495  inline
496  std::ostream&
497  operator<<(std::ostream& ostr, const line_graph<G>& g)
498  {
499  typedef line_graph<G> LG;
500  mln_vertex_iter(LG) v(g);
501  mln_vertex_nbh_edge_iter(LG) e(v);
502  for_all(v)
503  {
504  ostr << "v(" << v << ") : ";
505  for_all(e)
506  ostr << e << " ";
507  ostr << std::endl;
508  }
509 
510  return ostr;
511  }
512 
513  } // end of namespace mln::util
514 
515 } // end of namespace mln
516 
517 # endif // ! MLN_INCLUDE_ONLY
518 
519 
520 #endif // ! MLN_UTIL_LINE_GRAPH_HH