URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-04-28 Etienne FOLIO <folio(a)lrde.epita.fr>
Circular value type.
* folio/mln/value/circular.hh: New type.
* folio/test/value/circular.cc: New tests.
---
mln/value/circular.hh | 268 +++++++++++++++++++++++++++++++++++++++++++++++++
test/value/circular.cc | 48 ++++++++
2 files changed, 316 insertions(+)
Index: trunk/milena/sandbox/folio/test/value/circular.cc
===================================================================
--- trunk/milena/sandbox/folio/test/value/circular.cc (revision 0)
+++ trunk/milena/sandbox/folio/test/value/circular.cc (revision 3721)
@@ -0,0 +1,48 @@
+
+#include <mln/value/float01.hh>
+
+#include "../../mln/value/circular.hh"
+
+
+int main()
+{
+ using namespace mln;
+ using namespace mln::value;
+
+ circular<12, 0, 360> inter(21);
+ std::cout << "21: " << inter << " " <<
float(inter) << std::endl;
+ inter = 0;
+ std::cout << "0: " << inter << std::endl;
+ inter = 42;
+ std::cout << "42: " << inter << std::endl;
+ inter = 359;
+ std::cout << "359: " << inter << std::endl;
+ inter = 359.5;
+ std::cout << "359.5: " << inter << std::endl;
+ inter = 360;
+ std::cout << "360: " << inter << std::endl;
+ inter = 360.5;
+ std::cout << "360.5: " << inter << std::endl;
+ inter = 361;
+ std::cout << "361: " << inter << std::endl;
+ inter = 372;
+ std::cout << "372: " << inter << std::endl;
+ inter = 972;
+ std::cout << "972: " << inter << std::endl;
+ inter = -0.2;
+ std::cout << "-0.2: " << inter << std::endl;
+ inter = -1;
+ std::cout << "-1: " << inter << std::endl;
+ inter = -1;
+ std::cout << "-1: " << inter << std::endl;
+ inter = -359;
+ std::cout << "-359: " << inter << std::endl;
+ inter = -359.5;
+ std::cout << "-359.5: " << inter << std::endl;
+ inter = -360;
+ std::cout << "-360: " << inter << std::endl;
+ inter = -360.5;
+ std::cout << "-360.5: " << inter << std::endl;
+ inter = -361;
+ std::cout << "-361: " << inter << std::endl;
+}
Index: trunk/milena/sandbox/folio/mln/value/circular.hh
===================================================================
--- trunk/milena/sandbox/folio/mln/value/circular.hh (revision 0)
+++ trunk/milena/sandbox/folio/mln/value/circular.hh (revision 3721)
@@ -0,0 +1,268 @@
+// Copyright (C) 2006, 2007, 2008 EPITA Research and Development
+// Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_VALUE_CIRCULAR_HH
+# define MLN_VALUE_CIRCULAR_HH
+
+/*! \file mln/value/circular.hh
+ *
+ * \brief FIXME.
+ */
+
+# include <iostream>
+# include <math.h>
+# include <mln/core/contract.hh>
+# include <mln/metal/math/pow.hh>
+# include <mln/metal/bexpr.hh>
+
+# include <mln/value/int_u.hh>
+# include <mln/value/concept/floating.hh>
+# include <mln/value/internal/convert.hh>
+# include <mln/trait/value_.hh>
+
+
+
+namespace mln
+{
+
+ // Fwd decls.
+ namespace value {
+ template <unsigned n, int inf, int sup> struct circular;
+ }
+
+
+ namespace trait
+ {
+
+ template <unsigned n, int inf, int sup>
+ struct value_< mln::value::circular<n, inf, sup> >
+ {
+ enum constants_ {
+ dim = 1,
+ nbits = n,
+ card = mln_value_card_from_(nbits)
+ };
+
+ typedef trait::value::nature::floating nature;
+ typedef trait::value::kind::data kind;
+ typedef mln_value_quant_from_(card) quant;
+
+ static float min() { return 0.f; }
+ static float max() { return 1.f; }
+ static float epsilon() { return 0.f; }
+
+ typedef float comp;
+
+ typedef float sum;
+ };
+
+ } // end of namespace trait
+
+
+ namespace value
+ {
+
+ /// General class for the interval [0,1] of |R made discrete (quantized with n
bits).
+ template <unsigned n, int inf, int sup>
+ struct circular
+
+ : public Floating< circular<n, inf, sup> >,
+
+ public internal::value_like_< float, // Equivalent. // FIXME: Why not
circular?
+ mln_enc(int_u<n>), // Encoding.
+ float, // Interoperation.
+ circular<n, inf, sup> > // Exact.
+ {
+ /// Constructor without argument.
+ circular();
+
+ /// Constructor from a float.
+ circular(float val);
+
+ /// Assigment from a float.
+ circular<n, inf, sup>& operator=(float val);
+
+ /// Access to std type.
+ float value() const;
+
+ /// Set value to the \p val th position in the quantized interval.
+ void set_ind(unsigned long val);
+
+ /// Conversion to a float.
+ operator float() const;
+
+ private:
+ typedef mln_enc(int_u<n>) enc_;
+
+ float
+ circle(const float i) const;
+
+ float float01encode(const float i) const;
+ float float01decode(const float i) const;
+
+ };
+
+
+ namespace internal
+ {
+
+ template <unsigned n, int inf, int sup>
+ struct convert_< circular<n, inf, sup> >
+ {
+ static circular<n, inf, sup> value_at_index(unsigned i)
+ {
+ circular<n, inf, sup> tmp;
+ tmp.set_ind(i);
+ return tmp;
+ }
+
+ static unsigned index_of_value(const circular<n, inf, sup>& v)
+ {
+ return v.to_enc();
+ }
+ };
+ }
+
+
+ /// Op<<.
+ template <unsigned n, int inf, int sup>
+ std::ostream& operator<<(std::ostream& ostr, const circular<n, inf,
sup>& f);
+
+ template <unsigned n, int inf, int sup, unsigned m, int inf2, int sup2>
+ bool approx_equal(const circular<n, inf, sup>& lhs, const circular<m,
inf2, sup2>& rhs);
+
+ template <unsigned n, int inf, int sup>
+ bool approx_equal(const circular<n, inf, sup>& lhs, const float f);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ // Circular<n, inf, sup>.
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>::circular()
+ {
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::float01encode(const float i) const
+ {
+ return circle((i - inf) / (sup - inf));
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::float01decode(const float i) const
+ {
+ return i * (sup - inf) + inf;
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>::circular(float val)
+ {
+ this->v_ = static_cast<enc_>(float01encode(val) * (float(mln_max(enc_)) -
1.f)); // FIXME
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::circle(const float i) const
+ {
+ return (int(floor(i)) - inf) % (sup - inf) + inf + (i - floor(i));
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ float
+ circular<n, inf, sup>::value() const
+ {
+ return float(float01decode(this->v_)) / (float(mln_max(enc_)) - 1.f); // FIXME
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ void
+ circular<n, inf, sup>::set_ind(unsigned long val)
+ {
+ this->v_ = static_cast<enc_>(val);
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>&
+ circular<n, inf, sup>::operator=(float val)
+ {
+ this->v_ = static_cast<enc_>(float01encode(val) * (float(mln_max(enc_)) -
1.f)); // FIXME
+ return *this;
+ }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ circular<n, inf, sup>::operator float() const
+ {
+ return float(float01decode(this->v_)) / (float(mln_max(enc_)) - 1.f);
+ }
+
+
+ // Operators.
+
+ template <unsigned n, int inf, int sup>
+ inline
+ std::ostream& operator<<(std::ostream& ostr, const circular<n, inf,
sup>& f)
+ {
+ return ostr << f.value();
+ }
+
+ // template <unsigned n, int inf, int sup, unsigned m, int inf2, int sup2>
+ // inline
+ // bool approx_equal(const circular<n, inf, sup>& lhs, const circular<m,
inf2, sup2>& rhs)
+ // {
+ // return circular<n, inf, sup>(lhs) == circular<>(rhs);
+ // }
+
+ template <unsigned n, int inf, int sup>
+ inline
+ bool approx_equal(const circular<n, inf, sup>& lhs, float f)
+ {
+ return circular<n, inf, sup>(lhs) == circular<n, inf, sup>(f);
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::value
+
+} // end of namespace mln
+
+#endif // ! MLN_VALUE_CIRCULAR_HH