Problem when passing numerical solution of an equation as model function to lsqcurvefit

1 visualización (últimos 30 días)
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

Respuestas (1)

Alan Weiss
Alan Weiss el 24 de Nov. de 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 comentarios
Eugenio Luigi Cinquanta
Eugenio Luigi Cinquanta el 24 de Nov. de 2020
Thank you Alan,
in this way it works, thank you very much.
The poin is that I have to solve numerically eq(i) becasue it has no analytical solution. Do you have any suggestion about this? It is very slow indeed, but I do not know ho to improve my code.
Thanks again,
Eugenio
Alan Weiss
Alan Weiss el 25 de Nov. de 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

Iniciar sesión para comentar.

Categorías

Más información sobre Solver Outputs and Iterative Display en Help Center y File Exchange.

Productos

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by