Choosing a suitable fit for the graph
3 views (last 30 days)
Show older comments
Hi,
I'm a begginer in matlab, so maybe it's simple, but I couldn't find an answer online..
I work on scanning from fabry-perot, and I need to do fit on the plot. I'm not sure what type of fit I should use, here's the graph I have from the scan:
I found how to make a Gaussian fit for example, but this fit does not fit my graph.. Where can I see all the types of fits that exist? Or maybe I should make a fit with my own function? And if so, how do you do it?
I would appreciate help in terms of choosing the appropriate fit if you have an idea, and also help in terms of the code and how to do it.
Thank you!
0 Comments
Answers (2)
Star Strider
on 30 Apr 2024
I would choose a different function, perhaps something similar to with appropriate additional parameters. Then use findpeaks to locate the peak values (this will become ‘b(3)’ in the initial parameter estimates), and then choose the optimisation function of your choice (for example fminsearch) to fit the parameters. The initial estimate for ‘b(2)’ should always be negative, and relatively large (I chose -15 here in this illustration), with ‘b(1)’ determining the amplitude. Fit each pulse individually.
x = linspace(0, 4, 250);
pkfcn = @(b,x) b(1).*(x-b(3)).*exp(b(2)*(x-b(3))) .* (x>b(3)); % Peak Function
B1 = [1.5; -15; 1.2];
B2 = [1.5; -15; 3];
figure
plot(x, pkfcn(B1,x))
hold on
plot(x, pkfcn(B2,x))
hold off
grid
It would of course help to have your data.
.
4 Comments
Star Strider
on 30 Apr 2024
My pleasure!
The fit is not perfect, however it is reasonably close. (A better fit would be the function that describes the process that produced your data.)
Try this —
load('matlab data.mat')
whos('-file', 'matlab data.mat')
[pks,locs] = findpeaks(y, 'MinPeakProminence',0.01) % Get Peak Values & Location Indices
pkfcn = @(b,x) b(1).*(x-b(3)).*exp(b(2)*(x-b(3))) .* (x>b(3)); % Peak Function
for k = 1:numel(pks)
B0 = [pks(k)*10; -15; x(locs(k))]; % Initial Parameters Estimate
[B(:,k) fv(k)] = fminsearch(@(b)norm(pkfcn(b,x)-y), B0); % Nonlinear Regression To Fit Parameters 'B'
end
% B
figure
plot(x, y, '.', 'MarkerSize', 0.015, 'DisplayName','Data')
hold on
for k = 1:numel(pks)
plot(x, pkfcn(B(:,k), x), '-', 'LineWidth',1.75, 'DisplayName',["Peak at "+B(3,k)])
end
hold off
grid
xlabel('x')
ylabel('y')
title('Fit of: y(x) = \beta_2 \cdot(x-\beta_3) \cdot e^{\beta_2 \cdot (x-\beta_3)}')
legend('Location','best')
Parameter_Estimates = table(B(3,:).',B(1,:).',B(2,:).', 'VariableNames',{'Location','Amplitude','Exponent'})
.
S0852306
on 30 Apr 2024
You may try sum of multiple gaussian,i.e.
normalize x and y before the curve fit is perform, i.e.
x_hat = (x - mean(x)) / std(x);
y_hat = (y - mean(y)) / std(y);
, where are mean of and are standard deviation of .
this will make optimization easier to converge.
Here's the result when N is equal to 4. you might get more accurate fit when more gaussian are used.
e.g. N= 8
the following code is generate by Curve Fitter.
function [fitresult, gof] = createFit(x_hat, y_hat)
%CREATEFIT(X_HAT,Y_HAT)
% Create a fit.
%
% Data for 'untitled fit 1' fit:
% X Input: x_hat
% Y Output: y_hat
% Output:
% fitresult : a fit object representing the fit.
% gof : structure with goodness-of fit info.
%% Fit: 'untitled fit 1'.
[xData, yData] = prepareCurveData( x_hat, y_hat );
% Set up fittype and options.
ft = fittype( 'gauss4' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.Lower = [-Inf -Inf 0 -Inf -Inf 0 -Inf -Inf 0 -Inf -Inf 0];
opts.StartPoint = [7.52132714016075 -0.180555543273485 0.0773675110948242 7.50612216935737 1.08022250261202 0.0397394906485454 1.59916872787823 1.16365175905265 0.076917025245678 0.816149525496624 -0.0354931141625441 0.0690191466049118];
% If you have some prior knowledge about the data, you may guess a better
% start point.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, xData, yData );
legend( h, 'y_hat vs. x_hat', 'untitled fit 1', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'x_hat', 'Interpreter', 'none' );
ylabel( 'y_hat', 'Interpreter', 'none' );
grid on
Here's the result of FEX:
clear; clc;
data = load('DownloadData.mat');
x = data.x; y = data.y;
%%
NN.LabelAutoScaling = 'on';
NN.InputAutoScaling = 'on';
LayerStruct=[1, 10, 10, 10, 10, 1];
NN=Initialization(LayerStruct, NN);
%%
option.MaxIteration=300;
NN=OptimizationSolver(x, y, NN, option);
%%
predict = NN.Evaluate(x);
plot(x, y, 'LineWidth', 2)
hold on
plot(x, predict, 'LineWidth', 1)
legend('Data', 'Fitting')
%%
R = FittingReport(x, y, NN);
0 Comments
See Also
Categories
Find more on Get Started with Curve Fitting Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!