<?php
/*
* PolyFit
*
* This class perform linear least squres fitting to a polynome
* It uses LinearFit class the independent variable is transformated
*
* Copyright (C) 2013 José Gómez López
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
require_once('LinearFit.php');
/**
* PolyFit
*
* @author José Gómez López <[email protected]>
*
* This class perform linear least squres fitting to a polynome
* It uses LinearFit class the independent variable is transformated
* in an array which elements are its integer powers
**/
class PolyFit extends LinearFit
{
private $X;
private $Y;
private $Degree;
/**
* Initialize data
*
* Initialize internal data and prepare for next calculation
**/
protected function init()
{
$this->X=array();
$this->Y=array();
$this->Degree=0;
} // End of init()
/**
* Constructor
*
* Create a new object
**/
public function __construct ()
{
$this->init();
} // End of function __construct
/**
* Set degree
*
* set polynome degree for fitting
* @param $iDeg degree of polynome
**/
public function SetDegree($iDeg)
{
if ($this->Degree > 0)
{
$this->Coeffs=array();
$this->Conf=array();
parent::init();
}
if (count($this->X)>0)
{
for ($i=0; $i<count($this->X); $i++)
{
$adX[$i][0]=$this->X[$i];
}
for ($i=1; $i<$iDeg; $i++)
{
for ($j=0; $j<count($this->X); $j++)
{
$adX[$j][$i]=$this->X[$j]*$adX[$j][$i-1];
}
}
parent::SetData($adX, $this->Y);
}
$this->Degree=$iDeg;
}
/**
* Add New data
*
* Add new data to the fitting process
* @param double $dX
* @param double $dY value corresponding to $dX
**/
public function AddData ($dX, $dY)
{
if (is_array($dY))
{
if (!empty($this->Y) && is_array($this->Y[0]) && count($dY) != count($this->Y[0]) )
{
throw new Exception('Number of Y elements is wrong');
}
}
else
{
if (!empty($this->Y) && is_array($this->Y[0]) && count($this->Y[0])>1 )
{
throw new Exception('Y must be an array');
}
}
$this->Y[]=$dY;
$this->X[]=$dX;
if ($this->Degree>0)
{
$adX[0]=$dX;
for ($i=1; $i<$this->Degree; $i++)
{
$adX[$i]=$dX*$adX[$i-1];
}
parent::AddData($adX,$dY);
}
} // End of AddData
/**
* Set New data
*
* Set new data destroying previous data
* @param array double $adXin matrix with a set of X values
* @param array double $adY vector of values corresponding to each row of $adX
**/
public function SetData($adXin, $adY)
{
if (count($adXin) != count($adY))
{
throw new Exception('The size of both arrays should be the same');
}
else
{
$this->Y=$adY;
$this->X=$adXin;
} // End of if
if ($this->Degree>0)
{
if (count($this->X)>0)
{
for ($i=0; $i<count($this->X); $i++)
{
$adX[$i][0]=$this->X[$i];
}
for ($i=1; $i<$this->Degree; $i++)
{
for ($j=0; $j<count($this->X); $j++)
{
$adX[$j][$i]=$this->X[$j]*$adX[$j][$i-1];
}
}
parent::SetData($adX, $this->Y);
}
}
} // End of setData
/**
* Get values from an input
*
* Get the values of an input using the calculated coefficients
* @param array double $adXin input to get the values
*
* @return (array) double the value of the polynome for the input
* using the coefficients calculated
**/
public function GetValues($adXin)
{
if ($this->Degree>0)
{
if (is_array($adXin))
{
for ($i=0; $i<count($adXin); $i++)
{
$adX[0][$i]=$adXin[$i];
}
for ($i=1; $i<$this->Degree; $i++)
{
for ($j=0; $j<count($this->X); $j++)
{
$adX[$i][$j]=$adXin[$i]*$adX[$i-1][$j];
}
}
return parent::GetValues($adX);
}
else
{
$adX[0]=$adXin;
for ($i=1; $i<$this->Degree; $i++)
{
$adX[$i]=$adXin[$i]*$adX[$i-1];
}
return parent::GetValues($adX);
}
}
}
} // End of class PolyFit
?>
|