I made a function (bisection) that calculates the zero of a function (like fzero) using the bisection method, however when I run the function I get the following warning: "Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments."
No idea how to solve this.
bisection function
function[x, output, graf] = bisection(f, x0, TOL, NMAX)
graf = "no";
if(nargin > 1)
if (~exist('TOL','var') || TOL == '~')
TOL = eps;
end
if (~exist('NMAX','var') || NMAX == '~')
NMAX = 500;
end
else
error('Too few input arguments');
end
if isa(f, 'function_handle')
% f is a function
else
error('f is not a function!');
end
if isvector(x0)
disp(size(x0));
if (size(x0) > 2)
error('x0 has too many elements!');
else
if(size(x0) < 2)
error('x0 has too few elements!');
end
end
if ~isnumeric(x0(1)) || ~isnumeric(x0(2))
error('Elements of x0 must be numeric!');
end
if x0(1)>x0(2)
error('x0(1) is > than x0(2)');
end
else
error('x0 is not a vector!');
end
if f(x0(1))*f(x0(2)) > 0
error('There are no zeros!');
end
if ~isnumeric(NMAX)
error('NMAX must be a number');
else
if floor(NMAX) ~= NMAX
error('NMAX must be integer');
end
end
if ~isnumeric(TOL)
error('TOL must be numeric!');
end
x0 = [x0(1), x0(2)];
[x, output] = do_bisection(f,x0,TOL,NMAX);
output = [ output(1), NMAX - output(2) ];
if("yes" == "yes")
fplot(f,[x0(1)*2, x0(2)*2]);
title(strcat('Grafico f = ',func2str(f)));
xlabel('x');
ylabel('y = f(x)');
grid on;
grid minor;
set(gca,'xaxislocation','origin');
set(gca,'yaxislocation','origin');
hold on;
fplot(@(x) 0,[x0(1), x0(2)],'r -');
plot(x,f(x),'k s');
text(x0(1), 0.5, strcat('a=',num2str(x0(1))));
text(x0(2), 0.5, strcat('b=',num2str(x0(2))));
text(x, -0.5, strcat('x=',num2str(x)));
graf = "yes";
end
end
do_bisection
function[x, output] = do_bisection(f, x0, TOL, NMAX)
a = x0(1);
b = x0(2);
if f(a)*f(b)>0
error('non ci sono zeri');
end
iter = 0;
c = (a+b)/2;
while(iter<NMAX && (((abs(x0(2)-x0(1))/max(abs(x0(1)),abs(x0(2))))>TOL) && (abs(f(c)) > eps)))
if(f(c)*f(a) < 0)
b = c;
else
a = c;
end
c = (a +b)/2;
iter = iter +1;
end
x = c;
output = [ f(c), iter ];
end
I call the function
f = @(x) x^2 - 5;
x0 = [1, 3];
[x, out, graf] = bisection(f,x0,10.^(-5),500);
