# Fit specific function on scatter plot Matlab

22 views (last 30 days)
Rogier Busscher on 1 Jun 2017
Answered: Walter Roberson on 1 Jun 2017
So i have a scatterplot scatter(x,y) and I would like to find a best fit for a function of the type F(x)=e^(-(Bèta)*x) with x matching x and F(x) matching/approximating the corresponding y.
I would like to find the best fit and get the value of Bèta returned.
How do i do this?

Walter Roberson on 1 Jun 2017
If y = exp(-beta*x) then log(y) = -beta*x and beta = -log(y)/x . Your best fit in log space would then be approximately
beta = mean( -log(y) ./ x )
In linear space,
beta = lsqcurvefit(@(beta,x) exp(-beta*x), 3, x, y);
However, when I constructed artificial data by defining beta and using
c = 1;
y = exp(-beta*x + randn(size(x)) * c );
and then fit against that to recover beta, then I found that a closer beta to the one I defined could be calculated as
other_beta = lsqcurvefit(@(beta,x) beta*x, 3, x, -log(y));
As c gets reduced to (say) 1/10 then the two fittings become more similar.
With a noise model like
c = 1/15;
y = exp(-beta*x) + (2 * rand(size(x)) - 1) * c;
then the original beta version becomes a notably better fit. So which one to use would probably depend upon the model of noise / error that you have.

Image Analyst on 1 Jun 2017
Use fitnlm() in the Statistics and Machine Learning Toolbox. Here is a demo:
% Uses fitnlm() to fit a non-linear model (an exponential decay curve) through noisy data.
% Requires the Statistics and Machine Learning Toolbox, which is where fitnlm() is contained.
% Initialization steps.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Create the X coordinates from 0 to 20 every 0.5 units.
X = 0 : 0.5 : 20;
% Define function that the X values obey.
a = 0 % Arbitrary sample values I picked.
b = 0.4
Y = a + exp(-X * b); % Get a vector. No noise in this Y yet.
Y = Y + 0.05 * randn(1, length(Y));
% Now we have noisy training data that we can send to fitnlm().
% Plot the noisy initial data.
plot(X, Y, 'b*', 'LineWidth', 2, 'MarkerSize', 15);
grid on;
% Convert X and Y into a table, which is the form fitnlm() likes the input data to be in.
tbl = table(X', Y');
% Define the model as Y = a + exp(-b*x)
% Note how this "x" of modelfun is related to big X and big Y.
% x((:, 1) is actually X and x(:, 2) is actually Y - the first and second columns of the table.
modelfun = @(b,x) b(1) + exp(-b(2)*x(:, 1));
% Now the next line is where the actual model computation is done.
mdl = fitnlm(tbl, modelfun, beta0);
% Now the model creation is done and the coefficients have been determined.
% YAY!!!!
% Extract the coefficient values from the the model object.
% The actual coefficients are in the "Estimate" column of the "Coefficients" table that's part of the mode.
coefficients = mdl.Coefficients{:, 'Estimate'}
% Create smoothed/regressed data using the model:
yFitted = coefficients(1) + exp(-coefficients(2)*X);
% Now we're done and we can plot the smooth model as a red line going through the noisy blue markers.
hold on;
plot(X, yFitted, 'r-', 'LineWidth', 2);
grid on;
title('Exponential Regression with fitnlm()', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
legendHandle = legend('Noisy Y', 'Fitted Y', 'Location', 'north');
legendHandle.FontSize = 25;
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off') 