KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
diff_optim.h
Go to the documentation of this file.
1 /* =========================================================================== *
2  |
3  | Copyright (c) 1994-2011 by Kobus Barnard (author)
4  |
5  | Personal and educational use of this code is granted, provided that this
6  | header is kept intact, and that the authorship is not misrepresented, that
7  | its use is acknowledged in publications, and relevant papers are cited.
8  |
9  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
10  |
11  | Please note that the code in this file has not necessarily been adequately
12  | tested. Naturally, there is no guarantee of performance, support, or fitness
13  | for any particular task. Nonetheless, I am interested in hearing about
14  | problems that you encounter.
15  |
16  | Author: Ernesto Brau
17  * =========================================================================== */
18 
19 /* $Id$ */
20 
21 #ifndef DIFF_OPTIM_H
22 #define DIFF_OPTIM_H
23 
24 #include <l/l_verbose.h>
25 #include <l_cpp/l_exception.h>
26 #include <m_cpp/m_vector.h>
27 #include <diff_cpp/diff_util.h>
28 #include <vector>
29 #include <utility>
30 #include <limits>
31 #include <algorithm>
32 #include <functional>
33 
34 namespace kjb {
35 
54 template<class F, class M, class A>
55 double grid_maximize
56 (
57  const F& fcn,
58  const std::vector<std::pair<double, double> >& bounds,
59  size_t nbins,
60  const A& adapter,
61  M& mxm
62 )
63 {
64  const size_t D = bounds.size();
65  IFT(D != 0, Illegal_argument, "Cannot optimize 0-dimensional function");
66 
67  if(D > 8)
68  {
69  kjb_c::warn_pso("The dimensionality of this function is %d; this "
70  "approximation might take a really long time.", D);
71  }
72 
73  std::vector<double> bin_widths(D);
74  for(size_t i = 0; i < D; i++)
75  {
76  bin_widths[i] = (bounds[i].second - bounds[i].first)/nbins;
77  }
78 
79  std::vector<size_t> indices;
80  M x = mxm;
81  double mx = -std::numeric_limits<double>::max();
82  while(next_point(bounds, bin_widths, nbins, indices, x, adapter))
83  {
84  double fx = fcn(x);
85  if(fx > mx)
86  {
87  mx = fx;
88  mxm = x;
89  }
90  }
91 
92  return mx;
93 }
94 
109 template<class F, class V>
110 inline
111 double grid_maximize
112 (
113  const F& fcn,
114  const std::vector<std::pair<double, double> >& bounds,
115  size_t nbins,
116  V& mxm
117 )
118 {
119  const size_t D = bounds.size();
120  if(mxm.size() != D)
121  {
122  mxm.resize(D);
123  }
124 
125  return grid_maximize(fcn, bounds, nbins, Vector_adapter<V>(), mxm);
126 }
127 
146 template<class F, class M, class G, class A>
147 void gradient_ascent
148 (
149  const F& fcn,
150  M& x,
151  const std::vector<double>& steps,
152  const G& grad,
153  const A& adapter
154 )
155 {
156  const size_t D = adapter.size(&x);
157  IFT(D == steps.size(), Illegal_argument,
158  "cannot perform gradient ascent: wrong number of step sizes.");
159 
160  Vector g(D);
161  std::vector<double> exg(D);
162 
163  // simultaneuous optimization
164  double cur_f = fcn(x);
165  double prev_f;
166  do
167  {
168  // old f(x)
169  prev_f = cur_f;
170 
171  // compute gradient and move
172  g = grad(x);
173  std::transform(
174  steps.begin(),
175  steps.end(),
176  g.begin(),
177  exg.begin(),
178  std::multiplies<double>());
179 
180  // move model
181  move_params(x, exg, adapter);
182 
183  // new f(x)
184  cur_f = fcn(x);
185  }
186  while(cur_f > prev_f);
187 
188  std::transform(exg.begin(), exg.end(), exg.begin(), std::negate<double>());
189  move_params(x, exg, adapter);
190 }
191 
206 template<class F, class V, class G>
207 inline
208 void gradient_ascent
209 (
210  const F& fcn,
211  V& x,
212  const std::vector<double>& steps,
213  const G& grad
214 )
215 {
216  gradient_ascent(fcn, x, steps, grad, Vector_adapter<V>());
217 }
218 
234 template<class F, class M, class A>
235 void refine_max
236 (
237  const F& fcn,
238  M& x,
239  const std::vector<double>& steps,
240  const A& adapter
241 )
242 {
243  double cur_pt = fcn(x);
244  bool at_max = false;
245  while(!at_max)
246  {
247  at_max = true;
248  for(size_t i = 0; i < adapter.size(&x); i++)
249  {
250  double xi = adapter.get(&x, i);
251  // move right
252  move_param(x, i, steps[i], adapter);
253  double right_pt = fcn(x);
254 
255  // move left
256  move_param(x, i, -2.0*steps[i], adapter);
257  double left_pt = fcn(x);
258 
259  // move back
260  adapter.set(&x, i, xi);
261  if(cur_pt >= left_pt && cur_pt >= right_pt) continue;
262 
263  at_max = false;
264  if(left_pt > right_pt)
265  {
266  move_param(x, i, -steps[i], adapter);
267  cur_pt = left_pt;
268  }
269  else
270  {
271  move_param(x, i, steps[i], adapter);
272  cur_pt = right_pt;
273  }
274  }
275  }
276 }
277 
278 
279 } //namespace kjb
280 
281 #endif /*DIFF_OPTIM_H */
282 
283 
Int_matrix::Value_type max(const Int_matrix &mat)
Return the maximum value in this matrix.
Definition: l_int_matrix.h:1397
void gradient_ascent(const F &fcn, M &x, const std::vector< double > &steps, const G &grad, const A &adapter)
Maximizes a function using a simple gradient ascent method.
Definition: diff_optim.h:148
void move_param(Model &x, size_t i, double dv, const Adapter &aptr)
Helper function that moves a parameter by an amount.
Definition: diff_util.h:102
This class implements vectors, in the linear-algebra sense, with real-valued elements.
Definition: m_vector.h:87
#define IFT(a, ex, msg)
Definition: l_exception.h:101
bool next_point(const std::vector< std::pair< double, double > > &bounds, const std::vector< double > &widths, size_t nbins, std::vector< size_t > &indices, M &x, const A &adapter)
Gets the next point in a N-dimensional grid.
Definition: diff_util.h:145
void move_params(Model &x, size_t i, size_t j, double dv, double dw, const Adapter &aptr)
Helper function that moves a pair of parameters by an amount.
Definition: diff_util.h:111
x
Definition: APPgetLargeConnectedEdges.m:100
Default adapter for the hessian function.
Definition: diff_util.h:42
Object thrown when an argument to a function is not acceptable.
Definition: l_exception.h:377
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
D
Definition: APPgetLargeConnectedEdges.m:106
Support for error handling exception classes in libKJB.
double grid_maximize(const F &fcn, const std::vector< std::pair< double, double > > &bounds, size_t nbins, const A &adapter, M &mxm)
Maximizes a function by evaluating at all points in a grid.
Definition: diff_optim.h:56
void refine_max(const F &fcn, M &x, const std::vector< double > &steps, const A &adapter)
Refine the maximum of a function.
Definition: diff_optim.h:236
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...