Difference between revisions of "MATLAB:Fzero"

From PrattWiki
Jump to navigation Jump to search
 
Line 4: Line 4:
  
 
=== Most General Case ===
 
=== Most General Case ===
The following examples show a method that will work regardless of how many input variables your function has or how you define your function - whether it is built-in, a variable containing an anonymous function, an anonymous function generated on the fly, or a .m file function.  The example is based on wanting to determine roots of:
+
The following examples show a method that will work regardless of how many input variables your function has or how you define your function - whether it is built-in, a variable containing an anonymous function, an anonymous function generated on the fly, or a .m file function.  The paradigm is:
 +
<source lang="matlab">
 +
[ROOT, VAL_AT_ROOT] = fzero(@(DUMMY_VAR) FUNCTION_THING, INIT_STUFF, OPTIONS)
 +
</source>
 +
where
 +
*ROOT is the calculated value of the requested variable when the function is 0
 +
*VAL_AT_ROOT is the value of the function when substituting ROOT for the requested variable - nominally this is 0 but there may be roundoff issues to deal with
 +
*DUMMY_VAR is the variable you want to use in this FUNCTION_THING to indicate which of the various inputs <code>fzero</code> is allowed to alter
 +
*INIT_STUFF is either an initial guess or a valid initial bracket - note that <code>fzero</code> can ''only'' find one root at a time, so you ''cannot'' load this with several values and try to have <code>fzero</code> find multiple results (for that, you need loops)
 +
*FUNCTION_THING can be a built-in function, the name of an anonymous function, the name of a .m file function, or a calculation - whatever it is that you are trying to set equal to zero; note that DUMMY_VAR must appear somewhere in this expression for <code>fzero</code> to be able to do anything
 +
*OPTIONS are...optional - the most common is the command<source lang="matlab">optimset('Display', 'iter')</source> if you want to see the magic happen
 +
 
 +
The example is based on wanting to determine roots of:
 
<center><math>f(x, y, z)=\cos(x)+\sin(y)+z=0\,\!</math></center>
 
<center><math>f(x, y, z)=\cos(x)+\sin(y)+z=0\,\!</math></center>
We assume that two of the three variables <math>x</math>, <math>y</math>, and <math>z</math> are known and that we are looking for the third.   
+
We will assume that two of the three variables (<math>x</math> and <math>y</math>) are known and that we want to find<math>z</math> given those values.  We will further assume that <math>x=1</math> and <math>y=\pi</math>.  Finally, we will make an initial guess that <math>z=12</math>.
 +
 
 +
==== Function on the Fly ====
 +
If you only want to solve this problem once, and the calculation only requires one line of code, the process with the least "overhead" involves creating the function on the fly inside the <code>fzero</code> command.  All you have to do is put your expression in for the FUNCTION_THING, making sure the DUMMY_VAR is appropriately used.  The line:
 +
<source lang="matlab">
 +
[zValue, fValue] = fzero(@(zDummy) cos(1) + sin(pi) + zDummy, 12)
 +
</source>
 +
will produce
 +
<source lang="text">
 +
zValue =
 +
 
 +
  -5.4030e-01
 +
 
 +
 
 +
fValue =
 +
 
 +
    0
 +
</source>
 +
 
 +
A slightly "longer" version of this would have you pre-define the <math>x</math> and <math>y</math> variables first, then use the variables in the function definition:
 +
expression in for the FUNCTION_THING, making sure the DUMMY_VAR is appropriately used.  The line:
 +
<source lang="matlab">
 +
x = 1;
 +
y = pi;
 +
[zValue, fValue] = fzero(@(zDummy) cos(x) + sin(y) + zDummy, 12)
 +
</source>
 +
This works the same as the previous example - recall that when anonymous functions are created, they can take "snapshots" of the workspace.  In the case above, the FUNCTION_THING is able to "see" what the variables <code>x</code> and <code>y</code> contain.
 +
 
 +
==== Pre-Defined Functions ====
 +
If you want to solve the same problem multiple times, perhaps by altering initial guesses or altering one or more of the constant parameters in the function, you should first define the function.  If the expression can be calculated all on one line, you may choose to use a variable with an anonymous function - for example:
 +
<source lang="matlab">
 +
MyFun = @(xa, ya, za) cos(xa) + sin(ya) + za
 +
</source>
 +
 
 +
On the other hand, if the expression is more complicated or if you just want to put it in a .m file, you can certainly do that as well.  or example, instead of the <code>MyFun</code> variable above, you could write a <code>MyFun.m</code> file containing:
 +
<source lang="matlab">
 +
function out = MyFun(xb, yb, zb)
 +
out = cos(xb) + sin(yb) + zb;
 +
</source>
 +
 
 +
In either case, you would use <code>fzero</code> by properly building the FUNCTION_THING using the name of the function.  As in the previous example, you can hard-code the values for the <math>x</math> and <math>y</math> values:
 +
<source lang="matlab">
 +
[zValue, fValue] = fzero(@(zDummy) MyFun(1, pi, zDummy), 12)
 +
</source>
 +
or you can use variables to transmit the information:
 +
<source lang="matlab">
 +
x = 1;
 +
y = pi;
 +
[zValue, fValue] = fzero(@(zDummy) MyFun(x, y, zDummy), 12)
 +
</source>
 +
In any event, note again that the FUNCTION_THING only has one unknown, and that unknown is named as the DUMMY_VAR.
 +
 
 +
=== Single-Variable Anonymous Functions ===
 +
For single-variable anonymous functions, there is a slightly simpler way to run <code>fzero</code> - all you need to do is give the name of the variable to FUNCTION_THING rather than setting up the DUMMY_VARFor example, to find the solution to <math>x^2-\cos(x)=0</math> with an initial guess of <math>x=1</math>, you can set up an anonymous function for it as:
 +
<source lang="matlab">
 +
MyAnonCalc = @(x) x.^2-cos(x)
 +
</source>
 +
and then solve with:
 +
<source lang="matlab">
 +
[xValue, fValue] = fzero(MyAnonCalc, 1)
 +
</source>
 +
to get
 +
<source lang="text">
 +
xValue =
 +
 
 +
  8.2413e-01
 +
 
 +
 
 +
fValue =
 +
 
 +
  -1.1102e-16
 +
</source>
  
 
=== Single-Variable Built-in Functions and .m Functions ===
 
=== Single-Variable Built-in Functions and .m Functions ===
 
The following method works for both built-in single-input functions and .m file single-input functions (i.e. '''not''' variables containing anonymous functions).  The first argument is the name of the function in single quotes and the second argument is the initial guess or initial bracket for the one variable of the function.  For example, to find the solution to <math>\cos(x)=0</math> with an initial guess of <math>x=1</math>, you can type
 
The following method works for both built-in single-input functions and .m file single-input functions (i.e. '''not''' variables containing anonymous functions).  The first argument is the name of the function in single quotes and the second argument is the initial guess or initial bracket for the one variable of the function.  For example, to find the solution to <math>\cos(x)=0</math> with an initial guess of <math>x=1</math>, you can type
 
<source lang="matlab">
 
<source lang="matlab">
fzero('cos', 1)
+
[xValue, fValue] = fzero('cos', 1)
 
</source>
 
</source>
 
and get
 
and get
 
<source lang="text">
 
<source lang="text">
ans =
+
xValue =
  
 
   1.5708e+00
 
   1.5708e+00
 +
 +
 +
fValue =
 +
 +
  6.1232e-17
 
</source>
 
</source>
  
 
To find the solution for <math>x</math> values between 2 and 5 radians, you could type:
 
To find the solution for <math>x</math> values between 2 and 5 radians, you could type:
 
<source lang="matlab">
 
<source lang="matlab">
fzero('cos', [2 5])
+
[xValue, fValue] = fzero('cos', [2 5])
 
</source>
 
</source>
 
and get
 
and get
 
<source lang="text">
 
<source lang="text">
ans =
+
xValue =
  
 
   4.7124e+00
 
   4.7124e+00
 +
 +
 +
fValue =
 +
 +
  -1.8370e-16
 
</source>
 
</source>
  
If you have a .m file function of one variable, the process is the same.  For example, to find a root of <math>y=x^2-\cos(x)</math> with an initial guess of 1, you could first create a .m file called "MyFun.m" with:
+
If you have a .m file function of one variable, the process is the same.  For example, to find a root of <math>y=x^2-\cos(x)</math> with an initial guess of 1, you could first create a .m file called <code>MyCalc.m</code> with:
 
<source lang="matlab">
 
<source lang="matlab">
function out = MyFun(in)
+
function out = MyCalc(in)
 
out = in.^2 - cos(in);
 
out = in.^2 - cos(in);
 
</source>
 
</source>
 
then use fzero:
 
then use fzero:
 
<source lang="matlab">
 
<source lang="matlab">
fzero('MyFun', 1)
+
[xValue, fValue] = fzero('MyCalc', 1)
 
</source>
 
</source>
 
and get
 
and get
 
<source lang="text">
 
<source lang="text">
ans =
+
xValue =
  
 
   8.2413e-01
 
   8.2413e-01
</source>
 
  
=== Anonymous Functions On The Fly ===
 
  
 +
fValue =
 +
 +
  -1.1102e-16
 +
</source>
  
  

Revision as of 20:47, 10 October 2009

The fzero command in MATLAB can be used to find the value of a single parameter of a multivariable function that will set the function equal to zero (if such a value exists). The command can {\it only} find one root at a time, and can only find roots in one variable at a time. There are several different ways to present fzero with the specific function and variable.

Examples

Most General Case

The following examples show a method that will work regardless of how many input variables your function has or how you define your function - whether it is built-in, a variable containing an anonymous function, an anonymous function generated on the fly, or a .m file function. The paradigm is:

[ROOT, VAL_AT_ROOT] = fzero(@(DUMMY_VAR) FUNCTION_THING, INIT_STUFF, OPTIONS)

where

  • ROOT is the calculated value of the requested variable when the function is 0
  • VAL_AT_ROOT is the value of the function when substituting ROOT for the requested variable - nominally this is 0 but there may be roundoff issues to deal with
  • DUMMY_VAR is the variable you want to use in this FUNCTION_THING to indicate which of the various inputs fzero is allowed to alter
  • INIT_STUFF is either an initial guess or a valid initial bracket - note that fzero can only find one root at a time, so you cannot load this with several values and try to have fzero find multiple results (for that, you need loops)
  • FUNCTION_THING can be a built-in function, the name of an anonymous function, the name of a .m file function, or a calculation - whatever it is that you are trying to set equal to zero; note that DUMMY_VAR must appear somewhere in this expression for fzero to be able to do anything
  • OPTIONS are...optional - the most common is the command
    optimset('Display', 'iter')
    
    if you want to see the magic happen

The example is based on wanting to determine roots of:

\(f(x, y, z)=\cos(x)+\sin(y)+z=0\,\!\)

We will assume that two of the three variables (\(x\) and \(y\)) are known and that we want to find\(z\) given those values. We will further assume that \(x=1\) and \(y=\pi\). Finally, we will make an initial guess that \(z=12\).

Function on the Fly

If you only want to solve this problem once, and the calculation only requires one line of code, the process with the least "overhead" involves creating the function on the fly inside the fzero command. All you have to do is put your expression in for the FUNCTION_THING, making sure the DUMMY_VAR is appropriately used. The line:

[zValue, fValue] = fzero(@(zDummy) cos(1) + sin(pi) + zDummy, 12)

will produce

zValue =

  -5.4030e-01


fValue =

     0

A slightly "longer" version of this would have you pre-define the \(x\) and \(y\) variables first, then use the variables in the function definition: expression in for the FUNCTION_THING, making sure the DUMMY_VAR is appropriately used. The line:

x = 1;
y = pi;
[zValue, fValue] = fzero(@(zDummy) cos(x) + sin(y) + zDummy, 12)

This works the same as the previous example - recall that when anonymous functions are created, they can take "snapshots" of the workspace. In the case above, the FUNCTION_THING is able to "see" what the variables x and y contain.

Pre-Defined Functions

If you want to solve the same problem multiple times, perhaps by altering initial guesses or altering one or more of the constant parameters in the function, you should first define the function. If the expression can be calculated all on one line, you may choose to use a variable with an anonymous function - for example:

MyFun = @(xa, ya, za) cos(xa) + sin(ya) + za

On the other hand, if the expression is more complicated or if you just want to put it in a .m file, you can certainly do that as well. or example, instead of the MyFun variable above, you could write a MyFun.m file containing:

function out = MyFun(xb, yb, zb)
out = cos(xb) + sin(yb) + zb;

In either case, you would use fzero by properly building the FUNCTION_THING using the name of the function. As in the previous example, you can hard-code the values for the \(x\) and \(y\) values:

[zValue, fValue] = fzero(@(zDummy) MyFun(1, pi, zDummy), 12)

or you can use variables to transmit the information:

x = 1;
y = pi;
[zValue, fValue] = fzero(@(zDummy) MyFun(x, y, zDummy), 12)

In any event, note again that the FUNCTION_THING only has one unknown, and that unknown is named as the DUMMY_VAR.

Single-Variable Anonymous Functions

For single-variable anonymous functions, there is a slightly simpler way to run fzero - all you need to do is give the name of the variable to FUNCTION_THING rather than setting up the DUMMY_VAR. For example, to find the solution to \(x^2-\cos(x)=0\) with an initial guess of \(x=1\), you can set up an anonymous function for it as:

MyAnonCalc = @(x) x.^2-cos(x)

and then solve with:

[xValue, fValue] = fzero(MyAnonCalc, 1)

to get

xValue =

   8.2413e-01


fValue =

  -1.1102e-16

Single-Variable Built-in Functions and .m Functions

The following method works for both built-in single-input functions and .m file single-input functions (i.e. not variables containing anonymous functions). The first argument is the name of the function in single quotes and the second argument is the initial guess or initial bracket for the one variable of the function. For example, to find the solution to \(\cos(x)=0\) with an initial guess of \(x=1\), you can type

[xValue, fValue] = fzero('cos', 1)

and get

xValue =

   1.5708e+00


fValue =

   6.1232e-17

To find the solution for \(x\) values between 2 and 5 radians, you could type:

[xValue, fValue] = fzero('cos', [2 5])

and get

xValue =

   4.7124e+00


fValue =

  -1.8370e-16

If you have a .m file function of one variable, the process is the same. For example, to find a root of \(y=x^2-\cos(x)\) with an initial guess of 1, you could first create a .m file called MyCalc.m with:

function out = MyCalc(in)
out = in.^2 - cos(in);

then use fzero:

[xValue, fValue] = fzero('MyCalc', 1)

and get

xValue =

   8.2413e-01


fValue =

  -1.1102e-16


Questions

Post your questions by editing the discussion page of this article. Edit the page, then scroll to the bottom and add a question by putting in the characters *{{Q}}, followed by your question and finally your signature (with four tildes, i.e. ~~~~). Using the {{Q}} will automatically put the page in the category of pages with questions - other editors hoping to help out can then go to that category page to see where the questions are. See the page for Template:Q for details and examples.

External Links

References