The variabel 'total' seems to change size on every loop....-A while loop problem

1 次查看(过去 30 天)
I can't see what the problem is with my while loop. I'm trying to write a while loop to calculate a converging serie. I want the loop to stop at (pi/4).
Here is the code:
y(1)=1;
y(2)=(-1/3);
total(1)=y(1);
total(2)=total(1)+y(2);
k=3;
while (abs(total(k-1)-total(k-2))>.7854)%<----any suggestions how to tell the while loop to stop when the total sum of the terms in (pi/4)?
y(k)=(((-1)^(k))/(2*k+1));
total(k)=total(k-1)+y(k); % <----here matlab says the variabel 'total' changes size...
k=k+1;
end
fprintf('The sequence converges when the final element is equal to %8.4f \n',0.7854)
fprintf('At which point the value of the series is %5.4f \n',total(k-1))
fprintf('This compares to the value of the (pi/4),%5.4f \n',(pi/4))
fprintf('The sequence took %3.0f terms to converge \n',k)
  4 个评论
dpb
dpb 2013-10-15
编辑:dpb 2013-10-15
Try
>> p4=p/4; n=0; s=1; t=1; d=3;
>> while abs(s-p4)>0.001,t=-t;s=s+t/d;d=d+2;n=n+1;end,s,n
s =
0.7844
n =
249
>>
and work thru what it's doing, and how...
Britney
Britney 2013-10-15
Thank you dpb very much for the code. Simple and elegant.
I'm still a bit annoyed that my code doesn't work but I'll talk to my teacher about it tomorrow.
Thanks again xoxo

请先登录,再进行评论。

采纳的回答

Jan
Jan 2013-10-15
编辑:Jan 2013-10-15
You want to approximate pi/4 by:
1 - 1/3 + 1/5 - 1/7
But you code produces:
1 - 1/3 + (((-1)^3)/(2*3+1)) + (((-1)^4)/(2*4+1))
which is:
1 - 1/3 - 1/7 + 1/9
Therefore 1/5 is missing in the result. You have to set k=2 before the loop.
The MLint-warning, that total changes it size in each iteration is not an error. It reduces the run-time very much, but I do not assume, that this is a problem for a homework. So simply ignore this message. But keep in mind, that growing arrays will become a serious problem in real-world programs. You can search for the term "pre-allocation" in this forum.
  5 个评论
dpb
dpb 2013-10-16
编辑:dpb 2013-10-16
But your teacher will undoubtedly recognize it isn't your code if you submit it! :) It's not what a beginner will likely come up with; I did it to illustrate two things--the test in the loop and the accumulation of the sum without using an array to hold previous terms.
OK, to your specific questions --
On n first -- it's just the number of iterations in the loop; the total number of terms used in the calculation is, indeed, one more because the initial term is in the setting of the sum to 1 instead of 0. So, you're right on that part.
Next on t=1 initially and t=-t inside the loop -- that simply has the effect of flipping the sign -- it's the (-1)^k term in the series but it's much more efficient to simply change the sign than computing the power. That's a programming "trick" that'll become second nature with experience--you'll look for such "shortcuts" in implementation that have the same result as the more complicated expression but are either simpler to implement or less computationally intensive. This one is both.
The initial value of '1' and placing the negation term first is one of simply ensuring the first term after the initial constant that was loaded into the sum has the correct sign. If the series were alternating sign but the opposite terms being negative I would have initialized t to -1 or moved the sign-flip statement to follow its use--if you think about that you'll see that either of those ends up resulting in the same thing in the end.
As for why d=3 as the initial value, that again corresponds to the value of the denominator (2k+1) for k=1 which is the first term in the continuing series we're calculating in the loop -- remember we set the sum to the first value of the constant 1 already. Again, here is the disconnect that since n isn't ever actually used but is simply a counter to see how many terms were computed in the loop I initialized it to 0 arbitrarily.
And for the last as far as writing the expression as s=s+t/d, that's simply again recognizing the algebraic simplification of the the numerator and denominator and that the sum is accumulated by adding the next term to the previous. If you compute a fixed number of terms then the next doesn't need to know anything about what that value is; it just is the next term tacked onto the present value.
And, of course, it demonstrates the fundamental difference between the algebraic/mathematical meaning of the "=" sign and that of the computer language interpretation. In Matlab (and virtually all other procedural computing languages) the equal sign is actually the sign for "take whatever is on the right side of the = sign and assign it to the location represented by the variable on the left side". That is, fundamentally different than actually equating the two because the value of the variable on the left hand side isn't modified until the expression on the RHS is evaluated--hence the s there on the RHS is actually s(i-1) while the s on the LHS is s(i) for this pass. This what I was trying to get you to see in that you don't need the array to keep all the terms in...and is a fundamental breakthrough in coding when the concept dawns.
Britney
Britney 2013-10-16
Thank you very much dpb. Again I really enjoy your feedback. Very helpful. My teacher wrote an example in a very similar way of yours so maybe I'll be able to convince them it was still me ;)...Thank you again very much for helping me. Now my next problem is figuring out why Matlab doesn't want to run the script I wrote my loop in....(Murphy's law anyone?)

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Symbolic Math Toolbox 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by