LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Are the LinFit return values correct?

I am using the CVI function LinFit to find the slope and intercept values that best represent the linear fit of the data points (x, y).
 
Here is the gist my code:
double x[5];
double y[5];
double z[5];
double slope;
double intercept;
double mse;
  
x[0] = 53879.650000;
x[1] = 53879.688194;
x[2] = 53879.733333;
x[3] = 53879.775000;
x[4] = 53879.813194;
  
y[0] = -39042.387;
y[1] = -39041.885;
y[2] = -39040.899;
y[3] = -39040.543;
y[4] = -39039.507;
  
LinFit(x, y, 5, z, &slope, &intercept, &mse);
 
The values returned in z are as follows:
z[0] = -39038.099
z[1] = -39037.443
z[2] = -39036.668
z[3] = -39035.952
z[4] = -39035.296
 
Using these values certainly does not represent the linear fit of the data points since these values are ALL well below the values in y.  When entering the x, y pairs into Excel I get a more reasonable answer, that is:
z[0] = -39042.452
z[1] = -39041.796
z[2] = -39041.020
z[3] = -39040.305
z[4] = -39039.649
 
Even using just 2 pairs, ie:
y[0] = -39042.387;
y[1] = -39041.885;
LinFit returns:
z[0] = -39045.582
z[1] = -39044.581
 
With just two points I would have suspected the z values to equal the y values.
I did a similar comparison with approximately 100 data pairs and the difference in the CVI calculation and Excel calculation for the z values never exceeded 0.00017.
 
Does LinFit not return the correct values for a low number of data points or am I missing something?
-Kris
0 Kudos
Message 1 of 3
(4,079 Views)
Hi Kris.

The LinFit() function "...Finds the slope and intercept values that best represent the linear fit of the data points (X, Y) using the least squares method..." (from CVI Help, my emphasis).

CVI is losing precision in its calculations because it is working with very large numbers which are almost equal. Even a small error in the calculated slope will have a significant effect for large values of X.

Try running this in the interactive window:

#include < analysis.h >
#include < utility.h >

static double x[5], x1[5];
static double y[5], y1[5];
static double z[5];
static double slope;
static double intercept;
static double mse;
static double xMean, yMean;

x[0] = 53879.650000;
x[1] = 53879.688194;
x[2] = 53879.733333;
x[3] = 53879.775000;
x[4] = 53879.813194;

y[0] = -39042.387;
y[1] = -39041.885;
y[2] = -39040.899;
y[3] = -39040.543;
y[4] = -39039.507;

Mean (x, 5, &xMean);
LinEv1D (x, 5, 1.0, -xMean, x1);
Mean (y, 5, &yMean);
LinEv1D (y, 5, 1.0, -yMean, y1);

LinFit (x1, y1, 5, z, &slope, &intercept, &mse);
LinEv1D (z, 5, 1.0, yMean, z);


This yields similar results to the Excel method.

Regards,
Colin.
Message 2 of 3
(4,058 Views)

Kris,

like Colin has explained, the large offset of your measure represents a problem for LinFit function. Besides Colin way, one alternative solution is to scale your data before linearizing and restore their previous values after linearization:

 Scale1D (x, 5, x1, &ofsx, &scalex);
 Scale1D (y, 5, y1, &ofsy, &scaley);
 LinFit(x1, y1, 5, z1, &slope, &intercept, &mse);
 LinEv1D (x1, 5, scalex, ofsx, x1);
 LinEv1D (z1, 5, scaley, ofsy, z1);
 PlotXY (panel, PANEL_GRAPH, x1, z1, 5, VAL_DOUBLE, VAL_DOUBLE, VAL_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, VAL_BLACK);

These lines produce an output fitted line that effectively represents your data (and is almost identical to Excel results).

Hope this helps



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 3 of 3
(4,044 Views)