# Discover Ezyfit: A free curve fitting toolbox for Matlab

F. Moisy, 19 nov 2008.

Laboratory FAST, University Paris Sud.

## Contents

The EzyFit toolbox for Matlab enables you to perform simple curve fitting of one-dimensional data using arbitrary fitting functions. It provides command-line functions and a basic graphical user interface for interactive selection of the data.

## Simple fit: exponential decay

First plot some data, say, an exponential decay

```plotsample exp nodisp
``` A predefined fit called 'exp' allows you to fit your data:

```showfit exp
```
```Equation: y(x) = a*exp(b*x)
a = 4.3408
b = -0.22743
R = 0.99697  (lin)
``` Suppose now you want to use your own variable and function names. Let's fit this data with the function f(t)=a*exp(-t/tau), and show the fit with a bold red line:

```undofit  % deletes the previous fit
showfit('f(t)=a*exp(-t/tau)','fitlinewidth',2,'fitcolor','red');
```
```Equation: f(t) = a*exp(-t/tau)
a = 4.3409
tau = 4.397
R = 0.99697  (lin)
``` Note that showfit recognizes that t is the variable, and the coefficients of the fit are named a and tau.

If you want to use the values of the coefficients a and tau into Matlab, you need to create these variables into the base workspace:

```makevarfit
a
tau
```
```a =

4.3409

tau =

4.3970

```

## Initial guesses

Now suppose you want to fit more complex data, like a distribution showing two peaks. Let's try to fit these peaks with two gaussians, each of height a, mean m and width s.

```plotsample hist2 nodisp
showfit('a_1*exp(-(x-x_1)^2/(2*s_1^2)) + a_2*exp(-(x-x_2)^2/(2*s_2^2))');
```
```
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
Current function value: 369920.454653

Equation: y(x) = a_1*exp(-(x-x_1)^2/(2*s_1^2))+a_2*exp(-(x-x_2)^2/(2*s_2^2))
a_1 = 41.052
a_2 = -2492.7
s_1 = 1269.4
s_2 = 13.262
x_1 = 1062.3
x_2 = -38.289
R = 0.32602  (lin)
``` The solver obviously get lost in our 6-dimensional space. Let's help it, by providing initial guesses

```undofit
showfit('a_1*exp(-(x-m_1)^2/(2*s_1^2)) + a_2*exp(-(x-m_2)^2/(2*s_2^2)); a_1=120; m_1=7; a_2 = 100; m_2=15', 'fitcolor','blue','fitlinewidth',2);
```
```Equation: y(x) = a_1*exp(-(x-m_1)^2/(2*s_1^2))+a_2*exp(-(x-m_2)^2/(2*s_2^2))
a_1 = 128.41
a_2 = 77.126
m_1 = 6.9929
m_2 = 14.783
s_1 = 0.42396
s_2 = 1.4307
R = 0.98977  (lin)
``` The result seems to be correct now. Note that only 4 initial guesses are given here; the two other ones, s_1 and s_2, are taken as 1 -- which is close to the expected solution.

## Fitting in linear or in log scale

Suppose you want to fit a power law in logarithmic scale:

```plotsample power nodisp
showfit power
```
```Equation: y(x) = a*x^n
a = 0.4784
n = 2.494
R = 0.99934  (log)
``` would you have obtained the same result in linear scale? No:

```swy    % this shortcut turns the Y-axis to linear scale
showfit('power','fitcolor','red');
```
```Equation: y(x) = a*x^n
a = 2.9016
n = 2.2564
R = 0.99608  (lin)
``` The value of the coefficients have changed. In the first case, LOG(Y) was fitted, whereas in the second case Y was fitted, because the Y-axis has been changed.

You may however force showfit to fit LOG(Y) or Y whatever the Y axis, by specifying 'lin' or 'log' in the first input argument:

```rmfit % this removes all the fits
showfit('power; lin','fitcolor','red');
showfit('power; log','fitcolor','blue');
```
```Equation: y(x) = a*x^n
a = 2.9016
n = 2.2564
R = 0.99608  (lin)
Equation: y(x) = a*x^n
a = 0.4784
n = 2.494
R = 0.99934  (log)
``` In the equation information, it is specified (lin) or (log) after the R coefficient.

## Using the fit structure f

You can fit your the data without displaying it:

```x=1:10;
y=[15 14.2 13.6 13.2 12.9 12.7 12.5 12.4 12.4 12.2];
f = ezfit(x,y,'beta(rho) = beta_0 + Delta * exp(-rho * mu);  beta_0 = 12');
```

f is a structure that contains all the informations about the fit:

```f
```
```f =

name: 'beta(rho)=beta_0+Delta*exp(-rho*mu)'
yvar: 'beta'
xvar: 'rho'
fitmode: 'lin'
eq: 'beta_0+Delta*exp(-rho*mu)'
r: 0.9992
param: {'Delta'  'beta_0'  'mu'}
m: [3.9949 12.1058 0.3237]
m0: [1 12 1]
x: [1 2 3 4 5 6 7 8 9 10]
y: [1x10 double]

```

From this structure, you can plot the data and the fit:

```clf
plot(x,y,'r*');
showfit(f)
```
```Equation: beta(rho) = beta_0+Delta*exp(-rho*mu)
Delta = 3.9949
beta_0 = 12.106
mu = 0.32368
R = 0.99925  (lin)
``` you can also display the result of the fit

```dispeqfit(f)
```
```Equation: beta(rho) = beta_0+Delta*exp(-rho*mu)
Delta = 3.9949
beta_0 = 12.106
mu = 0.32368
R = 0.99925  (lin)
```

or create the variables in the base workspace

```makevarfit(f)
beta_0
mu
Delta
```
```beta_0 =

12.1058

mu =

0.3237

Delta =

3.9949

```

## Weigthed fit

Suppose now we want to fit data with unequal weights, shown here as error bars of different lengths:

```x =  1:10;
y =  [1.56 1.20 1.10 0.74 0.57 0.55 0.31 0.27 0.28 0.11];
dy = [0.02 0.02 0.20 0.03 0.03 0.10 0.05 0.02 0.10 0.05];
clf, errorbar(x,y,dy,'o');
``` In order to perform a weighted fit on this data, the vectors y and dy have to be merged into a 2-by-N matrix and given as the second input argument to ezfit. Compare the results for the usual and weighted fits:

```fw = ezfit(x, [y;dy], 'exp');
showfit(fw,'fitcolor','red');
f = ezfit(x, y, 'exp');
showfit(f,'fitcolor','blue');
```
```Equation: y(x) = a*exp(b*x)
a = 2.0017
b = -0.2519
R = 0.98832  (lin)
Equation: y(x) = a*exp(b*x)
a = 2.0071
b = -0.24013
R = 0.99067  (lin)
``` The red curve (weighted fit) tends to go through the data with smaller error bars.