KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
diff_gradient.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, Zewei Jiang
17  * =========================================================================== */
18 
19 /* $Id$ */
20 
21 #ifndef DIFF_GRADIENT_H
22 #define DIFF_GRADIENT_H
23 
24 #include <m_cpp/m_vector.h>
25 #include <diff_cpp/diff_util.h>
26 #include <vector>
27 
28 namespace kjb {
29 
45 template<class Func, class Model, class Adapter>
46 Vector gradient_cfd
47 (
48  const Func& f,
49  const Model& x,
50  const std::vector<double>& dx,
51  const Adapter& adapter
52 )
53 {
54  const size_t D = adapter.size(&x);
55 
56  Vector G(D);
57  Model y = x;
58 
59  for(size_t i = 0; i < D; i++)
60  {
61  double yi = adapter.get(&y, i);
62 
63  move_param(y, i, dx[i], adapter);
64  double fxp = f(y);
65 
66  move_param(y, i, -2*dx[i], adapter);
67  double fxm = f(y);
68 
69  G[i] = (fxp - fxm) / (2*dx[i]);
70 
71  // return to original spot
72  adapter.set(&y, i, yi);
73  }
74 
75  return G;
76 }
77 
88 template<class Func, class Vec>
89 inline
90 Vector gradient_cfd
91 (
92  const Func& f,
93  const Vec& x,
94  const std::vector<double>& dx
95 )
96 {
97  return gradient_cfd(f, x, dx, Vector_adapter<Vec>());
98 }
99 
115 template<class Func, class Model, class Adapter>
116 Vector gradient_ffd
117 (
118  const Func& f,
119  const Model& x,
120  const std::vector<double>& dx,
121  const Adapter& adapter
122 )
123 {
124  const size_t D = adapter.size(&x);
125 
126  Vector G(D);
127  double fx = f(x);
128  Model y = x;
129 
130  for(size_t i = 0; i < D; i++)
131  {
132  double yi = adapter.get(&y, i);
133  //y[i] += dx[i];
134  move_param(y, i, dx[i], adapter);
135  double fxp = f(y);
136 
137  G[i] = (fxp - fx) / dx[i];
138 
139  // return to original spot
140  //y[i] -= dx[i];
141  //move_param(y, i, -dx[i], adapter);
142  adapter.set(&y, i, yi);
143  }
144 
145  return G;
146 }
147 
158 template<class Func, class Vec>
159 inline
160 Vector gradient_ffd
161 (
162  const Func& f,
163  const Vec& x,
164  const std::vector<double>& dx
165 )
166 {
167  return gradient_ffd(f, x, dx, Vector_adapter<Vec>());
168 }
169 
170 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
171 /* INDEPENDENT VERSIONS OF GRADIENT */
172 /* */
173 /* These versions use "smart" functions that may exploit indepdendence prop- */
174 /* erties to avoid full function evaluation. For any dimension i, f(x) may */
175 /* be decomposed the sum of terms involing x_i and those not. The latter */
176 /* terms cancel in the finite-differences equation, and can be ignored. Thus */
177 /* the functions below receive f(x,i) which omits terms not involving x_i, */
178 /* often at great performance advantage. */
179 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
180 
198 template<class Func, class Model, class Adapter>
199 Vector gradient_ind_cfd
200 (
201  const Func& f,
202  const Model& x,
203  const std::vector<double>& dx,
204  const Adapter& adapter
205 )
206 {
207  const size_t D = adapter.size(&x);
208 
209  Vector G(D);
210  Model y = x;
211 
212  for(size_t i = 0; i < D; i++)
213  {
214  double yi = adapter.get(&y, i);
215 
216  move_param(y, i, dx[i], adapter);
217  double fxp = f(y, i);
218 
219  move_param(y, i, -2*dx[i], adapter);
220  double fxm = f(y, i);
221 
222  G[i] = (fxp - fxm) / (2*dx[i]);
223 
224  // return to original spot
225  adapter.set(&y, i, yi);
226  }
227 
228  return G;
229 }
230 
243 template<class Func, class Vec>
244 inline
245 Vector gradient_ind_cfd
246 (
247  const Func& f,
248  const Vec& x,
249  const std::vector<double>& dx
250 )
251 {
252  return gradient_ind_cfd(f, x, dx, Vector_adapter<Vec>());
253 }
254 
255 } //namespace kjb
256 
257 #endif /*DIFF_GRADIENT_H */
258 
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
x
Definition: APPgetLargeConnectedEdges.m:100
Vector & set(Value_type val)
Clone of zero_out(int)
Definition: m_vector.h:707
Vector gradient_cfd(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter)
Computes the gradient of a function, evaluated at a point, using central finite differences.
Definition: diff_gradient.h:47
Default adapter for the hessian function.
Definition: diff_util.h:42
Vector gradient_ffd(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter)
Computes the gradient of a function, evaluated at a point, using forward finite differences.
Definition: diff_gradient.h:117
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
D
Definition: APPgetLargeConnectedEdges.m:106
Vector gradient_ind_cfd(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter)
Computes the gradient of a function, evaluated at a point, using central finite differences.
Definition: diff_gradient.h:200
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...