# Lab 5

## Functions

So far we have only used MATLAB's built-in functions. In this lab, we will learn how to create our own functions.

### Defining Functions

Conceptually, a function takes some inputs and produces some outputs. For example, the input to the sin function is a matrix of numbers and the output is the sine of those numbers. Similarly, the round function will take any matrix and return the rounded values of the entries in that matrix. Some functions require more than one input (also called an arguments). For example, setdiff takes vectors A and B representing sets and returns the elements in A that are not in B, i.e., the set difference. Some functions have optional inputs, e.g., sum(A) vs. sum(A,2). Some functions have all optional inputs, e.g., rand(3,4) vs. rand(3) vs. rand().

 Q1: Let A = [1 2 3; 4 5 6; 7 8 9]. What's the difference between sum(A) and sum(A, 2)? Q2: Let x = [6 9 3 1 5 2 9 9 3 2]. The sort function sorts in ascending order. So if y = sort(x), then y = [1 2 2 3 3 5 6 9 9 9]. How do you call sort to sort x in descending order?

In MATLAB, as opposed to many other programming languages a function can have more than one output, e.g., [row,col]=find....

In order to create a MATLAB function, we first need to define the function's inputs and outputs. The basic pattern is:

```function [output1, output2,...] = FuncName(input1, input2,...)
% Help documentation
...
<function body and all its code starts here> ```

Note that you cannot create functions at the command prompt. Functions must be saved in .m files.

For example, if we wanted to create a function that takes a number as an input, adds six to that number, and outputs the resulting number, we would write:

``` function out = addsix(in)
% This function adds 6 to the input.
out = in + 6;  ```

After the function is defined, we can call it from the command window: b = addsix(2);  which would result in the value of b becoming 8. We could then call the function again: c = addsix(b). If we type help addsix, MATLAB will respond with "This function adds 6 to the input." Note that the variable names for this example are arbitrary, and the function could also be defined as:

```function clayton = addsix(brentwood)
% This function adds 6 to the input.
clayton = brentwood + 6 ```

Note that the name of the function has not been changed so the calls to the function from the command window would still be the same (b = addsix(2); and so forth).

IMPORTANT: Functions should be saved in a .m file with the same name. MATLAB always uses the file name that contains a function and ignores the declared name.

 lab5_1: Create a function that takes a vector and returns the same vector in reverse order. You will need to use one of the following functions: end, size, or length. If you're not sure how to do this, see the "Using Vectors to Access Vectors" section in Lab 1. Give your function an appropriate name and documentation for help. Note that your script should not be named lab5_1.m. isHSudoku.m: You may have heard of the game Sudoku, in which you must fill up the rows and columns of a matrix so that all the rows and columns add up to the same number. (This is only part of the definition of a Sudoku matrix, which is why we will call this "half-Sudoku" or h-Sudoku). Note that we ignore the diagonals in this exercise! For example, the matrix below is a legal matrix in h-Sudoku, because all the rows and columns each add up to the same number (in this case, they all add up to 15): 8 1 6 3 5 7 4 9 2 Your task is to create a function, called isHSudoku that will check whether or not a matrix is a legal h-Sudoku matrix. The function's input will be the matrix you want to check, and the output will be a boolean value: 1 if the input is a legal h-Sudoku matrix, and 0 otherwise. You can assume a square matrix (any size), and you do not have to check the diagonals or ensure unique digits. In order to compose the body of the function, you will need to use Boolean operators (things like ==, ~=, |, &, ~) and the function sum. Do not use if, while, or for statements. Work through the next section before demonstrating isHSudoku.m to the TA or instructor.

### Testing Functions

The most straightforward way to test a function is to give the function an input for which you know the output. Given a test matrix m, you can test your function at the command prompt:

isHSudoku(m)

If matrix m is a legal Sudoku matrix, the return value should be 1, otherwise it should be 0.

In order to gain confidence in your implementation, you should test with a variety of inputs. In this problem, you should use both valid h-Sudoku and invalid h-Sudoku matrices.

We have already provided you with one legal matrix:

matLegal = [8 1 6; 3 5 7; 4 9 2];

You can use any non-legal Sudoku matrix to test whether your function will correctly return 0.  Here is an example you can use:

matNotLegal = [1 2 3; 1 1 4; 2 2 2];

The transpose of this matrix is also not legal.

matNotLegal2 = matNotLegal';

These matrices are good test matrices because they are legal in one dimension but not the other. That is, one matrix is a positive test and the other is a negative test.

We can also use some built-in MATLAB functions to help us test our isHSudoku function. Try both of these commands:

isHSudoku(magic(5))
isHSudoku(round(10 * rand (5)))

 Q3: Let k be an integer greater than 2. Will isHSudoku(magic(k)) ever return false? Will isHSudoku(round(10 * rand (k))) ever return true? lab5_2.m: Write a script that tests your isHSudoku function using the matLegal, matNotLegal, matNotLegal2, magic and rand.

### nargin and nargout

One of MATLAB's coolest features is its capacity to create functions with a variable number of inputs and outputs. Various labs have shown how the function's behavior can be changed by adding new inputs, e.g., sum(M) vs. sum(M,2), or outputs, e.g., lin_idx=find(M==0) vs. [row,col]=find(M==0). In the first section, we created a simple one-input, one-output function. In this section, we will learn how to build functions with a variable number of inputs and outputs.

The key is the use of two MATLAB keywords: nargin and nargout. These operators are defined only within the context of a function. nargin specifies the number of arguments handed as input and nargout specifies the number of arguments handed as output. Therefore, we can adjust the computation in the function according to the way it was called.

Save this code in a file called tryme.m in your current working directory. Try calling this function with various inputs and outputs.

```function [out1,out2]=tryme(in1,in2)
% This function demonstrates the use of nargin and nargout
% Written by Tom Erez, Sept. 2008.

if nargout==0
disp('nice try, buddy')
return
end
if nargin==2
if nargout<2
out1=in1.*in2;
else
out1=in1./in2;
out2='what else do you want?';
end
elseif nargin==1
out1=in1+5;
out2='meaningless';
else
out1='if two outputs were requested in this case, this function would result in an error';
end```

The computation itself is, evidently, meaningless. However, note how the function behaves in different ways according to the different inputs and outputs. Also, note the use of the operator return.

 Q4: Run tryme for all combination of 0, 1, and 2 inputs and 0, 1, and 2 outputs. For example, the call [x, y] = tryme (9) calls the function with 1 input and 2 outputs. Be able to describe how this function works. Q5: What does the return statement accomplish (Hint: help return)? What happens when you remove it?
 Demonstrate Q1-Q5 and lab5_1.m, lab5_2.m, isHSudoku.m to the TA or instructor, and answer some questions to checkout.