Direct Graphical Models  v.1.7.0
Powell.cpp
1 #include "Powell.h"
2 #include "macroses.h"
3 
4 namespace DirectGraphicalModels
5 {
6  // Constructor
7  CPowell::CPowell(size_t nParams)
8  : m_nParams(nParams)
9  , m_vParams(nParams)
10  , m_vDeltas(nParams)
11  , m_vMin(nParams)
12  , m_vMax(nParams)
13  , m_vKappa(3)
14  , m_vConverged(nParams)
15  {
16  reset();
17  }
18 
19  void CPowell::reset(void)
20  {
21  m_paramID = 0; // first parameter
22  m_nSteps = 0;
23  m_koeff = 1.0f; // identity koefficient
24  m_acceleration = 0.1f; // default search acceleration
25 
26  std::fill(m_vParams.begin(), m_vParams.end(), 0.0f);
27  std::fill(m_vDeltas.begin(), m_vDeltas.end(), 0.1f);
28  std::fill(m_vMin.begin(), m_vMin.end(), -FLT_MAX);
29  std::fill(m_vMax.begin(), m_vMax.end(), FLT_MAX);
30  std::fill(m_vConverged.begin(), m_vConverged.end(), false);
31  std::fill(m_vKappa.begin(), m_vKappa.end(), -1.0f);
32  }
33 
34  void CPowell::setInitParams(const vec_float_t& vParams)
35  {
36  DGM_ASSERT_MSG(m_vParams.size() == vParams.size(), "The size of the argument (%zu) ddoes not correspond to the number of parameters (%zu)", vParams.size(), m_nParams);
37 
38  for (size_t p = 0; p < vParams.size(); p++) {
39  const float& param = vParams[p];
40  if (param > m_vMax[p]) {
41  DGM_WARNING("Argument[%zu]=%.2f exceeds the upper boundary %.2f and will not be set", p, param, m_vMax[p]);
42  continue;
43  }
44  if (param < m_vMin[p]) {
45  DGM_WARNING("Argument[%zu]=%.2f exceeds the lower boundary %.2f and will not be set", p, param, m_vMin[p]);
46  continue;
47  }
48  m_vParams[p] = param;
49  }
50  }
51 
52  void CPowell::setMinParams(const vec_float_t& vMinParam)
53  {
54  DGM_ASSERT_MSG(m_vMin.size() == vMinParam.size(), "The size of the argument (%zu) ddoes not correspond to the number of parameters (%zu)", vMinParam.size(), m_nParams);
55 
56  for (size_t p = 0; p < vMinParam.size(); p++) {
57  const float& minParam = vMinParam[p];
58  if (minParam > m_vParams[p]) DGM_WARNING("Argument[%zu]=%.2f contradicts the parameter value %.2f and will not be set", p, minParam, m_vParams[p]);
59  else m_vMin[p] =minParam;
60  }
61  }
62 
63  void CPowell::setMaxParams(const vec_float_t& vMaxParam)
64  {
65  DGM_ASSERT_MSG(m_vMax.size() == vMaxParam.size(), "The size of the argument (%zu) ddoes not correspond to the number of parameters (%zu)", vMaxParam.size(), m_nParams);
66 
67  for (size_t p = 0; p < vMaxParam.size(); p++) {
68  const float& maxParam = vMaxParam[p];
69  if (maxParam < m_vParams[p]) DGM_WARNING("Argument[%zu]=%.2f contradicts the parameter value %.2f and will not be set", p, maxParam, m_vParams[p]);
70  else m_vMax[p] = maxParam;
71  }
72  }
73 
74  void CPowell::setDeltas(const vec_float_t& vDeltas)
75  {
76  DGM_ASSERT_MSG(m_vDeltas.size() == vDeltas.size(), "The size of the argument (%zu) ddoes not correspond to the number of parameters (%zu)", vDeltas.size(), m_nParams);
77 
78  m_vDeltas = vDeltas;
79  }
80 
81  void CPowell::setAcceleration(float acceleration)
82  {
83  if (acceleration >= 0.0f) m_acceleration = acceleration;
84  else DGM_WARNING("Negative acceleration value was not set");
85  }
86 
87  vec_float_t CPowell::getParams(float kappa)
88  {
89  // Assertions
90  DGM_ASSERT_MSG(kappa > 0.0f, "Negative kappa values are not allowed");
91 
92 #ifdef DEBUG_PRINT_INFO
93  // Printing out the information
94  printf("[%zu]:\t", m_paramID);
95  for (float& param : m_vParams) printf("%.2f\t", param);
96  printf("%.2f\n", kappa);
97 #endif
98 
99  // If converged, no further steps are required
100  if (isConverged()) return m_vParams;
101 
102  // =============== Fill all 3 kappa values ===============
103  if (m_vKappa[oD] < 0) { m_vKappa[oD] = kappa; m_midPoint = curArg; }
104  else if (m_vKappa[mD] < 0) m_vKappa[mD] = kappa;
105  else if (m_vKappa[pD] < 0) m_vKappa[pD] = kappa;
106 
107  while (true) {
108  // Need kappa: -1
109  if (m_vKappa[mD] < 0) {
110  if (m_midPoint == minArg) m_vKappa[mD] = 0.0f;
111  else {
112  curArg = MAX(minArg, m_midPoint - m_koeff * delta);
113  return m_vParams;
114  }
115  }
116 
117  // Need kappa: +1
118  if (m_vKappa[pD] < 0) {
119  if (m_midPoint == maxArg) m_vKappa[pD] = 0.0f;
120  else {
121  curArg = MIN(maxArg, m_midPoint + m_koeff * delta);
122  return m_vParams;
123  }
124  }
125 
126  // =============== All 3 kappas are ready ===============
127  float maxKappa = *std::max_element(m_vKappa.begin(), m_vKappa.end());
128 
129  if (maxKappa == m_vKappa[oD]) { // >>>>> Middle value -> Proceed to the next argument
130  convArg = true;
131  curArg = m_midPoint;
132 
133  if (isConverged()) return m_vParams; // we have converged
134 
135  m_paramID = (m_paramID + 1) % m_nParams; // new argument
136 
137  // reset variabels for new argument
138  m_vKappa[mD] = -1;
139  m_vKappa[pD] = -1;
140  m_nSteps = 0;
141  m_koeff = 1.0;
142 
143  m_midPoint = curArg; // refresh the middle point
144  }
145  else if (maxKappa == m_vKappa[mD]) { // >>>>> Lower value -> Step argument down
146  std::fill(m_vConverged.begin(), m_vConverged.end(), false); // reset convergence
147 
148  m_midPoint = MAX(minArg, m_midPoint - m_koeff * delta); // refresh the middle point
149 
150  // shift kappa
151  m_vKappa[pD] = m_vKappa[oD];
152  m_vKappa[oD] = m_vKappa[mD];
153  m_vKappa[mD] = -1.0f;
154 
155  // increase the search step
156  m_nSteps++;
158  }
159  else if (maxKappa == m_vKappa[pD]) { // >>>>> Upper value -> Step argument up
160  std::fill(m_vConverged.begin(), m_vConverged.end(), false); // reset convergence
161 
162  m_midPoint = MIN(maxArg, m_midPoint + m_koeff * delta); // refresh the middle point
163 
164  // shift kappa
165  m_vKappa[mD] = m_vKappa[oD];
166  m_vKappa[oD] = m_vKappa[pD];
167  m_vKappa[pD] = -1.0f;
168 
169  // increase the search step
170  m_nSteps++;
172  }
173  } // infinite loop
174  }
175 
176  bool CPowell::isConverged(void) const
177  {
178  for (const bool& converged : m_vConverged) if (!converged) return false;
179  return true;
180  }
181 }
void setMinParams(const vec_float_t &vMinParam)
Sets the lower boundary for parameters (arguments) search.
Definition: Powell.cpp:52
void setDeltas(const vec_float_t &vDeltas)
Sets the searching steps along the parameters (arguments)
Definition: Powell.cpp:74
null Delta (current position)
Definition: Powell.h:132
CPowell(size_t nParams)
Constructor.
Definition: Powell.cpp:7
void setAcceleration(float acceleration)
Sets the acceleration coefficient.
Definition: Powell.cpp:81
vec_float_t getParams(float val)
Gets the updated parameters (arguments)
Definition: Powell.cpp:87
void setInitParams(const vec_float_t &vParams)
Sets the initial parameters (arguments) for the search algorithm.
Definition: Powell.cpp:34
bool isConverged(void) const
Indicates weather the method has converged.
Definition: Powell.cpp:176
void reset(void)
Resets class variables.
Definition: Powell.cpp:19
void setMaxParams(const vec_float_t &vMaxParam)
Sets the upper boundary for parameters (arguments) search.
Definition: Powell.cpp:63