JAN*_*JAN 4 matlab interpolation polynomial-math
我使用卷积和for循环(太多的循环)来计算插值使用
Lagrange's method
,这里是主要代码:
function[p] = lagrange_interpolation(X,Y)
L = zeros(n);
p = zeros(1,n);
% computing L matrice, so that each row i holds the polynom L_i
% Now we compute li(x) for i=0....n ,and we build the polynomial
for k=1:n
multiplier = 1;
outputConv = ones(1,1);
for index = 1:n
if(index ~= k && X(index) ~= X(k))
outputConv = conv(outputConv,[1,-X(index)]);
multiplier = multiplier * ((X(k) - X(index))^-1);
end
end
polynimialSize = length(outputConv);
for index = 1:polynimialSize
L(k,n - index + 1) = outputConv(polynimialSize - index + 1);
end
L(k,:) = multiplier .* L(k,:);
end
% continues
end
Run Code Online (Sandbox Code Playgroud)
这些对于计算循环来说太多了l_i(x)
(这是在最后一次计算之前完成的P_n(x) = Sigma of y_i * l_i(x)
).
有什么建议让它更正式matlab吗?
谢谢
是的,一些建议(在下面的版本1中实现):if
循环可以与for
上面的组合(只需通过下面的内容index
跳过); 总是相等的,总是相等的(因为你有数据点,带系数的多项式),所以最后一个循环和下一行也可以用简单替换k
jr(jr~=j)
polynomialSize
length(outputConv)
n
n
(n-1)th
n
for
L(k,:) = multiplier * outputConv;
所以我复制的例子http://en.wikipedia.org/wiki/Lagrange_polynomial(并通过他们的j-m
符号,但对我来说j
去1:n
和m
是1:n
和m~=j
),因此我的初始化看起来像
clear; clc;
X=[-9 -4 -1 7]; %example taken from http://en.wikipedia.org/wiki/Lagrange_polynomial
Y=[ 5 2 -2 9];
n=length(X); %Lagrange basis polinomials are (n-1)th order, have n coefficients
lj = zeros(1,n); %storage for numerator of Lagrange basis polyns - each w/ n coeff
Lj = zeros(n); %matrix of Lagrange basis polyns coeffs (lj(x))
L = zeros(1,n); %the Lagrange polynomial coefficients (L(x))
Run Code Online (Sandbox Code Playgroud)
然后v 1.0看起来像
jr=1:n; %j-range: 1<=j<=n
for j=jr %my j is your k
multiplier = 1;
outputConv = 1; %numerator of lj(x)
mr=jr(jr~=j); %m-range: 1<=m<=n, m~=j
for m = mr %my m is your index
outputConv = conv(outputConv,[1 -X(m)]);
multiplier = multiplier * ((X(j) - X(m))^-1);
end
Lj(j,:) = multiplier * outputConv; %jth Lagrange basis polinomial lj(x)
end
L = Y*Lj; %coefficients of Lagrange polinomial L(x)
Run Code Online (Sandbox Code Playgroud)
如果你意识到l_j(x)的分子只是一个具有特定根的多项式,那么可以进一步简化 - 因为在matlab中有一个很好的命令 - poly
.类似地,分母只是在X(j)处评估的多数 - 因为有polyval
.因此,v 1.9:
jr=1:n; %j-range: 1<=j<=n
for j=jr
mr=jr(jr~=j); %m-range: 1<=m<=n, m~=j
lj=poly(X(mr)); %numerator of lj(x)
mult=1/polyval(lj,X(j)); %denominator of lj(x)
Lj(j,:) = mult * lj; %jth Lagrange basis polinomial lj(x)
end
L = Y*Lj; %coefficients of Lagrange polinomial L(x)
Run Code Online (Sandbox Code Playgroud)
为什么版本1.9而不是2.0?好吧,有可能有办法摆脱这最后的循环,并将其全部写入1行,但我现在想不到它 - 它是v 2.0的todo :)
而且,对于甜点,如果你想获得与维基百科相同的图片:
figure(1);clf
x=-10:.1:10;
hold on
plot(x,polyval(Y(1)*Lj(1,:),x),'r','linewidth',2)
plot(x,polyval(Y(2)*Lj(2,:),x),'b','linewidth',2)
plot(x,polyval(Y(3)*Lj(3,:),x),'g','linewidth',2)
plot(x,polyval(Y(4)*Lj(4,:),x),'y','linewidth',2)
plot(x,polyval(L,x),'k','linewidth',2)
plot(X,Y,'ro','linewidth',2,'markersize',10)
hold off
xlim([-10 10])
ylim([-10 10])
set(gca,'XTick',-10:10)
set(gca,'YTick',-10:10)
grid on
Run Code Online (Sandbox Code Playgroud)
产生
享受并随意重用/改进