拉格朗日插值:原理推导 + 典型工程应用 + 完整可运行软件

发布时间:2026/7/26 1:13:35
拉格朗日插值:原理推导 + 典型工程应用 + 完整可运行软件 目录一、拉格朗日插值核心原理1. 基础问题描述2. 拉格朗日基函数核心3. 拉格朗日插值多项式公式4. 低阶常用形式工程最常用1线性插值2 点1 次拉格朗日2抛物插值3 点2 次拉格朗日精度最高性价比5. 插值误差截断误差二、拉格朗日插值典型工程应用三、完整软件项目实现项目架构说明3.1 Python 完整实现带绘图、通用 n 阶插值3.2 C 语言完整工程实现嵌入式通用可直接烧录 HC32/CH32/STM32头文件 lagrange.h源文件 lagrange.cmain.c 测试入口嵌入式测试代码3.3 嵌入式工程优化要点实际产品使用四、算法优缺点总结优点缺点一、拉格朗日插值核心原理1. 基础问题描述用该多项式对区间内未知 x 的函数值做估算就是拉格朗日插值。2. 拉格朗日基函数核心定义拉格朗日基函数 lk(x)第 k 个点对应的基函数基函数性质3. 拉格朗日插值多项式公式4. 低阶常用形式工程最常用5. 插值误差截断误差⚠️ 龙格现象高次插值n≥8在区间两端会剧烈震荡工程极少使用 8 阶以上拉格朗日插值一般分段低次插值。二、拉格朗日插值典型工程应用应用领域具体场景说明插值选型传感器信号校准PT100 热电偶、压力传感器多点标定拟合根据标定表反算真实物理量分段 2 次 / 线性插值ADC 采样数据平滑补点嵌入式采集离散 ADC 数值补齐采样空缺点、提升曲线连续性分段低次拉格朗日图像缩放 / 像素插值简易双线性插值本质就是二维拉格朗日插值双线性二维一阶数控系统轨迹插补CNC 机床离散坐标点生成连续平滑运动轨迹分段一次、二次插值气象 / 水文数据拟合离散监测站点数据推算区域中间位置数值分段二次插值标定表查表算法电路板温漂补偿、电源输出电压校准查表优先线性插值数值计算积分、微分数值近似复杂函数值近似计算2~4 阶插值三、完整软件项目实现项目架构说明Python 版本算法验证 绘图可视化教学、仿真C 语言版本嵌入式裸机可用工程代码MCU 直接移植无第三方依赖统一测试用例已知函数 ysin(x)取 5 个采样点做插值拟合对比3.1 Python 完整实现带绘图、通用 n 阶插值import numpy as np import matplotlib.pyplot as plt def lagrange_interp(x_sample, y_sample, x_eval): 通用拉格朗日插值函数 :param x_sample: 采样x数组 list/np.array :param y_sample: 采样y数组 :param x_eval: 需要求值的x标量/数组 :return: 插值结果 n len(x_sample) res 0.0 for k in range(n): # 计算第k个基函数 lk 1.0 for j in range(n): if j ! k: lk * (x_eval - x_sample[j]) / (x_sample[k] - x_sample[j]) res y_sample[k] * lk return res # 测试工程 if __name__ __main__: # 原始函数 y sin(x) f lambda x: np.sin(x) # 离散采样点 5个点(4次插值) x_nodes np.array([0, np.pi/4, np.pi/2, 3*np.pi/4, np.pi]) y_nodes f(x_nodes) # 密集求值点用于绘制曲线 x_plot np.linspace(0, np.pi, 200) y_true f(x_plot) y_interp np.array([lagrange_interp(x_nodes, y_nodes, xi) for xi in x_plot]) # 绘图对比 plt.figure(figsize(10, 5)) plt.plot(x_plot, y_true, label原始 sin(x) 真实曲线, colorred, linewidth2) plt.plot(x_plot, y_interp, label拉格朗日4次插值曲线, colorblue, linestyle--) plt.scatter(x_nodes, y_nodes, cblack, s60, label采样节点) plt.grid(True, alpha0.3) plt.legend() plt.title(拉格朗日插值拟合正弦曲线) plt.show() # 单点插值测试 test_x np.pi / 3 print(f输入x {test_x:.4f}) print(f真实值sin(x) {np.sin(test_x):.6f}) print(f拉格朗日插值计算值 {lagrange_interp(x_nodes, y_nodes, test_x):.6f})运行效果蓝色虚线插值曲线紧贴红色正弦真值曲线黑点为原始采样点输出单点插值误差极小。3.2 C 语言完整工程实现嵌入式通用可直接烧录 HC32/CH32/STM32文件lagrange.clagrange.h纯标准 C无库依赖头文件 lagrange.h#ifndef __LAGRANGE_H #define __LAGRANGE_H #include stdint.h typedef float float32_t; /** * brief 通用拉格朗日插值计算 * param x: 采样x数组 * param y: 采样y数组 * param node_num: 采样节点个数 * param x_in: 待插值的x坐标 * return 插值计算得到的y值 */ float32_t Lagrange_Calc(float32_t *x, float32_t *y, uint8_t node_num, float32_t x_in); // 分段线性插值封装传感器查表最常用 float32_t Lagrange_Linear(float32_t x0, float32_t y0, float32_t x1, float32_t y1, float32_t x); // 二次抛物插值封装 float32_t Lagrange_Quadratic(float32_t x0,float32_t y0,float32_t x1,float32_t y1,float32_t x2,float32_t y2,float32_t x); #endif源文件 lagrange.c#include lagrange.h float32_t Lagrange_Calc(float32_t *x, float32_t *y, uint8_t node_num, float32_t x_in) { float32_t res 0.0f; for(uint8_t k 0; k node_num; k) { float32_t base 1.0f; for(uint8_t j 0; j node_num; j) { if(k ! j) { base * (x_in - x[j]) / (x[k] - x[j]); } } res y[k] * base; } return res; } float32_t Lagrange_Linear(float32_t x0, float32_t y0, float32_t x1, float32_t y1, float32_t x) { return y0 * (x - x1)/(x0 - x1) y1 * (x - x0)/(x1 - x0); } float32_t Lagrange_Quadratic(float32_t x0,float32_t y0,float32_t x1,float32_t y1,float32_t x2,float32_t y2,float32_t x) { float32_t term0 y0 * ((x-x1)*(x-x2)) / ((x0-x1)*(x0-x2)); float32_t term1 y1 * ((x-x0)*(x-x2)) / ((x1-x0)*(x1-x2)); float32_t term2 y2 * ((x-x0)*(x-x1)) / ((x2-x0)*(x2-x1)); return term0 term1 term2; }main.c 测试入口嵌入式测试代码#include stdio.h #include lagrange.h #define PI 3.1415926535f // 测试函数 sin(x) float32_t my_sin(float32_t x) { return sinf(x); } int main(void) { // 采样节点和Python一致 float32_t x_nodes[] {0, PI/4, PI/2, 3*PI/4, PI}; float32_t y_nodes[5]; uint8_t n sizeof(x_nodes)/sizeof(float32_t); for(int i0;in;i) y_nodes[i] my_sin(x_nodes[i]); float32_t test_x PI / 3.0f; float32_t val_true my_sin(test_x); float32_t val_interp Lagrange_Calc(x_nodes, y_nodes, n, test_x); printf(X %.4f \r\n, test_x); printf(真实sin值 %.6f \r\n, val_true); printf(拉格朗日插值值 %.6f \r\n, val_interp); printf(绝对误差 %.8f \r\n, val_true - val_interp); // 二次插值单独测试 float32_t q_val Lagrange_Quadratic(x_nodes[1],y_nodes[1],x_nodes[2],y_nodes[2],x_nodes[3],y_nodes[3],test_x); printf(三点抛物插值结果%.6f\r\n, q_val); return 0; }3.3 嵌入式工程优化要点实际产品使用禁止全局高阶插值采用分段拉格朗日插值把整条曲线分成多段每段只用 2~3 个点插值彻底解决龙格震荡查表匹配优化传感器标定表先二分查找找到当前 x 所在区间再区间内做线性 / 二次插值浮点优化MCU 无硬件 FPU 时优先使用分段线性插值计算量远小于高阶插值边界判断插值 x 超出采样区间属于外插误差会急剧放大产品代码必须增加区间限幅保护。四、算法优缺点总结优点公式统一结构规整编程极易实现不需要求解方程组输入采样点直接计算插值多项式适合离线标定表拟合、静态数据插值。缺点新增 / 删除采样点所有基函数全部需要重算牛顿插值可增量计算全域高次插值存在龙格现象同等精度下计算量大于分段插值。