Thicket data repository for the EEG
at main 8.3 kB view raw
1{ 2 "id": "https://www.tunbury.org/2025/03/14/pi-day", 3 "title": "Pi Day - Archimedes Method", 4 "link": "https://www.tunbury.org/2025/03/14/pi-day/", 5 "updated": "2025-03-14T13:00:00", 6 "published": "2025-03-14T13:00:00", 7 "summary": "It’s Pi Day 2025", 8 "content": "<p>It’s <a href=\"https://en.wikipedia.org/wiki/Pi_Day\">Pi Day</a> 2025</p>\n\n<p>Archimedes calculated the perimeter of inscribed regular polygons\nwithin a circle to approximate the value of π.</p>\n\n<p>A square inscribed in a unit circle can be divided into four right\ntriangles with two sides of unit length, corresponding to the radius of\nthe circle. The third side can be calculated by Pythagoras’ theorem to\nbe √2. The perimeter of the square would be 4√2. Given, C=πd, we\ncan calculate π from the circumference by dividing it by the diameter,\n2, giving 2√2.</p>\n\n<p><img alt=\"\" src=\"https://www.tunbury.org/images/pi-archimedes-triangle.png\"></p>\n\n<p>CA, CD and CB are all the unit radius. AB is √2 as calculated above. The\nangle ACB can be bisected with the line CD. EB is half of AB. Using\nPythagoras’ theorem on the triangle BCE we can calculated CE. DE is then\n1 - CE, allowing us to use Pythagoras’ theorem for a final time on BDE to\ncalculated BD. The improved approximation of the perimeter is now 8 x BD.</p>\n\n<p>We can iterate on this process using the following code:</p>\n\n<div><div><pre><code><span>let</span> <span>rec</span> <span>pi</span> <span>edge_squared</span> <span>sides</span> <span>=</span> <span>function</span>\n <span>|</span> <span>0</span> <span>-&gt;</span> <span>sides</span> <span>*.</span> <span>Float</span><span>.</span><span>sqrt</span><span>(</span><span>edge_squared</span><span>)</span> <span>/.</span> <span>2</span><span>.</span>\n <span>|</span> <span>n</span> <span>-&gt;</span>\n <span>let</span> <span>edge_squared</span> <span>=</span> <span>2</span><span>.</span> <span>-.</span> <span>2</span><span>.</span> <span>*.</span> <span>Float</span><span>.</span><span>sqrt</span> <span>(</span><span>1</span><span>.</span> <span>-.</span> <span>edge_squared</span> <span>/.</span> <span>4</span><span>.</span><span>)</span> <span>in</span>\n <span>let</span> <span>sides</span> <span>=</span> <span>sides</span> <span>*.</span> <span>2</span><span>.</span> <span>in</span>\n <span>pi</span> <span>edge_squared</span> <span>sides</span> <span>(</span><span>n</span> <span>-</span> <span>1</span><span>)</span>\n\n<span>let</span> <span>approximation</span> <span>=</span> <span>pi</span> <span>2</span><span>.</span> <span>4</span><span>.</span> <span>13</span>\n<span>let</span> <span>()</span> <span>=</span> <span>Printf</span><span>.</span><span>printf</span> <span>\"pi %.31f</span><span>\\n</span><span>\"</span> <span>approximation</span>\n</code></pre></div></div>\n\n<p>I found this method quite interesting. Usually, as the number of\niterations increases the approximation of π becomes more accurate\nwith the delta between each step becoming smaller until the difference\nis effectively zero (given the limited precision of the floating\ncalculation). However, in this case, after 13 iterations the\napproximation becomes worse!</p>\n\n\n\n \n \n iteration\n approximation\n % error\n \n \n \n \n 0\n 2.8284271247461902909492437174777\n 9.968368\n \n \n 1\n 3.0614674589207178101446515938733\n 2.550464\n \n \n 2\n 3.1214451522580528575190328410827\n 0.641315\n \n \n 3\n 3.1365484905459406483885231864406\n 0.160561\n \n \n 4\n 3.1403311569547391890466769837076\n 0.040155\n \n \n 5\n 3.1412772509327568926096319046337\n 0.010040\n \n \n 6\n 3.1415138011441454679584239784162\n 0.002510\n \n \n 7\n 3.1415729403678827047485810908256\n 0.000627\n \n \n 8\n 3.1415877252799608854161306226160\n 0.000157\n \n \n 9\n 3.1415914215046352175875199463917\n 0.000039\n \n \n 10\n 3.1415923456110768086091411532834\n 0.000010\n \n \n 11\n 3.1415925765450043449789063743083\n 0.000002\n \n \n 12\n 3.1415926334632482408437681442592\n 0.000001\n \n \n 13\n 3.1415926548075892021927302266704\n -0.000000\n \n \n 14\n 3.1415926453212152935634549066890\n 0.000000\n \n \n 15\n 3.1415926073757196590463536267634\n 0.000001\n \n \n 16\n 3.1415929109396727447744979144773\n -0.000008\n \n \n 17\n 3.1415941251951911006301543238806\n -0.000047\n \n \n 18\n 3.1415965537048196054570325941313\n -0.000124\n \n \n 19\n 3.1415965537048196054570325941313\n -0.000124\n \n \n 20\n 3.1416742650217575061333263874985\n -0.002598\n \n \n 21\n 3.1418296818892015309643284126651\n -0.007545\n \n \n 22\n 3.1424512724941338071005247911671\n -0.027331\n \n \n 23\n 3.1424512724941338071005247911671\n -0.027331\n \n \n 24\n 3.1622776601683795227870632515987\n -0.658424\n \n \n 25\n 3.1622776601683795227870632515987\n -0.658424\n \n \n 26\n 3.4641016151377543863532082468737\n -10.265779\n \n \n 27\n 4.0000000000000000000000000000000\n -27.323954\n \n \n 28\n 0.0000000000000000000000000000000\n 100.000000\n \n \n\n\n<p>Using the <a href=\"https://opam.ocaml.org/packages/decimal/\">decimal</a> package\nwe can specify the floating point precision we want allowing us to\nget to 100 decimal places in 165 steps.</p>\n\n<div><div><pre><code><span>open</span> <span>Decimal</span>\n\n<span>let</span> <span>context</span> <span>=</span> <span>Context</span><span>.</span><span>make</span> <span>~</span><span>prec</span><span>:</span><span>200</span> <span>()</span>\n<span>let</span> <span>two</span> <span>=</span> <span>of_int</span> <span>2</span>\n<span>let</span> <span>four</span> <span>=</span> <span>of_int</span> <span>4</span>\n\n<span>let</span> <span>rec</span> <span>pi</span> <span>edge_squared</span> <span>sides</span> <span>n</span> <span>=</span>\n <span>match</span> <span>n</span> <span>with</span>\n <span>|</span> <span>0</span> <span>-&gt;</span> <span>mul</span> <span>~</span><span>context</span> <span>sides</span> <span>(</span><span>div</span> <span>~</span><span>context</span> <span>(</span><span>sqrt</span> <span>~</span><span>context</span> <span>edge_squared</span><span>)</span> <span>two</span><span>)</span>\n <span>|</span> <span>n</span> <span>-&gt;</span>\n <span>let</span> <span>edge_squared</span> <span>=</span>\n <span>sub</span> <span>~</span><span>context</span> <span>two</span>\n <span>(</span><span>mul</span> <span>~</span><span>context</span> <span>two</span>\n <span>(</span><span>sqrt</span> <span>~</span><span>context</span> <span>(</span><span>sub</span> <span>~</span><span>context</span> <span>one</span> <span>(</span><span>div</span> <span>~</span><span>context</span> <span>edge_squared</span> <span>four</span><span>))))</span>\n <span>in</span>\n <span>let</span> <span>sides</span> <span>=</span> <span>mul</span> <span>~</span><span>context</span> <span>sides</span> <span>two</span> <span>in</span>\n <span>pi</span> <span>edge_squared</span> <span>sides</span> <span>(</span><span>Int</span><span>.</span><span>pred</span> <span>n</span><span>)</span>\n\n<span>let</span> <span>()</span> <span>=</span> <span>pi</span> <span>two</span> <span>four</span> <span>165</span> <span>|&gt;</span> <span>to_string</span> <span>~</span><span>context</span> <span>|&gt;</span> <span>Printf</span><span>.</span><span>printf</span> <span>\"%s</span><span>\\n</span><span>\"</span>\n</code></pre></div></div>\n\n<p>This code is available on <a href=\"https://github.com/mtelvers/pi-archimedes\">GitHub</a></p>", 9 "content_type": "html", 10 "author": { 11 "name": "Mark Elvers", 12 "email": "mark.elvers@tunbury.org", 13 "uri": null 14 }, 15 "categories": [ 16 "pi", 17 "tunbury.org" 18 ], 19 "source": "https://www.tunbury.org/atom.xml" 20}