MATLAB: Error using fzero (line 257) Function values at interval endpoints must be finite and real.

error error257MATLAB

function y=fun(x,a,b)
y=(a*62.83*log(1+2.19/(a-x)))+(b*75.40*log(1+2.19/(b-x)))+(2.19*(75.40+62.83));
Can someone help me to correct this error, please?zerivolano.png

Best Answer

Look carefully at your objective function. I'll write it as function handle here for simplicity. Also, I was careful to use the ./ operator so the function is vectorized.
a = 147.61;
b = 155.96;
fun = @(x) (a*62.83*log(1+2.19./(a-x)))+(b*75.40*log(1+2.19./(b-x)))+(2.19*(75.40+62.83));
xrange = [149.8 155.96];
ezplot(fun,xrange)
So it looks as it the objective function has nasty singularities at or near each end of the interval.
fun(xrange)
ans =
-315474.745442145 + 29136.1867870011i Inf + 0i
Yes. It returns complex garbage at one end, and infinite at the other. The simple solution is to restrict your range.
[xsol,fval] = fzero(fun,[150,155.5])
xsol =
152.305880649054
fval =
7.73070496506989e-12
FZERO now has no problems at all.
Could you have used fsolve? Or perhaps fzero, with only one startpoint, not a bracket?
Use of fzero with a bracket around a root is a much better idea, if you can provide such a bracket. That makes the solution much more robust. In fact, it looks like if I call fzero with ony one point, it got in trouble, effectively getting lost in the complex plane. It must have wandered down in x, until it hit a region where the function returned complex results. That got it confused. The fzero algorithm really wants to find a bracket around a root. Then it immediately switches into the mode it likes to run in, that is, with a bracket.
fzero(fun,150)
ans =
148.91268292729 + 0.158520814535521i
As Madhan suggested, you could also have used fsolve, not really because it can sometimes survive complex return arguments, but here it does find a solution.
fsolve(fun,150)
Equation solved.
fsolve completed because the vector of function values is near zero
as measured by the default value of the function tolerance, and
the problem appears regular as measured by the gradient.
<stopping criteria details>
ans =
152.305880649054
At the same time, fzero is a much more robust and stable solver in general. If you have a one variable problem, I would always strongly recommend the use of fzero, WITH A BRACKET AROUND THE ROOT. Even without a bracket, fzero will probably be faster and more stable than fsolve. Today, fsolve got lucky. Fsolve is a great tool, but it really is targeted at multi-variable problems, whereas fzero is written with the explicit idea of a one-variable problem in mind. As such, it is usually the better tool when you do have only a one variable problem.