/**
* @file RTBLinear.h
* @brief random regression tree, which learns a LSE-model in every inner node during training
* @author Frank Prüfer
* @date 09/17/2013

*/
#ifndef RTBLINEARINCLUDE
#define RTBLINEARINCLUDE

#include <vector>

#include "core/vector/VectorT.h"
#include "core/vector/VVector.h"

#include "core/basics/Config.h"
#include "RegressionTreeBuilder.h"


namespace OBJREC {

/** random regression tree */
class RTBLinear : public RegressionTreeBuilder
{
  
  protected:
    int random_split_tests;
    int random_features;
    int max_depth;
    int min_examples;
    double minimum_error_reduction;
    
    int random_split_mode;
    
    /** save indices in leaves */
    bool save_indices;

    enum {
      RANDOM_SPLIT_INDEX = 0,
      RANDOM_SPLIT_UNIFORM
    };
    
    RegressionNode *buildRecursive ( const NICE::VVector & x,
          const NICE::Vector & y,
          std::vector<int> & selection,
          int depth);

    void computeLinearLSError ( const NICE::VVector & x,
                                const NICE::Vector & y,
                                const int & numEx,
                                double & lsError);

    bool errorReductionLeftRight ( const std::vector< std::pair< double, int > > values,
          const NICE::Vector & y,
          double threshold,
          double & error_left,
          double & error_right,
          int & count_left,
          int & count_right );

  public:
    
    /** simple constructor */
    RTBLinear( const NICE::Config *conf, std::string section = "RTBLinear" );
    
    /** simple destructor */
    virtual ~RTBLinear();
    
    RegressionNode *build ( const NICE::VVector & x,
          const NICE::Vector & y );
    
};
  
  
} // namespace

#endif 
