MiscMath.hpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
44 #ifndef GNSSTK_MISCMATH_HPP
45 #define GNSSTK_MISCMATH_HPP
46 
47 #include <cstring> // for size_t
48 #include <vector>
49 #include "MathBase.hpp"
50 #include "Exception.hpp"
51 
52 namespace gnsstk
53 {
57 
59 
65  template <class T>
66  T SimpleLagrangeInterpolation(const std::vector<T>& X,
67  const std::vector<T>& Y,
68  const T x)
69  {
70  if(Y.size() < X.size()) {
71  GNSSTK_THROW(Exception("Input vectors must be of same size"));
72  }
73  size_t i,j;
74  T Yx(0);
75  for(i=0; i<X.size(); i++) {
76  if(x==X[i]) return Y[i];
77 
78  T Li(1);
79  for(j=0; j<X.size(); j++)
80  if(i!=j) Li *= (x-X[j])/(X[i]-X[j]);
81 
82  Yx += Li*Y[i];
83  }
84  return Yx;
85  } // end T LagrangeInterpolation(const vector, const vector, const T)
86 
97  template <class T>
98  T LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y,
99  const T& x, T& err)
100  {
101  if(Y.size() < X.size() || X.size() < 4) {
102  GNSSTK_THROW(Exception("Input vectors must be of same length, at least 4"));
103  }
104 
105  std::size_t i,j,k;
106  T y,del;
107  std::vector<T> D,Q;
108 
109  err = T(0);
110  k = X.size()/2;
111  if(x == X[k]) return Y[k];
112  if(x == X[k-1]) return Y[k-1];
113  if(ABS(x-X[k-1]) < ABS(x-X[k])) k=k-1;
114  for(i=0; i<X.size(); i++) {
115  Q.push_back(Y[i]);
116  D.push_back(Y[i]);
117  }
118  y = Y[k--];
119  for(j=1; j<X.size(); j++) {
120  for(i=0; i<X.size()-j; i++) {
121  del = (Q[i+1]-D[i])/(X[i]-X[i+j]);
122  D[i] = (X[i+j]-x)*del;
123  Q[i] = (X[i]-x)*del;
124  }
125  err = (2*(k+1) < X.size()-j ? Q[k+1] : D[k--]); // NOT 2*k
126  y += err;
127  }
128  return y;
129  } // end T LagrangeInterpolation(vector, vector, const T, T&)
130 
131  // The following is a
132  // Straightforward implementation of Lagrange polynomial and its derivative
133  // { all sums are over index=0,N-1; Xi is short for X[i]; Lp is dL/dx;
134  // y(x) is the function being approximated. }
135  // y(x) = SUM[Li(x)*Yi]
136  // Li(x) = PROD(j!=i)[x-Xj] / PROD(j!=i)[Xi-Xj]
137  // dy(x)/dx = SUM[Lpi(x)*Yi]
138  // Lpi(x) = SUM(k!=i){PROD(j!=i,j!=k)[x-Xj]} / PROD(j!=i)[Xi-Xj]
139  // Define Pi = PROD(j!=i)[x-Xj], Di = PROD(j!=i)[Xi-Xj],
140  // Qij = PROD(k!=i,k!=j)[x-Xk] and Si = SUM(j!=i)Qij.
141  // then Li(x) = Pi/Di, and Lpi(x) = Si/Di.
142  // Qij is symmetric, there are only N(N+1)/2 - N of them, so store them
143  // in a vector of length N(N+1)/2, where Qij==Q[i+j*(j+1)/2] (ignore i=j).
144 
153  template <class T>
154  void LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y,
155  const T& x, T& y, T& dydx)
156  {
157  if(Y.size() < X.size() || X.size() < 4) {
158  GNSSTK_THROW(Exception("Input vectors must be of same length, at least 4"));
159  }
160 
161  std::size_t i,j,k,N=X.size(),M;
162  M = (N*(N+1))/2;
163  std::vector<T> P(N,T(1)),Q(M,T(1)),D(N,T(1));
164  for(i=0; i<N; i++) {
165  for(j=0; j<N; j++) {
166  if(i != j) {
167  P[i] *= x-X[j];
168  D[i] *= X[i]-X[j];
169  if(i < j) {
170  for(k=0; k<N; k++) {
171  if(k == i || k == j) continue;
172  Q[i+(j*(j+1))/2] *= (x-X[k]);
173  }
174  }
175  }
176  }
177  }
178  y = dydx = T(0);
179  for(i=0; i<N; i++) {
180  y += Y[i]*(P[i]/D[i]);
181  T S(0);
182  for(k=0; k<N; k++) if(i != k) {
183  if(k<i) S += Q[k+(i*(i+1))/2]/D[i];
184  else S += Q[i+(k*(k+1))/2]/D[i];
185  }
186  dydx += Y[i]*S;
187  }
188  } // end void LagrangeInterpolation(vector, vector, const T, T&, T&)
189 
190 
192  template <class T>
193  T LagrangeInterpolating2ndDerivative(const std::vector<T>& pos,
194  const std::vector<T>& val,
195  const T desiredPos)
196  {
197  int degree(pos.size());
198  int i,j,m,n;
199 
200  // First, compute interpolation factors
201  typedef std::vector< T > vectorType;
202  std::vector< vectorType > delta(degree, vectorType(degree, 0.0));
203 
204  for(i=0; i < degree; ++i) {
205  for(j=0; j < degree; ++j) {
206  if(j != i) {
207  delta[i][j] = ((desiredPos - pos[j])/(pos[i] - pos[j]));
208  }
209  }
210  }
211 
212  double retVal(0.0);
213  for(i=0; i < degree; ++i) {
214  double sum(0.0);
215 
216  for(m=0; m < degree; ++m) {
217  if(m != i) {
218  double weight1(1.0/(pos[i]-pos[m]));
219  double sum2(0.0);
220 
221  for(j=0; j < degree; ++j) {
222  if((j != i) && (j != m)) {
223  double weight2(1.0/(pos[i]-pos[j]));
224  for(n=0; n < degree; ++n) {
225  if((n != j) && (n != m) && (n != i)) {
226  weight2 *= delta[i][n];
227  }
228  }
229  sum2 += weight2;
230  }
231  }
232  sum += sum2*weight1;
233  }
234  }
235  retVal += val[i] * sum;
236  }
237 
238  return retVal;
239 
240  } // End of 'lagrangeInterpolating2ndDerivative()'
241 
242 #define tswap(x,y) { T tmp; tmp = x; x = y; y = tmp; }
243 
245  template <class T>
246  T RSS (T aa, T bb, T cc)
247  {
248  T a(ABS(aa)), b(ABS(bb)), c(ABS(cc));
249  if(a < b) tswap(a,b);
250  if(a < c) tswap(a,c);
251  if(a == T(0)) return T(0);
252  return a * SQRT(1 + (b/a)*(b/a) + (c/a)*(c/a));
253  }
254 
256  template <class T>
257  T RSS (T aa, T bb)
258  {
259  return RSS(aa,bb,T(0));
260  }
261 
263  template <class T>
264  T RSS (T aa, T bb, T cc, T dd)
265  {
266  T a(ABS(aa)), b(ABS(bb)), c(ABS(cc)), d(ABS(dd));
267  // For numerical reason, let's just put the biggest in "a" (we are not sorting)
268  if(a < b) tswap(a,b);
269  if(a < c) tswap(a,c);
270  if(a < d) tswap(a,d);
271  if(a == T(0)) return T(0);
272  return a * SQRT(1 + (b/a)*(b/a) + (c/a)*(c/a) + (d/a)*(d/a));
273  }
274 
275 #undef tswap
276 
277  inline double Round(double x)
278  {
279  return double(std::floor(x+0.5));
280  }
281 
283 
284 } // namespace gnsstk
285 
286 #endif
tswap
#define tswap(x, y)
Definition: MiscMath.hpp:242
SQRT
#define SQRT(x)
Definition: MathBase.hpp:74
gnsstk::TrackingCode::Y
@ Y
Encrypted legacy GPS precise code.
gnsstk::LagrangeInterpolating2ndDerivative
T LagrangeInterpolating2ndDerivative(const std::vector< T > &pos, const std::vector< T > &val, const T desiredPos)
Returns the second derivative of Lagrange interpolation.
Definition: MiscMath.hpp:193
gnsstk::sum
T sum(const ConstVectorBase< T, BaseClass > &l)
Definition: VectorBaseOperators.hpp:84
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
gnsstk::SimpleLagrangeInterpolation
T SimpleLagrangeInterpolation(const std::vector< T > &X, const std::vector< T > &Y, const T x)
Definition: MiscMath.hpp:66
gnsstk::Exception
Definition: Exception.hpp:151
y
page HOWTO subpage DoxygenGuide Documenting Your Code page DoxygenGuide Documenting Your Code todo Flesh out this document section doctips Tips for Documenting When defining make sure that the prototype is identical between the cpp and hpp including both the namespaces and the parameter names for you have std::string as the return type in the hpp file and string as the return type in the cpp Doxygen may get confused and autolink to the cpp version with no documentation If you don t use the same parameter names between the cpp and hpp that will also confuse Doxygen Don t put type information in return or param documentation It doesn t really add anything and will often cause Doxygen to complain and not produce the documentation< br > use note Do not put a comma after a param name unless you mean to document multiple parameters< br/> the output stream</code >< br/> y
Definition: DOCUMENTING.dox:15
example4.err
err
Definition: example4.py:126
gnsstk::RSS
T RSS(T aa, T bb, T cc)
Perform the root sum square of aa, bb and cc.
Definition: MiscMath.hpp:246
example4.pos
pos
Definition: example4.py:125
gnsstk::TrackingCode::P
@ P
Legacy GPS precise code.
ABS
#define ABS(x)
Definition: MathBase.hpp:73
Exception.hpp
GNSSTK_THROW
#define GNSSTK_THROW(exc)
Definition: Exception.hpp:366
MathBase.hpp
gnsstk::LagrangeInterpolation
T LagrangeInterpolation(const std::vector< T > &X, const std::vector< T > &Y, const T &x, T &err)
Definition: MiscMath.hpp:98
gnsstk::Round
double Round(double x)
Definition: MiscMath.hpp:277


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:40