1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

MATLAB Root-Finding Function

  1. Sep 20, 2011 #1
    1. The problem statement, all variables and given/known data
    Create and test a MATLAB function called bisection that implements the bisection root finding method. You will have to use a function handle and exit flag coding.


    2. Relevant equations
    -


    3. The attempt at a solution

    Code (Text):
    % bisection.m

    function [root, err, iter, exitFlag] = bisection (fun, lb, ub, errMax, iterMax)

    % This function performs the bisection algorithm on a function to
    % locate a root of the function (location where it crosses zero). The
    % function must be of a single variable and must return a scalar result
    % (i.e., a scalar function of a scalar argument).
    %
    % The approximation loop is controlled by three termination criteria:
    %  - estimate of the approximation error is less than errTol
    %  - number of iterations is greater than iterMax
    %  - function value magnitude is less than funTol
    %
    % The initial bracket controls the search. The initial bracket must be
    % defined such that the sign of the function is opposite at each end of the
    % bracket (to ensure a zero crossing exists between the two. THERE IS NO
    % ERROR CHECKING for this in the current code.
    %
    % Inputs:  @fun = function that is the subject of the root-finding
    %          lb = lower bound of the bisection search bracket
    %          ub = upper bound of the bisection search bracket
    %          errMax = maximum acceptable relative approximation error
    %          iterMax = maximum number of iterations
    %
    % Outputs: root = approximation of root location
    %          err = relative approximation error of solution
    %          iter = number of iterations taken to find the solution
    %          exitFlag = indicates termination status of function
    %
    % Exit Flag Encoding: 1: Alrogithm terminated normally (due to error being
    %                        sufficiently small)
    %                     0: Alrogithm terminated due to maximum number of
    %                        iterations being reached
    %                    -1: Algorithm terminated due to invalid bracket
    %                        specification (no root in bracket)
    %                    -2: Algorithm terminated due to invalid return value
    %                        from function fun (e.g., NaN, Inf, empty brakets)

    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % GENERAL INITIALIZATION %
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    iter = 0;       % iteration counter variable
    done = false;   % Boolean variable to control looping
    root = (ub+lb)/2; % initial approximation of root location
    err = 100*abs([ub-lb]/[ub+lb]); % estimate of error

    if fun(lb)*fun(ub)>0
        exitFlag = -1;
        error('invalid bracket: exitFlag = %g\n',exitFlag);

    elseif fun(root)+errMax>0 && fun(root)-errMax<0;
        exitFlag = 1;
        err = 100*abs([ub-lb]/[ub+lb]); % estimate of error
        done=true;
           
    elseif fun(lb)+errMax>0 && fun(lb)-errMax<0;
        exitFlag = 1;
        err = 100*abs([ub-lb]/[ub+lb]); % estimate of error
        root=lb;
        done=true;
           
    elseif fun(ub)+errMax>0 && fun(ub)-errMax<0;
        exitFlag = 1;
        err = 100*abs([ub-lb]/[ub+lb]); % estimate of error
        root=ub;
        done=true;

    elseif fun(lb)==NaN || Inf || -Inf || isempty(lb);
        exitFlag = -2;
        error('invalid lower bound: exitFlag = %g\n',exitFlag);
        done = true;

    elseif fun(ub)==NaN || Inf || -Inf || isempty(ub);
        exitFlag = -2;
        error('invalid upper bound: exitFlag = %g\n',exitFlag);
        done = true;

    else
        return;
         
    end

    %%%%%%%%%%%%%%%%%%%%%%
    % MAIN ITERATION LOOP
    %%%
    while ~done
       
        iter = iter+1;      % increment iteration counter
       
            % determine which way to go with next bracket
        if fun(lb)*fun(root)<0
            ub = root;
        else
            lb = root;
        end
       
        % update approximation of root location based on new bracket
        root = (ub+lb)/2;    
       
        err = 100*abs([ub-lb]/[ub+lb]); % estimate of error
           
        % loop control -- check for termination criteria
        if err<errMax
            exitFlag = 1;
            done = true;
        elseif iter >= iterMax
            exitFlag = 0;
                   
            % if the next line executes, it means at least one of the
            % termination criteria was true
            done = true;    
        end

    end
    Example of function call:
    Code (Text):
    [root, err, iter, exitFlag] = bisection (@(x)x^3-3*x,-4,2,.0001, 1000)

    My problem with the code is that the error flag -2 keeps popping up when I am trying to find a root
     
  2. jcsd
  3. Sep 20, 2011 #2

    Office_Shredder

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Two things: first, Doing fun(lb)==NaN doesn't work. Try it out, NaN==NaN returns 0, not 1. There's a function isnan that you should use instead,
    isnan(fun(lb))

    Second, you have a serious parenthesis problem. fun(lb)==NaN || Inf doesn't do (fun(lb)==NaN)||(fun(lb)==Inf), it does (fun(lb)==NaN) || Inf and Inf counts as true so your program always takes that part of the if statement and runs it
     
  4. Sep 20, 2011 #3
    Ok, thanks that helps. Between you and a TA I got it to work so thank you!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook