lsqcurvefit with 2 points trouble
2 次查看(过去 30 天)
显示 更早的评论
Hello Matlab Community,
I need help with a little code ...
I want to do this : , obtain by this code :
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:
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 个评论
Mathieu NOE
2023-5-2
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 ?
采纳的回答
Mathieu NOE
2023-5-2
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
更多回答(1 个)
Matt J
2023-5-2
编辑:Matt J
2023-5-2
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 个评论
Matt J
2023-5-2
编辑:Matt J
2023-5-2
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
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!