how can i fit a set of data to a function?

14 views (last 30 days)
i have a set of data point[s] (r,di) and i would like to fit this data to a so called pade function
M_0*(1+x)^3/(1+sigma(a_i*x^i)); i=1-7.
in which M_0 is just a constant and sigma is sum. I'm trying to get the a_i coefficients by fitting the data to pade function.
can any one please help me.
thank you
  2 Comments
dpb
dpb on 6 Jul 2016
Edited: dpb on 6 Jul 2016
How many observations do you have?
Which variable corresponds to x in the given expression?
Oh--and which Toolboxes do you have? Fitting/Optimization and/or Statistics, maybe, or just base Matlab?
Can you past in the data?
Joseph
Joseph on 7 Jul 2016
Edited: Joseph on 7 Jul 2016
i have 37 observation for x and y. i'm trying to get variables a_i. so i think a_i variables correspond to x. and i'm trying to use lscurvefit in matlab.

Sign in to comment.

Accepted Answer

the cyclist
the cyclist on 7 Jul 2016
If you have the Statistics and Machine Learning Toolbox, I would use fitnlm. Here is an example:
% Here is an example of using fitnlm(). For simplicity, none of
% of the fitted parameters are actually nonlinear!
% Define the data to be fit
x=(0:1:10)'; % Explanatory variable
y = 5 + 3*x + 7*x.^2; % Response variable (if response were perfect)
y = y + 2*randn((size(x)));% Add some noise to response variable
% Tabulate the data
tbl = table(x,y);
% % Fit the model
% Define function that will be used to fit data
% (F is a vector of fitting parameters)
f = @(F,x) F(1) + F(2).*x + F(3).*x.^2;
beta0 = [1 1 1];
mdl = fitnlm(tbl,f,beta0);
% Calculate the model values at the empirical x
y_predicted = predict(mdl,x);
% Plot the data and fit
figure
plot(x,y,'*',x,y_predicted,'g');
legend('data','fit')
  1 Comment
Joseph
Joseph on 7 Jul 2016
Edited: dpb on 7 Jul 2016
i have below scripts.
xdata=r;
ydata=dip;
x0=[-1.36399998 1 1 1 1 1 1 1];
F=@(x,xdata)x(1)*(1+xdata).^3/(1 + x(2)*xdata + x(3)*xdata.^2 + ...
x(4)*xdata.^3 + x(5)*xdata.^4 + ...
x(6)*xdata.^5 + x(7)*xdata.^6 + ...
x(8)*xdata.^7);
[x,resnorm] =lsqcurvefit(F,x0,xdata,ydata);
but it gives me below error:
Function value and YDATA sizes are not equal.

Sign in to comment.

More Answers (1)

dpb
dpb on 7 Jul 2016
Edited: dpb on 7 Jul 2016
Looks like you're missing a "." in the division...I'd rewrite the equation more succinctly, however, and also use a change of variables-- x and xdata are, to me, EXTREMELY confusing as to "who's who in the zoo" in terms of the expression. Using x for coefficients to be estimated and xdata as standin for x for the actual independent variable is just perverse albeit what TMW doc has. Note that the x,xdata in the function argument are just dummy variables; you can use whatever makes sense. I'll choose C for the coefficient array and x for the independent variable...
Semantics aside, instead of writing the polynomial terms out, use polyval to evaluate...
F=@(C,x) C(1)*(1+x).^3./polyval([C(2:8) 1],x); % isn't that much neater? :)
[coef,resnorm] =lsqcurvefit(F,x0,r,dip);
should get you there if it is estimable. At least with the sizable number of points you've got a chance, assuming the data do fit the model at least reasonably well.
NB: The reversal of order in using polyval; the convention internally is the conventional one of the highest-order written first. This simply reverses the meaning of the coefficients of the denominator polynomial from the order in which you wrote it explicitly following the summation notation. Also, note the augmentation with the 1 for the last term for the fixed coefficient.
Oh, also note the "./" in the division expression--that was the source of your issue..try evaluating the function definition both ways and look up
doc rdivide
doc mrdivide
to see the Matlab-definition of the difference in behavior between / and ./
  4 Comments
Joseph
Joseph on 12 Jul 2016
is there any way i could fix the X(1) (or C(1)) in the fit? i tried to put it as number in the function but it didn't accept it.
dpb
dpb on 12 Jul 2016
Edited: dpb on 13 Jul 2016
Surely, but you can't do it by trying to overwrite one of the C array; you've got to reduce the number of unknowns by that one that has been fixed--
F=@(C,x) 2.50*(1+x).^3./polyval([C(1:7) 1],x);
Now only the seven poly coefficients will be estimated; I chose an arbitrary 2.5 for the original C(1).
BTW, if you want "eat your cake and have it, too!" in the sense of being able to adjust this constant value w/o having to rewrite the function, see the link to "Passing Extra Parameters" in the doc to the various optimization functions that gives examples. Basically, your options are limited--either the technique above that only changes the additional values when the anonymous function is redefined or, two be able to actually have a flexible solution use a nested function which accepts the additional constant as well as the required and calls the optimization routine with its required syntax. This works by the nested function having access to the additional parameter(s) by virtue of their scope being "local global"--within the scope of the accessible function, they're global so the nested function doesn't have to have them in its argument list. The only other option is to actually make the added parameter GLOBAL in earnest which is to be avoided if at all possible for all the grief that can cause...

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!