M05 - Programming in Matlab - XXXX - CH05
M05 - Programming in Matlab - XXXX - CH05
M05 - Programming in Matlab - XXXX - CH05
Scripts
and Functions
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:
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.
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
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...’);
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:
>> 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);
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
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
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.
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
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.
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.
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);
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.
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
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
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
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)
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
x = 2
y = 0.8165
Let us consider the second way of passing variable number of arguments to a function.
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’
>> [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
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)
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.
>> x = 2;
>> eval(‘x^4’)
ans = 16
>> eval(‘cos(pi)’)
ans = -1
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
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
>> 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
0
−0.2
−0.4
−0.6
−0.8
−1
0 1 2 3 4 5 6 7
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
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
>> f1 = inline(‘cos(x)’);
>> f2 = inline(‘-sin(x)’);
>> NewtonRaphson(f1,f2,0.5,1.0e-6) %Initial guess = 0.5
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
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
while (error>tol)
prev_error = error; % Storing the previous error
iter = iter+1;
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;
3. >> x = 10;
>> y = 20;
>> eval(‘x*3 - y*2 + x*y’))
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;
>> 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.
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...’);
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:
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
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
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];
>> fz = conv(fx,fy)
fz =
1 6 16 16
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
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);
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.
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.
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
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
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.
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
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
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.
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.
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
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.
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.
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.