5
votes

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?

3

3 Answers

9
votes

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 + bwhere aand bare 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 aand 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 aand bit 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.

3
votes

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.

sample function and fitted function using marquardt

1
votes

There are two ways to implementing Curve Fitting Without ToolBox, They are

  1. In the Case of uniformly spaced samples and then want to impmlement the curve fit using some linear combination of shifted kernels (e.g. B-splines), then the following tool will help you:

http://www.mathworks.com/matlabcentral/fileexchange/26292-regular-control-point-interpolation-matrix-with-boundary-conditions

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