/**
* @file LaplaceApproximation.h
* @author Erik Rodner
* @date 02/17/2010

*/
#ifndef _NICE_OBJREC_LAPLACEAPPROXIMATIONINCLUDE
#define _NICE_OBJREC_LAPLACEAPPROXIMATIONINCLUDE

#include "core/basics/Config.h"
#include "vislearning/classifier/kernelclassifier/LikelihoodFunction.h"
#include "vislearning/math/kernels/KernelData.h"

namespace OBJREC
{

/** @class LaplaceApproximation
 * some utility functions for laplace approximation
 *
 * @author Erik Rodner
 */
class LaplaceApproximation
{

  protected:
    /** optimization settings */
    uint maxiterations;
    double minimumDelta;
    bool verbose;

    /** useful variables */
    NICE::Vector mode;
    NICE::Vector hessianW;
    NICE::Vector gradientL;
    NICE::Matrix cholB;

    NICE::Vector a;

    double objective;
    double noiseTerm;

    void updateCache ( const NICE::Matrix & kernelMatrix, const NICE::Vector & y, const LikelihoodFunction *likelihoodFunction );

  public:

    /** use standard settings */
    LaplaceApproximation();

    /** simple constructor using config values for numerical details */
    LaplaceApproximation ( const NICE::Config *conf, const std::string & section = "LaplaceApproximation" );

    /** simple destructor */
    virtual ~LaplaceApproximation();

    void approximate ( KernelData *kernelData, const NICE::Vector & y,
                       const LikelihoodFunction *likelihoodFunction );

    double predict ( const NICE::Vector & kernelVector, double kernelSelf, const NICE::Vector & y,
                     const LikelihoodFunction *likelihoodFunction ) const;

    const NICE::Vector & getMode () const
    {
      return mode;
    };
    const NICE::Vector & getHessian () const
    {
      return hessianW;
    };
    const NICE::Vector & getGradient () const
    {
      return gradientL;
    };
    const NICE::Vector & getAVector () const
    {
      return a;
    };
    const NICE::Matrix & getCholeskyB () const
    {
      return cholB;
    };

    double getObjective () const
    {
      return objective;
    };
};

}

#endif
