FloatArray.hh

Go to the documentation of this file.
00001 #ifndef BIT_FLOATARRAY_HH
00002 #define BIT_FLOATARRAY_HH
00003 
00004 #include "bit/util.hh"
00005 #include <float.h>
00006 #include "bit/Array.hh"
00007 #include "bit/endian.hh"
00008 
00009 namespace bit {
00010   
00013   class FloatArray : public Array {
00014   public:
00015 
00017     FloatArray()
00018       : Array(0, 0), m_mode(mode_default)
00019     {
00020     }
00021 
00026     FloatArray(u64 num_elems, unsigned int bits_per_elem = 0)
00027       : Array(num_elems, bits_per_elem), m_mode(mode_default)
00028     {
00029     }
00030 
00034     void set_mode(const FloatArray &array)
00035     {
00036       if (m_mode != mode_default)
00037         throw bit::invalid_call(
00038           "bit::FloatArray::set_mode() not default mode");
00039       if (array.m_mode == mode_default)
00040         return;
00041       else if (array.m_mode == mode_linear) {
00042         linear_quantization(array.m_linear_step);
00043         return;
00044       }
00045       assert(false);
00046     }
00047 
00054     void linear_quantization(double step)
00055     {
00056       if (m_mode != mode_default)
00057         throw bit::invalid_call(
00058           "bit::FloatArray::set_linear_quantization() already quantized");
00059       if (step < 0)
00060         throw bit::invalid_argument(
00061           "bit::FloatArray::set_linear_quantization() negative step");
00062 
00063       if (num_elems() == 0 || bits_per_elem() == 0) {
00064         m_mode = mode_linear;
00065         m_linear_step = step;
00066         return;
00067       }
00068 
00069       FloatArray new_array(num_elems(), 0);
00070       new_array.linear_quantization(step);
00071       for (u64 i = 0; i < num_elems(); i++)
00072         new_array.set_grow_widen(i, get(i));
00073       *this = new_array;
00074     }
00075 
00085     void linear_quantization_bits(unsigned int bits)
00086     {
00087       if (bits < 2 || bits > 31)
00088         throw bit::invalid_call(
00089           "bit::FloatArray::linear_quantization_bits() invalid bits argument");
00090 
00091       if (num_elems() == 0 || bits_per_elem() == 0)
00092         return;
00093 
00094       float min = FLT_MAX;
00095       float max = -FLT_MAX;
00096       for (u64 i = 0; i < num_elems(); i++) {
00097         float value = get(i);
00098         if (value < min)
00099           min = value;
00100         if (value > max)
00101           max = value;
00102       }
00103 
00104       float absmax = std::max(util::abs(min), util::abs(max));
00105       if (absmax == 0)
00106         return;
00107       
00108       linear_quantization(absmax / bit::one_masks[bits - 1]);
00109     }
00110 
00116     float get(u64 elem) const
00117     {
00118       return to_float(Array::get(elem));
00119     }
00120      
00129     void set(u64 elem, float value)
00130     {
00131       Array::set(elem, to_uint(value));
00132     }
00133 
00142     void set_grow(u64 elem, float value)
00143     {
00144       Array::set_grow(elem, to_uint(value));
00145     }
00146 
00155     void set_grow_widen(u64 elem, float value)
00156     {
00157       Array::set_grow_widen(elem, to_uint(value));
00158     }
00159 
00164     u32 to_uint(float value) const
00165     {
00166       switch (m_mode) {
00167       case mode_default:
00168         return float2uint(value);
00169       case mode_linear:
00170         return quantize_float(value, m_linear_step);
00171       case mode_kmeans:
00172         break;
00173       }
00174       assert(false);
00175       return 0;
00176     }
00177 
00182     float to_float(u32 i) const
00183     {
00184       switch (m_mode) {
00185       case mode_default:
00186         return uint2float(i);
00187       case mode_linear:
00188         return unquantize_float(i, m_linear_step);
00189       case mode_kmeans:
00190         break;
00191       }
00192       assert(false);
00193       return 0;
00194     }
00195 
00201     void write(FILE *file) const
00202     {
00203       fprintf(file, "FARRAY1:%d:", (int)m_mode);
00204       size_t ret = endian::write8(m_linear_step, file);
00205       try {
00206         if (ret != 1)
00207           throw io_error("writing m_linear_step failed");
00208         Array::write(file);
00209       }
00210       catch (std::exception &e) {
00211         throw io_error(
00212           std::string("bit::FloatArray::write() failed: ") + e.what());
00213       }
00214     }
00215 
00221     void read(FILE *file)
00222     {
00223       int version;
00224       int mode;
00225       int ret = fscanf(file, "FARRAY%d:%d:", &version, &mode);
00226       if (ret != 2 || version != 1)
00227         throw bit::io_error(
00228           "bit::FloatArray::read() error while reading header");
00229       m_mode = (Mode)mode;
00230       try {
00231         size_t ret = endian::read8(&m_linear_step, file);
00232         if (ret != 1)
00233           throw io_error("reading m_linear_step failed");
00234         Array::read(file);
00235       }
00236       catch (std::exception &e) {
00237         throw io_error(
00238           std::string("bit::FloatArray::read() failed: ") + e.what());
00239       }
00240     }
00241 
00242   private:
00243     
00245     enum Mode { mode_default = 0, mode_linear, mode_kmeans } m_mode;
00246 
00248     double m_linear_step;
00249 
00250   };
00251 
00252 };
00253 
00254 #endif /* BIT_FLOATARRAY_HH */

Generated on Mon Jan 8 15:51:03 2007 for bit by  doxygen 1.4.6