CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SequentialMinimizer.cc
Go to the documentation of this file.
1 #include "../interface/SequentialMinimizer.h"
2 
3 #include <cmath>
4 #include <stdexcept>
5 #include <memory>
6 #include <algorithm>
7 #include <limits>
8 #include "TString.h"
9 #include "RooRealVar.h"
10 #include "RooAbsReal.h"
11 #include "RooLinkedListIter.h"
12 #include <Math/MinimizerOptions.h>
13 #include <Math/Factory.h>
14 #include <boost/foreach.hpp>
15 #include "../interface/ProfilingTools.h"
16 #define foreach BOOST_FOREACH
17 
18 #define DEBUG_ODM_printf if (0) printf
19 //#define DEBUG_SM_printf if (0) printf
20 //#define DEBUGV_SM_printf if (0) printf
21 // #define DEBUG_ODM_printf printf
22 #define DEBUG_SM_printf if (fDebug > 1) printf
23 #define DEBUGV_SM_printf if (fDebug > 2) printf
24 
25 namespace {
26  const double GOLD_R1 = 0.61803399 ;
27  const double GOLD_R2 = 1-0.61803399 ;
28  const double XTOL = 10*std::sqrt(std::numeric_limits<double>::epsilon());
29 }
30 void cmsmath::OneDimMinimizer::initDefault(const MinimizerContext &ctx, unsigned int idx) {
32 }
33 
34 
35 bool cmsmath::OneDimMinimizer::minimize(int steps, double ytol, double xtol)
36 {
37  // get initial bracket
38  seek();
39 
40  bool done = doloop(steps,ytol,xtol);
41  parabolaStep();
42  x() = xi_[1];
43  xstep_ = xi_[2] - xi_[0];
44  return done;
45 }
46 
48 {
49  double x0 = x();
50  if (x0 < xi_[0] || x0 > xi_[2]) {
51  // could happen if somebody outside this loop modifies some parameters
52  DEBUG_ODM_printf("ODM: ALERT: variable %s outside bounds x = [%.4f, %.4f, %.4f], x0 = %.4f\n", name_.c_str(), xi_[0], xi_[1], xi_[2], x0);
53  x0 = x() = xi_[1];
54  } else {
55  xi_[1] = x0;
56  }
57  double y0 = eval();
58  yi_[1] = y0;
59  yi_[0] = eval(xi_[0]);
60  yi_[2] = eval(xi_[2]);
61  if (xtol == 0) xtol = (fabs(xi_[1])+XTOL)*XTOL;
62 
63  DEBUG_ODM_printf("ODM: start of improve %s x = [%.4f, %.4f, %.4f], y = [%.4f, %.4f, %.4f]\n", name_.c_str(), xi_[0], xi_[1], xi_[2], yi_[0], yi_[1], yi_[2]);
64 
65  if (yi_[1] <= yi_[0] && yi_[1] <= yi_[2]) {
66  if (ytol > 0 && (std::max(yi_[2],yi_[0]) - yi_[1]) < ytol) {
67  DEBUG_ODM_printf("ODM: immediate ytol for %s: ymin %.8f, ymax %.8f, diff %.8f\n", name_.c_str(), yi_[1], std::max(yi_[2],yi_[0]), std::max(yi_[2],yi_[0]) - yi_[1]);
68  if (!force || parabolaStep()) return Unchanged;
69  }
70  if (xtol > 0 && (xi_[2] - xi_[0]) < xtol) {
71  DEBUG_ODM_printf("ODM: immediate xtol for %s: xmin %.8f, xmax %.8f, diff %.8f\n", name_.c_str(), xi_[0], xi_[2], xi_[2] - xi_[0]);
72  if (!force || parabolaStep()) return Unchanged;
73  }
74  } else {
75  reseek();
76  }
77 
78  //post-condition: always a sorted interval
79  assert(xi_[0] < xi_[2]);
80  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
81  // if midpoint is not not one of the extremes, it's not higher than that extreme
82  assert(xi_[1] == xi_[0] || yi_[1] <= yi_[0]);
83  assert(xi_[1] == xi_[2] || yi_[1] <= yi_[2]);
84 
85  bool done = doloop(steps,ytol,xtol);
86  parabolaStep();
87 
88  //post-condition: always a sorted interval
89  assert(xi_[0] < xi_[2]);
90  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
91  // if midpoint is not not one of the extremes, it's not higher than that extreme
92  assert(xi_[1] == xi_[0] || yi_[1] <= yi_[0]);
93  assert(xi_[1] == xi_[2] || yi_[1] <= yi_[2]);
94 
95 
96  if (ytol > 0 && fabs(yi_[1] - y0) < ytol) {
97  DEBUG_ODM_printf("ODM: final ytol for %s: ymin(old) %.8f, ymin(new) %.8f, diff %.8f\n", name_.c_str(), y0, yi_[1], y0 -yi_[1]);
98  if (!force) x() = x0;
99  return Unchanged;
100  }
101 
102  if (xtol > 0 && fabs(xi_[1] - x0) < xtol) {
103  x() = (force ? xi_[1] : x0);
104  return Unchanged;
105  }
106  DEBUG_ODM_printf("ODM: doloop for %s is %s\n", name_.c_str(), done ? "Done" : "NotDone");
107  DEBUG_ODM_printf("ODM: end of improve %s x = [%.4f, %.4f, %.4f], y = [%.4f, %.4f, %.4f]\n", name_.c_str(), xi_[0], xi_[1], xi_[2], yi_[0], yi_[1], yi_[2]);
108  x() = xi_[1];
109  xstep_ = xi_[2] - xi_[0];
110  return done ? Done : NotDone;
111 }
112 
113 bool cmsmath::OneDimMinimizer::doloop(int steps, double ytol, double xtol)
114 {
115  if (steps <= 0) steps = 100;
116  for (int i = 0; i < steps; ++i) {
117  if (xtol > 0 && (xi_[2] - xi_[0]) < xtol) {
118  return true;
119  }
120  goldenBisection();
121  if (ytol > 0 && (std::max(yi_[2],yi_[0]) - yi_[1]) < ytol) {
122  DEBUG_ODM_printf("ODM: intermediate ytol for %s: ymin %.8f, ymax %.8f, diff %.8f\n", name_.c_str(), yi_[1], std::max(yi_[2],yi_[0]), std::max(yi_[2],yi_[0]) - yi_[1]);
123  return true;
124  }
125  DEBUG_ODM_printf("ODM: step %d/%d done for %s: ymin %.8f, ymax %.8f, diff %.8f\n", i+1, steps, name_.c_str(), yi_[1], std::max(yi_[2],yi_[0]), std::max(yi_[2],yi_[0]) - yi_[1]);
126  DEBUG_ODM_printf("ODM: %s x = [%.4f, %.4f, %.4f], y = [%.4f, %.4f, %.4f]\n", name_.c_str(), xi_[0], xi_[1], xi_[2], yi_[0], yi_[1], yi_[2]);
127  }
128 
129  return false;
130 }
131 
133 {
134  if (std::isfinite(xmax_-xmin_)) {
135  xstep_ = std::max(xstep_, 0.2*(xmax_-xmin_));
136  } else {
137  xstep_ = 1.0;
138  }
139  reseek();
140 }
142 {
143  double xtol2 = 2*(fabs(xi_[1])+XTOL)*XTOL;
144  if (xstep_ < xtol2) xstep_ = xtol2;
145  xi_[1] = x();
146  yi_[1] = eval(xi_[1]);
147  xi_[0] = std::max(xmin_, xi_[1]-xstep_);
148  yi_[0] = (xi_[0] == xi_[1] ? yi_[1] : eval(xi_[0]));
149  xi_[2] = std::min(xmax_, xi_[1]+xstep_);
150  yi_[2] = (xi_[2] == xi_[1] ? yi_[1] : eval(xi_[2]));
151  assert(xi_[0] < xi_[2]);
152  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
153 
154  for (;;) {
155  //DEBUG_ODM_printf("ODM: bracketing %s in x = [%.4f, %.4f, %.4f], y = [%.4f, %.4f, %.4f]\n", name_.c_str(), xi_[0], xi_[1], xi_[2], yi_[0], yi_[1], yi_[2]);
156  if (yi_[0] < yi_[1]) {
157  assign(2,1); // 2:=1
158  assign(1,0); // 1:=0
159  xi_[0] = std::max(xmin_, xi_[1]-xstep_);
160  yi_[0] = (xi_[0] == xi_[1] ? yi_[1] : eval(xi_[0]));
161  } else if (yi_[2] < yi_[1]) {
162  assign(0,1); // 0:=1
163  assign(1,2); // 1:=2
164  xi_[2] = std::min(xmax_, xi_[1]+xstep_);
165  yi_[2] = (xi_[2] == xi_[1] ? yi_[1] : eval(xi_[2]));
166  } else if (yi_[2] == yi_[1] && yi_[1] == yi_[0]) {
167  // function is identical in three points --> constant?
168  // try a scan
169  const int nPoints = 20;
170  double xi[nPoints], yi[nPoints];
171  double dx = (xmax_-xmin_)/nPoints, x = xmin_ - 0.5*dx;
172  bool isConst = true;
173  int iFound = 0;
174  for (int i = 0; i < nPoints; ++i, x += dx) {
175  xi[i] = x; yi[i] = eval(x);
176  if (yi[i] != yi_[1]) isConst = false;
177  if (yi[i] < yi[iFound]) { iFound = i; }
178  }
179  if (isConst) break;
180  xi_[0] = (iFound == 0 ? xmin_ : xi[iFound-1]);
181  xi_[2] = (iFound > nPoints-1 ? xmax_ : xi[iFound+1]);
182  xi_[1] = iFound; yi_[1] = yi_[iFound];
183  break;
184  } else {
185  xstep_ /= 2;
186  break;
187  }
188  xstep_ *= 2;
189  }
190  //DEBUG_ODM_printf("ODM: bracketed minimum of %s in [%.4f, %.4f, %.4f]\n", name_.c_str(), xi_[0], xi_[1], xi_[2]);
191  //post-condition: always a sorted interval
192  assert(xi_[0] < xi_[2]);
193  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
194  // if midpoint is not not one of the extremes, it's not higher than that extreme
195  assert(xi_[1] == xi_[0] || yi_[1] <= yi_[0]);
196  assert(xi_[1] == xi_[2] || yi_[1] <= yi_[2]);
197 }
198 
200 {
201  //pre-condition: always a sorted interval
202  assert(xi_[0] < xi_[2]);
203  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
204  // if midpoint is not not one of the extremes, it's not higher than that extreme
205  assert(xi_[1] == xi_[0] || yi_[1] <= yi_[0]);
206  assert(xi_[1] == xi_[2] || yi_[1] <= yi_[2]);
207  if (xi_[0] == xi_[1] || xi_[1] == xi_[2]) {
208  int isame = (xi_[0] == xi_[1] ? 0 : 2);
210  assert(yi_[isame] <= yi_[2-isame]);
211  xi_[1] = 0.5*(xi_[0]+xi_[2]);
212  yi_[1] = eval(xi_[1]);
213  if (yi_[1] < yi_[isame]) {
214  // maximum is in the interval-
215  // leave as is, next bisection steps will find it
216  } else {
217  // maximum remains on the boundary, leave both points there
218  assign(2-isame, 1);
219  assign(1, isame);
220  }
221  } else {
222  int inear = 2, ifar = 0;
223  if (xi_[2]-xi_[1] > xi_[1] - xi_[0]) {
224  inear = 0, ifar = 2;
225  } else {
226  inear = 2, ifar = 0;
227  }
228  double xc = xi_[1]*GOLD_R1 + xi_[ifar]*GOLD_R2;
229  double yc = eval(xc);
230  //DEBUG_ODM_printf("ODM: goldenBisection:\n\t\tfar = (%.2f,%.8f)\n\t\tnear = (%.2f,%.8f)\n\t\tcenter = (%.2f,%.8f)\n\t\tnew = (%.2f,%.8f)\n",
231  // xi_[ifar], yi_[ifar], xi_[inear], yi_[inear], xi_[1], yi_[1], xc, yc);
232  if (yc < yi_[1]) { // then use 1, c, far
233  assign(inear, 1);
234  xi_[1] = xc; yi_[1] = yc;
235  } else { // then use c, 1, near
236  xi_[ifar] = xc; yi_[ifar] = yc;
237  }
238  }
239  //post-condition: always a sorted interval
240  assert(xi_[0] < xi_[2]);
241  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
242  // if midpoint is not not one of the extremes, it's not higher than that extreme
243  assert(xi_[1] == xi_[0] || yi_[1] <= yi_[0]);
244  assert(xi_[1] == xi_[2] || yi_[1] <= yi_[2]);
245 
246 }
247 
249 {
250  if (xi_[0] == xi_[1] || xi_[1] == xi_[2]) {
251  return xi_[1];
252  }
253  double dx0 = xi_[1] - xi_[0], dx2 = xi_[1] - xi_[2];
254  double dy0 = yi_[1] - yi_[0], dy2 = yi_[1] - yi_[2];
255  double num = dx0*dx0*dy2 - dx2*dx2*dy0;
256  double den = dx0*dy2 - dx2*dy0;
257  if (den != 0) {
258  double x = xi_[1] - 0.5*num/den;
259  if (xi_[0] < x && x < xi_[2]) {
260  return x;
261  }
262  }
263  return xi_[1];
264 }
265 
267  double xc = parabolaFit();
268  if (xc != xi_[1]) {
269  double yc = eval(xc);
270  if (yc < yi_[1]) {
271  xi_[1] = xc;
272  yi_[1] = yc;
273  //post-condition: always a sorted interval
274  assert(xi_[0] < xi_[2]);
275  assert(xi_[0] <= xi_[1] && xi_[1] <= xi_[2]);
276  // if midpoint is not not one of the extremes, it's not higher than that extreme
277  assert(xi_[1] == xi_[0] || yi_[1] <= yi_[0]);
278  assert(xi_[1] == xi_[2] || yi_[1] <= yi_[2]);
279  return true;
280  }
281  }
282  return false;
283 }
284 
286  if (x == xmax_) {
287  xi_[0] = xmax_ - (xi_[2]-xi_[0]); yi_[0] = eval(xi_[0]);
288  xi_[1] = xmax_; yi_[1] = eval(xmax_);
289  xi_[2] = xmax_; yi_[2] = yi_[1];
290  } else if (x == xmin_) {
291  xi_[2] = xmin_ + (xi_[2]-xi_[0]); yi_[2] = eval(xi_[0]);
292  xi_[1] = xmin_; yi_[1] = eval(xmin_);
293  xi_[0] = xmin_; yi_[0] = yi_[1];
294  } else {
295  double dx = xi_[2] - xi_[0];
296  xi_[1] = x; yi_[0] = eval(x);
297  xi_[0] = std::max(xmin_, x-dx); yi_[0] = eval(xi_[0]);
298  xi_[2] = std::min(xmax_, x+dx); yi_[2] = eval(xi_[2]);
299  }
300 }
301 
302 void cmsmath::SequentialMinimizer::SetFunction(const ROOT::Math::IMultiGenFunction & func) {
303  DEBUG_SM_printf("SequentialMinimizer::SetFunction: nDim = %u\n", func.NDim());
304  func_.reset(new MinimizerContext(&func));
305  nFree_ = nDim_ = func_->x.size();
306  // create dummy workers
307  workers_.clear();
308  workers_.resize(nDim_);
309  // reset states
310  Clear();
311 }
312 
314  DEBUGV_SM_printf("SequentialMinimizer::Clear()\n");
315  minValue_ = std::numeric_limits<double>::quiet_NaN();
317  state_ = Cleared;
318  foreach(Worker &w, workers_) w.state = Cleared;
319 }
320 
321 bool cmsmath::SequentialMinimizer::SetVariable(unsigned int ivar, const std::string & name, double val, double step) {
322  DEBUGV_SM_printf("SequentialMinimizer::SetVariable(idx %u, name %s, val %g, step %g)\n", ivar, name.c_str(), val, step);
323  assert(ivar < nDim_);
324  func_->x[ivar] = val;
325  workers_[ivar].initUnbound(*func_, ivar, step, name);
326  workers_[ivar].state = Cleared;
327  return true;
328 }
329 
330 bool cmsmath::SequentialMinimizer::SetLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower, double upper) {
331  DEBUGV_SM_printf("SequentialMinimizer::SetLimitedVariable(idx %u, name %s, var %g, step %g, min %g, max %g)\n", ivar, name.c_str(), val, step, lower, upper);
332  assert(ivar < nDim_);
333  func_->x[ivar] = val;
334  workers_[ivar].init(*func_, ivar, lower, upper, step, name);
335  workers_[ivar].state = Cleared;
336  return true;
337 }
338 
339 bool cmsmath::SequentialMinimizer::SetFixedVariable(unsigned int ivar, const std::string & name, double val) {
340  DEBUGV_SM_printf("SequentialMinimizer::SetFixedVariable(idx %u, name %s, var %g)\n", ivar, name.c_str(), val);
341  assert(ivar < nDim_);
342  func_->x[ivar] = val;
343  workers_[ivar].initUnbound(*func_, ivar, 1.0, name);
344  workers_[ivar].state = Fixed;
345  return true;
346 }
347 
349  return minimize();
350 }
351 
353 {
354  for (unsigned int i = 0; i < nDim_; ++i) {
355  Worker &w = workers_[i];
356  if (!w.isInit() || w.state == Unknown) throw std::runtime_error(Form("SequentialMinimizer::worker[%u/%u] not initialized!\n", i, nDim_));
357  if (w.state != Fixed) {
358  w.minimize(1);
359  w.state = Ready;
360  }
361  }
362  state_ = Ready;
363  return improve(smallsteps);
364 }
365 
367 {
368  static int nFailWakeUpAttempts = runtimedef::get("SeqMinimizer_nFailWakeUpAttempts");
369 
370  // catch improve before minimize case
371  if (state_ == Cleared) return minimize(smallsteps);
372 
373  // setup default tolerances and steps
374  double ytol = Tolerance()/sqrt(workers_.size());
375  int bigsteps = MaxIterations()*20;
376 
377  // list of done workers (latest-done on top)
378  std::list<Worker*> doneWorkers;
379 
380  // start with active workers, for all except constants
381  foreach(Worker &w, workers_) {
382  if (w.state != Fixed) w.state = Active;
383  }
384 
385  state_ = Active;
386  for (int i = 0; i < bigsteps; ++i) {
387  DEBUG_SM_printf("Start of loop. Strategy %d, State is %s\n",fStrategy,(state_ == Done ? "DONE" : "ACTIVE"));
388  State newstate = Done;
389  int oldActiveWorkers = 0, newActiveWorkers = 0;
390  foreach(Worker &w, workers_) {
392  if (w.state == Done || w.state == Fixed) continue;
393  iret = w.improve(smallsteps,ytol);
394  oldActiveWorkers++;
395  if (iret == OneDimMinimizer::Unchanged) {
396  DEBUGV_SM_printf("\tMinimized %s: Unchanged. NLL = %.8f\n", w.cname(), func_->eval());
397  w.state = Done;
398  w.nUnaffected = 0;
399  doneWorkers.push_front(&w);
400  } else {
401  DEBUGV_SM_printf("\tMinimized %s: Changed. NLL = %.8f\n", w.cname(), func_->eval());
402  w.state = Active;
403  newstate = Active;
404  newActiveWorkers++;
405  }
406  }
407  if (fStrategy >= 2 && newActiveWorkers <= 30) { // arbitrary cut-off
408  DEBUG_SM_printf("Middle of loop. Strategy %d, active workers %d: firing full minimizer\n", fStrategy, newActiveWorkers);
409  if (doFullMinim()) newstate = Done;
410  }
411  if (newstate == Done) {
412  DEBUG_SM_printf("Middle of loop. Strategy %d, State is %s, active workers %d --> %d \n",fStrategy,(state_ == Done ? "DONE" : "ACTIVE"), oldActiveWorkers, newActiveWorkers);
413  oldActiveWorkers = 0; newActiveWorkers = 0;
414  double y0 = func_->eval();
415  std::list<Worker*>::iterator it = doneWorkers.begin();
416  // The topmost worker was added on the list just now, so by definition it's already done.
417  // We save a reference to it, remove it from the done list, and if the loop doesn't end there we set it to active again
418  Worker* firstWorker = *it;
419  it = doneWorkers.erase(it);
420  // Then we check all the others
421  while( it != doneWorkers.end()) {
422  Worker &w = **it;
423  if (nFailWakeUpAttempts && w.nUnaffected >= nFailWakeUpAttempts) { ++it; continue; }
424  OneDimMinimizer::ImproveRet iret = w.improve(smallsteps,ytol,0,/*force=*/true);
425  oldActiveWorkers++;
426  if (iret == OneDimMinimizer::Unchanged) {
427  DEBUGV_SM_printf("\tMinimized %s: Unchanged. NLL = %.8f\n", w.cname(), func_->eval());
428  w.nUnaffected++;
429  ++it;
430  } else {
431  DEBUGV_SM_printf("\tMinimized %s: Changed. NLL = %.8f\n", w.cname(), func_->eval());
432  w.state = Active;
433  newstate = Active;
434  w.nUnaffected = 0;
435  it = doneWorkers.erase(it);
436  newActiveWorkers++;
437  if (fStrategy == 0) break;
438  }
439  }
440  if (newstate == Active) { // wake up him too
441  firstWorker->state = Active;
442  firstWorker->nUnaffected = 0;
443  }
444  double y1 = func_->eval();
445  edm_ = y0 - y1;
446  }
447  DEBUG_SM_printf("End of loop. Strategy %d, State is %s, active workers %d --> %d \n",fStrategy,(state_ == Done ? "DONE" : "ACTIVE"), oldActiveWorkers, newActiveWorkers);
448  if (state_ == Done && newstate == Done) {
449  DEBUG_SM_printf("Converged after %d big steps\n",i);
450  minValue_ = func_->eval();
451  fStatus = 0;
452  return true;
453  }
454  state_ = newstate;
455  if (func_->nCalls > MaxFunctionCalls()) break;
456  }
457  DEBUG_SM_printf("Failed do converge after %d big steps\n",bigsteps);
458  fStatus = -1;
459  minValue_ = func_->eval();
460  return false;
461 }
462 
463 namespace cmsmath {
464  class SubspaceMultiGenFunction : public ROOT::Math::IMultiGenFunction {
465  public:
466  SubspaceMultiGenFunction(const ROOT::Math::IMultiGenFunction *f, int nDim, const int *idx, double *xi) :
467  f_(f), nDim_(nDim), idx_(idx), x_(xi) {}
468  virtual IBaseFunctionMultiDim * Clone() const { return new SubspaceMultiGenFunction(*this); }
469  virtual unsigned int NDim() const { return nDim_; }
470  private:
471  virtual double DoEval(const double * x) const {
472  for (int i = 0; i < nDim_; ++i) x_[idx_[i]] = x[i];
473  return (*f_)(x_);
474  }
475  const ROOT::Math::IMultiGenFunction *f_;
476  const int nDim_;
477  const int *idx_;
478  double *x_;
479  };
480 }
481 
483 {
484  if (fullMinimizer_.get() == 0) {
485  fullMinimizer_.reset(ROOT::Math::Factory::CreateMinimizer("Minuit2", ""));
486  fullMinimizer_->SetTolerance(Tolerance());
487  fullMinimizer_->SetStrategy(Strategy()-2);
488  }
489  subspaceIndices_.clear();
490  for (int i = 0, n = workers_.size(); i < n; ++i) {
491  if (workers_[i].state == Active) subspaceIndices_.push_back(i);
492  }
493  fullMinimizer_->Clear();
494  SubspaceMultiGenFunction subfunc(func_->func, subspaceIndices_.size(), &subspaceIndices_[0], &func_->x[0]);
495  fullMinimizer_->SetFunction(subfunc);
496  for (int i = 0, n = subspaceIndices_.size(); i < n; ++i) {
497  int j = subspaceIndices_[i];
498  Worker &w = workers_[j];
499  fullMinimizer_->SetLimitedVariable(i, w.name(), func_->x[j], w.step(), w.min(), w.max());
500  }
501  bool ok = fullMinimizer_->Minimize();
502  if (ok) {
503  const double *ximin = fullMinimizer_->X();
504  // move to the right place
505  for (int i = 0, n = subspaceIndices_.size(); i < n; ++i) {
506  func_->x[subspaceIndices_[i]] = ximin[i];
507  }
508  // update all workers
509  for (int i = 0, n = subspaceIndices_.size(); i < n; ++i) {
510  int j = subspaceIndices_[i];
511  Worker &w = workers_[j];
512  w.moveTo( ximin[i] );
513  }
514 
515  }
516  return ok;
517 }
518 
519 
520 #include <TPluginManager.h>
521 namespace {
522  static int load_seqmin() {
523  gPluginMgr->AddHandler("ROOT::Math::Minimizer", "SeqMinimizer", "cmsmath::SequentialMinimizer", "HiggsAnalysisCombinedLimit", "SequentialMinimizer(const char *)");
524  return 1;
525  }
526  static int loaded_seqmin = load_seqmin();
527 }
int i
Definition: DBlmapReader.cc:9
bool minimize(int steps=1, double ytol=0, double xtol=0)
not [yet] run
Definition: HLTenums.h:21
virtual bool SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double lower, double upper)
set upper/lower limited variable (override if minimizer supports them )
void seek()
search for a triplet of points bracketing the maximum. return false in case of errors ...
list step
Definition: launcher.py:15
bool minimize(int smallsteps=5)
int get(const char *name)
virtual double DoEval(const double *x) const
virtual bool Minimize()
method to perform the minimization
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)
set the function to minimize
#define assign
Definition: vmac.h:54
#define min(a, b)
Definition: mlp_lapack.h:161
void init(const MinimizerContext &ctx, unsigned int idx, double xmin, double xmax, double xstep, const std::string &name)
virtual bool SetVariable(unsigned int ivar, const std::string &name, double val, double step)
set free variable
void initDefault(const MinimizerContext &ctx, unsigned int idx)
const T & max(const T &a, const T &b)
ImproveRet improve(int steps=1, double ytol=0, double xtol=0, bool force=true)
T sqrt(T t)
Definition: SSEVec.h:46
const double infinity
virtual bool SetFixedVariable(unsigned int ivar, const std::string &name, double val)
set fixed variable (override if minimizer supports them )
int j
Definition: DBlmapReader.cc:9
double f[11][100]
bool improve(int smallsteps=5)
virtual void Clear()
reset for consecutive minimizations - implement if needed
const ROOT::Math::IMultiGenFunction * f_
const char * cname() const
virtual unsigned int NDim() const
SubspaceMultiGenFunction(const ROOT::Math::IMultiGenFunction *f, int nDim, const int *idx, double *xi)
bool doloop(int steps, double ytol, double xtol)
bool parabolaStep()
do the parabola fit
long long int num
Definition: procUtils.cc:71
Basic struct to call a function.
void goldenBisection()
do the golden bisection
char state
Definition: procUtils.cc:75
const std::string & name() const
#define DEBUGV_SM_printf
const double epsilon
Definition: DDAxes.h:10
#define DEBUG_ODM_printf
double parabolaFit()
do the parabola fit
virtual IBaseFunctionMultiDim * Clone() const
T w() const
#define DEBUG_SM_printf