请用C语言写一份完整的Savitzky-Golay filter算法


以下是一个完整的C语言实现Savitzky-Golay滤波器的代码示例。该实现包含多项式拟合和卷积计算的核心逻辑: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> // 计算Savitzky-Golay滤波器系数 void sg_filter_coeff(int window_size, int poly_order, double* coeff) { int m = (window_size - 1) / 2; double A = (double)malloc((poly_order + 1) * sizeof(double*)); for (int i = 0; i <= poly_order; i++) { A[i] = (double*)malloc((poly_order + 1) * sizeof(double)); } double* b = (double*)malloc((poly_order + 1) * sizeof(double)); // 构建设计矩阵A和向量b for (int i = 0; i <= poly_order; i++) { for (int j = 0; j <= poly_order; j++) { A[i][j] = 0.0; for (int k = -m; k <= m; k++) { A[i][j] += pow(k, i + j); } } b[i] = 0.0; for (int k = -m; k <= m; k++) { b[i] += pow(k, i); } } // 高斯消元法求解线性方程组 for (int k = 0; k <= poly_order; k++) { for (int i = k + 1; i <= poly_order; i++) { double factor = A[i][k] / A[k][k]; for (int j = k; j <= poly_order; j++) { A[i][j] -= factor * A[k][j]; } b[i] -= factor * b[k]; } } // 回代求解 for (int i = poly_order; i >= 0; i--) { for (int j = i + 1; j <= poly_order; j++) { b[i] -= A[i][j] * coeff[j]; } coeff[i] = b[i] / A[i][i]; } // 释放内存 for (int i = 0; i <= poly_order; i++) { free(A[i]); } free(A); free(b); } // 应用Savitzky-Golay滤波器 void sg_filter(double* input, double* output, int data_size, int window_size, int poly_order) { int m = (window_size - 1) / 2; double* coeff = (double*)malloc((poly_order + 1) * sizeof(double)); sg_filter_coeff(window_size, poly_order, coeff); for (int i = 0; i < data_size; i++) { output[i] = 0.0; for (int j = -m; j <= m; j++) { int idx = i + j; if (idx < 0) idx = 0; if (idx >= data_size) idx = data_size - 1; double term = 0.0; for (int k = 0; k <= poly_order; k++) { term += coeff[k] * pow(j, k); } output[i] += input[idx] * term; } } free(coeff); } int main() { // 示例数据 double input[] = {1.2, 2.3, 3.1, 4.5, 5.2, 6.7, 7.1, 8.4, 9.2, 10.5}; int data_size = sizeof(input) / sizeof(input[0]); double output[data_size]; // 滤波器参数 int window_size = 5; // 必须为奇数 int poly_order = 2; // 多项式阶数 sg_filter(input, output, data_size, window_size, poly_order); // 打印结果 printf("Original Data:\tFiltered Data:\n"); for (int i = 0; i < data_size; i++) { printf("%.2f\t\t%.2f\n", input[i], output[i]); } return 0; } ``` 注意事项: 1. 窗口大小(window_size)必须为奇数,以确保对称性。 2. 多项式阶数(poly_order)应小于窗口大小,否则会导致数值不稳定。 3. 边界处理采用简单镜像法,可根据需求修改为其他边界处理方式。 [2025-05-18 23:09:12 | AI写代码神器 | 1014点数解答]
- 采用 savitzky-golay 滤波方法对光谱曲线进行平滑滤波处理,消除毛刺噪声。对平滑处理后的光谱曲线进行一阶求导,根据一阶导数计算红边位置、红边幅值和红边面积。 红边位置 rep 为680~760nm波长范围内光谱一阶导数最大值对应的波长。 红边幅值为680~760nm波长范围内光谱一阶导数的最大值: dr=max┬(680≤λ≤760)〖ρ_λ^' 〗 式中,dr为红边幅值;ρ_λ^'为光谱一阶导数;λ为波长。 红边面积为680~760mm波长范围内光谱一阶导数的积分: sdr=∫_680^760▒〖ρ_λ^' dλ〗 式中,sdr为红边面积; ρ_λ^'为光谱一阶导数; λ为波长。 要求:计算所给光谱曲线的红边位置、红边幅值和红边面积。 提示: (1)savitzky-golay 滤波: result = savgol( nleft, nright, order, degree [, /double] ) 返回一个savitzky-golay平滑滤波器的系数,然后可以作为convol函数的卷积核,本实验中使用result = savgol( 5, 5, 0, 2 ) ((927点数解答 | 2024-11-13 13:10:27)544
- 采用 savitzky-golay 滤波方法对光谱曲线进行平滑滤波处理,使用verilog语言,使用二阶,7点的savitzky-golay 滤波器,输入数据是8bit,输出数据也是8bit,均为无符号数,计算过程也是无符号数 (404点数解答 | 2025-05-14 16:28:03)129
- savitzky-golay 实现的具体过程(319点数解答 | 2024-12-20 14:16:01)164
- 帮我做一款我的世界基岩版,c++完整 (182点数解答 | 2025-02-22 15:53:11)148
- VERILOG 写一个二次多项式 Savitzky-Golay滤波 (829点数解答 | 2025-07-29 09:52:39)71
- 请用“book”写几段示例英语日常用语句子,带翻译(229点数解答 | 2024-03-23 14:52:33)240
- 请用“applaud”写几段示例英语日常用语句子,统一格式输出:英文放第一行,翻译放第二行。(150点数解答 | 2024-03-23 15:23:55)209
- 请用“applaud”写几段示例英语日常用语句子,统一格式输出:英语句子放第一行,句子对应的翻译放第二行。(20点数解答 | 2024-03-23 15:24:42)216
- 请用“applaud”写几段示例英语日常用语句子,统一格式输出:英文放第一行,翻译放第二行。(215点数解答 | 2024-03-23 15:33:10)219
- 2 状态图 车辆行驶过程中有以下几种状态,如:启动、怠速、加速、减速、匀速、停止,请用 uml 状态图画出各种状态之间的转换关系。 使用环境为vsode下的plantuml(163点数解答 | 2024-08-13 13:57:14)363
- 车辆行驶过程中有以下几种状态,如:启动、怠速、加速、减速、匀速、停止,请用 uml 状态图画出各种状态之间的转换关系。(828点数解答 | 2024-08-14 23:18:48)363
- 车辆行驶过程中有以下几种状态,如:启动、怠速、加速、减速、匀速、停止,请用 uml 状态图画出各种状态之间的转换关系。(574点数解答 | 2024-08-14 23:19:19)321