https://svn.lrde.epita.fr/svn/oln/trunk/milena
Of course, there's a lot of duplication with the entities of graph-based
images, and we'll have to refactor, in particular when we'll implement
simplicial complexes.
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add the required entities to express line graph-based images.
* mln/core/point_pair.hh: New.
Used to represent the ``points'' of line graph-based images.
* mln/core/line_graph_elt_window.hh,
* mln/core/line_graph_image.hh,
* mln/core/line_graph_psite.hh,
* mln/core/line_graph_window_piter.hh,
* mln/core/p_line_graph.hh,
* mln/core/p_line_graph_piter.hh:
New.
Entities involved in line graph-based images.
* tests/core/line_graph_elt_window.cc,
* tests/core/line_graph_image.cc:
New tests.
* tests/core/Makefile.am: Reorder the lists of tests.
(check_PROGRAMS): Add line_graph_elt_window and line_graph_image.
(line_graph_elt_window_SOURCES, line_graph_image_SOURCES): New.
mln/core/line_graph_elt_window.hh | 54 ++++----
mln/core/line_graph_image.hh | 138 +++++++++++++---------
mln/core/line_graph_psite.hh | 148 +++++++++++++++++-------
mln/core/line_graph_window_piter.hh | 194 +++++++++++++++++++++++---------
mln/core/p_line_graph.hh | 97 +++++++++-------
mln/core/p_line_graph_piter.hh | 114 +++++++++++-------
mln/core/point_pair.hh | 217 ++++++++++++++++++++++++++++++++++++
tests/core/Makefile.am | 26 ++--
tests/core/line_graph_elt_window.cc | 18 +-
tests/core/line_graph_image.cc | 99 +++++++---------
10 files changed, 773 insertions(+), 332 deletions(-)
Index: mln/core/point_pair.hh
--- mln/core/point_pair.hh (revision 0)
+++ mln/core/point_pair.hh (revision 0)
@@ -0,0 +1,217 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_CORE_POINT_PAIR_HH
+# define MLN_CORE_POINT_PAIR_HH
+
+/// \file mln/core/point_pair.hh
+/// \brief Definition of the generic point_pair class mln::point_pair.
+
+// FIXME: Might be renamed to something else, like ``segment''.
+
+# include <utility>
+# include <ostream>
+
+# include <mln/core/concept/point.hh>
+
+
+namespace mln
+{
+
+ /** \brief Generic point pair class.
+
+ The sole parameter P is the type of the points of the pair.
+
+ Pair points are mainly used to make a reference to a given edge
+ in an line graph-based image. */
+ template <typename P>
+ struct point_pair : public Point< point_pair<P> >
+ {
+ /// \var dim
+ /// \brief Dimension of the space.
+ /// \invariant dim > 0
+ enum { dim = P::dim };
+
+ /// Mesh associated type.
+ // FIXME: Dummy value.
+ typedef mln_mesh(P) mesh;
+
+ /// Dpoint associated type.
+ // FIXME: Dummy value.
+ typedef void dpoint;
+
+ /// Coordinate associated type.
+ typedef std::pair<typename P::coord, typename P::coord> coord;
+
+ /// Constructors.
+ /// \{
+ /// Constructor without argument.
+ point_pair();
+ /// Constructor using two points.
+ point_pair(const P& first, const P& second);
+ /// Constructor using a pair of points.
+ point_pair(const std::pair<P, P>& points);
+ /// \}
+
+ /// Accessors.
+ /// \{
+
+ /// \brief Read-only access to the \p i-th coordinate value.
+ /// \param[in] i The coordinate index.
+ /// \pre \p i < \c dim
+ coord operator[](unsigned i) const;
+
+ /* FIXME: Providing this accessor requires the point pair to be
+ actually stored in this object, which both takes space and time
+ (updates). */
+
+// /// \brief Read-write access to the \p i-th coordinate value.
+// /// \param[in] i The coordinate index.
+// /// \pre \p i < \c dim
+// coord& operator[](unsigned i);
+
+ /// Read-only access to the first point.
+ P first() const;
+ /// Read-write access to the first point.
+ P& first();
+
+ /// Read-only access to the second point.
+ P second() const;
+ /// Read-write access to the second point.
+ P& second();
+ /// \}
+
+ protected:
+ /// The pair of points.
+ // FIXME: Should we use an ordpair_ instead of as std::pair?
+ std::pair<P, P> points_;
+ };
+
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const point_pair<P>& p);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*------------.
+ | Accessors. |
+ `------------*/
+
+ template <typename P>
+ inline
+ typename point_pair<P>::coord
+ point_pair<P>::operator[](unsigned i) const
+ {
+ assert(i < dim);
+ return std::make_pair(points_.first[i], points_.second[i]);
+ }
+
+// template <typename P>
+// inline
+// typename point_pair<P>::coord&
+// point_pair<P>::operator[](unsigned i)
+// {
+// assert(i < dim);
+// return std::make_pair(points_.first[i], points_.second[i]);
+// }
+
+ template <typename P>
+ inline
+ P
+ point_pair<P>::first() const
+ {
+ return points_.first;
+ }
+
+ template <typename P>
+ inline
+ P&
+ point_pair<P>::first()
+ {
+ return points_.first;
+ }
+
+ template <typename P>
+ inline
+ P
+ point_pair<P>::second() const
+ {
+ return points_.second;
+ }
+
+ template <typename P>
+ inline
+ P&
+ point_pair<P>::second()
+ {
+ return points_.second;
+ }
+
+ /*---------------.
+ | Constructors. |
+ `---------------*/
+
+ template <typename P>
+ inline
+ point_pair<P>::point_pair()
+ {
+ }
+
+ template <typename P>
+ inline
+ point_pair<P>::point_pair(const P& first, const P& second)
+ : points_(first, second)
+ {
+ }
+
+ template <typename P>
+ inline
+ point_pair<P>::point_pair(const std::pair<P, P>& points)
+ : points_(points)
+ {
+ }
+
+ /*----------.
+ | Display. |
+ `----------*/
+
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const point_pair<P>& p)
+ {
+ return ostr << '(' << p.first() << " -- "
<< p.second() << ")";
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+} // end of namespace mln
+
+
+#endif // ! MLN_CORE_POINT_PAIR_HH
Index: mln/core/line_graph_elt_window.hh
--- mln/core/line_graph_elt_window.hh (revision 1714)
+++ mln/core/line_graph_elt_window.hh (working copy)
@@ -25,37 +25,37 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_WIN_GRAPH_ELT_WINDOW_HH
-# define MLN_WIN_GRAPH_ELT_WINDOW_HH
+#ifndef MLN_CORE_LINE_GRAPH_ELT_WINDOW_HH
+# define MLN_CORE_LINE_GRAPH_ELT_WINDOW_HH
-/*! \file mln/core/graph_elt_window.hh
+/*! \file mln/core/line_graph_elt_window.hh
*
- * \brief Definition of the elementary ``window'' on a graph.
+ * \brief Definition of the elementary ``window'' on a line graph.
*
* \todo Make naming coherent: we have window (without '_') but
* point_, neighb_, etc.
*/
# include <mln/core/concept/window.hh>
-# include <mln/core/graph_psite.hh>
-# include <mln/core/graph_window_piter.hh>
+# include <mln/core/line_graph_psite.hh>
+# include <mln/core/line_graph_window_piter.hh>
namespace mln
{
// Fwd decls.
- template <typename P> class graph_window_fwd_piter;
- template <typename P> class graph_window_bkd_piter;
+ template <typename P> class line_graph_window_fwd_piter;
+ template <typename P> class line_graph_window_bkd_piter;
- /*! \brief Elementary window on graph class.
+ /*! \brief Elementary window on line graph class.
*
* FIXME: Doc.
*/
template <typename P>
- class graph_elt_window : public Window< graph_elt_window<P> >
+ class line_graph_elt_window : public Window< line_graph_elt_window<P> >
{
- typedef graph_elt_window<P> self_;
+ typedef line_graph_elt_window<P> self_;
public:
/// Associated types.
@@ -71,19 +71,19 @@
/*! \brief Point_Iterator type to browse the points of a generic window
* w.r.t. the ordering of delta-points.
*/
- typedef graph_window_fwd_piter<P> fwd_qiter;
+ typedef line_graph_window_fwd_piter<P> fwd_qiter;
/*! \brief Point_Iterator type to browse the points of a generic window
* w.r.t. the reverse ordering of delta-points.
*/
- typedef graph_window_bkd_piter<P> bkd_qiter;
+ typedef line_graph_window_bkd_piter<P> bkd_qiter;
/// The default qiter type.
typedef fwd_qiter qiter;
/// \}
- /// Construct an elementary graph window.
- graph_elt_window();
+ /// Construct an elementary line_graph window.
+ line_graph_elt_window();
/// Is the window is empty?
bool is_empty() const;
@@ -98,12 +98,12 @@
/// Return the maximum coordinate gap between the window center
/// and a window point.
/* FIXME: This method returns a dummy value (0), since the delta
- of a window on a graph
+ of a window on a line_graph
- 1. is not constant (graph nodes are not necessarily aligned on
- a regular grid);
+ 1. is not constant (line graph edges are not necessarily
+ aligned on a regular grid);
- 2. depends on the underlying graph, too.
+ 2. depends on the underlying line_graph, too.
It raises another question: should delta() be part of the
concept ``Window''? */
@@ -118,14 +118,14 @@
template <typename P>
inline
- graph_elt_window<P>::graph_elt_window()
+ line_graph_elt_window<P>::line_graph_elt_window()
{
}
template <typename P>
inline
bool
- graph_elt_window<P>::is_empty() const
+ line_graph_elt_window<P>::is_empty() const
{
return false;
}
@@ -133,7 +133,7 @@
template <typename P>
inline
bool
- graph_elt_window<P>::is_centered() const
+ line_graph_elt_window<P>::is_centered() const
{
return false;
}
@@ -141,7 +141,7 @@
template <typename P>
inline
bool
- graph_elt_window<P>::is_symmetric() const
+ line_graph_elt_window<P>::is_symmetric() const
{
return true;
}
@@ -149,7 +149,7 @@
template <typename P>
inline
unsigned
- graph_elt_window<P>::delta() const
+ line_graph_elt_window<P>::delta() const
{
// Dummy value (see the interface of the method above).
return 0;
@@ -157,8 +157,8 @@
template <typename P>
inline
- graph_elt_window<P>&
- graph_elt_window<P>::sym()
+ line_graph_elt_window<P>&
+ line_graph_elt_window<P>::sym()
{
return *this;
}
@@ -168,4 +168,4 @@
} // end of namespace mln
-#endif // ! MLN_WIN_GRAPH_ELT_WINDOW_HH
+#endif // ! MLN_CORE_LINE_GRAPH_ELT_WINDOW_HH
Index: mln/core/line_graph_image.hh
--- mln/core/line_graph_image.hh (revision 1714)
+++ mln/core/line_graph_image.hh (working copy)
@@ -25,40 +25,54 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_GRAPH_IMAGE_HH
-# define MLN_CORE_GRAPH_IMAGE_HH
+#ifndef MLN_CORE_LINE_GRAPH_IMAGE_HH
+# define MLN_CORE_LINE_GRAPH_IMAGE_HH
-/*! \file mln/core/graph_image.hh
- *
- * \brief Definition of a graph-based image.
- */
+/// \file mln/core/line_graph_image.hh
+/// \brief Definition of a line graph-based image.
# include <mln/trait/images.hh>
# include <mln/core/internal/image_primary.hh>
# include <mln/metal/vec.hh>
-# include <mln/core/p_graph.hh>
-# include <mln/core/graph_psite.hh>
+# include <mln/core/p_line_graph.hh>
+# include <mln/core/line_graph_psite.hh>
# include <mln/value/set.hh>
# include <vector>
+/* FIXME: This class shares a lot with graph_image. Factor as much as
+ possible. */
+
+/* FIXME: This is only a very naive prototype. For instance, this
+ image associates values to both the nodes and the edges of the
+ graph, but only values on edges are accessible. We probably want
+ to fork this class to have a pure image of line graph (with no data
+ on nodes) and one having data on both nodes and edges.
+
+ Moreover, in the current implementation, the type of values on
+ nodes and edges is necessarily the same (V). We should allow
+ different data types for nodes and edges. */
+
+
namespace mln
{
// Fwd decl.
- template <typename P, typename V> struct graph_image;
+ template <typename P, typename V> struct line_graph_image;
namespace internal
{
- /// \internal Data structure for \c mln::graph_image<P,V>.
+ /// \internal Data structure for \c mln::line_graph_image<P,V>.
template <typename P, typename V>
- struct data_< graph_image<P, V> >
+ struct data_< line_graph_image<P, V> >
{
- data_(p_graph<P>& g, std::vector<V>& val);
+ data_(p_line_graph<P>& g,
+ std::vector<V>& node_val, std::vector<V>& edge_val);
- std::vector<V> val_;
- p_graph<P>& pg_;
+ std::vector<V> node_val_;
+ std::vector<V> edge_val_;
+ p_line_graph<P>& plg_;
};
} // end of namespace mln::internal
@@ -68,7 +82,8 @@
{
template <typename P, typename V>
- struct image_< graph_image<P, V> > : default_image_< V,
graph_image<P, V> >
+ struct image_< line_graph_image<P, V> >
+ : default_image_< V, line_graph_image<P, V> >
{
typedef trait::image::category::primary category;
@@ -91,11 +106,12 @@
*
*/
template <typename P, typename V>
- struct graph_image :
- public internal::image_primary_< p_graph<P>, graph_image<P, V> >
+ struct line_graph_image :
+ public internal::image_primary_< p_line_graph<P>, line_graph_image<P,
V> >
{
- typedef mln::internal::image_base_< p_graph<P>, graph_image<P, V> >
super_;
+ typedef mln::internal::image_base_< p_line_graph<P>,
+ line_graph_image<P, V> > super_;
/// Value associated type.
typedef V value;
@@ -111,20 +127,22 @@
/// Skeleton.
- typedef graph_image< tag::psite_<P>, tag::value_<V> > skeleton;
+ typedef line_graph_image< tag::psite_<P>, tag::value_<V> >
skeleton;
/// Constructors.
- graph_image(p_graph<P>& g, std::vector<V>& val);
- graph_image();
+ line_graph_image(p_line_graph<P>& g,
+ std::vector<V>& node_val, std::vector<V>& edge_val);
+ line_graph_image();
/// Initialize an empty image.
- void init_(p_graph<P>& g, std::vector<V>& val);
+ void init_(p_line_graph<P>& g,
+ std::vector<V>& node_val, std::vector<V>& edge_val);
/// Read-only access of pixel value at point site \p p.
- const V& operator()(const graph_psite<P>& p) const;
+ const V& operator()(const line_graph_psite<P>& p) const;
/// Read-write access of pixel value at point site \p p.
- V& operator()(const graph_psite<P>& p);
+ V& operator()(const line_graph_psite<P>& p);
/// Give the set of values of the image.
const vset& values() const;
@@ -132,7 +150,9 @@
// FIXME: Keep this name?
const std::vector<V>& data_values () const;
- const p_graph<P>& domain() const;
+ const p_line_graph<P>& domain() const;
+
+ // FIXME: Do we want to provide these two methods?
/// Return the point of the first node adjacent to the edge with
/// id \a e.
@@ -145,7 +165,8 @@
// Fwd decl.
template <typename P, typename V>
void init_(tag::image_t,
- graph_image<P, V>& target, const graph_image<P, V>& model);
+ line_graph_image<P, V>& target,
+ const line_graph_image<P, V>& model);
# ifndef MLN_INCLUDE_ONLY
@@ -157,7 +178,8 @@
template <typename P, typename V>
inline
void init_(tag::image_t,
- graph_image<P, V>& target, const graph_image<P, V>& model)
+ line_graph_image<P, V>& target,
+ const line_graph_image<P, V>& model)
{
/* FIXME: Unfortunately, we cannot simply use
@@ -165,9 +187,9 @@
here, since domain() and data_values() return const data, and
init_ expects non mutable data. These constness problems exist
- also in graph_psite (see uses of const_cast<>). Hence the
+ also in line_graph_psite (see uses of const_cast<>). Hence the
inelegant use of const_cast<>'s. */
- target.init_(const_cast<p_graph<P>&> (model.domain()),
+ target.init_(const_cast<p_line_graph<P>&>(model.domain()),
const_cast<std::vector<V>&> (model.data_values ()));
}
@@ -179,9 +201,12 @@
{
template <typename P, typename V>
inline
- data_< graph_image<P, V> >::data_(p_graph<P>& g,
std::vector<V>& val)
- : val_ (val),
- pg_ (g)
+ data_< line_graph_image<P, V> >::data_(p_line_graph<P>& g,
+ std::vector<V>& node_val,
+ std::vector<V>& edge_val)
+ : node_val_(node_val),
+ edge_val_(edge_val),
+ plg_(g)
{
}
@@ -193,28 +218,33 @@
template <typename P, typename V>
inline
- graph_image<P, V>::graph_image(p_graph<P>& g, std::vector<V>&
val)
+ line_graph_image<P, V>::line_graph_image(p_line_graph<P>& g,
+ std::vector<V>& node_val,
+ std::vector<V>& edge_val)
{
- init_(g, val);
+ init_(g, node_val, edge_val);
}
template <typename P, typename V>
inline
- graph_image<P, V>::graph_image()
+ line_graph_image<P, V>::line_graph_image()
{
}
template <typename P, typename V>
inline
void
- graph_image<P, V>::init_(p_graph<P>& g, std::vector<V>& val)
+ line_graph_image<P, V>::init_(p_line_graph<P>& g,
+ std::vector<V>& node_val,
+ std::vector<V>& edge_val)
{
/* FIXME: We leak memory here: calling init_ twice loses the
previous content pointed by data_.
We should definitely write down formal guidelines on
initialization and memory management in general! */
- this->data_ = new internal::data_< graph_image<P, V> > (g, val);
+ this->data_ =
+ new internal::data_< line_graph_image<P, V> >(g, node_val, edge_val);
}
/*---------------.
@@ -224,27 +254,27 @@
template <typename P, typename V>
inline
const V&
- graph_image<P, V>::operator()(const graph_psite<P>& p) const
+ line_graph_image<P, V>::operator()(const line_graph_psite<P>& p) const
{
- mln_precondition(&p.pg() == &this->data_->pg_);
- mln_precondition(p.id() < this->data_->val_.size());
- return this->data_->val_[p.id()];
+ mln_precondition(&p.plg() == &this->data_->plg_);
+ mln_precondition(p.id() < this->data_->edge_val_.size());
+ return this->data_->edge_val_[p.id()];
}
template <typename P, typename V>
inline
V&
- graph_image<P, V>::operator()(const graph_psite<P>& p)
+ line_graph_image<P, V>::operator()(const line_graph_psite<P>& p)
{
- mln_precondition(&p.pg() == &this->data_->pg_);
- mln_precondition(p.id() < this->data_->val_.size());
- return this->data_->val_[p.id()];
+ mln_precondition(&p.plg() == &this->data_->plg_);
+ mln_precondition(p.id() < this->data_->edge_val_.size());
+ return this->data_->edge_val_[p.id()];
}
template <typename P, typename V>
inline
const mln::value::set<V> &
- graph_image<P, V>::values() const
+ line_graph_image<P, V>::values() const
{
return vset::the();
}
@@ -252,24 +282,24 @@
template <typename P, typename V>
inline
const std::vector<V>&
- graph_image<P, V>::data_values () const
+ line_graph_image<P, V>::data_values() const
{
- return this->data_->val_;
+ return this->data_->edge_val_;
}
template <typename P, typename V>
inline
- const p_graph<P>&
- graph_image<P, V>::domain() const
+ const p_line_graph<P>&
+ line_graph_image<P, V>::domain() const
{
mln_precondition(this->has_data());
- return this->data_->pg_;
+ return this->data_->plg_;
}
template <typename P, typename V>
inline
const P&
- graph_image<P, V>::node1(const util::edge_id& e) const
+ line_graph_image<P, V>::node1(const util::edge_id& e) const
{
// FIXME: Improve the interface of graph to avoid these low-level
// manipulations.
@@ -280,7 +310,7 @@
template <typename P, typename V>
inline
const P&
- graph_image<P, V>::node2(const util::edge_id& e) const
+ line_graph_image<P, V>::node2(const util::edge_id& e) const
{
// FIXME: Improve the interface of graph to avoid these low-level
// manipulations.
@@ -293,4 +323,4 @@
} // end of namespace mln
-#endif // ! MLN_CORE_GRAPH_IMAGE_HH
+#endif // ! MLN_CORE_LINE_GRAPH_IMAGE_HH
Index: mln/core/line_graph_psite.hh
--- mln/core/line_graph_psite.hh (revision 1714)
+++ mln/core/line_graph_psite.hh (working copy)
@@ -25,134 +25,200 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_GRAPH_PSITE_HH
-# define MLN_CORE_GRAPH_PSITE_HH
+#ifndef MLN_CORE_LINE_GRAPH_PSITE_HH
+# define MLN_CORE_LINE_GRAPH_PSITE_HH
-/// \file mln/core/graph_psite.hh
-/// \brief Definition of a graph-based point site.
+/// \file mln/core/line_graph_psite.hh
+/// \brief Definition of a line graph-based point site.
-# include <mln/core/p_graph.hh>
+# include <mln/core/p_line_graph.hh>
+# include <mln/core/point_pair.hh>
+
+/* FIXME: This class shares a lot with graph_psite. Factor as much as
+ possible. */
namespace mln
{
// Fwd decl.
- template<typename P> class p_graph;
+ template<typename P> class p_line_graph;
/// \brief Point site associated to a mln::graph_image.
template<typename P>
- class graph_psite : public Point_Site< graph_psite<P> >
+ class line_graph_psite : public Point_Site< line_graph_psite<P> >
{
- typedef graph_psite<P> self_;
+ typedef line_graph_psite<P> self_;
public:
- typedef mln_mesh(P) mesh;
- enum { dim = P::dim };
- typedef P point;
- typedef mln_dpoint(P) dpoint;
- typedef mln_coord(P) coord;
+ typedef point_pair<P> point;
+ typedef mln_mesh(point) mesh;
+ enum { dim = point::dim };
+ typedef mln_dpoint(point) dpoint;
+ typedef mln_coord(point) coord;
/// Construction and assignment.
/// \{
- graph_psite(const p_graph<P>& pg_, unsigned id);
- graph_psite(const self_& rhs);
+ line_graph_psite(const p_line_graph<P>& plg_, unsigned id);
+ line_graph_psite(const self_& rhs);
self_& operator= (const self_& rhs);
/// \}
/// Access to point/psite.
/// \{
- operator P() const;
+ operator point() const;
const point& to_point() const;
coord operator[](unsigned id) const;
/// \}
- /// Return the mln::p_graph this point site belongs to.
- const p_graph<P>& pg() const;
+ /// Return the mln::p_line_graph this point site belongs to.
+ const p_line_graph<P>& plg() const;
/// Return the node id of this point site.
util::node_id id() const;
private:
- const p_graph<P>& pg_;
- util::node_id id_;
+ /// Update \a p_.
+ void update_();
+ /// Is this psite valid?
+ bool is_valid_() const;
+
+ private:
+ /// The p_line_graph this point site belongs to.
+ const p_line_graph<P>& plg_;
+ /// The id of the edge this psite is pointing towards.
+ util::edge_id id_;
+ /** \brief The point associated to this psite.
+
+ Contrary to mln::graph_psite, this information is actually
+ stored in the mln::line_graph_psite. In mln::graph_psite, the
+ point is retrieved from the data associated with the
+ corresponding node in the graph. We cannot do this here,
+ since points associated to edges are computed on the fly
+ (storing them in the graph could be possible, but too costly
+ in space). */
+ point p_;
};
+ /* FIXME: This hand-made delegation is painful. We should rely on
+ the general mechanism provided by Point_Site. But then again, we
+ need to refine/adjust the interface of Point_Site w.r.t. the
+ mandatory conversions to points. */
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const line_graph_psite<P>& p);
# ifndef MLN_INCLUDE_ONLY
+ /* Careful, the current interface of line_graph_psite allows the
+ construction of ill-formed psites (i.e., whose edge is is beyond
+ bounds). Actually, p_line_graph_piters *do* create ill-formed
+ psites at their initialization. */
+
template<typename P>
inline
- graph_psite<P>::graph_psite(const p_graph<P>& g, util::node_id id)
- : pg_(g),
- id_(id)
+ line_graph_psite<P>::line_graph_psite(const p_line_graph<P>& g,
+ util::edge_id id)
+ : plg_(g),
+ id_(id),
+ p_()
{
}
template<typename P>
inline
- graph_psite<P>::graph_psite(const graph_psite<P>& rhs)
- : pg_(rhs.pg_),
+ line_graph_psite<P>::line_graph_psite(const line_graph_psite<P>& rhs)
+ : plg_(rhs.plg_),
id_(rhs.id_)
{
}
template<typename P>
inline
- graph_psite<P>&
- graph_psite<P>::operator= (const graph_psite<P>& rhs)
+ line_graph_psite<P>&
+ line_graph_psite<P>::operator= (const line_graph_psite<P>& rhs)
{
if (&rhs == this)
return *this;
// FIXME: Could we get rid of this cast?
- const_cast< p_graph<P>& >(pg_) = rhs.pg_;
+ const_cast< p_line_graph<P>& >(plg_) = rhs.plg_;
id_ = rhs.id_;
+ update_();
return *this;
}
template<typename P>
inline
- graph_psite<P>::operator P() const
+ line_graph_psite<P>::operator point_pair<P>() const
+ {
+ mln_assertion (is_valid_());
+ return p_;
+ }
+
+ template<typename P>
+ inline
+ bool
+ line_graph_psite<P>::is_valid_() const
{
- return pg_.gr_.node_data(id_);
+ return id_ < plg_.gr_.nedges();
}
template<typename P>
inline
- const P&
- graph_psite<P>::to_point() const
+ const point_pair<P>&
+ line_graph_psite<P>::to_point() const
{
- return pg_.gr_.node_data(id_);
+ return p_;
}
template<typename P>
inline
- mln_coord(P)
- graph_psite<P>::operator[](util::node_id id) const
+ mln_coord(point_pair<P>)
+ line_graph_psite<P>::operator[](unsigned i) const
{
- return to_point()[id];
+ mln_assertion (is_valid_());
+ return to_point()[i];
}
template<typename P>
inline
- const p_graph<P>&
- graph_psite<P>::pg() const
+ void
+ line_graph_psite<P>::update_()
{
- return pg_;
+ p_ = point(plg_.gr_.node_data(plg_.gr_.edge(id_).n1()),
+ plg_.gr_.node_data(plg_.gr_.edge(id_).n2()));
+ }
+
+ template<typename P>
+ inline
+ const p_line_graph<P>&
+ line_graph_psite<P>::plg() const
+ {
+ return plg_;
}
template<typename P>
inline
util::node_id
- graph_psite<P>::id() const
+ line_graph_psite<P>::id() const
{
return id_;
}
+
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const line_graph_psite<P>& p)
+ {
+ return ostr << p.to_point();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of mln
-#endif // MLN_CORE_GRAPH_PSITE_HH
+#endif // MLN_CORE_LINE_GRAPH_PSITE_HH
Index: mln/core/line_graph_window_piter.hh
--- mln/core/line_graph_window_piter.hh (revision 1714)
+++ mln/core/line_graph_window_piter.hh (working copy)
@@ -25,51 +25,56 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_GRAPH_WINDOW_PITER_HH
-# define MLN_CORE_GRAPH_WINDOW_PITER_HH
+#ifndef MLN_CORE_LINE_GRAPH_WINDOW_PITER_HH
+# define MLN_CORE_LINE_GRAPH_WINDOW_PITER_HH
-/// \file mln/core/graph_window_piter.hh
-/// \brief Definition of a point iterator on a graph window.
+/// \file mln/core/line_graph_window_piter.hh
+/// \brief Definition of a point iterator on a line_graph window.
# include <mln/core/concept/point_iterator.hh>
-# include <mln/core/p_graph.hh>
-# include <mln/core/graph_psite.hh>
+# include <mln/core/p_line_graph.hh>
+# include <mln/core/line_graph_psite.hh>
+# include <mln/core/point_pair.hh>
/* FIXME: Doc. */
-/* FIXME: Due to the poor interface of mln::p_graph and
+/* FIXME: Due to the poor interface of mln::p_line_graph and
mln::util::graph, we show to much implementation details here.
Enrich their interfaces to avoid that. */
namespace mln
{
// Fwd decls.
- template <typename P> class p_graph;
- template <typename P> class graph_psite;
+ template <typename P> class p_line_graph;
+ template <typename P> class line_graph_psite;
+ /*---------------------------------.
+ | line_graph_window_fwd_piter<P>. |
+ `---------------------------------*/
+
template <typename P>
- class graph_window_fwd_piter :
- public Point_Iterator< graph_window_fwd_piter<P> > // or
Iterator<...>?
+ class line_graph_window_fwd_piter :
+ public Point_Iterator< line_graph_window_fwd_piter<P> > // or
Iterator<...>?
{
- typedef graph_window_fwd_piter<P> self_;
+ typedef line_graph_window_fwd_piter<P> self_;
typedef Point_Iterator< self_ > super_;
public:
- typedef graph_psite<P> psite;
+ typedef line_graph_psite<P> psite;
enum { dim = P::dim };
// FIXME: Dummy value.
typedef void mesh;
- typedef P point;
+ typedef point_pair<P> point;
// FIXME: Dummy typedef.
typedef void dpoint;
- typedef mln_coord(P) coord;
+ typedef mln_coord(point) coord;
public:
template <typename W, typename Pref>
- graph_window_fwd_piter(const W& win, const Point_Site<Pref>& p_ref);
+ line_graph_window_fwd_piter(const W& win, const Point_Site<Pref>&
p_ref);
bool is_valid() const;
void invalidate();
@@ -77,23 +82,44 @@
void next_();
bool adjacent_or_equal_to_p_ref_() const;
+ /// Update the internal data of the iterator.
+ void update_();
- // FIXME: In fact, this method should be named `to_psite', since
- // it returns a mln::graph_psite<P> object, not a P object.
const point& to_point() const;
+ const psite& to_psite() const;
+
+ operator point() const;
operator psite () const;
+
/// Return the \a i th coordinate of the (iterated) point.
coord operator[](unsigned i) const;
private:
- /// The ``central'' point of the window.
+ /// The ``central'' psite of the window.
const psite& p_ref_;
-
- /// An internal iterator on the set of nodes of the underlying graph.
- util::node_id id_;
+ /// An internal iterator on the set of edges of the underlying graph.
+ util::edge_id id_;
+ /// The psite corresponding to this iterator.
+ psite psite_;
+ /// The point corresponding to this iterator.
+ point p_;
};
- // FIXME: Implement graph_window_bkd_piter.
+ /* FIXME: This hand-made delegation is painful. We should rely on
+ the general mechanism provided by Point_Site. But then again, we
+ need to refine/adjust the interface of Point_Site w.r.t. the
+ mandatory conversions to points. */
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const
line_graph_window_fwd_piter<P>& p);
+
+
+ /*---------------------------------.
+ | line_graph_window_bkd_piter<P>. |
+ `---------------------------------*/
+
+ // FIXME: Implement line_graph_window_bkd_piter.
# ifndef MLN_INCLUDE_ONLY
@@ -101,61 +127,76 @@
// FIXME: Currently, argument win is ignored.
template <typename P>
template <typename W, typename Pref>
- graph_window_fwd_piter<P>::graph_window_fwd_piter(const W& /* win */,
+ inline
+ line_graph_window_fwd_piter<P>::line_graph_window_fwd_piter(const W& /* win
*/,
const Point_Site<Pref>& p_ref)
- : p_ref_(exact(p_ref).to_psite())
+ : p_ref_(exact(p_ref).to_psite()),
+ // Initialize psite_ to a dummy value.
+ psite_(p_ref_.plg(), p_ref_.plg().nlines()),
+ p_()
{
// Invalidate id_.
invalidate();
}
template <typename P>
+ inline
bool
- graph_window_fwd_piter<P>::is_valid() const
+ line_graph_window_fwd_piter<P>::is_valid() const
{
// FIXME: We depend too much on the implementation of util::graph
// here. The util::graph should provide the service to abstract
// these manipulations.
- return id_ < p_ref_.pg().gr_.nnodes();
+ return id_ < p_ref_.plg().gr_.nedges();
}
template <typename P>
+ inline
void
- graph_window_fwd_piter<P>::invalidate()
+ line_graph_window_fwd_piter<P>::invalidate()
{
- id_ = p_ref_.pg().gr_.nnodes();
+ id_ = p_ref_.plg().gr_.nedges();
}
template <typename P>
+ inline
void
- graph_window_fwd_piter<P>::start()
+ line_graph_window_fwd_piter<P>::start()
{
id_ = 0;
if (!adjacent_or_equal_to_p_ref_())
next_();
+ /* FIXME: This is redundant with the end of next_(), but we might
+ change the implementation of start_() when we'll fix it later,
+ and no longer use next_(). */
+ if (is_valid())
+ update_();
}
template <typename P>
+ inline
void
- graph_window_fwd_piter<P>::next_()
+ line_graph_window_fwd_piter<P>::next_()
{
/* FIXME: This is inefficient. The graph structure should be able
- to produce the set of adjacent nodes fast. Boost Graphs
+ to produce the set of adjacent edges fast. Boost Graphs
probably provides adequates structures to fetch these
neighbors in constant time. */
/* FIXME: Moreover, the behavior of next shall depend on the
- window, which is not the case now! */
+ window, which is not the case now! (Currently, next_() behaves
+ as win was always an elementary window.) */
do
++id_;
while (is_valid() && !adjacent_or_equal_to_p_ref_());
+ if (is_valid())
+ update_();
}
template <typename P>
+ inline
bool
- graph_window_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const
+ line_graph_window_fwd_piter<P>::adjacent_or_equal_to_p_ref_() const
{
- // FIXME: Likewise, this is inefficient.
-
// Check wether the iterator points to P_REF_.
if (id_ == p_ref_.id())
return true;
@@ -163,15 +204,19 @@
// Check whether the iterator is among the neighbors of P_REF_.
{
// Paranoid assertion.
- assert (p_ref_.id() < p_ref_.pg().gr_.nnodes());
- // FIXME: This is too low-level. Yet another service the graph
- // should provide.
- typedef std::vector<util::node_id> adjacency_type;
- const adjacency_type& p_ref_neighbs =
- p_ref_.pg().gr_.nodes()[p_ref_.id()]->edges;
- adjacency_type::const_iterator j =
- std::find (p_ref_neighbs.begin(), p_ref_neighbs.end(), id_);
- if (j != p_ref_neighbs.end())
+ assert (p_ref_.id() < p_ref_.plg().gr_.nedges());
+ /* FIXME: We should have a convenient shortcut for these
+ repetitive accesses to p_ref_.plg().gr_ (e.g., a method gr()
+ or g() in this class. */
+ const typename p_line_graph<P>::graph& gr = p_ref_.plg().gr_;
+ // Check whether the edge this iterator points to is adjacent to
+ // the one p_ref points to, by comparing their ajacent nodes.
+ /* FIXME: This is too low-level. Yet another service the graph
+ // should provide. */
+ if (gr.edge(id_).n1() == gr.edge(p_ref_.id()).n1() ||
+ gr.edge(id_).n1() == gr.edge(p_ref_.id()).n2() ||
+ gr.edge(id_).n2() == gr.edge(p_ref_.id()).n1() ||
+ gr.edge(id_).n2() == gr.edge(p_ref_.id()).n2())
return true;
}
@@ -180,29 +225,70 @@
}
template <typename P>
- const P&
- graph_window_fwd_piter<P>::to_point() const
+ inline
+ void
+ line_graph_window_fwd_piter<P>::update_()
{
- return p_ref_.pg().gr_.node_data(id_);
+ // Update psite_.
+ psite_ = line_graph_psite<P>(p_ref_.plg(), id_);
+ // Update p_.
+ // FIXME: These repeated assignments might be very costly.
+ /* FIXME: Likewise, it's hard to read. Simplify accesses to the graph. */
+ p_ = point(p_ref_.plg().gr_.node_data(p_ref_.plg().gr_.edge(id_).n1()),
+ p_ref_.plg().gr_.node_data(p_ref_.plg().gr_.edge(id_).n2()));
}
template <typename P>
- graph_window_fwd_piter<P>::operator graph_psite<P> () const
+ inline
+ const point_pair<P>&
+ line_graph_window_fwd_piter<P>::to_point() const
{
- return graph_psite<P>(p_ref_.pg(), id_);
+ return p_;
}
template <typename P>
inline
- mln_coord(P)
- graph_window_fwd_piter<P>::operator[](unsigned i) const
+ const line_graph_psite<P>&
+ line_graph_window_fwd_piter<P>::to_psite() const
+ {
+ return psite_;
+ }
+
+ template <typename P>
+ inline
+ line_graph_window_fwd_piter<P>::operator point_pair<P>() const
+ {
+ mln_precondition(is_valid());
+ return p_;
+ }
+
+ template <typename P>
+ inline
+ line_graph_window_fwd_piter<P>::operator line_graph_psite<P> () const
+ {
+ mln_precondition(is_valid());
+ return psite_;
+ }
+
+ template <typename P>
+ inline
+ mln_coord(point_pair<P>)
+ line_graph_window_fwd_piter<P>::operator[](unsigned i) const
{
assert(i < dim);
- return to_point()[i];
+ return p_[i];
+ }
+
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const
line_graph_window_fwd_piter<P>& p)
+ {
+ return ostr << p.to_point();
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
-#endif // ! MLN_CORE_GRAPH_WINDOW_PITER_HH
+#endif // ! MLN_CORE_LINE_GRAPH_WINDOW_PITER_HH
Index: mln/core/p_line_graph.hh
--- mln/core/p_line_graph.hh (revision 1714)
+++ mln/core/p_line_graph.hh (working copy)
@@ -25,41 +25,58 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_GRAPH_P_HH
-# define MLN_CORE_GRAPH_P_HH
+#ifndef MLN_CORE_LINE_GRAPH_P_HH
+# define MLN_CORE_LINE_GRAPH_P_HH
# include <mln/core/concept/point_site.hh>
# include <mln/core/internal/point_set_base.hh>
# include <mln/accu/bbox.hh>
# include <mln/util/graph.hh>
-# include <mln/core/graph_psite.hh>
-# include <mln/core/p_graph_piter.hh>
+# include <mln/core/line_graph_psite.hh>
+# include <mln/core/p_line_graph_piter.hh>
+# include <mln/core/point_pair.hh>
-/// \file mln/core/p_graph.hh
-/// \brief Definition of a point set based on graph.
+/* FIXME: This class shares a lot with p_graph. Factor as much as
+ possible. */
+
+
+/// \file mln/core/p_line_graph.hh
+/// \brief Definition of a point set based on line graph.
namespace mln
{
- template<typename P> class p_graph_piter_;
+ // FIXME: Dummy specialization, only to have this first version of
+ // our code compile.
+ template <typename P>
+ struct box_< point_pair<P> > : public Box< box_<P> >
+ {
+ // Nothing.
+ };
+
+
+ template<typename P> class p_line_graph_piter_;
template<typename P>
- struct p_graph
- : public internal::point_set_base_< graph_psite<P>, p_graph<P> >
+ struct p_line_graph
+ : public internal::point_set_base_< line_graph_psite<P>,
p_line_graph<P> >
{
typedef util::graph<P> graph;
- /// Construct a graph psite set from a graph of points.
- p_graph (graph& gr);
+ /// Construct a line graph psite set from a graph of points.
+ p_line_graph (graph& gr);
/// Point_Site associated type.
- typedef graph_psite<P> psite;
+ typedef line_graph_psite<P> psite;
+
+ /// Point associated type.
+ typedef point_pair<P> point;
/// Forward Point_Iterator associated type.
- typedef p_graph_piter_<P> fwd_piter;
+ typedef p_line_graph_piter_<P> fwd_piter;
/// Backward Point_Iterator associated type.
- typedef p_graph_piter_<P> bkd_piter;
+ typedef p_line_graph_piter_<P> bkd_piter;
/// Return The number of points (i.e., nodes) in the graph.
std::size_t npoints() const;
@@ -68,32 +85,37 @@
std::size_t nlines() const;
/// Give the exact bounding box.
- const box_<P>& bbox() const;
+ // FIXME: Dummy.
+ const box_<point>& bbox() const;
bool has(const psite& p) const;
// FIXME: Should be private.
graph gr_;
// FIXME: (Roland) Is it really useful/needed?
- /* 2007-12-19: It seems so, since graph_image must implement a method
- named bbox(). Now the question is: should each image type have a
- bounding box? */
- box_<P> bb_;
+ /* 2007-12-19: It seems so, since graph_image must implement a
+ method named bbox(). Now the question is: should each image
+ type have a bounding box? In particular, an image whose sites
+ are actually /pairs of points/! */
+ // FIXME: Dummy.
+ box_<point> bb_;
};
# ifndef MLN_INCLUDE_ONLY
template<typename P>
inline
- p_graph<P>::p_graph (util::graph<P>& gr)
+ p_line_graph<P>::p_line_graph (util::graph<P>& gr)
: gr_ (gr)
{
- // FIXME: Warning: if the underlying graph is updated later, this
- // won't be taken into account by this p_graph!
- accu::bbox<P> a;
- for (unsigned i = 0; i < npoints(); ++i)
- a.take(gr_.node_data(i));
- bb_ = a.to_result();
+ // FIXME: Dummy initialization of bb_.
+// // FIXME: Warning: if the underlying graph is updated later, this
+// // won't be taken into account by this p_line_graph!
+// accu::bbox<point> a;
+// for (util::edge_id e = 0; e < nlines(); ++e)
+// a.take(point(gr_.node_data(gr_.edge(e).n1()),
+// gr_.node_data(gr_.edge(e).n2())));
+// bb_ = a.to_result();
}
// FIXME: Rename to npsites? In fact, this depends on the
@@ -101,7 +123,7 @@
template<typename P>
inline
std::size_t
- p_graph<P>::npoints() const
+ p_line_graph<P>::npoints() const
{
return this->gr_.nnodes();
}
@@ -109,15 +131,15 @@
template<typename P>
inline
std::size_t
- p_graph<P>::nlines() const
+ p_line_graph<P>::nlines() const
{
return this->gr_.nedges();
}
template<typename P>
inline
- const box_<P>&
- p_graph<P>::bbox() const
+ const box_< point_pair<P> >&
+ p_line_graph<P>::bbox() const
{
return bb_;
}
@@ -125,16 +147,13 @@
template<typename P>
inline
bool
- p_graph<P>::has(const psite& p) const
+ p_line_graph<P>::has(const psite& p) const
{
- // FIXME: util::graph (or util::internal::graph_base) should
- // provide the iteration facility (iterators, find, etc.)
- const typename graph::nodes_t& nodes = gr_.nodes();
- for (typename graph::nodes_t::const_iterator n = nodes.begin();
- n != nodes.end(); ++n)
- if ((*n)->data == p)
- return true;
- return false;
+ return
+ // Check whether P is compatible with this psite set.
+ (&p.plg() == this) &&
+ // Check that the edge id of P belongs to the range of valid edge ids.
+ (p.id() < gr_.nedges());
}
# endif // ! MLN_INCLUDE_ONLY
Index: mln/core/p_line_graph_piter.hh
--- mln/core/p_line_graph_piter.hh (revision 1714)
+++ mln/core/p_line_graph_piter.hh (working copy)
@@ -25,14 +25,15 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-#ifndef MLN_CORE_P_GRAPH_PITER_HH
-# define MLN_CORE_P_GRAPH_PITER_HH
+#ifndef MLN_CORE_P_LINE_GRAPH_PITER_HH
+# define MLN_CORE_P_LINE_GRAPH_PITER_HH
# include <mln/core/internal/point_iterator_base.hh>
-# include <mln/core/p_graph.hh>
-# include <mln/core/graph_psite.hh>
+# include <mln/core/p_line_graph.hh>
+# include <mln/core/line_graph_psite.hh>
+# include <mln/core/point_pair.hh>
-/*! \file mln/core/p_graph_piter.hh
+/*! \file mln/core/p_line_graph_piter.hh
*
* \brief Definition of point iterator on graph-based point set.
*/
@@ -40,30 +41,32 @@
namespace mln
{
// Fwd decls.
- template<typename P> class p_graph;
- template<typename P> class graph_psite;
+ template<typename P> class p_line_graph;
+ template<typename P> class line_graph_psite;
- // FIXME: Why `p_graph_piter_' and not `p_graph_piter' (without `_')?
+ // FIXME: Why `p_line_graph_piter_' and not `p_line_graph_piter'
+ // (without `_')?
template<typename P>
- class p_graph_piter_
- : public internal::point_iterator_base_< P, p_graph_piter_<P> >
+ class p_line_graph_piter_
+ : public internal::point_iterator_base_< P, p_line_graph_piter_<P> >
{
- typedef p_graph_piter_<P> self_;
+ typedef p_line_graph_piter_<P> self_;
typedef internal::point_iterator_base_< P, self_ > super_;
public:
// Make definitions from super class available.
enum { dim = super_::dim };
- typedef graph_psite<P> psite;
- typedef P point;
+ typedef line_graph_psite<P> psite;
+ typedef point_pair<P> point;
+ typedef mln_coord(point_pair<P>) coord;
- p_graph_piter_(const p_graph<P>& pg);
+ p_line_graph_piter_(const p_line_graph<P>& plg);
/// Read-only access to the \p i-th coordinate.
- mln_coord(P) operator[](unsigned i) const;
+ mln_coord(point) operator[](unsigned i) const;
/// Test if the iterator is valid.
bool is_valid() const;
@@ -93,32 +96,44 @@
operator psite() const;
protected:
- const p_graph<P>& pg_;
- unsigned i_;
- P p_;
+ /// The p_line_graph this point site belongs to.
+ const p_line_graph<P>& plg_;
+ /// The id of the edge this psite is pointing towards.
+ util::edge_id id_;
+ /// The psite corresponding to this iterator.
psite psite_;
+ /// The psite corresponding to this iterator.
+ point p_;
};
+ /* FIXME: This hand-made delegation is painful. We should rely on
+ the general mechanism provided by Point_Site. But then again, we
+ need to refine/adjust the interface of Point_Site w.r.t. the
+ mandatory conversions to points. */
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const p_line_graph_piter_<P>& p);
# ifndef MLN_INCLUDE_ONLY
template<typename P>
inline
- p_graph_piter_<P>::p_graph_piter_(const p_graph<P>& pg)
- : pg_(pg),
- p_(),
+ p_line_graph_piter_<P>::p_line_graph_piter_(const p_line_graph<P>&
plg)
+ : plg_(plg),
// Initialize psite_ to a dummy value.
- psite_(pg, pg_.npoints())
+ psite_(plg, plg_.nlines()),
+ p_()
{
- // Invalidate i_.
+ // Invalidate id_.
invalidate();
}
template<typename P>
inline
- mln_coord(P)
- p_graph_piter_<P>::operator[](unsigned i) const
+ mln_coord(point_pair<P>)
+ p_line_graph_piter_<P>::operator[](unsigned i) const
{
return p_[i];
}
@@ -126,25 +141,25 @@
template<typename P>
inline
bool
- p_graph_piter_<P>::is_valid() const
+ p_line_graph_piter_<P>::is_valid() const
{
- return i_ < pg_.npoints();
+ return id_ < plg_.nlines();
}
template<typename P>
inline
void
- p_graph_piter_<P>::invalidate()
+ p_line_graph_piter_<P>::invalidate()
{
- i_ = pg_.npoints();
+ id_ = plg_.nlines();
}
template<typename P>
inline
void
- p_graph_piter_<P>::start()
+ p_line_graph_piter_<P>::start()
{
- i_ = 0;
+ id_ = 0;
if (is_valid())
update_();
}
@@ -152,9 +167,9 @@
template<typename P>
inline
void
- p_graph_piter_<P>::next_()
+ p_line_graph_piter_<P>::next_()
{
- ++i_;
+ ++id_;
if (is_valid())
update_();
}
@@ -162,18 +177,20 @@
template<typename P>
inline
void
- p_graph_piter_<P>::update_()
+ p_line_graph_piter_<P>::update_()
{
- // Update p_.
- p_ = pg_.gr_.node_data(i_);
// Update psite_.
- psite_ = graph_psite<P>(pg_, i_);
+ psite_ = line_graph_psite<P>(plg_, id_);
+ // Update p_.
+ // FIXME: These repeated assignments might be very costly.
+ p_ = point(plg_.gr_.node_data(plg_.gr_.edge(id_).n1()),
+ plg_.gr_.node_data(plg_.gr_.edge(id_).n2()));
}
template<typename P>
inline
- const P&
- p_graph_piter_<P>::to_point() const
+ const point_pair<P>&
+ p_line_graph_piter_<P>::to_point() const
{
/* We don't check whether the iterator is valid before returning
the value using
@@ -191,8 +208,8 @@
template<typename P>
inline
- const graph_psite<P>&
- p_graph_piter_<P>::to_psite() const
+ const line_graph_psite<P>&
+ p_line_graph_piter_<P>::to_psite() const
{
/* We don't check whether the iterator is valid before returning
the value using
@@ -210,7 +227,7 @@
template<typename P>
inline
- p_graph_piter_<P>::operator P() const
+ p_line_graph_piter_<P>::operator point_pair<P>() const
{
mln_precondition(is_valid());
return p_;
@@ -218,15 +235,24 @@
template<typename P>
inline
- p_graph_piter_<P>::operator graph_psite<P>() const
+ p_line_graph_piter_<P>::operator line_graph_psite<P>() const
{
mln_precondition(is_valid());
return psite_;
}
+
+ template <typename P>
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const p_line_graph_piter_<P>& p)
+ {
+ return ostr << p.to_point();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of mln
-#endif // MLN_P_GRAPH_PITER_HH
+#endif // MLN_P_LINE_GRAPH_PITER_HH
Index: tests/core/line_graph_elt_window.cc
--- tests/core/line_graph_elt_window.cc (revision 1715)
+++ tests/core/line_graph_elt_window.cc (working copy)
@@ -25,15 +25,15 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/*! \file tests/core/graph_elt_window.cc
+/*! \file tests/core/line_graph_elt_window.cc
*
- * \brief Tests on mln::win::graph_elt_window.
+ * \brief Tests on mln::line_graph_elt_window.
*/
#include <vector>
#include <mln/core/point2d.hh>
-#include <mln/core/graph_elt_window.hh>
+#include <mln/core/line_graph_elt_window.hh>
#include <mln/debug/iota.hh>
#include <mln/debug/println.hh>
@@ -73,10 +73,10 @@
| Graph and window. |
`------------------*/
- // Graph psite set.
- p_graph<p_t> pg(g);
- // Graph point site.
- graph_psite<p_t> psite(pg, 0);
- // ``Sliding'' window (in fact, neighborhood) of a psite of PG.
- graph_elt_window<p_t> win;
+ // Line graph psite set.
+ p_line_graph<p_t> plg(g);
+ // Line graph point site.
+ line_graph_psite<p_t> psite(plg, 0);
+ // ``Sliding'' window of a psite of PLG.
+ line_graph_elt_window<p_t> win;
}
Index: tests/core/line_graph_image.cc
--- tests/core/line_graph_image.cc (revision 1714)
+++ tests/core/line_graph_image.cc (working copy)
@@ -31,9 +31,9 @@
#include <vector>
#include <mln/core/point2d.hh>
-#include <mln/core/graph_image.hh>
-#include <mln/core/graph_elt_window.hh>
-#include <mln/core/graph_window_piter.hh>
+#include <mln/core/line_graph_image.hh>
+#include <mln/core/line_graph_elt_window.hh>
+#include <mln/core/line_graph_window_piter.hh>
#include <mln/morpho/dilation.hh>
@@ -74,44 +74,26 @@
| Graph. |
`-------*/
- p_graph<point2d> pg(g);
-
- /*-------------.
- | Graph image. |
- `-------------*/
-
- // Values ("empty" vector).
- std::vector<int> values(5);
- // Graph image.
- typedef graph_image<point2d, int> ima_t;
- ima_t ima(pg, values);
- // Initialize values.
- debug::iota(ima);
- // Print the image.
- /* FIXME: Unfortunately, displaying graph images is not easy right
- now (2008-02-05). We could use
-
- debug::println(ima);
-
- but there's not specialization working for graph_image; the one
- selected by the compiler is based on a 2-D bbox, and expects the
- interface of graph_image to work with points (not psites).
- Moreover, this implementation only shows *values*, not the graph
- itslef.
-
- An alternative is to use draw::graph (which, again, is misnamed),
- but it doesn't show the values, only the nodes and edges of the
- graph.
-
- The current solution is a mix between draw::graph and hand-made
- iterations. */
- image2d<int> ima_rep(ima.bbox());
- // We use the value 9 in draw::graph instead of the default (which is
- // 1) to represent edges to distinguish it from nodes holding a
- // value of 1.
- draw::graph (ima_rep, ima, 9);
- debug::println (ima_rep);
+ p_line_graph<point2d> plg(g);
+ /*-------------------.
+ | Line graph image. |
+ `-------------------*/
+
+ // Values ("empty" vectors).
+ std::vector<int> node_values(5);
+ std::vector<int> edge_values(5);
+ // FIXME: hand-made iota's.
+ for (unsigned i = 0; i < node_values.size(); ++i)
+ node_values[i] = i;
+ for (unsigned i = 0; i < edge_values.size(); ++i)
+ edge_values[i] = i;
+
+ // Line graph image.
+ /* FIXME: We probably don't want to build line_graph_images by hand;
+ provide helpers and/or conversion functions. */
+ typedef line_graph_image<point2d, int> ima_t;
+ ima_t ima(plg, node_values, edge_values);
/*------------.
| Iterators. |
@@ -123,7 +105,7 @@
std::cout << "ima (" << p << ") = " <<
ima(p) << std::endl;
// Manual iterations over the neighborhoods of each point site of IMA.
- typedef graph_elt_window<point2d> win_t;
+ typedef line_graph_elt_window<point2d> win_t;
win_t win;
mln_qiter_(win_t) q(win, p);
for_all (p)
@@ -131,19 +113,30 @@
std::cout << "neighbors of " << p << " ("
<< ima(p) << "), "
<< "including the site itself:" << std::endl;
for_all (q)
- std::cout << " " << q << " (level = "
<< ima(q) << ")" << std::endl;
+ std::cout << " " << q << " (level = "
<< ima(q) << ")"
+ << std::endl;
}
std::cout << std::endl;
- /*-------------------------.
- | Processing graph images. |
- `-------------------------*/
-
- graph_image<point2d, int> ima_dil = morpho::dilation(ima, win);
- draw::graph(ima_rep, ima_dil, 9);
- debug::println(ima_rep);
-
- graph_image<point2d, int> ima_ero = morpho::erosion(ima, win);
- draw::graph(ima_rep, ima_ero, 9);
- debug::println(ima_rep);
+
+// /* FIXME: When implementing convert::to_line_graph_image, don't
+// forget to give a second argument defaulting to something like
+// fun::vv2v::max(). This second argument is a functor used to
+// compute the values of the edges of the line graph image. */
+// image2d ima; // = ...
+// lg_ima_t lg_ima = convert::to_line_graph_image (ima);
+
+// // Image2d representation.
+// image2d<value_t> out = convert::to_image2d (lg_ima);
+// io::pgm::save(out, "out.pgm");
+
+// /* FIXME: Then, add some real processing on the line graph image
+// before converting to an image2d:
+// - erosion/dilation,
+// - Beucher's gradient,
+// - Meyer's WST (on the gradient of LG_IMA?),
+// - attribute filters (see my notes on Laurent's remarks about
+// attributes),
+// - etc.
+// Creating seperate tests for all these would be wise. */
}
Index: tests/core/Makefile.am
--- tests/core/Makefile.am (revision 1717)
+++ tests/core/Makefile.am (working copy)
@@ -10,19 +10,21 @@
initialize \
graph_elt_window \
graph_image \
+ line_graph_elt_window \
+ line_graph_image \
mono_obased_rle_image \
mono_rle_image \
obased_rle_image \
- p_runs \
- rle_image \
- sparse_image \
- t_image \
- tr_image \
p_priority_queue \
p_priority_queue_fast \
p_priority_queue_fast_with_array \
p_queue \
- p_queue_fast
+ p_queue_fast \
+ p_runs \
+ rle_image \
+ sparse_image \
+ t_image \
+ tr_image
category_SOURCES = category.cc
clone_SOURCES = clone.cc
@@ -31,18 +33,20 @@
initialize_SOURCES = initialize.cc
graph_elt_window_SOURCES = graph_elt_window.cc
graph_image_SOURCES = graph_image.cc
+line_graph_elt_window_SOURCES = line_graph_elt_window.cc
+line_graph_image_SOURCES = line_graph_image.cc
mono_obased_rle_image_SOURCES = mono_obased_rle_image.cc
mono_rle_image_SOURCES = mono_rle_image.cc
obased_rle_image_SOURCES = obased_rle_image.cc
-p_runs_SOURCES = p_runs.cc
-rle_image_SOURCES = rle_image.cc
-sparse_image_SOURCES = sparse_image.cc
-t_image_SOURCES = t_image.cc
-tr_image_SOURCES = tr_image.cc
p_priority_queue_SOURCES = p_priority_queue.cc
p_priority_queue_fast_SOURCES = p_priority_queue_fast.cc
p_priority_queue_fast_with_array_SOURCES = p_priority_queue_fast.cc
p_queue_SOURCES = p_priority_queue_fast.cc
p_queue_fast_SOURCES = p_priority_queue_fast.cc
+p_runs_SOURCES = p_runs.cc
+rle_image_SOURCES = rle_image.cc
+sparse_image_SOURCES = sparse_image.cc
+t_image_SOURCES = t_image.cc
+tr_image_SOURCES = tr_image.cc
TESTS = $(check_PROGRAMS)