21xrx.com
2024-12-22 22:37:49 Sunday
登录
文章检索 我的文章 写文章
C++实现最小二乘法拟合正弦波曲线
2023-07-04 18:28:40 深夜i     --     --
C++ 最小二乘法 拟合 正弦波 曲线

最小二乘法是一种常用的数学方法,常被用来处理有线性关系的数据。它的应用非常广泛,比如用来拟合数据,求解方程组,甚至是图像处理等。在这里,我们就来介绍一下如何使用 C++ 语言来实现最小二乘法,来拟合正弦波曲线。

首先,我们需要了解正弦曲线的数学模型。正弦函数通常用公式 y=A*sin(ω*t+φ)+B 表示,其中,A 是振幅,ω 是角频率,φ 是相位,B 是常数项。我们的目标就是根据给定的正弦曲线点,求出最小二乘拟合的 A、ω、φ 值以及 B 常数项。

接下来,我们需要构建一个数据结构来存储正弦曲线点的信息。我们可以用一个向量或数组来存储这些点的横纵坐标。然后,我们需要定义一个函数来计算这些点的最小二乘解。

在 C++ 中,我们可以利用矩阵运算库,比如 Eigen,来实现最小二乘法求解。我们可以使用线性回归模型,计算出一个最优的拟合函数模型。我们可以通过以下的代码来实现:


#include <iostream>

#include <Eigen/Dense>

#include <cmath>

int main()

{

  // Define data vector and sin parameters

  Eigen::VectorXd t(10);

  t << 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9;

  Eigen::VectorXd y(10);

  y << 0.65, 0.97, 0.61, -0.29, -0.95, -0.77, 0.17, 0.96, 0.52, -0.49;

  // Create a linear regression model

  Eigen::MatrixXd X(10, 4);

  for (int i = 0; i < 10; i++)

  {

    double ti = t[i];

    X(i, 0) = sin(ti);

    X(i, 1) = cos(ti);

    X(i, 2) = ti;

    X(i, 3) = 1;

  }

  Eigen::VectorXd theta = X.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(y);

  double A = sqrt(theta[0] * theta[0] + theta[1] * theta[1]);

  double omega = atan2(-theta[0], theta[1]);

  double phi = atan2(theta[2], A * theta[1]);

  double B = theta[3];

  std::cout << "A = " << A << ", omega = " << omega << ", phi = " << phi << ", B = " << B << std::endl;

  return 0;

}

这段代码中,我们定义了一个 10 个点的正弦曲线。然后,我们构建了一个 10 * 4 的矩阵 X,其中的每一行代表一个样本数据,每一列分别代表 sin(ωt)、cos(ωt)、t、常数项 1。然后,我们通过 JacobiSVD() 函数求解矩阵的最小二乘解,得到拟合的参数 A、ω、φ 和常数项 B。

最后,我们可以打印出这四个参数的值,来检查我们的代码的正确性。这个代码可以应用于各种正弦曲线拟合问题,并且计算复杂度为 O(n^2),效率高。

  
  

评论区

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