00001 #ifndef ORLM_QUANTIZER_H
00002 #define ORLM_QUANTIZER_H
00003
00004 #include <vector>
00005 #include <cmath>
00006 #include "util/check.hh"
00007 #include <algorithm>
00008 #include "types.h"
00009
00010 static const float kFloatErr = 0.00001f;
00011
00012 #ifdef WIN32
00013 #define log2(X) (log((double)X)/log((double)2))
00014 #endif
00015
00017 class LogQtizer {
00018 public:
00019 LogQtizer(float i): base_(pow(2, 1 / i)) {
00020 CHECK(base_ > 1);
00021 max_code_ = 0;
00022 float value = 1;
00023 std::vector<float> code_to_value_vec;
00024 while (log2(value) < 30) {
00025 code_to_value_vec.push_back(value);
00026 value = pow(base_, ++max_code_);
00027 }
00028 code_to_value_vec.push_back(value);
00029
00030 max_value_ = code_to_value_vec[max_code_];
00031 min_value_ = 1;
00032
00033 code_to_value_ = new float[max_code_ + 1];
00034 code_to_log_value_ = new float[max_code_ + 1];
00035 for (int j = 0; j <= max_code_; ++j) {
00036
00037 code_to_value_[j] = floor(kFloatErr + code_to_value_vec[j]);
00038 code_to_log_value_[j] = log10(code_to_value_[j]);
00039 }
00040 std::cerr << "Initialized quantization (size = " << max_code_ + 1 << ")" << std::endl;
00041 }
00042 LogQtizer(FileHandler* fin) {
00043 CHECK(fin != NULL);
00044 load(fin);
00045 }
00046 int code(float value) {
00047
00048 CHECK(!(value < min_value_ || value > max_value_));
00049
00050 int code = static_cast<int>(std::lower_bound(code_to_value_, code_to_value_+ max_code_,
00051 value) - code_to_value_);
00052
00053 code = code_to_value_[code] > value ? code - 1 : code;
00054 return code;
00055 }
00056 inline float value(int code) {
00057
00058 return code_to_value_[code];
00059 }
00060 inline int maxcode() {
00061 return max_code_;
00062 }
00063 inline float logValue(int code) {
00064
00065 return code_to_log_value_[code];
00066 }
00067 ~LogQtizer() {
00068 delete[] code_to_value_;
00069 delete[] code_to_log_value_;
00070 }
00071 void save(FileHandler* fout) {
00072 fout->write((char*)&base_, sizeof(base_));
00073 fout->write((char*)&max_code_, sizeof(max_code_));
00074 fout->write((char*)&max_value_, sizeof(max_value_));
00075 fout->write((char*)&min_value_, sizeof(min_value_));
00076 for (int j = 0; j <= max_code_; ++j)
00077 fout->write((char*)&code_to_value_[j], sizeof(code_to_value_[j]));
00078 for (int j = 0; j <= max_code_; ++j)
00079 fout->write((char*)&code_to_log_value_[j], sizeof(code_to_log_value_[j]));
00080 std::cerr << "Saved log codebook with " << max_code_ + 1 << " codes." <<std::endl;
00081 }
00082 private:
00083 float base_;
00084 float* code_to_value_;
00085 float* code_to_log_value_;
00086 int max_code_;
00087 float max_value_;
00088 float min_value_;
00089 void load(FileHandler* fin) {
00090 fin->read((char*)&base_, sizeof(base_));
00091 fin->read((char*)&max_code_, sizeof(max_code_));
00092 fin->read((char*)&max_value_, sizeof(max_value_));
00093 fin->read((char*)&min_value_, sizeof(min_value_));
00094 code_to_value_ = new float[max_code_ + 1];
00095 for(int j = 0; j <= max_code_; ++j)
00096 fin->read((char*)&code_to_value_[j], sizeof(code_to_value_[j]));
00097 code_to_log_value_ = new float[max_code_ + 1];
00098 for(int j = 0; j <= max_code_; ++j)
00099 fin->read((char*)&code_to_log_value_[j], sizeof(code_to_log_value_[j]));
00100 std::cerr << "Loaded log codebook with " << max_code_ + 1 << " codes." << std::endl;
00101 }
00102 };
00103
00104 #endif