// @(#)root/minuit2:$Id$ // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005 /********************************************************************** * * * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT * * * **********************************************************************/ #ifndef ROOT_Minuit2_BasicFunctionMinimum #define ROOT_Minuit2_BasicFunctionMinimum #include "Minuit2/MinimumSeed.h" #include "Minuit2/MinimumState.h" #include "Minuit2/MnUserParameterState.h" #include "Minuit2/MnUserTransformation.h" #include "Minuit2/StackAllocator.h" #include namespace ROOT { namespace Minuit2 { //extern StackAllocator gStackAllocator; /** result of the minimization; both internal and external (MnUserParameterState) representation available For the parameters at the Minimum */ class BasicFunctionMinimum { public: class MnReachedCallLimit {}; class MnAboveMaxEdm {}; public: /// constructor from only MinimumSeed. Minimum is only from seed result not the full minimization BasicFunctionMinimum(const MinimumSeed& seed, double up) : fSeed(seed), fStates(std::vector(1, MinimumState(seed.Parameters(), seed.Error(), seed.Gradient(), seed.Parameters().Fval(), seed.NFcn()))), fErrorDef(up), fAboveMaxEdm(false), fReachedCallLimit(false), fUserState(MnUserParameterState()) {} /// constructor at the end of a successfull minimization from seed and vector of states BasicFunctionMinimum(const MinimumSeed& seed, const std::vector& states, double up) : fSeed(seed), fStates(states), fErrorDef(up), fAboveMaxEdm(false), fReachedCallLimit(false), fUserState(MnUserParameterState()) {} /// constructor at the end of a failed minimization due to exceeding function call limit BasicFunctionMinimum(const MinimumSeed& seed, const std::vector& states, double up, MnReachedCallLimit) : fSeed(seed), fStates(states), fErrorDef(up), fAboveMaxEdm(false), fReachedCallLimit(true), fUserState(MnUserParameterState()) {} /// constructor at the end of a failed minimization due to edm above maximum value BasicFunctionMinimum(const MinimumSeed& seed, const std::vector& states, double up, MnAboveMaxEdm) : fSeed(seed), fStates(states), fErrorDef(up), fAboveMaxEdm(true), fReachedCallLimit(false), fUserState(MnUserParameterState()) {} /// copy constructor BasicFunctionMinimum(const BasicFunctionMinimum& min) : fSeed(min.fSeed), fStates(min.fStates), fErrorDef(min.fErrorDef), fAboveMaxEdm(min.fAboveMaxEdm), fReachedCallLimit(min.fReachedCallLimit), fUserState(min.fUserState) {} BasicFunctionMinimum& operator=(const BasicFunctionMinimum& min) { fSeed = min.fSeed; fStates = min.fStates; fErrorDef = min.fErrorDef; fAboveMaxEdm = min.fAboveMaxEdm; fReachedCallLimit = min.fReachedCallLimit; fUserState = min.fUserState; return *this; } ~BasicFunctionMinimum() {} /// add latest minimization state (for example add Hesse result after Migrad) void Add(const MinimumState& state ) { fStates.push_back(state); // LM : update also the user state fUserState = MnUserParameterState(State(), Up(), Seed().Trafo()); // reset maxedm flag. If new state has edm over max other method must be used fAboveMaxEdm = false; } ///Add a new state and flag that edm is above maximum void Add(const MinimumState& state, MnAboveMaxEdm) { Add(state); fAboveMaxEdm = true; } const MinimumSeed& Seed() const {return fSeed;} const std::vector& States() const {return fStates;} // user representation of state at Minimum const MnUserParameterState& UserState() const { if(!fUserState.IsValid()) fUserState = MnUserParameterState(State(), Up(), Seed().Trafo()); return fUserState; } const MnUserParameters& UserParameters() const { if(!fUserState.IsValid()) fUserState = MnUserParameterState(State(), Up(), Seed().Trafo()); return fUserState.Parameters(); } const MnUserCovariance& UserCovariance() const { if(!fUserState.IsValid()) fUserState = MnUserParameterState(State(), Up(), Seed().Trafo()); return fUserState.Covariance(); } void* operator new(size_t nbytes) { return StackAllocatorHolder::Get().Allocate(nbytes); } void operator delete(void* p, size_t /*nbytes */) { StackAllocatorHolder::Get().Deallocate(p); } // forward interface of last state const MinimumState& State() const {return fStates.back();} const MinimumParameters& Parameters() const {return fStates.back().Parameters();} const MinimumError& Error() const {return fStates.back().Error();} const FunctionGradient& Grad() const {return fStates.back().Gradient();} double Fval() const {return fStates.back().Fval();} double Edm() const {return fStates.back().Edm();} int NFcn() const {return fStates.back().NFcn();} double Up() const {return fErrorDef;} bool IsValid() const { return State().IsValid() && !IsAboveMaxEdm() && !HasReachedCallLimit(); } bool HasValidParameters() const {return State().Parameters().IsValid();} bool HasValidCovariance() const {return State().Error().IsValid();} bool HasAccurateCovar() const {return State().Error().IsAccurate();} bool HasPosDefCovar() const {return State().Error().IsPosDef();} bool HasMadePosDefCovar() const {return State().Error().IsMadePosDef();} bool HesseFailed() const {return State().Error().HesseFailed();} bool HasCovariance() const {return State().Error().IsAvailable();} bool IsAboveMaxEdm() const {return fAboveMaxEdm;} bool HasReachedCallLimit() const {return fReachedCallLimit;} void SetErrorDef( double up) { fErrorDef = up; // update user state for new valeu of up (scaling of errors) fUserState = MnUserParameterState(State(), up, Seed().Trafo()); } private: MinimumSeed fSeed; std::vector fStates; double fErrorDef; bool fAboveMaxEdm; bool fReachedCallLimit; mutable MnUserParameterState fUserState; }; } // namespace Minuit2 } // namespace ROOT #endif // ROOT_Minuit2_BasicFunctionMinimum