Without the curve fit toolbox how do you fit a function to data in MATLAB?
In particular, how do you fit a function that isn't a polynomial, e.g., if I want to fit a function like y = x^(1/3) + 5 where it is not an integer?
If you know the form of the function you want to fit but do not know its parameters, you can use fminsearch
to find the parameters that would fit your data. If you have data (possibly noisy) that you want to fit to y=x^a + b
where a
and b
are unknown (here I will assume that the true values are a=1/3
and b=5
) this is how I'd have a quick answer:
Here I generate my data (you would not have to do that in a real life case)
>> x = linspace(0,5,10);
>> y = x.^(1/3) + 5;
>> y_noisy = y + 0.1*rand(size(y));
Then I define the function I want to minimize with respect to a
and b
and minimize it with fminsearch
. In this case, I minimize the integral of the square of the difference between my data and the function used for the fit. Below I have defined two functions, one with the noisy data, and one without noise. You see that in the absence of noise you recover exactly the values of a
and b
.
NB: fminsearch
wotks with a vector of parameters (v
in my case). I took a=v(1)
and b=v(2)
. You also have to provide some initial guess for v
(here [1 1]
).
>> err_noisy = @(v) trapz(x,(y_noisy - x.^v(1)-v(2)).^2);
>> err = @(v) trapz(x,(y - x.^v(1)-v(2)).^2);
>> v_noisy = fminsearch(err_noisy,[1 1])
v_noisy =
0.3345 5.0594
>> v = fminsearch(err,[1 1])
v =
0.3333 5.0000
Last comment, in cases where you have constraints on the values of a
and b
it is sometimes useful to perform some change of variable. For example if you know that a>0
, you might want to identify log(a)
and then convert the identified value to a
.
Hope this helps.
A.
immoptibox is a free toolbox for optimization and data fitting. Taking the same sample function as @Adrien y = x^a + b
, a
and b
are determined using marquardt
least square fit from immoptibox.
Two files are required in order to solve the task. sofit returns the residual r
as well as the Jacobian j
.
function [r, j] = sofit(x, fitData)
t = fitData(:,1);
y = fitData(:,2);
r = y - (t.^x(1) + x(2));
j = -[t.^x(1).*log(t), ones(length(t),1)];
end
The following runner script is used to generate data points for the sample function and calls marquardt
for data fitting.
%% function template
f = @(t, p1, p2) t.^p1 + p2;
%% sample function
a = 1/3;
b = 5;
t= linspace(1,100)';
y = f(t, a, b);
%% packaging fit data for @sofit
fitData(:,1) = t;
fitData(:,2) = y;
%% marquardt
[xfit, info, perf] = marquardt(@sofit, [1, 1], [], fitData);
%% presentation
figure;
plot(y);
hold all
plot(f(t, xfit(1,end), xfit(2,end)), 'ro');
grid;
legend('sample function', 'fitted function', 'Location','East')
Generated data points (blue) versus estimated (red) in the following figure.
There are two ways to implementing Curve Fitting Without ToolBox, They are
2.USe polyfit,for creating your own fitting toolbox from scratch... with the help of this, you can fit a function to data in MATLAB,
doc polyfit.
eg,
help polyfit;
help slash;
% ...
For More Information on polyfit Refer this http://www.mathworks.com/help/techdoc/ref/polyfit.html