# Lesson 12: M-files

MATLAB can execute a sequence of statements stored in a file. Such files are called "M-files" because they must have an extension of ".m" for its filename. Much of your work with MATLAB will be creting and refining M-files.

There are two types of M-files: script files and function files.

## Script files

A script file consists of a sequence of normal MATLAB statements. If the file has the filename, say, rotate.m, then the MATLAB command rotate will cause the statements in the file to be executed. Variables in a script file are global and will change the value of variables of the same name in the environment of the current MATLAB session.

Script files are often used to enter data into a large matrix; in such a file, entry errors can be easily edited out. If, for example, one enters in a diskfile data.m

```	A = [
1 2 3 4
5 6 7 8
];
```
then the MATLAB statement data will cause the assignment given in data.m to be carried out.

An M-file can also reference other M-files, including referencing itself recursively.

## Function files

Function files provide extensibility to MATLAB. You can create new functions specific to your problem which will then have the same status as other MATLAB functions. Variables in a function file are by default local. However, you can declare a variable to be global if you wish.

We first illustrate with a simple example of a function file.

```   function y = randint(m,n)
% RANDINT Randomly generated integral matrix.
%   randint(m,n) returns an m-by-n such matrix with
%   entries between 0 and 9.
y = floor(10*rand(m,n));
```

A more general version of this function is given as follow:

```   function y = randint(m,n,a,b)
% RANDINT Randomly generated integral matrix.
%   randint(m,n) returns an m-by-n such matrix with
%   entries between 0 and 9.
%   randint(m,n,a,b) returns entries between integers a and b.
if nargin < 3, a=0; b=9; end
y = floor((b-a+1)*rand(m,n))+a;
```

This should be placed in a diskfile with filename randint.m (corresponding to the function name). The first line declares the function name, input arguments and output arguments; without this line the file would be a script file. Then a MATLAB statement z = randint(4,5), for example, will cause the numbers 4 and 5 to be passed to the variables m and n in the function file with the output result being passed out to the variable z. Since variables in a function file are local, their names are independent of those in the current MATLAB environment.

Note that use of nargin ("number of input arguments") permits one to set a default value of an omitted input variable---such as a and b in the example given above.

A function may also have multiple output arguments. For example:

```   function [mean, stdev] = stat(x)
% STAT Mean and standard deviation
%   For a vector x, stat(x) returns the
%   mean and standard deviation of x.
%   For a matrix x, stat(x) returns two row
%   vectors containing, respectively, the
%   mean and standard deviation of each column.
[m n] = size(x);
if m == 1
m = n;   % handle case of a row vector
end
mean = sum(x)/m;
stdev = sqrt(sum(x.^2)/m -mean.^2);
```
Once this is placed in a diskfile stat.m, a MATLAB command [xm, xd] = stat(x), for example. will assign the mean and standard deviation of the entries in the vector x to xm and xd, respectively. Single assignments can also be made with a function having multiple output arguments. For example, xm = stat(x) (no brackets needed around xm) will assign the mean of x to xm.

The % symbol indicates that the rest of the line is a comment; MATLAB will ignore the rest of the line. However, the first few comments lines, which document the M-file, are available to the on-line help facility and will be displayed if, for example, help stat is entered. Such documentation should always be included in a function file.

This function illustrates some of the MATLAB features that can be used to produce efficient code. Note, for example, that x.^2 is the matrix squares of the entries of x, that sum is a vector function, that sqrt is a scalar function, and that the division in sum(x)/m is a matrix-scalar operation.

The following function, which gives the greatest common divisor of two integers via the Euclidean algorithm, illustrates the use of an error message.

```   function y = gcd(a,b)
% GCD Greatest common divisor
%   gcd(a,b) is the greatest common divisor
%   of the integers a and b, not both zero.
a = round(abs(a)); b = round(abs(b));
if a == 0 & b == 0
error('The gcd is not defined when both numbers are zero')
else
while b ~= 0
r = rem(a,b);
a = b; b = r;
end
end
```

Some more advanced features are illustrated by the following function. As noted earlier, some of the input arguments of a function---such as tol in the following example, may b made optional through use of nargin ("number of input arguments"). The variable nargout can be similarly used. Note that the fact that a relation is a number (1 when true; 0 when false) is used and that, when while of if evalutes a relation, "nonzero" means "true" and "zero" means "false". Finally, the MATLAB function feval permits one to have as an input variable a string naming function.

```   function [b, steps] = bisect(fun, x, tol)
% BISECT Zero of a function of one variable via bisection method.
%   bisect(fun,c) returns a zero of the function. fun is a string
%   containing the name of a real-valued function of a single real
%   variable; ordinarily functions are defined in M-files. x is a
%   starting guess. The value returned is near a point where fun
%   changes sign. For example, bisect('sin',3) is pi. Note the
%   quote around sin.
%
%   An optional third input argument seets a tolerance for the
%   relative accuracy of the result. The default is eps. An
%   optional second output arguments gives a matrix containing
%   a trace of the steps; the rows are of the form [c f(c)].

% Initialization
if nargin < 3, tol = eps; end
trace = (nargout == 2);
if x ~= 0, dx = x/20; else, dx = 1/20; end
a = x - dx; fa = feval(fun,a);
b = x + dx; fb = feval(fun,b);

% Find change of sign
while (fa > 0) == (fb > 0)
dx = 2.0*dx;
a = x - dx; fa = feval(fun,a);
if (fa > 0) ~= (fb > 0), break, end
b = x + dx; fb = feval(fun,b);
end
if trace, steps = [a fa; b fb]; end

% Main loop
while abs(b - a) > 2.0*tol*max(abs(b),1.0)
c = a + 0.5*(b - a); fc = feval(fun,c);
if trace, steps = [steps; [c fc]]; end
if (fb > 0) == (fc > 0)
b = c; fb = fc;
else
a = c; fa = fc;
end
end
```

Some of MATLAB's functions are built-in while others are distributed as M-files. The actual listing of any M-file---MATLAB's or your own---can be viewed with the MATLAB command type functionname. Try entering type eig, type vander and type rank.