function xr = incresearch ( func , xmin , xmax , ns )
% Derives number of dimensions ( variables ) of given function then
% Finds brackets of x that contain sign changes value of
% function on an interval (in this interval if the function
% would be continiues we have a root) then finds roots of function with using
% sectioning method in the interval [ xmin , xmax ]. It is a one dimensional root finder
% that finds all the roots.
%
% Clarification: It is not realy a root finder. It shows you the intervals
% that the function has roots. Then the user can use any fast root finder
% in that intervals.
%
% xr = incresearch ( func , xmin , xmax , ns , es , maxit )
%
% arguments: ( input )
% func - ( class - inline , symbolic or char ) - a function of one
% variable
%
% xmin - scalar ( double ) - defines the lower guesses of the root
%
% xmax - scalar ( double ) - defines the upper guesses of the root
%
% ns - scalar ( double ) - ( optional ) number of sections or number of
% subintervals along x axis used to search for brackets
%
% arguments: ( returned )
% xr - matrix of intervals
%
% Example:
% f1 = inline ( 'sqrt(9.81.*80./cd).*tanh(sqrt(9.81.*cd./80).*4)-36','cd');
% A = incresearch( f1 ,0.1,0.2,100)
% A =
% 0.1400 0.1410
%
% See also fzero.
%
% Copyright 2008
%
% Requirement: symbolic math toolbox
% check for simple errors
% if necessary, assign default values
if nargin > 4
error 'less than 5 arguments must be provided'
end % End of if loop
if ( nargin < 4 ) || isempty( ns ) %if ns blank set to 50
ns = 100 ;
end % End of if loop
if ( length ( xmin ) ~= 1 ) || ( ~isfloat ( xmin ) )
error 'xmin must be a scalar double variable'
elseif ( length ( xmax ) ~= 1 ) || ( ~isfloat ( xmax ) )
error 'xmax must be a scalar double variable'
elseif xmin > xmax
error 'xmax must be grater than xmin'
elseif ( length ( ns ) ~= 1 ) || ( ~isfloat ( ns ) ) || ( ns < 1 )
error 'ns must be a scalar positive integer variable'
end % End of if loop
if nargin < 3
error 'more than 2 arguments must be provided'
end % End of if loop
cl1 = class ( func ) ; % determines the class of given function
cl = char ( cl1 ) ; % converts the class of given function to charcter class
if strcmp ( cl , 'inline' ) % if the class of input function just saves the class
end % end of if loop
if strcmp ( cl , 'sym' ) % if the class of input function was symbolic converts it to class inline
func = inline ( func ) ; % converts the class of given function from symbolic to inline
end % end of if loop
if strcmp ( cl , 'char' ) % if the class of input function was char converts it to class inline
func = inline ( func ) ; % converts the class of given function from char to inline
end % end of if loop
% Incremental search
x = linspace ( xmin , xmax , ns+1 ) ; % Devide the interval into ns section
f = func ( x ) ; % Evaluates the value of function in the points
nb = 0 ;
for k = 1 : length ( x ) - 1 % k is the numerator of for loop
if sign ( f ( k ) ) ~= sign ( f ( k + 1 ) ) % Checks for sign change
nb = nb + 1 ;
xr ( nb , 1 ) = x ( k ) ;
xr ( nb , 2 ) = x ( k + 1 ) ;
end % End of if loop
end % End of for loop
if isempty ( xr ) % Display that no brackets were found
disp ( ' no roots found ' )
disp( ' check interval or increase ns ' )
end % End of if loop
% With special thanks to John D'Errico
% By Ali Mohammad Razeghi