Go to the documentation of this file.00001 #pragma once
00002
00003 #ifdef BOOST_UBLAS_TYPE_CHECK
00004 # undef BOOST_UBLAS_TYPE_CHECK
00005 #endif
00006 #define BOOST_UBLAS_TYPE_CHECK 0
00007 #ifndef _USE_MATH_DEFINES
00008 # define _USE_MATH_DEFINES
00009 #endif
00010
00011 #include <boost/numeric/ublas/matrix.hpp>
00012 #include <boost/numeric/ublas/lu.hpp>
00013 #include <vector>
00014 #include <stdexcept>
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 template<typename T>
00033 std::vector<T> polyfit( const std::vector<T>& oX, const std::vector<T>& oY, int nDegree )
00034 {
00035 using namespace boost::numeric::ublas;
00036
00037 if ( oX.size() != oY.size() )
00038 throw std::invalid_argument( "X and Y vector sizes do not match" );
00039
00040
00041 nDegree++;
00042
00043 size_t nCount = oX.size();
00044 matrix<T> oXMatrix( nCount, nDegree );
00045 matrix<T> oYMatrix( nCount, 1 );
00046
00047
00048 for ( size_t i = 0; i < nCount; i++ )
00049 {
00050 oYMatrix(i, 0) = oY[i];
00051 }
00052
00053
00054 for ( size_t nRow = 0; nRow < nCount; nRow++ )
00055 {
00056 T nVal = 1.0f;
00057 for ( int nCol = 0; nCol < nDegree; nCol++ )
00058 {
00059 oXMatrix(nRow, nCol) = nVal;
00060 nVal *= oX[nRow];
00061 }
00062 }
00063
00064
00065 matrix<T> oXtMatrix( trans(oXMatrix) );
00066
00067 matrix<T> oXtXMatrix( prec_prod(oXtMatrix, oXMatrix) );
00068
00069 matrix<T> oXtYMatrix( prec_prod(oXtMatrix, oYMatrix) );
00070
00071
00072 permutation_matrix<int> pert(oXtXMatrix.size1());
00073 const std::size_t singular = lu_factorize(oXtXMatrix, pert);
00074
00075 BOOST_ASSERT( singular == 0 );
00076
00077
00078 lu_substitute(oXtXMatrix, pert, oXtYMatrix);
00079
00080
00081 return std::vector<T>( oXtYMatrix.data().begin(), oXtYMatrix.data().end() );
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 template<typename T>
00098 std::vector<T> polyval( const std::vector<T>& oCoeff, const std::vector<T>& oX )
00099 {
00100 size_t nCount = oX.size();
00101 size_t nDegree = oCoeff.size();
00102 std::vector<T> oY( nCount );
00103
00104 for ( size_t i = 0; i < nCount; i++ )
00105 {
00106 T nY = 0;
00107 T nXT = 1;
00108 T nX = oX[i];
00109 for ( size_t j = 0; j < nDegree; j++ )
00110 {
00111
00112 nY += oCoeff[j] * nXT;
00113
00114 nXT *= nX;
00115 }
00116 oY[i] = nY;
00117 }
00118
00119 return oY;
00120 }