2

我得到了 x、y 和 z 的数据。我正在尝试将一组数据拟合到功能形式的模型中,如下所述:

z(x, y) = c0 + c1.* exp(-(c2 .* x)) + c3.* (y.^1)

其中c0c1和是要找到的系数c2c3

我尝试了 John D'Errico 的polyfitn()。但是,我怎样才能在这个函数中拟合我提出的模型呢?

% 到目前为止我已经尝试过

clc

x= [1 .. 60];

y= [0.001 .. 0.8];

z= [0.996297743 .. 0.095331687];

model= c0 + c1.* exp(-(c2 .* x)) + c3.* (y.^1);

p = polyfitn([x(:),y(:)], z(:),  'model')

% 这里 x,y 是自变量,z 是因变量。我不确定如何传递论点。

4

3 回答 3

2

在我看来,不需要外部工具,方便cftool可以在大多数情况下为您提供帮助。它将为您生成以下功能:

function [fitresult, gof] = expfit(x, y, z)

[xData, yData, zData] = prepareSurfaceData( x, y, z );

% Set up fittype and options.
ft = fittype( 'c0 + c1.* exp(-(c2 .* x)) + c3.* (y.^1);', 'independent', {'x', 'y'}, 'dependent', 'z' );
opts = fitoptions( ft );
opts.Display = 'Off';
opts.Lower = [-Inf -Inf -Inf -Inf];
opts.StartPoint = [0.0975404049994095 0.278498218867048 0.546881519204984 0.957506835434298];
opts.Upper = [Inf Inf Inf Inf];

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

% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult{1}, [xData, yData], zData );
legend( h, 'untitled fit 1', 'z vs. x, y', 'Location', 'NorthEast' );
% Label axes
xlabel( 'x' );
ylabel( 'y' );
zlabel( 'z' );
grid on

最后,您只需要一个脚本来评估您的 fitobject:

[res,gof] = expfit(x,y,z)
% gives you the coeffcients
coeffvalues(res{1})

简短的版本(没有额外的功能和情节)将是:

[xData, yData, zData] = prepareSurfaceData( x, y, z );
functionToFit = 'c0 + c1.* exp(-(c2 .* x)) + c3.* (y.^1);';
ft = fittype( functionToFit, 'independent', {'x', 'y'}, 'dependent', 'z' );
fitobj = fit( [xData, yData], zData, ft );
coeffvalues( fitobj{1} )

请注意,对于二维拟合,您需要使用prepareCurveData而不是prepareSurfaceData. 这些是 Matlab 内置函数,在某种程度上类似于meshgrid,但特别是“准备”用于曲线/曲面拟合。

于 2013-11-04T08:39:15.530 回答
2

您有一个不是多项式的模型,也无法将其转换为polyfitn可以求解的多项式。

要看到这一点,请重新编写您的方程式。进行替换u = exp(x),这样

z(ln(u), y) = c0 + c1·u^(-c2) + c3·y

这是一个 2 维多项式,其中-c2u, 为 1次y

polyfitn并非旨在解决自变量的未知和非整数幂;它仅(嗯,大部分)解决了coefficients。在您的情况下,它将解决c0,c1并且c3如果c2已知。

我会做的是以下几点:

%// function that computes the sum-of-squares for some estimate
model = @(c) sum((c(1) + c(2)*exp(-c(3)*x) + c(4)*y - z).^2);

%// optimize the fit 
C = fminsearch(model, [1 1 1 1]) %// NOTE: random starting values

用这两行代码,我得到

%// c0             c1             c2            c3
C = 2.3445e-001    8.4158e-001    1.5817e-001   -1.5584e-001     

如果我绘制模型和数据以及差异,这看起来很合理。

如果您有优化工具箱,以下内容可能会更强大:

%// function that computes the difference of the model to the data
model = @(c) c(1) + c(2)*exp(-c(3)*x) + c(4)*y - z;

%// optimize the fit 
C = lsqnonlin(model, [1 1 1 1]) %// NOTE: random starting values
于 2013-11-04T14:29:53.653 回答
0

假设您有一个自变量 C 和一个因变量 D,其中包含由 ft 定义的数据和 D=f(C) 的函数。这很好用:

ft = fittype('a*log(C)+b*cos(C)+c*exp(C)','independent','C','dependent','D');

fitobj = fit( x, D, ft );
KC=coeffvalues( fitobj )

plot(fitobj,C,D);
% 
txt = ['D= ' num2str(KC(1)) ' ln(C)' '+' num2str(KC(2))  ' cos(C)' '+'  num2str(KC(3))  ' exp(C)' ];
  annotation('textbox','String',txt,'FitBoxToText','on');
于 2018-09-23T18:17:37.260 回答