How can I solve this function below?
1 回表示 (過去 30 日間)
古いコメントを表示
parameters:a b c
KNOWN:(x1,y1),(x2,y2)... ...(xn,yn) How can I figure out all the parameters by using MATLAB?
0 件のコメント
採用された回答
the cyclist
2014 年 4 月 27 日
Your code was fine, but your variables were pretty badly scaled, so I think the fit was behaving badly numerically. Here is some code where I rescaled your time variable for the fit (and then rescaled it back to display):
TIME_SCALE = 1000;
time = [1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 ];
time = time/TIME_SCALE;
Y6711 = [0.001549451 0.001406211 0.001811241 0.001661079 0.002009743 0.001669221 0.002511118 0.001794201 0.003740947 0.00441657 0.004941945 0.004628348 0.004379816 0.005177686 0.004069535 0.004633793 0.007670759 0.009623098 0.009783128 0.010096395 0.012705525];
beta=nlinfit(time,Y6711,@curvefun,[0.5 0.5 0.5]);
a = beta(1);
b = beta(2);
c = beta(3);
%test the model
xx = min(time):(1/TIME_SCALE):max(time);
yy = a./(1+exp(b.*time+c));
plot(TIME_SCALE*time,Y6711,'o',TIME_SCALE*xx,yy,'r')
You are right that the initial guess is subjective. It is best to put in something that is approximately the right magnitude and sign if you can. For example, you know your parameter b has to be negative. But MATLAB figured it out here.
3 件のコメント
the cyclist
2014 年 4 月 29 日
I found your problem to be a bit tricky, but that is probably because I am not really an expert (and it is not something I do a lot of). I did spend some time thinking about it, though, because I found it quite interesting. Here's what I found.
Your parameter a doesn't really help the fit much, and seems to cause lots of problems because it is barely independent from c. I can get a very good fit with the function
function f=curvefun(a,x)
f = 1./(1+exp(a(1).*x+a(2)));
end
instead.
When I use that, then I could do the following to make a guess at the initial parameters. Take the reciprocal of each side:
(1/y) = 1 + exp(bx+c)
Given your range of y, the 1 is negligible at first order, so ignore it:
(1/y) = exp(bx+c) [approx]
Take the log:
log(1/y) ~= bx + c [approx]
You can use a linear regression to estimate b and c:
b_linear = regress(log(1./Y6711'),[ones(size(time')),time']);
If you look at the relationship between this equation and the original one, you can see that a good guess at the initial parameters would be
b0 = [b_linear(2) b_linear(1)];
Putting this all together, I used the following code:
TIME_SCALE = 1000;
time = [1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 ];
time = time/TIME_SCALE;
Y6711 = [0.001549451 0.001406211 0.001811241 0.001661079 0.002009743 0.001669221 0.002511118 0.001794201 0.003740947 0.00441657 0.004941945 0.004628348 0.004379816 0.005177686 0.004069535 0.004633793 0.007670759 0.009623098 0.009783128 0.010096395 0.012705525];
b_linear = regress(log(1./Y6711'),[ones(size(time')),time']);
b0 = [b_linear(2) b_linear(1)];
beta=nlinfit(time,Y6711,@curvefun,b0);
b = beta(1);
c = beta(2);
%test the model
xx = min(time):(1/TIME_SCALE):max(time);
yy = 1./(1+exp(b.*time+c));
figure
plot(TIME_SCALE*time,Y6711,'o',TIME_SCALE*xx,yy,'r')
function f=curvefun(a,x)
f = 1./(1+exp(a(1).*x+a(2)));
end
This gave me a fit that looks just as good as the original (with one fewer parameter).
その他の回答 (1 件)
the cyclist
2014 年 4 月 26 日
If you have the Statistics Toolbox, you could use the nlinfit() function to solve this.
参考
カテゴリ
Help Center および File Exchange で Particle & Nuclear Physics についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!