如何找到方程拟合参数的饱和度

时间:2018-12-31 09:14:47

标签: matlab curve-fitting equation

例如:abc和n是三个常数,需要使用特定方程式中的数据拟合方法来计算它们。

如何计算自定义方程(例如二次平稳方程)的参数统计量(均值,标准差,方差,偏度值和学生t检验值)?

示例:

x=[0,40,80,100,120,150,170,200], 
y=[1865,2855,3608,4057,4343,4389,4415,4478]

y=a*(x+n)^2+b*(x+n)+c, x < xc(Ymax) ....(1)   y=yp, x >= xc(Ymax) ....(2)

我已经用给定的代码拟合了这个方程:

yf = @(b,x) b(1).*(x+n).^2+b(2)*(x+n)+b(3); B0 = [0.006; 21; 1878];
[Bm,normresm] = fminsearch(@(b) norm(y - yf(b,x)), B0); a=Bm(1);
b=Bm(2); c=Bm(3); xc=(-b/(2*a))-n; p=p=a*(xc+n)^2+b*(xc+n)+c;  
if (x < xc) 
    yfit = a.*(x+n).^2+ b*(x+n)+c;  
else 
    yfit = p;  
end 
plot(x,yfit,'*') 
hold on; plot(x,y); hold off

注意:我已经使用过polyfit命令,它很有帮助,并为我提供了结果。但是,我真的觉得不合适,因为无法自定义方程式。我可以通过任何代码找到这些统计信息吗?

1 个答案:

答案 0 :(得分:2)

问题1、2和4) 如果您对等式系统有较早的了解,则好的做法是将初始值设置为接近最终结果:

您拥有的是一个超定线性方程组。

y(1) = a*x(1)^2 + b*x(1) + c
y(2) = a*x(2)^2 + b*x(2) + c
y(3) = a*x(3)^2 + b*x(3) + c
…
y(n) = a*x(n)^2 + b*x(n) + c

or in general:
y = A*X, where

A = [a; b; c]
X = [x(1)^2 x(1) 1;
     x(2)^2 x(2) 1;
     x(3)^2 x(2) 1;
     ...
     x(n)^2 x(n) 1]

适合于超定系统(since it has no solution)的一种常见做法是“ least square fit”(mldivide,\(链接))

x=[0; 40; 80; 100; 120; 150; 170; 200];
y=[1865; 2855; 3608; 4057; 4343; 4389; 4415; 4478];

X = [x.^2 x ones(numel(x),1)];

A = y\X;

a0=A(1); %- initial value for a
b0=A(2); %- initial value for b
c0=A(3); %- initial value for c

当您自定义X和A时,您可以自定义方程式

但是您也可以将初始值设置为1,它对结果的影响应该忽略不计。与问题4

相关的更多
a0=1;
b0=1; 
c0=1;

或随机值

rng(10);
A = rand(3,1);

a0=A(1);
b0=A(2); 
c0=A(3);

问题3-统计信息 如果您需要更多监控优化过程的控制,请使用更通用的形式编写匿名函数(在下面的代码中> myfun)以保存参数(a_iter,b_iter,c_iter)的所有中间值

function Fiting_ex()
global a_iter b_iter c_iter
a_iter = 0;
b_iter = 0;
c_iter = 0;
x=[0; 40; 80; 100; 120; 150; 170; 200];
y=[1865; 2855; 3608; 4057; 4343; 4389; 4415; 4478];

X = [x.^2 x ones(numel(x),1)];

A = y\X;

a0=A(1);
b0=A(2); 
c0=A(3);

B0 = [a0; b0; c0];

[Bm,normresm] = fminsearch(@(b) myfun(b,x,y),B0);

a=Bm(1);
b=Bm(2); 
c=Bm(3); 

xc=-b/(2*a); 
p=c-(b^2/(4*a));
yfit = zeros(numel(x),1);
for i=1:numel(x)
    if (x(i) < xc)
        yfit(i) = a.*x(i).^2+ b*x(i)+c;
    else
        yfit(i) = p;
    end
end

plot(x,yfit,'*') 
hold on; 
plot(x,y); 
hold off

% Statistic on optimization process
a_mean = mean(a_iter(2:end)); % mean value
a_var = var(a_iter(2:end)); % variance
a_std = std(a_iter(2:end)); % standard deviation

function f = myfun(Bm, x, y)
global a_iter b_iter c_iter
a_iter = [a_iter Bm(1)];
b_iter = [b_iter Bm(2)]; 
c_iter = [c_iter Bm(3)];

yf = Bm(1)*(x).^2+Bm(2)*(x)+Bm(3); 
a=Bm(1);
b=Bm(2); 
c=Bm(3); 
xc=-b/(2*a); 
p=c-(b^2/(4*a));
yfit = zeros(numel(x),1);
for i=1:numel(x)
    if (x(i) < xc)
        yfit(i) = a.*x(i).^2+ b*x(i)+c;
    else
        yfit(i) = p;
    end
end
f = norm(y - yfit);