MiscMath.hpp

Go to the documentation of this file.
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 //  This file is part of GPSTk, the GPS Toolkit.
00016 //
00017 //  The GPSTk is free software; you can redistribute it and/or modify
00018 //  it under the terms of the GNU Lesser General Public License as published
00019 //  by the Free Software Foundation; either version 2.1 of the License, or
00020 //  any later version.
00021 //
00022 //  The GPSTk is distributed in the hope that it will be useful,
00023 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025 //  GNU Lesser General Public License for more details.
00026 //
00027 //  You should have received a copy of the GNU Lesser General Public
00028 //  License along with GPSTk; if not, write to the Free Software Foundation,
00029 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00030 //  
00031 //  Copyright 2004, The University of Texas at Austin
00032 //
00033 //============================================================================
00034 
00035 //============================================================================
00036 //
00037 //This software developed by Applied Research Laboratories at the University of
00038 //Texas at Austin, under contract to an agency or agencies within the U.S. 
00039 //Department of Defense. The U.S. Government retains all rights to use,
00040 //duplicate, distribute, disclose, or release this software. 
00041 //
00042 //Pursuant to DoD Directive 523024 
00043 //
00044 // DISTRIBUTION STATEMENT A: This software has been approved for public 
00045 //                           release, distribution is unlimited.
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    }  // end T LagrangeInterpolation(vector, vector, const T, T&)
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       // First, compute interpolation factors
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    }  // End of 'lagrangeInterpolating2ndDerivative()'
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    }  // end T LagrangeInterpolation(vector, vector, const T, T&)
00187 
00188    // The following is a
00189    // Straightforward implementation of Lagrange polynomial and its derivative
00190    // { all sums are over index=0,N-1; Xi is short for X[i]; Lp is dL/dx;
00191    //   y(x) is the function being approximated. }
00192    // y(x) = SUM[Li(x)*Yi]
00193    // Li(x) = PROD(j!=i)[x-Xj] / PROD(j!=i)[Xi-Xj]
00194    // dy(x)/dx = SUM[Lpi(x)*Yi]
00195    // Lpi(x) = SUM(k!=i){PROD(j!=i,j!=k)[x-Xj]} / PROD(j!=i)[Xi-Xj]
00196    // Define Pi = PROD(j!=i)[x-Xj], Di = PROD(j!=i)[Xi-Xj],
00197    // Qij = PROD(k!=i,k!=j)[x-Xk] and Si = SUM(j!=i)Qij.
00198    // then Li(x) = Pi/Di, and Lpi(x) = Si/Di.
00199    // Qij is symmetric, there are only N(N+1)/2 - N of them, so store them
00200    // in a vector of length N(N+1)/2, where Qij==Q[i+j*(j+1)/2] (ignore i=j).
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 //std::cout << "Compute Q[" << i << "," << j << "=" << (i+(j*(j+1))/2) << "] = 1 ";
00221                   for(k=0; k<N; k++) {
00222                      if(k == i || k == j) continue;
00223 //std::cout << " * (x-X[" << k << "])";
00224                      Q[i+(j*(j+1))/2] *= (x-X[k]);
00225                   }
00226 //std::cout << " = " << Q[i+(j*(j+1))/2] << std::endl;
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    }  // end void LagrangeInterpolation(vector, vector, const T, T&, T&)
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          // First, compute interpolation factors
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    }  // End of 'lagrangeInterpolating2ndDerivative()'
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       // For numerical reason, let's just put the biggest in "a" (we are not sorting)
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 }  // namespace gpstk
00393 
00394 #endif

Generated on Wed Feb 8 03:31:00 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1