在 SAS 中实现递归二分法

Implementing recursive bisection in SAS

这里是第一个问题。

基本上,我想通过使用宏在 SAS 中实现递归二分算法。我已经编写了一个宏,它接受两个参数(当前区间的下端点和上端点)并生成一个 table 包含另一个区间的两个端点。我遇到的问题是编写一个宏来迭代这个过程,直到间隔的宽度低于某个阈值。

这是我目前所知道的,但是代码没有像我预期的那样工作。请记住,我所学的 SAS 知识的 99% 都是在过去三天左右学到的。非常感谢任何可以提供帮助的人!

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;

其中 %nextint(&a0,&b0) 产生一个 table interval 和一个观察值,两列 ab 的值从 &a0&b0。如您所见,SAS 对我来说完全是个谜,我不知道自己在做什么。

我建议您查看 SAS/IML 语法来进行数值分析工作。

Rick Wicklin 的

This blog 解释了如何使用 SAS/IML 求函数的根。

如果您仍想使用宏和数据步骤,可以使用 options mprint; 语句来调试您的代码并在日志中查看哪些命令实际上是 运行.

不确定你的宏 %nextint 是做什么的,但我写了一些东西只是为了展示 %iter 宏将如何运行。

您需要将这些调用 symput 放在数据步骤中。

我在这里使用null只是为了从区间数据集中获取宏变量a0和b0的新值。

注意,这将生成具有第一组 a 和 b 值的区间数据集,其中 b - a 小于 0.0001。

宏末尾的 %put 语句将显示每次交互时 a 和 b 的变化值。

    %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);