I added a fetcher to the
drive price tracking script. Now when you click on a drive size it shows a 6 month trend of price/gigabyte. I've wanted this fetcher for awhile and this weekend was the first time I've had some time in quite awhile. Because it's useful and I like playing with it, I also added linear regression to the plot. This gave me a reason to implement such a function.

For algorithm for linear regression looks rather complex, but it's really not that bad--just a little multiplication and division. Basically, the function give you the slope and y-intercept of the line that is at the center of the data. And anyone who remember algebra 2 will recall a line is expressed simply as
y = m*x b. Doing this in PHP isn't too hard either. As the code below shows, all the summations can be done in a single loop. From that, the slope (
m) and y-intercept (
b) are calculated. To draw the line, simple calculate two x values--one at the beginning of the graph and one at the end.
Below is the code to do linear regression in PHP--well, a chuck of the code. This is part of a class for drawing XY graphs I made.
I had considered using a pre-existing graphics library for PHP, but the one I found a few months ago lacks documentation. Oddly enough, I remember going through some examples I found and getting the thing to work. Now, nothing. Ah well....
//----------------------------------
// Draw linear regression plot
//----------------------------------
public function RenderLinearRegression()
{
$MarginLeft = $this->Window->GetX();
$MarginTop = $this->Window->GetY();
$MarginRight = $this->Window->GetXX();
$Y_Delta = $this->Y_Max - $this->Y_Min;
ksort( $this->Data );
$TimeDelta = $this->EndTime - $this->StartTime;
$WindowArray = $this->BuildWindowArray();
$Count = $n = count( $WindowArray );
// Do all sumations
$SumX = $SumY = $SumXY = $SumXX = $SumYY = 0.0;
for ( $Index = 0; $Index < $Count; $Index )
{
$x = $WindowArray[ $Index ][ "x" ];
$y = $WindowArray[ $Index ][ "y" ];
$SumX = $x; // ∑ x
$SumY = $y; // ∑ y
$SumXY = $x * $y; // ∑ xy
$SumXX = $x * $x; // ∑ x^2
$SumYY = $y * $y; // ∑ y^2
}
// Slope:
// n ∑xy - ∑x ∑y
// m = -------------------
// n ∑x^2 - ( ∑x )^2
//
$m = ( $n * $SumXY ) - ( $SumX * $SumY );
$m /= ( $n * $SumXX ) - ( $SumX * $SumX );
// Y-intercept:
// ∑y - m ∑x
// b = -----------
// n
//
$b = ( $SumY - ( $m * $SumX ) ) / $n;
// Standard line function is y = mx b
$y = $this->ScaleY( ( $m ) $b );
$yy = $this->ScaleY( ( $m * $TimeDelta ) $b );
// Save information
$this->Slope = $m;
$this->Y_Intercept = $b;
// Draw line (thickness of 4 pixels)
for ( $Index = 0; $Index < 4; $Index )
imageline(
$this->Image ,
$MarginLeft , $MarginTop $y $Index ,
$MarginRight , $MarginTop $yy $Index ,
$this->LinearRegressionColor );
}