给定(某条曲线上)多个点,选择合适的函数(可以是一个也可以多个)构造它们的最小二乘拟合,比较拟合函数和原函数的图像及误差C++
时间: 2023-11-28 20:47:59 浏览: 64
在C++中,可以使用最小二乘法来拟合数据点。以下是一个简单的示例代码:
```cpp
#include <iostream>
#include <cmath>
using namespace std;
// 定义最小二乘函数
void least_squares(int n, double x[], double y[], double &a, double &b)
{
double sx=0, sy=0, sxy=0, sx2=0;
for(int i=0; i<n; i++)
{
sx += x[i];
sy += y[i];
sxy += x[i] * y[i];
sx2 += x[i] * x[i];
}
double denom = n*sx2 - sx*sx;
a = (n*sxy - sx*sy) / denom;
b = (sx2*sy - sx*sxy) / denom;
}
// 定义原函数
double f(double x)
{
return sin(x);
}
int main()
{
// 定义数据点
const int n = 10;
double x[n] = {0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8};
double y[n];
for(int i=0; i<n; i++)
{
y[i] = f(x[i]) + 0.1 * (rand() / double(RAND_MAX) - 0.5);
}
// 最小二乘拟合
double a, b;
least_squares(n, x, y, a, b);
// 输出拟合函数
cout << "拟合函数为:y = " << a << " * x + " << b << endl;
// 绘制拟合函数和原函数的图像
FILE* pipe = popen("gnuplot -persist", "w");
fprintf(pipe, "set terminal png\n");
fprintf(pipe, "set output 'fit.png'\n");
fprintf(pipe, "plot '-' with points title 'Data', sin(x) with lines title 'Original Function', %f*x + %f with lines title 'Fitted Function'\n", a, b);
for(int i=0; i<n; i++)
{
fprintf(pipe, "%f %f\n", x[i], y[i]);
}
fprintf(pipe, "e\n");
fflush(pipe);
pclose(pipe);
// 计算误差
double err = 0;
for(int i=0; i<n; i++)
{
double y_fit = a * x[i] + b;
err += pow(y_fit - y[i], 2);
}
err /= n;
// 输出误差
cout << "误差为:" << err << endl;
return 0;
}
```
上述代码中使用最小二乘法来拟合一个包含噪声的正弦函数,并绘制拟合函数和原函数的图像。通过计算均方误差,可以评价拟合的优劣。
阅读全文