21xrx.com
2024-09-20 05:52:30 Friday
登录
文章检索 我的文章 写文章
C++实现最小二乘法拟合正弦波曲线
2023-07-10 03:35:54 深夜i     --     --
C++ 最小二乘法 拟合 正弦波曲线

最小二乘法是一种统计学和数学中常用的优化方法,其目的是通过最小化误差平方和来寻找一组参数,使拟合曲线和原始数据的差距最小化。

在使用最小二乘法拟合正弦波曲线时,我们可以使用C++编程语言实现。首先,我们需要定义一个正弦函数,以便生成一组有噪声的正弦波数据。此外,我们需要定义一个多项式回归函数,通过最小二乘法调整拟合参数,以逼近原始数据。

具体实现过程如下:

1.定义正弦函数和添加噪声


double sine(double A, double omega, double phi, double x) {

  return A * sin(omega * x + phi);

}

double noise(double level) {

  static std::default_random_engine generator;

  static std::normal_distribution<double> distribution(0.0, level);

  return distribution(generator);

}

std::vector<std::pair<double, double>> generateData(double A, double omega, double phi, double level, int count) {

  std::vector<std::pair<double, double>> data;

  for (int i = 0; i < count; ++i) {

    auto x = 2 * M_PI * i / count;

    auto y = sine(A, omega, phi, x) + noise(level);

    data.emplace_back(x, y);

  }

  return data;

}

2.定义多项式回归函数和计算拟合参数


Eigen::VectorXd polynomialRegression(const std::vector<std::pair<double, double>>& data, int degree) {

  int n = data.size();

  Eigen::MatrixXd A(n, degree + 1);

  Eigen::VectorXd b(n);

  for (int i = 0; i < n; ++i) {

    auto x = data[i].first;

    auto y = data[i].second;

    for (int j = 0; j <= degree; ++j) {

      A(i, j) = pow(x, j);

    }

    b(i) = y;

  }

  auto x = A.colPivHouseholderQr().solve(b); // 使用QR分解求解多项式拟合参数

  return x;

}

3.使用以上两个函数生成一组有噪声的正弦波数据,并进行拟合


int main() {

  double A = 1;

  double omega = 1;

  double phi = 0;

  double level = 0.2;

  int count = 100;

  auto data = generateData(A, omega, phi, level, count);

  int degree = 4;

  auto x = polynomialRegression(data, degree);

  std::cout << "Fitted parameters: " << std::endl << x << std::endl;

  return 0;

}

以上程序使用了Eigen数学库,该库提供了矩阵计算等多项数学计算工具。运行以上程序,可以得到一组拟合参数,将这些参数带入多项式回归函数中,即可得到一条拟合曲线,该曲线与原始正弦波数据的拟合程度较高。

总之,使用C++实现最小二乘法拟合正弦波曲线十分简单。通过定义正弦函数,添加噪声,以及实现多项式回归函数等步骤,可以进行一系列数学计算,得到拟合参数以及拟合曲线。这种方法既适用于正弦波,也适用于其他类型的数据,准确度和稳定性较高,因此在各个领域得到了广泛应用。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复