Theoretica
Mathematical Library
Loading...
Searching...
No Matches
extrema.h
Go to the documentation of this file.
1
5
6#ifndef THEORETICA_EXTREMA_H
7#define THEORETICA_EXTREMA_H
8
9#include "../core/constants.h"
10#include "./roots.h"
11
12
13namespace theoretica {
14
15
23 template<typename RealFunction>
24 inline iter_result<real> maximize_golden(
25 RealFunction f, real a, real b,
26 real tolerance = OPTIMIZATION_TOL,
27 unsigned int max_iter = OPTIMIZATION_GOLDENSECTION_ITER) {
28
29 if(a > b) {
30 TH_MATH_ERROR("maximize_golden", b, MathError::InvalidArgument);
31 return iter_result<real>(ConvergenceStatus::InvalidInput);
32 }
33
34 real x1 = a;
35 real x2 = b;
36 real x3 = b - (b - a) / PHI;
37 real x4 = a + (b - a) / PHI;
38
39 unsigned int iter = 0;
40
41 // Keep iterating until the bracketing interval is closer than the tolerance,
42 // or until the maximum number of iterations is reached.
43 while(abs(x2 - x1) > tolerance && iter <= max_iter) {
44
45 if(f(x3) > f(x4)) {
46 x2 = x4;
47 } else {
48 x1 = x3;
49 }
50
51 x3 = x2 - (x2 - x1) / PHI;
52 x4 = x1 + (x2 - x1) / PHI;
53
54 iter++;
55 }
56
57 if(iter > max_iter) {
58 TH_MATH_ERROR("maximize_golden", iter, MathError::NoConvergence);
59 return iter_result<real>(ConvergenceStatus::MaxIterations, iter, abs(x2 - x1) / 2.0);
60 }
61
62 return iter_result<real>((x2 + x1) / 2.0, iter, abs(x2 - x1) / 2.0);
63 }
64
65
73 template<typename RealFunction>
74 inline iter_result<real> minimize_goldensection(
75 RealFunction f, real a, real b,
76 real tolerance = OPTIMIZATION_TOL,
77 unsigned int max_iter = OPTIMIZATION_GOLDENSECTION_ITER) {
78
79 if(a > b) {
80 TH_MATH_ERROR("minimize_goldensection", b, MathError::InvalidArgument);
81 return iter_result<real>(ConvergenceStatus::InvalidInput);
82 }
83
84 real x1 = a;
85 real x2 = b;
86 real x3 = b - (b - a) / PHI;
87 real x4 = a + (b - a) / PHI;
88
89 unsigned int iter = 0;
90
91 while(abs(x2 - x1) > tolerance && iter <= max_iter) {
92
93 if(f(x3) < f(x4)) {
94 x2 = x4;
95 } else {
96 x1 = x3;
97 }
98
99 x3 = x2 - (x2 - x1) / PHI;
100 x4 = x1 + (x2 - x1) / PHI;
101
102 iter++;
103 }
104
105 if(iter > max_iter) {
106 TH_MATH_ERROR("minimize_goldensection", iter, MathError::NoConvergence);
107 return iter_result<real>(ConvergenceStatus::MaxIterations, iter, abs(x2 - x1) / 2.0);
108 }
109
110 return iter_result<real>((x2 + x1) / 2.0, iter, abs(x2 - x1) / 2.0);
111 }
112
113
123 template<typename RealFunction>
124 inline iter_result<real> maximize_newton(
125 RealFunction f, RealFunction Df, RealFunction D2f,
126 real guess = 0.0, real tolerance = OPTIMIZATION_TOL,
127 unsigned int max_iter = OPTIMIZATION_NEWTON_ITER) {
128
129 iter_result<real> z = root_newton(Df, D2f, guess, tolerance, max_iter);
130
131 if(D2f(z) < 0) {
132
133 TH_MATH_ERROR("maximize_newton", z, MathError::NoConvergence);
134
135 // If the root finding algorithm converged but found a solution
136 // with the wrong concavity (minimum instead of maximum),
137 // mark the status as diverged.
138 return iter_result<real>(
140 z.iterations,
141 z.residual
142 );
143 }
144
145 return iter_result<real>(z, z.iterations, z.residual);
146 }
147
148
158 template<typename RealFunction>
159 inline iter_result<real> minimize_newton(
160 RealFunction f, RealFunction Df,
161 RealFunction D2f, real guess = 0,
162 real tolerance = OPTIMIZATION_TOL,
163 unsigned int max_iter = OPTIMIZATION_NEWTON_ITER) {
164
165 iter_result<real> z = root_newton(Df, D2f, guess, tolerance, max_iter);
166
167 if(D2f(z) > 0) {
168
169 TH_MATH_ERROR("minimize_newton", z, MathError::NoConvergence);
170
171 // If the root finding algorithm converged but found a solution
172 // with the wrong concavity (maximum instead of minimum),
173 // mark the status as diverged.
174 return iter_result<real>(
176 z.iterations,
177 z.residual
178 );
179 }
180
181 return iter_result<real>(z, z.iterations, z.residual);
182 }
183
184
194 template<typename RealFunction>
195 inline iter_result<real> maximize_bisection(
196 RealFunction f, RealFunction Df,
197 real a, real b,
198 real tolerance = OPTIMIZATION_TOL,
199 unsigned int max_iter = OPTIMIZATION_BISECTION_ITER) {
200
201 iter_result<real> z = root_bisect(Df, a, b, tolerance, max_iter);
202
203 // Approximate the function concavity
204 if(deriv_central(Df, z) < 0) {
205
206 TH_MATH_ERROR("maximize_bisection", z, MathError::NoConvergence);
207
208 // If the root finding algorithm converged but found a solution
209 // with the wrong concavity (minimum instead of maximum),
210 // mark the status as diverged.
211 return iter_result<real>(
213 z.iterations,
214 z.residual
215 );
216 }
217
218 return iter_result<real>(z, z.iterations, z.residual);
219 }
220
221
231 template<typename RealFunction>
232 inline iter_result<real> minimize_bisect(
233 RealFunction f, RealFunction Df, real a, real b,
234 real tolerance = OPTIMIZATION_TOL,
235 unsigned int max_iter = OPTIMIZATION_BISECTION_ITER) {
236
237 iter_result<real> z = root_bisect(Df, a, b, tolerance, max_iter);
238
239 // Approximate the function concavity
240 if(deriv_central(Df, z) > 0) {
241
242 TH_MATH_ERROR("minimize_bisect", z, MathError::NoConvergence);
243
244 // If the root finding algorithm converged but found a solution
245 // with the wrong concavity (maximum instead of minimum),
246 // mark the status as diverged.
247 return iter_result<real>(
249 z.iterations,
250 z.residual
251 );
252 }
253
254 return iter_result<real>(z, z.iterations, z.residual);
255 }
256
257}
258
259#endif
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compilation op...
Definition error.h:238
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
double real
A real number, defined as a floating point type.
Definition constants.h:207
iter_result< real > maximize_golden(RealFunction f, real a, real b, real tolerance=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_GOLDENSECTION_ITER)
Approximate a function maximum using the Golden Section search algorithm.
Definition extrema.h:24
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:198
constexpr real OPTIMIZATION_TOL
Approximation tolerance for root finding.
Definition constants.h:297
constexpr unsigned int OPTIMIZATION_GOLDENSECTION_ITER
Maximum number of iterations for the golden section search algorithm.
Definition constants.h:303
iter_result< real > maximize_newton(RealFunction f, RealFunction Df, RealFunction D2f, real guess=0.0, real tolerance=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_NEWTON_ITER)
Approximate a function maximum given the function and its first two derivatives using Newton-Raphson'...
Definition extrema.h:124
iter_result< real > minimize_newton(RealFunction f, RealFunction Df, RealFunction D2f, real guess=0, real tolerance=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_NEWTON_ITER)
Approximate a function minimum given the function and its first two derivatives using Newton-Raphson'...
Definition extrema.h:159
iter_result< real > root_bisect(RealFunction f, real a, real b, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_BISECTION_ITER)
Find the root of a univariate real function using bisection inside a compact interval [a,...
Definition roots.h:61
iter_result< real > minimize_goldensection(RealFunction f, real a, real b, real tolerance=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_GOLDENSECTION_ITER)
Approximate a function minimum using the Golden Section search algorithm.
Definition extrema.h:74
@ InvalidArgument
Invalid argument.
@ NoConvergence
Algorithm did not converge.
real deriv_central(RealFunction f, real x, real h=CALCULUS_DERIV_STEP)
Approximate the first derivative of a real function using the central method.
Definition deriv.h:73
constexpr unsigned int OPTIMIZATION_BISECTION_ITER
Maximum number of iterations for the bisection algorithm.
Definition constants.h:300
constexpr unsigned int OPTIMIZATION_NEWTON_ITER
Maximum number of iterations for the Newton-Raphson algorithm.
Definition constants.h:309
constexpr real PHI
The Phi (Golden Section) mathematical constant.
Definition constants.h:219
iter_result< real > root_newton(RealFunction f, RealFunction Df, real guess=0.0, real tol=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_NEWTON_ITER)
Find a root of a univariate real function using Newton's method.
Definition roots.h:220
@ Success
Algorithm converged successfully.
@ Diverged
Algorithm diverged.
@ MaxIterations
Maximum iterations exceeded.
@ InvalidInput
Invalid input provided.
iter_result< real > maximize_bisection(RealFunction f, RealFunction Df, real a, real b, real tolerance=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_BISECTION_ITER)
Approximate a function maximum inside an interval given the function and its first derivative using b...
Definition extrema.h:195
iter_result< real > minimize_bisect(RealFunction f, RealFunction Df, real a, real b, real tolerance=OPTIMIZATION_TOL, unsigned int max_iter=OPTIMIZATION_BISECTION_ITER)
Approximate a function minimum inside an interval given the function and its first derivative using b...
Definition extrema.h:232
Root approximation of real functions.