3

First question here.

Basically, I want to implement a recursive bisection algorithm in SAS via the use of macros. I have already written a macro that takes two arguments (the lower and upper endpoints of the current interval) and produces a table containing the two endpoints of another interval. The problem I'm having is writing a macro that will iterate this process until the width of the interval is below a certain threshold.

Here is what I have so far, but the code does not work as I expect. Bear in mind, 99% of everything I've ever learned about SAS, I learned in the past three days or so. Much thanks to anyone who can help!

data interval;
     input a b;
     datalines;
          0 1
          ;
run;

%macro iter(a,b);
data rec;
     set interval;
     %let a0 = &a;
     %let b0 = &b;
     %do %while(%sysevalf(&b0 - &a0) > .00001);
          %nextint(&a0,&b0);
          call symput('a0',trim(left(a)));
          call symput('b0',trim(left(b)));
     %end;
run;
%mend;

where %nextint(&a0,&b0) produces a table interval with one observation, and two columns a and b with the values calculated from &a0 and &b0. As you can see, SAS is a complete mystery to me and I don't know what I'm doing.

heropup
  • 133
  • 3
  • Can you add some iterations? Also what does nextint do, are you sure it's working properly? This may be more appropriate for a data step with a custom function via PROC FCMP – Reeza Jan 16 '15 at 18:24

2 Answers2

3

Not sure what your macro %nextint does, but I wrote something just to show how the %iter macro will run.

You need to put those call symput's in a data step.

I used null here just to get new values for the macro variables a0 and b0 from the interval data set.

Note, this will produce the interval data set with the first set of values for a and b where b - a is less than 0.0001.

The %put statements at the end of the macro will show you the changing values of a and b for each interation.

    %macro nextint(a1,b1);
        data interval;
            a = &a1. + 0.1;
            b = &b1. - 0.1;
        run;
    %mend;


    %macro iter(a,b);
        %let a0 = &a.;
        %let b0 = &b.;
        %do %while(%sysevalf(%sysevalf(&b0. - &a0.) > 0.0001));
            %nextint(&a0,&b0);
            data _null_;
                set interval;
                call symput('a0',strip(a));
                call symput('b0',strip(b));
            run;
            %put &a0.;
            %put &b0.;
            %put %sysevalf(&b0. - &a0.);
        %end;
    %mend;

    %iter(0,1);
KnowYourOnion
  • 201
  • 1
  • 3
1

I would suggest that you look into SAS/IML syntax to do numerical analysis work.

This blog by Rick Wicklin explains how you can use SAS/IML to find the root of a function.

If you would still like to use macros and the data step, you can use the options mprint; statement to debug your code and see in the log which commands are actually ran.

jaamor
  • 317
  • 3
  • 15
  • Thank you for your feedback; however, I only have access to base SAS and not IML, which is why I need to implement this particular algorithm. – heropup Jan 16 '15 at 18:18