根据http://zh.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95里面的说法:
线性函数模型
典型的一类函数模型是线性函数模型。最简单的线性式是 ,写成矩阵式,为
直接给出该式的参数解:
和
其中,为t值的算术平均值。也可解得如下形式:
b1为斜率,b0为截距,可以先根据x,y数组,以及上面的公式先计算出斜率,再计算截距。
因为原来参考代码中,返回为一个数组,根据与原来代码的兼容性,调用LinearResult(double[],double[])方法返回是一个数组。result[0]为斜率,result[1]为截距。
-
class Linear
-
{
-
public double[] LinearResult(double[] arrayX, double[] arrayY)
-
{
-
double[] result = { 0, 0 };
-
if (arrayX.Length == arrayY.Length)
-
{
-
double averX = arrayX.Average();
-
double averY = arrayY.Average();
-
result[0] = Scale(averX, averY, arrayX, arrayY);
-
result[1] = Offset(result[0],averX,averY);
-
}
-
return result;
-
}
-
private double Scale(double averX, double averY, double[] arrayX, double[] arrayY)
-
{
-
double scale = 0;
-
if (arrayX.Length == arrayY.Length)
-
{
-
double Molecular = 0;
-
double Denominator = 0;
-
for (int i = 0; i < arrayX.Length; i++)
-
{
-
Molecular += (arrayX[i] - averX) * (arrayY[i] - averY);
-
Denominator += Math.Pow((arrayX[i] - averX), 2);
-
}
-
scale = Molecular / Denominator;
-
}
-
return scale;
-
}
-
private double Offset(double scale, double averX,double averY)
-
{
-
double offset = 0;
-
offset = averY - scale * averX;
-
return offset;
-
}
-
}
/// <summary> /// 计算一元一次方程系数(利用最小二乘法) /// 20200320新增 /// </summary> /// <param name="xValues"></param> /// <param name="yValues"></param> /// <returns></returns> private double[] CalCoefficientOfLinearEquation(double[] xValues, double[] yValues) { if (xValues.Length != yValues.Length) return null; int valCount = xValues.Length; //计算X2=∑(xi)^2 , X=∑ xi , Yx=∑(xi*yi) , Y=∑ yi double X2 = 0; double X = 0; double Yx = 0; double Y = 0; for (int i = 0; i < valCount; i++) { X2 += Math.Pow(xValues[i], 2); X += xValues[i]; Yx += xValues[i] * yValues[i]; Y += yValues[i]; } //计算线性方程系数y=ax+b double a = (Yx * valCount - X * Y) / (X2 * valCount - X * X); double b = (X2 * Y - Yx * X) / (X2 * valCount - X * X); //返回系数的数组 double[] temp = new double[] { a, b }; return temp; }