通过系列求解函数 (SAS)

问题描述

我需要一些帮助来检查我在 SAS 中使用循环来解决函数的程序,因为我正在挣扎。我需要解决函数是级数展开式的,它是:

ln(1+x)

我需要在 x0 = 0.8 处计算函数,并且在下一项小于 0.05 时必须停止求和。

这是我目前所拥有的,但我相信我离我需要的地方还很远:

data sumseries;
numerator = x;
denom =1;
x = 0.8;
do while (tot>abs(0.05));
    numerator=x*numerator;
    denom=denom+1;
    sign=sign*-1
    term=numerator/denom;
    tot=sign*tot+term;
    output;
end;
proc print data=sumseries;
run;

非常感谢任何帮助!

编辑:如果我对这个网站不熟悉,我的编码格式/演示等不符合要求,我深表歉意

编辑:更改名称/值但回复的答案仍然有效

解决方法

我将首先为您提供有关您的方法的指示,然后提供我首选的解决方案。

您的解决方案,更新了我的修复:

data q2;
  *indent please!;
  denom =1;
  x = 0.3;
  *Move this assignment to after x is assigned;
  numerator= x;
  *initialize sign;
  sign = 1;
  *initialize tot;
  tot=x;
  *need an output to start out with;
  output;
  *WHILE change to UNTIL (req. switching >  to <);
  *tot changed to term;
  do until (term < abs(0.000001));
      numerator=x*numerator;
      denom=denom+1;
      sign=sign*-1;
      term=numerator/denom;
      *you want to add (sign*term) to the total,right?;
      tot=tot + sign*term;
      output;
  end;
  *always include a RUN after data steps,even though not required;
run;

proc print data=q2;
run;

我的首选解决方案:

*Use the macro language to define things like starting values;
%let x=0.3;

*let us see how close we get to correct!;
%put %sysfunc(log(1.3));

data want;
  *initialize sum;
  sum = 0;

  *loop until we hit the limit.  The until here is technically unneeded;
  *but I like to include it for clarity;
  do term = 1 by 1 until (abs(new) lt 1e-6);

    *make the new value to be added (x to the power of term,divided by term;
    *times -1 to the power of term plus one to get the right value for the sign);
    new = (((&x)**term)/term) * (-1)**(term+1);
    *stop iterating if the new term would be too small;
    if abs(new) lt 1e-6 then leave;

    *add to the sum now and output;;
    sum = sum + new;
    output;
  end;
  stop;  *stop the data step loop;
run;

顺便说一下,您可能不想输出最后一行,但这应该很容易添加。

,

您可以使用 DIF 函数来比较两个 FIFO 堆叠的项目之间的差异。

示例:

假设将在 100 次迭代内达到模糊 (1e-5)。

data quotient;
  x = 0.3;
  guard = 100;

  numerator = 1;
  denom = 0;
  sign = -1;
  sum = 0;

  * Mercator series:
  * ln(1+x) = x^1/1 - x^2/2 + x^3/3 - x^4/4 + ... ;

  ln_1_3 = log(1+0.3);

  do iteration = 1 to guard until (iteration > 1 and abs(dif(sum)) < 1e-5);
      numerator = x * numerator;
      denom = denom + 1;
      sign = sign * -1;
      term = sign * numerator / denom;
      sum = sum + term;
      output;
  end;

  stop;
run;

proc print data=q2;
run;

enter image description here