(

The solutions for this case of root-finding are typified by the use of
Newton's
method or the bisection method. However, in MATLAB, your first line of
attack for robust root-finding should use the built-in function
` fzero`. The on-line information is fairly extensive and
the focus here is on outlining a simple method for using

[Back to main page] [Back to numerics page]

To use ** fzero**, you need to know how to write
functions in MATLAB.

As an illustration, consider the following problem:

Find the root(s) of
*f*(*x*) = *ae*^{-bx} - *cx* = 0
where, for example, *a* = 1, *b* = 2 and *c* = 3.

We'll go
thru the basic use of ** fzero**
and then add on some refinements. Finally,
the use of anonymous functions will be
reviewed to bring your use of

**Write a MATLAB function that evaluates the function whose root(s) you seek.**Your function should have a*single input*and a*single output*. Be sure to include all parameters needed for proper evaluation of the expression*within*the MATLAB function.For the example problem, the Mfile would be

**function y = rootex(x) %ROOTEX Example function for root-finding % Parameters a = 1; b = 2; c = 3; % Evaluate function: y = f(x). If x is a % root, y will be 0. y = a*exp(-b*x) - c*x;**(To get the most of of this procedure, you should start up MATLAB and create the function Mfile just given. If you open a new editor window, you can copy and paste from your browser into MATLAB to save some typing.)

**Hint:**If it is at all possible, make sure your function returns a variable () that is the same size as the input (`y`). While`x`does not require this, the next step will be much easier if you do so.`fzero`

**Establish a reasonable range of**If you are seeking multiple roots, you need to run*x*-values that you think should contain the root.separately for each root. Be sure to restrict the search range so that only one root can be found (this may not be a trivial exercise!).`fzero`The better the estimate of the interval that contains the root, the fewer problems you will have with

finding an answer.`fzero`For the example problem, the interval that contains the root will depend on the parameters (

*a*,*b*and*c*). One way to make a reasonable estimate of the interval is to plot the function and look for places that the curve passes through zero. If your MATLAB function was written to return an vector when provided with a vector, use this feature to your advantage. For example,**x = linspace(0,1); % intial guess for the interval y = rootex(x); % f(x) in the interval plot(x,y), grid % see how we did**(If you are running MATLAB, copy and paste the lines just given into the command window to see the plot). The guess was "lucky" and indeed the function changes sign in the interval. If the guess was not so fortuitous, I would have changed the interval and tried again.

**Use**:with the following syntax`fzero`**r = fzero(fname,[lo hi])**where

is a string containing the name of the`fname`*function*Mfile (without the`.m`extension) andand`lo`define the interval which contains the root (which you should have determined in Step 2).`hi`Note that the first argument (

) must be a string variable . There are two ways to ensure that this is so. For the example problem,`fname`Version 1: Use a variable.

**fname = 'rootex' % the function Mfile name r = fzero(fname,[0 1])**Version 2: Enter the name directly.

**r = fzero('rootex',[0 1])**In the first version, a variable called

was assigned the string`fname`while in the second,`'rootex'`was used directly as an input. See also the use of function handles, presented below.`'rootex'`When I ran this example (using either version), the root I found was 0.2163... .

**Controlling accuracy**

There is an optional third input you can supply to ** fzero**
to set the accuracy of the final result. For instance, using the example
problem from above,

overrides the default accuracy (1e-6) and tries to get the root accurate to 10 significant figures (roughly). More recent versions of MATLAB let you use the struct created byr = fzero('rootex',[0 1],1e-10)

**Changing parameters**

Very often, the function you are seeking the roots of comes from a physical problem and so there may be many parameters that change when the basis of the problem changes. For example:

- You might be looking for the bubble point of a mixture and have to
find the temperature at which a specific mixture reaches a specified
total pressure. The "
*x*" variable is the temperature in this case and the compostions and total pressure would be the parameters.

- You might be calculating the specific volume of a gas for a given
temperature and pressure using a cubic equation of state. In this
instance, the specific volume is the "
*x*" variable and the temperature and the pressure (and pehaps the material constants for a particular gas) would be parameters.

- You might be trying to compute the friction factor from the Colebrook
equation (which is implicit in the friction factor). In this instance,
the "
*x*" variable is the friction factor and the Reynolds number (along with the tube roughness, perhaps) would be the parameter.

The syntax of ** fzero** allows you to pass extra input
arguments to your Mfile and hence releases you from the requirement that
your function have a single input argument.

For the example problem, the Mfile can be modified so that the parametes are in the input argument list.

function y = rootex2(x,a,b,c) %ROOTEX2 Modified example function for root-finding % The parameters are now in the input list % Evaluate function: y = f(x). If x is a % root, y will be 0. y = a*exp(-b*x) - c*x;

Then, ** fzero** can be used as

r = fzero('rootex2',[0 1],1e-10,1,2,3)

or, in a more vebose form,

a = 1; b = 2; c = 3; r = fzero('rootex2',[0 1],1e-10,1,2,3)

to reproduce the first example (root at 0.2163) and as

r = fzero('rootex2',[0 1],1e-10,3,2,1)

to examine a different set of parameters (*a* = 3, *b* = 2 and
*c* = 1, in this case which leads to a root of 0.7162).

**Note:** You **must** explicitly include the accuracy argument
when you ask ** fzero** to pass parameters to your function.

The introduction of function handles in MATLAB is a good thing and, once you get used to this new data type and its associated syntax, you find yourself with much more flexibility in the development of code. Getting used to function handles, though, can take work and a good place to see the utility of function handles is to see them in action.

To re-do the first problem on this page, we could first "capture" the
function ** rootex** in a function handle via the

f1 = @ rootex

and then send that handle to ** fzero** to find the root via

r = fzero(f1,[0 1])

Granted there is not much difference in passing the name of the file versus passing a function handle derived from the name of the file but there is more than meets the eye here. The function handle provides a complete picture of the function at the time the handle was created and gives you a way, then, of doing things with that instance of the file that you cannot do with just a string of characters. For example, you can send the handle off to anywhere and not worry about where the file is that lead to the handle, a useful feature for more complex programming settings.

The problem involving the function ** rootex2** can better
illustrate the utility of function handles. In the example, the name of the
function and the list of parameters that were meant to be active when that
function was used in

Since we are anticipating
that there are parameters to provide to ** rootex2**, let's give them
values first (and be sure to read the warning, below)

a = 1; b = 2; c = 3;

and then create the function handle via

f2 = @(x) rootex2(x,a,b,c)

*Important!* Note that we defined the "parameters" (** a**,

In his use mode, the ** @** operator creates an "anonymous function". The
key difference between the handles

I can't say that it's very easy to look at the syntax for the definition of an anonymous function and grasp what it does. However, one way to read an anonymous-function definition is

h = @(essential variable list) f(essential variable list,parameter variable list)

Variables in the *essential list* must be provided by the function that
uses the function handle while the variables in the *parameter list* will
be set once (at handle creation time) and simply provided every time the
function contained in the function handle is evaluated.

Continuing, the root of the function for the set of parameters listed above is computed via

r = fzero(f2,[0 1])

Again, the difference in syntax between using a function handle to an
anonymous function and just the Mfile name with parameters tacked on to the end
of the call to ** fzero** is not one of substance (they both work!)
but one of organization and, in more complex settings, flexibility. By using
function handles (and anonymous functions, in particular), you make a cleaner
and clearer division between the attributes of the function doing the operating
(

[Back to main page] [Back to numerics page]

Comments? Contact Jim Maneval at