smooth_func.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2016-2020, Andrew W. Steiner
5 
6  This file is part of O2scl.
7 
8  O2scl is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  O2scl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with O2scl. If not, see <http://www.gnu.org/licenses/>.
20 
21  -------------------------------------------------------------------
22 */
23 /** \file smooth_func.h
24  \brief File for ..
25 */
26 #ifndef O2SCL_SMOOTH_FUNC_H
27 #define O2SCL_SMOOTH_FUNC_H
28 
29 #include <iostream>
30 #include <vector>
31 #include <gsl/gsl_qrng.h>
32 #include <o2scl/vector.h>
33 
34 #ifndef DOXYGEN_NO_O2NS
35 namespace o2scl {
36 #endif
37 
38  /** \brief Smooth a function by averaging in a neighborhood
39  of points defined by a Sobol sequence
40 
41  \warning The function \ref o2scl::smooth_func::set_func() stores a
42  pointer to the function specified by the user, so the user must
43  ensure that this pointer is still valid when
44  \ref o2scl::smooth_func::operator()() is called.
45 
46  \future Move memory allocation outside of \ref
47  o2scl::smooth_func::operator()() .
48  */
49  template<class vec_t, class func_t> class smooth_func {
50 
51  protected:
52 
53  /** \brief The pointer to the original function
54  */
55  func_t *f;
56 
57  /** \brief Step size defining the neighborhood (default 0.01)
58  */
59  std::vector<double> step;
60 
61  /** \brief Number of points in the Sobol sequence (default 40)
62  */
63  size_t N;
64 
65  public:
66 
67  smooth_func() {
68  N=40;
69  step.resize(1);
70  step[0]=1.0e-2;
71  f=0;
72  }
73 
74  /** \brief Set the base function
75  */
76  void set_func(func_t &func) {
77  f=&func;
78  return;
79  }
80 
81  /** \brief Set the number of points to use in the average
82 
83  If \c n_new is zero then the error handler will be called.
84  */
85  void set_n(size_t n_new) {
86  if (n_new==0) {
87  O2SCL_ERR2("Cannot call set_n() with argument 0 in ",
88  "smooth_func::set_n().",o2scl::exc_einval);
89  }
90  N=n_new;
91  return;
92  }
93 
94  /** \brief Set the stepsize
95  */
96  template<class vec2_t> void set_step(vec2_t &v) {
97  if (v.size()==0) {
98  O2SCL_ERR2("Sent an empty vector to ",
99  "smooth_func::set_step().",o2scl::exc_einval);
100  }
101  step.resize(v.size());
102  o2scl::vector_copy(v.size(),v,step);
103  return;
104  }
105 
106  /** \brief Evaluate the smoothed function
107 
108  If the user-specified function returns a non-zero value for any
109  point, then that contribution to the average is ignored. This
110  function will return a non-zero value if the user-specified
111  function returns a non-zero value for all of the points.
112  */
113  int operator()(size_t nv, const vec_t &x, vec_t &y) {
114 
115  if (f==0) {
116  O2SCL_ERR2("Function not set in ",
117  "smooth_func::operator().",o2scl::exc_einval);
118  }
119 
120  // Allocate the Sobol object
121  gsl_qrng *gq=gsl_qrng_alloc(gsl_qrng_sobol,nv);
122 
123  std::vector<double> v(nv);
124  vec_t x2(nv), y2(nv);
125 
126  for(size_t j=0;j<nv;j++) {
127  y(j)=0.0;
128  }
129 
130  int count=0;
131  for(size_t i=0;i<N;i++) {
132 
133  // Create the new x point
134  gsl_qrng_get(gq,&(v[0]));
135  for(size_t j=0;j<nv;j++) {
136  x2[j]=(1.0+(v[j]*2.0-1.0)*step[j%step.size()])*x[j];
137  }
138 
139  // Evaluate the function
140  int fret=(*f)(nv,x2,y2);
141 
142  // Add the y value to the running total
143  if (fret==0) {
144  for(size_t j=0;j<nv;j++) {
145  y[j]+=y2[j];
146  }
147  count++;
148  }
149  }
150 
151  if (count==0) {
152  return o2scl::exc_efailed;
153  }
154 
155  // Compute the average from the running total
156  for(size_t j=0;j<nv;j++) {
157  y[j]/=((double)count);
158  }
159 
160  gsl_qrng_free(gq);
161 
162  return 0;
163  }
164 
165  };
166 
167 #ifndef DOXYGEN_NO_O2NS
168 }
169 #endif
170 
171 #endif
o2scl::exc_efailed
@ exc_efailed
generic failure
Definition: err_hnd.h:61
O2SCL_ERR2
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
o2scl
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
Definition: anneal.h:42
o2scl::smooth_func::N
size_t N
Number of points in the Sobol sequence (default 40)
Definition: smooth_func.h:63
o2scl::smooth_func::f
func_t * f
The pointer to the original function.
Definition: smooth_func.h:55
o2scl::vector_copy
void vector_copy(const vec_t &src, vec2_t &dest)
Simple vector copy.
Definition: vector.h:124
o2scl_inte_qng_coeffs::x2
static const double x2[5]
Definition: inte_qng_gsl.h:66
o2scl::exc_einval
@ exc_einval
invalid argument supplied by user
Definition: err_hnd.h:59
o2scl::smooth_func::set_func
void set_func(func_t &func)
Set the base function.
Definition: smooth_func.h:76
o2scl::smooth_func::set_n
void set_n(size_t n_new)
Set the number of points to use in the average.
Definition: smooth_func.h:85
o2scl::smooth_func
Smooth a function by averaging in a neighborhood of points defined by a Sobol sequence.
Definition: smooth_func.h:49
o2scl::smooth_func::operator()
int operator()(size_t nv, const vec_t &x, vec_t &y)
Evaluate the smoothed function.
Definition: smooth_func.h:113
o2scl::smooth_func::set_step
void set_step(vec2_t &v)
Set the stepsize.
Definition: smooth_func.h:96
o2scl::smooth_func::step
std::vector< double > step
Step size defining the neighborhood (default 0.01)
Definition: smooth_func.h:59

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).