Statalist


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

Re: st: RE: Recursive program calls and the return list


From   "Sergiy Radyakin" <serjradyakin@gmail.com>
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: RE: Recursive program calls and the return list
Date   Tue, 21 Oct 2008 14:50:43 -0400

On Tue, Oct 21, 2008 at 1:45 PM, Nick Cox <n.j.cox@durham.ac.uk> wrote:
> Notwithstanding good advice from others, it seems to me that a much
> simpler way to proceed is to use globals.
>

( And then you don't need -recr- to be an rclass program :)

There are plenty of alternative solutions for this task: one can
append rows to a matrix (matrices are 'global'), append lines in a
text file, accumulate values in a list (passed from one iteration to
the other), etc.

In general however, recursive algorithms are not very efficient though
often quite elegant. Mike might want to see if recursion is really
necessary in his case. After that he will need to check if his maximum
recursion depth fits into Stata's limits (which is quite moderate,
IMHO): ~64:

 program define recurs
   display `1'
   recurs `=`1'+1'
 end

 recurs
1
2
..
63
system limit exceeded - see manual
r(1000);

See: help limits
I presume it is: "# of nested do-files" and in Stata 10 it is 64.

If more recursion is necessary, Mike might want to switch to Mata,
where the limit is much higher (thousands). Not sure how much higher,
however: Stata crashes if recursion is too deep:
*******************************
mata
void function f(real x) {
  x
  f(x+1)
}
*******************************
f(1) /* crashes Stata */

which (I assume) is a bug. Until it's fixed, Mike will have to be very
cautious about using recursive algorithms in Mata.

Best wishes,
   Sergiy Radyakin

> cap prog drop recr
> prog recr, rclass
>    args count stopit
>    if `count' == `stopit' {
>      global something`count' = -99
>    }
>    else {
>      global something`count' = uniform()
>      local k = `count' +1
>      recr `k' `stopit'
>    }
> end
> // Start count at 0, run 5 times
> recr 0 5
> mac list
>
> Nick
> n.j.cox@durham.ac.uk
>
> Mike Lacy
>
> I've been experimenting with implementing recursive calls to a Stata
> program, and in particular, getting the program to store something in
> the return list at each call, so that at the end of program, the
> return list would contain r(something1) , r(something2), ...,
> r(somethingNumberOfCalls).  I have experienced various difficulties
> in not clobbering the return list.  Here's a simple example to
> demonstrate one of the problems I have had:
>
> ///  A "do nothing" recursion example; recur calls itself "stopit"
> times,
> // and tries to return something each time in the locals something0,
> // something1, something2, ..,  but only "something0" shows up in the
> return list
> cap prog drop recr
> prog recr, rclass
>    args count stopit
>    if `count' == `stopit' {
>      return local something`count' = -99
>    }
>    else {
>      return local something`count' = uniform()
>      local k = `count' +1
>      recr `k' `stopit'
>    }
> end
> // Start count at 0, run 5 times
> recr 0 5
> ret list
>
> macros:
>         r(something0) : ".2769154107663781"
>
> How could this be changed so as to accumulate something in the return
> list at each recursive call?
>
>
> *
> *   For searches and help try:
> *   http://www.stata.com/help.cgi?search
> *   http://www.stata.com/support/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/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