Statalist The Stata Listserver


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: Novice question about programs and Mata


From   wgould@stata.com (William Gould, Stata)
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: Novice question about programs and Mata
Date   Mon, 05 Feb 2007 09:12:32 -0600

Venable <venablito@gmail.com> tried the following experiment with Mata:

> --- (begin LittleProgram.do-file) ---
> 
> clear
> capture program drop MyLittleProgram
> program define MyLittleProgram
>       args one two
>       mata:
>               one = st_local("`one'")
>               one
>               two = st_local("`two'")
>               two
>       end        
> end
> MyLittleProgram Test1 Test2

But could not make the -end-'s work out.  Included them both, as makes sense,
the the second results in an "unrecognized command" while the program is being
loaded.  Omit the second and the program loads okay, but execution results in
the error "unexpected end of file (end statement missing)".

One solution to Venable's program would be 

        program define MyLittleProgram
                args one two
                mata: one = st_local("`one'")
                mata: one
                mata: two = st_local("`two'")
                mata: two
        end

I am not seriously suggesting that as a solution, but it would work.

I am not suggesting that as a solution for the same reason that Venable would
not think much of me if I did:  (1) it is not very elegant and (2) wouldn't
all those invocation of Mata just slow things down?

Concerning (2), the answer is absolutely yes, but not for the reason you 
would guess.  The reason has to do with the Mata being a compiler.  It is not
the invocation of Mata per se that causes the inefficiency, it is that you are
forcing Mata to look at and compile source code.  To make this clearer,
let's pretend the syntax Venable tried worked and consider the following code
fragment:

        program Example
                ...
                forvalues i=1(1)1000 { 
                        mata:
                                <mata statements appear here>
                        end
                }
                ...
        end

Every time through the loop, which is to say, 1,000 times, Stata would 
feed the uncompiled source <mata statements appear hear> to Mata, and 
Mata would be forced to figure out what they mean (i.e., to compile them).
Compilation takes time.  Much of the speed advantage Mata has over Stata is
because Mata does not usually compile statements over and over again.

Thus, the -mata: ... end- is not allowed in ado-file so that you cannot 
make the construction error shown above.  Said more positively, you 
are forced to write, 

        program Example
                ...
                forvalues i=1(1)1000 { 
                        mata: myfunc(...)
                }
                ...
        end

        mata:
        function myfunc(...)
        {
                <mata statements appear here>
        }
        end

In the above construction, when the program is loaded, Mata is invoked 
once with <mata statements appear here>.  Then, at execution time, 
already compiled function myfunc() is called 1,000 times.

So here is how Venable should have written his LittleProgram.do:

        ------------------------ LittleProgram.do --- begin ---
        clear
        capture program drop MyLittleProgram
        program MyLittleProgram
                args one two
                mata:  LittleFunction("`one'", "`two'")
        end

        mata:
        void LittleFunction(name_of_one, name_of_two)
        {
                one = st_local(name_of_one)
                two = st_local(name_of_two)
                one
                two
        }
        end
        ------------------------ LittleProgram.do ----- end ---

The proper from takes more lines, but it will execute more quickly.

By the way, in certain circumstances, there is nothing wrong with writing

        program define MyLittleProgram
                args one two
                mata: one = st_local("`one'")
                mata: one
                mata: two = st_local("`two'")
                mata: two
        end

The inelegance of having to type -mata:- over and over reminds you of 
the inelegance of the compiled result.

-- Bill
wgould@stata.com
*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index