MATLAB - 无工具箱的指数曲线拟合

时间:2015-04-20 13:26:23

标签: matlab curve-fitting

我需要符合指数函数的数据点(x,y),

y = A + B * exp(C * x),

但我既不能使用曲线拟合工具箱也不能使用优化工具箱。

用户rayryeng是good enough to help me,其工作代码为:

x = [0    0.0036    0.0071    0.0107    0.0143    0.0178    0.0214    0.0250    0.0285    0.0321    0.0357    0.0392    0.0428    0.0464    0.0464];
y = [1.3985    1.3310    1.2741    1.2175    1.1694    1.1213    1.0804    1.0395    1.0043    0.9691    0.9385    0.9080    0.8809    0.7856    0.7856];

M = [ones(numel(x),1), x(:)]; %// Ensure x is a column vector
lny = log(y(:)); %// Ensure y is a column vector and take ln

X = M\lny; %// Solve for parameters
A = exp(X(1)); %// Solve for A
b = X(2); %// Get b

xval = linspace(min(x), max(x));
yval = A*exp(b*xval);
plot(x,y,'r.',xval,yval,'b');

但是,此代码仅适用于没有偏移

的等式
y = A * exp(B * x).

如何扩展此代码以适应三参数方程?


在另一次尝试中,我设法使用fminsearch

来适应该功能
function [xval, yval] = curve_fitting_exponential_1_optimized(x,y,xval)

start_point = rand(1, 3);
model = @expfun;
est = fminsearch(model, start_point);

    function [sse, FittedCurve] = expfun(params)
        A = params(1);
        B = params(2);
        C = params(3);
        FittedCurve = A + B .* exp(-C * x);
        ErrorVector = FittedCurve - y;
        sse = sum(ErrorVector .^ 2);
    end

yval = est(1)+est(2) * exp(-est(3) * xval);
end

这里的问题是结果取决于随机选择的起点,所以我没有得到稳定的解决方案。但由于我需要自动化功能,我需要一些稳定的东西。我怎样才能获得稳定的解决方案?

2 个答案:

答案 0 :(得分:4)

如何使用三个参数调整rayryeng的代码?

rayryeng使用该策略线性化非线性方程,以便可以应用标准回归方法。另请参阅Jubobs'对类似问题的回答。

如果存在非零偏移量A,则此策略不再有效。我们可以通过粗略估计偏移量来解决问题。正如评论中提到的rubenvb,我们可以通过min(y)估计A,但随后对数应用于零。相反,我们可以在A的猜测和数据的最小值之间留出一点空间,比如它的范围的一半。然后我们从数据中减去A并使用rayreng的方法:

x = x(:);  % bring the data into the standard, more
y = y(:);  % convenient format of column vectors
Aguess = min(y) - (max(y) - min(y) / 2;
guess = [ones(size(x)), -x] \ log(y - Aguess);
Bguess = exp(guess(1));
Cguess = guess(2);

对于给定的数据,结果为

Aguess =  0.4792
Bguess =  0.9440
Cguess = 21.7609

除了双参数情况之外,我们不能指望这是一个很好的选择。其上证所为0.007331。

如何获得稳定的解决方案?

然而,这个猜测可用作非线性优化的起点:

start_point = [Aguess, Bguess, Cguess];
est = fminsearch(@expfun, start_point);
Aest = est(1);
Best = est(2);
Cest = est(3);

现在优化达到稳定估计,因为计算是确定性的:

Aest = -0.1266
Best =  1.5106
Cest = 10.2314

此估计的SSE为0.004041。

这是数据(蓝点)和拟合曲线(绿色:猜测,红色:优化)的样子:

答案 1 :(得分:0)

这是整个功能的全部荣耀 - 特别感谢A. Donda!

function [xval, yval] = curve_fitting_exponential_1_optimized(x,y,xval)

x = x(:);  % bring the data into the standard, more convenient format of column vectors
y = y(:);

Aguess = min(y) - (max(y)-min(y)) / 2;
guess = [ones(size(x)), -x] \ log(y - Aguess);
Bguess = exp(guess(1));
Cguess = guess(2);

start_point = [Aguess, Bguess, Cguess];
est = fminsearch(@expfun, start_point);

    function [sse, FittedCurve] = expfun(params)
        A = params(1);
        B = params(2);
        C = params(3);
        FittedCurve = A + B .* exp(-C * x);
        ErrorVector = FittedCurve - y;
        sse = sum(ErrorVector .^ 2);
    end

yval = est(1)+est(2) * exp(-est(3) * xval);
end