Problem when passing numerical solution of an equation as model function to lsqcurvefit
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hello everyone,
I'm trying to fit my data with a model function. One part of my model function is a numerical solution of a nonlinear equation that has no analytical solution. When I try to fit the data with lsqcurvefit, I obtain the folloqing error:
"
Error using lsqcurvefit (line 259)
LSQCURVEFIT requires all values returned by functions to be of data type double.
Error in TRPL_PG_shift (line 74)
[out,resnorm,residual,exitflag,output,lambda,J]=lsqcurvefit(prova,x0, T,en,lb,ub,options);
"
Here is the relevant part my code. I just checked the T, en and mpg(x0,T) have the same size.
x0=[2.104 5.97 83.6E-3 3.53E5 -61.8E-3 12.3E-3];
lb=[2.101 5.93 83.3E-3 3.51E5 -62.0E-3 12.0e-3];
ub=[2.108 5.99 83.9E-3 3.55E5 -61.6E-3 12.8e-3];
fun0=double(mpg(x0,T));
options=optimoptions(@lsqcurvefit,'TolX', 1e-7, 'TolFun', 1e-7,'MaxFunctionEvaluations',200000, 'MaxIterations', 200000,'PlotFcn','optimplotfval','display','iter');
[out,resnorm,residual,exitflag,output,lambda,J]=lsqcurvefit(@(pars,T)mpg(pars,T),x0, T,en,lb,ub,options);
%%%%%MODEL FUNCTION%%%%%
function out = mpg(pars,t)
kb=8.617e-5;
k(1) = pars(1);
k(2) = pars(2);
k(3) = pars(3);
k(4) = pars(4);
k(5) = pars(5);
k(6) = pars(6);
function output = sol(~,t)
x = sym('x');
kb=8.617e-5;
for i=1:length(t)
eq(i)=x.*exp(x)-k(4).*((k(5)./(kb.*t(i))).^2-x).*exp(k(6)./(kb.*t(i)));
sol_x(i)=vpasolve(eq(i),x);
end
output=sol_x;
end
out=k(1)-k(2).*k(3).*(coth(k(3)./(2.*kb.*t))-1)-kb.*t.*sol(pars,t);
end
Thank you very much for your kind help,
Eugenio
0 commentaires
Réponses (1)
Alan Weiss
le 24 Nov 2020
You did not specify T or en so I cannot try to reproduce your results. But clearly, the error is due to a data type mismatch between your internal symbolic variables and the required doubles. I expect that creating symbolic variables inside your objective function is slow. I would rewrite the function not to use any symbolic variables.
That said, the easiest fix is probably to change your objective function to return double values. I mean, change the last line of your function out = mpg(pars,t) to:
out = double(k(1)-k(2).*k(3).*(coth(k(3)./(2.*kb.*t))-1)-kb.*t.*sol(pars,t));
Alan Weiss
MATLAB mathematical toolbox documentation
2 commentaires
Alan Weiss
le 25 Nov 2020
I suggest that you NOT solve it symbolically. Instead, solve it numerically using fsolve. I am not sure, but it might be best to start fsolve from the previous solution. See Follow Equation Solution as a Parameter Changes.
Alan Weiss
MATLAB mathematical toolbox documentation
Voir également
Catégories
En savoir plus sur Solver Outputs and Iterative Display dans Help Center et File Exchange
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!