Tan078 2017-10-25 08:44 采纳率: 100%

# c#实现最小二乘法线性拟合

public class MatrixEquation
{
private double[,] gaussMatrix;
private int coe;

    public MatrixEquation()
{
}

public MatrixEquation(double[] arrX, double[] arrY, int n)
{
coe = n;
gaussMatrix = GetGauss(GetXPowSum(arrX, n), GetXPowYSum(arrX, arrY, n), n);
}

public double[,] GetGaussMatrix()
{
return gaussMatrix;
}

public double[] GetResult()
{
return ComputeGauss(gaussMatrix, coe);
}

/// <summary> 计算获取x散点的幂次和数组 </summary>
/// <param name="arrX">x散点序列</param>
/// <param name="n">函数拟合次数</param>
/// <returns></returns>
protected double[] GetXPowSum(double[] arrX, int n)
{
int m = arrX.Length;//X散点的个数

double[] xPow = new double[2 * n + 1]; //存储X散点的幂次值

for (int i = 0; i < xPow.Length; i++)
{
if (i == 0)
{
xPow[i] = m;
}
else
{
//计算x的i次方和

double max = 0;
for (int j = 0; j < m; j++)
{
if (arrX[j] == 0)
max = max + 1;
else
max = max + Math.Pow(arrX[j], i);
}
xPow[i] = Math.Round(max, 4);
}
}
return xPow;
}

/// <summary>计算获取xy的幂次和序列 </summary>
/// <param name="arrX">x散点序列</param>
/// <param name="arrY">y散点序列</param>
/// <param name="n">拟合曲线次数</param>
/// <returns></returns>
protected double[] GetXPowYSum(double[] arrX, double[] arrY, int n)
{
int m = arrX.Length;//X散点的个数

double[] xyPow = new double[n + 1]; //仓储X散点的幂次值

for (int i = 0; i < xyPow.Length; i++)
{
//计算xy的i次方和

double max = 0;
for (int j = 0; j < m; j++)
{
if (arrX[j] == 0)
max = max + 1;
else
max = max + Math.Pow(arrX[j], i) * arrY[j];
}
xyPow[i] = Math.Round(max, 4);
}
return xyPow;
}

/// <summary> 获取高斯矩阵(增广矩阵) </summary>
/// <param name="arrX">X的幂次和</param>
/// <param name="arrXY">XY的幂次和</param>
/// <param name="n">拟合曲线次数</param>
/// <returns></returns>
protected double[,] GetGauss(double[] arrX, double[] arrXY, int n)
{
double[,] gauss = new double[n + 1, n + 2];
for (int i = 0; i < n + 1; i++)
{
int j;
int m = i;
for (j = 0; j < n + 1; j++)
{
gauss[i, j] = arrX[m];
m++;
}
gauss[i, j] = arrXY[i];
}

return gauss;
}

/// <summary> 求解拟合曲线的系数 </summary>
/// <param name="gauss">线性方程的增广矩阵</param>
/// <param name="n">方程次数</param>
/// <returns></returns>
protected double[] ComputeGauss(double[,] gauss, int n)
{
double[] a = new double[n + 1];
double s;
int matrixLine = n + 1;
for (int i = 0; i < n + 1; i++)
a[i] = 0;
//循环每列

for (int j = 0; j < matrixLine; j++)
{
//每列J行以后的绝对值最大值

double max = 0;
int k = j;
for (int i = j; i < matrixLine; i++)
{
if (Math.Abs(gauss[i, j]) > max)
{
max = gauss[i, j];
k = i;
}
}
//判断j行否为最大值行 若不是将j行调换为最大值行

if (k != j)
{
double temp; for (int m = j; m < matrixLine + 1; m++)
{
temp = gauss[j, m];
gauss[j, m] = gauss[k, m];
gauss[k, m] = temp;
}
}
if (max == 0)
{
//奇异矩阵无解

return a;
}
//进行初等行变换得到上三角矩阵

for (int i = j + 1; i < matrixLine; i++)
{
s = gauss[i, j];
for (int m = j; m < matrixLine + 1; m++)
{
gauss[i, m] = Math.Round(gauss[i, m] - gauss[j, m] * s / gauss[j, j], 6);
}
}
}
//根据倒推方式一次计算现行方程的解

for (int i = matrixLine - 1; i >= 0; i--)
{
s = 0;
for (int j = i + 1; j < matrixLine; j++)
{
s += gauss[i, j] * a[j];
}
a[i] = Math.Round((gauss[i, matrixLine] - s) / gauss[i, i], 6);
}
//返回方程的解即拟合曲线的系数

return a;
}
}
------------------------
以上是本人在网上看到的一个例子，但是不理解该怎么样测试这个类，请各位大神赐教！或者可以提供相关参考链接也可以。

• 写回答

#### 2条回答默认 最新

• threenewbee 2017-10-25 09:16
关注

MatrixEquation me = new MatrixEquation(x点的数组， y点的数组, n);
me.XXX调用，具体看你上面注释

本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 悬赏问题

• ¥15 进行基于用户的协同过滤推荐，使用准确率和召回率评价推荐模型的效果
• ¥15 关于#cesium#的问题：cesium 根据经纬度、高度、方位角、俯仰角和距离求另一点高度
• ¥15 word脚注设置不起空格符号
• ¥15 为什么apriori的运行时间会比fp growth的运行时间短呢
• ¥15 求解密json或者美化
• ¥15 帮我解决一下膳食平衡的线性规划模型的数据实例
• ¥40 万年历缺少农历，需要和阳历同时显示
• ¥250 雷电模拟器内存穿透、寻基址和特征码的教学
• ¥200 比特币ord程序wallet_constructor.rs文件支持一次性铸造1000个代币，并将它们分配到40个UTXO上（每个UTXO上分配25个代币），并设置找零地址
• ¥15 关于Java的学习问题