Products & Services Solutions Academia Support User Community Company

Learn more about Curve Fitting Toolbox   

Curve Fitting Objects and Methods

This section describes how to use Curve Fitting Toolbox functions from the command-line or to write programs for curve fitting applications.

For surface fitting, see Programmatic Surface Fitting.

Overview

In MATLAB programming, all workspace variables are objects of a particular class. Familiar examples of MATLAB classes are double, char, and function_handle. You can also create custom MATLAB classes, using object-oriented programming.

Methods are functions that operate exclusively on objects of a particular class. Data types package together objects and methods so that the methods operate exclusively on objects of their own type, and not on objects of other types. A clearly defined encapsulation of objects and methods is the goal of object-oriented programming.

Curve Fitting Toolbox software provides you with two new MATLAB data types for performing curve fitting:

Because cfit is a subtype of fittype, cfit inherits all fittype methods. In other words, you can apply fittype methods to both fittype and cfit objects, but cfit methods are used exclusively with cfit objects.

As an example, the fittype method islinear, which determines if a model is linear or nonlinear, would apply equally well before or after a fit; that is, to both fittype and cfit objects. On the other hand, the cfit methods coeffvalues and confint, which, respectively, return fit coefficients and their confidence intervals, would make no sense if applied to a general fittype object which describes a parametric model with undetermined coefficients.

Curve Fitting Objects

Curve fitting objects have properties that depend on their type, and also on the particulars of the model or the fit that they encapsulate. For example, the following code uses the constructor methods for the two curve fitting types to create a fittype object f and a cfit object c:

f = fittype('a*x^2+b*exp(n*x)')
f =
     General model:
       f(a,b,n,x) = a*x^2+b*exp(n*x)
c = cfit(f,1,10.3,-1e2)
c =
     General model:
       c(x) = a*x^2+b*exp(n*x)
     Coefficients:
       a =           1
       b =        10.3
       n =        -100

Note that the display method for fittype objects returns only basic information, piecing together outputs from formula and indepnames.

cfit and fittype objects are evaluated at predictor values x using feval. You can call feval indirectly using the following functional syntax:

y = cfun(x) % cfit objects;
y = ffun(coef1,coef2,...,x) % fittype objects;

Curve Fitting Methods

Curve fitting methods allow you to create, access, and modify curve fitting objects. They also allow you, through methods like plot and integrate, to perform operations that uniformly process the entirety of information encapsulated in a curve fitting object.

The methods listed in the following table are available for all fittype objects, including cfit objects.

Fit Type MethodDescription

argnames

Get input argument names

category

Get fit category

coeffnames

Get coefficient names

dependnames

Get dependent variable name

feval

Evaluate model at specified predictors

fittype

Construct fittype object

formula

Get formula string

indepnames

Get independent variable name

islinear

Determine if model is linear

numargs

Get number of input arguments

numcoeffs

Get number of coefficients

probnames

Get problem-dependent parameter names

setoptions

Set model fit options

type

Get name of model

The methods listed in the following table are available exclusively for cfit objects.

Curve Fit MethodDescription

cfit

Construct cfit object

coeffvalues

Get coefficient values

confint

Get confidence intervals for fit coefficients

differentiate

Differentiate fit

integrate

Integrate fit

plot

Plot fit

predint

Get prediction intervals

probvalues

Get problem-dependent parameter values

A complete list of methods for a curve fitting object can be obtained with the MATLAB methods command. For example,

f = fittype('a*x^2+b*exp(n*x)');
methods(f)

Methods for class fittype:

argnames     dependnames  fittype     islinear     probnames
category     feval        formula     numargs      setoptions
coeffnames   fitoptions	indepnames   numcoeffs    type

Note that some of the methods listed by methods do not appear in the tables above, and do not have reference pages in the Curve Fitting Toolbox documentation. These additional methods are generally low-level operations used by Curve Fitting Tool, and not of general interest when writing curve fitting applications.

There are no global accessor methods, comparable to getfield and setfield, available for fittype objects. Access is limited to the methods listed above. This is because many of the properties of fittype objects are derived from other properties, for which you do have access. For example,

f = fittype('a*cos( b*x-c )')
f =
     General model:
       f(a,b,c,x) = a*cos( b*x-c )

formula(f)
ans =
a*cos( b*x-c )

argnames(f)
ans = 
    'a'
    'b'
    'c'
    'x'

You construct the fittype object f by giving the formula, so you do have write access to that basic property of the object. You have read access to that property through the formula method. You also have read access to the argument names of the object, through the argnames method. You don't, however, have direct write access to the argument names, which are derived from the formula. If you want to set the argument names, set the formula.

Workflow for Object-Oriented Fitting

Curve Fitting Toolbox software provides a variety of methods for data analysis and modeling. In application, these methods are applied in a systematic manner, which can be represented in a standard workflow diagram such as the one below.

A typical analysis using curve fitting methods proceeds as follows:

  1. Import your data into the MATLAB workspace using the load command (if your data has previously been stored in MATLAB variables) or any of the more specialized MATLAB functions for reading data from particular file types.

  2. If your data is noisy, you might want to smooth it using the smooth function. Smoothing is used to identify major trends in the data that can assist you in choosing an appropriate family of parametric models. If a parametric model is not evident or appropriate, smoothing can be an end in itself, providing a nonparametric fit of the data.

      Note   Smoothing estimates the center of the distribution of the response at each predictor. It invalidates the assumption that errors in the data are independent, and so also invalidates the methods used to compute confidence and prediction intervals. Accordingly, once a parametric model is identified through smoothing, the original data should be passed to the fit function.

  3. A parametric model for the data—either a Curve Fitting Toolbox library model or a custom model that you define—is specified as a fittype object using the fittype function. Library models are displayed with the cflibhelp function.

  4. A fit options structure can be created for the fit using the fitoptions function. Fit options specify things like weights for the data, fitting methods, and low-level options for the fitting algorithm.

  5. An exclusion rule can be created for the fit using the excludedata function. Exclusion rules indicate which data values will be treated as outliers and excluded from the fit.

  6. Data, a fittype object, and (optionally) a fit options structure and an exclusion rule are all passed to the fit function to perform the fit. The fit function returns a cfit object that encapsulates the computed coefficients and the fit statistics.

  7. cfit objects returned by the fit function can then be passed to a variety of postprocessing functions, such as feval, differentiate, integrate, plot, coeffvalues, probvalues, confint, and predint.

Examples

The following examples illustrate the standard workflow outlined in Workflow for Object-Oriented Fitting. Further examples of programmatic fitting can be found in the reference pages for individual curve fitting methods.

Example: Smoothing Data I

Load the data in count.dat:

load count.dat

The 24-by-3 array count contains traffic counts at three intersections for each hour of the day.

First, use a moving average filter with a 5-hour span to smooth all of the data at once (by linear index) :

c = smooth(count(:));
C1 = reshape(c,24,3);

Plot the original data and the smoothed data:

subplot(3,1,1)
plot(count,':');
hold on
plot(C1,'-');
title('Smooth C1 (All Data)')

Second, use the same filter to smooth each column of the data separately:

C2 = zeros(24,3);
for I = 1:3,
    C2(:,I) = smooth(count(:,I));
end

Again, plot the original data and the smoothed data:

subplot(3,1,2)
plot(count,':');
hold on
plot(C2,'-');
title('Smooth C2 (Each Column)')

Plot the difference between the two smoothed data sets:

subplot(3,1,3)
plot(C2 - C1,'o-')
title('Difference C2 - C1')

Note the additional end effects from the 3-column smooth.

Example: Smoothing Data II

Create noisy data with outliers:

x = 15*rand(150,1); 
y = sin(x) + 0.5*(rand(size(x))-0.5);
y(ceil(length(x)*rand(2,1))) = 3;

Smooth the data using the loess and rloess methods with a span of 10%:

yy1 = smooth(x,y,0.1,'loess');
yy2 = smooth(x,y,0.1,'rloess');

Plot original data and the smoothed data.

[xx,ind] = sort(x);
subplot(2,1,1)
plot(xx,y(ind),'b.',xx,yy1(ind),'r-')
set(gca,'YLim',[-1.5 3.5])
legend('Original Data','Smoothed Data Using ''loess''',...
       'Location','NW')
subplot(2,1,2)
plot(xx,y(ind),'b.',xx,yy2(ind),'r-')
set(gca,'YLim',[-1.5 3.5])
legend('Original Data','Smoothed Data Using ''rloess''',...
       'Location','NW')

Note that the outliers have less influence on the robust method.

Example: Excluding Data

Load the vote counts and county names for the state of Florida from the 2000 U.S. presidential election:

load flvote2k

Use the vote counts for the two major party candidates, Bush and Gore, as predictors for the vote counts for third-party candidate Buchanan, and plot the scatters:

plot(bush,buchanan,'rs')
hold on
plot(gore,buchanan,'bo')
legend('Bush data','Gore data')

Assume a model where a fixed proportion of Bush or Gore voters choose to vote for Buchanan:

f = fittype({'x'})
f =
     Linear model:
       f(a,x) = a*x

Exclude the data from absentee voters, who did not use the controversial "butterfly" ballot:

absentee = find(strcmp(counties,'Absentee Ballots'));
nobutterfly = excludedata(bush,buchanan,'indices',absentee);

Perform a bisquare weights robust fit of the model to the two data sets, excluding absentee voters:

bushfit = fit(bush,buchanan,f,...
              'Exclude',nobutterfly,'Robust','on');
gorefit = fit(gore,buchanan,f,...
              'Exclude',nobutterfly,'Robust','on');

Robust fits give outliers a low weight, so large residuals from a robust fit can be used to identify the outliers:

figure
plot(bushfit,bush,buchanan,'rs','residuals')
hold on
plot(gorefit,gore,buchanan,'bo','residuals')

The residuals in the plot above can be computed as follows:

bushres = buchanan - feval(bushfit,bush);
goreres = buchanan - feval(gorefit,gore);

Large residuals can be identified as those outside the range [-500 500]:

bushoutliers = excludedata(bush,bushres,'range',[-500 500]);
goreoutliers = excludedata(gore,goreres,'range',[-500 500]);

The outliers for the two data sets correspond to the following counties:

counties(bushoutliers)
ans = 
    'Miami-Dade'
    'Palm Beach'

counties(goreoutliers)
ans = 
    'Broward'
    'Miami-Dade'
    'Palm Beach'

Miami-Dade and Broward counties correspond to the largest predictor values. Palm Beach county, the only county in the state to use the "butterfly" ballot, corresponds to the largest residual values.

Example: Specifying Fit Options

Create the default fit options structure and set the option to center and scale the data before fitting:

options = fitoptions;
options.Normal = 'on';
options
options =
    Normalize: 'on'
    Exclude: [1x0 double]
    Weights: [1x0 double]
    Method: 'None'

Modifying the default fit options structure is useful when you want to set the Normalize, Exclude, or Weights fields, and then fit your data using the same options with different fitting methods. For example:

load census
f1 = fit(cdate,pop,'poly3',options);
f2 = fit(cdate,pop,'exp1',options);
f3 = fit(cdate,pop,'cubicsp',options);

Data-dependent fit options are returned in the third output argument of the fit function. For example:

[f,gof,out] = fit(cdate,pop,'smooth');
smoothparam = out.p
smoothparam =
    0.0089

The default smoothing parameter can be modified for a new fit:

options = fitoptions('Method','Smooth','SmoothingParam',0.0098);
[f,gof,out] = fit(cdate,pop,'smooth',options);

Example: Robust Fitting

Create a baseline sinusoidal signal:

xdata = (0:0.1:2*pi)'; 
y0 = sin(xdata);

Add noise to the signal with non-constant variance:

% Response-dependent Gaussian noise
gnoise = y0.*randn(size(y0));

% Salt-and-pepper noise
spnoise = zeros(size(y0)); 
p = randperm(length(y0));
sppoints = p(1:round(length(p)/5));
spnoise(sppoints) = 5*sign(y0(sppoints));

ydata = y0 + gnoise + spnoise;

Fit the noisy data with a baseline sinusoidal model:

f = fittype('a*sin(b*x)'); 
fit1 = fit(xdata,ydata,f,'StartPoint',[1 1]);

Identify "outliers" as points at a distance greater than 1.5 standard deviations from the baseline model, and refit the data with the outliers excluded:

fdata = feval(fit1,xdata); 
I = abs(fdata - ydata) > 1.5*std(ydata); 
outliers = excludedata(xdata,ydata,'indices',I);

fit2 = fit(xdata,ydata,f,'StartPoint',[1 1],'Exclude',outliers);

Compare the effect of excluding the outliers with the effect of giving them lower bisquare weight in a robust fit:

fit3 = fit(xdata,ydata,f,'StartPoint',[1 1],'Robust','on');

Plot the data, the outliers, and the results of the fits:

plot(fit1,'r-',xdata,ydata,'k.',outliers,'m*') 
hold on
plot(fit2,'c--')
plot(fit3,'b:')
xlim([0 2*pi])

Plot the residuals for the two fits considering outliers:

figure 
plot(fit2,xdata,ydata,'co','residuals') 
hold on
plot(fit3,xdata,ydata,'bx','residuals')

Example: Differentiating and Integrating a Fit

Create a baseline sinusoidal signal:

xdata = (0:.1:2*pi)';
y0 = sin(xdata);

Add noise to the signal:

noise = 2*y0.*randn(size(y0)); % Response-dependent noise
ydata = y0 + noise;

Fit the noisy data with a custom sinusoidal model:

f = fittype('a*sin(b*x)');
fit1 = fit(xdata,ydata,f,'StartPoint',[1 1]);

Find the derivatives of the fit at the predictors:

[d1,d2] = differentiate(fit1,xdata);

Plot the data, the fit, and the derivatives:

subplot(3,1,1)
plot(fit1,xdata,ydata) % cfit plot method
subplot(3,1,2)
plot(xdata,d1,'m') % double plot method
grid on
legend('1st derivative')
subplot(3,1,3)
plot(xdata,d2,'c') % double plot method
grid on
legend('2nd derivative')

Note that derivatives can also be computed and plotted directly with the cfit plot method, as follows:

plot(fit1,xdata,ydata,{'fit','deriv1','deriv2'})

The plot method, however, does not return data on the derivatives.

Find the integral of the fit at the predictors:

int = integrate(fit1,xdata,0);

Plot the data, the fit, and the integral:

subplot(2,1,1)
plot(fit1,xdata,ydata) % cfit plot method
subplot(2,1,2)
plot(xdata,int,'m') % double plot method
grid on
legend('integral')

Note that integrals can also be computed and plotted directly with the cfit plot method, as follows:

plot(fit1,xdata,ydata,{'fit','integral'})

The plot method, however, does not return data on the integral.

Example: Prediction Intervals

Generate data with an exponential trend:

x = (0:0.2:5)';
y = 2*exp(-0.2*x) + 0.5*randn(size(x));

Fit the data using a single-term exponential:

fitresult = fit(x,y,'exp1');

Compute prediction intervals:

p11 = predint(fitresult,x,0.95,'observation','off');
p12 = predint(fitresult,x,0.95,'observation','on');
p21 = predint(fitresult,x,0.95,'functional','off');
p22 = predint(fitresult,x,0.95,'functional','on');

Plot the data, fit, and prediction intervals:

subplot(2,2,1)
plot(fitresult,x,y), hold on, plot(x,p11,'m--'), xlim([0 5])
title('Nonsimultaneous observation bounds','Color','m')
subplot(2,2,2)
plot(fitresult,x,y), hold on, plot(x,p12,'m--'), xlim([0 5])
title('Simultaneous observation bounds','Color','m')
subplot(2,2,3)
plot(fitresult,x,y), hold on, plot(x,p21,'m--'), xlim([0 5])
title('Nonsimultaneous functional bounds','Color','m')
subplot(2,2,4)
plot(fitresult,x,y), hold on, plot(x,p22,'m--'), xlim([0 5])
title('Simultaneous functional bounds','Color','m')

  


Recommended Products

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.

 © 1984-2009- The MathWorks, Inc.    -   Site Help   -   Patents   -   Trademarks   -   Privacy Policy   -   Preventing Piracy   -   RSS