primatologist-gpl 6.0.4
wolfe_d.h
Go to the documentation of this file.
1/* Copyright (C) 2000-2013 CEA
2 *
3 * This software and supporting documentation were developed by
4 * bioPICSEL
5 * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6 * 18, route du Panorama
7 * 92265 Fontenay-aux-Roses
8 * France
9 */
10
11#ifndef PRIMATOLOGIST_OPTIMIZATION_WOLFE_D_H
12#define PRIMATOLOGIST_OPTIMIZATION_WOLFE_D_H
13
15#include <cmath> // std::abs
16#include <iostream> // std::cout / std::endl
17#include <iomanip> // std::setw / std::setprecision
18#include <string> // std::string
19
20namespace aims {
21
22 //--------------------------------------------------------------------------
23 // CONSTRUCTOR / DESTRUCTOR / COPY
24 //--------------------------------------------------------------------------
25
26 template <typename O>
28 const Vector & x,
29 const Vector & p ):
30 _f(f),
31 _x(x),
32 _p(p)
33 {
34 setC1();
35 setC2();
39 setVerbose();
40 }
41
42 template <typename O>
44 _f(other._f),
45 _x(other._x),
46 _p(other._p),
47 _c1(other._c1),
48 _c2(other._c2),
49 _strong(other._strong),
50 _maximize(other._maximize),
51 _max_it(other._max_it),
52 _verbose(other._verbose),
56 {}
57
58 template <typename O>
61
62 template <typename O>
65 {
66 if( this != &other )
67 {
68 _f = other._f;
69 _x = other._x;
70 _p = other._p;
71 _c1 = other._c1;
72 _c2 = other._c2;
73 _strong = other._strong;
74 _maximize = other._maximize;
75 _max_it = other._max_it;
76 _verbose = other._verbose;
80 }
81 return *this;
82 }
83
84 //--------------------------------------------------------------------------
85 // SET PARAMETERS
86 //--------------------------------------------------------------------------
87 template <typename O>
89 {
90 _c1 = c1;
91 }
92
93 template <typename O>
95 {
96 _c2 = c2;
97 }
98
99 template <typename O>
101 {
102 _x = x;
103 }
104
105 template <typename O>
107 {
108 _p = p;
109 }
110
111 template <typename O>
113 {
114 _f = f;
115 }
116
117 template <typename O>
119 {
120 _strong = strong;
121 }
122
123 template <typename O>
125 {
126 _verbose = v;
127 }
128
129 template <typename O>
134
135 template <typename O>
137 {
138 _max_it = n;
139 }
140
141 //--------------------------------------------------------------------------
142 // GET PARAMETERS
143 //--------------------------------------------------------------------------
144
145 template <typename O>
147 {
148 return _c1;
149 }
150
151 template <typename O>
153 {
154 return _c2;
155 }
156
157 template <typename O>
158 const typename WolfeLineSearch<O>::Vector &
160 {
161 return _x;
162 }
163
164 template <typename O>
165 const typename WolfeLineSearch<O>::Vector &
167 {
168 return _p;
169 }
170
171 template <typename O>
172 const typename WolfeLineSearch<O>::Objective &
174 {
175 return _f;
176 }
177
178 template <typename O>
180 {
181 return _strong;
182 }
183
184 template <typename O>
186 {
187 return _verbose;
188 }
189
190 template <typename O>
192 {
193 return _maximize;
194 }
195
196 template <typename O>
198 {
199 return _max_it;
200 }
201
202 //--------------------------------------------------------------------------
203 // EXECUTE
204 //--------------------------------------------------------------------------
205
206 template <typename O>
209 {
210 if( verbose() > 1 )
211 {
212 std::cout << std::string(80, '-') << std::endl;
213 std::cout << std::setw(7) << "Search "
214 << std::setw(4) << "i "
215 << std::setw(15) << "f"
216 << std::setw(15) << "a"
217 << std::endl;
218 std::cout << std::string(80, '-') << std::endl;
219 }
220
221 if( verbose() > 0 )
222 {
223 std::cout << std::setw(7) << "W"
224 << std::setw(4) << 0
225 << std::setw(15) << std::setprecision(5) << _previous_value
226 << std::setw(15) << std::setprecision(5) << 0.;
227 }
228
229 if( !checkDirection() )
230 {
231 if( verbose() > 0 )
232 {
233 std::cout << " Not "
234 << std::string( maximize() ? "an ascent" : "a descent" )
235 << std::string( " direction." ) << std::endl;
236 }
237 return _x;
238 }
239 else if( verbose() > 0 )
240 std::cout << std::endl;
241
242 float a = 1.;
243 bool ok = false;
244 int i = 0;
245 float a_min = 0., a_max;
246 bool a_max_set = false;
247
248 do {
249 ++i;
250 _current_value = objectiveFunction().value( _x + a * _p );
251 if( ( maximize() &&_current_value <= _previous_value ) ||
253 {
254 // Because we know the direction is an ascent direction, the objective
255 // function should not decrease. If this is the case, it is because
256 // we took a step too big and found ourseleves farther than the
257 // local maxima.
258 // In this case, we thus decrease the step length.
259 if( verbose() > 0 )
260 {
261 std::cout << std::setw(7) << "W"
262 << std::setw(4) << i
263 << std::setw(15) << std::setprecision(5) << _current_value
264 << std::setw(15) << std::setprecision(5) << a
265 << " B"
266 << std::endl;
267 }
268 ok = false;
269 a_max = a;
270 a = ( a_max - a_min ) / 2. + a_min;
271 }
272 else if( not wolfe1(a) or not wolfe2(a) )
273 {
274 if( verbose() > 0 )
275 {
276 std::cout << std::setw(7) << "W"
277 << std::setw(4) << i
278 << std::setw(15) << std::setprecision(5) << _current_value
279 << std::setw(15) << std::setprecision(5) << a
280 << " W"
281 << std::endl;
282 }
283 ok = false;
284 a_min = a;
285 if( a_max_set )
286 a = ( a_max - a_min ) / 2. + a_min;
287 else
288 a *= 2.;
289 }
290 else
291 {
292 if( verbose() > 0 )
293 {
294 std::cout << std::setw(7) << "W"
295 << std::setw(4) << i
296 << std::setw(15) << std::setprecision(5) << _current_value
297 << std::setw(15) << std::setprecision(5) << a
298 << " OK"
299 << std::endl;
300 }
301 ok = true;
302 }
303
304 } while( not ok and ( maxIterations() < 0 or i < maxIterations() ) );
305
306 if( verbose() > 0 and maxIterations() > 0 and i >= maxIterations() )
307 std::cout << "Maximum number of iterations reached." << std::endl;
308
309 return _x + a * _p;
310 }
311
312 //--------------------------------------------------------------------------
313 // LINE SEARCH
314 //--------------------------------------------------------------------------
315
316 template <typename O>
318 {
320 _previous_scalarprod = (math::transpose( _p ) * objectiveFunction().derivative( _x )).at(0);
321 if( maximize() )
322 return _previous_scalarprod > 0;
323 else
324 return _previous_scalarprod < 0;
325 }
326
327 template <typename O>
328 bool WolfeLineSearch<O>::wolfe1( float a ) const
329 {
330 float righthand = _previous_value + _c1 * a * _previous_scalarprod;
331 if( maximize() )
332 return _current_value >= righthand;
333 else
334 return _current_value <= righthand;
335 }
336
337 template <typename O>
338 bool WolfeLineSearch<O>::wolfe2w( float a ) const
339 {
340 float current_scalarprod = (math::transpose(_p) * objectiveFunction().derivative( _x + a * _p )).at(0);
341 float righthand = _c2 * _previous_scalarprod;
342 if( maximize() )
343 return current_scalarprod <= righthand;
344 else
345 return current_scalarprod >= righthand;
346 }
347
348 template <typename O>
349 bool WolfeLineSearch<O>::wolfe2s( float a ) const
350 {
351 float current_scalarprod = (math::transpose(_p) * objectiveFunction().derivative( _x + a * _p )).at(0);
352 float righthand = _c2 * _previous_scalarprod;
353 return std::abs(current_scalarprod) <= std::abs(righthand);
354 }
355
356 template <typename O>
357 bool WolfeLineSearch<O>::wolfe2( float a ) const
358 {
359 if( _strong )
360 return wolfe2s(a);
361 else
362 return wolfe2w(a);
363 }
364
365} // namespace aims
366
367#endif // PRIMATOLOGIST_OPTIMIZATION_WOLFE_D_H
Once an ascent direction is given, this class performs a line search that respects wolfe conditions.
Definition wolfe_decl.h:39
WolfeLineSearch(const Objective &f=Objective(), const Vector &x=Vector(), const Vector &p=Vector())
Definition wolfe_d.h:27
void setMaxIterations(int n=- 1)
Definition wolfe_d.h:136
WolfeLineSearch< O > & operator=(const WolfeLineSearch< O > &other)
Definition wolfe_d.h:64
bool strongWolfe() const
Definition wolfe_d.h:179
float _c1
Wolfe c1.
Definition wolfe_decl.h:101
Objective _f
objectiveFunction
Definition wolfe_decl.h:105
bool wolfe1(float a) const
Armijo (= Wolfe 1st) condition.
Definition wolfe_d.h:328
bool maximize() const
Definition wolfe_d.h:191
void setSearchDirection(const Vector &p=Vector())
Definition wolfe_d.h:106
float _c2
Wolfe c2.
Definition wolfe_decl.h:102
void setObjectiveFunction(const Objective &f)
Definition wolfe_d.h:112
void setMaximize(bool maximize=false)
Definition wolfe_d.h:130
bool wolfe2w(float a) const
weak 2nd Wolfe condition
Definition wolfe_d.h:338
float _previous_value
f(x)
Definition wolfe_decl.h:120
bool checkDirection()
Compute f(x) and <p, g(x)>.
Definition wolfe_d.h:317
Vector _x
position
Definition wolfe_decl.h:103
const Objective & objectiveFunction() const
Definition wolfe_d.h:173
void setStrongWolfe(bool strong=false)
Definition wolfe_d.h:118
void setPosition(const Vector &x=Vector())
Definition wolfe_d.h:100
float _previous_scalarprod
<p, g(x)>
Definition wolfe_decl.h:122
int maxIterations() const
Definition wolfe_d.h:197
void setC1(float c1=1E-4)
Definition wolfe_d.h:88
bool _maximize
maximize or minimize
Definition wolfe_decl.h:108
float c2() const
Definition wolfe_d.h:152
int _max_it
maximum number of iterations
Definition wolfe_decl.h:109
int verbose() const
Definition wolfe_d.h:185
bool wolfe2s(float a) const
strong 2nd Wolfe condition
Definition wolfe_d.h:349
void setC2(float c2=0.9)
Definition wolfe_d.h:94
math::Vector Vector
Definition wolfe_decl.h:46
int _verbose
verbosity level
Definition wolfe_decl.h:107
float c1() const
Definition wolfe_d.h:146
void setVerbose(int v=carto::verbose)
Definition wolfe_d.h:124
bool _strong
strongWolfe
Definition wolfe_decl.h:106
const Vector & searchDirection() const
Definition wolfe_d.h:166
const Vector & position() const
Definition wolfe_d.h:159
Vector _p
ascentDirection
Definition wolfe_decl.h:104
bool wolfe2(float a) const
select condition based on _strong
Definition wolfe_d.h:357
float _current_value
f(x + a.p)
Definition wolfe_decl.h:121
MatrixBase< T > transpose(const MatrixBase< T > &)
Matrix transposition.
Definition matrix_d.h:165