Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MATLAB-无工具箱的指数曲线拟合_Matlab_Curve Fitting - Fatal编程技术网

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

MATLAB-无工具箱的指数曲线拟合,matlab,curve-fitting,Matlab,Curve Fitting,我有数据点(x,y),我需要拟合指数函数 y = A + B * exp(C * x), 但我既不能使用曲线拟合工具箱,也不能使用优化工具箱 用户rayryeng的工作代码为: 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

我有数据点(x,y),我需要拟合指数函数

y = A + B * exp(C * x),
但我既不能使用曲线拟合工具箱,也不能使用优化工具箱

用户rayryeng的工作代码为:

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
这里的问题是,结果取决于随机选择的起点,所以我没有得到稳定的解。但是因为我需要自动化的功能,我需要一些稳定的东西。如何获得稳定的解决方案?

如何使rayryeng的代码适应三个参数? 使用该策略将非线性方程线性化,以便可以应用标准回归方法。另请参见对类似问题的回答

如果存在非零偏移量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
除了双参数情况外,我们不能期望这是一个很好的匹配。其SSE为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

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

如何使rayryeng的代码适应三个参数? 使用该策略将非线性方程线性化,以便可以应用标准回归方法。另请参见对类似问题的回答

如果存在非零偏移量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
除了双参数情况外,我们不能期望这是一个很好的匹配。其SSE为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

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


以下是整个功能的全部荣耀——特别感谢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

这里是整个功能的全部荣耀-特别感谢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


你也可以看看。就我从链接中了解到的,没有优化就无法进行这样的曲线拟合。对吗?@ViharChervenkov你可以像我一样使用。@TroyHaskin谢谢,但正如我说的,我希望找到不依赖于首字母的东西guess@Vihar是的,您甚至可以从所有数据中减去min(y),执行
M\(lny ln(min(y))
,并将其用作fminsearch的起始值。在任何情况下,这都会给出一个很好的初步估计,但你需要确定这是否比从理智(但不是随机)的初始猜测开始的速度更快。你也可以看看。就我从链接中了解到的,没有优化就无法进行这样的曲线拟合。对吗?@ViharChervenkov你可以像我一样使用。@TroyHaskin谢谢,但正如我说的,我希望找到不依赖于首字母的东西guess@Vihar是的,您甚至可以从所有数据中减去min(y),执行
M\(lny ln(min(y))
,并将其用作fminsearch的起始值。在任何情况下,这都应该给出一个很好的第一个估计,但你需要确定这是否比从一个正常的(但不是随机的)初始猜测开始的速度更快。@BenVoigt,但他的优化代码已经容纳了一个非零偏移量。啊,好的,他想要修改第一个代码段。啊。好的,谢谢你指出这一点。谢谢你的回答。我只是想指出,我也没有统计工具箱,所以我不能使用范围。我用max(y)-min(y)代替。你可能想在回答中改变这一点。@ViharChervenkov,我不知道
range
属于工具箱,谢谢你指出这一点。很高兴我能帮上忙。@rayryeng,看来我一直拼错你的名字。对不起@BenVoigt,但是他的优化代码已经容纳了一个非零偏移量。啊,好的,他想要修改第一个代码段。啊。好的,谢谢你指出这一点。谢谢你的回答。我只是想指出,我也没有统计工具箱,所以我不能使用范围。我用max(y)-min(y)代替。你可能想在回答中改变这一点。@ViharChervenkov,我不知道
range
属于工具箱,谢谢你指出这一点。很高兴我能帮上忙。@rayryeng,看来我一直拼错你的名字。对不起!