Belle II Software development
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
15namespace 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.