#include "linalg\linear_least_squares.h"
#include "vision\drawing.h"
#include "stat\rng.h"
#include "linalg\null_space.h"
#include "bignum\bigfloat.h"
template<typename Real>
void linear_regression( const std::vector<Real> &X, const std::vector<Real> &Y,
Real &m, Real &b)
{
Real sX=0, sY=0, sXY=0, sXX=0;
for(unsigned i=0; i<X.size(); ++i)
{
Real x = X[i], y = Y[i];
sX += x;
sY += y;
sXY += x*y;
sXX += x*x;
}
Real n = X.size();
m = (sY*sX - n*sXY)/( sX*sX - n*sXX );
b = (sX*sXY - sY*sXX)/( sX*sX - n*sXX );
}int main()
{
using namespace heinlib;
using namespace cimgl;
bigfloat::set_default_precision(300);
typedef bigfloat Real;
bigfloat rr;
printf("precision = %d\n", rr.precision() );
CImg<float> image(250, 250, 1, 3, 0);
std::vector<Real> X, Y;
int N = 10;
for(unsigned i=0; i<N; ++i)
{
Real x = random<Real>::uniform(0, 250);
Real y = random<Real>::uniform(0, 250);
image.draw_circle( x, y, 3, color<float>::white() );
X.push_back(x);
Y.push_back(y);
}
Real m1, b1, m2, b2;
linear_regression(X, Y, m1, b1 );
linear_regression(Y, X, m2, b2 );
//flip second line
b2 = -b2/m2;
m2 = 1/m2;
cimg_draw_line( image, m1, b1, color<float>::yellow() );
cimg_draw_line( image, m2, b2, color<float>::purple() );
//find the means of X and Y
Real mX = 0, mY = 0;
for(unsigned i=0; i<N; ++i)
{
Real x = X[i], y = Y[i];
mX += x; mY += y;
}
mX /= N;
mY /= N;
//find least squares line by distance to line..
Real sXX=0, sYY=0, sXY=0;
for(unsigned i=0; i<N; ++i)
{
Real x = X[i] - mX,
y = Y[i] - mY;
sXX += x*x;
sYY += y*y;
sXY += x*y;
}
static_matrix<2,2,Real> A = { sXX, sXY,
sXY, sYY };
static_matrix<2,1,Real> Norm;
null_space_SVD(A, Norm);
//general form
static_matrix<3,1,Real> line = { Norm[0], Norm[1], -( mX*Norm[0] + mY*Norm[1] ) };
cimg_draw_line( image, line, color<float>::red() );
CImgDisplay disp(image);
system("pause");
}