/**
* @file RegPreRandomForests.h
* @brief Combination of a regression method with a pre-clustering using a random forest
* @author Sven Sickert
* @date 07/12/2013
*/
#ifndef REGPRERANDOMFORESTSINCLUDE
#define REGPRERANDOMFORESTSINCLUDE

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

#include <map>

#include "vislearning/regression/regressionbase/RegressionAlgorithm.h"
#include "vislearning/regression/randomforest/RegRandomForests.h"

namespace OBJREC{

/** Combination of a regression method with a pre-clustering using a random forest */
class RegPreRandomForests : public RegressionAlgorithm
{
  protected:
    /** the regression prototype used to process
        all examples in a leaf */
    RegressionAlgorithm *leafRegressionPrototype;
    
    /** regression of each leaf */
    std::map<RegressionNode *, RegressionAlgorithm *> leafRegressions;
    
    /** the random forest used to pre-cluster the features */
    RegRandomForests *randomforest;
    
    /** maximum number of Examples in a leaf */
    int mEx;
    
  public:
    /** simple constructor */
    RegPreRandomForests( const NICE::Config *conf,
          const std::string & section,
          RegressionAlgorithm * _leafRegressionPrototype );
   
   /** simple destructor */
   virtual ~ RegPreRandomForests();
   
   /** learn parameters/models/whatever using a set of vectors and
    *  their corresponding function values
    */
   void teach ( const NICE::VVector & X, const NICE::Vector & y );
   
   /** predict the function value for \c x */
   double predict ( const NICE::Vector & x );
   
   void clear();
   void store ( std::ostream & os, int format = 0 ) const;
   void restore ( std::istream & is, int format = 0 );

};

} // namespace

#endif