多项式拟合之Arnoldi算法
之前写过一篇多项式拟合的方程法,但是之前版本,包括matlab自带的多项式拟合函数,效果都不是特别好。在这里介绍一种多项式拟合法,由于本人能力有限,所以原理的关键地方也不懂。
多项式拟合一般表达式
y = a 0 + a 1 x + a 2 x 2 + ⋯ + a n x n = ∑ i = 0 n a i x i \begin{aligned} y&=a_0+a_1x+a_2x^2+\cdots +a_nx^n\\ &=\sum_{i=0}^{n}{a_ix^i} \end{aligned} y=a0+a1x+a2x2+⋯+anxn=i=0∑naixi
构建方程组
y
1
=
a
0
+
a
1
x
1
+
a
2
x
1
2
+
⋯
+
a
n
x
1
n
y
2
=
a
0
+
a
1
x
2
+
a
2
x
2
2
+
⋯
+
a
n
x
2
n
⋮
y
m
=
a
0
+
a
1
x
m
+
a
2
x
m
2
+
⋯
+
a
n
x
m
n
\begin{aligned} y_1&=a_0+a_1x_1+a_2x_1^2+\cdots +a_nx_1^n\\ y_2&=a_0+a_1x_2+a_2x_2^2+\cdots +a_nx_2^n\\ \vdots\\ y_m&=a_0+a_1x_m+a_2x_m^2+\cdots +a_nx_m^n\\ \end{aligned}
y1y2⋮ym=a0+a1x1+a2x12+⋯+anx1n=a0+a1x2+a2x22+⋯+anx2n=a0+a1xm+a2xm2+⋯+anxmn
令:
X
=
[
x
1
0
⋯
0
0
x
2
⋯
0
⋮
⋮
⋯
⋮
0
0
⋯
x
m
]
X=\left[ \begin{matrix} x_1&0&\cdots&0\\ 0&x_2&\cdots&0\\ \vdots&\vdots&\cdots&\vdots\\ 0&0&\cdots&x_m\\ \end{matrix} \right]
X=⎣⎢⎢⎢⎡x10⋮00x2⋮0⋯⋯⋯⋯00⋮xm⎦⎥⎥⎥⎤
b = ( b 0 b 1 ⋮ b n ) b=\left( \begin{matrix} b_0\\ b_1\\ \vdots\\ b_n\\ \end{matrix} \right) b=⎝⎜⎜⎜⎛b0b1⋮bn⎠⎟⎟⎟⎞
q 0 = [ 1 , ⋯ , 1 ] T A = [ q 0 , X q 0 , X 2 q 0 , ⋯ , X n q 0 ] = [ 1 x 1 ⋯ x 1 n 1 x 2 ⋯ x 2 n ⋮ ⋮ ⋯ ⋮ 1 x m ⋯ x m n ] q_0=[1,\cdots,1]^T\\ \begin{aligned} A&=[q_0,Xq_0,X^2q_0,\cdots,X^nq_0]\\ &=\left[ \begin{matrix} 1&x_1&\cdots&x_1^n\\ 1&x_2&\cdots&x_2^n\\ \vdots&\vdots&\cdots&\vdots\\ 1&x_m&\cdots&x_m^n\\ \end{matrix} \right] \end{aligned} q0=[1,⋯,1]TA=[q0,Xq0,X2q0,⋯,Xnq0]=⎣⎢⎢⎢⎡11⋮1x1x2⋮xm⋯⋯⋯⋯x1nx2n⋮xmn⎦⎥⎥⎥⎤
A b = f Ab=f Ab=f
Krylov 子空间
令 v ∈ R N v\in R^N v∈RN。“,由 v , A v , ⋯ , A m − 1 v v,Av,\cdots,A^{m-1}v v,Av,⋯,Am−1v 所生成的子空间称之为由 v v v与 A A A所生成的第 m m m个Krylov子空间,并记 K m ( v , A ) K_m{(v,A)} Km(v,A)。
剩余的推导
略,能力有限,见谅
代码
polyfitA.m
function [d,H] = polyfitA(x,f,n)
m = length(x);
Q = ones(m,1);
H = zeros(n+1,n);
for k = 1:n
q = x.*Q(:,k);
for j = 1:k
H(j,k) = Q(:,j)'*q/m;
q = q - H(j,k)*Q(:,j);
end
H(k+1,k) = norm(q)/sqrt(m);
Q = [Q q/H(k+1,k)];
end
d = Q\f;
polyvalA.m
function y = polyvalA(d,H,s)
M = length(s);
W = ones(M,1);
n = size(H,2);
for k = 1:n
w = s.*W(:,k);
for j = 1:k
w = w - H(j,k)*W(:,j);
end
W = [W w/H(k+1,k)];
end
y = W*d;
测试
测试代码
clear
close all
%% 准备数据
x = 1:0.1:50;
f=0.001*x.^3.2+0.04*x.^2+20*sin(x)-30*cos(x)+20*rand(size(x));
n=50;
%% matlab自带多项式拟合
c= polyfit(x',f',n);
%% 本文多项式拟合函数
[d,h]= polyfitA(x',f',n);
%% 测试效果
y1=polyval(c,x');% matlab自带
y2 = polyvalA(d,h,x'); %本文函数
err1 = sqrt(f*y1/length(f));
err2=sqrt(f*y2/length(f));
figure(1)
plot(x,f,x,y1','k') %matlab
title("matlab自带函数误差:"+err1);
figure(2)
plot(x,f,x,y2','r') %本文
title("本文函数误差:"+err2);
而且,当多项式次数比较高的时候,比如100次,matlab自带函数会出现错误!
这是80次的情况