MTALAB實現三次樣條插值及埃爾米特(Hermite)插值

問題描述:


本文將採用三次樣條插值及赫米特(Hermite)插值解決這一問題。

Sec 1


三次樣條插值的數學原理可自行百度


function Sanci(N)
%程序使用三次樣條插值
%N代表節點個數,數組形式

n=length(N);
for i=1:n
    jiedian=linspace(-2*pi,2*pi,N(i));%插值節點的確認
    %三次樣條插值
    %計算函數值
    for j=1:N(i)
        F(j)=0.5*jiedian(j)-cos(jiedian(j));
    end
    
    %計算差商
    deltx=diff(jiedian);
    delty=diff(F);
    firstorder=delty./deltx ;%一階差商
    for k=1:length(jiedian)-2
        delt2x(k)=jiedian(k+2)-jiedian(k);
    end
    delt2y=diff(firstorder);
    D=delt2y./delt2x; %二階差商
    
    %構造係數矩陣B
    CN=length(jiedian);
    for k=1:CN
        for j=1:CN
            if j==k
                B(k,j)=2;
                if k==1
                    B(k,k+1)=1;
                end
                if k==CN
                    B(k,k-1)=1;
                end
                if k>=2
                    B(k,j-1)=0.5;
                    B(k,j+1)=0.5;
                end
                if j~=k&&j~=k-1&&j~=k+1
                    B(k,j)=0;
                end
            end
        end
    end
    %求解待定參數M
    %根據手算得出邊界條件對應D值得表達式D=(6*(f_i-f_i-1)-3*h_i)/h_i^2
    D_1=(6*firstorder(1)-12*pi/N(i))/(4*pi/N(i))^2;
    D_Last=(6*firstorder(CN-1)-12*pi/N(i))/(4*pi/N(i))^2;
    C=[D_1,D,D_Last];%附加邊界條件的新系數矩陣
    M=(B'*C')';          
    for j=1:N(i)-1
        x1=jiedian(j);x2=jiedian(j+1);
        x_mid(j)=(x1+x2)/2;
        %構造插值函數
        S1(j)=(((x2-x_mid(j))^3)*M(j)+((x_mid(j)-x1)^3)*M(j+1))/(24*pi/N(i))+((x2-x_mid(j))*F(j)+(x_mid(j)-x1)*F(j+1))/(4*pi/N(i))-(4*pi*((x2-x_mid(j))*M(j)+(x_mid(j)-x1)*M(j+1)))/(6*N(i));
    end
    save('三次插值中點値.mat','S1');
    save('z','x_mid');
    subplot(3,2,i);
    plot(x_mid,S1,'k-')%繪圖
    hold on;
    plot(x_mid,S1,'ko');%三次樣條插值點
    hold on;
    %繪製f=0.5*x-cosx圖形
    sym x;
    f='0.5*x-cos(x)';
    h=ezplot(f,[-2*pi,2*pi]);
    set(h,'color','r');
    bt=strcat('節點=',num2str(N(i)));% 字符串連接
    title(bt);
end


在命令行窗口輸入:

Sanci([7,14,21,56,112])

可得到下面的圖片,可以看到,插值節點越多,插值曲線與原曲線擬合程度越高




Sec 2

赫米特插值

function Hermite(N)
%程序使用赫米特插值
%N代表節點個數,數組形式

n=length(N);
for i=1:n
    jiedian=linspace(-2*pi,2*pi,N(i));%插值節點的確認
    %Hermite 插值繪圖
    for j=1:N(i)-1
        x1=jiedian(j);x2=jiedian(j+1);
        x_mid(j)=(x1+x2)/2;
        h1(j)=0.5*x1-cos(x1); %插值節點x1的函數值
        h2(j)=0.5*x2-cos(x2); %插值節點x2的函數值
        hx1(j)=0.5+sin(x1); %插值節點x1的導數值
        hx2(j)=0.5+sin(x2); %插值節點x2的導數值
        %插值函數值的計算
        H(j)=(1+2*(x_mid(j)-x1)/(x2-x1))*(((x2-x_mid(j))/(x2-x1))^2)*h1(j)+(1+2*(x2-x_mid(j))/(x2-x1))*(((x_mid(j)-x1)/(x2-x1))^2)*h2(j)+((x_mid(j)-x1)*((x2-x_mid(j))^2)/((x2-x1)^2))*hx1(j)-((x2-x_mid(j))*((x_mid(j)-x1)^2)/((x2-x1)^2))*hx2(j);
    end
    save('Hermite插值中點値.mat','H');
    subplot(3,2,i);
plot(x_mid,H,'b-');%繪圖
hold on;
    plot(x_mid,H,'b*');%赫米特插值點
    %繪製f=0.5*x-cosx圖形
    sym x;
    f='0.5*x-cos(x)';
    h=ezplot(f,[-2*pi,2*pi]);
    set(h,'color','r');
    grid on;
    bt=strcat('節點=',num2str(N(i)));% 字符串連接
    title(bt);
end

在命令行窗口輸入:

>>Hermite([7,14,28,56,112])






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章