Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'm experimenting with different algorithms that approximate pi via iteration and comparing the result to pi. I want to both visualise and perhaps know the function (if any) that describes the increasing trend in accuracy as the number of iterations rises.

For example, 1 iteration might give me 3.0, 10 iterations might give me 3.12, 50 iterations might give me 3.1409 etc. The more iterations, the better. Sometimes it might be a case of diminishing returns, running 1000 iterations to get an additional decimal point of correctness - is it worth it? Knowing the sweet spot at which to quit would be nice to know, for each pi approximation algorithm type.

I'm a mature programmer who is rekindling an interest in math, and this project idea interests me. Trouble is, I don't know what the correct math and statistical terminology is to describe what I want to do. Could someone please locate my problem within the history of math and possibly illustrate with mathematica?

UPDATE: To be more specific. My pi generation algorithm produces the following pairs of numbers, where the first number is the number of iterations it looped and the second number is the abs(result - pi) i.e. how much the result differs from pi. The more iterations, the smaller the second number.

data = {{10, 0.19809}, {50, 0.039984}, {100, 0.019998}, {500, 
0.00399998}, {1000, 0.002}, {20000, 0.0001}, {100000, 
0.00002}, {500000, 4.*10^-6}}

I want to visualize what is going on with the data and find a function that describes what is going on. I'd like to also know what is possible in this area with this sort of data.

What I've tried:

ListPlot[data, Joined -> True]

gives me an an almost unreadable graph due to the small numbers involved.

GeneralizedLinearModelFit[data,{x},{x}]

gives me FittedModel[0.0405405 -<<22>> x] which when plotted Show[ListPlot[data,PlotStyle->Red],Plot[%36[x],{x,10,500000}]] gives me a straight line. Not helpful as it doesn't seem to tell me anything about the trend re gradually converging on pi.

I think there would be a curve of some sort that would better fit the data, but functions like FindFit seem to require you supply an expression e.g. Log and various parameters a, b etc - but how do I know what expression and what parameters to supply?

Should I be looking at Interpolation instead?

UPDATE 2:

Thanks for the answers so far. What's holding me back from accepting an answer is the fact that I'm expecting a curved graph - not a straight line. Because the whole point of more and more iterations is that it gets closer to pi and so the answer must be a curve. And that curve must have a formulae, which it would be nice to have defined.

So I did some experimenting in mathematica and came up with a curve after all. Here's how I did it.

My data came from a crude Wells / Gregory / Leibniz algorithm (see Gregory Series) where I get pi by alternately adding and subtracting 1/n where n is 3, 5, 7... for example

N[(1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 + 1/17) * 4]

which gives me 3.25237 - not bad for 8 numbers in the series, or 8 iterations if its a program that's generating the result. So I went on to define a Mathematica function that takes the number of iterations you want and generates pi. The following function also happens to subtract from real pi and return the discrepancy difference. The higher the iterations it_ passed to this function, the smaller the difference from pi and the smaller the result coming out of this function:

f[it_]:=Abs[N[Sum[(-1)^(n-1)/(2n-1),{n,it}]]*4-\[Pi]]

So my original data points were for 10, 50, 100, 1000, 20000 and 100000 iterations. I thought those would be representative. Thus I can now generate my original data in Mathematica with

data = {{10,f[10]},{50,f[50]},{100,f[100]},{500,f[500]},{1000,f[1000]},{20000,f[20000]},{100000,f[100000]}}
output: {{10,0.099753},{50,0.019998},{100,0.00999975},{500,0.002},{1000,0.001},{20000,0.00005},{100000,0.00001}}

then plot it using the recommended techniques offered as comments and answers on this page

ListLogLogPlot[data,Joined->True,GridLines->Automatic,PlotStyle->Thick]

and I of course get a straight line like everybody else.

Hmmm - remember I am after a curve. My instinct tells me it should be a curve.

So then I discover that if I generate a more gradual list of points like this:

data = Table[f[x],{x,20}]
ListPlot[data]

then I finally get my curve.

curved graph

Yey! It looks exactly like I imagined it would - curving gradually towards perfection. And if I change the iterations from 20 to 1000 or any higher number, I get the same curve, only smoother. So this is the function I want a precise definition of.

Interestingly, if I use the ListLogLogPlot everybody is recommending on my more gradually spaced data

ListLogLogPlot[data, Joined -> True, GridLines -> Automatic, PlotStyle -> Thick]

I get a straight line again! Grrr.

straight line again

What I suspect is going on here is that there was probably a curve in the normal ListPlot of my original data but we couldn't see it due to the scaling, which is why we went for the ListLogLogPlot. But that probably turns curves into straight lines (hence the log in the name?) - which disappointed me because I was expecting a visual curve.

And I don't think my original choice of x values (representing the number of iterations being fed into my pi calculation function) and how those x values are spaced makes a difference. My x values of 10, 50, 100, 1000, 20000 and 100000 certainly made it hard to see the curve in the graph, but the curve was still probably there. My second, gentler set of x data points (from the same pi generation function) of 1..20 makes the curve ridiculously easy to see.

So what counts as an answer to this question?

  • An exact definition of the curve being seen here.
  • And perhaps some commentary on what functions describing curves typically arise when attempting to visualise pi using iterative techniques.

I hope I haven't changed the goal posts in this question. I think I have always asked for an exact definition of the curve in my data plus some commentary of what might be typical / best practice in this sort of visualisation/graphing territory, where there is a known value we are iterating towards.

share|improve this question
3  
what have you tried? –  george2079 Aug 30 '13 at 16:39
1  
You might be interested in this issue: Finding long strings of identical digits in transcendental numbers –  Artes Aug 30 '13 at 16:41
    
Welcome to Mathematica.SE! Your question is still very broad. It would be easier to help you if you could narrow it down. Working code examples are also always welcome... –  Yves Klett Aug 30 '13 at 20:38
2  
Since the numbers vary over so many orders of magnitude, you should visualize them with ListLogLogPlot[data, Joined -> True, Mesh -> All] instead of a plain ListPlot. See Wikipedia. –  Rahul Aug 31 '13 at 1:15
1  
Perhaps the mention of Pi got people off on the wrong track (thanks anyway). My question could simply be how do I curve fit the 'data' in my question above. Of course some helpful general tips on curve fitting - in the situation where one knows the answer (e.g. pi or any other constant) and are iteratively trying to get closer to it, and want to see the curve - would be appreciated. –  tcab Aug 31 '13 at 12:16

2 Answers 2

There are many examples on the Wolfram Demonstrations web site on this topic:

http://demonstrations.wolfram.com/search.html?query=pi%20approximations

These examples come with the code that generated them and allow you to make your own variations.

share|improve this answer

As pointed out by Rahul, ListLogLogPlot does the job nicely and points you into the right direction model-wise:

data = {{10, 0.19809}, {50, 0.039984}, {100, 0.019998}, {500, 
    0.00399998}, {1000, 0.002}, {20000, 0.0001}, {100000, 
    0.00002}, {500000, 4.*10^-6}};

ListLogLogPlot[data, Joined -> True, GridLines -> Automatic,PlotStyle->Thick]

Mathematica graphics

sol = FindFit[data, model = a*x^-exp, {a, exp}, {x}]

(* {a -> 1.95817, exp -> 0.994979}*)

f = model /. sol

(* 1.95817/x^0.994979*)

datafit = {x, f} /. x -> # & /@ data[[All, 1]];

ListLogLogPlot[{data, datafit}, Joined -> True, Mesh -> All, 
 PlotStyle -> {Directive[Green, Thick], Red}, 
 PlotLegends -> {"data", "model"}]

Mathematica graphics

Note: FindFit also works with a*x^exp, but in a first incarnation I added some additional parameters that went better with -exp.

share|improve this answer
1  
Thanks for this. See also my UPDATE 2 in my question where I finally discover the curve in my data. Presumably ListLogLogPlot turns curves into straight lines? But there really is a curve in there. So is there an exact function for the curve in my data, such that I could type it into a graphing calculator and reproduce that curve? –  tcab Sep 5 '13 at 14:31
    
@tcab please have a look at this page explaining the principle of a log-log-plot. The fact that your data produces a straight line in log-log simply shows a decent fit to a y=a*x^k model. –  Yves Klett Sep 5 '13 at 16:25
    
I don't quite understand the steps following your FindFit, anyway: so you are saying the monomial y=a*x^k & specifically 1.9581670585906745*x^-0.9949794657517919 fits my data? I plotted this and got a curve - cool. But Curve Fitting says that y=a*x^k is a general form equation for a whole family of equations involving power relationships - so isn't this answer too broad? I tried a simpler FindFit[data, model = x^exp, {exp}, {x}] and got the same curve with x^-1.0129279111812564? Isn't that simpler? And shouldn't there be a guaranteed trend to 0? –  tcab Sep 8 '13 at 11:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.