I'm trying to implement the so-called golden-section optimization in C++. This is a simple algorithm to find an extremum of a univariate function \$f\$ within an interval \$[a,b]\$.
The crux is to write the code such that \$f\$ appears only once in the method body.
The code below is working but very far from elegant or optimal. Any ideas how to improve (reduce the number of lines and cases)?
#include <functional>
#include <math.h>
double Minimization(std::function<double(double)> f, double a, double b, double minstepwidth, int maxiterations)
{
double R = (sqrt(5.) - 1.) / 2.; // 1/golden ratio
double x1 = b + (a - b) * R;
double x2 = a + (b - a) * R;
double x,y, fx1 = 1E300, fx2 = 1E300;
int i = 0;
while (fabs(a - b) > minstepwidth && i < maxiterations)
{
if (fx1 == 1E300) // start detected
{
x = x1;
}
else if (fx2 == 1E300) // start detected
{
x = x2;
}
else if (fx1 < fx2)
{
b = x2;
x2 = x1;
x1 = b + (a - b) * R;
x = x1;
}
else
{
a = x1;
x1 = x2;
x2 = a + (b - a) * R;
x = x2;
}
y = f(x); // unique appearance
i++;
if (fx1 == 1E300)
{
fx1 = y;
}
else if (fx2 == 1E300)
{
fx2 = y;
}
else if (fx1 < fx2)
{
fx2 = fx1;
fx1 = y;
}
else
{
fx1 = fx2;
fx2 = y;
}
}
return (a + b) / 2.;
}
Addendum
Since everyone seems to be curious: Simplified, this C++ method (with float instead of double) is part of a larger code (running on the CPU) which needs an identical twin written in HLSL as a pixel shader (running on the GPU). The way \$f\$ is implemented (cannot be changed) increases the amount of shader instructions a lot every time \$f\$ appears in the HLSL code. Since both codes should be equal (for maintenance and to 100% return the same results) the constraint applies also for the C++ code.
