无法将非线性曲线拟合到 Matlab 中的数据

Unable to fit nonlinear curve to data in Matlab

我正在尝试将 Matlab 中的一些数据拟合为 y = r^n/(r^n+K^n) 形式的 Hill 函数。我有 r,y 的数据,我需要找到 K,n。

我在广泛阅读文档后尝试了两种不同的方法 - 一种使用 CurveFitting Toolbox 中的 fit,另一种使用 Optimization Toolbox 中的 lsqcurvefit。我也没有取得任何成功。我错过了什么?

这是我的 xdata 和 ydata:

xdata = logspace(-2,2,101);
ydata = [0.0981 0.1074 0.1177 0.1289 0.1411 0.1545 0.1692 0.1852 0.2027 ...
          0.2219 0.2428 0.2656 0.2905 0.3176 0.3472 0.3795 0.4146 0.4528 ...
          0.4944 0.5395 0.5886 0.6418 0.6994 0.7618 0.8293 0.9022 0.9808 ...
          1.0655 1.1566 1.2544 1.3592 1.4713 1.5909 1.7183 1.8537 1.9972 ...
          2.1490 2.3089 2.4770 2.6532 2.8371 3.0286 3.2272 3.4324 3.6437 ...
          3.8603 4.0815 4.3065 4.5344 4.7642 4.9950 5.2258 5.4556 5.6833 ...
          5.9082 6.1292 6.3457 6.5567 6.7616 6.9599 7.1511 7.3347 7.5105 ...
          7.6783 7.8379 7.9893 8.1324 8.2675 8.3946 8.5139 8.6257 8.7301 ...
          8.8276 8.9184 9.0029 9.0812 9.1539 9.2212 9.2834 9.3408 9.3939 ...
          9.4427 9.4877 9.5291 9.5672 9.6022 9.6343 9.6638 9.6909 9.7157 ...
          9.7384 9.7592 9.7783 9.7957 9.8117 9.8263 9.8397 9.8519 9.8630 ...
          9.8732 9.8826];

'Fit'代码:

HillEqn = '@(x,xdata)xdata.^x(1)./(xdata.^x(1)+x(2).^x(1))';
startPoints = [1 1];
fit(xdata',ydata',HillEqn,'Start',startPoints)

错误信息:

Error using fittype>iTestCustomModelEvaluation (line 726)
Expression @(x,xdata)xdata.^x(1)./(xdata.^x(1)+x(2).^x(1)) is not a valid MATLAB
expression, has non-scalar coefficients, or cannot be evaluated:
Undefined function 'imag' for input arguments of type 'function_handle'.

'lsqcurvefit'代码:

fun = @(x,xdata) xdata.^x(1)./(xdata.^x(1)+x(2).^x(1));
x0 = [1,1]; % Initial Parameter Estimates
x = lsqcurvefit(fun,x0,xdata,ydata);

错误信息:

Error using snls (line 47)
Objective function is returning undefined values at initial point. lsqcurvefit cannot
continue.

首先,我认为您需要 3 个变量作为起点,因为山函数的最大值为 1,而您的数据最大为 10。因此,要么通过 ydata=ydata./max(ydata) 规范化您的数据,要么添加第三个变量(我只是为了演示而做的)。我是这样做的:

startPoints = [1 1 1];
s = fitoptions('Method','NonlinearLeastSquares',... %
    'Lower',[0    0   0  ],...
    'Upper',[inf  inf inf],...
    'Startpoint',startPoints);

HillEqn = fittype( 'x.^a1./(x.^a1+a2.^a1)*a3','options',s);
[ffun,gofrr] = fit(xdata(:),ydata(:),HillEqn);
yfit=feval(ffun,xdata(:)); %Fitted function
plot(xdata,ydata,'-bx',xdata,yfit,'-ro');

ffun = 

 General model:
 ffun(x) = x.^a1./(x.^a1+a2.^a1)*a3
 Coefficients (with 95% confidence bounds):
   a1 =       1.004  (1.004, 1.004)
   a2 =      0.9977  (0.9975, 0.9979)
   a3 =       9.979  (9.978, 9.979)

旁注:

在你的情况下,你真正想要做的是通过查看 Y=1./ydata 来转换你的数据,然后适合,然后再取另一个 1./Y 来获得前面 "hill" 函数表示。这是因为你的问题本质上是双线性的,所以通过 1./ydata 你会得到一个双线性关系,为此 1 阶的 polyfit 会做:

Y=1./ydata;
X = 1./xdata;
p=polyfit(X,Y,1);
plot(X,Y,'-bx',X,polyval(p,X),'-ro')