Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Hi, The question about a Mata capture has come up at least one other time on Statalist, in the thread starting with http://www.stata.com/statalist/archive/2006-04/msg00739.html At that time (April 2006) the answer was that there is nothing quite like capture in Mata. People with more experience than me might also say that capturing is not the Mata way to do things. And, probably, someone might be along soon to show a better way to do this without capturing. However, I think there are times when capturing makes sense (for example, if testing that a function returns an error when you expect it to). So, I have written a capture function in Mata that works kinda like Stata's -capture-. I don't know if this will give you exactly what you want, but maybe this can be used together with an external variable or a class attribute. The definition of capture() is below. First, an example (make sure break button works before using) //---- begin Mata capture example ---- // Start in Stata (Ado) mode run capture.mata // to define capture() mata void while_func() { while (1) { printf("blah ") } } rc = capture(&while_func(), J(0,0,.)) [this will loop until you press the beak button] rc //---- end Mata capture example ---- capture() takes 1st argument: a function pointer 2nd argument: a vector of pointers to the function's arguments, or an empty matrix if no args 3rd argument, optional: pointer to an initialized variable to hold the function's return value, if needed Now, the file capture.mata //--- begin capture.mata ---- mata class Capture { pointer(function) scalar func_ptr pointer matrix arg_ptrs pointer scalar rv_ptr } capture = Capture() real scalar capture(pointer(function) scalar func_ptr, pointer matrix arg_ptrs, | pointer scalar rv_ptr) { real scalar rc, i, nargs string scalar run_str, arg_template external class Capture scalar capture // Check dimensions of arg_ptrs. It is allowed to be a vector, or // a zero-dimensional matrix if wanting to pass zero arguments. // I.e., J(0,0,.), J(0,1,.) J(123,0,.) are all allowed. if (rows(arg_ptrs) > 1 & cols(arg_ptrs) > 1) { exit(_error(3200, "arg pointers must be vector or zero-dim matrix")) } capture.func_ptr = func_ptr capture.arg_ptrs = arg_ptrs if (args() == 3) { capture.rv_ptr = rv_ptr run_str = "capture mata: *(capture.rv_ptr) = (*capture.func_ptr)(" } else { run_str = "capture mata: (*capture.func_ptr)(" } arg_template = "*(capture.arg_ptrs[%f])%s" nargs = length(arg_ptrs) for (i = 1; i <= nargs; i++) { run_str = run_str + sprintf(arg_template, i, i == nargs ? "" : ",") } run_str = run_str + ")" stata(run_str) stata("local rc = _rc") rc = strtoreal(st_local("rc")) return(rc) } end //---- end capture.mata ---- I've tested this code out, but I'm not quite 100% sure everything works the way it should. James On Tue, Oct 1, 2013 at 1:48 PM, George Vega Yon <g.vegayon@gmail.com> wrote: > Dear Stata listers, > > I've been reading Mata's documentation and I cannot find a way to > simply of working with -capture- block of code. I know that in Stata > one can create -capture- blocks such as > > capture { > ...code... > } > > if (_rc) { > ...code.... > } > > But I haven't seen something like that in Mata. What I'm actually > looking for is to, from within Mata, run a -while- loop and, if the > break key is pressed, do something. > > Checking functions -setbreakintr()-, -resetbreakkey()- and > -breakkey()- I know that I can suppress the break key from > interrupting the program, but as I change its behavior the > -breakkey()- function doesn't captures if the break key has been > pressed (which is what I understand from the Diagnostics section in > the help file). > > I've tried coding somethign like this > > mata: > mata clear > real scalar myfun() { > > /* Definitions */ > real scalar i, j, bk; > real scalar x; > > /* Setting breakkey interrupt off */ > bk=setbreakintr(0); > i=1; > while(!breakkey() & i < 1e4) > for(j=1;j<=1000;j ) x=i; > > /* Restoring breakkey and its mode */ > breakkeyreset(); > (void) setbreakintr(bk); > > return(x); > } > > myfun(); > > end > > For which, once running, I press the key Break, hoping that the while > loop stops, the x value stores the last -i- used and the breakkey > behavior restores; and what I get this message: "Break disallowed at > this time", and the program continues and returns 1e4 (what means that > it stayed in the loop until i=1e4, i.e. the breakkey() value never > changed from 0). > > I know that -setbreakintr(0)- is intended to be used in the same way > that Stata's -nobreak- blocks, but is there any way that I can work > this out using solely Mata? > > Thank you and excuse for any nonsense that I'm probably saying. > > Best regards, > > George Vega Yon > 7 647 2552 > http://cl.linkedin.com/in/georgevegayon > * > * For searches and help try: > * http://www.stata.com/help.cgi?search > * http://www.stata.com/support/faqs/resources/statalist-faq/ > * http://www.ats.ucla.edu/stat/stata/ * * For searches and help try: * http://www.stata.com/help.cgi?search * http://www.stata.com/support/faqs/resources/statalist-faq/ * http://www.ats.ucla.edu/stat/stata/ George Vega Yon 7 647 2552 http://cl.linkedin.com/in/georgevegayon * * For searches and help try: * http://www.stata.com/help.cgi?search * http://www.stata.com/support/faqs/resources/statalist-faq/ * http://www.ats.ucla.edu/stat/stata/

- Prev by Date:
**Re: st: Capture break in mata** - Next by Date:
**Re: st: Capture break in mata** - Previous by thread:
**st: RE: Calculating a pooled odds ratio from an adjusted odds ratio?** - Next by thread:
**st: nested loops with varying degrees of nesting** - Index(es):