• Matlab数值计算(多项式插值)


    多项式插值问题

    拉格朗日插值多项式


    例1:在某个化学反应过程中,在有限个时刻t(min),测得生成物浓度y(10^{^{-3}}g/cm^{3})d的数据如下:

    t_{i}12346810121416
    y_{i}4.006.418.018.799.539.8610.3310.4210.5310.61

    在时刻t=5分,t=16.4分时的浓度是多少。
    lagrange.m

    1. function y=lagrange(x0,y0,x)
    2. n=length(x0);m=length(x);
    3. for k=1:m
    4. z=x(k);
    5. s=0.0;
    6. for j=1:n
    7. p=1.0;
    8. for i=1:n
    9. if i~=j
    10. p=p*(z-x0(i))/(x0(j)-x0(i));
    11. end
    12. end
    13. s=p*y0(j)+s;
    14. end
    15. y(k)=s;
    16. end

    主程序:

    1. x0=[1 2 3 4 6 8 10 12 14 16]; % 给定的x坐标数据点
    2. y0=[4.00 6.41 8.01 8.79 9.53 9.86 10.33 10.42 10.53 10.61]; % 对应的y坐标数据点
    3. x=[1:0.1:16]; % 生成从116的步长为0.1的x坐标数据
    4. y=lagrange(x0,y0,x); % 使用拉格朗日插值计算在给定x坐标下的y值
    5. x1=5; % 指定的插值点x1
    6. x2=16.4; % 指定的插值点x2
    7. y1=lagrange(x0,y0,x1); % 在插值点x1处的拉格朗日插值结果
    8. y2=lagrange(x0,y0,x2); % 在插值点x2处的拉格朗日插值结果
    9. plot(x0,y0,'.k','markersize',20) % 绘制原始数据点
    10. hold on
    11. plot(x,y,'-r','markersize',30) % 绘制拉格朗日插值曲线
    12. hold on
    13. plot(x1,y1,'*b','markersize',8) % 标记插值点x1处的结果
    14. hold on
    15. plot(x2,y2,'*b','markersize',8) % 标记插值点x2处的结果
    16. legend('原数值点','Lagrange曲线') % 添加图例,说明原数值点和Lagrange曲线

    运行效果如下:

    例2:已知函数 y=f(x) 的如下离散数据:

    x012
    y2312
    (1)用线性插值求函数在x= 1.5 处的近似值
    (2)用二次插值求函数在x= 1.5 处的近似值
    (3)将以上信息可视化
    1. % 给定的数据点
    2. x = [0 1 2]; % 给定的x坐标数据点
    3. y = [2 3 12]; % 对应的y坐标数据点
    4. % (1) 线性插值
    5. x_interp = 1.5; % 想要进行插值的x坐标
    6. y_lin_interp = interp1(x, y, x_interp, 'linear'); % 使用interp1函数进行线性插值计算
    7. disp(['(1). 线性插值结果:', num2str(y_lin_interp)]); % 显示线性插值结果
    8. % (2) 二次插值
    9. n = length(x); % 数据点个数
    10. L = zeros(1, n); % 初始化存储拉格朗日基函数的数组
    11. for i = 1:n
    12. L(i) = prod((x_interp - x([1:i-1,i+1:end]))./(x(i) - x([1:i-1,i+1:end]))); % 计算拉格朗日基函数
    13. end
    14. y_quad_interp = sum(y .* L); % 计算二次插值的结果
    15. disp(['(2). 二次插值结果:', num2str(y_quad_interp)]); % 显示二次插值结果
    16. % 可视化结果
    17. figure;
    18. plot(x, y, 'ro', 'MarkerSize', 8); % 绘制原始数据点
    19. hold on;
    20. plot(x_interp, y_lin_interp, 'bs', 'MarkerSize', 8); % 绘制线性插值结果点
    21. plot(x_interp, y_quad_interp, 'gd', 'MarkerSize', 8); % 绘制二次插值结果点
    22. legend('原始数据点', '线性插值结果', '二次插值结果');
    23. xlabel('x');
    24. ylabel('y');
    25. title('线性插值和二次插值');
    26. grid on;

    运行效果:

    牛顿插值多项式

    用牛顿插值多项式解答上述例2

    1. % 给定的数据点
    2. x = [0 1 2]; % 给定的x坐标数据点
    3. y = [2 3 12]; % 对应的y坐标数据点
    4. % (1) 线性插值
    5. x_interp = 1.5; % 想要进行插值的x坐标
    6. y_lin_interp = interp1(x, y, x_interp, 'linear'); % 使用interp1函数进行线性插值计算
    7. disp(['(1). 线性插值结果:', num2str(y_lin_interp)]); % 显示线性插值结果
    8. % (2) 牛顿插值
    9. n = length(x); % 数据点个数
    10. % 计算差商
    11. f = y;
    12. for i = 2:n
    13. for j = n:-1:i
    14. f(j) = (f(j) - f(j-1)) / (x(j) - x(j-i+1));
    15. end
    16. end
    17. % 使用差商计算插值结果
    18. y_newton_interp = f(n);
    19. for i = n-1:-1:1
    20. y_newton_interp = f(i) + (x_interp - x(i)) * y_newton_interp;
    21. end
    22. disp(['(2). 牛顿插值结果:', num2str(y_newton_interp)]); % 显示牛顿插值结果
    23. % 可视化结果
    24. figure;
    25. plot(x, y, 'ro', 'MarkerSize', 8); % 绘制原始数据点
    26. hold on;
    27. plot(x_interp, y_lin_interp, 'bs', 'MarkerSize', 8); % 绘制线性插值结果点
    28. plot(x_interp, y_newton_interp, 'gd', 'MarkerSize', 8); % 绘制牛顿插值结果点
    29. legend('原始数据点', '线性插值结果', '牛顿插值结果');
    30. xlabel('x');
    31. ylabel('y');
    32. title('线性插值和牛顿插值');
    33. grid on;

    运行结果:

    分段线性插值多项式

    例3:已知数据

    01234
    21435

    用分段线性插值多项式求x=1.5的近似值

    1. % 给定的数据点
    2. x = [0 1 2 3 4]; % 给定的x坐标数据点
    3. y = [2 1 4 3 5]; % 对应的y坐标数据点
    4. % 想要进行插值的x坐标
    5. x_interp = 1.5;
    6. % 寻找 x_interp 所在的区间
    7. index = find(x <= x_interp, 1, 'last');
    8. % 计算分段线性插值
    9. if index < length(x)
    10. x_left = x(index);
    11. x_right = x(index + 1);
    12. y_left = y(index);
    13. y_right = y(index + 1);
    14. y_interp = y_left + (y_right - y_left) / (x_right - x_left) * (x_interp - x_left);
    15. else
    16. y_interp = y(end);
    17. end
    18. disp(['分段线性插值结果:', num2str(y_interp)]); % 显示分段线性插值结果
    19. % 可视化结果
    20. figure;
    21. plot(x, y, 'ro', 'MarkerSize', 8); % 绘制原始数据点
    22. hold on;
    23. plot(x_interp, y_interp, 'bs', 'MarkerSize', 8); % 绘制插值点
    24. legend('原始数据点', '插值点');
    25. xlabel('x');
    26. ylabel('y');
    27. title('分段线性插值');
    28. grid on;

    运行结果:

    三次样条插值

    用三次样条插值解决上述例3

    1. % 给定的数据点
    2. x = [0 1 2 3 4]; % 给定的x坐标数据点
    3. y = [2 1 4 3 5]; % 对应的y坐标数据点
    4. % 使用三次样条插值
    5. pp = spline(x, [0 y 0]); % 在端点处增加0值,进行自然边界条件插值
    6. % 想要进行插值的x坐标
    7. x_interp = 1.5;
    8. % 计算插值结果
    9. y_interp = ppval(pp, x_interp);
    10. disp(['三次样条插值结果:', num2str(y_interp)]); % 显示三次样条插值结果
    11. % 可视化结果
    12. xx = linspace(0, 4, 100); % 生成更密集的x坐标
    13. yy = ppval(pp, xx);
    14. figure;
    15. plot(x, y, 'ro', 'MarkerSize', 8); % 绘制原始数据点
    16. hold on;
    17. plot(xx, yy, 'b-'); % 绘制插值曲线
    18. legend('原始数据点', '三次样条插值曲线');
    19. xlabel('x');
    20. ylabel('y');
    21. title('三次样条插值');
    22. grid on;

    运行结果:

  • 相关阅读:
    强化学习章节脉络
    Swin Transformer算法解读
    javascript基本语法(一)
    算法(圆的定义和相关术语)
    告别卡顿,迎接流畅!你的mac电脑清洁利器CleanMyMac一键轻松解决所有问题!
    docker详解(尚硅谷阳哥)
    SpringCloud-微服务架构演变
    Oracle 数据库集群常用巡检命令
    聚类算法:kmeans和dbscan
    微服务框架 SpringCloud微服务架构 17 初识ES 17.6 安装IK 分词器
  • 原文地址:https://blog.csdn.net/weixin_73011353/article/details/136355923