KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
diff_gradient_mt.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_MT_H
22 #define DIFF_GRADIENT_MT_H
23 
24 #include <m_cpp/m_vector.h>
25 #include <diff_cpp/diff_util.h>
26 #include <boost/thread.hpp>
27 #include <boost/ref.hpp>
28 #include <vector>
29 #include <algorithm>
30 #include <sys/time.h>
31 
32 namespace kjb {
33 
35 template<class Func, class Model, class Adapter>
37 (
38  const Func& f,
39  const Model& x,
40  const std::vector<double>& dx,
41  const Adapter& adapter,
42  size_t i_start,
43  size_t i_end,
44  Vector& v
45 )
46 {
47  // copy to avoid concurrent access
48  Model y = x;
49  Adapter aptr = adapter;
50  for(size_t i = i_start; i <= i_end; i++)
51  {
52  double yi = adapter.get(&y, i);
53 
54  move_param(y, i, dx[i], aptr);
55  double fxp = f(y);
56 
57  move_param(y, i, -2*dx[i], aptr);
58  double fxm = f(y);
59 
60  v[i] = (fxp-fxm)/(2*dx[i]);
61 
62  // return to original spot
63  adapter.set(&y, i, yi);
64  }
65 }
66 
68 template<class Func, class Model, class Adapter>
70 (
71  const Func& f,
72  const Model& x,
73  const std::vector<double>& dx,
74  const Adapter& adapter,
75  double fx,
76  size_t i_start,
77  size_t i_end,
78  Vector& v
79 )
80 {
81  // copy to avoid concurrent access
82  Model y = x;
83  Adapter aptr = adapter;
84 
85  for(size_t i = i_start; i <= i_end; i++)
86  {
87  double yi = adapter.get(&y, i);
88  move_param(y, i, dx[i], aptr);
89  double fxp = f(y);
90 
91  v[i] = (fxp - fx) / dx[i];
92 
93  // return to original spot
94  //move_param(y, i, -dx[i], aptr);
95  adapter.set(&y, i, yi);
96  }
97 }
98 
118 template<class Func, class Model, class Adapter>
119 Vector gradient_cfd_mt
120 (
121  const Func& f,
122  const Model& x,
123  const std::vector<double>& dx,
124  const Adapter& adapter,
125  size_t nt
126 )
127 {
128  using namespace boost;
129 
130  size_t D = adapter.size(&x);
131  Vector G(D);
132 
133  size_t avail_core = thread::hardware_concurrency();
134  if(nt == 0 || nt > avail_core )
135  {
136  nt = avail_core;
137  }
138 
139  if(D < nt)
140  {
141  nt = D;
142  }
143 
144  if(nt == 0)
145  {
146  nt = 1;
147  }
148 
149  // send computation to threads
150  thread_group thrds;
151  for(size_t i = 0; i < nt; i++)
152  {
153  size_t l = (i == nt - 1 ? D : (D/nt) * (i+1));
154  thrds.create_thread(bind(
155  gradient_cfd_mt_worker<Func, Model, Adapter>,
156  boost::cref(f), boost::cref(x), boost::cref(dx), boost::cref(adapter),
157  (D/nt) * i, l - 1, boost::ref(G)));
158  }
159 
160  // join threads before returning
161  thrds.join_all();
162  return G;
163 }
164 
176 template<class Func, class Vec>
177 inline
178 Vector gradient_cfd_mt
179 (
180  const Func& f,
181  const Vec& x,
182  const std::vector<double>& dx,
183  size_t nt = 0
184 )
185 {
186  return gradient_cfd_mt(f, x, dx, Vector_adapter<Vec>(), nt);
187 }
188 
204 template<class Func, class Model, class Adapter>
205 Vector gradient_ffd_mt
206 (
207  const Func& f,
208  const Model& x,
209  const std::vector<double>& dx,
210  const Adapter& adapter,
211  size_t nt
212 )
213 {
214  using namespace boost;
215 
216  size_t D = adapter.size(&x);
217  Vector G(D);
218  double fx = f(x);
219 
220  size_t avail_core = thread::hardware_concurrency();
221  if(nt > avail_core )
222  {
223  nt = avail_core;
224  }
225 
226  if(D < nt)
227  {
228  nt = D;
229  }
230 
231  if(nt == 0)
232  {
233  nt = 1;
234  }
235 
236  // send computation to threads
237 // thread thrds[nt];
238  thread_group thrds;
239  for(size_t i = 0; i < nt; i++)
240  {
241 
242  size_t l = (i == nt - 1 ? D : (D/nt) * (i+1));
243 // thrds[i] = thread(bind(
244  thrds.create_thread(bind(
245  gradient_ffd_mt_worker<Func, Model, Adapter>,
246  boost::cref(f), boost::cref(x), boost::cref(dx), boost::cref(adapter),
247  fx, (D/nt) * i, l - 1, boost::ref(G)));
248  }
249 
250  // join threads before returning
251 // std::for_each(thrds, thrds + nt, bind(&thread::join, _1));
252  thrds.join_all();
253  return G;
254 }
255 
267 template<class Func, class Vec>
268 inline
269 Vector gradient_ffd_mt
270 (
271  const Func& f,
272  const Vec& x,
273  const std::vector<double>& dx,
274  size_t nt = 0
275 )
276 {
277  return gradient_ffd_mt(f, x, dx, Vector_adapter<Vec>(), nt);
278 }
279 
280 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
281 /* INDEPENDENT VERSIONS OF GRADIENT */
282 /* \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ */
283 
285 template<class Func, class Model, class Adapter>
287 (
288  const Func& f,
289  const Model& x,
290  const std::vector<double>& dx,
291  const Adapter& adapter,
292  size_t i_start,
293  size_t i_end,
294  Vector& v
295 )
296 {
297  // copy to avoid concurrent access
298  Model y = x;
299  Adapter aptr = adapter;
300 
301  for(size_t i = i_start; i <= i_end; i++)
302  {
303  double yi = adapter.get(&y, i);
304 
305  move_param(y, i, dx[i], aptr);
306  double fxp = f(y,i);
307 
308  move_param(y, i, -2*dx[i], aptr);
309  double fxm = f(y,i);
310 
311  v[i] = (fxp-fxm)/(2*dx[i]);
312 
313  // return to original spot
314  //move_param(y, i, dx[i], aptr);
315  adapter.set(&y, i, yi);
316  }
317 }
318 
336 template<class Func, class Model, class Adapter>
337 Vector gradient_ind_cfd_mt
338 (
339  const Func& f,
340  const Model& x,
341  const std::vector<double>& dx,
342  const Adapter& adapter,
343  size_t nt
344 )
345 {
346  using namespace boost;
347 
348  size_t D = adapter.size(&x);
349  Vector G(D);
350 
351  size_t avail_core = thread::hardware_concurrency();
352  if(nt == 0 || nt > avail_core )
353  {
354  nt = avail_core;
355  }
356 
357  if(D < nt)
358  {
359  nt = D;
360  }
361 
362  if(nt == 0)
363  {
364  nt = 1;
365  }
366 
367  // send computation to threads
368 // thread thrds[nt];
369  thread_group thrds;
370  for(size_t i = 0; i < nt; i++)
371  {
372  size_t l = (i == nt - 1 ? D : (D/nt) * (i+1));
373 // thrds[i] = thread(bind(
374  thrds.create_thread(bind(
375  gradient_ind_cfd_mt_worker<Func, Model, Adapter>,
376  boost::cref(f), boost::cref(x), boost::cref(dx), boost::cref(adapter),
377  (D/nt) * i, l - 1, boost::ref(G)));
378  }
379 
380  // join threads before returning
381 // std::for_each(thrds, thrds + nt, bind(&thread::join, _1));
382  thrds.join_all();
383 
384  return G;
385 }
386 
400 template<class Func, class Vec>
401 inline
402 Vector gradient_ind_cfd_mt
403 (
404  const Func& f,
405  const Vec& x,
406  const std::vector<double>& dx,
407  size_t nt = 0
408 )
409 {
410  return gradient_ind_cfd_mt(f, x, dx, Vector_adapter<Vec>(), nt);
411 }
412 
413 } //namespace kjb
414 
415 #endif /*DIFF_GRADIENT_MT_H */
416 
void gradient_ind_cfd_mt_worker(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter, size_t i_start, size_t i_end, Vector &v)
Helper function for gradient_ind_cfd_mt.
Definition: diff_gradient_mt.h:287
void gradient_ffd_mt_worker(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter, double fx, size_t i_start, size_t i_end, Vector &v)
Helper function for gradient_ffd_mt.
Definition: diff_gradient_mt.h:70
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
void gradient_cfd_mt_worker(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter, size_t i_start, size_t i_end, Vector &v)
Helper function for gradient_cfd_mt.
Definition: diff_gradient_mt.h:37
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_mt(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter, size_t nt)
Computes the gradient of a function, evaluated at a point, using central finite differences. Multi-threaded version.
Definition: diff_gradient_mt.h:120
Vector gradient_ind_cfd_mt(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter, size_t nt)
Computes the gradient of a function, evaluated at a point, using central finite differences. Multithreaded version.
Definition: diff_gradient_mt.h:338
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
Vector gradient_ffd_mt(const Func &f, const Model &x, const std::vector< double > &dx, const Adapter &adapter, size_t nt)
Computes the gradient of a function, evaluated at a point, using forward finite differences. Multi-threaded version.
Definition: diff_gradient_mt.h:206
D
Definition: APPgetLargeConnectedEdges.m:106
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...