00001 #pragma ident "$Id: MiscMath.hpp 2974 2011-11-11 09:14:39Z yanweignss $"
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 <vector>
00050 #include "MathBase.hpp"
00051 #include "DebugUtils.hpp"
00052
00053 namespace gpstk
00054 {
00057
00058 inline double Round(double x);
00059
00061 template <class T>
00062 T LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y, T x)
00063 {
00064 GPSTK_ASSERT(X.size()==Y.size());
00065
00066 T Yx(0.0);
00067 for(size_t i=0;i<X.size();i++)
00068 {
00069 if(x==X[i]) return Y[i];
00070
00071 T Li(1.0);
00072 for(size_t j=0;j<X.size();j++)
00073 {
00074 if(i!=j) Li *= (x-X[j])/(X[i]-X[j]);
00075 }
00076 Yx += Li*Y[i];
00077 }
00078
00079 return Yx;
00080
00081 }
00082
00084 template <class T>
00085 T LagrangeFirstDerivative(const std::vector<T>& X, const std::vector<T>& Y, T x)
00086 {
00087 GPSTK_ASSERT(X.size()==Y.size());
00088
00089 T dY1(0.0);
00090 for(size_t i=0; i<X.size(); i++)
00091 {
00092 T temp1(1.0);
00093 T temp2(0.0);
00094 for(size_t j=0; j<X.size(); j++)
00095 {
00096 if(j==i) continue;
00097
00098 T temp3(1.0);
00099 for(size_t k=0;k<X.size();k++)
00100 {
00101 if( (k!=i) && (k!=j) ) temp3 *= (x-X[k]);
00102 }
00103
00104 temp1 *= (X[i]-X[j]);
00105 temp2 += temp3;
00106 }
00107
00108 dY1 += temp2/temp1*Y[i];
00109 }
00110
00111 return dY1;
00112 }
00113
00115 template <class T>
00116 T LagrangeSecondDerivative(const std::vector<T>& X, const std::vector<T>& Y, T x)
00117 {
00118 GPSTK_ASSERT(X.size()==Y.size());
00119
00120 const size_t degree( X.size() );
00121
00122
00123 typedef std::vector< T > vectorType;
00124 std::vector< vectorType > delta( degree, vectorType(degree, 0.0) );
00125
00126 for (size_t i = 0; i < degree; ++i)
00127 {
00128 for (size_t j = 0; j < degree; ++j)
00129 {
00130 if (j != i) delta[i][j] = ( (x - X[j]) / (X[i] - X[j]) );
00131 }
00132 }
00133
00134 double retVal(0.0);
00135
00136 for( int i = 0; i < degree; ++i )
00137 {
00138 double sum( 0.0 );
00139
00140 for( int m = 0; m < degree; ++m )
00141 {
00142 if( m != i )
00143 {
00144 double weight1( 1.0/(X[i]-X[m]) );
00145 double sum2( 0.0 );
00146
00147 for( int j = 0; j < degree; ++j )
00148 {
00149 if( (j != i) && (j != m) )
00150 {
00151 double weight2( 1.0/(X[i]-X[j]) );
00152
00153 for( int n = 0; n < degree; ++n )
00154 {
00155 if( (n != j) && (n != m) && (n != i) ) weight2 *= delta[i][n];
00156 }
00157 sum2 += weight2;
00158 }
00159 }
00160
00161 sum += sum2*weight1;
00162 }
00163 }
00164
00165 retVal += Y[i] * sum;
00166 }
00167
00168 return retVal;
00169
00170 }
00171
00172
00174
00175
00180 template <class T>
00181 T LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y, const T& x, T& err)
00182 {
00183 err = 0.0;
00184 return LagrangeInterpolation(X,Y,x);
00185
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00208 template <class T>
00209 void LagrangeInterpolation(const std::vector<T>& X, const std::vector<T>& Y, const T& x, T& y, T& dydx)
00210 {
00211 size_t i,j,k,N=X.size(),M;
00212 M = (N*(N+1))/2;
00213 std::vector<T> P(N,T(1)),Q(M,T(1)),D(N,T(1));
00214 for(i=0; i<N; i++) {
00215 for(j=0; j<N; j++) {
00216 if(i != j) {
00217 P[i] *= x-X[j];
00218 D[i] *= X[i]-X[j];
00219 if(i < j) {
00220
00221 for(k=0; k<N; k++) {
00222 if(k == i || k == j) continue;
00223
00224 Q[i+(j*(j+1))/2] *= (x-X[k]);
00225 }
00226
00227 }
00228 }
00229 }
00230 }
00231 y = dydx = T(0);
00232 for(i=0; i<N; i++) {
00233 y += Y[i]*(P[i]/D[i]);
00234 T S(0);
00235 for(k=0; k<N; k++) if(i != k) {
00236 if(k<i) S += Q[k+(i*(i+1))/2]/D[i];
00237 else S += Q[i+(k*(k+1))/2]/D[i];
00238 }
00239 dydx += Y[i]*S;
00240 }
00241 }
00242
00243
00245 template <class T>
00246 T LagrangeInterpolating2ndDerivative( const std::vector<T>& pos,
00247 const std::vector<T>& val,
00248 T desiredPos )
00249 {
00250
00251 int degree( pos.size() );
00252
00253
00254 typedef std::vector< T > vectorType;
00255 std::vector< vectorType > delta( degree, vectorType(degree, 0.0) );
00256
00257
00258 for (int i = 0; i < degree; ++i)
00259 {
00260 for (int j = 0; j < degree; ++j)
00261 {
00262 if (j != i)
00263 {
00264 delta[i][j] = ( (desiredPos - pos[j]) / (pos[i] - pos[j]) );
00265 }
00266 }
00267 }
00268
00269 double retVal(0.0);
00270
00271 for( int i = 0; i < degree; ++i )
00272 {
00273 double sum( 0.0 );
00274
00275 for( int m = 0; m < degree; ++m )
00276 {
00277
00278 if( m != i )
00279 {
00280
00281 double weight1( 1.0/(pos[i]-pos[m]) );
00282 double sum2( 0.0 );
00283
00284 for( int j = 0; j < degree; ++j )
00285 {
00286
00287 if( (j != i) && (j != m) )
00288 {
00289
00290 double weight2( 1.0/(pos[i]-pos[j]) );
00291
00292 for( int n = 0; n < degree; ++n )
00293 {
00294
00295 if( (n != j) && (n != m) && (n != i) )
00296 {
00297 weight2 *= delta[i][n];
00298 }
00299 }
00300 sum2 += weight2;
00301 }
00302 }
00303
00304 sum += sum2*weight1;
00305 }
00306
00307 }
00308
00309 retVal += val[i] * sum;
00310 }
00311
00312 return retVal;
00313
00314 }
00315
00316
00318 template <class T>
00319 T RSS (T aa, T bb, T cc)
00320 {
00321 T a(ABS(aa)), b(ABS(bb)), c(ABS(cc));
00322 if ( (a > b) && (a > c) )
00323 return a * SQRT(1 + (b/a)*(b/a) + (c/a)*(c/a));
00324 if ( (b > a) && (b > c) )
00325 return b * SQRT(1 + (a/b)*(a/b) + (c/b)*(c/b));
00326 if ( (c > b) && (c > a) )
00327 return c * SQRT(1 + (b/c)*(b/c) + (a/c)*(a/c));
00328
00329 if (a == b)
00330 {
00331 if (b == c)
00332 return a * SQRT(T(3));
00333 a *= SQRT(T(2));
00334 if (a > c)
00335 return a * SQRT(1 + (c/a)*(c/a));
00336 else
00337 return c * SQRT(1 + (a/c)*(a/c));
00338 }
00339 if (a == c)
00340 {
00341 a *= SQRT(T(2));
00342 if (a > b)
00343 return a * SQRT(1 + (b/a)*(b/a));
00344 else
00345 return b * SQRT(1 + (a/b)*(a/b));
00346 }
00347 if (b == c)
00348 {
00349 b *= SQRT(T(2));
00350 if (b > a)
00351 return b * SQRT(1 + (a/b)*(a/b));
00352 else
00353 return a * SQRT(1 + (b/a)*(b/a));
00354 }
00355
00356 return T(0);
00357 }
00358
00360 template <class T>
00361 T RSS (T aa, T bb)
00362 {
00363 return RSS(aa,bb,T(0));
00364 }
00365
00366
00368 template <class T>
00369 T RSS (T aa, T bb, T cc, T dd)
00370 {
00371 #define swapValues(x,y) \
00372 { T temporalStorage; \
00373 temporalStorage = x; x = y; y = temporalStorage; }
00374
00375 T a(ABS(aa)), b(ABS(bb)), c(ABS(cc)), d(ABS(dd));
00376
00377
00378 if (a < b) std::swap(a,b);
00379 if (a < c) swapValues(a,c);
00380 if (a < d) swapValues(a,d);
00381
00382 return a * SQRT(1 + (b/a)*(b/a) + (c/a)*(c/a) + (d/a)*(d/a));
00383 }
00384
00385
00386 inline double Round(double x)
00387 {
00388 return double(std::floor(x+0.5));
00389 }
00391
00392 }
00393
00394 #endif