All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
interp2_neigh.h
Go to the documentation of this file.
1 /*
2  -------------------------------------------------------------------
3 
4  Copyright (C) 2006-2014, 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 #ifndef O2SCL_INTERP2_NEIGH_H
24 #define O2SCL_INTERP2_NEIGH_H
25 
26 /** \file interp2_neigh.h
27  \brief File defining \ref o2scl::interp2_neigh
28 */
29 
30 #include <iostream>
31 #include <string>
32 #include <cmath>
33 
34 #include <o2scl/err_hnd.h>
35 
36 #ifndef DOXYGEN_NO_O2NS
37 namespace o2scl {
38 #endif
39 
40  /** \brief Nearest-neighbor interpolation in two dimensions
41 
42  This class performs nearest-neighbor interpolation when the data
43  points are not arranged in a specified order (i.e. not on a
44  grid). For a set of data \f$ {x_i,y_i,f_i} \f$, the value of \f$
45  f \f$ is predicted given a new value of x and y. Distances are
46  determined with
47  \f[
48  d_{ij} = \sqrt{\left(\frac{x_i-x_j}{\Delta x}\right)^2 +
49  \left(\frac{y_i-y_j}{\Delta y}\right)^2}
50  \f]
51  The values \f$ \Delta_x \f$ and \f$ \Delta_y \f$ are specified
52  in \ref x_scale and \ref y_scale, respectively. If these values
53  are negative (the default) then they are computed with \f$
54  \Delta x = x_{\mathrm{max}}-x_{\mathrm{min}} \f$ and \f$ \Delta
55  y = y_{\mathrm{max}}-y_{\mathrm{min}} \f$ .
56 
57  This class stores pointers to the data, not a copy. The data can
58  be changed between interpolations without an additional call to
59  \ref set_data(), but the scales may need to be recomputed with
60  \ref compute_scale().
61 
62  The vector type can be any type with a suitably defined \c
63  operator[].
64 
65  \note This class operates by performing a \f$ {\cal O}(N) \f$
66  brute-force search to find the closest points.
67 
68  \future Make a parent class for this and \ref o2scl::interp2_planar.
69  */
70  template<class vec_t> class interp2_neigh {
71 
72  protected:
73 
74  /// The scale in the x direction
75  double dx;
76 
77  /// The scale in the y direction
78  double dy;
79 
80  public:
81 
84 
85  interp2_neigh() {
86  data_set=false;
87  x_scale=-1.0;
88  y_scale=-1.0;
89  dx=0.0;
90  dy=0.0;
91  }
92 
93  /// The user-specified x scale (default -1)
94  double x_scale;
95 
96  /// The user-specified y scale (default -1)
97  double y_scale;
98 
99  /// Find scaling
100  void compute_scale() {
101  if (x_scale<0.0) {
102  double minx=(*ux)[0], maxx=(*ux)[0];
103  for(size_t i=1;i<np;i++) {
104  if ((*ux)[i]<minx) minx=(*ux)[i];
105  if ((*ux)[i]>maxx) maxx=(*ux)[i];
106  }
107  dx=maxx-minx;
108  } else {
109  dx=x_scale;
110  }
111  if (y_scale<0.0) {
112  double miny=(*uy)[0], maxy=(*uy)[0];
113  for(size_t i=1;i<np;i++) {
114  if ((*uy)[i]<miny) miny=(*uy)[i];
115  if ((*uy)[i]>maxy) maxy=(*uy)[i];
116  }
117  dy=maxy-miny;
118  } else {
119  dy=y_scale;
120  }
121 
122  if (dx<=0.0 || dy<=0.0) {
123  O2SCL_ERR("No scale in interp2_planar::set_data().",exc_einval);
124  }
125 
126  return;
127  }
128 
129  /** \brief Initialize the data for the neigh interpolation
130 
131  This function will call the error handler if \c n_points
132  is zero.
133  */
134  void set_data(size_t n_points, vec_t &x, vec_t &y, vec_t &f) {
135  if (n_points<1) {
136  O2SCL_ERR2("Must provide at least one point in ",
137  "interp2_neigh::set_data()",exc_efailed);
138  }
139  np=n_points;
140  ux=&x;
141  uy=&y;
142  uf=&f;
143  data_set=true;
144 
145  compute_scale();
146 
147  return;
148  }
149 
150  /** \brief Perform the interpolation
151  */
152  double eval(double x, double y) const {
153  double x1, y1, f;
154  size_t i1;
155  eval_point(x,y,f,i1,x1,y1);
156  return f;
157  }
158 
159  /** \brief Perform the interpolation
160  */
161  double operator()(double x, double y) const {
162  return eval(x,y);
163  }
164 
165  /** \brief Perform the planar interpolation using the first two
166  elements of \c v as input
167  */
168  template<class vec2_t> double operator()(vec2_t &v) const {
169  return eval(v[0],v[1]);
170  }
171 
172  /** \brief Interpolation returning the closest point
173 
174  This function interpolates \c x and \c y into the data
175  returning \c f. It also returns the closest x- and y-values
176  found.
177  */
178  void eval_point(double x, double y, double &f,
179  size_t &i1, double &x1, double &y1) const {
180 
181  if (data_set==false) {
182  O2SCL_ERR("Data not set in interp_planar::eval_points().",
183  exc_einval);
184  }
185 
186  // Exhaustively search the data
187  i1=0;
188  double dist_min=pow((x-(*ux)[i1])/dx,2.0)+pow((y-(*uy)[i1])/dy,2.0);
189  for(size_t index=1;index<np;index++) {
190  double dist=pow((x-(*ux)[index])/dx,2.0)+pow((y-(*uy)[index])/dy,2.0);
191  if (dist<dist_min) {
192  i1=index;
193  dist_min=dist;
194  }
195  }
196 
197  // Return the function value
198 
199  f=(*uf)[i1];
200 
201  return;
202  }
203 
204 #ifndef DOXYGEN_INTERNAL
205 
206  protected:
207 
208  /// The number of points
209  size_t np;
210  /// The x-values
211  vec_t *ux;
212  /// The y-values
213  vec_t *uy;
214  /// The f-values
215  vec_t *uf;
216  /// True if the data has been specified
217  bool data_set;
218 
219 #endif
220 
221  };
222 
223 #ifndef DOXYGEN_NO_O2NS
224 }
225 #endif
226 
227 #endif
228 
229 
230 
Nearest-neighbor interpolation in two dimensions.
Definition: interp2_neigh.h:70
double y_scale
The user-specified y scale (default -1)
Definition: interp2_neigh.h:97
vec_t * ux
The x-values.
double x_scale
The user-specified x scale (default -1)
Definition: interp2_neigh.h:94
vec_t * uf
The f-values.
bool data_set
True if the data has been specified.
invalid argument supplied by user
Definition: err_hnd.h:59
double dx
The scale in the x direction.
Definition: interp2_neigh.h:75
generic failure
Definition: err_hnd.h:61
vec_t * uy
The y-values.
double eval(double x, double y) const
Perform the interpolation.
void eval_point(double x, double y, double &f, size_t &i1, double &x1, double &y1) const
Interpolation returning the closest point.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
double operator()(double x, double y) const
Perform the interpolation.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Definition: err_hnd.h:273
size_t np
The number of points.
double operator()(vec2_t &v) const
Perform the planar interpolation using the first two elements of v as input.
void set_data(size_t n_points, vec_t &x, vec_t &y, vec_t &f)
Initialize the data for the neigh interpolation.
double dy
The scale in the y direction.
Definition: interp2_neigh.h:78
static const double x1[5]
Definition: inte_qng_gsl.h:48
void compute_scale()
Find scaling.

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).
Hosted at Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads..