Statistical programming, matrix languages, and more

GOTO statement

Reply
Occasional Contributor
Posts: 5

GOTO statement

Hello,

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*/
end;
end;

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,

Nicolas
SAS Super FREQ
Posts: 3,415

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;
x=1;
finish;

start EM(args);
onError={ "if ErrorChecking then do;"
"rc = 1;"
"call push(onerror);"
"resume;"
"end;"
};
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 */
finish;

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;
end;
if err then do; /* error: reinitialize */
print "*** Error occurred...reinitialize ***";
run init; /* regenerate starting values*/
end;
end;
Ask a Question
Discussion stats
  • 1 reply
  • 565 views
  • 0 likes
  • 2 in conversation