propagate_node.hh 5.59 KB
Newer Older
1
// Copyright (C) 2009, 2013 EPITA Research and Development Laboratory (LRDE)
2
//
3
// This file is part of Olena.
4
//
5
6
7
8
9
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena is distributed in the hope that it will be useful,
10
11
12
13
14
// 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
15
// along with Olena.  If not, see <http://www.gnu.org/licenses/>.
16
17
//
// As a special exception, you may use this file as part of a free
18
// software project without restriction.  Specifically, if other files
19
// instantiate templates or use macros or inline functions from this
20
21
22
23
24
// 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.
25

Edwin Carlinet's avatar
Edwin Carlinet committed
26
27
#ifndef MLN_MORPHO_TREE_PROPAGATE_NODE_HH
# define MLN_MORPHO_TREE_PROPAGATE_NODE_HH
28

29
30
31
# include <mln/core/concept/image.hh>
# include <mln/core/macros.hh>
# include <mln/morpho/tree/data.hh>
32

33
/// \file
34
35
36
///
/// Functions to propagate node in the tree.

37

Edwin Carlinet's avatar
Edwin Carlinet committed
38
39
40
41
42
43
44
45
namespace mln
{

  namespace morpho
  {

    namespace tree
    {
46

47
      /*!
48
      ** Propagate a value \p v from a node \p n to its descendants.
49
      **
50
51
52
53
54
      ** \param[in] n	       Node to propagate.
      ** \param[in] t	       Component tree used for propagation.
      ** \param[in] a_	       Attribute image where values are propagated.
      ** \param[in] v	       Value to propagate.
      ** \param[out] nb_leaves Optional. Store the number of leaves in
55
      ** the component.
56
57
58
59
60
61
      */
      template <typename T, typename A>
      void
      propagate_node_to_descendants(mln_psite(A) n,
				    const T& t,
				    Image<A>& a_,
62
63
				    const mln_value(A)& v,
				    unsigned* nb_leaves = 0);
64

65
      /*!
66
67
      ** Propagate the node's value to its descendants.
      **
68
69
70
71
      ** \param[in] n	       Node to propagate.
      ** \param[in] t	       Component tree used for propagation.
      ** \param[in] a_	       Attribute image where values are propagated.
      ** \param[out] nb_leaves Optional. Store the number of leaves in
72
      ** the component.
73
74
      */
      template <typename T, typename A>
75
      inline
76
77
78
      void
      propagate_node_to_descendants(mln_psite(A)& n,
				    const T& t,
79
80
				    Image<A>& a_,
				    unsigned* nb_leaves = 0);
81

82

83
      /*!
84
      ** Propagate a value \p v from a node \p n to its ancestors.
85
      **
86
87
88
89
      ** \param[in] n Node to propagate.
      ** \param[in] t Component tree used for propagation.
      ** \param[in] a_ Attribute image where values are propagated.
      ** \param[in] v Value to propagate.
90
91
92
93
94
95
      */
      template <typename T, typename A>
      void
      propagate_node_to_ancestors(mln_psite(A) n,
				  const T& t,
				  Image<A>& a_,
96
				  const mln_value(A)& v);
97

98
      /*!
99
100
      ** Propagate the node's value to its ancestors.
      **
101
102
103
      ** \param[in] n Node to propagate.
      ** \param[in] t Component tree used for propagation.
      ** \param[in,out] a_ Attribute image where values are propagated.
104
105
      */
      template <typename T, typename A>
106
      inline
107
108
109
110
111
112
      void
      propagate_node_to_ancestors(mln_psite(A) n,
				  const T& t,
				  Image<A>& a_);


113
# ifndef MLN_INCLUDE_ONLY
114
115
116
117

      /* Descendants propagation */

      template <typename T, typename A>
118
      inline
119
120
121
122
      void
      propagate_node_to_descendants(mln_psite(A) n,
				    const T& t,
				    Image<A>& a_,
123
				    const mln_value(A)& v,
124
				    unsigned* nb_leaves)
125
126
127
128
129
130
131
132
133
      {
	A& a = exact(a_);
	mln_precondition(a.is_valid());
	mln_precondition(a.domain() == t.f().domain());
	mln_precondition(a.domain().has(n));


	if (!t.is_a_node(n)) // Get the representant.
	  n = t.parent(n);
134
135
	mln_assertion(t.is_a_node(n));

136
	typename T::depth1st_piter pp(t, n);
137

138
	pp.start(); // We don't set n to v.
139

140
	if (nb_leaves)
141
	  *nb_leaves += t.is_a_leaf(pp);
142

143
	for (pp.next(); pp.is_valid(); pp.next())
144
145
146
147
148
	  {
	    a(pp) = v;
	    if (nb_leaves && t.is_a_leaf(pp))
	      ++(*nb_leaves);
	  }
149
150
      }

151

152
153
154
155
156
      template <typename T, typename A>
      inline
      void
      propagate_node_to_descendants(mln_psite(A) n,
				    const T& t,
157
158
				    Image<A>& a_,
				    unsigned* nb_leaves = 0)
159
160
161

      {
	A& a = exact(a_);
162
	propagate_node_to_descendants(n, t, a, a(n), nb_leaves);
163
164
165
166
167
168
169
170
171
172
      }


      /* Ancestors propagation */

      template <typename T, typename A>
      void
      propagate_node_to_ancestors(mln_psite(A) n,
				  const T& t,
				  Image<A>& a_,
173
				  const mln_value(A)& v)
174
175
176
177
178
179
      {
	A& a = exact(a_);
	mln_precondition(a.is_valid());
	mln_precondition(a.domain() == t.f().domain());
	mln_precondition(a.domain().has(n));

180
	if (!t.is_a_node(n)) // Get the representant.
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
	  n = t.parent(n);
	mln_assertion(t.is_a_node(n));

	if (t.is_root(n))
	  return;

	do {
	  n = t.parent(n);
	  a(n) = v;
	} while (!t.is_root(n));

      }

      template <typename T, typename A>
      inline
      void
      propagate_node_to_ancestors(mln_psite(A) n,
				  const T& t,
				  Image<A>& a_)
      {
	A& a = exact(a_);
	propagate_node_to_ancestors(n, t, a, a(n));
      }

205
# endif // ! MLN_INCLUDE_ONLY
206
207

    } // end of namespace mln::morpho::tree
Edwin Carlinet's avatar
Edwin Carlinet committed
208

209
  } // end of namespace mln::morpho
Edwin Carlinet's avatar
Edwin Carlinet committed
210

211
212
} // end of namespace mln

Edwin Carlinet's avatar
Edwin Carlinet committed
213
#endif // ! MLN_MORPHO_TREE_PROPAGATE_NODE_HH