// @(#)root/minuit2:$Name:  $:$Id: MnHesse.h,v 1.1 2005/11/29 14:42:18 moneta Exp $
// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005  

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
 *                                                                    *
 **********************************************************************/

#ifndef ROOT_Minuit2_MnHesse
#define ROOT_Minuit2_MnHesse

#include "Minuit2/MnConfig.h"
#include "Minuit2/MnStrategy.h"

#include <vector>

namespace ROOT {

   namespace Minuit2 {


class FCNBase;
class MnUserParameterState;
class MnUserParameters;
class MnUserCovariance;
class MnUserTransformation;
class MinimumState;
class MnMachinePrecision;
class MnFcn;


/** API class for calculating the numerical covariance matrix 
    (== 2x Inverse Hessian == 2x Inverse 2nd derivative); can be used by the 
    user or Minuit itself
 */

class MnHesse {

public:

  /// default constructor with default strategy
  MnHesse() : fStrategy(MnStrategy(1)) {}

  /// constructor with user-defined strategy level
  MnHesse(unsigned int stra) : fStrategy(MnStrategy(stra)) {}

  /// conctructor with specific strategy
  MnHesse(const MnStrategy& stra) : fStrategy(stra) {}

  ~MnHesse() {}

  ///
  /// low-level API
  ///
  /// FCN + parameters + errors
  MnUserParameterState operator()(const FCNBase&, const std::vector<double>&, const std::vector<double>&, unsigned int maxcalls=0) const;
  /// FCN + parameters + covariance
  MnUserParameterState operator()(const FCNBase&, const std::vector<double>&, const std::vector<double>&, unsigned int, unsigned int maxcalls=0) const;
  /// FCN + parameters + MnUserCovariance
  MnUserParameterState operator()(const FCNBase&, const std::vector<double>&, const MnUserCovariance&, unsigned int maxcalls=0) const;
  ///
  /// high-level API
  ///
  /// FCN + MnUserParameters
  MnUserParameterState operator()(const FCNBase&, const MnUserParameters&, unsigned int maxcalls=0) const;
  /// FCN + MnUserParameters + MnUserCovariance
  MnUserParameterState operator()(const FCNBase&, const MnUserParameters&, const MnUserCovariance&, unsigned int maxcalls=0) const;
  /// FCN + MnUserParameterState
  MnUserParameterState operator()(const FCNBase&, const MnUserParameterState&, unsigned int maxcalls=0) const;
  ///
  /// internal interface
  ///
  MinimumState operator()(const MnFcn&, const MinimumState&, const MnUserTransformation&, unsigned int maxcalls=0) const;

  /// forward interface of MnStrategy
  unsigned int Ncycles() const {return fStrategy.HessianNCycles();}
  double Tolerstp() const {return fStrategy.HessianStepTolerance();}
  double TolerG2() const {return fStrategy.HessianG2Tolerance();}

private:

  MnStrategy fStrategy;
};

  }  // namespace Minuit2

}  // namespace ROOT

#endif  // ROOT_Minuit2_MnHesse
