/**
* @file FPCBoosting.h
* @brief implementation of boosting algorithms
* @author Erik Rodner
* @date 04/24/2008

*/
#ifndef FPCBoostingINCLUDE
#define FPCBoostingINCLUDE

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

#include "core/basics/Config.h"
#include "vislearning/classifier/classifierbase/FeaturePoolClassifier.h"
#include "vislearning/cbaselib/FeaturePool.h"
#include "core/basics/triplet.h"

namespace OBJREC
{

/** @brief a strong classifier is a collection of weighted classifiers: \f$a \cdot h_t(\mathbf{x}) + b\f$ */
class StrongClassifier : public std::vector< NICE::triplet<double, double, FeaturePoolClassifier *> >
  {};

/** @brief implementation of boosting algorithms */
class FPCBoosting : public FeaturePoolClassifier
{
  protected:
    const NICE::Config *conf;

    /** @brief normalize weights for each class independently */
    bool classwise_normalization;

    /** @brief boosting method ( select one value from the enum-type ) */
    int boosting_method;

    /** @brief class no corresponding to the positive class */
    int positive_class;

    /** @brief maximum number of rounds */
    int maxRounds;

    /** @brief memory efficiency by caching and storing of features on the hard disc */
    bool memory_efficient;

    /** @brief prototype of a weak classifier

        The generation of a new weak classifier is done by the clone method
        of this object.
    */
    FeaturePoolClassifier *weakClassifier;

    /** @brief final strong classifier */
    StrongClassifier strongClassifier;

    /** @brief perform boosting and build strongClassifier
        @param featureStorage pre calculated features
        @param fp pool of features
        @param examples training examples */
    void boosting ( const FeatureStorage & featureStorage,
                    FeaturePool & fp,
                    Examples & examples );

    /** @brief normalize weights of examples
        @param examples training examples
    */
    void normalizeWeights ( Examples & examples ) const;

  public:

    enum
    {
      BOOSTINGMETHOD_ADABOOST = 0,
      BOOSTINGMETHOD_REAL_ADABOOST,
      BOOSTINGMETHOD_GENTLEBOOST
    };

    /** @brief for cloning only */
    FPCBoosting() {};

    /** @brief constructor for training */
    FPCBoosting ( const NICE::Config *conf,
                  // refactor-nice.pl: check this substitution
                  // old: string section = "Boost" );
                  std::string section = "Boost" );

    /** @brief simple destructor */
    virtual ~FPCBoosting();

    /** @brief classify an unseen example */
    ClassificationResult classify ( Example & pce );

    /** @brief train this classifier
        @param fp pool of features
        @param examples training examples
    */
    virtual void train ( FeaturePool & fp,
                         Examples & examples );

    /** @{ methods for persistency */
    void restore ( std::istream & is, int format = 0 );
    void store ( std::ostream & os, int format = 0 ) const;
    void clear ();
    /** @} */

    /** @brief creates a copy of this object */
    FeaturePoolClassifier *clone () const;

    /** @brief direct access to the classifier parameters */
    StrongClassifier & getStrongClassifier ()
    {
      return strongClassifier;
    };

    /** @brief sets the maximum number of rounds */
    void setComplexity ( int size );
};


} // namespace

#endif
