Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
138 views
in Technique[技术] by (71.8m points)

loops - Solving a function through series (SAS)

I need some help in checking my program in SAS that uses loops to solve a function as i am struggling. The function which i need to solve is in terms of a series expansion and it is:

ln(1+x)

I need to evaluate the function at x0 = 0.8 and the summation must stop when the next term is less than 0.05.

This is what I have so far but I'm very far off from where I need to be I believe:

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;

Any help is greatly appreciated!

Edit: Apologies if my formatting/presentation of the coding etc isn't up to scratch as I'm not familiar with this site

Edit: Change of names/values but replied answer still stands

question from:https://stackoverflow.com/questions/65904308/solving-a-function-through-series-sas

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'll first give you pointers with your method, then provide my preferred solution.

Your solution, updated with my fixes:

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;

My preferred solution:

*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;

You might want to not output that last line, by the way, but that should be easy to add.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...