xmsinterp  1.0
InterpUtil.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
7 //------------------------------------------------------------------------------
8 
9 //----- Included files ---------------------------------------------------------
10 
11 // 1. Precompiled header
12 
13 // 2. My own header
15 
16 // 3. Standard library headers
17 
18 // 4. External library headers
19 #include <xmscore/math/math.h>
20 
21 // 5. Shared code headers
22 
23 // 6. Non-shared code headers
24 
25 //----- Forward declarations ---------------------------------------------------
26 
27 //----- External globals -------------------------------------------------------
28 
29 //----- Namespace declaration --------------------------------------------------
30 namespace xms
31 {
32 //----- Constants / Enumerations -----------------------------------------------
33 
34 //----- Classes / Structs ------------------------------------------------------
35 
36 //----- Internal functions -----------------------------------------------------
37 
38 //----- Class / Function definitions -------------------------------------------
39 
40 //------------------------------------------------------------------------------
49 //------------------------------------------------------------------------------
51  double yk,
52  double fk,
53  const std::vector<InterpPtInfo>& closest,
54  double** M,
55  double* VV)
56 {
57  int i, j, n;
58  double v1[6], v2[6]; // fg_vv is made up of two summations
59  double wi, xi, yi, fi;
60 
61  n = (int)closest.size();
62  // initialize matrix and vector.
63  for (i = 1; i <= 5; i++)
64  {
65  v1[i] = 0.0;
66  v2[i] = 0.0;
67  VV[i - 1] = 0.0;
68  for (j = 1; j <= 5; j++)
69  M[i - 1][j - 1] = 0.0;
70  }
71 
72  for (i = 0; i < n; i++)
73  { // weights will all be zero when i=n-1
74  wi = closest[i].m_weight;
75  xi = closest[i].m_loc.x - xk;
76  yi = closest[i].m_loc.y - yk;
77  fi = closest[i].m_scalar;
78 
79  // set up matrix in banded form.
80  M[0][0] = M[0][0] + wi * xi * xi;
81  M[0][1] = M[0][1] + wi * xi * yi;
82  M[0][2] = M[0][2] + wi * xi * xi * xi;
83  M[0][3] = M[0][3] + wi * xi * xi * yi;
84  M[0][4] = M[0][4] + wi * xi * yi * yi;
85  v1[1] = v1[1] + wi * xi * fi;
86  v2[1] = v2[1] + wi * xi;
87 
88  M[1][0] = M[1][0] + wi * yi * yi;
89  M[1][1] = M[1][1] + wi * xi * xi * yi;
90  M[1][2] = M[1][2] + wi * xi * yi * yi;
91  M[1][3] = M[1][3] + wi * yi * yi * yi;
92  v1[2] = v1[2] + wi * yi * fi;
93  v2[2] = v2[2] + wi * yi;
94 
95  M[2][0] = M[2][0] + wi * xi * xi * xi * xi;
96  M[2][1] = M[2][1] + wi * xi * xi * xi * yi;
97  M[2][2] = M[2][2] + wi * xi * xi * yi * yi;
98  v1[3] = v1[3] + wi * xi * xi * fi;
99  v2[3] = v2[3] + wi * xi * xi;
100 
101  M[3][0] = M[3][0] + wi * xi * xi * yi * yi;
102  M[3][1] = M[3][1] + wi * xi * yi * yi * yi;
103  v1[4] = v1[4] + wi * xi * yi * fi;
104  v2[4] = v2[4] + wi * xi * yi;
105 
106  M[4][0] = M[4][0] + wi * yi * yi * yi * yi;
107  v1[5] = v1[5] + wi * yi * yi * fi;
108  v2[5] = v2[5] + wi * yi * yi;
109  }
110 
111  for (i = 1; i <= 5; i++)
112  VV[i - 1] = v1[i] - fk * v2[i];
113 
114 } // inNodalFuncSetUpMatrixAndVector
115 //------------------------------------------------------------------------------
125 //------------------------------------------------------------------------------
127  double yk,
128  double zk,
129  double fk,
130  const std::vector<InterpPtInfo>& closest,
131  double** M,
132  double* vv)
133 {
134  int i, j;
135  double v1[10], v2[10]; // vv is made up of two summations
136  double wi, xi, yi, zi, fi;
137  double xyi, xzi, yzi, x2i, y2i, z2i, wXi;
138  double** m = M;
139 
140  // initialize to matrix and vector.
141  // NOTE: arrays are defined from 1,not 0: this is so I'm compatible with
142  // the function solve_banded_matrix in matrices.c
143  for (i = 1; i < 10; i++)
144  {
145  v1[i] = 0.0;
146  v2[i] = 0.0;
147  vv[i - 1] = 0.0;
148  for (j = 1; j < 10; j++)
149  m[i - 1][j - 1] = 0.0;
150  }
151 
152  for (i = 0; i < (int)closest.size(); ++i)
153  {
154  wi = closest[i].m_weight;
155  xi = closest[i].m_loc.x - xk;
156  yi = closest[i].m_loc.y - yk;
157  zi = closest[i].m_loc.z - zk;
158  fi = closest[i].m_scalar;
159 
160  // set up matrix in banded form.
161  xyi = xi * yi;
162  xzi = xi * zi;
163  yzi = yi * zi;
164  x2i = xi * xi;
165  y2i = yi * yi;
166  z2i = zi * zi;
167 
168  wXi = wi * xi;
169  m[0][0] += (wXi * xi);
170  m[0][1] += (wXi * yi);
171  m[0][2] += (wXi * zi);
172  m[0][3] += (wXi * xyi);
173  m[0][4] += (wXi * xzi);
174  m[0][5] += (wXi * yzi);
175  m[0][6] += (wXi * x2i);
176  m[0][7] += (wXi * y2i);
177  m[0][8] += (wXi * z2i);
178  v1[1] += (wXi * fi);
179  v2[1] += wXi;
180 
181  wXi = wi * yi;
182  m[1][0] += (wXi * yi);
183  m[1][1] += (wXi * zi);
184  m[1][2] += (wXi * xyi);
185  m[1][3] += (wXi * xzi);
186  m[1][4] += (wXi * yzi);
187  m[1][5] += (wXi * x2i);
188  m[1][6] += (wXi * y2i);
189  m[1][7] += (wXi * z2i);
190  v1[2] += (wXi * fi);
191  v2[2] += wXi;
192 
193  wXi = wi * zi;
194  m[2][0] += (wXi * zi);
195  m[2][1] += (wXi * xyi);
196  m[2][2] += (wXi * xzi);
197  m[2][3] += (wXi * yzi);
198  m[2][4] += (wXi * x2i);
199  m[2][5] += (wXi * y2i);
200  m[2][6] += (wXi * z2i);
201  v1[3] += (wXi * fi);
202  v2[3] += wXi;
203 
204  wXi = wi * xyi;
205  m[3][0] += (wXi * xyi);
206  m[3][1] += (wXi * xzi);
207  m[3][2] += (wXi * yzi);
208  m[3][3] += (wXi * x2i);
209  m[3][4] += (wXi * y2i);
210  m[3][5] += (wXi * z2i);
211  v1[4] += (wXi * fi);
212  v2[4] += wXi;
213 
214  wXi = wi * xzi;
215  m[4][0] += (wXi * xzi);
216  m[4][1] += (wXi * yzi);
217  m[4][2] += (wXi * x2i);
218  m[4][3] += (wXi * y2i);
219  m[4][4] += (wXi * z2i);
220  v1[5] += (wXi * fi);
221  v2[5] += wXi;
222 
223  wXi = wi * yzi;
224  m[5][0] += (wXi * yzi);
225  m[5][1] += (wXi * x2i);
226  m[5][2] += (wXi * y2i);
227  m[5][3] += (wXi * z2i);
228  v1[6] += (wXi * fi);
229  v2[6] += wXi;
230 
231  wXi = wi * x2i;
232  m[6][0] += (wXi * x2i);
233  m[6][1] += (wXi * y2i);
234  m[6][2] += (wXi * z2i);
235  v1[7] += (wXi * fi);
236  v2[7] += wXi;
237 
238  wXi = wi * y2i;
239  m[7][0] += (wXi * y2i);
240  m[7][1] += (wXi * z2i);
241  v1[8] += (wXi * fi);
242  v2[8] += wXi;
243 
244  wXi = wi * z2i;
245  m[8][0] += (wXi * z2i);
246  v1[9] += (wXi * fi);
247  v2[9] += wXi;
248  }
249 
250  for (i = 1; i <= 9; i++)
251  vv[i - 1] = v1[i] - fk * v2[i];
252 } // inNodalFuncSetUpMatrixAndVector3d
253 //------------------------------------------------------------------------------
265 //------------------------------------------------------------------------------
266 void inDistanceSquared(const Pt3d& a_pt,
267  const std::vector<int>& a_ptIdxs,
268  const std::vector<Pt3d>& a_ptLoc,
269  bool a_2d,
270  std::vector<double>& a_d2)
271 {
272  bool useAll = a_ptIdxs.empty();
273  size_t nPtIdxs = useAll ? a_ptLoc.size() : a_ptIdxs.size();
274  a_d2.resize(0);
275  a_d2.reserve(nPtIdxs);
276  size_t j;
277  double d2;
278  for (size_t i = 0; i < nPtIdxs; ++i)
279  {
280  j = useAll ? i : a_ptIdxs[i];
281  d2 = xms::sqr(a_pt.x - a_ptLoc[j].x) + xms::sqr(a_pt.y - a_ptLoc[j].y);
282  if (!a_2d)
283  d2 += xms::sqr(a_pt.z - a_ptLoc[j].z);
284  a_d2.push_back(d2);
285  }
286 } // inDistanceSquared
287 //------------------------------------------------------------------------------
304 //------------------------------------------------------------------------------
305 void inIdwWeights(const std::vector<double>& a_distSquare,
306  double a_power,
307  bool a_modifiedShepardWeights,
308  std::vector<double>& a_w)
309 {
310  std::vector<double> d2(a_distSquare);
311  double distSum(0), dExp(a_power / 2), r, d;
312  a_w.resize(0);
313  a_w.assign(d2.size(), 0);
314  r = sqrt(*std::max_element(d2.begin(), d2.end()));
315  for (size_t i = 0; i < d2.size(); ++i)
316  { // this is basically at the same location as our point
317  if (d2[i] < 1e-20)
318  d2[i] = 1e10;
319  }
320  for (size_t i = 0; i < d2.size(); ++i)
321  {
322  if (a_modifiedShepardWeights)
323  { // Franke, R., and Neilson, G. 1980. Smooth interpolation of large sets
324  // of scattered data. International Journal of Numerical Methods
325  // in Engineering 15, 1691-1704.
326 
327  // r is the distance to the furthest point, d is the distance to the
328  // current point
329  d = sqrt(d2[i]);
330  d2[i] = xms::sqr((r - d) / (r * d));
331  }
332  else
333  { // classic weighting function
334  if (dExp == 1)
335  { // 1 over distance squared
336  d2[i] = 1 / d2[i];
337  }
338  else
339  { // if the m_power variable is not 2 then we have to use the "pow" function
340  d2[i] = 1 / pow(d2[i], dExp);
341  }
342  }
343  distSum += d2[i];
344  }
345  if (0.0 == distSum)
346  {
347  d2 = a_distSquare;
348  for (size_t i = 0; i < d2.size(); ++i)
349  distSum += d2[i];
350  }
351  for (size_t i = 0; i < d2.size(); ++i)
352  {
353  a_w[i] = d2[i] / distSum;
354  }
355 } // inIdwWeights
356 //------------------------------------------------------------------------------
362 //------------------------------------------------------------------------------
363 bool inAllScalarsEqual(const std::vector<float>& a_scalars, const DynBitset& a_act)
364 {
365  bool allScalarsSame(true);
366  if (a_scalars.empty())
367  return allScalarsSame;
368 
369  if (a_act.empty() || a_act.size() != a_scalars.size())
370  {
371  float f = a_scalars[0];
372  for (size_t i = 1; allScalarsSame && i < a_scalars.size(); ++i)
373  {
374  if (f != a_scalars[i])
375  allScalarsSame = false;
376  }
377  return allScalarsSame;
378  }
379 
380  // get first active value
381  size_t idx(0);
382  if (!a_act[0])
383  {
384  for (size_t i = 1; idx == 0 && i < a_act.size(); ++i)
385  {
386  if (a_act[i])
387  idx = i;
388  }
389  }
390 
391  float f = a_scalars[idx];
392  for (size_t i = idx + 1; allScalarsSame && i < a_scalars.size(); ++i)
393  {
394  if (a_act[i] && f != a_scalars[i])
395  allScalarsSame = false;
396  }
397  return allScalarsSame;
398 } // inAllScalarsEqual
399 
400 } // namespace xms
boost::dynamic_bitset< size_t > DynBitset
void inNodalFuncSetUpMatrixAndVector(double xk, double yk, double fk, const std::vector< InterpPtInfo > &closest, double **M, double *VV)
Sets up matrices for nodal function calculations. Refactored out of GMS.
Definition: InterpUtil.cpp:50
void inNodalFuncSetUpMatrixAndVector3d(double xk, double yk, double zk, double fk, const std::vector< InterpPtInfo > &closest, double **M, double *vv)
Sets up matrices for nodal function calculations. Refactored out of GMS.
Definition: InterpUtil.cpp:126
Utility functions called by interpolation code.
void inDistanceSquared(const Pt3d &a_pt, const std::vector< int > &a_ptIdxs, const std::vector< Pt3d > &a_ptLoc, bool a_2d, std::vector< double > &a_d2)
Computes the distance squared between the point "a_pt" and the other points. The other points are def...
Definition: InterpUtil.cpp:266
void inIdwWeights(const std::vector< double > &a_distSquare, double a_power, bool a_modifiedShepardWeights, std::vector< double > &a_w)
Computes the idw weights that would be assigned to points associated with the distance squared that i...
Definition: InterpUtil.cpp:305
bool inAllScalarsEqual(const std::vector< float > &a_scalars, const DynBitset &a_act)
Check to see if the all of the values in the scalars array are the same. It will also take into accou...
Definition: InterpUtil.cpp:363