From a21b6be86226eb61dc0d3acc750f7d61245c7738 Mon Sep 17 00:00:00 2001 From: liu946 Date: Sat, 3 Jun 2017 16:25:40 +0800 Subject: [PATCH] srl include dir --- src/srl/include/CMakeLists.txt | 17 +++ src/srl/include/base/config.cpp | 116 ++++++++++++++++++ src/srl/include/base/config.h | 73 +++++++++++ src/srl/include/base/debug.cpp | 26 ++++ src/srl/include/base/debug.h | 93 ++++++++++++++ src/srl/include/base/process.h | 28 +++++ src/srl/include/base/processLoader.h | 38 ++++++ src/srl/include/base/progressBar.h | 47 +++++++ src/srl/include/base/timer.h | 58 +++++++++ src/srl/include/extractor/AbstractConverter.h | 25 ++++ src/srl/include/extractor/AbstractExtractor.h | 25 ++++ src/srl/include/extractor/BiConverter.h | 50 ++++++++ src/srl/include/extractor/Converter.h | 60 +++++++++ .../extractor/ConverterBlockToConcept.h | 28 +++++ .../extractor/ConverterConceptToSample.h | 27 ++++ .../include/extractor/ConverterFileReader.h | 56 +++++++++ .../extractor/ConverterMultiLineFileReader.h | 91 ++++++++++++++ src/srl/include/extractor/Extractor.h | 31 +++++ .../extractor/ExtractorFileToSample.cpp | 5 + .../include/extractor/ExtractorFileToSample.h | 30 +++++ src/srl/include/model/LoopCounter.h | 34 +++++ src/srl/include/model/Model.h | 21 ++++ src/srl/include/model/RandomOrderMap.h | 46 +++++++ src/srl/include/process/AbstractPredictor.h | 28 +++++ src/srl/include/process/AbstractTrainer.h | 27 ++++ src/srl/include/process/ConditionStopper.h | 55 +++++++++ src/srl/include/process/ModelPredictor.h | 32 +++++ src/srl/include/process/ModelTester.h | 31 +++++ src/srl/include/process/ModelTrainer.h | 29 +++++ src/srl/include/structure/Data.h | 21 ++++ src/srl/include/structure/DataConcept.h | 18 +++ .../include/structure/DataFileBlockContext.h | 35 ++++++ src/srl/include/structure/DataFileContext.h | 23 ++++ src/srl/include/structure/DataFileName.h | 24 ++++ src/srl/include/structure/Performance.h | 42 +++++++ src/srl/include/structure/Prediction.h | 13 ++ 36 files changed, 1403 insertions(+) create mode 100644 src/srl/include/CMakeLists.txt create mode 100644 src/srl/include/base/config.cpp create mode 100644 src/srl/include/base/config.h create mode 100644 src/srl/include/base/debug.cpp create mode 100644 src/srl/include/base/debug.h create mode 100644 src/srl/include/base/process.h create mode 100644 src/srl/include/base/processLoader.h create mode 100644 src/srl/include/base/progressBar.h create mode 100644 src/srl/include/base/timer.h create mode 100644 src/srl/include/extractor/AbstractConverter.h create mode 100644 src/srl/include/extractor/AbstractExtractor.h create mode 100644 src/srl/include/extractor/BiConverter.h create mode 100644 src/srl/include/extractor/Converter.h create mode 100644 src/srl/include/extractor/ConverterBlockToConcept.h create mode 100644 src/srl/include/extractor/ConverterConceptToSample.h create mode 100644 src/srl/include/extractor/ConverterFileReader.h create mode 100644 src/srl/include/extractor/ConverterMultiLineFileReader.h create mode 100644 src/srl/include/extractor/Extractor.h create mode 100644 src/srl/include/extractor/ExtractorFileToSample.cpp create mode 100644 src/srl/include/extractor/ExtractorFileToSample.h create mode 100644 src/srl/include/model/LoopCounter.h create mode 100644 src/srl/include/model/Model.h create mode 100644 src/srl/include/model/RandomOrderMap.h create mode 100644 src/srl/include/process/AbstractPredictor.h create mode 100644 src/srl/include/process/AbstractTrainer.h create mode 100644 src/srl/include/process/ConditionStopper.h create mode 100644 src/srl/include/process/ModelPredictor.h create mode 100644 src/srl/include/process/ModelTester.h create mode 100644 src/srl/include/process/ModelTrainer.h create mode 100644 src/srl/include/structure/Data.h create mode 100644 src/srl/include/structure/DataConcept.h create mode 100644 src/srl/include/structure/DataFileBlockContext.h create mode 100644 src/srl/include/structure/DataFileContext.h create mode 100644 src/srl/include/structure/DataFileName.h create mode 100644 src/srl/include/structure/Performance.h create mode 100644 src/srl/include/structure/Prediction.h diff --git a/src/srl/include/CMakeLists.txt b/src/srl/include/CMakeLists.txt new file mode 100644 index 000000000..aec4e1b62 --- /dev/null +++ b/src/srl/include/CMakeLists.txt @@ -0,0 +1,17 @@ +# look for Boost +if(DEFINED ENV{BOOST_ROOT}) + set(Boost_NO_SYSTEM_PATHS ON) +endif() +set(Boost_REALPATH ON) +find_package(Boost COMPONENTS program_options REQUIRED) +include_directories(${Boost_INCLUDE_DIR}) + +set(base_src + base/config.cpp + base/debug.cpp + ) + +add_library(base_static_lib STATIC ${base_src}) +target_link_libraries(base_static_lib ${Boost_LIBRARIES}) +add_library(base_shared_lib SHARED ${base_src}) +target_link_libraries(base_shared_lib ${Boost_LIBRARIES}) \ No newline at end of file diff --git a/src/srl/include/base/config.cpp b/src/srl/include/base/config.cpp new file mode 100644 index 000000000..44ed8a186 --- /dev/null +++ b/src/srl/include/base/config.cpp @@ -0,0 +1,116 @@ +// +// Created by liu on 2016/12/19. +// + +#include "config.h" +#include "iostream" +#include +#include +#include + +using namespace std; + +const boost::program_options::variables_map &base::config::getConf() const { + return conf; +} + +string base::config::toString(string outerSep, string innerSep) { + map >::iterator iter; + std::ostringstream stream; + for (iter = confMap.begin(); iter != confMap.end(); iter++) { + stream << outerSep << iter->first << innerSep; + switch (iter->second.first) { + case (INT): stream << *((int*)(iter->second.second)); break; + case (UNSIGNED): stream << *((unsigned*)(iter->second.second)); break; + case (FLOAT): stream << *((float*)(iter->second.second)); break; + case (STRING): stream << *((string*)(iter->second.second)); break; + case (BOOL): stream << *((bool*)(iter->second.second)); break; + } + + } + return stream.str(); +} + + +void base::config::init(int argc, char **argv) { + /* 当传入 @configFile 时要正确解析 */ + /* 覆盖策略: + * 前面定义的覆盖后面的 // 命令行必须在 配置文件之前 + * --a b @config(其中a=c) // a最终为b + * @config(其中a=b) @config(其中a=c) // a最终为b + * */ + try { + + if (argc >=2) { + if (argv[1][0] == '@' && argc == 2) { // @config + init(argv[1] + 1); + return; + } else if (argv[1][0] == '@') { // @config1 @config2 + ifstream f(argv[1] + 1); if (!f) { cerr << "config file '" << (char *)(argv[1] + 1) << "' not found!"; exit(1);} + po::store(po::parse_config_file(f,optionDescription), conf); + f.close(); + init(argc - 1, argv + 1); + return; + } else { + int firstConfigFile = 1; + for (; firstConfigFile < argc && argv[firstConfigFile][0] != '@' ; firstConfigFile += 2); + if (firstConfigFile >= argc) {// --a b + po::store(po::parse_command_line(argc, (const char *const *) argv, optionDescription), conf); + } else { // --a b @config + po::store(po::parse_command_line(firstConfigFile, (const char *const *) argv, optionDescription), conf); + init(argc - firstConfigFile + 1, argv + firstConfigFile - 1); + return; + } + } + } else { + po::store(po::parse_command_line(argc, (const char *const *) argv, optionDescription), conf); + } + if (conf.count("help")) { + cerr << optionDescription << endl; + exit(1); + } + po::notify(conf); + extractBool(); + } catch ( boost::exception_detail::clone_impl > & e) { + cerr << endl << "[error] " << e.get_option_name() << " must be set!" << endl << endl; + cerr << optionDescription << endl; + exit(1); + } catch (boost::exception_detail::clone_impl > & e) { + cerr << endl << "[error] unrecognised option '" << e.get_option_name() << "'." << endl << endl; + cerr << optionDescription << endl; + exit(1); + } + +} + +void base::config::init(string configFile) { + try { + ifstream f(configFile); + if (!f) { cerr << "config file '" << configFile << "' not found!"; exit(1);} + po::store(po::parse_config_file(f,optionDescription), conf); + if (conf.count("help")) { + cerr << optionDescription << endl; + exit(1); + } + po::notify(conf); + extractBool(); + f.close(); + } catch ( boost::exception_detail::clone_impl > & e) { + cerr << endl << "[error] " << e.get_option_name() << " must be set!" << endl << endl; + cerr << optionDescription << endl; + exit(1); + } catch (boost::exception_detail::clone_impl > & e) { + cerr << endl << "[error] unrecognised option '" << e.get_option_name() << "'." << endl << endl; + cerr << optionDescription << endl; + exit(1); + } +} + +void base::config::extractBool() { + map >::iterator iter; + for (iter = confMap.begin(); iter != confMap.end(); iter++) { + if (iter->second.first == BOOL) { + *(bool*)(iter->second.second) = (bool) conf.count(iter->first); + } + } +} diff --git a/src/srl/include/base/config.h b/src/srl/include/base/config.h new file mode 100644 index 000000000..3b1cf9635 --- /dev/null +++ b/src/srl/include/base/config.h @@ -0,0 +1,73 @@ +// +// Created by liu on 2016/12/19. +// + +#ifndef PROJECT_CONFIG_H +#define PROJECT_CONFIG_H + +#include +#include +#include +#include +#include +#include +using namespace std; +using boost::any_cast; + +namespace po = boost::program_options; +namespace base { + + class config { + public: + enum Type{ + INT, + UNSIGNED, + FLOAT, + STRING, + BOOL, + }; + po::variables_map conf; + map > confMap; + po::options_description optionDescription; + po::options_description_easy_init addOpt; + + public: + config(string confName = "Configuration"): + optionDescription(confName), + addOpt(optionDescription.add_options()) + { + addOpt = addOpt("help,h", "Help"); + }; + + string toString(string outerSep = "_", string innerSep = "_"); + + template + void registerConf(const char * name, base::config::Type type, T& arg, const char * comment); + template + void registerConf(const char * name, base::config::Type type, T& arg, const char * comment, T def); + + void extractBool(); + + const boost::program_options::variables_map &getConf() const; + virtual void init(int argc, char * argv[]); + virtual void init(string configFile); + }; +} + +template +void base::config::registerConf(const char * name, base::config::Type type, T& arg, const char * comment) { + confMap[name] = make_pair(type, &arg); + if (type == BOOL) { + addOpt = addOpt(name, comment); + } else { + addOpt = addOpt(name, po::value(&arg)->required(), comment); + } +} + +template +void base::config::registerConf(const char * name, base::config::Type type, T& arg, const char * comment, T def) { + confMap[name] = make_pair(type, &arg); + addOpt = addOpt(name, po::value(&arg)->default_value(def), comment); +} + +#endif //PROJECT_CONFIG_H diff --git a/src/srl/include/base/debug.cpp b/src/srl/include/base/debug.cpp new file mode 100644 index 000000000..dc76f34fe --- /dev/null +++ b/src/srl/include/base/debug.cpp @@ -0,0 +1,26 @@ +// +// Created by liu on 2016/12/19. +// + +#include "debug.h" + +base::Debug::Debug(string modelName):modelName(modelName) { + if (enabledModels.count(modelName) || enabledModels.count("*")) { + disable = false; + } +} + +void base::Debug::init(base::DebugConfig config) { + logLevel = config.logLevel; + vector enModelsVec; + boost::split(enModelsVec, config.enabledModels, boost::is_any_of(",")); + enabledModels.clear(); + for (auto i :enModelsVec) { + enabledModels.insert(i); + } +} + +int base::Debug::logLevel = (int)LogLevel::info; +char* base::Debug::tmpBuffer = new char[4096]; +set base::Debug::enabledModels; + diff --git a/src/srl/include/base/debug.h b/src/srl/include/base/debug.h new file mode 100644 index 000000000..63216064c --- /dev/null +++ b/src/srl/include/base/debug.h @@ -0,0 +1,93 @@ +// +// Created by liu on 2016/12/19. +// + +#ifndef PROJECT_DEBUG_H +#define PROJECT_DEBUG_H + +#include "stdarg.h" +#include +#include +#include +#include +#include +#include "config.h" +#include +#include +#include +using namespace std; + +namespace base { + enum LogLevel { + info = 0, debug, war, err + }; + + class DebugConfig: virtual public base::config { + public: + int logLevel; + string enabledModels; + DebugConfig(string confName = "Configuration"):base::config(confName) { + registerConf ("loglevel" , INT , logLevel , " 0 = err, war, debug, info",0); + registerConf ("debugModels" , STRING , enabledModels , "debuginfo enabled Models name list","*"); + } + }; + + class Debug { + static set enabledModels; + static int logLevel; + static char* tmpBuffer; + public: + string modelName; + bool disable = true; + + static void init(DebugConfig config); + + Debug(string modelName); + + inline void debug(string msg, ...) { + va_list ap; va_start(ap, msg); vsprintf(tmpBuffer, msg.c_str(), ap); va_end(ap); + if (!disable && logLevel <= LogLevel::debug) + printAtTime(" \x1b[;32mDEBUG\x1b[0m " + modelName + "\t \x1b[;32m" + tmpBuffer + "\x1b[0m"); + } + + inline void info(string msg, ...) { + va_list ap; va_start(ap, msg); vsprintf(tmpBuffer, msg.c_str(), ap); va_end(ap); + if (!disable && logLevel <= LogLevel::info) + printAtTime(" \x1b[;34mINFO\x1b[0m " + modelName + "\t \x1b[;34m" + tmpBuffer + "\x1b[0m"); + } + + inline void warning(string msg, ...) { + va_list ap; va_start(ap, msg); vsprintf(tmpBuffer, msg.c_str(), ap); va_end(ap); + if (!disable && logLevel <= LogLevel::war) + printAtTime(" \x1b[;33mWARNING\x1b[0m " + modelName + "\t \x1b[;33m" + tmpBuffer + "\x1b[0m"); + } + + inline void error(string msg, ...) { + va_list ap; va_start(ap, msg); vsprintf(tmpBuffer, msg.c_str(), ap); va_end(ap); + if (!disable && logLevel <= LogLevel::err) + printAtTime(" \x1b[;31mERROR\x1b[0m " + modelName + "\t \x1b[;31m" + tmpBuffer + "\x1b[0m"); + } + + inline void printAtTime(string str) { + print('[' + getTime() + ']' + str); + } + + virtual inline void print(string str) { + cout << str << endl; + } + + static inline string getTime(const char daySep = '/', const char secSep = ':') { + string formatString; + formatString += "%Y"; formatString += daySep; formatString += "%m"; formatString += daySep; + formatString += "%d-%H"; + formatString += secSep; formatString += "%M"; formatString += secSep; formatString += "%S"; + time_t t; + time(&t); + char buffer [2048]; + strftime (buffer, sizeof(buffer), formatString.c_str(), localtime(&t)); + return string(buffer); + } + }; +} + +#endif //PROJECT_DEBUG_H diff --git a/src/srl/include/base/process.h b/src/srl/include/base/process.h new file mode 100644 index 000000000..140852ace --- /dev/null +++ b/src/srl/include/base/process.h @@ -0,0 +1,28 @@ +// +// Created by liu on 2017/1/5. +// + +#ifndef PROJECT_PROCESS_H +#define PROJECT_PROCESS_H + +#include "config.h" +namespace base { + template + class Process { + public: + ConfigClass & config; + int returnNum = 0; + + Process(ConfigClass &config): config(config) {} + + virtual void main() = 0; + + static ConfigClass createConfig() { + return ConfigClass(); + } + }; +} + + + +#endif //PROJECT_PROCESS_H diff --git a/src/srl/include/base/processLoader.h b/src/srl/include/base/processLoader.h new file mode 100644 index 000000000..6cdf8f06b --- /dev/null +++ b/src/srl/include/base/processLoader.h @@ -0,0 +1,38 @@ +// +// Created by liu on 2017/1/5. +// + +#ifndef PROJECT_PROCESSLOADER_H +#define PROJECT_PROCESSLOADER_H + +#include "config.h" +#include "debug.h" + +namespace base{ + class ProcessLoader { + int argc; + char ** argv; + Debug * debug; + + public: + ProcessLoader(int argc, char * argv[]):argc(argc), argv(argv) { } + + template + int runProcess() { + auto c = RunClass::createConfig(); + c.init(argc, argv); + + base::Debug::init(c); + debug = new base::Debug("main"); + debug->debug(c.toString("\n", " -> ")); + + RunClass processRunner(c); + processRunner.main(); + return processRunner.returnNum; + } + }; +} + + + +#endif //PROJECT_PROCESSLOADER_H diff --git a/src/srl/include/base/progressBar.h b/src/srl/include/base/progressBar.h new file mode 100644 index 000000000..d40ede354 --- /dev/null +++ b/src/srl/include/base/progressBar.h @@ -0,0 +1,47 @@ +// +// Created by liu on 2017/1/3. +// + +#ifndef PROJECT_PROGRESSBAR_H +#define PROJECT_PROGRESSBAR_H + +#include +#include "iostream" +#include "string" +using namespace std; + +namespace base { + class ProgressBar { + public: + int total; + int currentLength = 0; + double duration; + clock_t start; + ProgressBar(int total, float duration = 1): + total(total), duration(duration) { + start = clock(); + } + + inline bool updateLength(int length) { + currentLength = length; + clock_t now = clock(); + if (double(now - start)/CLOCKS_PER_SEC > duration) { + start = now; + return true; + } + return false; + } + + inline string getProgress(int length) { + char tmpBuffer[20]; + sprintf(tmpBuffer, "%.2lf%%", 100.0 * length / total); + return string(tmpBuffer); + } + + inline string getProgress() { + return getProgress(currentLength); + } + }; +} + +#endif //PROJECT_PROGRESSBAR_H diff --git a/src/srl/include/base/timer.h b/src/srl/include/base/timer.h new file mode 100644 index 000000000..84305e622 --- /dev/null +++ b/src/srl/include/base/timer.h @@ -0,0 +1,58 @@ +// +// Created by liu on 2017/1/4. +// + +#ifndef PROJECT_TIMER_H +#define PROJECT_TIMER_H + +#include +#include +#include "string" +#include "iostream" +using namespace std; + +namespace base { + class Timer { + chrono::time_point startTime, endTime; + public: + Timer(): startTime(chrono::high_resolution_clock::now()) { } + Timer & start() { + startTime = chrono::high_resolution_clock::now(); + return *this; + } + + void pause() { + throw "not implement yet."; + } + void resume() { + throw "not implement yet."; + } + + string end() { + endTime = chrono::high_resolution_clock::now(); + return getDuration(); + } + + string getDuration() { + long long int durationTime = chrono::duration_cast(endTime - startTime).count(); + char buf[50]; + if (durationTime < 1000) { + sprintf(buf, "%lld us", durationTime); + } else if (durationTime < 1000l * 1000) { + sprintf(buf, "%.2lf ms", durationTime/1000.0); + } else if (durationTime < 1000l * 1000 * 1000) { + sprintf(buf, "%.2lf s", durationTime/1000.0/1000.0); + } else if (durationTime < 1000l * 1000 * 1000 * 60) { + sprintf(buf, "%.2lf min", durationTime/1000.0/1000.0/60.0); + } else { + sprintf(buf, "%.2lf h", durationTime/1000.0/1000.0/60.0/60.0); + } + return buf; + } + + static string getClassName() { return "Timer"; } + + }; +} + +#endif //PROJECT_TIMER_H diff --git a/src/srl/include/extractor/AbstractConverter.h b/src/srl/include/extractor/AbstractConverter.h new file mode 100644 index 000000000..86b2f77a3 --- /dev/null +++ b/src/srl/include/extractor/AbstractConverter.h @@ -0,0 +1,25 @@ +// +// Created by liu on 2017/1/3. +// + +#ifndef PROJECT_ABSTRUCTCONVERTER_H +#define PROJECT_ABSTRUCTCONVERTER_H + +#include "string" +using namespace std; + +namespace extractor { + template + class AbstractConverter{ + virtual void init(T1 & origin_data_ref) = 0; + virtual void run() = 0; + virtual T2 & getResult() = 0; + virtual void clear() {}; + + static string getClassName() { + return "Converter<" + T1::getClassName() + ", " + T2::getClassName() + ">"; + } + }; +} + +#endif //PROJECT_ABSTRUCTCONVERTER_H diff --git a/src/srl/include/extractor/AbstractExtractor.h b/src/srl/include/extractor/AbstractExtractor.h new file mode 100644 index 000000000..1541def5f --- /dev/null +++ b/src/srl/include/extractor/AbstractExtractor.h @@ -0,0 +1,25 @@ +// +// Created by liu on 2017/1/4. +// + +#ifndef PROJECT_ABSTRACTEXTRACTOR_H +#define PROJECT_ABSTRACTEXTRACTOR_H + +#include "string" +using namespace std; + +namespace extractor { + template + class AbstractExtractor { + + virtual void init(StartClass & start) = 0; + + virtual EndClass run() = 0; + + static string getClassName() { + return "AbstractExtractor"; + } + }; +} + +#endif //PROJECT_ABSTRACTEXTRACTOR_H diff --git a/src/srl/include/extractor/BiConverter.h b/src/srl/include/extractor/BiConverter.h new file mode 100644 index 000000000..cbd363989 --- /dev/null +++ b/src/srl/include/extractor/BiConverter.h @@ -0,0 +1,50 @@ +// +// Created by liu on 2017/1/7. +// + +#ifndef PROJECT_BICONVERTER_H +#define PROJECT_BICONVERTER_H + +#include "Converter.h" +namespace extractor { + template + class BiConverter : public Converter { + public: + base::Debug debug; + BiConverter(): debug("BiConverter") {}; + + virtual void iconv(vector * t2dataPtr = NULL) { + vector& d2 = (t2dataPtr == NULL) ? this->data : (*t2dataPtr); + for (int j = 0; j < d2.size(); ++j) { + iconvOne((*(this->origin_data_ref))[d2[j].upDataIndex], d2[j], d2[j].upDataInnerIndex ); + } + }; + + virtual void run() { + unsigned num = this->origin_data_ref->size(); + debug.debug("Convert '%s' to '%s' start. total %u %s items", T1::getClassName().c_str(), T2::getClassName().c_str(), num, T1::getClassName().c_str()); + base::ProgressBar bar(num); + for (unsigned i = 0; i < num; i++) { + unsigned startIndex = this->data.size(); + this->convert((*(this->origin_data_ref))[i]); + unsigned endSize = this->data.size(); + injectUpDataIndex(startIndex, endSize, i); + if (bar.updateLength(i + 1)) + debug.info("(%d)%s is converted %d data generate.", i + 1, bar.getProgress(i + 1).c_str(), this->data.size()); + } + debug.debug("Convert '%s' to '%s' finish. generate %u %s items", T1::getClassName().c_str(), T2::getClassName().c_str(), this->data.size(), T2::getClassName().c_str()); + } + + virtual void iconvOne(T1 &t1, T2 &t2, int innerIndex) = 0; + + private: + void injectUpDataIndex(unsigned startIndex, unsigned endSize, unsigned upIndex) { + for (int i = startIndex, ii = 0; i < endSize; i++, ii++) { + this->data[i].upDataIndex = upIndex; + this->data[i].upDataInnerIndex = ii; + } + } + }; +} + +#endif //PROJECT_BICONVERTER_H diff --git a/src/srl/include/extractor/Converter.h b/src/srl/include/extractor/Converter.h new file mode 100644 index 000000000..2e4e5a218 --- /dev/null +++ b/src/srl/include/extractor/Converter.h @@ -0,0 +1,60 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_CONVERTER_H +#define PROJECT_CONVERTER_H + +#include "AbstractConverter.h" +#include "vector" +#include "../base/debug.h" +#include "../base/progressBar.h" +using namespace std; + +namespace extractor{ + template + class Converter : public AbstractConverter, vector>{ + public: + vector * origin_data_ref; + vector data; + base::Debug debug; + Converter(): debug("Converter") {}; + virtual void init(vector & origin_data) { + origin_data_ref = & origin_data; + } + + virtual void run() { + unsigned num = origin_data_ref->size(); + debug.debug("Convert '%s' to '%s' start. total %u %s items", T1::getClassName().c_str(), T2::getClassName().c_str(), num, T1::getClassName().c_str()); + base::ProgressBar bar(num); + beforeConvert(); + for (unsigned i = 0; i < num; i++) { + convert((*origin_data_ref)[i]); + if (bar.updateLength(i + 1)) + debug.info("(%d)%s is converted %d data generate.", i + 1, bar.getProgress(i + 1).c_str(), data.size()); + } + afterConvert(); + debug.debug("Convert '%s' to '%s' finish. generate %u %s items", T1::getClassName().c_str(), T2::getClassName().c_str(), data.size(), T2::getClassName().c_str()); + } + + virtual void beforeConvert() {} // 开始转换之前 + virtual void convert(T1 &) = 0; + virtual void afterConvert() {} // 结束之后 + + virtual void insert(T2 item) { + data.push_back(item); + }; + virtual vector & getResult() { + return data; + }; + virtual string getClassName() { + return "Converter<" + T1::getClassName() + ", " + T2::getClassName() + ">"; + } + + virtual void clear() { + data.clear(); + } + }; +} + +#endif //PROJECT_CONVERTER_H diff --git a/src/srl/include/extractor/ConverterBlockToConcept.h b/src/srl/include/extractor/ConverterBlockToConcept.h new file mode 100644 index 000000000..595050441 --- /dev/null +++ b/src/srl/include/extractor/ConverterBlockToConcept.h @@ -0,0 +1,28 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_CONVERTERBLOCKTOCONCEPT_H +#define PROJECT_CONVERTERBLOCKTOCONCEPT_H + +#include "BiConverter.h" +#include "../structure/DataFileBlockContext.h" +#include "../structure/DataConcept.h" +#include "../base/debug.h" + + +namespace extractor { + template + class ConverterBlockToConcept: public BiConverter { + public: + base::Debug debug; + ConverterBlockToConcept():debug("ConverterBlockToConcept") {} + + virtual void convert(T1 & fileBlock) { + debug.debug("testing ConverterBlockToConcept Class - convert foo."); + } + }; +} + + +#endif //PROJECT_CONVERTERBLOCKTOCONCEPT_H diff --git a/src/srl/include/extractor/ConverterConceptToSample.h b/src/srl/include/extractor/ConverterConceptToSample.h new file mode 100644 index 000000000..5b063213d --- /dev/null +++ b/src/srl/include/extractor/ConverterConceptToSample.h @@ -0,0 +1,27 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_CONVERTERCONCEPTTOSAMPLE_H +#define PROJECT_CONVERTERCONCEPTTOSAMPLE_H + +#include "../base/debug.h" +#include "BiConverter.h" +#include "../structure/DataSample.h" +#include "../structure/DataConcept.h" +namespace extractor { + template + class ConverterConceptToSample : public BiConverter { + public: + base::Debug debug; + ConverterConceptToSample():debug("ConverterConceptToSample") {} + + // 由子类实现 virtual void convert(T1 &) = 0; + // virtual void convert(T1 &) { + // debug.debug("testing ConverterConceptToSample Class - convert foo."); + // debug.error("this is not finished yet."); + // } + }; +} + +#endif //PROJECT_CONVERTERCONCEPTTOSAMPLE_H diff --git a/src/srl/include/extractor/ConverterFileReader.h b/src/srl/include/extractor/ConverterFileReader.h new file mode 100644 index 000000000..c21647f04 --- /dev/null +++ b/src/srl/include/extractor/ConverterFileReader.h @@ -0,0 +1,56 @@ +// +// Created by liu on 2017/1/1. +// + +#ifndef PROJECT_FILEREADER_H +#define PROJECT_FILEREADER_H + +#include "../base/debug.h" +#include +#include "Converter.h" +#include "../structure/DataFileName.h" +#include "../structure/DataFileContext.h" +#include "fstream" +using namespace std; +namespace extractor { +/** + * 此类是一个接口类,用来定义文件到字符串数组的转换 + * 例1:每行分割无关,行内按照某些字符有特殊含义 + * 例2:每个空行分割无关,行内 + */ + + class ConverterFileReader : public Converter { + public: + base::Debug debug; + + ConverterFileReader() : debug("ConverterFileReader") {}; + + virtual void convert(DataFileName & dataFileName) { + string fileName = dataFileName.fileName; + debug.debug("reading file '%s'", fileName.c_str()); + ifstream in(fileName); + if (!in) { + debug.error("reading file '%s' failed! ", fileName.c_str()); + exit(1); + } + string line; + int lineCounter = 0, blockCounter = 0; + while (getline(in, line)) { + if (!(++lineCounter % 10000)) debug.info("%d lines read", lineCounter); + readLine(line); + } + debug.info("read %d lines and get %d blocks", lineCounter, blockCounter); + debug.debug("finish reading file '%s'", fileName.c_str()); + }; + + virtual void readLine(string& line) { + vector lineFeatures; + split(lineFeatures, line, boost::is_any_of(" \t")); + insert(DataFileContext(lineFeatures)); + } + + + }; +} + +#endif //PROJECT_FILEREADER_H diff --git a/src/srl/include/extractor/ConverterMultiLineFileReader.h b/src/srl/include/extractor/ConverterMultiLineFileReader.h new file mode 100644 index 000000000..11ae9b529 --- /dev/null +++ b/src/srl/include/extractor/ConverterMultiLineFileReader.h @@ -0,0 +1,91 @@ +// +// Created by liu on 2017/1/1. +// + +#ifndef PROJECT_MULTILINEFILEREADER_H +#define PROJECT_MULTILINEFILEREADER_H + + +#include "Converter.h" +#include "../structure/DataFileName.h" +#include "../structure/DataFileBlockContext.h" +#include "../base/debug.h" +#include +#include +#include "iostream" +#include "string" +#include "fstream" +using namespace std; +using namespace boost; + +namespace extractor { + class ConverterMultiLineFileReader : public Converter { + public: + base::Debug debug; + + explicit ConverterMultiLineFileReader() : debug("MultiLineFileReader") {}; + + virtual void convert(DataFileName & dataFileName) { + string fileName = dataFileName.fileName; + debug.debug("reading file '%s'", fileName.c_str()); + ifstream in(fileName); + string line; + int lineCounter = 0, blockCounter = 0; + unsigned blockLength = 0; + while (getline(in, line)) { + if (!(++lineCounter % 10000)) debug.info("%d lines read", lineCounter); + if (line.empty()) { + if (!(++blockCounter % 1000)) debug.info("%d blocks generate", blockCounter); + handleMultiLine(); + blockLength = 0; + continue; + } + readLine(line); + if (blockLength) { +// if (blockLength != fileBlock.getLast().size()) { +// debug.error("file format error."); exit(0); +// } + } else { + blockLength = fileBlock.getLast().size(); + } + } + if (fileBlock.data.size() != 0) { + handleMultiLine(); + } + debug.info("read %d lines and get %d blocks", lineCounter, blockCounter); + debug.debug("finish reading file '%s'", fileName.c_str()); + }; + + virtual void reWriteFile(string fileName) { + debug.debug("extract data to '%s'", fileName.c_str()); + ofstream out(fileName); + for (int j = 0; j < data.size(); ++j) { + for (int k = 0; k < data[j].data.size(); ++k) { + for (int l = 0; l < data[j].data[k].size(); ++l) { + out << data[j].data[k][l]; + if (l != data[j].data[k].size() - 1) out << "\t"; + } + out << endl; + } + out << endl; + } + out.close(); + } + + protected: + DataFileBlockContext fileBlock; + + virtual void readLine(string &line) { + vector lineFeatures; + split(lineFeatures, line, is_any_of(" \t\n")); + fileBlock.push_back(lineFeatures); + } + + virtual void handleMultiLine() { + insert(fileBlock); + fileBlock.clear(); + } + }; +} + +#endif //PROJECT_MULTILINEFILEREADER_H diff --git a/src/srl/include/extractor/Extractor.h b/src/srl/include/extractor/Extractor.h new file mode 100644 index 000000000..b2f535123 --- /dev/null +++ b/src/srl/include/extractor/Extractor.h @@ -0,0 +1,31 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_ERACTOR_H +#define PROJECT_ERACTOR_H + +#include "AbstractExtractor.h" + +#include "vector" +using namespace std; + +namespace extractor { + template + class Extractor : public AbstractExtractor, vector>{ + public: + vector * startPtr; + + virtual void init(vector& start) { + startPtr = &start; + }; + + virtual vector run() = 0; + + static string getClassName() { + return "Extractor<" + StartClass::getClassName() + ", " + EndClass::getClassName() + ">"; + } + }; +} + +#endif //PROJECT_ERACTOR_H diff --git a/src/srl/include/extractor/ExtractorFileToSample.cpp b/src/srl/include/extractor/ExtractorFileToSample.cpp new file mode 100644 index 000000000..e0324b7da --- /dev/null +++ b/src/srl/include/extractor/ExtractorFileToSample.cpp @@ -0,0 +1,5 @@ +// +// Created by liu on 2017/1/2. +// + +#include "ExtractorFileToSample.h" diff --git a/src/srl/include/extractor/ExtractorFileToSample.h b/src/srl/include/extractor/ExtractorFileToSample.h new file mode 100644 index 000000000..5ce561061 --- /dev/null +++ b/src/srl/include/extractor/ExtractorFileToSample.h @@ -0,0 +1,30 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_ETRACTORFILETOSAMPLE_H +#define PROJECT_ETRACTORFILETOSAMPLE_H + +#include "Extractor.h" +#include "../structure/DataFileName.h" +namespace extractor { + template + class ExtractorFileToSample : public Extractor { + public: + virtual vector run() { +// Converter1Class con1; +// Converter2Class con2; +// Converter3Class con3; +// con1.init(*(this->startPtr)); +// con1.run(); +// con2.init(con1.getResult()); +// con2.run(); +// con3.init(con2.getResult()); +// con3.run(); +// return con3.getResult(); + return vector(); + } + }; +} + +#endif //PROJECT_ETRACTORFILETOSAMPLE_H diff --git a/src/srl/include/model/LoopCounter.h b/src/srl/include/model/LoopCounter.h new file mode 100644 index 000000000..8c7d8cfb7 --- /dev/null +++ b/src/srl/include/model/LoopCounter.h @@ -0,0 +1,34 @@ +// +// Created by liu on 2017/1/5. +// + +#ifndef PROJECT_LOOPCOUNTER_H +#define PROJECT_LOOPCOUNTER_H + +namespace model { + class LoopCounter { + unsigned counter = 0; + public: + unsigned size; + LoopCounter(unsigned size): size(0) {} + + /** + * +=1 + * @return if overflow + */ + inline bool update() { + counter += 1; + if (counter == size) { + counter = 0; + return true; + } + return false; + } + + inline unsigned getCounter() { + return counter; + } + }; +} + +#endif //PROJECT_LOOPCOUNTER_H diff --git a/src/srl/include/model/Model.h b/src/srl/include/model/Model.h new file mode 100644 index 000000000..c91659d26 --- /dev/null +++ b/src/srl/include/model/Model.h @@ -0,0 +1,21 @@ +// +// Created by liu on 2017/1/4. +// + +#ifndef PROJECT_MODEL_H +#define PROJECT_MODEL_H + +#include "../base/debug.h" +#include "string" +using namespace std; + +namespace model { + class Model { + static string getClassName() { return "Model"; } + virtual void init() = 0; + virtual void save() = 0; + virtual bool load() = 0; + }; +} + +#endif //PROJECT_MODEL_H diff --git a/src/srl/include/model/RandomOrderMap.h b/src/srl/include/model/RandomOrderMap.h new file mode 100644 index 000000000..af1318ee9 --- /dev/null +++ b/src/srl/include/model/RandomOrderMap.h @@ -0,0 +1,46 @@ +// +// Created by liu on 2017/1/5. +// + +#ifndef PROJECT_RANDOMORDERMAP_H +#define PROJECT_RANDOMORDERMAP_H + +#include "algorithm" +#include "../base/debug.h" +#include "vector" +using namespace std; +namespace model { + class RandomOrderMap { + vector order; + unsigned size; + base::Debug debug; + public: + RandomOrderMap(unsigned size): order(size), size(size), debug("RandomOrderMap"){ + for (int j = 0; j < size; ++j) { + order[j] = j; + } + shuffle(); + } + + inline unsigned operator[](unsigned index) { + return order[index]; + } + + void shuffle() { + debug.debug("**SHUFFLE"); + random_shuffle(order.begin(), order.end()); + } + + inline unsigned operator++(int) { + static unsigned innerCounter = 0; + if (innerCounter >= size) { + innerCounter = 0; + shuffle(); + } + return operator[](innerCounter++); + } + + }; +} + +#endif //PROJECT_RANDOMORDERMAP_H diff --git a/src/srl/include/process/AbstractPredictor.h b/src/srl/include/process/AbstractPredictor.h new file mode 100644 index 000000000..62a6bc834 --- /dev/null +++ b/src/srl/include/process/AbstractPredictor.h @@ -0,0 +1,28 @@ +// +// Created by liu on 2017/1/7. +// + +#ifndef PROJECT_ABSTRACTPREDICTOR_H +#define PROJECT_ABSTRACTPREDICTOR_H + +#include "../base/process.h" +namespace model { + template + class AbstractPredictor : public base::Process{ + public: + AbstractPredictor(TestConfigClass &config) : base::Process(config) {} + + virtual void main() { + init(); + predict(); + extractResult(); + } + virtual void init() = 0; + virtual void predict() = 0; + virtual void extractResult() = 0; + + }; +} + + +#endif //PROJECT_ABSTRACTPREDICTOR_H diff --git a/src/srl/include/process/AbstractTrainer.h b/src/srl/include/process/AbstractTrainer.h new file mode 100644 index 000000000..659dc3cd4 --- /dev/null +++ b/src/srl/include/process/AbstractTrainer.h @@ -0,0 +1,27 @@ +// +// Created by liu on 2017/1/5. +// + +#ifndef PROJECT_ABSTRACTTRAINER_H +#define PROJECT_ABSTRACTTRAINER_H + +#include "../base/process.h" +namespace model { + template + class AbstractTrainer : public base::Process { + public: + AbstractTrainer(TrainConfigClass & config):base::Process(config) {} + + virtual void main() { + this->init(); + this->train(); + } + + virtual void train() = 0; + virtual void init() {}; + }; +} + + + +#endif //PROJECT_ABSTRACTTRAINER_H diff --git a/src/srl/include/process/ConditionStopper.h b/src/srl/include/process/ConditionStopper.h new file mode 100644 index 000000000..2d66d4c78 --- /dev/null +++ b/src/srl/include/process/ConditionStopper.h @@ -0,0 +1,55 @@ +// +// Created by liu on 2017/5/11. +// + +#ifndef PROJECT_CONDITIONSTOPPER_H +#define PROJECT_CONDITIONSTOPPER_H + +#include "../base/debug.h" + +namespace process { + class ConditionStopper { + private: + double fast_iter, slow_iter, min_epoth_iter, train_dev_gap, no_train_update_zero, no_save_turn; + int min_batches_iter; + double fast_f = 0, slow_f = 0; + base::Debug debug; + public: + ConditionStopper(double fast_iter = 0.3, + double slow_iter = 0.1, + double min_epoth_iter = 2.0, + double train_dev_gap = 0.05, + double no_train_update_zero = 0.02, + double no_save_turn = 20, + int min_batches_iter = 300) : + fast_iter(fast_iter), + slow_iter(slow_iter), + min_epoth_iter(min_epoth_iter), + train_dev_gap(train_dev_gap), + no_train_update_zero(no_train_update_zero), + no_save_turn(no_save_turn), + min_batches_iter(min_batches_iter), + debug(ConditionStopper::getClassName()) + { } + + virtual bool auto_end(Performance & trainPerf, Performance & bestDevPerf, int batches, double epoch, int lastSaveTurn) { + fast_f = fast_iter * trainPerf.fscore() + (1 - fast_iter) * fast_f; + slow_f = slow_iter * trainPerf.fscore() + (1 - slow_iter) * slow_f; + if (fast_f != fast_f) fast_f = 0.0; // test nan + if (slow_f != slow_f) slow_f = 0.0; + + return batches > min_batches_iter && + epoch > min_epoth_iter && + lastSaveTurn > no_save_turn && + (slow_f > 0.99 || slow_f - bestDevPerf.fscore() > train_dev_gap) && + fast_f - slow_f < no_train_update_zero; + } + + static string getClassName() { + return "ConditionStopper"; + } + + }; +} + +#endif //PROJECT_CONDITIONSTOPPER_H diff --git a/src/srl/include/process/ModelPredictor.h b/src/srl/include/process/ModelPredictor.h new file mode 100644 index 000000000..03de2f5f7 --- /dev/null +++ b/src/srl/include/process/ModelPredictor.h @@ -0,0 +1,32 @@ +// +// Created by liu on 2017/1/4. +// + +#ifndef PROJECT_MODELPREDICTOR_H +#define PROJECT_MODELPREDICTOR_H + +#include "process/AbstractPredictor.h" +namespace model { + template + class ModelPredictor : public AbstractPredictor{ + public: + ModelPredictor(TestConfigClass &config) : AbstractPredictor(config) {} + + virtual void init() { + + } + + virtual void predict() { + + } + + virtual void extractResult() { + + } + + }; +} + + + +#endif //PROJECT_MODELPREDICTOR_H diff --git a/src/srl/include/process/ModelTester.h b/src/srl/include/process/ModelTester.h new file mode 100644 index 000000000..68eac5e54 --- /dev/null +++ b/src/srl/include/process/ModelTester.h @@ -0,0 +1,31 @@ +// +// Created by liu on 2017/1/10. +// + +#ifndef PROJECT_MODELTESTER_H +#define PROJECT_MODELTESTER_H + +#include "AbstractPredictor.h" + +namespace model { + template + class ModelTester : public AbstractPredictor { + public: + ModelTester(TestConfigClass &config) : AbstractPredictor(config) {} + + virtual void init() { + + } + + virtual void predict() { + + } + + virtual void extractResult() { + + } + }; + +} + +#endif //PROJECT_MODELTESTER_H diff --git a/src/srl/include/process/ModelTrainer.h b/src/srl/include/process/ModelTrainer.h new file mode 100644 index 000000000..bdaeb299f --- /dev/null +++ b/src/srl/include/process/ModelTrainer.h @@ -0,0 +1,29 @@ +// +// Created by liu on 2017/1/4. +// + +#ifndef PROJECT_MODELTRAINER_H +#define PROJECT_MODELTRAINER_H + +#include "../model/Model.h" +#include "AbstractTrainer.h" + +namespace model { + template + class ModelTrainer : public AbstractTrainer { + public: + ModelTrainer(TrainConfigClass & config):AbstractTrainer(config) {} + virtual void train() { + + }; + + virtual bool checkDev() { + return false; + } + + }; +} + + + +#endif //PROJECT_MODELTRAINER_H diff --git a/src/srl/include/structure/Data.h b/src/srl/include/structure/Data.h new file mode 100644 index 000000000..bbc634203 --- /dev/null +++ b/src/srl/include/structure/Data.h @@ -0,0 +1,21 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_CORPUSDATA_H +#define PROJECT_CORPUSDATA_H + +#include "string" +using namespace std; + +namespace extractor { + class Data { + public: + int upDataIndex = 0; + int upDataInnerIndex = 0; + static string getClassName() { return "Data"; } + virtual void clear() {}; + }; +} + +#endif //PROJECT_CORPUSDATA_H diff --git a/src/srl/include/structure/DataConcept.h b/src/srl/include/structure/DataConcept.h new file mode 100644 index 000000000..d34e86485 --- /dev/null +++ b/src/srl/include/structure/DataConcept.h @@ -0,0 +1,18 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_DATACONCEPT_H +#define PROJECT_DATACONCEPT_H + +#include "Data.h" + +namespace extractor { + class DataConcept: public Data { + public: + static string getClassName() { return "DataConcept"; } + + }; +} + +#endif //PROJECT_DATACONCEPT_H diff --git a/src/srl/include/structure/DataFileBlockContext.h b/src/srl/include/structure/DataFileBlockContext.h new file mode 100644 index 000000000..061b30e43 --- /dev/null +++ b/src/srl/include/structure/DataFileBlockContext.h @@ -0,0 +1,35 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_DATAFILEBLOCKCONTEXT_H +#define PROJECT_DATAFILEBLOCKCONTEXT_H + +#include "vector" +#include "string" +#include "iostream" +#include "Data.h" +using namespace std; +namespace extractor { + class DataFileBlockContext : public Data { + public: + static string getClassName() { return "DataFileBlockContext"; } + vector > data; + /** + * overwrite + * @return + */ + void push_back(vector &block) { + data.push_back(block); + } + void clear() { + data.clear(); + } + vector & getLast() { + return data[data.size() - 1]; + } + + }; +} + +#endif //PROJECT_DATAFILEBLOCKCONTEXT_H diff --git a/src/srl/include/structure/DataFileContext.h b/src/srl/include/structure/DataFileContext.h new file mode 100644 index 000000000..b6c1143fe --- /dev/null +++ b/src/srl/include/structure/DataFileContext.h @@ -0,0 +1,23 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_DATAFILECONTEXT_H +#define PROJECT_DATAFILECONTEXT_H + +#include "vector" +#include "string" +#include "iostream" +#include "Data.h" +using namespace std; +namespace extractor { + class DataFileContext : public Data { + public: + static string getClassName() { return "DataFileContext"; } + vector data; + DataFileContext() {}; + DataFileContext(vector& data): data(data) {} + }; +} + +#endif //PROJECT_DATAFILECONTEXT_H diff --git a/src/srl/include/structure/DataFileName.h b/src/srl/include/structure/DataFileName.h new file mode 100644 index 000000000..9ec7c8471 --- /dev/null +++ b/src/srl/include/structure/DataFileName.h @@ -0,0 +1,24 @@ +// +// Created by liu on 2017/1/2. +// + +#ifndef PROJECT_DATAFILENAME_H +#define PROJECT_DATAFILENAME_H + +#include "string" +#include "iostream" +#include "Data.h" +using namespace std; +namespace extractor { + class DataFileName: public Data { + public: + static string getClassName() { return "DataFileName"; } + string fileName; + DataFileName() {}; + + DataFileName(const string &fileNameString) { + fileName = fileNameString; + }; + }; +} +#endif //PROJECT_DATAFILENAME_H diff --git a/src/srl/include/structure/Performance.h b/src/srl/include/structure/Performance.h new file mode 100644 index 000000000..49cad761d --- /dev/null +++ b/src/srl/include/structure/Performance.h @@ -0,0 +1,42 @@ +// +// Created by liu on 2017/1/5. +// + +#ifndef PROJECT_PERFORMANCE_H +#define PROJECT_PERFORMANCE_H + + +struct Performance { + double tp = 0; + double n_arg = 0; + double n_parg = 0; + + inline double precision() { + if (n_parg == 0) return 0.0; + return tp / n_parg; + } + inline double recall() { + if (n_arg == 0) return 0.0; + return tp / n_arg; + } + inline double fscore() { + if (n_arg == 0 || n_parg == 0) return 0; + return 2 * precision() * recall() / (precision() + recall()); + } + string toString() { + char buf[64]; + sprintf(buf, " P:%.3lf(%.0lf/%.0lf) R:%.3lf(%.0lf/%.0lf) F:%.3lf", + precision(), tp , n_parg, + recall(), tp , n_arg, + fscore()); + return string(buf); + } +}; + +/* + * perf.precision = perf.tp / perf.n_parg; + * perf.recall = perf.tp / perf.n_arg; + * perf.fscore = 2 * perf.precision * perf.recall / (perf.precision + perf.recall); + */ + +#endif //PROJECT_PERFORMANCE_H diff --git a/src/srl/include/structure/Prediction.h b/src/srl/include/structure/Prediction.h new file mode 100644 index 000000000..dece9466e --- /dev/null +++ b/src/srl/include/structure/Prediction.h @@ -0,0 +1,13 @@ +// +// Created by liu on 2017/1/6. +// + +#ifndef PROJECT_PREDICTION_H +#define PROJECT_PREDICTION_H + +#include "utility" +using namespace std; + +typedef vector> Prediction; + +#endif //PROJECT_PREDICTION_H