【问题标题】:fitting curve with nonlinear function using cftool in matlab在matlab中使用cftool拟合具有非线性函数的曲线
【发布时间】:2017-12-12 19:50:55
【问题描述】:

我需要像这样用非线性函数拟合数据:

y=a+b*cos(c*x+d)+e*exp(f*x);

其中 a、b、c、d、e 和 f 是要找到的系数。我在cftool中使用了Custom Equation方法,结果很糟糕,那么如何调整cftool中的StartPoint以获得更好的结果呢?否则,还有其他方法可以解决我的问题吗?非常感谢。

这是我的数据,每个都是 1*35:

    x = [1970:2004];
    y = [46808,49416,53094,57237,56677,56198,59673,61826,64158,65220,63108,60944,59543,58779,59882,60087,61825,63104,64963,66902,66443,67061,67273,67372,68679,69995,71522,73292,73932,75826,76954,78105,78439,79892,82631];

好的,Dan,这是我关于 cftool 的代码,函数由 cftool 的 Custom Equation 生成

% This file include two functions:
% 1. Main: testForFit.m
% 2. Function generated by cftool
function testForFit
clc; clear all;
x = 1970:2004;
y = [46808,49416,53094,57237,56677,56198,59673,61826,64158,65220,63108,60944,59543,58779,59882,60087,61825,63104,64963,66902,66443,67061,67273,67372,68679,69995,71522,73292,73932,75826,76954,78105,78439,79892,82631];
plot(x, y, 'or')
[fitresult, gof] = createFit(x, y)
end

function [fitresult, gof] = createFit(x, y)
%CREATEFIT(X,Y)
%  Create a fit.
%
%  Data for 'untitled fit 1' fit:
%      X Input : x
%      Y Output: y
%  Output:
%      fitresult : a fit object representing the fit.
%      gof : structure with goodness-of fit info.
%
%  See also FIT, CFIT, SFIT.
%  Auto-generated by MATLAB on 04-Feb-2014 00:23:03
%% Fit: curve fitting of gived form of function.
[xData, yData] = prepareCurveData( x, y );

% Set up fittype and options.
ft = fittype( 'a+b*cos(c*x+d)+e*exp(f*x)', 'independent', 'x', 'dependent', 'y' );
% ft = fittype( 'a+e*exp(f*x)', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';

% http://stackoverflow.com/questions/21551951/fitting-curve-with-nonlinear-function-using-cftool-in-matlab
% Firstly, give the estimation, then calculate it
% funlist={1, @(p,x) cos(p(1)*x+p(2)), @(p,x) exp(p(3)*x)};
% NLPstart = [0.605 -3159.659 0.02369];
% [cdf,abe] = fminspleas(funlist,NLPstart,x,y)
% c=cdf(1); d=cdf(2); f=cdf(3);
% a=abe(1); b=abe(2); e=abe(3);
% opts.StartPoint = [a b c d e f];

% How to give the value of StartPoint ?
opts.StartPoint = [0.957166948242946 0.485375648722841 0.8002804688888 0.141886338627215 0.421761282626275 0.915735525189067];
% opts.StartPoint = [31950 1557 0.605 -3159.659 1.183e-16 0.02369];

% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );

% Plot fit with data.
figure( 'Name', 'curve fitting' );
h = plot( fitresult, xData, yData );
legend( h, 'y vs. x', 'curve fitting', 'Location', 'NorthEast' );
% Label axes
% 31950 1557 0.605 -3159.659 1.183e-16 0.02369
% title('31950+1557*cos(0.605*x-3159.659)+1.183e-16*exp(0.02369*x)')
xlabel( 'x' );
ylabel( 'y' );
grid on
% x = [1970:2004];
% y = [46808,49416,53094,57237,56677,56198,59673,61826,64158,65220,63108,60944,59543,58779,59882,60087,61825,63104,64963,66902,66443,67061,67273,67372,68679,69995,71522,73292,73932,75826,76954,78105,78439,79892,82631];
% Baidu Zhidao
% http://zhidao.baidu.com/question/198731054514100005.html?push=keyword
end

如果起点不正确会发生一些错误...

【问题讨论】:

  • 请包含您尝试使用cftool 的代码并说明问题所在。您可以编辑您的问题以添加此信息。

标签: matlab math


【解决方案1】:

我没有 CurveFit 工具箱,但据说在您选择曲线类型的位置附近有一个“Fit Options”按钮,您可以在其中选择自己的初始点。

我还建议您尝试FMINSPLEAS,它可以利用 y 对 6 个参数中的 3 个具有线性相关性这一事实。你也只需要提供非线性参数的初始猜测NLPstart=[c,d,f]

funlist={1, @(p,x) cos(p(1)*x+p(2)), @(p,x) exp(p(3)*x)};

[cdf,abe] = fminspleas(funlist,NLPstart,x,y);

c=cdf(1); d=cdf(2); f=cdf(3);
a=abe(1); b=abe(2); e=abe(3);

【讨论】:

  • 谢谢!所以可以计算线性参数,但是如何提供非线性参数的初始猜测呢?我知道如果我只适合f(x) = e*exp(f*x),f 可以很容易地计算出来; 但是如何得到关于 c 和 d 的初始猜测?
  • 如果指数项正在衰减,那么渐近地,前两项服从Sum of Sines 模型。也许将数据的尾部提供给 cftool 以仅半准确地估计正弦部分?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
相关资源
最近更新 更多