In my quest to understand recursive programming in SAS, I have tried, unsuccessfully many times, to write a version of a two-argument Ackermann function.
The function states that:
I was only going to calculate m & n for values ranging from 0 - 3, as values of m >= 4 cause the returned values to become large very rapidly.
I was shooting for a relatively simple output; something like:
Ack(0,0) = 1
Ack(0,1) = 2
Ack(0,2) = 3
Ack(0,3) = 4
Ack(1,0) = 2
Ack(1,1) = 3
And so on to Ack(3,3) = 61
I was unable to find any reference online to someone doing this in SAS. So, if someone could help me with this, I would really appreciate it!
Thanks!
It is difficult to do recursion in normal SAS code. But it is easy in macro code.
%macro a(m,n);
%if %sysfunc(verify(&m.&n,0123456789)) %then %do;
%put WARNING: Invalid input to macro &sysmacroname.. Use only non-negative integers.;
.
%end;
%else %if (&m=0) %then %eval(&n+1);
%else %if (&n=0) %then %a(%eval(&m-1),1);
%else %a(%eval(&m-1),%a(&m,%eval(&n-1)));
%mend a;
If you must use it with the values of dataset variables then you might consider using the resolve() function.
data testa;
do i=0 to 3; do j=0 to 3;
a=input(resolve(cats('%a(',i,',',j,')')),32.);
output;
end;end;
run;
proc print; run;
Results
Obs i j a
1 0 0 1
2 0 1 2
3 0 2 3
4 0 3 4
5 1 0 2
6 1 1 3
7 1 2 4
8 1 3 5
9 2 0 3
10 2 1 5
11 2 2 7
12 2 3 9
13 3 0 5
14 3 1 13
15 3 2 29
16 3 3 61
Of course if you are only ever going to use arguments from 0 to 3 then perhaps you just need to use an array lookup instead.
data testb;
array _a(0:3,0:3) _temporary_
(1 2 3 4
2 3 4 5
3 5 7 9
5 13 29 61
);
do i=0 to 3; do j=0 to 3; a=_a(i,j); output; end; end;
run;