2. Writing and Plotting Functions
Now we learn to write functions in Function form: what we wrote in the last section was a raw script.
a = a + 2 is a function. It consists of an input and an output and may be written as a script (as in the last section) or in function form. The pros and cons of writing Function form vs. Raw script has been discussed here (and in many other places).
Writing in Function form is useful if you want to try out or compare different values for a given model, or if you want to use the script as part of another script, so you don’t have to rewrite the thing over again. Bigger models or analyses often just consist of several to many “function calls” written one after the other.
Take the function y = a*x + b
This represents a straight line (you may remember from earlier). To write this as a function, type this into a Script window:
function y = line(x,a,b)
y = a*x + b;
So, the “formatting” of function goes like this:
function outputs = function_name(inputs)
Formatting is just the way to write the line so that Matlab recognises it. For most functions, the formatting is defined in the documentation/help.
It is similar to how we write =ttest(a,b,2) in Excel to run a t-test, =average(array_1, array_2) to find out means. Function_name will become the name of the function AND the file name (.m). Save the file either in the current folder or in a folder on the Matlab search path.
Arrays: Vectors and Matrices
We use arrays all the time. A table in Excel that contains information is an array. It could have a single column or multiple columns. There are three basic types of numerical arrays: Single number (scalar), Vector, and Matrix.
Vectors and Matrices are VERY similar to filling out an excel spreadsheet — it often makes sense to think of them as such. Although this is not the case for matrix algebra. Array space can also be useful for holding information, similar to Excel.
In the Command Window, type this:
R = rand(5) % R is a five-by-five matrix of random numbers between 0 to 1.
^Use “%” for commenting.
You can select a line or lines then use Ctrl-R, Ctrl-T to quickly covert or revert the selected line to/from a comment. Note rand(5,5) is the same as rand(5). Check out the Matlab documentation-help for variants of rand.
rand(1,5) % one row, five columns (row vector) —the numbers in brackets are always row number followed by column number.
rand(5,1) % five rows, one column (column vector)R(2,3) % the element of the second row, third column of R.
R(2, :) % second row of R, all columns
Similarly,
R(2, 3:5) % elements in second row of R, columns 3 through 5
If you want to make a matrix yourself, use [square brackets] to indicate a vector or matrix.
- [3 5 6 7 9 10] or [3 5; 6 7; 9 10] (Note that a semicolon “;” inside of brackets indicate a new row. You may use commas in place of spaces as well).
- [3:9] is the same as [3:1:9] and [3,4,5,6,7,8,9]
- [3:2:9] is the same as [3,5,7,9] (3 to 9 in intervals of two)
You may use the function linspace to create a vector of x values between a and b. i.e. linspace(a,b,x)
If you want to multiply element-by-element from two matrices or vectors: element wise multiplication/division (i.e. 1st element of A by 1st element of B, 2nd by 2nd, and so on). Simply add a full-stop before the * or / sign:
A = linspace(6,9,5)
B = linspace(2,6,5)
C = A.*B
D = A./B
Note: There is no such thing as matrix division in matrix algebra, but there is matrix multiplication.
Completing and plotting our linear function
Let’s go back to our linear function.
Click the drop down menu next to Run, then click on type code to run. Next, type in values for x, a and b
e.g. line (0.1, 2, 7)
^Note that this will also work if you manually type it in the Command Window.
Congrats! You’ve written your very own function!
As long as the (.m) file is located on the search path, your function will work whenever you open up Matlab. If it doesn’t, you may have to open the file manually and then run it first.
NOTE: Don’t use “linear” as an (.m) name. It will expect that your inputs are string or cell variables.
You’ll get an output for y in return.
How about over a range of values for x (and subsequently y as well)?
After all, drawing a linear plot will require x and y to be across a range of values anyway. Well, a and b can stay as constants (single values — not a vector or a matrix).
We only need to change x (x-axis) into a vector containing a range of values (instead of a constant), say every integer from -10 to 10. We can do this in a number of ways. One of which is x = [-10:10]. Another way is to create ‘n’ number of equal sized spaces between -10 and 10 using linspace. In certain cases you’d want more data points in your plot and linspace is good for that.
Now we want to define x in the function — x doesn’t need to be inside the function line anymore. Alternatively, you may leave x in the function line but you do have to input x as [-10:10] manually (see figure above).
We want to define x first before using it. Like this:
If you swapped Line 3 and Line 4 around, Matlab will throw a mini-tantrum. It will question you about what x actually is.
Next, we plot with the Matlab function plot. Plug in these lines at Line 6:
figure % Creates a new figure
plot(x,y)
Remember that x and y must both be vectors of the same size for the plot to work (you can check the size of x and y at the Workspace, or at the Command Window by typing x and then press enter, and y and then press enter. Are they the size you want? ←note: can use size(a) or length(a)). If x is a vector, y will also become a vector
The figure line can be omitted if you don’t mind overwriting figures from previous runs. If you ever find your screen cluttering up with figures, close them with close all in the Command Window.
The idea is the same for more complex models. Essentially it is just a few more variables, and a few more plots.
In the next section we look at loops, and learn about what we can do with them.
R
- Writing functions
addition = function(a,b)
{return (a + b)}
Slightly different arrangement compared to Matlab. { } are vital. *See next section for an example in R.
Note: ‘return’ specifies that’s the output — the last expression in the function gets returned anyway.
( function y = addition(a,b)
y = a + b; ) - Commenting
‘#’ for commenting (← %).
Ctrl-Shift-c comment-uncomment selected/line (← Ctrl -r and Ctrl-t) - clc/clear all
Ctrl-L (← clc)
rm(list=ls()) See rm function. (← clear all)
Note there is a ‘point + click’ option at the environment pane. - Vector
a = 0:10 and a = 1:3:10 (← same as Matlab)
a = c(1,5,3,4,8) commas are vital in R. ( ← a = [1 5 3 4 8] )
a[2] ( ← a(2) ) a[2:4] ( ← a(2:4) )
b = a[-3] negative indexing excludes the element. ( ← b = a; b(3) = [ ] )
seq(1,10,length=7) ( ← linspace(1,10,7) ) - Matrix
b[ ,3] all rows third column ( ← b(:,3) )
b = matrix(c(2,5,3,6,4,7), nrow=2, ncol=3) or
b = array(c(2,5,3,6,4,7), dim = c(2,3))
or the crisper — b = rbind(c(2,3,4),c(5,6,7))
← ( b = [2 3 4; 5 6 7] or b = reshape([2 5 3 6 4 7],[2,3]) )
R fills out matrix by columns first. Can do via rows first by including an option ‘byrow’. Check out the R documentation for matrix. You’ll see the default setting for byrow is FALSE.
b = matrix(c(2,3,4,5,6,7),nrow=2,ncol=3, byrow = TRUE)
- Random numbers
matrix(runif(9),3) matrix of 9 elements, 3 columns ( ← rand(3,3) )
runif numbers from random uniform distribution (← rand)
rnorm numbers from random normal distribution(← randn)
matrix(sample(1:15, replace = TRUE), nrow = 3, ncol = 3)
(3,3) matrix of random integers 1:15 ( ← randi([1 15],3,3) )
Note: ‘replace = TRUE’ specifies replacement after picking (numbers are repeatable). The default setting/argument is ‘replace = FALSE’. - Element-wise multiplication
a*c (← a.*c)
a %*% c matrix multiplication (← a*c) - Plotting functions
plot(x,y) (← same as Matlab)
New figure pane dev.new() (← figure)
Close all open figure windows graphics.off() (← close all )
Add more lines to a figure points(x,y) or lines(x,y) (← hold on)