/**
 * @file FPCSMLR.h
 * @brief implementation of Sparse Multinomial Logistic Regression (SMLR) Classififier, it uses a SLR for each class and combines the results
 * @author Björn Fröhlich
 * @date 06/23/2009

 */
#ifndef FPCSMLRDEF
#define FPCSMLRDEF

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

#include "vislearning/classifier/classifierbase/FeaturePoolClassifier.h"
#include "vislearning/classifier/fpclassifier/logisticregression/SLR.h"
#include "vislearning/cbaselib/FeaturePool.h"
#include "core/algebra/GMSparseVectorMatrix.h"

namespace OBJREC
{

class FPCSMLR : public FeaturePoolClassifier
{
  protected:
    //! the configuration file
    const NICE::Config *conf;

    //! section in the configfile
    std::string confsection;

    //! the featurepool
    FeaturePool fp;

    //! the one vs all sparse logistic classifiers
    std::vector<SLR> classifiers;

    //! just use the features from pictures, which the class contains
    bool inpic;

  public:
    /**
     * standard constructor
     * @param conf configfile
     * @param section section name in configfile for classifier
     */
    FPCSMLR ( const NICE::Config *conf, std::string section="SMLR" );


    /**
     * simple constructor -> does nothing
     */
    FPCSMLR ();

    /**
     * simple destructor
     */
    ~FPCSMLR();

    /**
     * main classification function
     * @param pce input feature
     * @return a classification result
     */
    ClassificationResult classify ( Example & pce );

    /**
     * start training
     * @param fp a featurepool (how to handle which features...)
     * @param examples input features
     */
    void train ( FeaturePool & _fp, Examples & examples );

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

    /**
     * set complexity for the next training process e.g. number of weak classifiers
     * @param size new complexity
     */
    void setComplexity ( int size );

    /** IO functions */
    void restore ( std::istream & is, int format = 0 );
    void store ( std::ostream & os, int format = 0 ) const;
    void clear ();
};

} // namespace

#endif
