问题描述
我需要一些帮助来检查我在 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;