<?php /* * FunctionFit * * This class perform linear least squres fitting to a linear * combination of user defined functions in the form * y=a0+a1*F1(X)+ ... + an*Fn(X) * * 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');
/** * FunctionFit * * @author José Gómez López <jose.gomez.lopez@gmail.com> * * This class perform linear least squres fitting to a linear * combination of user defined functions in the form * y=a0+a1*F1(X)+ ... + an*Fn(X) * It uses LinearFit class the independent variable vector is transformated * in an array which elements are its function values **/ class FunctionFit extends LinearFit { private $X; private $Y; private $Func; private $Size; private $Vars; private $nY;
/** * Initialize data * * Initialize internal data and prepare for next calculation **/ protected function init() { $this->X=array(); $this->Y=array(); $this->Func=array(); $this->Conf=array(); $this->Size=0; $this->Vars=0; $this->nY=0; } // End of init()
/** * Constructor * * Create a new object **/ public function __construct () { $this->init(); } // End of function __construct
/** * Set Functions * * sets foron array set for fitting * @param array $aFunction array of functions **/ public function SetFunctions($aFunction) { if (count($this->Func) > 0) { $this->Coeffs=array(); $this->Conf=array(); parent::init(); } $this->Func=$aFunction; if ($this->Size>0) { for ($i=0; $i<count($this->Func); $i++) { for ($j=0; $j<count($this->X); $j++) { $adX[$j][$i]=call_user_func($this->Func[$i],$this->X[$j]); } } parent::SetData($adX, $this->Y); } }
/** * Add New data * * Add new data to the fitting process * @param array double $adX vector with values for each variable * @param double $dY value corresponding to $adX **/ public function AddData ($adX, $dY) { if ($this->Size>0 && $this->Vars>0 && $this->Vars != count($adX)) { throw new Exception('# of variables of stored data and input vector is different'); } else { $this->Size++; $this->Vars=count($adX); if (is_array($dY)) { if ($this->nY==0) { $this->nY=count($dY); } if (count($dY) != $this->nY ) { throw new Exception('Number of Y elements is wrong'); }
} else { if ($this->nY==0) { $this->nY=1; } if ($this->nY != 1) { throw new Exception('Y must be an array'); } } $this->Y[]=$dY; $this->X[]=$adX; if (count($this->Func)>0) { for ($i=0; $i<count($this->Func); $i++) { $adXr[$i]=call_user_func($this->Func[$i],$adX); } parent::AddData($adXr,$dY); } } // End of if } // End of AddData
/** * Set New data * * Set new data destroying previous data * @param array double $adX matrix with a set of X values * @param array double $adY vector of values corresponding to each row of $adX **/ public function SetData($adX, $adY) { if (count($adX) != count($adY)) { throw new Exception('The size of both arrays should be the same'); } else { $this->Size=count($adX); if (is_array($adX[0])) { $this->Vars=count($adX[0]); } else { $this->Vars=1; } $this->Y=$adY; $this->X=$adX; if ( is_array($adY[0]) ) { $this->nY=count($adY[0]); } else { $this->nY=1; } if (count($this->Func)>0) { if (count($this->X)>0) { for ($i=0; $i<count($this->Func); $i++) { for ($j=0; $j<count($adX); $j++) { $adXr[$j][$i]=call_user_func($this->Func[$i],$adX[$j]); } } parent::SetData($adXr, $this->Y); } } } // End of if } // End of setData
/** * Get values from an input * * Get the values of an input using the calculated coefficients * @param array double $adX input to get the values **/ public function GetValues($adXo) { if (count($this->Func)>0) { if (!is_array($adXo)) { $adXin=array($adXo); } else { $adXin=$adXo; } for ($i=0; $i<count($this->Func); $i++) { for ($j=0; $j<count($adXin); $j++) { $adXr[$j][$i]=call_user_func($this->Func[$i],$adXin[$j]); } }
if (!is_array($adXo)) { return parent::GetValues($adXr)[0]; } else { return parent::GetValues($adXr); } } } } // End of class FunctionFit ?>
|