【问题标题】:MATLAB Fitting FunctionMATLAB 拟合函数
【发布时间】:2023-04-04 09:45:01
【问题描述】:

我试图在不使用 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 个订单后暂停以查看是否合适。

【问题讨论】:

  • 它确实有效。这里有两个问题。首先,您的 1000 作为要拟合的最大次数多项式不是一个好主意,因为您只生成大约 100 个数据点,因此您应该拟合一个次数
  • @David 我明白为什么它不能准确地拟合它是有道理的。我可以实现更多的东西以使其更像 polyfit 和 polyval 函数,还是因为该函数而无法做到?

标签: matlab linear-regression


【解决方案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];

除非您特别需要多项式基,否则您可以应用您对问题域的知识来找到适合您的其他潜在基函数,或者尝试使您执行拟合的域更线性。

【讨论】:

  • 感谢丹尼斯的帮助!
【解决方案2】:

正如 dennis 所提到的,一组不同的基函数可能会做得更好。但是,您可以使用 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

【讨论】:

  • 经过一些修改后,我得到了它与我的代码一起使用。谢谢你和丹尼斯的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
相关资源
最近更新 更多