source/numeric/polyeqnsolver.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  The Contents of this file are made available subject to
00004  *  the terms of GNU Lesser General Public License Version 2.1.
00005  *
00006  *
00007  *    GNU Lesser General Public License Version 2.1
00008  *    =============================================
00009  *    Copyright 2005-2008 by Kohei Yoshida.
00010  *    1039 Kingsway Dr., Apex, NC 27502, USA
00011  *
00012  *    This library is free software; you can redistribute it and/or
00013  *    modify it under the terms of the GNU Lesser General Public
00014  *    License version 2.1, as published by the Free Software Foundation.
00015  *
00016  *    This library is distributed in the hope that it will be useful,
00017  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  *    Lesser General Public License for more details.
00020  *
00021  *    You should have received a copy of the GNU Lesser General Public
00022  *    License along with this library; if not, write to the Free Software
00023  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00024  *    MA  02111-1307  USA
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         // We need at least 2 data points to form a polynomial equation.
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     // coef = (c, b, a)
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 }}

Generated on Mon Jul 28 09:13:20 2008 for scsolver by  doxygen 1.5.3