00001 #pragma ident "$Id: MiscMath.hpp 3327 2012-10-31 13:11:36Z btolman $"
00002
00003
00004
00010 #ifndef GPSTK_MISCMATH_HPP
00011 #define GPSTK_MISCMATH_HPP
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <cstring>
00050 #include <vector>
00051 #include "MathBase.hpp"
00052 #include "DebugUtils.hpp"
00053
00054 namespace gpstk
00055 {
00058
00069 template <class T>
00070 T LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y, T x)
00071 {
00072 GPSTK_ASSERT(X.size()==Y.size());
00073
00074 T Yx(0.0);
00075 for(std::size_t i=0;i<X.size();i++)
00076 {
00077 if(x==X[i]) return Y[i];
00078
00079 T Li(1.0);
00080 for(std::size_t j=0;j<X.size();j++)
00081 {
00082 if(i!=j) Li *= (x-X[j])/(X[i]-X[j]);
00083 }
00084 Yx += Li*Y[i];
00085 }
00086
00087 return Yx;
00088
00089 }
00090
00091
00096 template <class T>
00097 T LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y, const T& x, T& err)
00098 {
00099 std::size_t i,j,k;
00100 T y,del;
00101 std::vector<T> D,Q;
00102
00103 err = T(0);
00104 k = X.size()/2;
00105 if(x == X[k]) return Y[k];
00106 if(x == X[k-1]) return Y[k-1];
00107 if(ABS(x-X[k-1]) < ABS(x-X[k])) k=k-1;
00108 for(i=0; i<X.size(); i++) {
00109 Q.push_back(Y[i]);
00110 D.push_back(Y[i]);
00111 }
00112 y = Y[k--];
00113 for(j=1; j<X.size(); j++) {
00114 for(i=0; i<X.size()-j; i++) {
00115 del = (Q[i+1]-D[i])/(X[i]-X[i+j]);
00116 D[i] = (X[i+j]-x)*del;
00117 Q[i] = (X[i]-x)*del;
00118 }
00119 err = (2*k < X.size()-j ? Q[k+1] : D[k--]);
00120 y += err;
00121 }
00122 return y;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00145 template <class T>
00146 void LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y, const T& x, T& y, T& dydx)
00147 {
00148 std::size_t i,j,k,N=X.size(),M;
00149 M = (N*(N+1))/2;
00150 std::vector<T> P(N,T(1)),Q(M,T(1)),D(N,T(1));
00151 for(i=0; i<N; i++) {
00152 for(j=0; j<N; j++) {
00153 if(i != j) {
00154 P[i] *= x-X[j];
00155 D[i] *= X[i]-X[j];
00156 if(i < j) {
00157
00158 for(k=0; k<N; k++) {
00159 if(k == i || k == j) continue;
00160
00161 Q[i+(j*(j+1))/2] *= (x-X[k]);
00162 }
00163
00164 }
00165 }
00166 }
00167 }
00168 y = dydx = T(0);
00169 for(i=0; i<N; i++) {
00170 y += Y[i]*(P[i]/D[i]);
00171 T S(0);
00172 for(k=0; k<N; k++) if(i != k) {
00173 if(k<i) S += Q[k+(i*(i+1))/2]/D[i];
00174 else S += Q[i+(k*(k+1))/2]/D[i];
00175 }
00176 dydx += Y[i]*S;
00177 }
00178 }
00179
00180
00182 template <class T>
00183 T LagrangeInterpolating2ndDerivative( const std::vector<T>& pos,
00184 const std::vector<T>& val,
00185 T desiredPos )
00186 {
00187
00188 int degree( pos.size() );
00189
00190
00191 typedef std::vector< T > vectorType;
00192 std::vector< vectorType > delta( degree, vectorType(degree, 0.0) );
00193
00194
00195 for (int i = 0; i < degree; ++i)
00196 {
00197 for (int j = 0; j < degree; ++j)
00198 {
00199 if (j != i)
00200 {
00201 delta[i][j] = ( (desiredPos - pos[j]) / (pos[i] - pos[j]) );
00202 }
00203 }
00204 }
00205
00206 double retVal(0.0);
00207
00208 for( int i = 0; i < degree; ++i )
00209 {
00210 double sum( 0.0 );
00211
00212 for( int m = 0; m < degree; ++m )
00213 {
00214
00215 if( m != i )
00216 {
00217
00218 double weight1( 1.0/(pos[i]-pos[m]) );
00219 double sum2( 0.0 );
00220
00221 for( int j = 0; j < degree; ++j )
00222 {
00223
00224 if( (j != i) && (j != m) )
00225 {
00226
00227 double weight2( 1.0/(pos[i]-pos[j]) );
00228
00229 for( int n = 0; n < degree; ++n )
00230 {
00231
00232 if( (n != j) && (n != m) && (n != i) )
00233 {
00234 weight2 *= delta[i][n];
00235 }
00236 }
00237 sum2 += weight2;
00238 }
00239 }
00240
00241 sum += sum2*weight1;
00242 }
00243
00244 }
00245
00246 retVal += val[i] * sum;
00247 }
00248
00249 return retVal;
00250
00251 }
00252
00253
00255 template <class T>
00256 T RSS (T aa, T bb, T cc)
00257 {
00258 T a(ABS(aa)), b(ABS(bb)), c(ABS(cc));
00259 if ( (a > b) && (a > c) )
00260 return a * SQRT(1 + (b/a)*(b/a) + (c/a)*(c/a));
00261 if ( (b > a) && (b > c) )
00262 return b * SQRT(1 + (a/b)*(a/b) + (c/b)*(c/b));
00263 if ( (c > b) && (c > a) )
00264 return c * SQRT(1 + (b/c)*(b/c) + (a/c)*(a/c));
00265
00266 if (a == b)
00267 {
00268 if (b == c)
00269 return a * SQRT(T(3));
00270 a *= SQRT(T(2));
00271 if (a > c)
00272 return a * SQRT(1 + (c/a)*(c/a));
00273 else
00274 return c * SQRT(1 + (a/c)*(a/c));
00275 }
00276 if (a == c)
00277 {
00278 a *= SQRT(T(2));
00279 if (a > b)
00280 return a * SQRT(1 + (b/a)*(b/a));
00281 else
00282 return b * SQRT(1 + (a/b)*(a/b));
00283 }
00284 if (b == c)
00285 {
00286 b *= SQRT(T(2));
00287 if (b > a)
00288 return b * SQRT(1 + (a/b)*(a/b));
00289 else
00290 return a * SQRT(1 + (b/a)*(b/a));
00291 }
00292
00293 return T(0);
00294 }
00295
00297 template <class T>
00298 T RSS (T aa, T bb)
00299 {
00300 return RSS(aa,bb,T(0));
00301 }
00302
00303
00305 template <class T>
00306 T RSS (T aa, T bb, T cc, T dd)
00307 {
00308 #define swapValues(x,y) \
00309 { T temporalStorage; \
00310 temporalStorage = x; x = y; y = temporalStorage; }
00311
00312 T a(ABS(aa)), b(ABS(bb)), c(ABS(cc)), d(ABS(dd));
00313
00314
00315 if (a < b) std::swap(a,b);
00316 if (a < c) swapValues(a,c);
00317 if (a < d) swapValues(a,d);
00318
00319 return a * SQRT(1 + (b/a)*(b/a) + (c/a)*(c/a) + (d/a)*(d/a));
00320 }
00321
00322
00323 inline double Round(double x)
00324 {
00325 return double(std::floor(x+0.5));
00326 }
00328
00329 }
00330
00331 #endif