"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import YouTubeVideo\n",
"YouTubeVideo(\"HrRMnzANHHs\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reference Pi: \n",
"\n",
"3.14159265358979323846264338327950288419716939937510\n",
" 58209749445923078164062862089986280348253421170679\n",
" 82148086513282306647093844609550582231725359408128\n",
" 48111745028410270193852110555964462294895493038196\n",
" 44288109756659334461284756482337867831652712019091\n",
" 45648566923460348610454326648213393607260249141273\n",
" 72458700660631558817488152092096282925409171536436\n",
" 78925903600113305305488204665213841469519415116094\n",
" 33057270365759591953092186117381932611793105118548\n",
" 07446237996274956735188575272489122793818301194912\n",
" 98336733624406566430860213949463952247371907021798\n",
" 60943702770539217176293176752384674818467669405132\n",
" 00056812714526356082778577134275778960917363717872\n",
" 14684409012249534301465495853710507922796892589235\n",
" 42019956112129021960864034418159813629774771309960\n",
" 51870721134999999837297804995105973173281609631859\n",
" 50244594553469083026425223082533446850352619311881\n",
" 71010003137838752886587533208381420617177669147303\n",
" 59825349042875546873115956286388235378759375195778\n",
" 18577805321712268066130019278766111959092164201989\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The sequence of odd fractions, as a running total, converges to pi/4, albeit slowly...\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.14209240\n"
]
}
],
"source": [
"from fractions import Fraction\n",
"from itertools import count, islice\n",
"from decimal import Decimal, localcontext\n",
"\n",
"def convert(f):\n",
" \"\"\"get a Decimal from a Fraction (and multiply by 4)\"\"\"\n",
" return (Decimal(f.numerator) / Decimal(f.denominator)) * Decimal(4)\n",
"\n",
"def pi_series():\n",
" \"...converges very slowly\"\n",
" denoms = count(1,2) # odd numbers from 1\n",
" total = Fraction(1,next(denoms)) # 1/1\n",
" while True:\n",
" yield total\n",
" total -= Fraction(1, next(denoms)) # - 1/3\n",
" total += Fraction(1, next(denoms)) # + 1/5 and so on\n",
"\n",
"def nth(iterable, n, default=None):\n",
" \"Returns the nth item or a default value\"\n",
" return next(islice(iterable, n, None), default)\n",
"\n",
"with localcontext() as ctx: # <-- context manager object\n",
" ctx.prec = 3000\n",
" pi = pi_series()\n",
" print(\"{0}\".format(convert(nth(pi, 1000)))[:10])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Youtube above describes how to use successive primes in successive terms to build a running product that converges to 2/pi."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541]\n"
]
}
],
"source": [
"def Primes():\n",
" \"\"\"generate successive prime numbers (trial by division)\"\"\"\n",
" candidate = 1\n",
" _primes_so_far = [2] # first prime, only even prime\n",
" yield _primes_so_far[-1]\n",
" while True:\n",
" candidate += 2 # check odds only from now on\n",
" for prev in _primes_so_far:\n",
" if prev**2 > candidate:\n",
" yield candidate\n",
" _primes_so_far.append(candidate)\n",
" break\n",
" if not divmod(candidate, prev)[1]: # no remainder!\n",
" break # done looping\n",
"\n",
"\n",
"p = Primes()\n",
"print([next(p) for _ in range(100)]) # next 30 primes please! "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.13702930\n"
]
}
],
"source": [
"def convert(f):\n",
" \"\"\"get a Decimal from a Fraction (and multiply by 4)\"\"\"\n",
" return (Decimal(f.denominator) / Decimal(f.numerator))\n",
"\n",
"def Pi():\n",
" primes = Primes()\n",
" result = Fraction(1,1)\n",
" while True:\n",
" p = next(primes)\n",
" if divmod(p, 4)[1] == 1:\n",
" term = (1 + Fraction(1,p))\n",
" else:\n",
" term = (1 - Fraction(1,p))\n",
" result *= term\n",
" yield result\n",
" \n",
"\n",
"with localcontext() as ctx: # <-- context manager object\n",
" ctx.prec = 300 # feel free to boost\n",
" pi = Pi()\n",
" print(\"{0}\".format(convert(nth(pi, 333)))[:10])\n",
" # print(\"{0}\".format(convert(nth(pi, 3000)))[:20])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Ramanujan](http://mathforum.org/kb/thread.jspa?threadID=2246748&tstart=0)
\n",
"[Pi Contest](http://mathforum.org/kb/thread.jspa?threadID=2246748&tstart=0)\n",
"\n",
"Below is a famous one from Ramanujan. Why it works I'm not sure anyone knows exactly.\n",
"\n",
"\n",
"\n",
"Thanks to [a change in Python 3.8](https://bugs.python.org/issue33083), factorial no longer accepts the Decimal type. I've had to update the code for forward compatibility.\n",
"\n",
"![formula](ramanujan_formula.jpeg)\n",
"\n",
"Here's [a corresponding script](https://repl.it/@kurner/computepi) on repl.it."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706\n"
]
}
],
"source": [
"from math import factorial as fact\n",
"def pieinsky():\n",
" \"\"\"Ramanujan's: converges relatively quickly\"\"\"\n",
" c1 = Decimal(4)\n",
" c2 = Decimal(1103)\n",
" c3 = Decimal(26390)\n",
" c4 = Decimal(396)\n",
" c5 = Decimal(9801)\n",
" # code formatted for readability (make it be one line)\n",
" root8 = Decimal('8').sqrt()\n",
" i = Decimal(0)\n",
" thesum = Decimal(0)\n",
" \n",
" while True:\n",
" # explicit casts to int create forward compatibility\n",
" term = (fact(int(c1*i))*(c2 + c3*i))/(pow(fact(int(i)),4)*pow(c4,4*i))\n",
" thesum = thesum + term\n",
" yield 1/((root8/c5)*thesum)\n",
" i += 1\n",
"\n",
"with localcontext() as ctx: # <-- context manager object\n",
" ctx.prec = 1000\n",
" pi = pieinsky()\n",
" print(\"{0}\".format(nth(pi, 100))[:100])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The generator below gives successive digits of Pi."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067\n"
]
}
],
"source": [
"\"\"\"\n",
"Another generator example: converging to Pi\n",
"\n",
"https://mail.python.org/pipermail/edu-sig/2015-September/date.html\n",
"\n",
"\"\"\"\n",
"\n",
"def pi():\n",
"\n",
" k, a, b, a1, b1 = 2, 4, 1, 12, 4\n",
" while True:\n",
" p, q, k = k*k, 2*k+1, k+1\n",
" a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1\n",
" d, d1 = a/b, a1/b1\n",
" while d == d1:\n",
" yield int(d)\n",
" a, a1 = 10*(a%b), 10*(a1%b1)\n",
" d, d1 = a/b, a1/b1\n",
"\n",
"if __name__ == \"__main__\": \n",
" the_gen = pi()\n",
" for _ in range(100):\n",
" print(next(the_gen),end=\"\")\n",
" print()\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"gen = pi()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"generator"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(gen)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"next(gen)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"next(gen)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![giphy pi day](https://media.giphy.com/media/yLmlkXeMCrrW0/giphy.gif)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This I-Python Notebook is by Kirby Urner, copyleft MIT License, March 2016."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}