Statistical programming, matrix languages, and more

GOTO statement

Occasional Contributor
Posts: 5

GOTO statement


In order to estimate mixture models i need to generate multiple random starts and estimate the local maxima of the likelihood by the expectation-maximization algorithm. Thus, i have two loops, one outer loop for a particular set of starting values and an inner loop for the EM iterations. For some bad start values the EM-iterations encounter computational problems such as singular matrices, overflows,.. This is not a problem, just discard these start values and try a new set. I try to do this as follows:

onerror=" goto st; resume; ";
do s=1 to n_start;
call push(onerror);
st: run start; /*some module to generate start values*/
do e=1 to em_iterations;
run em; /*some module to perform 1 EM-iteration*/

This however doesn't work and i get ERROR: Unresolved label: ST. I've also tried
onerror=" do; goto st; resume; end;"; but that doesn't work either.

Does anyone have an idea how to make this work (or knows a better way to go about this)?

Thanks in advance,

Posts: 4,175

Re: GOTO statement

I think the fundamental problem is that the error occurs in the EM module, but you are trying to jump to a statement outside of the module. that's why the ST label is not recognized.

What I like to do is to have the module that might fail return a "return code" that can be handled by the calling routine. In the code below, I use a DO/WHILE loop to jump out of the iterative loop when the EM module fails. I then call the INIT routine and continue to the next set of starting values.

proc iml;
start init;

start EM(args);
onError={ "if ErrorChecking then do;"
"rc = 1;"
"call push(onerror);"
call push(onError);
rc = 0; /* return 0 if no error */
ErrorChecking = 1; /* turn on error checking */
t = log(0.75-uniform(54321));/* error 25% of the time */
ErrorChecking = 0; /* turn off error checking */
return (rc); /* return whether error occurred */

myargs = {1,2,3};
run init;
do s=1 to 3;
err = 0; /* no error */
do e=1 to 5 while(err=0); /* exit loop on error */
err = EM(myargs); /* perform 1 iteration*/
print s e err;
if err then do; /* error: reinitialize */
print "*** Error occurred...reinitialize ***";
run init; /* regenerate starting values*/
Ask a Question
Discussion stats
  • 1 reply
  • 2 in conversation