/**
 * @file SLR.h
 * @brief implementation of Sparse Logistic Regression (SMLR) Classififier (one vs. all)
 * @author Björn Fröhlich
 * @date 06/23/2009
 */
#ifndef SLRDEF
#define SLRDEF

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

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

namespace OBJREC {

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

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

    //! weight vectors
    SparseVector weight;

    //! the featurepool
    FeaturePool fp;

    //! maximum number of iterations
    int maxiter;

    //! Decay rate in the probability of resampling a zero weight.1.0 will immediately decrease to the min_resamp from 1.0, 0.0 will never decrease from 1.0.
    double resamp_decay;

    //! convergence criterium for stepwise regression
    double convergence_tol;

    //! Minimum resampling probability for zeroed weights"
    double min_resamp;

    //! Feature Dimension
    int fdim;

    //! The penalty term lambda. Larger values will give rise to more sparsification
    double lambda;

    //! how many samples per class should be used
    double samplesperclass;

    //! for normalization
    std::vector<double> minval, maxval;

  public:


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


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

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

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

    /**
     * start training
     * @param fp a featurepool (how to handle which features...)
     * @param classno which class should be learned
     * @param examples input features
     */
    void train ( FeaturePool & _fp, Examples & examples, int classno = 1 );

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

    /**
     * perform the stepwise regression
     * @param x input features
     * @param classno which class should be learned
     * @return number of iterations
     */
    int stepwise_regression ( Examples &x, int classno = 1 );

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

} // namespace
#endif