m-Files are appropriately named as they refer to any
file with suffix `.m`. They can be used to define
scripts and functions.

If you save a sequence of commands to a file `name.m`,
then whenever you type:

>> name

is the same as if you had entered in all the lines of the file
`name.m` at the command line.

This can be used to perform repetitive tasks, such as
creating the matrix for a simple linear regression. For
example, save the following to a file `lr.m`:

A = [x, ones(size(x))]; c = A \ y

Then, if in Matlab you type:

>> x = (1:10)'; >> y = [1.30 2.39 3.46 4.36 5.08 6.20 7.46 8.45 9.20 10.44]'; >> lr c = 1.0018 0.3240

You can also use this to set up an environment. For example,
if you are regularly using some constants, you could create
a file `mycons.m`:

% MYCONS Defines some variables Na = 6.0221367e23; % Avagadro's number c = 299792458; % speed of light g = 9.80665; % acceleration due to gravity mph = .44704; % 1 mph = 0.44704 m/s kmph = 5/18.; % 1 km/h = .27777777 m/s

Idea taken from Recktenwald.

Normally, if you run a `.m` script, on the output
not suppressed by semicolons is shown. If you want to see
the input as well as the output, type:

>> echo on >> name

In this case, the script is saved to the file `name.m`.

A function in Matlab takes 0 or more arguments and is
called by its name with the arguments in parentheses. For
example, `sin(3.2)`.

There are two types of functions: built in and **.m**
functions. Built in functions are programmed into Matlab in
C, while **.m** functions are saved in files with the
same name as the function. For example, if you wanted
to write a function which evaluated the expression
`f(x) = x^2 - 4*x*sin(x) + 7*sin(x)^2`, you would
save the following to a file `f.m`:

function y = f(x) % F Some function. % F(X) evaluates the scalar X at X^2-4*X*sin(X)+7*sin(X)^2 y = x^2 - 4*x*sin(x) + 7*sin(x)^2;

Looking at the output, we note the following:

- The first line contains the key word
`function`followed by`y = f(x)`. The`y`is the output variable and the`x`is the argument. - Some comments. Any comments immediately following the
the
`function`line are displayed when the user types`help f`. - The body. In the body, the expression is evaluated and assigned to the output variable.

Note, the name of the function and the name of the file must
match. If you save a function `F` to a file called `f.m`,
Matlab will not find it when you type `F(3.2)`.

As expected, a function can have more than one argument.
What is interesting is that a function can also have more than
one output variable. The following example has two output
variables. Save this to a file `g.m`

function [a, b] = g(x) % G Some function G. % Evaluate sin(x) and cos(x) a = sin(x); b = cos(x);

Note: the comma in row vector is necessary in the definition.

At this point, you can type into matlab:

>> [st ct] = g(3.252) st = -0.1102 ct = -0.9939

If you now type only `g(3.252)` or `st = g(3.252)`, you
only get the first argument assigned to. The other result
(`cos(3.252)`) is discarded.

You may have noted this with the `max` function. If the
output is assigned to two variables, the second variable is
assigned the position where the maximum occured.

In this case, the function can determine how many output arguments
it is being called with, and may assign the output accordingly.
The variable is `nargout`. In the next example, we will
rewrite `g` so that if it is called with two output variables, it
assigns them appropriately, but if it is called with zero or one
output variables, it returns a vector with the two answers:

function [a, b] = g(x) % G Some function G. % Evaluate sin(x) and cos(x) if nargout == 2 a = sin(x); b = cos(x); else a = [sin(x), cos(x)]; end

Now, when you do:

>> g(3.242) ans = -0.1002 -0.9950 >> stct = g(3.242) stct = -0.1002 -0.9950 >> [st ct] = g(3.242) st = -0.1002 ct = -0.9950 >> [a b c] = g(3.242) ??? Error using ==> g Too many output arguments.

In the last example, we assigned the output to three variables, in which case, Matlab raised an error message.

You can see this with the `size` function. If the output
is assigned to either zero or one variables, then a vector of the row
and column dimensions is returned. If the output is assigned to two
variables, those variables are assigned the row and column dimensions,
respectively:

>> A = rand( 10, 20 ); >> size( A ) ans = 10 20 >> a = size( A ) a = 10 20 >> [m, n] = size( A ) m = 10 n = 20

You may have already seen this with the `lu` function,
for example. If the output of `lu(A)` is assigned to either zero or
one variables, then the sum `L - eye(size(A)) + U` is returned
as one matrix. If the output is assigned to two arguments, then
`P^-1 * L, U` are assigned to the two output variables, and
finally, if the output is assigned to three variables, the
variables are assigned the `L, U, P` matrices, respectively.

A function can also tell how many arguments it is being called with.
For example, the `diag` function behaves differently if it is
called with two arguments instead of with just one. You can check
for the number of arguments a function is called with by the variable
`nargin`. Save this file to a file called `hilbert`:

function H = hilbert( N, a ) % HILBERT Hilbert matrix % HILBERT(N) creates the N by N matrix with elements 1/(i+j-1) % HILBERT(N, a) creates the N by N matrix with elements 1/(i+j+a) % The function HILBERT(N) is identical to HILBERT(N, -1) H = zeros(N); if nargin == 1 aa = -1; else aa = a; end % This is inefficient, but good for demonstration purposes for i=1:N for j=1:N H(i,j) = 1/(i + j + aa); end end

Any line of a function which does not have its output suppressed with a semicolon is displayed when the function is run. This is a good way of debugging your code.

Use comments liberally through your code so that next week, when you read your own code, that you remember what you did. For example, the above hilbert code is much more efficiently implemented as:

H = zeros(N); invs = zeros(1,2*N-1); for i=1:2*N-1 invs(i) = 1/(i + 1 + aa); end for i=1:N H(i,:) = invs(i:(i+N-1)); end

but in two weeks, you'd be hard pressed to remember that that is what this code did.

Out of interest's sake, the optimized version above takes approximately 1 second to create a 1000x1000 Hilbert matrix, whereas the original code (using two for loops) takes approximately 45 seconds.