Yesterday I showed you how to write Mata functions. Today we will look at how they work with Stata.

In interactive mode, a Mata function like mymulti() is called simply as

mata: mymulti(st_matrix("first"),st_matrix("second"))

This assumes that the two matrices are Stata matrices previously declared and currently in memory. Mata and Stata matrices are different things. Mata needs this translator function, st_matrix(), to read Stata matrices. The call above will output to screen the matrix resulting from multiplying the two matrices, if they're conformable, or will give you an error message if they're not.

What if you want to save this result into a proper Stata matrix? You will want to set up a shell matrix of the correct size, using the J() matrix function, as in

matrix third=J(r',c',0)

The r' and c' locals will have to be right -- r' will be the number of rows of first, c' the number of columns of second. Once that's in place, Mata will replace the zeroes with all the right figures like so:

mata: st_matrix("third",mymulti(st_matrix("first"),st_matrix("second")))

As you guessed, Mata uses the same st_matrix() translation function for two different jobs: if you call it with a string argument it will attempt to read the Stata matrix with that name. If you call it with two arguments separated by a comma, it will replace the Stata matrix named as in the first argument with the contents of the matrix resulting from the second argument -- which can either be a currently existing matrix, or it can be a result derived from a function like mymulti().

Then there all the other things you can already do with Stata's programming capabilities. You could, for example, encapsulate all the Mata business into programs that your clients can use blissfully oblivious that there's Mata stuff under the hood, like so:

capture prog drop matrixMultiplication
prog def matrixMultiplication

version 10
args first second
mata: mymulti("first'","second'")

end

I kept the same argument names for convenience, but you probably figured out already that they're local to the Mata function and the Stata program respectively. You could have defined the program above as

capture prog drop matrixMultiplication
prog def matrixMultiplication

version 10
args foo bar
mata: mymulti("foo'","bar'")

end

And it would have worked just the same. Finally, if the client's matrices are called A and B, that's fine. They can be multiplied either with

mata: mymulti(st_matrix("A"),st_matrix("B"))

or with

matrixMultiplication A B

That is the beauty of encapsulation. Locals are local to whatever function or program definition uses them. You can call them any names you want outside those definitions, and they will still work. This is very helpful if you write numerous pieces of separate code that need to work with each other -- or if you have several people working on the same project. They only have to share their functions' and programs' names and syntax and need not worry about any of the guts.