├── Big Numbers.ipynb ├── Classic Constants.ipynb ├── Classic Fractals.ipynb ├── Fourier Series.ipynb ├── PRIMES in NP.ipynb └── Sum of powers.ipynb /Big Numbers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
Paul Novaes
July 2018
\n", 8 | "\n", 9 | "# Big Numbers\n", 10 | "\n", 11 | "The goal of this notebook is to show how to perform the 4 basic arithmetic operations on big numbers.\n", 12 | "\n", 13 | "By big number, we mean an arbitrary nonnegative integer, with no limit on its size, for example with 1,000,000 digits.\n", 14 | "\n", 15 | "Though Python already supports big numbers, the following algorithms are interesting in themselves and can be used in other languages and environments.\n", 16 | "\n", 17 | "## Number Representation\n", 18 | "\n", 19 | "We will represent (big) numbers as arrays of digits. For example 123 will be represented by $[1, 2, 3]$.\n", 20 | "\n", 21 | "The following functions will be used later.\n", 22 | "\n", 23 | "__Conversions between int and number__" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "# Returns a number (array) from an int.\n", 33 | "def number_from_int(n):\n", 34 | " assert(isinstance(n, int) and n >= 0)\n", 35 | " if n == 0: return [0]\n", 36 | " number = []\n", 37 | " while n > 0:\n", 38 | " number.append(n % 10)\n", 39 | " n = n // 10\n", 40 | " return number[::-1]\n", 41 | "\n", 42 | "# Returns an int from a number (array).\n", 43 | "def number_to_int(n):\n", 44 | " result = 0\n", 45 | " for i in range(0, len(n)):\n", 46 | " result = result*10 + n[i]\n", 47 | " return result" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "__Easy digit access__" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "# Gets n_i in n = n_k...n_1n_0.\n", 64 | "def number_get_digit(n, i):\n", 65 | " if i >= len(n): return 0\n", 66 | " return n[len(n) - 1 - i]\n", 67 | "\n", 68 | "# Sets n_i to d in n = n_k...n_1n_0.\n", 69 | "def number_set_digit(n, i, d):\n", 70 | " n[len(n) - 1 - i] = d" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "__Utility functions__" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 3, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "# Trims leading zeroes, from a possibly improper representation of a number.\n", 87 | "def number_trim(n):\n", 88 | " leading_zeroes = 0\n", 89 | " for i in range(len(n) - 1):\n", 90 | " if n[i] == 0:\n", 91 | " leading_zeroes += 1\n", 92 | " else:\n", 93 | " break\n", 94 | " del n[0:leading_zeroes]\n", 95 | " number_assert(n)\n", 96 | " \n", 97 | "# Asserts n is a proper representation of a number.\n", 98 | "def number_assert(n):\n", 99 | " assert (not(len(n) > 1 and n[0] == 0))\n", 100 | " for d in n:\n", 101 | " is_digit = isinstance(d, int) and d >= 0 and d <= 9\n", 102 | " assert(is_digit)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "__Unit Test__" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 4, 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "name": "stdout", 119 | "output_type": "stream", 120 | "text": [ 121 | " succeeded\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "def test_number_representation():\n", 127 | " for i in range(100):\n", 128 | " n = number_from_int(i)\n", 129 | " number_assert(n)\n", 130 | " return number_to_int(n) == i\n", 131 | "\n", 132 | "def run_test(test):\n", 133 | " if test():\n", 134 | " print(test, 'succeeded')\n", 135 | " else:\n", 136 | " print(test, 'failed')\n", 137 | " assert(False)\n", 138 | " \n", 139 | "run_test(test_number_representation)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "## Addition\n", 147 | "\n", 148 | "We use the standard algorithm. It only assumes that we have an \"addition table\", that is that we know how to add 2 individual digits." 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 5, 154 | "metadata": {}, 155 | "outputs": [], 156 | "source": [ 157 | "# Returns a + b.\n", 158 | "def number_add(a, b):\n", 159 | " def add_digits(d1, d2, carry):\n", 160 | " assert(carry <= 1)\n", 161 | " sum = d1 + d2 + carry\n", 162 | " return int(sum / 10), sum % 10\n", 163 | " number_assert(a)\n", 164 | " number_assert(b)\n", 165 | " num_digits = max(len(a), len(b)) + 1\n", 166 | " sum = [0 for i in range(num_digits)]\n", 167 | " # Add pairs of digits starting from the right and set the carry bit appropriately.\n", 168 | " for i in range(num_digits):\n", 169 | " carry, digit_sum = add_digits(number_get_digit(a, i), \n", 170 | " number_get_digit(b, i), \n", 171 | " number_get_digit(sum, i))\n", 172 | " number_set_digit(sum, i, digit_sum)\n", 173 | " if (carry > 0):\n", 174 | " number_set_digit(sum, i + 1, 1)\n", 175 | " number_trim(sum)\n", 176 | " return sum" 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "__Unit Test__" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 6, 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | " succeeded\n" 196 | ] 197 | } 198 | ], 199 | "source": [ 200 | "def test_number_add():\n", 201 | " for i in range(200):\n", 202 | " for j in range(200):\n", 203 | " a = number_from_int(i)\n", 204 | " b = number_from_int(j)\n", 205 | " sum = number_add(a, b)\n", 206 | " if i + j != number_to_int(sum):\n", 207 | " return False\n", 208 | " return True\n", 209 | " \n", 210 | "run_test(test_number_add)" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "__Example__" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 7, 223 | "metadata": {}, 224 | "outputs": [ 225 | { 226 | "name": "stdout", 227 | "output_type": "stream", 228 | "text": [ 229 | "\n", 230 | "2 * 10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376 = 21430172143725346418968500981200036211228096234110672148875007767407021022498722449863967576313917162551893458351062936503742905713846280871969155149397149607869135549648461970842149210124742283755908364306092949967163882534797535118331087892154125829142392955373084335320859663305248773674411336138752\n" 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "def twice(a):\n", 236 | " return number_add(a, a)\n", 237 | " \n", 238 | "n = 2**1000\n", 239 | "a = number_from_int(n)\n", 240 | "result = number_to_int(twice(a))\n", 241 | "\n", 242 | "assert(result == n * 2)\n", 243 | "print('\\n2 *', n, '=', result)" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "## Subtraction\n", 251 | "\n", 252 | "We use again the standard algorithm, and we only assume that we have a \"subtraction table\" that let us subtract 2 individual digits." 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 8, 258 | "metadata": {}, 259 | "outputs": [], 260 | "source": [ 261 | "# Returns a - b.\n", 262 | "# Assumes that a >= b.\n", 263 | "def number_subtract(a, b):\n", 264 | " def subtract_digits(d1, d2, borrow):\n", 265 | " assert(borrow <= 1)\n", 266 | " diff = d1 - d2 - borrow\n", 267 | " if diff >= 0: return 0, diff\n", 268 | " return 1, diff + 10\n", 269 | " number_assert(a)\n", 270 | " number_assert(b)\n", 271 | " num_digits = len(a) \n", 272 | " diff = [0 for i in range(num_digits)]\n", 273 | " borrow = 0\n", 274 | " # Subtract pairs of digits starting from the right and set the borrow bit appropriately.\n", 275 | " for i in range(num_digits):\n", 276 | " borrow, digit_diff = subtract_digits(number_get_digit(a, i), \n", 277 | " number_get_digit(b, i), \n", 278 | " borrow)\n", 279 | " number_set_digit(diff, i, digit_diff)\n", 280 | " assert(borrow == 0)\n", 281 | " number_trim(diff)\n", 282 | " return diff" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": {}, 288 | "source": [ 289 | "__Unit Test__" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 9, 295 | "metadata": {}, 296 | "outputs": [ 297 | { 298 | "name": "stdout", 299 | "output_type": "stream", 300 | "text": [ 301 | " succeeded\n" 302 | ] 303 | } 304 | ], 305 | "source": [ 306 | "def test_number_subtract():\n", 307 | " for i in range(100):\n", 308 | " for j in range(i + 1):\n", 309 | " a = number_from_int(i)\n", 310 | " b = number_from_int(j)\n", 311 | " diff = number_subtract(a, b)\n", 312 | " if i - j != number_to_int(diff):\n", 313 | " return False\n", 314 | " return True\n", 315 | "\n", 316 | "run_test(test_number_subtract)" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "__Example__" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": 10, 329 | "metadata": {}, 330 | "outputs": [ 331 | { 332 | "name": "stdout", 333 | "output_type": "stream", 334 | "text": [ 335 | "\n", 336 | "10**100 - 1 = 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999\n" 337 | ] 338 | } 339 | ], 340 | "source": [ 341 | "n = 10**100\n", 342 | "a = number_from_int(n)\n", 343 | "result = number_to_int(number_subtract(a, [1]))\n", 344 | "\n", 345 | "assert(result == n - 1)\n", 346 | "print('\\n10**100 - 1 =', result)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "## Multiplication\n", 354 | "\n", 355 | "We essentially use the standard method that involves:\n", 356 | "1. multiplying the multiplicand by the digits in the multiplier\n", 357 | "2. shifting the partial results appropriately\n", 358 | "3. adding the partial results\n", 359 | "\n", 360 | "For the first step we avoid using a \"multiplication table\". Instead we precompute multiples of the multiplicand by every digit between 0 and 9. This is overkill for small multipliers but it works well here." 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": 11, 366 | "metadata": {}, 367 | "outputs": [], 368 | "source": [ 369 | "# Shifts n 'k' places to the left. That is, multiplies n by 10**k.\n", 370 | "def shift_left(n, k):\n", 371 | " num_digits = len(n) + k\n", 372 | " shifted = [0 for i in range(num_digits)]\n", 373 | " for i in range(len(n)):\n", 374 | " number_set_digit(shifted, i + k, number_get_digit(n, i))\n", 375 | " number_trim(shifted)\n", 376 | " return shifted\n", 377 | "\n", 378 | "# Returns a * b.\n", 379 | "def number_multiply(a, b):\n", 380 | " product = [0]\n", 381 | " # Precompute multiples of 'a'. This is overkill if 'b' is small but it is\n", 382 | " # useful when 'b' has many digits, and simplifies the algorithm.\n", 383 | " multiples_of_a = [[0] for i in range(10)]\n", 384 | " for i in range(1, 10):\n", 385 | " multiples_of_a[i] = number_add(multiples_of_a[i-1], a)\n", 386 | " # Standard algorithm, where we multiply 'a' by each digit in 'b', shifting the\n", 387 | " # result as necessary.\n", 388 | " for i in range(len(b)):\n", 389 | " b_digit = number_get_digit(b, i)\n", 390 | " product = number_add(product, \n", 391 | " shift_left(multiples_of_a[b_digit], i))\n", 392 | " return product " 393 | ] 394 | }, 395 | { 396 | "cell_type": "markdown", 397 | "metadata": {}, 398 | "source": [ 399 | "__Unit Test__" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": 12, 405 | "metadata": {}, 406 | "outputs": [ 407 | { 408 | "name": "stdout", 409 | "output_type": "stream", 410 | "text": [ 411 | " succeeded\n" 412 | ] 413 | } 414 | ], 415 | "source": [ 416 | "def test_number_multiply():\n", 417 | " for i in range(100):\n", 418 | " for j in range(100):\n", 419 | " a = number_from_int(i)\n", 420 | " b = number_from_int(j)\n", 421 | " product = number_multiply(a, b)\n", 422 | " if i * j != number_to_int(product):\n", 423 | " return False\n", 424 | " return True\n", 425 | " \n", 426 | "run_test(test_number_multiply)" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "__Examples__" 434 | ] 435 | }, 436 | { 437 | "cell_type": "code", 438 | "execution_count": 13, 439 | "metadata": {}, 440 | "outputs": [ 441 | { 442 | "name": "stdout", 443 | "output_type": "stream", 444 | "text": [ 445 | "\n", 446 | "100! = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000\n", 447 | "\n", 448 | "1 terabyte = 1099511627776\n" 449 | ] 450 | } 451 | ], 452 | "source": [ 453 | "def factorial(n):\n", 454 | " result = [1]\n", 455 | " while n != [0]:\n", 456 | " result = number_multiply(result, n)\n", 457 | " n = number_subtract(n, [1])\n", 458 | " return result\n", 459 | "\n", 460 | "def power(n, m):\n", 461 | " result = [1]\n", 462 | " while m != [0]:\n", 463 | " result = number_multiply(result, n)\n", 464 | " m = number_subtract(m, [1])\n", 465 | " return result\n", 466 | "\n", 467 | "import math\n", 468 | "\n", 469 | "result = number_to_int(factorial(number_from_int(100)))\n", 470 | "assert(result == math.factorial(100))\n", 471 | "print('\\n100! =', result)\n", 472 | "\n", 473 | "result = number_to_int(power(number_from_int(2), number_from_int(40)))\n", 474 | "assert(result == 2**40)\n", 475 | "print('\\n1 terabyte =', result)" 476 | ] 477 | }, 478 | { 479 | "cell_type": "markdown", 480 | "metadata": {}, 481 | "source": [ 482 | "## Division\n", 483 | "\n", 484 | "Standard division is pretty tedious. To compute a/b, we typically consider the first couple of digits of a and b, and try to estimate the first digit d of the division. We then compute b * d and hope that the product is not too small and not to big. Otherwise we try d-1 or d+1.\n", 485 | "\n", 486 | "Our algorithm avoids this guessing game, even it is a little bit slower." 487 | ] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": 14, 492 | "metadata": {}, 493 | "outputs": [], 494 | "source": [ 495 | "def number_compare(a, b):\n", 496 | " number_assert(a)\n", 497 | " number_assert(b)\n", 498 | " if len(a) > len(b): return 1\n", 499 | " if len(a) < len(b): return -1 \n", 500 | " num_digits = len(a) \n", 501 | " for i in range(num_digits):\n", 502 | " if a[i] > b[i]: return 1\n", 503 | " elif a[i] < b[i]: return -1\n", 504 | " return 0\n", 505 | "\n", 506 | "# Returns q, r with a = q*b + r and r < b.\n", 507 | "def number_divide(a, b):\n", 508 | " number_assert(a)\n", 509 | " number_assert(b)\n", 510 | " # At all times a = q*b + r and, at the end, r < b.\n", 511 | " q = [0]\n", 512 | " r = a\n", 513 | " while number_compare(r, b) >= 0:\n", 514 | " # Remove from r, b*10**k, for k as large as possible.\n", 515 | " k = len(r) - len(b)\n", 516 | " if number_compare(shift_left(b, k), r) > 0:\n", 517 | " k -= 1\n", 518 | " q = number_add(shift_left([1], k), q)\n", 519 | " r = number_subtract(r, shift_left(b, k))\n", 520 | " return q, r" 521 | ] 522 | }, 523 | { 524 | "cell_type": "markdown", 525 | "metadata": {}, 526 | "source": [ 527 | "__Example__" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 15, 533 | "metadata": { 534 | "scrolled": true 535 | }, 536 | "outputs": [ 537 | { 538 | "name": "stdout", 539 | "output_type": "stream", 540 | "text": [ 541 | "\n", 542 | "gcd of 2**512*3**256 and 2**256*3**512 is 16096079122395561512061763913577304064976913480336184419870793713264277662647884811647537309195067118494671396772863385036070451166210844912750004569643271101628982439604781505910612662005364378566656\n" 543 | ] 544 | } 545 | ], 546 | "source": [ 547 | "def gcd(a, b):\n", 548 | " if b == [0]:\n", 549 | " return a\n", 550 | " q, r = number_divide(a, b)\n", 551 | " return gcd(b, r)\n", 552 | "\n", 553 | "a = number_from_int(2**512*3**256)\n", 554 | "b = number_from_int(2**256*3**512)\n", 555 | "\n", 556 | "result = number_to_int(gcd(a, b))\n", 557 | "assert(result == 2**256*3**256)\n", 558 | "print('\\ngcd of 2**512*3**256 and 2**256*3**512 is', number_to_int(gcd(a, b)))\n", 559 | " " 560 | ] 561 | }, 562 | { 563 | "cell_type": "markdown", 564 | "metadata": {}, 565 | "source": [ 566 | "## Discussion\n", 567 | "\n", 568 | "Overall, that was a bit easier than expected.\n", 569 | "\n", 570 | "There were a few surprises:\n", 571 | "* Subtraction is not more difficult than addition. In fact the 2 algorithms are nearly identical.\n", 572 | "* We don't need a multiplication table to multiply big numbers. We can just use addition. This is not optimal, but still OK from a big-O point of view.\n", 573 | "* Division was surprisingly easy. We don't really need to guess each digit and we don't need to know how to multiply. Again this is not optimal, but OK from a big-O point of view.\n", 574 | "\n", 575 | "A few more remarks:\n", 576 | "* It would be even easier if we dealt with binary, instead of decimal, numbers. But we would still need to convert between the 2 representations.\n", 577 | "* Performance could be improved by representing numbers in a larger base, say 10^5, but the multiplication and division algorithms would become more complicated.\n", 578 | "* Addition and substraction run in linear time while multiplication and division run in quadratic time which is standard. The space complexity is probably substandard though. " 579 | ] 580 | } 581 | ], 582 | "metadata": { 583 | "kernelspec": { 584 | "display_name": "Python 3", 585 | "language": "python", 586 | "name": "python3" 587 | }, 588 | "language_info": { 589 | "codemirror_mode": { 590 | "name": "ipython", 591 | "version": 3 592 | }, 593 | "file_extension": ".py", 594 | "mimetype": "text/x-python", 595 | "name": "python", 596 | "nbconvert_exporter": "python", 597 | "pygments_lexer": "ipython3", 598 | "version": "3.6.5" 599 | } 600 | }, 601 | "nbformat": 4, 602 | "nbformat_minor": 2 603 | } 604 | -------------------------------------------------------------------------------- /Classic Constants.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
Paul Novaes
July 2018
\n", 8 | "\n", 9 | "\n", 10 | "# Classic Constants\n", 11 | "\n", 12 | "In this notebook, we show how to compute the 3 classic constants, __$e$__, __$\\sqrt 2$__ and __$\\pi$__ with __unlimited precision__.\n", 13 | "\n", 14 | "Though other methods are possible, and in some cases faster, we will use __Taylor series__, which are easy to implement and are fast enough.\n", 15 | "\n", 16 | "We assume that we can compute the 4 arithmetic operations on integers (but not on decimals) with arbitrary precision, which is the case of Python. We get away from decimals by multiplying the Taylor series by $10^d$, where $d$ is the number of digits sought, and working strictly with integers.\n", 17 | "\n", 18 | "## Computing $e$\n", 19 | "\n", 20 | "Using the Taylor Series for $e^x$ on $x = 1$, we get:\n", 21 | "\n", 22 | "$$e = {1\\over {0!}} + {1\\over {1!}} + {1\\over {2!}} + {1\\over {3!}} + \\cdots$$\n", 23 | "\n", 24 | "It is easy to see that, for $n$ large enough, $n$ terms give at least $n$ correct digits." 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "metadata": { 31 | "scrolled": true 32 | }, 33 | "outputs": [ 34 | { 35 | "name": "stdout", 36 | "output_type": "stream", 37 | "text": [ 38 | "10000 digits of e:\n", 39 | "\n", 40 | "27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354021234078498193343210681701210056278802351930332247450158539047304199577770935036604169973297250886876966403555707162268447162560798826517871341951246652010305921236677194325278675398558944896970964097545918569563802363701621120477427228364896134225164450781824423529486363721417402388934412479635743702637552944483379980161254922785092577825620926226483262779333865664816277251640191059004916449982893150566047258027786318641551956532442586982946959308019152987211725563475463964479101459040905862984967912874068705048958586717479854667757573205681288459205413340539220001137863009455606881667400169842055804033637953764520304024322566135278369511778838638744396625322498506549958862342818997077332761717839280349465014345588970719425863987727547109629537415211151368350627526023264847287039207643100595841166120545297030236472549296669381151373227536450988890313602057248176585118063036442812314965507047510254465011727211555194866850800368532281831521960037356252794495158284188294787610852639813955990067376482922443752871846245780361929819713991475644882626039033814418232625150974827987779964373089970388867782271383605772978824125611907176639465070633045279546618550966661856647097113444740160704626215680717481877844371436988218559670959102596862002353718588748569652200050311734392073211390803293634479727355955277349071783793421637012050054513263835440001863239914907054797780566978533580489669062951194324730995876552368128590413832411607226029983305353708761389396391779574540161372236187893652605381558415871869255386061647798340254351284396129460352913325942794904337299085731580290958631382683291477116396337092400316894586360606458459251269946557248391865642097526850823075442545993769170419777800853627309417101634349076964237222943523661255725088147792231519747780605696725380171807763603462459278778465850656050780844211529697521890874019660906651803516501792504619501366585436632712549639908549144200014574760819302212066024330096412704894390397177195180699086998606636583232278709376502260149291011517177635944602023249300280401867723910288097866605651183260043688508817157238669842242201024950551881694803221002515426494639812873677658927688163598312477886520141174110913601164995076629077943646005851941998560162647907615321038727557126992518275687989302761761146162549356495903798045838182323368612016243736569846703785853305275833337939907521660692380533698879565137285593883499894707416181550125397064648171946708348197214488898790676503795903669672494992545279033729636162658976039498576741397359441023744329709355477982629614591442936451428617158587339746791897571211956187385783644758448423555581050025611492391518893099463428413936080383091662818811503715284967059741625628236092168075150177725387402564253470879089137291722828611515915683725241630772254406337875931059826760944203261924285317018781772960235413060672136046000389661093647095141417185777014180606443636815464440053316087783143174440811949422975599314011888683314832802706553833004693290115744147563139997221703804617092894579096271662260740718749975359212756084414737823303270330168237193648002173285734935947564334129943024850235732214597843282641421684878721673367010615094243456984401873312810107945127223737886126058165668053714396127888732527373890392890506865324138062796025930387727697783792868409325365880733988457218746021005311483351323850047827169376218004904795597959290591655470505777514308175112698985188408718564026035305583737832422924185625644255022672155980274012617971928047139600689163828665277009752767069777036439260224372841840883251848770472638440379530166905465937461619323840363893131364327137688841026811219891275223056256756254701725086349765367288605966752740868627407912856576996313789753034660616669804218267724560530660773899624218340859882071864682623215080288286359746839654358856685503773131296587975810501214916207656769950659715344763470320853215603674828608378656803073062657633469774295634643716709397193060876963495328846833613038829431040800296873869117066666146800015121143442256023874474325250769387077775193299942137277211258843608715834835626961661980572526612206797540621062080649882918454395301529982092503005498257043390553570168653120526495614857249257386206917403695213533732531666345466588597286659451136441370331393672118569553952108458407244323835586063106806964924851232632699514603596037297253198368423363904632136710116192821711150282801604488058802382031981493096369596735832742024988245684941273860566491352526706046234450549227581151709314921879592718001940968866986837037302200475314338181092708030017205935530520700706072233999463990571311587099635777359027196285061146514837526209565346713290025994397663114545902685898979115837093419370441155121920117164880566945938131183843765620627846310490346293950029458341164824114969758326011800731699437393506966295712410273239138741754923071862454543222039552735295240245903805744502892246886285336542213815722131163288112052146489805180092024719391710555390113943316681515828843687606961102505171007392762385553386272553538830960671644662370922646809671254061869502143176211668140097595281493907222601112681153108387317617323235263605838173151034595736538223534992935822836851007810884634349983518404451704270189381994243410090575376257767571118090088164183319201962623416288166521374717325477727783488774366518828752156685719506371936565390389449366421764003121527870222366463635755503565576948886549500270853923617105502131147413744106134445544192101336172996285694899193369184729478580729156088510396781959429833186480756083679551496636448965592948187851784038773326247051945050419847742014183947731202815886845707290544057510601285258056594703046836344592652552137008068752009593453607316226118728173928074623094685367823106097921599360019946237993434210687813497346959246469752506246958616909178573976595199392993995567542714654910456860702099012606818704984178079173924071945996323060254707901774527513186809982284730860766536866855516467702911336827563107223346726113705490795365834538637196235856312618387156774118738527722922594743373785695538456246801013905727871016512966636764451872465653730402443684140814488732957847348490003019477888020460324660842875351848364959195082888323206522128104190448047247949291342284951970022601310430062410717971502793433263407995960531446053230488528972917659876016667811937932372453857209607582277178483361613582612896226118129455927462767137794487586753657544861407611931125958512655759734573015333642630767985443385761715333462325270572005303988289499034259566232975782488735029259166825894456894655992658454762694528780516501720674785417887982276806536650641910973434528878338621726156269582654478205672987756426325321594294418039943217000090542650763095588465895171709147607437136893319469090981904501290307099566226620303182649365733698419555776963787624918852865686607600566025605445711337286840205574416030837052312242587223438854123179481388550075689381124935386318635287083799845692619981794523364087429591180747453419551420351726184200845509170845682368200897739455842679214273477560879644279202708312150156406341341617166448069815483764491573900121217041547872591998943825364950514771379399147205219529079396137621107238494290616357604596231253506068537651423115349665683715116604220796394466621163255157729070978473156278277598788136491951257483328793771571459091064841642678309949723674420175862269402159407924480541255360431317992696739157542419296607312393763542139230617876753958711436104089409966089471418340698362993675362621545247298464213752891079884381306095552622720837518629837066787224430195793793786072107254277289071732854874374355781966511716618330881129120245204048682200072344035025448202834254187884653602591506445271657700044521097735585897622655484941621714989532383421600114062950718490427789258552743035221396835679018076406042138307308774460170842688272261177180842664333651780002171903449234264266292261456004337383868335555343453004264818473989215627086095650629340405264943244261445665921291225648893569655009154306426134252668472594914314239398845432486327461842846655985332312210466259890141712103446084271616619001257195870793217569698544013397622096749454185407118446433946990162698351607848924514058940946395267807354579700307051163682519487701189764002827648414160587206184185297189154019688253289309149665345753571427318482016384644832499037886069008072709327673127581966563941148961716832980455139729506687604740915420428429993541025829113502241690769431668574242522509026939034814856451303069925199590436384028429267412573422447765584177886171737265462085498294498946787350929581652632072258992368768457017823038096567883112289305809140572610865884845873101658151167533327674887014829167419701512559782572707406431808601428149024146780472327597684269633935773542930186739439716388611764209004068663398856841681003872389214483176070116684503887212364367043314091155733280182977988736590916659612402021778558854876176161989370794380056663364884365089144805571039765214696027662583599051987042300179465535139\n" 41 | ] 42 | } 43 | ], 44 | "source": [ 45 | "def e(num_terms, num_digits):\n", 46 | " term = 10**num_digits\n", 47 | " result = term\n", 48 | " for i in range(1, num_terms + 1):\n", 49 | " term //= i\n", 50 | " result += term\n", 51 | " return result\n", 52 | "\n", 53 | "num_digits = 10000\n", 54 | "print(num_digits, 'digits of e:\\n')\n", 55 | "print(e(num_digits, num_digits))" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "All digits, except the last 3, are correct (3 incorrect digits are roughly what we would expect from rounding errors).\n", 63 | "\n", 64 | "## Computing $\\sqrt 2$\n", 65 | "\n", 66 | "The Taylor Series for $(1 + x)^\\alpha$ is:\n", 67 | "\n", 68 | "$$(1 + x)^\\alpha = 1 + {\\alpha \\over {1!}}x + {{\\alpha(\\alpha - 1)} \\over {2!}}x^2 + {{\\alpha(\\alpha -1)(\\alpha - 2)} \\over {3!}}x^3 + \\cdots$$\n", 69 | "\n", 70 | "For $x = 1$ and $\\alpha = {1 \\over 2}$, the ratio between successive terms tends to 1, and therefore the series converges very slowly.\n", 71 | "\n", 72 | "But we can use $x = -{1\\over 2}$ and $\\alpha = -{1\\over 2}$ instead, since $$\\sqrt 2 = \\left({1\\over 2}\\right)^{-{1\\over 2}}$$\n", 73 | "\n", 74 | "It is easy to see that, for $n$ large enough, $4n$ terms give at least $n$ correct digits." 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 2, 80 | "metadata": {}, 81 | "outputs": [ 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "10000 digits of sqrt(2):\n", 87 | "\n", 88 | "14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488472089694633862891562882765952635140542267653239694617511291602408715510135150455381287560052631468017127402653969470240300517495318862925631385188163478001569369176881852378684052287837629389214300655869568685964595155501644724509836896036887323114389415576651040883914292338113206052433629485317049915771756228549741438999188021762430965206564211827316726257539594717255934637238632261482742622208671155839599926521176252698917540988159348640083457085181472231814204070426509056532333398436457865796796519267292399875366617215982578860263363617827495994219403777753681426217738799194551397231274066898329989895386728822856378697749662519966583525776198939322845344735694794962952168891485492538904755828834526096524096542889394538646625744927556381964410316979833061852019379384940057156333720548068540575867999670121372239475821426306585132217408832382947287617393647467837431960001592188807347857617252211867490424977366929207311096369721608933708661156734585334833295254675851644710757848602463600834449114818587655554286455123314219926311332517970608436559704352856410087918500760361009159465670676883605571740076756905096136719401324935605240185999105062108163597726431380605467010293569971042425105781749531057255934984451126922780344913506637568747760283162829605532422426957534529028838768446429173282770888318087025339852338122749990812371892540726475367850304821591801886167108972869229201197599880703818543332536460211082299279293072871780799888099176741774108983060800326311816427988231171543638696617029999341616148786860180455055539869131151860103863753250045581860448040750241195184305674533683613674597374423988553285179308960373898915173195874134428817842125021916951875593444387396189314549999906107587049090260883517636224749757858858368037457931157339802099986622186949922595913276423619410592100328026149874566599688874067956167391859572888642473463585886864496822386006983352642799056283165613913942557649062065186021647263033362975075697870606606856498160092718709292153132368281356988937097416504474590960537472796524477094099241238710614470543986743647338477454819100872886222149589529591187892149179833981083788278153065562315810360648675873036014502273208829351341387227684176678436905294286984908384557445794095986260742499549168028530773989382960362133539875320509199893607513906444495768456993471276364507163279154701597733548638939423257277540038260274785674172580951416307159597849818009443560379390985590168272154034581581521004936662953448827107292396602321638238266612626830502572781169451035379371568823365932297823192986064679789864092085609558142614363631004615594332550474493975933999125419532300932175304476533964706627611661753518754646209676345587386164880198848497479264045065444896910040794211816925796857563784881498986416854994916357614484047021033989215342377037233353115645944389703653166721949049351882905806307401346862641672470110653463493916407146285567980177933814424045269137066609777638784866238003392324370474115331872531906019165996455381157888413808433232105337674618121780142960928324113627525408873729051294073394794330619439569367020794295158782283493219316664111301549594698378977674344435393377099571349884078908508158923660700886581054709497904657229888808924612828160131337010290802909997456478495815456146487155163905024198579061310934587833062002622073724716766854554999049940857108099257599288932366154382719550057816251330381531465779079268685008069844284791524242754410268057563215653220618857512251130639370253629271619682512591920252160587011895967322442392674237344907646467273753479645988191498079317180024238554538860383683108007791824664627541174442500187277795181643834514634612990207633430179685543856316677235183893366670422221109391449302879638128398893117313084300421255501854985065294556377660314612559091046113847682823595924772286290426427361632645854433928772638603431498048963973633297548859256811492968361267258985738332164366634870234773026101061305072986115341299488087744731112295426527516536659117301423606265258690771982170370981046443604772267392829874152593069562063847108274082184906737233058743029709242899481739244078693752844010443990485208788519141935415129006817351703069386970590047425157655248078447362144105016200845444122255956202984725940352801906798068098300396453985685930458625260637797453559927747299064888745451242496076378010863900191058092874764720751109238605950195432281602088796215162338521612875228518025292876183257037172857406763944909825464422184654308806610580201584728406712630254593798906508168571371656685941300533197036596403376674146104956376510308366134893109478026812935573318905519705201845150399690986631525124116111925940552808564989319589834562331983683494880806171562439112866312797848371978953369015277600549805516635019785557110140555297633841275044686046476631832661165182067501204766991098721910444744032689436415959427921994423553718704299559240314091712848158543866005385713583639816309452407557009325168243441682408361979273372825215462246961533217026829950979089034594858878349439616204358422497397187113958927305092197054917176961600445580899427878880369169432894595147226722926124850696173163809410821860045286102696547576304310256027152313969482135519821409716549097319992834925674097490392297126348693414574933198041718076111963902278664075922434167762466236238913110270343304576368141128321326308582239456219598086612939996201234156176318174312420089014983848560480879864608393596492366514296812577314322914568716827621996118278269531574983802624651759054103976181287604216386134502213262727756612441133610775195557749508656360673786650623185640699122801875741785494661253275997697960597760590756489106661015838417202818530432119044657752554277543798726054881736198267581686283295260789932226683602838513512281059318591028641508157056319717315183136250243590414632122392176633982689368253150530059891547029095371932662073411234947433678846902013904978428521634144292145895582878476693946464267812219049785636355263368278051860098699248937786002398769169807656621943898544370805946433362333810587458162354756001365924352426571430834655457680023708146757325254702550747637471635067851599173693793251032682760628645914618204721486370370771926926823623334720379245964691810526139153086280291440965482563873092730426544662929045896063751918711469345361973324789572707031530930901921199199993615765003503984054067425387927527922724733566770607837911384488936261367657060263600315132952095395202854897384486256134924414708607086602676349978793420875836121947116994223848482595914304528107062601508969135303017720062717054402090669514915274597719705947695474095210287872557856880022193717743558110793930883384558648277291008629554566141306721230848740227121058686323388237413884428938155444647105755651468435702946635062893873569868688376480326519528414653517395302736120137420300986739838514321900436028982698293529399414129230580384565022707216815161941011449826301364900877048398488386090653368599054583895203185648041493272142390865164999431659207965953569430723112911629286797517156688905439322035691293324570208067194440497304943981408227829602799424541083166675921424835182723817205041039274288801556223380796147512433514731021284545944899444996000752437519570116683417447490795882099517836768023236517674972301487457742725994760962198432714835298611190272873584905217975908374197486026706053746231530039375212367867752848692195857137554269684827836317861109933680143915905974842858054516130230143979057016108898627779610750673332676048654929251399781390535882276893732204941483940135560356560442140176120605131806891989962606184831853401836237821726637580455247196266174925422852804571442048578342113228008528704205488992341278554812367615377071042544698685219911228354266349997127483660762462418207364666171283947484732804744304033441072004287271275670279567582429262719454580530026664899650795697781786219421720052371653694677041951119127046248360511302890464377511486948878496151188414719100012558838366606772084112351535588112677895715585904125762616010675131535802124273318710006358249545040995794072547989003168265123731190556682915194305370848930786919742829049038603723116099283424317122250994547150192866648787107951995180054633883844315481724635480244518030845273431000621371034625733060012349737443558180965678464641533905146569193245623531405779193698988423647183525375805257713311200797104068315492665402026046806818391437827214769063242469517128636738443139833371176159418699934662623453734523567940124168092291163609563721674528391709909146648507392051516056047378710615470216996074656930979442612146925615934256494019122989514732544715181263258368897282262833295240359700727863364604594707124174729468775705958157349962848099567839255474240448991887071069675242507745201229360810574142653234724064162141033353340551104521261750359028403745459186450472762434207177092979354010214096464502836834180407586081001407216192477179809859681115404464437285689592868319777977869346415984697451339177415379048778808300220583350467465553230285873228374\n" 89 | ] 90 | } 91 | ], 92 | "source": [ 93 | "def sqrt2(num_terms, num_digits):\n", 94 | " term = 10**num_digits\n", 95 | " result = term\n", 96 | " for i in range(1, num_terms + 1):\n", 97 | " # Multiply term by ((alpha - (i - 1))/i)*x, for alpha = -1/2, x = -1/2,\n", 98 | " # that is by (2*i - 1)/(4i).\n", 99 | " term *= 2*i - 1\n", 100 | " term //= 4*i\n", 101 | " result += term\n", 102 | " return result\n", 103 | "\n", 104 | "num_digits = 10000\n", 105 | "print(num_digits, 'digits of sqrt(2):\\n') \n", 106 | "print(sqrt2(4*num_digits, num_digits))" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "All digits, up to the last 5, are correct.\n", 114 | "\n", 115 | "## Computing $\\pi$\n", 116 | "\n", 117 | "To compute $\\pi$ one can use the Taylor series of $\\arctan$:\n", 118 | "\n", 119 | "$$\\arctan(x) = x - {{x^3}\\over 3} + {{x^5}\\over 5} - {{x^7}\\over 7} + \\cdots$$\n", 120 | "\n", 121 | "With $x = 1$, we get\n", 122 | "\n", 123 | "$${\\pi \\over 4} = 1 - {1\\over 3} + {1\\over 5} - {1\\over 7} + \\cdots$$\n", 124 | "\n", 125 | "Unfortunately the rate of convergence for $x = 1$ is very slow.\n", 126 | "\n", 127 | "Instead we will use\n", 128 | "\n", 129 | "$${\\pi\\over 4} = \\arctan({1\\over 2}) + \\arctan({1\\over 3})$$\n", 130 | "\n", 131 | "This formula can easily be verified by taking the $\\tan$ of both sides of the formula and by using \n", 132 | "\n", 133 | "$$\\tan(\\alpha + \\beta) = {{\\tan(\\alpha) + \\tan(\\beta)}\\over{1 - \\tan(\\alpha)\\tan(\\beta)}}$$" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 3, 139 | "metadata": { 140 | "scrolled": false 141 | }, 142 | "outputs": [ 143 | { 144 | "name": "stdout", 145 | "output_type": "stream", 146 | "text": [ 147 | "10000 digits of pi:\n", 148 | "\n", 149 | "31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256321480\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "# Computes the arctan of 1/n, where n is an integer.\n", 155 | "def arctan(n, num_terms, num_digits):\n", 156 | " term = 10**num_digits // n\n", 157 | " result = term\n", 158 | " for i in range(1, num_terms + 1):\n", 159 | " term //= -n*n\n", 160 | " result += term // (i * 2 + 1)\n", 161 | " return result\n", 162 | "\n", 163 | "def pi(num_terms, num_digits):\n", 164 | " return 4*(arctan(2, num_terms, num_digits) + arctan(3, num_terms, num_digits))\n", 165 | "\n", 166 | "num_digits = 10000\n", 167 | "print(num_digits, 'digits of pi:\\n')\n", 168 | "print(pi(4*num_digits, num_digits))" 169 | ] 170 | }, 171 | { 172 | "cell_type": "markdown", 173 | "metadata": {}, 174 | "source": [ 175 | "All digits, up to the last 5, are correct.\n", 176 | "\n", 177 | "## Notes\n", 178 | "\n", 179 | "__About $\\sqrt 2$__\n", 180 | "\n", 181 | "The classical way of computing $\\sqrt n$ uses Newton's method:\n", 182 | "* $x_0 = 1$\n", 183 | "* for $i \\ge 0$, $x_{i+1} = (x_i + n/x_i)/2$" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 4, 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "1.414213562373095\n" 196 | ] 197 | } 198 | ], 199 | "source": [ 200 | "def newton_sqrt(n, num_terms):\n", 201 | " x = 1\n", 202 | " for i in range(1, num_terms + 1):\n", 203 | " x = (x + n/x)/2\n", 204 | " return x\n", 205 | " \n", 206 | "print(newton_sqrt(2, 5))" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "This method is extremely fast as $n$ terms yield rough $2^n$ correct digits.\n", 214 | "\n", 215 | "__About $\\pi$__\n", 216 | "\n", 217 | "The history of $\\pi$ is fascinating but it is not until the 1700s that at least 100 digits of $\\pi$ were computed.\n", 218 | "\n", 219 | "In the 1940s, with desk calculators, the 1000-digit milestone was reached but it's not until the late 1950s that the early digital computers were able to produce 10,000 digits.\n", 220 | "\n", 221 | "In all these cases, the methods used were based on Taylor series, with formulas similar to the one we used (which is due to Euler). A famous such formula (which converges a little faster than Euler's) is due to John Machin:\n", 222 | "\n", 223 | "$${\\pi\\over 4} = 4\\arctan({1\\over 5}) + \\arctan({1\\over 239})$$" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 5, 229 | "metadata": { 230 | "scrolled": false 231 | }, 232 | "outputs": [ 233 | { 234 | "name": "stdout", 235 | "output_type": "stream", 236 | "text": [ 237 | "10000 digits of pi (Machin):\n", 238 | "\n", 239 | "31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275900994657640789512694683983525957098258226205224894077267194782684826014769909026401363944374553050682034962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382686838689427741559918559252459539594310499725246808459872736446958486538367362226260991246080512438843904512441365497627807977156914359977001296160894416948685558484063534220722258284886481584560285060168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125150760694794510965960940252288797108931456691368672287489405601015033086179286809208747609178249385890097149096759852613655497818931297848216829989487226588048575640142704775551323796414515237462343645428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344037420073105785390621983874478084784896833214457138687519435064302184531910484810053706146806749192781911979399520614196634287544406437451237181921799983910159195618146751426912397489409071864942319615679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215030680384477345492026054146659252014974428507325186660021324340881907104863317346496514539057962685610055081066587969981635747363840525714591028970641401109712062804390397595156771577004203378699360072305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116722910981690915280173506712748583222871835209353965725121083579151369882091444210067510334671103141267111369908658516398315019701651511685171437657618351556508849099898599823873455283316355076479185358932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923233260972997120844335732654893823911932597463667305836041428138830320382490375898524374417029132765618093773444030707469211201913020330380197621101100449293215160842444859637669838952286847831235526582131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396665573092547110557853763466820653109896526918620564769312570586356620185581007293606598764861179104533488503461136576867532494416680396265797877185560845529654126654085306143444318586769751456614068007002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830634328587856983052358089330657574067954571637752542021149557615814002501262285941302164715509792592309907965473761255176567513575178296664547791745011299614890304639947132962107340437518957359614589019389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571853061422881375850430633217518297986622371721591607716692547487389866549494501146540628433663937900397692656721463853067360965712091807638327166416274888800786925602902284721040317211860820419000422966171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513622224771589150495309844489333096340878076932599397805419341447377441842631298608099888687413260472156951623965864573021631598193195167353812974167729478672422924654366800980676928238280689964004824354037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617557829735233446042815126272037343146531977774160319906655418763979293344195215413418994854447345673831624993419131814809277771038638773431772075456545322077709212019051660962804909263601975988281613323166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267945612753181340783303362542327839449753824372058353114771199260638133467768796959703098339130771098704085913374641442822772634659470474587847787201927715280731767907707157213444730605700733492436931138350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415956258658655705526904965209858033850722426482939728584783163057777560688876446248246857926039535277348030480290058760758251047470916439613626760449256274204208320856611906254543372131535958450687724602901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455254079091451357111369410911939325191076020825202618798531887705842972591677813149699009019211697173727847684726860849003377024242916513005005168323364350389517029893922334517220138128069650117844087451960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510228334508504860825039302133219715518430635455007668282949304137765527939751754613953984683393638304746119966538581538420568533862186725233402830871123282789212507712629463229563989898935821167456270102183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501956730229219139339185680344903982059551002263535361920419947455385938102343955449597783779023742161727111723643435439478221818528624085140066604433258885698670543154706965747458550332323342107301545940516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867446047746491599505497374256269010490377819868359381465741268049256487985561453723478673303904688383436346553794986419270563872931748723320837601123029911367938627089438799362016295154133714248928307220126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605277219005561484255518792530343513984425322341576233610642506390497500865627109535919465897514131034822769306247435363256916078154781811528436679570611086153315044521274739245449454236828860613408414863776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862916421939949072362346468441173940326591840443780513338945257423995082965912285085558215725031071257012668302402929525220118726767562204154205161841634847565169998116141010029960783869092916030288400269104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157959847035622262934860034158722980534989650226291748788202734209222245339856264766914905562842503912757710284027998066365825488926488025456610172967026640765590429099456815065265305371829412703369313785178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291616152881384379099042317473363948045759314931405297634757481193567091101377517210080315590248530906692037671922033229094334676851422144773793937517034436619910403375111735471918550464490263655128162288244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968340800535598491754173818839994469748676265516582765848358845314277568790029095170283529716344562129640435231176006651012412006597558512761785838292041974844236080071930457618932349229279650198751872127267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522742995818072471625916685451333123948049470791191532673430282441860414263639548000448002670496248201792896476697583183271314251702969234889627668440323260927524960357996469256504936818360900323809293459588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885690941130315095261793780029741207665147939425902989695946995565761218656196733786236256125216320862869222103274889218654364802296780705765615144632046927906821207388377814233562823608963208068222468012248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417254370906979396122571429894671543578468788614445812314593571984922528471605049221242470141214780573455105008019086996033027634787081081754501193071412233908663938339529425786905076431006383519834389341596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848308407611830130527932054274628654036036745328651057065874882256981579367897669742205750596834408697350201410206723585020072452256326513410559240190274216248439140359989535394590944070469120914093870012645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256321480\n" 240 | ] 241 | } 242 | ], 243 | "source": [ 244 | "def machin_pi(num_terms, num_digits):\n", 245 | " return 4*(4*arctan(5, num_terms, num_digits) - arctan(239, num_terms, num_digits))\n", 246 | "\n", 247 | "num_digits = 10000\n", 248 | "print(num_digits, 'digits of pi (Machin):\\n')\n", 249 | "print(pi(2*num_digits, num_digits))" 250 | ] 251 | } 252 | ], 253 | "metadata": { 254 | "kernelspec": { 255 | "display_name": "Python 3", 256 | "language": "python", 257 | "name": "python3" 258 | }, 259 | "language_info": { 260 | "codemirror_mode": { 261 | "name": "ipython", 262 | "version": 3 263 | }, 264 | "file_extension": ".py", 265 | "mimetype": "text/x-python", 266 | "name": "python", 267 | "nbconvert_exporter": "python", 268 | "pygments_lexer": "ipython3", 269 | "version": "3.6.5" 270 | } 271 | }, 272 | "nbformat": 4, 273 | "nbformat_minor": 2 274 | } 275 | -------------------------------------------------------------------------------- /PRIMES in NP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
Paul Novaes
July 2018
\n", 8 | "\n", 9 | "# PRIMES in NP\n", 10 | "\n", 11 | "This notebook shows that primes have efficient short proofs of primality.\n", 12 | "\n", 13 | "More precisely, for any prime $p$, there is a certificate of primality whose length is polynomial in the number of digits of $p$, and that can be verified in polynomial time.\n", 14 | "\n", 15 | "Note that we are not saying that it is easy to find such certificates. We are just saying that they exist.\n", 16 | "\n", 17 | "## PRIMES is in coNP\n", 18 | "\n", 19 | "A related problem is to show that a number is __not__ prime. This is a much easier problem: to show that $n$ is composite it is enough to give 2 integers $a$ and $b$, greater than 1, such that \n", 20 | "\n", 21 | "$$n = ab$$\n", 22 | "\n", 23 | "Here the certificate of compositeness is the pair $(a, b)$ and it can be verified by computing $ab$ and checking that it gives $n$, indeed. For example:" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | "( 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151 , 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127 )\n", 36 | "\n", 37 | "is a certificate of compositeness for\n", 38 | "\n", 39 | "3646154850295011369707131011438711095400799139943170490872585628683549034362552065955809589514611470241298944167703929337528884908857116141935206466329731087514964112054543019336536216107629523597606330154669196064144182472739556974502462402438903115845725630946428943768540714098264727068026730424033578827886916761701429264950573899186177\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "# These Mersenne numbers are known to be prime.\n", 45 | "mersenne_521 = 2**521 - 1\n", 46 | "mersenne_607 = 2**607 - 1\n", 47 | "\n", 48 | "n = mersenne_521 * mersenne_607\n", 49 | "a = mersenne_521\n", 50 | "b = mersenne_607\n", 51 | "\n", 52 | "print('(', a, ',', b, ')')\n", 53 | "print('\\nis a certificate of compositeness for\\n')\n", 54 | "print(n)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "The goal of this notebook is to show that there are also short proofs (though not as short) for the primality of primes such as the 2 Mersenne numbers above.\n", 62 | "\n", 63 | "## Traditional primality algorithm\n", 64 | "The traditional way of checking that a number $n$ is prime is by making sure it cannot be evenly divided by smaller numbers. Actually, checking up to $\\sqrt n$ is enough." 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 2, 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "name": "stdout", 74 | "output_type": "stream", 75 | "text": [ 76 | "List of prime numbers:\n", 77 | "\n", 78 | "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 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 ...\n" 79 | ] 80 | } 81 | ], 82 | "source": [ 83 | "# Returns True if n is prime.\n", 84 | "def is_prime(n):\n", 85 | " if n <= 2: return False\n", 86 | " if n == 2: return True\n", 87 | " if n % 2 == 0: return False\n", 88 | " i = 3\n", 89 | " while (i*i <= n):\n", 90 | " if n % i == 0:\n", 91 | " return False\n", 92 | " i += 2\n", 93 | " return True\n", 94 | "\n", 95 | "print('List of prime numbers:\\n')\n", 96 | "for n in range(1, 1000):\n", 97 | " if is_prime(n):\n", 98 | " print(n, end=' ')\n", 99 | "print('...')" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": {}, 105 | "source": [ 106 | "This works well for relatively small numbers but doesn't scale up to, say, 100 digits. Note that the time complexity is $\\Theta(\\sqrt n)$, that is exponential __on the number of digits__.\n", 107 | "\n", 108 | "## Fermat's little theorem\n", 109 | "\n", 110 | "__Fermat's little theorem__\n", 111 | "\n", 112 | "If $p$ is prime and $0 < a < p$ then\n", 113 | "\n", 114 | "$$a^{p-1} = 1 \\mod p$$\n", 115 | "\n", 116 | "__Proof__\n", 117 | "\n", 118 | "For any $a$\n", 119 | "\n", 120 | "$$(a + 1)^{p} = {p\\choose 0}a^p + {p\\choose 1}a^{p-1} + {p\\choose 2}a^{p-2} + \\cdots + {p\\choose p}a^0$$\n", 121 | "\n", 122 | "Since $p$ is prime, most of the coefficients are divisible by $p$. Indeed for $1 \\leq q \\leq p-1$, ${p\\choose q} = {{p!} \\over {q!(p-q)!}}$ has $p$ in the numerator, but not in the denominator. Therefore we have\n", 123 | "\n", 124 | "$$(a + 1)^{p} = a^p + 1 \\mod p$$\n", 125 | "\n", 126 | "For $a = 1$, we get $$2^p = 2 \\mod p$$\n", 127 | "and using induction on $a$, we get more generally $$a^p = a \\mod p$$\n", 128 | "\n", 129 | "If $(a, p) = 1$, $a$ has an inverse (mod p), as can be seen using Euclid's algorithm, and therefore, for $0 < a < p$\n", 130 | "\n", 131 | "$$a^{p-1} = 1 \\mod p$$\n", 132 | "\n", 133 | "Let's check the theorem for a few values:" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 3, 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "name": "stdout", 143 | "output_type": "stream", 144 | "text": [ 145 | "2 ** ( 2 - 1 ) = 1 mod 3\n", 146 | "2 ** ( 96 - 1 ) = 1 mod 97\n", 147 | "23 ** ( 58 - 1 ) = 1 mod 59\n", 148 | "2 ** ( 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057150 - 1 ) = 1 mod 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151\n", 149 | "2 ** ( 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728126 - 1 ) = 1 mod 531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "# Computes a**n mod m.\n", 155 | "def pow_mod(a, n, m):\n", 156 | " if a >= m:\n", 157 | " a %= m\n", 158 | " if n == 0:\n", 159 | " return 1\n", 160 | " result = pow_mod(a, n // 2, m) ** 2\n", 161 | " if n % 2 == 1: \n", 162 | " result = a * result\n", 163 | " result = result % m\n", 164 | " return result\n", 165 | "\n", 166 | "def fermat_test(n, a):\n", 167 | " return pow_mod(a, n-1, n) == 1\n", 168 | "\n", 169 | "def check_fermat(a, n):\n", 170 | " assert(fermat_test(n, a))\n", 171 | " print(a, '** (', n-1, '- 1 ) = 1 mod', n)\n", 172 | " \n", 173 | "check_fermat(2, 3)\n", 174 | "check_fermat(2, 97)\n", 175 | "check_fermat(23, 59)\n", 176 | "check_fermat(2, mersenne_521)\n", 177 | "check_fermat(2, mersenne_607)" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "On the other hand:" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 4, 190 | "metadata": { 191 | "scrolled": false 192 | }, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "n = 3646154850295011369707131011438711095400799139943170490872585628683549034362552065955809589514611470241298944167703929337528884908857116141935206466329731087514964112054543019336536216107629523597606330154669196064144182472739556974502462402438903115845725630946428943768540714098264727068026730424033578827886916761701429264950573899186177\n", 199 | "\n", 200 | "is composite. Indeed: 2^(n-1) mod n =\n", 201 | "\n", 202 | "117617898447960240594738066243890558744589682390176529192112418734563680630878699069868895603571073655147079382052381245794746597893046791796022644053827181234957536466206089534971894653069934981964122654984031075848787023021459140241103234472410417849613699642368118324583536948112226181224721873646572082806254147448685639776817059429343\n" 203 | ] 204 | } 205 | ], 206 | "source": [ 207 | "composite = mersenne_521 * mersenne_607\n", 208 | "print('n =', composite)\n", 209 | "print('\\nis composite. Indeed: 2^(n-1) mod n =\\n')\n", 210 | "print(pow_mod(2, composite-1, composite))" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "Note that Fermat's test is very fast even for very large numbers, and gives us, at least in the case above, a very fast proof of compositeness. \n", 218 | "\n", 219 | "## Pseudoprimes\n", 220 | "\n", 221 | "Fermat's little theorem is remarkable not only in itself, but also because its converse is almost true. But not quite as we are going to see.\n", 222 | "\n", 223 | "__Poulet numbers__\n", 224 | "\n", 225 | "Does $$2^{n-1} = 1 \\mod n$$ imply that $n$ is prime?\n", 226 | "\n", 227 | "Unfortunately, this is not true in general. Such numbers, composite but verifying the identity above, are called Poulet numbers." 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": 5, 233 | "metadata": {}, 234 | "outputs": [ 235 | { 236 | "name": "stdout", 237 | "output_type": "stream", 238 | "text": [ 239 | "Poulet numbers\n", 240 | "\n", 241 | "Interval[ 2 , 1000 ]\n", 242 | " 167 primes\n", 243 | " 3 poulet numbers : [341, 561, 645]\n", 244 | "\n", 245 | "Interval[ 1000000 , 1010000 ]\n", 246 | " 753 primes\n", 247 | " 1 poulet numbers : [1004653]\n" 248 | ] 249 | } 250 | ], 251 | "source": [ 252 | "def is_poulet(n):\n", 253 | " return fermat_test(n, 2) and not is_prime(n)\n", 254 | "\n", 255 | "def pseudoprimes(start, end, is_pseudoprime):\n", 256 | " num_primes = 0\n", 257 | " pseudoprimes = []\n", 258 | " for n in range(start, end + 1):\n", 259 | " if is_prime(n):\n", 260 | " num_primes += 1\n", 261 | " elif is_pseudoprime(n):\n", 262 | " pseudoprimes.append(n)\n", 263 | " return pseudoprimes, num_primes\n", 264 | "\n", 265 | "def study_pseudoprimes(start, end, is_pseudoprime, name):\n", 266 | " pseudoprimes_list, num_primes = pseudoprimes(start, end, is_pseudoprime)\n", 267 | " print('Interval[', start, ',', end, ']')\n", 268 | " print(' ', num_primes, 'primes')\n", 269 | " print(' ', len(pseudoprimes_list), name, ':', pseudoprimes_list)\n", 270 | "\n", 271 | "print('Poulet numbers\\n') \n", 272 | "study_pseudoprimes(2, 1000, is_poulet, 'poulet numbers')\n", 273 | "print()\n", 274 | "study_pseudoprimes(1000000, 1010000, is_poulet, 'poulet numbers')" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "While it looks like Poulet numbers are rare and this could be a good heuristic (and it seems to get better for larger numbers) it is not a __proof__ of primality.\n", 282 | "\n", 283 | "__2-3 Pseudoprimes__\n", 284 | "\n", 285 | "Our next attempt is to extend the test, and use 2 and 3 (and not just 2). \n", 286 | "\n", 287 | "Does $$2^{n-1} = 1 \\mod n$$ and $$3^{n-1} = 1 \\mod n$$ imply that $n$ is prime?\n", 288 | "\n", 289 | "Things get a little better but, unfortunately, the answer is no again." 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 6, 295 | "metadata": {}, 296 | "outputs": [ 297 | { 298 | "name": "stdout", 299 | "output_type": "stream", 300 | "text": [ 301 | "2-3 pseudoprimes\n", 302 | "\n", 303 | "Interval[ 2 , 1000 ]\n", 304 | " 167 primes\n", 305 | " 0 2-3 pseudoprimes : []\n", 306 | "Interval[ 1000000 , 1010000 ]\n", 307 | " 753 primes\n", 308 | " 0 2-3 pseudoprimes : []\n", 309 | "Interval[ 1000000 , 1100000 ]\n", 310 | " 7216 primes\n", 311 | " 4 2-3 pseudoprimes : [1024651, 1033669, 1050985, 1082809]\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "def is_2_3_pseudoprime(n):\n", 317 | " return fermat_test(n, 2) and fermat_test(n, 3) and not is_prime(n)\n", 318 | "\n", 319 | "print('2-3 pseudoprimes\\n') \n", 320 | "study_pseudoprimes(2, 1000, is_2_3_pseudoprime, '2-3 pseudoprimes')\n", 321 | "study_pseudoprimes(1000000, 1010000, is_2_3_pseudoprime, '2-3 pseudoprimes')\n", 322 | "study_pseudoprimes(1000000, 1100000, is_2_3_pseudoprime, '2-3 pseudoprimes')" 323 | ] 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "We could try to refine this approach, but it seems it can produce better and better heuristics, but not a proof.\n", 330 | "\n", 331 | "## Primality witnesses\n", 332 | "\n", 333 | "As we saw earlier, $341$ is a pseudoprime. The question is whether there is some way of distinguishing of real primes.\n", 334 | "\n", 335 | "The answer is yes. Real primes have generators. More precisely:\n", 336 | "\n", 337 | "if $p$ is prime, there is $g$ such that all the elements of the sequence $g^1, g^2, \\ldots, g^{p-1}$ are distinct." 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 7, 343 | "metadata": {}, 344 | "outputs": [], 345 | "source": [ 346 | "def sequence(a, n):\n", 347 | " res = a\n", 348 | " len = 1\n", 349 | " count = 0\n", 350 | " while True:\n", 351 | " print(res, end=' ')\n", 352 | " res = (res * a) % n\n", 353 | " len += 1\n", 354 | " if res == 1:\n", 355 | " print(res)\n", 356 | " break\n", 357 | " if (count == 30):\n", 358 | " break\n", 359 | " count += 1\n", 360 | " return len\n", 361 | "\n", 362 | "def study_sequence(a, n):\n", 363 | " len = sequence(a, n)\n", 364 | " print('(', a, ',', n, ') period =', len, end='\\n')\n", 365 | "\n", 366 | " \n", 367 | "#study_sequence(11, 341)\n", 368 | " \n", 369 | "#for i in range(2, 341):\n", 370 | "# study_sequence(i, 341)\n", 371 | " \n", 372 | "#study_sequence(3, 341)\n", 373 | "#study_sequence(2, 347)\n", 374 | "#study_sequence(3, 347)" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 8, 380 | "metadata": {}, 381 | "outputs": [], 382 | "source": [ 383 | "def is_generator(a, n):\n", 384 | " res = 1\n", 385 | " for i in range(n - 2):\n", 386 | " res = (res * a) % n\n", 387 | " if res == 1:\n", 388 | " return False\n", 389 | " return True\n", 390 | "\n", 391 | "def gcd(a, b):\n", 392 | " if b == 0: return a\n", 393 | " return gcd(b, a % b)\n", 394 | " \n", 395 | "def has_generator(n):\n", 396 | " for a in range(2, n):\n", 397 | " if gcd(a, n) == 1 and is_generator(a, n):\n", 398 | " return True\n", 399 | " return False\n", 400 | "\n", 401 | "for n in range(3, 1000):\n", 402 | " prime = is_prime(n)\n", 403 | " generator = has_generator(n)\n", 404 | " assert(not (prime and not generator))\n", 405 | " assert(not (not prime and generator))" 406 | ] 407 | }, 408 | { 409 | "cell_type": "markdown", 410 | "metadata": {}, 411 | "source": [ 412 | "## Primality Verifier\n", 413 | "\n", 414 | "We present now a function that allows to verify primality certificates." 415 | ] 416 | }, 417 | { 418 | "cell_type": "code", 419 | "execution_count": 9, 420 | "metadata": {}, 421 | "outputs": [], 422 | "source": [ 423 | "# Verifies that (factors, witnesses) is a valid primality certificate for n.\n", 424 | "# The indentation helps readability, showing the recursion level in the output.\n", 425 | "# The verified_set is the set of primes that have been already verified, so we \n", 426 | "# don't verify them again.\n", 427 | "def verify_primality_certificate(n, factors, witnesses, indentation='', verified_set=[]):\n", 428 | " if n == 2:\n", 429 | " print(indentation,\"2 is a known prime\")\n", 430 | " return True\n", 431 | " if n in verified_set:\n", 432 | " print(indentation, n, \"already verified\")\n", 433 | " return True\n", 434 | " print(indentation, \"verifying\", n, \"...\")\n", 435 | " myfactors = factors[n]\n", 436 | " # Verify product.\n", 437 | " product = 1\n", 438 | " for f in myfactors:\n", 439 | " product *= f\n", 440 | " if product != n - 1:\n", 441 | " print(indentation, product, '!=', n - 1)\n", 442 | " return False\n", 443 | " print(indentation, \"product checked for\", n, '- 1')\n", 444 | " # Verify criteria.\n", 445 | " witness = witnesses[n]\n", 446 | " if pow_mod(witness, n-1, n) != 1:\n", 447 | " return False\n", 448 | " for f in myfactors:\n", 449 | " if pow_mod(witness, (n-1)//f, n) == 1:\n", 450 | " print('Oops', witness, n, (n-1)//f, n)\n", 451 | " return False\n", 452 | " print(indentation, \"witness checked for\", n)\n", 453 | " # Recurse.\n", 454 | " print(indentation, 'recursing on factors', myfactors, 'of', n, '- 1')\n", 455 | " for f in myfactors:\n", 456 | " if not verify_primality_certificate(f, factors, witnesses, indentation + ' ', verified_set):\n", 457 | " return False\n", 458 | " print(indentation, '==>', n, \"is prime\")\n", 459 | " verified_set.append(n)\n", 460 | " return True" 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "metadata": {}, 466 | "source": [ 467 | "__Verifying 31__" 468 | ] 469 | }, 470 | { 471 | "cell_type": "code", 472 | "execution_count": 10, 473 | "metadata": {}, 474 | "outputs": [ 475 | { 476 | "name": "stdout", 477 | "output_type": "stream", 478 | "text": [ 479 | " verifying 31 ...\n", 480 | " product checked for 31 - 1\n", 481 | " witness checked for 31\n", 482 | " recursing on factors [2, 3, 5] of 31 - 1\n", 483 | " 2 is a known prime\n", 484 | " verifying 3 ...\n", 485 | " product checked for 3 - 1\n", 486 | " witness checked for 3\n", 487 | " recursing on factors [2] of 3 - 1\n", 488 | " 2 is a known prime\n", 489 | " ==> 3 is prime\n", 490 | " verifying 5 ...\n", 491 | " product checked for 5 - 1\n", 492 | " witness checked for 5\n", 493 | " recursing on factors [2, 2] of 5 - 1\n", 494 | " 2 is a known prime\n", 495 | " 2 is a known prime\n", 496 | " ==> 5 is prime\n", 497 | " ==> 31 is prime\n" 498 | ] 499 | }, 500 | { 501 | "data": { 502 | "text/plain": [ 503 | "True" 504 | ] 505 | }, 506 | "execution_count": 10, 507 | "metadata": {}, 508 | "output_type": "execute_result" 509 | } 510 | ], 511 | "source": [ 512 | "n = 31\n", 513 | "\n", 514 | "# (factors, witnesses) is the certificate of primality for 31.\n", 515 | "factors = {n:[2,3,5], 3:[2], 5:[2,2]}\n", 516 | "witnesses = {n:3, 3:2, 5:2}\n", 517 | "\n", 518 | "verify_primality_certificate(n, factors, witnesses, '', [])" 519 | ] 520 | }, 521 | { 522 | "cell_type": "markdown", 523 | "metadata": {}, 524 | "source": [ 525 | "__Verifying $2^{89} - 1$__" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": 11, 531 | "metadata": {}, 532 | "outputs": [ 533 | { 534 | "name": "stdout", 535 | "output_type": "stream", 536 | "text": [ 537 | " verifying 618970019642690137449562111 ...\n", 538 | " product checked for 618970019642690137449562111 - 1\n", 539 | " witness checked for 618970019642690137449562111\n", 540 | " recursing on factors [2, 3, 5, 17, 23, 89, 353, 397, 683, 2113, 2931542417] of 618970019642690137449562111 - 1\n", 541 | " 2 is a known prime\n", 542 | " verifying 3 ...\n", 543 | " product checked for 3 - 1\n", 544 | " witness checked for 3\n", 545 | " recursing on factors [2] of 3 - 1\n", 546 | " 2 is a known prime\n", 547 | " ==> 3 is prime\n", 548 | " verifying 5 ...\n", 549 | " product checked for 5 - 1\n", 550 | " witness checked for 5\n", 551 | " recursing on factors [2, 2] of 5 - 1\n", 552 | " 2 is a known prime\n", 553 | " 2 is a known prime\n", 554 | " ==> 5 is prime\n", 555 | " verifying 17 ...\n", 556 | " product checked for 17 - 1\n", 557 | " witness checked for 17\n", 558 | " recursing on factors [2, 2, 2, 2] of 17 - 1\n", 559 | " 2 is a known prime\n", 560 | " 2 is a known prime\n", 561 | " 2 is a known prime\n", 562 | " 2 is a known prime\n", 563 | " ==> 17 is prime\n", 564 | " verifying 23 ...\n", 565 | " product checked for 23 - 1\n", 566 | " witness checked for 23\n", 567 | " recursing on factors [2, 11] of 23 - 1\n", 568 | " 2 is a known prime\n", 569 | " verifying 11 ...\n", 570 | " product checked for 11 - 1\n", 571 | " witness checked for 11\n", 572 | " recursing on factors [2, 5] of 11 - 1\n", 573 | " 2 is a known prime\n", 574 | " 5 already verified\n", 575 | " ==> 11 is prime\n", 576 | " ==> 23 is prime\n", 577 | " verifying 89 ...\n", 578 | " product checked for 89 - 1\n", 579 | " witness checked for 89\n", 580 | " recursing on factors [2, 2, 2, 11] of 89 - 1\n", 581 | " 2 is a known prime\n", 582 | " 2 is a known prime\n", 583 | " 2 is a known prime\n", 584 | " 11 already verified\n", 585 | " ==> 89 is prime\n", 586 | " verifying 353 ...\n", 587 | " product checked for 353 - 1\n", 588 | " witness checked for 353\n", 589 | " recursing on factors [2, 2, 2, 2, 2, 11] of 353 - 1\n", 590 | " 2 is a known prime\n", 591 | " 2 is a known prime\n", 592 | " 2 is a known prime\n", 593 | " 2 is a known prime\n", 594 | " 2 is a known prime\n", 595 | " 11 already verified\n", 596 | " ==> 353 is prime\n", 597 | " verifying 397 ...\n", 598 | " product checked for 397 - 1\n", 599 | " witness checked for 397\n", 600 | " recursing on factors [2, 2, 3, 3, 11] of 397 - 1\n", 601 | " 2 is a known prime\n", 602 | " 2 is a known prime\n", 603 | " 3 already verified\n", 604 | " 3 already verified\n", 605 | " 11 already verified\n", 606 | " ==> 397 is prime\n", 607 | " verifying 683 ...\n", 608 | " product checked for 683 - 1\n", 609 | " witness checked for 683\n", 610 | " recursing on factors [2, 11, 31] of 683 - 1\n", 611 | " 2 is a known prime\n", 612 | " 11 already verified\n", 613 | " verifying 31 ...\n", 614 | " product checked for 31 - 1\n", 615 | " witness checked for 31\n", 616 | " recursing on factors [2, 3, 5] of 31 - 1\n", 617 | " 2 is a known prime\n", 618 | " 3 already verified\n", 619 | " 5 already verified\n", 620 | " ==> 31 is prime\n", 621 | " ==> 683 is prime\n", 622 | " verifying 2113 ...\n", 623 | " product checked for 2113 - 1\n", 624 | " witness checked for 2113\n", 625 | " recursing on factors [2, 2, 2, 2, 2, 2, 3, 11] of 2113 - 1\n", 626 | " 2 is a known prime\n", 627 | " 2 is a known prime\n", 628 | " 2 is a known prime\n", 629 | " 2 is a known prime\n", 630 | " 2 is a known prime\n", 631 | " 2 is a known prime\n", 632 | " 3 already verified\n", 633 | " 11 already verified\n", 634 | " ==> 2113 is prime\n", 635 | " verifying 2931542417 ...\n", 636 | " product checked for 2931542417 - 1\n", 637 | " witness checked for 2931542417\n", 638 | " recursing on factors [2, 2, 2, 2, 11, 1913, 8707] of 2931542417 - 1\n", 639 | " 2 is a known prime\n", 640 | " 2 is a known prime\n", 641 | " 2 is a known prime\n", 642 | " 2 is a known prime\n", 643 | " 11 already verified\n", 644 | " verifying 1913 ...\n", 645 | " product checked for 1913 - 1\n", 646 | " witness checked for 1913\n", 647 | " recursing on factors [2, 2, 2, 239] of 1913 - 1\n", 648 | " 2 is a known prime\n", 649 | " 2 is a known prime\n", 650 | " 2 is a known prime\n", 651 | " verifying 239 ...\n", 652 | " product checked for 239 - 1\n", 653 | " witness checked for 239\n", 654 | " recursing on factors [2, 7, 17] of 239 - 1\n", 655 | " 2 is a known prime\n", 656 | " verifying 7 ...\n", 657 | " product checked for 7 - 1\n", 658 | " witness checked for 7\n", 659 | " recursing on factors [2, 3] of 7 - 1\n", 660 | " 2 is a known prime\n", 661 | " 3 already verified\n", 662 | " ==> 7 is prime\n", 663 | " 17 already verified\n", 664 | " ==> 239 is prime\n", 665 | " ==> 1913 is prime\n", 666 | " verifying 8707 ...\n", 667 | " product checked for 8707 - 1\n", 668 | " witness checked for 8707\n", 669 | " recursing on factors [2, 3, 1451] of 8707 - 1\n", 670 | " 2 is a known prime\n", 671 | " 3 already verified\n", 672 | " verifying 1451 ...\n", 673 | " product checked for 1451 - 1\n", 674 | " witness checked for 1451\n", 675 | " recursing on factors [2, 5, 5, 29] of 1451 - 1\n", 676 | " 2 is a known prime\n", 677 | " 5 already verified\n", 678 | " 5 already verified\n", 679 | " verifying 29 ...\n", 680 | " product checked for 29 - 1\n", 681 | " witness checked for 29\n", 682 | " recursing on factors [2, 2, 7] of 29 - 1\n", 683 | " 2 is a known prime\n", 684 | " 2 is a known prime\n", 685 | " 7 already verified\n", 686 | " ==> 29 is prime\n", 687 | " ==> 1451 is prime\n", 688 | " ==> 8707 is prime\n", 689 | " ==> 2931542417 is prime\n", 690 | " ==> 618970019642690137449562111 is prime\n" 691 | ] 692 | }, 693 | { 694 | "data": { 695 | "text/plain": [ 696 | "True" 697 | ] 698 | }, 699 | "execution_count": 11, 700 | "metadata": {}, 701 | "output_type": "execute_result" 702 | } 703 | ], 704 | "source": [ 705 | "mersenne_89 = 2**89 - 1\n", 706 | "\n", 707 | "# (factors, witnesses) is the certificate of primality for mersenne_89.\n", 708 | "\n", 709 | "# Maps n to the factors of n-1.\n", 710 | "# The n's are the primes needed in the verification.\n", 711 | "factors = {mersenne_89:[2,3,5,17,23,89,353,397,683,2113,2931542417],\n", 712 | " 3:[2],\n", 713 | " 5:[2,2],\n", 714 | " 7:[2,3],\n", 715 | " 11:[2,5],\n", 716 | " 17:[2,2,2,2],\n", 717 | " 23:[2,11],\n", 718 | " 29:[2,2,7],\n", 719 | " 31:[2,3,5],\n", 720 | " 89:[2,2,2,11],\n", 721 | " 239:[2,7,17],\n", 722 | " 353:[2,2,2,2,2,11],\n", 723 | " 397:[2,2,3,3,11],\n", 724 | " 683:[2,11,31],\n", 725 | " 1451:[2,5,5,29],\n", 726 | " 1913:[2,2,2,239],\n", 727 | " 2113:[2,2,2,2,2,2,3,11],\n", 728 | " 8707:[2,3,1451],\n", 729 | " 2931542417:[2,2,2,2,11,1913,8707]}\n", 730 | "\n", 731 | "# Maps n to its witness for Fermat's test.\n", 732 | "# The n's are the primes needed in the verification.\n", 733 | "witnesses = {mersenne_89:3, \n", 734 | " 3:2, \n", 735 | " 5:2, \n", 736 | " 7:3,\n", 737 | " 11:2, \n", 738 | " 17:3, \n", 739 | " 23:5, \n", 740 | " 29:2,\n", 741 | " 31:3, \n", 742 | " 89:3, \n", 743 | " 239:7,\n", 744 | " 353:3, \n", 745 | " 397:5, \n", 746 | " 683:5,\n", 747 | " 1451:2,\n", 748 | " 1913:3,\n", 749 | " 2113:5, \n", 750 | " 8707:5,\n", 751 | " 2931542417:3}\n", 752 | "\n", 753 | "verify_primality_certificate(mersenne_89, factors, witnesses, '', [])" 754 | ] 755 | } 756 | ], 757 | "metadata": { 758 | "kernelspec": { 759 | "display_name": "Python 3", 760 | "language": "python", 761 | "name": "python3" 762 | }, 763 | "language_info": { 764 | "codemirror_mode": { 765 | "name": "ipython", 766 | "version": 3 767 | }, 768 | "file_extension": ".py", 769 | "mimetype": "text/x-python", 770 | "name": "python", 771 | "nbconvert_exporter": "python", 772 | "pygments_lexer": "ipython3", 773 | "version": "3.6.5" 774 | } 775 | }, 776 | "nbformat": 4, 777 | "nbformat_minor": 2 778 | } 779 | -------------------------------------------------------------------------------- /Sum of powers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
Paul Novaes
June 2018
\n", 8 | "\n", 9 | "# Sum of Powers\n", 10 | "\n", 11 | "We show how to find closed formulas for $$1^k+2^k +\\cdots + n^k$$\n", 12 | "using a simple program and elementary linear algebra.\n", 13 | "\n", 14 | "We then compare our results to those in Bernouilli's [Ars Conjectandi](https://en.wikipedia.org/wiki/Ars_Conjectandi) and find a typo in [its formula](https://books.google.com/books?id=kD4PAAAAQAAJ&pg=PA97#v=onepage&q&f=false) for $\\int n^9$.\n", 15 | "\n", 16 | "![Wikipedia](https://upload.wikimedia.org/wikipedia/commons/7/74/JakobBernoulliSummaePotestatum.png)" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## Finding a closed formula\n", 24 | "\n", 25 | "The goal is to find close formulas for the sum of powers, such as $1+2 +\\cdots + n = {{n(n+1)}\\over 2}$. Of course we could look them up, but it would be more fun to find them by ourselves, rather than to deal with Bernouilli numbers and what not. \n", 26 | "\n", 27 | "Let's define $$S_k(n) = 1^k+2^k +\\cdots + n^k$$\n", 28 | "\n", 29 | "We will assume that $S_k(n)$ is a polynomial of degree $k+1$. Note that this same assuption had to be made by Bernouilli too, since his formulas were not proven until Jacobi.\n", 30 | "\n", 31 | "Our goal is to find a polynomial $$P_k(n) = a_{k+1}n^{k+1} + a_kn^k + \\cdots a_0n^0$$ such that, for all $n \\ge 0$, $P_k(n) = S_k(n)$.\n", 32 | "\n", 33 | "Since a polynomial of degree $d$ is uniquely determined by its value on $d+1$ points, we just need to find $P_k$ such that $P_k(n) = S_k(n)$ for $n = 0, 1, \\ldots, k+1$. Or, in matrix form:\n", 34 | "\n", 35 | "\n", 36 | "\\begin{equation}\n", 37 | "\\begin{pmatrix} 0^{k+1} & 0^k & \\cdots & 0^0 \\\\ 1^{k+1} & 1^k & \\cdots & 1^0 \\\\ \\vdots & \\vdots & & \\vdots \\\\ (k+1)^{k+1} & (k+1)^k & \\cdots & (k+1)^0 \\end{pmatrix}\n", 38 | "\\begin{pmatrix} a_{k+1} \\\\ a_k \\\\ \\vdots \\\\ a_0 \\end{pmatrix}\n", 39 | "= \\begin{pmatrix} 0 \\\\ 1^k \\\\ \\vdots \\\\ 1^k + 2^k + \\cdots + (k+1)^k\\end{pmatrix} \n", 40 | "\\end{equation}\n", 41 | "\n", 42 | "So we have reduced our problem to solving a system of linear equations of the form $AX = B$, where $A$ and $B$ are known and $X$ (the coefficients of the polynomial) is unknown.\n", 43 | "\n", 44 | "Note that in the formula above, we follow Python's convention: $0^0 = 1$." 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "## Using sympy to solve the system" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 1, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "from sympy import *\n", 61 | "\n", 62 | "def MatrixA(k):\n", 63 | " A = [[0 for x in range(k + 2)] for y in range(k + 2)]\n", 64 | " for i in range(k + 2):\n", 65 | " for j in range(k + 2):\n", 66 | " A[i][j] = i ** (k - j + 1)\n", 67 | " return Matrix(A)\n", 68 | "\n", 69 | "def MatrixB(k):\n", 70 | " B = [0 for x in range(k + 2)]\n", 71 | " for i in range(1, k + 2):\n", 72 | " B[i] = B[i - 1] + i ** k \n", 73 | " return Matrix(B)\n", 74 | "\n", 75 | "def formula_sum_of_powers(k):\n", 76 | " A = MatrixA(k)\n", 77 | " B = MatrixB(k)\n", 78 | " X = A.LUsolve(B)\n", 79 | " return X" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "## Verifying the formula in simple cases" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 2, 92 | "metadata": { 93 | "scrolled": true 94 | }, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "Matrix([\n", 100 | "[1/2],\n", 101 | "[1/2],\n", 102 | "[ 0]])" 103 | ] 104 | }, 105 | "execution_count": 2, 106 | "metadata": {}, 107 | "output_type": "execute_result" 108 | } 109 | ], 110 | "source": [ 111 | "formula_sum_of_powers(1)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "That is, we have the familiar formula $$1+2+\\cdots+n = {{n^2}\\over 2} + {n\\over 2}$$" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 3, 124 | "metadata": { 125 | "scrolled": true 126 | }, 127 | "outputs": [ 128 | { 129 | "data": { 130 | "text/plain": [ 131 | "Matrix([\n", 132 | "[1/3],\n", 133 | "[1/2],\n", 134 | "[1/6],\n", 135 | "[ 0]])" 136 | ] 137 | }, 138 | "execution_count": 3, 139 | "metadata": {}, 140 | "output_type": "execute_result" 141 | } 142 | ], 143 | "source": [ 144 | "formula_sum_of_powers(2)" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "That is, $$1^2+2^2+\\cdots+n^2 = {{n^3}\\over3} + {{n^2}\\over 2} + {n\\over 6}$$" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "## Finding a formula for $1^{100} + 2^{100} + \\cdots + n^{100}$\n", 159 | "\n", 160 | "Using our program, it is a breeze to show that $1^{100} + 2^{100} + \\cdots + n^{100}$ can be expressed as\n", 161 | "\n", 162 | "$${1\\over 101}n^{101} + {1\\over 2}n^{100} + {25\\over 3}n^{99} + \\cdots -{94598037819122125295227433069493721872702841533066936133385696204311395415197247711\\over 33330}n$$" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 4, 168 | "metadata": {}, 169 | "outputs": [ 170 | { 171 | "data": { 172 | "text/plain": [ 173 | "Matrix([\n", 174 | "[ 1/101],\n", 175 | "[ 1/2],\n", 176 | "[ 25/3],\n", 177 | "[ 0],\n", 178 | "[ -2695/2],\n", 179 | "[ 0],\n", 180 | "[ 298760],\n", 181 | "[ 0],\n", 182 | "[ -66698170],\n", 183 | "[ 0],\n", 184 | "[ 43232541100/3],\n", 185 | "[ 0],\n", 186 | "[ -2987368590010],\n", 187 | "[ 0],\n", 188 | "[ 592545208316600],\n", 189 | "[ 0],\n", 190 | "[ -1909010939318560231/17],\n", 191 | "[ 0],\n", 192 | "[ 60927624576260699950/3],\n", 193 | "[ 0],\n", 194 | "[ -10503770178403996919537/3],\n", 195 | "[ 0],\n", 196 | "[ 574696979476592789539800],\n", 197 | "[ 0],\n", 198 | "[ -89701724868851868404757210],\n", 199 | "[ 0],\n", 200 | "[ 13296745470530926863904296852],\n", 201 | "[ 0],\n", 202 | "[ -1869298239768618416234153813290],\n", 203 | "[ 0],\n", 204 | "[ 248870955751990847260270884407400],\n", 205 | "[ 0],\n", 206 | "[ -1065245686771269279784908613651828005/34],\n", 207 | "[ 0],\n", 208 | "[ 3723652407297582727619274890591931075],\n", 209 | "[ 0],\n", 210 | "[ -10844299000116828980379757772973769420469/26],\n", 211 | "[ 0],\n", 212 | "[ 43950288418050613210495571589828389262800],\n", 213 | "[ 0],\n", 214 | "[ -4348447505694585428839166185138223415249684],\n", 215 | "[ 0],\n", 216 | "[ 403139711179170251736670257248480111641926600],\n", 217 | "[ 0],\n", 218 | "[ -34944260063316672143127900206016265956506516820],\n", 219 | "[ 0],\n", 220 | "[ 2825393845314372316887963516463774302220183874480],\n", 221 | "[ 0],\n", 222 | "[ -46975128963737486419489164499794297560673231041202090/221],\n", 223 | "[ 0],\n", 224 | "[ 14838677083702274079364344314958348779821717660137900],\n", 225 | "[ 0],\n", 226 | "[ -958463607702055700662952442255558159708363131670845130],\n", 227 | "[ 0],\n", 228 | "[ 57102248319760803358389861613269821873306861123018474800],\n", 229 | "[ 0],\n", 230 | "[ -3127153223428501512572222954783017354698250212191091945572],\n", 231 | "[ 0],\n", 232 | "[ 156839198684220220595062954768424384099662857573873761392200],\n", 233 | "[ 0],\n", 234 | "[ -93273006623793637434656479802977293641893710056414115793830132/13],\n", 235 | "[ 0],\n", 236 | "[ 298055222117767447988694875776788702575308931452828672542296400],\n", 237 | "[ 0],\n", 238 | "[ -380420681562789081339436627697748498619486609696130138245054547645/34],\n", 239 | "[ 0],\n", 240 | "[ 377511069257143967197314136886615170865786408764196373626268649635],\n", 241 | "[ 0],\n", 242 | "[ -22758671683254934243234770245768111655371809025564559292966948184145/2],\n", 243 | "[ 0],\n", 244 | "[ 304383493005866429515905139920856508495517057169598168611307541714600],\n", 245 | "[ 0],\n", 246 | "[ -93215398532963113031284566771666289746833192047887884379325411297276490/13],\n", 247 | "[ 0],\n", 248 | "[ 147482537396120605270641214092320919218664984298368495230915199366025300],\n", 249 | "[ 0],\n", 250 | "[ -13112574861745373977119865065563790341936971501269597493806710307275562234/5],\n", 251 | "[ 0],\n", 252 | "[ 39857448167724145521712375634202721882854746999642509687138048831663608600],\n", 253 | "[ 0],\n", 254 | "[ -8684587426344073606489504709883050170678418405635672010429984157277666084023/17],\n", 255 | "[ 0],\n", 256 | "[ 16304634906294224258925539055711850026937478314146500355475130833028845746350/3],\n", 257 | "[ 0],\n", 258 | "[ -612067818251686839120746668057583204003010059302601007211600982133792394509295/13],\n", 259 | "[ 0],\n", 260 | "[ 324388433491984944852419075920450620931865462636226130063940688368734730163320],\n", 261 | "[ 0],\n", 262 | "[ -1725539552167813151807602972961047761861449443882732089672204732211086637590530],\n", 263 | "[ 0],\n", 264 | "[ 225010984573490896048358130480328881791747873028668541553377868767760647319540900/33],\n", 265 | "[ 0],\n", 266 | "[ -56995948223784756021697384698478769187481110881793715780290371409596995575985270/3],\n", 267 | "[ 0],\n", 268 | "[ 34649381621107623485288357725441359210991177541965976048926944361209977534643400],\n", 269 | "[ 0],\n", 270 | "[ -16293234618989521508515025064456465992824384487957638029599182473343901462949018943/442],\n", 271 | "[ 0],\n", 272 | "[ 18674771685049011296614057325260991542019103825338734064995339343748060441015725],\n", 273 | "[ 0],\n", 274 | "[-94598037819122125295227433069493721872702841533066936133385696204311395415197247711/33330],\n", 275 | "[ 0]])" 276 | ] 277 | }, 278 | "execution_count": 4, 279 | "metadata": {}, 280 | "output_type": "execute_result" 281 | } 282 | ], 283 | "source": [ 284 | "formula_sum_of_powers(100)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "## A typo in _Ars Conjectandi_\n", 292 | "\n", 293 | "In _Ars Conjectandi_, it says, for $\\int n^9$ (Bernouilli's notation for $\\sum_{i=1}^n{i^9}$):\n", 294 | "\n", 295 | "$$\\int n^9 = {1\\over 10}n^{10} + {1\\over 2}n^9 +{3\\over 4}n^8 -{7\\over 10}n^6 +{1\\over 2}n^4 -{1\\over 12}nn$$\n", 296 | "\n", 297 | "But the actual closed formula is\n", 298 | "\n", 299 | "$$\\int n^9 = {1\\over 10}n^{10} + {1\\over 2}n^9 +{3\\over 4}n^8 -{7\\over 10}n^6 +{1\\over 2}n^4 -{3\\over 20}nn$$\n", 300 | "\n", 301 | "Indeed:" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 5, 307 | "metadata": {}, 308 | "outputs": [ 309 | { 310 | "data": { 311 | "text/plain": [ 312 | "Matrix([\n", 313 | "[ 1/10],\n", 314 | "[ 1/2],\n", 315 | "[ 3/4],\n", 316 | "[ 0],\n", 317 | "[-7/10],\n", 318 | "[ 0],\n", 319 | "[ 1/2],\n", 320 | "[ 0],\n", 321 | "[-3/20],\n", 322 | "[ 0],\n", 323 | "[ 0]])" 324 | ] 325 | }, 326 | "execution_count": 5, 327 | "metadata": {}, 328 | "output_type": "execute_result" 329 | } 330 | ], 331 | "source": [ 332 | "formula_sum_of_powers(9)" 333 | ] 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": {}, 338 | "source": [ 339 | "## Bernouilli numbers\n", 340 | "\n", 341 | "Finally, let's note that the coefficient of $n$ in the polynomial for $S_k(n)$ is the k-th [Bernouilli number](https://en.wikipedia.org/wiki/Bernoulli_number). Therefore, we have:" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "execution_count": 6, 347 | "metadata": {}, 348 | "outputs": [], 349 | "source": [ 350 | "def bernouilli_number(k):\n", 351 | " return formula_sum_of_powers(k)[k]" 352 | ] 353 | }, 354 | { 355 | "cell_type": "markdown", 356 | "metadata": {}, 357 | "source": [ 358 | "Which can be used to find the first 20 Bernouilli numbers:" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 7, 364 | "metadata": {}, 365 | "outputs": [ 366 | { 367 | "name": "stdout", 368 | "output_type": "stream", 369 | "text": [ 370 | "B_1 = 1/2\n", 371 | "B_2 = 1/6\n", 372 | "B_3 = 0\n", 373 | "B_4 = -1/30\n", 374 | "B_5 = 0\n", 375 | "B_6 = 1/42\n", 376 | "B_7 = 0\n", 377 | "B_8 = -1/30\n", 378 | "B_9 = 0\n", 379 | "B_10 = 5/66\n", 380 | "B_11 = 0\n", 381 | "B_12 = -691/2730\n", 382 | "B_13 = 0\n", 383 | "B_14 = 7/6\n", 384 | "B_15 = 0\n", 385 | "B_16 = -3617/510\n", 386 | "B_17 = 0\n", 387 | "B_18 = 43867/798\n", 388 | "B_19 = 0\n", 389 | "B_20 = -174611/330\n" 390 | ] 391 | } 392 | ], 393 | "source": [ 394 | "for i in range(1, 21):\n", 395 | " print(\"B_\", i, \" = \", bernouilli_number(i), sep=\"\")" 396 | ] 397 | } 398 | ], 399 | "metadata": { 400 | "kernelspec": { 401 | "display_name": "Python 3", 402 | "language": "python", 403 | "name": "python3" 404 | }, 405 | "language_info": { 406 | "codemirror_mode": { 407 | "name": "ipython", 408 | "version": 3 409 | }, 410 | "file_extension": ".py", 411 | "mimetype": "text/x-python", 412 | "name": "python", 413 | "nbconvert_exporter": "python", 414 | "pygments_lexer": "ipython3", 415 | "version": "3.6.5" 416 | } 417 | }, 418 | "nbformat": 4, 419 | "nbformat_minor": 2 420 | } 421 | --------------------------------------------------------------------------------