如何使用polyfitn在MATLAB中查找系数?

时间:2013-11-04 04:49:54

标签: matlab equation

我给出了x,y和z的数据。我试图将一组数据拟合到功能形式的模型中,如下所述:

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

其中c0c1c2c3是要找到的系数。

我试过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是因变量。 我不确定如何传递参数。

3 个答案:

答案 0 :(得分: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类似,但特别是“准备好”用于曲线/曲面拟合。

答案 1 :(得分:2)

您的模型不是多项式,也不能转换为polyfitn可以求解的多项式。

要看到这一点,请重新编写等式。替换u = exp(x),以便

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

这是一个二维多项式,-c2的度uy的度数为1。

polyfitn不是为解决自变量的未知和非整数幂而设计的;它只解决(好的,大多数)系数。在您的情况下,如果知道c0,它将解决c1c3c2

我会做的是以下几点:

%// 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

答案 2 :(得分:0)

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

nav { min-height: 100%; }