KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
diff_hessian.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_HESSIAN_H
22 #define DIFF_HESSIAN_H
23 
24 #include <m_cpp/m_matrix.h>
25 #include <diff_cpp/diff_util.h>
26 #include <vector>
27 
28 namespace kjb {
29 
44 template<class Func, class Model, class Adapter>
45 Matrix hessian
46 (
47  const Func& f,
48  const Model& x,
49  const std::vector<double>& dx,
50  const Adapter& adapter
51 )
52 {
53  const size_t D = adapter.size(&x);
54 
55  Matrix H(D, D);
56  double fx = f(x);
57  Model y = x;
58 
59  for(size_t i = 0; i < D; i++)
60  {
61  for(size_t j = 0; j < D; j++)
62  {
63  if(i == j)
64  {
65  move_param(y, i, dx[i], adapter);
66  double fxp = f(y);
67 
68  move_param(y, i, -2*dx[i], adapter);
69  double fxm = f(y);
70 
71  H(i, i) = (fxp - 2*fx + fxm) / (dx[i]*dx[i]);
72 
73  move_param(y, i, dx[i], adapter);
74  }
75  else
76  {
77  move_params(y, i, j, dx[i], dx[j], adapter);
78  double fxpp = f(y);
79 
80  move_param(y, j, -2*dx[j], adapter);
81  double fxpm = f(y);
82 
83  move_param(y, i, -2*dx[i], adapter);
84  double fxmm = f(y);
85 
86  move_param(y, j, 2*dx[j], adapter);
87  double fxmp = f(y);
88 
89  H(i, j) = (fxpp - fxpm - fxmp + fxmm) / (4*dx[i]*dx[j]);
90 
91  move_params(y, i, j, dx[i], -dx[j], adapter);
92  }
93  }
94  }
95 
96  return H;
97 }
98 
108 template<class Func, class Vec>
109 inline
110 Matrix hessian
111 (
112  const Func& f,
113  const Vec& x,
114  const std::vector<double>& dx
115 )
116 {
117  return hessian(f, x, dx, Vector_adapter<Vec>());
118 }
119 
135 template<class Func, class Model, class Adapter>
136 Matrix hessian_symmetric
137 (
138  const Func& f,
139  const Model& x,
140  const std::vector<double>& dx,
141  const Adapter& adapter
142 )
143 {
144  const size_t D = adapter.size(&x);
145 
146  Matrix H(D, D);
147  double fx = f(x);
148  Model y = x;
149 
150  for(size_t i = 0; i < D; i++)
151  {
152  for(size_t j = 0; j <= i; j++)
153  {
154  if(i == j)
155  {
156  move_param(y, i, dx[i], adapter);
157  double fxp = f(y);
158 
159  move_param(y, i, -2*dx[i], adapter);
160  double fxm = f(y);
161 
162  H(i, i) = (fxp - 2*fx + fxm) / (dx[i]*dx[i]);
163 
164  move_param(y, i, dx[i], adapter);
165  }
166  else
167  {
168  move_params(y, i, j, dx[i], dx[j], adapter);
169  double fxpp = f(y);
170 
171  move_param(y, j, -2*dx[j], adapter);
172  double fxpm = f(y);
173 
174  move_param(y, i, -2*dx[i], adapter);
175  double fxmm = f(y);
176 
177  move_param(y, j, 2*dx[j], adapter);
178  double fxmp = f(y);
179 
180  // symmetry assumption
181  H(i, j) = (fxpp - fxpm - fxmp + fxmm) / (4*dx[i]*dx[j]);
182  H(j, i) = H(i, j);
183 
184  move_params(y, i, j, dx[i], -dx[j], adapter);
185  }
186  }
187  }
188 
189  return H;
190 }
191 
201 template<class Func, class Vec>
202 inline
203 Matrix hessian_symmetric
204 (
205  const Func& f,
206  const Vec& x,
207  const std::vector<double>& dx
208 )
209 {
210  return hessian_symmetric(f, x, dx, Vector_adapter<Vec>());
211 }
212 
227 template<class Func, class Model, class Adapter>
228 Matrix hessian_diagonal
229 (
230  const Func& f,
231  const Model& x,
232  const std::vector<double>& dx,
233  const Adapter& adapter
234 )
235 {
236  const size_t D = adapter.size(&x);
237 
238  Matrix H(D, D);
239  double fx = f(x);
240  Model y = x;
241 
242  for(size_t i = 0; i < D; i++)
243  {
244  for(size_t j = 0; j < D; j++)
245  {
246  if(i == j)
247  {
248  move_param(y, i, dx[i], adapter);
249  double fxp = f(y);
250 
251  move_param(y, i, -2*dx[i], adapter);
252  double fxm = f(y);
253 
254  H(i, i) = (fxp - 2*fx + fxm) / (dx[i]*dx[i]);
255 
256  move_param(y, i, dx[i], adapter);
257  }
258  }
259  }
260  return H;
261 }
262 
272 template<class Func, class Vec>
273 inline
274 Matrix hessian_diagonal
275 (
276  const Func& f,
277  const Vec& x,
278  const std::vector<double>& dx
279 )
280 {
281  return hessian_diagonal(f, x, dx, Vector_adapter<Vec>());
282 }
283 
284 } //namespace kjb
285 
286 #endif /*DIFF_HESSIAN_H */
287 
Definition for the Matrix class, a thin wrapper on the KJB Matrix struct and its related functionalit...
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
Matrix hessian_symmetric(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter)
Computes the Hessian of a function, evaluated at a point, using finite differences. This function assumes that the Hessian is SYMMETRIC, and only computes the lower triangle of it.
Definition: diff_hessian.h:137
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
Matrix hessian_diagonal(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter)
Computes the diagonal Hessian of a function, evaluated at a point, using finite differences.
Definition: diff_hessian.h:229
Default adapter for the hessian function.
Definition: diff_util.h:42
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
This class implements matrices, in the linear-algebra sense, with real-valued elements.
Definition: m_matrix.h:94
D
Definition: APPgetLargeConnectedEdges.m:106
Matrix hessian(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter)
Computes the Hessian of a function, evaluated at a point, using finite differences.
Definition: diff_hessian.h:46