Olena-patches
Threads by month
- ----- 2025 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
October 2012
- 9 participants
- 221 discussions

18 Oct '12
---
milena/ChangeLog | 4 ++++
milena/tests/value/interval.cc | 6 ++++++
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 42a6553..5fd931d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,9 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ * tests/value/interval.cc: Add more tests.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Introduce level tag.
* mln/util/level.hh,
diff --git a/milena/tests/value/interval.cc b/milena/tests/value/interval.cc
index 0fd8e6d..2f57c4c 100644
--- a/milena/tests/value/interval.cc
+++ b/milena/tests/value/interval.cc
@@ -101,4 +101,10 @@ int main()
mln_assertion(r1.ith_element(8) == 11.5);
}
+ {
+ interval<intsub<1> > r1(0, 255);
+ mln_assertion(r1.ith_element(0) == 0);
+ mln_assertion(r1.ith_element(4) == 4);
+ }
+
}
--
1.7.2.5
1
0
* mln/accu/stat/median_interval.hh: Fix bugs and add support for
a different return type.
* tests/accu/stat/median_interval.cc: Add more tests.
---
milena/ChangeLog | 9 ++++
milena/mln/accu/stat/median_interval.hh | 75 +++++++++++++---------------
milena/tests/accu/stat/median_interval.cc | 59 ++++++++++++++++++++++
3 files changed, 103 insertions(+), 40 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 98c1406..d86373c 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix accu::stat::median_interval.
+
+ * mln/accu/stat/median_interval.hh: Fix bugs and add support for
+ a different return type.
+
+ * tests/accu/stat/median_interval.cc: Add more tests.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Introduce K2 and Kn spaces.
* mln/world/k1/immerse.hh: Make use of kn::immerse.
diff --git a/milena/mln/accu/stat/median_interval.hh b/milena/mln/accu/stat/median_interval.hh
index ff54710..6315f61 100644
--- a/milena/mln/accu/stat/median_interval.hh
+++ b/milena/mln/accu/stat/median_interval.hh
@@ -55,7 +55,7 @@ namespace mln
///
/// \ingroup modaccuvalues
//
- template <unsigned n>
+ template <unsigned n, unsigned m=2*n>
struct median_interval
: public mln::accu::internal::base< const value::intsub<2*n>&, median_interval<n> >
{
@@ -114,23 +114,23 @@ namespace mln
namespace stat
{
- template <unsigned n>
- median_interval<n>::median_interval(const value::interval<argument >& inter)
+ template <unsigned n, unsigned m>
+ median_interval<n,m>::median_interval(const value::interval<argument >& inter)
: inter_(inter)
{
init();
}
- template <unsigned n>
- median_interval<n>::median_interval(const argument& first, const argument& last)
+ template <unsigned n, unsigned m>
+ median_interval<n,m>::median_interval(const argument& first, const argument& last)
: inter_(first, last)
{
init();
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::take(const argument& t)
+ median_interval<n,m>::take(const argument& t)
{
mln_precondition(inter_.has(t));
@@ -149,10 +149,10 @@ namespace mln
result_ready = false;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
inline
void
- median_interval<n>::take(const median_interval<n>& other)
+ median_interval<n,m>::take(const median_interval<n,m>& other)
{
mln_precondition(inter_ == other.inter_);
@@ -171,9 +171,9 @@ namespace mln
result_ready = false;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::untake(const argument& t)
+ median_interval<n,m>::untake(const argument& t)
{
mln_precondition(inter_.has(t));
mln_precondition(h_[inter_.index_of(t)] != 0);
@@ -193,11 +193,12 @@ namespace mln
result_ready = false;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::init()
+ median_interval<n,m>::init()
{
h_.resize(inter_.nvalues(), 0);
+ h_.fill(0);
sum_minus_ = 0;
sum_plus_ = 0;
sum_ = 0;
@@ -206,9 +207,9 @@ namespace mln
result_ready = true;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
const value::intsub<2*n>&
- median_interval<n>::to_result() const
+ median_interval<n,m>::to_result() const
{
mln_precondition(is_valid());
@@ -217,42 +218,36 @@ namespace mln
return t_;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
bool
- median_interval<n>::is_valid() const
+ median_interval<n,m>::is_valid() const
{
return sum_ > 1;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
inline
void
- median_interval<n>::update_() const
+ median_interval<n,m>::update_() const
{
result_ready = true;
if (sum_ < 1)
return;
- if (2 * sum_minus_ > sum_)
+ if (2 * sum_minus_ >= sum_)
go_minus_();
else
- if (2 * sum_plus_ > sum_)
+ if (2 * sum_plus_ >= sum_)
go_plus_();
- else
- if (h_[n_] == 0)
- {
- // go to the heaviest side
- if (sum_plus_ > sum_minus_)
- go_plus_();
- else
- go_minus_(); // default when both sides are balanced
- }
+ else // Both sides are balanced
+ if (h_[n_] == 0 || sum_ == 2)
+ go_minus_();
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::go_minus_() const
+ median_interval<n,m>::go_minus_() const
{
do
{
@@ -289,9 +284,9 @@ namespace mln
: value::iota<value::intsub<2*n> >::value());
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::go_plus_() const
+ median_interval<n,m>::go_plus_() const
{
do
{
@@ -329,9 +324,9 @@ namespace mln
: value::iota<value::intsub<2*n> >::value());
}
- template <unsigned n>
- typename median_interval<n>::index_t
- median_interval<n>::find_n1_() const
+ template <unsigned n, unsigned m>
+ typename median_interval<n,m>::index_t
+ median_interval<n,m>::find_n1_() const
{
index_t id = value::succ(n_);
while (id < h_.nelements() && h_[id] == 0)
@@ -341,10 +336,10 @@ namespace mln
}
- template <unsigned n>
- std::ostream& operator<<(std::ostream& ostr, const median_interval<n>& m)
+ template <unsigned n, unsigned m>
+ std::ostream& operator<<(std::ostream& ostr, const median_interval<n,m>& med)
{
- return ostr << m.to_result();
+ return ostr << med.to_result();
}
} // end of namespace mln::accu::stat
diff --git a/milena/tests/accu/stat/median_interval.cc b/milena/tests/accu/stat/median_interval.cc
index 6a5fd95..c0af4a1 100644
--- a/milena/tests/accu/stat/median_interval.cc
+++ b/milena/tests/accu/stat/median_interval.cc
@@ -102,6 +102,19 @@ int main()
mln_assertion(med.to_result() == 2);
}
+ // Various values
+ {
+ accu::stat::median_interval<1> med(0, 4);
+ med.take(0);
+ med.take(1);
+ med.take(1);
+ med.take(2);
+ med.take(3);
+ med.take(3);
+ med.take(4);
+ mln_assertion(med.to_result() == 2);
+ }
+
// Same value several times + one different higher value.
{
accu::stat::median_interval<1> med(1, 4);
@@ -241,4 +254,50 @@ int main()
mln_assertion(med.to_result() == 0.5);
}
+
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(126);
+ med.take(128);
+ mln_assertion(med.to_result() == 127);
+ }
+
+
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(126);
+ med.take(128);
+ med.take(128);
+ med.take(128);
+ med.take(128);
+ med.take(130);
+ mln_assertion(med.to_result() == 128);
+ }
+
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(126);
+ med.take(128);
+ med.take(129);
+ med.take(130);
+ med.take(130);
+ med.take(130);
+ mln_assertion(med.to_result() == 129.5);
+ }
+
+ // One value...
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(128);
+ med.take(128);
+ med.take(124);
+ med.take(124);
+ std::cout << med.to_result() << std::endl;
+ mln_assertion(med.to_result() == 126);
+ }
+
}
--
1.7.2.5
1
0
* mln/accu/stat/median_interval.hh: Fix bugs and add support for
a different return type.
* tests/accu/stat/median_interval.cc: Add more tests.
---
milena/ChangeLog | 9 ++++
milena/mln/accu/stat/median_interval.hh | 75 +++++++++++++---------------
milena/tests/accu/stat/median_interval.cc | 59 ++++++++++++++++++++++
3 files changed, 103 insertions(+), 40 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 87afe57..31968b3 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Fix accu::stat::median_interval.
+
+ * mln/accu/stat/median_interval.hh: Fix bugs and add support for
+ a different return type.
+
+ * tests/accu/stat/median_interval.cc: Add more tests.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Introduce K2 and Kn spaces.
* mln/world/k1/immerse.hh: Make use of kn::immerse.
diff --git a/milena/mln/accu/stat/median_interval.hh b/milena/mln/accu/stat/median_interval.hh
index ff54710..6315f61 100644
--- a/milena/mln/accu/stat/median_interval.hh
+++ b/milena/mln/accu/stat/median_interval.hh
@@ -55,7 +55,7 @@ namespace mln
///
/// \ingroup modaccuvalues
//
- template <unsigned n>
+ template <unsigned n, unsigned m=2*n>
struct median_interval
: public mln::accu::internal::base< const value::intsub<2*n>&, median_interval<n> >
{
@@ -114,23 +114,23 @@ namespace mln
namespace stat
{
- template <unsigned n>
- median_interval<n>::median_interval(const value::interval<argument >& inter)
+ template <unsigned n, unsigned m>
+ median_interval<n,m>::median_interval(const value::interval<argument >& inter)
: inter_(inter)
{
init();
}
- template <unsigned n>
- median_interval<n>::median_interval(const argument& first, const argument& last)
+ template <unsigned n, unsigned m>
+ median_interval<n,m>::median_interval(const argument& first, const argument& last)
: inter_(first, last)
{
init();
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::take(const argument& t)
+ median_interval<n,m>::take(const argument& t)
{
mln_precondition(inter_.has(t));
@@ -149,10 +149,10 @@ namespace mln
result_ready = false;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
inline
void
- median_interval<n>::take(const median_interval<n>& other)
+ median_interval<n,m>::take(const median_interval<n,m>& other)
{
mln_precondition(inter_ == other.inter_);
@@ -171,9 +171,9 @@ namespace mln
result_ready = false;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::untake(const argument& t)
+ median_interval<n,m>::untake(const argument& t)
{
mln_precondition(inter_.has(t));
mln_precondition(h_[inter_.index_of(t)] != 0);
@@ -193,11 +193,12 @@ namespace mln
result_ready = false;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::init()
+ median_interval<n,m>::init()
{
h_.resize(inter_.nvalues(), 0);
+ h_.fill(0);
sum_minus_ = 0;
sum_plus_ = 0;
sum_ = 0;
@@ -206,9 +207,9 @@ namespace mln
result_ready = true;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
const value::intsub<2*n>&
- median_interval<n>::to_result() const
+ median_interval<n,m>::to_result() const
{
mln_precondition(is_valid());
@@ -217,42 +218,36 @@ namespace mln
return t_;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
bool
- median_interval<n>::is_valid() const
+ median_interval<n,m>::is_valid() const
{
return sum_ > 1;
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
inline
void
- median_interval<n>::update_() const
+ median_interval<n,m>::update_() const
{
result_ready = true;
if (sum_ < 1)
return;
- if (2 * sum_minus_ > sum_)
+ if (2 * sum_minus_ >= sum_)
go_minus_();
else
- if (2 * sum_plus_ > sum_)
+ if (2 * sum_plus_ >= sum_)
go_plus_();
- else
- if (h_[n_] == 0)
- {
- // go to the heaviest side
- if (sum_plus_ > sum_minus_)
- go_plus_();
- else
- go_minus_(); // default when both sides are balanced
- }
+ else // Both sides are balanced
+ if (h_[n_] == 0 || sum_ == 2)
+ go_minus_();
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::go_minus_() const
+ median_interval<n,m>::go_minus_() const
{
do
{
@@ -289,9 +284,9 @@ namespace mln
: value::iota<value::intsub<2*n> >::value());
}
- template <unsigned n>
+ template <unsigned n, unsigned m>
void
- median_interval<n>::go_plus_() const
+ median_interval<n,m>::go_plus_() const
{
do
{
@@ -329,9 +324,9 @@ namespace mln
: value::iota<value::intsub<2*n> >::value());
}
- template <unsigned n>
- typename median_interval<n>::index_t
- median_interval<n>::find_n1_() const
+ template <unsigned n, unsigned m>
+ typename median_interval<n,m>::index_t
+ median_interval<n,m>::find_n1_() const
{
index_t id = value::succ(n_);
while (id < h_.nelements() && h_[id] == 0)
@@ -341,10 +336,10 @@ namespace mln
}
- template <unsigned n>
- std::ostream& operator<<(std::ostream& ostr, const median_interval<n>& m)
+ template <unsigned n, unsigned m>
+ std::ostream& operator<<(std::ostream& ostr, const median_interval<n,m>& med)
{
- return ostr << m.to_result();
+ return ostr << med.to_result();
}
} // end of namespace mln::accu::stat
diff --git a/milena/tests/accu/stat/median_interval.cc b/milena/tests/accu/stat/median_interval.cc
index 6a5fd95..c0af4a1 100644
--- a/milena/tests/accu/stat/median_interval.cc
+++ b/milena/tests/accu/stat/median_interval.cc
@@ -102,6 +102,19 @@ int main()
mln_assertion(med.to_result() == 2);
}
+ // Various values
+ {
+ accu::stat::median_interval<1> med(0, 4);
+ med.take(0);
+ med.take(1);
+ med.take(1);
+ med.take(2);
+ med.take(3);
+ med.take(3);
+ med.take(4);
+ mln_assertion(med.to_result() == 2);
+ }
+
// Same value several times + one different higher value.
{
accu::stat::median_interval<1> med(1, 4);
@@ -241,4 +254,50 @@ int main()
mln_assertion(med.to_result() == 0.5);
}
+
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(126);
+ med.take(128);
+ mln_assertion(med.to_result() == 127);
+ }
+
+
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(126);
+ med.take(128);
+ med.take(128);
+ med.take(128);
+ med.take(128);
+ med.take(130);
+ mln_assertion(med.to_result() == 128);
+ }
+
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(126);
+ med.take(128);
+ med.take(129);
+ med.take(130);
+ med.take(130);
+ med.take(130);
+ mln_assertion(med.to_result() == 129.5);
+ }
+
+ // One value...
+ {
+ accu::stat::median_interval<1> med(0, 255);
+
+ med.take(128);
+ med.take(128);
+ med.take(124);
+ med.take(124);
+ std::cout << med.to_result() << std::endl;
+ mln_assertion(med.to_result() == 126);
+ }
+
}
--
1.7.2.5
1
0
* mln/world/k1/immerse.hh: Make use of kn::immerse.
* mln/world/k2/convert_on_access.hh,
* mln/world/k2/fill_0_from_1_faces.hh,
* mln/world/k2/fill_1_from_2_faces.hh,
* mln/world/k2/fill_non_primary_from_primary_faces.hh,
* mln/world/k2/immerse.hh,
* mln/world/k2/immerse_with.hh,
* mln/world/k2/is_non_primary_face.hh,
* mln/world/k2/is_non_primary_face_cross.hh,
* mln/world/k2/is_non_primary_face_horizontal.hh,
* mln/world/k2/is_non_primary_face_vertical.hh,
* mln/world/k2/is_primary_face.hh,
* mln/world/k2/neighb2d.hh,
* mln/world/kn/immerse.hh: New.
---
milena/ChangeLog | 20 ++
milena/mln/world/k1/immerse.hh | 64 +++----
milena/mln/world/k2/convert_on_access.hh | 126 ++++++++++++
milena/mln/world/k2/fill_0_from_1_faces.hh | 114 +++++++++++
milena/mln/world/k2/fill_1_from_2_faces.hh | 118 +++++++++++
.../k2/fill_non_primary_from_primary_faces.hh | 212 ++++++++++++++++++++
milena/mln/world/k2/immerse.hh | 127 ++++++++++++
milena/mln/world/k2/immerse_with.hh | 173 ++++++++++++++++
milena/mln/world/k2/is_non_primary_face.hh | 83 ++++++++
milena/mln/world/k2/is_non_primary_face_cross.hh | 88 ++++++++
.../mln/world/k2/is_non_primary_face_horizontal.hh | 83 ++++++++
.../mln/world/k2/is_non_primary_face_vertical.hh | 83 ++++++++
milena/mln/world/k2/is_primary_face.hh | 82 ++++++++
milena/mln/world/k2/neighb2d.hh | 139 +++++++++++++
milena/mln/world/kn/immerse.hh | 161 +++++++++++++++
15 files changed, 1635 insertions(+), 38 deletions(-)
create mode 100644 milena/mln/world/k2/convert_on_access.hh
create mode 100644 milena/mln/world/k2/fill_0_from_1_faces.hh
create mode 100644 milena/mln/world/k2/fill_1_from_2_faces.hh
create mode 100644 milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
create mode 100644 milena/mln/world/k2/immerse.hh
create mode 100644 milena/mln/world/k2/immerse_with.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_cross.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_horizontal.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_vertical.hh
create mode 100644 milena/mln/world/k2/is_primary_face.hh
create mode 100644 milena/mln/world/k2/neighb2d.hh
create mode 100644 milena/mln/world/kn/immerse.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 551ff9d..98c1406 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,25 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Introduce K2 and Kn spaces.
+
+ * mln/world/k1/immerse.hh: Make use of kn::immerse.
+
+ * mln/world/k2/convert_on_access.hh,
+ * mln/world/k2/fill_0_from_1_faces.hh,
+ * mln/world/k2/fill_1_from_2_faces.hh,
+ * mln/world/k2/fill_non_primary_from_primary_faces.hh,
+ * mln/world/k2/immerse.hh,
+ * mln/world/k2/immerse_with.hh,
+ * mln/world/k2/is_non_primary_face.hh,
+ * mln/world/k2/is_non_primary_face_cross.hh,
+ * mln/world/k2/is_non_primary_face_horizontal.hh,
+ * mln/world/k2/is_non_primary_face_vertical.hh,
+ * mln/world/k2/is_primary_face.hh,
+ * mln/world/k2/neighb2d.hh,
+ * mln/world/kn/immerse.hh: New.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Some fixes.
* mln/labeling/compute.hh: Fix include.
diff --git a/milena/mln/world/k1/immerse.hh b/milena/mln/world/k1/immerse.hh
index b9b58fb..1f59f7e 100644
--- a/milena/mln/world/k1/immerse.hh
+++ b/milena/mln/world/k1/immerse.hh
@@ -34,6 +34,8 @@
# include <mln/core/concept/box.hh>
# include <mln/core/alias/point2d.hh>
+# include <mln/world/kn/immerse.hh>
+
namespace mln
{
@@ -45,6 +47,11 @@ namespace mln
/*! \brief Immerse a 2D image into K1.
+ \param[in] ima 2D Image in K0.
+ \param[in] new_type Value type of the immersed image.
+
+ \return A 2D image immersed in k1 of value type \tparam V.
+
\verbatim
-1 0 1 2 3
@@ -57,60 +64,41 @@ namespace mln
\endverbatim
*/
+ template <typename I, typename V>
+ mln_concrete(I) immerse(const Image<I>& ima, const V& new_type);
+
+ /// \overload
+ /// new_type is set to mln_value(I).
template <typename I>
mln_concrete(I) immerse(const Image<I>& ima);
# ifndef MLN_INCLUDE_ONLY
- namespace internal
- {
-
- /// Return the equivalent point in K1 from a point in K0.
- inline
- point2d immerse_point(const point2d& p)
- {
- point2d tmp(2 * p.row(), 2 * p.col());
- return tmp;
- }
-
- /// \brief Return the equivalent domain in K1 from a domain in
- /// K0.
- template <typename B>
- inline
- B domain_from_K0(const Box<B>& b_)
- {
- mln_precondition(exact(b_).is_valid());
- const B& b = exact(b_);
-
- mln_deduce(B, site, delta) one;
- one.set_all(1);
- return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
- }
-
- } // end of namespace mln::world::k1::internal
-
-
-
// Facade
- template <typename I>
- mln_concrete(I) immerse(const Image<I>& ima_)
+ template <typename I, typename V>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const V& new_type)
{
trace::entering("mln::world::k1::immerse");
- mln_precondition(exact(ima_).is_valid());
- const I& ima = exact(ima_);
+ mln_precondition(exact(ima).is_valid());
- mln_concrete(I) output(internal::domain_from_K0(ima.domain()));
-
- mln_piter(I) p(ima.domain());
- for_all(p)
- output(internal::immerse_point(p)) = ima(p);
+ mln_concrete(I) output = kn::immerse(ima, 1, V());
trace::exiting("mln::world::k1::immerse");
return output;
}
+
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima)
+ {
+ typedef mln_value(I) V;
+ return immerse(ima, V());
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::world::k1
diff --git a/milena/mln/world/k2/convert_on_access.hh b/milena/mln/world/k2/convert_on_access.hh
new file mode 100644
index 0000000..4c9ab20
--- /dev/null
+++ b/milena/mln/world/k2/convert_on_access.hh
@@ -0,0 +1,126 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
+# define MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k2/is_non_primary_face_vertical.hh>
+# include <mln/world/k2/is_non_primary_face_horizontal.hh>
+# include <mln/world/k2/convert_on_access.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/intsub.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ using namespace mln::value;
+
+ template <unsigned n>
+ void convert_on_access(const intsub<n>& from, intsub<n/2>& to);
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, intsub<n>& to);
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, interval<intsub<n> >& to);
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, int& to);
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, value::int_u8& to);
+
+ template <typename T, typename U>
+ void convert_on_access(const T& from, U& to);
+
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n>
+ void convert_on_access(const intsub<n/2>& from, intsub<n>& to)
+ {
+ to = from.to_int();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, intsub<n>& to)
+ {
+ to = from.to_equiv();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, interval<intsub<n> >& to)
+ {
+ to = intsub<n>(from.to_interop());
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, int& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, value::int_u8& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, intsub<n/2>& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first().to_interop();
+ }
+
+ template <typename T, typename U>
+ void convert_on_access(const T& from, U& to)
+ {
+ to = static_cast<U>(from);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
diff --git a/milena/mln/world/k2/fill_0_from_1_faces.hh b/milena/mln/world/k2/fill_0_from_1_faces.hh
new file mode 100644
index 0000000..5f4830e
--- /dev/null
+++ b/milena/mln/world/k2/fill_0_from_1_faces.hh
@@ -0,0 +1,114 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
+# define MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_0_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical 1 faces:
+
+ \verbatim
+ x | x
+ \endverbatim
+
+ * In case of horizontal 1 face:
+
+ \verbatim
+ x
+ -
+ x
+ \endverbatim
+
+ */
+ template <typename I, typename A>
+ void fill_0_from_1_faces(Image<I>& inout,
+ const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+
+ template <typename I, typename A>
+ void fill_0_from_1_faces(Image<I>& inout_,
+ const Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_0_from_1_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+
+ A accu = A();
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (k1::is_0_face(p))
+ {
+ accu.init();
+ accu.take(inout(p + left));
+ accu.take(inout(p + right));
+ accu.take(inout(p + up));
+ accu.take(inout(p + down));
+ inout(p) = accu.to_result();
+ }
+
+ trace::exiting("mln::world::k2::fill_0_from_1_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
diff --git a/milena/mln/world/k2/fill_1_from_2_faces.hh b/milena/mln/world/k2/fill_1_from_2_faces.hh
new file mode 100644
index 0000000..5e242d2
--- /dev/null
+++ b/milena/mln/world/k2/fill_1_from_2_faces.hh
@@ -0,0 +1,118 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
+# define MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_1_face_vertical.hh>
+# include <mln/world/k1/is_1_face_horizontal.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical 1 faces:
+
+ \verbatim
+ x | x
+ \endverbatim
+
+ * In case of horizontal 1 face:
+
+ \verbatim
+ x
+ -
+ x
+ \endverbatim
+
+ */
+ template <typename I, typename A>
+ void fill_1_from_2_faces(Image<I>& inout, const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+
+ template <typename I, typename A>
+ void fill_1_from_2_faces(Image<I>& inout_, const Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_1_from_2_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+
+ A accu = A();
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (k1::is_1_face_vertical(p))
+ {
+ accu.init();
+ accu.take(inout(p + left));
+ accu.take(inout(p + right));
+ inout(p) = accu.to_result();
+ }
+ else if (k1::is_1_face_horizontal(p))
+ {
+ accu.init();
+ accu.take(inout(p + up));
+ accu.take(inout(p + down));
+ inout(p) = accu.to_result();
+ }
+
+ trace::exiting("mln::world::k2::fill_1_from_2_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
diff --git a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
new file mode 100644
index 0000000..bc7509f
--- /dev/null
+++ b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
@@ -0,0 +1,212 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
+# define MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k2/is_non_primary_face_vertical.hh>
+# include <mln/world/k2/is_non_primary_face_horizontal.hh>
+# include <mln/world/k2/is_non_primary_face_cross.hh>
+# include <mln/world/k2/convert_on_access.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill non-primary 2-faces in a K2 2D image using
+ * primary 2-faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical non-primary 2-faces:
+
+ \verbatim
+ x o x
+ \endverbatim
+
+ * In case of horizontal non-primary 2-face:
+
+ \verbatim
+ x
+ o
+ x
+ \endverbatim
+
+ * In case of cross non-primary 2-face:
+
+ \verbatim
+ x x
+ o
+ x x
+ \endverbatim
+
+ */
+ /// \overload
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout,
+ const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ F& functor_)
+ {
+ trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+ typedef typename A::argument V;
+
+ A& accu = exact(accu_);
+
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (is_non_primary_face_vertical(p))
+ {
+ accu.init();
+ V tmp1, tmp2;
+
+ convert_on_access(inout(p + 2 * left), tmp1);
+ convert_on_access(inout(p + 2 * right), tmp2);
+ convert_on_access(f(tmp1, tmp2), inout(p));
+ }
+ else if (is_non_primary_face_horizontal(p))
+ {
+ accu.init();
+ V tmp1, tmp2;
+
+ convert_on_access(inout(p + 2 * up), tmp1);
+ convert_on_access(inout(p + 2 * down), tmp2);
+ convert_on_access(f(tmp1, tmp2), inout(p));
+ }
+ else if (is_non_primary_face_cross(p))
+ {
+ accu.init();
+ V tmp1, tmp2, tmp3, tmp4;
+
+ convert_on_access(inout(p + 2 * up_left), tmp1);
+ convert_on_access(inout(p + 2 * up_right), tmp2);
+ convert_on_access(inout(p + 2 * down_left), tmp3);
+ convert_on_access(inout(p + 2 * down_right), tmp4);
+ convert_on_access(f(tmp1, tmp2, tmp3, tmp4), inout(p));
+ }
+
+ trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
+ }
+
+
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+ typedef typename A::argument V;
+
+ A& accu = exact(accu_);
+
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (is_non_primary_face_vertical(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+ else if (is_non_primary_face_horizontal(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * up), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+ else if (is_non_primary_face_cross(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * up_left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * up_right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down_left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down_right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+
+ trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
diff --git a/milena/mln/world/k2/immerse.hh b/milena/mln/world/k2/immerse.hh
new file mode 100644
index 0000000..eb6ba30
--- /dev/null
+++ b/milena/mln/world/k2/immerse.hh
@@ -0,0 +1,127 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Immerse a 2D image into K2.
+
+#ifndef MLN_WORLD_K2_IMMERSE_HH
+# define MLN_WORLD_K2_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Immerse a 2D image into K2.
+
+ \verbatim
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in K2 from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p)
+ {
+ point2d tmp(4 * p.row(), 4 * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in K2 from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
+ }
+
+ } // end of namespace mln::world::k2::internal
+
+
+
+ // Facade
+
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima_)
+ {
+ trace::entering("mln::world::k2::immerse");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+
+ mln_concrete(I) output(internal::domain_from_K0(ima.domain()));
+
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ output(internal::immerse_point(p)) = ima(p);
+ output(internal::immerse_point(p) + 2 * right) = ima(p);
+ output(internal::immerse_point(p) + 2 * down) = ima(p);
+ output(internal::immerse_point(p) + 2 * down_right) = ima(p);
+ }
+
+ trace::exiting("mln::world::k2::immerse");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IMMERSE_HH
diff --git a/milena/mln/world/k2/immerse_with.hh b/milena/mln/world/k2/immerse_with.hh
new file mode 100644
index 0000000..bc8e8ad
--- /dev/null
+++ b/milena/mln/world/k2/immerse_with.hh
@@ -0,0 +1,173 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Immerse a 2D image into K2.
+
+#ifndef MLN_WORLD_K2_IMMERSE_HH
+# define MLN_WORLD_K2_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/value/interval.hh>
+# include <mln/fun/vv2v/span.hh>
+# include <mln/fun/vvvv2v/span.hh>
+
+# include <mln/world/k1/fill_0_from_1_faces.hh>
+# include <mln/world/k1/fill_1_from_2_faces.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Immerse a 2D image into K2.
+
+ \verbatim
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in K2 from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p)
+ {
+ point2d tmp(4 * p.row(), 4 * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in K2 from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
+ }
+
+ } // end of namespace mln::world::k2::internal
+
+
+
+ // Facade
+
+ template <typename I, typename F2, typename F4>
+ mln_ch_value(I, value::interval<mln_result(F4)>)
+ immerse_with(const Image<I>& ima_,
+ Function_vv2v<F2>& f2_, Function_vvvv2v<F4>& f4_)
+ {
+ trace::entering("mln::world::k2::immerse_with");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+ const F2& f2 = exact(f2_);
+ const F4& f4 = exact(f4_);
+
+ // FIXME: how to initialize the border... ?
+ // border::fill(ima, 0);
+
+ typedef mln_result(F4) V;
+ typedef value::interval<V> VOUT;
+ mln_ch_value(I,VOUT)
+ output(internal::domain_from_K0(ima.domain()));
+
+ // Filling 2-Faces
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ // .-.-
+ // ab |x|*| -> a
+ // cd -> .-.-.
+ // |*|*|
+ // .-.-.
+ output(internal::immerse_point(p)) = ima(p);
+
+ // .-.-
+ // ab |*|x| -> f2(a,b)
+ // cd -> .-.-.
+ // |*|*|
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * right) = f2(ima(p), ima(p + right));
+
+ // .-.-
+ // ab |*|*|
+ // cd -> .-.-.
+ // |x|*| -> f2(a,c)
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * down) = f2(ima(p), ima(p + down));
+
+ // .-.-
+ // ab |*|*|
+ // cd -> .-.-.
+ // |*|x| -> f4(a,b,c,d)
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * down_right)
+ = f4(ima(p), ima(p + right), ima(p + down), ima(p + down_right));
+ }
+
+ fun::vv2v::span<V> span2;
+ k1::fill_1_from_2_faces(output, span2);
+ fun::vvvv2v::span<V> span4;
+ k1::fill_0_from_1_faces(output, span4);
+
+ trace::exiting("mln::world::k2::immerse_with");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IMMERSE_HH
diff --git a/milena/mln/world/k2/is_non_primary_face.hh b/milena/mln/world/k2/is_non_primary_face.hh
new file mode 100644
index 0000000..2088040
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a non-primary face
+ bool is_non_primary_face(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face(const point2d& p)
+ {
+ return is_non_primary_face(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return k1::is_2_face(row, col) && !is_primary_face(row, col);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_cross.hh b/milena/mln/world/k2/is_non_primary_face_cross.hh
new file mode 100644
index 0000000..fad4c23
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_cross.hh
@@ -0,0 +1,88 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a cross non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
+
+# include <mln/core/alias/point2d.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a cross non-primary face
+ ///
+ /// |a| |b|
+ /// .-.-.-.
+ /// | |x| |
+ /// .-.-.-.
+ /// |c| |d|
+ ///
+ bool is_non_primary_face_cross(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_cross(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_cross(const point2d& p)
+ {
+ return is_non_primary_face_cross(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_cross(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return (row % 4 == 2) && (col % 4 == 2);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_horizontal.hh b/milena/mln/world/k2/is_non_primary_face_horizontal.hh
new file mode 100644
index 0000000..3a65995
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_horizontal.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a horizontal non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_non_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a horizontal non-primary face
+ bool is_non_primary_face_horizontal(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_horizontal(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_horizontal(const point2d& p)
+ {
+ return is_non_primary_face_horizontal(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_horizontal(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return is_non_primary_face(row, col) && ! (col % 4);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_vertical.hh b/milena/mln/world/k2/is_non_primary_face_vertical.hh
new file mode 100644
index 0000000..5fd2d24
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_vertical.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a vertical non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_non_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a vertical non-primary face
+ bool is_non_primary_face_vertical(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_vertical(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_vertical(const point2d& p)
+ {
+ return is_non_primary_face_vertical(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_vertical(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return is_non_primary_face(row, col) && ! (row % 4);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
diff --git a/milena/mln/world/k2/is_primary_face.hh b/milena/mln/world/k2/is_primary_face.hh
new file mode 100644
index 0000000..033c7a4
--- /dev/null
+++ b/milena/mln/world/k2/is_primary_face.hh
@@ -0,0 +1,82 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a primary face.
+
+#ifndef MLN_WORLD_K2_IS_PRIMARY_FACE_HH
+# define MLN_WORLD_K2_IS_PRIMARY_FACE_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a primary face
+ bool is_primary_face(const point2d& p);
+
+
+ /// \overload
+ bool is_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_primary_face(const point2d& p)
+ {
+ return is_primary_face(p.row(), p.col());
+ }
+
+ inline
+ bool is_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return !((row % 4) + (col % 4));
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_PRIMARY_FACE_HH
diff --git a/milena/mln/world/k2/neighb2d.hh b/milena/mln/world/k2/neighb2d.hh
new file mode 100644
index 0000000..e248cef
--- /dev/null
+++ b/milena/mln/world/k2/neighb2d.hh
@@ -0,0 +1,139 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief 2D neighborhood working in K2.
+
+#ifndef MLN_WORLD_K2_NEIGHB2D_HH
+# define MLN_WORLD_K2_NEIGHB2D_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/win/multiple.hh>
+# include <mln/make/double_neighb2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ o| |o
+ -.-.-
+ |x|
+ -.-.-
+ o| |o
+ \endverbatim
+ */
+ const neighb2d& cross_np2p_faces();
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ |o|
+ .-.
+ |x|
+ .-.
+ |o|
+ \endverbatim
+ */
+ const neighb2d& vertical_np2p_faces();
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ .-.-.-.
+ |o|x|o|
+ .-.-.-.
+ \endverbatim
+ */
+ const neighb2d& horizontal_np2p_faces();
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ const neighb2d& cross_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, X, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+
+ const neighb2d& vertical_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+
+ const neighb2d& horizontal_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_NEIGHB2D_HH
diff --git a/milena/mln/world/kn/immerse.hh b/milena/mln/world/kn/immerse.hh
new file mode 100644
index 0000000..380b52f
--- /dev/null
+++ b/milena/mln/world/kn/immerse.hh
@@ -0,0 +1,161 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Immerse a 2D image into Kn.
+
+#ifndef MLN_WORLD_Kn_IMMERSE_HH
+# define MLN_WORLD_Kn_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/value/interval.hh>
+# include <mln/fun/vv2v/span.hh>
+# include <mln/fun/vvvv2v/span.hh>
+
+# include <mln/world/k1/fill_0_from_1_faces.hh>
+# include <mln/world/k1/fill_1_from_2_faces.hh>
+
+# include <mln/world/k2/convert_on_access.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace kn
+ {
+
+ /*! \brief Immerse a 2D image into Kn.
+
+ \param[in] ima 2D Image in K0.
+ \param[in] n Set in which space to immerse \p ima (ex: n=1 => k1).
+ \param[in] new_type Value type of the immersed image.
+
+ \return A 2D image immersed in k\p n of value type \tparam V.
+
+ \verbatim
+
+ Example with n=1 :
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I, typename V>
+ mln_ch_value(I, V)
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type);
+
+ /// \overload
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const unsigned n);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in Kn from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p, const unsigned n)
+ {
+ point2d tmp(std::pow(2u, n) * p.row(), std::pow(2u, n) * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in Kn from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_, const unsigned n)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin(), n) - one, immerse_point(b.pmax(), n) + one);
+ }
+
+ } // end of namespace mln::world::kn::internal
+
+
+
+ // Facade
+
+ template <typename I, typename V>
+ mln_ch_value(I, V)
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type)
+ {
+ trace::entering("mln::world::kn::immerse_with");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+ (void) new_type;
+
+ mln_ch_value(I,V)
+ output(internal::domain_from_K0(ima.domain(), n));
+
+ // Filling Primary 2-Faces
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ V tmp;
+ k2::convert_on_access(ima(p), tmp);
+ output(internal::immerse_point(p, n)) = tmp;
+ }
+
+ trace::exiting("mln::world::kn::immerse_with");
+ return output;
+ }
+
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const unsigned n)
+ {
+ typedef mln_value(I) V;
+ return immerse(ima, n, V());
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::kn
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_Kn_IMMERSE_HH
--
1.7.2.5
1
0
* mln/world/k1/immerse.hh: Make use of kn::immerse.
* mln/world/k2/convert_on_access.hh,
* mln/world/k2/fill_0_from_1_faces.hh,
* mln/world/k2/fill_1_from_2_faces.hh,
* mln/world/k2/fill_non_primary_from_primary_faces.hh,
* mln/world/k2/immerse.hh,
* mln/world/k2/immerse_with.hh,
* mln/world/k2/is_non_primary_face.hh,
* mln/world/k2/is_non_primary_face_cross.hh,
* mln/world/k2/is_non_primary_face_horizontal.hh,
* mln/world/k2/is_non_primary_face_vertical.hh,
* mln/world/k2/is_primary_face.hh,
* mln/world/k2/neighb2d.hh,
* mln/world/kn/immerse.hh: New.
---
milena/ChangeLog | 20 ++
milena/mln/world/k1/immerse.hh | 64 +++----
milena/mln/world/k2/convert_on_access.hh | 126 ++++++++++++
milena/mln/world/k2/fill_0_from_1_faces.hh | 114 +++++++++++
milena/mln/world/k2/fill_1_from_2_faces.hh | 118 +++++++++++
.../k2/fill_non_primary_from_primary_faces.hh | 212 ++++++++++++++++++++
milena/mln/world/k2/immerse.hh | 127 ++++++++++++
milena/mln/world/k2/immerse_with.hh | 173 ++++++++++++++++
milena/mln/world/k2/is_non_primary_face.hh | 83 ++++++++
milena/mln/world/k2/is_non_primary_face_cross.hh | 88 ++++++++
.../mln/world/k2/is_non_primary_face_horizontal.hh | 83 ++++++++
.../mln/world/k2/is_non_primary_face_vertical.hh | 83 ++++++++
milena/mln/world/k2/is_primary_face.hh | 82 ++++++++
milena/mln/world/k2/neighb2d.hh | 139 +++++++++++++
milena/mln/world/kn/immerse.hh | 161 +++++++++++++++
15 files changed, 1635 insertions(+), 38 deletions(-)
create mode 100644 milena/mln/world/k2/convert_on_access.hh
create mode 100644 milena/mln/world/k2/fill_0_from_1_faces.hh
create mode 100644 milena/mln/world/k2/fill_1_from_2_faces.hh
create mode 100644 milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
create mode 100644 milena/mln/world/k2/immerse.hh
create mode 100644 milena/mln/world/k2/immerse_with.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_cross.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_horizontal.hh
create mode 100644 milena/mln/world/k2/is_non_primary_face_vertical.hh
create mode 100644 milena/mln/world/k2/is_primary_face.hh
create mode 100644 milena/mln/world/k2/neighb2d.hh
create mode 100644 milena/mln/world/kn/immerse.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 4b7a84a..87afe57 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,25 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Introduce K2 and Kn spaces.
+
+ * mln/world/k1/immerse.hh: Make use of kn::immerse.
+
+ * mln/world/k2/convert_on_access.hh,
+ * mln/world/k2/fill_0_from_1_faces.hh,
+ * mln/world/k2/fill_1_from_2_faces.hh,
+ * mln/world/k2/fill_non_primary_from_primary_faces.hh,
+ * mln/world/k2/immerse.hh,
+ * mln/world/k2/immerse_with.hh,
+ * mln/world/k2/is_non_primary_face.hh,
+ * mln/world/k2/is_non_primary_face_cross.hh,
+ * mln/world/k2/is_non_primary_face_horizontal.hh,
+ * mln/world/k2/is_non_primary_face_vertical.hh,
+ * mln/world/k2/is_primary_face.hh,
+ * mln/world/k2/neighb2d.hh,
+ * mln/world/kn/immerse.hh: New.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Some fixes.
* mln/labeling/compute.hh: Fix include.
diff --git a/milena/mln/world/k1/immerse.hh b/milena/mln/world/k1/immerse.hh
index b9b58fb..1f59f7e 100644
--- a/milena/mln/world/k1/immerse.hh
+++ b/milena/mln/world/k1/immerse.hh
@@ -34,6 +34,8 @@
# include <mln/core/concept/box.hh>
# include <mln/core/alias/point2d.hh>
+# include <mln/world/kn/immerse.hh>
+
namespace mln
{
@@ -45,6 +47,11 @@ namespace mln
/*! \brief Immerse a 2D image into K1.
+ \param[in] ima 2D Image in K0.
+ \param[in] new_type Value type of the immersed image.
+
+ \return A 2D image immersed in k1 of value type \tparam V.
+
\verbatim
-1 0 1 2 3
@@ -57,60 +64,41 @@ namespace mln
\endverbatim
*/
+ template <typename I, typename V>
+ mln_concrete(I) immerse(const Image<I>& ima, const V& new_type);
+
+ /// \overload
+ /// new_type is set to mln_value(I).
template <typename I>
mln_concrete(I) immerse(const Image<I>& ima);
# ifndef MLN_INCLUDE_ONLY
- namespace internal
- {
-
- /// Return the equivalent point in K1 from a point in K0.
- inline
- point2d immerse_point(const point2d& p)
- {
- point2d tmp(2 * p.row(), 2 * p.col());
- return tmp;
- }
-
- /// \brief Return the equivalent domain in K1 from a domain in
- /// K0.
- template <typename B>
- inline
- B domain_from_K0(const Box<B>& b_)
- {
- mln_precondition(exact(b_).is_valid());
- const B& b = exact(b_);
-
- mln_deduce(B, site, delta) one;
- one.set_all(1);
- return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
- }
-
- } // end of namespace mln::world::k1::internal
-
-
-
// Facade
- template <typename I>
- mln_concrete(I) immerse(const Image<I>& ima_)
+ template <typename I, typename V>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const V& new_type)
{
trace::entering("mln::world::k1::immerse");
- mln_precondition(exact(ima_).is_valid());
- const I& ima = exact(ima_);
+ mln_precondition(exact(ima).is_valid());
- mln_concrete(I) output(internal::domain_from_K0(ima.domain()));
-
- mln_piter(I) p(ima.domain());
- for_all(p)
- output(internal::immerse_point(p)) = ima(p);
+ mln_concrete(I) output = kn::immerse(ima, 1, V());
trace::exiting("mln::world::k1::immerse");
return output;
}
+
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima)
+ {
+ typedef mln_value(I) V;
+ return immerse(ima, V());
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::world::k1
diff --git a/milena/mln/world/k2/convert_on_access.hh b/milena/mln/world/k2/convert_on_access.hh
new file mode 100644
index 0000000..4c9ab20
--- /dev/null
+++ b/milena/mln/world/k2/convert_on_access.hh
@@ -0,0 +1,126 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
+# define MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k2/is_non_primary_face_vertical.hh>
+# include <mln/world/k2/is_non_primary_face_horizontal.hh>
+# include <mln/world/k2/convert_on_access.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/intsub.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ using namespace mln::value;
+
+ template <unsigned n>
+ void convert_on_access(const intsub<n>& from, intsub<n/2>& to);
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, intsub<n>& to);
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, interval<intsub<n> >& to);
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, int& to);
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, value::int_u8& to);
+
+ template <typename T, typename U>
+ void convert_on_access(const T& from, U& to);
+
+
+#ifndef MLN_INCLUDE_ONLY
+
+ template <unsigned n>
+ void convert_on_access(const intsub<n/2>& from, intsub<n>& to)
+ {
+ to = from.to_int();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, intsub<n>& to)
+ {
+ to = from.to_equiv();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const int_u8& from, interval<intsub<n> >& to)
+ {
+ to = intsub<n>(from.to_interop());
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, int& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, value::int_u8& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first();
+ }
+
+ template <unsigned n>
+ void convert_on_access(const interval<intsub<n> >& from, intsub<n/2>& to)
+ {
+ mln_precondition(from.is_degenerated());
+ to = from.first().to_interop();
+ }
+
+ template <typename T, typename U>
+ void convert_on_access(const T& from, U& to)
+ {
+ to = static_cast<U>(from);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_CONVERT_ON_ACCESS_HH
diff --git a/milena/mln/world/k2/fill_0_from_1_faces.hh b/milena/mln/world/k2/fill_0_from_1_faces.hh
new file mode 100644
index 0000000..5f4830e
--- /dev/null
+++ b/milena/mln/world/k2/fill_0_from_1_faces.hh
@@ -0,0 +1,114 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
+# define MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_0_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical 1 faces:
+
+ \verbatim
+ x | x
+ \endverbatim
+
+ * In case of horizontal 1 face:
+
+ \verbatim
+ x
+ -
+ x
+ \endverbatim
+
+ */
+ template <typename I, typename A>
+ void fill_0_from_1_faces(Image<I>& inout,
+ const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+
+ template <typename I, typename A>
+ void fill_0_from_1_faces(Image<I>& inout_,
+ const Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_0_from_1_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+
+ A accu = A();
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (k1::is_0_face(p))
+ {
+ accu.init();
+ accu.take(inout(p + left));
+ accu.take(inout(p + right));
+ accu.take(inout(p + up));
+ accu.take(inout(p + down));
+ inout(p) = accu.to_result();
+ }
+
+ trace::exiting("mln::world::k2::fill_0_from_1_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_0_FROM_1_FACES_HH
diff --git a/milena/mln/world/k2/fill_1_from_2_faces.hh b/milena/mln/world/k2/fill_1_from_2_faces.hh
new file mode 100644
index 0000000..5e242d2
--- /dev/null
+++ b/milena/mln/world/k2/fill_1_from_2_faces.hh
@@ -0,0 +1,118 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
+# define MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_1_face_vertical.hh>
+# include <mln/world/k1/is_1_face_horizontal.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical 1 faces:
+
+ \verbatim
+ x | x
+ \endverbatim
+
+ * In case of horizontal 1 face:
+
+ \verbatim
+ x
+ -
+ x
+ \endverbatim
+
+ */
+ template <typename I, typename A>
+ void fill_1_from_2_faces(Image<I>& inout, const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+
+ template <typename I, typename A>
+ void fill_1_from_2_faces(Image<I>& inout_, const Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_1_from_2_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+
+ A accu = A();
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (k1::is_1_face_vertical(p))
+ {
+ accu.init();
+ accu.take(inout(p + left));
+ accu.take(inout(p + right));
+ inout(p) = accu.to_result();
+ }
+ else if (k1::is_1_face_horizontal(p))
+ {
+ accu.init();
+ accu.take(inout(p + up));
+ accu.take(inout(p + down));
+ inout(p) = accu.to_result();
+ }
+
+ trace::exiting("mln::world::k2::fill_1_from_2_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_1_FROM_2_FACES_HH
diff --git a/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
new file mode 100644
index 0000000..bc7509f
--- /dev/null
+++ b/milena/mln/world/k2/fill_non_primary_from_primary_faces.hh
@@ -0,0 +1,212 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Fill 1 faces in a K2 2D image using its 2 faces.
+
+#ifndef MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
+# define MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k2/is_non_primary_face_vertical.hh>
+# include <mln/world/k2/is_non_primary_face_horizontal.hh>
+# include <mln/world/k2/is_non_primary_face_cross.hh>
+# include <mln/world/k2/convert_on_access.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Fill non-primary 2-faces in a K2 2D image using
+ * primary 2-faces.
+
+ \param[in,out] inout A 2D image immersed in K2.
+ \param[in,out] accu An accumulator.
+
+ This function use the following neighborhoods:
+
+ * In case of vertical non-primary 2-faces:
+
+ \verbatim
+ x o x
+ \endverbatim
+
+ * In case of horizontal non-primary 2-face:
+
+ \verbatim
+ x
+ o
+ x
+ \endverbatim
+
+ * In case of cross non-primary 2-face:
+
+ \verbatim
+ x x
+ o
+ x x
+ \endverbatim
+
+ */
+ /// \overload
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout,
+ const Accumulator<A>& accu);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ F& functor_)
+ {
+ trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+ typedef typename A::argument V;
+
+ A& accu = exact(accu_);
+
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (is_non_primary_face_vertical(p))
+ {
+ accu.init();
+ V tmp1, tmp2;
+
+ convert_on_access(inout(p + 2 * left), tmp1);
+ convert_on_access(inout(p + 2 * right), tmp2);
+ convert_on_access(f(tmp1, tmp2), inout(p));
+ }
+ else if (is_non_primary_face_horizontal(p))
+ {
+ accu.init();
+ V tmp1, tmp2;
+
+ convert_on_access(inout(p + 2 * up), tmp1);
+ convert_on_access(inout(p + 2 * down), tmp2);
+ convert_on_access(f(tmp1, tmp2), inout(p));
+ }
+ else if (is_non_primary_face_cross(p))
+ {
+ accu.init();
+ V tmp1, tmp2, tmp3, tmp4;
+
+ convert_on_access(inout(p + 2 * up_left), tmp1);
+ convert_on_access(inout(p + 2 * up_right), tmp2);
+ convert_on_access(inout(p + 2 * down_left), tmp3);
+ convert_on_access(inout(p + 2 * down_right), tmp4);
+ convert_on_access(f(tmp1, tmp2, tmp3, tmp4), inout(p));
+ }
+
+ trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
+ }
+
+
+ template <typename I, typename A>
+ void fill_non_primary_from_primary_faces(Image<I>& inout_,
+ Accumulator<A>& accu_)
+ {
+ trace::entering("mln::world::k2::fill_non_primary_from_primary_faces");
+
+ mln_precondition(exact(inout_).is_valid());
+ I& inout = exact(inout_);
+ (void) accu_;
+ typedef typename A::argument V;
+
+ A& accu = exact(accu_);
+
+ mln_piter(I) p(inout.domain());
+ for_all(p)
+ if (is_non_primary_face_vertical(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+ else if (is_non_primary_face_horizontal(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * up), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+ else if (is_non_primary_face_cross(p))
+ {
+ accu.init();
+ V tmp;
+
+ convert_on_access(inout(p + 2 * up_left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * up_right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down_left), tmp);
+ accu.take(tmp);
+
+ convert_on_access(inout(p + 2 * down_right), tmp);
+ accu.take(tmp);
+
+ convert_on_access(accu.to_result(), inout(p));
+ }
+
+ trace::exiting("mln::world::k2::fill_non_primary_from_primary_faces");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_FILL_NON_PRIMARY_FROM_PRIMARY_FACES_HH
diff --git a/milena/mln/world/k2/immerse.hh b/milena/mln/world/k2/immerse.hh
new file mode 100644
index 0000000..eb6ba30
--- /dev/null
+++ b/milena/mln/world/k2/immerse.hh
@@ -0,0 +1,127 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Immerse a 2D image into K2.
+
+#ifndef MLN_WORLD_K2_IMMERSE_HH
+# define MLN_WORLD_K2_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Immerse a 2D image into K2.
+
+ \verbatim
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in K2 from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p)
+ {
+ point2d tmp(4 * p.row(), 4 * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in K2 from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
+ }
+
+ } // end of namespace mln::world::k2::internal
+
+
+
+ // Facade
+
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima_)
+ {
+ trace::entering("mln::world::k2::immerse");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+
+ mln_concrete(I) output(internal::domain_from_K0(ima.domain()));
+
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ output(internal::immerse_point(p)) = ima(p);
+ output(internal::immerse_point(p) + 2 * right) = ima(p);
+ output(internal::immerse_point(p) + 2 * down) = ima(p);
+ output(internal::immerse_point(p) + 2 * down_right) = ima(p);
+ }
+
+ trace::exiting("mln::world::k2::immerse");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IMMERSE_HH
diff --git a/milena/mln/world/k2/immerse_with.hh b/milena/mln/world/k2/immerse_with.hh
new file mode 100644
index 0000000..bc8e8ad
--- /dev/null
+++ b/milena/mln/world/k2/immerse_with.hh
@@ -0,0 +1,173 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Immerse a 2D image into K2.
+
+#ifndef MLN_WORLD_K2_IMMERSE_HH
+# define MLN_WORLD_K2_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/value/interval.hh>
+# include <mln/fun/vv2v/span.hh>
+# include <mln/fun/vvvv2v/span.hh>
+
+# include <mln/world/k1/fill_0_from_1_faces.hh>
+# include <mln/world/k1/fill_1_from_2_faces.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Immerse a 2D image into K2.
+
+ \verbatim
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I>
+ mln_concrete(I) immerse(const Image<I>& ima);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in K2 from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p)
+ {
+ point2d tmp(4 * p.row(), 4 * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in K2 from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin()) - one, immerse_point(b.pmax()) + one);
+ }
+
+ } // end of namespace mln::world::k2::internal
+
+
+
+ // Facade
+
+ template <typename I, typename F2, typename F4>
+ mln_ch_value(I, value::interval<mln_result(F4)>)
+ immerse_with(const Image<I>& ima_,
+ Function_vv2v<F2>& f2_, Function_vvvv2v<F4>& f4_)
+ {
+ trace::entering("mln::world::k2::immerse_with");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+ const F2& f2 = exact(f2_);
+ const F4& f4 = exact(f4_);
+
+ // FIXME: how to initialize the border... ?
+ // border::fill(ima, 0);
+
+ typedef mln_result(F4) V;
+ typedef value::interval<V> VOUT;
+ mln_ch_value(I,VOUT)
+ output(internal::domain_from_K0(ima.domain()));
+
+ // Filling 2-Faces
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ // .-.-
+ // ab |x|*| -> a
+ // cd -> .-.-.
+ // |*|*|
+ // .-.-.
+ output(internal::immerse_point(p)) = ima(p);
+
+ // .-.-
+ // ab |*|x| -> f2(a,b)
+ // cd -> .-.-.
+ // |*|*|
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * right) = f2(ima(p), ima(p + right));
+
+ // .-.-
+ // ab |*|*|
+ // cd -> .-.-.
+ // |x|*| -> f2(a,c)
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * down) = f2(ima(p), ima(p + down));
+
+ // .-.-
+ // ab |*|*|
+ // cd -> .-.-.
+ // |*|x| -> f4(a,b,c,d)
+ // .-.-.
+ output(internal::immerse_point(p) + 2 * down_right)
+ = f4(ima(p), ima(p + right), ima(p + down), ima(p + down_right));
+ }
+
+ fun::vv2v::span<V> span2;
+ k1::fill_1_from_2_faces(output, span2);
+ fun::vvvv2v::span<V> span4;
+ k1::fill_0_from_1_faces(output, span4);
+
+ trace::exiting("mln::world::k2::immerse_with");
+ return output;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IMMERSE_HH
diff --git a/milena/mln/world/k2/is_non_primary_face.hh b/milena/mln/world/k2/is_non_primary_face.hh
new file mode 100644
index 0000000..2088040
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a non-primary face
+ bool is_non_primary_face(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face(const point2d& p)
+ {
+ return is_non_primary_face(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return k1::is_2_face(row, col) && !is_primary_face(row, col);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_cross.hh b/milena/mln/world/k2/is_non_primary_face_cross.hh
new file mode 100644
index 0000000..fad4c23
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_cross.hh
@@ -0,0 +1,88 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a cross non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
+
+# include <mln/core/alias/point2d.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a cross non-primary face
+ ///
+ /// |a| |b|
+ /// .-.-.-.
+ /// | |x| |
+ /// .-.-.-.
+ /// |c| |d|
+ ///
+ bool is_non_primary_face_cross(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_cross(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_cross(const point2d& p)
+ {
+ return is_non_primary_face_cross(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_cross(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return (row % 4 == 2) && (col % 4 == 2);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_CROSS_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_horizontal.hh b/milena/mln/world/k2/is_non_primary_face_horizontal.hh
new file mode 100644
index 0000000..3a65995
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_horizontal.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a horizontal non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_non_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a horizontal non-primary face
+ bool is_non_primary_face_horizontal(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_horizontal(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_horizontal(const point2d& p)
+ {
+ return is_non_primary_face_horizontal(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_horizontal(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return is_non_primary_face(row, col) && ! (col % 4);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_HORIZONTAL_HH
diff --git a/milena/mln/world/k2/is_non_primary_face_vertical.hh b/milena/mln/world/k2/is_non_primary_face_vertical.hh
new file mode 100644
index 0000000..5fd2d24
--- /dev/null
+++ b/milena/mln/world/k2/is_non_primary_face_vertical.hh
@@ -0,0 +1,83 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a vertical non-primary face.
+
+#ifndef MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
+# define MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+# include <mln/world/k2/is_non_primary_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a vertical non-primary face
+ bool is_non_primary_face_vertical(const point2d& p);
+
+
+ /// \overload
+ bool is_non_primary_face_vertical(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_non_primary_face_vertical(const point2d& p)
+ {
+ return is_non_primary_face_vertical(p.row(), p.col());
+ }
+
+ inline
+ bool is_non_primary_face_vertical(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return is_non_primary_face(row, col) && ! (row % 4);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_NON_PRIMARY_FACE_VERTICAL_HH
diff --git a/milena/mln/world/k2/is_primary_face.hh b/milena/mln/world/k2/is_primary_face.hh
new file mode 100644
index 0000000..033c7a4
--- /dev/null
+++ b/milena/mln/world/k2/is_primary_face.hh
@@ -0,0 +1,82 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Check if site is a primary face.
+
+#ifndef MLN_WORLD_K2_IS_PRIMARY_FACE_HH
+# define MLN_WORLD_K2_IS_PRIMARY_FACE_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/world/k1/is_2_face.hh>
+
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /// \brief Check if site is a primary face
+ bool is_primary_face(const point2d& p);
+
+
+ /// \overload
+ bool is_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+
+ // Facade
+
+ inline
+ bool is_primary_face(const point2d& p)
+ {
+ return is_primary_face(p.row(), p.col());
+ }
+
+ inline
+ bool is_primary_face(const mln::def::coord& row,
+ const mln::def::coord& col)
+ {
+ return !((row % 4) + (col % 4));
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_IS_PRIMARY_FACE_HH
diff --git a/milena/mln/world/k2/neighb2d.hh b/milena/mln/world/k2/neighb2d.hh
new file mode 100644
index 0000000..e248cef
--- /dev/null
+++ b/milena/mln/world/k2/neighb2d.hh
@@ -0,0 +1,139 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief 2D neighborhood working in K2.
+
+#ifndef MLN_WORLD_K2_NEIGHB2D_HH
+# define MLN_WORLD_K2_NEIGHB2D_HH
+
+# include <mln/core/alias/point2d.hh>
+# include <mln/core/alias/neighb2d.hh>
+# include <mln/win/multiple.hh>
+# include <mln/make/double_neighb2d.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace k2
+ {
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ o| |o
+ -.-.-
+ |x|
+ -.-.-
+ o| |o
+ \endverbatim
+ */
+ const neighb2d& cross_np2p_faces();
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ |o|
+ .-.
+ |x|
+ .-.
+ |o|
+ \endverbatim
+ */
+ const neighb2d& vertical_np2p_faces();
+
+ /*! \brief Non-primary to primary faces neighborhood.
+
+ \verbatim
+ .-.-.-.
+ |o|x|o|
+ .-.-.-.
+ \endverbatim
+ */
+ const neighb2d& horizontal_np2p_faces();
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ const neighb2d& cross_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, X, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+
+ const neighb2d& vertical_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+
+ const neighb2d& horizontal_np2p_faces()
+ {
+ static neighb2d it;
+ if (it.size() == 0)
+ {
+ static bool vals[] = { 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0 };
+ convert::from_to(vals, it);
+ }
+ return it;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::k2
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_K2_NEIGHB2D_HH
diff --git a/milena/mln/world/kn/immerse.hh b/milena/mln/world/kn/immerse.hh
new file mode 100644
index 0000000..380b52f
--- /dev/null
+++ b/milena/mln/world/kn/immerse.hh
@@ -0,0 +1,161 @@
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// 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,
+// 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+/// \file
+///
+/// \brief Immerse a 2D image into Kn.
+
+#ifndef MLN_WORLD_Kn_IMMERSE_HH
+# define MLN_WORLD_Kn_IMMERSE_HH
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/box.hh>
+# include <mln/core/alias/point2d.hh>
+# include <mln/value/interval.hh>
+# include <mln/fun/vv2v/span.hh>
+# include <mln/fun/vvvv2v/span.hh>
+
+# include <mln/world/k1/fill_0_from_1_faces.hh>
+# include <mln/world/k1/fill_1_from_2_faces.hh>
+
+# include <mln/world/k2/convert_on_access.hh>
+
+namespace mln
+{
+
+ namespace world
+ {
+
+ namespace kn
+ {
+
+ /*! \brief Immerse a 2D image into Kn.
+
+ \param[in] ima 2D Image in K0.
+ \param[in] n Set in which space to immerse \p ima (ex: n=1 => k1).
+ \param[in] new_type Value type of the immersed image.
+
+ \return A 2D image immersed in k\p n of value type \tparam V.
+
+ \verbatim
+
+ Example with n=1 :
+
+ -1 0 1 2 3
+ 0 1 -1 . - . - .
+ 0 o o 0 | o | o |
+ 1 o o -> 1 . - . - .
+ 2 | o | o |
+ 3 . - . - .
+
+ \endverbatim
+
+ */
+ template <typename I, typename V>
+ mln_ch_value(I, V)
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type);
+
+ /// \overload
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const unsigned n);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ /// Return the equivalent point in Kn from a point in K0.
+ inline
+ point2d immerse_point(const point2d& p, const unsigned n)
+ {
+ point2d tmp(std::pow(2u, n) * p.row(), std::pow(2u, n) * p.col());
+ return tmp;
+ }
+
+ /// \brief Return the equivalent domain in Kn from a domain in
+ /// K0.
+ template <typename B>
+ inline
+ B domain_from_K0(const Box<B>& b_, const unsigned n)
+ {
+ mln_precondition(exact(b_).is_valid());
+ const B& b = exact(b_);
+
+ mln_deduce(B, site, delta) one;
+ one.set_all(1);
+ return B(immerse_point(b.pmin(), n) - one, immerse_point(b.pmax(), n) + one);
+ }
+
+ } // end of namespace mln::world::kn::internal
+
+
+
+ // Facade
+
+ template <typename I, typename V>
+ mln_ch_value(I, V)
+ immerse(const Image<I>& ima_, const unsigned n, const V& new_type)
+ {
+ trace::entering("mln::world::kn::immerse_with");
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
+ (void) new_type;
+
+ mln_ch_value(I,V)
+ output(internal::domain_from_K0(ima.domain(), n));
+
+ // Filling Primary 2-Faces
+ mln_piter(I) p(ima.domain());
+ for_all(p)
+ {
+ V tmp;
+ k2::convert_on_access(ima(p), tmp);
+ output(internal::immerse_point(p, n)) = tmp;
+ }
+
+ trace::exiting("mln::world::kn::immerse_with");
+ return output;
+ }
+
+ template <typename I>
+ mln_concrete(I)
+ immerse(const Image<I>& ima, const unsigned n)
+ {
+ typedef mln_value(I) V;
+ return immerse(ima, n, V());
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::world::kn
+
+ } // end of namespace mln::world
+
+} // end of namespace mln
+
+#endif // ! MLN_WORLD_Kn_IMMERSE_HH
--
1.7.2.5
1
0
* mln/labeling/compute.hh: Fix include.
* mln/value/int_u.hh: Add iota definition.
* mln/value/interval.hh: Add span overloads and self_open()
method.
---
milena/ChangeLog | 11 +++++
milena/mln/labeling/compute.hh | 2 +-
milena/mln/value/int_u.hh | 21 +++++++++-
milena/mln/value/interval.hh | 87 +++++++++++++++++++++++++++++++++++++++-
4 files changed, 118 insertions(+), 3 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 647018e..551ff9d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,16 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Some fixes.
+
+ * mln/labeling/compute.hh: Fix include.
+
+ * mln/value/int_u.hh: Add iota definition.
+
+ * mln/value/interval.hh: Add span overloads and self_open()
+ method.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
New span accumulator.
* mln/accu/math/span.hh: New.
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index 4ad48b5..1743181 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -51,7 +51,7 @@
# include <mln/util/array.hh>
# include <mln/convert/from_to.hh>
# include <mln/geom/ncols.hh>
-# include <mln/value/next.hh>
+# include <mln/value/succ.hh>
namespace mln
diff --git a/milena/mln/value/int_u.hh b/milena/mln/value/int_u.hh
index d051c13..7fa217d 100644
--- a/milena/mln/value/int_u.hh
+++ b/milena/mln/value/int_u.hh
@@ -39,6 +39,7 @@
# include <mln/value/concept/integer.hh>
# include <mln/trait/value_.hh>
# include <mln/debug/format.hh>
+# include <mln/value/iota.hh>
# include <mln/value/internal/make_generic_name.hh>
@@ -159,6 +160,16 @@ namespace mln
};
+ // Iota
+
+ template <unsigned n>
+ struct iota<int_u<n> >
+ {
+ static int_u<n> value();
+ };
+
+
+
// Safety.
template <> struct int_u<0>;
template <> struct int_u<1>;
@@ -181,7 +192,6 @@ namespace mln
std::istream& operator>>(std::istream& istr, int_u<n>& i);
-
// Conversions
/// \internal Conversion: int_u -> unsigned.
@@ -300,6 +310,15 @@ namespace mln
return this->v_ + 1;
}
+ // Iota
+
+ template <unsigned n>
+ int_u<n>
+ iota<int_u<n> >::value()
+ {
+ return 1;
+ }
+
template <unsigned n>
inline
std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i)
diff --git a/milena/mln/value/interval.hh b/milena/mln/value/interval.hh
index 13c7947..d3cbbdd 100644
--- a/milena/mln/value/interval.hh
+++ b/milena/mln/value/interval.hh
@@ -34,6 +34,8 @@
# include <iostream>
# include <mln/value/inc.hh>
# include <mln/value/concept/interval.hh>
+# include <mln/util/level.hh>
+
namespace mln
{
@@ -50,6 +52,7 @@ namespace mln
typedef T equiv;
interval();
+ interval(T single);
interval(T first, T last);
interval& operator=(const interval& rhs);
@@ -77,6 +80,11 @@ namespace mln
/// The last value included in this interval.
const T& last() const;
+ /// Open this interval and exclude first and last values from
+ /// it. The interval is then defined on [first + iota, last -
+ /// iota].
+ void self_open();
+
private:
T first_;
T last_;
@@ -164,6 +172,12 @@ namespace mln
interval<T>
span(const interval<T>& r1, const interval<T>& r2);
+ /// \brief Compute the span of \p r1, \p r2, \p r3 and \p r4.
+ template <typename T>
+ interval<T>
+ span(const interval<T>& r1, const interval<T>& r2,
+ const interval<T>& r3, const interval<T>& r4);
+
// op<<
template <typename T>
@@ -207,6 +221,16 @@ namespace mln
}
template <typename T>
+ interval<T>::interval(T single)
+ {
+ first_ = single;
+ last_ = single;
+
+ nvalues_ = 1;
+ }
+
+
+ template <typename T>
interval<T>::interval(T first, T last)
{
mln_precondition(last >= first);
@@ -285,6 +309,18 @@ namespace mln
return last_;
}
+ template <typename T>
+ void
+ interval<T>::self_open()
+ {
+ mln_precondition(! is_degenerated());
+ mln_precondition(nvalues_ > 2);
+
+ first += iota<T>::value();
+ last_ -= iota<T>::value();
+ nvalues_ -= 2;
+ }
+
// comparison
@@ -302,8 +338,49 @@ namespace mln
return ! (lhs == rhs);
}
+ // thresholding
- // set ops
+ template <typename T, typename U>
+ inline
+ bool
+ operator<=(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return i.first() <= v.value;
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator>(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return ! (i <= v);
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator>=(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return v.value <= i.last();
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator<(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return ! (i >= v);
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator==(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return i >= v && i <= v;
+ }
+
+ // set ops
template <typename T>
bool
@@ -357,6 +434,14 @@ namespace mln
std::max(r1.last(), r2.last()));
}
+ template <typename T>
+ interval<T>
+ span(const interval<T>& r1, const interval<T>& r2,
+ const interval<T>& r3, const interval<T>& r4)
+ {
+ return span(span(r1, r2), span(r3, r4));
+ }
+
// op<<
--
1.7.2.5
1
0
* mln/labeling/compute.hh: Fix include.
* mln/value/int_u.hh: Add iota definition.
* mln/value/interval.hh: Add span overloads and self_open()
method.
---
milena/ChangeLog | 11 +++++
milena/mln/labeling/compute.hh | 2 +-
milena/mln/value/int_u.hh | 25 ++++++++++-
milena/mln/value/interval.hh | 87 +++++++++++++++++++++++++++++++++++++++-
4 files changed, 121 insertions(+), 4 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index aa215c4..4b7a84a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,16 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Some fixes.
+
+ * mln/labeling/compute.hh: Fix include.
+
+ * mln/value/int_u.hh: Add iota definition.
+
+ * mln/value/interval.hh: Add span overloads and self_open()
+ method.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
New span accumulator.
* mln/accu/math/span.hh: New.
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index 4ad48b5..1743181 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -51,7 +51,7 @@
# include <mln/util/array.hh>
# include <mln/convert/from_to.hh>
# include <mln/geom/ncols.hh>
-# include <mln/value/next.hh>
+# include <mln/value/succ.hh>
namespace mln
diff --git a/milena/mln/value/int_u.hh b/milena/mln/value/int_u.hh
index f3786f9..3b22918 100644
--- a/milena/mln/value/int_u.hh
+++ b/milena/mln/value/int_u.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
-// Laboratory (LRDE)
+// Copyright (C) 2007, 2008, 2009, 2010, 2012 EPITA Research and
+// Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -41,6 +41,7 @@
# include <mln/value/concept/integer.hh>
# include <mln/trait/value_.hh>
# include <mln/debug/format.hh>
+# include <mln/value/iota.hh>
# include <mln/value/internal/make_generic_name.hh>
@@ -195,6 +196,16 @@ namespace mln
};
+ // Iota
+
+ template <unsigned n>
+ struct iota<int_u<n> >
+ {
+ static int_u<n> value();
+ };
+
+
+
// Safety.
template <> struct int_u<0>;
template <> struct int_u<1>;
@@ -218,6 +229,7 @@ namespace mln
} // end of namespace mln::value
+
# ifndef MLN_INCLUDE_ONLY
namespace convert
@@ -352,6 +364,15 @@ namespace mln
return this->v_ + 1;
}
+ // Iota
+
+ template <unsigned n>
+ int_u<n>
+ iota<int_u<n> >::value()
+ {
+ return 1;
+ }
+
template <unsigned n>
inline
std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i)
diff --git a/milena/mln/value/interval.hh b/milena/mln/value/interval.hh
index 13c7947..d3cbbdd 100644
--- a/milena/mln/value/interval.hh
+++ b/milena/mln/value/interval.hh
@@ -34,6 +34,8 @@
# include <iostream>
# include <mln/value/inc.hh>
# include <mln/value/concept/interval.hh>
+# include <mln/util/level.hh>
+
namespace mln
{
@@ -50,6 +52,7 @@ namespace mln
typedef T equiv;
interval();
+ interval(T single);
interval(T first, T last);
interval& operator=(const interval& rhs);
@@ -77,6 +80,11 @@ namespace mln
/// The last value included in this interval.
const T& last() const;
+ /// Open this interval and exclude first and last values from
+ /// it. The interval is then defined on [first + iota, last -
+ /// iota].
+ void self_open();
+
private:
T first_;
T last_;
@@ -164,6 +172,12 @@ namespace mln
interval<T>
span(const interval<T>& r1, const interval<T>& r2);
+ /// \brief Compute the span of \p r1, \p r2, \p r3 and \p r4.
+ template <typename T>
+ interval<T>
+ span(const interval<T>& r1, const interval<T>& r2,
+ const interval<T>& r3, const interval<T>& r4);
+
// op<<
template <typename T>
@@ -207,6 +221,16 @@ namespace mln
}
template <typename T>
+ interval<T>::interval(T single)
+ {
+ first_ = single;
+ last_ = single;
+
+ nvalues_ = 1;
+ }
+
+
+ template <typename T>
interval<T>::interval(T first, T last)
{
mln_precondition(last >= first);
@@ -285,6 +309,18 @@ namespace mln
return last_;
}
+ template <typename T>
+ void
+ interval<T>::self_open()
+ {
+ mln_precondition(! is_degenerated());
+ mln_precondition(nvalues_ > 2);
+
+ first += iota<T>::value();
+ last_ -= iota<T>::value();
+ nvalues_ -= 2;
+ }
+
// comparison
@@ -302,8 +338,49 @@ namespace mln
return ! (lhs == rhs);
}
+ // thresholding
- // set ops
+ template <typename T, typename U>
+ inline
+ bool
+ operator<=(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return i.first() <= v.value;
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator>(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return ! (i <= v);
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator>=(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return v.value <= i.last();
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator<(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return ! (i >= v);
+ }
+
+ template <typename T, typename U>
+ inline
+ bool
+ operator==(const interval<T>& i, const util::level_t<U>& v)
+ {
+ return i >= v && i <= v;
+ }
+
+ // set ops
template <typename T>
bool
@@ -357,6 +434,14 @@ namespace mln
std::max(r1.last(), r2.last()));
}
+ template <typename T>
+ interval<T>
+ span(const interval<T>& r1, const interval<T>& r2,
+ const interval<T>& r3, const interval<T>& r4)
+ {
+ return span(span(r1, r2), span(r3, r4));
+ }
+
// op<<
--
1.7.2.5
1
0
* mln/accu/math/span.hh: New.
---
milena/ChangeLog | 6 ++
milena/mln/accu/math/{inf.hh => span.hh} | 97 +++++++++++++----------------
2 files changed, 50 insertions(+), 53 deletions(-)
copy milena/mln/accu/math/{inf.hh => span.hh} (63%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index fb22a83..647018e 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ New span accumulator.
+
+ * mln/accu/math/span.hh: New.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add functions.
* mln/fun/vv2v/span.hh,
diff --git a/milena/mln/accu/math/inf.hh b/milena/mln/accu/math/span.hh
similarity index 63%
copy from milena/mln/accu/math/inf.hh
copy to milena/mln/accu/math/span.hh
index 17780b9..eda4e85 100644
--- a/milena/mln/accu/math/inf.hh
+++ b/milena/mln/accu/math/span.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,18 +23,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_ACCU_MATH_INF_HH
-# define MLN_ACCU_MATH_INF_HH
+#ifndef MLN_ACCU_MATH_SPAN_HH
+# define MLN_ACCU_MATH_SPAN_HH
/// \file
///
-/// Define an accumulator that computes a inf.
+/// Define an accumulator that computes a span.
# include <mln/accu/internal/base.hh>
-# include <mln/core/concept/meta_accumulator.hh>
-# include <mln/trait/value_.hh>
-# include <mln/util/pix.hh>
-# include <mln/fun/math/inf.hh>
+# include <mln/value/interval.hh>
namespace mln
{
@@ -46,29 +43,30 @@ namespace mln
{
- /// \brief Generic inf accumulator class.
+ /// \brief Generic span accumulator class.
///
- /// The parameter \c T is the type of values.
+ /// The parameter \c T is the type of values used in the
+ /// underlying interval.
///
/// \ingroup modaccuvalues
//
template <typename T>
- struct inf : public mln::accu::internal::base< const T&, inf<T> >
+ struct span : public mln::accu::internal::base< const value::interval<T>&, span<T> >
{
- typedef T argument;
+ typedef value::interval<T> argument;
- inf();
+ span();
/// Manipulators.
/// \{
void init();
void take_as_init_(const argument& t);
void take(const argument& t);
- void take(const inf<T>& other);
+ void take(const span<T>& other);
/// \}
/// Get the value of the accumulator.
- const T& to_result() const;
+ const value::interval<T>& to_result() const;
/// Check whether this accu is able to return a result.
/// Always true here.
@@ -76,36 +74,13 @@ namespace mln
protected:
- T t_;
- typename mln::fun::inf::with<T, T>::ret fun_;
+ value::interval<T> t_;
+ bool is_valid_;
};
-
- template <typename I> struct inf< util::pix<I> >;
-
} // end of mln::accu::math
- namespace meta
- {
-
- namespace math
- {
-
- /// Meta accumulator for inf.
-
- struct inf : public Meta_Accumulator< inf >
- {
- template <typename T>
- struct with
- {
- typedef accu::math::inf<T> ret;
- };
- };
-
- } // end of namespace mln::accu::meta::math
-
- } // end of namespace mln::accu::meta
# ifndef MLN_INCLUDE_ONLY
@@ -115,7 +90,7 @@ namespace mln
template <typename T>
inline
- inf<T>::inf()
+ span<T>::span()
{
init();
}
@@ -123,37 +98,53 @@ namespace mln
template <typename T>
inline
void
- inf<T>::init()
+ span<T>::init()
{
- t_ = mln_max(T);
+ is_valid_ = false;
}
template <typename T>
inline
- void inf<T>::take_as_init_(const argument& t)
+ void span<T>::take_as_init_(const argument& t)
{
t_ = t;
+ is_valid_ = true;
}
template <typename T>
inline
- void inf<T>::take(const argument& t)
+ void span<T>::take(const argument& t)
{
- this->t_ = this->fun_(t_, t);
+ if (is_valid_)
+ this->t_ = value::span(this->t_, t);
+ else
+ {
+ this->t_ = t;
+ if (!is_valid_)
+ is_valid_ = true;
+ }
}
template <typename T>
inline
void
- inf<T>::take(const inf<T>& other)
+ span<T>::take(const span<T>& other)
{
- this->t_ = this->fun_(t_, other.t_);
+ mln_precondition(other.is_valid());
+
+ if (is_valid_)
+ this->t_ = value::span(this->t_, other.t_);
+ else
+ {
+ this->t_ = other.t_;
+ is_valid_ = other.is_valid_;
+ }
}
template <typename T>
inline
- const T&
- inf<T>::to_result() const
+ const value::interval<T>&
+ span<T>::to_result() const
{
return t_;
}
@@ -161,9 +152,9 @@ namespace mln
template <typename T>
inline
bool
- inf<T>::is_valid() const
+ span<T>::is_valid() const
{
- return true;
+ return is_valid_;
}
} // end of namespace mln::accu::math
@@ -175,4 +166,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_ACCU_MATH_INF_HH
+#endif // ! MLN_ACCU_MATH_SPAN_HH
--
1.7.2.5
1
0
* mln/accu/math/span.hh: New.
---
milena/ChangeLog | 6 ++
milena/mln/accu/math/{inf.hh => span.hh} | 97 +++++++++++++----------------
2 files changed, 50 insertions(+), 53 deletions(-)
copy milena/mln/accu/math/{inf.hh => span.hh} (63%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 5d2bea5..aa215c4 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,11 @@
2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+ New span accumulator.
+
+ * mln/accu/math/span.hh: New.
+
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add functions.
* mln/fun/vv2v/span.hh,
diff --git a/milena/mln/accu/math/inf.hh b/milena/mln/accu/math/span.hh
similarity index 63%
copy from milena/mln/accu/math/inf.hh
copy to milena/mln/accu/math/span.hh
index 17780b9..eda4e85 100644
--- a/milena/mln/accu/math/inf.hh
+++ b/milena/mln/accu/math/span.hh
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2012 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -23,18 +23,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_ACCU_MATH_INF_HH
-# define MLN_ACCU_MATH_INF_HH
+#ifndef MLN_ACCU_MATH_SPAN_HH
+# define MLN_ACCU_MATH_SPAN_HH
/// \file
///
-/// Define an accumulator that computes a inf.
+/// Define an accumulator that computes a span.
# include <mln/accu/internal/base.hh>
-# include <mln/core/concept/meta_accumulator.hh>
-# include <mln/trait/value_.hh>
-# include <mln/util/pix.hh>
-# include <mln/fun/math/inf.hh>
+# include <mln/value/interval.hh>
namespace mln
{
@@ -46,29 +43,30 @@ namespace mln
{
- /// \brief Generic inf accumulator class.
+ /// \brief Generic span accumulator class.
///
- /// The parameter \c T is the type of values.
+ /// The parameter \c T is the type of values used in the
+ /// underlying interval.
///
/// \ingroup modaccuvalues
//
template <typename T>
- struct inf : public mln::accu::internal::base< const T&, inf<T> >
+ struct span : public mln::accu::internal::base< const value::interval<T>&, span<T> >
{
- typedef T argument;
+ typedef value::interval<T> argument;
- inf();
+ span();
/// Manipulators.
/// \{
void init();
void take_as_init_(const argument& t);
void take(const argument& t);
- void take(const inf<T>& other);
+ void take(const span<T>& other);
/// \}
/// Get the value of the accumulator.
- const T& to_result() const;
+ const value::interval<T>& to_result() const;
/// Check whether this accu is able to return a result.
/// Always true here.
@@ -76,36 +74,13 @@ namespace mln
protected:
- T t_;
- typename mln::fun::inf::with<T, T>::ret fun_;
+ value::interval<T> t_;
+ bool is_valid_;
};
-
- template <typename I> struct inf< util::pix<I> >;
-
} // end of mln::accu::math
- namespace meta
- {
-
- namespace math
- {
-
- /// Meta accumulator for inf.
-
- struct inf : public Meta_Accumulator< inf >
- {
- template <typename T>
- struct with
- {
- typedef accu::math::inf<T> ret;
- };
- };
-
- } // end of namespace mln::accu::meta::math
-
- } // end of namespace mln::accu::meta
# ifndef MLN_INCLUDE_ONLY
@@ -115,7 +90,7 @@ namespace mln
template <typename T>
inline
- inf<T>::inf()
+ span<T>::span()
{
init();
}
@@ -123,37 +98,53 @@ namespace mln
template <typename T>
inline
void
- inf<T>::init()
+ span<T>::init()
{
- t_ = mln_max(T);
+ is_valid_ = false;
}
template <typename T>
inline
- void inf<T>::take_as_init_(const argument& t)
+ void span<T>::take_as_init_(const argument& t)
{
t_ = t;
+ is_valid_ = true;
}
template <typename T>
inline
- void inf<T>::take(const argument& t)
+ void span<T>::take(const argument& t)
{
- this->t_ = this->fun_(t_, t);
+ if (is_valid_)
+ this->t_ = value::span(this->t_, t);
+ else
+ {
+ this->t_ = t;
+ if (!is_valid_)
+ is_valid_ = true;
+ }
}
template <typename T>
inline
void
- inf<T>::take(const inf<T>& other)
+ span<T>::take(const span<T>& other)
{
- this->t_ = this->fun_(t_, other.t_);
+ mln_precondition(other.is_valid());
+
+ if (is_valid_)
+ this->t_ = value::span(this->t_, other.t_);
+ else
+ {
+ this->t_ = other.t_;
+ is_valid_ = other.is_valid_;
+ }
}
template <typename T>
inline
- const T&
- inf<T>::to_result() const
+ const value::interval<T>&
+ span<T>::to_result() const
{
return t_;
}
@@ -161,9 +152,9 @@ namespace mln
template <typename T>
inline
bool
- inf<T>::is_valid() const
+ span<T>::is_valid() const
{
- return true;
+ return is_valid_;
}
} // end of namespace mln::accu::math
@@ -175,4 +166,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_ACCU_MATH_INF_HH
+#endif // ! MLN_ACCU_MATH_SPAN_HH
--
1.7.2.5
1
0
* mln/fun/vv2v/span.hh,
* mln/fun/vvvv2v/max.hh,
* mln/fun/vvvv2v/min.hh,
* mln/fun/vvvv2v/span.hh: New.
* mln/math/max.hh,
* mln/math/min.hh: New overloads.
---
milena/ChangeLog | 12 ++++++++++
milena/mln/fun/vv2v/{mean.hh => span.hh} | 33 ++++++++++++++-------------
milena/mln/fun/vvvv2v/{mean.hh => max.hh} | 20 ++++++++--------
milena/mln/fun/vvvv2v/mean.hh | 2 +-
milena/mln/fun/vvvv2v/{mean.hh => min.hh} | 20 ++++++++--------
milena/mln/fun/vvvv2v/{mean.hh => span.hh} | 34 ++++++++++++++++-----------
milena/mln/math/max.hh | 17 ++++++++++++++
milena/mln/math/min.hh | 17 ++++++++++++++
8 files changed, 104 insertions(+), 51 deletions(-)
copy milena/mln/fun/vv2v/{mean.hh => span.hh} (70%)
copy milena/mln/fun/vvvv2v/{mean.hh => max.hh} (79%)
copy milena/mln/fun/vvvv2v/{mean.hh => min.hh} (79%)
copy milena/mln/fun/vvvv2v/{mean.hh => span.hh} (67%)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 04fb5c5..fb22a83 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,15 @@
+2012-10-18 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add functions.
+
+ * mln/fun/vv2v/span.hh,
+ * mln/fun/vvvv2v/max.hh,
+ * mln/fun/vvvv2v/min.hh,
+ * mln/fun/vvvv2v/span.hh: New.
+
+ * mln/math/max.hh,
+ * mln/math/min.hh: New overloads.
+
2012-10-05 Guillaume Lazzara <z(a)lrde.epita.fr>
Improve accu::median_interval.
diff --git a/milena/mln/fun/vv2v/mean.hh b/milena/mln/fun/vv2v/span.hh
similarity index 70%
copy from milena/mln/fun/vv2v/mean.hh
copy to milena/mln/fun/vv2v/span.hh
index 510b9a6..e9cd002 100644
--- a/milena/mln/fun/vv2v/mean.hh
+++ b/milena/mln/fun/vv2v/span.hh
@@ -23,15 +23,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_FUN_VV2V_MEAN_HH
-# define MLN_FUN_VV2V_MEAN_HH
+#ifndef MLN_FUN_VV2V_SPAN_HH
+# define MLN_FUN_VV2V_SPAN_HH
/// \file
///
-/// Functor that computes the mean of two values.
+/// Functor that computes the spanimum of two values.
# include <mln/core/concept/function.hh>
-# include <mln/math/mean.hh>
+# include <mln/value/interval.hh>
namespace mln
@@ -45,24 +45,25 @@ namespace mln
// FIXME: Doc.
- /// \brief A functor computing the mean of two values.
- template <typename L, typename R = L>
- struct mean : public Function_vv2v< mean<L,R> >,
- private mlc_converts_to(R,L)::check_t
+ /// \brief A functor computing the span of two interval values.
+ template <typename T>
+ struct span : public Function_vv2v< span<T> >
{
- typedef R result;
- R operator()(const L& v1, const L& v2) const;
+ typedef value::interval<T> result;
+
+ value::interval<T> operator()(const value::interval<T>& v1,
+ const value::interval<T>& v2) const;
};
# ifndef MLN_INCLUDE_ONLY
- template <typename L, typename R>
- inline
- R
- mean<L,R>::operator()(const L& v1, const L& v2) const
+ template <typename T>
+ value::interval<T>
+ span<T>::operator()(const value::interval<T>& v1,
+ const value::interval<T>& v2) const
{
- return R(mln::math::mean(v1, v2);
+ return value::span(v1, v2);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -74,4 +75,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_FUN_VV2V_MEAN_HH
+#endif // ! MLN_FUN_VV2V_SPAN_HH
diff --git a/milena/mln/fun/vvvv2v/mean.hh b/milena/mln/fun/vvvv2v/max.hh
similarity index 79%
copy from milena/mln/fun/vvvv2v/mean.hh
copy to milena/mln/fun/vvvv2v/max.hh
index 0dba050..311bcfe 100644
--- a/milena/mln/fun/vvvv2v/mean.hh
+++ b/milena/mln/fun/vvvv2v/max.hh
@@ -23,15 +23,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_FUN_VVVV2V_MEAN_HH
-# define MLN_FUN_VVVV2V_MEAN_HH
+#ifndef MLN_FUN_VVVV2V_MAX_HH
+# define MLN_FUN_VVVV2V_MAX_HH
/// \file
///
-/// Functor that computes the mean of two values.
+/// Functor that computes the max of two values.
# include <mln/core/concept/function.hh>
-# include <mln/math/mean.hh>
+# include <mln/math/max.hh>
namespace mln
@@ -45,9 +45,9 @@ namespace mln
// FIXME: Doc.
- /// \brief A functor computing the mean of two values.
+ /// \brief A functor computing the max of two values.
template <typename T, typename R=T>
- struct mean : public Function_vvvv2v< mean<T> >
+ struct max : public Function_vvvv2v< max<T> >
{
typedef R result;
R operator()(const T& v1, const T& v2, const T& v3, const T& v4) const;
@@ -56,12 +56,12 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- template <typename T>
+ template <typename T, typename R>
inline
R
- mean<T,R>::operator()(const T& v1, const T& v2, const T& v3, const T& v4) const
+ max<T,R>::operator()(const T& v1, const T& v2, const T& v3, const T& v4) const
{
- return R(mln::math::mean(v1, v2, v3, v4));
+ return R(mln::math::max(v1, v2, v3, v4));
}
# endif // ! MLN_INCLUDE_ONLY
@@ -73,4 +73,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_FUN_VVVV2V_MEAN_HH
+#endif // ! MLN_FUN_VVVV2V_MAX_HH
diff --git a/milena/mln/fun/vvvv2v/mean.hh b/milena/mln/fun/vvvv2v/mean.hh
index 0dba050..d9810ab 100644
--- a/milena/mln/fun/vvvv2v/mean.hh
+++ b/milena/mln/fun/vvvv2v/mean.hh
@@ -56,7 +56,7 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- template <typename T>
+ template <typename T, typename R>
inline
R
mean<T,R>::operator()(const T& v1, const T& v2, const T& v3, const T& v4) const
diff --git a/milena/mln/fun/vvvv2v/mean.hh b/milena/mln/fun/vvvv2v/min.hh
similarity index 79%
copy from milena/mln/fun/vvvv2v/mean.hh
copy to milena/mln/fun/vvvv2v/min.hh
index 0dba050..f0c4b63 100644
--- a/milena/mln/fun/vvvv2v/mean.hh
+++ b/milena/mln/fun/vvvv2v/min.hh
@@ -23,15 +23,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_FUN_VVVV2V_MEAN_HH
-# define MLN_FUN_VVVV2V_MEAN_HH
+#ifndef MLN_FUN_VVVV2V_MIN_HH
+# define MLN_FUN_VVVV2V_MIN_HH
/// \file
///
-/// Functor that computes the mean of two values.
+/// Functor that computes the min of two values.
# include <mln/core/concept/function.hh>
-# include <mln/math/mean.hh>
+# include <mln/math/min.hh>
namespace mln
@@ -45,9 +45,9 @@ namespace mln
// FIXME: Doc.
- /// \brief A functor computing the mean of two values.
+ /// \brief A functor computing the min of two values.
template <typename T, typename R=T>
- struct mean : public Function_vvvv2v< mean<T> >
+ struct min : public Function_vvvv2v< min<T> >
{
typedef R result;
R operator()(const T& v1, const T& v2, const T& v3, const T& v4) const;
@@ -56,12 +56,12 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
- template <typename T>
+ template <typename T, typename R>
inline
R
- mean<T,R>::operator()(const T& v1, const T& v2, const T& v3, const T& v4) const
+ min<T,R>::operator()(const T& v1, const T& v2, const T& v3, const T& v4) const
{
- return R(mln::math::mean(v1, v2, v3, v4));
+ return R(mln::math::min(v1, v2, v3, v4));
}
# endif // ! MLN_INCLUDE_ONLY
@@ -73,4 +73,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_FUN_VVVV2V_MEAN_HH
+#endif // ! MLN_FUN_VVVV2V_MIN_HH
diff --git a/milena/mln/fun/vvvv2v/mean.hh b/milena/mln/fun/vvvv2v/span.hh
similarity index 67%
copy from milena/mln/fun/vvvv2v/mean.hh
copy to milena/mln/fun/vvvv2v/span.hh
index 0dba050..8c99bd1 100644
--- a/milena/mln/fun/vvvv2v/mean.hh
+++ b/milena/mln/fun/vvvv2v/span.hh
@@ -23,15 +23,15 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef MLN_FUN_VVVV2V_MEAN_HH
-# define MLN_FUN_VVVV2V_MEAN_HH
+#ifndef MLN_FUN_VVVV2V_SPAN_HH
+# define MLN_FUN_VVVV2V_SPAN_HH
/// \file
///
-/// Functor that computes the mean of two values.
+/// Functor that computes the spanimum of two values.
# include <mln/core/concept/function.hh>
-# include <mln/math/mean.hh>
+# include <mln/value/interval.hh>
namespace mln
@@ -45,23 +45,29 @@ namespace mln
// FIXME: Doc.
- /// \brief A functor computing the mean of two values.
- template <typename T, typename R=T>
- struct mean : public Function_vvvv2v< mean<T> >
+ /// \brief A functor computing the span of two interval values.
+ template <typename T>
+ struct span : public Function_vvvv2v< span<T> >
{
- typedef R result;
- R operator()(const T& v1, const T& v2, const T& v3, const T& v4) const;
+ typedef value::interval<T> result;
+
+ value::interval<T> operator()(const value::interval<T>& v1,
+ const value::interval<T>& v2,
+ const value::interval<T>& v3,
+ const value::interval<T>& v4) const;
};
# ifndef MLN_INCLUDE_ONLY
template <typename T>
- inline
- R
- mean<T,R>::operator()(const T& v1, const T& v2, const T& v3, const T& v4) const
+ value::interval<T>
+ span<T>::operator()(const value::interval<T>& v1,
+ const value::interval<T>& v2,
+ const value::interval<T>& v3,
+ const value::interval<T>& v4) const
{
- return R(mln::math::mean(v1, v2, v3, v4));
+ return value::span(v1, v2, v3, v4);
}
# endif // ! MLN_INCLUDE_ONLY
@@ -73,4 +79,4 @@ namespace mln
} // end of namespace mln
-#endif // ! MLN_FUN_VVVV2V_MEAN_HH
+#endif // ! MLN_FUN_VVVV2V_SPAN_HH
diff --git a/milena/mln/math/max.hh b/milena/mln/math/max.hh
index 0fe8ea4..786aa2e 100644
--- a/milena/mln/math/max.hh
+++ b/milena/mln/math/max.hh
@@ -43,6 +43,9 @@ namespace mln
template <typename T>
T max(const T& v1, const T& v2);
+ /// Return the maximum of four values.
+ template <typename T>
+ T max(const T& v1, const T& v2, const T& v3, const T& v4);
} // end of namespace mln::math
@@ -55,6 +58,14 @@ namespace mln
return v1 > v2 ? v1 : v2;
}
+ /// \internal Generic implementation of the maximum function.
+ template <typename T>
+ T max_(const T& v1, const T& v2, const T& v3, const T& v4)
+ {
+ return max_(max_(exact(v1), exact(v2)), max_(exact(v3), exact(v4)));
+ }
+
+
namespace math
{
@@ -64,6 +75,12 @@ namespace mln
return max_(exact(v1), exact(v2));
}
+ template <typename T>
+ T max(const T& v1, const T& v2, const T& v3, const T& v4)
+ {
+ return max_(exact(v1), exact(v2), exact(v3), exact(v4));
+ }
+
} // end of namespace mln::math
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/math/min.hh b/milena/mln/math/min.hh
index d2a5503..706c103 100644
--- a/milena/mln/math/min.hh
+++ b/milena/mln/math/min.hh
@@ -43,6 +43,9 @@ namespace mln
template <typename T>
T min(const T& v1, const T& v2);
+ /// Return the minimum of four values.
+ template <typename T>
+ T min(const T& v1, const T& v2, const T& v3, const T& v4);
} // end of namespace mln::math
@@ -55,6 +58,14 @@ namespace mln
return v1 < v2 ? v1 : v2;
}
+ /// \internal Generic implementation of the minimum function.
+ template <typename T>
+ T min_(const T& v1, const T& v2, const T& v3, const T& v4)
+ {
+ return min_(min_(v1, v2), min_(v3, v4));
+ }
+
+
namespace math
{
@@ -64,6 +75,12 @@ namespace mln
return min_(exact(v1), exact(v2));
}
+ template <typename T>
+ T min(const T& v1, const T& v2, const T& v3, const T& v4)
+ {
+ return min_(exact(v1), exact(v2), exact(v3), exact(v4));
+ }
+
} // end of namespace mln::math
# endif // ! MLN_INCLUDE_ONLY
--
1.7.2.5
1
0