我试图在不使用polyfit和polyval的情况下为某些数据拟合一条线。我已经得到了一些关于如何实现这一点的好帮助,并且我已经使用简单的sin函数。但是,当应用于我试图适合的功能时,它不起作用。这是我的代码:
clear all
clc
lb=0.001; %lowerbound of data
ub=10; %upperbound of data
step=.1; %step-size through data
a=.03;
la=1482/120000; %1482 is speed of sound in water and 120kHz
ep1=.02;
ep2=.1;
x=lb:step:ub;
r_sq_des=0.90; %desired value of r^2 for the fit of data without noise present
i=1;
for x=lb:step:ub
G(i,1)= abs(sin((a/la)*pi*x*(sqrt(1+(1/x)^2)-1)));
N(i,1)=2*rand()-1;
Ghat(i,1)=(1+ep1*N(i,1))*G(i,1)+ep2*N(i,1);
r(i,1)=x;
i=i+1;
end
x=r;
y=G;
V=[x.^0];
Vfit=[x.^0];
for i=1:1:1000
V = [x.^i V];
c = V \ y;
Vfit = [x.^i Vfit];
yFit=Vfit*c;
plot(x,y,'o',x,yFit,'--')
drawnow
pause
end
前两节只是定义变量和函数。第二个for循环是我正在进行拟合的地方。正如你所看到的,我在每个第n个订单后暂停它以便看到合适。
答案 0 :(得分:1)
我改变了你的健康公式,我得到了相同的答案,但很快得到了 矩阵是单数的警告。没有意义继续过去 反转是奇异的。
根据您的工作情况,您通常可以更改变量或更改域名。 这没有做得更好,但似乎有点帮助。
自曲线的初始部分以来,我将样本数增加了10倍 看起来不够高。
我添加了一个加权变量,但在下面的代码中将其设置为相等的权重。尝试 减轻尾巴并没有像我希望的那样多。
可能不是一个真正的解决方案,但也许会有更多的旋钮/变量。
...
step=.01; %step-size through data
...
x=r;
y=G;
t=x.*sqrt(1+x.^(-2));
t=log(t);
V=[ t.^0];
w=ones(size(t));
for i=1:1:1000
% Trying to solve for value of c
% c that
% yhat = V*c approximates y
% or y = V*c
% V'*y = V'*V * c
% c = (V'*V) \ V'*y
V = [t.^i V];
c = (V'*diag(w.^2)*V ) \ (V'*diag(w.^2)*y) ;
yFit=V*c;
subplot(211)
plot(t,y,'o',t,yFit,'--')
subplot(212)
plot(x,y,'o',x,yFit,'--')
drawnow
pause
end
它看起来更像是频率估算问题,并试图适应未知频率 多项式倾向于触摸和去。用快速替换多项式基础 sin / cos基础似乎没有做坏事。
V = [sin(t*i) cos(t*i) V];
除非您特别需要多项式基础,否则您可以应用您对问题域的了解来找到适合您的其他潜在基函数,或者尝试使您执行拟合的域更加线性。
答案 1 :(得分:0)
正如丹尼斯所提到的,一组不同的基函数可能会做得更好。但是,您可以使用QR因子分解来改进多项式拟合,而不仅仅是解决矩阵方程。无论你做什么,它都是一个严重的条件问题,并且使用平滑的基函数不会让你准确地再现实际功能中的尖角。
clear all
close all
clc
lb=0.001; %lowerbound of data
ub=10; %upperbound of data
step=.1; %step-size through data
a=.03;
la=1482/120000; %1482 is speed of sound in water and 120kHz
ep1=.02;
ep2=.1;
x=logspace(log10(lb),log10(ub),100)';
r_sq_des=0.90; %desired value of r^2 for the fit of data without noise present
y=abs(sin(a/la*pi*x.*(sqrt(1+(1./x).^2)-1)));
N=2*rand(size(x))-1;
Ghat=(1+ep1*N).*y+ep2*N;
V=[x.^0];
xs=(lb:.01:ub)';
Vfit=[xs.^0];
for i=1:1:20%length(x)-1
V = [x.^i V];
Vfit = [xs.^i Vfit];
[Q,R]=qr(V,0);
c = R\(Q'*y);
yFit=Vfit*c;
plot(x,y,'o',xs,yFit)
axis([0 10 0 1])
drawnow
pause
end