FUNCTION_BLOCK FB_KURVFIT
// by Jesper M. Pedersen
// Curvefits logged points of (x,y) to y=f(x)=a+b(x).
// The coefficients a and b are found by running through all points of x and y.
// The "weight" allows to let some points be more important than others, i.e. for "aging" of datapoints for example.
// If "weighing" or "aging" is not to be used, simply set rWeight:=1.0.
// The looping through of the datapoints is done in the calling block.
// This block updates one point per call.
// Need to be done: Calculating a "quality" of the approximated curve.
VAR_INPUT
biReset : BOOL ;
rx : REAL ;
ry : REAL ;
rWeight : REAL ;
END_VAR
VAR_OUTPUT
ra : REAL ;
rb : REAL ;
END_VAR
VAR_TEMP
rDivisor :REAL ;
rWeight_squared : REAL ;
END_VAR
VAR
rn : REAL ;
rsum_y : REAL ;
rsum_x : REAL ;
rsum_xsquared : REAL ;
rsum_xy : REAL ;
END_VAR
IF biReset THEN
rn := 0.0 ;
rsum_y := 0.0 ;
rsum_x := 0.0 ;
rsum_xsquared := 0.0 ;
rsum_xy := 0.0 ;
ra := 0.0 ;
rb := 0.0 ;
END_IF ;
IF NOT biReset THEN
IF NOT (rx=0.0 AND ry=0.0) THEN // ignore if empty values
// first add up all summed values
rn := rn + rWeight ;
rsum_y := rsum_y + (rWeight * ry) ;
rsum_x := rsum_x + (rWeight * rx) ;
rWeight_squared := rWeight * rWeight ;
rsum_xsquared := rsum_xsquared + (rWeight * rx * rx) ;
rsum_xy := rsum_xy + (rWeight * rx * ry) ;
//then do the actual curvefit
rDivisor := (rn * rsum_xsquared) - (rsum_x * rsum_x) ;
ra := ((rsum_y * rsum_xsquared) - (rsum_x * rsum_xy))/rDivisor ;
rb := ((rn * rsum_xy) - (rsum_x * rsum_y))/rDivisor ;
END_IF ;
END_IF ;
END_FUNCTION_BLOCK