M05 - Programming in Matlab - XXXX - CH05

Download as pdf or txt
Download as pdf or txt
You are on page 1of 38

5

Scripts
and Functions

After studying this chapter, you should be able to:


 write scripts and functions in MATLAB  represent and use polynomials
 understand the scope of variables
inside a function

5.1 Introduction
MATLAB is a command-line driven language that sequentially processes whatever statements
are entered at the command prompt. When working on large problems, it is convenient to save
your code in a text file. MATLAB provides the facility to write a series of MATLAB state-
ments in a file and then execute them with a single command. You can write your program in an
ordinary text file, giving it a suitable name such as myfile.m. The program in myfile.m can be
executed at the command prompt as follows:

>> myfile %This would run the program in myfile.m

Files with .m extension containing MATLAB statements are known as M-files. M-files can
be scripts that execute a series of MATLAB statements or they can be functions that accept
arguments and return results. Functions in MATLAB are like functions in C, subroutines
in FORTRAN and BASIC, and procedures in PASCAL. They are building blocks of larger
programs. When a large task is broken into small functions, it becomes easier to
understand, debug, and modify the program. The topics discussed in this chapter
include: how to write scripts and functions, the scope of variables inside func-
tions, and the types of functions. Also, the chapter deals with how polynomi-
als are represented in MATLAB and what functions are provided for manipulating
polynomials.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 128 1/15/2014 3:17:07 PM


129 Ñ Making Simple Script and Function Files

5.2 Making Simple Script and Function Files


To create an M-file, click on the File menu on the MATLAB desktop, and then select New and
click on M-File. The MATLAB Editor/Debugger window pops up. Another way of opening the
editor window is to type edit and press the Enter key at the command prompt. You can now type
your code in the editor window and make any changes. When you are done with typing, click
on File in the MATLAB Editor/Debugger window and select Save As. Choose a name for your
file, for example, firstfile.m and click on Save. Make sure that your file is saved in the directory
that is in MATLAB’s search path.
You should not keep the name of your M-File same as one of the MATLAB commands. To
find out if a particular name, say firstfile.m, is not the same as any of the MATLAB commands,
type the following:
>> which firstfile
firstfile not found.

On the other hand, sum.m does not turn out to be a good option for a filename, as you can see
by typing the following:
>> which sum
sum is a built-in function.

If you use sum.m as your filename, then you will not be able to use the sum command provided
by MATLAB.
The next thing to decide is whether your M-file should be a script file or a function file.
This depends on the nature of your task and how often you would invoke that task. A script
file is merely a collection of MATLAB statements. When a script file is executed, the result is
the same as it would be if all the statements in the script file were typed directly into the com-
mand window. In other words, a script file shares the command window’s workspace. Variables
that exist in the workspace at the time of execution of the script file are visible to the script
file. Similarly, any variables created by the script file remain in the workspace after it finishes
execution. In contrast, a function file runs in its own independent workspace. In other words,
variables in the command workspace are not reflected in the function workspace.
Scripts are generally used for automating a set of statements that is to be repeated several times.
On the other hand, functions are more general and they are used for extending your library com-
mands. Let us take some examples of script files and function files to illustrate the difference.

Example 5.1
Example 5.1:
A vector A contains both positive and negative integer values. To
Writing a
“script” file (m-file)
compute the logarithm of A, it is desired to separate the nonpositive
in MATLAB elements, and the logarithm of these elements should be assigned
a value of -1. The following script, log_positive.m does this task:
log_positive.m
disp(‘Executing log_positive...’);
n = length(A);
for i = 1:n

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 129 1/15/2014 3:17:14 PM


Scripts and Functions  É 130

if A(i)<=0
B(i) = -1;
else
B(i) = log10(A(i));
% log10 computes base 10 logarithm
end
end
disp(‘Finished executing log_positive...’);

Following is an example of running the script:


>> A = [3 -1 4 0 -10 2];
% The array on which logarithm is desired
>> log_positive % Way to execute script file
Executing log_positive...
Finished executing log_positive...

Since the script shares its workspace with the command workspace, the output stored in
the vector B can be accessed at the command prompt as shown here:
>> B
B =
0.4771 -1.0000 0.6021 -1.0000 -1.0000 0.3010

Example 5.2
While writing or executing scripts some careful measures are Example 5.2:
Good
required. Execution of scripts can modify the value of variables in
programming
an unexpected manner as illustrated in Example 5.2. Suppose you practice: avoid-
want to find out the logarithm of elements with the maximum value ing ambiguity in
in A. Consider the following sequence of commands: variables
>> C = rand(1,8)
C =
0.2722 0.1988 0.0153 0.7468 0.4451 0.9318 0.4660 0.4186
>> A = [1 -1 10 0 -10 2];
>> [y,n] = max(A)
y = 4 % The maximum value
n = 3 % Index of the maximum value

These statements store the index of the largest number in A in the variable n. The next
step is to run the script log_positive.m to compute the logarithm as follows:
>> log_positive
Executing log_positive...
Finished executing log_positive...

Since B stores the output matrix, the logarithm of the maximum value can be obtained
by the following command:

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 130 1/15/2014 3:17:14 PM


131 Ñ 
  Making Simple Script and Function Files

>> B(n)
% n stores the value 3 i.e.,
% the index of maximum value
ans =
0.3010
However, the expected answer was 1 corresponding to B(3) = log10(A(3)), since A(3) = 10.
An incorrect value has resulted here because the value of n was changed from n = 3 to n
= length(A) during the execution of the script log_positive.m as shown here:
>> n
n =
6

This is because the script log_positive.m had also employed the variable n in the state-
ment n = length(A);

Time for Practice 5.1


A person invests $1000.00 in a savings account yielding 5 percent interest. Assuming that
all interest is left on deposit in the account, calculate the amount of money in the account at
the end of each year for 10 years by writing a script. Use the following formula for determining
these amounts:
FA = IA ∗ (1 + r)n
Where, FA and IA are final and initial amounts, r is rate and n is the number of years.

In order to avoid such errors, you should keep long and seldom used names for temporary vari-
ables in a script, and not commonly used variable names such as n. Another source of error
while storing the results of your computations is shown in Example 5.3.

Example 5.3
Example 5.3:
Consider the following situation where B exists in command
Good pro-
workspace before the script is called:
gramming practice:
clearing workspace >> B = rand(1,8)
variables B =
0.2722 0.1988 0.0153 0.7468 0.4451 0.9318
0.4660 0.4186
>> A = [3 -1 4 0 -10 2];
>> log_positive
Executing log_positive...
Finished executing log_positive...
B would be expected to be of same size as A and have values computed from the script.
But since B already exists, only its first six entries are changed during the execution of
log_positive.m, resulting in the following incorrect vector:
>> B
B =
0.477 -1.000 0.602 -1.000 -1.000 0.301 0.4660 0.4186

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 131 1/15/2014 3:17:15 PM


Scripts and Functions  É 132

The last two entries of B correspond to the values that were assigned prior to the execu-
tion of log_positive.m.
Before executing a script, you should type whos to examine which variables already exist and
make sure that there is no over-writing or unintentional sharing of variables by the script. Use
the clear command to remove variables that would not be required in future.
Another problem with scripts is that they are difficult to reuse in future. For example, since
the script log_positive takes A as its input vector, every time you want to use log_­
positive, you have to write the input vector in A.
The function M-files do not suffer from these problems associated with script files.

Example 5.4
Let us write a function that does the same task as the script log_ Example 5.4:
Writing a
positive.m. In other words, the function should compute the loga-
function/learning
rithm of positive elements in a vector.
function structure
Open the editor window and type the following commands and
save the file as func_log_positive.m.
func_log_positive.m
Function Definition Line
function Y = func_log_positive(X)
H1 Line   % Return log of positive elements in Y
  % X is an input vector of integers
  % Example: Y = func_log_positive([1 2 -1])
Help Text With %   disp(‘In function func_log_positive...’);
  n = length(X);
  for i = 1:n
if X(i)<=0
Y(i) = -1;
Function Body else
Y(i) = log10(X(i));
end
end
disp(‘Finished executing func_log_positive...’);

It can be observed from Example 5.4 that the first line in a function file must begin with
a function definition statement, which lists the inputs and outputs of the function. This
statement distinguishes a function M-file from a script M-file. The syntax of the first line
of a function M-file is as follows:
function [output_variables] = function_name(input_variables);
Note that the output variables are enclosed in square brackets except when there is a single out-
put, while the input variables must be enclosed within parentheses. If there is no output, leave
the output field blank as follows:
function function_name(input_variables);

The function_name must be the same as the filename in which it is saved (with the .m exten-
sion). Generally, MATLAB editor automatically recognizes a function M-file from the presence

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 132 1/15/2014 3:17:15 PM


133 Ñ 
  Making Simple Script and Function Files

of a function header. Thus when asked to save, it automatically suggests the filename same as
the function name in the header. Since we named the function func_log_positive, it is saved in
the file func_log_ positive.m.
The H1 line (refer to code of Example 5.4) stands for “help 1” line and it is displayed when
you use the lookfor command to search for information. MATLAB displays the help text
together with the H1 line when you request help on a specific function. Let us see the use of H1
and help text through the execution of the following commands:
>> lookfor ‘positive elements’
func_log_positive.m: % Return log of positive elements in Y
>> help func_log_positive
Return log of positive elements in Y
X is an input vector of integers
Example: Y = func_log_positive([1 2 -1])

The input and output variables are referred directly with their assigned names (as stated in the
function header line) in the body of the function. No “return” statements or “end” statements are
required to signify the end of a function’s body. MATLAB knows the end of the function by the
end of the function M-file. As the function exits, the current values of the output variables are
passed out. Although return and error commands are available, they are used to suddenly
end the function and exit out of it, or to stop execution in case of an error.

Time for Practice 5.2


Consider the following code:
fun1.m
function fun1(A)
sort(A);
for i = length(A)
disp(i);
end

What will be the output of the following line:


>>fun1([9 5 10 15]);

A function is “called” by typing its name without .m extension at the command line. Consider
the following sequence of commands:
>> B = rand(1,8)
B =
0.302 0.541 0.150 0.697 0.378 0.860 0.853 0.593
>> A = [3 -1 4 0 -10 2];
>> [y,n] = max(A)
y = 4 % Maximum value
n = 3 % Index of maximum value
>> B = func_log_positive(A); % Save the output in B

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 133 1/15/2014 3:17:15 PM


Scripts and Functions  É 134

In function func_log_positive...
Finished executing func_log_positive...
>> B
B =
0.4771 -1.0000 0.6021 -1.0000 -1.0000 0.3010
>> n
n =
3

It can be seen that the vector B was overwritten when the function returned its output in B. Thus,
B stores the correct computed value and has six elements. During its execution, a function oper-
ates on variables within its own workspace, which is separate from the workspace available at
MATLAB’s command prompt. Therefore, though the variable n was used in the function, the
value of variable n (n = 4) in the command workspace was preserved. Since functions do not
interfere with the command workspace, they are more reusable than scripts. The variables that
you pass to the function need not have the same name as defined in the function definition line.

Time for Practice 5.3


Consider the following two functions:
The first function is:
fun1.m
function y = fun1(x)
y = fun2(x*x);

The second function is:


fun2.m
function x = fun2(y)
x = y *2;

What will be the output of the following sequence of commands?


>> x = 10;
>> y = fun1(x);
>> disp(x);
>> disp(y);

5.3  Input and Output Arguments in Functions


The input arguments of a function can be passed through either a pass-by-value scheme or a
pass-by-reference scheme. In the pass-by-value scheme, a copy of the actual arguments is made
and the function accesses the copied values. In the pass-by-reference scheme, a separate copy
of the input arguments is not made and the function accesses the same memory space. From
the programmer’s perspective, MATLAB appears to pass all input arguments by value to the
function. However, MATLAB passes-by-value only those arguments that a function modifies.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 134 1/15/2014 3:17:15 PM


135 Ñ 
  Input and Output Arguments in Functions

If a function does not alter an argument but simply uses it in a computation, MATLAB passes
the argument by reference to optimize memory use. This implies that even if the function modi-
fies the input arguments, it will not affect the original data in the invoking code as illustrated in
Example 5.5.

Time for Practice 5.4


Consider the evaluation of the function log 
1 
. When x ≥ 1 the argument will be non-
 1− x 
positive and “invalid”. Create a function invlog.m using an if-construct that will evaluate the
function and print either its value or an error message indicating the message that the input
is out of range.

Consider the following function sq_root which modifies the input x in its function body. You
would see that x retains the same value as it had before calling the function.

Example 5.5
Example 5.5:
Consider the following function sq_root which modifies the
MATLAB’s way
of passing the argu- input x in its function body. You would see that x retains the
ments to a function same value as it had before calling the function.

sq_root.m
function out = sq_root(x)
% Computes the square root of absolute value of x
if (x<0)
x = -x;
end
out = sqrt(x);

Observe the execution of the following commands:


>> x = -3;
>> y = sq_root(x)
y = 1.7321
>> x
x = -3

Though x was changed inside the function sq_root, the change does not reflect in the value
of x in the command workspace. MATLAB’s scheme for passing input arguments is the same
for all different variable types including scalars, vectors, and arrays.

5.3.1  Arguments of Different Types


Functions in MATLAB can receive multiple arguments of scalar, vector, or other types and
return multiple output variables. For instance, the following cylindrical function accepts three
input arguments and returns three outputs.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 135 1/15/2014 3:17:15 PM


Scripts and Functions  É 136

Example 5.6
Example 5.6:
The following formulas enable us to convert a 3-D point represen-
Function with
tation from cartesian coordinates (x,y,z) to cylindrical coordinates
multiple output
(r,q, zcyl): and multiple input
arguments
r= x 2 + y2
 y
q = tan −1  
 x
zycl = z

The following function converts cartesian coordinates to cylindrical coordinates. The


function should be saved as cylindrical.m in your working directory.
cylindrical.m
function [r,theta,zcyl] = cylindrical(x,y,z)
% Converts Cartesian coord. to cylindrical coord.
r = sqrt( x.*x + y.*y );
theta = atan( y ./ x);
zcyl = z;

The function cylindrical is called as follows:


First it is ensured that cylindrical.m is in the current path:
>> dir
. .. cylindrical.m other_files.m temp1.m

Instead of using dir command, we can also use which command to find out if a file-
name is in the MATLAB search path. Following are a few examples of calling cylindri-
cal function from the command prompt:
>> [r,t,z]= cylindrical(10,10,20)
r = 14.1421
t = 0.7854
z = 20
>> cylindrical(10,10,20)
ans =
14.1421
% In this case since it was not specified which
% variables collect the outputs, therefore the
% default variable ‘ans’ collected the first
% output while the other outputs were lost

Time for Practice 5.5


Write a function cubert  that accepts an argument x and computes 3 x . Your function should
work with vector argument in addition to scalar argument, just as built-in MATLAB functions
like sqrt. For example, cubert ([8,64]) should return a vector of the cube roots of 8 and 64.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 136 1/15/2014 3:17:16 PM


137 Ñ 
  Input and Output Arguments in Functions

The types of variables that are passed to a function are not fixed. Depending upon what user
passes, the arguments can be processed. Consider the cylindrical function defined in Example 5.6,
you may pass three single numbers and you will receive three numbers as output. If you
pass three vectors, which define a set of points in the cartesian system, you will receive three
vectors as output. Since the operators .* and ./ have been used in cylindrical function, the
multiplication and division operations will be array operations and you will receive the cor-
rect answer as a set of points in the cylindrical coordinate system. Consider the following
example:
>> a = 1:5
a =
1 2 3 4 5
>> b = 2:2:10
b =
2 4 6 8 10
>> c = a.*a
c =
1 4 9 16 25
>> [m,n,p]= cylindrical(a,b,c)
m =
2.2361 4.4721 6.7082 8.9443 11.1803
n =
1.1071 1.1071 1.1071 1.1071 1.1071
p =
1 4 9 16 25

5.3.2  Variable Number of Arguments


A function may choose to accept/return a variable number of arguments/outputs depending
upon the situation. Many MATLAB functions support passing variable number of input argu-
ments and output arguments. For example, the plot function can be called with as few as two
or as many as seven input arguments. Consider another example of the function call I = find(x)
which returns in I the indices of the vector x that are nonzero. However, when x is a matrix, we
would like to know the row index and column index of nonzero elements. The same function
find when called as [I, J] = find(X) returns the row and column indices of the nonzero entries
in the matrix X in I and J, respectively. How does MATLAB process variable number of input
and output arguments?
There are two ways of receiving variable number of inputs in a function. One is through
checking the number of function arguments at run-time. The other is to code the function
through varargin and varargout commands.
Consider the first way of checking the arguments. When the maximum number of argu-
ments is fixed and reasonably small, the function is defined in the usual form with all argu-
ments and MATLAB accepts the user’s passing less number of arguments than those defined.
However, if the user tries to pass more arguments, MATLAB gives an error. Internally, the
function must check how many arguments were actually passed by the user and should not
try to use the variables that were not passed. MATLAB provides nargin command by

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 137 1/15/2014 3:17:16 PM


Scripts and Functions  É 138

which the function can check how many arguments were passed. Inside the body of a user-
defined function, nargin returns the number of input arguments that were used to call the
function.

Example 5.7
Example 5.7:
Let R be the pth order norm (Lp vector norm) of a vector V, com-
Function
puted by the following equation:
with variable
1/ p number of input
 n p
R =  ∑ Vi  arguments
 i =1 

If p is not specified, a default value of 2 is to be assumed. The following is the code for
the computation of vector norm R.

vecnorm.m
function R = vecnorm(V,p)
% To compute Lp norm of vector V
if nargin == 0
% nargin = number of arguments received
error(‘Too few parameters passed’);
elseif nargin == 1
p = 2;
% p is not specified, so computing L2 norm
else
p = round(p); % Ensuring that p is an integer
end
V2 = abs(V);
% The abs function will act on the whole vector
R = ( sum( V2.^p ) ) ^ (1/p);

The error command used in the function terminates the execution of the function imme-
diately and displays the specified error string on MATLAB command window. vecnorm
can be given input arguments in different ways as shown here:
>> vecnorm([1 1])
ans =
1.4142
>> vecnorm([1 1],1)
ans =
2

A MATLAB function could be called with less output arguments than declared, and this is not
an error. For example, consider the following function call to cylindrical.
>> r = cylindrical(2,3,4)
r = 3.6056
>> [r,theta] = cylindrical(2,3,4)

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 138 1/15/2014 3:17:17 PM


139 Ñ 
  Input and Output Arguments in Functions

r = 3.6056
theta = 0.9828
>> [r,theta,zcyl] = cylindrical(2,3,4)
r = 3.6056
theta = 0.9828
zcyl = 4

It can be seen that the function can be successfully called with one, two, or three output param-
eters and that there is no error. However, sometimes it is helpful to determine the number of
output parameters, so that parameters that are not required need not be calculated. Thus, a
programmer could speed up the operation of his program by avoiding unnecessary calculations.
nargout can be used in user-defined functions to get the number of actual output arguments
that were used to call the function.

Example 5.8
Example 5.8: Consider the following function stat which calculates the mean
Function
and standard deviation of an input vector using the following
with variable
formula:
number of output
arguments
1 N
s = ∑ ( xi − x ) 2
N i =1
The equation computes standard deviation for N samples. xi  is the ith sample and a square
is taken by subtracting each sample from the mean.
stat.m
function [mean, std] = stat(x)
% Calculates the mean and standard deviation of
% the input vector x
n = length(x);
mean = sum(x)/n;
if nargout == 2
disp(‘Computing Std. Deviation’);
std = sqrt(sum((x-mean).^2/n));
% Compute Standard deviation
end

When stat is called with one output argument, the mean is returned and the code for com-
puting standard deviation is not executed as shown here through the following commands:
>> [a] = stat([1 2 3])
a = 2 % value of mean returned in a

When stat is called with two output arguments, the mean and standard deviation are
returned as follows:
>> [x y] = stat([1 2 3])
Computing Std. Deviation

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 139 1/15/2014 3:17:17 PM


Scripts and Functions  É 140

x = 2
y = 0.8165

Let us consider the second way of passing variable number of arguments to a function.

Time for Practice 5.6


Write a function sum_var which takes variable number of scalar number of inputs and returns
the sum. For example:
>>sum_var(2,4,10)
ans =
16
>> sum_var(13,10,20,30)
ans =
73

When the maximum number of arguments is large or unknown, the unknown arguments are
specified using the name varargin. The command varargin returns a cell-array of argu-
ments while varargout returns any number of arguments in a cell-array. Cell- arrays are dis-
cussed in greater detail in Chapter 11. In brief, the syntactical difference between usual arrays
and cell-arrays is that cell-arrays are indexed using curly braces instead of round braces, for
example, use C{i}(j) instead of C(i,j). The elements of cell-arrays contain other arrays. Cell-
arrays collect related data and information of a dissimilar size together. The following example
illustrates how a cell-array temp can be assigned:
>> temp = {17 ‘hello’ ones(2)}
temp =
[17] ‘hello’ [2x2 double]

Note that different cells of the cell-array temp have different data types, scalar, string, or a
matrix. You can access individual cells of the array in the following manner:
>> temp{1} % First cell
ans =
17
>> temp{2} % Second cell
ans =
hello
>> temp{2}(2) % Second element of cell 2 (i.e., ‘e’ in ‘hello’)
ans =
e
>> temp{3} % 3rd Cell
ans =
1 1
1 1
>> temp{4} = ‘another element’ % Adding a new cell
temp =
[17] ‘hello’ [2x2 double] ‘another element’

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 140 1/15/2014 3:17:17 PM


141 Ñ 
  Input and Output Arguments in Functions

Time for Practice 5.7


Write a function sort_vectors which takes variable number of vectors as inputs, sorts them
in ascending order returns, based on the variable number of inputs. For example:
>> [r1, r2] = sort_vectors([10, 3, 9], [3, 5, 2], [12, 14, 20])
r1 =
3 9 10
r2 =
2 3 5

>> [r1, r2, r3] = sort_vectors([10, 3, 9], [3, 5, 2], [12, 14,
20])
r1 =
3 9 10
r2 =
2 3 5
r3 =
12 14 20

Example 5.9
Example 5.9:
Example 5.9 function illustrates the use of varargin and vara-
Application
rgout. Any number of vectors can be given as input and their pth
of “ varargin” and
“varagout” as func- vector norm will be returned in the output. In general you also use
tion arguments nargin and nargout to determine the number of input argu-
ments and the number of output arguments respectively.
var_vecnorm.m
Output parameters must end with
function varargout = var_vecnorm(p,varargin) varargout
% To compute Lp norm of any number of
given vectors
% The usage format will be:
Input parameters must end with
%
 [r1,r2,...,rn] = varargin
vecnorm(p,v1,v2,...,vn)
if nargin<2
error(‘Too few parameters passed’);
else
p = round(p); % Ensuring that p is an integer
end
for i = 1:(nargin-1)
V = varargin{i}; % V would contain ith cell vector
V2 = abs(V);
R = (sum(V2.^p))^(1/p);
varargout{i}= R;
% Packing R in ith cell of output
end

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 141 1/15/2014 3:17:17 PM


Scripts and Functions  É 142

In this function, the loop runs on each argument contained in the varargin. Here is a
sample execution of the function var_vecnorm:
>> [r1,r2,r3] = var_vecnorm(2,[1 1],[1 1 1],[1 1 1 1])
r1 =
1.4142
r2 =
1.7321
r3 =
2
During the execution of the function call, p will be assigned two and the remaining three
vectors will form one cell-array, varargin. The output is assigned as follows: just before
exiting the function, the cell-array varargout contains {[1.4142] [1.7321] [2]}, which
is the order assigned to the variables r1, r2, and r3, respectively, leading to the output (a
scalar can be thought of as one element vector). If the output variables were only r1 and
r2, the first two cell values would be assigned to them as shown here:
>> [r1,r2] = var_vecnorm(2,[1 1],[1 1 1],[1 1 1 1])
r1 =
1.4142
r2 =
1.7321

On the other hand, if you try to give four output arguments, MATLAB would give an
error as there are only three cells. This is shown here:
>> [r1,r2,r3,r4] = var_vecnorm(2,[1 1],[1 1 1],[1 1 1 1])
??? Error using ==> var_vecnorm
Too many output arguments.

An important point to note here is that the input arguments that are necessary must be placed in
the beginning of the function, as MATLAB does not allow arguments to be skipped in between.
For example, if a user has to provide the fourth argument, he must also provide the first three.
For the same reason, arguments are usually ordered according to decreasing necessity. The
varargin and varargout are the last input/return arguments as the following sample function
declaration shows:
function [a,b,varargout]= xyz(d,e,f,varargin)

5.4  Types of Functions


When you call a function M-file from either the command line or from within another M-file,
MATLAB parses the function into pseudocode and stores it in the memory. This prevents
MATLAB from having to reparse a function each time you call it during a session. The pseu-
docode remains in the memory until you clear it using the clear function, or until you quit
MATLAB. You can use clear in any of the following ways to remove functions from the
MATLAB workspace.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 142 1/15/2014 3:17:17 PM


143 Ñ 
  Types of Functions

>> clear function_name


% Remove specified function from workspace
>> clear functions
% Remove all compiled M-functions
>> clear all
% Remove all variables and functions

MATLAB supports different types of functions for solving a variety of problems. You have
seen so far examples of normal functions. There are other types of functions such as function
functions, subfunctions, and private functions. These will be discussed in the next section 5.4.1.

5.4.1  Function Functions, Feval, and Inline


Function functions are those functions that take user-defined functions as input arguments instead
of numeric arrays. MATLAB supports calling functions with input arguments that include the
names of other functions. For example, MATLAB contains a function called fzero, which
accepts a function as an argument and locates the zero of the function that is passed to it. For
example, the statement fzero(’x ^ 2 − 1′, [0 2]) locates the zero of the function x 2 − 1 between
zero and two returning the answer as one.
MATLAB accomplishes the passing of a function as an argument through two special com-
mands, eval and feval.
The commands eval(s), where s is a string, causes MATLAB to execute the string as
an expression or statement. This allows a MATLAB script or function to construct executable
statements during its execution. Here are two examples of using eval:

>> x = 2;
>> eval(‘x^4’)
ans = 16
>> eval(‘cos(pi)’)
ans = -1

Feval is a useful command in passing functions as arguments to a function. The syntax is


feval(F, x1,…,xn), where F is the function name given as a string and x1, x2,…, xn are argu-
ments to be passed to function F. Consider the following statement:
>> [r,t,z] = feval(‘cylindrical’,2,1,2)

This is exactly equivalent to saying,


>> [r,t,z]w = cylindrical(2,1,2)

Another example using feval is:


>> y = feval(‘cos’,pi/4)
y = 0.7071
Another command that is useful with feval is the inline command. It is a powerful com-
mand to generate any mathematical function in symbolic form. For example:
>> f1 = inline(‘x*x’)

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 143 1/15/2014 3:17:18 PM


Scripts and Functions  É 144

f1 =
Inline function:
f1(x) = x*x
>> f1(2) % Evaluate f1 at 2
ans =
4
>> f2 = inline(‘sin(t)/cos(t) - 3*(t^3) + 4*t’)
f2 =
Inline function:
f2(t) = sin(t)/cos(t) - 3*(t^3) + 4*t
>> f2(1) % Evaluate f2 at 1
ans =
2.5574
You can also create functions of more than one argument with inline by specifying the
names of the input arguments along with the string expression. For example, the following
function has two input arguments x and y:
>> f3 = inline(‘log( (x+y) / (x-y) )’, ‘x’, ‘y’)
f3 =
Inline function:
f3(x,y) = log( (x+y) / (x-y) )
>> f3(2,1)
% Evaluate at x = 2, y = 1
ans =
1.0986

Example 5.10
As an aid to school kids, a program is needed that requests the Example 5.10:
Special
students to enter the function as a string and the range as input.
MATLAB com-
The task is to design a program that shows the plot of the function mands in functions
over the user specified range. The students can enter more func- (“eval” and “inline”)
tions until they quit by typing an “!” character.
Since both the function and the range are passed as strings, this
problem requires the use of eval to convert the range string to a numeric array, and the
use of inline command to convert the function string into a function. Following is the
listing of function plotfunc:
plotfunc.m
function plotfunc()
%% Plots user defined functions over a range
%% Takes the function and range as string inputs
funcstr = input(‘Enter the fn. to plot (! to quit): ’,‘s’);
while (funcstr ~= ‘!’)
rangestr = input(‘Enter the range: ’,‘s’);
rangevalue = eval(rangestr);
% rangevalue is now numeric array
func = inline(funcstr); % func is the function
figure; % Create a new space for next plot

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 144 1/15/2014 3:17:18 PM


145 Ñ 
  Types of Functions

plot(rangevalue,func(rangevalue))
% func(rangevalue) is array of
% func values at rangevalue
ylabel(funcstr); % Label the Y-axis
str = strcat(‘Plot of ’, funcstr,‘ over the range ’, rangestr);
% strcat command concatenates strings
title(str);
funcstr = input(‘Enter the fn. to plot (! to quit): ’,‘s’);
end

Following is an example execution of the function:

>> plotfunc
Enter the fn. to plot (! to quit): sin(x)
% sin(x) entered by user
Enter the range: 0:0.1:2*pi
% Range 0:0.1:2*pi entered by user
% A window with a new plot pops up here
% (see Figure 5.1)
Enter the fn. to plot (! to quit): !
% user enters ‘!’ to quit

Plot of sin(x) over the range 0:0.1:2*pi


1
0.8
0.6
0.4
0.2
sin(x)

0
−0.2
−0.4
−0.6
−0.8
−1
0 1 2 3 4 5 6 7

Figure 5.1 Plot resulting from the output of exe-


cuting function plotfunc with sin(x)
as user input (see Example 5.10)

Example 5.11:
Passing functions as
Example 5.11
arguments to a function
(learning “feval” command Function functions find their use in situations such as
and “inline” functions) the implementation of Newton-Raphson(NR) algorithm for
finding a root of a function f(x). The NR method starts with

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 145 1/15/2014 3:17:19 PM


Scripts and Functions  É 146

an initial guess of the root (xo). At the n + 1– th iteration, it refines the current estimate of
the root (xn) using the following formula:

f ( xn )
xn+1 = xn −
f ′( xn )

The iteration process stops when there is an insignificant improvement in the guess from
one iteration to the next, or when the estimate becomes infinity. The following NR pro-
gram needs the user to provide a function whose roots have to be computed. In this case,
the user can pass on the name of his function to the NR function. The NR function then
uses feval command to evaluate the user-named function at a particular point.

NewtonRaphson.m
function Root = NewtonRaphson(F,FD,guess,tol)
% F is the user defined function
% FD is the derivative function of F
% guess is the initial guess
% tol is the error tolerance
error = inf; iter = 0; x = guess;
while ( (error>tol) & (~isinf(x)) )
% Either no improvement in guess
% Or estimate is infinity, then quit
iter = iter+1;
fx = feval(F,x); % Evaluate f(x) at guess
fdx = feval(FD,x); % Evaluate f’(x) at guess
xnew = x-fx/fdx;
% Use equation to compute next guess
error = abs(xnew-x);
x = xnew;
% Start the process from a new guess
end
if isinf(x)
disp(‘No root exists’);
Root = nan;
else
Root = x;
end

The derivative FD of function F can be computed in MATLAB using the symbolic


toolbox which is discussed in Chapter 11. Here we pass the function in F and the
derivative of the function in FD. Following are some execution runs of the mentioned
program:

>> f1 = inline(‘cos(x)’);
>> f2 = inline(‘-sin(x)’);
>> NewtonRaphson(f1,f2,0.5,1.0e-6) %Initial guess = 0.5

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 146 1/15/2014 3:17:19 PM


147 Ñ 
  Types of Functions

ans =
1.5708 % This is pi/2
% cos(pi/2) = 0;
>> NewtonRaphson(f1,f2,4,1.0e-6)
ans =
4.7124 % This is 3*pi/2
>> NewtonRaphson(f1,f2,0,1.0e-6)
Warning: Divide by zero.
> In C:\MATLAB6p1\work\NewtonRaphson.m at line 16
ans =
NaN

Time for Practice 5.8


Given the following code as an m-function, how would you obtain a plot of cos(q ) for values
of q between 0 and 2p.
function [x, y] = evaluate( myfunc, x0, x1, n )
x = linspace(x0, x1, n );
y = feval( myfunc, x );

You can verify if the following solution works:


>> [x, y] = evaluate(‘cos’, 0, 2*pi, 550);
>> plot(x, y)

Example 5.12
Example 5.12:
It is possible to exit out of a MATLAB function suddenly by
Conditional exit
from a function with using the return command. For example, following is a modi-
“return” command fied version of the NR function. In the previous NR function,
exit criterion was that either error (= xnew - x) becomes less
than tolerance, or divergence tends to go to infinity. Here the
check for divergence is modified so that error keeps on increasing for five continuous
iterations. The return command helps exit out of iterations in the middle.
NewtonRaphson2.m
function Root = NewtonRaphson2(F,FD,guess,tol)
% F is the user defined function passed as a
% string. FD is the derivative function of F,
% again passed as a string. Guess is the
% initial guess. Tol is the error tolerance

error = inf; iter = 0; x = guess;


count = 0;
% In this variable we will count the number of
% times the error consecutively increases

while (error>tol)
prev_error = error; % Storing the previous error
iter = iter+1;

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 147 1/15/2014 3:17:19 PM


Scripts and Functions  É 148

fx = feval(F,x);
fdx = feval(FD,x);
xnew = x-fx/fdx;
error = abs(xnew-x);
x = xnew;
% The following statements check for
% progressively increasing errors and quit if NR
% is diverging.

if prev_error>error
count = count+1;
else
count = 0;
end
if count>4
disp(‘Divergence occured’);
Root = nan;
return;
end
end
Root = x;

Here is a sample execution of the program:


>> f1 = inline(‘log(x)’)
f1 =
Inline function:
f1(x) = log(x)
>> f1d = inline(‘1/x’)
f1d =
Inline function:
f1d(x) = 1/x
>> NewtonRaphson2(f1,f1d,0.8,1.0e-5)
ans =
1.0000
>> NewtonRaphson2(f1,f1d,2,1.0e-5)
Divergence occurred
ans =
NaN

Time for Practice 5.9


What are the outputs of the following?
1. >> f3 = inline(‘x^2 + y^2 -1’, ‘x’, ‘y’)
>> f3(3,1)
2. >> f4 = inline(‘x^ 3-1’, ‘x’)
>> feval(f4,4)

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 148 1/15/2014 3:17:19 PM


149 Ñ 
  Types of Functions

3. >> x = 10;
>> y = 20;
>> eval(‘x*3 - y*2 + x*y’))

Time for Practice 5.10


Write a function stat_matrix that accepts a matrix as an argument and returns the maximum
and minimum numbers in the matrix. The function stat_matrix calls two other subfunctions
which return the maximum and minimum numbers in the matrix.

5.4.2 Subfunctions
When more than one function is present in a function file (say func_name.m), the top function
(  func_name) is a normal function, while the ones below it are subfunctions or internal func-
tions. These subfunction definitions are like normal functions, but they are only accessible to
the other functions within the same file. As smaller functions that are part of a main function’s
M-file, they assist the main function.
Each subfunction begins with its own function definition line. The functions immediately
follow each other. The various subfunctions can occur in any order, as long as the primary func-
tion appears first. Functions within the same M-file cannot access the same variables unless you
declare them as global within the pertinent functions, or pass them as arguments. In addition,
the help facility can only access the primary function in an M-file.

Example 5.13
Example 5.13:
The following example defines a function sindegree that accepts
Subfunction of a
x in degrees and computes sine of x. Note that MATLAB trigo-
function
nometric functions expect their argument to be in radians.
sindegree.m
function out = sindegree(x)
% sindegree is a main function
%% Finds sine of x, where x is in degree
y = convert(x);
out = sin(y);
function a = convert(x)
% convert is a subfunction
%% Convert a number in degree to radian
a = (x*pi)/180;

Here is a sample output at command prompt:


>> m = sindegree(45)
m = 0.7071

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 149 1/15/2014 3:17:19 PM


Scripts and Functions  É 150

>> convert(45)
??? Undefined function or variable ‘convert’.

The function sindegree can be called at the command line or by any other function, but the
subfunction convert can only be called by other functions in the same file.

5.4.3  Private Functions


Private functions are functions that reside in subdirectories with the special name private.
They are visible only to functions in the parent directory. Because private functions are invis-
ible outside the parent directory, they can use the same names as functions in other directories.
For example, assume the directory folder_name is in the MATLAB search path. A subdirec-
tory of folder_name called private can contain functions that only the functions residing in
folder_name can call.
Private functions are useful if you want to create your own version of particular functions
while retaining the original ones in another directory. Because MATLAB looks for private func-
tions before standard M-file functions, it will find a private function named function_name.m
before a nonprivate M-file named function_name.m. You can create your own private directo-
ries simply by creating subdirectories called private using the standard procedures for creat-
ing directories or folders on your computer. Do not place these private directories on your
MATLAB path.

5.4.4  Function Name Resolution


When MATLAB comes upon a new name, it resolves it into a specific function by following
these steps in the order as follows:
1. Checks to see if the name is a variable.
2. Checks to see if the name is a subfunction, a MATLAB function that resides in the same
M-file as the calling function.
3. Checks to see if the name is a private function, a MATLAB function that resides in a private
directory, a directory accessible only to M-files in the directory immediately above it.
4. Checks to see if the name is a function on the MATLAB search path.
MATLAB uses the first file it encounters with the specified name. If you duplicate function
names, MATLAB executes the one found first using the above rules.

5.5  Global and Persistent Variables


In MATLAB, you do not need to declare variables. Before assigning one variable to another,
however, you must be sure that the variable on the right-hand side of the assignment has a value.
Any operation that assigns a value to a variable creates the variable if needed, or overwrites
its current value if it already exists. Variables defined within the function do not appear in the
workspace. They are destroyed as soon as the function ends. Similarly, when a function is called
from within a script file (program), the function cannot access the script file’s variables, nor can
the script file access the function’s variables. The function’s internal variables do not appear

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 150 1/15/2014 3:17:19 PM


151 Ñ 
  Global and Persistent Variables

anywhere on the workspace. These variables are initialized each time the function is called and
are destroyed when the function returns.
In addition to the argument list, MATLAB functions can exchange data with each other and
with the command workspace through global memory. The global command declares certain
variables global, and therefore their values are available to the global workspace and to the
other functions that declare these variables global. The form of global statement is as follows:
global var1, var2, var3 ;
Where var1, var2 and var3 are the variables to be placed in global memory.

Example 5.14
Example 5.14:
Here is an illustration of global command in two functions.
Use of global
func_global1 is declared as follows:
variables
func_global1.m
function out = func1_global1(x)
global y;
y = [1 2 3];
disp(‘Executed func1...’);

func_global2 that takes global variable y is declared as follows:


func_global2.m
function out2 = func_global2()
global y;
out2 = sort(y);

Note the following sequences of command execution at the workspace:


>> clear
> y = 10;
>> func_global1
Executed func1...
>> func_global2 % y value was updated to [1,2,3]
ans =
1 2 3
>> y
% At command workspace, y value remained same
y =
10
>> global y % Now, declare y as global
% MATLAB’s response follows
Warning: The value of local variables may have been changed to
match the globals.
>> y % y value is updated to [1,2,3]
y =
1 2 3

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 151 1/15/2014 3:17:19 PM


Scripts and Functions  É 152

When a function finishes executing, the local variable workspace of the function is destroyed.
However, it is sometimes useful to preserve some local information within a function between
calls to the function. MATLAB includes a special mechanism to allow local variables to
be preserved between calls to a function through persistent command. The syntax of
persistent command is:

persistent var1, var2, var3;

where var1, var2, and var3 are the variables whose values are needed in future function
calls.
Persistent variables are similar to global variables because MATLAB creates permanent stor-
age for both. They differ from global variables as persistent variables are known only to the
function in which they are declared.

Example 5.15
Consider the following function temp_ func: Example 5.15:
Use of persis-
tent variables
function y = temp_func(x)
persistent var1;
if isempty(var1)
var1 = 1;
else
var1 = var1 + 2* x;
end
y = var1;

Here, we have declared a persistent variable var1. On first time executing the func-
tion temp_func, var1 will be assigned the value 1. During the next run, the value will
be computed by the formula var1 = var1 + 2*x. The following is the output of the
function:
>> temp_func(2) % First time run
ans =
1
>> temp_func(2) % Second time run
ans =
5
>> temp_func(2) % Third time run
ans =
9
>> clear
% Clear does not clear the persistent variables
>> temp_func(2) % Fourth time run
ans =
13

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 152 1/15/2014 3:17:19 PM


153 Ñ 
  Polynomial Functions

5.6  Polynomial Functions


In MATLAB, a polynomial is represented by a vector. To create a polynomial in MATLAB,
simply enter each coefficient of the polynomial into the vector in descending order. For instance,
consider the following polynomial:

f 1( x ) = x 4 + 3 x 3 − 15 x 2 − 2 x + 9

To enter this into MATLAB, just enter it as a vector in the following manner:
>> f1x = [1 3 -15 -2 9]
f1x = 1 3 -15 -2 9

MATLAB interprets a vector of length n + 1 as an nth order polynomial. Thus, if a polynomial


is missing any coefficients, one must enter zeros in the appropriate place in the vector. For
example, if f 2( x ) = x 4 + 2 x 2 , then it would be represented in MATLAB as f 2( x ) = [1 0 2 0 0].
The value of a polynomial f(x) can be evaluated at x = k using the polyval function. For exam-
ple, to find the value of the polynomial f 2(x) at x = 2, use the polyval as shown here:
>> z = polyval([1 0 2 0 0],2)
z = 24

You can also extract the roots of a polynomial. This is especially useful when you have a high-
order polynomial such as f 1( x ) = x 4 + 3 x 3 − 15 x 2 − 2 x + 9. Finding the roots is done by using
the roots command in MATLAB as shown here:
>>x = roots([1 3 -15 -2 9])
x =
-5.5745
2.5836
-0.7951
0.7860

To get the original polynomial back, you can use the poly command. poly(v) is a vector whose
elements are the coefficients of the polynomial whose roots are the elements of v. The com-
mands roots and poly are inverse functions of each other. You can see the output by using
poly as follows:
>> poly(x)
ans =
1.0000 3.0000 -15.0000 -2.0000 9.0000

Let us say you want to multiply two polynomials together. The product of two polynomials is found
by taking the convolution of their coefficients. For example, consider two polynomials fx = x + 2
and fy = x 2 + 4 x + 8. The product polynomial is given as fz = fx * fy = x 3 + 6 x 2 + 16 x + 16.
MATLAB function conv gives the product of two polynomials as shown here:
>> fx = [1 2];
>> fy = [1 4 8];

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 153 1/15/2014 3:17:21 PM


Scripts and Functions  É 154

>> fz = conv(fx,fy)
fz =
1 6 16 16

Time for Practice 5.11


Find a polynomial p of degree at most 5 that minimizes the pointwise error in approximating
the function f (x ) = sin(3x ), 0 ≤ x ≤ 1, and also find a polynomial q of degree at most 4 that
best approximates the function g (x ) = e x . Do not spend too much time here; your approxi-
mations need not be perfect.

Dividing two polynomials is also easy in MATLAB. The deconv function will return the
remainder as well as the result. Let us divide fz by fy and see if we get fx.
>>[xx, R] = deconv(fz,fy)
xx = 1 2
R = 0 0 0 0

As it can be seen, the vector xx is just the polynomial (vector) fx.


The polyder function computes the derivative of any polynomial. You can compute the
derivative of the polynomial p = [1 0 -2 -5] using polyder as shown here:
>> q = polyder(p)
q =
3 0 -2

Polynomial curve fitting can be done using polyfit command. polyfit finds the coefficients
of a polynomial that fits a set of data in the least-squares sense. polyfit(x,y,n) finds the coeffi-
cients of a polynomial p(x) of degree n that fits the data, p(x(i)) to y(i), in the least squares sense.
The result p is a row vector of length n + 1 containing the polynomial coefficients in descend-
ing powers. x and y are vectors containing the x and y data to be fitted, and n is the order of the
polynomial to return. For example, consider the x-y test data:
>> x = [1 2 3 4 5];
>> y = [5.5 43.1 128 290.7 498.4];
A third order polynomial that approximately fits the data is:
>> p = polyfit(x,y,3)
p =
-0.1917 31.5821 -60.3262 35.3400

Example 5.16
This example involves fitting the cos function, cos(x), by a pol- Example 5.16:
Polynomial fitting
ynomial of order 5 in x. We should evaluate how close is the
and evaluation
curve fitting.
First we generate a vector x of points equally spaced in the
interval [0, pi]; then we evaluate cos(x) at those points as shown here:
>> x = (0: 0.1: pi)’;
>> y = cos(x);

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 154 1/15/2014 3:17:22 PM


155 Ñ 
  Recursive Functions

The coefficients in the approximating polynomial of degree 5 are:


>> p = polyfit(x,y,5)
p =
-0.0076 0.0593 -0.0206 -0.4886 -0.0024 1.0001

There are six coefficients in p. To see how good the fit is, evaluate the polynomial at the
data points with the following:
>> f = polyval(p,x);
% A table showing the data, fit, and error is
>> table = [x y f y-f];
>> table(1:5,:)
ans =
% x y f    
y-f (error)
0 1.0000 1.0001 -0.0001
0.1000 0.9950 0.9949 0.0001
0.2000 0.9801 0.9800 0.0001
0.3000 0.9553 0.9553 0.0000
0.4000 0.9211 0.9211 -0.0000

From the above table, it can be seen that on this interval, the fit is good to three digits.
Let us evaluate the difference beyond the interval (0, pi) on which curve fitting was done.
>> x2 = pi * [11/10 9/8 7/6 5/4 3/2]’;
>> y2 = cos(x2);
>> f2 = polyval(p,x2);
>> table2 = [x2 y2 f2 y2-f2]
table2 =
% x2 y2 f2    
y2-f2 (error)
3.4558 -0.9511 -0.9541 0.0030
3.5343 -0.9239 -0.9287 0.0048
3.6652 -0.8660 -0.8755 0.0094
3.9270 -0.7071 -0.7360 0.0289
4.7124 -0.0000 -0.3138 0.3138

The graph shows that beyond the curve fitting interval the error increases and the approx-
imation deteriorates.

5.7  Recursive Functions


A function can use either iterative method using loops, or it can be recursive in nature. Iteration
is the process of repeatedly executing a set of operations until a condition is met. It is usually
implemented using “for ” and “while ” loop. Recursion (or a recurrence relation) in mathemat-
ics is the process of defining a function in terms of a simpler version of itself. It is the process of
successively breaking a problem into smaller parts, where each is a smaller/simpler version of
the previous one until a simple solution is reached. Back-substitution then leads to the solution
for the original problem. For example, n ! = n × (n −1)! is a recursive relationship.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 155 1/15/2014 3:17:22 PM


Scripts and Functions  É 156

Example 5.17
Example 5.17:
The goal of this example is to see what the parts of a recursive
Writing recursive
function are and how they execute. The following simple recur-
functions
sive function calculates the factorial of an input integer n.
recr_fact.m
function value = recr_fact(n)
% Recursive version of factorial
% n is positive integer i.e., greater than 0
if (n==1) % Terminating condition
value = 1;
return
else
disp(‘Calling recr_fact with n =’); disp(n-1);
value = n*recr_fact(n-1);
% Recursive call bringing argument
% closer to the terminating condition
disp(‘Updated value for n = ’); disp(n);
end

Several important concepts can be observed from this program. Typically, a recursive program
has three elements, which are often programmed in an “If-else” construct. The elements of a
recursive program are:
1. The stopping or terminating condition is assigned a fixed value.
2. The function’s value is computed for the current argument, following which the argument
is incremented to bring it closer to the terminating condition.
3. The function calls itself to compute its value for the incremented argument.
The recursive functions go to the terminating condition and then pass the value back as shown
in the example here:
>> recr_fact(3)
Calling recr_fact with n = % called recr_fact(2)
2
Calling recr_fact with n = % called recr_fact(1)
1
Updated value for n = % Computed recr_fact(2)
2 % Now return to space of recr_fact(3)
Updated value for n = % Computed recr_fact(3)
3
ans = % Exit from the function
6
Recursive functions are sought in the following situations:
1. Some functions are inherently recursive such as finding the determinant of a matrix.
2. It is easier to think of solution in terms of recursion.
3. Recursive function takes less execution time than iterative methods.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 156 1/15/2014 3:17:22 PM


157 Ñ 
  Recursive Functions

Example 5.18
Example 5.18:
Let us illustrate the recursion through the computation of a square
Special appli-
root of a positive number N via the following relationship:
cations of recursive
functions 1 N 
xn = x n −1 +
2  xn −1 
Repeated application of the above equation would bring xn closer to N . Try substitut-
ing N in the mentioned equation. A convergence criterion is required to indicate the
end of iteration. A good convergence criterion in this case is:
x n − x n −1
≤ e (2)
x n −1
Where, e is a very small number (say, eps, the floating precision for the computer being
used). The following program is the implementation of this recursive relation:
sq_root.m
function value = sq_root(N, x)
% SQ_ROOT computes the square root of a
% positive number N by Newton’s method
% Usage value = sq_root(N,x) where N is the
% number for which square root is desired and x
% is the initial guess

if (N < 0)
error(‘Error using sq_root ==> argument N must be positive’);
end
xnew = 1/2*(x + N/x); % Compute new x for next step

if (abs((xnew-x)/x) <= eps) %Check for convergence


disp(‘The square root is:’)
% Display the result
value = x;
disp(value)
else
disp(xnew) % Display the new iteration value
value = sq_root(N,xnew)
% Compute the iteration with xnew
End

Time for Practice 5.12


Consider the following definition for a SamNumber.
The first SamNumber is 2. The second SamNumber is 3. The third SamNumber is 3*(2 − 3)
= −3. The fourth SamNumber is 4*(3 − (−3)) = 24. The fifth SamNumber is 5* (−3 − 24) =
−135
Write a recursive function to calculate the SamNumbers. Display the first 10 SamNumbers.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 157 1/15/2014 3:17:24 PM


Scripts and Functions  É 158

The function sq_root is an example of a typical recursive function having a base case satisfying
convergence condition and a call to the function itself with the modified value of the argument.
Try executing function sq_root on MATLAB with input N = 450, x = 100 and N = 450, x = 10.

Example 5.19
Consider a program for exponentiating a number to an integer Example 5.19:
power; that is, it computes xn for arbitrary x and an integer n. Recursive func-
tions for efficient
The standard way for the computation would be to multiply n
computation
times the number x as illustrated in function exp1.
x n = x n −1 × x

exp1.m
function value = exp1(x,n)
% Iterative method for computing x^n
value = 1;
for i = 1:n
value = value.*x;
end

Another way of doing this is to note the following recursive relation:


x n = ( x n / 2 )2
If n is a power of 2 this recursive relation would lead to a function that called itself
log 2 (n) times. Thus, if n were large this would be efficient than the program exp1.m.
Note that if n is odd, computation of x n / 2 using this equation would be computationally
expensive. Thus, for odd n, it would be better to work with xn = xn-1*x.
Let us now write function exp2, which is based on recursion as follows:
exp2.m
function value = exp2(x,n)
% Recursive version
if (n == 1) % terminating condition
value = x;
elseif (rem(n,2)== 1)
value = x.* exp2(x,n-1);
else
value = exp2(x,n/2).^2;
end

It turns out that on large vectors and for large powers, exp2 is faster than exp1 as shown
by the following execution:
>> x = 0:0.001:10;
>> tic; for i = 1:100, exp1(x,401); end, toc
Elapsed time is 9.708980 seconds.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 158 1/15/2014 3:17:25 PM


159 Ñ 
  Recursive Functions

>> tic; for i = 1:100, exp2(x,401); end, toc


Elapsed time is 0.423583 seconds.

Time for Practice 5.13


This exercise concerns writing a function determinant.m that recursively computes the deter-
minant of a square matrix. Verify if the following function is correct.

Example 5.20
Example 5.20: The following function computes the determinant of a matrix
Writing complex using recursion as follows:
functions using
recursion determinant.m
function value = determinant(M)
%% DETERMINANT calculates the determinant of a
%% square matrix M
%% USAGE value = determinant(M), where M is a n
%% x n matrix
if size(M,1)~ = size(M,2)
error(‘Error ==> argument M must be square matrix’);
end
if size(M,1) ==1 % When matrix has 1 element
value = M(1,1);
end
%%%% First examine the terminating case
if size(M,1)==2 %% if M = (a b )
%% (c d )
value = M(1,1)*M(2,2) - M(1,2)*M(2,1);
% determinant = ad - bc
else
val = 0;
% val is a temporary variable

for i = 1: size(M,1)
%% Construct the new matrix removing the first
%% row and i-th column
Mnew = M; % M is first copied in Mnew
Mnew(1,:) = []
% Mnew(1,:) deletes the first row and makes the
% old second row as the first row
Mnew(:,i) = []; % delete the i-th column
val = val + (-1)^(i+1)*M(1,i)*determinant(Mnew);
% Compute the determinant term for the M(1,i)
end
value = val;
end

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 159 1/15/2014 3:17:25 PM


Scripts and Functions  É 160

5.8  Common Errors in Using Functions


Section 5.8 helps you to identify the possible cause(s) for an error message that is being gener-
ated by your MATLAB code as follows:
1. When you receive an error message as follows:
??? Error: File: A function declaration cannot appear within a script
M-file.

The possible cause is that you have defined a function inside a script file as shown in the
following script file (try1.m):
try1.m
x = 2;
y=square(x)
function out_var = square(x)
out_var = x*x;

A function can never be defined in a script file. MATLAB does not execute a script file if it
finds a function declaration within it.
2. Consider the following error message:
Attempt to execute SCRIPT try2 as a function.
try2.m is the name of file that you want to execute at command workspace. The common
causes of this error are:
(a) You are attempting to call a script file as though it were a function file by passing argu-
ments to it. For example, you create a script file try2.m and execute the following com-
mand at the workspace:
>> try2([1 2]);
(b) You have created a script M-file with the same name as a function on the MATLAB
path but higher on the path than that function. Execute the following command to verify
that the file you expect to execute is being used instead of any other file with the same
name:
>> which –all try2.m
(c) You are attempting to index into an array that does not exist when a script file with that
name exists. You can find out if the array exists using who or which commands
(d) You have defined function with wrong syntax, for example, instead of “function” you
used “Function” as follows:
try2.m
Function value = try2(x,y)
% Wrong syntax
% Correct syntax: function value = try2(x,y)
% Function body

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 160 1/15/2014 3:17:25 PM


161 Ñ 
  Common Errors in Using Functions

3. Consider the following error message:


Undefined function or variable
The reason behind this error is that MATLAB does not recognize the specified string as the
name of a function on the MATLAB path or a variable visible to that function. Some com-
mon causes are:
(a) You have made a typographical error when typing a command or variable name or you
have used the wrong case for a function or variable name. Verify that the name of the
function or variable is correct. Stop MATLAB at the statement where the error occurs
using the debugging facility, and type which –all tname where tname is the func-
tion that you were trying to access.
(b) You have changed directories so that a function you use is no longer on MATLAB’s
search path.
4. Consider the following error messages:
Too many output arguments.
Too many input arguments.
Not enough input arguments.
The reason behind these error messages is that the function that you are trying to call
expects fewer input/output arguments, or more input arguments, than you have provided.
Consider the following example of a function try1.m.
try1.m
function [array, index] = try1(inp_vector)
% the function takes an input vector and
% returns the sorted array and the index
% to sorting
[array, index] = sort(inp_vector);

If you call this function with incorrect syntax from another function or script file as shown
here, it may result in an error as follows:
‘too many input arguments supplied’:

try2.m
% Script file
[y1 y2] = try1(1,2,3);
% Correct usage [y1 y2] = try1([1,2,3]);

The correct syntax was to give a scalar input or an array. Instead three scalars were sup-
plied. You should stop MATLAB at the statement where the error occurs and verify that
you have specified the correct number of input and/or output arguments. To avoid calling
the wrong function, use which command to determine which version of the function you
are using. Another way to debug this problem is to use nargin and nargout. When
you pass to nargin or nargout the name of the function that you want to use, they
respectively return the number of input or output arguments that function accepts.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 161 1/15/2014 3:17:25 PM


Scripts and Functions É 162

Programming Tips and Pitfalls


Following are some tips to effectively use the concept of MATLAB functions:
1. Break your problem down into small chunks and test each chunk separately. This usually
means writing a number of small function files and documenting them.
2. Try to make functions work regardless of the size of the parameters. For example, if you
need to evaluate a polynomial function, write a function that accepts a vector of values and a
coefficient vector. If you need such a function once, it is likely you will need it again. Also,
if you change your problem by using a fifth order polynomial rather than a fourth order, you
will not need to rewrite your evaluation function.
3. Try to avoid hard-coding parameter values and dimensions into your code. Suppose you
have a problem that involves an interest rate of 10%. Do not put a lot of 0.1’s into your code.
Later on you may want to change the interest rate to 8%. You should be able to make this
change in a single line with a nice comment attached to it, for example:
intrate = 0.1; % the interest rate

4. Errors that occur with the use of functions are usually due to an incorrect interface used to
pass parameters between the calling code and the called function. Examine each call to a
function to see that you have the right number of parameters and correct parameter data types.
5. While writing your code, you can insert output statements to print the values of parameters
immediately before and after calls to the functions and verify that the output is in accord-
ance to your expectation.
6. If a function requires a parameter to be within a certain range, try calling the function with
values in the middle of the range and its extremes.

SUMMARY
MATLAB allows programs to be expressed as scripts and functions. Script files do not have
input and output arguments and they share the workspace with command workspace. The
variables created in a script are visible in command workspace. Functions are more widely
used as they have input and output parameters. Since functions have an independent work-
space, there are lesser errors due to interference from variables in command workspace. You
can share a variable in several function files using the global command. By the persis-
tent command, you can retain the value of a variable in a function since its last execution.
MATLAB provides the facility for function arguments to not be restricted to only one
data type. In other words, the same function can accept or return either scalar, vector,
or a matrix.You can give even a variable number of arguments using varargin and
varargout commands. A function can know the number of input arguments and the
number of output arguments using nargin and nargout commands, respectively. You
can declare subfunctions that assist the top main function and are hidden outside the main
function. You can also hide your functions by making them private functions.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 162 1/15/2014 3:17:25 PM


163 Ñ Exercises

The concept of function functions enables you to pass functions as arguments. You can
evaluate the function as an argument using feval command. The inline command
creates a function from a string expression, while eval command evaluates the function
given in a string expression. MATLAB also provides functions to represent polynomials,
evaluate a polynomial at a point, multiply and divide polynomials, and take derivative
of a polynomial. MATLAB supports a function to call itself and you can write recursive
functions.

EXERCISES

5.1. You are given the following function:


function A = fnk(t)
nvals = length(t);
large = t(1);
for ii = 2:(nvals-1)
if t(ii) > large
large = t(ii);
end
end
A = large;
What will be the output if you type the following at the MATLAB prompt?
>> fnk( [1, -3, 10, 8, 19] )
5.2. Let the function f ( x ) be defined as follows (for real x):
1 1 
f ( x) =  1 − x * cos( x ) − *sin( x )
2 2
Write a MATLAB function myfx such that myfx returns f ( x ) when x is scalar. If x is a vec-
tor, myfx(x) should evaluate the function f for all elements of x and return the results as a
vector.
5.3. A number z is said to be the nth root of 1, if z n = 1. We write z = 11/ n . When n is a positive
integer then n different roots of 1, z0 , z1 , ..., zn −1 are given by the following formula:

 2p k   2p k 
zk = cos  + i sin  , k = 0,1,…, n − 1
 n   n 
Write a subfunction that computes zk. You should write rootsone such that it uses this
subfunction to compute the result.
5.4. Write a MATLAB function cubegreat(n) to find the first odd integer whose cube is greater
than n, and display the result.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 163 1/15/2014 3:17:28 PM


Scripts and Functions  É 164

5.5. Write a m-function that will compute the array division, C = A./B. Your function should
accept A and B and return C as follows: C = mdiv(A, B). Make sure your function checks
that A and B are of the same size and issues an error message if they are not of same size.
5.6. Write a function called form_vector which will accept a vector of numeric labels for four
elements (e.g., [1 4 5 7]) and a corresponding vector of sample sizes (frequencies) for the
group (e.g., 4 1 2 3). The output should consist of a column vector containing one entry
for each individual, specifying its group membership (e.g., 1;1;1;1;4;5;5;7;7;7). The func-
tion should be the following: USAGE: grps = form vector(labels, freq)
5.7. Write a script file called do_makegroup that will pass the vector labels = [2 ,4, 5, 8] and
frequency vector, freq = [5, 5, 3, 4] to the function form_vector as defined in Question 6
and then store the matrices, labels, frequencies, and groups into a mat file grpData.mat.
5.8. The following relationship exists among the elements of a n  ×  matrix P pi +1, j +1 = pi , j + 1,1 ≤ i, j ≤ n
pi +1, j +1 = pi , j + 1,1 ≤ i, j ≤ n − 1 and p(1,1) = 1; p(1, i ) = 0, for i ≠ 1; p(i,1) ∨ i. 
Construct a function
matP that outputs P with the usage P = matP(n) where n is the number of rows in the
matrix.
5.9. Write a function fillmatd that will accept a single scalar value indicating the size of a
square matrix and will fill the upper off-diagonal portion of the matrix with consecutive
integers by row and the lower off-diagonal portion by column. The diagonal should con-
tain zeros. For example, fillmatd(5) will produce the following matrix:
0 1 2 3 4 
1 0 5 6 7 
 
M5× 5 =  2 5 0 8 9 
 3 6 8 0 10
 
 4 7 9 10 0 
5.10. Write a function unique_el which will accept any matrix and will return a column vector
containing the unique values in the matrix. For example, if:
 1 4 2
 2 1 1
A= 
 4 2 4
 7 1 4
Then, the statement u = unique_el(A) should return the following:
 1
 2
u= 
 4
 7
If the input matrix is null, return a null output matrix. Also extend the program to print the
frequencies of each unique element.
5.11. Write a function polycompute (pol, x) that computes the polynomial pol for x. When x is
a vector, the polynomial should be computed at each value of the elements in x.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 164 1/15/2014 3:17:29 PM


165 Ñ 
 Exercises

5.12. Write a function that accepts a vector representing a polynomial f(x). The function
integrates the polynomial. The constant of integration should be chosen so that if
g = integrate (  f), then g(–1) = f(–1).
5.13. This exercise is based on calculating the Euler number of an integer number n. The Euler
number E(n) is defined by an asymptotic three term recurrence relationship:
 2 * E (n) E (n − 2) 32 
E ( n + 2) = E ( n) ×  − −
 E (n − 2) E (n − 4) p 2 

Also, it is known that E(n) = 0 for all odd n. Write a function euler.m that finds the Euler
number for an input integer n.
5.14. Write a function that accepts three linear equations as arguments, and returns their solu-
tion. The equations are in three variables of the form: 3.1x + 4.2y + 8z = 20.

M05_PROGRAMMING IN MATLAB_XXXX_CH05.indd 165 1/15/2014 3:17:30 PM

You might also like