拉格朗日插值matlab實現


已給sin0.32=0.314567,sin0.34=0.333487,sin0.36=0.352274,用線性插值及拋物插值計算sin0.3367的值並估計截斷誤差。

1. 線性插值

clc;clear;
y=sin_L(0.32,0.314567,0.34,0.333487,0.3367);
function y=sin_L(x0,y0,x1,y1,x)
% sin_L輸出sin(x)使用線性插值計算得到的函數值
% 例如: y=sin_L(0.32,0.314567,0.34,0.333487,0.3367)
%       y = 
%           0.3304
%       R = 
%           9.1892e-06
 
% 以下為判斷輸入值是否合法的代碼
if nargin~=5 %nargin表示number of function input arguments,判斷函數輸入參數的個數
    error('請輸入一次插值的2個插值節點和待插值點')
end
if ~( isnumeric(x0)&&isnumeric(y0)&&isnumeric(x1)&&isnumeric(y1)&&isnumeric(x) ) %isnumeric()檢測字符串是否只由數字組成,如果字符串中只包括數字,就返回Ture,否則返回False。
    error('輸入參數必須是數')
end
 
% 核心計算的代碼
%y=y0+(y1-y0)*(x-x0)/(x1-x0);%已知一次多項式,即直線上兩點,可以用點斜式寫出直線
y=y0*(x-x1)/(x0-x1)+y1*(x-x0)/(x1-x0); %兩點式
% 以下為求解截斷誤差的代碼
syms M2; % 因為sin(x)的二階導數是本身,所以只需要挑出最大的y值,即可得到M2  %syms函數用於創建符號對象
if y0>y1
    M2=y0; 
else
    M2=y1;
end
R=M2*abs((x-x0)*(x-x1))/2;
disp(['插值結果是:y=',num2str(y)]);
disp(['最大誤差是:R=',num2str(R)]);
end

2. 拋物插值

clc;clear;
%y1=sin_L(0.32,0.314567,0.34,0.333487,0.3367);%一次性插值
y2=sin_T(0.32,0.314567,0.34,0.333487,0.36,0.352274,0.3367)%二次拋物插值
function y=sin_L(x0,y0,x1,y1,x)
% sin_L輸出sin(x)使用線性插值計算得到的函數值
% 例如: y=sin_L(0.32,0.314567,0.34,0.333487,0.3367)
%       y = 
%           0.3304
%       R = 
%           9.1892e-06
 
% 以下為判斷輸入值是否合法的代碼
if nargin~=5 %nargin表示number of function input arguments,判斷函數輸入參數的個數
    error('請輸入一次插值的2個插值節點和待插值點')
end
if ~( isnumeric(x0)&&isnumeric(y0)&&isnumeric(x1)&&isnumeric(y1)&&isnumeric(x) ) %isnumeric()檢測字符串是否只由數字組成,如果字符串中只包括數字,就返回Ture,否則返回False。
    error('輸入參數必須是數')
end
 
% 核心計算的代碼
%y=y0+(y1-y0)*(x-x0)/(x1-x0);%已知一次多項式,即直線上兩點,可以用點斜式寫出直線
y=y0*(x-x1)/(x0-x1)+y1*(x-x0)/(x1-x0); %兩點式
% 以下為求解截斷誤差的代碼
syms M2; % 因為sin(x)的二階導數是本身,所以只需要挑出最大的y值,即可得到M2  %syms函數用於創建符號對象
if y0>y1
    M2=y0; 
else
    M2=y1;
end
R=M2*abs((x-x0)*(x-x1))/2;
disp(['插值結果是:y=',num2str(y)]);
disp(['最大誤差是:R=',num2str(R)]);
end


function y=sin_T(x0,y0,x1,y1,x2,y2,x)
% sin_T輸出sin(x)使用拋物插值計算得到的函數值
% 例如: y=sin_T(0.32,0.314567,0.34,0.333487,0.36,0.352274,0.3367)
%       y = 
%           0.3304
%       R = 
%           2.0315e-07
 
% 以下為判斷輸入值是否合法的代碼
if nargin~=7
    error('請輸入線性插值的插值節點和插值點')
end
if ~( isnumeric(x0)&&isnumeric(y0)&&isnumeric(x1)&&isnumeric(y1)&&isnumeric(x2)&&isnumeric(y2)&&isnumeric(x) )
    error('輸入參數必須是數')
end
 
% 核心計算的代碼
y=y0*(x-x1)*(x-x2)/((x0-x1)*(x0-x2))+y1*(x-x0)*(x-x2)/((x1-x0)*(x1-x2))+y2*(x-x0)*(x-x1)/((x2-x0)*(x2-x1));
 
%{
% 以下為求解截斷誤差的代碼
y_0=cos(x0); % 因為sin(x)的三階導數是cos(x),那么只要求出x0,x1,x2的cos值,然后去最大即可得到M3
y_1=cos(x1);
y_2=cos(x2);
syms M3;
if y_0>y_1
    M3=y_0;
else
    M3=y_1;
end
if y_2>M3
    M3=y_2;
end
R=M3*abs((x-x0)*(x-x1)*(x-x2))/6
end
%}

% 以下為求解截斷誤差的代碼
%sysm M3;
M3=cos(x0);%因為在第一象限,cosx是減函數,所以節點處的最大值在第一個節點那里取得
R=M3*abs((x-x0)*(x-x1)*(x-x2))/6
end

 

參考來源:https://blog.csdn.net/m0_37395228/article/details/80874393

五,優點和缺點

  拉格朗日插值法的公式結構整齊緊湊,在理論分析中十分方便,然而在計算中,當插值點增加或減少一個時,所對應的基本多項式就需要全部重新計算,於是整個公式都會變化,非常繁瑣。這時可以用重心拉格朗日插值法或牛頓插值法來代替。此外,當插值點比較多的時候,拉格朗日插值多項式的次數可能會很高,因此具有數值不穩定的特點,也就是說盡管在已知的幾個點取到給定的數值,但在附近卻會和“實際上”的值之間有很大的偏差這類現象也被稱為龍格現象,解決的辦法是分段用較低次數的插值多項式。(https://www.cnblogs.com/fengzhiyuan/p/8645246.html)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM