- Added maximization features, with corresponding plugins. Added painting feature...
[mldemos:mldemos.git] / _3rdParty / dlib / optimization / optimization_line_search_abstract.h
1 // Copyright (C) 2008  Davis E. King (davis@dlib.net)\r
2 // License: Boost Software License   See LICENSE.txt for the full license.\r
3 #undef DLIB_OPTIMIZATIOn_ABSTRACT_\r
4 #ifdef DLIB_OPTIMIZATIOn_ABSTRACT_\r
5 \r
6 #include <cmath>\r
7 #include <limits>\r
8 #include "../matrix/matrix_abstract.h"\r
9 #include "../algs.h"\r
10 \r
11 \r
12 namespace dlib\r
13 {\r
14 \r
15 // ----------------------------------------------------------------------------------------\r
16 \r
17     template <\r
18         typename funct, \r
19         typename T\r
20         >\r
21     class line_search_funct; \r
22     /*!\r
23         This object is a function object that represents a line search function.\r
24 \r
25         Moreover, it represents a function with the signature:\r
26             double l(double x)\r
27     !*/\r
28 \r
29     template <\r
30         typename funct, \r
31         typename T\r
32         >\r
33     const line_search_funct<funct,T> make_line_search_function (\r
34         const funct& f, \r
35         const T& start, \r
36         const T& direction\r
37     ); \r
38     /*!\r
39         requires\r
40             - is_col_vector(start) && is_col_vector(direction) && start.size() == direction.size() \r
41               (i.e. start and direction should be column vectors of the same size)\r
42             - f must return either a double or a column vector the same length as start\r
43             - f(start + 1.5*direction) should be a valid expression\r
44         ensures\r
45             - if (f returns a double) then\r
46                 - returns a line search function that computes l(x) == f(start + x*direction)\r
47             - else\r
48                 - returns a line search function that computes l(x) == dot(f(start + x*direction),direction).\r
49                   That is, we assume f is the derivative of some other function and that what\r
50                   f returns is a gradient vector. \r
51                   So the following two expressions both create the derivative of l(x): \r
52                     - derivative(make_line_search_function(funct,start,direction))\r
53                     - make_line_search_function(derivative(funct),start,direction)\r
54     !*/\r
55 \r
56     template <\r
57         typename funct, \r
58         typename T\r
59         >\r
60     const line_search_funct<funct,T> make_line_search_function (\r
61         const funct& f, \r
62         const T& start, \r
63         const T& direction,\r
64         double& f_out\r
65     ); \r
66     /*!\r
67         This function is identical to the above three argument version of make_line_search_function() \r
68         except that, if f() outputs a double, every time f() is evaluated its output is also stored \r
69         into f_out.\r
70     !*/\r
71 \r
72     template <\r
73         typename funct, \r
74         typename T\r
75         >\r
76     const line_search_funct<funct,T> make_line_search_function (\r
77         const funct& f, \r
78         const T& start, \r
79         const T& direction,\r
80         T& gradient_out\r
81     ); \r
82     /*!\r
83         This function is identical to the above three argument version of make_line_search_function() \r
84         except that, if f() outputs a column vector, every time f() is evaluated its output is also \r
85         stored into gradient_out.\r
86     !*/\r
87 \r
88 // ----------------------------------------------------------------------------------------\r
89 \r
90     inline double poly_min_extrap (\r
91         double f0,\r
92         double d0,\r
93         double f1,\r
94         double d1\r
95     );\r
96     /*!\r
97         ensures\r
98             - let c(x) be a 3rd degree polynomial such that:\r
99                 - c(0) == f0\r
100                 - c(1) == f1\r
101                 - derivative of c(x) at x==0 is d0\r
102                 - derivative of c(x) at x==1 is d1\r
103             - returns the point in the range [0,1] that minimizes the polynomial c(x) \r
104     !*/\r
105 \r
106 // ----------------------------------------------------------------------------------------\r
107 \r
108     inline double lagrange_poly_min_extrap (\r
109         double p1, \r
110         double p2,\r
111         double p3,\r
112         double f1,\r
113         double f2,\r
114         double f3\r
115     );\r
116     /*!\r
117         requires\r
118             - f1 >= f2 <= f3\r
119             - p1 < p2 < p3\r
120         ensures\r
121             - let c(x) be the second order Lagrange polynomial that interpolates the\r
122               points p1, p2, and p3 where c(p1)==f1, c(p2)==f2, and c(p3)==f3\r
123             - this function returns the point in the range [p1,p3] that minimizes \r
124               the polynomial c(x) \r
125     !*/\r
126 \r
127 // ----------------------------------------------------------------------------------------\r
128 \r
129     template <\r
130         typename funct, \r
131         typename funct_der\r
132         >\r
133     double line_search (\r
134         const funct& f, \r
135         const double f0,\r
136         const funct_der& der, \r
137         const double d0,\r
138         double rho, \r
139         double sigma, \r
140         double min_f,\r
141         unsigned long max_iter\r
142     )\r
143     /*!\r
144         requires\r
145             - 0 < rho < sigma < 1\r
146             - f and der are scalar functions of scalars\r
147               (e.g. line_search_funct objects)\r
148             - der is the derivative of f\r
149             - f0 == f(0)\r
150             - d0 == der(0)\r
151             - max_iter > 0\r
152         ensures\r
153             - Performs a line search and uses the strong Wolfe conditions to decide when\r
154               the search can stop.  \r
155                 - rho == the parameter of the Wolfe sufficient decrease condition\r
156                 - sigma == the parameter of the Wolfe curvature condition\r
157                 - max_iter == the maximum number of iterations allowable.  After this\r
158                   many evaluations of f() line_search() is guaranteed to terminate.\r
159             - returns a value alpha such that f(alpha) is significantly closer to \r
160               the minimum of f than f(0).\r
161             - It is assumed that the minimum possible value of f(x) is min_f.  So if\r
162               an alpha is found such that f(alpha) <= min_f then the search stops\r
163               immediately.\r
164             - This function is also optimized for the case where der(0) is negative.  I.e.\r
165               positive values of the argument to f() should be in a descent direction.  \r
166             - When this function makes calls to f() and der() it always does so by\r
167               first calling f() and then calling der().  That is, these two functions\r
168               are always called in pairs with f() being called first and then der()\r
169               being called second.\r
170     !*/\r
171 \r
172     /*\r
173         A good discussion of the Wolfe conditions and line search algorithms in \r
174         general can be found in the book Practical Methods of Optimization by R. Fletcher\r
175         and also in the more recent book Numerical Optimization by Nocedal and Wright.\r
176     */\r
177 \r
178 // ----------------------------------------------------------------------------------------\r
179 \r
180     class optimize_single_variable_failure : public error;\r
181     /*!\r
182         This is the exception class used by the functions defined below.\r
183     !*/\r
184 \r
185 // ----------------------------------------------------------------------------------------\r
186 \r
187     template <\r
188         typename funct\r
189         >\r
190     double find_min_single_variable (\r
191         const funct& f,\r
192         double& starting_point,\r
193         const double begin = -1e200,\r
194         const double end = 1e200,\r
195         const double eps = 1e-3,\r
196         const long max_iter = 100\r
197     )\r
198     /*!\r
199         requires\r
200             - eps > 0\r
201             - max_iter > 1\r
202             - begin <= starting_point <= end\r
203             - f must be a function of a double that returns a double\r
204               (e.g. f(starting_point) should be a valid expression that evaluates to a double)\r
205         ensures\r
206             - Finds a point P such that:\r
207                 - P is a local minimum of the function f().   \r
208                 - begin <= P <= end\r
209             - Evaluates f() no more than max_iter times\r
210             - Stops searching when the window around the minimum point is smaller than eps.\r
211               The search will begin with the given starting_point.\r
212             - #starting_point == P\r
213             - returns f(P)\r
214         throws\r
215             - optimize_single_variable_failure \r
216                 This exception is thrown if max_iter iterations are performed without \r
217                 determining the min point to the requested accuracy of eps.\r
218     !*/\r
219 \r
220 // ----------------------------------------------------------------------------------------\r
221 \r
222     template <\r
223         typename funct\r
224         >\r
225     double find_max_single_variable (\r
226         const funct& f,\r
227         double& starting_point,\r
228         const double begin = -1e200,\r
229         const double end = 1e200,\r
230         const double eps = 1e-3,\r
231         const long max_iter = 100\r
232     )\r
233     /*!\r
234         requires\r
235             - eps > 0\r
236             - max_iter > 1\r
237             - begin <= starting_point <= end\r
238             - f must be a function of a double that returns a double\r
239               (e.g. f(starting_point) should be a valid expression that evaluates to a double)\r
240         ensures\r
241             - Finds a point P such that:\r
242                 - P is a local maximum of the function f().   \r
243                 - begin <= P <= end\r
244             - Evaluates f() no more than max_iter times\r
245             - Stops searching when the window around the minimum point is smaller than eps.\r
246               The search will begin with the given starting_point.\r
247             - #starting_point == P\r
248             - returns f(P)\r
249         throws\r
250             - optimize_single_variable_failure \r
251                 This exception is thrown if max_iter iterations are performed without \r
252                 determining the max point to the requested accuracy of eps.\r
253     !*/\r
254 \r
255 // ----------------------------------------------------------------------------------------\r
256 \r
257 }\r
258 \r
259 #endif // DLIB_OPTIMIZATIOn_ABSTRACT_\r
260 \r