C语言直线拟合函数

直线拟合算法

函数说明:

通过一些点拟合出一条直线。

参数:

pt_input
指向传入的点的指针。

ptNumbers
传入的点数量。

k
指向拟合直线参数k的指针。

b
指向拟合直线参数b的指针。

返回值:

返回一个代数值判断拟合是否成功。如果成功,则返回 0。如果返回-1,表示点的数量<2。如果返回-2,表示x坐标无变化。

代码:

typedef struct tagPOINT_2 {
	double x;
	double y;
}POINT_2, *PPOINT_2;

int LineInfo(POINT_2 *pt_input, int ptNumbers, double * k, double * b)
{
	int nRet = 0;
	
	double X_aver = 0;
	double Y_aver = 0;
	double A = 0;
	double B = 0;

	double _2_XY_av = 0;
	double _2_XX_av = 0;

	do
	{
		if (ptNumbers < 2)
		{
			nRet = -1;
			break;
		}

		for (int loop = 0; loop < ptNumbers; loop++)
		{
			X_aver += pt_input[loop].x;
			Y_aver += pt_input[loop].y;

			_2_XY_av += pt_input[loop].x * pt_input[loop].y;
			_2_XX_av += pt_input[loop].x * pt_input[loop].x;
		}
		X_aver /= ptNumbers;
		Y_aver /= ptNumbers;

		_2_XY_av /= ptNumbers;
		_2_XX_av /= ptNumbers;

		for (int loop = 0; loop < ptNumbers; loop++)
		{
			A += fabs((pt_input[loop].x - X_aver) * (pt_input[loop].y - Y_aver));
			B += fabs((pt_input[loop].x - X_aver) * (pt_input[loop].x - X_aver));
		}

		if (B < 0.000001)
		{
			nRet = -2;
			break;
		}
		//方式一
		//*k = A / B;
		//*b = Y_aver - *k * X_aver;
		//方式二
		*k = (_2_XY_av - X_aver * Y_aver) / (_2_XX_av - X_aver * X_aver);
		*b = Y_aver - (*k) * X_aver;
	} while (0);

	return nRet;
}

测试代码:
#include <stdio.h>
#include <math.h>
int main()
{
	POINT_2 pt[10] = {
	{0.1 , 0.3},
	{1.2 , 2.0},
	{2.2 , 4.3},
	{3.1 , 5.8},
	{4.0 , 8.5},
	{5.3 , 10.8},
	{5.9 , 11.1},
	{6.8 , 13.9},
	{8.1 , 16.5},
	{9.0 , 17.9},
	};
	int ret;
	double k = 0, b = 0;
	ret = LineInfo(pt, 10, &k, &b);
	switch (ret)
	{
	case 0: printf("拟合成功,直线为y = %lf * x + %lf\n", k, b); break;
	case -1: printf("拟合失败,传入的点少于二点\n"); break;
	case -2: printf("拟合失败,传入的点x坐标重合\n"); break;
	default:printf("error\n"); break;
	}

	return 0;
}
测试结果:

在这里插入图片描述

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 最小二乘法是一种常见的数据拟合方法,可以用于拟合一次函数。下面是使用C语言实现最小二乘法拟合一次函数的示例代码: ```c #include <stdio.h> #include <math.h> int main() { int n = 5; // 数据点个数 double x[] = {1, 2, 3, 4, 5}; // 自变量 double y[] = {2.1, 3.9, 6.1, 8.2, 10.1}; // 因变量 double sumx = 0, sumy = 0, sumxy = 0, sumx2 = 0; // 定义一些中间变量 for (int i = 0; i < n; i++) { sumx += x[i]; sumy += y[i]; sumxy += x[i] * y[i]; sumx2 += x[i] * x[i]; } double a = (n * sumxy - sumx * sumy) / (n * sumx2 - sumx * sumx); // 计算斜率a double b = (sumy - a * sumx) / n; // 计算截距b printf("y = %gx + %g\n", a, b); // 输出拟合结果 return 0; } ``` 上述代码中,我们假设要拟合的一次函数为y=ax+b,其中a表示斜率,b表示截距。我们通过最小二乘法的公式计算出斜率a和截距b,然后输出拟合结果。 ### 回答2: C语言最小二乘法拟合一次函数的基本思路是通过已知的数据点来拟合一条一次函数直线。下面是一个简单的实现步骤: 1. 定义两个数组,存储已知的数据点的横坐标和纵坐标。例如,分别定义一个数组x[]和y[]分别存储已知点的横坐标和纵坐标。 2. 计算已知数据点的个数n,并计算数组x[]和y[]的平均值,分别记为x_avg和y_avg。 3. 计算回归直线的斜率a和截距b。 - 先计算斜率a的分子sum1和分母sum2,其中sum1为Σ((x[i]-x_avg) * (y[i]-y_avg))的和,sum2为Σ(x[i]-x_avg)^2的和。 - 计算斜率a = sum1 / sum2。 - 计算截距b = y_avg - a * x_avg。 4. 根据得到的斜率a和截距b,输出拟合的一次函数的方程。 这样就完成了通过最小二乘法拟合一次函数的过程。 需要注意的是,上述的实现只适用于已知的数据点是符合一次函数关系的情况。对于非线性关系的数据点,最小二乘法会得到拟合效果不好的结果。此外,还可以考虑使用其他更高阶的多项式来拟合数据点,或者使用其他更高级的拟合算法来提高拟合精度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值