C#实现最小二乘法

根据http://zh.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%98%E6%B3%95里面的说法:

 

线性函数模型

 

典型的一类函数模型是线性函数模型。最简单的线性式是 ,写成矩阵式,为

 

直接给出该式的参数解:

  和   

其中\bar t = \frac{1}{n} \sum_{i=1}^n t_i,为t值的算术平均值。也可解得如下形式:

 

b1为斜率,b0为截距,可以先根据x,y数组,以及上面的公式先计算出斜率,再计算截距。

因为原来参考代码中,返回为一个数组,根据与原来代码的兼容性,调用LinearResult(double[],double[])方法返回是一个数组。result[0]为斜率,result[1]为截距。

 

 
  1. class Linear

  2. {

  3. public double[] LinearResult(double[] arrayX, double[] arrayY)

  4. {

  5. double[] result = { 0, 0 };

  6.  
  7. if (arrayX.Length == arrayY.Length)

  8. {

  9. double averX = arrayX.Average();

  10. double averY = arrayY.Average();

  11. result[0] = Scale(averX, averY, arrayX, arrayY);

  12. result[1] = Offset(result[0],averX,averY);

  13. }

  14.  
  15. return result;

  16. }

  17.  
  18. private double Scale(double averX, double averY, double[] arrayX, double[] arrayY)

  19. {

  20. double scale = 0;

  21. if (arrayX.Length == arrayY.Length)

  22. {

  23. double Molecular = 0;

  24. double Denominator = 0;

  25. for (int i = 0; i < arrayX.Length; i++)

  26. {

  27. Molecular += (arrayX[i] - averX) * (arrayY[i] - averY);

  28. Denominator += Math.Pow((arrayX[i] - averX), 2);

  29. }

  30. scale = Molecular / Denominator;

  31. }

  32.  
  33. return scale;

  34. }

  35.  
  36. private double Offset(double scale, double averX,double averY)

  37. {

  38. double offset = 0;

  39. offset = averY - scale * averX;

  40. return offset;

  41. }

  42. }

 /// <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;        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值