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

조회 수: 2 (최근 30일)
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

답변 (1개)

Alan Weiss
Alan Weiss 2020년 11월 24일
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
Eugenio Luigi Cinquanta
Eugenio Luigi Cinquanta 2020년 11월 24일
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 2020년 11월 25일
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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Solver Outputs and Iterative Display에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by