/**
 * @file PCA.h
 * @brief extract fourier domain value
 * @author Michael Koch
 * @date 5/27/2008

 */
#ifndef PCAINCLUDE
#define PCAINCLUDE

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

#include "vislearning/math/ftransform/FTransform.h"


namespace OBJREC {

/** extract PCA features */
class PCA: public FTransform
{

  protected:
    NICE::Vector mean;

    NICE::Matrix basis;
    NICE::Matrix normbasis;

    NICE::Matrix normalization;
    uint targetDimension;
    uint maxiteration;
    double mindelta;

    void calculateMean ( const NICE::Matrix &features, NICE::Vector & mean );

  public:

    PCA ( uint dim, uint maxiteration = 100, double mindelta = 1e-4 );
    PCA ( void );

    NICE::Matrix getBasis();

    NICE::Vector getMean();
    void restore ( std::istream & is, int format = 0 );
    void store ( std::ostream & os, int format = 0 ) const;
    void clear ();

    /**
     * get Basis Vectors of PCA
     * @param features Input Features
     * @param dimension Dimension size / number of principal components
    * @return Basis Vectors
    */
    void calculateBasis ( const NICE::Matrix &features, const uint targetDimension, const uint mode = 0 );
    void calculateBasis ( const NICE::Matrix &features, const uint targetDimension, const bool adaptive, const double targetRatio = 1.0 );

    /**
     * returns the dimension of the transformed features
     * @return feature dim
     */
    int getTargetDim();

    /**
     * get Features in PCA Space
     * @param data input data
     * @param normalize normalisation switch
     * @return Features as Vector
     */

    NICE::Vector getFeatureVector ( const NICE::Vector &data, const bool normalize = true );

    ~PCA();

  private:

    void init ( uint dim = 10, uint maxiteration = 100, double mindelta = 1e-4 );

};


} // namespace

#endif
