Personal fit using lsq
1 view (last 30 days)
Show older comments
Hi every one. I have a couple of data "t,y" file
i need to fit them by using this function
where a,b,c are parameters that I must get by the fit.
I wrote:
A=load('D:/datifit.txt')
t=A(:,1);
y=A(:,2);
plot(t,y,'ro');
title('Data');
to plot the data and I get the plot...later, to fit, I wrote:
F=@(x,xdata)(xdata/15+0.964)*(xdata/15+0.964)*x(1)+2*(xdata/15+0.964)*(xdata*xdata/15-0.36*xdata)*x(2)+(xdata*xdata/15-0.36*xdata)*(xdata*xdata/15-0.36*xdata)*x(3)
x0=[1 1 1];
[x,resnorm,~,exitflag,output] = lsqcurvefit(F,x0,t,y)
but I get this error
Error using *
Inner matrix dimensions must agree.
Error in
@(x,xdata)(xdata/15+0.964)*(xdata/15+0.964)*x(1)+2*(xdata/15+0.964)*(xdata*xdata/15-0.36*xdata)*x(2)+(xdata*xdata/15-0.36*xdata)*(xdata*xdata/15-0.36*xdata)*x(3)
Error in lsqcurvefit (line 202)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});
Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT cannot continue.
Can someone help me please?
1 Comment
Image Analyst
on 9 Jun 2018
Here I was getting all ready to help you and then I found out you forgot to attach 'D:/datifit.txt'. I'll check back later in the day. http://www.mathworks.com/matlabcentral/answers/6200-tutorial-how-to-ask-a-question-on-answers-and-get-a-fast-answer
Answers (3)
Image Analyst
on 9 Jun 2018
Edited: Image Analyst
on 9 Jun 2018
Since you didn't supply your actual data, I just made up some. Here is my program for you:
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 short g;
format compact;
fontSize = 25;
% Define function that the X values obey.
X = sort(rand(1, 50));
a = 10 % Arbitrary sample values I picked.
b = 1
c = 1
% Get a vector. No noise in this Y yet.
Y = (X/15+0.964)*a + 2*(X/15+0.964).*(X.^2/15-0.36*X)*b+(X.^2/15-0.36).^2*c;
plot(X, Y, 'bd-');
grid on;
% Add noise to Y.
Y = Y + 0.001 * 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 = (X/15+0.964)*a + 2*(X/15+0.964).*(X.^2/15-0.36*X)*b+(X.^2/15-0.36).^2*c
% 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) (x(:, 1)/15+0.964)*b(1) + 2*(x(:, 1)/15+0.964).*(x(:, 1).^2/15-0.36*x(:, 1))*b(2)+(x(:, 1).^2/15-0.36).^2*b(3);
beta0 = [10, .8, 1.2]; % 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:
a = coefficients(1)
b = coefficients(2)
c = coefficients(3)
yFitted = (X/15+0.964)*a + 2*(X/15+0.964).*(X.^2/15-0.36*X)*b+(X.^2/15-0.36).^2*c;
% 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('Non-Linear Regression with fitnlm()', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
legendHandle = legend('Noisy Y', 'Fitted Y', 'Location', 'north');
legendHandle.FontSize = 25;
message = sprintf('Coefficients : \n a = %8.5f\n b = %8.5f\n c = %8.5f',...
coefficients(1), coefficients(2), coefficients(3));
text(0.1, 9.778, message, 'FontSize', 23, 'Color', 'r', 'FontWeight', 'bold', 'Interpreter', 'none');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]);
% 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')
and here is the result:
3 Comments
Image Analyst
on 9 Jun 2018
Stephan, do you like it enough to "Accept this Answer" and "Vote" for it?
For the others, don't be afraid that the code looks long and complicated. It's not. Most of the code is just comment lines, lines to create a sample data set, and code to make a fancy plot. The actual code that does the fit/regressions and get the coefficients is only 3 lines!
modelfun = @(b,x) (x(:, 1)/15+0.964)*b(1) + 2*(x(:, 1)/15+0.964).*(x(:, 1).^2/15-0.36*x(:, 1))*b(2)+(x(:, 1).^2/15-0.36).^2*b(3);
beta0 = [10, .8, 1.2];
mdl = fitnlm(tbl, modelfun, beta0);
Stephan
on 9 Jun 2018
Edited: Stephan
on 9 Jun 2018
Hi,
try this:
F = @(x,xdata)x(1).*(xdata.*(1.0./1.5e1)+2.41e2./2.5e2).^2+x(3).*(xdata.*(9.0./2.5e1)-xdata.^2.*(1.0./1.5e1)).^2-x(2).*(xdata.*(2.0./1.5e1)+2.41e2./1.25e2).*(xdata.*(9.0./2.5e1)-xdata.^2.*(1.0./1.5e1))
do not worry - matlab symbolic toolbox has reshaped your equation slightly. But this should work.
Best regards
Stephan
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!