在 MATLAB 中添加分段多项式
Adding piecewise polynomials in MATLAB
我需要添加从多个数据集导出的分段多项式。有没有一种简单的方法可以在不进行插值的情况下将分段多项式加在一起?换句话说,给定 PP1 和 PP2,有没有办法生成 PP3(其中 PP3 保持分段多项式形式)?例如...
t1 = linspace(0,1,5);
t2 = linspace(0,1,7);
pp1 = spline(t1,sin(pi*t1));
pp2 = spline(t2,t2.^2);
close all
hold on
tnew = linspace(0,1,50);
h(:,1) = plot(tnew,ppval(pp1,tnew));
plot(t1,ppval(pp1,t1),'bs')
h(:,2) = plot(tnew,ppval(pp2,tnew));
plot(t2,ppval(pp2,t2),'rs')
h(:,3) = plot(tnew,ppval(pp1,tnew)+ppval(pp2,tnew));
legend(h,{'spline of sin(\pi t)','spline of t^2','sin(\pi t)+t^2'},...
'location','northwest')
xlabel('t')
但我不想明确指定 tnew
,而是想要一个新的分段多项式 pp3
,它实际上是 pp1
+pp2
.
这可能是获得 pp1
+ pp2
的最简单方法 添加到问题中的代码中:
pp12 = @(x) ppval(pp1,x)+ppval(pp2,x);
breaks = unique([pp1.breaks,pp2.breaks]);
pp3 = spline(breaks,pp12(breaks));
plot(tnew,ppval(pp3,tnew),'k:');
给出黑色虚线:
其中 pp3
是分段多项式形式,其段仅由 pp1 和 pp2 的断点定义。 运行 max(abs(ppval(pp3,tnew) - pp12(tnew)))
产生 2.7756e-16
,这是 eps
.
的数量级
感谢@LuisMendo 和@TroyHaskin 的建议。
x1 = pp1.breaks;
x2 = pp2.breaks;
x = unique([x1,x2]);
idx1 = lookup(x1,x(1:end-1));
idx2 = lookup(x2,x(1:end-1));
coefs = pp1.coefs(idx1,:) + pp2.coefs(idx2,:);
pp3 = mkpp(x,coefs);
y = ppval(pp3,x);
h(:,4) = plot(tnew,ppval(pp3,tnew));
legend(h,{'spline of sin(\pi t)','spline of t^2','sin(\pi t)+t^2','pp3'},'location','northwest')
xlabel('t')
我认为这段代码应该有效,但事实并非如此。我想是因为mkpp合成的分段多项式系数是局部的,在同一区间内相加并不能解决问题。但它可以作为解决方案的起点。
来自 mkpp 的 Matlab 帮助:
“由于 coefs 中的多项式系数是每个区间的局部系数,因此必须减去相应结区间的下端点才能使用常规多项式方程中的系数。换句话说,对于系数 [a,b,c,d ]在区间[x1,x2]上,对应的多项式为
f(x)=a(x−x1)3+b(x−x1)2+c(x−x1)+d ."
我需要添加从多个数据集导出的分段多项式。有没有一种简单的方法可以在不进行插值的情况下将分段多项式加在一起?换句话说,给定 PP1 和 PP2,有没有办法生成 PP3(其中 PP3 保持分段多项式形式)?例如...
t1 = linspace(0,1,5);
t2 = linspace(0,1,7);
pp1 = spline(t1,sin(pi*t1));
pp2 = spline(t2,t2.^2);
close all
hold on
tnew = linspace(0,1,50);
h(:,1) = plot(tnew,ppval(pp1,tnew));
plot(t1,ppval(pp1,t1),'bs')
h(:,2) = plot(tnew,ppval(pp2,tnew));
plot(t2,ppval(pp2,t2),'rs')
h(:,3) = plot(tnew,ppval(pp1,tnew)+ppval(pp2,tnew));
legend(h,{'spline of sin(\pi t)','spline of t^2','sin(\pi t)+t^2'},...
'location','northwest')
xlabel('t')
但我不想明确指定 tnew
,而是想要一个新的分段多项式 pp3
,它实际上是 pp1
+pp2
.
这可能是获得 pp1
+ pp2
的最简单方法 添加到问题中的代码中:
pp12 = @(x) ppval(pp1,x)+ppval(pp2,x);
breaks = unique([pp1.breaks,pp2.breaks]);
pp3 = spline(breaks,pp12(breaks));
plot(tnew,ppval(pp3,tnew),'k:');
给出黑色虚线:
其中 pp3
是分段多项式形式,其段仅由 pp1 和 pp2 的断点定义。 运行 max(abs(ppval(pp3,tnew) - pp12(tnew)))
产生 2.7756e-16
,这是 eps
.
感谢@LuisMendo 和@TroyHaskin 的建议。
x1 = pp1.breaks;
x2 = pp2.breaks;
x = unique([x1,x2]);
idx1 = lookup(x1,x(1:end-1));
idx2 = lookup(x2,x(1:end-1));
coefs = pp1.coefs(idx1,:) + pp2.coefs(idx2,:);
pp3 = mkpp(x,coefs);
y = ppval(pp3,x);
h(:,4) = plot(tnew,ppval(pp3,tnew));
legend(h,{'spline of sin(\pi t)','spline of t^2','sin(\pi t)+t^2','pp3'},'location','northwest')
xlabel('t')
我认为这段代码应该有效,但事实并非如此。我想是因为mkpp合成的分段多项式系数是局部的,在同一区间内相加并不能解决问题。但它可以作为解决方案的起点。
来自 mkpp 的 Matlab 帮助: “由于 coefs 中的多项式系数是每个区间的局部系数,因此必须减去相应结区间的下端点才能使用常规多项式方程中的系数。换句话说,对于系数 [a,b,c,d ]在区间[x1,x2]上,对应的多项式为
f(x)=a(x−x1)3+b(x−x1)2+c(x−x1)+d ."