00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "numeric/polyeqnsolver.hxx"
00029 #include "numeric/matrix.hxx"
00030 #include <stdio.h>
00031
00032 using ::std::list;
00033
00034 namespace scsolver { namespace numeric {
00035
00036 const char* NotEnoughDataPoints::what() const throw()
00037 {
00038 return "not enough data points to solve a polynomial equation (minimum of 2 required)";
00039 }
00040
00041 DataPoint::DataPoint(double x, double y) :
00042 X(x), Y(y)
00043 {
00044 }
00045
00046 PolyEqnSolver::PolyEqnSolver()
00047 {
00048 }
00049
00050 PolyEqnSolver::~PolyEqnSolver() throw()
00051 {
00052 }
00053
00054 void PolyEqnSolver::addDataPoint(double x, double y)
00055 {
00056 DataPoint pt(x, y);
00057 m_DataPoints.push_back(pt);
00058 }
00059
00060 const Matrix PolyEqnSolver::solve()
00061 {
00062 size_t nDPSize = m_DataPoints.size();
00063 if (nDPSize < 2)
00064 {
00065
00066 throw NotEnoughDataPoints();
00067 }
00068
00069 Matrix mxRight(nDPSize, nDPSize), mxLeft(nDPSize, 1);
00070 list<DataPoint>::const_iterator itr = m_DataPoints.begin(), itrEnd = m_DataPoints.end();
00071 for (size_t nRow = 0; itr != itrEnd; ++itr, ++nRow)
00072 {
00073 double varTerm = 1.0;
00074 for (size_t nCol = 0; nCol < nDPSize; ++nCol)
00075 {
00076 mxRight(nRow, nCol) = varTerm;
00077 varTerm *= itr->X;
00078 }
00079 mxLeft(nRow, 0) = itr->Y;
00080 }
00081
00082 return mxRight.inverse() * mxLeft;
00083 }
00084
00085 void PolyEqnSolver::clear()
00086 {
00087 m_DataPoints.clear();
00088 }
00089
00090 size_t PolyEqnSolver::size() const
00091 {
00092 return m_DataPoints.size();
00093 }
00094
00095
00096
00097 void getQuadraticPeak(double& x, double& y, const Matrix& coef)
00098 {
00099
00100 double a = coef(2, 0);
00101 double b = coef(1, 0);
00102 double c = coef(0, 0);
00103 x = b / (-2.0*a);
00104 y = x * x * a + x * b + c;
00105 }
00106
00107 }}