lsqcurvefit with 2 points trouble
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Mindy
am 2 Mai 2023
Kommentiert: Mathieu NOE
am 3 Mai 2023
Hello Matlab Community,
I need help with a little code ...
I want to do this :
, obtain by this code :
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1372479/image.png)
xdata2 = [0.9 1.5 13.8 19.8 24.1 28.2 35.2 60.3 74.6 81.3];
ydata2 = [455.2 428.6 124.1 67.3 43.2 28.1 13.1 -0.4 -1.3 -1.5];
fun = @(x,xdata2)x(1)-x(2)*xdata2(1:2).^2;
x0 = [100,-1];
x = lsqcurvefit(fun,x0,xdata2,ydata2(1:2))
times = linspace(xdata2(1),xdata2(end));
figure
hold on
plot(xdata2,ydata2,'ko')
plot(times,x(1)-x(2)*times.^2,'b--')
ylim([-10 500])
xlim([0 100])
legend('Data','Fitted curve')
title('Data and Fitted Curve')
with my own data but I obtain this :
with the following code:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1372484/image.png)
xdata2 = 2e-5:2e-5:18e-5;
ydata2 = [0.997 0.991 0.983 0.974 0.964 0.954 0.944 0.935 0.926];
fun = @(x,xdata2)x(1)-x(2)*xdata2(1:2).^2;
x0 = [100,-1];
x = lsqcurvefit(fun,x0,xdata2,ydata2(1:2))
times = linspace(xdata2(1),xdata2(end));
figure
hold on
plot(xdata2,ydata2,'ko')
plot(times,x(1)-x(2)*times.^2,'b--')
legend('Data','Fitted curve')
title('Data and Fitted Curve')
. I expect a line which passes by at least the 2 first points... Do you know why please?
Thanks in advance.
Regards,
2 Kommentare
Mathieu NOE
am 2 Mai 2023
hello
I am not sure to understandwhat shape / model you want to fit
from your function description, looks like you want to fit an inverted parabola ? in the first picture the legend speaks about an exponential fit , so what do you want ?
Akzeptierte Antwort
Mathieu NOE
am 2 Mai 2023
maybe you want a parabola , you can use polyfit to obtain the best fit :
x = 2e-5:2e-5:18e-5;
y = [0.997 0.991 0.983 0.974 0.964 0.954 0.944 0.935 0.926];
% y = a - b*x²
% Fit a polynomial p of degree "degree" to the (x,y) data:
degree = 2;
p = polyfit(x,y,degree);
% Evaluate the fitted polynomial p and plot:
f = polyval(p,x);
eqn = poly_equation(flip(p)); % polynomial equation (string)
Rsquared = my_Rsquared_coeff(y,f); % correlation coefficient
figure(3);plot(x,y,'o',x,f,'-')
legend('data',eqn)
title(['Data fit - R squared = ' num2str(Rsquared)]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Rsquared = my_Rsquared_coeff(data,data_fit)
% R2 correlation coefficient computation
% The total sum of squares
sum_of_squares = sum((data-mean(data)).^2);
% The sum of squares of residuals, also called the residual sum of squares:
sum_of_squares_of_residuals = sum((data-data_fit).^2);
% definition of the coefficient of correlation is
Rsquared = 1 - sum_of_squares_of_residuals/sum_of_squares;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function eqn = poly_equation(a_hat)
eqn = " y = "+a_hat(1);
for i = 2:(length(a_hat))
if sign(a_hat(i))>0
str = " + ";
else
str = " ";
end
if i == 2
eqn = eqn+str+a_hat(i)+"*x";
else
eqn = eqn+str+a_hat(i)+"*x^"+(i-1)+" ";
end
end
eqn = eqn+" ";
end
3 Kommentare
Weitere Antworten (1)
Matt J
am 2 Mai 2023
Bearbeitet: Matt J
am 2 Mai 2023
Change the units of your xdata to something more natural:
xdata2 = (2e-5:2e-5:18e-5)*1e5;
and then,
ydata2 = [0.997 0.991 0.983 0.974 0.964 0.954 0.944 0.935 0.926];
fun = @(x,xdata2)x(1)-x(2)*xdata2(1:2).^2;
x0 = [100,-1];
x = lsqcurvefit(fun,x0,xdata2,ydata2(1:2))
times = linspace(xdata2(1),xdata2(end));
figure
hold on
plot(xdata2,ydata2,'ko')
plot(times,x(1)-x(2)*times.^2,'b--')
legend('Data','Fitted curve')
title('Data and Fitted Curve')
2 Kommentare
Matt J
am 2 Mai 2023
Bearbeitet: Matt J
am 2 Mai 2023
You can, of course, change xdata2 back to their original units by multiplying x(2) by 1e10. Don't know why you would prefer the original units, however.
Alternatively, you can introduce a scaling coefficient in your model equation:
xdata2 = (2e-5:2e-5:18e-5);
ydata2 = [0.997 0.991 0.983 0.974 0.964 0.954 0.944 0.935 0.926];
fun = @(x,xdata2)x(1)-1e10*x(2)*xdata2.^2;
x0 = [100,-1];
x = lsqcurvefit(fun,x0,xdata2(1:2),ydata2(1:2))
times = linspace(xdata2(1),xdata2(end));
figure
hold on
plot(xdata2,ydata2,'ko', times,fun(x,times),'b--')
legend('Data','Fitted curve')
title('Data and Fitted Curve')
hold off
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!