Fit specific function on scatter plot Matlab

22 views (last 30 days)
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?

Accepted Answer

Walter Roberson
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.

More Answers (1)

Image Analyst
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.
% Add noise to Y.
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));
beta0 = [10, .4]; % Guess values to start with. Just make your best guess.
% 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.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!