All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
interpm_idw.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_INTERPM_IDW_H
24 #define O2SCL_INTERPM_IDW_H
25 
26 /** \file interpm_idw.h
27  \brief File defining \ref o2scl::interpm_idw
28 */
29 
30 #include <iostream>
31 #include <string>
32 #include <cmath>
33 
34 #include <gsl/gsl_combination.h>
35 
36 #include <o2scl/err_hnd.h>
37 #include <o2scl/vector.h>
38 
39 #ifndef DOXYGEN_NO_O2NS
40 namespace o2scl {
41 #endif
42 
43  /** \brief Multi-dimensional interpolation by inverse distance
44  weighting
45 
46  This class performs interpolation on a multi-dimensional data
47  set specified as a series of scattered points using the inverse
48  distance-weighted average of the nearest three points. The
49  function \ref set_data() takes as input: the number of
50  dimensions, the number of points which specify the data, and a
51  "vector of vectors", e.g. <tt>std::vector<std::vector<double>
52  ></tt> which contains the data for all the points.
53  */
54  template<class vec_t> class interpm_idw {
55 
56  public:
57 
60 
61  interpm_idw() {
62  data_set=false;
63  scales.resize(1);
64  scales[0]=1.0;
65  }
66 
67  /// Distance scales for each coordinate
69 
70  /** \brief Initialize the data for the interpolation
71 
72  The object \c vecs should be a vector (of size <tt>dim+1</tt>)
73  of vectors (all of size <tt>n_points</tt>). It may have any
74  type for which the data can be accessed through
75  <tt>operator[][]</tt>.
76  */
77  template<class vec_vec_t>
78  void set_data(size_t dim, size_t n_points, vec_vec_t &vecs) {
79 
80  if (n_points<3) {
81  O2SCL_ERR2("Must provide at least three points in ",
82  "interpm_idw::set_data()",exc_efailed);
83  }
84  np=n_points;
85  nd=dim;
86  ptrs.resize(dim+1);
87  for(size_t i=0;i<dim+1;i++) {
88  ptrs[i]=&vecs[i];
89  }
90  data_set=true;
91 
92  return;
93  }
94 
95  /** \brief Perform the interpolation
96  */
97  template<class vec2_t> double operator()(vec2_t &x) const {
98  return eval(x);
99  }
100 
101  /** \brief Perform the interpolation
102  */
103  template<class vec2_t> double eval(vec2_t &x) const {
104 
105  if (data_set==false) {
106  O2SCL_ERR("Data not set in interpm_idw::eval_points().",
107  exc_einval);
108  }
109 
110  // Find the three closest points by
111  // exhaustively searching the data
112 
113  // Put in initial points
114  size_t i1=0;
115  size_t i2=1;
116  size_t i3=2;
117  double c1=dist(i1,x);
118  double c2=dist(i2,x);
119  double c3=dist(i3,x);
120 
121  // Sort initial points
122  if (c2<c1) {
123  if (c3<c2) {
124  // 321
125  swap(i1,c1,i3,c3);
126  } else if (c3<c1) {
127  // 231
128  swap(i1,c1,i2,c2);
129  swap(i2,c2,i3,c3);
130  } else {
131  // 213
132  swap(i1,c1,i2,c2);
133  }
134  } else {
135  if (c3<c1) {
136  // 312
137  swap(i1,c1,i3,c3);
138  swap(i2,c2,i3,c3);
139  } else if (c3<c2) {
140  // 132
141  swap(i3,c3,i2,c2);
142  }
143  // 123
144  }
145 
146  // Go through remaining points and sort accordingly
147  for(size_t j=3;j<np;j++) {
148  size_t i4=j;
149  double c4=dist(i4,x);
150  if (c4<c1) {
151  swap(i4,c4,i3,c3);
152  swap(i3,c3,i2,c2);
153  swap(i2,c2,i1,c1);
154  } else if (c4<c2) {
155  swap(i4,c4,i3,c3);
156  swap(i3,c3,i2,c2);
157  } else if (c4<c3) {
158  swap(i4,c4,i3,c3);
159  }
160  }
161 
162  // The function values of the three-closest points
163  double f1=(*(ptrs[nd]))[i1];
164  double f2=(*(ptrs[nd]))[i2];
165  double f3=(*(ptrs[nd]))[i3];
166 
167  // Check if any of the distances is zero
168  if (c1==0.0) {
169  return f1;
170  } else if (c2==0.0) {
171  return f2;
172  } else if (c3==0.0) {
173  return f3;
174  }
175 
176  // Return the inverse-distance weighed average
177  double norm=1.0/c1+1.0/c2+1.0/c3;
178  return (f1/c1+f2/c2+f3/c3)/norm;
179  }
180 
181 #ifndef DOXYGEN_INTERNAL
182 
183  protected:
184 
185  /// The number of points
186  size_t np;
187  /// The number of dimensions
188  size_t nd;
189  /// A vector of pointers holding the data
190  std::vector<vec_t *> ptrs;
191  /// True if the data has been specified
192  bool data_set;
193 
194  /// Compute the distance between \c x and the point at index \c index
195  template<class vec2_t> double dist(size_t index, vec2_t &x) const {
196  double ret=0.0;
197  size_t nscales=scales.size();
198  for(size_t i=0;i<nd;i++) {
199  ret+=pow((x[i]-(*(ptrs[i]))[index])/scales[i%nscales],2.0);
200  }
201  return sqrt(ret);
202  }
203 
204  /// Swap points 1 and 2
205  int swap(size_t &index_1, double &dist_1, size_t &index_2,
206  double &dist_2) const {
207 
208  size_t index_temp;
209  double dist_temp;
210 
211  index_temp=index_1; dist_temp=dist_1;
212  index_1=index_2; dist_1=dist_2;
213  index_2=index_temp; dist_2=dist_temp;
214 
215  return 0;
216  }
217 
218 #endif
219 
220  };
221 
222 #ifndef DOXYGEN_NO_O2NS
223 }
224 #endif
225 
226 #endif
227 
228 
229 
Multi-dimensional interpolation by inverse distance weighting.
Definition: interpm_idw.h:54
double eval(vec2_t &x) const
Perform the interpolation.
Definition: interpm_idw.h:103
invalid argument supplied by user
Definition: err_hnd.h:59
std::vector< vec_t * > ptrs
A vector of pointers holding the data.
Definition: interpm_idw.h:190
size_t nd
The number of dimensions.
Definition: interpm_idw.h:188
generic failure
Definition: err_hnd.h:61
ubvector scales
Distance scales for each coordinate.
Definition: interpm_idw.h:68
int swap(size_t &index_1, double &dist_1, size_t &index_2, double &dist_2) const
Swap points 1 and 2.
Definition: interpm_idw.h:205
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Definition: err_hnd.h:281
double operator()(vec2_t &x) const
Perform the interpolation.
Definition: interpm_idw.h:97
#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.
Definition: interpm_idw.h:186
bool data_set
True if the data has been specified.
Definition: interpm_idw.h:192
double dist(size_t index, vec2_t &x) const
Compute the distance between x and the point at index index.
Definition: interpm_idw.h:195
void set_data(size_t dim, size_t n_points, vec_vec_t &vecs)
Initialize the data for the interpolation.
Definition: interpm_idw.h:78

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..