Theoretica
A C++ numerical and automatic mathematical library
multi_extrema.h
Go to the documentation of this file.
1 
5 
6 #ifndef THEORETICA_MULTI_EXTREMA_H
7 #define THEORETICA_MULTI_EXTREMA_H
8 
9 #include "../core/constants.h"
10 #include "../autodiff/autodiff.h"
11 #include "./extrema.h"
12 
13 #include <functional>
14 
15 
16 namespace theoretica {
17 
18 
31  template<unsigned int N>
33  multidual<N>(*f)(vec<multidual<N>, N>),
34  vec<real, N> guess = vec<real, N>(0),
37  unsigned int max_iter = OPTIMIZATION_MINGRAD_ITER) {
38 
39  if(gamma >= 0) {
40  TH_MATH_ERROR("multi_minimize_grad", gamma, INVALID_ARGUMENT);
41  return vec<real, N>(nan());
42  }
43 
44  vec<real, N> x = guess;
45  vec<real, N> grad;
46  unsigned int iter = 0;
47 
48  do {
49 
50  grad = gradient(f, x);
51  x += gamma * grad;
52  iter++;
53 
54  } while(grad.norm() > OPTIMIZATION_MINGRAD_TOLERANCE && iter <= max_iter);
55 
56  if(iter > max_iter) {
57  TH_MATH_ERROR("multi_minimize_grad", iter, NO_ALGO_CONVERGENCE);
58  return vec<real, N>(nan());
59  }
60 
61  return x;
62  }
63 
64 
77  template<unsigned int N>
79  multidual<N>(*f)(vec<multidual<N>, N>),
80  vec<real, N> guess = vec<real, N>(0),
83  unsigned int max_iter = OPTIMIZATION_MINGRAD_ITER) {
84 
85  return multi_minimize_grad(f, guess, -gamma, tolerance, max_iter);
86  }
87 
88 
100  template<unsigned int N>
102  multidual<N>(*f)(vec<multidual<N>, N>),
103  vec<real, N> guess = vec<real, N>(0),
105  unsigned int max_iter = OPTIMIZATION_MINGRAD_ITER) {
106 
107  vec<real, N> x = guess;
108  vec<real, N> grad;
109  unsigned int iter = 0;
110 
111  do {
112 
113  grad = autodiff::gradient(f, x);
114 
115  // Minimize f(x + gamma * gradient) in [-1, 0]
116  // using Golden Section extrema search
118  [f, x, grad](real gamma){
119  return f(multidual<N>::make_argument(x + gamma * grad)).Re();
120  }, -1, 0);
121 
122  // Fallback value
123  if(-gamma <= MACH_EPSILON)
125 
126  x += gamma * grad;
127  iter++;
128 
129  } while(grad.norm() > OPTIMIZATION_MINGRAD_TOLERANCE && iter <= max_iter);
130 
131  if(iter > max_iter) {
132  TH_MATH_ERROR("multi_minimize_lingrad", iter, NO_ALGO_CONVERGENCE);
133  return vec<real, N>(nan());
134  }
135 
136  return x;
137  }
138 
139 
151  template<unsigned int N>
153  multidual<N>(*f)(vec<multidual<N>, N>),
154  vec<real, N> guess = vec<real, N>(0),
156  unsigned int max_iter = OPTIMIZATION_MINGRAD_ITER) {
157 
158  vec<real, N> x = guess;
159  vec<real, N> grad;
160  unsigned int iter = 0;
161 
162  do {
163 
164  grad = -gradient(f, x);
165 
166  // Maximize f(x + gamma * gradient) in [-1, 0]
167  // using Golden Section extrema search
169  [f, x, grad](real gamma){
170  return f(multidual<N>::make_argument(x + gamma * grad)).Re();
171  }, -1, 0);
172 
173  // Fallback value
174  if(-gamma <= MACH_EPSILON)
176 
177  x += gamma * grad;
178  iter++;
179 
180  } while(grad.norm() > OPTIMIZATION_MINGRAD_TOLERANCE && iter <= max_iter);
181 
182  if(iter > max_iter) {
183  TH_MATH_ERROR("multi_maximize_lingrad", iter, NO_ALGO_CONVERGENCE);
184  return vec<real, N>(nan());
185  }
186 
187  return x;
188  }
189 
190 
200  template<unsigned int N>
202  multidual<N>(*f)(vec<multidual<N>, N>),
204 
205  return multi_minimize_lingrad(f, guess, tolerance);
206  }
207 
208 
218  template<unsigned int N>
220  multidual<N>(*f)(vec<multidual<N>, N>),
222 
223  return multi_maximize_lingrad<N>(f, guess, tolerance);
224  }
225 
226 }
227 
228 
229 #endif
Multidual number algebra for functions of the form .
Definition: multidual.h:26
A statically allocated N-dimensional vector with elements of the given type.
Definition: vec.h:88
Type norm() const
Compute the norm of the vector (sqrt(v * v))
Definition: vec.h:292
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition: error.h:219
Extrema approximation of real functions.
auto gradient(Function f, const Vector &x)
Compute the gradient for a given of a scalar field of the form using automatic differentiation.
Definition: autodiff.h:148
real gamma(unsigned int k)
Gamma special function of positive integer argument.
Definition: special.h:23
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:188
vec< real, N > multi_maximize_lingrad(multidual< N >(*f)(vec< multidual< N >, N >), vec< real, N > guess=vec< real, N >(0), real tolerance=OPTIMIZATION_MINGRAD_TOLERANCE, unsigned int max_iter=OPTIMIZATION_MINGRAD_ITER)
Find a local maximum of the given multivariate function using gradient descent with linear search.
Definition: multi_extrema.h:152
vec< real, N > multi_minimize_grad(multidual< N >(*f)(vec< multidual< N >, N >), vec< real, N > guess=vec< real, N >(0), real gamma=OPTIMIZATION_MINGRAD_GAMMA, real tolerance=OPTIMIZATION_MINGRAD_TOLERANCE, unsigned int max_iter=OPTIMIZATION_MINGRAD_ITER)
Find a local minimum of the given multivariate function using fixed-step gradient descent.
Definition: multi_extrema.h:32
constexpr real OPTIMIZATION_MINGRAD_TOLERANCE
Default tolerance for gradient descent minimization.
Definition: constants.h:308
vec< real, N > multi_maximize_grad(multidual< N >(*f)(vec< multidual< N >, N >), vec< real, N > guess=vec< real, N >(0), real gamma=OPTIMIZATION_MINGRAD_GAMMA, real tolerance=OPTIMIZATION_MINGRAD_TOLERANCE, unsigned int max_iter=OPTIMIZATION_MINGRAD_ITER)
Find a local maximum of the given multivariate function using fixed-step gradient descent.
Definition: multi_extrema.h:78
constexpr unsigned int OPTIMIZATION_MINGRAD_ITER
Maximum number of iterations for gradient descent minimization.
Definition: constants.h:311
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition: constants.h:197
real maximize_goldensection(RealFunction f, real a, real b)
Approximate a function maximum using the Golden Section search algorithm.
Definition: extrema.h:24
real minimize_goldensection(RealFunction f, real a, real b)
Approximate a function minimum using the Golden Section search algorithm.
Definition: extrema.h:69
vec< real, N > multi_minimize(multidual< N >(*f)(vec< multidual< N >, N >), vec< real, N > guess=vec< real, N >(0), real tolerance=OPTIMIZATION_MINGRAD_TOLERANCE)
Use the best available algorithm to find a local minimum of the given multivariate function.
Definition: multi_extrema.h:201
vec< real, N > multi_minimize_lingrad(multidual< N >(*f)(vec< multidual< N >, N >), vec< real, N > guess=vec< real, N >(0), real tolerance=OPTIMIZATION_MINGRAD_TOLERANCE, unsigned int max_iter=OPTIMIZATION_MINGRAD_ITER)
Find a local minimum of the given multivariate function using gradient descent with linear search.
Definition: multi_extrema.h:101
real nan()
Return a quiet NaN number in floating point representation.
Definition: error.h:54
constexpr real OPTIMIZATION_MINGRAD_GAMMA
Default step size for gradient descent minimization.
Definition: constants.h:305
vec< real, N > multi_maximize(multidual< N >(*f)(vec< multidual< N >, N >), vec< real, N > guess=vec< real, N >(0), real tolerance=OPTIMIZATION_MINGRAD_TOLERANCE)
Use the best available algorithm to find a local maximum of the given multivariate function.
Definition: multi_extrema.h:219