Plot a large array of doubles

8 views (last 30 days)
billyjthorton
billyjthorton on 10 Jun 2017
Edited: dpb on 13 Jun 2017
I'm having a few issues with my Code that I could use some help on.
Here is my code:
format long
fileId = fopen('PiResults.txt','w');
Pi = zeros(1:1000000)
for n = 0:1000000
x = ((-1).^n)./(2*n+1);
currentPi = 4*x;
fprintf(fileId,'%d\n', currentPi);
Pi(n) = currentPi;
end
sum(x)
x1 = 4.*x;
total = sum(x1)
fprintf(fileId,'%d\n', total);
fclose(fileId);
plot(n,Pi);
The problem I'm having is I'm not sure how to plot all the estimates of Pi given that it is such a big array. I might have messed up in my implementation, but I could use some advice to get this type of plot to work. Line should be quite variant across the X-axis. To show a few sample points from the fprintf statement above:
4
-1.333333e+00
8.000000e-01
-5.714286e-01
4.444444e-01
-3.636364e-01
3.076923e-01
-2.666667e-01
2.352941e-01
-2.105263e-01
And the code (certainly not as is, but with a few minor adjustments), using this techniques, produces a rather decent estimate of Pi: 3.141594e+00. However, gathering all that data and putting it into a pretty graph has proved more challenging than I thought.
Thanks for all your help in advanced, I really appreciate it!
  5 Comments
dpb
dpb on 11 Jun 2017
Good catch, Walter...
dpb
dpb on 11 Jun 2017
I answered that (and some other enhancements) earlier...

Sign in to comment.

Answers (1)

dpb
dpb on 11 Jun 2017
Edited: dpb on 11 Jun 2017
for n = 0:1000000
...
Pi(n) = currentPi;
end
...
plot(n,Pi);
n is just a single value of 1000000, the last value of the loop; to plot the array Pi versus ordinal number is just
plot(Pi)
While it's not the problem with the plotting, some comments on Matlab usage and a nit or two...
You preallocated the output vector; that's good. But notice
Pi = zeros(1:1000000)
for n = 0:1000000
there are 1000000 +1 elements in the vector 0:1000000, not just 1000000.
The bigger issue here is that Pi is actually a ND array of 1:1000000 sets of arrays (if there were sufficient memory; you'd run out long before N reached anything even close to 1000000.
Pi = zeros(1000000,1);
or more easily maintained, set the maximum N wanted and use it instead--
N=1000000; % terms in series expansion
Pi=zeros(N+1,1); % allocate array (0:N elements)
Best use of Matlab, however, is to vectorize expressions where one can when doing so doesn't require just totally obscure techniques...the series expansion above can be written as
n=0:1000000;
Pi=4*(-2*mod(n,2)+1)./(2*n+1);
Illustrate:
>> n=0:9; % compute first 10 elements
>> Pi=4*(-2*mod(n,2)+1)./(2*n+1)
Pi =
4.0000 -1.3333 0.8000 -0.5714 0.4444 -0.3636 0.3077 -0.2667 0.2353 -0.2105
>> cumsum(Pi)
ans =
4.0000 2.6667 3.4667 2.8952 3.3397 2.9760 3.2837 3.0171 3.2524 3.0418
>> ans-pi
ans =
0.8584 -0.4749 0.3251 -0.2464 0.1981 -0.1655 0.1421 -0.1245 0.1108 -0.0998
>>
You generally "win" by trading memory for code and the ability to use the builtin functions on larger chunks of data at a time.
  4 Comments
billyjthorton
billyjthorton on 12 Jun 2017
Thank you so much for your help! Excellent answer and thanks for explaining. I think one of the big mistakes I was making that you pointed out was that I was worrying about setting the x-axis, but given n elements, MATLAB does that for you.
Additionally, how did you come up with the vectorized expression? That is something I struggled with a little bit.
@Stephen Cobeldick: In response to your comment, as I understand it, a vector is just a 1xn array. So when I do the zero functions it's nxn? If not, is there any different between the two? @dpb uses the zeros function above as well?
dpb
dpb on 12 Jun 2017
Edited: dpb on 13 Jun 2017
"zero functions it's nxn?"
For a single argument, yes. But you gave a vector argument, not a value. Read the doc for zeros on details but try some 'spearmints at the command line and see what you get from
zeros(1)
zeros(2)
zeros(2,1)
zeros(1,2)
zeros(1:2)
The vector solution is simply looking at the functional form (-1)^n is simply a sign swap each term; the mod expression is one way to generate a series of +/-1 from a vector of [0:n]; the second term should be obvious. The "trick" is the dot operator for the division that is the element-by-element version rather than matrix operation. "Time in grade" and working thru examples is the way one gets somewhere; some knowledge of matrix algebra and a little head-scratching go a long ways, too...
For the plot, you can certainly also provide the x array; there's no need for ordinal plotting but you could also plot vs n and the above would just be
plot(n,Pi)
with n defined as I did.
Note, however, in your original code (as is explained above) n is the loop index variable and hence is only one value, not a vector. Your plot command tried to plot all values at one x; the last value of the loop before it exited. You would have gotten plot of all points at the last value 100000 on the x-axis and probably nothing was visible owing to the size of default dot on the screen the individual points may have not been visible.
Try the same code (fixing the argument to zeros first) and change the plot call to
plot(n,Pi,'*')
and see what happens...

Sign in to comment.

Categories

Find more on Creating and Concatenating Matrices in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!