
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-10-02 Matthieu Garrigues <garrigues@lrde.epita.fr> Add float01 values. float01_<n> type is used to represent quantified float numbers in the range [0..1]. * mln/value/float01.hh: New. * mln/value/float01_.hh: New. * mln/value/float01_16.hh: New. * mln/value/float01_8.hh: New. * tests/value_float01.cc: New. --- mln/value/float01.hh | 244 ++++++++++++++++++++++++++++++++++++++++++++++++ mln/value/float01_.hh | 218 ++++++++++++++++++++++++++++++++++++++++++ mln/value/float01_16.hh | 55 ++++++++++ mln/value/float01_8.hh | 55 ++++++++++ tests/value_float01.cc | 77 +++++++++++++++ 5 files changed, 649 insertions(+) Index: trunk/milena/tests/value_float01.cc =================================================================== --- trunk/milena/tests/value_float01.cc (revision 0) +++ trunk/milena/tests/value_float01.cc (revision 1218) @@ -0,0 +1,77 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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. + +#include <iostream> +#include <mln/value/float01_8.hh> +#include <mln/value/float01_16.hh> + + + +float fi(int x) { return 0.5; } +int ii(int x) { return 1; } + +float fd(double x) { return 0.5; } +int id(double x) { return 1; } + +int main() +{ + using namespace mln::value; + + float01_8 a(0.5); + float01_16 b(0.5); + + assert(approx_equal(b,a)); + + std::cout << b << std::endl; + b = b + 0.2; + std::cout << b << std::endl; + b = b - 0.2; + std::cout << b << std::endl; + b = b * 1.5; + std::cout << b << std::endl; + b = b / 4.6; + std::cout << b << std::endl; + + b = b / 3; + std::cout << b << std::endl; + b = b * 1; + std::cout << b << std::endl; + + a = fi(a); + a = ii(a); + a = fd(a); + a = id(a); + + b = a; + a = b; + b = 0.34; + std::cout << b << std::endl; + b = 0; + std::cout << b << std::endl; + b = 1; + std::cout << b << std::endl; +} Index: trunk/milena/mln/value/float01_8.hh =================================================================== --- trunk/milena/mln/value/float01_8.hh (revision 0) +++ trunk/milena/mln/value/float01_8.hh (revision 1218) @@ -0,0 +1,55 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_FLOAT01_8_HH +# define MLN_VALUE_FLOAT01_8_HH + +/*! \file mln/value/float01_8.hh + * + * \brief Define the alias value::float01_8. + */ + +# include <mln/value/float01_.hh> + + +namespace mln +{ + + namespace value + { + + + /// Alias for 8 bit float01. + typedef float01_<8> float01_8; + + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_FLOAT01_8_HH Index: trunk/milena/mln/value/float01_.hh =================================================================== --- trunk/milena/mln/value/float01_.hh (revision 0) +++ trunk/milena/mln/value/float01_.hh (revision 1218) @@ -0,0 +1,218 @@ +// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_CORE_VALUE_FLOAT01__HH +# define MLN_CORE_VALUE_FLOAT01__HH + +# include <iostream> +# include <mln/core/contract.hh> +# include <mln/metal/math.hh> +# include <mln/metal/bexpr.hh> +# include <mln/value/internal/value_like.hh> +# include <mln/value/internal/encoding.hh> +# include <mln/value/float01.hh> +# include <mln/value/props.hh> + +namespace mln +{ + + namespace value + { + + /// Fwd decl. + class float01; + + + /// General float01-level class on n bits. + template <unsigned n> + class float01_ + : public internal::value_like_< double, + float01_<n> > + { + public: + + /// Encoding associated type. + typedef typename internal::encoding_unsigned_<n>::ret enc; + + /// Ctor. + float01_(); + + /// Ctor. + float01_(const double val); + + /// Access to std type. + double value() const; + + void set_ind(unsigned long val); + + enc value_ind() const; + + /// Op encoding_t. + operator double() const; + + /// Op float01_. + operator float01_() const; + + /// Op<. + bool operator<(const float01_<n>& rhs) const; + + float01_<n>& operator=(const double val); + /// Op==. + // bool operator==(const float01_<n>& rhs) const; + + protected: + enc val_; + }; + + + template <unsigned n> + struct props< float01_<n> > + { + static const std::size_t card_ = metal::pow<2, n>::value; + static const float01_<n> min() { return 0; } + static const float01_<n> max() { return 1; } + static const unsigned nbits = n; + typedef trait::kind::data kind; + typedef float sum; + typedef float interop; + }; + + + /// Op<<. + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const float01_<n>& g); + + + template <unsigned n, unsigned m> + bool approx_equal(const float01_<n>& lhs, const float01_<m>& rhs); + + template <unsigned n> + bool operator==(const float01_<n>& lhs, const float01_<n>& rhs); + + template <unsigned n> + bool approx_equal(const float01_<n>& lhs, const double f); + +# ifndef MLN_INCLUDE_ONLY + + // Float01_<n>. + + template <unsigned n> + float01_<n>::float01_() + : val_(0) + { + } + + template <unsigned n> + float01_<n>::float01_(const double val) + : val_( int(val * (mln_card_(float01_<n>) - 1)) ) + { + mln_precondition(val >= 0); + mln_precondition(val <= 1); + } + + template <unsigned n> + double + float01_<n>::value() const + { + return (double(val_) / (mln_card_(float01_<n>) - 1)); + } + + template <unsigned n> + void + float01_<n>::set_ind(unsigned long val) + { + val_ = val; + } + + template <unsigned n> + typename float01_<n>::enc + float01_<n>::value_ind() const + { + return (val_); + } + + template <unsigned n> + float01_<n>& + float01_<n>::operator=(const double val) + { + mln_precondition(val >= 0); + mln_precondition(val <= 1); + this->val_ = long(val * (mln_card_(float01_<n>) - 1)); + return *this; + } + + template <unsigned n> + float01_<n>::operator float01_() const + { + float01 tmp(n, val_); + return tmp; + } + + template <unsigned n> + float01_<n>::operator double() const + { + return double(val_) / (mln_card_(float01_<n>) - 1); + } + + template <unsigned n> + bool float01_<n>::operator<(const float01_<n>& rhs) const + { + return val_ < rhs.val_; + } + + template <unsigned n> + std::ostream& operator<<(std::ostream& ostr, const float01_<n>& g) + { + return ostr << g.value(); + } + + template <unsigned n> + bool operator==(const float01_<n>& lhs, const float01_<n>& rhs) + { + return lhs.value_ind() == rhs.value_ind(); + } + + template <unsigned n, unsigned m> + bool approx_equal(const float01_<n>& lhs, const float01_<m>& rhs) + { + return float01(lhs) == float01(rhs); + } + + template <unsigned n> + bool approx_equal(const float01_<n>& lhs, const double f) + { + return float01(lhs) == float01_<n>(f); + } + +# endif + + + } // end of namespace mln::value + +} // end of namespace mln + +#endif // ! MLN_CORE_VALUE_FLOAT01__HH Index: trunk/milena/mln/value/float01.hh =================================================================== --- trunk/milena/mln/value/float01.hh (revision 0) +++ trunk/milena/mln/value/float01.hh (revision 1218) @@ -0,0 +1,244 @@ +// Copyright (C) 2006, 2007 EPITA Research and Development Laboratory +// +// 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_FLOAT01_HH +# define MLN_VALUE_FLOAT01_HH + +# include <iostream> + +# include <mln/core/concept/value.hh> +# include <mln/value/float01_.hh> + + + +namespace mln +{ + + // Fwd decls. + namespace value + { + template <unsigned N> class float01_; + class float01; + + /// General float01_ class where n bits is not know at compile-time. + /// This class is used for exchange between float01_ types purpose. + + class float01 : public Value<float01> + { + public: + + /// Encoding associated type. + typedef double enc; + + /// Equivalent associated type. + typedef double equiv; + + /// Ctor. + float01(); + + /// Ctor. + template <unsigned N> + float01(const float01_<N>& val); + + /// Ctor. + float01(unsigned nbits, double val); + + /// Access to std type. + double value() const; + unsigned long value_ind() const; + + unsigned nbits() const; + + void set_nbits(unsigned nbits); + + float01 to_nbits(unsigned nbits) const; + + template <unsigned N> + operator float01_<N>() const; + + protected: + unsigned nbits_; + unsigned long val_; + }; + + std::ostream& operator<<(std::ostream& ostr, const float01& g); + + bool operator==(const float01& lhs, const float01& rhs); + bool operator<(const float01& lhs, const float01& rhs); + + +# ifndef MLN_INCLUDE_ONLY + + namespace internal + { + + unsigned long two_pow_(unsigned n) + { + if (n == 0) + return 1; + else + return 2 * two_pow_(n - 1); + } + + unsigned long two_pow_n_minus_1(unsigned n) + { + return two_pow_(n) - 1; + } + + template <unsigned n_dest> + unsigned long convert(unsigned n_src, unsigned long val) + { + if (n_dest == n_src) + return val; + else + if (n_dest > n_src) + return val * two_pow_n_minus_1(n_dest) / two_pow_n_minus_1(n_src); + else + return val / two_pow_(n_src - n_dest); + } + + } // end of mln::value::internal + + // Float01. + + float01::float01() + : nbits_(0) + { + } + + template <unsigned n> + float01::float01(const float01_<n>& g) + : nbits_(n), + val_(g.value_ind()) + { + } + + float01::float01(unsigned nbits, double val) + : nbits_(nbits), + val_(unsigned(val * internal::two_pow_n_minus_1(nbits))) + { + } + + double float01::value() const + { + mln_invariant(nbits_ != 0); + return val_ / internal::two_pow_n_minus_1(nbits_); + } + + unsigned long float01::value_ind() const + { + mln_invariant(nbits_ != 0); + return val_; + } + + unsigned float01::nbits() const + { + return nbits_; + } + + + + void float01::set_nbits(unsigned nbits) + { + mln_precondition(nbits != 0); + mln_invariant(nbits_ != 0); + if (nbits == nbits_) + return; + if (nbits > nbits_) + { + val_ *= internal::two_pow_n_minus_1(nbits); + val_ /= internal::two_pow_n_minus_1(nbits_); + } + else // nbits < nbits_ + { + val_ /= internal::two_pow_(nbits_ - nbits); + } + nbits_ = nbits; + } + + + float01 float01::to_nbits(unsigned nbits) const + { + mln_precondition(nbits != 0); + mln_invariant(nbits_ != 0); + float01 tmp(*this); + tmp.set_nbits(nbits); + return tmp; + } + + + template <unsigned n> + float01::operator float01_<n>() const + { + mln_precondition(nbits_ != 0); + float01_<n> tmp; + tmp.set_ind(internal::convert<n>(nbits_, val_)); + mln_assertion(tmp.value() < internal::two_pow_(n)); + return tmp; + } + + // operators + + std::ostream& operator<<(std::ostream& ostr, const float01& g) + { + return ostr << g.value() << '/' << g.nbits() << "nbits"; + } + + bool operator==(const float01& lhs, const float01& rhs) + { + mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0); + + if (rhs.nbits() == lhs.nbits()) + return lhs.value_ind() == rhs.value_ind(); + + if (lhs.nbits() < rhs.nbits()) + return lhs.value_ind() == rhs.to_nbits(lhs.nbits()).value_ind(); + else + { + return lhs.to_nbits(rhs.nbits()).value_ind() == rhs.value_ind(); + } + } + + bool operator<(const float01& lhs, const float01& rhs) + { + mln_precondition(lhs.nbits() != 0 and rhs.nbits() != 0); + if (rhs.nbits() == lhs.nbits()) + return lhs.value() < rhs.value(); + if (lhs.nbits() > rhs.nbits()) + return lhs.value() < rhs.to_nbits(lhs.nbits()).value(); + else + return lhs.to_nbits(rhs.nbits()).value() < rhs.value(); + } + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_FLOAT01_HH Index: trunk/milena/mln/value/float01_16.hh =================================================================== --- trunk/milena/mln/value/float01_16.hh (revision 0) +++ trunk/milena/mln/value/float01_16.hh (revision 1218) @@ -0,0 +1,55 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// 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_FLOAT01_16_HH +# define MLN_VALUE_FLOAT01_16_HH + +/*! \file mln/value/float01_16.hh + * + * \brief Define the alias value::float01_16. + */ + +# include <mln/value/float01_.hh> + + +namespace mln +{ + + namespace value + { + + + /// Alias for 16 bit float01. + typedef float01_<16> float01_16; + + + } // end of namespace mln::value + +} // end of namespace mln + + +#endif // ! MLN_VALUE_FLOAT01_16_HH