Belle II Software  release-08-01-10
minimizer.h
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #pragma once
10 
11 #include <vector>
12 #include <functional>
13 
14 
15 namespace Belle2 {
23  inline std::pair<double, double> getMinima(std::vector<std::vector<double>> vals, int i0, int j0)
24  {
25  int N = vals.size();
26  int Nzoom = (N + 1) / 2;
27 
28 
29  double minIn = std::numeric_limits<double>::max();
30  double minOut = std::numeric_limits<double>::max();
31 
32  for (int i = 0; i < N; ++i)
33  for (int j = 0; j < N; ++j) {
34  if ((i0 <= i && i < i0 + Nzoom) &&
35  (j0 <= j && j < j0 + Nzoom))
36  minIn = std::min(minIn, vals[i][j]);
37  else
38  minOut = std::min(minOut, vals[i][j]);
39  }
40  return {minIn, minOut};
41  }
42 
44  inline std::vector<double> getMinimum(std::function<double(double, double)> fun, double xMin, double xMax, double yMin, double yMax)
45  {
46  const int N = 17; //the grid has size N x N
47  const int Nzoom = (N + 1) / 2; // the size of the zoomed rectangle where minimum is
48 
49 
50  const int kMax = 35; //number of iterations
51 
52  std::vector<std::vector<double>> vals(N);
53  for (auto& v : vals) v.resize(N);
54 
55  for (int k = 0; k < kMax; ++k) {
56 
57  // get values of the function
58  for (int i = 0; i < N; ++i)
59  for (int j = 0; j < N; ++j) {
60  double x = xMin + i * (xMax - xMin) / (N - 1.);
61  double y = yMin + j * (yMax - yMin) / (N - 1.);
62  vals[i][j] = fun(x, y);
63  }
64 
65  if (k == kMax - 1) break;
66 
67  double mOutMax = - std::numeric_limits<double>::max();
68  int iOpt = -1, jOpt = -1;
69  //find optimal rectangle
70  for (int i = 0; i < N - Nzoom; ++i)
71  for (int j = 0; j < N - Nzoom; ++j) {
72  double mIn, mOut;
73  std::tie(mIn, mOut) = getMinima(vals, i, j);
74 
75  if (mOut > mOutMax) {
76  mOutMax = mOut;
77  iOpt = i;
78  jOpt = j;
79  }
80  }
81 
82  //Zoom to the optimal rectangle
83  // get values of the function
84 
85  double xMinNow = xMin + iOpt * (xMax - xMin) / (N - 1.);
86  double xMaxNow = xMin + (iOpt + Nzoom - 1) * (xMax - xMin) / (N - 1.);
87 
88  double yMinNow = yMin + jOpt * (yMax - yMin) / (N - 1.);
89  double yMaxNow = yMin + (jOpt + Nzoom - 1) * (yMax - yMin) / (N - 1.);
90 
91  xMin = xMinNow;
92  xMax = xMaxNow;
93  yMin = yMinNow;
94  yMax = yMaxNow;
95 
96  }
97 
98 
99  //get the overall minimum
100  double minTot = std::numeric_limits<double>::max();
101  int iOpt = -1, jOpt = -1;
102 
103  for (int i = 0; i < N; ++i)
104  for (int j = 0; j < N; ++j) {
105  if (vals[i][j] < minTot) {
106  minTot = vals[i][j];
107  iOpt = i;
108  jOpt = j;
109  }
110  }
111 
112  double xMinNow = xMin + iOpt * (xMax - xMin) / (N - 1.);
113  double yMinNow = yMin + jOpt * (yMax - yMin) / (N - 1.);
114 
115  return {xMinNow, yMinNow};
116  }
117 
119 }
std::pair< double, double > getMinima(std::vector< std::vector< double >> vals, int i0, int j0)
Get minimum inside and outside of the smaller window defined by i0, j0.
Definition: minimizer.h:23
std::vector< double > getMinimum(std::function< double(double, double)> fun, double xMin, double xMax, double yMin, double yMax)
Get minimum of 2D function in the rectangular domain defined by xMin,xMax & yMin,yMax.
Definition: minimizer.h:44
Abstract base class for different kinds of events.