00001 #ifndef HiggsAnalysis_CombinedLimit_SequentialMinimizer_h
00002 #define HiggsAnalysis_CombinedLimit_SequentialMinimizer_h
00003
00004 struct RooAbsReal;
00005 struct RooRealVar;
00006 #include <vector>
00007 #include <memory>
00008 #include <Math/Minimizer.h>
00009
00010 namespace cmsmath {
00011
00013 struct MinimizerContext {
00014 MinimizerContext(const ROOT::Math::IMultiGenFunction *function) : func(function), x(func->NDim()), nCalls(0) {}
00015
00016 double eval() const { nCalls++; return (*func)(&x[0]); }
00017 double setAndEval(unsigned int i, double xi) const { x[i] = xi; return eval(); }
00018 double cleanEval(unsigned int i, double xi) const { double x0 = x[i]; x[i] = xi; double y = eval(); x[i] = x0; return y; }
00019
00020 const ROOT::Math::IMultiGenFunction * func;
00021
00022 mutable std::vector<double> x;
00023 mutable unsigned int nCalls;
00024 };
00025
00026 class OneDimMinimizer {
00027 public:
00028 OneDimMinimizer() : f_(0), idx_(0) {}
00029 OneDimMinimizer(const MinimizerContext &ctx, unsigned int idx) :
00030 f_(&ctx), idx_(idx) {}
00031 OneDimMinimizer(const MinimizerContext &ctx, unsigned int idx, double xmin, double xmax, double xstep, const std::string &name) :
00032 f_(&ctx), idx_(idx), name_(name), xmin_(xmin), xmax_(xmax), xstep_(xstep) {}
00033
00034 const std::string & name() const { return name_; }
00035 const char * cname() const { return name_.c_str(); }
00036 double max() const { return xmax_; }
00037 double min() const { return xmin_; }
00038 double step() const { return xstep_; }
00039
00040 bool isInit() const { return f_ != 0; }
00041 void init(const MinimizerContext &ctx, unsigned int idx, double xmin, double xmax, double xstep, const std::string &name) {
00042 f_ = &ctx; idx_ = idx;
00043 xmin_ = xmin; xmax_ = xmax; xstep_ = xstep;
00044 name_ = name;
00045 }
00046 void initUnbound(const MinimizerContext &ctx, unsigned int idx, double xstep, const std::string &name) {
00047 init(ctx, idx, -std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), xstep, name);
00048 }
00049
00050 void initDefault(const MinimizerContext &ctx, unsigned int idx) ;
00051
00054 bool minimize(int steps=1, double ytol=0, double xtol = 0);
00055
00063 enum ImproveRet { Unchanged = 2, Done = 1, NotDone = 0 };
00064 ImproveRet improve(int steps=1, double ytol=0, double xtol = 0, bool force=true);
00065
00066 void moveTo(double x) ;
00067 private:
00068
00069 const MinimizerContext * f_;
00070
00071 unsigned int idx_;
00072
00073 std::string name_;
00074
00075
00076 double xi_[3], yi_[3];
00077
00078
00079 double xmin_, xmax_, xstep_;
00080
00083 bool doloop(int steps, double ytol, double xtol) ;
00084
00086 void seek() ;
00087
00090 void reseek() ;
00091
00093 void goldenBisection();
00094
00096 bool parabolaStep();
00097
00099 double parabolaFit();
00100
00102 inline double &x() { return f_->x[idx_]; }
00103 inline double eval() { return f_->eval(); }
00104 inline double eval(double x) { return f_->cleanEval(idx_, x); }
00105
00106 inline void assign(int to, int from) { xi_[to] = xi_[from]; yi_[to] = yi_[from]; }
00107 };
00108
00109 class SequentialMinimizer : public ROOT::Math::Minimizer {
00110 public:
00111 SequentialMinimizer(const char *name=0) : ROOT::Math::Minimizer() {}
00112
00114 virtual void Clear() ;
00115
00117 virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func) ;
00118
00120 virtual bool SetVariable(unsigned int ivar, const std::string & name, double val, double step) ;
00121
00123 virtual bool SetLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower, double upper) ;
00124
00126 virtual bool SetFixedVariable(unsigned int ivar, const std::string & name, double val) ;
00127
00129 virtual bool Minimize() ;
00130
00132 virtual double MinValue() const { return minValue_; }
00133
00135 virtual double Edm() const { return edm_; }
00136
00138 virtual const double * X() const { return & func_->x[0]; }
00139
00141 virtual const double * MinGradient() const { return 0; }
00142
00144 virtual unsigned int NCalls() const { return func_->nCalls; }
00145
00148 virtual unsigned int NDim() const { return nDim_; }
00149
00152 virtual unsigned int NFree() const { return nFree_; }
00153
00155 virtual bool ProvidesError() const { return false; }
00156
00158 virtual const double * Errors() const { return 0; }
00159
00160 virtual double CovMatrix(unsigned int i, unsigned int j) const { return 0; }
00161
00162
00163 enum State { Cleared, Ready, Active, Done, Fixed, Unknown };
00164 struct Worker : public OneDimMinimizer {
00165 Worker() : OneDimMinimizer(), state(Unknown) {}
00166 State state;
00167 int nUnaffected;
00168 };
00169 protected:
00170 bool minimize(int smallsteps=5);
00171 bool improve(int smallsteps=5);
00172 bool doFullMinim();
00173
00174 std::auto_ptr<MinimizerContext> func_;
00175 unsigned int nDim_, nFree_;
00176
00177
00178 double minValue_;
00179 double edm_;
00180
00181
00182 std::vector<Worker> workers_;
00183 State state_;
00184
00185
00186 std::auto_ptr<ROOT::Math::Minimizer> fullMinimizer_;
00187 std::vector<int> subspaceIndices_;
00188
00189 };
00190
00191 }
00192 #endif