I am confused about why my code doesn't lead to a fitting result.
Afficher commentaires plus anciens
x=[0 1 2 3 4 5 6 7 8 9 10]
xs = 0:0.01:120;
y=[0 4 9 16 25 36 49 64 81 100 121]
myfunc=@fitting;
rng('shuffle');
best_r = inf;
best_p = [-inf, -inf];
best_c = [-inf];
a=0.00001;
b=3;
d=2;
for iters = 1 : 100
p0 = a+(b-a).*rand(1,2);
c0 = a+(d-a).*rand(1,1);
ytotal0 = fitting(p0,c0,xs);
try
[p, c, r] =nlinfit(x,y,myfunc,p0,c0);
if any(p < 0), or (c < 0)
fprintf('rejected negative output on iteration %d\n', iters);
continue;
end
if any(norm(r)==best_r)
continue;
end
nr = norm(r);
if nr < best_r
fprintf('improved on iteration %d\n', iters);
best_r = nr;
best_p = p;
best_c = c;
end
catch ME
fprintf('failed iteration %d\n', iters);
end
end
c = best_c
p = best_p
%c = lsqcurvefit(myfunc,c0,x,y)
ytotal = fitting(p,c,x);
%for adding points
hold on
plot(x,y,'o', 'displayname', 'original')
hold off
xlim auto
ylim auto
legend show
%for adding points
hold on
xs = 0:0.1:150;
ytotal = fitting(p,c,xs);
plot(xs,ytotal)
hold off
R2=1-(sum((fitting(p,c,x)-y).^2)/sum((y-mean(y)).^2));
function ytotal = fitting(p,c,x)
xspan = x;
y0 = zeros(2,1);
[t,ye] = ode15s(@(x,y)eq2(x,y,p,c), xspan, y0);
%protect against failure of integration
if t(end) ~= xspan(end)
ytotal = inf(numel(xspan),1);
else
ytotal = ye(:,1)+ye(:,2)+c(1);
end
end
function dy=eq2(x,y,p,c)
%y(1)=CE,y(2)=LE
dy=zeros(2,1);
dy(1) = p(1) .* x;
dy(2) = p(2);
end
Réponse acceptée
Plus de réponses (1)
Bora Eryilmaz
le 2 Fév 2023
If you print out the exception inside the catch block, it will tell you what the error is.
catch ME
ME
fprintf('failed iteration %d\n', iters);
To start with, you are not passing the right number of arguments to the fitting() function: it would be passed two arguments from nlinfit, but your code expects three input arguments.
6 commentaires
Jinglei
le 3 Fév 2023
Bora Eryilmaz
le 3 Fév 2023
Modifié(e) : Bora Eryilmaz
le 3 Fév 2023
You function fitting() takes three input arguments, p, c, and x. However, I think nlinfit will call that function with only two arguments.
Also, please read the documentation for nlinfit: https://www.mathworks.com/help/stats/nlinfit.html. Among other things, nlinfit does not return the estimated coefficients individually; it returns them together as a vector.
Finally, using Inf as initial guesses of parameters does not sound right; initial parameters are supposed to be at reasonable, ballpark values.
Walter Roberson
le 3 Fév 2023
For the case where you are passing in fixed values (for example a table of oxygen absorption) then see http://www.mathworks.com/help/matlab/math/parameterizing-functions.html for how to construct a function handle that the function would be happy with.
The objective function you pass to nlinfit must expect exactly two parameters: the vector of proposed coefficients, and the set of X values that the proposed parameters are to be applied to. If you have a model in which you are wanting more than one model variable to be altered, then put all of the model variables into a vector. For example if you have a model in parameters c and p and you want nlinfit to alter both of those, then create
function y = fitting(cp, x)
c = cp(1);
p = cp(2);
y = appropriate expression
end
Jinglei
le 5 Fév 2023
Jinglei
le 6 Fév 2023
Catégories
En savoir plus sur Calendar dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

