C++完整实现Savitzky - Golay滤波器算法:代码详解与逻辑要点
下面是用C++实现的Savitzky-Golay滤波器算法。代码中包含了必要的注释以便于理解。 ```cpp #include <iostream> #include <vector> #include <cmath> // 计算组合数 C(n, k) double combination(int n, int k) { if (k > n) return 0; double result = 1.0; for (int i = 1; i <= k; ++i) { result *= (n - i + 1) / static_cast<double>(i); } return result; } // 生成Savitzky-Golay系数矩阵 std::vector<std::vector<double>> generateCoefficients(int windowSize, int polynomialOrder) { std::vector<std::vector<double>> coefficients(windowSize, std::vector<double>(windowSize, 0.0)); for (int i = 0; i < windowSize; ++i) { for (int j = 0; j <= polynomialOrder; ++j) { coefficients[i][j] = pow(i - windowSize / 2, j) * combination(j, j); } } return coefficients; } // 应用Savitzky-Golay滤波器 std::vector<double> savitzkyGolayFilter(const std::vector<double>& data, int windowSize, int polynomialOrder) { if (windowSize % 2 == 0 || windowSize <= polynomialOrder || windowSize > static_cast<int>(data.size())) { throw std::invalid_argument("Invalid window size or polynomial order"); } std::vector<std::vector<double>> coefficients = generateCoefficients(windowSize, polynomialOrder); // 使用最小二乘法求解系数矩阵 std::vector<std::vector<double>> A(windowSize, std::vector<double>(polynomialOrder + 1, 0.0)); for (int i = 0; i < windowSize; ++i) { for (int j = 0; j <= polynomialOrder; ++j) { A[i][j] = pow(i - windowSize / 2, j); } } std::vector<std::vector<double>> ATA(polynomialOrder + 1, std::vector<double>(polynomialOrder + 1, 0.0)); for (int i = 0; i <= polynomialOrder; ++i) { for (int j = 0; j <= polynomialOrder; ++j) { for (int k = 0; k < windowSize; ++k) { ATA[i][j] += A[k][i] * A[k][j]; } } } std::vector<std::vector<double>> ATAInverse = invertMatrix(ATA); // 假设invertMatrix是一个已实现的矩阵求逆函数 std::vector<double> filteredData(data.size(), 0.0); for (size_t i = windowSize / 2; i < data.size() - windowSize / 2; ++i) { double sum = 0.0; for (int j = -windowSize / 2; j <= windowSize / 2; ++j) { sum += ATAInverse[0][j + windowSize / 2] * data[i + j]; } filteredData[i] = sum; } return filteredData; } // 矩阵求逆函数(假设已实现) std::vector<std::vector<double>> invertMatrix(const std::vector<std::vector<double>>& matrix) { // 实现矩阵求逆逻辑 // ... } int main() { std::vector<double> data = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; int windowSize = 5; int polynomialOrder = 2; try { std::vector<double> filteredData = savitzkyGolayFilter(data, windowSize, polynomialOrder); for (double value : filteredData) { std::cout << value << " "; } } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; } ``` 需要注意的逻辑点 - 窗口大小必须为奇数,并且大于多项式阶数。 - 数据长度应足够大以适应窗口大小,否则会导致越界访问。 - 矩阵求逆部分需要一个可靠的数值计算方法来确保精度。 ######[AI写代码神器 | 997点数解答 | 2025-04-17 11:25:07]
- Verilog 实现 8 位无符号二阶 7 点Savitzky - Golay 光谱曲线平滑滤波及注意要点 (字节豆包 | 404点数解答 | 2025-05-14 16:28:03)168
- 基于 Savitzky - Golay 滤波的光谱曲线处理:计算红边位置、幅值与面积(讯飞星火 | 927点数解答 | 2024-11-13 13:10:27)596
- Python 实现 Savitzky - Golay 滤波的详细过程及注意要点(字节豆包 | 319点数解答 | 2024-12-20 14:16:01)205
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)368
- 工程师必知:软件系统用户文档编写九大要点揭秘(百度文心 | 350点数解答 | 2023-11-09 18:23:53)210
- 深度揭秘 Oracle Workarea Size Policy:参数调优助力数据库性能飞升(阿里通义 | 372点数解答 | 2024-05-13 10:54:45)251
- C++ 实现我的世界基岩版:从简单框架到开发要点揭秘(字节豆包 | 182点数解答 | 2025-02-22 15:53:11)211
- C++ 实现完整斗地主:含洗牌、发牌与手牌展示,可按需扩展!(字节豆包 | 1028点数解答 | 2026-01-10 08:02:37)53
- Verilog 实现二次多项式 Savitzky - Golay 滤波:代码示例、解释与注意要点(字节豆包 | 829点数解答 | 2025-07-29 09:52:39)115
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)339
- 用 JS 中 for 循环实现 1 到 100 相加并输出结果到页面的完整代码 ( | 240点数解答 | 2024-05-20 22:11:29)493
- 用 JS 的 while 循环实现 1 到 100 相加并输出到页面的代码揭秘( | 47点数解答 | 2024-05-20 22:16:48)377