Delphi - linear approximation 2D

the source code of this page may not appear correctly in certain browsers
due to special characters. Have a look at the source of this HTML page
with notepad instead
also known as least square linear regression, a line is fitted
through a bunch of points.

theory

be the line equation : f(x):= {y:=a*x+b}
the square error for the ith point is : Sqr(f(xi)-yi) = Sqr(a*xi+b-yi)
for all points : sum(i:=1 to N, Sqr(f(xi)-yi) = sum(i:=1 to N, Sqr(a*xi+b-yi)) =
sum(i:=1 to N, a^2*xi^2+b^2+yi^2+2a*xi*b-2a*xi*yi-2b*yi)
as the variables are a and b, derive by a and b :
d/da sum(i:=1 to N, Sqr(a*xi+b-yi))=
d/da sum(i:=1 to N, a^2*xi^2+b^2+yi^2+2a*xi*b-2a*xi*yi-2b*yi) =
sum(i:=1 to N, 2a*xi^2 + 2xi*b - 2xi*yi)
d/db sum(i:=1 to N, Sqr(a*xi+b-yi))=
d/db sum(i:=1 to N, a^2*xi^2+b^2+yi^2+2a*xi*b-2a*xi*yi-2b*yi) =
sum(i:=1 to N, 2b +2a*xi - 2yi)
For the error to be minmal, set the derivatives to zero :
sum(i:=1 to N, 2a*xi^2 + 2xi*b - 2xi*yi) = 0
sum(i:=1 to N, 2b +2a*xi - 2yi) =0
2a*sum(xi^2) + 2b*sum(xi) -2sum(xi*yi) = 0
2Nb + 2a*sum(xi) - 2sum(yi) =0
this gives the equation system for a and b:
| N sum(xi) |*|b| =| sum(yi) |
|sum(xi) sum(xi^2)| |a| | sum(xi*yi) |
And some care has to be taken when the line is vertical :
when sum(xi)=0, the x and y are swapped.
Tom Berry inspired me to add this theory

notes

the swap in the proc approx is set true when the line is vertical,
meaning the coordinates are swapped.
Use :
MyApprox:=TLinApprox2D.create;
MyApprox.add(0,0);
MyApprox.add(1,0.5);
..
MyApprox.approx(a,b,swap);
The line will be y:=ax+b unless swap, then x:=ay+b

storage- and runtimeoptimized version

In the above version I omitted a procedure showpoints.
Without this ability, the points do not have to be stored.Klaus Huemmeler found this optimized solution :