DrIbraComms
DrIbraComms

Reputation: 11

Recreate a function extracted from curve fitting

Is it possible to recreate a function using stored parameters that are extracted from curve fitting in MATLAB?

Here's an example. Say I run:

[population gof] = fit(x, y, 'smoothingspline');

For some values of x and y, we get: population(x) = piecewise polynomial computed from p

 Coefficients:
   p = coefficient structure

and

gof =
  struct with fields:

           sse: 0.0020
       rsquare: 0.9995
           dfe: 25.0754
    adjrsquare: 0.9987
          rmse: 0.0089

To view the curvefitting results, we use the plot function:

plot(population) 

Now I want to store the numbers of gof in a file (as numbers and not the object/structure gof) and then use them to plot the curve again (without having access to the orginal population and gof)

Is it possible recreate the function from the stored values in a way if I do the plot operation it can fit the original plot?

Upvotes: 0

Views: 382

Answers (1)

BillBokeey
BillBokeey

Reputation: 3485

As seen in the fit documentation :

[population,gof] = fit(x, y, 'smoothingspline');

Yields two outputs.

The second output, gof, is a structure, that contains coefficients relative to the "goodness of fit" of the fit that was made. In other words, these coefficient give you a global idea of how close the fit is from the initial values. It is impossible to reconstruct the signal from this information, as for a set of these coefficients there is an infinity of possible candidates.

The first output, population, is a cfit object.It is the object which holds the information you need. You can use this object in a variety of ways. Some of the ways MATLAB wants you to use this object would be by using:

plot(population) % To plot the fitted values

population(x) % where x can be a vector, to get the values of the fit at the query points x

What you should do, is just save the variable population, and then when you want to use the piecewise polynomial fit, load the variable back into the workspace and use it like you would after a call to fit.

Now if you want to do it the hard way, you'll need to :

  1. Extract the coefficients and the bin boundaries of the piecewise polynomial fit
  2. Save these in your file
  3. Load the numerical arrays from your file when you need them
  4. Recreate a piecewise polynomial object from these numerical array

See below :

% Set of point to fit
x = linspace(0,1,100).';
y = sin(2*pi*x)+sin(4*pi*x)+sin(6*pi*x);
figure;plot(x,y); hold on

% fit the data and extract the bins and the coefs of the 
piecewise polynomial fit
f = fit(x,y,'smoothingspline');
breaks_extracted = f.p.breaks;
coefs_extracted = f.p.coefs;

% Save the coefficients to a file (Exercise)

% ...

% Load the coefficients when you need them (Exercise)
% For the sake of this example i'll just use the one I extracted

% Recreate a piecewise polynomial object
pp = mkpp(breaks_extracted,coefs_extracted);

% query points
xq =linspace(min(breaks_extracted(:)),max(breaks_extracted(:)),250);

plot(xq,ppval(pp,xq),'or')
title('A very lenghty way to do simple stuff')
legend({'Initial data','Fit'})

Output

If you want to output to a file in order to reconstruct the fit somewhere else than MATLAB, you can still do it:

  • The breaks_extracted variable is a 1xN vector, in which consecutive values give you the x coordinates of the intervals where the piecewise polynomial fit has been calculated.

  • The coefs_extracted variable is a (N-1)xM matrix, where M is the order of the polynomials used in each interval. If you want the value of the fit at a point xq in the k-th interval, you need to calculate:

    yq = sum(coefs_extracted(k,:).*xq.^((M-1):0));

What is left to do is to check in which interval is each of the query points

Upvotes: 2

Related Questions