00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_VALUE_FLOAT01__HH
00027 # define MLN_VALUE_FLOAT01__HH
00028
00034 # include <iostream>
00035 # include <mln/core/contract.hh>
00036 # include <mln/metal/math/pow.hh>
00037 # include <mln/metal/bexpr.hh>
00038
00039 # include <mln/value/int_u.hh>
00040 # include <mln/value/concept/floating.hh>
00041 # include <mln/value/internal/convert.hh>
00042 # include <mln/value/float01.hh>
00043 # include <mln/trait/value_.hh>
00044
00045
00046
00047 namespace mln
00048 {
00049
00050
00051 namespace value {
00052 class float01;
00053 template <unsigned n> struct float01_;
00054 }
00055
00056
00057 namespace trait
00058 {
00059
00060 template <unsigned n>
00061 struct value_< mln::value::float01_<n> >
00062 {
00063 enum constants_ {
00064 dim = 1,
00065 nbits = n,
00066 card = mln_value_card_from_(nbits)
00067 };
00068
00069 typedef trait::value::nature::floating nature;
00070 typedef trait::value::kind::data kind;
00071 typedef mln_value_quant_from_(card) quant;
00072
00073 static float min() { return 0.f; }
00074 static float max() { return 1.f; }
00075 static float epsilon() { return 0.f; }
00076
00077 typedef float comp;
00078
00079 typedef float sum;
00080 };
00081
00082 }
00083
00084
00085 namespace value
00086 {
00087
00089 template <unsigned n>
00090 struct float01_
00091
00092 : public Floating< float01_<n> >,
00093
00094 public internal::value_like_< float,
00095 mln_enc(int_u<n>),
00096 float,
00097 float01_<n> >
00098 {
00100 float01_();
00101
00103 float01_(float val);
00104
00106 float01_(const mln::literal::zero_t&);
00107 float01_& operator=(const mln::literal::zero_t&);
00108 float01_(const mln::literal::one_t&);
00109 float01_& operator=(const mln::literal::one_t&);
00111
00113 float01_<n>& operator=(float val);
00114
00116 float value() const;
00117
00119 void set_ind(unsigned long val);
00120
00122 operator float() const;
00123
00124 private:
00125 typedef mln_enc(int_u<n>) enc_;
00126 };
00127
00128
00129 namespace internal
00130 {
00131
00132 template <unsigned n>
00133 struct convert_< float01_<n> >
00134 {
00135 static float01_<n> value_at_index(unsigned i)
00136 {
00137 float01_<n> tmp;
00138 tmp.set_ind(i);
00139 return tmp;
00140 }
00141
00142 static unsigned index_of_value(const float01_<n>& v)
00143 {
00144 return v.to_enc();
00145 }
00146 };
00147 }
00148
00149
00151 template <unsigned n>
00152 std::ostream& operator<<(std::ostream& ostr, const float01_<n>& f);
00153
00154
00155 template <unsigned n, unsigned m>
00156 bool approx_equal(const float01_<n>& lhs, const float01_<m>& rhs);
00157
00158 template <unsigned n>
00159 bool approx_equal(const float01_<n>& lhs, const float f);
00160
00161
00162
00163 # ifndef MLN_INCLUDE_ONLY
00164
00165
00166
00167 template <unsigned n>
00168 inline
00169 float01_<n>::float01_()
00170 {
00171 }
00172
00173 template <unsigned n>
00174 inline
00175 float01_<n>::float01_(float val)
00176 {
00177 mln_precondition(val >= 0.f);
00178 mln_precondition(val <= 1.f);
00179 this->v_ = static_cast<enc_>(val * (float(mln_max(enc_)) - 1.f));
00180 }
00181
00182 template <unsigned n>
00183 inline
00184 float
00185 float01_<n>::value() const
00186 {
00187 return float(this->v_) / (float(mln_max(enc_)) - 1.f);
00188 }
00189
00190 template <unsigned n>
00191 inline
00192 void
00193 float01_<n>::set_ind(unsigned long val)
00194 {
00195 this->v_ = static_cast<enc_>(val);
00196 }
00197
00198 template <unsigned n>
00199 inline
00200 float01_<n>::float01_(const mln::literal::zero_t&)
00201 {
00202 this->v_ = 0;
00203 }
00204
00205 template <unsigned n>
00206 inline
00207 float01_<n>&
00208 float01_<n>::operator=(const mln::literal::zero_t&)
00209 {
00210 this->v_ = 0;
00211 return *this;
00212 }
00213
00214 template <unsigned n>
00215 inline
00216 float01_<n>::float01_(const mln::literal::one_t&)
00217 {
00218 this->v_ = 1;
00219 }
00220
00221 template <unsigned n>
00222 inline
00223 float01_<n>&
00224 float01_<n>::operator=(const mln::literal::one_t&)
00225 {
00226 this->v_ = 1;
00227 return *this;
00228 }
00229
00230 template <unsigned n>
00231 inline
00232 float01_<n>&
00233 float01_<n>::operator=(float val)
00234 {
00235 mln_precondition(val >= 0.f);
00236 mln_precondition(val <= 1.f);
00237 this->v_ = static_cast<enc_>(val * (float(mln_max(enc_)) - 1.f));
00238 return *this;
00239 }
00240
00241 template <unsigned n>
00242 inline
00243 float01_<n>::operator float() const
00244 {
00245 return float(this->v_) / (float(mln_max(enc_)) - 1.f);
00246 }
00247
00248
00249
00250
00251 template <unsigned n>
00252 inline
00253 std::ostream& operator<<(std::ostream& ostr, const float01_<n>& f)
00254 {
00255 return ostr << f.value();
00256 }
00257
00258 template <unsigned n, unsigned m>
00259 inline
00260 bool approx_equal(const float01_<n>& lhs, const float01_<m>& rhs)
00261 {
00262 return float01(lhs) == float01(rhs);
00263 }
00264
00265 template <unsigned n>
00266 inline
00267 bool approx_equal(const float01_<n>& lhs, float f)
00268 {
00269 return float01(lhs) == float01_<n>(f);
00270 }
00271
00272
00273 # endif // ! MLN_INCLUDE_ONLY
00274
00275 }
00276
00277 }
00278
00279 #endif // ! MLN_VALUE_FLOAT01__HH