Any code written in Matlab needs to be somehow organized. As you grow your program, it becomes essential to write functions. Functions are elementary pieces of computations that take inputs, process them and send the result out. As you can reuse them multiple times, they are essential to provide structure to your program and allow to grow the complexity of it but most importantly make your life easier. In this post, I explain the basics of using functions in Matlab.
Programmers are usually very lazy people that hate repetitions. These are the kind of guys that could spend hours working out a way to automate a process that could be done manually in minutes. Although it could seem strange (I know, I have been there), they have very good reasons for that : Computer are machine of automation, they are designed to scale up very efficiently. But to scale up, every process needs to be well designed in the first place. As you learn more about programming, this is a mind game that you will inevitably slowly acquire : there is inherent beauty in a well organized program that nicely grow its roots from very well written elementary piece of computation.
As an aside, this is one of the reason I am working in Neuroscience (although I love programming too) : I am convinced the underlying computational blocks of the brain are going to be pure beauty and I would love to see that knowledge unfold in the next decades.
In programming, building these blocks is done using functions or subroutines. Apart from the aforementioned aesthetic, functions are essential to :
- Organize your overall program.
- Make it easier to maintain and read.
- Allow to very efficiently optimize separated calculations/processes.
Alright, I have done my preaching. Let’s be a little more practical. How to get started with this?
I am going to present you two ways to make functions : first I’ll show you how to create an independent M-file and then how to create local sub-functions. Keep in mind that this is just a subset of all possibilities, but it’s a good start.
I thought I would use a nice and entertaining example for all this.
There are some rumors that Georges Lucas used an algorithm to pick the name of his Star Wars character as follow :
How to determine your "Star Wars" name: For your new first name: 1. Take the first 3 letters of your 1st name and add 2. the first 2 letters of your last name For your new last name: 3. Then take the first 2 letters of your Mom's maiden name and add 4. the first 3 letters of the city you were born
In the following, we are basically going to convert this scheme into Matlab code.
As you can tell, you need 4 inputs : Your first name, your last name, your mom’s name and your birth place.
In classical scripting fashion (without functions), you would do :
FirstName='John'; LastName='Smith'; MotherMaiden='Hopkins'; BirthPlace='New York'; JediFirst=[FirstName(1:3),LastName(1:2)]; JediLast=[MotherMaiden(1:2),BirthPlace(1:3)];
Please consult my post on strings if you need to understand what is going on.
With this, John Smith becomes Johsm Honew.
My own jedi name is : Jerle Besan (Sorry, you won’t get to know my mother maiden name).
Of course, you might want to use that code easily and creating a function makes a lot of sense here. To do so, we need to takes all 4 inputs and send the result out. So create a file named FindJediName.m (it is important to name your function file with meaningfull names), and fill it with :
function [JediFirst,JediLast]=FindJediName(FirstName,LastName,MotherMaiden,BirthPlace) JediFirst=[FirstName(1:3),LastName(1:2)]; JediLast=[MotherMaiden(1:2),BirthPlace(1:3)];
Already, our code is getting nicer. We have separated the parameter declaration from the calculation of the name. Remember that your M-file must be named after your function name (declared after function). Note how all inputs are passed in between the ( and ). The output are also declared both on the left of the = as within your function. Not respecting this syntax will lead to errors. As oppose to C or C++, Matlab does not require you to deal with the data type that you pass in and out of the function. It just requires a name.
To use this function, the M-file must be saved and available within your search path (or in the current directory).
Then all you have to do, from the Matlab command line is :
>> [First,Last]=FindJediName(‘John’,’Smith’,’Hopkins’,’New York’)
I am sure you noticed that I used a different name to store the output (First and Last instead of JediFirst and JediLast). This is actually a very important concept that you must understand. Functions actually create a separated memory space for their code to run. This means that all variables are passed around by value not by their name. There is a lot more to say about this (many things happen in the background like Copy On Write), but let’s keep things simple for today.
Now that you have your first function running. You can use it anywhere you want. You can call this function from the command line, from a script M-file or even from another function file. This function is indeed public.
You can also, if you need, create local sub-function that are only available to the current function. You might want to do so if the scope of your code is only local. In this example, you might want to create 2 sub-functions : One that calculate your Jedi first name and one for the last name.
This is quite easy :
function [JediFirst,JediLast]=FindJediName(FirstName,LastName,MotherMaiden,BirthPlace) JediFirst=FindJediFirstName(FirstName,LastName); JediLast=FindJediLastName(MotherMaiden,BirthPlace); end function FirstNameOut=FindJediFirstName(FirstNameIn,LastNameIn) FirstNameOut=[FirstNameIn(1:3),LastNameIn(1:2)]; end function LastNameOut=FindJediLastName(MotherMaidenIn,BirthPlaceIn) LastNameOut=[MotherMaidenIn(1:2),BirthPlaceIn(1:3)]; end
Please note, how I played around with the naming of inputs and outputs. This is not to confuse you, but to make sure you understand you are free to choose them independently.
Please also note the appearance of the end statement. This is now required to delineate the beginning and the end of each function.
FindJediLastName will only be available to functions within the M-file, not outside. ONLY
FindJediName (the one named after the file itself) is available from outside.
Sub-functions declared like this do not have accessed to all variables that the calling function have. You still need to pass all required variables as inputs.
To avoid this , you will have to nest them like so :
function [JediFirst,JediLast]=FindJediName(FirstName,LastName,MotherMaiden,BirthPlace) JediFirst=FindJediFirstName(); JediLast=FindJediLastName(); function FirstNameOut=FindJediFirstName() FirstNameOut=[FirstName(1:3),LastName(1:2)]; end function LastNameOut=FindJediLastName() LastNameOut=[MotherMaiden(1:2),BirthPlace(1:3)]; end end
Note how the end statements are now nested. All sub-functions now have access to all variables of the big functions.
So, what is your jedi name?