TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
golden_search_extrema.cpp
Go to the documentation of this file.
1
10#define _USE_MATH_DEFINES //< required for MS Visual C++
11#include <cassert>
12#include <cmath>
13#include <cstdint>
14#include <functional>
15#include <iostream>
16#include <limits>
17
18#define EPSILON 1e-7
19
30double get_minima(const std::function<double(double)> &f, double lim_a,
31 double lim_b) {
32 uint32_t iters = 0;
33 double c, d;
34 double prev_mean, mean = std::numeric_limits<double>::infinity();
35
36 // golden ratio value
37 const double M_GOLDEN_RATIO = (1.f + std::sqrt(5.f)) / 2.f;
38
39 // ensure that lim_a < lim_b
40 if (lim_a > lim_b) {
41 std::swap(lim_a, lim_b);
42 } else if (std::abs(lim_a - lim_b) <= EPSILON) {
43 std::cerr << "Search range must be greater than " << EPSILON << "\n";
44 return lim_a;
45 }
46
47 do {
48 prev_mean = mean;
49
50 // compute the section ratio width
51 double ratio = (lim_b - lim_a) / M_GOLDEN_RATIO;
52 c = lim_b - ratio; // right-side section start
53 d = lim_a + ratio; // left-side section end
54
55 if (f(c) < f(d)) {
56 // select left section
57 lim_b = d;
58 } else {
59 // selct right section
60 lim_a = c;
61 }
62
63 mean = (lim_a + lim_b) / 2.f;
64 iters++;
65
66 // continue till the interval width is greater than sqrt(system epsilon)
67 } while (std::abs(lim_a - lim_b) > EPSILON);
68
69 std::cout << " (iters: " << iters << ") ";
70 return prev_mean;
71}
72
79void test1() {
80 // define the function to minimize as a lambda function
81 std::function<double(double)> f1 = [](double x) {
82 return (x - 2) * (x - 2);
83 };
84
85 std::cout << "Test 1.... ";
86
87 double minima = get_minima(f1, 1, 5);
88
89 std::cout << minima << "...";
90
91 assert(std::abs(minima - 2) < EPSILON);
92 std::cout << "passed\n";
93}
94
101void test2() {
102 // define the function to maximize as a lambda function
103 // since we are maximixing, we negated the function return value
104 std::function<double(double)> func = [](double x) {
105 return -std::pow(x, 1.f / x);
106 };
107
108 std::cout << "Test 2.... ";
109
110 double minima = get_minima(func, -2, 10);
111
112 std::cout << minima << " (" << M_E << ")...";
113
114 assert(std::abs(minima - M_E) < EPSILON);
115 std::cout << "passed\n";
116}
117
124void test3() {
125 // define the function to maximize as a lambda function
126 // since we are maximixing, we negated the function return value
127 std::function<double(double)> func = [](double x) { return std::cos(x); };
128
129 std::cout << "Test 3.... ";
130
131 double minima = get_minima(func, -4, 12);
132
133 std::cout << minima << " (" << M_PI << ")...";
134
135 assert(std::abs(minima - M_PI) < EPSILON);
136 std::cout << "passed\n";
137}
138
140int main() {
141 std::cout.precision(9);
142
143 std::cout << "Computations performed with machine epsilon: " << EPSILON
144 << "\n";
145
146 test1();
147 test2();
148 test3();
149
150 return 0;
151}
#define EPSILON
solution accuracy limit
void test2()
Test function to find maxima for the function in the interval Expected result: .
void test1()
Test function to find minima for the function in the interval Expected result = 2.
double get_minima(const std::function< double(double)> &f, double lim_a, double lim_b)
Get the minima of a function in the given interval. To get the maxima, simply negate the function....
void test3()
Test function to find maxima for the function in the interval Expected result: .